~kris/9p

9hist

f82c55e630f2f8f6212e77643f4b7f2669a00387 — David du Colombier 27 years ago bc923c1
Plan 9 from Bell Labs 1999-09-09
7 files changed, 128 insertions(+), 91 deletions(-)

M ip/ip.h
M ip/ipifc.c
M ip/udp.c
M pc/devlml.c
M pc/devlml.h
M pc/vgamach64xx.c
M port/devsdp.c
M ip/ip.h => ip/ip.h +1 -0
@@ 333,6 333,7 @@ enum
	Runi=		(1<<3),		/* a unicast self address */
	Rbcast=		(1<<4),		/* a broadcast self address */
	Rmulti=		(1<<5),		/* a multicast self address */
	Rproxy=		(1<<6),		/* this route should be proxied */
};

struct Routewalk

M ip/ipifc.c => ip/ipifc.c +7 -5
@@ 345,10 345,15 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)

	f = ifc->conv->p->f;

	type = Rifc;
	memset(ip, 0, IPaddrlen);
	memset(mask, 0, IPaddrlen);
	memset(rem, 0, IPaddrlen);
	switch(argc){
	case 6:
		if(strcmp(argv[5], "proxy") == 0)
			type |= Rproxy;
		/* fall through */
	case 5:
		mtu = strtoul(argv[4], 0, 0);
		if(mtu >= ifc->m->minmtu && mtu <= ifc->m->maxmtu)


@@ 396,7 401,6 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)
	*l = lifc;

	/* add a route for the local network */
	type = Rifc;
	if(ipcmp(mask, IPallbits) == 0){
		/* point to point networks are a hack */
		if(ipcmp(ip, rem) == 0)


@@ 410,7 414,7 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)

	addselfcache(f, ifc, lifc, ip, Runi);

	if(type & Rptpt){
	if((type & (Rptpt|Rproxy)) == (Rptpt|Rproxy)){
		ipifcregisterproxy(f, ifc, rem);
		goto out;
	}


@@ 1088,9 1092,7 @@ ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip)
	r = v6lookup(f, ip);
	if(r == nil)
		return 0;
	if((r->type & Rifc) == 0)
		return 0;
	if((r->type & Rptpt) == 0)
	if((r->type & (Rifc|Rptpt|Rproxy)) != (Rifc|Rptpt|Rproxy))
		return 0;

	/* see if this is on the right interface */

M ip/udp.c => ip/udp.c +25 -16
@@ 234,7 234,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
{
	int len, olen, ottl;
	Udphdr *uh;
	Conv *c, **p;
	Conv *c, **p, *gc;
	Udpcb *ucb;
	uchar raddr[IPaddrlen], laddr[IPaddrlen];
	ushort rport, lport;


@@ 272,8 272,12 @@ udpiput(Proto *udp, uchar *ia, Block *bp)

	qlock(udp);

	/* Look for a conversation structure for this port */
	c = nil;
	/*
	 *  Look for a conversation structure for this port.  One
	 *  with headers off wins over one with headers on, i.e.,
	 *  specific wins over generic.
	 */
	gc = c = nil;
	for(p = udp->conv; *p; p++) {
		c = *p;
		if(c->inuse == 0)


@@ 282,8 286,10 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
			ucb = (Udpcb*)c->ptcl;

			/* with headers turned on, descriminate only on local port */
			if(ucb->headers)
				break;
			if(ucb->headers && gc == nil){
				gc = c;
				continue;
			}

			/* otherwise discriminate on lport, rport, and raddr */
			if(c->rport == 0 || c->rport == rport)


@@ 292,17 298,20 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
				break;
		}
	}

	if(*p == nil) {
		upriv->ustats.udpNoPorts++;
		qunlock(udp);
		netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
			laddr, lport);
		uh->Unused = ottl;
		hnputs(uh->udpplen, olen);
		icmpnoconv(f, bp);
		freeblist(bp);
		return;
	if(*p == nil){
		if(gc != nil)
			c = gc;
		else {
			upriv->ustats.udpNoPorts++;
			qunlock(udp);
			netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
				laddr, lport);
			uh->Unused = ottl;
			hnputs(uh->udpplen, olen);
			icmpnoconv(f, bp);
			freeblist(bp);
			return;
		}
	}

	ucb = (Udpcb*)c->ptcl;

M pc/devlml.c => pc/devlml.c +1 -1
@@ 351,7 351,7 @@ lmlintr(Ureg *, void *) {
		}
		thetime = todget(nil);
		jpgheader[fno].sec  = (ulong)(thetime / 1000000000LL);
		jpgheader[fno].usec = (ulong)(thetime % 1000000000LL) / 1000;
		jpgheader[fno].nsec = (ulong)(thetime % 1000000000LL);
		jpgheader[fno].frameSize =
			(codeData->statCom[fno] & 0x00ffffff) >> 1;
		jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24;

