where the flamingcow roams

Asynchronous name resolution in C


Down another rabbit hole, this time into yet another seemingly simple problem: how do you turn a name into an address that you can connect() to without blocking your thread, in 2016. Let’s survey state of the world:

getaddrinfo_a()

Look, it’s exactly what we need! Just joking. It’s has the same resolution behavior as getaddrinfo, but:

libadns

libasyncns

c-ares

I failed to find docs for this, but I found a gist with an example. Looks like the API is designed for use with select(), though there’s a hook to get an fd when it’s created, so you might be able to associate it with a query, possibly unreliably. Again, you’d have to recreate getaddrinfo() behavior yourself. Also, this gem is at the top of the header:

#elif defined(WIN32)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <winsock2.h>
# include <ws2tcpip.h>

So maybe not.

So now what?

Maybe we can build something. I really don’t need to write another DNS library in my lifetime (the c-ares Other Libraries page links to my previous one, humorously). Let’s see if we can scope some requirements:

And some nice-to-haves:

After looking at all these libraries, you’d think this would be a massive job. In fact, it’s 127 lines of C, and that’s with generous error checking and readability. Hopefully, I never have to solve this problem again.