aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-09-26 08:43:34 +0000
committerUlrich Drepper <drepper@redhat.com>2004-09-26 08:43:34 +0000
commitca225a410beec632da27617ea972df345986b54e (patch)
tree83050d08d3147df88d9723281688ee83dac5563f
parentfe6ce1705917adeaf4db069d484060ecd2aff81b (diff)
downloadglibc-ca225a410beec632da27617ea972df345986b54e.zip
glibc-ca225a410beec632da27617ea972df345986b54e.tar.gz
glibc-ca225a410beec632da27617ea972df345986b54e.tar.bz2
[BZ #358]
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]
-rw-r--r--ChangeLog9
-rw-r--r--posix/Makefile3
-rw-r--r--posix/tst-getaddrinfo2.c75
-rw-r--r--sysdeps/posix/getaddrinfo.c41
4 files changed, 116 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 371d384..5a248c3 100644
--- 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
diff --git a/posix/Makefile b/posix/Makefile
index 766c1dd..82d3537 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -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
index 0000000..b0bce59
--- /dev/null
+++ b/posix/tst-getaddrinfo2.c
@@ -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"
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 225c1a1..20e60de 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -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