From owner-cvs-all Mon Jul 23 11:25:12 2001 Delivered-To: cvs-all@freebsd.org Received: from light.imasy.or.jp (light.imasy.or.jp [202.227.24.4]) by hub.freebsd.org (Postfix) with ESMTP id BF2EE37B405; Mon, 23 Jul 2001 11:24:33 -0700 (PDT) (envelope-from ume@mahoroba.org) Received: (from uucp@localhost) by light.imasy.or.jp (8.11.3+3.4W/8.11.3/light) with UUCP id f6NIOK204871; Tue, 24 Jul 2001 03:24:20 +0900 (JST) (envelope-from ume@mahoroba.org) Received: from peace.mahoroba.org (IDENT:9xmsb3kpfPayHylKpz6AxtHRSqly57j6AhjnwC5b+lo90+fFR8s55x+zIH+DBlwv@peace.mahoroba.org [3ffe:505:2:0:200:f8ff:fe05:3eae]) (authenticated as ume with CRAM-MD5) by mail.mahoroba.org (8.11.4/8.11.4/chaos) with ESMTP/inet6 id f6NINkL02793; Tue, 24 Jul 2001 03:23:47 +0900 (JST) (envelope-from ume@mahoroba.org) Date: Tue, 24 Jul 2001 03:23:44 +0900 (JST) Message-Id: <20010724.032344.71142385.ume@mahoroba.org> To: brian@Awfulhak.org Cc: brian@FreeBSD.org, cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/lib/libutil realhostname.c From: Hajimu UMEMOTO In-Reply-To: <200107230040.f6N0efg12288@hak.lan.Awfulhak.org> References: <200107230040.f6N0efg12288@hak.lan.Awfulhak.org> X-Mailer: xcite1.38> Mew version 1.95b119 on Emacs 20.7 / Mule 4.0 =?iso-2022-jp?B?KBskQjJWMWMbKEIp?= X-PGP-Public-Key: http://www.imasy.org/~ume/publickey.asc X-PGP-Fingerprint: 6B 0C 53 FC 5D D0 37 91 05 D0 B3 EF 36 9B 6A BC X-URL: http://www.imasy.org/~ume/ X-Operating-System: FreeBSD 5.0-CURRENT Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-cvs-all@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hi, >>>>> On Mon, 23 Jul 2001 01:40:40 +0100 >>>>> Brian Somers said: brian> It seems to me that realhostname_sa() already has to deal specially brian> with ipv4 mapped ipv6 addresses. Surely the correct answer is to brian> special-case such addresses in the getaddrinfo() hints (see the brian> attached patch - based on what's in -current at the moment). It seems working for IPv4 mapped IPv6 address to me. However, I still cannot understand why changing AF_UNSPEC to AF_INET6 solves your problem. If AF_INET6 returns FQDN, I think AF_UNSPEC also returns FQDN. brian> The only alternative that I can think of is to have getaddrinfo() brian> with a hint of AF_UNSPEC end up finding all A and AAAA records. If brian> it returns only one type of address, then it can't satisfy both the brian> ipv4 mapped address case *and* the normal ipv6 case (as per my brian> fec0::* addresses that I mentioned before). It is actually expected behavior of getaddrinfo(). It seems working so for global, and I could not find special case for site-local in getaddrinfo(). In anyway, existing realhostname_sa() is too complex around handling IPv4 mapped IPv6 address. I propose to simplify it. Here is a patch from -current. Index: lib/libutil/realhostname.c =================================================================== RCS file: /home/ncvs/src/lib/libutil/realhostname.c,v retrieving revision 1.12 diff -u -r1.12 realhostname.c --- lib/libutil/realhostname.c 2001/07/21 00:18:54 1.12 +++ lib/libutil/realhostname.c 2001/07/23 17:53:51 @@ -93,31 +93,47 @@ { int result, error; char buf[NI_MAXHOST]; + struct sockaddr_in sin; result = HOSTNAME_INVALIDADDR; - error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, 0); +#ifdef INET6 + /* IPv4 mapped IPv6 addr consideraton, specified in rfc2373. */ + if (addr->sa_family == AF_INET6 && + addrlen == sizeof(struct sockaddr_in6) && + IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)addr)->sin6_addr)) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)addr; + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_port = sin6->sin6_port; + memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], + sizeof(struct in_addr)); + addr = (struct sockaddr *)&sin; + addrlen = sin.sin_len; + } +#endif + + error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, + NI_WITHSCOPEID); if (error == 0) { struct addrinfo hints, *res, *ores; struct sockaddr *sa; memset(&hints, 0, sizeof(struct addrinfo)); - switch (addr->sa_family) { - case AF_INET: - case AF_INET6: - hints.ai_family = addr->sa_family; - break; - default: - hints.ai_family = AF_UNSPEC; - break; - } - hints.ai_flags = AI_CANONNAME; + hints.ai_family = addr->sa_family; + hints.ai_flags = AI_CANONNAME | AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(buf, NULL, &hints, &res); if (error) { result = HOSTNAME_INVALIDNAME; goto numeric; - } else for (ores = res; ; res = res->ai_next) { + } + for (ores = res; ; res = res->ai_next) { if (res == NULL) { freeaddrinfo(ores); result = HOSTNAME_INCORRECTNAME; @@ -131,15 +147,19 @@ } if (sa->sa_len == addrlen && sa->sa_family == addr->sa_family) { - u_int16_t port; - - port = ((struct sockinet *)addr)->si_port; - ((struct sockinet *)addr)->si_port = 0; + ((struct sockinet *)sa)->si_port = ((struct sockinet *)addr)->si_port; +#ifdef INET6 + /* + * XXX: sin6_socpe_id may not been + * filled by DNS + */ + if (sa->sa_family == AF_INET6 && + ((struct sockaddr_in6 *)sa)->sin6_scope_id == 0) + ((struct sockaddr_in6 *)sa)->sin6_scope_id = ((struct sockaddr_in6 *)addr)->sin6_scope_id; +#endif if (!memcmp(sa, addr, sa->sa_len)) { result = HOSTNAME_FOUND; - ((struct sockinet *)addr)->si_port = - port; - if (ores->ai_canonname == 0) { + if (ores->ai_canonname == NULL) { freeaddrinfo(ores); goto numeric; } @@ -154,58 +174,11 @@ strncpy(host, buf, hsize); break; } - ((struct sockinet *)addr)->si_port = port; - } -#ifdef INET6 - /* - * XXX IPv4 mapped IPv6 addr consideraton, - * specified in rfc2373. - */ - if (sa->sa_family == AF_INET && - addr->sa_family == AF_INET6) { - struct in_addr *in; - struct in6_addr *in6; - - in = &((struct sockaddr_in *)sa)->sin_addr; - in6 = &((struct sockaddr_in6 *)addr)->sin6_addr; - if (IN6_IS_ADDR_V4MAPPED(in6) && - !memcmp(&in6->s6_addr[12], in, - sizeof(*in))) { - result = HOSTNAME_FOUND; - if (ores->ai_canonname == 0 || - strlen(ores->ai_canonname) > hsize) { - freeaddrinfo(ores); - goto numeric; - } - strncpy(host, ores->ai_canonname, - hsize); - break; - } } -#endif } freeaddrinfo(ores); } else { - struct sockaddr_in sin; numeric: -#ifdef INET6 - if (addr->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6; - - sin6 = (struct sockaddr_in6 *)addr; - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_family = AF_INET; - sin.sin_port = sin6->sin6_port; - memcpy(&sin.sin_addr, - &sin6->sin6_addr.s6_addr[12], - sizeof(struct in_addr)); - addr = (struct sockaddr *)&sin; - addrlen = sin.sin_len; - } - } -#endif if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID) == 0) strncpy(host, buf, hsize); -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@bisd.hitachi.co.jp ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message