⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devsdp.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 3 页
字号:
		b->wp[pad-1] = pad;		b->wp += pad;	}	/* Make space to fit sdp header */	b = padblock(b, 4 + c->out.cipherivlen);	b->rp[0] = (type << 4) | subtype;	c->out.seq++;	if(c->out.seq == (1<<24)) {		c->out.seq = 0;		c->out.seqwrap++;	}	b->rp[1] = c->out.seq>>16;	b->rp[2] = c->out.seq>>8;	b->rp[3] = c->out.seq;		if(c->out.cipher)		(*c->out.cipher)(&c->out, b->rp+4, BLEN(b)-4);	// auth	if(c->out.auth) {		b->wp += c->out.authlen;		(*c->out.auth)(&c->out, b->rp, BLEN(b));	}		convwriteblock(c, b);}// assume hold conv lockstatic voidconvoconnect(Conv *c, int op, ulong dialid, ulong acceptid){	Block *b;	c->lstats.outPackets++;	assert(c->chan != nil);	b = allocb(9);	b->wp[0] = (TConnect << 4) | op;	hnputl(b->wp+1, dialid);	hnputl(b->wp+5, acceptid);	b->wp += 9;	if(!waserror()) {		convwriteblock(c, b);		poperror();	}}static Block *convreadblock(Conv *c, int n){	Block *b;	Chan *ch;	qlock(&c->readlk);	if(waserror()) {		c->readproc = nil;		qunlock(&c->readlk);		nexterror();	}	qlock(c);	if(c->state == CClosed) {		qunlock(c);		error("closed");	}	c->readproc = up;	ch = c->chan;	assert(c->ref > 0);	qunlock(c);	b = devtab[ch->type]->bread(ch, n, 0);	c->readproc = nil;	poperror();	qunlock(&c->readlk);	return b;}static intreadready(void *a){	Conv *c = a;	return c->in.controlpkt != nil || (c->state == CClosed) || (c->state == CRemoteClose);}static Block *readcontrol(Conv *c, int n){	Block *b;	USED(n);	qlock(&c->in.controllk);	if(waserror()) {		qunlock(&c->in.controllk);		nexterror();	}	qlock(c);	// this lock is not held during the sleep below	for(;;) {		if(c->chan == nil || c->state == CClosed) {			qunlock(c);if(0)print("readcontrol: return error - state = %s\n", convstatename[c->state]);			error("conversation closed");		}		if(c->in.controlpkt != nil)			break;		if(c->state == CRemoteClose) {			qunlock(c);if(0)print("readcontrol: return nil - state = %s\n", convstatename[c->state]);			poperror();			return nil;		}		qunlock(c);		sleep(&c->in.controlready, readready, c);		qlock(c);	}	convack(c);	b = c->in.controlpkt;	c->in.controlpkt = nil;	qunlock(c);	poperror();	qunlock(&c->in.controllk);	return b;}static intwriteready(void *a){	Conv *c = a;	return c->out.controlpkt == nil || (c->state == CClosed) || (c->state == CRemoteClose);}// c is lockedstatic voidwritewait(Conv *c){	for(;;) {		if(c->state == CInit || c->state == CClosed || c->state == CRemoteClose)			error("conversation closed");		if(c->state == COpen && c->out.controlpkt == nil)			break;		qunlock(c);		if(waserror()) {			qlock(c);			nexterror();		}		sleep(&c->out.controlready, writeready, c);		poperror();		qlock(c);	}}static voidwritecontrol(Conv *c, void *p, int n, int wait){	Block *b;	qlock(&c->out.controllk);	qlock(c);	if(waserror()) {		qunlock(c);		qunlock(&c->out.controllk);		nexterror();	}	writewait(c);	b = allocb(4+n);	c->out.controlseq++;	hnputl(b->wp, c->out.controlseq);	memmove(b->wp+4, p, n);	b->wp += 4+n;	c->out.controlpkt = b;	convretryinit(c);	convoput(c, TControl, ControlMesg, copyblock(b, blocklen(b)));	if(wait)		writewait(c);	poperror();	qunlock(c);	qunlock(&c->out.controllk);}static Block *readdata(Conv *c, int n){	Block *b;	int nn;	for(;;) {		// some slack for tunneling overhead		nn = n + 100;		// make sure size is big enough for control messages		if(nn < 1000)			nn = 1000;		b = convreadblock(c, nn);		if(b == nil)			return nil;		qlock(c);		if(waserror()) {			qunlock(c);			return nil;		}		b = conviput(c, b, 0);		poperror();		qunlock(c);		if(b != nil) {			if(BLEN(b) > n)				b->wp = b->rp + n;			return b;		}	}}static longwritedata(Conv *c, Block *b){	int n;	ulong seq;	int subtype;	qlock(c);	if(waserror()) {		qunlock(c);		nexterror();	}	if(c->state != COpen) {		freeb(b);		error("conversation not open");	}	n = BLEN(b);	c->lstats.outDataPackets++;	c->lstats.outDataBytes += n;	if(c->out.comp != nil) {		// must generate same value as convoput		seq = (c->out.seq + 1) & (SeqMax-1);		subtype = (*c->out.comp)(c, 0, seq, &b);		c->lstats.outCompDataBytes += BLEN(b);		convoput(c, TCompData, subtype, b);	} else		convoput(c, TData, 0, b);	poperror();	qunlock(c);	return n;}static voidconvreader(void *a){	Conv *c = a;	Block *b;	qlock(c);	assert(c->reader == 1);	while(c->dataopen == 0 && c->state != CClosed) {		qunlock(c);		b = nil;		if(!waserror()) {			b = convreadblock(c, 2000);			poperror();		}		qlock(c);		if(b == nil) {			if(strcmp(up->error, Eintr) != 0) {				convsetstate(c, CClosed);				break;			}		} else if(!waserror()) {			conviput(c, b, 1);			poperror();		}	}	c->reader = 0;	convderef(c);	qunlock(c);	pexit("hangup", 1);}/* ciphers, authenticators, and compressors  */static voidsetalg(Conv *c, char *name, Algorithm *alg, Algorithm **p){	for(; alg->name; alg++)		if(strcmp(name, alg->name) == 0)			break;	if(alg->name == nil)		error("unknown algorithm");	*p = alg;	alg->init(c);}static voidsetsecret(OneWay *ow, char *secret){	char *p;	int i, c;		i = 0;	memset(ow->secret, 0, sizeof(ow->secret));	for(p=secret; *p; p++) {		if(i >= sizeof(ow->secret)*2)			break;		c = *p;		if(c >= '0' && c <= '9')			c -= '0';		else if(c >= 'a' && c <= 'f')			c -= 'a'-10;		else if(c >= 'A' && c <= 'F')			c -= 'A'-10;		else			error("bad character in secret");		if((i&1) == 0)			c <<= 4;		ow->secret[i>>1] |= c;		i++;	}}static voidsetkey(uchar *key, int n, OneWay *ow, char *prefix){	uchar ibuf[SHA1dlen], obuf[MD5dlen], salt[10];	int i, round = 0;	while(n > 0){		for(i=0; i<round+1; i++)			salt[i] = 'A'+round;		sha1((uchar*)prefix, strlen(prefix), ibuf, sha1(salt, round+1, nil, nil));		md5(ibuf, SHA1dlen, obuf, md5(ow->secret, sizeof(ow->secret), nil, nil));		i = (n<MD5dlen) ? n : MD5dlen;		memmove(key, obuf, i);		key += i;		n -= i;		if(++round > sizeof salt)			panic("setkey: you ask too much");	}}static voidcipherfree(Conv *c){	if(c->in.cipherstate) {		free(c->in.cipherstate);		c->in.cipherstate = nil;	}	if(c->out.cipherstate) {		free(c->out.cipherstate);		c->out.cipherstate = nil;	}	c->in.cipher = nil;	c->in.cipherblklen = 0;	c->out.cipherblklen = 0;	c->in.cipherivlen = 0;	c->out.cipherivlen = 0;}static voidauthfree(Conv *c){	if(c->in.authstate) {		free(c->in.authstate);		c->in.authstate = nil;	}	if(c->out.authstate) {		free(c->out.authstate);		c->out.authstate = nil;	}	c->in.auth = nil;	c->in.authlen = 0;	c->out.authlen = 0;}static voidcompfree(Conv *c){	if(c->in.compstate) {		free(c->in.compstate);		c->in.compstate = nil;	}	if(c->out.compstate) {		free(c->out.compstate);		c->out.compstate = nil;	}	c->in.comp = nil;}static voidnullcipherinit(Conv *c){	cipherfree(c);}static intdesencrypt(OneWay *ow, uchar *p, int n){	uchar *pp, *ip, *eip, *ep;	DESstate *ds = ow->cipherstate;	if(n < 8 || (n & 0x7 != 0))		return 0;	ep = p + n;	memmove(p, ds->ivec, 8);	for(p += 8; p < ep; p += 8){		pp = p;		ip = ds->ivec;		for(eip = ip+8; ip < eip; )			*pp++ ^= *ip++;		block_cipher(ds->expanded, p, 0);		memmove(ds->ivec, p, 8);	}	return 1;}static intdesdecrypt(OneWay *ow, uchar *p, int n){	uchar tmp[8];	uchar *tp, *ip, *eip, *ep;	DESstate *ds = ow->cipherstate;	if(n < 8 || (n & 0x7 != 0))		return 0;	ep = p + n;	memmove(ds->ivec, p, 8);	p += 8;	while(p < ep){		memmove(tmp, p, 8);		block_cipher(ds->expanded, p, 1);		tp = tmp;		ip = ds->ivec;		for(eip = ip+8; ip < eip; ){			*p++ ^= *ip;			*ip++ = *tp++;		}	}	return 1;}static voiddescipherinit(Conv *c){	uchar key[8];	uchar ivec[8];	int i;	int n = c->cipher->keylen;	cipherfree(c);		if(n > sizeof(key))		n = sizeof(key);	/* in */	memset(key, 0, sizeof(key));	setkey(key, n, &c->in, "cipher");	memset(ivec, 0, sizeof(ivec));	c->in.cipherblklen = 8;	c->in.cipherivlen = 8;	c->in.cipher = desdecrypt;	c->in.cipherstate = smalloc(sizeof(DESstate));	setupDESstate(c->in.cipherstate, key, ivec);		/* out */	memset(key, 0, sizeof(key));	setkey(key, n, &c->out, "cipher");	for(i=0; i<8; i++)		ivec[i] = nrand(256);	c->out.cipherblklen = 8;	c->out.cipherivlen = 8;	c->out.cipher = desencrypt;	c->out.cipherstate = smalloc(sizeof(DESstate));	setupDESstate(c->out.cipherstate, key, ivec);}static intrc4encrypt(OneWay *ow, uchar *p, int n){	CipherRc4 *cr = ow->cipherstate;	if(n < 4)		return 0;	hnputl(p, cr->cseq);	p += 4;	n -= 4;	rc4(&cr->current, p, n);	cr->cseq += n;	return 1;}static intrc4decrypt(OneWay *ow, uchar *p, int n){	CipherRc4 *cr = ow->cipherstate;	RC4state tmpstate;	ulong seq;	long d, dd;	if(n < 4)		return 0;	seq = nhgetl(p);	p += 4;	n -= 4;	d = seq-cr->cseq;	if(d == 0) {		rc4(&cr->current, p, n);		cr->cseq += n;		if(cr->ovalid) {			dd = cr->cseq - cr->lgseq;			if(dd > RC4back)				cr->ovalid = 0;		}	} else if(d > 0) {//print("missing packet: %uld %ld\n", seq, d);		// this link is hosed 		if(d > RC4forward)			return 0;		cr->lgseq = seq;		if(!cr->ovalid) {			cr->ovalid = 1;			cr->oseq = cr->cseq;			memmove(&cr->old, &cr->current, sizeof(RC4state));		}		rc4skip(&cr->current, d);		rc4(&cr->current, p, n);		cr->cseq = seq+n;	} else {//print("reordered packet: %uld %ld\n", seq, d);		dd = seq - cr->oseq;		if(!cr->ovalid || -d > RC4back || dd < 0)			return 0;		memmove(&tmpstate, &cr->old, sizeof(RC4state));		rc4skip(&tmpstate, dd);		rc4(&tmpstate, p, n);		return 1;	}	// move old state up	if(cr->ovalid) {		dd = cr->cseq - RC4back - cr->oseq;		if(dd > 0) {			rc4skip(&cr->old, dd);			cr->oseq += dd;		}	}	return 1;}static voidrc4cipherinit(Conv *c){	uchar key[32];	CipherRc4 *cr;	int n;	cipherfree(c);	n = c->cipher->keylen;	if(n > sizeof(key))		n = sizeof(key);	/* in */	memset(key, 0, sizeof(key));	setkey(key, n, &c->in, "cipher");	c->in.cipherblklen = 1;	c->in.cipherivlen = 4;	c->in.cipher = rc4decrypt;	cr = smalloc(sizeof(CipherRc4));	memset(cr, 0, sizeof(*cr));	setupRC4state(&cr->current, key, n);	c->in.cipherstate = cr;	/* out */	memset(key, 0, sizeof(key));	setkey(key, n, &c->out, "cipher");	c->out.cipherblklen = 1;	c->out.cipherivlen = 4;	c->out.cipher = rc4encrypt;	cr = smalloc(sizeof(CipherRc4));	memset(cr, 0, sizeof(*cr));	setupRC4state(&cr->current, key, n);	c->out.cipherstate = cr;}static voidnullauthinit(Conv *c){	authfree(c);}static voidshaauthinit(Conv *c){	authfree(c);}static voidseanq_hmac_md5(uchar hash[MD5dlen], ulong wrap, uchar *t, long tlen, uchar *key, long klen){	uchar ipad[65], opad[65], wbuf[4];	int i;	DigestState *digest;	uchar innerhash[MD5dlen];	for(i=0; i<64; i++){		ipad[i] = 0x36;		opad[i] = 0x5c;	}	ipad[64] = opad[64] = 0;	for(i=0; i<klen; i++){		ipad[i] ^= key[i];		opad[i] ^= key[i];	}	hnputl(wbuf, wrap);	digest = md5(ipad, 64, nil, nil);	digest = md5(wbuf, sizeof(wbuf), nil, digest);	md5(t, tlen, innerhash, digest);	digest = md5(opad, 64, nil, nil);	md5(innerhash, MD5dlen, hash, digest);}static intmd5auth(OneWay *ow, uchar *t, int tlen){	uchar hash[MD5dlen];	int r;	if(tlen < ow->authlen)		return 0;	tlen -= ow->authlen;	memset(hash, 0, MD5dlen);	seanq_hmac_md5(hash, ow->seqwrap, t, tlen, (uchar*)ow->authstate, 16);	r = memcmp(t+tlen, hash, ow->authlen) == 0;	memmove(t+tlen, hash, ow->authlen);	return r;}static voidmd5authinit(Conv *c){	int keylen;	authfree(c);	keylen = c->auth->keylen;	if(keylen > 16)		keylen = 16;	/* in */	c->in.authstate = smalloc(16);	memset(c->in.authstate, 0, 16);	setkey(c->in.authstate, keylen, &c->in, "auth");	c->in.authlen = 12;	c->in.auth = md5auth;		/* out */	c->out.authstate = smalloc(16);	memset(c->out.authstate, 0, 16);	setkey(c->out.authstate, keylen, &c->out, "auth");	c->out.authlen = 12;	c->out.auth = md5auth;}static voidnullcompinit(Conv *c){	compfree(c);}static intthwackcomp(Conv *c, int, ulong seq, Block **bp){	Block *b, *bb;	int nn;	// add ack info	b = padblock(*bp, 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;	bb = allocb(BLEN(b));	nn = thwack(c->out.compstate, bb->wp, b->rp, BLEN(b), seq, c->lstats.outCompStats);	if(nn < 0) {		freeb(bb);		*bp = b;		return ThwackU;	} else {		bb->wp += nn;		freeb(b);		*bp = bb;		return ThwackC;	}}static intthwackuncomp(Conv *c, int subtype, ulong seq, Block **bp){	Block *b, *bb;	ulong mask;	ulong mseq;	int n;	switch(subtype) {	default:		return 0;	case ThwackU:		b = *bp;		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);		return 1;	case ThwackC:		bb = *bp;		b = allocb(ThwMaxBlock);		n = unthwack(c->in.compstate, b->wp, ThwMaxBlock, bb->rp, BLEN(bb), seq);		freeb(bb);		if(n < 0) {print("unthwack failed: %r!\n");			freeb(b);			return 0;		}		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;		*bp = b;		return 1;	}}static voidthwackcompinit(Conv *c){	compfree(c);	c->in.compstate = malloc(sizeof(Unthwack));	if(c->in.compstate == nil)		error(Enomem);	unthwackinit(c->in.compstate);	c->out.compstate = malloc(sizeof(Thwack));	if(c->out.compstate == nil)		error(Enomem);	thwackinit(c->out.compstate);	c->in.comp = thwackuncomp;	c->out.comp = thwackcomp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -