plan 9 kernel history: overview | file list | diff list

ip/rudp.c (diff list | history)

1998/0630/sys/src/9/ip/rudp.c:8,141998/0726/sys/src/9/ip/rudp.c:8,15 (short | long)
1998/0630    
 
#include	"ip.h" 
 
#define DPRINT if(1)print 
1998/0726    
#define DEBUG	0 
#define DPRINT if(DEBUG)print 
1998/0630    
 
enum 
{ 
1998/0630/sys/src/9/ip/rudp.c:22,281998/0726/sys/src/9/ip/rudp.c:23,29
1998/0630    
 
	Rudprxms	= 200, 
	Rudptickms	= 100, 
	Rudpmaxxmit	= 1, 
1998/0726    
	Rudpmaxxmit	= 10, 
1998/0630    
 
}; 
 
1998/0630/sys/src/9/ip/rudp.c:105,1181998/0726/sys/src/9/ip/rudp.c:106,121
1998/0630    
typedef struct Rudppriv Rudppriv; 
struct Rudppriv 
{ 
1998/0726    
	Rendez	vous; 
1998/0630    
 
                 
	/* MIB counters */ 
	Rudpstats	ustats; 
 
	/* non-MIB stats */ 
	ulong		csumerr;		/* checksum errors */ 
	ulong		lenerr;			/* short packet */ 
1998/0726    
	ulong	csumerr;		/* checksum errors */ 
	ulong	lenerr;			/* short packet */ 
	ulong	rxmits;			/* # of retransmissions */ 
	ulong	orders;			/* # of out of order pkts */ 
1998/0630    
 
}; 
 
1998/0630/sys/src/9/ip/rudp.c:119,1241998/0726/sys/src/9/ip/rudp.c:122,132
1998/0630    
 
static ulong generation = 0; 
static Rendez rend; 
1998/0726    
 
/* Used only for debugging */ 
static ushort drop = 0; 
static ushort drop_rate = 10; 
 
1998/0630    
/* 
 *  protocol specific part of Conv 
 */ 
1998/0630/sys/src/9/ip/rudp.c:135,1411998/0726/sys/src/9/ip/rudp.c:143,149
1998/0630    
 */ 
void	relsendack( Conv *, Reliable * ); 
int	reliput( Conv *, Block *, uchar *, ushort ); 
Reliable *relstate( Rudpcb *, uchar *, ushort ); 
1998/0726    
Reliable *relstate( Rudpcb *, uchar *, ushort, char *from ); 
1998/0630    
void	relackproc( void * ); 
void	relackq( Reliable *, Block * ); 
void	relhangup( Conv *, Reliable * ); 
1998/0630/sys/src/9/ip/rudp.c:157,1631998/0726/sys/src/9/ip/rudp.c:165,171
1998/0630    
rudpstate(Conv *c, char *state, int n) 
{ 
	USED(c); 
	return snprint(state, n, "%s", "Reliable UDP"); 
1998/0726    
	return snprint(state, n, "%s", "Reliable UDP V0.1"); 
1998/0630    
} 
 
static char* 
1998/0630/sys/src/9/ip/rudp.c:264,2701998/0726/sys/src/9/ip/rudp.c:272,280
1998/0630    
		bp->rp += 4;			/* Igonore local port */ 
		break; 
	default: 
		rport = 0; 
1998/0726    
		ipmove( raddr, c->raddr ); 
		ipmove( laddr, c->laddr ); 
		rport = c->rport; 
1998/0630    
 
		break; 
	} 
1998/0630/sys/src/9/ip/rudp.c:280,2851998/0726/sys/src/9/ip/rudp.c:290,296
1998/0630    
 
	rh = &(uh->rhdr); 
 
1998/0726    
 
1998/0630    
	ptcllen = dlen + (RUDP_HDRSIZE-RUDP_PHDRSIZE); 
	uh->Unused = 0; 
	uh->rudpproto = IP_RUDPPROTO; 
1998/0630/sys/src/9/ip/rudp.c:308,3141998/0726/sys/src/9/ip/rudp.c:319,325
1998/0630    
 
 
	qlock( ucb ); 
	r = relstate( ucb, raddr, rport ); 
1998/0726    
	r = relstate( ucb, raddr, rport, "kick" ); 
1998/0630    
	r->sndseq++; 
	hnputl( rh->relseq, r->sndseq ); 
	hnputl( rh->relsgen, r->sndgen ); 
