[BZ #358]
authorUlrich Drepper <drepper@redhat.com>
Sun, 26 Sep 2004 08:43:34 +0000 (08:43 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 26 Sep 2004 08:43:34 +0000 (08:43 +0000)
Update.
2004-09-26  Ulrich Drepper  <drepper@redhat.com>

* sysdeps/posix/getaddrinfo.c (getaddrinfo): Remove incorrect
requirement on socktype and protocol.
(gaih_inet): If numeric port number is given, return records for all
possible socket types.
* posix/tst-getaddrinfo2.c: New file.
* posix/Makefile (tests): Add tst-getaddrinfo2.  [BZ #358]

ChangeLog
posix/Makefile
posix/tst-getaddrinfo2.c [new file with mode: 0644]
sysdeps/posix/getaddrinfo.c

index 371d384..5a248c3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2004-09-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/posix/getaddrinfo.c (getaddrinfo): Remove incorrect
+       requirement on socktype and protocol.
+       (gaih_inet): If numeric port number is given, return records for all
+       possible socket types.
+       * posix/tst-getaddrinfo2.c: New file.
+       * posix/Makefile (tests): Add tst-getaddrinfo2.  [BZ #358]
+
 2004-09-25  Ulrich Drepper  <drepper@redhat.com>
 
        * locale/loadlocale.c (_nl_intern_locale_data): Recognize LC_CTYPE
index 766c1dd..82d3537 100644 (file)
@@ -81,7 +81,8 @@ tests         := tstgetopt testfnm runtests runptests      \
                   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
                   bug-regex21 bug-regex22 bug-regex23 tst-nice tst-nanosleep \
                   transbug tst-rxspencer tst-pcre tst-boost \
-                  bug-ga1 tst-vfork1 tst-vfork2 tst-waitid
+                  bug-ga1 tst-vfork1 tst-vfork2 tst-waitid \
+                  tst-getaddrinfo2
 xtests         := bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs      := globtest
diff --git a/posix/tst-getaddrinfo2.c b/posix/tst-getaddrinfo2.c
new file mode 100644 (file)
index 0000000..b0bce59
--- /dev/null
@@ -0,0 +1,75 @@
+/* Test by David L Stevens <dlstevens@us.ibm.com> [BZ #358] */
+#include <errno.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+static int
+do_test (void)
+{
+  const char portstr[] = "583";
+  int port = atoi (portstr);
+  struct addrinfo hints, *aires, *pai;
+  int rv;
+  int res = 1;
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = AF_INET;
+  rv = getaddrinfo (NULL, portstr, &hints, &aires);
+  if (rv == 0)
+    {
+      struct sockaddr_in *psin = 0;
+      int got_tcp, got_udp;
+      int err = 0;
+
+      got_tcp = got_udp = 0;
+      for (pai = aires; pai; pai = pai->ai_next)
+        {
+          printf ("ai_family=%d, ai_addrlen=%d, ai_socktype=%d",
+                  (int) pai->ai_family, (int) pai->ai_addrlen,
+                  (int) pai->ai_socktype);
+          if (pai->ai_family == AF_INET)
+            printf (", port=%d",
+                    ntohs (((struct sockaddr_in *) pai->ai_addr)->sin_port));
+          puts ("");
+
+          err |= pai->ai_family != AF_INET;
+          err |= pai->ai_addrlen != sizeof (struct sockaddr_in);
+          err |= pai->ai_addr == 0;
+          if (pai->ai_family == AF_INET)
+            err |=
+              ntohs (((struct sockaddr_in *) pai->ai_addr)->sin_port) != port;
+          got_tcp |= pai->ai_socktype == SOCK_STREAM;
+          got_udp |= pai->ai_socktype == SOCK_DGRAM;
+          if (err)
+            break;
+        }
+      if (err)
+        {
+          printf ("FAIL getaddrinfo IPv4 socktype 0,513: "
+                  "fam %d alen %d addr 0x%08X addr/fam %d "
+                  "addr/port %d H[%d]\n",
+                  pai->ai_family, pai->ai_addrlen, psin,
+                  psin ? psin->sin_family : 0,
+                  psin ? psin->sin_port : 0,
+                  psin ? htons (psin->sin_port) : 0);
+        }
+      else if (got_tcp && got_udp)
+        {
+          printf ("SUCCESS getaddrinfo IPv4 socktype 0,513\n");
+          res = 0;
+        }
+      else
+        printf ("FAIL getaddrinfo IPv4 socktype 0,513 TCP %d"
+                " UDP %d\n", got_tcp, got_udp);
+      freeaddrinfo (aires);
+    }
+  else
+    printf ("FAIL getaddrinfo IPv4 socktype 0,513 returns %d "
+            "(\"%s\")\n", rv, gai_strerror (rv));
+
+  return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 225c1a1..20e60de 100644 (file)
@@ -445,12 +445,35 @@ gaih_inet (const char *name, const struct gaih_service *service,
        }
       else
        {
-         st = __alloca (sizeof (struct gaih_servtuple));
-         st->next = NULL;
-         st->socktype = tp->socktype;
-         st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
-                         ? req->ai_protocol : tp->protocol);
-         st->port = htons (service->num);
+         if (req->ai_socktype || req->ai_protocol)
+           {
+             st = __alloca (sizeof (struct gaih_servtuple));
+             st->next = NULL;
+             st->socktype = tp->socktype;
+             st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
+                             ? req->ai_protocol : tp->protocol);
+             st->port = htons (service->num);
+           }
+         else
+           {
+             /* Neither socket type nor protocol is set.  Return all
+                socket types we know about.  */
+             struct gaih_servtuple **lastp = &st;
+             for (tp = gaih_inet_typeproto + 1; tp->name[0]; ++tp)
+               if ((tp->protoflag & GAI_PROTO_NOSERVICE) == 0)
+                 {
+                   struct gaih_servtuple *newp;
+
+                   newp = __alloca (sizeof (struct gaih_servtuple));
+                   newp->next = NULL;
+                   newp->socktype = tp->socktype;
+                   newp->protocol = tp->protocol;
+                   newp->port = htons (service->num);
+
+                   *lastp = newp;
+                   lastp = &newp->next;
+                 }
+           }
        }
     }
   else if (req->ai_socktype || req->ai_protocol)
@@ -1493,11 +1516,7 @@ getaddrinfo (const char *name, const char *service,
 
          gaih_service.num = -1;
        }
-      else
-       /* Can't specify a numerical socket unless a protocol family was
-          given. */
-        if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
-          return EAI_SERVICE;
+
       pservice = &gaih_service;
     }
   else