~kris/9p

9hist

94d5d66d86a1e53ec3173d65c73d030e729e235d — David du Colombier 28 years ago 21c56d2
Plan 9 from Bell Labs 1998-07-26
1 files changed, 58 insertions(+), 28 deletions(-)

M ip/rudp.c
M ip/rudp.c => ip/rudp.c +58 -28
@@ 8,7 8,8 @@

#include	"ip.h"

#define DPRINT if(1)print
#define DEBUG	0
#define DPRINT if(DEBUG)print

enum
{


@@ 22,7 23,7 @@ enum

	Rudprxms	= 200,
	Rudptickms	= 100,
	Rudpmaxxmit	= 1,
	Rudpmaxxmit	= 10,

};



@@ 105,20 106,27 @@ struct Rudpstats
typedef struct Rudppriv Rudppriv;
struct Rudppriv
{

	Rendez	vous;

	/* MIB counters */
	Rudpstats	ustats;

	/* non-MIB stats */
	ulong		csumerr;		/* checksum errors */
	ulong		lenerr;			/* short packet */
	ulong	csumerr;		/* checksum errors */
	ulong	lenerr;			/* short packet */
	ulong	rxmits;			/* # of retransmissions */
	ulong	orders;			/* # of out of order pkts */

};


static ulong generation = 0;
static Rendez rend;

/* Used only for debugging */
static ushort drop = 0;
static ushort drop_rate = 10;

/*
 *  protocol specific part of Conv
 */


@@ 135,7 143,7 @@ struct Rudpcb
 */
void	relsendack( Conv *, Reliable * );
int	reliput( Conv *, Block *, uchar *, ushort );
Reliable *relstate( Rudpcb *, uchar *, ushort );
Reliable *relstate( Rudpcb *, uchar *, ushort, char *from );
void	relackproc( void * );
void	relackq( Reliable *, Block * );
void	relhangup( Conv *, Reliable * );


@@ 157,7 165,7 @@ static int
rudpstate(Conv *c, char *state, int n)
{
	USED(c);
	return snprint(state, n, "%s", "Reliable UDP");
	return snprint(state, n, "%s", "Reliable UDP V0.1");
}

static char*


@@ 264,7 272,9 @@ rudpkick(Conv *c, int)
		bp->rp += 4;			/* Igonore local port */
		break;
	default:
		rport = 0;
		ipmove( raddr, c->raddr );
		ipmove( laddr, c->laddr );
		rport = c->rport;

		break;
	}


@@ 280,6 290,7 @@ rudpkick(Conv *c, int)

	rh = &(uh->rhdr);


	ptcllen = dlen + (RUDP_HDRSIZE-RUDP_PHDRSIZE);
	uh->Unused = 0;
	uh->rudpproto = IP_RUDPPROTO;


@@ 308,7 319,7 @@ rudpkick(Conv *c, int)


	qlock( ucb );
	r = relstate( ucb, raddr, rport );
	r = relstate( ucb, raddr, rport, "kick" );
	r->sndseq++;
	hnputl( rh->relseq, r->sndseq );
	hnputl( rh->relsgen, r->sndgen );


@@ 328,8 339,8 @@ rudpkick(Conv *c, int)



	DPRINT( "sent: %d/%d, %d/%d\n", 
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen );
	DPRINT( "sent: %d/%d, %d/%d, r->sndgen = %d\n", 
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen );

	ipoput(f, bp, 0, c->ttl);
}


@@ 372,6 383,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)
	if(nhgets(uh->rudpcksum)) {
		if(ptclcsum(bp, RUDP_IPHDR, len+RUDP_PHDRSIZE)) {
			upriv->ustats.rudpInErrors++;
			upriv->csumerr++;
			netlog(f, Logrudp, "rudp: checksum error %I\n", raddr);
			DPRINT("rudp: checksum error %I\n", raddr);
			freeblist(bp);


@@ 537,11 549,13 @@ rudpstats(Proto *rudp, char *buf, int len)
	Rudppriv *upriv;

	upriv = rudp->priv;
	return snprint(buf, len, "%d %d %d %d\n",
	return snprint(buf, len, "%d %d %d %d %d %d\n",
		upriv->ustats.rudpInDatagrams,
		upriv->ustats.rudpNoPorts,
		upriv->ustats.rudpInErrors,
		upriv->ustats.rudpOutDatagrams);
		upriv->ustats.rudpOutDatagrams,
		upriv->rxmits,
		upriv->orders);
}

void


@@ 569,7 583,7 @@ rudpinit(Fs *fs)

	Fsproto(fs, rudp);

	kproc( "relackproc", relackproc, rudp );
	kproc("relackproc", relackproc, rudp);
	
}



