aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2003-01-09 23:55:06 +0000
committerKen Raeburn <raeburn@mit.edu>2003-01-09 23:55:06 +0000
commit50ecaa127cc91b2b1878cc9a03026bc3058a8ff2 (patch)
tree4d87a750fd0838713fed5a9e59fe165b4c99c76c
parent31d1da1652f8bd41ed923a8f9ebfee53c56bca77 (diff)
downloadkrb5-50ecaa127cc91b2b1878cc9a03026bc3058a8ff2.zip
krb5-50ecaa127cc91b2b1878cc9a03026bc3058a8ff2.tar.gz
krb5-50ecaa127cc91b2b1878cc9a03026bc3058a8ff2.tar.bz2
AIX 4.3.3 getaddrinfo() is broken in a slightly different way than I thought
* fake-addrinfo.h (getaddrinfo) [_AIX]: Always overwrite sa_family and sa_len fields, since sa_family at least may be non-zero *and* wrong. (protoname, socktypename, familyname, debug_dump_getaddrinfo_args, debug_dump_error, debug_dump_error, debug_dump_addrinfos) [DEBUG_ADDRINFO]: New debugging functions. (fake_getaddrinfo, getaddrinfo) [DEBUG_ADDRINFO]: Use them. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15104 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/ChangeLog10
-rw-r--r--src/include/fake-addrinfo.h141
2 files changed, 144 insertions, 7 deletions
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index 1288702..3c165d4 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -1,3 +1,13 @@
+2003-01-09 Ken Raeburn <raeburn@mit.edu>
+
+ * fake-addrinfo.h (getaddrinfo) [_AIX]: Always overwrite sa_family
+ and sa_len fields, since sa_family at least may be non-zero *and*
+ wrong.
+ (protoname, socktypename, familyname, debug_dump_getaddrinfo_args,
+ debug_dump_error, debug_dump_error, debug_dump_addrinfos)
+ [DEBUG_ADDRINFO]: New debugging functions.
+ (fake_getaddrinfo, getaddrinfo) [DEBUG_ADDRINFO]: Use them.
+
2003-01-08 Ezra Peisach <epeisach@bu.edu>
* fake-addrinfo.h (freeaddrinfo): Back out 1/3/03 change. ANSI
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index 76593b0..d32802a 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -365,6 +365,112 @@ struct addrinfo {
#endif /* ! HAVE_GETADDRINFO */
+#if (!defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)) && defined(DEBUG_ADDRINFO)
+/* Some debug routines. */
+
+static const char *protoname (int p) {
+ static char buf[30];
+
+#define X(N) if (p == IPPROTO_ ## N) return #N
+
+ X(TCP);
+ X(UDP);
+ X(ICMP);
+ X(IPV6);
+#ifdef IPPROTO_GRE
+ X(GRE);
+#endif
+ X(NONE);
+ X(RAW);
+#ifdef IPPROTO_COMP
+ X(COMP);
+#endif
+
+ sprintf(buf, " %-2d", p);
+ return buf;
+}
+
+static const char *socktypename (int t) {
+ static char buf[30];
+ switch (t) {
+ case SOCK_DGRAM: return "DGRAM";
+ case SOCK_STREAM: return "STREAM";
+ case SOCK_RAW: return "RAW";
+ case SOCK_RDM: return "RDM";
+ case SOCK_SEQPACKET: return "SEQPACKET";
+ }
+ sprintf(buf, " %-2d", t);
+ return buf;
+}
+
+static const char *familyname (int f) {
+ static char buf[30];
+ switch (f) {
+ default:
+ sprintf(buf, "AF %d", f);
+ return buf;
+ case AF_INET: return "AF_INET";
+ case AF_INET6: return "AF_INET6";
+#ifdef AF_UNIX
+ case AF_UNIX: return "AF_UNIX";
+#endif
+ }
+}
+
+static void debug_dump_getaddrinfo_args (const char *name, const char *serv,
+ const struct addrinfo *hint)
+{
+ const char *sep;
+ fprintf(stderr,
+ "getaddrinfo(hostname %s, service %s,\n"
+ " hints { ",
+ name ? name : "(null)", serv ? serv : "(null)");
+ if (hint) {
+ sep = "";
+#define Z(FLAG) if (hint->ai_flags & AI_##FLAG) fprintf(stderr, "%s%s", sep, #FLAG), sep = "|"
+ Z(CANONNAME);
+ Z(PASSIVE);
+#ifdef AI_NUMERICHOST
+ Z(NUMERICHOST);
+#endif
+ if (sep[0] == 0)
+ fprintf(stderr, "no-flags");
+ if (hint->ai_family)
+ fprintf(stderr, " %s", familyname(hint->ai_family));
+ if (hint->ai_socktype)
+ fprintf(stderr, " SOCK_%s", socktypename(hint->ai_socktype));
+ if (hint->ai_protocol)
+ fprintf(stderr, " IPPROTO_%s", protoname(hint->ai_protocol));
+ } else
+ fprintf(stderr, "(null)");
+ fprintf(stderr, " }):\n");
+}
+
+static void debug_dump_error (int err)
+{
+ fprintf(stderr, "error %d: %s\n", err, gai_strerror(err));
+}
+
+static void debug_dump_addrinfos (const struct addrinfo *ai)
+{
+ int count = 0;
+ fprintf(stderr, "addrinfos returned:\n");
+ while (ai) {
+ fprintf(stderr, "%p...", ai);
+ fprintf(stderr, " socktype=%s", socktypename(ai->ai_socktype));
+ fprintf(stderr, " ai_family=%s", familyname(ai->ai_family));
+ if (ai->ai_family != ai->ai_addr->sa_family)
+ fprintf(stderr, " sa_family=%s",
+ familyname(ai->ai_addr->sa_family));
+ fprintf(stderr, "\n");
+ ai = ai->ai_next;
+ count++;
+ }
+ fprintf(stderr, "end addrinfos returned (%d)\n");
+}
+
+#endif
+
#if !defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)
static
@@ -506,6 +612,10 @@ fake_getaddrinfo (const char *name, const char *serv,
int flags;
struct addrinfo template;
+#ifdef DEBUG_ADDRINFO
+ debug_dump_getaddrinfo_args(name, serv, hint);
+#endif
+
if (hint != 0) {
if (hint->ai_family != 0 && hint->ai_family != AF_INET)
return EAI_NODATA;
@@ -774,12 +884,17 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
#if defined(_AIX) || defined(COPY_FIRST_CANONNAME)
struct addrinfo *ai;
#endif
-
#ifdef NUMERIC_SERVICE_BROKEN
int service_is_numeric = 0;
int service_port = 0;
int socket_type = 0;
+#endif
+#ifdef DEBUG_ADDRINFO
+ debug_dump_getaddrinfo_args(name, serv, hint);
+#endif
+
+#ifdef NUMERIC_SERVICE_BROKEN
/* AIX 4.3.3 is broken. (Or perhaps out of date?)
If a numeric service is provided, and it doesn't correspond to
@@ -803,8 +918,12 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
#endif
aierr = (*gaiptr) (name, serv, hint, result);
- if (aierr || *result == 0)
+ if (aierr || *result == 0) {
+#ifdef DEBUG_ADDRINFO
+ debug_dump_error(aierr);
+#endif
return aierr;
+ }
/* Linux libc version 6 (libc-2.2.4.so on Debian) is broken.
@@ -893,6 +1012,9 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
if (name2 != 0 && ai->ai_canonname == 0) {
(*faiptr)(ai);
*result = 0;
+#ifdef DEBUG_ADDRINFO
+ debug_dump_error(EAI_MEMORY);
+#endif
return EAI_MEMORY;
}
}
@@ -916,12 +1038,13 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
#ifdef _AIX
for (ai = *result; 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;
+ fields of the sockaddr structures. Usually, sa_family is
+ zero, but I've seen it set to 1 in some cases also (maybe
+ just leftover from previous contents of the memory
+ block?). So, always override what libc returned. */
+ ai->ai_addr->sa_family = ai->ai_family;
#ifdef HAVE_SA_LEN /* always true on AIX, actually */
- if (ai->ai_addr->sa_len == 0)
- ai->ai_addr->sa_len = ai->ai_addrlen;
+ ai->ai_addr->sa_len = ai->ai_addrlen;
#endif
}
#endif
@@ -932,6 +1055,10 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
certain cases when multiple IPv4 and IPv6 addresses are
available. */
+#ifdef DEBUG_ADDRINFO
+ debug_dump_addrinfos(*result);
+#endif
+
return 0;
}