Skip site navigation (1)Skip section navigation (2)
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>