net: Allow connectionless convs to auto bind
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Feb 2017 16:20:01 +0000 (11:20 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Feb 2017 18:34:59 +0000 (13:34 -0500)
Conversations/sockets from connectionless protocols can immediately write
to Qdata, without a bind.  We'll automatically bind to a local port before
sending.  SOCK_DGRAM supports this, but instead of doing it in glibc,
it seemed like something Plan-9-networking apps could use too.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/net/devip.c

index 65c638a..0bc5093 100644 (file)
@@ -1328,6 +1328,22 @@ static void ttlctlmsg(struct conv *c, struct cmdbuf *cb)
                c->ttl = atoi(cb->f[1]);
 }
 
+/* Binds a conversation, as if the user wrote "bind *" into ctl. */
+static void autobind(struct conv *cv)
+{
+       ERRSTACK(1);
+       struct cmdbuf *cb;
+
+       cb = parsecmd("bind *", 7);
+       if (waserror()) {
+               kfree(cb);
+               nexterror();
+       }
+       bindctlmsg(cv->p, cv, cb);
+       poperror();
+       kfree(cb);
+}
+
 static long ipwrite(struct chan *ch, void *v, long n, int64_t off)
 {
        ERRSTACK(1);
@@ -1348,6 +1364,10 @@ static long ipwrite(struct chan *ch, void *v, long n, int64_t off)
                case Qdata:
                        x = f->p[PROTO(ch->qid)];
                        c = x->conv[CONV(ch->qid)];
+                       /* connection-less protocols (UDP) can write without manually
+                        * binding. */
+                       if (c->lport == 0)
+                               autobind(c);
                        if (ch->flag & O_NONBLOCK)
                                qwrite_nonblock(c->wq, a, n);
                        else