summaryrefslogtreecommitdiff
path: root/sys/src/9/ip
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-11-15 20:28:45 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2016-11-15 20:28:45 +0100
commit1f628ef1327882e070394595d58c7bec50d619af (patch)
tree8d22af36530b9592d04fb34bf4a1afa5d1bb4d70 /sys/src/9/ip
parentfdc8187038cc6761f764559a37bf7d9de87a0d2f (diff)
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.
Diffstat (limited to 'sys/src/9/ip')
-rw-r--r--sys/src/9/ip/tcp.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/sys/src/9/ip/tcp.c b/sys/src/9/ip/tcp.c
index 545cdb42e..050a24a0b 100644
--- a/sys/src/9/ip/tcp.c
+++ b/sys/src/9/ip/tcp.c
@@ -47,7 +47,7 @@ enum
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,32 +846,36 @@ localclose(Conv *s, char *reason) /* called with tcb locked */
/* 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.
*/
*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 @@ tcpsndsyn(Conv *s, Tcpctl *tcb)
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 @@ sndsynack(Proto *tcp, Limbo *lp)
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 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version)
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)