getaddrinfo performance problems

Ed W lists at wildgooses.com
Mon Apr 16 17:42:02 UTC 2012


On 16/04/2012 16:48, Rich Felker wrote:
> On Mon, Apr 16, 2012 at 03:05:54PM +0100, Ed W wrote:
>> Hi, I'm suffering extreme performance problems with getaddrinfo
>> being used by ipset to do conversions from IP textual strings to
>> number.  Although the IP address is textual there is a reverse DNS
>> lookup performed and in the event that my resolver is slow, this is
>> sometimes taking 60seconds or so to return
> I have not looked at the source, but I suspect this is a uClibc bug
> based on a misreading of the standard. Many incorrect historical
> getaddrinfo implementations performed unnecessary reverse dns lookups
> to fill in the ai_canonname field of the addrinfo structure. POSIX is
> very clear that this is wrong:
>
>    A numeric host address string is not a ``name'', and thus does not
>    have a ``canonical name'' form; no address to host name translation
>    is performed. See below for handling of the case where a canonical
>    name cannot be obtained.
>
> Source:
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html
>
>

OK, attached is my patch which implements posix defined behaviour, 
including returning an error condition if we hint AI_NUMERICSERV and it 
isn't

Grateful if someone could look it over and apply if it seems fine?

Main change is that DNS lookups will not be triggered for a bunch of 
unnecessary situations. This can be a big performance increase in 
certain cases

Thanks

Ed W
-------------- next part --------------
Posix says that we should not do reverse dns lookups in getaddrinfo
to populate canonname. 
See: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html

Signed-off-by: Ed Wildgoose <lists at wildgooses.com>
---

--- a/libc/inet/getaddrinfo.c	2012-04-16 18:28:05.000000000 +0100
+++ b/libc/inet/getaddrinfo.c	2012-04-16 18:28:30.000000000 +0100
@@ -628,13 +628,18 @@
 		char buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
 
 		while (at2 != NULL) {
-			if (req->ai_flags & AI_CANONNAME) {
+            if ( (req->ai_flags & AI_CANONNAME) 
+                && !inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer)) ) {
 				struct hostent *h = NULL;
 				int herrno;
 				struct hostent th;
 				size_t tmpbuflen = 512;
 				char *tmpbuf;
 
+                /* Hint says numeric, but address is not */
+                if (req->ai_flags & AI_NUMERICSERV)
+                    return -EAI_NONAME;
+
 				do {
 					tmpbuflen *= 2;
 					tmpbuf = alloca(tmpbuflen);


More information about the uClibc mailing list