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

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

1999/0930/sys/src/9/port/devsdp.c:7,121999/1001/sys/src/9/port/devsdp.c:7,13 (short | long | prev | next)
1999/0824    
#include "../port/error.h" 
 
#include	<libcrypt.h> 
1999/1001    
#include "../port/thwack.h" 
1999/0824    
 
1999/0907    
/* 
 * sdp - secure datagram protocol 
1999/0930/sys/src/9/port/devsdp.c:18,231999/1001/sys/src/9/port/devsdp.c:19,25
1999/0929    
typedef struct Stats Stats; 
1999/0907    
typedef struct ConnectPkt ConnectPkt; 
1999/0929    
typedef struct AckPkt AckPkt; 
1999/1001    
typedef struct Algorithm Algorithm; 
1999/0824    
 
enum 
{ 
1999/0930/sys/src/9/port/devsdp.c:39,471999/1001/sys/src/9/port/devsdp.c:41,51
1999/0824    
 
1999/0907    
	Maxconv= 256,		// power of 2 
	Nfs= 4,				// number of file systems 
1999/0914    
	MaxRetries=	4, 
1999/1001    
	MaxRetries=	8, 
1999/0909    
	KeepAlive = 60,		// keep alive in seconds 
1999/0907    
	KeyLength= 32, 
1999/1001    
	SeqMax = (1<<24), 
	SeqWindow = 32, 
1999/0824    
}; 
 
#define TYPE(x) 	((x).path & 0xff) 
1999/0930/sys/src/9/port/devsdp.c:115,1211999/1001/sys/src/9/port/devsdp.c:119,126
1999/0901    
 
1999/0929    
	Stats	lstats; 
	Stats	rstats; 
                 
1999/1001    
	 
	ulong	lastrecv;	// time last packet was received  
1999/0906    
	ulong	timeout; 
	int		retries; 
 
1999/0930/sys/src/9/port/devsdp.c:133,1381999/1001/sys/src/9/port/devsdp.c:138,146
1999/0901    
	int	perm; 
 
1999/0907    
	uchar	masterkey[KeyLength]; 
1999/1001    
	char *authname; 
	char *ciphername; 
	char *compname; 
1999/0907    
 
1999/0906    
	int drop; 
 
1999/0930/sys/src/9/port/devsdp.c:193,1981999/1001/sys/src/9/port/devsdp.c:201,212
1999/0929    
	uchar	inBadSeq[4]; 
}; 
1999/0907    
 
1999/1001    
struct Algorithm 
{ 
	char 	*name; 
	int		keylen;		// in bytes 
	void	(*init)(Conv*, char* name, int keylen); 
}; 
1999/0929    
 
1999/0824    
static Dirtab sdpdirtab[]={ 
	"log",		{Qlog},		0,	0666, 
1999/0930/sys/src/9/port/devsdp.c:208,2131999/1001/sys/src/9/port/devsdp.c:222,252
1999/0929    
	"rstats",	{Qrstats},	0,	0444, 
1999/0824    
}; 
 
1999/1001    
#ifdef XXX 
static Algorithm cipheralg[] = 
{ 
	"null",			0,	nullcipherinit, 
	"des_56_cbc",	7,	descipherinit, 
	"rc4_128",		16,	rc4cipherinit, 
	nil,			0,	nil, 
}; 
 
static Algorithm authalg[] = 
{ 
	"null",			0,	nullauthinit, 
	"hmac_sha_96",	16,	shaauthinit, 
	"hmac_md5_96",	16,	md5authinit, 
	nil,			0,	nil, 
}; 
 
static Algorithm compalg[] = 
{ 
	"null",			0,	nullcompinit, 
	"thwack",		0,	thwackcompinit, 
	nil,			0,	nil, 
}; 
#endif 
 
1999/0824    
static int m2p[] = { 
	[OREAD]		4, 
	[OWRITE]	2, 
1999/0930/sys/src/9/port/devsdp.c:572,5781999/1001/sys/src/9/port/devsdp.c:611,616
1999/0824    
			error(p); 
		return n; 
1999/0914    
	case Qcontrol: 
print("writecontrol %ld\n", n); 
1999/0929    
		writecontrol(sdp->conv[CONV(ch->qid)], a, n, 0); 
1999/0914    
		return n; 
1999/0915    
	case Qdata: 
1999/0930/sys/src/9/port/devsdp.c:660,6651999/1001/sys/src/9/port/devsdp.c:698,704
1999/0901    
			c = malloc(sizeof(Conv)); 
			if(c == nil) 
				error(Enomem); 
1999/1001    
			memset(c, 0, sizeof(Conv)); 
1999/0901    
			qlock(c); 
			c->sdp = sdp; 
			c->id = pp - sdp->conv; 
1999/0930/sys/src/9/port/devsdp.c:681,6861999/1001/sys/src/9/port/devsdp.c:720,730
1999/0901    
 
1999/0902    
	c->ref++; 
1999/0906    
	c->state = CInit; 
1999/1001    
	c->in.window = ~0; 
	c->in.compstate = malloc(sizeof(Unthwack)); 
	unthwackinit(c->in.compstate); 
	c->out.compstate = malloc(sizeof(Thwack)); 
	thwackinit(c->out.compstate); 
1999/0907    
	strncpy(c->owner, up->user, sizeof(c->owner)); 
1999/0901    
	c->perm = 0660; 
	qunlock(c); 
1999/0930/sys/src/9/port/devsdp.c:719,7251999/1001/sys/src/9/port/devsdp.c:763,769
1999/0902    
{ 
1999/0914    
	Block *b; 
 
1999/0906    
	if(c->timeout == 0 || c->timeout > sec) 
1999/1001    
	if(c->timeout > sec) 
1999/0906    
		return; 
1999/0902    
	qlock(c); 
1999/0906    
	if(waserror()) { 
1999/0930/sys/src/9/port/devsdp.c:740,7491999/1001/sys/src/9/port/devsdp.c:784,810
1999/0914    
		if(b != nil) { 
			if(convretry(c, 1)) 
				convoput(c, TControl, copyblock(b, blocklen(b))); 
		} else { 
			c->timeout = 0; 
1999/1001    
			break; 
1999/0914    
		} 
		// keepalive 
1999/1001    
 
		c->timeout = c->lastrecv + KeepAlive; 
		if(c->timeout > sec) 
			break; 
		// keepalive - randomly spaced between KeepAlive and 2*KeepAlive 
		if(c->timeout + KeepAlive > sec && nrand(c->lastrecv + 2*KeepAlive - sec) > 0) 
			break; 
print("sending keep alive: %ld\n", sec - c->lastrecv); 
		// can not use writecontrol 
		b = allocb(4); 
		c->out.controlseq++; 
		hnputl(b->wp, c->out.controlseq); 
		b->wp += 4; 
		c->out.controlpkt = b; 
		convretryinit(c); 
		if(!waserror()) { 
			convoput(c, TControl, copyblock(b, blocklen(b))); 
			poperror(); 
		} 
1999/0906    
		break; 
1999/0910    
	case CLocalClose: 
1999/0914    
		if(convretry(c, 0)) 
1999/0930/sys/src/9/port/devsdp.c:751,7571999/1001/sys/src/9/port/devsdp.c:812,818
1999/0906    
		break; 
1999/0914    
	case CRemoteClose: 
	case CClosed: 
		c->timeout = 0; 
1999/1001    
		c->timeout = ~0; 
1999/0914    
		break; 
1999/0906    
	} 
1999/0914    
	poperror(); 
1999/0930/sys/src/9/port/devsdp.c:858,8731999/1001/sys/src/9/port/devsdp.c:919,948
1999/0910    
			free(c->channame); 
			c->channame = nil; 
		} 
1999/0907    
		strcpy(c->owner, "network"); 
1999/1001    
		if(c->ciphername) { 
			free(c->ciphername); 
			c->ciphername = nil; 
		} 
		if(c->authname) { 
			free(c->authname); 
			c->authname = nil; 
		} 
			if(c->compname) { 
			free(c->compname); 
			c->compname = nil; 
		} 
	strcpy(c->owner, "network"); 
1999/0907    
		c->perm = 0660; 
		c->dialid = 0; 
		c->acceptid = 0; 
		c->timeout = 0; 
1999/1001    
		c->timeout = ~0; 
1999/0907    
		c->retries = 0; 
		c->drop = 0; 
		memset(c->masterkey, 0, sizeof(c->masterkey)); 
		onewaycleanup(&c->in); 
		onewaycleanup(&c->out); 
1999/1001    
		memset(&c->lstats, 0, sizeof(Stats)); 
		memset(&c->rstats, 0, sizeof(Stats)); 
1999/0906    
		break; 
	} 
	c->state = state; 
1999/0930/sys/src/9/port/devsdp.c:979,9871999/1001/sys/src/9/port/devsdp.c:1054,1065
1999/0907    
static Block * 
conviput(Conv *c, Block *b, int control) 
{ 
	int type; 
	ulong seq, cseq; 
1999/1001    
	int type, n; 
	ulong seq, seqwrap, cseq; 
	long seqdiff; 
1999/0929    
	AckPkt *ack; 
1999/1001    
	ulong mseq, mask; 
	Block *bb; 
1999/0907    
 
1999/0930    
	c->lstats.inPackets++; 
1999/0929    
 
1999/0930/sys/src/9/port/devsdp.c:999,10101999/1001/sys/src/9/port/devsdp.c:1077,1134
1999/0907    
	seq = (b->rp[1]<<16) + (b->rp[2]<<8) + b->rp[3]; 
	b->rp += 4; 
 
	USED(seq); 
1999/1001    
	seqwrap = c->in.seqwrap; 
	seqdiff = seq - c->in.seq; 
	if(seqdiff < -(SeqMax*3/4)) { 
		seqwrap++; 
		seqdiff += SeqMax; 
	} else if(seqdiff > SeqMax*3/4) { 
		seqwrap--; 
		seqdiff -= SeqMax; 
	} 
 
	if(seqdiff <= 0) { 
		if(seqdiff <= -SeqWindow) { 
print("old sequence number: %ld (%ld %ld)\n", seq, c->in.seqwrap, seqdiff); 
			c->lstats.inBadSeq++; 
			freeb(b); 
			return nil; 
		} 
 
		if(c->in.window & (1<<-seqdiff)) { 
print("dup sequence number: %ld (%ld %ld)\n", seq, c->in.seqwrap, seqdiff); 
			c->lstats.inDup++; 
			freeb(b); 
			return nil; 
		} 
 
		c->lstats.inReorder++; 
	} 
 
	// ok the sequence number looks ok 
1999/0930    
if(0) print("coniput seq=%ulx\n", seq); 
1999/0907    
	// auth 
	// decrypt 
 
	// ok the packet is good 
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); 
				c->lstats.inMissing++; 
			} 
			c->in.window <<= 1; 
			seqdiff--; 
		} 
		if(seqdiff > 0) { 
print("missing packets: %ld-%ld\n", seq - SeqWindow - seqdiff+1, seq-SeqWindow); 
			c->lstats.inMissing += seqdiff; 
		} 
		c->in.seq = seq; 
		c->in.seqwrap = seqwrap; 
		c->in.window |= 1; 
	} 
	c->lastrecv = TK2SEC(m->ticks); 
1999/0907    
 
	switch(type) { 
	case TControl: 
1999/0930/sys/src/9/port/devsdp.c:1059,10641999/1001/sys/src/9/port/devsdp.c:1183,1189
1999/0907    
		freeb(b); 
		freeb(c->out.controlpkt); 
1999/0914    
		c->out.controlpkt = nil; 
1999/1001    
		c->timeout = c->lastrecv + KeepAlive; 
1999/0907    
		wakeup(&c->out.controlready); 
		return nil; 
	case TData: 
1999/0930/sys/src/9/port/devsdp.c:1068,10731999/1001/sys/src/9/port/devsdp.c:1193,1227
1999/0907    
		if(control) 
			break; 
		return b; 
1999/1001    
	case TThwackU: 
		c->lstats.inDataPackets++; 
		c->lstats.inCompDataBytes += BLEN(b); 
		mask = b->rp[0]; 
		mseq = (b->rp[1]<<16) | (b->rp[2]<<8) | b->rp[3]; 
		b->rp += 4; 
		thwackack(c->out.compstate, mseq, mask); 
		c->lstats.inDataBytes += BLEN(b); 
		if(control) 
			break; 
		return b; 
	case TThwackC: 
		c->lstats.inDataPackets++; 
		c->lstats.inCompDataBytes += BLEN(b); 
		bb = b; 
		b = allocb(ThwMaxBlock); 
		n = unthwack(c->in.compstate, b->wp, ThwMaxBlock, bb->rp, BLEN(bb), seq); 
		freeb(bb); 
		if(n < 0) 
			break; 
		b->wp += n; 
		mask = b->rp[0]; 
		mseq = (b->rp[1]<<16) | (b->rp[2]<<8) | b->rp[3]; 
		thwackack(c->out.compstate, mseq, mask); 
		b->rp += 4; 
		c->lstats.inDataBytes += BLEN(b); 
		if(control) 
			break; 
		return b; 
1999/0907    
	} 
print("droping packet %d n=%ld\n", type, BLEN(b)); 
	freeb(b); 
1999/0930/sys/src/9/port/devsdp.c:1112,11181999/1001/sys/src/9/port/devsdp.c:1266,1271
1999/0910    
		goto Reset; 
	} 
 
                 
1999/0907    
	switch(con->op) { 
1999/0909    
	case ConOpenRequest: 
		switch(c->state) { 
1999/0930/sys/src/9/port/devsdp.c:1189,11951999/1001/sys/src/9/port/devsdp.c:1342,1348
1999/0930    
convwriteblock(Conv *c, Block *b) 
{ 
	// simulated errors 
	if(c->drop && c->drop > nrand(c->drop)) 
1999/1001    
	if(c->drop && nrand(c->drop) == 0) 
1999/0930    
		return; 
 
	if(waserror()) { 
1999/0930/sys/src/9/port/devsdp.c:1388,13991999/1001/sys/src/9/port/devsdp.c:1541,1549
1999/0914    
	b->wp += 4+n; 
	c->out.controlpkt = b; 
	convretryinit(c); 
print("send %ld size=%ld\n", c->out.controlseq, BLEN(b));	 
	convoput(c, TControl, copyblock(b, blocklen(b))); 
1999/0930    
	if(wait) { 
print("writecontrol wait!\n"); 
1999/1001    
	if(wait) 
1999/0929    
		writewait(c); 
1999/0930    
	} 
1999/0915    
	poperror(); 
1999/0929    
	qunlock(c); 
1999/0915    
	qunlock(&c->out.controllk); 
1999/0930/sys/src/9/port/devsdp.c:1424,14301999/1001/sys/src/9/port/devsdp.c:1574,1582
1999/0915    
static long 
writedata(Conv *c, Block *b) 
{ 
	int n; 
1999/1001    
	int n, nn; 
	ulong seq; 
	Block *bb; 
1999/0915    
 
	qlock(c); 
	if(waserror()) { 
1999/0930/sys/src/9/port/devsdp.c:1440,14471999/1001/sys/src/9/port/devsdp.c:1592,1627
1999/0915    
	n = BLEN(b); 
1999/0930    
	c->lstats.outDataPackets++; 
	c->lstats.outDataBytes += n; 
	c->lstats.outCompDataBytes += n; 
1999/0915    
	convoput(c, TData, b); 
1999/1001    
 
	if(0) { 
		c->lstats.outCompDataBytes += n; 
		convoput(c, TData, b); 
		poperror(); 
		qunlock(c); 
		return n; 
	} 
	b = padblock(b, 4); 
	b->rp[0] = (c->in.window>>1) & 0xff; 
	b->rp[1] = c->in.seq>>16; 
	b->rp[2] = c->in.seq>>8; 
	b->rp[3] = c->in.seq; 
 
	// must generate same value as convoput 
	seq = (c->out.seq + 1) & (SeqMax-1); 
 
	bb = allocb(BLEN(b)); 
	nn = thwack(c->out.compstate, bb->wp, b->rp, BLEN(b), seq); 
	if(nn < 0) { 
		c->lstats.outCompDataBytes += BLEN(b); 
		convoput(c, TThwackU, b); 
		freeb(bb); 
	} else { 
		c->lstats.outCompDataBytes += nn; 
		bb->wp += nn; 
		convoput(c, TThwackC, bb); 
		freeb(b); 
	} 
 
1999/0915    
	poperror(); 
	qunlock(c); 
	return n; 


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