1998/0630/sys/src/9/ip/rudp.c:328,3351998/0726/sys/src/9/ip/rudp.c:339,346
1998/0630    
 
 
 
	DPRINT( "sent: %d/%d, %d/%d\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen ); 
1998/0726    
	DPRINT( "sent: %d/%d, %d/%d, r->sndgen = %d\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen ); 
1998/0630    
 
	ipoput(f, bp, 0, c->ttl); 
} 
1998/0630/sys/src/9/ip/rudp.c:372,3771998/0726/sys/src/9/ip/rudp.c:383,389
1998/0630    
	if(nhgets(uh->rudpcksum)) { 
		if(ptclcsum(bp, RUDP_IPHDR, len+RUDP_PHDRSIZE)) { 
			upriv->ustats.rudpInErrors++; 
1998/0726    
			upriv->csumerr++; 
1998/0630    
			netlog(f, Logrudp, "rudp: checksum error %I\n", raddr); 
			DPRINT("rudp: checksum error %I\n", raddr); 
			freeblist(bp); 
1998/0630/sys/src/9/ip/rudp.c:537,5471998/0726/sys/src/9/ip/rudp.c:549,561
1998/0630    
	Rudppriv *upriv; 
 
	upriv = rudp->priv; 
	return snprint(buf, len, "%d %d %d %d\n", 
1998/0726    
	return snprint(buf, len, "%d %d %d %d %d %d\n", 
1998/0630    
		upriv->ustats.rudpInDatagrams, 
		upriv->ustats.rudpNoPorts, 
		upriv->ustats.rudpInErrors, 
		upriv->ustats.rudpOutDatagrams); 
1998/0726    
		upriv->ustats.rudpOutDatagrams, 
		upriv->rxmits, 
		upriv->orders); 
1998/0630    
} 
 
void 
1998/0630/sys/src/9/ip/rudp.c:569,5751998/0726/sys/src/9/ip/rudp.c:583,589
1998/0630    
 
	Fsproto(fs, rudp); 
 
	kproc( "relackproc", relackproc, rudp ); 
1998/0726    
	kproc("relackproc", relackproc, rudp); 
1998/0630    
	 
} 
 
1998/0630/sys/src/9/ip/rudp.c:607,6241998/0726/sys/src/9/ip/rudp.c:621,640
1998/0630    
	Proto *rudp; 
	Reliable *r; 
	Conv **s, *c; 
1998/0726    
	Rudppriv *upriv; 
1998/0630    
 
	rudp = (Proto *)a; 
1998/0726    
	upriv = rudp->priv; 
 
1998/0630    
loop: 
	tsleep(&rend, return0, 0, Rudptickms); 
1998/0726    
	tsleep(&upriv->vous, return0, 0, Rudptickms); 
1998/0630    
 
	for(s = rudp->conv; *s; s++) { 
		c = *s; 
		ucb = (Rudpcb*)c->ptcl; 
		qlock( ucb ); 
1998/0726    
		qlock(ucb); 
1998/0630    
 
		for(r = ucb->r; r; r = r->next){ 
                 
1998/0726    
		for(r = ucb->r; r; r = r->next) { 
1998/0630    
			if(r->unacked != nil){ 
				r->timeout += Rudptickms; 
				if(r->timeout > Rudprxms*r->xmits) 
1998/0630/sys/src/9/ip/rudp.c:627,6331998/0726/sys/src/9/ip/rudp.c:643,649
1998/0630    
			if(r->acksent < r->rcvseq) 
				relsendack(c, r); 
		} 
		qunlock( ucb ); 
1998/0726    
		qunlock(ucb); 
1998/0630    
	} 
	goto loop; 
} 
1998/0630/sys/src/9/ip/rudp.c:636,6461998/0726/sys/src/9/ip/rudp.c:652,663
1998/0630    
 *  get the state record for a conversation 
 */ 
Reliable* 
relstate(Rudpcb *ucb, uchar *addr, ushort port) 
1998/0726    
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from ) 
1998/0630    
{ 
	Reliable *r, **l; 
 
 
1998/0726    
 
1998/0630    
	l = &ucb->r; 
	for(r = *l; r; r = *l){ 
		if( memcmp( addr, r->addr, IPaddrlen) == 0 &&  
1998/0630/sys/src/9/ip/rudp.c:651,6591998/0726/sys/src/9/ip/rudp.c:668,677
1998/0630    
 
	/* 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); 
1998/0726    
		DPRINT( "from %s new state %d for %I!%d\n",  
		        from, generation, addr, port ); 
1998/0630    
		r = smalloc( sizeof( Reliable ) ); 
		*l = r; 
		memmove( r->addr, addr, IPaddrlen); 
1998/0630/sys/src/9/ip/rudp.c:682,6871998/0726/sys/src/9/ip/rudp.c:700,706
1998/0630    
{ 
	Block *nbp; 
	Rudpcb *ucb; 
1998/0726    
	Rudppriv *upriv; 
1998/0630    
	Rudphdr *uh; 
	Reliable *r; 
	Relhdr *rh; 
1998/0630/sys/src/9/ip/rudp.c:698,7191998/0726/sys/src/9/ip/rudp.c:717,738
1998/0630    
	agen = nhgetl(rh->relagen); 
 
 
                 
1998/0726    
	upriv = c->p->priv; 
1998/0630    
	ucb = (Rudpcb*)c->ptcl; 
	r = relstate(ucb, addr, port); 
1998/0726    
	r = relstate(ucb, addr, port, "input" ); 
1998/0630    
	 
 
	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d, r->ackrcvd = %d\n",  
		seq, sgen, ack, agen, r->sndgen, r->ackrcvd); 
1998/0726    
	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n",  
		seq, sgen, ack, agen, r->sndgen); 
1998/0630    
 
	/* 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); 
1998/0726    
			DPRINT("%d/%d acked, r->sndgen = %d\n",  
			       ack, agen, r->sndgen); 
1998/0630    
			freeb(nbp); 
			r->ackrcvd++; 
			ackreal = 1; 
1998/0630/sys/src/9/ip/rudp.c:751,7581998/0726/sys/src/9/ip/rudp.c:770,784
1998/0630    
	if(seq == 0) 
		return -1; 
 
1998/0726    
	if( DEBUG && ++drop == drop_rate ){ 
		DPRINT( "drop pkt on purpose\n" ); 
		drop = 0; 
		return -1; 
	} 
 
1998/0630    
	/* refuse out of order delivery */ 
	if(seq != r->rcvseq + 1){ 
1998/0726    
		upriv->orders++; 
1998/0630    
		DPRINT("out of sequence %d not %d\n", seq, r->rcvseq + 1); 
		return -1; 
	} 
1998/0630/sys/src/9/ip/rudp.c:846,8531998/0726/sys/src/9/ip/rudp.c:872,882
1998/0630    
void 
relrexmit(Conv *c, Reliable *r) 
{ 
1998/0726    
	Rudppriv *upriv; 
1998/0630    
	Block *np; 
	Fs *f; 
1998/0726    
 
	upriv = c->p->priv; 
1998/0630    
	f = c->p->f; 
	r->timeout = 0; 
	if(r->xmits++ > Rudpmaxxmit){ 
1998/0630/sys/src/9/ip/rudp.c:855,8611998/0726/sys/src/9/ip/rudp.c:884,891
1998/0630    
		return; 
	} 
 
1998/0726    
	upriv->rxmits++; 
1998/0630    
	np = copyblock(r->unacked, blocklen(r->unacked)); 
	//DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1); 
1998/0726    
	DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1); 
1998/0630    
	ipoput(f, np, 0, c->ttl); 
} 
1998/0726/sys/src/9/ip/rudp.c:1,41998/0728/sys/src/9/ip/rudp.c:1,7 (short | long)
1998/0630    
                 
1998/0728    
/* 
 *  This protocol is compatible with UDP's packet format. 
 *  It could be done over UDP if need be. 
 */ 
1998/0630    
#include	"u.h" 
#include	"../port/lib.h" 
#include	"mem.h" 
1998/0726/sys/src/9/ip/rudp.c:13,251998/0728/sys/src/9/ip/rudp.c:16,28
1998/0630    
 
enum 
{ 
	RUDP_PHDRSIZE	= 12, 
	RUDP_HDRSIZE	= 36, 
	RUDP_RHDRSIZE	= 16, 
	RUDP_IPHDR	= 8, 
	IP_RUDPPROTO	= 254, 
	RUDP_USEAD6	= 36, 
	RUDP_USEAD4	= 12, 
1998/0728    
	UDP_HDRSIZE	= 20,	/* pseudo header + udp header */ 
	UDP_PHDRSIZE	= 12,	/* pseudo header */ 
	UDP_RHDRSIZE	= 36,	/* pseudo header + udp header + rudp header */ 
	UDP_IPHDR	= 8,	/* ip header */ 
	IP_UDPPROTO	= 254, 
	UDP_USEAD6	= 36, 
	UDP_USEAD4	= 12, 
1998/0630    
 
	Rudprxms	= 200, 
	Rudptickms	= 100, 
1998/0726/sys/src/9/ip/rudp.c:27,421998/0728/sys/src/9/ip/rudp.c:30,57
1998/0630    
 
}; 
 
/* 
 *  reliable header 
 */ 
typedef struct Relhdr Relhdr; 
struct Relhdr 
1998/0728    
typedef struct Udphdr Udphdr; 
struct Udphdr 
1998/0630    
{ 
	uchar	relseq[4];	/* id of this packet (or 0) */ 
	uchar	relsgen[4];	/* generation/time stamp */ 
	uchar	relack[4];	/* packet being acked (or 0) */ 
	uchar	relagen[4];	/* generation/time stamp */ 
1998/0728    
	/* ip header */ 
	uchar	vihl;		/* Version and header length */ 
	uchar	tos;		/* Type of service */ 
	uchar	length[2];	/* packet length */ 
	uchar	id[2];		/* Identification */ 
	uchar	frag[2];	/* Fragment information */ 
 
	/* pseudo header starts here */ 
	uchar	Unused; 
	uchar	udpproto;	/* Protocol */ 
	uchar	udpplen[2];	/* Header plus data length */ 
	uchar	udpsrc[4];	/* Ip source */ 
	uchar	udpdst[4];	/* Ip destination */ 
 
	/* udp header */ 
	uchar	udpsport[2];	/* Source port */ 
	uchar	udpdport[2];	/* Destination port */ 
	uchar	udplen[2];	/* data length */ 
	uchar	udpcksum[2];	/* Checksum */ 
1998/0630    
}; 
 
typedef struct Rudphdr Rudphdr; 
1998/0726/sys/src/9/ip/rudp.c:48,651998/0728/sys/src/9/ip/rudp.c:63,87
1998/0630    
	uchar	length[2];	/* packet length */ 
	uchar	id[2];		/* Identification */ 
	uchar	frag[2];	/* Fragment information */ 
	uchar	Unused;	 
	uchar	rudpproto;	/* Protocol */ 
	uchar	rudpplen[2];	/* Header plus data length */ 
	uchar	rudpsrc[4];	/* Ip source */ 
	uchar	rudpdst[4];	/* Ip destination */ 
 
1998/0728    
	/* pseudo header starts here */ 
	uchar	Unused; 
	uchar	udpproto;	/* Protocol */ 
	uchar	udpplen[2];	/* Header plus data length */ 
	uchar	udpsrc[4];	/* Ip source */ 
	uchar	udpdst[4];	/* Ip destination */ 
 
	/* udp header */ 
	uchar	udpsport[2];	/* Source port */ 
	uchar	udpdport[2];	/* Destination port */ 
	uchar	udplen[2];	/* data length (includes rudp header) */ 
	uchar	udpcksum[2];	/* Checksum */ 
 
1998/0630    
	/* rudp header */ 
	uchar	rudpsport[2];	/* Source port */ 
	uchar	rudpdport[2];	/* Destination port */ 
	Relhdr	rhdr;		/* reliable header */ 
	uchar	rudplen[2];	/* data length */ 
	uchar	rudpcksum[2];	/* Checksum */ 
1998/0728    
	uchar	relseq[4];	/* id of this packet (or 0) */ 
	uchar	relsgen[4];	/* generation/time stamp */ 
	uchar	relack[4];	/* packet being acked (or 0) */ 
	uchar	relagen[4];	/* generation/time stamp */ 
1998/0630    
}; 
 
 
1998/0726/sys/src/9/ip/rudp.c:74,801998/0728/sys/src/9/ip/rudp.c:96,101
1998/0630    
	uchar addr[IPaddrlen];	/* always V6 when put here */ 
	ushort	port; 
 
                 
	Block	*unacked;	/* unacked msg list */ 
	Block	*unackedtail;	/*  and its tail */ 
 
1998/0726/sys/src/9/ip/rudp.c:141,1531998/0728/sys/src/9/ip/rudp.c:162,174
1998/0630    
/* 
 * local functions  
 */ 
void	relsendack( Conv *, Reliable * ); 
int	reliput( Conv *, Block *, uchar *, ushort ); 
1998/0726    
Reliable *relstate( Rudpcb *, uchar *, ushort, char *from ); 
1998/0630    
void	relackproc( void * ); 
void	relackq( Reliable *, Block * ); 
void	relhangup( Conv *, Reliable * ); 
void	relrexmit( Conv *, Reliable * ); 
1998/0728    
void	relsendack(Conv *, Reliable *); 
int	reliput(Conv *, Block *, uchar *, ushort); 
Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); 
void	relackproc(void *); 
void	relackq(Reliable *, Block *); 
void	relhangup(Conv *, Reliable *); 
void	relrexmit(Conv *, Reliable *); 
1998/0630    
 
static char* 
rudpconnect(Conv *c, char **argv, int argc) 
1998/0726/sys/src/9/ip/rudp.c:204,2181998/0728/sys/src/9/ip/rudp.c:225,239
1998/0630    
 
	ucb = (Rudpcb*)c->ptcl; 
	ucb->headers = 0; 
	qlock( ucb ); 
	for( r = ucb->r; r; r = nr ){ 
1998/0728    
	qlock(ucb); 
	for(r = ucb->r; r; r = nr){ 
1998/0630    
		nr = r->next; 
		relhangup( c, r ); 
		free( r ); 
1998/0728    
		relhangup(c, r); 
		free(r); 
1998/0630    
	} 
	ucb->r = 0; 
 
	qunlock( ucb ); 
1998/0728    
	qunlock(ucb); 
1998/0630    
 
	unlock(c); 
} 
1998/0726/sys/src/9/ip/rudp.c:220,2311998/0728/sys/src/9/ip/rudp.c:241,252
1998/0630    
void 
rudpkick(Conv *c, int) 
{ 
	Rudphdr *uh; 
1998/0728    
	Udphdr *uh; 
1998/0630    
	ushort rport; 
	uchar laddr[IPaddrlen], raddr[IPaddrlen]; 
	Block *bp; 
	Rudpcb *ucb; 
	Relhdr *rh; 
1998/0728    
	Rudphdr *rh; 
1998/0630    
	Reliable *r; 
	int dlen, ptcllen; 
	Rudppriv *upriv; 
1998/0726/sys/src/9/ip/rudp.c:243,2491998/0728/sys/src/9/ip/rudp.c:264,270
1998/0630    
	switch(ucb->headers) { 
	case 6: 
		/* get user specified addresses */ 
		bp = pullupblock(bp, RUDP_USEAD6); 
1998/0728    
		bp = pullupblock(bp, UDP_USEAD6); 
1998/0630    
		if(bp == nil) 
			return; 
		ipmove(raddr, bp->rp); 
1998/0726/sys/src/9/ip/rudp.c:258,2641998/0728/sys/src/9/ip/rudp.c:279,285
1998/0630    
		bp->rp += 4;			/* Igonore local port */ 
		break; 
	case 4: 
		bp = pullupblock(bp, RUDP_USEAD4); 
1998/0728    
		bp = pullupblock(bp, UDP_USEAD4); 
1998/0630    
		if(bp == nil) 
			return; 
		v4tov6(raddr, bp->rp); 
1998/0726/sys/src/9/ip/rudp.c:272,2791998/0728/sys/src/9/ip/rudp.c:293,300
1998/0630    
		bp->rp += 4;			/* Igonore local port */ 
		break; 
	default: 
1998/0726    
		ipmove( raddr, c->raddr ); 
		ipmove( laddr, c->laddr ); 
1998/0728    
		ipmove(raddr, c->raddr); 
		ipmove(laddr, c->laddr); 
1998/0726    
		rport = c->rport; 
1998/0630    
 
		break; 
1998/0726/sys/src/9/ip/rudp.c:282,3471998/0728/sys/src/9/ip/rudp.c:303,364
1998/0630    
	dlen = blocklen(bp); 
 
	/* Make space to fit rudp & ip header */ 
	bp = padblock(bp, RUDP_IPHDR+RUDP_HDRSIZE); 
1998/0728    
	bp = padblock(bp, UDP_IPHDR+UDP_RHDRSIZE); 
1998/0630    
	if(bp == nil) 
		return; 
 
	uh = (Rudphdr *)(bp->rp); 
1998/0728    
	uh = (Udphdr *)(bp->rp); 
1998/0630    
 
	rh = &(uh->rhdr); 
1998/0728    
	rh = (Rudphdr*)uh; 
1998/0630    
 
1998/0726    
                 
1998/0630    
	ptcllen = dlen + (RUDP_HDRSIZE-RUDP_PHDRSIZE); 
1998/0728    
	ptcllen = dlen + (UDP_RHDRSIZE-UDP_PHDRSIZE); 
1998/0630    
	uh->Unused = 0; 
	uh->rudpproto = IP_RUDPPROTO; 
1998/0728    
	uh->udpproto = IP_UDPPROTO; 
1998/0630    
	uh->frag[0] = 0; 
	uh->frag[1] = 0; 
	hnputs(uh->rudpplen, ptcllen); 
1998/0728    
	hnputs(uh->udpplen, ptcllen); 
1998/0630    
	switch(ucb->headers){ 
	case 4: 
	case 6: 
		v6tov4(uh->rudpdst, raddr); 
		hnputs(uh->rudpdport, rport); 
		v6tov4(uh->rudpsrc, laddr); 
1998/0728    
		v6tov4(uh->udpdst, raddr); 
		hnputs(uh->udpdport, rport); 
		v6tov4(uh->udpsrc, laddr); 
1998/0630    
		break; 
	default: 
		v6tov4(uh->rudpdst, c->raddr); 
		hnputs(uh->rudpdport, c->rport); 
1998/0728    
		v6tov4(uh->udpdst, c->raddr); 
		hnputs(uh->udpdport, c->rport); 
1998/0630    
		if(ipcmp(c->laddr, IPnoaddr) == 0) 
			findlocalip(f, c->laddr, c->raddr); 
		v6tov4(uh->rudpsrc, c->laddr); 
1998/0728    
		v6tov4(uh->udpsrc, c->laddr); 
1998/0630    
		break; 
	} 
	hnputs(uh->rudpsport, c->lport); 
	hnputs(uh->rudplen, ptcllen); 
	uh->rudpcksum[0] = 0; 
	uh->rudpcksum[1] = 0; 
1998/0728    
	hnputs(uh->udpsport, c->lport); 
	hnputs(uh->udplen, ptcllen); 
	uh->udpcksum[0] = 0; 
	uh->udpcksum[1] = 0; 
1998/0630    
 
                 
	qlock( ucb ); 
1998/0726    
	r = relstate( ucb, raddr, rport, "kick" ); 
1998/0728    
	qlock(ucb); 
	r = relstate(ucb, raddr, rport, "kick"); 
1998/0630    
	r->sndseq++; 
	hnputl( rh->relseq, r->sndseq ); 
	hnputl( rh->relsgen, r->sndgen ); 
1998/0728    
	hnputl(rh->relseq, r->sndseq); 
	hnputl(rh->relsgen, r->sndgen); 
1998/0630    
 
	hnputl( rh->relack, r->rcvseq );  /* ACK last rcvd packet */ 
	hnputl( rh->relagen, r->rcvgen ); 
1998/0728    
	hnputl(rh->relack, r->rcvseq);  /* ACK last rcvd packet */ 
	hnputl(rh->relagen, r->rcvgen); 
1998/0630    
 
	if(r->rcvseq < r->acksent) 
		r->acksent = r->rcvseq; 
 
	hnputs(uh->rudpcksum, ptclcsum(bp, RUDP_IPHDR, dlen+RUDP_HDRSIZE)); 
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); 
1998/0630    
 
	relackq( r, bp ); 
	qunlock( ucb ); 
1998/0728    
	relackq(r, bp); 
	qunlock(ucb); 
1998/0630    
 
	upriv->ustats.rudpOutDatagrams++; 
 
1998/0728    
	DPRINT("sent: %d/%d, %d/%d, r->sndgen = %d\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen); 
1998/0630    
 
                 
1998/0726    
	DPRINT( "sent: %d/%d, %d/%d, r->sndgen = %d\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen ); 
1998/0630    
                 
	ipoput(f, bp, 0, c->ttl); 
} 
 
1998/0726/sys/src/9/ip/rudp.c:349,3551998/0728/sys/src/9/ip/rudp.c:366,372
1998/0630    
rudpiput(Proto *rudp, uchar *ia, Block *bp) 
{ 
	int len, olen, ottl; 
	Rudphdr *uh; 
1998/0728    
	Udphdr *uh; 
1998/0630    
	Conv *c, **p; 
	Rudpcb *ucb; 
	uchar raddr[IPaddrlen], laddr[IPaddrlen]; 
1998/0726/sys/src/9/ip/rudp.c:362,3681998/0728/sys/src/9/ip/rudp.c:379,385
1998/0630    
 
	upriv->ustats.rudpInDatagrams++; 
 
	uh = (Rudphdr*)(bp->rp); 
1998/0728    
	uh = (Udphdr*)(bp->rp); 
1998/0630    
 
	/* Put back pseudo header for checksum  
	 * (remember old values for icmpnoconv())  
1998/0726/sys/src/9/ip/rudp.c:369,3871998/0728/sys/src/9/ip/rudp.c:386,402
1998/0630    
	 */ 
	ottl = uh->Unused; 
	uh->Unused = 0; 
	len = nhgets(uh->rudplen); 
	olen = nhgets(uh->rudpplen); 
	hnputs(uh->rudpplen, len); 
1998/0728    
	len = nhgets(uh->udplen); 
	olen = nhgets(uh->udpplen); 
	hnputs(uh->udpplen, len); 
1998/0630    
 
	v4tov6(raddr, uh->rudpsrc); 
	v4tov6(laddr, uh->rudpdst); 
	lport = nhgets(uh->rudpdport); 
	rport = nhgets(uh->rudpsport); 
1998/0728    
	v4tov6(raddr, uh->udpsrc); 
	v4tov6(laddr, uh->udpdst); 
	lport = nhgets(uh->udpdport); 
	rport = nhgets(uh->udpsport); 
1998/0630    
 
                 
                 
	if(nhgets(uh->rudpcksum)) { 
		if(ptclcsum(bp, RUDP_IPHDR, len+RUDP_PHDRSIZE)) { 
1998/0728    
	if(nhgets(uh->udpcksum)) { 
		if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) { 
1998/0630    
			upriv->ustats.rudpInErrors++; 
1998/0726    
			upriv->csumerr++; 
1998/0630    
			netlog(f, Logrudp, "rudp: checksum error %I\n", raddr); 
1998/0726/sys/src/9/ip/rudp.c:397,4041998/0728/sys/src/9/ip/rudp.c:412,430
1998/0630    
		c = *p; 
		if(c->inuse == 0) 
			continue; 
		if(c->lport == lport && (c->rport == 0 || c->rport == rport)) 
			break; 
1998/0728    
		if(c->lport == lport){ 
			ucb = (Rudpcb*)c->ptcl; 
 
			/* with headers turned on, descriminate only on local port */ 
			if(ucb->headers) 
				break; 
 
			/* otherwise discriminate on lport, rport, and raddr */ 
			if(c->rport == 0 || c->rport == rport) 
			if(ipisbm(c->raddr) || ipcmp(c->raddr, IPnoaddr) == 0 
			   || ipcmp(c->raddr, raddr) == 0) 
				break; 
		} 
1998/0630    
	} 
 
	if(*p == nil) { 
1998/0726/sys/src/9/ip/rudp.c:405,4141998/0728/sys/src/9/ip/rudp.c:431,440
1998/0630    
		upriv->ustats.rudpNoPorts++; 
		netlog(f, Logrudp, "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
			laddr, lport); 
		DPRINT( "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
1998/0728    
		DPRINT("rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
1998/0630    
			laddr, lport); 
		uh->Unused = ottl; 
		hnputs(uh->rudpplen, olen); 
1998/0728    
		hnputs(uh->udpplen, olen); 
1998/0630    
		icmpnoconv(f, bp); 
		freeblist(bp); 
		return; 
1998/0726/sys/src/9/ip/rudp.c:416,4251998/0728/sys/src/9/ip/rudp.c:442,451
1998/0630    
 
	ucb = (Rudpcb*)c->ptcl; 
 
	qlock( ucb ); 
	if( reliput( c, bp, raddr, rport ) < 0 ){ 
		qunlock( ucb ); 
		freeb( bp ); 
1998/0728    
	qlock(ucb); 
	if(reliput(c, bp, raddr, rport) < 0){ 
		qunlock(ucb); 
		freeb(bp); 
1998/0630    
		return; 
	} 
 
1998/0726/sys/src/9/ip/rudp.c:427,4381998/0728/sys/src/9/ip/rudp.c:453,464
1998/0630    
	 * Trim the packet down to data size 
	 */ 
 
	len -= (RUDP_HDRSIZE-RUDP_PHDRSIZE); 
	bp = trimblock(bp, RUDP_IPHDR+RUDP_HDRSIZE, len); 
1998/0728    
	len -= (UDP_RHDRSIZE-UDP_PHDRSIZE); 
	bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len); 
1998/0630    
	if(bp == nil){ 
		netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n",  
			raddr, rport, laddr, lport); 
		DPRINT( "rudp: len err %I.%d -> %I.%d\n",  
1998/0728    
		DPRINT("rudp: len err %I.%d -> %I.%d\n",  
1998/0630    
			raddr, rport, laddr, lport); 
		upriv->lenerr++; 
		return; 
1998/0726/sys/src/9/ip/rudp.c:441,4521998/0728/sys/src/9/ip/rudp.c:467,476
1998/0630    
	netlog(f, Logrudpmsg, "rudp: %I.%d -> %I.%d l %d\n",  
		raddr, rport, laddr, lport, len); 
 
                 
                 
	switch(ucb->headers){ 
	case 6: 
		/* pass the src address */ 
		bp = padblock(bp, RUDP_USEAD6); 
1998/0728    
		bp = padblock(bp, UDP_USEAD6); 
1998/0630    
		ipmove(bp->rp, raddr); 
		if(ipforme(f, laddr) == Runi) 
			ipmove(bp->rp+IPaddrlen, laddr); 
1998/0726/sys/src/9/ip/rudp.c:457,4631998/0728/sys/src/9/ip/rudp.c:481,487
1998/0630    
		break; 
	case 4: 
		/* pass the src address */ 
		bp = padblock(bp, RUDP_USEAD4); 
1998/0728    
		bp = padblock(bp, UDP_USEAD4); 
1998/0630    
		v6tov4(bp->rp, raddr); 
		if(ipforme(f, laddr) == Runi) 
			v6tov4(bp->rp+IPv4addrlen, laddr); 
1998/0726/sys/src/9/ip/rudp.c:492,4981998/0728/sys/src/9/ip/rudp.c:516,522
1998/0630    
	else 
		qpass(c->rq, bp); 
	 
	qunlock( ucb ); 
1998/0728    
	qunlock(ucb); 
1998/0630    
} 
 
char* 
1998/0726/sys/src/9/ip/rudp.c:516,5321998/0728/sys/src/9/ip/rudp.c:540,556
1998/0630    
void 
rudpadvise(Proto *rudp, Block *bp, char *msg) 
{ 
	Rudphdr *h; 
1998/0728    
	Udphdr *h; 
1998/0630    
	uchar source[IPaddrlen], dest[IPaddrlen]; 
	ushort psource, pdest; 
	Conv *s, **p; 
 
	h = (Rudphdr*)(bp->rp); 
1998/0728    
	h = (Udphdr*)(bp->rp); 
1998/0630    
 
	v4tov6(dest, h->rudpdst); 
	v4tov6(source, h->rudpsrc); 
	psource = nhgets(h->rudpsport); 
	pdest = nhgets(h->rudpdport); 
1998/0728    
	v4tov6(dest, h->udpdst); 
	v4tov6(source, h->udpsrc); 
	psource = nhgets(h->udpsport); 
	pdest = nhgets(h->udpdport); 
1998/0630    
 
	/* Look for a connection */ 
	for(p = rudp->conv; *p; p++) { 
1998/0726/sys/src/9/ip/rudp.c:577,5831998/0728/sys/src/9/ip/rudp.c:601,607
1998/0630    
	rudp->rcv = rudpiput; 
	rudp->advise = rudpadvise; 
	rudp->stats = rudpstats; 
	rudp->ipproto = IP_RUDPPROTO; 
1998/0728    
	rudp->ipproto = IP_UDPPROTO; 
1998/0630    
	rudp->nc = 16; 
	rudp->ptclsize = sizeof(Rudpcb); 
 
1998/0726/sys/src/9/ip/rudp.c:652,6661998/0728/sys/src/9/ip/rudp.c:676,688
1998/0630    
 *  get the state record for a conversation 
 */ 
Reliable* 
1998/0726    
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from ) 
1998/0728    
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from) 
1998/0630    
{ 
	Reliable *r, **l; 
 
                 
1998/0726    
                 
1998/0630    
	l = &ucb->r; 
	for(r = *l; r; r = *l){ 
		if( memcmp( addr, r->addr, IPaddrlen) == 0 &&  
1998/0728    
		if(memcmp(addr, r->addr, IPaddrlen) == 0 &&  
1998/0630    
		    port == r->port) 
			break; 
		l = &r->next; 
1998/0726/sys/src/9/ip/rudp.c:670,6801998/0728/sys/src/9/ip/rudp.c:692,702
1998/0630    
	if(r == nil){ 
		if(generation == 0) 
			generation = TK2SEC(MACHP(0)->ticks); 
1998/0726    
		DPRINT( "from %s new state %d for %I!%d\n",  
		        from, generation, addr, port ); 
1998/0630    
		r = smalloc( sizeof( Reliable ) ); 
1998/0728    
		DPRINT("from %s new state %d for %I!%d\n",  
		        from, generation, addr, port); 
		r = smalloc(sizeof(Reliable)); 
1998/0630    
		*l = r; 
		memmove( r->addr, addr, IPaddrlen); 
1998/0728    
		memmove(r->addr, addr, IPaddrlen); 
1998/0630    
		r->port = port; 
		r->unacked = 0; 
		r->sndgen = generation++; 
1998/0726/sys/src/9/ip/rudp.c:701,7161998/0728/sys/src/9/ip/rudp.c:723,738
1998/0630    
	Block *nbp; 
	Rudpcb *ucb; 
1998/0726    
	Rudppriv *upriv; 
1998/0630    
	Rudphdr *uh; 
1998/0728    
	Udphdr *uh; 
1998/0630    
	Reliable *r; 
	Relhdr *rh; 
1998/0728    
	Rudphdr *rh; 
1998/0630    
	ulong seq, ack, sgen, agen, ackreal; 
 
 
 
	/* get fields */ 
	uh = (Rudphdr *)(bp->rp); 
	rh = &(uh->rhdr); 
1998/0728    
	uh = (Udphdr*)(bp->rp); 
	rh = (Rudphdr*)uh; 
1998/0630    
	seq = nhgetl(rh->relseq); 
	sgen = nhgetl(rh->relsgen); 
	ack = nhgetl(rh->relack); 
1998/0726/sys/src/9/ip/rudp.c:719,7251998/0728/sys/src/9/ip/rudp.c:741,747
1998/0630    
 
1998/0726    
	upriv = c->p->priv; 
1998/0630    
	ucb = (Rudpcb*)c->ptcl; 
1998/0726    
	r = relstate(ucb, addr, port, "input" ); 
1998/0728    
	r = relstate(ucb, addr, port, "input"); 
1998/0630    
	 
 
1998/0726    
	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n",  
1998/0726/sys/src/9/ip/rudp.c:770,7771998/0728/sys/src/9/ip/rudp.c:792,799
1998/0630    
	if(seq == 0) 
		return -1; 
 
1998/0726    
	if( DEBUG && ++drop == drop_rate ){ 
		DPRINT( "drop pkt on purpose\n" ); 
1998/0728    
	if(DEBUG && ++drop == drop_rate){ 
		DPRINT("drop pkt on purpose\n"); 
1998/0726    
		drop = 0; 
		return -1; 
	} 
1998/0726/sys/src/9/ip/rudp.c:790,8281998/0728/sys/src/9/ip/rudp.c:812,846
1998/0630    
void 
relsendack(Conv *c, Reliable *r) 
{ 
	Rudphdr *uh; 
1998/0728    
	Udphdr *uh; 
1998/0630    
	Block *bp; 
	Relhdr *rh; 
1998/0728    
	Rudphdr *rh; 
1998/0630    
	int ptcllen; 
	Fs *f; 
 
	bp = allocb(RUDP_IPHDR + RUDP_HDRSIZE); 
1998/0728    
	bp = allocb(UDP_IPHDR + UDP_RHDRSIZE); 
1998/0630    
	if(bp == nil) 
		return; 
	bp->wp += RUDP_IPHDR + RUDP_HDRSIZE; 
1998/0728    
	bp->wp += UDP_IPHDR + UDP_RHDRSIZE; 
1998/0630    
	f = c->p->f; 
	uh = (Rudphdr *)(bp->rp); 
	rh = &(uh->rhdr); 
1998/0728    
	uh = (Udphdr *)(bp->rp); 
	rh = (Rudphdr*)uh; 
1998/0630    
 
	ptcllen = (RUDP_HDRSIZE-RUDP_PHDRSIZE); 
1998/0728    
	ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE); 
1998/0630    
	uh->Unused = 0; 
	uh->rudpproto = IP_RUDPPROTO; 
1998/0728    
	uh->udpproto = IP_UDPPROTO; 
1998/0630    
	uh->frag[0] = 0; 
	uh->frag[1] = 0; 
	hnputs(uh->rudpplen, ptcllen); 
1998/0728    
	hnputs(uh->udpplen, ptcllen); 
1998/0630    
 
                 
                 
	v6tov4( uh->rudpdst, r->addr ); 
	hnputs(uh->rudpdport, r->port); 
	hnputs(uh->rudpsport, c->lport); 
1998/0728    
	v6tov4(uh->udpdst, r->addr); 
	hnputs(uh->udpdport, r->port); 
	hnputs(uh->udpsport, c->lport); 
1998/0630    
	if(ipcmp(c->laddr, IPnoaddr) == 0) 
		findlocalip(f, c->laddr, c->raddr); 
	v6tov4(uh->rudpsrc, c->laddr); 
	hnputs(uh->rudplen, ptcllen); 
1998/0728    
	v6tov4(uh->udpsrc, c->laddr); 
	hnputs(uh->udplen, ptcllen); 
1998/0630    
 
                 
                 
	hnputl(rh->relsgen, r->sndgen); 
	hnputl(rh->relseq, 0); 
	hnputl(rh->relagen, r->rcvgen); 
1998/0726/sys/src/9/ip/rudp.c:831,8411998/0728/sys/src/9/ip/rudp.c:849,859
1998/0630    
	if(r->acksent < r->rcvseq) 
		r->acksent = r->rcvseq; 
 
	uh->rudpcksum[0] = 0; 
	uh->rudpcksum[1] = 0; 
	hnputs(uh->rudpcksum, ptclcsum(bp, RUDP_IPHDR, RUDP_HDRSIZE)); 
1998/0728    
	uh->udpcksum[0] = 0; 
	uh->udpcksum[1] = 0; 
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); 
1998/0630    
 
	DPRINT( "sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen ); 
1998/0728    
	DPRINT("sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
	ipoput(f, bp, 0, c->ttl); 
} 
 
1998/0726/sys/src/9/ip/rudp.c:843,8491998/0728/sys/src/9/ip/rudp.c:861,867
1998/0630    
 *  called with ucb locked (and c locked if user initiated close) 
 */ 
void 
relhangup( Conv *, Reliable *r ) 
1998/0728    
relhangup(Conv *, Reliable *r) 
1998/0630    
{ 
	Block *bp; 
 
1998/0728/sys/src/9/ip/rudp.c:492,4981998/0731/sys/src/9/ip/rudp.c:492,498 (short | long)
1998/0630    
		break; 
	default: 
		/* connection oriented rudp */ 
		if(c->raddr == 0){ 
1998/0731    
		if(ipcmp(c->raddr, IPnoaddr) == 0){ 
1998/0630    
			/* save the src address in the conversation */ 
		 	ipmove(c->raddr, raddr); 
			c->rport = rport; 
1998/0728/sys/src/9/ip/rudp.c:691,6971998/0731/sys/src/9/ip/rudp.c:691,697
1998/0630    
	/* no state for this addr/port, create some */ 
	if(r == nil){ 
		if(generation == 0) 
			generation = TK2SEC(MACHP(0)->ticks); 
1998/0731    
			generation = rand(); 
1998/0728    
		DPRINT("from %s new state %d for %I!%d\n",  
		        from, generation, addr, port); 
		r = smalloc(sizeof(Reliable)); 
1998/0728/sys/src/9/ip/rudp.c:727,7341998/0731/sys/src/9/ip/rudp.c:727,732
1998/0630    
	Reliable *r; 
1998/0728    
	Rudphdr *rh; 
1998/0630    
	ulong seq, ack, sgen, agen, ackreal; 
                 
                 
 
	/* get fields */ 
1998/0728    
	uh = (Udphdr*)(bp->rp); 
1998/0731/sys/src/9/ip/rudp.c:14,191998/0801/sys/src/9/ip/rudp.c:14,28 (short | long)
1998/0726    
#define DEBUG	0 
#define DPRINT if(DEBUG)print 
1998/0630    
 
1998/0801    
#define SEQDIFF(a,b) ( (a)>=(b)?\ 
			(a)-(b):\ 
			0xffffffffUL-((b)-(a)) ) 
#define INSEQ(a,start,end) ( (start)<=(end)?\ 
				((a)>(start)&&(a)<=(end)):\ 
				((a)>(start)||(a)<=(end)) ) 
#define UNACKED(r) SEQDIFF(r->sndseq, r->ackrcvd) 
#define NEXTSEQ(a) ( (a)+1 == 0 ? 1 : (a)+1 ) 
 
1998/0630    
enum 
{ 
1998/0728    
	UDP_HDRSIZE	= 20,	/* pseudo header + udp header */ 
1998/0731/sys/src/9/ip/rudp.c:27,331998/0801/sys/src/9/ip/rudp.c:36,42
1998/0630    
	Rudprxms	= 200, 
	Rudptickms	= 100, 
1998/0726    
	Rudpmaxxmit	= 10, 
1998/0630    
                 
1998/0801    
	Maxunacked	= 100, 
1998/0630    
}; 
 
1998/0728    
typedef struct Udphdr Udphdr; 
1998/0731/sys/src/9/ip/rudp.c:93,991998/0801/sys/src/9/ip/rudp.c:102,108
1998/0630    
{ 
	Reliable *next; 
 
	uchar addr[IPaddrlen];	/* always V6 when put here */ 
1998/0801    
	uchar	addr[IPaddrlen];	/* always V6 when put here */ 
1998/0630    
	ushort	port; 
 
	Block	*unacked;	/* unacked msg list */ 
1998/0731/sys/src/9/ip/rudp.c:110,1151998/0801/sys/src/9/ip/rudp.c:119,129
1998/0630    
 
	ulong	acksent;	/* last ack sent */ 
	ulong	ackrcvd;	/* last msg for which ack was rcvd */ 
1998/0801    
 
	/* flow control */ 
	QLock	lock; 
	Rendez	vous; 
	int	blocked; 
1998/0630    
}; 
 
 
1998/0731/sys/src/9/ip/rudp.c:185,1921998/0801/sys/src/9/ip/rudp.c:199,215
1998/0630    
static int 
rudpstate(Conv *c, char *state, int n) 
{ 
	USED(c); 
1998/0726    
	return snprint(state, n, "%s", "Reliable UDP V0.1"); 
1998/0801    
	Rudpcb *ucb; 
	Reliable *r; 
	int m; 
 
	m = snprint(state, n, "%s", c->inuse?"Open":"Closed"); 
	ucb = (Rudpcb*)c->ptcl; 
	qlock(ucb); 
	for(r = ucb->r; r; r = r->next) 
		m += snprint(state+m, n-m, " %I/%d", r->addr, UNACKED(r)); 
	qunlock(ucb); 
	return m; 
1998/0630    
} 
 
static char* 
1998/0731/sys/src/9/ip/rudp.c:238,2431998/0801/sys/src/9/ip/rudp.c:261,272
1998/0630    
	unlock(c); 
} 
 
1998/0801    
int 
flow(Reliable *r) 
{ 
	return UNACKED(r) <= Maxunacked; 
} 
 
1998/0630    
void 
rudpkick(Conv *c, int) 
{ 
1998/0731/sys/src/9/ip/rudp.c:339,3451998/0801/sys/src/9/ip/rudp.c:368,374
1998/0630    
 
1998/0728    
	qlock(ucb); 
	r = relstate(ucb, raddr, rport, "kick"); 
1998/0630    
	r->sndseq++; 
1998/0801    
	r->sndseq = NEXTSEQ(r->sndseq); 
1998/0728    
	hnputl(rh->relseq, r->sndseq); 
	hnputl(rh->relsgen, r->sndgen); 
1998/0630    
 
1998/0731/sys/src/9/ip/rudp.c:346,3521998/0801/sys/src/9/ip/rudp.c:375,381
1998/0728    
	hnputl(rh->relack, r->rcvseq);  /* ACK last rcvd packet */ 
	hnputl(rh->relagen, r->rcvgen); 
1998/0630    
 
	if(r->rcvseq < r->acksent) 
1998/0801    
	if(r->rcvseq != r->acksent) 
1998/0630    
		r->acksent = r->rcvseq; 
 
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); 
1998/0731/sys/src/9/ip/rudp.c:360,3651998/0801/sys/src/9/ip/rudp.c:389,403
1998/0728    
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen); 
1998/0630    
 
	ipoput(f, bp, 0, c->ttl); 
1998/0801    
 
	/* flow control of sorts */ 
	qlock(&r->lock); 
	if(UNACKED(r) > Maxunacked){ 
		r->blocked = 1; 
		sleep(&r->vous, flow, r); 
		r->blocked = 0; 
	} 
	qunlock(&r->lock); 
1998/0630    
} 
 
void 
1998/0731/sys/src/9/ip/rudp.c:664,6701998/0801/sys/src/9/ip/rudp.c:702,708
1998/0630    
				if(r->timeout > Rudprxms*r->xmits) 
					relrexmit(c, r); 
			} 
			if(r->acksent < r->rcvseq) 
1998/0801    
			if(r->acksent != r->rcvseq) 
1998/0630    
				relsendack(c, r); 
		} 
1998/0726    
		qunlock(ucb); 
1998/0731/sys/src/9/ip/rudp.c:736,7421998/0801/sys/src/9/ip/rudp.c:774,779
1998/0630    
	ack = nhgetl(rh->relack); 
	agen = nhgetl(rh->relagen); 
 
                 
1998/0726    
	upriv = c->p->priv; 
1998/0630    
	ucb = (Rudpcb*)c->ptcl; 
1998/0728    
	r = relstate(ucb, addr, port, "input"); 
1998/0731/sys/src/9/ip/rudp.c:748,7631998/0801/sys/src/9/ip/rudp.c:785,804
1998/0630    
	/* dequeue acked packets */ 
	if(ack && agen == r->sndgen){ 
		ackreal = 0; 
		while(r->unacked != nil && ack > r->ackrcvd){ 
1998/0801    
		while(r->unacked != nil && INSEQ(ack, r->ackrcvd, r->sndseq)){ 
1998/0630    
			nbp = r->unacked; 
			r->unacked = nbp->list; 
1998/0726    
			DPRINT("%d/%d acked, r->sndgen = %d\n",  
			       ack, agen, r->sndgen); 
1998/0630    
			freeb(nbp); 
			r->ackrcvd++; 
1998/0801    
			r->ackrcvd = NEXTSEQ(r->ackrcvd); 
1998/0630    
			ackreal = 1; 
		} 
 
1998/0801    
		/* flow control */ 
		if(UNACKED(r) < Maxunacked/8 && r->blocked) 
			wakeup(&r->vous); 
 
1998/0630    
		/* 
		 *  retransmit next packet if the acked packet 
		 *  was transmitted more than once 
1998/0731/sys/src/9/ip/rudp.c:777,7831998/0801/sys/src/9/ip/rudp.c:818,823
1998/0630    
		if(seq != 1) 
			return -1; 
 
                 
		/* new connection */ 
		if(r->rcvgen != 0){ 
			DPRINT("new con r->rcvgen = %d, sgen = %d\n", r->rcvgen, sgen); 
1998/0731/sys/src/9/ip/rudp.c:786,7931998/0801/sys/src/9/ip/rudp.c:826,833
1998/0630    
		r->rcvgen = sgen; 
	} 
 
	/* no message */ 
	if(seq == 0) 
1998/0801    
	/* no message or input queue full */ 
	if(seq == 0 || qfull(c->rq)) 
1998/0630    
		return -1; 
 
1998/0728    
	if(DEBUG && ++drop == drop_rate){ 
1998/0731/sys/src/9/ip/rudp.c:797,8051998/0801/sys/src/9/ip/rudp.c:837,845
1998/0726    
	} 
 
1998/0630    
	/* refuse out of order delivery */ 
	if(seq != r->rcvseq + 1){ 
1998/0801    
	if(seq != NEXTSEQ(r->rcvseq)){ 
1998/0726    
		upriv->orders++; 
1998/0630    
		DPRINT("out of sequence %d not %d\n", seq, r->rcvseq + 1); 
1998/0801    
		DPRINT("out of sequence %d not %d\n", seq, NEXTSEQ(r->rcvseq)); 
1998/0630    
		return -1; 
	} 
	r->rcvseq = seq; 
1998/0731/sys/src/9/ip/rudp.c:880,8851998/0801/sys/src/9/ip/rudp.c:920,926
1998/0630    
	r->ackrcvd = 0; 
	r->xmits = 0; 
	r->timeout = 0; 
1998/0801    
	wakeup(&r->vous); 
1998/0630    
} 
 
/* 
1998/0801/sys/src/9/ip/rudp.c:207,2131998/0825/sys/src/9/ip/rudp.c:207,213 (short | long)
Bug fix: print format.
rsc Fri Mar 4 12:44:25 2005
1998/0801    
	ucb = (Rudpcb*)c->ptcl; 
	qlock(ucb); 
	for(r = ucb->r; r; r = r->next) 
		m += snprint(state+m, n-m, " %I/%d", r->addr, UNACKED(r)); 
1998/0825    
		m += snprint(state+m, n-m, " %I/%ld", r->addr, UNACKED(r)); 
1998/0801    
	qunlock(ucb); 
	return m; 
1998/0630    
} 
1998/0801/sys/src/9/ip/rudp.c:385,3921998/0825/sys/src/9/ip/rudp.c:385,392
1998/0630    
 
	upriv->ustats.rudpOutDatagrams++; 
 
1998/0728    
	DPRINT("sent: %d/%d, %d/%d, r->sndgen = %d\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen); 
1998/0825    
	DPRINT("sent: %lud/%lud, %lud/%lud\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
 
	ipoput(f, bp, 0, c->ttl); 
1998/0801    
 
1998/0801/sys/src/9/ip/rudp.c:611,6171998/0825/sys/src/9/ip/rudp.c:611,617
1998/0630    
	Rudppriv *upriv; 
 
	upriv = rudp->priv; 
1998/0726    
	return snprint(buf, len, "%d %d %d %d %d %d\n", 
1998/0825    
	return snprint(buf, len, "%lud %lud %lud %lud %lud %lud\n", 
1998/0630    
		upriv->ustats.rudpInDatagrams, 
		upriv->ustats.rudpNoPorts, 
		upriv->ustats.rudpInErrors, 
1998/0801/sys/src/9/ip/rudp.c:730,7361998/0825/sys/src/9/ip/rudp.c:730,736
1998/0630    
	if(r == nil){ 
		if(generation == 0) 
1998/0731    
			generation = rand(); 
1998/0728    
		DPRINT("from %s new state %d for %I!%d\n",  
1998/0825    
		DPRINT("from %s new state %lud for %I!%ud\n",  
1998/0728    
		        from, generation, addr, port); 
		r = smalloc(sizeof(Reliable)); 
1998/0630    
		*l = r; 
1998/0801/sys/src/9/ip/rudp.c:779,7851998/0825/sys/src/9/ip/rudp.c:779,785
1998/0728    
	r = relstate(ucb, addr, port, "input"); 
1998/0630    
	 
 
1998/0726    
	DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n",  
1998/0825    
	DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",  
1998/0726    
		seq, sgen, ack, agen, r->sndgen); 
1998/0630    
 
	/* dequeue acked packets */ 
1998/0801/sys/src/9/ip/rudp.c:788,7941998/0825/sys/src/9/ip/rudp.c:788,794
1998/0801    
		while(r->unacked != nil && INSEQ(ack, r->ackrcvd, r->sndseq)){ 
1998/0630    
			nbp = r->unacked; 
			r->unacked = nbp->list; 
1998/0726    
			DPRINT("%d/%d acked, r->sndgen = %d\n",  
1998/0825    
			DPRINT("%lud/%lud acked, r->sndgen = %lud\n",  
1998/0726    
			       ack, agen, r->sndgen); 
1998/0630    
			freeb(nbp); 
1998/0801    
			r->ackrcvd = NEXTSEQ(r->ackrcvd); 
1998/0801/sys/src/9/ip/rudp.c:820,8261998/0825/sys/src/9/ip/rudp.c:820,826
1998/0630    
 
		/* new connection */ 
		if(r->rcvgen != 0){ 
			DPRINT("new con r->rcvgen = %d, sgen = %d\n", r->rcvgen, sgen); 
1998/0825    
			DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen); 
1998/0630    
			relhangup(c, r); 
		} 
		r->rcvgen = sgen; 
1998/0801/sys/src/9/ip/rudp.c:839,8451998/0825/sys/src/9/ip/rudp.c:839,845
1998/0630    
	/* refuse out of order delivery */ 
1998/0801    
	if(seq != NEXTSEQ(r->rcvseq)){ 
1998/0726    
		upriv->orders++; 
1998/0801    
		DPRINT("out of sequence %d not %d\n", seq, NEXTSEQ(r->rcvseq)); 
1998/0825    
		DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); 
1998/0630    
		return -1; 
	} 
	r->rcvseq = seq; 
1998/0801/sys/src/9/ip/rudp.c:891,8971998/0825/sys/src/9/ip/rudp.c:891,897
1998/0728    
	uh->udpcksum[1] = 0; 
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); 
1998/0630    
 
1998/0728    
	DPRINT("sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0825    
	DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
	ipoput(f, bp, 0, c->ttl); 
} 
 
1998/0801/sys/src/9/ip/rudp.c:943,9481998/0825/sys/src/9/ip/rudp.c:943,948
1998/0630    
 
1998/0726    
	upriv->rxmits++; 
1998/0630    
	np = copyblock(r->unacked, blocklen(r->unacked)); 
1998/0726    
	DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1); 
1998/0825    
	DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); 
1998/0630    
	ipoput(f, np, 0, c->ttl); 
} 
1998/0825/sys/src/9/ip/rudp.c:152,1571998/0924/sys/src/9/ip/rudp.c:152,160 (short | long)
1998/0726    
	ulong	rxmits;			/* # of retransmissions */ 
	ulong	orders;			/* # of out of order pkts */ 
1998/0630    
 
1998/0924    
	/* keeping track of the ack kproc */ 
	int	ackprocstarted; 
	QLock	apl; 
1998/0630    
}; 
 
 
1998/0825/sys/src/9/ip/rudp.c:184,1941998/0924/sys/src/9/ip/rudp.c:187,216
1998/0728    
void	relhangup(Conv *, Reliable *); 
void	relrexmit(Conv *, Reliable *); 
1998/0630    
 
1998/0924    
static void 
rudpstartackproc(Proto *rudp) 
{ 
	Rudppriv *rpriv; 
	char kpname[NAMELEN]; 
 
	rpriv = rudp->priv; 
	if(rpriv->ackprocstarted == 0){ 
		qlock(&rpriv->apl); 
		if(rpriv->ackprocstarted == 0){ 
			sprint(kpname, "#I%drudpack", rudp->f->dev); 
			kproc(kpname, relackproc, rudp); 
			rpriv->ackprocstarted = 1; 
		} 
		qunlock(&rpriv->apl); 
	} 
} 
 
1998/0630    
static char* 
rudpconnect(Conv *c, char **argv, int argc) 
{ 
	char *e; 
 
1998/0924    
	rudpstartackproc(c->p); 
1998/0630    
	e = Fsstdconnect(c, argv, argc); 
	Fsconnected(c, e); 
 
1998/0825/sys/src/9/ip/rudp.c:217,2221998/0924/sys/src/9/ip/rudp.c:239,245
1998/0630    
{ 
	char *e; 
 
1998/0924    
	rudpstartackproc(c->p); 
1998/0630    
	e = Fsstdannounce(c, argv, argc); 
	if(e != nil) 
		return e; 
1998/0825/sys/src/9/ip/rudp.c:644,6521998/0924/sys/src/9/ip/rudp.c:667,672
1998/0630    
	rudp->ptclsize = sizeof(Rudpcb); 
 
	Fsproto(fs, rudp); 
                 
1998/0726    
	kproc("relackproc", relackproc, rudp); 
1998/0630    
	                 
} 
 
/*********************************************/ 
1998/0924/sys/src/9/ip/rudp.c:34,401998/1117/sys/src/9/ip/rudp.c:34,40 (short | long)
1998/0728    
	UDP_USEAD4	= 12, 
1998/0630    
 
	Rudprxms	= 200, 
	Rudptickms	= 100, 
1998/1117    
	Rudptickms	= 50, 
1998/0726    
	Rudpmaxxmit	= 10, 
1998/0801    
	Maxunacked	= 100, 
1998/0630    
}; 
1998/0924/sys/src/9/ip/rudp.c:858,8631998/1117/sys/src/9/ip/rudp.c:858,864
1998/0726    
 
1998/0630    
	/* refuse out of order delivery */ 
1998/0801    
	if(seq != NEXTSEQ(r->rcvseq)){ 
1998/1117    
		relsendack(c, r);	/* tell him we got it already */ 
1998/0726    
		upriv->orders++; 
1998/0825    
		DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); 
1998/0630    
		return -1; 
1998/1117/sys/src/9/ip/rudp.c:161,1701998/1118/sys/src/9/ip/rudp.c:161,166 (short | long)
1998/0630    
static ulong generation = 0; 
static Rendez rend; 
1998/0726    
 
/* Used only for debugging */ 
static ushort drop = 0; 
static ushort drop_rate = 10; 
                 
1998/0630    
/* 
 *  protocol specific part of Conv 
 */ 
1998/1117/sys/src/9/ip/rudp.c:173,1781998/1118/sys/src/9/ip/rudp.c:169,175
1998/0630    
{ 
	QLock; 
	uchar	headers; 
1998/1118    
	uchar	randdrop; 
1998/0630    
	Reliable *r; 
}; 
 
1998/1117/sys/src/9/ip/rudp.c:261,2661998/1118/sys/src/9/ip/rudp.c:258,272
1998/0630    
	Rudpcb *ucb; 
	Reliable *r, *nr; 
 
1998/1118    
	/* force out any delayed acks */ 
	ucb = (Rudpcb*)c->ptcl; 
	qlock(ucb); 
	for(r = ucb->r; r; r = r->next){ 
		if(r->acksent != r->rcvseq) 
			relsendack(c, r); 
	} 
	qunlock(ucb); 
 
1998/0630    
	qclose(c->rq); 
	qclose(c->wq); 
	qclose(c->eq); 
1998/1117/sys/src/9/ip/rudp.c:269,2781998/1118/sys/src/9/ip/rudp.c:275,286
1998/0630    
	c->lport = 0; 
	c->rport = 0; 
 
	ucb = (Rudpcb*)c->ptcl; 
	ucb->headers = 0; 
1998/1118    
	ucb->randdrop = 0; 
1998/0728    
	qlock(ucb); 
	for(r = ucb->r; r; r = nr){ 
1998/1118    
		if(r->acksent != r->rcvseq) 
			relsendack(c, r); 
1998/0630    
		nr = r->next; 
1998/0728    
		relhangup(c, r); 
		free(r); 
1998/1117/sys/src/9/ip/rudp.c:284,2891998/1118/sys/src/9/ip/rudp.c:292,312
1998/0630    
	unlock(c); 
} 
 
1998/1118    
/* 
 *  randomly don't send packets 
 */ 
static void 
doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl) 
{ 
	Rudpcb *ucb; 
 
	ucb = (Rudpcb*)c->ptcl; 
	if(ucb->randdrop && nrand(10) == 1) 
		freeblist(bp); 
	else 
		ipoput(f, bp, x, ttl); 
} 
 
1998/0801    
int 
flow(Reliable *r) 
{ 
1998/1117/sys/src/9/ip/rudp.c:411,4171998/1118/sys/src/9/ip/rudp.c:434,440
1998/0825    
	DPRINT("sent: %lud/%lud, %lud/%lud\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
 
	ipoput(f, bp, 0, c->ttl); 
1998/1118    
	doipoput(c, f, bp, 0, c->ttl); 
1998/0801    
 
	/* flow control of sorts */ 
	qlock(&r->lock); 
1998/1117/sys/src/9/ip/rudp.c:593,5981998/1118/sys/src/9/ip/rudp.c:616,624
1998/0630    
		} else if(strcmp(f[0], "headers") == 0){ 
			ucb->headers = 6; 
			return nil; 
1998/1118    
		} else if(strcmp(f[0], "randdrop") == 0){ 
			ucb->randdrop = 1; 
			return nil; 
1998/0630    
		} 
	} 
	return "unknown control request"; 
1998/1117/sys/src/9/ip/rudp.c:802,8071998/1118/sys/src/9/ip/rudp.c:828,846
1998/0825    
	DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",  
1998/0726    
		seq, sgen, ack, agen, r->sndgen); 
1998/0630    
 
1998/1118    
	/* make sure we're not talking to a new remote side */ 
	if(r->rcvgen != sgen){ 
		if(seq != 1) 
			return -1; 
 
		/* new connection */ 
		if(r->rcvgen != 0){ 
			DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen); 
			relhangup(c, r); 
		} 
		r->rcvgen = sgen; 
	} 
 
1998/0630    
	/* dequeue acked packets */ 
	if(ack && agen == r->sndgen){ 
		ackreal = 0; 
1998/1117/sys/src/9/ip/rudp.c:833,8611998/1118/sys/src/9/ip/rudp.c:872,881
1998/0630    
		 
	} 
 
	/* make sure we're not talking to a new remote side */ 
	if(r->rcvgen != sgen){ 
		if(seq != 1) 
			return -1; 
                 
		/* new connection */ 
		if(r->rcvgen != 0){ 
1998/0825    
			DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen); 
1998/0630    
			relhangup(c, r); 
		} 
		r->rcvgen = sgen; 
	} 
                 
1998/0801    
	/* no message or input queue full */ 
	if(seq == 0 || qfull(c->rq)) 
1998/0630    
		return -1; 
 
1998/0728    
	if(DEBUG && ++drop == drop_rate){ 
		DPRINT("drop pkt on purpose\n"); 
1998/0726    
		drop = 0; 
		return -1; 
	} 
                 
1998/0630    
	/* refuse out of order delivery */ 
1998/0801    
	if(seq != NEXTSEQ(r->rcvseq)){ 
1998/1117    
		relsendack(c, r);	/* tell him we got it already */ 
1998/1117/sys/src/9/ip/rudp.c:913,9191998/1118/sys/src/9/ip/rudp.c:933,939
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); 
1998/0630    
 
1998/0825    
	DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
	ipoput(f, bp, 0, c->ttl); 
1998/1118    
	doipoput(c, f, bp, 0, c->ttl); 
1998/0630    
} 
 
/* 
1998/1117/sys/src/9/ip/rudp.c:920,9291998/1118/sys/src/9/ip/rudp.c:940,954
1998/0630    
 *  called with ucb locked (and c locked if user initiated close) 
 */ 
void 
1998/0728    
relhangup(Conv *, Reliable *r) 
1998/1118    
relhangup(Conv *c, Reliable *r) 
1998/0630    
{ 
1998/1118    
	int n; 
1998/0630    
	Block *bp; 
1998/1118    
	char hup[ERRLEN]; 
1998/0630    
 
1998/1118    
	n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); 
	qproduce(c->eq, hup, n); 
 
1998/0630    
	/* 
	 *  dump any unacked outgoing messages 
	 */ 
1998/1117/sys/src/9/ip/rudp.c:965,9691998/1118/sys/src/9/ip/rudp.c:990,994
1998/0726    
	upriv->rxmits++; 
1998/0630    
	np = copyblock(r->unacked, blocklen(r->unacked)); 
1998/0825    
	DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); 
1998/0630    
	ipoput(f, np, 0, c->ttl); 
1998/1118    
	doipoput(c, f, np, 0, c->ttl); 
1998/0630    
} 
1998/1118/sys/src/9/ip/rudp.c:828,8331998/1124/sys/src/9/ip/rudp.c:828,837 (short | long)
1998/0825    
	DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",  
1998/0726    
		seq, sgen, ack, agen, r->sndgen); 
