X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fip%2Ftcp.c;h=f241a5c8ef775e7ec9adbe76f47da67893fd44d5;hb=ccf72da47d29772af51b0b348d2845fbbbd8a881;hp=d1addc9d76444aa7bd7316715ba645b10f6aad3f;hpb=98f47d5867cbbaa06f2c9080c301c9191e196205;p=plan9front.git diff --git a/sys/src/9/ip/tcp.c b/sys/src/9/ip/tcp.c index d1addc9d7..f241a5c8e 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,37 @@ 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){ + ifc = r->ifc; + mtu = ifc->maxtu - ifc->m->hsize; + if(version == V4) + return mtu - (TCP4_PKT + TCP4_HDRSIZE); + mtu -= TCP6_PKT + TCP6_HDRSIZE; + if((r->type & (Rifc|Runi)) != 0 || mtu <= DEF_MSS6) + return mtu; + } + if(version == V6) + return DEF_MSS6; + else + return DEF_MSS; } static void @@ -1034,14 +1039,10 @@ htontcp6(Tcp *tcph, Block *data, Tcp6hdr *ph, Tcpctl *tcb) if(data) { dlen = blocklen(data); data = padblock(data, hdrlen + TCP6_PKT); - if(data == nil) - return nil; } else { dlen = 0; data = allocb(hdrlen + TCP6_PKT + 64); /* the 64 pad is to meet mintu's */ - if(data == nil) - return nil; data->wp += hdrlen + TCP6_PKT; } @@ -1118,14 +1119,10 @@ htontcp4(Tcp *tcph, Block *data, Tcp4hdr *ph, Tcpctl *tcb) if(data) { dlen = blocklen(data); data = padblock(data, hdrlen + TCP4_PKT); - if(data == nil) - return nil; } else { dlen = 0; data = allocb(hdrlen + TCP4_PKT + 64); /* the 64 pad is to meet mintu's */ - if(data == nil) - return nil; data->wp += hdrlen + TCP4_PKT; } @@ -1317,7 +1314,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; } @@ -1495,7 +1492,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 */ @@ -1770,11 +1767,13 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version) tcb->flgcnt = 0; tcb->flags |= SYNACK; + /* set desired mss and 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) { + if(lp->mss != 0 && lp->mss < tcb->mss) tcb->mss = lp->mss; - tpriv->stats[Mss] = tcb->mss; - } + tpriv->stats[Mss] = tcb->mss; /* window scaling */ tcpsetscale(new, tcb, lp->rcvscale, lp->sndscale); @@ -2435,10 +2434,7 @@ reset: * receive queue */ if(bp) { - bp = packblock(bp); - if(bp == nil) - panic("tcp packblock"); - qpassnolim(s->rq, bp); + qpassnolim(s->rq, packblock(bp)); bp = nil; } tcb->rcv.nxt += length; @@ -3252,6 +3248,8 @@ tcpadvise(Proto *tcp, Block *bp, char *msg) if(tcb->state != Closed) if(ipcmp(s->raddr, dest) == 0) if(ipcmp(s->laddr, source) == 0){ + if(s->ignoreadvice) + break; qlock(s); qunlock(tcp); switch(tcb->state){ @@ -3284,6 +3282,8 @@ tcpporthogdefensectl(char *val) static char* tcpctl(Conv* c, char** f, int n) { + if(n == 1 && strcmp(f[0], "close") == 0) + return tcpclose(c), nil; if(n == 1 && strcmp(f[0], "hangup") == 0) return tcphangup(c); if(n >= 1 && strcmp(f[0], "keepalive") == 0)