static void tcpreader(void *a) { Session *s = a; uchar *buf; int buflen = 0x1ffff + 4; buf = nbemalloc(buflen); for (;;) { int n; uchar flags; ushort length; n = readn(s->fd, buf, 4); if (n != 4) { die: free(buf); if (s->state == Connected) (*s->write)(s, nil, -1); deletesession(s); return; } flags = buf[1]; length = nhgets(buf + 2) | ((flags & 1) << 16); n = readn(s->fd, buf + 4, length); if (n != length) goto die; if (flags & 0xfe) { print("nbss: invalid flags field 0x%.2ux\n", flags); goto die; } switch (buf[0]) { case 0: /* session message */ if (s->state != Connected && s->state != Dead) { print("nbss: unexpected session message\n"); goto die; } if (s->state == Connected) { if ((*s->write)(s, buf + 4, length) != 0) { s->state = Dead; goto die; } } break; case 0x81: /* session request */ { uchar *p, *ep; Listen *l; int k; int called_found; uchar error_code; if (s->state == Connected) { print("nbss: unexpected session request\n"); goto die; } p = buf + 4; ep = p + length; k = nbnamedecode(p, p, ep, s->to); if (k == 0) { print("nbss: malformed called name in session request\n"); goto die; } p += k; k = nbnamedecode(p, p, ep, s->from); if (k == 0) { print("nbss: malformed calling name in session request\n"); goto die; } /* p += k; if (p != ep) { print("nbss: extra data at end of session request\n"); goto die; } */ called_found = 0; //print("nbss: called %B calling %B\n", s->to, s->from); qlock(&listens); for (l = listens.head; l; l = l->next) if (nbnameequal(l->to, s->to)) { called_found = 1; if (nbnameequal(l->from, s->from)) break; } if (l == nil) { qunlock(&listens); error_code = called_found ? 0x81 : 0x80; replydie: buf[0] = 0x83; buf[1] = 0; hnputs(buf + 2, 1); buf[4] = error_code; write(s->fd, buf, 5); goto die; } if (!(*l->accept)(l->magic, s, &s->write)) { qunlock(&listens); error_code = 0x83; goto replydie; } buf[0] = 0x82; buf[1] = 0; hnputs(buf + 2, 0); if (write(s->fd, buf, 4) != 4) { qunlock(&listens); goto die; } s->state = Connected; qunlock(&listens); break; } case 0x85: /* keep awake */ break; default: print("nbss: opcode 0x%.2ux unexpected\n", buf[0]); goto die; } } }
static void udplistener(void *) { //print("udplistener - starting\n"); for (;;) { uint8_t msg[Udphdrsize + 576]; int len = read(udp.fd, msg, sizeof(msg)); if (len < 0) break; if (len >= nbudphdrsize) { NbDgram s; // Udphdr *uh; uint8_t *p; int n; // uh = (Udphdr*)msg; p = msg + nbudphdrsize; len -= nbudphdrsize; n = nbdgramconvM2S(&s, p, p + len); if (n) { switch (s.type) { case NbDgramError: print("nbdgramlisten: error: ip %I port %d code 0x%.2x\n", s.srcip, s.srcport, s.error.code); break; case NbDgramDirectUnique: case NbDgramDirectGroup: case NbDgramBroadcast: { int delivered = 0; Listen **lp, *l; if ((s.flags & NbDgramMore) || s.datagram.offset != 0) break; if (!nbnameisany(s.datagram.dstname) && !nbnametablefind(s.datagram.dstname, 0)) { /* - only do this if a broadcast node, and can tell when packets are broadcast... s.flags &= 3; ipmove(s.srcip, nbglobals.myipaddr); s.srcport = NbDgramPort; s.type = NbDgramError; s.error.code = NbDgramErrorDestinationNameNotPresent; nbdgramsendto(uh->raddr, nhgets(uh->rport), &s); */ break; } qlock(&listens); for (lp = &listens.head; (l = *lp) != nil;) { if (nbnameisany(l->to) || nbnameequal(l->to, s.datagram.dstname)) { switch ((*l->deliver)(l->magic, &s)) { case 0: delivered = 1; /* fall through */ case -1: *lp = l->next; free(l); continue; default: delivered = 1; break; } } lp = &l->next; } qunlock(&listens); USED(delivered); } default: ; } } } } print("udplistener - exiting\n"); qlock(&udp); udp.thread = -1; qunlock(&udp); }