From owner-freebsd-net Sat Dec 14 16:17:12 2002 Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0D74737B401 for ; Sat, 14 Dec 2002 16:17:07 -0800 (PST) Received: from basie.internet2.edu (basie.internet2.edu [207.75.164.22]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3911643EB2 for ; Sat, 14 Dec 2002 16:17:06 -0800 (PST) (envelope-from boote@internet2.edu) Received: from localhost (localhost.localdomain [127.0.0.1]) by basie.internet2.edu (Postfix) with ESMTP id 741757B470; Sat, 14 Dec 2002 19:17:00 -0500 (EST) Received: from internet2.edu (localhost [127.0.0.1]) by basie.internet2.edu (Postfix) with ESMTP id CF7AD7B46E; Sat, 14 Dec 2002 19:16:57 -0500 (EST) Message-ID: <3DFBC9F9.9BEAA413@internet2.edu> Date: Sat, 14 Dec 2002 17:16:57 -0700 From: "Jeff W. Boote" X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en MIME-Version: 1.0 To: JINMEI@internet2.edu, Tatuya@internet2.edu, /@internet2.edu, "$B?\"@L@C#:Hnet2.edu?fetch>UID>|INBOX>9535"@internet2.edu Cc: freebsd-net@FreeBSD.ORG Subject: Re: IPv6 udp socket bind: EADDRNOTAVAIL? References: <3DFA268D.A073F0F3@internet2.edu> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Virus-Scanned: by AMaViS 0.3.12pre8 Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org JINMEI Tatuya / $B?@L@C#:H(B wrote: > > 2. This system is auto configuring this address... Is it possible that > > I'm just having this problem because the system is reconfiguring the > > address at this time? (I must admit that I have not looked at the auto > > configuration stuff.) > > I don't think so. Even if the system is reconfiguring global > addresses, it should have other stable addresses, such as link-local > and loopback ones. So the address list starting at in6_ifaddr should > rarely be empty. > > I suspect the EADDRNOTAVAIL error comes from a different part of the > kernel (or the kernel has a serious bug). I *may* have found my problem. (Since this has been intermittent I will need to let my fix run for a while longer before I'm convinced.) In my code, I am creating the struct sockaddr directly. (not using getaddrinfo or anything like that.) This is because the "control" connection was requesting a specific numeric address for the udp "test". I believe my problem may have been that I had the sa_len value set to 0. (It was zero because I memset the entire structure before starting, and I was attempting to write portable code - and that member is not portable. In any case, I have determined that getnameinfo on FreeBSD doesn't work unless it is set. So it wouldn't surprise me if bind failed in this case as well.) I have modified my code to set the sa_len field. Incidentally - I'm setting the flowinfo and scope_id fields to 0 as well. I believe that is the correct thing to do. At least it looked like that was correct the last time I checked, but I admit I have not looked at the latest version of 2553bis to see if this has changed. > If you give us more > information, we may be able to diagnose the problem. The information > can include: Oops. Sorry - I definitely should have done that in the first message. This gets kind of long, but I don't know of any way to make it shorter: I'm running a 4.6 kernel on that system. > - the result of ifconfig -a inet6 owamp@nms2-ipls:~[510]$ ifconfig -a inet6 sk0: flags=8843 mtu 1500 inet6 fe80::200:5aff:fe9a:6a3c%sk0 prefixlen 64 scopeid 0x1 inet6 2001:468:12:3:200:5aff:fe9a:6a3c prefixlen 64 autoconf fxp0: flags=8843 mtu 1500 inet6 fe80::203:47ff:fef1:5071%fxp0 prefixlen 64 scopeid 0x2 inet6 2001:468:12:2:203:47ff:fef1:5071 prefixlen 64 autoconf fxp1: flags=8802 mtu 1500 ifconfig: fxp1 has no inet6 interface address! lo0: flags=8049 mtu 16384 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 ppp0: flags=8010 mtu 1500 ifconfig: ppp0 has no inet6 interface address! sl0: flags=c010 mtu 552 ifconfig: sl0 has no inet6 interface address! faith0: flags=8002 mtu 1500 ifconfig: faith0 has no inet6 interface address! > - the result of netstat -anl -f inet6 (Of course, I'm not currently having the problem... Hmm - perhaps I should set something up to run netstat automatically if/when this happens again.) owamp@nms2-ipls:~[512]$ netstat -anl -f inet6 Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.4822 2001:468:f:2:203:47ff:fef1:4daf.1782 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.4822 2001:468:15:2:203:47ff:fef1:505d.2790 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.4822 2001:468:f:2:203:47ff:fef1:4daf.1780 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.4822 2001:468:15:2:203:47ff:fef1:505d.2788 ESTABLISHED tcp46 0 0 *.4822 *.* LISTEN tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.2971 2001:468:f:2:203:47ff:fef1:4daf.4822 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.2970 2001:468:f:2:203:47ff:fef1:4daf.4822 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.2920 2001:468:15:2:203:47ff:fef1:505d.4822 ESTABLISHED tcp6 0 0 2001:468:12:2:203:47ff:fef1:5071.2917 2001:468:15:2:203:47ff:fef1:505d.4822 ESTABLISHED tcp46 0 0 *.22 *.* LISTEN udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.1366 2001:468:f:2:203:47ff:fef1:4daf.1297 udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.3754 *.* udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.3752 *.* udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.3750 *.* udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.3747 *.* udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.3162 2001:468:15:2:203:47ff:fef1:505d.2156 udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.2888 2001:468:f:2:203:47ff:fef1:4daf.1283 udp6 0 0 2001:468:12:2:203:47ff:fef1:5071.4675 2001:468:15:2:203:47ff:fef1:505d.2137 udp6 0 0 *.514 *.* > - the IPv6 address (and port) being bound in the error case (udp) Addr: 2001:468:12:2:203:47ff:fef1:5071 Port: 0 (I'm trying to allocate a port.) > - the (related part of the) source code of the daemon Ok... to make it just related will take some annotating: # This is the part of the daemon where I initialize the # sockaddr structures. # sender and receiver are pointers to sockaddr_storage variables # that have been initialized with 0 values. # (This function reads a request off the network and is decoding # the message. I'm only including the part that decodes the # address.) # The last part with the HAVE_STRUCT_SOCKADDR_SA_LEN I just added, # and have not seen errors since. # switch(*ipvn){ struct sockaddr_in *saddr4; #ifdef AF_INET6 struct sockaddr_in6 *saddr6; case 6: if(*socklen < sizeof(struct sockaddr_in6)){ OWPError(ctx,OWPErrFATAL,OWPErrINVALID, "_OWPDecodeV3TestRequest:socklen not big enough (%d < %d)", *socklen,sizeof(struct sockaddr_in6)); *socklen = 0; return OWPErrFATAL; } *socklen = sizeof(struct sockaddr_in6); /* sender address and port */ saddr6 = (struct sockaddr_in6*)sender; saddr6->sin6_family = AF_INET6; memcpy(saddr6->sin6_addr.s6_addr,&buf[4],16); if(*server_conf_sender) saddr6->sin6_port = 0; else saddr6->sin6_port = *(u_int16_t*)&buf[36]; /* receiver address and port */ saddr6 = (struct sockaddr_in6*)receiver; saddr6->sin6_family = AF_INET6; memcpy(saddr6->sin6_addr.s6_addr,&buf[20],16); if(*server_conf_receiver) saddr6->sin6_port = 0; else saddr6->sin6_port = *(u_int16_t*)&buf[38]; break; #endif case 4: if(*socklen < sizeof(struct sockaddr_in)){ *socklen = 0; OWPError(ctx,OWPErrFATAL,OWPErrINVALID, "_OWPDecodeV3TestRequest:socklen not big enough (%d < %d)", *socklen,sizeof(struct sockaddr_in)); return OWPErrFATAL; } *socklen = sizeof(struct sockaddr_in); /* sender address and port */ saddr4 = (struct sockaddr_in*)sender; saddr4->sin_family = AF_INET; saddr4->sin_addr.s_addr = *(u_int32_t*)&buf[4]; if(*server_conf_sender) saddr4->sin_port = 0; else saddr4->sin_port = *(u_int16_t*)&buf[36]; /* receiver address and port */ saddr4 = (struct sockaddr_in*)receiver; saddr4->sin_family = AF_INET; saddr4->sin_addr.s_addr = *(u_int32_t*)&buf[20]; if(*server_conf_receiver) saddr4->sin_port = 0; else saddr4->sin_port = *(u_int16_t*)&buf[38]; break; default: OWPError(ctx,OWPErrFATAL,OWPErrINVALID, "_OWPDecodeV3TestRequest:Unsupported IP version (%d)", *ipvn); return OWPErrFATAL; } #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN sender->sa_len = receiver->sa_len = *socklen; #endif # # Ok - a bunch of things happen between the allocation # and the creation of the udp socket. (Policy checks and # the like.) localaddr is a wrapper structure that encodes # all the addr information that is needed to create the # socket in a non-addr specific way. (almost an addrinfo # structure.) # Now this is the part where I actually use that sockaddr. # localaddr->saddr is either sender or receiver from the # initialization function depending upon the context of # the actual request. (In the error case it is the sender, # but that is only because that is the case I've been # testing - there is no difference in the two cases until # after the socket is bound.) /* * Create the socket. */ ep->sockfd = socket(localaddr->saddr->sa_family,localaddr->so_type, localaddr->so_protocol); if(ep->sockfd<0){ OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN,"socket(): %M"); goto error; } /* * bind it to the local address getting an ephemeral port number. */ if(bind(ep->sockfd,localaddr->saddr,localaddr->saddrlen) != 0){ OWPError(ctx,OWPErrFATAL,OWPErrUNKNOWN, "bind([%s]:%s): %M",localaddr->node,localaddr->port); goto error; } # # And this is an example of the error messages I have been seeing: Nov 26 16:30:10 nms2-ipls owampd[87121]: FILE=endpoint.c, LINE=437, bind([2001:468:12:2:203:47ff:fef1:5071]:0): Can't assign requested address Nov 26 16:30:12 nms2-ipls owampd[87134]: FILE=endpoint.c, LINE=437, bind([2001:468:12:2:203:47ff:fef1:5071]:0): Can't assign requested address Nov 26 16:30:13 nms2-ipls owampd[87121]: FILE=endpoint.c, LINE=437, bind([2001:468:12:2:203:47ff:fef1:5071]:0): Can't assign requested address Now, when this happens, it happens for about 10 seconds - and then things start working again. So, how likely is it that not initializing sa_len was causing this? (My ipv4 tests never had problems, and I would think they would behave the same in this particular regard.) (If anyone has actually read down this far, I truely thank you.) Thanks, jeff To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message