~kris/9p

9hist

8df99f1ca907699bc9dde35b90f191e20d619468 — David du Colombier 34 years ago 66db053
Plan 9 from Bell Labs 1991-10-24
6 files changed, 122 insertions(+), 91 deletions(-)

M port/devenv.c
M port/devip.c
M port/ipdat.h
M port/proc.c
M port/segment.c
M port/stil.c
M port/devenv.c => port/devenv.c +3 -0
@@ 391,6 391,8 @@ evfree(Envval *ev)

	if(ev->prev)
		ev->prev->next = ev->next;
	else
		panic("evfree");
	if(ev->next)
		ev->next->prev = ev->prev;
	n = (ev->len + ALIGN - 1) & ~(ALIGN - 1);


@@ 399,6 401,7 @@ evfree(Envval *ev)
	if(n > EVFREE)
		n = EVFREE;
	ev->next = envalloc.free[n];
	ev->prev = 0;
	envalloc.free[n] = ev;
}


M port/devip.c => port/devip.c +80 -74
@@ 181,7 181,7 @@ ipopen(Chan *c, int omode)
			error(Eprotonosup);

		if(cp->backlog == 0)
			cp->backlog = 1;
			cp->backlog = 3;

		streamopen(c, &ipinfo);
		if(c->stream->devq->next->info != cp->stproto)


@@ 226,7 226,7 @@ ipclonecon(Chan *c)
	base = ipconv[c->dev];
	etab = &base[conf.ip];
	for(new = base; new < etab; new++) {
		new = ipincoming(c->dev);
		new = ipincoming(base);
		if(new == 0)
			error(Enodev);



@@ 243,11 243,10 @@ ipclonecon(Chan *c)
}

