git: 9front

Download patch

ref: 79306deebc73d07cb4a7da1e4341fa36a5aebc3a
parent: c7c52675f9bce383a99212ce2035bf25b6b1e7b4
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Nov 15 15:28:45 EST 2016

ip/tcp: only calculae mss from interface mtu when directly reachable for v6

we currently do not implement path mtu discovery so for
destinations that are not directly reachable assume the
minimum mtu of 1280 bytes.

--- a/sys/src/9/ip/tcp.c
+++ b/sys/src/9/ip/tcp.c
@@ -47,7 +47,7 @@
 	MSL2		= 10,
 	MSPTICK		= 50,		/* Milliseconds per timer tick */
 	DEF_MSS		= 1460,		/* Default maximum segment */
-	DEF_MSS6	= 1280,		/* Default maximum segment (min) for v6 */
+	DEF_MSS6	= 1220,		/* Default maximum segment (min) for v6 */
 	DEF_RTT		= 500,		/* Default round trip */
 	DEF_KAT		= 120000,	/* Default time (ms) between keep alives */
 	TCP_LISTEN	= 0,		/* Listen connection */
@@ -846,25 +846,11 @@
 
 /* mtu (- TCP + IP hdr len) of 1st hop */
 static int
-tcpmtu(Proto *tcp, uchar *addr, int version, uint *scale)
+tcpmtu(Route *r, int version, uint *scale)
 {
 	Ipifc *ifc;
 	int mtu;
 
-	ifc = findipifc(tcp->f, addr, 0);
-	switch(version){
-	default:
-	case V4:
-		mtu = DEF_MSS;
-		if(ifc != nil)
-			mtu = ifc->maxtu - ifc->m->hsize - (TCP4_PKT + TCP4_HDRSIZE);
-		break;
-	case V6:
-		mtu = DEF_MSS6;
-		if(ifc != nil)
-			mtu = ifc->maxtu - ifc->m->hsize - (TCP6_PKT + TCP6_HDRSIZE);
-		break;
-	}
 	/*
 	 * set the ws.  it doesn't commit us to anything.
 	 * ws is the ultimate limit to the bandwidth-delay product.
@@ -871,7 +857,25 @@
 	 */
 	*scale = Defadvscale;
 
-	return mtu;
+	/*
+	 * currently we do not implement path MTU discovery
+	 * so use interface MTU *only* if directly reachable
+	 * or when we use V4 which allows routers to fragment.
+	 * otherwise, we use the default MSS which assumes a
+	 * safe minimum MTU of 1280 bytes for V6.
+	 */  
+	if(r != nil && (version == V4 || (r->type & (Rifc|Runi)) != 0)){
+		ifc = r->ifc;
+		mtu = ifc->maxtu - ifc->m->hsize;
+		if(version == V6)
+			return mtu - (TCP6_PKT + TCP6_HDRSIZE);
+		else
+			return mtu - (TCP4_PKT + TCP4_HDRSIZE);
+	}
+	if(version == V6)
+		return DEF_MSS6;
+	else
+		return DEF_MSS;
 }
 
 static void
@@ -1309,7 +1313,7 @@
 	tcb->sndsyntime = NOW;
 
 	/* set desired mss and scale */
-	tcb->mss = tcpmtu(s->p, s->laddr, s->ipversion, &tcb->scale);
+	tcb->mss = tcpmtu(v6lookup(s->p->f, s->raddr, s), s->ipversion, &tcb->scale);
 	tpriv = s->p->priv;
 	tpriv->stats[Mss] = tcb->mss;
 }
@@ -1487,7 +1491,7 @@
 	seg.ack = lp->irs+1;
 	seg.flags = SYN|ACK;
 	seg.urg = 0;
-	seg.mss = tcpmtu(tcp, lp->laddr, lp->version, &scale);
+	seg.mss = tcpmtu(v6lookup(tcp->f, lp->raddr, nil), lp->version, &scale);
 	seg.wnd = QMAX;
 
 	/* if the other side set scale, we should too */
@@ -1763,7 +1767,7 @@
 	tcb->flags |= SYNACK;
 
 	/* set desired mss and scale */
-	tcb->mss = tcpmtu(s->p, dst, s->ipversion, &tcb->scale);
+	tcb->mss = tcpmtu(v6lookup(s->p->f, src, s), version, &tcb->scale);
 
 	/* our sending max segment size cannot be bigger than what he asked for */
 	if(lp->mss != 0 && lp->mss < tcb->mss)
--