Date: Sun, 14 Jul 2002 19:01:20 +0200 (CEST) From: Jean-Luc Richier <Jean-Luc.Richier@imag.fr> To: FreeBSD-gnats-submit@FreeBSD.org Cc: Jean-Luc.Richier@imag.fr Subject: kern/40561: TTCP does not work with IPv6 Message-ID: <200207141701.g6EH1KlP093084@luna.imag.fr>
next in thread | raw e-mail | index | archive | help
>Number: 40561 >Category: kern >Synopsis: TTCP does not work with IPv6 >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jul 14 10:10:01 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Jean-Luc Richier >Release: FreeBSD 4.6-RELEASE i386 >Organization: LSR-IMAG Grenoble, France >Environment: System: FreeBSD luna.imag.fr 4.6-RELEASE FreeBSD 4.6-RELEASE #6: Wed Jun 12 18:55:37 GMT 2002 richier@luna.imag.fr:/usr/src/sys/compile/VLAN i386 also FreeBSD current (June, 24 2002) and KAME FreeBSD (kame-20020708-freebsd46-snap.tgz) Description: On an SOCK_STREAM PF_INET6 socket ttcp doesnt not work (sendto returns Socket is not connected) Also the INET6 ttcp code doesnt not accept IPv6 IPv4mapped addresses How-To-Repeat: + Write and execute the following test program: - s = socket(PF_INET6, SOCK_STREAM, 0); - getaddrinfo("2001::1","echo", &hints, &res); - sendto(s, "data", 4, 0, res->ai_addr, res->ai_addrlen); ---> ./tstttcp: sendto: Socket is not connected Fix: There are two bugs. - The first one is in sys/netinet6/in6_proto.c, the PR_IMPLOPCL flag needed to support implicit connexion of ttcp is not set in the TCP INET6 protocol description - The second one is that sys/netinet/tcp_usrreq.c code for ttcp does not test the IPv6 IPv4mapped addresses case. To correct apply the following patches --- /sys/netinet6/in6_proto.c.DIST Sun Apr 28 07:40:27 2002 +++ /sys/netinet6/in6_proto.c Mon May 27 18:40:07 2002 @@ -153,7 +153,7 @@ 0, 0, 0, 0, &udp6_usrreqs, }, -{ SOCK_STREAM, &inet6domain, IPPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN, +{ SOCK_STREAM, &inet6domain, IPPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_IMPLOPCL, tcp6_input, 0, tcp6_ctlinput, tcp_ctloutput, 0, #ifdef INET /* don't call initialization and timeout routines twice */ --- /sys/netinet/tcp_usrreq.c.DIST Fri Jun 7 22:54:02 2002 +++ /sys/netinet/tcp_usrreq.c Wed Jun 12 20:29:46 2002 @@ -509,9 +509,6 @@ int error = 0; struct inpcb *inp = sotoinpcb(so); struct tcpcb *tp; -#ifdef INET6 - int isipv6; -#endif TCPDEBUG0; if (inp == NULL) { @@ -529,9 +526,6 @@ TCPDEBUG1(); goto out; } -#ifdef INET6 - isipv6 = nam && nam->sa_family == AF_INET6; -#endif /* INET6 */ tp = intotcpcb(inp); TCPDEBUG1(); if (control) { @@ -545,27 +539,57 @@ } m_freem(control); /* empty control, just free it */ } - if(!(flags & PRUS_OOB)) { - sbappend(&so->so_snd, m); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ + if (flags & PRUS_OOB) { + if (sbspace(&so->so_snd) < -512) { + m_freem(m); + error = ENOBUFS; + goto out; + } + /* + * According to RFC961 (Assigned Protocols), + * the urgent pointer points to the last octet + * of urgent data. We continue, however, + * to consider it to indicate the first octet + * of data past the urgent section. + * Otherwise, snd_up should be one lower. + */ + } + sbappend(&so->so_snd, m); + if (nam && tp->t_state < TCPS_SYN_SENT) { + /* + * Do implied connect if not yet connected, + * initialize window to default value, and + * initialize maxseg/maxopd using peer's cached + * MSS. + */ #ifdef INET6 - if (isipv6) - error = tcp6_connect(tp, nam, p); - else -#endif /* INET6 */ - error = tcp_connect(tp, nam, p); - if (error) - goto out; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); + struct sockaddr_in sin; + int isipv6 = nam->sa_family == AF_INET6; + + if (isipv6 && + ip6_mapped_addr_on && + IN6_IS_ADDR_V4MAPPED(&satosin6(nam)->sin6_addr)) { + isipv6 = 0; + in6_sin6_2_sin(&sin, satosin6(nam)); + nam = sintosa(&sin); + inp->inp_vflag &= ~INP_IPV6; + inp->inp_vflag |= INP_IPV4; } + /* XXX Should disallow multicast addresses. */ + if (isipv6) { + inp->inp_inc.inc_isipv6 = 1; + error = tcp6_connect(tp, nam, p); + } else +#endif /* INET6 */ + error = tcp_connect(tp, nam, p); + if (error) + goto out; + tp->snd_wnd = TTCP_CLIENT_SND_WND; + tcp_mss(tp, -1); + } + + if(!(flags & PRUS_OOB)) { if (flags & PRUS_EOF) { /* * Close the send side of the connection after @@ -582,38 +606,6 @@ tp->t_flags &= ~TF_MORETOCOME; } } else { - if (sbspace(&so->so_snd) < -512) { - m_freem(m); - error = ENOBUFS; - goto out; - } - /* - * According to RFC961 (Assigned Protocols), - * the urgent pointer points to the last octet - * of urgent data. We continue, however, - * to consider it to indicate the first octet - * of data past the urgent section. - * Otherwise, snd_up should be one lower. - */ - sbappend(&so->so_snd, m); - if (nam && tp->t_state < TCPS_SYN_SENT) { - /* - * Do implied connect if not yet connected, - * initialize window to default value, and - * initialize maxseg/maxopd using peer's cached - * MSS. - */ -#ifdef INET6 - if (isipv6) - error = tcp6_connect(tp, nam, p); - else -#endif /* INET6 */ - error = tcp_connect(tp, nam, p); - if (error) - goto out; - tp->snd_wnd = TTCP_CLIENT_SND_WND; - tcp_mss(tp, -1); - } tp->snd_up = tp->snd_una + so->so_snd.sb_cc; tp->t_force = 1; error = tcp_output(tp); >Description: >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207141701.g6EH1KlP093084>