~kris/9p

9hist

c5ce870ef3f5ab1593349511574b3f041a00fed5 — David du Colombier 24 years ago def14cb
Plan 9 from Bell Labs 2002-07-04
M ip/ethermedium.c => ip/ethermedium.c +9 -4
@@ 115,7 115,7 @@ struct Etherarp
static void
etherbind(Ipifc *ifc, int argc, char **argv)
{
	Chan *mchan4, *cchan4, *achan, *mchan6, *cchan6;
	Chan *mchan4, *cchan4, *achan, *mchan6, *cchan6, *schan;
	char addr[Maxpath];	//char addr[2*KNAMELEN];
	char dir[Maxpath];	//char dir[2*KNAMELEN];
	char *buf;


@@ 158,9 158,14 @@ etherbind(Ipifc *ifc, int argc, char **argv)
	 */
	snprint(addr, sizeof(addr), "%s/stats", dir);
	buf = smalloc(512);
	achan = namec(addr, Aopen, OREAD, 0);
	n = devtab[achan->type]->read(achan, buf, 511, 0);
	cclose(achan);
	schan = namec(addr, Aopen, OREAD, 0);
	if(waserror()){
		cclose(schan);
		nexterror();
	}
	n = devtab[schan->type]->read(schan, buf, 511, 0);
	cclose(schan);
	poperror();
	buf[n] = 0;

	ptr = strstr(buf, "addr: ");

M ip/tcp.c => ip/tcp.c +29 -22
@@ 679,23 679,19 @@ tcpmtu(Conv *s)
	uchar version;

	version = s->ipversion;
	mtu = 0;
	ifc = findipifc(s->p->f, s->raddr, 0);
	if(ifc != nil) {
		switch(version){
		case V4:
	switch(version){
	default:
	case V4:
		mtu = DEF_MSS;
		if(ifc != nil)
			mtu = ifc->maxmtu - ifc->m->hsize - (TCP4_PKT + TCP4_HDRSIZE);
			break;
		case V6:
		break;
	case V6:
		mtu = DEF_MSS6;
		if(ifc != nil)
			mtu = ifc->maxmtu - ifc->m->hsize - (TCP6_PKT + TCP6_HDRSIZE);
			break;
		default:
			panic("tcpmtu: version %d", version);
		}
	}

	if(mtu < 32) {
		mtu = 1280;
		break;
	}

	return mtu;


@@ 1665,6 1661,19 @@ reset:
		break;
	}

	if(tcb->state != Syn_received){
		/*
		 *  One DOS attack is to open connections to us and then forget about them,
		 *  thereby tying up a conv at no long term cost to the attacker.
		 *  This is an attempt to defeat these stateless DOS attacks.  See
		 *  corresponding code in tcpsendka().
		 */
		if(seq_within(seg.ack, tcb->snd.una-(1<<31), tcb->snd.una-(1<<29))){
			print("stateless hog %lux - %lux - %lux\n", tcb->snd.una-(1<<31), seg.ack, tcb->snd.una-(1<<29));
			localclose(s, "stateless hog");
		}
	}

	/* Cut the data to fit the receive window */
	if(tcptrim(tcb, &seg, &bp, &length) == -1) {
		netlog(f, Logtcp, "tcp len < 0, %lux\n", seg.seq);


@@ 2122,6 2131,10 @@ tcpoutput(Conv *s)

/*
 *  the BSD convention (hack?) for keep alives.  resend last uchar acked.
 *
 *  To avoid stateless Conv hogs, we pick a sequence number at random.  If
 *  it that number gets acked by the other end, we shut down the connection.
 *  See the equivalent code in tcpiput().
 */
void
tcpsendka(Conv *s)


@@ 2138,7 2151,7 @@ tcpsendka(Conv *s)
	seg.dest = s->rport;
	seg.flags = ACK|PSH;
	seg.mss = 0;
	seg.seq = tcb->snd.una-1;
	seg.seq = tcb->snd.una-(1<<30)-nrand(1<<20);
	seg.ack = tcb->rcv.nxt;
	seg.wnd = tcb->rcv.wnd;
	tcb->last_ack = tcb->rcv.nxt;


@@ 2320,7 2333,6 @@ void
procsyn(Conv *s, Tcp *seg)
{
	Tcpctl *tcb;
	int mtu;

	tcb = (Tcpctl*)s->ptcl;
	tcb->flags |= FORCE;


@@ 2330,14 2342,9 @@ procsyn(Conv *s, Tcp *seg)
	tcb->irs = seg->seq;
	tcb->snd.wnd = seg->wnd;

	if(seg->mss != 0)
	if(seg->mss != 0 && seg->mss < tcb->mss)
		tcb->mss = seg->mss;

	tcb->max_snd = seg->wnd;

	mtu = tcpmtu(s);
	if(tcb->mss > mtu)
		tcb->mss = mtu;
	tcb->cwind = tcb->mss;
}


M port/devrealtime.c => port/devrealtime.c +13 -11
@@ 13,6 13,7 @@

/* debugging */
extern int			edfprint;
extern Edfinterface	realedf, *edf;

static Schedevent *events;
static int nevents, revent, wevent;


@@ 219,6 220,7 @@ devrtinit(void)
	events = (Schedevent *)malloc(sizeof(Schedevent) * Nevents);
	assert(events);
	nevents = revent = wevent = 0;
	edf = &realedf;
}

static Chan *


@@ 286,7 288,7 @@ devrtopen(Chan *c, int mode)
	case Qclone:
		if (mode == OREAD) 
			error(Eperm);
		edfinit();
		edf->edfinit();
		/* open a new task */
		for (t = tasks; t< tasks + Maxtasks; t++){
			qlock(t);


@@ 638,7 640,7 @@ removetask(Task *t)
	Resource *r;

	qlock(t);
	edfexpel(t);
	edf->edfexpel(t);
	for (pp = t->procs; pp < t->procs + nelem(t->procs); pp++)
		if (p = *pp)
			p->task = nil;


@@ 724,7 726,7 @@ devrtwrite(Chan *c, void *va, long n, vlong)
				if (e=parsetime(&time, v))
					error(e);
				ticks = time2ticks(time);
				edfexpel(t);
				edf->edfexpel(t);
				switch(add){
				case -1:
					if (ticks > t->T)


@@ 745,7 747,7 @@ devrtwrite(Chan *c, void *va, long n, vlong)
				if (e=parsetime(&time, v))
					error(e);
				ticks = time2ticks(time);
				edfexpel(t);
				edf->edfexpel(t);
				switch(add){
				case -1:
					if (ticks > t->D)


@@ 764,7 766,7 @@ devrtwrite(Chan *c, void *va, long n, vlong)
				if (e=parsetime(&time, v))
					error(e);
				ticks = time2ticks(time);
				edfexpel(t);
				edf->edfexpel(t);
				switch(add){
				case -1:
					if (ticks > t->C)


@@ 784,7 786,7 @@ devrtwrite(Chan *c, void *va, long n, vlong)
			}else if (strcmp(a, "resources") == 0){
				if (v == nil)
					error("resources: value missing");
				edfexpel(t);
				edf->edfexpel(t);
				if (add == 0){
					for (rp = t->res; rp < t->res + nelem(t->res); rp++)
						if (*rp){


@@ 809,7 811,7 @@ devrtwrite(Chan *c, void *va, long n, vlong)
				if (v == nil)
					error("procs: value missing");
				if (add <= 0){
					edfexpel(t);
					edf->edfexpel(t);
				}
				if (add == 0){
					for (pp = t->procs; pp < t->procs + nelem(t->procs); pp++)


@@ 835,10 837,10 @@ devrtwrite(Chan *c, void *va, long n, vlong)
						error(e);
				}
			}else if (strcmp(a, "admit") == 0){
				if (e = edfadmit(t))
				if (e = edf->edfadmit(t))
					error(e);
			}else if (strcmp(a, "expel") == 0){
				edfexpel(t);
				edf->edfexpel(t);
			}else if (strcmp(a, "remove") == 0){
				removetask(t);
				return n;	/* Ignore any subsequent commands */


@@ 857,8 859,8 @@ devrtwrite(Chan *c, void *va, long n, vlong)
				else
					t->flags |= Useblocking;
			}else if (strcmp(a, "yield") == 0){
				if (isedf(up) && up->task == t){
					edfdeadline(up);	/* schedule next release */
				if (edf->isedf(up) && up->task == t){
					edf->edfdeadline(up);	/* schedule next release */
					sched();
				}else
					error("yield outside task");

M port/edf.c => port/edf.c +25 -11
@@ 49,6 49,7 @@ enum{

static int earlierrelease(Task *t1, Task *t2) {return t1->r < t2->r;}
static int earlierdeadline(Task *t1, Task *t2) {return t1->d < t2->d;}
static void	edfrelease(Task *t);

/* Tasks waiting for release, head earliest release time */
Taskq		qwaitrelease =	{{0}, nil, earlierrelease};


@@ 71,7 72,7 @@ static void		edfreleaseintr(Ureg *, Timer *cy);
static void		edfdeadlineintr(Ureg*, Timer*);
static char *	edftestschedulability(Task *thetask);

void
static void
edfinit(void)
{
	int i;


@@ 96,13 97,13 @@ edfinit(void)
	iunlock(&edflock);
}

int
static int
isedf(Proc *p)
{
	return p && p->task && p->task->state >= EdfIdle;
}

int
static int
edfanyready(void)
{
	return edfstack[m->machno].head || qreleased.head;


@@ 220,7 221,7 @@ edfreleasetimer(void)
	timeradd(&releasetimer[m->machno]);
}

void
static void
edfblock(Proc *p)
{
	Task *t, *pt;


@@ 284,7 285,7 @@ deadline(Proc *p, SEvent why)
	edfresched(t);
}

void
static void
edfdeadline(Proc *p)
{
	DPRINT("%d edfdeadline\n", m->machno);


@@ 295,7 296,7 @@ edfdeadline(Proc *p)
	iunlock(&edflock);
}

char *
static char *
edfadmit(Task *t)
{
	char *err;


@@ 361,7 362,7 @@ edfadmit(Task *t)
	return nil;
}

void
static void
edfexpel(Task *t)
{
	Task *tt;


@@ 492,7 493,7 @@ edfdeadlineintr(Ureg*, Timer*)
	splhi();
}

void
static void
edfbury(Proc *p)
{
	Task *t;


@@ 526,7 527,7 @@ edfbury(Proc *p)
	iunlock(&edflock);
}

void
static void
edfready(Proc *p)
{
	Task *t;


@@ 671,7 672,7 @@ edfresched(Task *t)
	}
}

void
static void
edfrelease(Task *t)
{
	DPRINT("%d edfrelease, %s, %d\n", m->machno, edfstatename[t->state], t->runq.n);


@@ 685,7 686,7 @@ edfrelease(Task *t)
	if(devrt) devrt(t, now, SRelease);
}

Proc *
static Proc *
edfrunproc(void)
{
	/* Return an edf proc to run or nil */


@@ 961,3 962,16 @@ time2ticks(Time time)
	assert(time >= 0);
	return uvmuldiv(time, fasthz, Onesecond);
}

Edfinterface realedf = {
	.isedf		= isedf,
	.edfbury		= edfbury,
	.edfanyready	= edfanyready,
	.edfready		= edfready,
	.edfrunproc	= edfrunproc,
	.edfblock		= edfblock,
	.edfinit		= edfinit,
	.edfexpel		= edfexpel,
	.edfadmit		= edfadmit,
	.edfdeadline	= edfdeadline,
};

M port/edf.h => port/edf.h +4 -4
@@ 14,10 14,10 @@ enum {
typedef vlong	Time;
typedef uvlong	Ticks;

typedef struct Task		Task;
typedef struct Resource	Resource;
typedef struct Edf		Edf;
typedef struct Taskq		Taskq;
typedef struct Task			Task;
typedef struct Resource		Resource;
typedef struct Edf			Edf;
typedef struct Taskq			Taskq;

enum Edfstate {
	EdfUnused,		/* task structure not in use */

M port/nulledf.c => port/nulledf.c +39 -6
@@ 6,36 6,69 @@
#include	"../port/error.h"
#include	"../port/edf.h"

int
static int
isedf(Proc*)
{
	return 0;
}

void
static void
edfbury(Proc*)
{
}

int
static int
edfanyready(void)
{
	return 0;
}

void
static void
edfready(Proc*)
{
}

Proc*
static Proc*
edfrunproc(void)
{
	return nil;
}

void
static void
edfblock(Proc*)
{
}

static void
edfinit(void)
{
}

static void
edfexpel(Task*)
{
}

static char *
edfadmit(Task*)
{
	return "No edf";
}

static void
edfdeadline(Proc*)
{
}

Edfinterface nulledf = {
	.isedf		= isedf,
	.edfbury		= edfbury,
	.edfanyready	= edfanyready,
	.edfready		= edfready,
	.edfrunproc	= edfrunproc,
	.edfblock		= edfblock,
	.edfinit		= edfinit,
	.edfexpel		= edfexpel,
	.edfadmit		= edfadmit,
	.edfdeadline	= edfdeadline,
};

M port/portclock.c => port/portclock.c +1 -1
@@ 122,7 122,7 @@ hzclock(Ureg *ur)
		return;

	/* i.e. don't deschedule an EDF process here! */
	if(anyready() && !isedf(up)){
	if(anyready() && !edf->isedf(up)){
		sched();
		splhi();
	}

M port/portdat.h => port/portdat.h +16 -0
@@ 6,6 6,7 @@ typedef struct Cmdtab	Cmdtab;
typedef struct Cname	Cname;
typedef struct Dev	Dev;
typedef struct Dirtab	Dirtab;
typedef struct Edfinterface	Edfinterface;
typedef struct Egrp	Egrp;
typedef struct Evalue	Evalue;
typedef struct Fgrp	Fgrp;


@@ 846,6 847,21 @@ struct Timer
	ulong	period;
};

struct Edfinterface {
	int		(*isedf)(Proc*);
	void		(*edfbury)(Proc*);
	int		(*edfanyready)(void);
	void		(*edfready)(Proc*);
	Proc*	(*edfrunproc)(void);
	void		(*edfblock)(Proc*);
	void		(*edfinit)(void);
	void		(*edfexpel)(Task *t);
	char *	(*edfadmit)(Task *t);
	void		(*edfdeadline)(Proc *p);
};

extern Edfinterface *edf;

#define DEVDOTDOT -1

#pragma	varargck	argpos	print	1

M port/portfns.h => port/portfns.h +0 -12
@@ 87,17 87,6 @@ void		dumpstack(void);
Fgrp*		dupfgrp(Fgrp*);
void		duppage(Page*);
void		dupswap(Page*);
void		edfdeadline(Proc*);
void		edfrelease(Task*);
char*		edfadmit(Task*);
void		edfexpel(Task*);
void		edfbury(Proc*);
void		edfsched(Task*);
int		edfanyready(void);
void		edfready(Proc*);
Proc*		edfrunproc(void);
void		edfblock(Proc*);
void		edfinit(void);
int		emptystr(char*);
int		encrypt(void*, void*, int);
void		envcpy(Egrp*, Egrp*);


@@ 140,7 129,6 @@ int		incref(Ref*);
void		initseg(void);
int		iprint(char*, ...);
void		isdir(Chan*);
int		isedf(Proc*);
int		iseve(void);
int		islo(void);
Segment*	isoverlap(Proc*, ulong, int);

M port/proc.c => port/proc.c +18 -14
@@ 22,6 22,10 @@ static struct Procalloc

static Schedq	runq[Nrq];

extern Edfinterface	nulledf;

Edfinterface *edf = &nulledf;

char *statename[] =
{	/* BUG: generate automatically */
	"Dead",


@@ 57,8 61,8 @@ schedinit(void)		/* never returns */
			break;
		case Moribund:
			up->state = Dead;
			if (isedf(up))
				edfbury(up);
			if (edf->isedf(up))
				edf->edfbury(up);

			/*
			 * Holding locks from pexit:


@@ 122,7 126,7 @@ sched(void)
int
anyready(void)
{
	return nrdy || edfanyready();
	return nrdy || edf->edfanyready();
}

int


@@ 153,8 157,8 @@ ready(Proc *p)

	s = splhi();

	if(isedf(p)){
		edfready(p);
	if(edf->isedf(p)){
		edf->edfready(p);
		splx(s);
		return;
	}


@@ 208,7 212,7 @@ runproc(void)
	Proc *p, *l;
	ulong rt;

	if ((p = edfrunproc()) != nil)
	if ((p = edf->edfrunproc()) != nil)
		return p;

loop:


@@ 503,8 507,8 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
			unlock(r);
			// Behind unlock, we may call wakeup on ourselves.

			if (isedf(up))
				edfblock(up);
			if (edf->isedf(up))
				edf->edfblock(up);

			gotolabel(&m->sched);
		}


@@ 713,8 717,8 @@ addbroken(Proc *p)
	broken.p[broken.n++] = p;
	qunlock(&broken);

	if (isedf(up))
		edfbury(up);
	if (edf->isedf(up))
		edf->edfbury(up);
	p->state = Broken;
	p->psstate = 0;
	sched();


@@ 884,8 888,8 @@ pexit(char *exitstr, int freemem)
	lock(&procalloc);
	lock(&palloc);

	if (isedf(up))
		edfbury(up);
	if (edf->isedf(up))
		edf->edfbury(up);
	up->state = Moribund;
	sched();
	panic("pexit");


@@ 1139,8 1143,8 @@ procctl(Proc *p)
		qunlock(&p->debug);
		splhi();
		p->state = Stopped;
		if (isedf(up))
			edfblock(up);
		if (edf->isedf(up))
			edf->edfblock(up);
		sched();
		p->psstate = state;
		splx(s);

M port/qlock.c => port/qlock.c +6 -6
@@ 43,8 43,8 @@ qlock(QLock *q)
	up->state = Queueing;
	up->qpc = getcallerpc(&q);
	unlock(&q->use);
	if(isedf(up))
		edfblock(up);
	if(edf->isedf(up))
		edf->edfblock(up);
	sched();
}



@@ 107,8 107,8 @@ rlock(RWlock *q)
	up->qnext = 0;
	up->state = QueueingR;
	unlock(&q->use);
	if (isedf(up))
		edfblock(up);
	if (edf->isedf(up))
		edf->edfblock(up);
	sched();
}



@@ 164,8 164,8 @@ wlock(RWlock *q)
	up->qnext = 0;
	up->state = QueueingW;
	unlock(&q->use);
	if (isedf(up))
		edfblock(up);
	if (edf->isedf(up))
		edf->edfblock(up);
	sched();
}


M port/sysproc.c => port/sysproc.c +2 -2
@@ 839,8 839,8 @@ sysrendezvous(ulong *arg)
	*l = up;
	up->state = Rendezvous;
	unlock(up->rgrp);
	if (isedf(up))
		edfblock(up);
	if (edf->isedf(up))
		edf->edfblock(up);

	sched();