M pc/devlml.h => pc/devlml.h +1 -1
@@ 71,7 71,7 @@ struct FrameHeader {	// Don't modify this struct, used by h/w
	char nm[4];
	ushort frameNo;
	ulong sec;
	ulong usec;
	ulong nsec;
	ulong frameSize;
	ulong frameSeqNo;
};

M pc/vgamach64xx.c => pc/vgamach64xx.c +1 -0
@@ 25,6 25,7 @@ static ushort mach64xxdid[] = {
	('G'<<8)|'Q',
	('G'<<8)|'T',
	('G'<<8)|'U',
	('G'<<8)|'Z',
	('V'<<8)|'T',
	('V'<<8)|'U',
	0,

M port/devsdp.c => port/devsdp.c +92 -68
@@ 36,7 36,8 @@ enum

	Maxconv= 256,		// power of 2
	Nfs= 4,				// number of file systems
	Maxretries=	4,
	MaxRetries=	8,
	KeepAlive = 60,		// keep alive in seconds
	KeyLength= 32,
};



@@ 70,7 71,8 @@ struct OneWay
// conv states
enum {
	CInit,
	COpening,
	CDial,
	CAccept,
	COpen,
	CClosing,
	CClosed,


@@ 127,11 129,11 @@ enum {
};

enum {
	ConOpen,
	ConOpenRequest,
	ConOpenAck,
	ConOpenNack,
	ConClose,
	ConCloseAck,
	ConReset,
};

struct ConnectPkt


@@ 181,7 183,8 @@ static Dirtab	*dirtab[MaxQ];
static Sdp sdptab[Nfs];
static char *convstatename[] = {
	[CInit] "Init",
	[COpening] "Opening",
	[CDial] "Dial",
	[CAccept] "Accept",
	[COpen] "Open",
	[CClosing] "Closing",
	[CClosed] "Closed",


@@ 325,7 328,6 @@ sdpopen(Chan* ch, int omode)
		if(strcmp(up->user, c->owner) != 0 || (perm & c->perm) != perm)
				error(Eperm);
		c->ref++;
print(c->ref = %d\n", c->ref);
		if(TYPE(ch->qid) == Qdata)
			c->dataopen++;
		qunlock(c);


@@ 373,6 375,7 @@ print("close c->ref = %d\n", c->ref);
			default:
				convsetstate(c, CClosed);
				break;
			case CAccept:
			case COpen:
				convsetstate(c, CClosing);
				break;


@@ 391,7 394,6 @@ sdpread(Chan *ch, void *a, long n, vlong off)
{
	char buf[256];
	Sdp *sdp = sdptab + ch->dev;
	char *s;
	Conv *c;
	Block *b;



@@ 408,23 410,7 @@ sdpread(Chan *ch, void *a, long n, vlong off)
	case Qstatus:
		c = sdp->conv[CONV(ch->qid)];
		qlock(c);
		switch(c->state) {
		default:
			panic("unknown state");
		case CClosed:
			s = "closed";
			break;
		case COpening:
			s = "opening";
			break;
		case COpen:
			s = "open";
			break;
		case CClosing:
			s = "closing";
			break;
		}
		n = readstr(off, a, n, s);
		n = readstr(off, a, n, convstatename[c->state]);
		qunlock(c);
		return n;
	case Qctl:


@@ 498,11 484,11 @@ print("cmd = %s\n", arg0);
			if(cb->nf != 2)
				error("usage: accect id");
			c->dialid = atoi(cb->f[1]);
			convsetstate(c, COpen);
			convsetstate(c, CAccept);
		} else if(strcmp(arg0, "dial") == 0) {
			if(cb->nf != 1)
				error("usage: dial");
			convsetstate(c, COpening);
			convsetstate(c, CDial);
		} else if(strcmp(arg0, "drop") == 0) {
			if(cb->nf != 2)
				error("usage: drop permil");


@@ 620,16 606,25 @@ sdpclone(Sdp *sdp)
}

// assume c is locked
static void
convretryinit(Conv *c)
{
	c->retries = 0;
	// +2 to avoid rounding effects.
	c->timeout = TK2SEC(m->ticks) + 2;
};

// assume c is locked
static int
convretry(Conv *c)
{
	c->retries++;
	if(c->retries > Maxretries) {
	if(c->retries > MaxRetries) {
print("convretry: giving up\n");
		convsetstate(c, CClosed);
		return 0;
	}
	c->timeout = TK2SEC(m->ticks) + (1<<c->retries);
	c->timeout = TK2SEC(m->ticks) + (c->retries+1);
	return 1;
}



@@ 643,17 638,20 @@ convtimer(Conv *c, ulong sec)
		qunlock(c);
		nexterror();
	}
print("convtimer: %s\n", convstatename[c->state]);
	switch(c->state) {
	case COpening:
print("COpening timeout\n");
	case CDial:
		if(convretry(c))
			convoput2(c, ConOpenRequest, c->dialid, 0);
		break;
	case CAccept:
		if(convretry(c))
			convoput2(c, ConOpen, c->dialid, 0);
			convoput2(c, ConOpenAck, c->dialid, c->acceptid);
		break;
	case COpen:
		// check for control packet
		// check for control packet and keepalive
		break;
	case CClosing:
print("CClosing timeout\n");
		if(convretry(c))
			convoput2(c, ConClose, c->dialid, c->acceptid);
		break;


@@ 716,31 714,30 @@ print("convsetstate %s -> %s\n", convstatename[c->state], convstatename[state]);
	switch(state) {
	default:
		panic("setstate: bad state: %d", state);
	case COpening:
		if(c->state != CInit)
			error("convsetstate: illegal transition");
	case CDial:
		assert(c->state == CInit);
		c->dialid = (rand()<<16) + rand();
		c->timeout = TK2SEC(m->ticks) + 2;
		c->retries = 0;
		convoput2(c, ConOpen, c->dialid, 0);
		convretryinit(c);
		convoput2(c, ConOpenRequest, c->dialid, 0);
		break;
	case CAccept:
		assert(c->state == CInit);
		c->acceptid = (rand()<<16) + rand();
		convretryinit(c);
		convoput2(c, ConOpenAck, c->dialid, c->acceptid);
		break;
	case COpen:
		switch(c->state) {
		default:
			error("convsetstate: illegal transition");
		case CInit:
			c->acceptid = (rand()<<16) + rand();
		assert(c->state == CDial || c->state == CAccept);
		if(c->state == CDial) {
			convretryinit(c);
			convoput2(c, ConOpenAck, c->dialid, c->acceptid);
			break;
		case COpening:
			break;
		}
		// setup initial key and auth method
		break;
	case CClosing:
		assert(c->state == COpen);
		convretryinit(c);
		convoput2(c, ConClose, c->dialid, c->acceptid);
		c->timeout = TK2SEC(m->ticks) + 2;
		c->retries = 0;
		break;
	case CClosed:
		if(c->readproc)


@@ 900,32 897,59 @@ conviput2(Conv *c, Block *b)

print("conviput2: %d %uld %uld\n", con->op, dialid, acceptid);
	switch(con->op) {
	case ConOpen:
		if(c->state != COpen || dialid != c->dialid || acceptid != c->acceptid)
			convoput2(c, ConOpenNack, dialid, acceptid);
		else
			convoput2(c, ConOpenAck, dialid, acceptid);
		break;
	case ConOpenAck:
		if(c->state != COpening || dialid != c->dialid)
	case ConOpenRequest:
		switch(c->state) {
		default:
			convoput2(c, ConReset, dialid, acceptid);
			break;
		case CInit:
			c->dialid = dialid;
			convsetstate(c, CAccept);
			break;
		c->acceptid = acceptid;
		convsetstate(c, COpen);
		case CAccept:
		case COpen:
			if(dialid != c->dialid || acceptid != c->acceptid)
				convoput2(c, ConReset, dialid, acceptid);
			break;
		}
		break;
	case ConOpenNack:
		if(c->state != COpening || dialid != c->dialid)
	case ConOpenAck:
		switch(c->state) {
		case CDial:
			if(dialid != c->dialid) {
				convoput2(c, ConReset, dialid, acceptid);
				break;
			}
			c->acceptid = acceptid;
			convsetstate(c, COpen);
			break;
		convsetstate(c, CClosed);
		case CAccept:
			if(dialid != c->dialid || acceptid != c->acceptid) {
				convoput2(c, ConReset, dialid, acceptid);
				break;
			}
			convsetstate(c, COpen);
		}
		break;
	case ConClose:
		if(dialid != c->dialid || acceptid != c->acceptid)
		convoput2(c, ConCloseAck, dialid, acceptid);
		// fall though
	case ConReset:
		switch(c->state) {
		case CDial:
			if(dialid == c->dialid)
				convsetstate(c, CClosed);
			break;
		convsetstate(c, CClosed);
		break;
	case ConCloseAck:
		if(c->state != CClosing || dialid != c->dialid || acceptid != c->acceptid)
		case CAccept:
		case COpen:
		case CClosing:
			if(dialid == c->dialid && acceptid == c->acceptid)
				convsetstate(c, CClosed);
			break;
		convsetstate(c, CClosed);
		}
	case ConCloseAck:
		if(c->state == CClosing && dialid == c->dialid && acceptid == c->acceptid)
			convsetstate(c, CClosed);
		break;
	}
}