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]

Re: (usagi-core 00277) Re: glibc-2.1.97 fixes from USAGI Project


Sorry for my late response,

In article <200011070752.IAA00815@loewis.home.cs.tu-berlin.de> (at Tue, 7 Nov 2000 08:52:28 +0100), "Martin v. Loewis" <martin@loewis.home.cs.tu-berlin.de> says:

> >                              compiled with
> >                         glibc-2.1   glibc-2.2
> > --------------------------------------------------
> > kernel 2.2 + glibc-2.1  buggy       -
> >            + glibc-2.2  ng          buggy
> > 	   + usagi-2.2  ok          ok
> > kernel 2.4 + glibc-2.1  buggy       -
> >            + glibc-2.2  ng          buggy
> >            + usagi-2.2  ok          ok
> 
> For those of us not following IPv6 that closely, could you please
> elaborate on this table somewhat? Specifically, it appears that glibc
> 2.2 compiled applications, when used with glibc 2.2 on a kernel 2.4,
> are still buggy, and that they work fine when your patch is applied -
> IOW, there is are IPv6 bugs in glibc 2.1.9x.

Your interpretation is right.


> Can you please give an example for this bug? What kind of bug is it?
> (application crashes, does not work as expected, does not implement
> latest specification drafts, ...)

There're several bugs.  Major things are:

 a) getaddrinfo() (sysdeps/posix/getaddrinfo.c)

     1. if a node has more that one inet6 addresses, it fills garbage 
        sin6_scope_id.[bug]
     2. getaddrinfo() can return unexpected (protocol) sets.[bug]
     3. raw socket are wrongly sticked with IPPROTO_RAW.[buggy]

 b) getnameinfo() (inet/getnameinfo.c)

     1. NI_NOFQDN flag is broken.  current getnameinfo() checks this flag and
        store appropriate result in the buffer but later it is overwritten
        by fqdn.[bug]
     2. check for sin6_scope_id is wrong; because of this,
        getnameinfo() won't return scope-id in normal cases.[bug]
     3. even if it tried to return scope-id, the result could not be correct;
        its scope-delimiter was missing or it includes unexpected garbage 
        character, etc.[bug]

We're trying to prepare real example.
One possible code to is attatched to this mail.
(License of this code is GPL compatible.)

-- 
Hideaki YOSHIFUJI @ USAGI Project  <yoshfuji@linux-ipv6.org>
PGP5i FP: F731 6599 5EB2 BBA7 1515  1323 1806 A96F 5700 6B25 
/* $USAGI: gai_test.c,v 1.13 2000/11/08 06:02:53 kunitake Exp $ */

