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>
