Have #I show Qlisten FDs in chaninfo
[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 Qlisten:
615                         proto = f->p[PROTO(ch->qid)];
616                         conv = proto->conv[CONV(ch->qid)];
617                         snprintf(ret, ret_l, "Qlisten, proto %s, conv idx %d", proto->name,
618                                          conv->x);
619                         break;
620                 case Qlog:
621                         ret = "Qlog";
622                         break;
623                 case Qndb:
624                         ret = "Qndb";
625                         break;
626                 case Qctl:
627                         proto = f->p[PROTO(ch->qid)];
628                         conv = proto->conv[CONV(ch->qid)];
629                         snprintf(ret, ret_l, "Qctl, proto %s, conv idx %d", proto->name,
630                                          conv->x);
631                         break;
632         }
633         return ret;
634 }
635
636 static void closeconv(struct conv *cv)
637 {
638         struct conv *nc;
639         struct Ipmulti *mp;
640
641         qlock(&cv->qlock);
642
643         if (--cv->inuse > 0) {
644                 qunlock(&cv->qlock);
645                 return;
646         }
647
648         /* close all incoming calls since no listen will ever happen */
649         for (nc = cv->incall; nc; nc = cv->incall) {
650                 cv->incall = nc->next;
651                 closeconv(nc);
652         }
653         cv->incall = NULL;
654
655         kstrdup(&cv->owner, network);
656         cv->perm = 0660;
657
658         while ((mp = cv->multi) != NULL)
659                 ipifcremmulti(cv, mp->ma, mp->ia);
660
661         cv->r = NULL;
662         cv->rgen = 0;
663         cv->p->close(cv);
664         cv->state = Idle;
665         qunlock(&cv->qlock);
666 }
667
668 static void ipclose(struct chan *c)
669 {
670         struct Fs *f;
671
672         f = ipfs[c->dev];
673         switch (TYPE(c->qid)) {
674                 default:
675                         break;
676                 case Qlog:
677                         if (c->flag & COPEN)
678                                 netlogclose(f);
679                         break;
680                 case Qiprouter:
681                         if (c->flag & COPEN)
682                                 iprouterclose(f);
683                         break;
684                 case Qdata:
685                 case Qctl:
686                 case Qerr:
687                         if (c->flag & COPEN)
688                                 closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
689                         break;
690                 case Qsnoop:
691                         if (c->flag & COPEN)
692                                 atomic_dec(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
693                         break;
694         }
695         kfree(((struct IPaux *)c->aux)->owner);
696         kfree(c->aux);
697 }
698
699 enum {
700         Statelen = 32 * 1024,
701 };
702
703 static long ipread(struct chan *ch, void *a, long n, int64_t off)
704 {
705         struct conv *c;
706         struct Proto *x;
707         char *buf, *p;
708         long rv;
709         struct Fs *f;
710         uint32_t offset = off;
711         size_t sofar;
712
713         f = ipfs[ch->dev];
714
715         p = a;
716         switch (TYPE(ch->qid)) {
717                 default:
718                         error(Eperm);
719                 case Qtopdir:
720                 case Qprotodir:
721                 case Qconvdir:
722                         return devdirread(ch, a, n, 0, 0, ipgen);
723                 case Qarp:
724                         return arpread(f->arp, a, offset, n);
725                 case Qbootp:
726                         return bootpread(a, offset, n);
727                 case Qndb:
728                         return readstr(offset, a, n, f->ndb);
729                 case Qiproute:
730                         return routeread(f, a, offset, n);
731                 case Qiprouter:
732                         return iprouterread(f, a, n);
733                 case Qipselftab:
734                         return ipselftabread(f, a, offset, n);
735                 case Qlog:
736                         return netlogread(f, a, offset, n);
737                 case Qctl:
738                         snprintf(get_cur_genbuf(), GENBUF_SZ, "%lu", CONV(ch->qid));
739                         return readstr(offset, p, n, get_cur_genbuf());
740                 case Qremote:
741                         buf = kzmalloc(Statelen, 0);
742                         x = f->p[PROTO(ch->qid)];
743                         c = x->conv[CONV(ch->qid)];
744                         if (x->remote == NULL) {
745                                 snprintf(buf, Statelen, "%I!%d\n", c->raddr, c->rport);
746                         } else {
747                                 (*x->remote) (c, buf, Statelen - 2);
748                         }
749                         rv = readstr(offset, p, n, buf);
750                         kfree(buf);
751                         return rv;
752                 case Qlocal:
753                         buf = kzmalloc(Statelen, 0);
754                         x = f->p[PROTO(ch->qid)];
755                         c = x->conv[CONV(ch->qid)];
756                         if (x->local == NULL) {
757                                 snprintf(buf, Statelen, "%I!%d\n", c->laddr, c->lport);
758                         } else {
759                                 (*x->local) (c, buf, Statelen - 2);
760                         }
761                         rv = readstr(offset, p, n, buf);
762                         kfree(buf);
763                         return rv;
764                 case Qstatus:
765                         /* this all is a bit screwed up since the size of some state's
766                          * buffers will change from one invocation to another.  a reader
767                          * will come in and read the entire buffer.  then it will come again
768                          * and read from the next offset, expecting EOF.  if the buffer
769                          * changed sizes, it'll reprint the end of the buffer slightly. */
770                         buf = kzmalloc(Statelen, 0);
771                         x = f->p[PROTO(ch->qid)];
772                         c = x->conv[CONV(ch->qid)];
773                         sofar = (*x->state) (c, buf, Statelen - 2);
774                         sofar += snprintf(buf + sofar, Statelen - 2 - sofar, "nonblock %s\n",
775                                           c->nonblock ? "on" : "off");
776                         rv = readstr(offset, p, n, buf);
777                         kfree(buf);
778                         return rv;
779                 case Qdata:
780                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
781                         return qread(c->rq, a, n);
782                 case Qerr:
783                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
784                         return qread(c->eq, a, n);
785                 case Qsnoop:
786                         c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
787                         return qread(c->sq, a, n);
788                 case Qstats:
789                         x = f->p[PROTO(ch->qid)];
790                         if (x->stats == NULL)
791                                 error("stats not implemented");
792                         buf = kzmalloc(Statelen, 0);
793                         (*x->stats) (x, buf, Statelen);
794                         rv = readstr(offset, p, n, buf);
795                         kfree(buf);
796                         return rv;
797         }
798 }
799
800 static struct block *ipbread(struct chan *ch, long n, uint32_t offset)
801 {
802         struct conv *c;
803         struct Proto *x;
804         struct Fs *f;
805
806         switch (TYPE(ch->qid)) {
807                 case Qdata:
808                         f = ipfs[ch->dev];
809                         x = f->p[PROTO(ch->qid)];
810                         c = x->conv[CONV(ch->qid)];
811                         return qbread(c->rq, n);
812                 default:
813                         return devbread(ch, n, offset);
814         }
815 }
816
817 /*
818  *  set local address to be that of the ifc closest to remote address
819  */
820 static void setladdr(struct conv *c)
821 {
822         findlocalip(c->p->f, c->laddr, c->raddr);
823 }
824
825 /*
826  *  set a local port making sure the quad of raddr,rport,laddr,lport is unique
827  */
828 static char *setluniqueport(struct conv *c, int lport)
829 {
830         struct Proto *p;
831         struct conv *xp;
832         int x;
833
834         p = c->p;
835
836         qlock(&p->qlock);
837         for (x = 0; x < p->nc; x++) {
838                 xp = p->conv[x];
839                 if (xp == NULL)
840                         break;
841                 if (xp == c)
842                         continue;
843                 if ((xp->state == Connected || xp->state == Announced)
844                         && xp->lport == lport
845                         && xp->rport == c->rport
846                         && ipcmp(xp->raddr, c->raddr) == 0
847                         && ipcmp(xp->laddr, c->laddr) == 0) {
848                         qunlock(&p->qlock);
849                         return "address in use";
850                 }
851         }
852         c->lport = lport;
853         qunlock(&p->qlock);
854         return NULL;
855 }
856
857 /*
858  *  pick a local port and set it
859  */
860 static void setlport(struct conv *c)
861 {
862         struct Proto *p;
863         uint16_t *pp;
864         int x, found;
865
866         p = c->p;
867         if (c->restricted)
868                 pp = &p->nextrport;
869         else
870                 pp = &p->nextport;
871         qlock(&p->qlock);
872         for (;; (*pp)++) {
873                 /*
874                  * Fsproto initialises p->nextport to 0 and the restricted
875                  * ports (p->nextrport) to 600.
876                  * Restricted ports must lie between 600 and 1024.
877                  * For the initial condition or if the unrestricted port number
878                  * has wrapped round, select a random port between 5000 and 1<<15
879                  * to start at.
880                  */
881                 if (c->restricted) {
882                         if (*pp >= 1024)
883                                 *pp = 600;
884                 } else
885                         while (*pp < 5000)
886                                 *pp = nrand(1 << 15);
887
888                 found = 0;
889                 for (x = 0; x < p->nc; x++) {
890                         if (p->conv[x] == NULL)
891                                 break;
892                         if (p->conv[x]->lport == *pp) {
893                                 found = 1;
894                                 break;
895                         }
896                 }
897                 if (!found)
898                         break;
899         }
900         c->lport = (*pp)++;
901         qunlock(&p->qlock);
902 }
903
904 /*
905  *  set a local address and port from a string of the form
906  *      [address!]port[!r]
907  */
908 static char *setladdrport(struct conv *c, char *str, int announcing)
909 {
910         char *p;
911         char *rv;
912         uint16_t lport;
913         uint8_t addr[IPaddrlen];
914
915         rv = NULL;
916
917         /*
918          *  ignore restricted part if it exists.  it's
919          *  meaningless on local ports.
920          */
921         p = strchr(str, '!');
922         if (p != NULL) {
923                 *p++ = 0;
924                 if (strcmp(p, "r") == 0)
925                         p = NULL;
926         }
927
928         c->lport = 0;
929         if (p == NULL) {
930                 if (announcing)
931                         ipmove(c->laddr, IPnoaddr);
932                 else
933                         setladdr(c);
934                 p = str;
935         } else {
936                 if (strcmp(str, "*") == 0)
937                         ipmove(c->laddr, IPnoaddr);
938                 else {
939                         parseip(addr, str);
940                         if (ipforme(c->p->f, addr))
941                                 ipmove(c->laddr, addr);
942                         else
943                                 return "not a local IP address";
944                 }
945         }
946
947         /* one process can get all connections */
948         if (announcing && strcmp(p, "*") == 0) {
949                 if (!iseve())
950                         error(Eperm);
951                 return setluniqueport(c, 0);
952         }
953
954         lport = atoi(p);
955         if (lport <= 0)
956                 setlport(c);
957         else
958                 rv = setluniqueport(c, lport);
959         return rv;
960 }
961
962 static char *setraddrport(struct conv *c, char *str)
963 {
964         char *p;
965
966         p = strchr(str, '!');
967         if (p == NULL)
968                 return "malformed address";
969         *p++ = 0;
970         parseip(c->raddr, str);
971         c->rport = atoi(p);
972         p = strchr(p, '!');
973         if (p) {
974                 if (strstr(p, "!r") != NULL)
975                         c->restricted = 1;
976         }
977         return NULL;
978 }
979
980 /*
981  *  called by protocol connect routine to set addresses
982  */
983 char *Fsstdconnect(struct conv *c, char *argv[], int argc)
984 {
985         char *p;
986
987         switch (argc) {
988                 default:
989                         return "bad args to connect";
990                 case 2:
991                         p = setraddrport(c, argv[1]);
992                         if (p != NULL)
993                                 return p;
994                         setladdr(c);
995                         setlport(c);
996                         break;
997                 case 3:
998                         p = setraddrport(c, argv[1]);
999                         if (p != NULL)
1000                                 return p;
1001                         p = setladdrport(c, argv[2], 0);
1002                         if (p != NULL)
1003                                 return p;
1004         }
1005
1006         if ((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
1007                  memcmp(c->laddr, v4prefix, IPv4off) == 0)
1008                 || ipcmp(c->raddr, IPnoaddr) == 0)
1009                 c->ipversion = V4;
1010         else
1011                 c->ipversion = V6;
1012
1013         return NULL;
1014 }
1015
1016 /*
1017  *  initiate connection and sleep till its set up
1018  */
1019 static int connected(void *a)
1020 {
1021         return ((struct conv *)a)->state == Connected;
1022 }
1023
1024 static void connectctlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1025 {
1026         ERRSTACK(1);
1027         char *p;
1028
1029         if (c->state != 0)
1030                 error(Econinuse);
1031         c->state = Connecting;
1032         c->cerr[0] = '\0';
1033         if (x->connect == NULL)
1034                 error("connect not supported");
1035         p = x->connect(c, cb->f, cb->nf);
1036         if (p != NULL)
1037                 error(p);
1038
1039         qunlock(&c->qlock);
1040         if (waserror()) {
1041                 qlock(&c->qlock);
1042                 nexterror();
1043         }
1044         rendez_sleep(&c->cr, connected, c);
1045         qlock(&c->qlock);
1046         poperror();
1047
1048         if (c->cerr[0] != '\0')
1049                 error(c->cerr);
1050 }
1051
1052 /*
1053  *  called by protocol announce routine to set addresses
1054  */
1055 char *Fsstdannounce(struct conv *c, char *argv[], int argc)
1056 {
1057         memset(c->raddr, 0, sizeof(c->raddr));
1058         c->rport = 0;
1059         switch (argc) {
1060                 default:
1061                         return "bad args to announce";
1062                 case 2:
1063                         return setladdrport(c, argv[1], 1);
1064         }
1065 }
1066
1067 /*
1068  *  initiate announcement and sleep till its set up
1069  */
1070 static int announced(void *a)
1071 {
1072         return ((struct conv *)a)->state == Announced;
1073 }
1074
1075 static void announcectlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1076 {
1077         ERRSTACK(1);
1078         char *p;
1079
1080         if (c->state != 0)
1081                 error(Econinuse);
1082         c->state = Announcing;
1083         c->cerr[0] = '\0';
1084         if (x->announce == NULL)
1085                 error("announce not supported");
1086         p = x->announce(c, cb->f, cb->nf);
1087         if (p != NULL)
1088                 error(p);
1089
1090         qunlock(&c->qlock);
1091         if (waserror()) {
1092                 qlock(&c->qlock);
1093                 nexterror();
1094         }
1095         rendez_sleep(&c->cr, announced, c);
1096         qlock(&c->qlock);
1097         poperror();
1098
1099         if (c->cerr[0] != '\0')
1100                 error(c->cerr);
1101 }
1102
1103 /*
1104  *  called by protocol bind routine to set addresses
1105  */
1106 char *Fsstdbind(struct conv *c, char *argv[], int argc)
1107 {
1108         switch (argc) {
1109                 default:
1110                         return "bad args to bind";
1111                 case 2:
1112                         return setladdrport(c, argv[1], 0);
1113         }
1114 }
1115
1116 void Fsconvnonblock(struct conv *cv, bool onoff)
1117 {
1118         qnonblock(cv->wq, onoff);
1119         qnonblock(cv->rq, onoff);
1120         cv->nonblock = onoff;
1121 }
1122
1123 static void bindctlmsg(struct Proto *x, struct conv *c, struct cmdbuf *cb)
1124 {
1125         char *p;
1126
1127         if (x->bind == NULL)
1128                 p = Fsstdbind(c, cb->f, cb->nf);
1129         else
1130                 p = x->bind(c, cb->f, cb->nf);
1131         if (p != NULL)
1132                 error(p);
1133 }
1134
1135 static void nonblockctlmsg(struct conv *c, struct cmdbuf *cb)
1136 {
1137         if (cb->nf < 2)
1138                 goto err;
1139         if (!strcmp(cb->f[1], "on"))
1140                 Fsconvnonblock(c, TRUE);
1141         else if (!strcmp(cb->f[1], "off"))
1142                 Fsconvnonblock(c, FALSE);
1143         else
1144                 goto err;
1145         return;
1146 err:
1147         set_errno(EINVAL);
1148         error("nonblock [on|off]");
1149 }
1150
1151 static void tosctlmsg(struct conv *c, struct cmdbuf *cb)
1152 {
1153         if (cb->nf < 2)
1154                 c->tos = 0;
1155         else
1156                 c->tos = atoi(cb->f[1]);
1157 }
1158
1159 static void ttlctlmsg(struct conv *c, struct cmdbuf *cb)
1160 {
1161         if (cb->nf < 2)
1162                 c->ttl = MAXTTL;
1163         else
1164                 c->ttl = atoi(cb->f[1]);
1165 }
1166
1167 static long ipwrite(struct chan *ch, void *v, long n, int64_t off)
1168 {
1169         ERRSTACK(1);
1170         struct conv *c;
1171         struct Proto *x;
1172         char *p;
1173         struct cmdbuf *cb;
1174         uint8_t ia[IPaddrlen], ma[IPaddrlen];
1175         struct Fs *f;
1176         char *a;
1177
1178         a = v;
1179         f = ipfs[ch->dev];
1180
1181         switch (TYPE(ch->qid)) {
1182                 default:
1183                         error(Eperm);
1184                 case Qdata:
1185                         x = f->p[PROTO(ch->qid)];
1186                         c = x->conv[CONV(ch->qid)];
1187                         qwrite(c->wq, a, n);
1188                         break;
1189                 case Qarp:
1190                         return arpwrite(f, a, n);
1191                 case Qiproute:
1192                         return routewrite(f, ch, a, n);
1193                 case Qlog:
1194                         netlogctl(f, a, n);
1195                         return n;
1196                 case Qndb:
1197                         return ndbwrite(f, a, off, n);
1198                 case Qctl:
1199                         x = f->p[PROTO(ch->qid)];
1200                         c = x->conv[CONV(ch->qid)];
1201                         cb = parsecmd(a, n);
1202
1203                         qlock(&c->qlock);
1204                         if (waserror()) {
1205                                 qunlock(&c->qlock);
1206                                 kfree(cb);
1207                                 nexterror();
1208                         }
1209                         if (cb->nf < 1)
1210                                 error("short control request");
1211                         if (strcmp(cb->f[0], "connect") == 0)
1212                                 connectctlmsg(x, c, cb);
1213                         else if (strcmp(cb->f[0], "announce") == 0)
1214                                 announcectlmsg(x, c, cb);
1215                         else if (strcmp(cb->f[0], "bind") == 0)
1216                                 bindctlmsg(x, c, cb);
1217                         else if (strcmp(cb->f[0], "nonblock") == 0)
1218                                 nonblockctlmsg(c, cb);
1219                         else if (strcmp(cb->f[0], "ttl") == 0)
1220                                 ttlctlmsg(c, cb);
1221                         else if (strcmp(cb->f[0], "tos") == 0)
1222                                 tosctlmsg(c, cb);
1223                         else if (strcmp(cb->f[0], "ignoreadvice") == 0)
1224                                 c->ignoreadvice = 1;
1225                         else if (strcmp(cb->f[0], "addmulti") == 0) {
1226                                 if (cb->nf < 2)
1227                                         error("addmulti needs interface address");
1228                                 if (cb->nf == 2) {
1229                                         if (!ipismulticast(c->raddr))
1230                                                 error("addmulti for a non multicast address");
1231                                         parseip(ia, cb->f[1]);
1232                                         ipifcaddmulti(c, c->raddr, ia);
1233                                 } else {
1234                                         parseip(ma, cb->f[2]);
1235                                         if (!ipismulticast(ma))
1236                                                 error("addmulti for a non multicast address");
1237                                         parseip(ia, cb->f[1]);
1238                                         ipifcaddmulti(c, ma, ia);
1239                                 }
1240                         } else if (strcmp(cb->f[0], "remmulti") == 0) {
1241                                 if (cb->nf < 2)
1242                                         error("remmulti needs interface address");
1243                                 if (!ipismulticast(c->raddr))
1244                                         error("remmulti for a non multicast address");
1245                                 parseip(ia, cb->f[1]);
1246                                 ipifcremmulti(c, c->raddr, ia);
1247                         } else if (x->ctl != NULL) {
1248                                 p = x->ctl(c, cb->f, cb->nf);
1249                                 if (p != NULL)
1250                                         error(p);
1251                         } else
1252                                 error("unknown control request");
1253                         qunlock(&c->qlock);
1254                         kfree(cb);
1255                         poperror();
1256         }
1257         return n;
1258 }
1259
1260 static long ipbwrite(struct chan *ch, struct block *bp, uint32_t offset)
1261 {
1262         struct conv *c;
1263         struct Proto *x;
1264         struct Fs *f;
1265         int n;
1266
1267         switch (TYPE(ch->qid)) {
1268                 case Qdata:
1269                         f = ipfs[ch->dev];
1270                         x = f->p[PROTO(ch->qid)];
1271                         c = x->conv[CONV(ch->qid)];
1272                         if (bp->next)
1273                                 bp = concatblock(bp);
1274                         n = BLEN(bp);
1275                         qbwrite(c->wq, bp);
1276                         return n;
1277                 default:
1278                         return devbwrite(ch, bp, offset);
1279         }
1280 }
1281
1282 static void ip_wake_cb(struct queue *q, void *data, int filter)
1283 {
1284         struct conv *conv = (struct conv*)data;
1285         struct fd_tap *tap_i;
1286         /* For these two, we want to ignore events on the opposite end of the
1287          * queues.  For instance, we want to know when the WQ is writable.  Our
1288          * writes will actually make it readable - we don't want to trigger a tap
1289          * for that.  However, qio doesn't know how/why we are using a queue, or
1290          * even who the ends are (hence the callbacks) */
1291         if ((filter & FDTAP_FILT_READABLE) && (q == conv->wq))
1292                 return;
1293         if ((filter & FDTAP_FILT_WRITABLE) && (q == conv->rq))
1294                 return;
1295         /* At this point, we have an event we want to send to our taps (if any).
1296          * The lock protects list integrity and the existence of the tap.
1297          *
1298          * Previously, I thought of using the conv qlock.  That actually breaks, due
1299          * to weird usages of the qlock (someone holds it for a long time, blocking
1300          * the inbound wakeup from etherread4).
1301          *
1302          * I opted for a spinlock for a couple reasons:
1303          * - fire_tap should not block.  ideally it'll be fast too (it's mostly a
1304          * send_event).
1305          * - our callers might not want to block.  A lot of network wakeups will
1306          * come network processes (etherread4) or otherwise unrelated to this
1307          * particular conversation.  I'd rather do something like fire off a KMSG
1308          * than block those.
1309          * - if fire_tap takes a while, holding the lock only slows down other
1310          * events on this *same* conversation, or other tap registration.  not a
1311          * huge deal. */
1312         spin_lock(&conv->tap_lock);
1313         SLIST_FOREACH(tap_i, &conv->data_taps, link)
1314                 fire_tap(tap_i, filter);
1315         spin_unlock(&conv->tap_lock);
1316 }
1317
1318 int iptapfd(struct chan *chan, struct fd_tap *tap, int cmd)
1319 {
1320         struct conv *conv;
1321         struct Proto *x;
1322         struct Fs *f;
1323         int ret;
1324
1325         #define DEVIP_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
1326                                        FDTAP_FILT_HANGUP)
1327         #define DEVIP_LEGAL_LISTEN_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)
1328
1329         /* That's a lot of pointers to get to the conv! */
1330         f = ipfs[chan->dev];
1331         x = f->p[PROTO(chan->qid)];
1332         conv = x->conv[CONV(chan->qid)];
1333
1334         switch (TYPE(chan->qid)) {
1335                 case Qdata:
1336                         if (tap->filter & ~DEVIP_LEGAL_DATA_TAPS) {
1337                                 set_errno(ENOSYS);
1338                                 set_errstr("Unsupported #I data tap, must be %p",
1339                                            DEVIP_LEGAL_DATA_TAPS);
1340                                 return -1;
1341                         }
1342                         spin_lock(&conv->tap_lock);
1343                         switch (cmd) {
1344                                 case (FDTAP_CMD_ADD):
1345                                         if (SLIST_EMPTY(&conv->data_taps)) {
1346                                                 qio_set_wake_cb(conv->rq, ip_wake_cb, conv);
1347                                                 qio_set_wake_cb(conv->wq, ip_wake_cb, conv);
1348                                         }
1349                                         SLIST_INSERT_HEAD(&conv->data_taps, tap, link);
1350                                         ret = 0;
1351                                         break;
1352                                 case (FDTAP_CMD_REM):
1353                                         SLIST_REMOVE(&conv->data_taps, tap, fd_tap, link);
1354                                         if (SLIST_EMPTY(&conv->data_taps)) {
1355                                                 qio_set_wake_cb(conv->rq, 0, conv);
1356                                                 qio_set_wake_cb(conv->wq, 0, conv);
1357                                         }
1358                                         ret = 0;
1359                                         break;
1360                                 default:
1361                                         set_errno(ENOSYS);
1362                                         set_errstr("Unsupported #I data tap command");
1363                                         ret = -1;
1364                         }
1365                         spin_unlock(&conv->tap_lock);
1366                         return ret;
1367                 case Qlisten:
1368                         if (tap->filter & ~DEVIP_LEGAL_LISTEN_TAPS) {
1369                                 set_errno(ENOSYS);
1370                                 set_errstr("Unsupported #I listen tap, must be %p",
1371                                            DEVIP_LEGAL_LISTEN_TAPS);
1372                                 return -1;
1373                         }
1374                         spin_lock(&conv->tap_lock);
1375                         switch (cmd) {
1376                                 case (FDTAP_CMD_ADD):
1377                                         SLIST_INSERT_HEAD(&conv->listen_taps, tap, link);
1378                                         ret = 0;
1379                                         break;
1380                                 case (FDTAP_CMD_REM):
1381                                         SLIST_REMOVE(&conv->listen_taps, tap, fd_tap, link);
1382                                         ret = 0;
1383                                         break;
1384                                 default:
1385                                         set_errno(ENOSYS);
1386                                         set_errstr("Unsupported #I data tap command");
1387                                         ret = -1;
1388                         }
1389                         spin_unlock(&conv->tap_lock);
1390                         return ret;
1391                 default:
1392                         set_errno(ENOSYS);
1393                         set_errstr("Can't tap #I file type %d", TYPE(chan->qid));
1394                         return -1;
1395         }
1396 }
1397
1398 struct dev ipdevtab __devtab = {
1399         .dc = 'I',
1400         .name = "ip",
1401
1402         .reset = ipreset,
1403         .init = ipinit,
1404         .shutdown = devshutdown,
1405         .attach = ipattach,
1406         .walk = ipwalk,
1407         .stat = ipstat,
1408         .open = ipopen,
1409         .create = devcreate,
1410         .close = ipclose,
1411         .read = ipread,
1412         .bread = ipbread,
1413         .write = ipwrite,
1414         .bwrite = ipbwrite,
1415         .remove = devremove,
1416         .wstat = ipwstat,
1417         .power = devpower,
1418         .chaninfo = ipchaninfo,
1419         .tapfd = iptapfd,
1420 };
1421
1422 int Fsproto(struct Fs *f, struct Proto *p)
1423 {
1424         if (f->np >= Maxproto)
1425                 return -1;
1426
1427         qlock_init(&p->qlock);
1428         p->f = f;
1429
1430         if (p->ipproto > 0) {
1431                 if (f->t2p[p->ipproto] != NULL)
1432                         return -1;
1433                 f->t2p[p->ipproto] = p;
1434         }
1435
1436         p->qid.type = QTDIR;
1437         p->qid.path = QID(f->np, 0, Qprotodir);
1438         p->conv = kzmalloc(sizeof(struct conv *) * (p->nc + 1), 0);
1439         if (p->conv == NULL)
1440                 panic("Fsproto");
1441
1442         p->x = f->np;
1443         p->nextport = 0;
1444         p->nextrport = 600;
1445         f->p[f->np++] = p;
1446
1447         return 0;
1448 }
1449
1450 /*
1451  *  return true if this protocol is
1452  *  built in
1453  */
1454 int Fsbuiltinproto(struct Fs *f, uint8_t proto)
1455 {
1456         return f->t2p[proto] != NULL;
1457 }
1458
1459 /*
1460  *  called with protocol locked
1461  */
1462 struct conv *Fsprotoclone(struct Proto *p, char *user)
1463 {
1464         struct conv *c, **pp, **ep;
1465
1466 retry:
1467         c = NULL;
1468         ep = &p->conv[p->nc];
1469         for (pp = p->conv; pp < ep; pp++) {
1470                 c = *pp;
1471                 if (c == NULL) {
1472                         c = kzmalloc(sizeof(struct conv), 0);
1473                         if (c == NULL)
1474                                 error(Enomem);
1475                         qlock_init(&c->qlock);
1476                         qlock_init(&c->listenq);
1477                         rendez_init(&c->cr);
1478                         rendez_init(&c->listenr);
1479                         SLIST_INIT(&c->data_taps);      /* already = 0; set to be futureproof */
1480                         SLIST_INIT(&c->listen_taps);
1481                         spinlock_init(&c->tap_lock);
1482                         qlock(&c->qlock);
1483                         c->p = p;
1484                         c->x = pp - p->conv;
1485                         if (p->ptclsize != 0) {
1486                                 c->ptcl = kzmalloc(p->ptclsize, 0);
1487                                 if (c->ptcl == NULL) {
1488                                         kfree(c);
1489                                         error(Enomem);
1490                                 }
1491                         }
1492                         *pp = c;
1493                         p->ac++;
1494                         c->eq = qopen(1024, Qmsg, 0, 0);
1495                         (*p->create) (c);
1496                         assert(c->rq && c->wq);
1497                         break;
1498                 }
1499                 if (canqlock(&c->qlock)) {
1500                         /*
1501                          *  make sure both processes and protocol
1502                          *  are done with this Conv
1503                          */
1504                         if (c->inuse == 0 && (p->inuse == NULL || (*p->inuse) (c) == 0))
1505                                 break;
1506
1507                         qunlock(&c->qlock);
1508                 }
1509         }
1510         if (pp >= ep) {
1511                 if (p->gc != NULL && (*p->gc) (p))
1512                         goto retry;
1513                 return NULL;
1514         }
1515
1516         c->inuse = 1;
1517         kstrdup(&c->owner, user);
1518         c->perm = 0660;
1519         c->state = Idle;
1520         ipmove(c->laddr, IPnoaddr);
1521         ipmove(c->raddr, IPnoaddr);
1522         c->r = NULL;
1523         c->rgen = 0;
1524         c->lport = 0;
1525         c->rport = 0;
1526         c->restricted = 0;
1527         c->ttl = MAXTTL;
1528         c->tos = DFLTTOS;
1529         c->nonblock = FALSE;
1530         qreopen(c->rq);
1531         qreopen(c->wq);
1532         qreopen(c->eq);
1533
1534         qunlock(&c->qlock);
1535         return c;
1536 }
1537
1538 int Fsconnected(struct conv *c, char *msg)
1539 {
1540         if (msg != NULL && *msg != '\0')
1541                 strncpy(c->cerr, msg, sizeof(c->cerr));
1542
1543         switch (c->state) {
1544
1545                 case Announcing:
1546                         c->state = Announced;
1547                         break;
1548
1549                 case Connecting:
1550                         c->state = Connected;
1551                         break;
1552         }
1553
1554         rendez_wakeup(&c->cr);
1555         return 0;
1556 }
1557
1558 struct Proto *Fsrcvpcol(struct Fs *f, uint8_t proto)
1559 {
1560         if (f->ipmux)
1561                 return f->ipmux;
1562         else
1563                 return f->t2p[proto];
1564 }
1565
1566 struct Proto *Fsrcvpcolx(struct Fs *f, uint8_t proto)
1567 {
1568         return f->t2p[proto];
1569 }
1570
1571 static void fire_listener_taps(struct conv *conv)
1572 {
1573         struct fd_tap *tap_i;
1574         if (SLIST_EMPTY(&conv->listen_taps))
1575                 return;
1576         spin_lock(&conv->tap_lock);
1577         SLIST_FOREACH(tap_i, &conv->listen_taps, link)
1578                 fire_tap(tap_i, FDTAP_FILT_READABLE);
1579         spin_unlock(&conv->tap_lock);
1580 }
1581
1582 /*
1583  *  called with protocol locked
1584  */
1585 struct conv *Fsnewcall(struct conv *c, uint8_t * raddr, uint16_t rport,
1586                                            uint8_t * laddr, uint16_t lport, uint8_t version)
1587 {
1588         struct conv *nc;
1589         struct conv **l;
1590         int i;
1591
1592         qlock(&c->qlock);
1593         i = 0;
1594         for (l = &c->incall; *l; l = &(*l)->next)
1595                 i++;
1596         if (i >= Maxincall) {
1597                 qunlock(&c->qlock);
1598                 return NULL;
1599         }
1600
1601         /* find a free conversation */
1602         nc = Fsprotoclone(c->p, network);
1603         if (nc == NULL) {
1604                 qunlock(&c->qlock);
1605                 return NULL;
1606         }
1607         ipmove(nc->raddr, raddr);
1608         nc->rport = rport;
1609         ipmove(nc->laddr, laddr);
1610         nc->lport = lport;
1611         nc->next = NULL;
1612         *l = nc;
1613         nc->state = Connected;
1614         nc->ipversion = version;
1615
1616         qunlock(&c->qlock);
1617
1618         rendez_wakeup(&c->listenr);
1619         fire_listener_taps(c);
1620
1621         return nc;
1622 }
1623
1624 static long ndbwrite(struct Fs *f, char *a, uint32_t off, int n)
1625 {
1626         if (off > strlen(f->ndb))
1627                 error(Eio);
1628         if (off + n >= sizeof(f->ndb) - 1)
1629                 error(Eio);
1630         memmove(f->ndb + off, a, n);
1631         f->ndb[off + n] = 0;
1632         f->ndbvers++;
1633         f->ndbmtime = seconds();
1634         return n;
1635 }
1636
1637 uint32_t scalednconv(void)
1638 {
1639         //if(conf.npage*BY2PG >= 128*MB)
1640         return Nchans * 4;
1641         //  return Nchans;
1642 }