socketry/rubydns

Resolver's IP address question

leonardteo opened this issue · 3 comments

Hi Samuel,

I just had a very quick question about RubyDNS - which looks like an awesome project btw, congrats.

I am writing a "poor man's CDN" and I'd like to set up a DNS server. RubyDNS looks like it can do the job, but one feature that I would like to write is to do a GeoIP lookup of the client's IP address.

The thing is, I'm not sure if the client's IP address is available in the lookup? (or if it's even part of the DNS protocol!?)

Given that you know far far more about DNS than I do, I just wanted to know if it's possible to get the client's IP address? This would enable us to do funky things like GeoIP lookup and return the IP address of the closest server.

Thanks!

Leo

There is already an example of the geo lookup in the test directory: https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb

However the next release (0.9.x) builds on Celluloid and the API for getting the clients IP address has changed. The problem is that with EventMachine it is quite slow to get the peer address (slow enough to show up in profiling). I believe the celluloid implementation doesn't have the same performance overhead but it hasn't been released yet because I'm still waiting on a stable release of celluloid 0.16.0.

The direction RubyDNS is heading is that the stable 1.0 release will be based on some version of celluloid, so while you may use EventMachine today for the 0.8 branch of the code, be aware that you'd likely want to upgrade to 0.9 in the near future.

The reason for upgrading is mostly 4 points: performance, stability, scalability and IPv6.

1/ EventMachine actually is pretty reasonable for performance but there are some buggy edge cases where I've seen it occasionally perform quite badly (i.e. high per-request latency). Celluloid appears to have no such issues.

2/ EventMachine actually appears to be fairly buggy and is no longer maintained. I've encountered crash bugs on the latest Ruby releases and other weird issues so I'm basically assuming EventMachine is EOL and will become more unstable over time as thing change within Ruby itself.

3/ Celluloid is built on solid and proven multi-threading principals. Technically, with JRuby or Rubinius, RubyDNS should scale up linearly per core as long as it is configured to do so. Celluloid also provides a transparent deadlock-free actor based concurrency model, which lets you do things like, during an active DNS request, look up MySQL concurrently while processing other requests, and once the response is given back from MySQL driver, then respond to client DNS request. All this happens concurrently with other requests (where possible).

4/ EventMachine won't support IPv6 ever as it is EOL. Even if it did, I wouldn't have much hope of it being reliable or stable long term, so yeah, basically that's a complete deal breaker.

So, by all means, use the current 0.8.x example, but be prepared to update, probably by the end of this year - for you, it will mostly be minor API changes.

Here is the relevant API in the celluloid branch, soon to become 0.9.0 and then 1.0: https://github.com/ioquatix/rubydns/blob/3e479b2da403763bf9d7a7362b455c48c6789609/spec/rubydns/daemon_spec.rb#L48-L50

Hi Samuel,

Thank you so so much. I should have cloned the repo and checked out the test/examples. It just didn't occur to me they were there! This is great.

I'll try it out and see how the performance is. The migration to celluloid looks like it will make sense.

Thanks again!

Leo