Add support for FD taps on Qlisten chans in #I
[akaros.git] / kern / src / net / devip.c
1 // INFERNO
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <ip.h>
15
16 enum {
17         Qtopdir = 1,                            /* top level directory */
18         Qtopbase,
19         Qarp = Qtopbase,
20         Qbootp,
21         Qndb,
22         Qiproute,
23         Qiprouter,
24         Qipselftab,
25         Qlog,
26
27         Qprotodir,      /* directory for a protocol */
28         Qprotobase,
29         Qclone = Qprotobase,
30         Qstats,
31
32         Qconvdir,       /* directory for a conversation */
33         Qconvbase,
34         Qctl = Qconvbase,
35         Qdata,
36         Qerr,
37         Qlisten,
38         Qlocal,
39         Qremote,
40         Qstatus,
41         Qsnoop,
42
43         Logtype = 5,
44         Masktype = (1 << Logtype) - 1,
45         Logconv = 12,
46         Maskconv = (1 << Logconv) - 1,
47         Shiftconv = Logtype,
48         Logproto = 8,
49         Maskproto = (1 << Logproto) - 1,
50         Shiftproto = Logtype + Logconv,
51
52         Nfs = 32,
53 };
54 #define TYPE(x)         ( ((uint32_t)(x).path) & Masktype )
55 #define CONV(x)         ( (((uint32_t)(x).path) >> Shiftconv) & Maskconv )
56 #define PROTO(x)        ( (((uint32_t)(x).path) >> Shiftproto) & Maskproto )
57 #define QID(p, c, y)    ( ((p)<<(Shiftproto)) | ((c)<<Shiftconv) | (y))
58 static char network[] = "network";
59
60 qlock_t fslock;
61 struct Fs *ipfs[Nfs];                   /* attached fs's */
62 struct queue *qlog;
63
64 extern void nullmediumlink(void);
65 extern void pktmediumlink(void);
66 extern char *eve;
67 static long ndbwrite(struct Fs *, char *unused_char_p_t, uint32_t, int);
68 static void closeconv(struct conv *);
69
70 static inline int founddevdir(struct chan *c, struct qid q, char *n,
71                                                           int64_t length, char *user, long perm,
72                                                           struct dir *db)
73 {
74         devdir(c, q, n, length, user, perm, db);
75         return 1;
76 }
77
78 static int topdirgen(struct chan *c, struct dir *dp)
79 {
80         struct qid q;
81         mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
82         snprintf(get_cur_genbuf(), GENBUF_SZ, "#I%lu", c->dev);
83         return founddevdir(c, q, get_cur_genbuf(), 0, network, 0555, dp);
84 }
85
86
87 static int ip3gen(struct chan *c, int i, struct dir *dp)
88 {
89         struct qid q;
90         struct conv *cv;
91         char *p;
92
93         cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)];
94         if (cv->owner == NULL)
95                 kstrdup(&cv->owner, eve);
96         mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE);
97
98         switch (i) {
99                 default:
100                         return -1;
101                 case Qctl:
102                         return founddevdir(c, q, "ctl", 0,
103                                                    cv->owner, cv->perm, dp);
104                 case Qdata:
105                         return founddevdir(c, q, "data", qlen(cv->rq),
106                                                            cv->owner, cv->perm, dp);
107                 case Qerr:
108                         return founddevdir(c, q, "err", qlen(cv->eq),
109                                                            cv->owner, cv->perm, dp);
110                 case Qlisten:
111                         return founddevdir(c, q, "listen", 0, cv->owner, cv->perm, dp);
112                 case Qlocal:
113                         p = "local";
114                         break;
115                 case Qremote:
116                         p = "remote";
117                         break;
118                 case Qsnoop:
119                         if (strcmp(cv->p->name, "ipifc") != 0)
120                                 return -1;
121                         return founddevdir(c, q, "snoop", qlen(cv->sq),
122                                                            cv->owner, 0400, dp);
123                 case Qstatus:
124                         p = "status";
125                         break;
126         }
127         return founddevdir(c, q, p, 0, cv->owner, 0444, dp);
128 }
129
130 static int ip2gen(struct chan *c, int i, struct dir *dp)
131 {
132         struct qid q;
133         mkqid(&q, QID(PROTO(c->qid), 0, i), 0, QTFILE);
134         switch (i) {
135                 case Qclone:
136                         return founddevdir(c, q, "clone", 0, network, 0666, dp);
137                 case Qstats:
138                         return founddevdir(c, q, "stats", 0, network, 0444, dp);
139         }
140         return -1;
141 }
142
143 static int ip1gen(struct chan *c, int i, struct dir *dp)
144 {
145         struct qid q;
146         char *p;
147         int prot;
148         int len = 0;
149         struct Fs *f;
150         extern uint32_t kerndate;
151
152         f = ipfs[c->dev];
153
154         prot = 0666;
155         mkqid(&q, QID(0, 0, i), 0, QTFILE);
156         switch (i) {
157                 default:
158                         return -1;
159                 case Qarp:
160                         p = "arp";
161                         break;
162                 case Qbootp:
163                         if (bootp == NULL)
164                                 return 0;
165                         p = "bootp";
166                         break;
167                 case Qndb:
168                         p = "ndb";
169                         len = strlen(f->ndb);
170                         q.vers = f->ndbvers;
171                         break;
172                 case Qiproute:
173                         p = "iproute";
174                         break;
175                 case Qipselftab:
176                         p = "ipselftab";
177                         prot = 0444;
178                         break;
179                 case Qiprouter:
180                         p = "iprouter";
181                         break;
182                 case Qlog:
183                         p = "log";
184                         break;
185         }
186         devdir(c, q, p, len, network, prot, dp);
187         if (i == Qndb && f->ndbmtime > kerndate)
188                 dp->mtime = f->ndbmtime;
189         return 1;
190 }
191
192 static int
193 ipgen(struct chan *c, char *unused_char_p_t, struct dirtab *d, int unused_int,
194           int s, struct dir *dp)
195 {
196         struct qid q;
197         struct conv *cv;
198         struct Fs *f;
199
200         f = ipfs[c->dev];
201
202         switch (TYPE(c->qid)) {
203                 case Qtopdir:
204                         if (s == DEVDOTDOT)
205                                 return topdirgen(c, dp);
206                         if (s < f->np) {
207                                 if (f->p[s]->connect == NULL)
208                                         return 0;       /* protocol with no user interface */
209                                 mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
210                                 return founddevdir(c, q, f->p[s]->name, 0, network, 0555, dp);
211                         }
212                         s -= f->np;
213                         return ip1gen(c, s + Qtopbase, dp);
214                 case Qarp:
215                 case Qbootp:
216                 case Qndb:
217                 case Qlog:
218                 case Qiproute:
219                 case Qiprouter:
220                 case Qipselftab:
221                         return ip1gen(c, TYPE(c->qid), dp);
222                 case Qprotodir:
223                         if (s == DEVDOTDOT)
224                                 return topdirgen(c, dp);
225                         else if (s < f->p[PROTO(c->qid)]->ac) {
226                                 cv = f->p[PROTO(c->qid)]->conv[s];
227                                 snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", s);
228                                 mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
229                                 return
230                                         founddevdir(c, q, get_cur_genbuf(), 0, cv->owner, 0555, dp);
231                         }
232                         s -= f->p[PROTO(c->qid)]->ac;
233                         return ip2gen(c, s + Qprotobase, dp);
234                 case Qclone:
235                 case Qstats:
236                         return ip2gen(c, TYPE(c->qid), dp);
237                 case Qconvdir:
238                         if (s == DEVDOTDOT) {
239                                 s = PROTO(c->qid);
240                                 mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
241                                 devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
242                                 return 1;
243                         }
244                         return ip3gen(c, s + Qconvbase, dp);
245                 case Qctl:
246                 case Qdata:
247                 case Qerr:
248                 case Qlisten:
249                 case Qlocal:
250                 case Qremote:
251                 case Qstatus:
252                 case Qsnoop:
253                         return ip3gen(c, TYPE(c->qid), dp);
254         }
255         return -1;
256 }
257
258 static void ipinit(void)
259 {
260         qlock_init(&fslock);
261         nullmediumlink();
262         pktmediumlink();
263 /* if only
264         fmtinstall('i', eipfmt);
265         fmtinstall('I', eipfmt);
266         fmtinstall('E', eipfmt);
267         fmtinstall('V', eipfmt);
268         fmtinstall('M', eipfmt);
269 */
270 }
271
272 static void ipreset(void)
273 {
274 }
275
276 static struct Fs *ipgetfs(int dev)
277 {
278         extern void (*ipprotoinit[]) (struct Fs *);
279         struct Fs *f;
280         int i;
281
282         if (dev >= Nfs)
283                 return NULL;
284
285         qlock(&fslock);
286         if (ipfs[dev] == NULL) {
287                 f = kzmalloc(sizeof(struct Fs), KMALLOC_WAIT);
288                 rwinit(&f->rwlock);
289                 qlock_init(&f->iprouter.qlock);
290                 ip_init(f);
291                 arpinit(f);
292                 netloginit(f);
293                 for (i = 0; ipprotoinit[i]; i++)
294                         ipprotoinit[i] (f);
295                 f->dev = dev;
296                 ipfs[dev] = f;
297         }
298         qunlock(&fslock);
299
300         return ipfs[dev];
301 }
302
303 struct IPaux *newipaux(char *owner, char *tag)
304 {
305         struct IPaux *a;
306         int n;
307
308         a = kzmalloc(sizeof(*a), 0);
309         kstrdup(&a->owner, owner);
310         memset(a->tag, ' ', sizeof(a->tag));
311         n = strlen(tag);
312         if (n > sizeof(a->tag))
313                 n = sizeof(a->tag);
314         memmove(a->tag, tag, n);
315         return a;
316 }
317
318 #define ATTACHER(c) (((struct IPaux*)((c)->aux))->owner)
319
320 static struct chan *ipattach(char *spec)
321 {
322         struct chan *c;
323         int dev;
324
325         dev = atoi(spec);
326         if (dev >= Nfs)
327                 error("bad specification");
328
329         ipgetfs(dev);
330         c = devattach('I', spec);
331         mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR);
332         c->dev = dev;
333
334         c->aux = newipaux(commonuser(), "none");
335
336         return c;
337 }
338
339 static struct walkqid *ipwalk(struct chan *c, struct chan *nc, char **name,
340                                                           int nname)
341 {
342         struct IPaux *a = c->aux;
343         struct walkqid *w;
344
345         w = devwalk(c, nc, name, nname, NULL, 0, ipgen);
346         if (w != NULL && w->clone != NULL)
347                 w->clone->aux = newipaux(a->owner, a->tag);
348         return w;
349 }
350
351 static int ipstat(struct chan *c, uint8_t * db, int n)
352 {
353         return devstat(c, db, n, NULL, 0, ipgen);
354 }
355
356 static int should_wake(void *arg)
357 {
358         struct conv *cv = arg;
359         /* signal that the conv is closed */
360         if (qisclosed(cv->rq))
361                 return TRUE;
362         return cv->incall != NULL;
363 }
364
365 static struct chan *ipopen(struct chan *c, int omode)
366 {
367         ERRSTACK(2);
368         struct conv *cv, *nc;
369         struct Proto *p;
370         int perm;
371         struct Fs *f;
372
373         /* perm is a lone rwx, not the rwx------ from the conversion */
374         perm = omode_to_rwx(omode) >> 6;
375
376         f = ipfs[c->dev];
377
378         switch (TYPE(c->qid)) {
379                 default:
380                         break;
381                 case Qndb:
382                         if (omode & (O_WRITE | O_TRUNC) && !iseve())
383                                 error(Eperm);
384                         if ((omode & (O_WRITE | O_TRUNC)) == (O_WRITE | O_TRUNC))
385                                 f->ndb[0] = 0;
386                         break;
387                 case Qlog:
388                         netlogopen(f);
389                         break;
390                 case Qiprouter:
391                         iprouteropen(f);
392                         break;
393                 case Qiproute:
394                         break;
395                 case Qtopdir:
396                 case Qprotodir:
397                 case Qconvdir:
398                 case Qstatus:
399                 case Qremote:
400                 case Qlocal:
401                 case Qstats:
402                 case Qbootp:
403                 case Qipselftab:
404                         if (omode & O_WRITE)
405                                 error(Eperm);
406                         break;
407                 case Qsnoop:
408                         if (omode & O_WRITE)
409                                 error(Eperm);
410                         p = f->p[PROTO(c->qid)];
411                         cv = p->conv[CONV(c->qid)];
412                         if (strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
413                                 error(Eperm);
414                         atomic_inc(&cv->snoopers);
415                         break;
416                 case Qclone:
417                         p = f->p[PROTO(c->qid)];
418                         qlock(&p->qlock);
419                         if (waserror()) {
420                                 qunlock(&p->qlock);
421                                 nexterror();
422                         }
423                         cv = Fsprotoclone(p, ATTACHER(c));
424                         qunlock(&p->qlock);
425                         poperror();
426                         if (cv == NULL) {
427                                 error(Enodev);
428                                 break;
429                         }
430                         /* we only honor nonblock on a clone */
431                         if (c->flag & O_NONBLOCK)
432                                 Fsconvnonblock(cv, TRUE);
433                         mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
434                         break;
435                 case Qdata:
436                 case Qctl:
437                 case Qerr:
438                         p = f->p[PROTO(c->qid)];
439                         qlock(&p->qlock);
440                         cv = p->conv[CONV(c->qid)];
441                         qlock(&cv->qlock);
442                         if (waserror()) {
443                                 qunlock(&cv->qlock);
444                                 qunlock(&p->qlock);
445                                 nexterror();
446                         }
447                         if ((perm & (cv->perm >> 6)) != perm) {
448                                 if (strcmp(ATTACHER(c), cv->owner) != 0)
449                                         error(Eperm);
450                                 if ((perm & cv->perm) != perm)
451                                         error(Eperm);
452
453                         }
454                         cv->inuse++;
455                         if (cv->inuse == 1) {
456                                 kstrdup(&cv->owner, ATTACHER(c));
457                                 cv->perm = 0660;
458                         }
459                         qunlock(&cv->qlock);
460                         qunlock(&p->qlock);
461                         poperror();
462                         break;
463                 case Qlisten:
464                         cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
465                         /* No permissions or Announce checks required.  We'll see if that's
466                          * a good idea or not. (the perm check would do nothing, as is,
467                          * since an O_PATH perm is 0).
468                          *
469                          * But we probably want to incref to keep the conversation around
470                          * until this FD/chan is closed.  #I is a little weird in that
471                          * objects never really go away (high water mark for convs, you can
472                          * always find them in the ns).  I think it is possible to
473                          * namec/ipgen a chan, then have that conv close, then have that
474                          * chan be opened.  You can probably do this with a data file. */
475                         if (omode & O_PATH) {
476                                 qlock(&cv->qlock);
477                                 cv->inuse++;
478                                 qunlock(&cv->qlock);
479                                 break;
480                         }
481                         if ((perm & (cv->perm >> 6)) != perm) {
482                                 if (strcmp(ATTACHER(c), cv->owner) != 0)
483                                         error(Eperm);
484                                 if ((perm & cv->perm) != perm)
485                                         error(Eperm);
486
487                         }
488
489                         if (cv->state != Announced)
490                                 error("not announced");
491
492                         if (waserror()) {
493                                 closeconv(cv);
494                                 nexterror();
495                         }
496                         qlock(&cv->qlock);
497                         cv->inuse++;
498                         qunlock(&cv->qlock);
499
500                         nc = NULL;
501                         while (nc == NULL) {
502                                 /* give up if we got a hangup */
503                                 if (qisclosed(cv->rq))
504                                         error("listen hungup");
505
506                                 qlock(&cv->listenq);
507                                 if (waserror()) {
508                                         qunlock(&cv->listenq);
509                                         nexterror();
510                                 }
511                                 /* we can peek at incall without grabbing the cv qlock.  if
512                                  * anything is there, it'll remain there until we dequeue it.
513                                  * no one else can, since we hold the listenq lock */
514                                 if (cv->nonblock && !cv->incall) {
515                                         set_errno(EAGAIN);
516                                         error("listen queue empty");
517                                 }
518                                 /* wait for a connect */
519                                 rendez_sleep(&cv->listenr, should_wake, cv);
520
521                                 /* if there is a concurrent hangup, they will hold the qlock
522                                  * until the hangup is complete, including closing the cv->rq */
523                                 qlock(&cv->qlock);
524                                 nc = cv->incall;
525                                 if (nc != NULL) {
526                                         cv->incall = nc->next;
527                                         mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
528                                         kstrdup(&cv->owner, ATTACHER(c));
529                                         /* O_NONBLOCK/CNONBLOCK when opening listen means the *new*
530                                          * conv is already non-blocking, like accept4() in Linux */
531                                         if (c->flag & O_NONBLOCK)
532                                                 Fsconvnonblock(nc, TRUE);
533                                 }
534                                 qunlock(&cv->qlock);
535
536                                 qunlock(&cv->listenq);
537                                 poperror();
538                         }
539                         closeconv(cv);
540                         poperror();
541                         break;
542         }
543         c->mode = openmode(omode);
544         c->flag |= COPEN;
545         c->offset = 0;
546         return c;
547 }
548
549 static int ipwstat(struct chan *c, uint8_t * dp, int n)
550 {
551         ERRSTACK(2);
552         struct dir *d;
553         struct conv *cv;
554         struct Fs *f;
555         struct Proto *p;
556
557         f = ipfs[c->dev];
558         switch (TYPE(c->qid)) {
559                 default:
560                         error(Eperm);
561                         break;
562                 case Qctl:
563                 case Qdata:
564                         break;
565         }
566
567         d = kzmalloc(sizeof(*d) + n, 0);
568         if (waserror()) {
569                 kfree(d);
570                 nexterror();
571         }
572         n = convM2D(dp, n, d, (char *)&d[1]);
573         if (n == 0)
574                 error(Eshortstat);
575         p = f->p[PROTO(c->qid)];
576         cv = p->conv[CONV(c->qid)];
577         if (!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
578                 error(Eperm);
579         if (!emptystr(d->uid))
580                 kstrdup(&cv->owner, d->uid);
581         if (d->mode != ~0UL)
582                 cv->perm = d->mode & 0777;
583         poperror();
584         kfree(d);
585         return n;
586 }
587
588 /* Should be able to handle any file type chan. Feel free to extend it. */
589 static char *ipchaninfo(struct chan *ch, char *ret, size_t ret_l)
590 {
591         struct conv *conv;
592         struct Proto *proto;
593         char *p;
594         struct Fs *f;
595
596         f = ipfs[ch->dev];
597
598         switch (TYPE(ch->qid)) {
599                 default:
600                         ret = "Unknown type";
601                         break;
602                 case Qdata:
603                         proto = f->p[PROTO(ch->qid)];
604                         conv = proto->conv[CONV(ch->qid)];
605                         snprintf(ret, ret_l, "Qdata, proto %s, conv idx %d", proto->name,
606                                          conv->x);
607                         break;
608                 case Qarp:
609                         ret = "Qarp";
610                         break;
611                 case Qiproute:
612                         ret = "Qiproute";
613                         break;
614                 case Qlog:
615                         ret = "Qlog";
616                         break;
617                 case Qndb:
618                         ret = "Qndb";
619                         break;
620                 case Qctl:
621                         proto = f->p[PROTO(ch->qid)];
622                         conv = proto->conv[CONV(ch->qid)];
623                         snprintf(ret, ret_l, "Qctl, proto %s, conv idx %d", proto->name,
624                                          conv->x);
625                         break;
626         }
627         return ret;
628 }
629
630 static void closeconv(struct conv *cv)
631 {
632         struct conv *nc;
633         struct Ipmulti *mp;
634
635         qlock(&cv->qlock);
636
637         if (--cv->inuse > 0) {
638                 qunlock(&cv->qlock);
639                 return;
640         }
641
642         /* close all incoming calls since no listen will ever happen */
643         for (nc = cv->incall; nc; nc = cv->incall) {
644                 cv->incall = nc->next;
645                 closeconv(nc);
646         }
647         cv->incall = NULL;
648
649         kstrdup(&cv->owner, network);
650         cv->perm = 0660;
651
652         while ((mp = cv->multi) != NULL)
653                 ipifcremmulti(cv, mp->ma, mp->ia);
654
655         cv->r = NULL;
656         cv->rgen = 0;
657         cv->p->close(cv);
658         cv->state = Idle;
659         qunlock(&cv->qlock);
660 }
661
662 static void ipclose(struct chan *c)
663 {
664         struct Fs *f;
665
666         f = ipfs[c->dev];
667         switch (TYPE(c->qid)) {
668                 default:
669                         break;
670                 case Qlog:
671                         if (c->flag & COPEN)
672                                 netlogclose(f);
673                         break;
674                 case Qiprouter:
675                         if (c->flag & COPEN)
676                                 iprouterclose(f);
677                         break;
678                 case Qdata:
679                 case Qctl:
680                 case Qerr:
681                         if (c->flag & COPEN)
682                                 closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
683                         break;
684                 case Qsnoop:
685                         if (c->flag & COPEN)
686                                 atomic_dec(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
687                         break;
688         }
689         kfree(((struct IPaux *)c->aux)->owner);
690         kfree(c->aux);
691 }
692
693 enum {
694         Statelen = 32 * 1024,
695 };
696
697 static long ipread(struct chan *ch, void *a, long n, int64_t off)
698 {
699         struct conv *c;
700         struct Proto *x;
701         char *buf, *p;
702         long rv;
703         struct Fs *f;
704         uint32_t offset = off;
705         size_t sofar;
706
707         f = ipfs[ch->dev];
708
709         p = a;
710         switch (TYPE(ch->qid)) {
711                 default:
712                         error(Eperm);
713                 case Qtopdir:
714                 case Qprotodir:
715                 case Qconvdir:
716                         return devdirread(ch, a, n, 0, 0, ipgen);
717                 case Qarp:
718                         return arpread(f->arp, a, offset, n);
719                 case Qbootp:
720                         return bootpread(a, offset, n);
721                 case Qndb:
722                         return readstr(offset, a, n, f->ndb);
723                 case Qiproute:
724                         return routeread(f, a, offset, n);
725                 case Qiprouter:
726                         return iprouterread(f, a, n);
727                 case Qipselftab:
728                         return ipselftabread(f, a, offset, n);
729                 case Qlog:
730                         return netlogread(f, a, offset, n);
731                 case Qctl:
732                         snprintf(get_cur_genbuf(), GENBUF_SZ, "%lu", CONV(ch->qid));
733                         return readstr(offset, p, n, get_cur_genbuf());
734                 case Qremote:
735                         buf = kzmalloc(Statelen, 0);
736                         x = f->p[PROTO(ch->qid)];
737                         c = x->conv[CONV(ch->qid)];
738                         if (x->remote == NULL) {
739                                 snprintf(buf, Statelen, "%I!%d\n", c->raddr, c->rport);
740                         } else {
741                                 (*x->remote) (c, buf, Statelen - 2);
742                         }
743                         rv = readstr(offset, p, n, buf);
744                         kfree(buf);
745                         return rv;
746                 case Qlocal:
747                         buf = kzmalloc(Statelen, 0);
748                         x = f->p[PROTO(ch->qid)];
749                         c = x->conv[CONV(ch->qid)];
750                         if (x->local == NULL) {
751                                 snprintf(buf, Statelen, "%I!%d\n", c->laddr, c->lport);
752                         } else {
753                                 (*x->local) (c, buf, Statelen - 2);
754                         }
755                         rv = readstr(offset, p, n, buf);
756                         kfree(buf);
757                         return rv;
758                 case Qstatus:
759                         /* this all is a bit screwed up since the size of some state's
760                          * buffers will change from one invocation to another.  a reader
761                          * will come in and read the entire buffer.  then it will come again
762                          * and read from the next offset, expecting EOF.  if the buffer
763                          * changed sizes, it'll reprint the end of the buffer slightly. */
764                         buf = kzmalloc(Statelen, 0);
765                         x = f->p[PROTO(ch->qid)];
766                         c = x->conv[CONV(ch->qid)];
767                         sofar = (*x->state) (c, buf, Statelen - 2);
768                         sofar += snprintf(buf + sofar, Statelen - 2 - sofar, "nonblock %s\n",
769                                           c->nonblock ? "on" : "off");
770                         rv = readstr(offset, p, n, buf);
771                         kfree(buf);
772                         return rv;
773                 case Qdata:
774                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
775                         return qread(c->rq, a, n);
776                 case Qerr:
777                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
778                         return qread(c->eq, a, n);
779                 case Qsnoop:
780                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
781                         return qread(c->sq, a, n);
782                 case Qstats:
783                         x = f->p[PROTO(ch->qid)];
784                         if (x->stats == NULL)
785                                 error("stats not implemented");
786                         buf = kzmalloc(Statelen, 0);
787                         (*x->stats) (x, buf, Statelen);
788                         rv = readstr(offset, p, n, buf);
789                         kfree(buf);
790                         return rv;
791         }
792 }
793
794 static struct block *ipbread(struct chan *ch, long n, uint32_t offset)
795 {
796         struct conv *c;
797         struct Proto *x;
798         struct Fs *f;
799
800         switch (TYPE(ch->qid)) {
801                 case Qdata:
802                         f = ipfs[ch->dev];
803                         x = f->p[PROTO(ch->qid)];
804                         c = x->conv[CONV(ch->qid)];
805                         return qbread(c->rq, n);
806                 default:
807                         return devbread(ch, n, offset);
808         }
809 }
810
811 /*
812  *  set local address to be that of the ifc closest to remote address
813  */
814 static void setladdr(struct conv *c)
815 {
816         findlocalip(c->p->f, c->laddr, c->raddr);
817 }
818
819 /*
820  *  set a local port making sure the quad of raddr,rport,laddr,lport is unique
821  */
822 static char *setluniqueport(struct conv *c, int lport)
823 {
824         struct Proto *p;
825         struct conv *xp;
826         int x;
827
828         p = c->p;
829
830         qlock(&p->qlock);
831         for (x = 0; x < p->nc; x++) {
832                 xp = p->conv[x];
833                 if (xp == NULL)
834                         break;
835                 if (xp == c)
836                         continue;
837                 if ((xp->state == Connected || xp->state == Announced)
838                         && xp->lport == lport
839                         && xp->rport == c->rport
840                         && ipcmp(xp->raddr, c->raddr) == 0
841                         && ipcmp(xp->laddr, c->laddr) == 0) {
842                         qunlock(&p->qlock);
843                         return "address in use";
844                 }
845         }
846         c->lport = lport;
847         qunlock(&p->qlock);
848         return NULL;
849 }
850
851 /*
852  *  pick a local port and set it
853  */
854 static void setlport(struct conv *c)
855 {
856         struct Proto *p;
857         uint16_t *pp;
858         int x, found;
859
860         p = c->p;
861         if (c->restricted)
862                 pp = &p->nextrport;
863         else
864                 pp = &p->nextport;
865         qlock(&p->qlock);
866         for (;; (*pp)++) {
867                 /*
868                  * Fsproto initialises p->nextport to 0 and the restricted
869                  * ports (p->nextrport) to 600.
870                  * Restricted ports must lie between 600 and 1024.
871                  * For the initial condition or if the unrestricted port number
872                  * has wrapped round, select a random port between 5000 and 1<<15
873                  * to start at.
874                  */
875                 if (c->restricted) {
876                         if (*pp >= 1024)
877                                 *pp = 600;
878                 } else
879                         while (*pp < 5000)
880                                 *pp = nrand(1 << 15);
881
882                 found = 0;
883                 for (x = 0; x < p->nc; x++) {
884                         if (p->conv[x] == NULL)
885                                 break;
886                         if (p->conv[x]->lport == *pp) {
887                                 found = 1;
888                                 break;
889                         }
890                 }
891                 if (!found)
892                         break;
893         }
894         c->lport = (*pp)++;
895         qunlock(&p->qlock);
896 }
897
898 /*
899  *  set a local address and port from a string of the form
900  *      [address!]port[!r]
901  */
902 static char *setladdrport(struct conv *c, char *str, int announcing)
903 {
904         char *p;
905         char *rv;
906         uint16_t lport;
907         uint8_t addr[IPaddrlen];
908
909         rv = NULL;
910
911         /*
912          *  ignore restricted part if it exists.  it's
913          *  meaningless on local ports.
914          */
915         p = strchr(str, '!');
916         if (p != NULL) {
917                 *p++ = 0;
918                 if (strcmp(p, "r") == 0)
919                         p = NULL;
920         }
921
922         c->lport = 0;
923         if (p == NULL) {
924                 if (announcing)
925                         ipmove(c->laddr, IPnoaddr);
926                 else
927                         setladdr(c);
928                 p = str;
929         } else {
930                 if (strcmp(str, "*") == 0)
931                         ipmove(c->laddr, IPnoaddr);
932                 else {
933                         parseip(addr, str);
934                         if (ipforme(c->p->f, addr))
935                                 ipmove(c->laddr, addr);
936                         else
937                                 return "not a local IP address";
938                 }
939         }
940
941         /* one process can get all connections */
942         if (announcing && strcmp(p, "*") == 0) {
943                 if (!iseve())
944                         error(Eperm);
945                 return setluniqueport(c, 0);
946         }
947
948         lport = atoi(p);
949         if (lport <= 0)
950                 setlport(c);
951         else
952                 rv = setluniqueport(c, lport);
953         return rv;
954 }
955
956 static char *setraddrport(struct conv *c, char *str)
957 {
958         char *p;
959
960         p = strchr(str, '!');
961         if (p == NULL)
962                 return "malformed address";
963         *p++ = 0;
964         parseip(c->raddr, str);
965         c->rport = atoi(p);
966         p = strchr(p, '!');
967         if (p) {
968                 if (strstr(p, "!r") != NULL)
969                         c->restricted = 1;
970         }
971         return NULL;
972 }
973
974 /*
975  *  called by protocol connect routine to set addresses
976  */
977 char *Fsstdconnect(struct conv *c, char *argv[], int argc)
978 {
979         char *p;
980
981         switch (argc) {
982                 default:
983                         return "bad args to connect";
984                 case 2:
985                         p = setraddrport(c, argv[1]);
986                         if (p != NULL)
987                                 return p;
988                         setladdr(c);
989                         setlport(c);
990                         break;
991                 case 3:
992                         p = setraddrport(c, argv[1]);
993                         if (p != NULL)
994                                 return p;
995                         p = setladdrport(c, argv[2], 0);
996                         if (p != NULL)
997                                 return p;
998         }
999
1000         if ((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
1001                  memcmp(c->laddr, v4prefix, IPv4off) == 0)
1002                 || ipcmp(c->raddr, IPnoaddr) == 0)
1003                 c->ipversion = V4;
1004         else
1005                 c->ipversion = V6;
1006
1007         return NULL;
1008 }
1009
1010 /*
1011  *  initiate connection and sleep till its set up
1012  */
1013 static int connected(void *a)
1014 {
1015         return ((struct conv *)a)->state == Connected;
1016 }
1017
1018 static void connectctlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1019 {
1020         ERRSTACK(1);
1021         char *p;
1022
1023         if (c->state != 0)
1024                 error(Econinuse);
1025         c->state = Connecting;
1026         c->cerr[0] = '\0';
1027         if (x->connect == NULL)
1028                 error("connect not supported");
1029         p = x->connect(c, cb->f, cb->nf);
1030         if (p != NULL)
1031                 error(p);
1032
1033         qunlock(&c->qlock);
1034         if (waserror()) {
1035                 qlock(&c->qlock);
1036                 nexterror();
1037         }
1038         rendez_sleep(&c->cr, connected, c);
1039         qlock(&c->qlock);
1040         poperror();
1041
1042         if (c->cerr[0] != '\0')
1043                 error(c->cerr);
1044 }
1045
1046 /*
1047  *  called by protocol announce routine to set addresses
1048  */
1049 char *Fsstdannounce(struct conv *c, char *argv[], int argc)
1050 {
1051         memset(c->raddr, 0, sizeof(c->raddr));
1052         c->rport = 0;
1053         switch (argc) {
1054                 default:
1055                         return "bad args to announce";
1056                 case 2:
1057                         return setladdrport(c, argv[1], 1);
1058         }
1059 }
1060
1061 /*
1062  *  initiate announcement and sleep till its set up
1063  */
1064 static int announced(void *a)
1065 {
1066         return ((struct conv *)a)->state == Announced;
1067 }
1068
1069 static void announcectlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1070 {
1071         ERRSTACK(1);
1072         char *p;
1073
1074         if (c->state != 0)
1075                 error(Econinuse);
1076         c->state = Announcing;
1077         c->cerr[0] = '\0';
1078         if (x->announce == NULL)
1079                 error("announce not supported");
1080         p = x->announce(c, cb->f, cb->nf);
1081         if (p != NULL)
1082                 error(p);
1083
1084         qunlock(&c->qlock);
1085         if (waserror()) {
1086                 qlock(&c->qlock);
1087                 nexterror();
1088         }
1089         rendez_sleep(&c->cr, announced, c);
1090         qlock(&c->qlock);
1091         poperror();
1092
1093         if (c->cerr[0] != '\0')
1094                 error(c->cerr);
1095 }
1096
1097 /*
1098  *  called by protocol bind routine to set addresses
1099  */
1100 char *Fsstdbind(struct conv *c, char *argv[], int argc)
1101 {
1102         switch (argc) {
1103                 default:
1104                         return "bad args to bind";
1105                 case 2:
1106                         return setladdrport(c, argv[1], 0);
1107         }
1108 }
1109
1110 void Fsconvnonblock(struct conv *cv, bool onoff)
1111 {
1112         qnonblock(cv->wq, onoff);
1113         qnonblock(cv->rq, onoff);
1114         cv->nonblock = onoff;
1115 }
1116
1117 static void bindctlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1118 {
1119         char *p;
1120
1121         if (x->bind == NULL)
1122                 p = Fsstdbind(c, cb->f, cb->nf);
1123         else
1124                 p = x->bind(c, cb->f, cb->nf);
1125         if (p != NULL)
1126                 error(p);
1127 }
1128
1129 static void nonblockctlmsg(struct conv *c, struct cmdbuf *cb)
1130 {
1131         if (cb->nf < 2)
1132                 goto err;
1133         if (!strcmp(cb->f[1], "on"))
1134                 Fsconvnonblock(c, TRUE);
1135         else if (!strcmp(cb->f[1], "off"))
1136                 Fsconvnonblock(c, FALSE);
1137         else
1138                 goto err;
1139         return;
1140 err:
1141         set_errno(EINVAL);
1142         error("nonblock [on|off]");
1143 }
1144
1145 static void tosctlmsg(struct conv *c, struct cmdbuf *cb)
1146 {
1147         if (cb->nf < 2)
1148                 c->tos = 0;
1149         else
1150                 c->tos = atoi(cb->f[1]);
1151 }
1152
1153 static void ttlctlmsg(struct conv *c, struct cmdbuf *cb)
1154 {
1155         if (cb->nf < 2)
1156                 c->ttl = MAXTTL;
1157         else
1158                 c->ttl = atoi(cb->f[1]);
1159 }
1160
1161 static long ipwrite(struct chan *ch, void *v, long n, int64_t off)
1162 {
1163         ERRSTACK(1);
1164         struct conv *c;
1165         struct Proto *x;
1166         char *p;
1167         struct cmdbuf *cb;
1168         uint8_t ia[IPaddrlen], ma[IPaddrlen];
1169         struct Fs *f;
1170         char *a;
1171
1172         a = v;
1173         f = ipfs[ch->dev];
1174
1175         switch (TYPE(ch->qid)) {
1176                 default:
1177                         error(Eperm);
1178                 case Qdata:
1179                         x = f->p[PROTO(ch->qid)];
1180                         c = x->conv[CONV(ch->qid)];
1181                         qwrite(c->wq, a, n);
1182                         break;
1183                 case Qarp:
1184                         return arpwrite(f, a, n);
1185                 case Qiproute:
1186                         return routewrite(f, ch, a, n);
1187                 case Qlog:
1188                         netlogctl(f, a, n);
1189                         return n;
1190                 case Qndb:
1191                         return ndbwrite(f, a, off, n);
1192                 case Qctl:
1193                         x = f->p[PROTO(ch->qid)];
1194                         c = x->conv[CONV(ch->qid)];
1195                         cb = parsecmd(a, n);
1196
1197                         qlock(&c->qlock);
1198                         if (waserror()) {
1199                                 qunlock(&c->qlock);
1200                                 kfree(cb);
1201                                 nexterror();
1202                         }
1203                         if (cb->nf < 1)
1204                                 error("short control request");
1205                         if (strcmp(cb->f[0], "connect") == 0)
1206                                 connectctlmsg(x, c, cb);
1207                         else if (strcmp(cb->f[0], "announce") == 0)
1208                                 announcectlmsg(x, c, cb);
1209                         else if (strcmp(cb->f[0], "bind") == 0)
1210                                 bindctlmsg(x, c, cb);
1211                         else if (strcmp(cb->f[0], "nonblock") == 0)
1212                                 nonblockctlmsg(c, cb);
1213                         else if (strcmp(cb->f[0], "ttl") == 0)
1214                                 ttlctlmsg(c, cb);
1215                         else if (strcmp(cb->f[0], "tos") == 0)
1216                                 tosctlmsg(c, cb);
1217                         else if (strcmp(cb->f[0], "ignoreadvice") == 0)
1218                                 c->ignoreadvice = 1;
1219                         else if (strcmp(cb->f[0], "addmulti") == 0) {
1220                                 if (cb->nf < 2)
1221                                         error("addmulti needs interface address");
1222                                 if (cb->nf == 2) {
1223                                         if (!ipismulticast(c->raddr))
1224                                                 error("addmulti for a non multicast address");
1225                                         parseip(ia, cb->f[1]);
1226                                         ipifcaddmulti(c, c->raddr, ia);
1227                                 } else {
1228                                         parseip(ma, cb->f[2]);
1229                                         if (!ipismulticast(ma))
1230                                                 error("addmulti for a non multicast address");
1231                                         parseip(ia, cb->f[1]);
1232                                         ipifcaddmulti(c, ma, ia);
1233                                 }
1234                         } else if (strcmp(cb->f[0], "remmulti") == 0) {
1235                                 if (cb->nf < 2)
1236                                         error("remmulti needs interface address");
1237                                 if (!ipismulticast(c->raddr))
1238                                         error("remmulti for a non multicast address");
1239                                 parseip(ia, cb->f[1]);
1240                                 ipifcremmulti(c, c->raddr, ia);
1241                         } else if (x->ctl != NULL) {
1242                                 p = x->ctl(c, cb->f, cb->nf);
1243                                 if (p != NULL)
1244                                         error(p);
1245                         } else
1246                                 error("unknown control request");
1247                         qunlock(&c->qlock);
1248                         kfree(cb);
1249                         poperror();
1250         }
1251         return n;
1252 }
1253
1254 static long ipbwrite(struct chan *ch, struct block *bp, uint32_t offset)
1255 {
1256         struct conv *c;
1257         struct Proto *x;
1258         struct Fs *f;
1259         int n;
1260
1261         switch (TYPE(ch->qid)) {
1262                 case Qdata:
1263                         f = ipfs[ch->dev];
1264                         x = f->p[PROTO(ch->qid)];
1265                         c = x->conv[CONV(ch->qid)];
1266                         if (bp->next)
1267                                 bp = concatblock(bp);
1268                         n = BLEN(bp);
1269                         qbwrite(c->wq, bp);
1270                         return n;
1271                 default:
1272                         return devbwrite(ch, bp, offset);
1273         }
1274 }
1275
1276 static void ip_wake_cb(struct queue *q, void *data, int filter)
1277 {
1278         struct conv *conv = (struct conv*)data;
1279         struct fd_tap *tap_i;
1280         /* For these two, we want to ignore events on the opposite end of the
1281          * queues.  For instance, we want to know when the WQ is writable.  Our
1282          * writes will actually make it readable - we don't want to trigger a tap
1283          * for that.  However, qio doesn't know how/why we are using a queue, or
1284          * even who the ends are (hence the callbacks) */
1285         if ((filter & FDTAP_FILT_READABLE) && (q == conv->wq))
1286                 return;
1287         if ((filter & FDTAP_FILT_WRITABLE) && (q == conv->rq))
1288                 return;
1289         /* At this point, we have an event we want to send to our taps (if any).
1290          * The lock protects list integrity and the existence of the tap.
1291          *
1292          * Previously, I thought of using the conv qlock.  That actually breaks, due
1293          * to weird usages of the qlock (someone holds it for a long time, blocking
1294          * the inbound wakeup from etherread4).
1295          *
1296          * I opted for a spinlock for a couple reasons:
1297          * - fire_tap should not block.  ideally it'll be fast too (it's mostly a
1298          * send_event).
1299          * - our callers might not want to block.  A lot of network wakeups will
1300          * come network processes (etherread4) or otherwise unrelated to this
1301          * particular conversation.  I'd rather do something like fire off a KMSG
1302          * than block those.
1303          * - if fire_tap takes a while, holding the lock only slows down other
1304          * events on this *same* conversation, or other tap registration.  not a
1305          * huge deal. */
1306         spin_lock(&conv->tap_lock);
1307         SLIST_FOREACH(tap_i, &conv->data_taps, link)
1308                 fire_tap(tap_i, filter);
1309         spin_unlock(&conv->tap_lock);
1310 }
1311
1312 int iptapfd(struct chan *chan, struct fd_tap *tap, int cmd)
1313 {
1314         struct conv *conv;
1315         struct Proto *x;
1316         struct Fs *f;
1317         int ret;
1318
1319         #define DEVIP_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
1320                                        FDTAP_FILT_HANGUP)
1321         #define DEVIP_LEGAL_LISTEN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
1322
1323         /* That's a lot of pointers to get to the conv! */
1324         f = ipfs[chan->dev];
1325         x = f->p[PROTO(chan->qid)];
1326         conv = x->conv[CONV(chan->qid)];
1327
1328         switch (TYPE(chan->qid)) {
1329                 case Qdata:
1330                         if (tap->filter & ~DEVIP_LEGAL_DATA_TAPS) {
1331                                 set_errno(ENOSYS);
1332                                 set_errstr("Unsupported #I data tap, must be %p",
1333                                            DEVIP_LEGAL_DATA_TAPS);
1334                                 return -1;
1335                         }
1336                         spin_lock(&conv->tap_lock);
1337                         switch (cmd) {
1338                                 case (FDTAP_CMD_ADD):
1339                                         if (SLIST_EMPTY(&conv->data_taps)) {
1340                                                 qio_set_wake_cb(conv->rq, ip_wake_cb, conv);
1341                                                 qio_set_wake_cb(conv->wq, ip_wake_cb, conv);
1342                                         }
1343                                         SLIST_INSERT_HEAD(&conv->data_taps, tap, link);
1344                                         ret = 0;
1345                                         break;
1346                                 case (FDTAP_CMD_REM):
1347                                         SLIST_REMOVE(&conv->data_taps, tap, fd_tap, link);
1348                                         if (SLIST_EMPTY(&conv->data_taps)) {
1349                                                 qio_set_wake_cb(conv->rq, 0, conv);
1350                                                 qio_set_wake_cb(conv->wq, 0, conv);
1351                                         }
1352                                         ret = 0;
1353                                         break;
1354                                 default:
1355                                         set_errno(ENOSYS);
1356                                         set_errstr("Unsupported #I data tap command");
1357                                         ret = -1;
1358                         }
1359                         spin_unlock(&conv->tap_lock);
1360                         return ret;
1361                 case Qlisten:
1362                         if (tap->filter & ~DEVIP_LEGAL_LISTEN_TAPS) {
1363                                 set_errno(ENOSYS);
1364                                 set_errstr("Unsupported #I listen tap, must be %p",
1365                                            DEVIP_LEGAL_LISTEN_TAPS);
1366                                 return -1;
1367                         }
1368                         spin_lock(&conv->tap_lock);
1369                         switch (cmd) {
1370                                 case (FDTAP_CMD_ADD):
1371                                         SLIST_INSERT_HEAD(&conv->listen_taps, tap, link);
1372                                         ret = 0;
1373                                         break;
1374                                 case (FDTAP_CMD_REM):
1375                                         SLIST_REMOVE(&conv->listen_taps, tap, fd_tap, link);
1376                                         ret = 0;
1377                                         break;
1378                                 default:
1379                                         set_errno(ENOSYS);
1380                                         set_errstr("Unsupported #I data tap command");
1381                                         ret = -1;
1382                         }
1383                         spin_unlock(&conv->tap_lock);
1384                         return ret;
1385                 default:
1386                         set_errno(ENOSYS);
1387                         set_errstr("Can't tap #I file type %d", TYPE(chan->qid));
1388                         return -1;
1389         }
1390 }
1391
1392 struct dev ipdevtab __devtab = {
1393         .dc = 'I',
1394         .name = "ip",
1395
1396         .reset = ipreset,
1397         .init = ipinit,
1398         .shutdown = devshutdown,
1399         .attach = ipattach,
1400         .walk = ipwalk,
1401         .stat = ipstat,
1402         .open = ipopen,
1403         .create = devcreate,
1404         .close = ipclose,
1405         .read = ipread,
1406         .bread = ipbread,
1407         .write = ipwrite,
1408         .bwrite = ipbwrite,
1409         .remove = devremove,
1410         .wstat = ipwstat,
1411         .power = devpower,
1412         .chaninfo = ipchaninfo,
1413         .tapfd = iptapfd,
1414 };
1415
1416 int Fsproto(struct Fs *f, struct Proto *p)
1417 {
1418         if (f->np >= Maxproto)
1419                 return -1;
1420
1421         qlock_init(&p->qlock);
1422         p->f = f;
1423
1424         if (p->ipproto > 0) {
1425                 if (f->t2p[p->ipproto] != NULL)
1426                         return -1;
1427                 f->t2p[p->ipproto] = p;
1428         }
1429
1430         p->qid.type = QTDIR;
1431         p->qid.path = QID(f->np, 0, Qprotodir);
1432         p->conv = kzmalloc(sizeof(struct conv *) * (p->nc + 1), 0);
1433         if (p->conv == NULL)
1434                 panic("Fsproto");
1435
1436         p->x = f->np;
1437         p->nextport = 0;
1438         p->nextrport = 600;
1439         f->p[f->np++] = p;
1440
1441         return 0;
1442 }
1443
1444 /*
1445  *  return true if this protocol is
1446  *  built in
1447  */
1448 int Fsbuiltinproto(struct Fs *f, uint8_t proto)
1449 {
1450         return f->t2p[proto] != NULL;
1451 }
1452
1453 /*
1454  *  called with protocol locked
1455  */
1456 struct conv *Fsprotoclone(struct Proto *p, char *user)
1457 {
1458         struct conv *c, **pp, **ep;
1459
1460 retry:
1461         c = NULL;
1462         ep = &p->conv[p->nc];
1463         for (pp = p->conv; pp < ep; pp++) {
1464                 c = *pp;
1465                 if (c == NULL) {
1466                         c = kzmalloc(sizeof(struct conv), 0);
1467                         if (c == NULL)
1468                                 error(Enomem);
1469                         qlock_init(&c->qlock);
1470                         qlock_init(&c->listenq);
1471                         rendez_init(&c->cr);
1472                         rendez_init(&c->listenr);
1473                         SLIST_INIT(&c->data_taps);      /* already = 0; set to be futureproof */
1474                         SLIST_INIT(&c->listen_taps);
1475                         spinlock_init(&c->tap_lock);
1476                         qlock(&c->qlock);
1477                         c->p = p;
1478                         c->x = pp - p->conv;
1479                         if (p->ptclsize != 0) {
1480                                 c->ptcl = kzmalloc(p->ptclsize, 0);
1481                                 if (c->ptcl == NULL) {
1482                                         kfree(c);
1483                                         error(Enomem);
1484                                 }
1485                         }
1486                         *pp = c;
1487                         p->ac++;
1488                         c->eq = qopen(1024, Qmsg, 0, 0);
1489                         (*p->create) (c);
1490                         assert(c->rq && c->wq);
1491                         break;
1492                 }
1493                 if (canqlock(&c->qlock)) {
1494                         /*
1495                          *  make sure both processes and protocol
1496                          *  are done with this Conv
1497                          */
1498                         if (c->inuse == 0 && (p->inuse == NULL || (*p->inuse) (c) == 0))
1499                                 break;
1500
1501                         qunlock(&c->qlock);
1502                 }
1503         }
1504         if (pp >= ep) {
1505                 if (p->gc != NULL && (*p->gc) (p))
1506                         goto retry;
1507                 return NULL;
1508         }
1509
1510         c->inuse = 1;
1511         kstrdup(&c->owner, user);
1512         c->perm = 0660;
1513         c->state = Idle;
1514         ipmove(c->laddr, IPnoaddr);
1515         ipmove(c->raddr, IPnoaddr);
1516         c->r = NULL;
1517         c->rgen = 0;
1518         c->lport = 0;
1519         c->rport = 0;
1520         c->restricted = 0;
1521         c->ttl = MAXTTL;
1522         c->tos = DFLTTOS;
1523         c->nonblock = FALSE;
1524         qreopen(c->rq);
1525         qreopen(c->wq);
1526         qreopen(c->eq);
1527
1528         qunlock(&c->qlock);
1529         return c;
1530 }
1531
1532 int Fsconnected(struct conv *c, char *msg)
1533 {
1534         if (msg != NULL && *msg != '\0')
1535                 strncpy(c->cerr, msg, sizeof(c->cerr));
1536
1537         switch (c->state) {
1538
1539                 case Announcing:
1540                         c->state = Announced;
1541                         break;
1542
1543                 case Connecting:
1544                         c->state = Connected;
1545                         break;
1546         }
1547
1548         rendez_wakeup(&c->cr);
1549         return 0;
1550 }
1551
1552 struct Proto *Fsrcvpcol(struct Fs *f, uint8_t proto)
1553 {
1554         if (f->ipmux)
1555                 return f->ipmux;
1556         else
1557                 return f->t2p[proto];
1558 }
1559
1560 struct Proto *Fsrcvpcolx(struct Fs *f, uint8_t proto)
1561 {
1562         return f->t2p[proto];
1563 }
1564
1565 static void fire_listener_taps(struct conv *conv)
1566 {
1567         struct fd_tap *tap_i;
1568         if (SLIST_EMPTY(&conv->listen_taps))
1569                 return;
1570         spin_lock(&conv->tap_lock);
1571         SLIST_FOREACH(tap_i, &conv->listen_taps, link)
1572                 fire_tap(tap_i, FDTAP_FILT_READABLE);
1573         spin_unlock(&conv->tap_lock);
1574 }
1575
1576 /*
1577  *  called with protocol locked
1578  */
1579 struct conv *Fsnewcall(struct conv *c, uint8_t * raddr, uint16_t rport,
1580                                            uint8_t * laddr, uint16_t lport, uint8_t version)
1581 {
1582         struct conv *nc;
1583         struct conv **l;
1584         int i;
1585
1586         qlock(&c->qlock);
1587         i = 0;
1588         for (l = &c->incall; *l; l = &(*l)->next)
1589                 i++;
1590         if (i >= Maxincall) {
1591                 qunlock(&c->qlock);
1592                 return NULL;
1593         }
1594
1595         /* find a free conversation */
1596         nc = Fsprotoclone(c->p, network);
1597         if (nc == NULL) {
1598                 qunlock(&c->qlock);
1599                 return NULL;
1600         }
1601         ipmove(nc->raddr, raddr);
1602         nc->rport = rport;
1603         ipmove(nc->laddr, laddr);
1604         nc->lport = lport;
1605         nc->next = NULL;
1606         *l = nc;
1607         nc->state = Connected;
1608         nc->ipversion = version;
1609
1610         qunlock(&c->qlock);
1611
1612         rendez_wakeup(&c->listenr);
1613         fire_listener_taps(c);
1614
1615         return nc;
1616 }
1617
1618 static long ndbwrite(struct Fs *f, char *a, uint32_t off, int n)
1619 {
1620         if (off > strlen(f->ndb))
1621                 error(Eio);
1622         if (off + n >= sizeof(f->ndb) - 1)
1623                 error(Eio);
1624         memmove(f->ndb + off, a, n);
1625         f->ndb[off + n] = 0;
1626         f->ndbvers++;
1627         f->ndbmtime = seconds();
1628         return n;
1629 }
1630
1631 uint32_t scalednconv(void)
1632 {
1633         //if(conf.npage*BY2PG >= 128*MB)
1634         return Nchans * 4;
1635         //  return Nchans;
1636 }