ref: 1f628ef1327882e070394595d58c7bec50d619af
parent: fdc8187038cc6761f764559a37bf7d9de87a0d2f
author: cinap_lenrek <[email protected]>
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)