~kris/9p

9hist

4c9859b5079edda2615bb4c4716e304fe7d248aa — David du Colombier 29 years ago 141c876
Plan 9 from Bell Labs 1997-05-29
2 files changed, 21 insertions(+), 41 deletions(-)

M ip/ip.c
M port/sysfile.c
M ip/ip.c => ip/ip.c +20 -41
@@ 37,7 37,6 @@ struct Iphdr

struct Fragment
{
	QLock;
	Block*	blist;
	Fragment* next;
	Ipaddr 	src;


@@ 52,9 51,9 @@ struct Ipfrag
	ushort	flen;
};

QLock		fraglock;
Fragment*	flisthead;
Fragment*	fragfree;
QLock		fraglock;
ulong		Id;
int		iprouting;	/* true if we route like a gateway */
ulong		ipcsumerr;


@@ 70,7 69,7 @@ ulong		ipout, ippout;		/* bytes, packets out */

ushort		ipcsum(byte*);
Block*		ipreassemble(int, Block*, Iphdr*);
void		ipfragfree(Fragment*, int);
void		ipfragfree(Fragment*);
Fragment*	ipfragallo(void);

void


@@ 309,8 308,6 @@ ipstats(char *buf, int len)
	return n;
}

QLock iplock;

Block*
ipreassemble(int offset, Block *bp, Iphdr *ip)
{


@@ 333,20 330,18 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
		ip = (Iphdr *)(bp->rp);
	}

	qlock(&iplock);
	qlock(&fraglock);

	/*
	 *  find a reassembly queue for this fragment
	 */
	qlock(&fraglock);
	for(f = flisthead; f; f = fnext){
		fnext = f->next;	/* because ipfragfree changes the list */
		if(f->src == src && f->dst == dst && f->id == id)
			break;
		if(f->age > msec && canqlock(f))
			ipfragfree(f, 0);
		if(f->age < msec)
			ipfragfree(f);
	}
	qunlock(&fraglock);

	/*
	 *  if this isn't a fragmented packet, accept it


@@ 354,11 349,9 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
	 *  with it.
	 */
	if(!ip->tos && (offset & ~(IP_MF|IP_DF)) == 0) {
		if(f != nil) {
			qlock(f);
			ipfragfree(f, 1);
		}
		qunlock(&iplock);
		if(f != nil)
			ipfragfree(f);
		qunlock(&fraglock);
		return bp;
	}



@@ 373,18 366,15 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
	/* First fragment allocates a reassembly queue */
	if(f == nil) {
		f = ipfragallo();
		qlock(f);
		f->id = id;
		f->src = src;
		f->dst = dst;

		f->blist = bp;

		qunlock(f);
		qunlock(&iplock);
		qunlock(&fraglock);
		return nil;
	}
	qlock(f);

	/*
	 *  find the new fragment's position in the queue


@@ 404,8 394,7 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
		if(ovlap > 0) {
			if(ovlap >= BKFG(bp)->flen) {
				freeblist(bp);
				qunlock(f);
				qunlock(&iplock);
				qunlock(&fraglock);
				return nil;
			}
			BKFG(prev)->flen -= ovlap;


@@ 465,24 454,23 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)

			bl = f->blist;
			f->blist = nil;
			ipfragfree(f, 1);
			ipfragfree(f);
			ip = BLKIP(bl);
			hnputs(ip->length, len);
			qunlock(&iplock);
			qunlock(&fraglock);
			return bl;		
		}
		pktposn += BKFG(bl)->flen;
	}
	qunlock(f);
	qunlock(&iplock);
	qunlock(&fraglock);
	return nil;
}

/*
 * ipfragfree - Free a list of fragments, fragment list must be locked
 * ipfragfree - Free a list of fragments - assume hold fraglock
 */
void
ipfragfree(Fragment *frag, int lockq)
ipfragfree(Fragment *frag)
{
	Fragment *fl, **l;



@@ 492,10 480,6 @@ ipfragfree(Fragment *frag, int lockq)
	frag->src = 0;
	frag->id = 0;
	frag->blist = nil;
	qunlock(frag);

	if(lockq)
		qlock(&fraglock);

	l = &flisthead;
	for(fl = *l; fl; fl = fl->next) {


@@ 509,25 493,21 @@ ipfragfree(Fragment *frag, int lockq)
	frag->next = fragfree;
	fragfree = frag;

	if(lockq)
		qunlock(&fraglock);
}

/*
 * ipfragallo - allocate a reassembly queue
 * ipfragallo - allocate a reassembly queue - assume hold fraglock
 */
Fragment *
ipfragallo(void)
{
	Fragment *f;

	qlock(&fraglock);
	while(fragfree == nil) {
		for(f = flisthead; f; f = f->next)
			if(canqlock(f)) {
				ipfragfree(f, 0);
				break;
			}
		/* free last entry on fraglist */
		for(f = flisthead; f->next; f = f->next)
			;
		ipfragfree(f);
	}
	f = fragfree;
	fragfree = f->next;


@@ 535,7 515,6 @@ ipfragallo(void)
	flisthead = f;
	f->age = msec + 30000;

	qunlock(&fraglock);
	return f;
}


M port/sysfile.c => port/sysfile.c +1 -0
@@ 25,6 25,7 @@ newfd(Chan *c)
			return i;
		}
	unlock(f);
print("process %d (%s) out of file descriptors\n", up->pid, up->text);
	exhausted("file descriptors");
	return 0;
}