1998/0630    
 
1998/1124    
	/* if acking an incorrect generation, ignore */ 
	if(ack && agen != r->sndgen) 
		return -1; 
 
1998/1118    
	/* make sure we're not talking to a new remote side */ 
	if(r->rcvgen != sgen){ 
		if(seq != 1) 
1998/1124/sys/src/9/ip/rudp.c:774,7801998/1127/sys/src/9/ip/rudp.c:774,780 (short | long)
1998/0630    
 
	/* no state for this addr/port, create some */ 
	if(r == nil){ 
		if(generation == 0) 
1998/1127    
		while(generation == 0) 
1998/0731    
			generation = rand(); 
1998/0825    
		DPRINT("from %s new state %lud for %I!%ud\n",  
1998/0728    
		        from, generation, addr, port); 
1998/1124/sys/src/9/ip/rudp.c:834,8401998/1127/sys/src/9/ip/rudp.c:834,840
1998/1124    
 
1998/1118    
	/* make sure we're not talking to a new remote side */ 
	if(r->rcvgen != sgen){ 
		if(seq != 1) 
1998/1127    
		if(seq != 0 && seq != 1) 
1998/1118    
			return -1; 
 
		/* new connection */ 
1998/1127/sys/src/9/ip/rudp.c:301,3071998/1230/sys/src/9/ip/rudp.c:301,307 (short | long)
1998/1118    
	Rudpcb *ucb; 
 
	ucb = (Rudpcb*)c->ptcl; 
	if(ucb->randdrop && nrand(10) == 1) 
1998/1230    
	if(ucb->randdrop && nrand(100) < ucb->randdrop) 
1998/1118    
		freeblist(bp); 
	else 
		ipoput(f, bp, x, ttl); 
1998/1127/sys/src/9/ip/rudp.c:603,6271998/1230/sys/src/9/ip/rudp.c:603,636
1998/0728    
	qunlock(ucb); 
1998/0630    
} 
 
1998/1230    
static char *rudpunknown = "unknown rudp ctl request"; 
 
1998/0630    
char* 
rudpctl(Conv *c, char **f, int n) 
{ 
	Rudpcb *ucb; 
1998/1230    
	int x; 
1998/0630    
 
	ucb = (Rudpcb*)c->ptcl; 
	if(n == 1){ 
		if(strcmp(f[0], "headers4") == 0){ 
			ucb->headers = 4; 
			return nil; 
		} else if(strcmp(f[0], "headers") == 0){ 
			ucb->headers = 6; 
			return nil; 
1998/1118    
		} else if(strcmp(f[0], "randdrop") == 0){ 
			ucb->randdrop = 1; 
			return nil; 
1998/0630    
		} 
1998/1230    
	if(n < 1) 
		return rudpunknown; 
 
	if(strcmp(f[0], "headers4") == 0){ 
		ucb->headers = 4; 
		return nil; 
	} else if(strcmp(f[0], "headers") == 0){ 
		ucb->headers = 6; 
		return nil; 
	} else if(strcmp(f[0], "randdrop") == 0){ 
		x = 10;		/* default is 10% */ 
		if(n > 1) 
			x = atoi(f[1]); 
		if(x > 100 || x < 0) 
			return "illegal rudp drop rate"; 
		ucb->randdrop = x; 
		return nil; 
1998/0630    
	} 
	return "unknown control request"; 
1998/1230    
	return rudpunknown; 
1998/0630    
} 
 
void 
1998/1230/sys/src/9/ip/rudp.c:289,2951999/0302/sys/src/9/ip/rudp.c:289,295 (short | long)
1998/0630    
 
1998/0728    
	qunlock(ucb); 
1998/0630    
 
	unlock(c); 
1999/0302    
	qunlock(c); 
1998/0630    
} 
 
1998/1118    
/* 
1998/1230/sys/src/9/ip/rudp.c:490,4951999/0302/sys/src/9/ip/rudp.c:490,497
1998/0630    
		} 
	} 
 
1999/0302    
	qlock(rudp); 
 
1998/0630    
	/* Look for a conversation structure for this port */ 
	c = nil; 
	for(p = rudp->conv; *p; p++) { 
1998/1230/sys/src/9/ip/rudp.c:512,5171999/0302/sys/src/9/ip/rudp.c:514,520
1998/0630    
	} 
 
	if(*p == nil) { 
1999/0302    
		qunlock(rudp); 
1998/0630    
		upriv->ustats.rudpNoPorts++; 
		netlog(f, Logrudp, "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
			laddr, lport); 
1998/1230/sys/src/9/ip/rudp.c:525,5321999/0302/sys/src/9/ip/rudp.c:528,536
1998/0630    
	} 
 
	ucb = (Rudpcb*)c->ptcl; 
                 
1998/0728    
	qlock(ucb); 
1999/0302    
	qunlock(rudp); 
 
1998/0728    
	if(reliput(c, bp, raddr, rport) < 0){ 
		qunlock(ucb); 
		freeb(bp); 
1999/0302/sys/src/9/ip/rudp.c:308,3151999/0320/sys/src/9/ip/rudp.c:308,317 (short | long)
1998/1118    
} 
 
1998/0801    
int 
flow(Reliable *r) 
1999/0320    
flow(void *v) 
1998/0801    
{ 
1999/0320    
	Reliable *r = v; 
 
1998/0801    
	return UNACKED(r) <= Maxunacked; 
} 
 
1999/0320/sys/src/9/ip/rudp.c:296,3021999/0817/sys/src/9/ip/rudp.c:296,302 (short | long)
1998/1118    
 *  randomly don't send packets 
 */ 
static void 
doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl) 
1999/0817    
doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos) 
1998/1118    
{ 
	Rudpcb *ucb; 
 
1999/0320/sys/src/9/ip/rudp.c:304,3101999/0817/sys/src/9/ip/rudp.c:304,310
1998/1230    
	if(ucb->randdrop && nrand(100) < ucb->randdrop) 
1998/1118    
		freeblist(bp); 
	else 
		ipoput(f, bp, x, ttl); 
1999/0817    
		ipoput(f, bp, x, ttl, tos); 
1998/1118    
} 
 
