summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2002-06-25 23:33:36 +0000
committerKen Raeburn <raeburn@mit.edu>2002-06-25 23:33:36 +0000
commit7d2bf7e5c9760b98622daeff425a2281dfd59dce (patch)
tree36f7f5d0462efc452c5d131edb5c3f30cbc7ac55 /src/include
parent2b19ecf1685a79dd762de0e17508af0a5830ecff (diff)
downloadkrb5-7d2bf7e5c9760b98622daeff425a2281dfd59dce.tar.gz
krb5-7d2bf7e5c9760b98622daeff425a2281dfd59dce.tar.xz
krb5-7d2bf7e5c9760b98622daeff425a2281dfd59dce.zip
* fake-addrinfo.h (GET_SERV_BY_PORT) [HAVE_GETSERVBYNAME_R &&
!GETSERVBYNAME_R_RETURNS_INT]: Fix getservbyport_r calling sequence, based on IRIX man pages. (getaddrinfo) [WRAP_GETADDRINFO]: Handle case where gethostbyname fails because host has no IPv4 addresses. Don't return a success indication without replacing the old ai_canonname value if it wasn't null. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14582 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ChangeLog8
-rw-r--r--src/include/fake-addrinfo.h75
2 files changed, 54 insertions, 29 deletions
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index e327680a7..5f338fc9d 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -1,5 +1,13 @@
2002-06-25 Ken Raeburn <raeburn@mit.edu>
+ * fake-addrinfo.h (GET_SERV_BY_PORT) [HAVE_GETSERVBYNAME_R &&
+ !GETSERVBYNAME_R_RETURNS_INT]: Fix getservbyport_r calling
+ sequence, based on IRIX man pages.
+ (getaddrinfo) [WRAP_GETADDRINFO]: Handle case where gethostbyname
+ fails because host has no IPv4 addresses. Don't return a success
+ indication without replacing the old ai_canonname value if it
+ wasn't null.
+
* socket-utils.h (ss2sin6): Enable compilation of inline function
version.
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index 8a937c192..c5083bcd7 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -222,7 +222,7 @@ gai_strerror (int code) /*@*/;
(ERR) = my_s_err; \
}
#else
-/* returns ptr */
+/* returns ptr -- IRIX? */
#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \
{ \
struct servent my_s_ent; \
@@ -235,12 +235,13 @@ gai_strerror (int code) /*@*/;
#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \
{ \
- struct servent my_s_ent; \
- int my_s_err; \
+ struct servent my_s_ent, *my_sp; \
char my_s_buf[8192]; \
- (SP) = getservbyport_r((PORT), (PROTO), &my_s_ent, \
- my_s_buf, sizeof (my_s_buf), &my_s_err); \
- (ERR) = my_s_err; \
+ my_sp = getservbyport_r((PORT), (PROTO), &my_s_ent, \
+ my_s_buf, sizeof (my_s_buf)); \
+ (SP) = my_sp; \
+ (ERR) = my_sp == 0; \
+ (ERR) = (ERR); /* avoid "unused" warning */ \
}
#endif
#endif
@@ -603,11 +604,11 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
if (host) {
if (flags & NI_NUMERICHOST) {
-#if (defined(__GNUC__) && defined(__mips__)) || 1 /* thread-safe version */
+#if (defined(__GNUC__) && defined(__mips__)) || 1 /* thread safety always */
/* The inet_ntoa call, passing a struct, fails on IRIX 6.5
using gcc 2.95; we get back "0.0.0.0". Since this in a
configuration still important at Athena, here's the
- workaround.... */
+ workaround, which also happens to be thread-safe.... */
const unsigned char *uc;
char tmpbuf[20];
numeric_host:
@@ -648,16 +649,10 @@ fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
sprintf (numbuf, "%d", port);
strncpy (service, numbuf, servicelen);
} else {
-#ifdef HAVE_GETSERVBYPORT_R
- char my_s_buf[1024];
- struct servent my_s_ent;
- sp = getservbyport_r(sinp->sin_port,
- (flags & NI_DGRAM) ? "udp" : "tcp",
- &my_s_ent, my_s_buf, sizeof(my_s_buf));
-#else
- sp = getservbyport (sinp->sin_port,
- (flags & NI_DGRAM) ? "udp" : "tcp");
-#endif
+ int serr;
+ GET_SERV_BY_PORT(sinp->sin_port,
+ (flags & NI_DGRAM) ? "udp" : "tcp",
+ sp, serr);
if (sp == 0)
goto numeric_service;
strncpy (service, sp->s_name, servicelen);
@@ -765,7 +760,7 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
struct addrinfo **result)
{
int aierr;
-#ifdef _AIX
+#if defined(_AIX) || defined(COPY_FIRST_CANONNAME)
struct addrinfo *ai;
#endif
@@ -803,20 +798,42 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
Since it's dependent on the target hostname, it's hard to check
for at configure time. Always do it on Linux for now. When
they get around to fixing it, add a compile-time or run-time
- check for the glibc version in use. */
+ check for the glibc version in use.
+
+ Some Windows documentation says that even when AI_CANONNAME is
+ set, the returned ai_canonname field can be null. The NetBSD
+ 1.5 implementation also does this, if the input hostname is a
+ numeric host address string. That case isn't handled well at
+ the moment. */
+
#ifdef COPY_FIRST_CANONNAME
- if (/* name && hint && (hint->ai_flags & AI_CANONNAME) */ (*result)->ai_canonname) {
+ /*
+ * This code must *always* return an error, return a null
+ * ai_canonname, or return an ai_canonname allocated here using
+ * malloc, so that freeaddrinfo can always free a non-null
+ * ai_canonname. Note that it really doesn't matter if the
+ * AI_CANONNAME flag was set.
+ */
+ ai = *result;
+ if (ai->ai_canonname) {
struct hostent *hp;
const char *name2 = 0;
int i, herr;
+ /*
+ * Current versions of GET_HOST_BY_NAME will fail if the
+ * target hostname has IPv6 addresses only. Make sure it
+ * fails fairly cleanly.
+ */
GET_HOST_BY_NAME (name, hp, herr);
if (hp == 0) {
- if ((*result)->ai_canonname != 0)
- /* XXX Indicate success with the existing name? */
- return 0;
- /* No canonname listed, and gethostbyname failed. */
- name2 = name;
+ /*
+ * This case probably means it's an IPv6-only name. If
+ * ai_canonname is a numeric address, get rid of it.
+ */
+ if (ai->ai_canonname && strchr(ai->ai_canonname, ':'))
+ ai->ai_canonname = 0;
+ name2 = ai->ai_canonname ? ai->ai_canonname : name;
} else {
/* Sometimes gethostbyname will be directed to /etc/hosts
first, and sometimes that file will have entries with
@@ -834,9 +851,9 @@ getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
name2 = hp->h_name;
}
- (*result)->ai_canonname = strdup(name2);
- if ((*result)->ai_canonname == 0) {
- (*faiptr)(*result);
+ ai->ai_canonname = strdup(name2);
+ if (name2 != 0 && ai->ai_canonname == 0) {
+ (*faiptr)(ai);
*result = 0;
return EAI_MEMORY;
}