/*
 * Copyright (C) 2000 USAGI/WIDE Project.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>

int main (int argc, char **argv){
	char *host, *port;
	const char *myname = argv[0];
	sa_family_t family = PF_UNSPEC;
	int socktype = 0;
	int protocol = 0;
	int flags = 0;
#ifndef REVERSE_NI_NUMERIC
	int niflags = 0;
#else
#ifdef NI_NUMRICSCOPE
	int niflags = NI_NUMERICHOST|NI_NUMERICSERV|NI_NUMERICSCOPE;
#else
	int niflags = NI_NUMERICHOST|NI_NUMERICSERV;
#endif
#endif
	int usage = 0;
	struct addrinfo hints, *res0, *res;
	int gai;
	int c;

#ifdef REVERSE_NI_NUMERIC
#ifdef NI_NUMERICSCOPE
	printf("# Warning: NI_NUMERICSCOPE is not available on this platform\n");
#endif
#endif

	while((c = getopt(argc, argv, "46sdrTUncmaHPSFR")) != EOF){
		switch(c){
		case '4':	
			family = PF_INET;
			break;
		case '6':
			family = PF_INET6;
			break;
		case 's':
			socktype = SOCK_STREAM;
			break;
		case 'd':
			socktype = SOCK_DGRAM;
			break;
		case 'r':
			socktype = SOCK_RAW;
			break;
		case 'T':
			protocol = IPPROTO_TCP;
			break;
		case 'U':
			protocol = IPPROTO_UDP;
			break;
		case 'n':
			flags |= AI_NUMERICHOST;
			break;
		case 'c':
#ifdef AI_ADDRCONFIG
			flags |= AI_ADDRCONFIG;
#else
			printf("# warning: AI_ADDRCONFIG is not available on this platform.\n");
#endif
			break;
		case 'm':
#ifdef AI_V4MAPPED
			flags |= AI_V4MAPPED;
#else
			printf("# warning: AI_V4MAPPED is not available on this platform.\n");
#endif
			break;
		case 'a':
#ifdef AI_ALL
			flags |= AI_ALL;
#else
			printf("# warning: AI_ALL is not available on this platform.\n");
#endif
			break;
		case 'H':
#ifndef REVERSE_NI_NUMERIC
			niflags |= NI_NUMERICHOST;
#else
			niflags &= ~NI_NUMERICHOST;
#endif
			break;
		case 'P':
#ifndef REVERSE_NI_NUMERIC
			niflags |= NI_NUMERICSERV;
#else
			niflags &= ~NI_NUMERICSERV;
#endif
			break;
		case 'S':
#ifndef REVERSE_NI_NUMERIC
#ifdef NI_NUMERICSCOPE
			niflags |= NI_NUMERICSCOPE;
#else
			printf("Warning: NI_NUMERICSCOPE is not available on this platform.\n");
#endif
#else
#ifdef NI_NUMERICSCOPE
			niflags &= ~NI_NUMERICSCOPE;
#endif
#endif
			break;
		case 'F':
			niflags |= NI_NOFQDN;
			break;
		case 'R':
			niflags |= NI_NAMEREQD;
			break;
		default:
			usage = 1;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1 || usage){
		fprintf(stderr, 
			"Usage: %s [-46] [-sur] [-TUI] [-H][-P][-S] host [port]\n"
			"\n"
			"\t-46         : PF_INET / PF_INET6 (default: PF_UNSPEC)\n"
			"\t-sdr        : SOCK_STREAM / SOCK_DGRAM / SOCK_RAW (default: 0)\n"
			"\t-TUI        : IPPROTO_TCP / IPPROTO_UDP (default: 0)\n"
			"\t-n,-c,-m,-a : AI_NUMERICHOST, AI_ADDRCONFIG, AI_V4MAPPED, AI_ALL\n"
#ifndef REVERSE_NI_NUMERIC
			"\t-H,-P,-S    : NI_NUMERICHOST, NI_NUMERICSERV, NI_NUMERICSCOPE\n"
#else
			"\t-H,-P,-S    : !NI_NUMERICHOST, !NI_NUMERICSERV, !NI_NUMERICSCOPE\n"
#endif
			"\t-F,-R       : NI_NOFQDN, NI_NAMEREQD\n"
			"\n",
			myname);
		exit(1);
	}
	host = argv[0];
	port = argc > 1 ? argv[1] : NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = socktype;
	hints.ai_protocol = protocol;
	hints.ai_flags = flags;

	printf("# host=%s, service=%s\n", host, port ? port : "NULL");
	printf("# family = %d, ai_socktype = %d, protocol = %d\n",
		hints.ai_family, hints.ai_socktype, hints.ai_protocol);
	printf("# flags = 0x%08x\n", hints.ai_flags);
	printf("# niflags = 0x%08x\n", niflags);
	printf("\n");

	gai = getaddrinfo(host, port, &hints, &res0);
	if (gai){
		printf("getaddrinfo() failed: %s\n", gai_strerror(gai));
		exit(1);
	}
	else if (!res0){
		printf("getaddrinfo() succeeded but got NULL result!?\n");
		exit(2);
	}
	for (res=res0; res; res=res->ai_next){
		char abuf[NI_MAXHOST], pbuf[NI_MAXSERV];
		int gni;
		if (!res->ai_addr || !res->ai_addrlen){
			printf("ai_addr = NULL and/or ai_addrlen = 0 !?\n");
			continue;
		}
		if (res->ai_family != res->ai_addr->sa_family){
			printf("ai_addr->sa_family = %3, while ai_family = %d\n",
				res->ai_addr->sa_family, res->ai_family);
			continue;
		}
		gni = getnameinfo(res->ai_addr, res->ai_addrlen,
				  abuf, sizeof(abuf), pbuf, sizeof(pbuf),
				  niflags);
		if (gni){
			printf("getnameinfo failed: family = %d, length = %d : (%d)%s\n",
				res->ai_addr->sa_family, res->ai_addrlen, 
				gni, gai_strerror(gni));
			continue;
		}
		printf("family = %d, socktype = %d, protocol = %d, length = %d, addr = %s, port = %s\n",
			res->ai_family, res->ai_socktype, res->ai_protocol, res->ai_addrlen,
			abuf, pbuf);
	}
	freeaddrinfo(res0);
	exit(0);
}


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