Ipconv *
ipincoming(int dev)
ipincoming(Ipconv *base)
{
	Ipconv *base, *new, *etab;
	Ipconv *new, *etab;

	base = ipconv[dev];
	etab = &base[conf.ip];
	for(new = base; new < etab; new++) {
		if(new->ref == 0 && canqlock(new)) {


@@ 335,86 334,93 @@ long
ipwrite(Chan *c, char *a, long n, ulong offset)
{
	int 	m, backlog, type;
	char 	*field[5], buf[256];
	Ipconv  *cp;
	char 	*field[5], *ctlarg[5], buf[256];
	Port	port, base;
	Ipconv  *cp;

	type = STREAMTYPE(c->qid.path);
	if (type == Sdataqid)
		return streamwrite(c, a, n, 0); 

	if (type == Sctlqid) {
		cp = &ipconv[c->dev][STREAMID(c->qid.path)];

		strncpy(buf, a, sizeof buf);
		m = getfields(buf, field, 5, ' ');

		if(strcmp(field[0], "connect") == 0) {
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
					error(Edevbusy);

			if(m != 2)
				error(Ebadarg);

			switch(getfields(field[1], field, 5, '!')) {
			default:
				error(Ebadarg);
			case 2:
				base = PORTALLOC;
				break;
			case 3:
				if(strcmp(field[2], "r") != 0)
					error(Eperm);
				base = PRIVPORTALLOC;
				break;
			}
			cp->dst = ipparse(field[0]);
			cp->pdst = atoi(field[1]);
	if (type != Sctlqid)
		error(Eperm);

			/* If we have no local port assign one */
			qlock(&ipalloc);
			if(cp->psrc == 0)
				cp->psrc = nextport(ipconv[c->dev], base);
			qunlock(&ipalloc);
	cp = &ipconv[c->dev][STREAMID(c->qid.path)];

	m = n;
	if(m > sizeof(buf)-1)
		m = sizeof(buf)-1;
	strncpy(buf, a, m);
	buf[m] = '\0';

	m = getfields(buf, field, 5, ' ');
	if(m < 1)
		errors("bad ip control");

	if(strcmp(field[0], "connect") == 0) {
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
				error(Edevbusy);

		if(m != 2)
			error(Ebadarg);

		switch(m = getfields(field[1], ctlarg, 5, '!')) {
		default:
			error(Ebadarg);
		case 2:
			base = PORTALLOC;
			break;
		case 3:
			if(strcmp(ctlarg[2], "r") != 0)
				error(Eperm);
			base = PRIVPORTALLOC;
			break;
		}
		else if(strcmp(field[0], "announce") == 0 ||
			strcmp(field[0], "reserve") == 0) {
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
					error(Edevbusy);

			if(m != 2)
				error(Ebadarg);
			port = atoi(field[1]);

			qlock(&ipalloc);
			if(portused(ipconv[c->dev], port)) {
				qunlock(&ipalloc);	
				error(Einuse);
			}
			cp->psrc = port;
			cp->ptype = *field[0];
			qunlock(&ipalloc);
		}
		else if(strcmp(field[0], "backlog") == 0) {
			if(m != 2)
				error(Ebadarg);
			backlog = atoi(field[1]);
			if(backlog == 0)
				error(Ebadarg);
			if(backlog > 5)
				backlog = 5;
			cp->backlog = backlog;
		}
		else
			return streamwrite(c, a, n, 0);
		cp->dst = ipparse(ctlarg[0]);
		cp->pdst = atoi(ctlarg[1]);

		/* If we have no local port assign one */
		qlock(&ipalloc);
		if(cp->psrc == 0)
			cp->psrc = nextport(ipconv[c->dev], base);
		qunlock(&ipalloc);

		return n;
	}
	else if(strcmp(field[0], "announce") == 0 ||
		strcmp(field[0], "reserve") == 0) {
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
				error(Edevbusy);

	error(Eperm);
		if(m != 2)
			error(Ebadarg);

		port = atoi(field[1]);

		qlock(&ipalloc);
		if(portused(ipconv[c->dev], port)) {
			qunlock(&ipalloc);	
			error(Einuse);
		}
		cp->psrc = port;
		cp->ptype = *field[0];
		qunlock(&ipalloc);
	}
	else if(strcmp(field[0], "backlog") == 0) {
		if(m != 2)
			error(Ebadarg);
		backlog = atoi(field[1]);
		if(backlog == 0)
			error(Ebadarg);
		if(backlog > 5)
			backlog = 5;
		cp->backlog = backlog;
	}
	else
		return streamwrite(c, a, n, 0);

	return n;
}




@@ 690,7 696,7 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base)
				pushq(c->stream, new->stproto);
				new->ref--;
				qunlock(&s->listenq);

print("ip listener!\n");
				return;
			}
		}

M port/ipdat.h => port/ipdat.h +3 -0
@@ 46,6 46,7 @@ struct Udphdr
	uchar	d[6];		/* Ethernet destination */
	uchar	s[6];		/* Ethernet source */
	uchar	type[2];	/* Ethernet packet type */

	uchar	vihl;		/* Version and header length */
	uchar	tos;		/* Type of service */
	uchar	length[2];	/* packet length */


@@ 72,6 73,7 @@ struct Ilhdr
	uchar	d[6];		/* Ethernet destination */
	uchar	s[6];		/* Ethernet source */
	uchar	type[2];	/* Ethernet packet type */

	uchar	vihl;		/* Version and header length */
	uchar	tos;		/* Type of service */
	uchar	length[2];	/* packet length */


@@ 265,6 267,7 @@ struct Ipconv
	Ipaddr	dst;			/* Destination from connect */
	Port	psrc;			/* Source port */
	Port	pdst;			/* Destination port */
	char	ptype;			/* Port type */

	Ipifc	*ipinterface;		/* Ip protocol interface */
	Queue	*readq;			/* Pointer to upstream read q */

M port/proc.c => port/proc.c +4 -4
@@ 521,6 521,10 @@ pexit(char *exitstr, int freemem)

	if(c->fgrp)
		closefgrp(c->fgrp);
	closepgrp(c->pgrp);
	close(u->dot);
	if(c->egrp)
		closeegrp(c->egrp);

	if(c->kp == 0) {
		wq = newwaitq();


@@ 566,10 570,6 @@ pexit(char *exitstr, int freemem)
			*s = 0;
			putseg(os);
		}
	closepgrp(c->pgrp);
	if(c->egrp)
		closeegrp(c->egrp);
	close(u->dot);

	lock(&c->exl);		/* Prevent my children from leaving waits */
	c->pid = 0;

M port/segment.c => port/segment.c +8 -7
@@ 265,21 265,22 @@ imagereclaim(void)
	if(!canqlock(&ireclaim))	/* Somebody is already cleaning the page cache */
		return;

	lock(&palloc);
	for(p = palloc.head; p; p = p->next) {
		if(p->image == 0)
			continue;
	for(;;) {
		lock(&palloc);
		for(p = palloc.head; p; p = p->next)
			if(p->image && p->ref == 0 && p->image != &swapimage)
				break;

		unlock(&palloc);
		if(p == 0)
			break;

		lockpage(p);
		if(p->ref == 0 && p->image != &swapimage)
			uncachepage(p);
		unlockpage(p);
		lock(&palloc);
	}

	unlock(&palloc);

	qunlock(&ireclaim);
}


M port/stil.c => port/stil.c +24 -6
@@ 187,8 187,9 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
	int plen;
	Ipconv *s, *etab, *new;
	short sp, dp;
	Ipaddr dst;

	ih = (Ilhdr *)bp;
	ih = (Ilhdr *)bp->rptr;

	plen = blen(bp);
	if(plen < IL_EHSIZE+IL_HDRSIZE)


@@ 201,17 202,26 @@ ilrcvmsg(Ipconv *ipc, Block *bp)

	sp = nhgets(ih->ildst);
	dp = nhgets(ih->ilsrc);
	dst = nhgetl(ih->src);

print("got packet from %d.%d.%d.%d %d %d\n", fmtaddr(dst), sp, dp);

	etab = &ipc[conf.ip];
	for(s = ipc; s < etab; s++) {
		if(s->psrc == sp && s->pdst == dp) {
		if(s->psrc == sp && s->pdst == dp && s->dst == dst) {
			ilprocess(s, ih, bp);
			return;
		}
			
	}

	if(s->curlog > s->backlog) {
print("Backlog\n");
		goto reset;
	}

	for(s = ipc; s < etab; s++) {
		if(s->ilctl.state == Illistening && s->psrc == 0) {
		if(s->ilctl.state == Illistening && s->pdst == 0) {
			/* Do the listener stuff */
			new = ipincoming(ipc);
			if(new == 0) 


@@ 222,6 232,7 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
			new->newcon = 1;
			new->ipinterface = s->ipinterface;
			s->ipinterface->ref++;
			s->curlog++;
			new->psrc = sp;
			new->pdst = dp;
			new->dst = nhgetl(ih->src);


@@ 240,6 251,8 @@ drop:
void
ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
{
	Block *nb;

	switch(s->ilctl.state) {
	case Ilclosed:
	case Ilclosing:


@@ 265,10 278,14 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
	case Ildata:
		ilackto(&s->ilctl, nhgetl(h->ilack));
		bp->rptr += IL_EHSIZE+IL_HDRSIZE;
/* Check and trim to length */
		PUTNEXT(s->readq, bp);
		break;
	case Ilreset:
		s->ilctl.state = Ilclosed;
		nb = allocb(0);
		nb->type = M_HANGUP;
		PUTNEXT(s->readq, nb);
		freeb(bp);
	}
}


@@ 287,17 304,18 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack)
	ic = &ipc->ilctl;

	/* Ip fields */
	hnputl(ih->src, Myip);
	hnputl(ih->dst, ipc->dst);
	ih->proto = IP_ILPROTO;
	hnputl(ih->src, Myip);
	hnputs(ih->illen, IL_HDRSIZE);
	if(inih) {
		hnputl(ih->dst, nhgetl(inih->src));
		hnputs(ih->ilsrc, nhgets(inih->ildst));
		hnputs(ih->ildst, nhgets(inih->ilsrc));
		hnputl(ih->ilid, nhgetl(inih->ilack));
		hnputl(ih->ilack, nhgetl(inih->ilid));
	}
	else {
		hnputl(ih->dst, ipc->dst);
		hnputs(ih->ilsrc, ipc->psrc);
		hnputs(ih->ildst, ipc->pdst);
		hnputl(ih->ilid, ic->sent);


@@ 311,7 329,7 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack)
	if(ilcksum)
		hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE));

	if(!ack) {
	if(!ack && ipc) {
		ic->sent++;			/* Maybe needs locking */
		ilackq(&ipc->ilctl, bp);
	}