## diffname ip/rudp.c 1998/0630
## diff -e /dev/null /n/emeliedump/1998/0630/sys/src/brazil/ip/rudp.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "ip.h"
#define DPRINT if(1)print
enum
{
RUDP_PHDRSIZE = 12,
RUDP_HDRSIZE = 36,
RUDP_RHDRSIZE = 16,
RUDP_IPHDR = 8,
IP_RUDPPROTO = 254,
RUDP_USEAD6 = 36,
RUDP_USEAD4 = 12,
Rudprxms = 200,
Rudptickms = 100,
Rudpmaxxmit = 1,
};
/*
* reliable header
*/
typedef struct Relhdr Relhdr;
struct Relhdr
{
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 */
};
typedef struct Rudphdr Rudphdr;
struct Rudphdr
{
/* 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 */
uchar Unused;
uchar rudpproto; /* Protocol */
uchar rudpplen[2]; /* Header plus data length */
uchar rudpsrc[4]; /* Ip source */
uchar rudpdst[4]; /* Ip destination */
/* 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 */
};
/*
* one state structure per destination
*/
typedef struct Reliable Reliable;
struct Reliable
{
Reliable *next;
uchar addr[IPaddrlen]; /* always V6 when put here */
ushort port;
Block *unacked; /* unacked msg list */
Block *unackedtail; /* and its tail */
int timeout; /* time since first unacked msg sent */
int xmits; /* number of times first unacked msg sent */
ulong sndseq; /* next packet to be sent */
ulong sndgen; /* and its generation */
ulong rcvseq; /* last packet received */
ulong rcvgen; /* and its generation */
ulong acksent; /* last ack sent */
ulong ackrcvd; /* last msg for which ack was rcvd */
};
/* MIB II counters */
typedef struct Rudpstats Rudpstats;
struct Rudpstats
{
ulong rudpInDatagrams;
ulong rudpNoPorts;
ulong rudpInErrors;
ulong rudpOutDatagrams;
};
typedef struct Rudppriv Rudppriv;
struct Rudppriv
{
/* MIB counters */
Rudpstats ustats;
/* non-MIB stats */
ulong csumerr; /* checksum errors */
ulong lenerr; /* short packet */
};
static ulong generation = 0;
static Rendez rend;
/*
* protocol specific part of Conv
*/
typedef struct Rudpcb Rudpcb;
struct Rudpcb
{
QLock;
uchar headers;
Reliable *r;
};
/*
* local functions
*/
void relsendack( Conv *, Reliable * );
int reliput( Conv *, Block *, uchar *, ushort );
Reliable *relstate( Rudpcb *, uchar *, ushort );
void relackproc( void * );
void relackq( Reliable *, Block * );
void relhangup( Conv *, Reliable * );
void relrexmit( Conv *, Reliable * );
static char*
rudpconnect(Conv *c, char **argv, int argc)
{
char *e;
e = Fsstdconnect(c, argv, argc);
Fsconnected(c, e);
return e;
}
static int
rudpstate(Conv *c, char *state, int n)
{
USED(c);
return snprint(state, n, "%s", "Reliable UDP");
}
static char*
rudpannounce(Conv *c, char** argv, int argc)
{
char *e;
e = Fsstdannounce(c, argv, argc);
if(e != nil)
return e;
Fsconnected(c, nil);
return nil;
}
static void
rudpcreate(Conv *c)
{
c->rq = qopen(64*1024, 1, 0, 0);
c->wq = qopen(64*1024, 0, 0, 0);
}
static void
rudpclose(Conv *c)
{
Rudpcb *ucb;
Reliable *r, *nr;
qclose(c->rq);
qclose(c->wq);
qclose(c->eq);
ipmove(c->laddr, IPnoaddr);
ipmove(c->raddr, IPnoaddr);
c->lport = 0;
c->rport = 0;
ucb = (Rudpcb*)c->ptcl;
ucb->headers = 0;
qlock( ucb );
for( r = ucb->r; r; r = nr ){
nr = r->next;
relhangup( c, r );
free( r );
}
ucb->r = 0;
qunlock( ucb );
unlock(c);
}
void
rudpkick(Conv *c, int)
{
Rudphdr *uh;
ushort rport;
uchar laddr[IPaddrlen], raddr[IPaddrlen];
Block *bp;
Rudpcb *ucb;
Relhdr *rh;
Reliable *r;
int dlen, ptcllen;
Rudppriv *upriv;
Fs *f;
upriv = c->p->priv;
f = c->p->f;
netlog(c->p->f, Logrudp, "rudp: kick\n");
bp = qget(c->wq);
if(bp == nil)
return;
ucb = (Rudpcb*)c->ptcl;
switch(ucb->headers) {
case 6:
/* get user specified addresses */
bp = pullupblock(bp, RUDP_USEAD6);
if(bp == nil)
return;
ipmove(raddr, bp->rp);
bp->rp += IPaddrlen;
ipmove(laddr, bp->rp);
bp->rp += IPaddrlen;
/* pick interface closest to dest */
if(ipforme(f, laddr) != Runi)
findlocalip(f, laddr, raddr);
rport = nhgets(bp->rp);
bp->rp += 4; /* Igonore local port */
break;
case 4:
bp = pullupblock(bp, RUDP_USEAD4);
if(bp == nil)
return;
v4tov6(raddr, bp->rp);
bp->rp += IPv4addrlen;
v4tov6(laddr, bp->rp);
bp->rp += IPv4addrlen;
if(ipforme(f, laddr) != Runi)
findlocalip(f, laddr, raddr);
rport = nhgets(bp->rp);
bp->rp += 4; /* Igonore local port */
break;
default:
rport = 0;
break;
}
dlen = blocklen(bp);
/* Make space to fit rudp & ip header */
bp = padblock(bp, RUDP_IPHDR+RUDP_HDRSIZE);
if(bp == nil)
return;
uh = (Rudphdr *)(bp->rp);
rh = &(uh->rhdr);
ptcllen = dlen + (RUDP_HDRSIZE-RUDP_PHDRSIZE);
uh->Unused = 0;
uh->rudpproto = IP_RUDPPROTO;
uh->frag[0] = 0;
uh->frag[1] = 0;
hnputs(uh->rudpplen, ptcllen);
switch(ucb->headers){
case 4:
case 6:
v6tov4(uh->rudpdst, raddr);
hnputs(uh->rudpdport, rport);
v6tov4(uh->rudpsrc, laddr);
break;
default:
v6tov4(uh->rudpdst, c->raddr);
hnputs(uh->rudpdport, c->rport);
if(ipcmp(c->laddr, IPnoaddr) == 0)
findlocalip(f, c->laddr, c->raddr);
v6tov4(uh->rudpsrc, c->laddr);
break;
}
hnputs(uh->rudpsport, c->lport);
hnputs(uh->rudplen, ptcllen);
uh->rudpcksum[0] = 0;
uh->rudpcksum[1] = 0;
qlock( ucb );
r = relstate( ucb, raddr, rport );
r->sndseq++;
hnputl( rh->relseq, r->sndseq );
hnputl( rh->relsgen, r->sndgen );
hnputl( rh->relack, r->rcvseq ); /* ACK last rcvd packet */
hnputl( rh->relagen, r->rcvgen );
if(r->rcvseq < r->acksent)
r->acksent = r->rcvseq;
hnputs(uh->rudpcksum, ptclcsum(bp, RUDP_IPHDR, dlen+RUDP_HDRSIZE));
relackq( r, bp );
qunlock( ucb );
upriv->ustats.rudpOutDatagrams++;
DPRINT( "sent: %d/%d, %d/%d\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen );
ipoput(f, bp, 0, c->ttl);
}
void
rudpiput(Proto *rudp, uchar *ia, Block *bp)
{
int len, olen, ottl;
Rudphdr *uh;
Conv *c, **p;
Rudpcb *ucb;
uchar raddr[IPaddrlen], laddr[IPaddrlen];
ushort rport, lport;
Rudppriv *upriv;
Fs *f;
upriv = rudp->priv;
f = rudp->f;
upriv->ustats.rudpInDatagrams++;
uh = (Rudphdr*)(bp->rp);
/* Put back pseudo header for checksum
* (remember old values for icmpnoconv())
*/
ottl = uh->Unused;
uh->Unused = 0;
len = nhgets(uh->rudplen);
olen = nhgets(uh->rudpplen);
hnputs(uh->rudpplen, len);
v4tov6(raddr, uh->rudpsrc);
v4tov6(laddr, uh->rudpdst);
lport = nhgets(uh->rudpdport);
rport = nhgets(uh->rudpsport);
if(nhgets(uh->rudpcksum)) {
if(ptclcsum(bp, RUDP_IPHDR, len+RUDP_PHDRSIZE)) {
upriv->ustats.rudpInErrors++;
netlog(f, Logrudp, "rudp: checksum error %I\n", raddr);
DPRINT("rudp: checksum error %I\n", raddr);
freeblist(bp);
return;
}
}
/* Look for a conversation structure for this port */
c = nil;
for(p = rudp->conv; *p; p++) {
c = *p;
if(c->inuse == 0)
continue;
if(c->lport == lport && (c->rport == 0 || c->rport == rport))
break;
}
if(*p == nil) {
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,
laddr, lport);
uh->Unused = ottl;
hnputs(uh->rudpplen, olen);
icmpnoconv(f, bp);
freeblist(bp);
return;
}
ucb = (Rudpcb*)c->ptcl;
qlock( ucb );
if( reliput( c, bp, raddr, rport ) < 0 ){
qunlock( ucb );
freeb( bp );
return;
}
/*
* Trim the packet down to data size
*/
len -= (RUDP_HDRSIZE-RUDP_PHDRSIZE);
bp = trimblock(bp, RUDP_IPHDR+RUDP_HDRSIZE, len);
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",
raddr, rport, laddr, lport);
upriv->lenerr++;
return;
}
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);
ipmove(bp->rp, raddr);
if(ipforme(f, laddr) == Runi)
ipmove(bp->rp+IPaddrlen, laddr);
else
ipmove(bp->rp+IPaddrlen, ia);
hnputs(bp->rp+2*IPaddrlen, rport);
hnputs(bp->rp+2*IPaddrlen+2, lport);
break;
case 4:
/* pass the src address */
bp = padblock(bp, RUDP_USEAD4);
v6tov4(bp->rp, raddr);
if(ipforme(f, laddr) == Runi)
v6tov4(bp->rp+IPv4addrlen, laddr);
else
v6tov4(bp->rp+IPv4addrlen, ia);
hnputs(bp->rp + 2*IPv4addrlen, rport);
hnputs(bp->rp + 2*IPv4addrlen + 2, lport);
break;
default:
/* connection oriented rudp */
if(c->raddr == 0){
/* save the src address in the conversation */
ipmove(c->raddr, raddr);
c->rport = rport;
/* reply with the same ip address (if not broadcast) */
if(ipforme(f, laddr) == Runi)
ipmove(c->laddr, laddr);
else
v4tov6(c->laddr, ia);
}
break;
}
if(bp->next)
bp = concatblock(bp);
if(qfull(c->rq)){
netlog(f, Logrudp, "rudp: qfull %I.%d -> %I.%d\n", raddr, rport,
laddr, lport);
freeblist(bp);
}
else
qpass(c->rq, bp);
qunlock( ucb );
}
char*
rudpctl(Conv *c, char **f, int n)
{
Rudpcb *ucb;
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;
}
}
return "unknown control request";
}
void
rudpadvise(Proto *rudp, Block *bp, char *msg)
{
Rudphdr *h;
uchar source[IPaddrlen], dest[IPaddrlen];
ushort psource, pdest;
Conv *s, **p;
h = (Rudphdr*)(bp->rp);
v4tov6(dest, h->rudpdst);
v4tov6(source, h->rudpsrc);
psource = nhgets(h->rudpsport);
pdest = nhgets(h->rudpdport);
/* Look for a connection */
for(p = rudp->conv; *p; p++) {
s = *p;
if(s->rport == pdest)
if(s->lport == psource)
if(ipcmp(s->raddr, dest) == 0)
if(ipcmp(s->laddr, source) == 0){
qhangup(s->rq, msg);
qhangup(s->wq, msg);
break;
}
}
freeblist(bp);
}
int
rudpstats(Proto *rudp, char *buf, int len)
{
Rudppriv *upriv;
upriv = rudp->priv;
return snprint(buf, len, "%d %d %d %d\n",
upriv->ustats.rudpInDatagrams,
upriv->ustats.rudpNoPorts,
upriv->ustats.rudpInErrors,
upriv->ustats.rudpOutDatagrams);
}
void
rudpinit(Fs *fs)
{
Proto *rudp;
rudp = smalloc(sizeof(Proto));
rudp->priv = smalloc(sizeof(Rudppriv));
rudp->name = "rudp";
rudp->kick = rudpkick;
rudp->connect = rudpconnect;
rudp->announce = rudpannounce;
rudp->ctl = rudpctl;
rudp->state = rudpstate;
rudp->create = rudpcreate;
rudp->close = rudpclose;
rudp->rcv = rudpiput;
rudp->advise = rudpadvise;
rudp->stats = rudpstats;
rudp->ipproto = IP_RUDPPROTO;
rudp->nc = 16;
rudp->ptclsize = sizeof(Rudpcb);
Fsproto(fs, rudp);
kproc( "relackproc", relackproc, rudp );
}
/*********************************************/
/* Here starts the reliable helper functions */
/*********************************************/
/*
* Enqueue a copy of an unacked block for possible retransmissions
*/
void
relackq(Reliable *r, Block *bp)
{
Block *np;
np = copyblock(bp, blocklen(bp));
if(r->unacked)
r->unackedtail->list = np;
else {
/* restart timer */
r->timeout = 0;
r->xmits = 1;
r->unacked = np;
}
r->unackedtail = np;
np->list = nil;
}
/*
* retransmit unacked blocks
*/
void
relackproc(void *a)
{
Rudpcb *ucb;
Proto *rudp;
Reliable *r;
Conv **s, *c;
rudp = (Proto *)a;
loop:
tsleep(&rend, 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){
if(r->unacked != nil){
r->timeout += Rudptickms;
if(r->timeout > Rudprxms*r->xmits)
relrexmit(c, r);
}
if(r->acksent < r->rcvseq)
relsendack(c, r);
}
qunlock( ucb );
}
goto loop;
}
/*
* get the state record for a conversation
*/
Reliable*
relstate(Rudpcb *ucb, uchar *addr, ushort port)
{
Reliable *r, **l;
l = &ucb->r;
for(r = *l; r; r = *l){
if( memcmp( addr, r->addr, IPaddrlen) == 0 &&
port == r->port)
break;
l = &r->next;
}
/* 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);
r = smalloc( sizeof( Reliable ) );
*l = r;
memmove( r->addr, addr, IPaddrlen);
r->port = port;
r->unacked = 0;
r->sndgen = generation++;
r->sndseq = 0;
r->ackrcvd = 0;
r->rcvgen = 0;
r->rcvseq = 0;
r->acksent = 0;
r->xmits = 0;
r->timeout = 0;
}
return r;
}
/*
* process a rcvd reliable packet. return -1 if not to be passed to user process,
* 0 therwise.
*/
int
reliput(Conv *c, Block *bp, uchar *addr, ushort port)
{
Block *nbp;
Rudpcb *ucb;
Rudphdr *uh;
Reliable *r;
Relhdr *rh;
ulong seq, ack, sgen, agen, ackreal;
/* get fields */
uh = (Rudphdr *)(bp->rp);
rh = &(uh->rhdr);
seq = nhgetl(rh->relseq);
sgen = nhgetl(rh->relsgen);
ack = nhgetl(rh->relack);
agen = nhgetl(rh->relagen);
ucb = (Rudpcb*)c->ptcl;
r = relstate(ucb, addr, port);
DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d, r->ackrcvd = %d\n",
seq, sgen, ack, agen, r->sndgen, r->ackrcvd);
/* 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);
freeb(nbp);
r->ackrcvd++;
ackreal = 1;
}
/*
* retransmit next packet if the acked packet
* was transmitted more than once
*/
if(ackreal && r->unacked != nil){
r->timeout = 0;
if(r->xmits > 1){
r->xmits = 1;
relrexmit(c, r);
}
}
}
/* 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 = %d, sgen = %d\n", r->rcvgen, sgen);
relhangup(c, r);
}
r->rcvgen = sgen;
}
/* no message */
if(seq == 0)
return -1;
/* refuse out of order delivery */
if(seq != r->rcvseq + 1){
DPRINT("out of sequence %d not %d\n", seq, r->rcvseq + 1);
return -1;
}
r->rcvseq = seq;
return 0;
}
void
relsendack(Conv *c, Reliable *r)
{
Rudphdr *uh;
Block *bp;
Relhdr *rh;
int ptcllen;
Fs *f;
bp = allocb(RUDP_IPHDR + RUDP_HDRSIZE);
if(bp == nil)
return;
bp->wp += RUDP_IPHDR + RUDP_HDRSIZE;
f = c->p->f;
uh = (Rudphdr *)(bp->rp);
rh = &(uh->rhdr);
ptcllen = (RUDP_HDRSIZE-RUDP_PHDRSIZE);
uh->Unused = 0;
uh->rudpproto = IP_RUDPPROTO;
uh->frag[0] = 0;
uh->frag[1] = 0;
hnputs(uh->rudpplen, ptcllen);
v6tov4( uh->rudpdst, r->addr );
hnputs(uh->rudpdport, r->port);
hnputs(uh->rudpsport, c->lport);
if(ipcmp(c->laddr, IPnoaddr) == 0)
findlocalip(f, c->laddr, c->raddr);
v6tov4(uh->rudpsrc, c->laddr);
hnputs(uh->rudplen, ptcllen);
hnputl(rh->relsgen, r->sndgen);
hnputl(rh->relseq, 0);
hnputl(rh->relagen, r->rcvgen);
hnputl(rh->relack, r->rcvseq);
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));
DPRINT( "sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen );
ipoput(f, bp, 0, c->ttl);
}
/*
* called with ucb locked (and c locked if user initiated close)
*/
void
relhangup( Conv *, Reliable *r )
{
Block *bp;
/*
* dump any unacked outgoing messages
*/
for(bp = r->unacked; bp != nil; bp = r->unacked){
r->unacked = bp->list;
bp->list = nil;
freeb(bp);
}
r->rcvgen = 0;
r->rcvseq = 0;
r->acksent = 0;
r->sndgen = generation++;
r->sndseq = 0;
r->ackrcvd = 0;
r->xmits = 0;
r->timeout = 0;
}
/*
* called with ucb locked
*/
void
relrexmit(Conv *c, Reliable *r)
{
Block *np;
Fs *f;
f = c->p->f;
r->timeout = 0;
if(r->xmits++ > Rudpmaxxmit){
relhangup(c, r);
return;
}
np = copyblock(r->unacked, blocklen(r->unacked));
//DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1);
ipoput(f, np, 0, c->ttl);
}
.
## diffname ip/rudp.c 1998/0726
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0726/sys/src/brazil/ip/rudp.c
859c
DPRINT("rxmit r->ackrvcd+1 = %d\n", r->ackrcvd+1);
.
857a
upriv->rxmits++;
.
850a
upriv = c->p->priv;
.
848a
Rudppriv *upriv;
.
755a
upriv->orders++;
.
753a
if( DEBUG && ++drop == drop_rate ){
DPRINT( "drop pkt on purpose\n" );
drop = 0;
return -1;
}
.
716c
DPRINT("%d/%d acked, r->sndgen = %d\n",
ack, agen, r->sndgen);
.
711d
706,707c
DPRINT("rcvd %d/%d, %d/%d, r->sndgen = %d\n",
seq, sgen, ack, agen, r->sndgen);
.
703c
r = relstate(ucb, addr, port, "input" );
.
701c
upriv = c->p->priv;
.
684a
Rudppriv *upriv;
.
656a
DPRINT( "from %s new state %d for %I!%d\n",
from, generation, addr, port );
.
654d
643a
.
639c
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from )
.
630c
qunlock(ucb);
.
620,621c
for(r = ucb->r; r; r = r->next) {
.
618c
qlock(ucb);
.
613c
tsleep(&upriv->vous, return0, 0, Rudptickms);
.
611a
upriv = rudp->priv;
.
609a
Rudppriv *upriv;
.
572c
kproc("relackproc", relackproc, rudp);
.
544c
upriv->ustats.rudpOutDatagrams,
upriv->rxmits,
upriv->orders);
.
540c
return snprint(buf, len, "%d %d %d %d %d %d\n",
.
374a
upriv->csumerr++;
.
331,332c
DPRINT( "sent: %d/%d, %d/%d, r->sndgen = %d\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen );
.
311c
r = relstate( ucb, raddr, rport, "kick" );
.
282a
.
267c
ipmove( raddr, c->raddr );
ipmove( laddr, c->laddr );
rport = c->rport;
.
160c
return snprint(state, n, "%s", "Reliable UDP V0.1");
.
138c
Reliable *relstate( Rudpcb *, uchar *, ushort, char *from );
.
121a
/* Used only for debugging */
static ushort drop = 0;
static ushort drop_rate = 10;
.
114,115c
ulong csumerr; /* checksum errors */
ulong lenerr; /* short packet */
ulong rxmits; /* # of retransmissions */
ulong orders; /* # of out of order pkts */
.
109d
107a
Rendez vous;
.
25c
Rudpmaxxmit = 10,
.
11c
#define DEBUG 0
#define DPRINT if(DEBUG)print
.
## diffname ip/rudp.c 1998/0728
## diff -e /n/emeliedump/1998/0726/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0728/sys/src/brazil/ip/rudp.c
846c
relhangup(Conv *, Reliable *r)
.
838c
DPRINT("sendack: %d/%d, %d/%d\n", 0, r->sndgen, r->rcvseq, r->rcvgen);
.
834,836c
uh->udpcksum[0] = 0;
uh->udpcksum[1] = 0;
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE));
.
824,825d
821,822c
v6tov4(uh->udpsrc, c->laddr);
hnputs(uh->udplen, ptcllen);
.
814,818c
v6tov4(uh->udpdst, r->addr);
hnputs(uh->udpdport, r->port);
hnputs(uh->udpsport, c->lport);
.
812c
hnputs(uh->udpplen, ptcllen);
.
809c
uh->udpproto = IP_UDPPROTO;
.
807c
ptcllen = (UDP_RHDRSIZE-UDP_PHDRSIZE);
.
804,805c
uh = (Udphdr *)(bp->rp);
rh = (Rudphdr*)uh;
.
802c
bp->wp += UDP_IPHDR + UDP_RHDRSIZE;
.
799c
bp = allocb(UDP_IPHDR + UDP_RHDRSIZE);
.
795c
Rudphdr *rh;
.
793c
Udphdr *uh;
.
773,774c
if(DEBUG && ++drop == drop_rate){
DPRINT("drop pkt on purpose\n");
.
722c
r = relstate(ucb, addr, port, "input");
.
712,713c
uh = (Udphdr*)(bp->rp);
rh = (Rudphdr*)uh;
.
706c
Rudphdr *rh;
.
704c
Udphdr *uh;
.
677c
memmove(r->addr, addr, IPaddrlen);
.
673,675c
DPRINT("from %s new state %d for %I!%d\n",
from, generation, addr, port);
r = smalloc(sizeof(Reliable));
.
663c
if(memcmp(addr, r->addr, IPaddrlen) == 0 &&
.
659,660d
655c
relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from)
.
580c
rudp->ipproto = IP_UDPPROTO;
.
526,529c
v4tov6(dest, h->udpdst);
v4tov6(source, h->udpsrc);
psource = nhgets(h->udpsport);
pdest = nhgets(h->udpdport);
.
524c
h = (Udphdr*)(bp->rp);
.
519c
Udphdr *h;
.
495c
qunlock(ucb);
.
460c
bp = padblock(bp, UDP_USEAD4);
.
449c
bp = padblock(bp, UDP_USEAD6);
.
444,445d
435c
DPRINT("rudp: len err %I.%d -> %I.%d\n",
.
430,431c
len -= (UDP_RHDRSIZE-UDP_PHDRSIZE);
bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len);
.
419,422c
qlock(ucb);
if(reliput(c, bp, raddr, rport) < 0){
qunlock(ucb);
freeb(bp);
.
411c
hnputs(uh->udpplen, olen);
.
408c
DPRINT("rudp: no conv %I!%d -> %I!%d\n", raddr, rport,
.
400,401c
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;
}
.
381,384c
if(nhgets(uh->udpcksum)) {
if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) {
.
376,379c
v4tov6(raddr, uh->udpsrc);
v4tov6(laddr, uh->udpdst);
lport = nhgets(uh->udpdport);
rport = nhgets(uh->udpsport);
.
372,374c
len = nhgets(uh->udplen);
olen = nhgets(uh->udpplen);
hnputs(uh->udpplen, len);
.
365c
uh = (Udphdr*)(bp->rp);
.
352c
Udphdr *uh;
.
341,344d
339a
DPRINT("sent: %d/%d, %d/%d, r->sndgen = %d\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen, r->sndgen);
.
335,336c
relackq(r, bp);
qunlock(ucb);
.
333c
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_RHDRSIZE));
.
327,328c
hnputl(rh->relack, r->rcvseq); /* ACK last rcvd packet */
hnputl(rh->relagen, r->rcvgen);
.
324,325c
hnputl(rh->relseq, r->sndseq);
hnputl(rh->relsgen, r->sndgen);
.
320,322c
qlock(ucb);
r = relstate(ucb, raddr, rport, "kick");
.
315,318c
hnputs(uh->udpsport, c->lport);
hnputs(uh->udplen, ptcllen);
uh->udpcksum[0] = 0;
uh->udpcksum[1] = 0;
.
312c
v6tov4(uh->udpsrc, c->laddr);
.
308,309c
v6tov4(uh->udpdst, c->raddr);
hnputs(uh->udpdport, c->rport);
.
303,305c
v6tov4(uh->udpdst, raddr);
hnputs(uh->udpdport, rport);
v6tov4(uh->udpsrc, laddr);
.
299c
hnputs(uh->udpplen, ptcllen);
.
296c
uh->udpproto = IP_UDPPROTO;
.
293,294c
ptcllen = dlen + (UDP_RHDRSIZE-UDP_PHDRSIZE);
.
291c
rh = (Rudphdr*)uh;
.
289c
uh = (Udphdr *)(bp->rp);
.
285c
bp = padblock(bp, UDP_IPHDR+UDP_RHDRSIZE);
.
275,276c
ipmove(raddr, c->raddr);
ipmove(laddr, c->laddr);
.
261c
bp = pullupblock(bp, UDP_USEAD4);
.
246c
bp = pullupblock(bp, UDP_USEAD6);
.
228c
Rudphdr *rh;
.
223c
Udphdr *uh;
.
215c
qunlock(ucb);
.
210,211c
relhangup(c, r);
free(r);
.
207,208c
qlock(ucb);
for(r = ucb->r; r; r = nr){
.
144,150c
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 *);
.
77d
58,62c
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 */
.
56a
/* 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 */
.
51,55d
36,39c
/* 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 */
.
30,34c
typedef struct Udphdr Udphdr;
struct Udphdr
.
16,22c
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,
.
1c
/*
* This protocol is compatible with UDP's packet format.
* It could be done over UDP if need be.
*/
.
## diffname ip/rudp.c 1998/0731
## diff -e /n/emeliedump/1998/0728/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0731/sys/src/brazil/ip/rudp.c
730,731d
694c
generation = rand();
.
495c
if(ipcmp(c->raddr, IPnoaddr) == 0){
.
## diffname ip/rudp.c 1998/0801
## diff -e /n/emeliedump/1998/0731/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0801/sys/src/brazil/ip/rudp.c
882a
wakeup(&r->vous);
.
802c
DPRINT("out of sequence %d not %d\n", seq, NEXTSEQ(r->rcvseq));
.
800c
if(seq != NEXTSEQ(r->rcvseq)){
.
789,790c
/* no message or input queue full */
if(seq == 0 || qfull(c->rq))
.
780d
760a
/* flow control */
if(UNACKED(r) < Maxunacked/8 && r->blocked)
wakeup(&r->vous);
.
757c
r->ackrcvd = NEXTSEQ(r->ackrcvd);
.
751c
while(r->unacked != nil && INSEQ(ack, r->ackrcvd, r->sndseq)){
.
739d
667c
if(r->acksent != r->rcvseq)
.
362a
/* 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);
.
349c
if(r->rcvseq != r->acksent)
.
342c
r->sndseq = NEXTSEQ(r->sndseq);
.
240a
int
flow(Reliable *r)
{
return UNACKED(r) <= Maxunacked;
}
.
188,189c
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;
.
112a
/* flow control */
QLock lock;
Rendez vous;
int blocked;
.
96c
uchar addr[IPaddrlen]; /* always V6 when put here */
.
30c
Maxunacked = 100,
.
16a
#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 )
.
## diffname ip/rudp.c 1998/0825
## diff -e /n/emeliedump/1998/0801/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0825/sys/src/brazil/ip/rudp.c
946c
DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1);
.
894c
DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen);
.
842c
DPRINT("out of sequence %lud not %lud\n", seq, NEXTSEQ(r->rcvseq));
.
823c
DPRINT("new con r->rcvgen = %lud, sgen = %lud\n", r->rcvgen, sgen);
.
791c
DPRINT("%lud/%lud acked, r->sndgen = %lud\n",
.
782c
DPRINT("rcvd %lud/%lud, %lud/%lud, r->sndgen = %lud\n",
.
733c
DPRINT("from %s new state %lud for %I!%ud\n",
.
614c
return snprint(buf, len, "%lud %lud %lud %lud %lud %lud\n",
.
388,389c
DPRINT("sent: %lud/%lud, %lud/%lud\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen);
.
210c
m += snprint(state+m, n-m, " %I/%ld", r->addr, UNACKED(r));
.
## diffname ip/rudp.c 1998/0924
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/0924/sys/src/brazil/ip/rudp.c
647,649d
219a
rudpstartackproc(c->p);
.
191a
rudpstartackproc(c->p);
.
186a
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);
}
}
.
154a
/* keeping track of the ack kproc */
int ackprocstarted;
QLock apl;
.
## diffname ip/rudp.c 1998/1117
## diff -e /n/emeliedump/1998/0924/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/1117/sys/src/brazil/ip/rudp.c
860a
relsendack(c, r); /* tell him we got it already */
.
37c
Rudptickms = 50,
.
## diffname ip/rudp.c 1998/1118
## diff -e /n/emeliedump/1998/1117/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/1118/sys/src/brazil/ip/rudp.c
968c
doipoput(c, f, np, 0, c->ttl);
.
926a
n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port);
qproduce(c->eq, hup, n);
.
925a
char hup[ERRLEN];
.
924a
int n;
.
923c
relhangup(Conv *c, Reliable *r)
.
916c
doipoput(c, f, bp, 0, c->ttl);
.
853,858d
836,848d
804a
/* 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;
}
.
595a
} else if(strcmp(f[0], "randdrop") == 0){
ucb->randdrop = 1;
return nil;
.
414c
doipoput(c, f, bp, 0, c->ttl);
.
286a
/*
* 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);
}
.
275a
if(r->acksent != r->rcvseq)
relsendack(c, r);
.
273a
ucb->randdrop = 0;
.
272d
263a
/* 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);
.
175a
uchar randdrop;
.
164,167d
## diffname ip/rudp.c 1998/1124
## diff -e /n/emeliedump/1998/1118/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/1124/sys/src/brazil/ip/rudp.c
830a
/* if acking an incorrect generation, ignore */
if(ack && agen != r->sndgen)
return -1;
.
## diffname ip/rudp.c 1998/1127
## diff -e /n/emeliedump/1998/1124/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/1127/sys/src/brazil/ip/rudp.c
837c
if(seq != 0 && seq != 1)
.
777c
while(generation == 0)
.
## diffname ip/rudp.c 1998/1230
## diff -e /n/emeliedump/1998/1127/sys/src/brazil/ip/rudp.c /n/emeliedump/1998/1230/sys/src/brazil/ip/rudp.c
624c
return rudpunknown;
.
612,622c
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;
.
609a
int x;
.
605a
static char *rudpunknown = "unknown rudp ctl request";
.
304c
if(ucb->randdrop && nrand(100) < ucb->randdrop)
.
## diffname ip/rudp.c 1999/0302
## diff -e /n/emeliedump/1998/1230/sys/src/brazil/ip/rudp.c /n/emeliedump/1999/0302/sys/src/brazil/ip/rudp.c
529a
qunlock(rudp);
.
528d
514a
qunlock(rudp);
.
492a
qlock(rudp);
.
292c
qunlock(c);
.
## diffname ip/rudp.c 1999/0320
## diff -e /n/emeliedump/1999/0302/sys/src/brazil/ip/rudp.c /n/emeliedump/1999/0320/sys/src/brazil/ip/rudp.c
312a
Reliable *r = v;
.
311c
flow(void *v)
.
## diffname ip/rudp.c 1999/0817
## diff -e /n/emeliedump/1999/0320/sys/src/brazil/ip/rudp.c /n/emeliedump/1999/0817/sys/src/brazil/ip/rudp.c
1012c
doipoput(c, f, np, 0, c->ttl, c->tos);
.
955c
doipoput(c, f, bp, 0, c->ttl, c->tos);
.
439c
doipoput(c, f, bp, 0, c->ttl, c->tos);
.
307c
ipoput(f, bp, x, ttl, tos);
.
299c
doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos)
.
## diffname ip/rudp.c 2000/0317
## diff -e /n/emeliedump/1999/0817/sys/src/brazil/ip/rudp.c /n/emeliedump/2000/0317/sys/src/9/ip/rudp.c
982a
if(generation == Hangupgen)
generation++;
.
957a
.
942c
if(hangup)
hnputl(rh->relsgen, Hangupgen);
else
hnputl(rh->relsgen, r->sndgen);
.
911c
relsendack(Conv *c, Reliable *r, int hangup)
.
907c
rv = 0;
out:
relput(r);
qunlock(ucb);
return rv;
.
903c
goto out;
.
900c
relsendack(c, r, 0); /* tell him we got it already */
.
896c
goto out;
.
853c
goto out;
.
849a
/* Look for a hangup */
if(sgen == Hangupgen) {
if(agen == r->sndgen)
relforget(c, addr, port, 0);
goto out;
}
.
848c
goto out;
.
841d
839a
qlock(ucb);
.
828a
int rv = -1;
.
814a
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;
}
}
.
813a
void
relput(Reliable *r)
{
if(decref(r) == 0)
free(r);
}
.
810c
incref(r);
.
808a
r->ref = 0;
incref(r); /* one reference for being in the list */
.
800a
if(generation == Hangupgen)
generation++;
.
767c
relsendack(c, r, 0);
.
629a
} 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;
.
617a
uchar ip[IPaddrlen];
.
448c
relput(r);
qunlock(ucb);
.
442d
432d
283c
relsendack(c, r, 0);
.
266c
relsendack(c, r, 0);
.
181a
void relput(Reliable *);
void relforget(Conv *, uchar *, int, int);
.
179c
void relsendack(Conv *, Reliable *, int);
.
124d
102a
Ref;
.
41a
#define Hangupgen 0xffffffff /* used only in hangup messages */
.
39a
.
## diffname ip/rudp.c 2000/0328
## diff -e /n/emeliedump/2000/0317/sys/src/9/ip/rudp.c /n/emeliedump/2000/0328/sys/src/9/ip/rudp.c
453d
451a
qunlock(&r->lock);
.
446a
qlock(&r->lock);
.
437a
qunlock(ucb);
.
128a
QLock lock;
.
## diffname ip/rudp.c 2000/0403
## diff -e /n/emeliedump/2000/0328/sys/src/9/ip/rudp.c /n/emeliedump/2000/0403/sys/src/9/ip/rudp.c
968d
891d
867a
*
* called with ucb locked.
.
842a
/*
* forget a Reliable state
*/
.
830a
*l = r;
.
815d
813a
.
455a
.
293c
relput(r);
.
## diffname ip/rudp.c 2000/0605
## diff -e /n/emeliedump/2000/0403/sys/src/9/ip/rudp.c /n/emeliedump/2000/0605/sys/src/9/ip/rudp.c
834a
.
812a
.
610c
if(qfull(c->rq)) {
.
557c
if(bp == nil) {
.
457a
poperror();
.
456a
qunlock(&r->lock);
.
455d
447a
if(waserror()) {
relput(r);
qunlock(&r->lock);
nexterror();
}
.
298d
190,192c
void relackq(Reliable *, Block*);
void relhangup(Conv *, Reliable*);
void relrexmit(Conv *, Reliable*);
void relput(Reliable*);
.
184,188c
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);
.
## diffname ip/rudp.c 2000/1220
## diff -e /n/emeliedump/2000/0605/sys/src/9/ip/rudp.c /n/emeliedump/2000/1220/sys/src/9/ip/rudp.c
299d
## diffname ip/rudp.c 2001/0301
## diff -e /n/emeliedump/2000/1220/sys/src/9/ip/rudp.c /n/emeliedump/2001/0301/sys/src/9/ip/rudp.c
546d
538,539d
536c
qunlock(rudp);
netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport,
.
512,534c
c = iphtlook(&upriv->ht, raddr, rport, laddr, lport);
if(c == nil){
/* no converstation found */
.
471c
Conv *c;
.
268a
upriv = c->p->priv;
iphtrem(&upriv->ht, c);
.
267a
Rudppriv *upriv;
.
251a
iphtadd(&upriv->ht, c);
.
246a
upriv = c->p->priv;
.
245a
Rudppriv *upriv;
.
220a
iphtadd(&upriv->ht, c);
.
217a
upriv = c->p->priv;
.
216a
Rudppriv *upriv;
.
149a
Ipht ht;
.
## diffname ip/rudp.c 2001/0306
## diff -e /n/emeliedump/2001/0301/sys/src/9/ip/rudp.c /n/emeliedump/2001/0306/sys/src/9/ip/rudp.c
336c
rudpkick(Conv *c)
.
## diffname ip/rudp.c 2001/0623
## diff -e /n/emeliedump/2001/0306/sys/src/9/ip/rudp.c /n/emeliedump/2001/0623/sys/src/9/ip/rudp.c
598c
v4tov6(c->laddr, ifc->lifc->local);
.
583c
v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local);
.
572c
ipmove(bp->rp+IPaddrlen, ifc->lifc->local);
.
478c
rudpiput(Proto *rudp, Ipifc *ifc, Block *bp)
.
## diffname ip/rudp.c 2001/0918
## diff -e /n/emeliedump/2001/0623/sys/src/9/ip/rudp.c /n/emeliedump/2001/0918/sys/src/9/ip/rudp.c
1035c
char hup[ERRMAX];
.
200c
char kpname[KNAMELEN];
.
## diffname ip/rudp.c 2002/0507
## diff -e /n/emeliedump/2001/0918/sys/src/9/ip/rudp.c /n/emeliedump/2002/0507/sys/src/9/ip/rudp.c
989a
uh->vihl = IP_VER4;
.
404a
uh->vihl = IP_VER4;
.
324c
ipoput4(f, bp, x, ttl, tos);
.
## diffname ip/rudp.c 2002/0711
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/rudp.c /n/emeliedump/2002/0711/sys/src/9/ip/rudp.c
266c
c->rq = qopen(64*1024, Qmsg, 0, 0);
.
## diffname ip/rudp.c 2002/0712
## diff -e /n/emeliedump/2002/0711/sys/src/9/ip/rudp.c /n/emeliedump/2002/0712/sys/src/9/ip/rudp.c
711d
337a
Conv *c = x;
.
336c
rudpkick(void *x)
.
267c
c->wq = qopen(64*1024, Qkick, rudpkick, c);
.
194a
void rudpkick(void *x);
.
## diffname ip/rudp.c 2003/0308
## diff -e /n/emeliedump/2002/0712/sys/src/9/ip/rudp.c /n/emeliedump/2003/0308/sys/src/9/ip/rudp.c
325c
ipoput4(f, bp, x, ttl, tos, nil);
.
## diffname ip/rudp.c 2003/0407
## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/rudp.c /n/emeliedump/2003/0407/sys/src/9/ip/rudp.c
769c
tsleep(&up->sleep, return0, 0, Rudptickms);
.
149d
## diffname ip/rudp.c 2003/0409
## diff -e /n/emeliedump/2003/0407/sys/src/9/ip/rudp.c /n/emeliedump/2003/0409/sys/src/9/ip/rudp.c
765d
762d
## diffname ip/rudp.c 2003/0419
## diff -e /n/emeliedump/2003/0409/sys/src/9/ip/rudp.c /n/emeliedump/2003/0419/sys/src/9/ip/rudp.c
631,632c
if(strcmp(f[0], "headers++4") == 0){
ucb->headers = 7;
.
578,588d
570,576c
p = bp->rp;
ipmove(p, raddr); p += IPaddrlen;
ipmove(p, ipforme(f, laddr)==Runi ? laddr : ifc->lifc->local); p += IPaddrlen;
hnputs(p, rport); p += 2;
hnputs(p, lport);
.
566a
case 7:
/* pass the src address */
bp = padblock(bp, UDP_USEAD7);
p = bp->rp;
ipmove(p, raddr); p += IPaddrlen;
ipmove(p, laddr); p += IPaddrlen;
ipmove(p, ifc->lifc->local); p += IPaddrlen;
hnputs(p, rport); p += 2;
hnputs(p, lport);
break;
.
489a
uchar *p;
.
418a
case 7:
.
417d
380,383c
ipmove(raddr, bp->rp);
bp->rp += IPaddrlen;
ipmove(laddr, bp->rp);
bp->rp += IPaddrlen;
/* pick interface closest to dest */
.
376,377c
case 6:
/* get user specified addresses */
bp = pullupblock(bp, UDP_USEAD6);
.
373,374c
bp->rp += 2+2; /* Ignore local port */
.
371a
bp->rp += IPaddrlen; /* Ignore ifc address */
.
362c
bp = pullupblock(bp, UDP_USEAD7);
.
360c
case 7:
.
32a
UDP_USEAD7 = 52,
.
|