From 54824bb0af1c05f0811cb43a0ce0a8f8753eec02 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sun, 10 Feb 2002 23:53:55 +0000 Subject: [PATCH] * fake-addrinfo.h: Always check for FAI_PREFIX, not just when fake getaddrinfo support is needed. (fixup_addrinfo): Declare. * fake-addrinfo.c (fixup_addrinfo): New function, fixes up breakage in AIX and GNU implementations (so far) of getaddrinfo. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14139 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/ChangeLog | 8 +++++++ src/include/fake-addrinfo.c | 47 +++++++++++++++++++++++++++++++++++++ src/include/fake-addrinfo.h | 10 ++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 35c585a3e..3b405fa08 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,11 @@ +2002-02-10 Ken Raeburn + + * fake-addrinfo.h: Always check for FAI_PREFIX, not just when fake + getaddrinfo support is needed. + (fixup_addrinfo): Declare. + * fake-addrinfo.c (fixup_addrinfo): New function, fixes up + breakage in AIX and GNU implementations (so far) of getaddrinfo. + 2002-01-08 Ken Raeburn * socket-utils.h (ss2sin6) [__GNUC__]: Define inline function only diff --git a/src/include/fake-addrinfo.c b/src/include/fake-addrinfo.c index 3ade9dc74..1f0047213 100644 --- a/src/include/fake-addrinfo.c +++ b/src/include/fake-addrinfo.c @@ -48,6 +48,53 @@ #include "fake-addrinfo.h" +void fixup_addrinfo (struct addrinfo *ai) +{ + struct addrinfo *ai2; + + if (ai == 0) + return; + + /* Linux libc version 6 (libc-2.2.4.so on Debian) is broken. + + RFC 2553 says that when AI_CANONNAME is set, the ai_canonname + flag of the first returned structure has the canonical name of + the host. Instead, GNU libc sets ai_canonname in all the + returned structures, sometimes it's the canonical name and + sometimes it's the numeric form of an address. So if we + actually want the canonical name, we may have to look through + the list and discard numeric addresses. + + Since it's dependent on the target hostname, it's hard to check + for at configure time. */ + if (ai->ai_canonname && strchr(ai->ai_canonname, ':')) { + for (ai2 = ai->ai_next; ai2; ai2 = ai2->ai_next) { + if (ai2->ai_canonname == 0) + continue; + if (!strchr(ai2->ai_canonname, ':')) { + char *p = ai->ai_canonname; + ai->ai_canonname = ai2->ai_canonname; + ai2->ai_canonname = p; + break; + } + } + if (ai2 == 0) + /* Ran off end, with no non-numeric name. What to do? */ + ; + } + + for (; ai; ai = ai->ai_next) { + /* AIX 4.3.3 libc is broken. It doesn't set the family or len + fields of the sockaddr structures. */ + if (ai->ai_addr->sa_family == 0) + ai->ai_addr->sa_family = ai->ai_family; +#ifdef HAVE_SA_LEN + if (ai->ai_addr->sa_len == 0) + ai->ai_addr->sa_len = ai->ai_addrlen; +#endif + } +} + #ifdef HAVE_FAKE_GETADDRINFO static int translate_h_errno (int h); diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h index 0ad9505d5..3f34b76a8 100644 --- a/src/include/fake-addrinfo.h +++ b/src/include/fake-addrinfo.h @@ -44,8 +44,6 @@ #include "port-sockets.h" #include "socket-utils.h" -#if !defined (HAVE_GETADDRINFO) || defined (BROKEN_GETADDRINFO) - #ifndef FAI_PREFIX # error "FAI_PREFIX must be defined when fake-addrinfo.h is included" #endif @@ -53,6 +51,14 @@ #define FAI_CONCAT(A,B) FAI_CONCAT2(A,B) #define FAI_CONCAT2(A,B) A ## B +/* Various C libraries have broken implementations of getaddrinfo. */ +#undef fixup_addrinfo +#define fixup_addrinfo FAI_CONCAT(FAI_PREFIX, _fixup_addrinfo) + +extern void fixup_addrinfo (struct addrinfo *ai); + +#if !defined (HAVE_GETADDRINFO) || defined (BROKEN_GETADDRINFO) + #undef getaddrinfo #define getaddrinfo FAI_CONCAT(FAI_PREFIX, _fake_getaddrinfo) #undef getnameinfo -- 2.26.2