1998/0801    
int 
1999/0320/sys/src/9/ip/rudp.c:436,4421999/0817/sys/src/9/ip/rudp.c:436,442
1998/0825    
	DPRINT("sent: %lud/%lud, %lud/%lud\n",  
		r->sndseq, r->sndgen, r->rcvseq, r->rcvgen); 
1998/0630    
 
1998/1118    
	doipoput(c, f, bp, 0, c->ttl); 
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0801    
 
	/* flow control of sorts */ 
	qlock(&r->lock); 
1999/0320/sys/src/9/ip/rudp.c:952,9581999/0817/sys/src/9/ip/rudp.c:952,958
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE)); 
1998/0630    
 
1998/0825    
	DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen); 
1998/1118    
	doipoput(c, f, bp, 0, c->ttl); 
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0630    
} 
 
/* 
1999/0320/sys/src/9/ip/rudp.c:1009,10131999/0817/sys/src/9/ip/rudp.c:1009,1013
1998/0726    
	upriv->rxmits++; 
1998/0630    
	np = copyblock(r->unacked, blocklen(r->unacked)); 
1998/0825    
	DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1); 
1998/1118    
	doipoput(c, f, np, 0, c->ttl); 
1999/0817    
	doipoput(c, f, np, 0, c->ttl, c->tos); 
1998/0630    
} 
1999/0817/sys/src/9/ip/rudp.c:37,442000/0317/sys/src/9/ip/rudp.c:37,47 (short | long)
1998/1117    
	Rudptickms	= 50, 
1998/0726    
	Rudpmaxxmit	= 10, 
1998/0801    
	Maxunacked	= 100, 
2000/0317    
 
1998/0630    
}; 
 
2000/0317    
#define Hangupgen	0xffffffff	/* used only in hangup messages */ 
 
