]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/ip/tcp.c
set router R-flag when sendra is active for neighbor advertisement
[plan9front.git] / sys / src / 9 / ip / tcp.c
index d1addc9d76444aa7bd7316715ba645b10f6aad3f..f241a5c8ef775e7ec9adbe76f47da67893fd44d5 100644 (file)
@@ -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)