plan 9 kernel history: overview | file list | diff list

1999/1211/port/devsdp.c (diff list | history)

1999/1116/sys/src/9/port/devsdp.c:41,481999/1211/sys/src/9/port/devsdp.c:41,48 (short | long | prev | next)
1999/0824    
 
1999/0907    
	Maxconv= 256,		// power of 2 
	Nfs= 4,				// number of file systems 
1999/1001    
	MaxRetries=	8, 
1999/0909    
	KeepAlive = 60,		// keep alive in seconds 
1999/1211    
	MaxRetries=	4, 
	KeepAlive = 10,		// keep alive in seconds 
1999/1015    
	SecretLength= 32,	// a secret per direction 
1999/1001    
	SeqMax = (1<<24), 
	SeqWindow = 32, 
1999/1116/sys/src/9/port/devsdp.c:104,1091999/1211/sys/src/9/port/devsdp.c:104,110
1999/0901    
 
1999/0907    
// conv states 
1999/0902    
enum { 
1999/1211    
	CFree, 
1999/0906    
	CInit, 
1999/0909    
	CDial, 
	CAccept, 
1999/1116/sys/src/9/port/devsdp.c:115,1261999/1211/sys/src/9/port/devsdp.c:116,130
1999/0902    
 
1999/0901    
struct Conv { 
	QLock; 
1999/0824    
	int	id; 
1999/0906    
	int ref;	// number of times the conv is opened 
1999/0824    
	Sdp	*sdp; 
1999/1211    
	int	id; 
1999/0901    
 
1999/1211    
	int ref;	// holds conv up 
 
1999/0902    
	int state; 
1999/0906    
	int dataopen; 
1999/1211    
 
	int dataopen;	// ref count of opens on Qdata 
	int controlopen;	// ref count of opens on Qcontrol 
1999/0910    
	int reader;		// reader proc has been started 
1999/0901    
 
1999/0929    
	Stats	lstats; 
1999/1116/sys/src/9/port/devsdp.c:137,1431999/1211/sys/src/9/port/devsdp.c:141,147
1999/0910    
	QLock readlk;		// protects readproc 
1999/0907    
	Proc *readproc; 
1999/0910    
 
1999/0902    
	Chan *chan;	// packet channel 
1999/1211    
	Chan *chan;		// packet channel 
1999/0910    
	char *channame; 
1999/0902    
 
1999/0907    
	char owner[NAMELEN];		/* protections */ 
1999/1116/sys/src/9/port/devsdp.c:268,3021999/1211/sys/src/9/port/devsdp.c:272,308
1999/0824    
static Dirtab	*dirtab[MaxQ]; 
static Sdp sdptab[Nfs]; 
1999/0908    
static char *convstatename[] = { 
	[CInit] "Init", 
1999/0909    
	[CDial] "Dial", 
	[CAccept] "Accept", 
1999/0908    
	[COpen] "Open", 
1999/1211    
	[CFree]		"Free", 
	[CInit]		"Init", 
	[CDial]		"Dial", 
	[CAccept]	"Accept", 
	[COpen]		"Open", 
1999/0910    
	[CLocalClose] "LocalClose", 
	[CRemoteClose] "RemoteClose", 
1999/0908    
	[CClosed] "Closed", 
1999/1211    
	[CClosed]	"Closed", 
1999/0908    
}; 
1999/0824    
 
static int sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp); 
1999/0901    
static Conv *sdpclone(Sdp *sdp); 
1999/0906    
static void convsetstate(Conv *c, int state); 
static void sdpackproc(void *a); 
1999/0907    
static void onewaycleanup(OneWay *ow); 
static int readready(void *a); 
static int controlread(); 
1999/1211    
static void convsetstate(Conv *c, int state); 
static Block *readcontrol(Conv *c, int n); 
static void writecontrol(Conv *c, void *p, int n, int wait); 
static Block *readdata(Conv *c, int n); 
static long writedata(Conv *c, Block *b); 
static void convderef(Conv *c); 
1999/0907    
static Block *conviput(Conv *c, Block *b, int control); 
1999/1015    
static void conviconnect(Conv *c, int op, Block *b); 
static void convicontrol(Conv *c, int op, Block *b); 
1999/1016    
static Block *convicomp(Conv *c, int op, ulong, Block *b); 
1999/0929    
static void writecontrol(Conv *c, void *p, int n, int wait); 
1999/0907    
static Block *readcontrol(Conv *c, int n); 
static Block *readdata(Conv *c, int n); 
1999/0915    
static long writedata(Conv *c, Block *b); 
1999/1015    
static void convoput(Conv *c, int type, int subtype, Block *b); 
static void convoconnect(Conv *c, int op, ulong dialid, ulong acceptid); 
1999/0910    
static void convreader(void *a); 
1999/0914    
static void convopenchan(Conv *c, char *path); 
1999/0929    
static void convstats(Conv *c, int local, char *buf, int n); 
1999/1211    
static void convreader(void *a); 
1999/0824    
 
1999/1022    
static void setalg(Conv *c, char *name, Algorithm *tab, Algorithm **); 
1999/1015    
static void setsecret(OneWay *cc, char *secret); 
1999/1116/sys/src/9/port/devsdp.c:412,4171999/1211/sys/src/9/port/devsdp.c:418,424
1999/0824    
	devstat(c, db, nil, 0, sdpgen); 
} 
 