1998/0728    
typedef struct Udphdr Udphdr; 
struct Udphdr 
1998/0630    
{ 
1999/0817/sys/src/9/ip/rudp.c:100,1052000/0317/sys/src/9/ip/rudp.c:103,110
1998/0630    
typedef struct Reliable Reliable; 
struct Reliable 
{ 
2000/0317    
	Ref; 
 
1998/0630    
	Reliable *next; 
 
1998/0801    
	uchar	addr[IPaddrlen];	/* always V6 when put here */ 
1999/0817/sys/src/9/ip/rudp.c:121,1272000/0317/sys/src/9/ip/rudp.c:126,131
1998/0630    
	ulong	ackrcvd;	/* last msg for which ack was rcvd */ 
1998/0801    
 
	/* flow control */ 
	QLock	lock; 
	Rendez	vous; 
	int	blocked; 
1998/0630    
}; 
1999/0817/sys/src/9/ip/rudp.c:176,1842000/0317/sys/src/9/ip/rudp.c:180,190
1998/0630    
/* 
 * local functions  
 */ 
1998/0728    
void	relsendack(Conv *, Reliable *); 
2000/0317    
void	relsendack(Conv *, Reliable *, int); 
1998/0728    
int	reliput(Conv *, Block *, uchar *, ushort); 
Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); 
2000/0317    
void	relput(Reliable *); 
void	relforget(Conv *, uchar *, int, int); 
1998/0728    
void	relackproc(void *); 
void	relackq(Reliable *, Block *); 
void	relhangup(Conv *, Reliable *); 
1999/0817/sys/src/9/ip/rudp.c:263,2692000/0317/sys/src/9/ip/rudp.c:269,275
1998/1118    
	qlock(ucb); 
	for(r = ucb->r; r; r = r->next){ 
		if(r->acksent != r->rcvseq) 
			relsendack(c, r); 
2000/0317    
			relsendack(c, r, 0); 
1998/1118    
	} 
	qunlock(ucb); 
 