@@ 607,18 621,20 @@ relackproc(void *a)
	Proto *rudp;
	Reliable *r;
	Conv **s, *c;
	Rudppriv *upriv;

	rudp = (Proto *)a;
	upriv = rudp->priv;

loop:
	tsleep(&rend, return0, 0, Rudptickms);
	tsleep(&upriv->vous, return0, 0, Rudptickms);

	for(s = rudp->conv; *s; s++) {
		c = *s;
		ucb = (Rudpcb*)c->ptcl;
		qlock( ucb );

		for(r = ucb->r; r; r = r->next){
		qlock(ucb);

		for(r = ucb->r; r; r = r->next) {
			if(r->unacked != nil){
				r->timeout += Rudptickms;
				if(r->timeout > Rudprxms*r->xmits)


@@ 627,7 643,7 @@ loop:
			if(r->acksent < r->rcvseq)
				relsendack(c, r);
		}
		qunlock( ucb );
		qunlock(ucb);
	}
	goto loop;
}


@@ 636,11 652,12 @@ loop:
 *  get the state record for a conversation
 */
Reliable*
relstate(Rudpcb *ucb, uchar *addr, ushort port)
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from )
{
	Reliable *r, **l;



	l = &ucb->r;
	for(r = *l; r; r = *l){
		if( memcmp( addr, r->addr, IPaddrlen) == 0 && 


@@ 651,9 668,10 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port)

	/* no state for this addr/port, create some */
	if(r == nil){
		DPRINT( "new state %d\n", generation );
		if(generation == 0)
			generation = TK2SEC(MACHP(0)->ticks);
		DPRINT( "from %s new state %d for %I!%d\n", 
		        from, generation, addr, port );
		r = smalloc( sizeof( Reliable ) );
		*l = r;
		memmove( r->addr, addr, IPaddrlen);


@@ 682,6 700,7 @@ reliput(Conv *c, Block *bp, uchar *addr, ushort port)
{
	Block *nbp;
	Rudpcb *ucb;
	Rudppriv *upriv;
	Rudphdr *uh;
	Reliable *r;
	Relhdr *rh;


@@ 698,22 717,22 @@ reliput(Conv *c, Block *bp, uchar *addr, ushort port)
	agen = nhgetl(rh->relagen);



	upriv = c->p->priv;
	ucb = (Rudpcb*)c->ptcl;
	r = relstate(ucb, addr, port);
	r = relstate(ucb, addr, port, "input" );
	

	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d, r->ackrcvd = %d\n", 
		seq, sgen, ack, agen, r->sndgen, r->ackrcvd);
	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n", 
		seq, sgen, ack, agen, r->sndgen);

	/* dequeue acked packets */
	if(ack && agen == r->sndgen){
		DPRINT( "Here\n" );
		ackreal = 0;
		while(r->unacked != nil && ack > r->ackrcvd){
			nbp = r->unacked;
			r->unacked = nbp->list;
			DPRINT("%d/%d acked\n", ack, agen);
			DPRINT("%d/%d acked, r->sndgen = %d\n", 
			       ack, agen, r->sndgen);
			freeb(nbp);
			r->ackrcvd++;
			ackreal = 1;


@@ 751,8 770,15 @@ reliput(Conv *c, Block *bp, uchar *addr, ushort port)
	if(seq == 0)
		return -1;

	if( DEBUG && ++drop == drop_rate ){
		DPRINT( "drop pkt on purpose\n" );
		drop = 0;
		return -1;
	}

	/* refuse out of order delivery */
	if(seq != r->rcvseq + 1){
		upriv->orders++;
		DPRINT("out of sequence %d not %d\n", seq, r->rcvseq + 1);
		return -1;
	}


@@ 846,8 872,11 @@ relhangup( Conv *, Reliable *r )
void
relrexmit(Conv *c, Reliable *r)
{
	Rudppriv *upriv;
	Block *np;
	Fs *f;

	upriv = c->p->priv;
	f = c->p->f;
	r->timeout = 0;
	if(r->xmits++ > Rudpmaxxmit){


@@ 855,7 884,8 @@ relrexmit(Conv *c, Reliable *r)
		return;
	}

	upriv->rxmits++;
	np = copyblock(r->unacked, blocklen(r->unacked));
	//DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1);
	DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1);
	ipoput(f, np, 0, c->ttl);
}