net: tcp: Don't increment snd.nxt
[akaros.git] / kern / src / net / udp.c
index 658c1b9..da58226 100644 (file)
@@ -142,7 +142,6 @@ void udpkick(void *x, struct block *bp);
  */
 typedef struct Udpcb Udpcb;
 struct Udpcb {
-       qlock_t qlock;
        uint8_t headers;
 };
 
@@ -157,6 +156,15 @@ static void udpconnect(struct conv *c, char **argv, int argc)
        iphtadd(&upriv->ht, c);
 }
 
+static void udpbind(struct conv *c, char **argv, int argc)
+{
+       Udppriv *upriv;
+
+       upriv = c->p->priv;
+       Fsstdbind(c, argv, argc);
+       iphtadd(&upriv->ht, c);
+}
+
 static int udpstate(struct conv *c, char *state, int n)
 {
        return snprintf(state, n, "%s qin %d qout %d\n",
@@ -174,6 +182,14 @@ static void udpannounce(struct conv *c, char **argv, int argc)
        iphtadd(&upriv->ht, c);
 }
 
+static void udpbypass(struct conv *cv, char **argv, int argc)
+{
+       Udppriv *upriv = cv->p->priv;
+
+       Fsstdbypass(cv, argv, argc);
+       iphtadd(&upriv->ht, cv);
+}
+
 static void udpcreate(struct conv *c)
 {
        c->rq = qopen(128 * 1024, Qmsg, 0, 0);
@@ -315,6 +331,7 @@ void udpkick(void *x, struct block *bp)
                                   ~ptclcsum(bp, UDP4_PHDR_OFF, UDP4_PHDR_SZ));
                        bp->checksum_start = UDP4_IPHDR_SZ;
                        bp->checksum_offset = uh4->udpcksum - uh4->udpsport;
+                       bp->transport_header_end = UDP4_IPHDR_SZ;
                        bp->flag |= Budpck;
                        uh4->vihl = IP_VER4;
                        ipoput4(f, bp, 0, c->ttl, c->tos, rc);
@@ -353,6 +370,7 @@ void udpkick(void *x, struct block *bp)
                                   ptclcsum(bp, UDP6_PHDR_OFF,
                                                        dlen + UDP_UDPHDR_SZ + UDP6_PHDR_SZ));
                        memset(uh6, 0, 8);
+                       bp->transport_header_end = UDP6_IPHDR_SZ;
                        uh6->viclfl[0] = IP_VER6;
                        hnputs(uh6->len, ptcllen);
                        uh6->nextheader = IP_UDPPROTO;
@@ -447,13 +465,10 @@ void udpiput(struct Proto *udp, struct Ipifc *ifc, struct block *bp)
                        return; /* to avoid a warning */
        }
 
-       qlock(&udp->qlock);
-
        c = iphtlook(&upriv->ht, raddr, rport, laddr, lport);
        if (c == NULL) {
                /* no converstation found */
                upriv->ustats.udpNoPorts++;
-               qunlock(&udp->qlock);
                netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
                           laddr, lport);
 
@@ -471,6 +486,12 @@ void udpiput(struct Proto *udp, struct Ipifc *ifc, struct block *bp)
                freeblist(bp);
                return;
        }
+
+       if (c->state == Bypass) {
+               bypass_or_drop(c, bp);
+               return;
+       }
+
        ucb = (Udpcb *) c->ptcl;
 
        if (c->state == Announced) {
@@ -488,9 +509,10 @@ void udpiput(struct Proto *udp, struct Ipifc *ifc, struct block *bp)
                                                panic("udpiput3: version %d", version);
                                }
                        }
+                       qlock(&udp->qlock);
                        c = Fsnewcall(c, raddr, rport, laddr, lport, version);
+                       qunlock(&udp->qlock);
                        if (c == NULL) {
-                               qunlock(&udp->qlock);
                                freeblist(bp);
                                return;
                        }
@@ -500,7 +522,6 @@ void udpiput(struct Proto *udp, struct Ipifc *ifc, struct block *bp)
        }
 
        qlock(&c->qlock);
-       qunlock(&udp->qlock);
 
        /*
         * Trim the packet down to data size
@@ -617,7 +638,6 @@ void udpadvise(struct Proto *udp, struct block *bp, char *msg)
        }
 
        /* Look for a connection */
-       qlock(&udp->qlock);
        for (p = udp->conv; *p; p++) {
                s = *p;
                if (s->rport == pdest)
@@ -627,7 +647,6 @@ void udpadvise(struct Proto *udp, struct block *bp, char *msg)
                                                if (s->ignoreadvice)
                                                        break;
                                                qlock(&s->qlock);
-                                               qunlock(&udp->qlock);
                                                qhangup(s->rq, msg);
                                                qhangup(s->wq, msg);
                                                qunlock(&s->qlock);
@@ -635,7 +654,6 @@ void udpadvise(struct Proto *udp, struct block *bp, char *msg)
                                                return;
                                        }
        }
-       qunlock(&udp->qlock);
        freeblist(bp);
 }
 
@@ -654,14 +672,6 @@ int udpstats(struct Proto *udp, char *buf, int len)
        return p - buf;
 }
 
-void udpnewconv(struct Proto *udp, struct conv *conv)
-{
-       /* Fsprotoclone alloc'd our priv struct and attached it to conv already.
-        * Now we need to init it */
-       struct Udpcb *ucb = (struct Udpcb *)conv->ptcl;
-       qlock_init(&ucb->qlock);
-}
-
 void udpinit(struct Fs *fs)
 {
        struct Proto *udp;
@@ -670,7 +680,9 @@ void udpinit(struct Fs *fs)
        udp->priv = kzmalloc(sizeof(Udppriv), 0);
        udp->name = "udp";
        udp->connect = udpconnect;
+       udp->bind = udpbind;
        udp->announce = udpannounce;
+       udp->bypass = udpbypass;
        udp->ctl = udpctl;
        udp->state = udpstate;
        udp->create = udpcreate;
@@ -679,8 +691,7 @@ void udpinit(struct Fs *fs)
        udp->advise = udpadvise;
        udp->stats = udpstats;
        udp->ipproto = IP_UDPPROTO;
-       udp->nc = Nchans;
-       udp->newconv = udpnewconv;
+       udp->nc = 4096;
        udp->ptclsize = sizeof(Udpcb);
 
        Fsproto(fs, udp);