I write portable Windows/Linux application that uses sockets. I use gethostbyname
function to perform DNS lookups.
However, I don't see how to set gethostbyname
timeout and secure my application against hanging during name lookup.
Of course, it is possible to run gethostbyname
on another thread, and that what I do. However, it is solution for trivial applications only.
My application uses 1000-3000 connections in parallel. In such situation the question is: what to do with timeouted threads? I don't see good solution. We can "forget" them, however, we are at risk that our program threads count will grow up to infinity on bad networks. We can terminate them, but the idea looks terrible. From my experience, Windows can crash after thousands of threads termination, and I don't know how Linux will behave in such conditions.
Also, thread creation needs many resources; it is not good idea to create 3000 threads just to run gethostbyname
function and exit.
So, separate thread doesn't look like good idea for really complex application. Another alternative is to write own DNS client of course, however, it also doesn't look good.
Is there any "official" way on Windows and Linux (or better portable way) to get host address with custom timeout?

- 4,434
- 4
- 35
- 77
-
IIRC, some Windows and Windows Server versions do support asynchronous lookups, with timeouts, via the overlapped I/O mechansim, (GetAddrInfoEx). but this is hardly portable. You could implement a fixed-size threadpool, (64?), to run the blocking queries and a delta-queue of 'DNSrequest' objects, run by one more thread, to implement your timeouts. You could implement that with POSIX semaphores and a sprinkling of other synchro objects. – Martin James Jun 25 '14 at 08:45
-
You can use some third-party library for resolving or write your own implementation. – someuser Jun 25 '14 at 08:45
-
@Martin James GetAddrInfoEx is sockets 2, which is not portable and even worse, it is problematic to complile togeather with static library that uses sockets 1.1 like libcurl, openssl. Probably portable solution doesn't exist... – Vitalii Jun 25 '14 at 08:48
-
@GoodGuySoft - I'm fairly sure that you could implement such a system with POSIX threads and semaphores etc. You should check out a lib or two before attempting to roll-your-own. I will say, though, that continually creating, terminating and destroying a thread for each query is a really bad design for multiple reasons, some of which you already appreciate. – Martin James Jun 25 '14 at 09:14
2 Answers
First of all: don't use gethostbyname()
, it's obsolete. Use getaddrinfo()
instead.
What you want is asynchronous name resolution. It's a common requirement, but unfortunately there is no "standard" way, how to do it. Here my hints for finding the best solution for you:
Don't implement a DNS client. Name resolution is more than just DNS. Think of mDNS, hosts files and so on. Use a system function like
getaddrinfo()
that abstracts the different name resolution mechanisms for you.Some systems offer asynchronous versions of the resolution functions, like glibc offers
getaddrinfo_a()
.There are asynchronous resolution libraries, that wrap around the synchronous system resolver functions. At first libasyncns comes to my mind.
Boost.Asio supports to use the resolver with a thread pool. See here.
The most portable solution is indeed to use a separate thread for name resolution. This is also documented in MSDN.
Non portable solutions exist that perform asynchronous name looksups.
Linux glibc 2.2.3+: getaddrinfo_a
Windows: WSAAsyncGetHostByName IPv4 only :(
There are asynchronous DNS libraries out there: TADNS for example looks easy enough.

- 21,822
- 5
- 49
- 75