This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

glibc-2.1.97 fixes from USAGI Project


Please apply these fixes (mainly related to IPv6) for glibc-2.2.

Summary:
  1. repair getnameinfo() sin6_socpe_id support.
  2. repair getaddrinfo() sin6_scope_id support.
  3. repair getnameinfo() NI_NOFQDN flag.
  4. improve linux22 compatibility.
  5. check if flags are valid for getnameinfo().
  6. ease raw socket creation.

These things are surely needed.
Here's the changes and patch.

-------------------------------------
2000-11-06 17:55  yoshfuji

	* sysdeps/posix/getaddrinfo.c: clean-up: define family to hold
	target family.

2000-11-06 17:44  yoshfuji

	* sysdeps/posix/getaddrinfo.c: Loosen protocol check to ease raw
	socket creation.

2000-11-06 16:31  yoshfuji

	* sysdeps/posix/getaddrinfo.c: ensure to fill ai_socktype and
	ai_protocol by internal table if service was not given.

2000-11-06 15:31  yoshfuji

	* sysdeps/posix/getaddrinfo.c: Don't raise an error even if
	numerical port was specified with protocol without socktype.

2000-11-06 15:22  yoshfuji

	* sysdeps/posix/getaddrinfo.c: ensure to check if protocol is ok

2000-11-06 12:57  yoshfuji

	* inet/getnameinfo.c: getnameinfo() NI_xxx flag validation.

2000-11-06 12:47  yoshfuji

	* sysdeps/posix/getaddrinfo.c: ensure not to fill garbage value in
	sin6_scope_id field.

2000-11-06 12:35  yoshfuji

	* inet/getnameinfo.c: Repair getnameinfo() sin6_socpe_id support.

2000-11-06 12:09  yoshfuji

	* inet/getnameinfo.c: repair NI_NOFQDN flag support.

2000-11-06 12:06  yoshfuji

	* inet/getnameinfo.c: Wake-up sin6_scope_id support in
	getnameinfo(): check for whether sin6_socpe_id exist was wrong.

2000-11-06 12:04  yoshfuji

	* inet/: getnameinfo.c, netinet/in.h: linux-2.2.x compatibility
	hack:  1. define struct __sockaddr_in6_rfc2133 as old definition.  
	2. don't raise an error even if old sockaddr_in6      (i.e.
	__sockaddr_in6_rfc2133) was passed.	 This is needed because
	getpeername(2) etcetra in the linux-2.2.x kernel      returns
	without sin6_scope_id field.

2000-11-03 16:25  yoshfuji

	* inet/: getnameinfo.c, rexec.c: glibc-2.1.97 +
	glibc-linux-threads-2.1.97


Index: glibc22/inet/getnameinfo.c
diff -u glibc22/inet/getnameinfo.c:1.1.1.2 glibc22/inet/getnameinfo.c:1.1.1.2.4.6
--- glibc22/inet/getnameinfo.c:1.1.1.2	Fri Nov  3 16:25:51 2000
+++ glibc22/inet/getnameinfo.c	Mon Nov  6 13:59:00 2000
@@ -1,3 +1,5 @@
+/* $USAGI: getnameinfo.c,v 1.1.1.2.4.6 2000/11/06 04:59:00 yoshfuji Exp $ */
+
 /* The Inner Net License, Version 2.00
 
   The author(s) grant permission for redistribution and use in source and
@@ -175,6 +177,10 @@
   struct hostent th;
   int ok = 0;
 
+  if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|
+		NI_NAMEREQD|NI_DGRAM))
+    return -1;
+
   if (sa == NULL || addrlen < sizeof (sa_family_t))
     return -1;
 
@@ -189,7 +195,7 @@
 	return -1;
       break;
     case AF_INET6:
-      if (addrlen < sizeof (struct sockaddr_in6))
+      if (addrlen < sizeof (struct __sockaddr_in6_rfc2133))
 	return -1;
       break;
     default:
@@ -273,8 +279,11 @@
 			ok = 1;
 		      }
 		  }
-		strncpy (host, h->h_name, hostlen);
-		ok = 1;
+		else
+		  {
+		    strncpy (host, h->h_name, hostlen);
+		    ok = 1;
+		  }
 	      }
 	  }
 
@@ -295,40 +304,37 @@
 
 		    c = inet_ntop (AF_INET6,
 				   (void *) &sin6p->sin6_addr, host, hostlen);
-		    if (addrlen > sizeof (struct sockaddr_in6)
+		    if (addrlen >= sizeof (struct sockaddr_in6)
 			&& (scopeid = sin6p->sin6_scope_id))
 		      {
 			/* Buffer is >= IFNAMSIZ+1.  */
-			char scopebuf[IFNAMSIZ + 1];
+			char scopebuf[IFNAMSIZ + 1]={SCOPE_DELIMITER};
+			char *scopeptr = &scopebuf[1];
 			int ni_numericscope = 0;
