Esempio n. 1
0
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;
		}
	}
}
Esempio n. 2
0
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);
}