From 94d5d66d86a1e53ec3173d65c73d030e729e235d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 26 Jul 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-07-26 --- ip/rudp.c | 86 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/ip/rudp.c b/ip/rudp.c index 84d3439651b3c63c7769c2a7680bd2b1ee484c92..9803a758331a4a8891225988cfb1cbd2bb14dbbf 100644 --- a/ip/rudp.c +++ b/ip/rudp.c @@ -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); }