+			size_t real_hostlen = __strnlen(host, hostlen);
+			size_t scopelen = 0;
 
 			if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
 			    || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
 			  {
 			    if (if_indextoname (scopeid, scopebuf) == NULL)
 			      ++ni_numericscope;
+			    else
+			      scopelen = strlen(scopebuf);
 			  }
 			else
 			  ++ni_numericscope;
 
 			if (ni_numericscope)
-			  {
-			    char *scopeptr = &scopebuf[1];
-			    size_t real_hostlen;
-			    size_t scopelen;
-
-			    scopebuf[0] = SCOPE_DELIMITER;
-			    scopelen = 1 + __snprintf (scopeptr,
-						       (scopebuf
-							+ sizeof scopebuf
-							- scopeptr),
-						       "%u", scopeid);
-
-			    real_hostlen = __strnlen (host, hostlen);
-			    if (real_hostlen + scopelen + 1 > hostlen)
-			      return -1;
-			    memcpy (host + real_hostlen, scopebuf, scopelen);
-			  }
+			  scopelen = 1 + __snprintf (scopeptr,
+						     (scopebuf
+						      + sizeof scopebuf
+						      - scopeptr),
+						     "%u", scopeid);
+
+			if (real_hostlen + scopelen + 1 > hostlen)
+			  return -1;
+			memcpy (host + real_hostlen, scopebuf, scopelen + 1);
 		      }
 		  }
 		else
Index: glibc22/inet/netinet/in.h
diff -u glibc22/inet/netinet/in.h:1.1.1.1 glibc22/inet/netinet/in.h:1.1.1.1.4.2
--- glibc22/inet/netinet/in.h:1.1.1.1	Fri Oct 13 18:38:50 2000
+++ glibc22/inet/netinet/in.h	Mon Nov  6 13:59:00 2000
@@ -1,3 +1,5 @@
+/* $USAGI: in.h,v 1.1.1.1.4.2 2000/11/06 04:59:00 yoshfuji Exp $ */
+
 /* Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -212,6 +214,15 @@
     struct in6_addr sin6_addr;	/* IPv6 address */
     uint32_t sin6_scope_id;	/* IPv6 scope-id */
   };
+#ifdef __USE_GNU
+struct __sockaddr_in6_rfc2133
+  {
+    __SOCKADDR_COMMON (__sin6_);
+    in_port_t __sin6_port;
+    uint32_t __sin6_flowinfo;
+    struct in6_addr __sin6_addr;
+  };
+#endif
 
 /* IPv6 multicast request.  */
 struct ipv6_mreq
Index: glibc22/sysdeps/posix/getaddrinfo.c
diff -u glibc22/sysdeps/posix/getaddrinfo.c:1.1.1.1 glibc22/sysdeps/posix/getaddrinfo.c:1.1.1.1.4.8
--- glibc22/sysdeps/posix/getaddrinfo.c:1.1.1.1	Fri Oct 13 18:38:40 2000
+++ glibc22/sysdeps/posix/getaddrinfo.c	Mon Nov  6 17:55:47 2000
@@ -1,3 +1,5 @@
+/* $USAGI: getaddrinfo.c,v 1.1.1.1.4.8 2000/11/06 08:55:47 yoshfuji Exp $ */
+
 /* The Inner Net License, Version 2.00
 
   The author(s) grant permission for redistribution and use in source and
@@ -99,13 +101,14 @@
 
 /* Values for `protoflag'.  */
 #define GAI_PROTO_NOSERVICE	1
+#define GAI_PROTO_PROTOANY	2
 
 static struct gaih_typeproto gaih_inet_typeproto[] =
 {
   { 0, 0, NULL, 0 },
   { SOCK_STREAM, IPPROTO_TCP, (char *) "tcp", 0 },
   { SOCK_DGRAM, IPPROTO_UDP, (char *) "udp", 0 },
-  { SOCK_RAW, IPPROTO_RAW, (char *) "raw", GAI_PROTO_NOSERVICE },
+  { SOCK_RAW, 0, (char *) "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
   { 0, 0, NULL, 0 }
 };
 
@@ -150,6 +153,7 @@
 	     && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
 		 || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 		 || (req->ai_protocol != 0
+		     && !(tp->protoflag & GAI_PROTO_PROTOANY)
 		     && req->ai_protocol != tp->protocol)))
 	++tp;
 
