~kris/9p

9hist

86113cfb3cde412682f01ec46cdf1a088cf43264 — David du Colombier 34 years ago 8df99f1
Plan 9 from Bell Labs 1991-10-25
4 files changed, 96 insertions(+), 45 deletions(-)

M port/devip.c
M port/devproc.c
M port/ipdat.h
M port/stil.c
M port/devip.c => port/devip.c +8 -3
@@ 365,7 365,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
		if(m != 2)
			error(Ebadarg);

		switch(m = getfields(field[1], ctlarg, 5, '!')) {
		switch(getfields(field[1], ctlarg, 5, '!')) {
		default:
			error(Ebadarg);
		case 2:


@@ 676,10 676,15 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base)
	Ipconv *etab, *new;

	qlock(&s->listenq);

	if(waserror()) {
		qunlock(&s->listenq);
		nexterror();
	}
print("listener on %lux R 0x%lux\n", s, &s->listenr);
	for(;;) {
		sleep(&s->listenr, iphavecon, s);

		poperror();
print("listen awoke\n");
		new = base;
 		for(etab = &base[conf.ip]; new < etab; new++) {
			if(new->newcon) {

M port/devproc.c => port/devproc.c +6 -0
@@ 313,6 313,12 @@ procread(Chan *c, void *va, long n, ulong offset)
			memmove(a, (char*)offset, n);
			return n;
		}
		if(offset>=KZERO && offset<KZERO+conf.base1+conf.npage1*BY2PG){
			if(offset+n > KZERO+conf.base1+conf.npage1*BY2PG)
				n = KZERO+conf.base1+conf.npage1*BY2PG - offset;
			memmove(a, (char*)offset, n);
			return n;
		}
		return 0;
		break;


M port/ipdat.h => port/ipdat.h +1 -1
@@ 102,7 102,6 @@ struct Ilcb				/* Control block */
	Block	*unacked;
	Block	*unackedtail;
	Block	*outoforder;
	Block	*outofordertail;
	ulong	sent;
	ulong	recvd;
	ulong	lastack;


@@ 508,6 507,7 @@ void 	tcp_timeout(void *);
void	tcp_acktimer(void *);
Ipconv  *ipclonecon(Chan *);
void	iplisten(Chan *, Ipconv *, Ipconv *);
void	iloutoforder(Ipconv*, Ilhdr*, Block*);

#define	fmtaddr(xx)	(xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff
#define	MIN(a, b)	((a) < (b) ? (a) : (b))

M port/stil.c => port/stil.c +81 -41
@@ 135,7 135,6 @@ ilackq(Ilcb *ic, Block *bp)
	/* Enqueue a copy on the unacked queue in case this one gets lost */
	np = copyb(bp, blen(bp));

	lock(ic);
	if(ic->unacked) {
		ic->unackedtail->next = np;
		ic->unackedtail = np;


@@ 145,7 144,6 @@ ilackq(Ilcb *ic, Block *bp)
		ic->unackedtail = np;
	}
	np->next = 0;
	unlock(ic);
}

void


@@ 154,23 152,13 @@ ilackto(Ilcb *ic, ulong ackto)
	Ilhdr *h;
	Block *bp;

	for(;;) {
		lock(ic);
		if(ic->unacked) {
			h = (Ilhdr *)ic->unacked->rptr;
			if(ackto < nhgetl(h->ilack)) {
				unlock(ic);
				break;	
			}
			bp = ic->unacked;
			ic->unacked = bp->next;
			unlock(ic);
			freeb(bp);
		}
		else {
			unlock(ic);
			break;
		}
	while(ic->unacked) {
		h = (Ilhdr *)ic->unacked->rptr;
		if(ackto < nhgetl(h->ilack))
			break;	
		bp = ic->unacked;
		ic->unacked = bp->next;
		freeb(bp);
	}
}



@@ 215,29 203,28 @@ print("got packet from %d.%d.%d.%d %d %d\n", fmtaddr(dst), sp, dp);
			
	}

	if(s->curlog > s->backlog) {
print("Backlog\n");
	if(s->curlog > s->backlog)
		goto reset;
	}

	for(s = ipc; s < etab; s++) {
		if(s->ilctl.state == Illistening && s->pdst == 0) {
		if(s->ilctl.state == Illistening && s->pdst == 0 && s->dst == 0) {
			/* Do the listener stuff */
			new = ipincoming(ipc);
			if(new == 0) 
			if(new == 0)
				goto reset;
			if(ih->type != Ilsync)
			if(ih->iltype != Ilsync)
				goto reset;

			new->newcon = 1;
			new->ipinterface = s->ipinterface;
			s->ipinterface->ref++;
			s->curlog++;
			new->psrc = sp;
			new->pdst = dp;
			new->ilctl.state = Ilsyncee;
			new->dst = nhgetl(ih->src);
			ilprocess(new, ih, bp);

			s->ipinterface->ref++;
			s->curlog++;
			wakeup(&s->listenr);
			return;
		}


@@ 252,22 239,32 @@ void
ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
{
	Block *nb;
	ulong id, ack;

	/* Active transition machine - this tracks connection state */
	switch(s->ilctl.state) {
	case Ilsyncee:	
		switch(h->iltype) {
		case Ilsync:
			ilsendctl(s, 0, Ilsync, 0);
			break;
		case Ilack:
			s->ilctl.state = Ilestablished;
			break;
		}
		break;
	case Ilclosed:
	case Ilclosing:
	case Illistening:
		error(Ehungup);
		goto hungup;
	}

	/* Passive actions based on packet type */
	switch(h->iltype) {
	case Ilsync:
		if(s->ilctl.state == Ilsync)
			s->ilctl.state = Ilestablished;
		freeb(bp);
		break;
	case Ilack:
		ilackto(&s->ilctl, nhgetl(h->ilack));
		ack = nhgetl(h->ilack);
		if(s->ilctl.recvd+1 == ack)
			s->ilctl.recvd = ack;
		ilackto(&s->ilctl, ack);
		freeb(bp);
		break;
	case Ilquerey:


@@ 277,20 274,63 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
	case Ildataquery:
	case Ildata:
		ilackto(&s->ilctl, nhgetl(h->ilack));
		bp->rptr += IL_EHSIZE+IL_HDRSIZE;
/* Check and trim to length */
		PUTNEXT(s->readq, bp);
		switch(s->ilctl.state) {
		default:
			iloutoforder(s, h, bp);
			break;
		case Ilestablished:
			id = nhgetl(h->ilid);
			if(id < s->ilctl.recvd)
				freeb(bp);
			else if(id > s->ilctl.recvd)
				iloutoforder(s, h, bp);
			else {
				bp->rptr += IL_EHSIZE+IL_HDRSIZE;
				PUTNEXT(s->readq, bp);
			}
		}
		break;
	case Ilreset:
		s->ilctl.state = Ilclosed;
		nb = allocb(0);
		nb->type = M_HANGUP;
		PUTNEXT(s->readq, nb);
	hungup:
		if(s->readq) {
			nb = allocb(0);
			nb->type = M_HANGUP;
			PUTNEXT(s->readq, nb);
		}
		freeb(bp);
	}
}

void
iloutoforder(Ipconv *s, Ilhdr *h, Block *bp)
{
	Block *f, **l;
	Ilcb *ic;
	ulong id;
	uchar *lid;

	ic = &s->ilctl;

	if(ic->outoforder == 0) {
		ic->outoforder = bp;
		bp->next = 0;
		return;
	}

	id = nhgetl(h->id);
	l = &ic->outoforder;
	for(f = *l; f; f = f->next) {
		lid = ((Ilhdr*)(bp->rptr))->ilid;
		if(id < nhgetl(lid))
			break;
		l = &f->next;
	}
	bp->next = *l;
	*l = bp;
}

void
ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack)
{
	Ilhdr *ih;