* fake-addrinfo.h: Always check for FAI_PREFIX, not just when fake getaddrinfo
authorKen Raeburn <raeburn@mit.edu>
Sun, 10 Feb 2002 23:53:55 +0000 (23:53 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sun, 10 Feb 2002 23:53:55 +0000 (23:53 +0000)
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
src/include/fake-addrinfo.c
src/include/fake-addrinfo.h

index 35c585a3eecf76cd9fd506e94b4a3707b0d112b8..3b405fa087d587791bbf1bb9f4115bcedc691fc7 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-10  Ken Raeburn  <raeburn@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * socket-utils.h (ss2sin6) [__GNUC__]: Define inline function only
index 3ade9dc74f28731408fdbc8804a7b3a008076fa9..1f0047213fb58d0f358b38f176329378a94a4920 100644 (file)
 
 #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);
index 0ad9505d535ad080f2368d8ec9cf1d23ca661ff7..3f34b76a8c7238efce24bd4d1d1d593ea043b2e3 100644 (file)
@@ -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
 #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