@@ -229,6 +233,7 @@
 
 static int
 gaih_inet_serv (const char *servicename, struct gaih_typeproto *tp,
+	       const struct addrinfo *req,
 	       struct gaih_servtuple *st)
 {
   struct servent *s;
@@ -255,7 +260,8 @@
 
   st->next = NULL;
   st->socktype = tp->socktype;
-  st->protocol = tp->protocol;
+  st->protocol = (tp->protoflag & GAI_PROTO_PROTOANY) ?
+		 req->ai_protocol : tp->protocol;
   st->port = s->s_port;
 
   return 0;
@@ -291,8 +297,10 @@
     {								\
       for (i = 0; h->h_addr_list[i]; i++)			\
 	{							\
-	  if (*pat == NULL)					\
+	  if (*pat == NULL) {					\
 	    *pat = __alloca (sizeof(struct gaih_addrtuple));	\
+	    (*pat)->scopeid = 0;				\
+	  }							\
 	  (*pat)->next = NULL;					\
 	  (*pat)->family = _family;				\
 	  memcpy ((*pat)->addr, h->h_addr_list[i],		\
@@ -319,6 +327,7 @@
       while (tp->name != NULL
 	     && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 		 || (req->ai_protocol != 0
+		     && !(tp->protoflag & GAI_PROTO_PROTOANY)
 		     && req->ai_protocol != tp->protocol)))
 	++tp;
 
@@ -343,7 +352,7 @@
 	      st = (struct gaih_servtuple *)
 		__alloca (sizeof (struct gaih_servtuple));
 
-	      if ((rc = gaih_inet_serv (service->name, tp, st)))
+	      if ((rc = gaih_inet_serv (service->name, tp, req, st)))
 		return rc;
 	    }
 	  else
@@ -359,11 +368,15 @@
 		  if (req->ai_socktype != 0
 		      && req->ai_socktype != tp->socktype)
 		    continue;
+		  if (req->ai_protocol != 0 
+		      && !(tp->protoflag & GAI_PROTO_PROTOANY)
+		      && req->ai_protocol != tp->protocol)
+		    continue;
 
 		  newp = (struct gaih_servtuple *)
 		    __alloca (sizeof (struct gaih_servtuple));
 
-		  if ((rc = gaih_inet_serv (service->name, tp, newp)))
+		  if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
 		    {
 		      if (rc & GAIH_OKIFUNSPEC)
 			continue;
@@ -382,7 +395,8 @@
 	  st = __alloca (sizeof (struct gaih_servtuple));
 	  st->next = NULL;
 	  st->socktype = tp->socktype;
-	  st->protocol = tp->protocol;
+	  st->protocol = (tp->protoflag & GAI_PROTO_PROTOANY) ?
+			 req->ai_protocol : tp->protocol;
 	  st->port = htons (service->num);
 	}
     }
@@ -390,8 +404,9 @@
     {
       st = __alloca (sizeof (struct gaih_servtuple));
       st->next = NULL;
-      st->socktype = req->ai_socktype;
-      st->protocol = req->ai_protocol;
+      st->socktype = tp->socktype;
+      st->protocol = (tp->protoflag & GAI_PROTO_PROTOANY) ?
+		     req->ai_protocol : tp->protocol;
       st->port = 0;
     }
   else
@@ -542,6 +557,7 @@
     struct gaih_servtuple *st2;
     struct gaih_addrtuple *at2 = at;
     size_t socklen, namelen;
+    sa_family_t family;
 
     /*
       buffer is the size of an unformatted IPv6 address in printable format.
@@ -597,9 +613,15 @@
 	  namelen = 0;
 
 	if (at2->family == AF_INET6)
-	  socklen = sizeof (struct sockaddr_in6);
+	  { 
+	    family = AF_INET6;
+	    socklen = sizeof (struct sockaddr_in6);
+	  }
 	else
-	  socklen = sizeof (struct sockaddr_in);
+	  {
+	    family = AF_INET;
+	    socklen = sizeof (struct sockaddr_in);
+	  }
 
 	for (st2 = st; st2 != NULL; st2 = st2->next)
 	  {
@@ -608,7 +630,7 @@
 	      return -EAI_MEMORY;
 
 	    (*pai)->ai_flags = req->ai_flags;
-	    (*pai)->ai_family = at2->family;
+	    (*pai)->ai_family = family;
 	    (*pai)->ai_socktype = st2->socktype;
 	    (*pai)->ai_protocol = st2->protocol;
 	    (*pai)->ai_addrlen = socklen;
@@ -616,9 +638,9 @@
 #if SALEN
 	    (*pai)->ai_addr->sa_len = socklen;
 #endif /* SALEN */
-	    (*pai)->ai_addr->sa_family = at2->family;
+	    (*pai)->ai_addr->sa_family = family;
 
-	    if (at2->family == AF_INET6)
+	    if (family == AF_INET6)
 	      {
 		struct sockaddr_in6 *sin6p =
 		  (struct sockaddr_in6 *) (*pai)->ai_addr;
@@ -703,7 +725,7 @@
       else
 	/* Can't specify a numerical socket unless a protocol family was
 	   given. */
-        if (hints->ai_socktype == 0)
+        if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
           return EAI_SERVICE;
       pservice = &gaih_service;
     }


Regards,

-- 
Hideaki YOSHIFUJI @ USAGI Project  <yoshfuji@linux-ipv6.org>
PGP5i FP: F731 6599 5EB2 BBA7 1515  1323 1806 A96F 5700 6B25 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]