Subject: Usability enhancement for IP6
To: None <tech-net@netbsd.org>
From: Bryan Phillippe <bp009@terran.org>
List: tech-net
Date: 02/05/2005 11:06:39
Hello,

Ever since I configured a private IPv6 network with NetBSD, I've had the
annoying problem of having to wait for multiple failed retransmits to
public sites such as www.netbsd.org, before falling down to IPv4.  Other
IPv6 stacks, such as Microsoft, do not have this problem.

The following small patch fixes the problem for me: IPv6 connections to
other private IPv6 hosts work fine and IPv6 connections to unreachable
public IPv6 hosts fail immediately and fall back to IPv4.

It could probably use some cleanup, and perhaps making it configurable via
sysctl (or make it dependent on net.inet6.ip6.v6only) would be better.

Index: netinet/tcp_subr.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.160.2.5
diff -u -r1.160.2.5 tcp_subr.c
--- netinet/tcp_subr.c	19 Sep 2004 15:38:01 -0000	1.160.2.5
+++ netinet/tcp_subr.c	5 Feb 2005 19:00:24 -0000
@@ -1342,17 +1342,18 @@

 	/*
 	 * Ignore some errors if we are hooked up.
-	 * If connection hasn't completed, has retransmitted several times,
-	 * and receives a second error, give up now.  This is better
-	 * than waiting a long time to establish a connection that
-	 * can never complete.
+	 * If connection hasn't completed, and either gets a "host/net
+	 * unreachable" or has retransmitted several times and receives a
+	 * second error, give up now.  This is better than waiting a long
+	 * time to establish a connection that can never complete.
 	 */
 	if (tp->t_state == TCPS_ESTABLISHED &&
 	     (error == EHOSTUNREACH || error == ENETUNREACH ||
 	      error == EHOSTDOWN)) {
 		return;
 	} else if (TCPS_HAVEESTABLISHED(tp->t_state) == 0 &&
-	    tp->t_rxtshift > 3 && tp->t_softerror)
+	    ((error == EHOSTUNREACH || error == ENETUNREACH) ||
+	     (tp->t_rxtshift > 3 && tp->t_softerror)))
 		so->so_error = error;
 	else
 		tp->t_softerror = error;

-bp
--