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

📄 il.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			break;		}		mbfree(mb);		break;	}}staticvoidilsendctl(Chan *cp, Ilpkt *inih, int type, ulong id, ulong ack, int ilspec){	Ifc *ifc;	Ilpkt *ih;	Msgbuf *mb;	Ilp *ilp;	ilp = cp->pdata;	mb = mballoc(Ensize+Ipsize+Ilsize, cp, Mbil3);	ih = (Ilpkt*)mb->data;	ih->proto = Ilproto;	ifc = cp->ifc;	memmove(ih->src, ifc->ipa, Pasize);	hnputs(ih->illen, Ilsize);	if(inih) {		memmove(ih->dst, inih->src, Pasize);		memmove(ih->ilsrc, inih->ildst, sizeof(ih->ilsrc));		memmove(ih->ildst, inih->ilsrc, sizeof(ih->ildst));		memmove(ih->ilid, inih->ilack, sizeof(ih->ilid));		memmove(ih->ilack, inih->ilid, sizeof(ih->ilack));	} else {		memmove(ih->dst, ilp->iphis, Pasize);		hnputs(ih->ilsrc, ilp->dstp);		hnputs(ih->ildst, ilp->srcp);		hnputl(ih->ilid, id);		hnputl(ih->ilack, ack);		ilp->acksent = ack;		ilp->acktime = msec;	}	ih->iltype = type;	ih->ilspec = ilspec;	ih->ilsum[0] = 0;	ih->ilsum[1] = 0;	hnputs(ih->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), Ilsize));	ipsend(mb);}staticvoidilhangup(Chan *cp, char *msg, int dolock){	Ilp *ilp;	int s;	ilp = cp->pdata;	s = ilp->state;	ilp->state = Ilclosed;	if(s == Ilsyncer)		wakeup(&ilp->syn);	if(msg != nil)		print("hangup! %s %d/%I.%d\n", msg, ilp->srcp,			ilp->iphis, ilp->dstp);	ilfreeq(cp);	fileinit(cp);	cp->whotime = 0;	strcpy(cp->whoname, "<none>");	if(dolock)		lock(&il);	ilp->alloc = 0;	ilp->srcp = 0;	ilp->dstp = 0;	memset(ilp->iphis, 0, sizeof(ilp->iphis));	if(dolock)		unlock(&il);}staticvoidilpullup(Chan *cp){	Ilpkt *oh;	Msgbuf *mb;	Ilp *ilp;	ulong oid, dlen;	ilp = cp->pdata;	lock(ilp);	while(ilp->outoforder) {		mb = ilp->outoforder;		oh = (Ilpkt*)mb->data;		oid = nhgetl(oh->ilid);		if(oid <= ilp->recvd) {			ilp->outoforder = mb->next;			mbfree(mb);			continue;		}		if(oid != ilp->recvd+1)			break;		ilp->recvd = oid;		ilp->outoforder = mb->next;		/*		 * strip off the header		 */		dlen = nhgets(oh->illen)-Ilsize;		mb->data += Ensize+Ipsize+Ilsize;		mb->count = dlen;		send(cp->send, mb);	}	unlock(ilp);}staticvoidiloutoforder(Chan *cp, Ilpkt *h, Msgbuf *mb){	Msgbuf **l, *f;	Ilp *ilp;	ulong id, ilid;	uchar *lid;	ilp = cp->pdata;	id = nhgetl(h->ilid);	/*	 * Window checks	 */	if(id <= ilp->recvd || id > ilp->recvd+ilp->window) {		mbfree(mb);		return;	}	/*	 * Packet is acceptable so	 * sort onto receive queue for pullup	 */	mb->next = 0;	lock(ilp);	if(ilp->outoforder == 0) {		ilp->outoforder = mb;	} else {		l = &ilp->outoforder;		for(f = *l; f; f = f->next) {			lid = ((Ilpkt*)(f->data))->ilid;			ilid = nhgetl(lid);			if(id <= ilid) {				if(id == ilid) {					mbfree(mb);					unlock(ilp);					return;				}				mb->next = f;				break;			}			l = &f->next;		}		*l = mb;	}	unlock(ilp);}staticvoidilrttcalc(Ilp *ilp, Msgbuf *mb){	int rtt, tt, pt, delay, rate;	rtt = msec - ilp->rttstart + TK2MS(1) - 1;	delay = ilp->delay;	rate = ilp->rate;	/* Guard against zero wrap */	if(rtt > 120000 || rtt < 0)		return;	/* this block had to be transmitted after the one acked so count its size */	ilp->rttlen += mb->count+Ipsize+Ilsize;	if(ilp->rttlen < 256){		/* guess fixed delay as rtt of small packets */		delay += rtt - (delay>>LogAGain);		if(delay < AGain)			delay = AGain;		ilp->delay = delay;	} else {		/* if packet took longer than avg rtt delay, recalc rate */		tt = rtt - (delay>>LogAGain);		if(tt > 0){			rate += ilp->rttlen/tt - (rate>>LogAGain);			if(rate < AGain)				rate = AGain;			ilp->rate = rate;		}	}	/* mdev */	pt = ilp->rttlen/(rate>>LogAGain) + (delay>>LogAGain);	ilp->mdev += abs(rtt-pt) - (ilp->mdev>>LogDGain);	if(rtt > ilp->maxrtt)		ilp->maxrtt = rtt;}staticvoidilackto(Chan *cp, ulong ackto, Msgbuf *mb){	Ilpkt *h;	Ilp *ilp;	ulong id;	ilp = cp->pdata;	if(ilp->rttack == ackto)		ilrttcalc(ilp, mb);	/* Cancel if we lost the packet we were interested in */	if(ilp->rttack <= ackto)		ilp->rttack = 0;	lock(ilp);	while(ilp->unacked) {		h = (Ilpkt*)ilp->unacked->data;		id = nhgetl(h->ilid);		if(ackto < id)			break;		mb = ilp->unacked;		ilp->unacked = mb->next;		mb->next = 0;		ilp->unackedbytes -= mb->count;		mbfree(mb);		ilp->rexmit = 0;		ilsettimeout(ilp);	}	unlock(ilp);}staticvoidilrexmit(Ilp *ilp){	Msgbuf *omb, *mb;	Ilpkt *h;	lock(ilp);	omb = ilp->unacked;	if(omb == 0) {		unlock(ilp);		return;	}/* botch -- a reference count will save this copy */	mb = mballoc(omb->count, omb->chan, Mbil4);	memmove(mb->data, omb->data, omb->count);	unlock(ilp);	h = (Ilpkt*)mb->data;	h->iltype = Ildataquery;	hnputl(h->ilack, ilp->recvd);	h->ilspec = ilnextqt(ilp);	h->ilsum[0] = 0;	h->ilsum[1] = 0;	hnputs(h->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), nhgets(h->illen)));	ilbackoff(ilp);	ipsend(mb);}staticvoidilfreeq(Chan *cp){	Ilp *ilp;	Msgbuf *mb, *next;	ilp = cp->pdata;	lock(ilp);	for(mb = ilp->unacked; mb; mb = next) {		next = mb->next;		mbfree(mb);	}	ilp->unacked = 0;	for(mb = ilp->outoforder; mb; mb = next) {		next = mb->next;		mbfree(mb);	}	ilp->outoforder = 0;	unlock(ilp);}staticvoidilsettimeout(Ilp *ilp){	Timet pt;	pt = (ilp->delay>>LogAGain)		+ ilp->unackedbytes/(ilp->rate>>LogAGain)		+ (ilp->mdev>>(LogDGain-1))		+ AckDelay;	if(pt > MaxTimeout)		pt = MaxTimeout;	ilp->timeout = msec + pt;}staticvoidilbackoff(Ilp *ilp){	Timet pt;	int i;	pt = (ilp->delay>>LogAGain)		+ ilp->unackedbytes/(ilp->rate>>LogAGain)		+ (ilp->mdev>>(LogDGain-1))		+ AckDelay;	for(i = 0; i < ilp->rexmit; i++)		pt = pt + (pt>>1);	if(pt > MaxTimeout)		pt = MaxTimeout;	ilp->timeout = msec + pt;	ilp->rexmit++;}/* * il timer * every 100ms */static	Rendez	ilt;staticvoidcallil(Alarm *a, void *){	cancel(a);	wakeup(&ilt);}// complain if two numbers not within an hour of each other#define Tfuture (1000*60*60)intlater(Timet t1, Timet t2, char *x){	Timet dt;	dt = t1 - t2;	if(dt > 0) {		if(dt > Tfuture)			print("%s: way future %ld\n", x, dt);		return 1;	}	if(dt < -Tfuture) {		print("%s: way past %ld\n", x, -dt);		return 1;	}	return 0;}staticvoidiltimer(void){	Chan *cp;	Ilp *ilp;loop:	lock(&il);	for(cp = il.chan; cp; cp = ilp->chan) {		ilp = cp->pdata;		if(ilp->alloc == 0)			continue;		switch(ilp->state) {		case Ilclosed:		case Illistening:			break;		case Ilclosing:			if(later(msec, ilp->timeout, "timeout")){				if(ilp->rexmit > MaxRexmit){					ilp->state = Ilclosed;					ilhangup(cp, "connection timed out-0", 0);					break;				}				ilsendctl(cp, 0, Ilclose, ilp->next, ilp->recvd, 0);				ilbackoff(ilp);			}			break;		case Ilsyncee:		case Ilsyncer:			if(later(msec, ilp->timeout, "timeout")){				if(ilp->rexmit > MaxRexmit){					ilp->state = Ilclosed;					ilhangup(cp, "connection timed out-1", 0);					break;				}				ilsendctl(cp, 0, Ilsync, ilp->start, ilp->recvd, 0);				ilbackoff(ilp);			}			break;		case Ilestablished:			if(ilp->recvd != ilp->acksent)			if(later(msec, ilp->acktime, "acktime"))				ilsendctl(cp, 0, Ilack, ilp->next, ilp->recvd, 0);			if(later(msec, ilp->querytime, "querytime")){				if(later(msec, ilp->lastrecv+DeathTime, "deathtime")){					ilhangup(cp, "connection timed out-2", 0);					break;				}				ilsendctl(cp, 0, Ilquery, ilp->next, ilp->recvd, ilnextqt(ilp));				ilp->querytime = msec + QueryTime;			}			if(ilp->unacked != nil)			if(later(msec, ilp->timeout, "timeout")) {				if(ilp->rexmit > MaxRexmit) {					ilp->state = Ilclosed;					ilhangup(cp, "connection timed out-3", 0);					break;				}				ilsendctl(cp, 0, Ilquery, ilp->next, ilp->recvd, ilnextqt(ilp));				ilbackoff(ilp);			}			break;		}	}	unlock(&il);	alarm(Iltickms, callil, 0);	sleep(&ilt, no, 0);	goto loop;}staticintnotsyncer(void *ic){	return ((Ilp*)ic)->state != Ilsyncer;}staticvoidcallildial(Alarm *a, void*){	cancel(a);	wakeup(&ild);}staticintilnextqt(Ilp *ilp){	int x;	lock(ilp);	x = ilp->qtx;	if(++x > Nqt)		x = 1;	ilp->qtx = x;	ilp->qt[x] = ilp->next-1;	/* highest xmitted packet */	ilp->qt[0] = ilp->qt[x];	/* compatibility with old implementations */	unlock(ilp);	return x;}#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))#define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))static voidilgoaway(Msgbuf *inmb, Ifc *ifc){	Chan *cp;	int size;	Ilpkt *ih, *inih;	Msgbuf *mb;	Ilp *ilp;	uchar *p;	inih = (Ilpkt*)inmb->data;	/* allocate a temporary message, channel, and Ilp structure */	size = ROUNDUP(Ensize+Ipsize+Ilsize, BY2WD)+sizeof(Chan)+sizeof(Ilp);	mb = mballoc(size, nil, Mbil3);	p = mb->data;	p += ROUNDUP(Ensize+Ipsize+Ilsize, BY2WD);	cp = (Chan*)p;	p += sizeof(Chan);	ilp = (Ilp*)p;	/* link them together */	cp->ifc = ifc;	mb->chan = cp;	cp->pdata = ilp;	/* figure out next hop */	memmove(ilp->ipgate, inih->src, Pasize);	if((nhgetl(ifc->ipa)&ifc->mask) != (nhgetl(inih->src)&ifc->mask))		iproute(ilp->ipgate, inih->src, ifc->netgate);	/* create a close message */	ih = (Ilpkt*)mb->data;	ih->proto = Ilproto;	hnputs(ih->illen, Ilsize);	memmove(ih->src, ifc->ipa, Pasize);	memmove(ih->dst, inih->src, Pasize);	memmove(ih->ilsrc, inih->ildst, sizeof(ih->ilsrc));	memmove(ih->ildst, inih->ilsrc, sizeof(ih->ildst));	memmove(ih->ilid, inih->ilack, sizeof(ih->ilid));	memmove(ih->ilack, inih->ilid, sizeof(ih->ilack));	ih->iltype = Ilclose;	ih->ilspec = 0;	ih->ilsum[0] = 0;	ih->ilsum[1] = 0;	hnputs(ih->ilsum, ptclcsum((uchar*)mb->data+(Ensize+Ipsize), Ilsize));	ipsend(mb);}

⌨️ 快捷键说明

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