1999/1211    
 
1999/0824    
static Chan* 
1999/0901    
sdpopen(Chan* ch, int omode) 
1999/0824    
{ 
1999/1116/sys/src/9/port/devsdp.c:450,4551999/1211/sys/src/9/port/devsdp.c:457,463
1999/0929    
	case Qstats: 
	case Qrstats: 
1999/0902    
		c = sdp->conv[CONV(ch->qid)]; 
1999/1211    
print("open %d:%d: ref=%d\n", c->id, TYPE(ch->qid), c->ref); 
1999/0902    
		qlock(c); 
		if(waserror()) { 
			qunlock(c); 
1999/1116/sys/src/9/port/devsdp.c:458,4691999/1211/sys/src/9/port/devsdp.c:466,481
1999/0902    
		if((perm & (c->perm>>6)) != perm) 
1999/0907    
		if(strcmp(up->user, c->owner) != 0 || (perm & c->perm) != perm) 
1999/0902    
				error(Eperm); 
1999/1211    
 
1999/0902    
		c->ref++; 
1999/0910    
		if(TYPE(ch->qid) == Qdata) { 
			if(c->dataopen == 0) 
1999/1211    
			c->dataopen++; 
			// kill reader if Qdata is opened for the first time 
			if(c->dataopen == 1) 
1999/0910    
			if(c->readproc != nil) 
				postnote(c->readproc, 1, "interrupt", 0); 
1999/0907    
			c->dataopen++; 
1999/1211    
		} else if(TYPE(ch->qid) == Qcontrol) {	 
			c->controlopen++; 
1999/0910    
		} 
1999/0902    
		qunlock(c); 
		poperror(); 
1999/1116/sys/src/9/port/devsdp.c:481,5121999/1211/sys/src/9/port/devsdp.c:493,537
1999/0902    
	Sdp *sdp  = sdptab + ch->dev; 
1999/0907    
	Conv *c; 
1999/0824    
 
1999/1211    
	if(!(ch->flag & COPEN)) 
		return; 
1999/0902    
	switch(TYPE(ch->qid)) { 
1999/0824    
	case Qlog: 
1999/0902    
		if(ch->flag & COPEN) 
1999/0824    
			logclose(sdp); 
1999/1211    
		logclose(sdp); 
1999/0824    
		break; 
1999/0907    
	case Qdata: 
	case Qctl: 
	case Qstatus: 
	case Qcontrol: 
		if(!(ch->flag & COPEN)) 
			break; 
1999/1211    
	case Qstats: 
	case Qrstats: 
1999/0907    
		c = sdp->conv[CONV(ch->qid)]; 
		qlock(c); 
		if(waserror()) { 
			qunlock(c); 
			nexterror(); 
1999/1211    
		convderef(c); 
		qunlock(c); 
		break; 
 
	case Qdata: 
		c = sdp->conv[CONV(ch->qid)]; 
		qlock(c); 
		c->dataopen--; 
		convderef(c); 
		if(c->dataopen == 0) 
		if(c->reader == 0) 
		if(c->chan != nil) 
		if(!waserror()) { 
			kproc("convreader", convreader, c); 
			c->reader = 1; 
			c->ref++; 
			poperror(); 
1999/0907    
		} 
		c->ref--; 
		if(TYPE(ch->qid) == Qdata) { 
			c->dataopen--; 
1999/0915    
			if(c->dataopen == 0 && c->reader == 0) { 
				kproc("convreader", convreader, c); 
				c->reader = 1; 
			} 
1999/0907    
		} 
		if(c->ref == 0) { 
1999/1211    
		qunlock(c); 
		break; 
 
	case Qcontrol: 
		c = sdp->conv[CONV(ch->qid)]; 
		qlock(c); 
		c->controlopen--; 
		convderef(c); 
		if(c->controlopen == 0 && c->ref != 0) { 
1999/0907    
			switch(c->state) { 
			default: 
				convsetstate(c, CClosed); 
1999/1116/sys/src/9/port/devsdp.c:515,5221999/1211/sys/src/9/port/devsdp.c:540,545
1999/0907    
			case COpen: 
1999/0910    
				convsetstate(c, CLocalClose); 
1999/0907    
				break; 
1999/0910    
			case CLocalClose: 
				panic("local close already happened"); 
1999/0907    
			} 
		} 
		qunlock(c); 
1999/1116/sys/src/9/port/devsdp.c:771,7781999/1211/sys/src/9/port/devsdp.c:794,802
1999/0901    
			sdp->nconv++; 
			break; 
		} 
		if(canqlock(c)){ 
1999/1116    
			if(c->state == CClosed && c->reader == 0 && c->ref == 0) 
1999/1211    
		if(c->ref == 0 && canqlock(c)){ 
print("%d: state=%d reader=%d ref=%d\n", c->id, c->state, c->reader, c->ref); 
			if(c->ref == 0) 
1999/0901    
				break; 
			qunlock(c); 
		} 
1999/1116/sys/src/9/port/devsdp.c:783,7891999/1211/sys/src/9/port/devsdp.c:807,815
1999/0902    
	if(pp >= ep) 
1999/0901    
		return nil; 
 
1999/0902    
	c->ref++; 
1999/1211    
	assert(c->state == CFree); 
	// set ref to 2 - 1 ref for open - 1 ref for channel state 
	c->ref = 2; 
1999/0906    
	c->state = CInit; 
1999/1001    
	c->in.window = ~0; 
1999/0907    
	strncpy(c->owner, up->user, sizeof(c->owner)); 
1999/1116/sys/src/9/port/devsdp.c:819,8241999/1211/sys/src/9/port/devsdp.c:845,851
1999/0906    
	return 1; 
} 
 
1999/1211    
// assumes c is locked 
1999/0902    
static void 
1999/0906    
convtimer(Conv *c, ulong sec) 
1999/0902    
{ 
1999/1116/sys/src/9/port/devsdp.c:826,8371999/1211/sys/src/9/port/devsdp.c:853,862
1999/0914    
 
1999/1001    
	if(c->timeout > sec) 
1999/0906    
		return; 
1999/0902    
	qlock(c); 
1999/0906    
	if(waserror()) { 
1999/0902    
		qunlock(c); 
1999/0906    
		nexterror(); 
1999/0902    
	} 
1999/1211    
 
1999/0906    
	switch(c->state) { 
1999/1211    
	case CInit: 
		break; 
1999/0909    
	case CDial: 
1999/0914    
		if(convretry(c, 1)) 
1999/1015    
			convoconnect(c, ConOpenRequest, c->dialid, 0); 
1999/1116/sys/src/9/port/devsdp.c:873,8831999/1211/sys/src/9/port/devsdp.c:898,905
1999/0906    
		break; 
1999/0914    
	case CRemoteClose: 
	case CClosed: 
1999/1001    
		c->timeout = ~0; 
1999/0914    
		break; 
1999/0906    
	} 
1999/0914    
	poperror(); 
1999/0906    
	qunlock(c); 
} 
1999/0902    
 
 
1999/1116/sys/src/9/port/devsdp.c:895,9041999/1211/sys/src/9/port/devsdp.c:917,932
1999/0906    
		qlock(sdp); 
		for(i=0; i<sdp->nconv; i++) { 
			c = sdp->conv[i]; 
			if(!waserror()) { 
1999/1211    
			if(c->ref == 0) 
				continue; 
			qunlock(sdp); 
			qlock(c); 
			if(c->ref > 0 && !waserror()) { 
1999/0906    
				convtimer(c, sec); 
				poperror(); 
			} 
1999/1211    
			qunlock(c); 
			qlock(sdp); 
1999/0906    
		} 
		qunlock(sdp); 
1999/0902    
	} 
1999/1116/sys/src/9/port/devsdp.c:949,9541999/1211/sys/src/9/port/devsdp.c:977,983
1999/0909    
		break; 
1999/0906    
	case COpen: 
1999/0909    
		assert(c->state == CDial || c->state == CAccept); 
1999/1211    
		c->lastrecv = TK2SEC(m->ticks); 
1999/0909    
		if(c->state == CDial) { 
			convretryinit(c); 
1999/1015    
			convoconnect(c, ConOpenAckAck, c->dialid, c->acceptid); 
1999/1116/sys/src/9/port/devsdp.c:971,9771999/1211/sys/src/9/port/devsdp.c:1000,1006
1999/0906    
		break; 
1999/0910    
	case CRemoteClose: 
1999/0914    
		wakeup(&c->in.controlready); 
1999/1027    
// convoconnect(c, ConReset, c->dialid, c->acceptid); 
1999/1211    
		wakeup(&c->out.controlready); 
1999/0910    
		break; 
1999/0906    
	case CClosed: 
1999/0914    
		wakeup(&c->in.controlready); 
1999/1116/sys/src/9/port/devsdp.c:978,10141999/1211/sys/src/9/port/devsdp.c:1007,1058
1999/0915    
		wakeup(&c->out.controlready); 
1999/0907    
		if(c->readproc) 
			postnote(c->readproc, 1, "interrupt", 0); 
1999/0915    
print("CClosed -> ref = %d\n", c->ref); 
1999/0907    
		if(c->chan) {	 
			cclose(c->chan); 
			c->chan = nil; 
		} 
1999/0915    
		if(c->ref) 
			break; 
1999/0910    
		if(c->channame) { 
			free(c->channame); 
			c->channame = nil; 
		} 
1999/1022    
		c->cipher = nil; 
		c->auth = nil; 
		c->comp = nil; 
1999/1001    
	strcpy(c->owner, "network"); 
1999/0907    
		c->perm = 0660; 
		c->dialid = 0; 
		c->acceptid = 0; 
1999/1001    
		c->timeout = ~0; 
1999/0907    
		c->retries = 0; 
		c->drop = 0; 
		onewaycleanup(&c->in); 
		onewaycleanup(&c->out); 
1999/1001    
		memset(&c->lstats, 0, sizeof(Stats)); 
		memset(&c->rstats, 0, sizeof(Stats)); 
1999/1211    
		if(c->state != CClosed) 
			convderef(c); 
1999/0906    
		break; 
	} 
	c->state = state; 
} 
 
1999/1211    
 
//assumes c is locked 
1999/0906    
static void 
1999/1211    
convderef(Conv *c) 
{ 
	c->ref--; 
print("convderef: %d: ref == %d\n", c->id, c->ref); 
	if(c->ref > 0) 
		return; 
	assert(c->ref == 0); 
	assert(c->dataopen == 0); 
	assert(c->controlopen == 0); 
//print("convderef: %d: ref == 0!\n", c->id); 
	c->state = CFree; 
	if(c->chan) {	 
		cclose(c->chan); 
		c->chan = nil; 
	} 
	if(c->channame) { 
		free(c->channame); 
		c->channame = nil; 
	} 
	c->cipher = nil; 
	c->auth = nil; 
	c->comp = nil; 
	strcpy(c->owner, "network"); 
	c->perm = 0660; 
	c->dialid = 0; 
	c->acceptid = 0; 
	c->timeout = 0; 
	c->retries = 0; 
	c->drop = 0; 
	onewaycleanup(&c->in); 
	onewaycleanup(&c->out); 
	memset(&c->lstats, 0, sizeof(Stats)); 
	memset(&c->rstats, 0, sizeof(Stats)); 
} 
 
static void 
1999/0907    
onewaycleanup(OneWay *ow) 
1999/0906    
{ 
1999/0907    
	if(ow->controlpkt) 
1999/1116/sys/src/9/port/devsdp.c:1040,10461999/1211/sys/src/9/port/devsdp.c:1084,1095
1999/0914    
		nexterror(); 
	} 
	kproc("convreader", convreader, c); 
1999/1211    
 
	assert(c->reader == 0 && c->ref > 0); 
	// after kproc in case it fails 
1999/0914    
	c->reader = 1; 
1999/1211    
	c->ref++; 
 
1999/0914    
	poperror(); 
} 
1999/0907    
 
1999/1116/sys/src/9/port/devsdp.c:1215,12211999/1211/sys/src/9/port/devsdp.c:1264,1270
1999/1001    
	if(seqdiff > 0) { 
		while(seqdiff > 0 && c->in.window != 0) { 
			if((c->in.window & (1<<(SeqWindow-1))) == 0) { 
print("missing packet: %ld\n", seq - seqdiff); 
1999/1211    
//print("missing packet: %ld\n", seq - seqdiff); 
1999/1001    
				c->lstats.inMissing++; 
			} 
			c->in.window <<= 1; 
1999/1116/sys/src/9/port/devsdp.c:1222,12281999/1211/sys/src/9/port/devsdp.c:1271,1277
1999/1001    
			seqdiff--; 
		} 
		if(seqdiff > 0) { 
print("missing packets: %ld-%ld\n", seq - SeqWindow - seqdiff+1, seq-SeqWindow); 
1999/1211    
//print("missing packets: %ld-%ld\n", seq - SeqWindow - seqdiff+1, seq-SeqWindow); 
1999/1001    
			c->lstats.inMissing += seqdiff; 
		} 
		c->in.seq = seq; 
1999/1116/sys/src/9/port/devsdp.c:1520,15291999/1211/sys/src/9/port/devsdp.c:1569,1575
1999/0930    
	Block *b; 
1999/0907    
 
1999/0929    
	c->lstats.outPackets++; 
1999/0906    
	if(c->chan == nil) { 
print("chan = nil\n"); 
		error("no channel attached"); 
	} 
1999/1211    
	assert(c->chan != nil); 
1999/1015    
	b = allocb(9); 
	b->wp[0] = (TConnect << 4) | op; 
	hnputl(b->wp+1, dialid); 
1999/1116/sys/src/9/port/devsdp.c:1530,15361999/1211/sys/src/9/port/devsdp.c:1576,1585
1999/1015    
	hnputl(b->wp+5, acceptid); 
	b->wp += 9; 
1999/0906    
 
1999/0930    
	convwriteblock(c, b); 
1999/1211    
	if(!waserror()) { 
		convwriteblock(c, b); 
		poperror(); 
	} 
1999/0907    
} 
 
1999/0910    
static Block * 
1999/1116/sys/src/9/port/devsdp.c:1537,15491999/1211/sys/src/9/port/devsdp.c:1586,1596
1999/0910    
convreadblock(Conv *c, int n) 
{ 
	Block *b; 
	Chan *ch = nil; 
1999/1211    
	Chan *ch; 
1999/0910    
 
	qlock(&c->readlk); 
	if(waserror()) { 
		c->readproc = nil; 
		if(ch) 
			cclose(ch); 
		qunlock(&c->readlk); 
		nexterror(); 
	} 
1999/1116/sys/src/9/port/devsdp.c:1554,15651999/1211/sys/src/9/port/devsdp.c:1601,1611
1999/0910    
	} 
	c->readproc = up; 
	ch = c->chan; 
	incref(ch); 
1999/1211    
	assert(c->ref > 0); 
1999/0910    
	qunlock(c); 
 
	b = devtab[ch->type]->bread(ch, n, 0); 
	c->readproc = nil; 
	cclose(ch); 
	poperror(); 
	qunlock(&c->readlk); 
 
1999/1116/sys/src/9/port/devsdp.c:1770,17791999/1211/sys/src/9/port/devsdp.c:1816,1822
1999/0910    
		if(b == nil) { 
1999/0915    
print("up->error = %s\n", up->error); 
			if(strcmp(up->error, Eintr) != 0) { 
				if(!waserror()) { 
					convsetstate(c, CClosed); 
					poperror(); 
				} 
1999/1211    
				convsetstate(c, CClosed); 
1999/0915    
				break; 
			} 
		} else if(!waserror()) { 
1999/1116/sys/src/9/port/devsdp.c:1783,17881999/1211/sys/src/9/port/devsdp.c:1826,1832
1999/0910    
	} 
1999/0914    
print("convreader exiting\n"); 
1999/0910    
	c->reader = 0; 
1999/1211    
	convderef(c); 
1999/0910    
	qunlock(c); 
	pexit("hangup", 1); 
1999/0906    
} 
1999/1116/sys/src/9/port/devsdp.c:2025,20311999/1211/sys/src/9/port/devsdp.c:2069,2075
1999/1022    
				cr->ovalid = 0; 
		} 
	} else if(d > 0) { 
print("missing packet: %uld %ld\n", seq, d); 
1999/1211    
//print("missing packet: %uld %ld\n", seq, d); 
1999/1022    
		// this link is hosed  
		if(d > RC4forward) 
			return 0; 
1999/1116/sys/src/9/port/devsdp.c:2039,20451999/1211/sys/src/9/port/devsdp.c:2083,2089
1999/1022    
		rc4(&cr->current, p, n); 
		cr->cseq = seq+n; 
	} else { 
print("reordered packet: %uld %ld\n", seq, d); 
1999/1211    
//print("reordered packet: %uld %ld\n", seq, d); 
1999/1022    
		dd = seq - cr->oseq; 
		if(!cr->ovalid || -d > RC4back || dd < 0) 
			return 0; 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)