1999/0817/sys/src/9/ip/rudp.c:280,2862000/0317/sys/src/9/ip/rudp.c:286,292
1998/0728    
	qlock(ucb); 
	for(r = ucb->r; r; r = nr){ 
1998/1118    
		if(r->acksent != r->rcvseq) 
			relsendack(c, r); 
2000/0317    
			relsendack(c, r, 0); 
1998/0630    
		nr = r->next; 
1998/0728    
		relhangup(c, r); 
		free(r); 
1999/0817/sys/src/9/ip/rudp.c:429,4352000/0317/sys/src/9/ip/rudp.c:435,440
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); 
1998/0630    
 
1998/0728    
	relackq(r, bp); 
	qunlock(ucb); 
1998/0630    
 
	upriv->ustats.rudpOutDatagrams++; 
 
1999/0817/sys/src/9/ip/rudp.c:439,4512000/0317/sys/src/9/ip/rudp.c:444,456
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0801    
 
	/* flow control of sorts */ 
	qlock(&r->lock); 
	if(UNACKED(r) > Maxunacked){ 
		r->blocked = 1; 
		sleep(&r->vous, flow, r); 
		r->blocked = 0; 
	} 
	qunlock(&r->lock); 
2000/0317    
	relput(r); 
	qunlock(ucb); 
1998/0630    
} 
 
void 
1999/0817/sys/src/9/ip/rudp.c:615,6202000/0317/sys/src/9/ip/rudp.c:620,626
1998/0630    
rudpctl(Conv *c, char **f, int n) 
{ 
	Rudpcb *ucb; 
2000/0317    
	uchar ip[IPaddrlen]; 
1998/1230    
	int x; 
1998/0630    
 
	ucb = (Rudpcb*)c->ptcl; 
1999/0817/sys/src/9/ip/rudp.c:627,6322000/0317/sys/src/9/ip/rudp.c:633,647
1998/1230    
	} else if(strcmp(f[0], "headers") == 0){ 
		ucb->headers = 6; 
		return nil; 
2000/0317    
	} else if(strcmp(f[0], "hangup") == 0){ 
		if(n < 3) 
			return "bad syntax"; 
		parseip(ip, f[1]); 
		x = atoi(f[2]); 
		qlock(ucb); 
		relforget(c, ip, x, 1); 
		qunlock(ucb); 
		return nil; 
1998/1230    
	} else if(strcmp(f[0], "randdrop") == 0){ 
		x = 10;		/* default is 10% */ 
		if(n > 1) 
1999/0817/sys/src/9/ip/rudp.c:764,7702000/0317/sys/src/9/ip/rudp.c:779,785
1998/0630    
					relrexmit(c, r); 
			} 
