[ipv6hackers] An idea for a happy eyeballs "shim" (was Re: Windows 7/2008 R2 Improved Resilliency to IPv6 Floods)
markzzzsmith at yahoo.com.au
Thu Apr 18 11:19:15 CEST 2013
----- Original Message -----
> From: Andrew Yourtchenko <ayourtch at gmail.com>
> To: IPv6 Hackers Mailing List <ipv6hackers at lists.si6networks.com>
> Sent: Thursday, 18 April 2013 9:12 AM
> Subject: Re: [ipv6hackers] Windows 7/2008 R2 Improved Resilliency to IPv6 Floods
> Hi Marc, all,
> re. "sample code for happy eyeballs" - I had that ambition in the
> (it was a bit more - to try to create a patch to retrofit the existing code
> with stuff like LD_PRELOAD and similar), but after studying the wide
> variety of the ways the various hosts do the connections, I decided against
> it - way too cludgy.
> Happy Eyeballs implies more than one connection in progress, and this
> implies the concurrency model, and between the poll() loop, select() loop,
> threads du jour and separate processes I had decided there is no way to
> make a sample code that would be useful enough.
> One thought I had which might make this a bit tractable is to suggest a
> model that would separate the DNS lookup/connection establishment into a
> separate process, and use some more or less portable mechanism  to pass
> the file descriptors around..
> The idea is to export a function with an interface of:
> int connect_by_name(char *hostname, char *service);
> which if necessary would fork and start a "happy connection process",
> in turn does all arbitration and maintains the "knowledge" between the
> But I am very much divided from the security PoV - this delegates all the
> connection authority to a separate process, and seemingly break the
> assumptions the various anti-evil software might have, and I did not have
> enough quiet time to think it through.
> What do the folks think - would such a project be useful ?
So here is an idea I've been thinking about a bit recently, which might be the next step on from your thoughts. I've been mainly thinking about a TCP application, however the idea might also be applicable to UDP applications (and maybe SCTP or DCCP):
(1) Have a daemon (perhaps called "happy-shim"), which catches calls to getaddrinfo() and the old gethostbyname() (via LD_PRELOAD or similar). The daemon then does the following :
(2) returns either 127.0.0.1 (or another address within 127/8) or ::1 to the caller of getaddrinfo() depending on flags or calling of gethostbyname() for IPv4 only applications.
(3) performs it's own call of getaddrinfo() for the name, and remembers all results, in a table, which also remembers details of the process that called getaddrinfo() or gethostbyname().
(4) when the application calls connect(), now to the 127.0.0.1 or ::1 address, catch that via LD_PRELOAD or similar. Look up the table, and then using happy eyeballs techniques, have the daemon establish a connection to the actual IPv4/IPv6 etc. addresses that were returned to the daemon when it called getaddrinfo(). Once the daemon's TCP connection is established, pass it back to the application via the file descriptor supplied in the connect() call.
(5) catch when the application calls close(), and have the happy-shim daemon tear down the connection it established to the actual destination.
One variation which might be useful would be to delay step (3) until when the application calls connect() in step (4).
I think happy eyeball techniques could also be applied to the DNS queries in (3), so that upstream resolvers that don't like IPv6 AAAA queries are worked around (e.g. first lookup is a single IPv4/IPv6 query, if there is no response within 400ms or NX Domain or similar, perform separate and parallel IPv4 only and IPv6 only queries. A broken resolver will likely drop the IPv6 only query, but allow the IPv4 only query to pass. It'd be "semantic retransmission" to overcome packet loss in the network caused by a broken upstream DNS resolver, rather than literal retransmission of the failed IPv4/IPv6 DNS query.).
One idea which might make it simpler to implement and perhaps easier to troubleshoot is to take advantage of 127/8's large address space, and return to each different application that is "shimmed" it's own unique 127/8 address. That idea couldn't be applied to IPv6 as it's autoconfigured loopback prefix only has a single address.
Applications which send their own local addresses within their application data are likely to break, as e.g, an IPv4 only application would supply it's address to an IPv6 peer that is hidden behind the happy-shim daemon. Those types of applications might be pretty easy to identify and perhaps could be black listed such that their calls to getaddrinfo() or gethostbyname() are ignored by happy-shim, and given standard treatment. It may even be possible to maintain that list of blacklisted applications and their version numbers or some other unique identifier within the DNS system, rather than within the happy-shim daemon itself.
So I think this idea would transparently IPv6 enable a subset of the IPv4 only applications, and would transparently give a subset of IPv4/IPv6 applications happy eyeballs support.
More information about the Ipv6hackers