1998/0801    
			if(r->acksent != r->rcvseq) 
1998/0630    
				relsendack(c, r); 
2000/0317    
				relsendack(c, r, 0); 
1998/0630    
		} 
1998/0726    
		qunlock(ucb); 
1998/0630    
	} 
1999/0817/sys/src/9/ip/rudp.c:798,8032000/0317/sys/src/9/ip/rudp.c:813,820
1998/0728    
		memmove(r->addr, addr, IPaddrlen); 
1998/0630    
		r->port = port; 
		r->unacked = 0; 
2000/0317    
		if(generation == Hangupgen) 
			generation++; 
1998/0630    
		r->sndgen = generation++; 
		r->sndseq = 0; 
		r->ackrcvd = 0; 
1999/0817/sys/src/9/ip/rudp.c:806,8172000/0317/sys/src/9/ip/rudp.c:823,864
1998/0630    
		r->acksent = 0; 
		r->xmits = 0; 
		r->timeout = 0; 
2000/0317    
		r->ref = 0; 
		incref(r);	/* one reference for being in the list */ 
1998/0630    
	} 
                 
2000/0317    
	incref(r); 
1998/0630    
	return r; 
} 
 
2000/0317    
void 
relput(Reliable *r) 
{ 
	if(decref(r) == 0) 
		free(r); 
} 
1998/0630    
 
2000/0317    
void 
relforget(Conv *c, uchar *ip, int port, int originator) 
{ 
	Rudpcb *ucb; 
	Reliable *r, **l; 
 
	ucb = (Rudpcb*)c->ptcl; 
 
	l = &ucb->r; 
	for(r = *l; r; r = *l){ 
		if(ipcmp(ip, r->addr) == 0 && port == r->port){ 
			*l = r->next; 
			if(originator) 
				relsendack(c, r, 1); 
			relhangup(c, r); 
			relput(r);	/* remove from the list */ 
			break; 
		} 
		l = &r->next; 
	} 
} 
 
1998/0630    
/*  
 *  process a rcvd reliable packet. return -1 if not to be passed to user process, 
 *  0 therwise. 
1999/0817/sys/src/9/ip/rudp.c:826,8312000/0317/sys/src/9/ip/rudp.c:873,879
1998/0630    
	Reliable *r; 
1998/0728    
	Rudphdr *rh; 
1998/0630    
	ulong seq, ack, sgen, agen, ackreal; 
2000/0317    
	int rv = -1; 
1998/0630    
 
	/* get fields */ 
1998/0728    
	uh = (Udphdr*)(bp->rp); 
1999/0817/sys/src/9/ip/rudp.c:837,8442000/0317/sys/src/9/ip/rudp.c:885,892
1998/0630    
 
1998/0726    
	upriv = c->p->priv; 
1998/0630    
	ucb = (Rudpcb*)c->ptcl; 
2000/0317    
	qlock(ucb); 
1998/0728    
	r = relstate(ucb, addr, port, "input"); 
1998/0630    
	                 
 
1998/0825    
	DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",  
1998/0726    
		seq, sgen, ack, agen, r->sndgen); 
1999/0817/sys/src/9/ip/rudp.c:845,8562000/0317/sys/src/9/ip/rudp.c:893,911
1998/0630    
 
1998/1124    
	/* if acking an incorrect generation, ignore */ 
	if(ack && agen != r->sndgen) 
		return -1; 
2000/0317    
		goto out; 
1998/1124    
 
2000/0317    
	/* Look for a hangup */ 
	if(sgen == Hangupgen) { 
		if(agen == r->sndgen) 
			relforget(c, addr, port, 0); 
		goto out; 
	} 
 
1998/1118    
	/* make sure we're not talking to a new remote side */ 
	if(r->rcvgen != sgen){ 
1998/1127    
		if(seq != 0 && seq != 1) 
1998/1118    
			return -1; 
2000/0317    
			goto out; 
1998/1118    
 
		/* new connection */ 
		if(r->rcvgen != 0){ 
1999/0817/sys/src/9/ip/rudp.c:893,9142000/0317/sys/src/9/ip/rudp.c:948,973
1998/0630    
 
1998/0801    
	/* no message or input queue full */ 
	if(seq == 0 || qfull(c->rq)) 
1998/0630    
		return -1; 
2000/0317    
		goto out; 
1998/0630    
 
	/* refuse out of order delivery */ 
1998/0801    
	if(seq != NEXTSEQ(r->rcvseq)){ 
1998/1117    
		relsendack(c, r);	/* tell him we got it already */ 
2000/0317    
		relsendack(c, r, 0);	/* tell him we got it already */ 
1998/0726    
		upriv->orders++; 
1998/0825    
		DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq)); 
1998/0630    
		return -1; 
2000/0317    
		goto out; 
1998/0630    
	} 
	r->rcvseq = seq; 
 
	return 0; 
2000/0317    
	rv = 0; 
out: 
	relput(r); 
	qunlock(ucb); 
	return rv; 
1998/0630    
} 
 
void 
relsendack(Conv *c, Reliable *r) 
2000/0317    
relsendack(Conv *c, Reliable *r, int hangup) 
1998/0630    
{ 
1998/0728    
	Udphdr *uh; 
1998/0630    
	Block *bp; 
1999/0817/sys/src/9/ip/rudp.c:939,9452000/0317/sys/src/9/ip/rudp.c:998,1007
1998/0728    
	v6tov4(uh->udpsrc, c->laddr); 
	hnputs(uh->udplen, ptcllen); 
1998/0630    
 
	hnputl(rh->relsgen, r->sndgen); 
2000/0317    
	if(hangup) 
		hnputl(rh->relsgen, Hangupgen); 
	else 
		hnputl(rh->relsgen, r->sndgen); 
1998/0630    
	hnputl(rh->relseq, 0); 
	hnputl(rh->relagen, r->rcvgen); 
	hnputl(rh->relack, r->rcvseq); 
1999/0817/sys/src/9/ip/rudp.c:955,9602000/0317/sys/src/9/ip/rudp.c:1017,1023
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0630    
} 
 
2000/0317    
 
1998/0630    
/* 
 *  called with ucb locked (and c locked if user initiated close) 
 */ 
1999/0817/sys/src/9/ip/rudp.c:980,9852000/0317/sys/src/9/ip/rudp.c:1043,1050
1998/0630    
	r->rcvgen = 0; 
	r->rcvseq = 0; 
	r->acksent = 0; 
2000/0317    
	if(generation == Hangupgen) 
		generation++; 
1998/0630    
	r->sndgen = generation++; 
	r->sndseq = 0; 
	r->ackrcvd = 0; 
2000/0317/sys/src/9/ip/rudp.c:126,1312000/0328/sys/src/9/ip/rudp.c:126,132 (short | long)
1998/0630    
	ulong	ackrcvd;	/* last msg for which ack was rcvd */ 
1998/0801    
 
	/* flow control */ 
2000/0328    
	QLock	lock; 
1998/0801    
	Rendez	vous; 
	int	blocked; 
1998/0630    
}; 
2000/0317/sys/src/9/ip/rudp.c:435,4402000/0328/sys/src/9/ip/rudp.c:436,442
1998/0728    
	hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE)); 
1998/0630    
 
1998/0728    
	relackq(r, bp); 
2000/0328    
	qunlock(ucb); 
1998/0630    
 
	upriv->ustats.rudpOutDatagrams++; 
 
2000/0317/sys/src/9/ip/rudp.c:444,4562000/0328/sys/src/9/ip/rudp.c:446,459
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0801    
 
	/* flow control of sorts */ 
2000/0328    
	qlock(&r->lock); 
1998/0801    
	if(UNACKED(r) > Maxunacked){ 
		r->blocked = 1; 
		sleep(&r->vous, flow, r); 
		r->blocked = 0; 
	} 
2000/0328    
	qunlock(&r->lock); 
2000/0317    
	relput(r); 
	qunlock(ucb); 
1998/0630    
} 
 
void 
2000/0328/sys/src/9/ip/rudp.c:290,2962000/0403/sys/src/9/ip/rudp.c:290,296 (short | long)
2000/0317    
			relsendack(c, r, 0); 
1998/0630    
		nr = r->next; 
1998/0728    
		relhangup(c, r); 
		free(r); 
2000/0403    
		relput(r); 
1998/0630    
	} 
	ucb->r = 0; 
 
2000/0328/sys/src/9/ip/rudp.c:453,4582000/0403/sys/src/9/ip/rudp.c:453,459
1998/0801    
		r->blocked = 0; 
	} 
2000/0328    
	qunlock(&r->lock); 
2000/0403    
 
2000/0317    
	relput(r); 
1998/0630    
} 
 
2000/0328/sys/src/9/ip/rudp.c:811,8182000/0403/sys/src/9/ip/rudp.c:812,819
1998/0731    
			generation = rand(); 
1998/0825    
		DPRINT("from %s new state %lud for %I!%ud\n",  
1998/0728    
		        from, generation, addr, port); 
2000/0403    
 
1998/0728    
		r = smalloc(sizeof(Reliable)); 
1998/0630    
		*l = r; 
1998/0728    
		memmove(r->addr, addr, IPaddrlen); 
1998/0630    
		r->port = port; 
		r->unacked = 0; 
2000/0328/sys/src/9/ip/rudp.c:828,8332000/0403/sys/src/9/ip/rudp.c:829,836
1998/0630    
		r->timeout = 0; 
2000/0317    
		r->ref = 0; 
		incref(r);	/* one reference for being in the list */ 
2000/0403    
 
		*l = r; 
1998/0630    
	} 
2000/0317    
	incref(r); 
1998/0630    
	return r; 
2000/0328/sys/src/9/ip/rudp.c:840,8452000/0403/sys/src/9/ip/rudp.c:843,851
2000/0317    
		free(r); 
} 
1998/0630    
 
2000/0403    
/* 
 *  forget a Reliable state 
 */ 
2000/0317    
void 
relforget(Conv *c, uchar *ip, int port, int originator) 
{ 
2000/0328/sys/src/9/ip/rudp.c:865,8702000/0403/sys/src/9/ip/rudp.c:871,878
1998/0630    
/*  
 *  process a rcvd reliable packet. return -1 if not to be passed to user process, 
 *  0 therwise. 
2000/0403    
 * 
 *  called with ucb locked. 
1998/0630    
 */ 
int 
reliput(Conv *c, Block *bp, uchar *addr, ushort port) 
2000/0328/sys/src/9/ip/rudp.c:888,8942000/0403/sys/src/9/ip/rudp.c:896,901
1998/0630    
 
1998/0726    
	upriv = c->p->priv; 
1998/0630    
	ucb = (Rudpcb*)c->ptcl; 
2000/0317    
	qlock(ucb); 
1998/0728    
	r = relstate(ucb, addr, port, "input"); 
1998/0630    
 
1998/0825    
	DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",  
2000/0328/sys/src/9/ip/rudp.c:965,9712000/0403/sys/src/9/ip/rudp.c:972,977
2000/0317    
	rv = 0; 
out: 
	relput(r); 
	qunlock(ucb); 
	return rv; 
1998/0630    
} 
 
2000/0403/sys/src/9/ip/rudp.c:181,1952000/0605/sys/src/9/ip/rudp.c:181,196 (short | long)
1998/0630    
/* 
 * local functions  
 */ 
2000/0317    
void	relsendack(Conv *, Reliable *, int); 
1998/0728    
int	reliput(Conv *, Block *, uchar *, ushort); 
Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); 
2000/0317    
void	relput(Reliable *); 
void	relforget(Conv *, uchar *, int, int); 
2000/0605    
void	relsendack(Conv*, Reliable*, int); 
int	reliput(Conv*, Block*, uchar*, ushort); 
Reliable *relstate(Rudpcb*, uchar*, ushort, char*); 
void	relput(Reliable*); 
void	relforget(Conv *, uchar*, int, int); 
1998/0728    
void	relackproc(void *); 
void	relackq(Reliable *, Block *); 
void	relhangup(Conv *, Reliable *); 
void	relrexmit(Conv *, Reliable *); 
2000/0605    
void	relackq(Reliable *, Block*); 
void	relhangup(Conv *, Reliable*); 
void	relrexmit(Conv *, Reliable*); 
void	relput(Reliable*); 
1998/0630    
 
1998/0924    
static void 
rudpstartackproc(Proto *rudp) 
2000/0403/sys/src/9/ip/rudp.c:295,3012000/0605/sys/src/9/ip/rudp.c:296,301
1998/0630    
	ucb->r = 0; 
 
1998/0728    
	qunlock(ucb); 
1998/0630    
                 
1999/0302    
	qunlock(c); 
1998/0630    
} 
 
2000/0403/sys/src/9/ip/rudp.c:445,4502000/0605/sys/src/9/ip/rudp.c:445,456
1998/0630    
 
1999/0817    
	doipoput(c, f, bp, 0, c->ttl, c->tos); 
1998/0801    
 
2000/0605    
	if(waserror()) { 
		relput(r); 
		qunlock(&r->lock); 
		nexterror(); 
	} 
 
1998/0801    
	/* flow control of sorts */ 
2000/0328    
	qlock(&r->lock); 
1998/0801    
	if(UNACKED(r) > Maxunacked){ 
2000/0403/sys/src/9/ip/rudp.c:452,4602000/0605/sys/src/9/ip/rudp.c:458,467
1998/0801    
		sleep(&r->vous, flow, r); 
		r->blocked = 0; 
	} 
2000/0328    
	qunlock(&r->lock); 
2000/0403    
 
2000/0605    
	qunlock(&r->lock); 
2000/0317    
	relput(r); 
2000/0605    
	poperror(); 
1998/0630    
} 
 
void 
2000/0403/sys/src/9/ip/rudp.c:554,5602000/0605/sys/src/9/ip/rudp.c:561,567
1998/0630    
 
1998/0728    
	len -= (UDP_RHDRSIZE-UDP_PHDRSIZE); 
	bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len); 
1998/0630    
	if(bp == nil){ 
2000/0605    
	if(bp == nil) { 
1998/0630    
		netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n",  
			raddr, rport, laddr, lport); 
1998/0728    
		DPRINT("rudp: len err %I.%d -> %I.%d\n",  
2000/0403/sys/src/9/ip/rudp.c:607,6132000/0605/sys/src/9/ip/rudp.c:614,620
1998/0630    
	if(bp->next) 
		bp = concatblock(bp); 
 
	if(qfull(c->rq)){ 
2000/0605    
	if(qfull(c->rq)) { 
1998/0630    
		netlog(f, Logrudp, "rudp: qfull %I.%d -> %I.%d\n", raddr, rport, 
			laddr, lport); 
		freeblist(bp); 
2000/0403/sys/src/9/ip/rudp.c:810,8152000/0605/sys/src/9/ip/rudp.c:817,823
1998/0630    
	if(r == nil){ 
1998/1127    
		while(generation == 0) 
1998/0731    
			generation = rand(); 
2000/0605    
 
1998/0825    
		DPRINT("from %s new state %lud for %I!%ud\n",  
1998/0728    
		        from, generation, addr, port); 
2000/0403    
 
2000/0403/sys/src/9/ip/rudp.c:832,8372000/0605/sys/src/9/ip/rudp.c:840,846
2000/0403    
 
		*l = r; 
1998/0630    
	} 
2000/0605    
 
2000/0317    
	incref(r); 
1998/0630    
	return r; 
} 
2000/0605/sys/src/9/ip/rudp.c:296,3022000/1220/sys/src/9/ip/rudp.c:296,301 (short | long)
1998/0630    
	ucb->r = 0; 
 
1998/0728    
	qunlock(ucb); 
1999/0302    
	qunlock(c); 
1998/0630    
} 
 
1998/1118    
/* 
2000/1220/sys/src/9/ip/rudp.c:147,1522001/0301/sys/src/9/ip/rudp.c:147,153 (short | long)
1998/0630    
struct Rudppriv 
{ 
1998/0726    
	Rendez	vous; 
2001/0301    
	Ipht	ht; 
1998/0630    
 
	/* MIB counters */ 
	Rudpstats	ustats; 
2000/1220/sys/src/9/ip/rudp.c:214,2232001/0301/sys/src/9/ip/rudp.c:215,227
1998/0630    
rudpconnect(Conv *c, char **argv, int argc) 
{ 
	char *e; 
2001/0301    
	Rudppriv *upriv; 
1998/0630    
 
2001/0301    
	upriv = c->p->priv; 
1998/0924    
	rudpstartackproc(c->p); 
1998/0630    
	e = Fsstdconnect(c, argv, argc); 
	Fsconnected(c, e); 
2001/0301    
	iphtadd(&upriv->ht, c); 
1998/0630    
 
	return e; 
} 
2000/1220/sys/src/9/ip/rudp.c:243,2542001/0301/sys/src/9/ip/rudp.c:247,261
1998/0630    
rudpannounce(Conv *c, char** argv, int argc) 
{ 
	char *e; 
2001/0301    
	Rudppriv *upriv; 
1998/0630    
 
2001/0301    
	upriv = c->p->priv; 
1998/0924    
	rudpstartackproc(c->p); 
1998/0630    
	e = Fsstdannounce(c, argv, argc); 
	if(e != nil) 
		return e; 
	Fsconnected(c, nil); 
2001/0301    
	iphtadd(&upriv->ht, c); 
1998/0630    
 
	return nil; 
} 
2000/1220/sys/src/9/ip/rudp.c:265,2712001/0301/sys/src/9/ip/rudp.c:272,282
1998/0630    
{ 
	Rudpcb *ucb; 
	Reliable *r, *nr; 
2001/0301    
	Rudppriv *upriv; 
1998/0630    
 
2001/0301    
	upriv = c->p->priv; 
	iphtrem(&upriv->ht, c); 
 
1998/1118    
	/* force out any delayed acks */ 
	ucb = (Rudpcb*)c->ptcl; 
	qlock(ucb); 
2000/1220/sys/src/9/ip/rudp.c:468,4742001/0301/sys/src/9/ip/rudp.c:479,485
1998/0630    
{ 
	int len, olen, ottl; 
1998/0728    
	Udphdr *uh; 
1998/0630    
	Conv *c, **p; 
2001/0301    
	Conv *c; 
1998/0630    
	Rudpcb *ucb; 
	uchar raddr[IPaddrlen], laddr[IPaddrlen]; 
	ushort rport, lport; 
2000/1220/sys/src/9/ip/rudp.c:509,5422001/0301/sys/src/9/ip/rudp.c:520,532
1998/0630    
 
1999/0302    
	qlock(rudp); 
 
1998/0630    
	/* Look for a conversation structure for this port */ 
	c = nil; 
	for(p = rudp->conv; *p; p++) { 
		c = *p; 
		if(c->inuse == 0) 
			continue; 
1998/0728    
		if(c->lport == lport){ 
			ucb = (Rudpcb*)c->ptcl; 
                 
			/* with headers turned on, descriminate only on local port */ 
			if(ucb->headers) 
				break; 
                 
			/* otherwise discriminate on lport, rport, and raddr */ 
			if(c->rport == 0 || c->rport == rport) 
			if(ipisbm(c->raddr) || ipcmp(c->raddr, IPnoaddr) == 0 
			   || ipcmp(c->raddr, raddr) == 0) 
				break; 
		} 
1998/0630    
	} 
                 
	if(*p == nil) { 
1999/0302    
		qunlock(rudp); 
2001/0301    
	c = iphtlook(&upriv->ht, raddr, rport, laddr, lport); 
	if(c == nil){ 
		/* no converstation found */ 
1998/0630    
		upriv->ustats.rudpNoPorts++; 
		netlog(f, Logrudp, "rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
2001/0301    
		qunlock(rudp); 
		netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, 
1998/0630    
			laddr, lport); 
1998/0728    
		DPRINT("rudp: no conv %I!%d -> %I!%d\n", raddr, rport, 
1998/0630    
			laddr, lport); 
		uh->Unused = ottl; 
1998/0728    
		hnputs(uh->udpplen, olen); 
1998/0630    
		icmpnoconv(f, bp); 
2000/1220/sys/src/9/ip/rudp.c:543,5492001/0301/sys/src/9/ip/rudp.c:533,538
1998/0630    
		freeblist(bp); 
		return; 
	} 
                 
	ucb = (Rudpcb*)c->ptcl; 
1998/0728    
	qlock(ucb); 
1999/0302    
	qunlock(rudp); 
2001/0301/sys/src/9/ip/rudp.c:333,3392001/0306/sys/src/9/ip/rudp.c:333,339 (short | long)
1998/0801    
} 
 
1998/0630    
void 
rudpkick(Conv *c, int) 
2001/0306    
rudpkick(Conv *c) 
1998/0630    
{ 
1998/0728    
	Udphdr *uh; 
1998/0630    
	ushort rport; 
2001/0306/sys/src/9/ip/rudp.c:475,4812001/0623/sys/src/9/ip/rudp.c:475,481 (short | long)
1998/0630    
} 
 
void 
rudpiput(Proto *rudp, uchar *ia, Block *bp) 
2001/0623    
rudpiput(Proto *rudp, Ipifc *ifc, Block *bp) 
1998/0630    
{ 
	int len, olen, ottl; 
1998/0728    
	Udphdr *uh; 
2001/0306/sys/src/9/ip/rudp.c:569,5752001/0623/sys/src/9/ip/rudp.c:569,575
1998/0630    
		if(ipforme(f, laddr) == Runi) 
			ipmove(bp->rp+IPaddrlen, laddr); 
		else 
			ipmove(bp->rp+IPaddrlen, ia); 
2001/0623    
			ipmove(bp->rp+IPaddrlen, ifc->lifc->local); 
1998/0630    
		hnputs(bp->rp+2*IPaddrlen, rport); 
		hnputs(bp->rp+2*IPaddrlen+2, lport); 
		break; 
2001/0306/sys/src/9/ip/rudp.c:580,5862001/0623/sys/src/9/ip/rudp.c:580,586
1998/0630    
		if(ipforme(f, laddr) == Runi) 
			v6tov4(bp->rp+IPv4addrlen, laddr); 
		else 
			v6tov4(bp->rp+IPv4addrlen, ia); 
2001/0623    
			v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local); 
1998/0630    
		hnputs(bp->rp + 2*IPv4addrlen, rport); 
		hnputs(bp->rp + 2*IPv4addrlen + 2, lport); 
		break; 
2001/0306/sys/src/9/ip/rudp.c:595,6012001/0623/sys/src/9/ip/rudp.c:595,601
1998/0630    
			if(ipforme(f, laddr) == Runi) 
				ipmove(c->laddr, laddr); 
			else 
				v4tov6(c->laddr, ia); 
2001/0623    
				v4tov6(c->laddr, ifc->lifc->local); 
1998/0630    
		} 
		break; 
	} 
2001/0623/sys/src/9/ip/rudp.c:197,2032001/0918/sys/src/9/ip/rudp.c:197,203 (short | long)
1998/0924    
rudpstartackproc(Proto *rudp) 
{ 
	Rudppriv *rpriv; 
	char kpname[NAMELEN]; 
2001/0918    
	char kpname[KNAMELEN]; 
1998/0924    
 
	rpriv = rudp->priv; 
	if(rpriv->ackprocstarted == 0){ 
2001/0623/sys/src/9/ip/rudp.c:1032,10382001/0918/sys/src/9/ip/rudp.c:1032,1038
1998/0630    
{ 
1998/1118    
	int n; 
1998/0630    
	Block *bp; 
1998/1118    
	char hup[ERRLEN]; 
2001/0918    
	char hup[ERRMAX]; 
1998/0630    
 
1998/1118    
	n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); 
	qproduce(c->eq, hup, n); 
2001/0918/sys/src/9/ip/rudp.c:321,3272002/0507/sys/src/9/ip/rudp.c:321,327 (short | long)
1998/1230    
	if(ucb->randdrop && nrand(100) < ucb->randdrop) 
1998/1118    
		freeblist(bp); 
	else 
1999/0817    
		ipoput(f, bp, x, ttl, tos); 
2002/0507    
		ipoput4(f, bp, x, ttl, tos); 
1998/1118    
} 
 
1998/0801    
int 
2001/0918/sys/src/9/ip/rudp.c:402,4072002/0507/sys/src/9/ip/rudp.c:402,408
1998/0630    
		return; 
 
1998/0728    
	uh = (Udphdr *)(bp->rp); 
2002/0507    
	uh->vihl = IP_VER4; 
1998/0630    
 
1998/0728    
	rh = (Rudphdr*)uh; 
1998/0630    
 
2001/0918/sys/src/9/ip/rudp.c:987,9922002/0507/sys/src/9/ip/rudp.c:988,994
1998/0728    
	bp->wp += UDP_IPHDR + UDP_RHDRSIZE; 
1998/0630    
	f = c->p->f; 
1998/0728    
	uh = (Udphdr *)(bp->rp); 
2002/0507    
	uh->vihl = IP_VER4; 
1998/0728    
	rh = (Rudphdr*)uh; 
1998/0630    
 
1998/0728    
	ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE); 
2002/0507/sys/src/9/ip/rudp.c:263,2692002/0711/sys/src/9/ip/rudp.c:263,269 (short | long)
1998/0630    
static void 
rudpcreate(Conv *c) 
{ 
	c->rq = qopen(64*1024, 1, 0, 0); 
2002/0711    
	c->rq = qopen(64*1024, Qmsg, 0, 0); 
1998/0630    
	c->wq = qopen(64*1024, 0, 0, 0); 
} 
 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)