## diffname ip/il.c 1997/0327
## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/ip/il.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"
char *ilstates[] =
{
"Closed",
"Syncer",
"Syncee",
"Established",
"Listening",
"Closing"
};
char *iltype[] =
{
"sync",
"data",
"dataquerey",
"ack",
"querey",
"state",
"close"
};
static char *etime = "connection timed out";
enum /* Packet types */
{
Ilsync,
Ildata,
Ildataquery,
Ilack,
Ilquerey,
Ilstate,
Ilclose,
};
enum /* Connection state */
{
Ilclosed,
Ilsyncer,
Ilsyncee,
Ilestablished,
Illistening,
Ilclosing,
};
typedef struct Ilcb Ilcb;
struct Ilcb /* Control block */
{
int state; /* Connection state */
Conv *conv;
QLock ackq; /* Unacknowledged queue */
Block *unacked;
Block *unackedtail;
QLock outo; /* Out of order packet queue */
Block *outoforder;
ulong next; /* Id of next to send */
ulong recvd; /* Last packet received */
ulong start; /* Local start id */
ulong rstart; /* Remote start id */
int timeout; /* Time out counter */
int slowtime; /* Slow time counter */
int fasttime; /* Retransmission timer */
int acktime; /* Acknowledge timer */
int querytime; /* Query timer */
int deathtime; /* Time to kill connection */
int rtt; /* Average round trip time */
ulong rttack; /* The ack we are waiting for */
ulong ackms; /* Time we issued */
int window; /* Maximum receive window */
};
enum
{
IL_IPSIZE = 20,
IL_HDRSIZE = 18,
IL_LISTEN = 0,
IL_CONNECT = 1,
IP_ILPROTO = 40,
};
typedef struct Ilhdr Ilhdr;
struct Ilhdr
{
byte vihl; /* Version and header length */
byte tos; /* Type of service */
byte length[2]; /* packet length */
byte id[2]; /* Identification */
byte frag[2]; /* Fragment information */
byte ttl; /* Time to live */
byte proto; /* Protocol */
byte cksum[2]; /* Header checksum */
byte src[4]; /* Ip source */
byte dst[4]; /* Ip destination */
byte ilsum[2]; /* Checksum including header */
byte illen[2]; /* Packet length */
byte iltype; /* Packet type */
byte ilspec; /* Special */
byte ilsrc[2]; /* Src port */
byte ildst[2]; /* Dst port */
byte ilid[4]; /* Sequence id */
byte ilack[4]; /* Acked sequence */
};
/* Always Acktime < Fasttime < Slowtime << Ackkeepalive */
enum
{
Seconds = 1000,
Iltickms = 100, /* time base */
Ackkeepalive = 6000*Iltickms,
Acktime = 2*Iltickms, /* max time twixt message rcvd & ack sent */
Slowtime = 90*Seconds, /* min time waiting for an ack before hangup */
Fasttime = 4*Iltickms, /* min time between rexmit */
Querytime = 5*Seconds, /* time between subsequent queries */
Keepalivetime = 60*Seconds, /* time before first query */
Deathtime = 120*Seconds, /* time between first query and hangup */
Defaultwin = 20,
ILgain = 8,
};
void ilrcvmsg(Conv*, Block*);
void ilsendctl(Conv*, Ilhdr*, int, ulong, ulong);
void ilackq(Ilcb*, Block*);
void ilprocess(Conv*, Ilhdr*, Block*);
void ilpullup(Conv*);
void ilhangup(Conv*, char*);
void ilfreeq(Ilcb*);
void ilrexmit(Ilcb*);
void ilbackoff(Ilcb*);
void iltimers(Ilcb*);
char* ilstart(Conv*, int, int);
void ilackproc();
void iloutoforder(Conv*, Ilhdr*, Block*);
void iliput(Block*);
void iladvise(Block*, char*);
#define DBG(x) if((logmask & Logilmsg) && (iponly == 0 || x == iponly))netlog
Proto il;
int ilcksum = 1;
static int initseq = 25001;
extern Fs fs;
static char*
ilconnect(Conv *c, char **argv, int argc)
{
char *e;
e = ilstart(c, IL_CONNECT, 20);
if(e != nil)
return e;
return Fsstdconnect(c, argv, argc);
}
int
ilstate(char **msg, Conv *c)
{
Ilcb *ic;
int isclose;
ic = (Ilcb*)(c->ptcl);
isclose = 0;
if(ic->state == Ilclosed)
isclose = 1;
*msg = ilstates[ic->state];
return isclose;
}
/* called with c locked */
static void
ilannounce(Conv *c)
{
char *e;
e = ilstart(c, IL_LISTEN, 20);
Fsconnected(&fs, c, e);
}
static void
ilclose(Conv *c)
{
Ilcb *ic;
ic = (Ilcb*)c->ptcl;
qclose(c->rq);
qclose(c->wq);
qclose(c->eq);
switch(ic->state) {
case Ilclosing:
case Ilclosed:
break;
case Ilsyncer:
case Ilsyncee:
case Ilestablished:
ilfreeq(ic);
ic->state = Ilclosing;
ilsendctl(c, nil, Ilclose, ic->next, ic->recvd);
break;
case Illistening:
ic->state = Ilclosed;
c->laddr = 0;
c->lport = 0;
break;
}
unlock(c);
}
void
ilkick(Conv *c, int l)
{
Ilhdr *ih;
Ilcb *ic;
int dlen;
ulong id;
Block *bp;
USED(l);
ic = (Ilcb*)c->ptcl;
bp = qget(c->wq);
if(bp == nil)
return;
switch(ic->state) {
case Ilclosed:
case Illistening:
case Ilclosing:
freeblist(bp);
qhangup(c->rq, nil);
return;
}
dlen = blocklen(bp);
/* Make space to fit il & ip */
bp = padblock(bp, IL_IPSIZE+IL_HDRSIZE);
ih = (Ilhdr *)(bp->rp);
/* Ip fields */
ih->frag[0] = 0;
ih->frag[1] = 0;
hnputl(ih->dst, c->raddr);
hnputl(ih->src, c->laddr);
ih->proto = IP_ILPROTO;
/* Il fields */
hnputs(ih->illen, dlen+IL_HDRSIZE);
hnputs(ih->ilsrc, c->lport);
hnputs(ih->ildst, c->rport);
qlock(&ic->ackq);
id = ic->next++;
hnputl(ih->ilid, id);
hnputl(ih->ilack, ic->recvd);
ih->iltype = Ildata;
ih->ilspec = 0;
ih->ilsum[0] = 0;
ih->ilsum[1] = 0;
/* Checksum of ilheader plus data (not ip & no pseudo header) */
if(ilcksum)
hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, dlen+IL_HDRSIZE));
ilackq(ic, bp);
qunlock(&ic->ackq);
/* Start the round trip timer for this packet if the timer is free */
if(ic->rttack == 0) {
ic->rttack = id;
ic->ackms = msec;
}
ic->acktime = Ackkeepalive;
ipoput(bp, 0, c->ttl);
}
static void
ilcreate(Conv *c)
{
c->rq = qopen(64*1024, 0, 0, c);
c->wq = qopen(64*1024, 0, 0, 0);
}
void
ilinit(Fs *fs)
{
il.name = "il";
il.kick = ilkick;
il.connect = ilconnect;
il.announce = ilannounce;
il.state = ilstate;
il.create = ilcreate;
il.close = ilclose;
il.rcv = iliput;
il.ctl = nil;
il.advise = iladvise;
il.ipproto = IP_ILPROTO;
il.nc = Nchans;
il.ptclsize = sizeof(Ilcb);
kproc("ilack", ilackproc, 0);
Fsproto(fs, &il);
}
void
ilackq(Ilcb *ic, Block *bp)
{
Block *np;
/* Enqueue a copy on the unacked queue in case this one gets lost */
np = copyblock(bp, blocklen(bp));
if(ic->unacked)
ic->unackedtail->list = np;
else {
/* Start timer since we may have been idle for some time */
iltimers(ic);
ic->unacked = np;
}
ic->unackedtail = np;
np->list = nil;
}
void
ilackto(Ilcb *ic, ulong ackto)
{
Ilhdr *h;
Block *bp;
ulong id, t;
if(ic->rttack == ackto) {
t = msec - ic->ackms;
/* Guard against the ulong zero wrap of MACHP(0)->ticks */
if(t < 120000)
ic->rtt = (ic->rtt*(ILgain-1)+t)/ILgain;
if(ic->rtt < Iltickms)
ic->rtt = Iltickms;
}
/* Cancel if we lost the packet we were interested in */
if(ic->rttack <= ackto)
ic->rttack = 0;
qlock(&ic->ackq);
while(ic->unacked) {
h = (Ilhdr *)ic->unacked->rp;
id = nhgetl(h->ilid);
if(ackto < id)
break;
bp = ic->unacked;
ic->unacked = bp->list;
bp->list = nil;
freeblist(bp);
}
qunlock(&ic->ackq);
}
void
iliput(Block *bp)
{
char *st;
Ilcb *ic;
Ilhdr *ih;
Ipaddr dst;
ushort sp, dp, csum;
int plen, illen;
Conv *s, **p, *new, *spec, *gen;
ih = (Ilhdr *)bp->rp;
plen = blocklen(bp);
if(plen < IL_IPSIZE+IL_HDRSIZE){
netlog(Logil, "il: hlenerr\n");
il.hlenerr++;
goto raise;
}
illen = nhgets(ih->illen);
if(illen+IL_IPSIZE > plen){
netlog(Logil, "il: lenerr\n");
il.lenerr++;
goto raise;
}
sp = nhgets(ih->ildst);
dp = nhgets(ih->ilsrc);
dst = nhgetl(ih->src);
if(ilcksum && (csum = ptclcsum(bp, IL_IPSIZE, illen)) != 0) {
if(ih->iltype < 0 || ih->iltype > Ilclose)
st = "?";
else
st = iltype[ih->iltype];
il.csumerr++;
netlog(Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %i/%d->%d)\n",
csum, st, nhgetl(ih->ilid), nhgetl(ih->ilack), dst, sp, dp);
goto raise;
}
for(p = il.conv; *p; p++) {
s = *p;
if(s->lport == sp && s->rport == dp && s->raddr == dst) {
ilprocess(s, ih, bp);
return;
}
}
if(ih->iltype != Ilsync){
if(ih->iltype < 0 || ih->iltype > Ilclose)
st = "?";
else
st = iltype[ih->iltype];
netlog(Logil, "il: no channel, pkt(%s id %lud ack %lud %i/%ud->%ud)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), dst, sp, dp);
goto raise;
}
gen = nil;
spec = nil;
for(p = il.conv; *p; p++) {
s = *p;
ic = (Ilcb*)s->ptcl;
if(ic->state != Illistening)
continue;
if(s->rport == 0 && s->raddr == 0) {
if(s->lport == sp) {
spec = s;
break;
}
if(s->lport == 0)
gen = s;
}
}
if(spec)
s = spec;
else
if(gen)
s = gen;
else
goto raise;
new = Fsnewcall(&fs, s, nhgetl(ih->src), dp, nhgetl(ih->dst), sp);
if(new == nil){
netlog(Logil, "il: bad newcall %i/%ud->%ud\n", dst, sp, dp);
ilsendctl(nil, ih, Ilclose, 0, nhgetl(ih->ilid));
goto raise;
}
ic = (Ilcb*)new->ptcl;
ic->conv = new;
ic->state = Ilsyncee;
initseq += msec;
ic->start = initseq & 0xffffff;
ic->next = ic->start+1;
ic->recvd = 0;
ic->rstart = nhgetl(ih->ilid);
ic->slowtime = Slowtime;
ic->rtt = Iltickms;
ic->querytime = Keepalivetime;
ic->deathtime = Deathtime;
ic->window = Defaultwin;
ilprocess(new, ih, bp);
return;
raise:
freeblist(bp);
return;
}
int sdataquery; /* temporary counters for measuring */
int squery;
void
_ilprocess(Conv *s, Ilhdr *h, Block *bp)
{
Ilcb *ic;
ulong id, ack;
id = nhgetl(h->ilid);
ack = nhgetl(h->ilack);
ic = (Ilcb*)s->ptcl;
ic->querytime = Keepalivetime;
ic->deathtime = Deathtime;
switch(ic->state) {
default:
netlog(Logil, "il: unknown state %d\n", ic->state);
case Ilclosed:
freeblist(bp);
break;
case Ilsyncer:
switch(h->iltype) {
default:
break;
case Ilsync:
if(ack != ic->start)
ilhangup(s, "connection rejected");
else {
ic->recvd = id;
ic->rstart = id;
ilsendctl(s, nil, Ilack, ic->next, ic->recvd);
ic->state = Ilestablished;
Fsconnected(&fs, s, nil);
ilpullup(s);
iltimers(ic);
}
break;
case Ilclose:
if(ack == ic->start)
ilhangup(s, "remote close");
break;
}
freeblist(bp);
break;
case Ilsyncee:
switch(h->iltype) {
default:
break;
case Ilsync:
if(id != ic->rstart || ack != 0)
ic->state = Ilclosed;
else {
ic->recvd = id;
ilsendctl(s, nil, Ilsync, ic->start, ic->recvd);
iltimers(ic);
}
break;
case Ilack:
if(ack == ic->start) {
ic->state = Ilestablished;
ilpullup(s);
iltimers(ic);
}
break;
case Ilclose:
if(ack == ic->start)
ilhangup(s, "remote close");
break;
}
freeblist(bp);
break;
case Ilestablished:
switch(h->iltype) {
case Ilsync:
if(id != ic->rstart)
ilhangup(s, "remote close");
else {
ilsendctl(s, nil, Ilack, ic->next, ic->rstart);
iltimers(ic);
}
freeblist(bp);
break;
case Ildata:
iltimers(ic);
ilackto(ic, ack);
ic->acktime = Acktime;
iloutoforder(s, h, bp);
ilpullup(s);
break;
case Ildataquery:
sdataquery++;
iltimers(ic);
ilackto(ic, ack);
ic->acktime = Acktime;
iloutoforder(s, h, bp);
ilpullup(s);
ilsendctl(s, nil, Ilstate, ic->next, ic->recvd);
break;
case Ilack:
ilackto(ic, ack);
iltimers(ic);
freeblist(bp);
break;
case Ilquerey:
squery++;
ilackto(ic, ack);
ilsendctl(s, nil, Ilstate, ic->next, ic->recvd);
iltimers(ic);
freeblist(bp);
break;
case Ilstate:
ilackto(ic, ack);
ilrexmit(ic);
iltimers(ic);
freeblist(bp);
break;
case Ilclose:
freeblist(bp);
if(ack < ic->start || ack > ic->next)
break;
ilsendctl(s, nil, Ilclose, ic->next, ic->recvd);
ic->state = Ilclosing;
ilfreeq(ic);
iltimers(ic);
break;
}
break;
case Illistening:
freeblist(bp);
break;
case Ilclosing:
switch(h->iltype) {
case Ilclose:
ic->recvd = id;
ilsendctl(s, nil, Ilclose, ic->next, ic->recvd);
if(ack == ic->next)
ilhangup(s, nil);
iltimers(ic);
break;
default:
break;
}
freeblist(bp);
break;
}
}
void
ilrexmit(Ilcb *ic)
{
Ilhdr *h;
Block *nb;
nb = nil;
qlock(&ic->ackq);
if(ic->unacked)
nb = copyblock(ic->unacked, blocklen(ic->unacked));
qunlock(&ic->ackq);
if(nb == nil)
return;
h = (Ilhdr*)nb->rp;
/* netlog(Logil, "il: rxmit %ux %d\n", nb, nhgetl(h->ilid)); */
h->iltype = Ildataquery;
hnputl(h->ilack, ic->recvd);
h->ilsum[0] = 0;
h->ilsum[1] = 0;
if(ilcksum)
hnputs(h->ilsum, ptclcsum(nb, IL_IPSIZE, nhgets(h->illen)));
il.rexmit++;
ipoput(nb, 0, ic->conv->ttl);
}
/* DEBUG */
void
ilprocess(Conv *s, Ilhdr *h, Block *bp)
{
Ilcb *ic;
ic = (Ilcb*)s->ptcl;
USED(ic);
DBG(s->raddr)(Logilmsg, "%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
ilstates[ic->state], ic->rstart, ic->recvd, ic->start,
ic->next, iltype[h->iltype], nhgetl(h->ilid),
nhgetl(h->ilack), nhgets(h->ilsrc), nhgets(h->ildst));
_ilprocess(s, h, bp);
DBG(s->raddr)(Logilmsg, "%11s rcv %d snt %d\n", ilstates[ic->state], ic->recvd, ic->next);
}
void
ilhangup(Conv *s, char *msg)
{
Ilcb *ic;
int callout;
netlog(Logil, "il: hangup! %i %d/%d\n", s->raddr, s->lport, s->rport);
ic = (Ilcb*)s->ptcl;
callout = ic->state == Ilsyncer;
ic->state = Ilclosed;
qhangup(s->rq, msg);
qhangup(s->wq, msg);
if(callout)
Fsconnected(&fs, s, msg);
}
void
ilpullup(Conv *s)
{
Ilcb *ic;
Ilhdr *oh;
Block *bp;
ulong oid, dlen;
ic = (Ilcb*)s->ptcl;
if(ic->state != Ilestablished)
return;
qlock(&ic->outo);
while(ic->outoforder) {
bp = ic->outoforder;
oh = (Ilhdr*)bp->rp;
oid = nhgetl(oh->ilid);
if(oid <= ic->recvd) {
ic->outoforder = bp->list;
freeblist(bp);
continue;
}
if(oid != ic->recvd+1)
break;
ic->recvd = oid;
ic->outoforder = bp->list;
bp->list = nil;
dlen = nhgets(oh->illen)-IL_HDRSIZE;
bp = trimblock(bp, IL_IPSIZE+IL_HDRSIZE, dlen);
/*
* Upper levels don't know about multiple-block
* messages so copy all into one (yick).
*/
bp = concatblock(bp);
if(bp == 0)
panic("ilpullup");
qpass(s->rq, bp);
}
qunlock(&ic->outo);
}
void
iloutoforder(Conv *s, Ilhdr *h, Block *bp)
{
Ilcb *ic;
byte *lid;
Block *f, **l;
ulong id, newid;
ic = (Ilcb*)s->ptcl;
bp->list = nil;
id = nhgetl(h->ilid);
/* Window checks */
if(id <= ic->recvd || id > ic->recvd+ic->window) {
netlog(Logil, "il: message outside window %ud <%ud-%ud>: %i %d/%d\n",
id, ic->recvd, ic->recvd+ic->window, s->raddr, s->lport, s->rport);
freeblist(bp);
return;
}
/* Packet is acceptable so sort onto receive queue for pullup */
qlock(&ic->outo);
if(ic->outoforder == nil)
ic->outoforder = bp;
else {
l = &ic->outoforder;
for(f = *l; f; f = f->list) {
lid = ((Ilhdr*)(f->rp))->ilid;
newid = nhgetl(lid);
if(id <= newid) {
if(id == newid) {
qunlock(&ic->outo);
freeblist(bp);
return;
}
bp->list = f;
*l = bp;
qunlock(&ic->outo);
return;
}
l = &f->list;
}
*l = bp;
}
qunlock(&ic->outo);
}
void
ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack)
{
Ilhdr *ih;
Ilcb *ic;
Block *bp;
int ttl;
bp = allocb(IL_IPSIZE+IL_HDRSIZE);
bp->wp += IL_IPSIZE+IL_HDRSIZE;
ih = (Ilhdr *)(bp->rp);
/* Ip fields */
ih->proto = IP_ILPROTO;
hnputs(ih->illen, IL_HDRSIZE);
ih->frag[0] = 0;
ih->frag[1] = 0;
if(inih) {
hnputl(ih->dst, nhgetl(inih->src));
hnputl(ih->src, nhgetl(inih->dst));
hnputs(ih->ilsrc, nhgets(inih->ildst));
hnputs(ih->ildst, nhgets(inih->ilsrc));
hnputl(ih->ilid, nhgetl(inih->ilack));
hnputl(ih->ilack, nhgetl(inih->ilid));
ttl = MAXTTL;
}
else {
hnputl(ih->dst, ipc->raddr);
hnputl(ih->src, ipc->laddr);
hnputs(ih->ilsrc, ipc->lport);
hnputs(ih->ildst, ipc->rport);
hnputl(ih->ilid, id);
hnputl(ih->ilack, ack);
ic = (Ilcb*)ipc->ptcl;
ic->acktime = Ackkeepalive;
ttl = ipc->ttl;
}
ih->iltype = type;
ih->ilspec = 0;
ih->ilsum[0] = 0;
ih->ilsum[1] = 0;
if(ilcksum)
hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
if(ipc){
DBG(ipc->raddr)(Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
nhgets(ih->ilsrc), nhgets(ih->ildst));
}
ipoput(bp, 0, ttl);
}
void
ilackproc()
{
Ilcb *ic;
Conv **s, *p;
static Rendez ilr;
loop:
tsleep(&ilr, return0, 0, Iltickms);
for(s = il.conv; s && *s; s++) {
p = *s;
ic = (Ilcb*)p->ptcl;
ic->timeout += Iltickms;
switch(ic->state) {
case Ilclosed:
case Illistening:
break;
case Ilclosing:
if(ic->timeout >= ic->fasttime) {
ilsendctl(p, nil, Ilclose, ic->next, ic->recvd);
ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime)
ilhangup(p, nil);
break;
case Ilsyncee:
case Ilsyncer:
if(ic->timeout >= ic->fasttime) {
ilsendctl(p, nil, Ilsync, ic->start, ic->recvd);
ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime)
ilhangup(p, etime);
break;
case Ilestablished:
ic->acktime -= Iltickms;
if(ic->acktime <= 0)
ilsendctl(p, nil, Ilack, ic->next, ic->recvd);
ic->querytime -= Iltickms;
if(ic->querytime <= 0){
ic->deathtime -= Querytime;
if(ic->deathtime < 0){
netlog(Logil, "il: hangup due to deathtime (%d) < 0 \n", ic->deathtime);
ilhangup(p, etime);
break;
}
ilsendctl(p, nil, Ilquerey, ic->next, ic->recvd);
ic->querytime = Querytime;
}
if(ic->unacked == nil) {
ic->timeout = 0;
break;
}
if(ic->timeout >= ic->fasttime) {
ilrexmit(ic);
ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
netlog(Logil, "il: hangup due to timeout (%d) >= slowtime (%d)\n", ic->timeout, ic->slowtime);
ilhangup(p, etime);
break;
}
break;
}
}
goto loop;
}
void
ilbackoff(Ilcb *ic)
{
if(ic->fasttime < Slowtime/2)
ic->fasttime += Fasttime;
else
ic->fasttime = (ic->fasttime)*3/2;
}
char*
ilstart(Conv *c, int type, int window)
{
char *e;
Ilcb *ic;
ic = (Ilcb*)c->ptcl;
ic->conv = c;
e = nil;
if(ic->state != Ilclosed)
return e;
ic->unacked = nil;
ic->outoforder = nil;
ic->slowtime = Slowtime;
ic->rtt = Iltickms;
iltimers(ic);
initseq += msec;
ic->start = initseq & 0xffffff;
ic->next = ic->start+1;
ic->recvd = 0;
ic->window = window;
switch(type) {
default:
netlog(Logil, "il: start: type %d\n", type);
break;
case IL_LISTEN:
ic->state = Illistening;
break;
case IL_CONNECT:
ic->state = Ilsyncer;
ilsendctl(c, nil, Ilsync, ic->start, ic->recvd);
break;
}
return e;
}
void
ilfreeq(Ilcb *ic)
{
Block *bp, *next;
qlock(&ic->ackq);
for(bp = ic->unacked; bp; bp = next) {
next = bp->list;
freeblist(bp);
}
ic->unacked = nil;
qunlock(&ic->ackq);
qlock(&ic->outo);
for(bp = ic->outoforder; bp; bp = next) {
next = bp->list;
freeblist(bp);
}
ic->outoforder = nil;
qunlock(&ic->outo);
}
void
iltimers(Ilcb *ic)
{
ic->timeout = 0;
ic->fasttime = (Fasttime*ic->rtt)/Iltickms;
ic->slowtime = (Slowtime*ic->rtt)/Iltickms;
}
void
iladvise(Block *bp, char *msg)
{
Ilhdr *h;
Ilcb *ic;
Ipaddr source, dest;
ushort psource;
Conv *s, **p;
h = (Ilhdr*)(bp->rp);
dest = nhgetl(h->dst);
source = nhgetl(h->src);
psource = nhgets(h->ilsrc);
/* Look for a connection, unfortunately the destination port is missing */
for(p = il.conv; *p; p++) {
s = *p;
if(s->laddr == source && s->lport == psource)
if(s->raddr == dest){
ic = (Ilcb*)s->ptcl;
switch(ic->state){
case Ilsyncer:
ilhangup(s, msg);
break;
}
break;
}
}
freeblist(bp);
}
.
## diffname ip/il.c 1997/0403
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/ip/il.c /n/emeliedump/1997/0403/sys/src/brazil/ip/il.c
187c
if(e != nil)
return e;
Fsconnected(&fs, c, nil);
return nil;
.
185a
e = Fsstdannounce(c, argv, argc);
if(e != nil);
return e;
.
181,182c
static char*
ilannounce(Conv *c, char **argv, int argc)
.
## diffname ip/il.c 1997/0404
## diff -e /n/emeliedump/1997/0403/sys/src/brazil/ip/il.c /n/emeliedump/1997/0404/sys/src/brazil/ip/il.c
187c
if(e != nil)
.
## diffname ip/il.c 1997/0423
## diff -e /n/emeliedump/1997/0404/sys/src/brazil/ip/il.c /n/emeliedump/1997/0423/sys/src/brazil/ip/il.c
391a
USED(m);
.
382c
iliput(Media *m, Block *bp)
.
143c
void iliput(Media*, Block*);
.
## diffname ip/il.c 1997/0521
## diff -e /n/emeliedump/1997/0423/sys/src/brazil/ip/il.c /n/emeliedump/1997/0521/sys/src/brazil/ip/il.c
161c
return ilstart(c, IL_CONNECT, 20);
.
158c
e = Fsstdconnect(c, argv, argc);
.
## diffname ip/il.c 1997/0730
## diff -e /n/emeliedump/1997/0521/sys/src/brazil/ip/il.c /n/emeliedump/1997/0730/sys/src/brazil/ip/il.c
1005,1006c
pt = ic->delay>>LogAGain;
pt += ic->unackedbytes/(ic->rate>>LogAGain);
ic->fasttime = (Fasttime*pt)/Iltickms;
ic->slowtime = (Slowtime*pt)/Iltickms;
.
1003a
int pt;
.
961a
ic->rexmit = 0;
.
953,954c
ic->unackedbytes = 0;
ilinitrtt(ic);
.
931,934c
ic->fasttime = (ic->fasttime)*3/2;
.
671a
ic->rexmit++;
.
483c
ilinitrtt(ic);
.
375a
ic->unackedbytes -= blocklen(bp);
.
356,359c
if(t > 120000){
/* seed connection parameters with time of first ack */
if(ic->lrttlen < 0){
ic->rate = (ic->rttlen/t)<<LogAGain;
ic->delay = t<<LogAGain;
ic->mdev = t<<LogDGain;
ic->lrttlen = ic->rttlen;
ic->lrtt = t;
}
pt = ic->rttlen/(ic->rate>>LogAGain) + (ic->delay>>LogAGain);
/* mdev */
ic->mdev += abs(t-pt) - (ic->mdev>>LogDGain);
/* fixed delay */
if(ic->rttlen != ic->lrttlen){
x = (ic->lrtt*ic->rttlen - t*ic->lrttlen)/(ic->rttlen-ic->lrttlen);
ic->delay += x - (ic->delay>>LogAGain);
}
/* rate */
if(ic->lrtt != t){
x = (ic->lrttlen - ic->rttlen)/(ic->lrtt - t);
ic->rate += x - (ic->rate>>LogAGain);
}
ic->lrtt = t;
ic->lrttlen = ic->rttlen;
}
if(ic->delay < (Iltickms<<LogAGain))
ic->delay = Iltickms<<LogAGain;
.
354c
t = msec - ic->rttms;
.
351c
ulong id;
int x, t, pt;
.
346a
ilinitrtt(Ilcb *ic)
{
ic->delay = Iltickms<<LogAGain;
ic->mdev = Iltickms<<LogDGain;
ic->rate = 10000<<LogAGain; /* 10 meg ether */
ic->lrttlen = -1;
}
void
.
343a
ic->unackedbytes += n;
.
334c
np = copyblock(bp, n);
.
332a
n = blocklen(bp);
.
331a
int n;
.
292c
ic->rttms = msec;
ic->rttlen = dlen + IL_IPSIZE + IL_HDRSIZE;
.
176c
sprint(ic->buf, "%s del %d Br %d md %d una %d rex %d", ilstates[ic->state],
ic->delay>>LogAGain, ic->rate>>LogAGain, ic->mdev>>LogDGain,
ic->unackedbytes, ic->rexmit);
*msg = ic->buf;
.
127c
LogAGain = 3,
LogDGain = 2,
.
76a
int rexmit;
char buf[128];
.
75c
int rttlen; /* Length of rttack packet */
ulong rttms; /* Time we issued rttack packet */
int lrtt; /* Last rtt seen */
int lrttlen; /* Length of the packet lrtt is for */
.
73c
int delay; /* Average of the fixed rtt delay */
int rate; /* Average byte rate */
int mdev; /* Mean deviation of rtt */
.
60a
ulong unackedbytes;
.
## diffname ip/il.c 1997/0801
## diff -e /n/emeliedump/1997/0730/sys/src/brazil/ip/il.c /n/emeliedump/1997/0801/sys/src/brazil/ip/il.c
1063,1064c
pt = (ic->delay>>LogAGain) + ic->unackedbytes/(ic->rate>>LogAGain) + ic->mdev;
.
393,417d
380,391c
if(ic->rttack == ackto)
ilrttcalc(ic);
.
378d
371a
static void
ilrttcalc(Ilcb *ic)
{
int dlen, dt, t, pt, x;
t = msec - ic->rttms;
/* Guard against the ulong zero wrap of MACHP(0)->ticks */
if(t > 120000)
return;
/* seed connection parameters with time of first ack */
if(ic->lrttlen == 0){
ic->lrttlen = ic->rttlen;
/* account pessimisticly for clock resolution */
if(t == 0)
t = TK2MS(1);
ic->lrtt = t;
x = (ic->rttlen/t)<<LogAGain;
if(x < AGain)
x = AGain;
ic->rate = x;
ic->delay = t<<LogAGain;
ic->mdev = t<<LogDGain;
goto out;
}
dlen = ic->rttlen - ic->lrttlen;
dt = t - ic->lrtt;
/* fixed delay */
if(dlen == 0)
x = t - ic->rttlen/(ic->rate>>LogAGain);
else
x = (ic->lrtt*ic->rttlen - t*ic->lrttlen)/dlen;
if(x > 0){
x += ic->delay - (ic->delay>>LogAGain);
if(x < AGain)
x = AGain;
ic->delay = x;
}
/* rate */
if(dt == 0){
if(dlen)
x = DefByteRate;
else
x = -1;
} else
x = dlen/dt;
if(x > 0){
x += ic->rate - (ic->rate>>LogAGain);
if(x < AGain)
x = AGain;
ic->rate = x;
}
/* mdev */
pt = ic->rttlen/(ic->rate>>LogAGain) + (ic->delay>>LogAGain);
ic->mdev += abs(t-pt) - (ic->mdev>>LogDGain);
out:
ic->lrtt = t;
ic->lrttlen = ic->rttlen;
}
.
368,369c
ic->rate = DefByteRate<<LogAGain; /* 10 meg ether */
ic->lrtt = 0;
ic->lrttlen = 0;
.
136a
DGain = 1<<LogDGain,
DefByteRate = 1000,
.
135a
AGain = 1<<LogAGain,
.
## diffname ip/il.c 1997/0802
## diff -e /n/emeliedump/1997/0801/sys/src/brazil/ip/il.c /n/emeliedump/1997/0802/sys/src/brazil/ip/il.c
1099,1100c
ic->fasttime = (Fasttime/Seconds)*pt;
if(ic->fasttime > Fasttime)
ic->fasttime = Fasttime;
ic->slowtime = (Slowtime/Seconds)*pt;
if(ic->slowtime > Slowtime)
ic->slowtime = Slowtime;
.
1024c
ic->fasttime += ic->fasttime<<1;
.
764a
ic->rttack = 0; /* stop counting rtt */
.
453c
/* Cancel if we've passed the packet we were interested in */
.
438,440c
if(rtt > ic->maxrtt)
ic->maxrtt = rtt;
.
435,436c
pt = ic->rttlen/(rate>>LogAGain) + (delay>>LogAGain);
ic->mdev += abs(rtt-pt) - (ic->mdev>>LogDGain);
.
420,431c
tt = rtt - (delay>>LogAGain);
if(tt > 0){
rate += ic->rttlen/tt - (rate>>LogAGain);
if(rate < AGain)
rate = AGain;
ic->rate = rate;
.
404,418d
387,401c
/* guess fixed delay as rtt of small packets */
if(ic->rttlen < 128){
delay += rtt - (delay>>LogAGain);
if(delay < AGain)
delay = AGain;
ic->delay = delay;
.
384c
if(rtt > 120000)
.
381c
/* add in clock resolution hack */
rtt = (msec + TK2MS(1) - 1) - ic->rttms;
delay = ic->delay;
rate = ic->rate;
.
379c
int rtt, tt, pt, delay, rate;
.
372,373d
190c
ic->unackedbytes, ic->rexmit, ic->maxrtt);
.
188c
sprint(ic->buf, "%s del %d Br %d md %d una %d rex %d max %d", ilstates[ic->state],
.
139c
DefByteRate = 1000, /* 10 meg ether */
.
128,129c
Slowtime = 90*Seconds, /* max time waiting for an ack before hangup */
Fasttime = 4*Seconds, /* max time between rexmit */
.
80,81d
76a
int maxrtt; /* largest rtt seen */
.
## diffname ip/il.c 1997/0803
## diff -e /n/emeliedump/1997/0802/sys/src/brazil/ip/il.c /n/emeliedump/1997/0803/sys/src/brazil/ip/il.c
734c
/*
* Double delay estimate and half bandwidth estimate. This is
* in keeping with van jacobson's tcp alg.
*/
ic->rttack = 0;
if((ic->delay>>LogAGain) < 2*Seconds)
ic->delay *= 2;
x = ic->rate>>1;
if(x >= (1<<LogAGain))
ic->rate = x;
.
731a
c = ic->conv;
id = nhgetl(h->ilid);
netlog(Logil, "il: rexmit %ud %ud: %d %d: %i %d/%d\n", id, ic->recvd,
ic->fasttime, ic->timeout,
c->raddr, c->lport, c->rport);
.
723d
711a
Conv *c;
int x;
ulong id;
.
664d
650d
557,559d
## diffname ip/il.c 1997/0804
## diff -e /n/emeliedump/1997/0803/sys/src/brazil/ip/il.c /n/emeliedump/1997/0804/sys/src/brazil/ip/il.c
1121a
}
int
ilnextqt(Ilcb *ic)
{
int x;
qlock(&ic->ackq);
x = ic->qtx;
ic->qt[x] = ic->next-1; /* highest xmitted packet */
ic->qt[0] = ic->qt[x]; /* compatibility with old implementations */
if(++x > Nqt)
x = 1;
ic->qtx = x;
qunlock(&ic->ackq);
return x;
.
1083c
ic->fasttime = Acktime + pt + Iltickms - 1;
.
1047c
ilsendctl(c, nil, Ilsync, ic->start, ic->recvd, 0);
.
1036a
ic->qtx = 1;
.
983c
ilsendctl(p, nil, Ilquery, ic->next, ic->recvd, ilnextqt(ic));
.
973c
ilsendctl(p, nil, Ilack, ic->next, ic->recvd, 0);
.
964c
ilsendctl(p, nil, Ilsync, ic->start, ic->recvd, 0);
.
955c
ilsendctl(p, nil, Ilclose, ic->next, ic->recvd, 0);
.
919c
ih->ilspec = ilspec;
.
881c
ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
.
723a
h->ilspec = ilnextqt(ic);
.
709a
int x;
.
708d
689c
ilsendctl(s, nil, Ilclose, ic->next, ic->recvd, 0);
.
675c
ilsendctl(s, nil, Ilclose, ic->next, ic->recvd, 0);
.
667c
if(h->ilspec > Nqt)
h->ilspec = 0;
if(ic->qt[h->ilspec] > ack)
ilrexmit(ic);
.
661c
ilsendctl(s, nil, Ilstate, ic->next, ic->recvd, h->ilspec);
.
659c
case Ilquery:
.
652c
ilsendctl(s, nil, Ilstate, ic->next, ic->recvd, h->ilspec);
.
634c
ilsendctl(s, nil, Ilack, ic->next, ic->rstart, 0);
.
610c
ilsendctl(s, nil, Ilsync, ic->start, ic->recvd, 0);
.
587c
ilsendctl(s, nil, Ilack, ic->next, ic->recvd, 0);
.
531c
ilsendctl(nil, ih, Ilclose, 0, nhgetl(ih->ilid), 0);
.
231c
ilsendctl(c, nil, Ilclose, ic->next, ic->recvd, 0);
.
155a
int ilnextqt(Ilcb*);
.
142c
void ilsendctl(Conv*, Ilhdr*, int, ulong, ulong, int);
.
140a
/* state for query/dataquery messages */
.
82c
int rexmit; /* number of retransmits */
ulong qt[Nqt+1]; /* state table for query messages */
int qtx; /* ... index into qt */
.
52a
enum
{
Nqt= 8,
};
.
38c
Ilquery,
.
26c
"query",
.
24c
"dataquery",
.
## diffname ip/il.c 1997/0805
## diff -e /n/emeliedump/1997/0804/sys/src/brazil/ip/il.c /n/emeliedump/1997/0805/sys/src/brazil/ip/il.c
1043c
ic->delay = Iltickms<<LogAGain;
ic->mdev = Iltickms<<LogDGain;
ic->rate = DefByteRate<<LogAGain;
.
555c
ic->delay = Iltickms<<LogAGain;
ic->mdev = Iltickms<<LogDGain;
ic->rate = DefByteRate<<LogAGain;
.
377,384d
375a
static
.
140a
.
139d
## diffname ip/il.c 1997/0806
## diff -e /n/emeliedump/1997/0805/sys/src/brazil/ip/il.c /n/emeliedump/1997/0806/sys/src/brazil/ip/il.c
1018c
ic->fasttime += ic->fasttime>>1;
.
131c
Ackkeepalive = 600*Seconds,
.
## diffname ip/il.c 1997/0902
## diff -e /n/emeliedump/1997/0806/sys/src/brazil/ip/il.c /n/emeliedump/1997/0902/sys/src/brazil/ip/il.c
787c
netlog(Logil, "il: hangup! %i %d/%d: %s\n", s->raddr, s->lport, s->rport, msg?msg:"no reason");
.
249a
ilfreeq(ic);
.
240d
## diffname ip/il.c 1997/0916
## diff -e /n/emeliedump/1997/0902/sys/src/brazil/ip/il.c /n/emeliedump/1997/0916/sys/src/brazil/ip/il.c
873a
ilstats.dup++;
ilstats.dupb += blocklen(bp);
.
823a
}
.
822c
if(oid != ic->recvd+1){
il.order++;
.
344a
il.stats = ilxstats;
.
331a
int
ilxstats(char *buf, int len)
{
return snprint(buf, len, "\tdupp %d dupb %d\n", ilstats.dup, ilstats.dupb);
}
.
124a
static struct Ilstats
{
ulong dup;
ulong dupb;
} ilstats;
.
## diffname ip/il.c 1997/0917
## diff -e /n/emeliedump/1997/0916/sys/src/brazil/ip/il.c /n/emeliedump/1997/0917/sys/src/brazil/ip/il.c
1117c
if(ic->slowtime < Slowtime)
.
## diffname ip/il.c 1997/1003
## diff -e /n/emeliedump/1997/0917/sys/src/brazil/ip/il.c /n/emeliedump/1997/1003/sys/src/brazil/ip/il.c
1112,1113c
pt = (ic->delay>>LogAGain) + ic->unackedbytes/(ic->rate>>LogAGain) + (ic->mdev>>(LogDGain-1));
ic->fasttime = pt + Iltickms - 1;
.
1018c
ilsendctl(p, nil, Ilquery, ic->next, ic->recvd, ilnextqt(ic));
ic->querytime = Querytime;
ic->timeout = 0;
.
## diffname ip/il.c 1998/0306
## diff -e /n/emeliedump/1997/1003/sys/src/brazil/ip/il.c /n/emeliedump/1998/0306/sys/src/brazil/ip/il.c
1142,1143c
if(s->lport == psource)
if(ipcmp(s->laddr, source) == 0)
if(ipcmp(s->raddr, dest) == 0){
.
1134,1135c
v4tov6(dest, h->dst);
v4tov6(source, h->src);
.
1128c
uchar source[IPaddrlen], dest[IPaddrlen];
.
1114,1115c
pt = (ic->delay>>LogAGain) + ic->unackeduchars/(ic->rate>>LogAGain) + ic->mdev;
ic->fasttime = Acktime + pt + Iltickms - 1;
.
1056c
ic->unackeduchars = 0;
.
1018,1020c
ilrexmit(ic);
.
935,936c
v6tov4(ih->dst, ipc->raddr);
v6tov4(ih->src, ipc->laddr);
.
862c
uchar *lid;
.
800c
netlog(Logil, "il: hangup! %I %d/%d: %s\n", s->raddr, s->lport, s->rport, msg?msg:"no reason");
.
547c
netlog(Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
.
545c
v4tov6(laddr, ih->dst);
new = Fsnewcall(&fs, s, raddr, dp, laddr, sp);
.
527c
if(s->rport == 0 && ipcmp(s->raddr, IPnoaddr) == 0) {
.
514,515c
netlog(Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
.
503c
if(s->lport == sp)
if(s->rport == dp)
if(ipcmp(s->raddr, raddr) == 0) {
.
496,497c
netlog(Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %I/%d->%d)\n",
csum, st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
.
488c
v4tov6(raddr, ih->src);
.
470d
465c
uchar raddr[IPaddrlen];
uchar laddr[IPaddrlen];
.
460c
iliput(uchar*, Block *bp)
.
453c
ic->unackeduchars -= blocklen(bp);
.
386c
ic->unackeduchars += n;
.
357a
il.inuse = ilinuse;
.
341c
int n;
n = snprint(buf, len,
"il: csum %d hlen %d len %d order %d rexmit %d",
il.csumerr, il.hlenerr, il.lenerr, il.order, il.rexmit);
n += snprint(buf+n, len-n, " dupp %d dupb %d\n",
ilstats.dup, ilstats.dupb);
.
294,295c
v6tov4(ih->dst, c->raddr);
v6tov4(ih->src, c->laddr);
.
251c
ipmove(c->laddr, IPnoaddr);
.
204,208c
ic = (Ilcb*)(c->ptcl);
return ic->state != Ilclosed;
.
200,202c
static int
ilinuse(Conv *c)
{
Ilcb *ic;
.
198a
return snprint(state, n, "%14.14s del %5.5d Br %5.5d md %5.5d una %5.5d rex %5.5d max %5.5d",
ilstates[ic->state],
ic->delay>>LogAGain, ic->rate>>LogAGain, ic->mdev>>LogDGain,
ic->unackeduchars, ic->rexmit, ic->maxrtt);
}
.
196d
192,193c
static int
ilstate(Conv *c, char *state, int n)
.
170c
void iliput(uchar*, Block*);
.
105,122c
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 ttl; /* Time to live */
uchar proto; /* Protocol */
uchar cksum[2]; /* Header checksum */
uchar src[4]; /* Ip source */
uchar dst[4]; /* Ip destination */
uchar ilsum[2]; /* Checksum including header */
uchar illen[2]; /* Packet length */
uchar iltype; /* Packet type */
uchar ilspec; /* Special */
uchar ilsrc[2]; /* Src port */
uchar ildst[2]; /* Dst port */
uchar ilid[4]; /* Sequence id */
uchar ilack[4]; /* Acked sequence */
.
90d
80c
int rate; /* Average uchar rate */
.
66c
ulong unackeduchars;
.
## diffname ip/il.c 1998/0307
## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/il.c /n/emeliedump/1998/0307/sys/src/brazil/ip/il.c
349a
return n;
.
## diffname ip/il.c 1998/0313
## diff -e /n/emeliedump/1998/0307/sys/src/brazil/ip/il.c /n/emeliedump/1998/0313/sys/src/brazil/ip/il.c
1151c
for(p = il->conv; *p; p++) {
.
1135c
iladvise(Proto *il, Block *bp, char *msg)
.
1083c
netlog(c->p->f, Logil, "il: start: type %d\n", type);
.
1035c
netlog(il->f, Logil, "il: hangup due to timeout (%d) >= slowtime (%d)\n", ic->timeout, ic->slowtime);
.
1019c
netlog(il->f, Logil, "il: hangup due to deathtime (%d) < 0 \n", ic->deathtime);
.
983,984c
tsleep(&ipriv->ilr, return0, 0, Iltickms);
for(s = il->conv; s && *s; s++) {
.
981a
il = x;
ipriv = il->priv;
.
980c
Proto *il;
Ilpriv *ipriv;
.
976c
ilackproc(void *x)
.
972c
ipoput(ipc->p->f, bp, 0, ttl);
.
967c
netlog(ipc->p->f, Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
.
902,903c
ipriv->dup++;
ipriv->dupb += blocklen(bp);
.
885c
netlog(s->p->f, Logil, "il: message outside window %ud <%ud-%ud>: %i %d/%d\n",
.
878a
ipriv = s->p->priv;
.
877a
Ilpriv *ipriv;
.
849c
ipriv = s->p->priv;
ipriv->order++;
.
832a
Ilpriv *ipriv;
.
823c
Fsconnected(s, msg);
.
813c
netlog(s->p->f, Logil, "il: hangup! %I %d/%d: %s\n", s->raddr, s->lport, s->rport, msg?msg:"no reason");
.
804c
netlog(s->p->f, Logilmsg, "%11s rcv %d snt %d\n", ilstates[ic->state], ic->recvd, ic->next);
.
797c
netlog(s->p->f, Logilmsg, "%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
.
785c
ipoput(c->p->f, nb, 0, ic->conv->ttl);
.
771c
ipriv->rexmit++;
.
767c
netlog(c->p->f, Logil, "il: rexmit %ud %ud: %d %d: %i %d/%d\n", id, ic->recvd,
.
765a
ipriv = c->p->priv;
.
762,763c
hnputs(h->ilsum, ptclcsum(nb, IL_IPSIZE, nhgets(h->illen)));
.
744a
Ilpriv *ipriv;
.
621c
Fsconnected(s, nil);
.
605c
netlog(s->p->f, Logil, "il: unknown state %d\n", ic->state);
.
560c
netlog(il->f, Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
.
558c
new = Fsnewcall(s, raddr, dp, laddr, sp);
.
533c
for(p = il->conv; *p; p++) {
.
526c
netlog(il->f, Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
.
511c
for(p = il->conv; *p; p++) {
.
505,506c
ipriv->csumerr++;
netlog(il->f, Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %I/%d->%d)\n",
.
500c
if((csum = ptclcsum(bp, IL_IPSIZE, illen)) != 0) {
.
491,492c
netlog(il->f, Logil, "il: lenerr\n");
ipriv->lenerr++;
.
484,485c
netlog(il->f, Logil, "il: hlenerr\n");
ipriv->hlenerr++;
.
480a
ipriv = il->priv;
.
479a
Ilpriv *ipriv;
.
470c
iliput(Proto *il, uchar*, Block *bp)
.
374c
kproc("ilack", ilackproc, il);
.
372c
il = smalloc(sizeof(Proto));
il->priv = smalloc(sizeof(Ilpriv));
il->name = "il";
il->kick = ilkick;
il->connect = ilconnect;
il->announce = ilannounce;
il->state = ilstate;
il->create = ilcreate;
il->close = ilclose;
il->rcv = iliput;
il->ctl = nil;
il->advise = iladvise;
il->stats = ilxstats;
il->inuse = ilinuse;
il->ipproto = IP_ILPROTO;
il->nc = Nchans;
il->ptclsize = sizeof(Ilcb);
Fsproto(f, il);
.
356,370c
Proto *il;
.
354c
ilinit(Fs *f)
.
349c
ipriv->dup, ipriv->dupb);
.
347c
ipriv->csumerr, ipriv->hlenerr, ipriv->lenerr, ipriv->order, ipriv->rexmit);
.
344a
ipriv = il->priv;
.
343a
Ilpriv *ipriv;
.
341c
ilxstats(Proto *il, char *buf, int len)
.
330c
ipoput(f, bp, 0, c->ttl);
.
271a
f = c->p->f;
.
268a
Fs *f;
.
225c
Fsconnected(c, nil);
.
178d
173,175d
169,170c
void iliput(Proto*, uchar*, Block*);
void iladvise(Proto*, Block*, char*);
.
167c
void ilackproc(void*);
.
129a
/* non-MIB stats */
ulong csumerr; /* checksum errors */
ulong hlenerr; /* header length error */
ulong lenerr; /* short packet */
ulong order; /* out of order */
ulong rexmit; /* retransmissions */
ulong dup;
ulong dupb;
Rendez ilr;
};
.
126,128d
124c
typedef struct Ilpriv Ilpriv;
struct Ilpriv
.
## diffname ip/il.c 1998/0407
## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/il.c /n/emeliedump/1998/0407/sys/src/brazil/ip/il.c
204c
return snprint(state, n, "%s del %5.5d Br %5.5d md %5.5d una %5.5d rex %5.5d max %5.5d",
.
## diffname ip/il.c 1998/0630
## diff -e /n/emeliedump/1998/0407/sys/src/brazil/ip/il.c /n/emeliedump/1998/0630/sys/src/brazil/ip/il.c
204c
return snprint(state, n, "%14.14s del %5.5d Br %5.5d md %5.5d una %5.5d rex %5.5d max %5.5d",
.
## diffname ip/il.c 1998/0724
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/il.c /n/emeliedump/1998/0724/sys/src/brazil/ip/il.c
204c
return snprint(state, n, "%s del %5.5d Br %5.5d md %5.5d una %5.5d rex %5.5d max %5.5d",
.
## diffname ip/il.c 1998/0825
## diff -e /n/emeliedump/1998/0724/sys/src/brazil/ip/il.c /n/emeliedump/1998/0825/sys/src/brazil/ip/il.c
360c
n += snprint(buf+n, len-n, " dupp %lud dupb %lud\n",
.
358c
"il: csum %lud hlen %lud len %lud order %lud rexmit %lud",
.
204c
return snprint(state, n, "%s del %5.5d Br %5.5d md %5.5d una %5.5lud rex %5.5d max %5.5d",
.
## diffname ip/il.c 1998/0918
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/ip/il.c /n/emeliedump/1998/0918/sys/src/brazil/ip/il.c
887c
qpassnolim(s->rq, packblock(bp));
.
## diffname ip/il.c 1998/0923
## diff -e /n/emeliedump/1998/0918/sys/src/brazil/ip/il.c /n/emeliedump/1998/0923/sys/src/brazil/ip/il.c
887c
bp = packblock(bp);
if(bp == 0)
panic("ilpullup2");
qpassnolim(s->rq, bp);
.
## diffname ip/il.c 1998/0924
## diff -e /n/emeliedump/1998/0923/sys/src/brazil/ip/il.c /n/emeliedump/1998/0924/sys/src/brazil/ip/il.c
1085a
Ilpriv *ipriv;
char kpname[NAMELEN];
ipriv = c->p->priv;
if(ipriv->ackprocstarted == 0){
qlock(&ipriv->apl);
if(ipriv->ackprocstarted == 0){
sprint(kpname, "#I%dilack", c->p->f->dev);
kproc(kpname, ilackproc, c->p);
ipriv->ackprocstarted = 1;
}
qunlock(&ipriv->apl);
}
.
388,389d
138a
/* keeping track of the ack kproc */
int ackprocstarted;
QLock apl;
.
## diffname ip/il.c 1998/0925
## diff -e /n/emeliedump/1998/0924/sys/src/brazil/ip/il.c /n/emeliedump/1998/0925/sys/src/brazil/ip/il.c
1080a
if(ic->fasttime > Fasttime)
ic->fasttime = Fasttime;
.
599a
ic->unackeduchars = 0;
.
## diffname ip/il.c 1998/0929
## diff -e /n/emeliedump/1998/0925/sys/src/brazil/ip/il.c /n/emeliedump/1998/0929/sys/src/brazil/ip/il.c
1231a
}
/* quick and dirty conversion from fastticks to microseconds */
static void
initfast(void)
{
int i;
uvlong x, hz;
fastticks(&hz);
x = 3;
for(i = 1; i < 40; i++){
if(x >= hz)
break;
x <<= 1;
}
microshift = i - 20;
}
void
ilinit(Fs *f)
{
Proto *il;
initfast();
il = smalloc(sizeof(Proto));
il->priv = smalloc(sizeof(Ilpriv));
il->name = "il";
il->kick = ilkick;
il->connect = ilconnect;
il->announce = ilannounce;
il->state = ilstate;
il->create = ilcreate;
il->close = ilclose;
il->rcv = iliput;
il->ctl = nil;
il->advise = iladvise;
il->stats = ilxstats;
il->inuse = ilinuse;
il->ipproto = IP_ILPROTO;
il->nc = Nchans;
il->ptclsize = sizeof(Ilcb);
Fsproto(f, il);
.
1169,1183d
1143c
return nil;
.
1122,1129d
1114,1120c
ilcbinit(ic);
.
1112c
return nil;
.
1109,1110d
1089d
1087c
ilstart(Conv *c, int type)
.
1081,1083c
ic->start = nrand(0x1000000);
ic->next = ic->start+1;
ic->recvd = 0;
ic->window = Defaultwin;
ic->unackeduchars = 0;
ic->unacked = nil;
ic->outoforder = nil;
ic->rexmit = 0;
ic->rxtot = 0;
ic->qtx = 1;
/* timers */
ic->delay = DefRtt<<LogAGain;
ic->mdev = DefRtt<<LogDGain;
ic->rate = DefByteRate<<LogAGain;
ic->querytime = msec + QueryTime;
ic->lastrecv = msec; /* or we'll timeout right away */
ilsettimeout(ic);
.
1079c
ilcbinit(Ilcb *ic)
.
1067,1071d
1065d
1059,1063c
if(ic->unacked != nil && ic->timeout <= msec) {
if(ic->rexmit > MaxRexmit){
netlog(il->f, Logil, "il: hangup: too many rexmits\n");
ilhangup(p, etime);
break;
}
.
1057c
ic->querytime = msec + QueryTime;
.
1048,1052c
if(ic->querytime <= msec){
if(msec - ic->lastrecv > DeathTime){
netlog(il->f, Logil, "il: hangup: deathtime\n");
.
1044,1045c
if(ic->recvd != ic->acksent && ic->acktime <= msec)
.
1040,1041d
1036c
if(ic->timeout <= msec) {
if(ic->rexmit > MaxRexmit){
ilhangup(p, etime);
break;
}
.
1031,1032d
1027c
if(ic->timeout <= msec) {
if(ic->rexmit > MaxRexmit){
ilhangup(p, nil);
break;
}
.
1021d
1004a
ilsettimeout(Ilcb *ic)
{
ulong pt;
pt = (ic->delay>>LogAGain) + ic->unackeduchars/(ic->rate>>LogAGain) + ic->mdev;
pt += AckDelay;
if(pt > MaxTimeout)
pt = MaxTimeout;
ic->timeout = msec + pt;
}
void
ilbackoff(Ilcb *ic)
{
ulong pt;
int i;
Ilpriv *priv;
pt = (ic->delay>>LogAGain) + ic->unackeduchars/(ic->rate>>LogAGain) + ic->mdev;
pt += AckDelay;
for(i = 0; i < ic->rexmit; i++)
pt = pt + (pt>>1);
if(pt > MaxTimeout)
pt = MaxTimeout;
ic->timeout = msec + pt;
ic->rxtot++;
ic->rexmit++;
priv = ic->conv->p->priv;
priv->rexmit++;
}
void
.
984c
ic->acksent = ack;
ic->acktime = msec;
.
835c
netlog(s->p->f, Logil, "il: hangup! %I %d/%d: %s\n", s->raddr,
s->lport, s->rport, msg?msg:"no reason");
.
806a
ilbackoff(ic);
.
801,805d
793,799c
/* rtt calcs are useless during retransmissions */
.
789,790c
netlog(c->p->f, Logil, "il: rexmit %d %ud: %d %d: %i %d/%d\n", id, ic->recvd,
ic->rexmit, ic->timeout,
.
787d
765,766d
748d
734d
724c
ilsettimeout(ic);
}
.
722c
if(ic->qt[h->ilspec] > ack){
.
719c
ilackto(ic, ack, bp);
.
715d
713c
ilackto(ic, ack, bp);
.
708,709c
ilackto(ic, ack, bp);
.
700,702c
ilackto(ic, ack, bp);
.
693,695c
ilackto(ic, ack, bp);
.
688,689d
686c
else
.
671d
664d
644d
621,622c
ic->lastrecv = msec;
.
593,600d
588,591c
ilcbinit(ic);
.
481a
ic->rexmit = 0;
ilsettimeout(ic);
.
464c
ilrttcalc(ic, bp);
.
460d
457c
ilackto(Ilcb *ic, ulong ackto, Block *bp)
.
452,453c
if(mrtt > ic->maxrtt)
ic->maxrtt = mrtt;
.
450c
ic->mdev += abs(mrtt-pt) - (ic->mdev>>LogDGain);
.
439,440c
/* this block had to be transmitted after the one acked so count its size */
ic->rttlen += blocklen(bp) + IL_IPSIZE + IL_HDRSIZE;
/* if packet took longer than round trip delay, reset rate */
tt = mrtt - (delay>>LogAGain);
.
433c
delay += mrtt - (delay>>LogAGain);
.
427,428c
/* Guard against zero wrap */
if(rtt > 120000000)
.
422,423c
fastrtt = fastticks(nil) - ic->rttstart;
if(microshift >= 0)
rtt = fastrtt >> microshift;
else
rtt = fastrtt << -microshift;
mrtt = rtt >> 10;
.
420c
uvlong fastrtt;
int rtt, tt, pt, delay, rate, mrtt;
.
418c
ilrttcalc(Ilcb *ic, Block *bp)
.
410d
406,408c
else
.
370,394d
342a
if(ic->timeout <= msec)
ilsettimeout(ic);
.
341d
338c
ic->rttstart = fastticks(nil);
.
321,322c
ack = ic->recvd;
hnputl(ih->ilack, ack);
ic->acksent = ack;
ic->acktime = msec + AckDelay;
.
278c
ulong id, ack;
.
233c
e = ilstart(c, IL_LISTEN);
.
211c
ic->unackeduchars, ic->rxtot, ic->maxrtt);
.
199c
return ilstart(c, IL_CONNECT);
.
190a
.
189a
static int microshift;
.
186a
void ilcbinit(Ilcb*);
.
180,181c
void ilsettimeout(Ilcb*);
char* ilstart(Conv*, int);
.
165a
DefRtt = 50, /* cross country on a great day */
.
151,158c
MaxRexmit = 10, /* max retransmissions before hangup */
.
149c
Iltickms = 50, /* time base */
AckDelay = 2*Iltickms, /* max time twixt message rcvd & ack sent */
MaxTimeout = 4*Seconds, /* max time between rexmit */
QueryTime = 5*Seconds, /* time between subsequent queries */
DeathTime = 5*QueryTime,
.
145d
85,89c
uvlong rttstart; /* Time we issued rttack packet */
.
73,78c
int window; /* Maximum receive window */
int rxtot; /* number of retransmits on this connection */
int rexmit; /* number of retransmits of *unacked */
ulong qt[Nqt+1]; /* state table for query messages */
int qtx; /* ... index into qt */
/* timers */
ulong lastxmit; /* time of last xmit */
ulong lastrecv; /* time of last recv */
ulong timeout; /* retransmission time for *unacked */
ulong acktime; /* time to send next ack */
ulong querytime; /* time to send next query */
/* adaptive measurements */
.
70a
ulong acksent; /* Last packet acked */
.
52a
static char *etime = "connection timed out";
.
43,50c
char *iltype[] =
{
"sync",
"data",
"dataquery",
"ack",
"query",
"state",
"close"
.
20,31d
9a
enum /* Connection state */
{
Ilclosed,
Ilsyncer,
Ilsyncee,
Ilestablished,
Illistening,
Ilclosing,
};
.
## diffname ip/il.c 1998/0930
## diff -e /n/emeliedump/1998/0929/sys/src/brazil/ip/il.c /n/emeliedump/1998/0930/sys/src/brazil/ip/il.c
1225c
inittimeshift();
.
1217c
timeshift = i - 10;
if(i < 0)
timeround = (1<<-i)-1;
else
timeround = 0;
.
1212c
for(i = 1; i < 45; i++){
.
1205c
inittimeshift(void)
.
1203c
/* calculate shift that converts fast ticks to ms (more or less) */
.
1071c
ic->unackedbytes = 0;
.
1056c
ilsendctl(p, nil, Ilquery, ic->next, ic->recvd, ilnextqt(ic));
ic->rxquery++;
ilbackoff(ic);
.
989,991d
987d
979,980c
pt = (ic->delay>>LogAGain)
+ ic->unackedbytes/(ic->rate>>LogAGain)
+ (ic->mdev>>(LogDGain-1))
+ AckDelay;
.
977d
965,966c
pt = (ic->delay>>LogAGain)
+ ic->unackedbytes/(ic->rate>>LogAGain)
+ (ic->mdev>>(LogDGain-1))
+ AckDelay;
.
761a
/* statistics */
ic->rxtot++;
priv = c->p->priv;
priv->rexmit++;
.
756,758d
730a
Ilpriv *priv;
.
685a
if(ack >= ic->rttack)
ic->rttack = 0;
.
468c
ic->unackedbytes -= blocklen(bp);
.
441,442c
if(rtt > ic->maxrtt)
ic->maxrtt = rtt;
.
439c
ic->mdev += abs(rtt-pt) - (ic->mdev>>LogDGain);
.
425,436d
422a
} else {
/* if packet took longer than avg rtt delay, recalc rate */
tt = rtt - (delay>>LogAGain);
if(tt > 0){
rate += ic->rttlen/tt - (rate>>LogAGain);
if(rate < AGain)
rate = AGain;
ic->rate = rate;
}
.
417,419c
/* this block had to be transmitted after the one acked so count its size */
ic->rttlen += blocklen(bp) + IL_IPSIZE + IL_HDRSIZE;
if(ic->rttlen < 256){
/* guess fixed delay as rtt of small packets */
delay += rtt - (delay>>LogAGain);
.
414c
if(rtt > 120000)
.
405,409c
if(timeshift >= 0)
rtt = fastrtt >> timeshift;
else {
rtt = fastrtt;
rtt = (rtt<<-timeshift)+timeround;
}
.
402c
int rtt, tt, pt, delay, rate;
.
394c
ic->unackedbytes += n;
.
217c
ic->unackedbytes, ic->rxtot, ic->rxquery, ic->maxrtt);
.
214c
return snprint(state, n, "%s del %5.5d Br %5.5d md %5.5d una %5.5lud rex %5.5d rxq %5.5d max %5.5d",
.
196d
194c
static int timeshift, timeround;
static char *etime = "connection timed out";
.
151,170d
75a
int rxquery; /* number of queries on this connection */
.
67c
ulong unackedbytes;
.
53a
MaxRexmit = 16, /* max retransmissions before hangup */
Defaultwin = 20,
LogAGain = 3,
AGain = 1<<LogAGain,
LogDGain = 2,
DGain = 1<<LogDGain,
DefByteRate = 100, /* assume a megabit link */
DefRtt = 50, /* cross country on a great day */
};
.
52c
enum
{
Seconds = 1000,
Iltickms = 50, /* time base */
AckDelay = 2*Iltickms, /* max time twixt message rcvd & ack sent */
MaxTimeout = 4*Seconds, /* max time between rexmit */
QueryTime = 5*Seconds, /* time between subsequent queries */
DeathTime = 5*QueryTime,
.
27c
"Closing",
"Opening", /* only for file server */
.
17a
Ilopening, /* only for file server */
.
## diffname ip/il.c 1998/1001
## diff -e /n/emeliedump/1998/0930/sys/src/brazil/ip/il.c /n/emeliedump/1998/1001/sys/src/brazil/ip/il.c
1084a
ic->rxquery = 0;
.
990c
+ (ic->mdev>>(LogDGain-2))
.
975c
+ (ic->mdev>>(LogDGain-2))
.
## diffname ip/il.c 1998/1013
## diff -e /n/emeliedump/1998/1001/sys/src/brazil/ip/il.c /n/emeliedump/1998/1013/sys/src/brazil/ip/il.c
1207a
ic->qt[x] = ic->next-1; /* highest xmitted packet */
ic->qt[0] = ic->qt[x]; /* compatibility with old implementations */
.
1203,1204d
745a
}
.
744c
if(nb == nil){
print("ilrexmit: copyblock returns nil\n");
.
603a
ic->querytime = msec + QueryTime;
.
60c
QueryTime = 10*Seconds, /* time between subsequent queries */
.
## diffname ip/il.c 1999/0302
## diff -e /n/emeliedump/1998/1013/sys/src/brazil/ip/il.c /n/emeliedump/1999/0302/sys/src/brazil/ip/il.c
1195a
qunlock(il);
.
1193c
freeblist(bp);
return;
.
1186a
qunlock(il);
.
1181a
qlock(il);
.
584a
qunlock(new);
poperror();
.
583a
qlock(new);
qunlock(il);
if(waserror()){
qunlock(new);
nexterror();
}
.
578a
.
572a
qunlock(il);
.
568a
}
.
567c
else {
qunlock(il);
.
534a
qunlock(il);
.
529a
qunlock(s);
poperror();
.
528a
qlock(s);
qunlock(il);
if(waserror()){
qunlock(s);
nexterror();
}
.
523a
qlock(il);
.
277c
qunlock(c);
.
## diffname ip/il.c 1999/0331
## diff -e /n/emeliedump/1999/0302/sys/src/brazil/ip/il.c /n/emeliedump/1999/0331/sys/src/brazil/ip/il.c
1068a
.
1057a
.
## diffname ip/il.c 1999/0424
## diff -e /n/emeliedump/1999/0331/sys/src/brazil/ip/il.c /n/emeliedump/1999/0424/sys/src/brazil/ip/il.c
1085c
if(ic->unacked != nil)
if(later(msec, ic->timeout, "timeout")) {
.
1075,1076c
if(later(msec, ic->querytime, "querytime")){
if(later(msec, ic->lastrecv+DeathTime, "deathtime")){
.
1072c
if(ic->recvd != ic->acksent)
if(later(msec, ic->acktime, "acktime"))
.
1061c
if(later(msec, ic->timeout, "timeout")) {
.
1049c
if(later(msec, ic->timeout, "timeout")) {
.
1026a
// complain if two numbers not within an hour of each other
#define Tfuture (1000*60*60)
int
later(ulong t1, ulong t2, char *x)
{
int dt;
dt = t1 - t2;
if(dt > 0) {
if(dt > Tfuture)
print("%s: way future %d\n", x, dt);
return 1;
}
if(dt < -Tfuture) {
print("%s: way past %d\n", x, -dt);
return 1;
}
return 0;
}
.
## diffname ip/il.c 1999/0429
## diff -e /n/emeliedump/1999/0424/sys/src/brazil/ip/il.c /n/emeliedump/1999/0429/sys/src/brazil/ip/il.c
1107c
if(later(msec, ic->timeout, "timeout2")) {
.
1081c
if(later(msec, ic->timeout, "timeout1")) {
.
1069c
if(later(msec, ic->timeout, "timeout0")) {
.
729a
ilsettimeout(ic);
.
352c
if(later(msec, ic->timeout, "ilkick"))
.
267a
ilsettimeout(ic);
.
## diffname ip/il.c 1999/0430
## diff -e /n/emeliedump/1999/0429/sys/src/brazil/ip/il.c /n/emeliedump/1999/0430/sys/src/brazil/ip/il.c
1043c
if(x != nil)
print("%s: way past %d\n", x, -dt);
.
1038c
if(x != nil && dt > Tfuture)
.
353c
if(later(msec, ic->timeout, nil))
.
## diffname ip/il.c 1999/0501
## diff -e /n/emeliedump/1999/0430/sys/src/brazil/ip/il.c /n/emeliedump/1999/0501/sys/src/brazil/ip/il.c
192a
int later(ulong, ulong, char*);
.
## diffname ip/il.c 1999/0529
## diff -e /n/emeliedump/1999/0501/sys/src/brazil/ip/il.c /n/emeliedump/1999/0529/sys/src/brazil/ip/il.c
59c
MaxTimeout = 30*Seconds, /* max time between rexmit */
.
## diffname ip/il.c 1999/0630
## diff -e /n/emeliedump/1999/0529/sys/src/brazil/ip/il.c /n/emeliedump/1999/0630/sys/src/brazil/ip/il.c
992d
988,989c
netlog(ipc->p->f, Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
.
590c
ilsendctl(s, ih, Ilclose, 0, nhgetl(ih->ilid), 0);
.
## diffname ip/il.c 1999/0703
## diff -e /n/emeliedump/1999/0630/sys/src/brazil/ip/il.c /n/emeliedump/1999/0703/sys/src/brazil/ip/il.c
1295c
inittimescale();
.
1283,1287d
1277,1281c
if(hz > 1000){
scalediv = hz/1000;
scalemul = 1;
} else {
scalediv = 1;
scalemul = 1000/hz;
.
1273,1274c
uvlong hz;
.
1271c
inittimescale(void)
.
1269c
/* calculate scale constants that converts fast ticks to ms (more or less) */
.
1017c
+ (ic->mdev>>(LogDGain-1))
.
1002c
+ (ic->mdev>>(LogDGain-1))
.
419c
if(rtt > 120000 || rtt < 0)
.
408,414c
rtt = fastticks(nil) - ic->rttstart;
rtt = (rtt*scalemul)/scalediv;
.
405d
197c
static ulong scalediv, scalemul;
.
## diffname ip/il.c 1999/0817
## diff -e /n/emeliedump/1999/0703/sys/src/brazil/ip/il.c /n/emeliedump/1999/0817/sys/src/brazil/ip/il.c
986c
ipoput(ipc->p->f, bp, 0, ttl, tos);
.
972a
tos = ipc->tos;
.
960a
tos = DFLTTOS;
.
941c
int ttl, tos;
.
787c
ipoput(c->p->f, nb, 0, ic->conv->ttl, ic->conv->tos);
.
356c
ipoput(f, bp, 0, c->ttl, c->tos);
.
## diffname ip/il.c 1999/0821
## diff -e /n/emeliedump/1999/0817/sys/src/brazil/ip/il.c /n/emeliedump/1999/0821/sys/src/brazil/ip/il.c
768d
765,766c
if(nb == nil)
.
## diffname ip/il.c 1999/0916
## diff -e /n/emeliedump/1999/0821/sys/src/brazil/ip/il.c /n/emeliedump/1999/0916/sys/src/brazil/ip/il.c
679a
established:
.
671a
case Ildata:
if(ack == ic->start) {
ic->state = Ilestablished;
goto established;
}
break;
.
## diffname ip/il.c 1999/0917
## diff -e /n/emeliedump/1999/0916/sys/src/brazil/ip/il.c /n/emeliedump/1999/0917/sys/src/brazil/ip/il.c
993a
}
void
ilreject(Fs *f, Ilhdr *inih)
{
Ilhdr *ih;
Block *bp;
bp = allocb(IL_IPSIZE+IL_HDRSIZE);
bp->wp += IL_IPSIZE+IL_HDRSIZE;
ih = (Ilhdr *)(bp->rp);
/* Ip fields */
ih->proto = IP_ILPROTO;
hnputs(ih->illen, IL_HDRSIZE);
ih->frag[0] = 0;
ih->frag[1] = 0;
hnputl(ih->dst, nhgetl(inih->src));
hnputl(ih->src, nhgetl(inih->dst));
hnputs(ih->ilsrc, nhgets(inih->ildst));
hnputs(ih->ildst, nhgets(inih->ilsrc));
hnputl(ih->ilid, nhgetl(inih->ilack));
hnputl(ih->ilack, nhgetl(inih->ilid));
ih->iltype = Ilclose;
ih->ilspec = 0;
ih->ilsum[0] = 0;
ih->ilsum[1] = 0;
if(ilcksum)
hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
ipoput(f, bp, 0, MAXTTL, DFLTTOS);
.
730a
ic->recvd = id;
.
649c
ilhangup(s, "connection rejected");
.
575a
ilreject(il->f, ih); /* no listener */
.
545a
ilreject(il->f, ih); /* no channel and not sync */
.
193a
void ilreject(Fs*, Ilhdr*);
.
## diffname ip/il.c 2000/0424
## diff -e /n/emeliedump/1999/0917/sys/src/brazil/ip/il.c /n/emeliedump/2000/0424/sys/src/9/ip/il.c
1343a
il->gc = nil;
.
## diffname ip/il.c 2000/0706
## diff -e /n/emeliedump/2000/0424/sys/src/9/ip/il.c /n/emeliedump/2000/0706/sys/src/9/ip/il.c
926,927c
ipriv->stats[DupMsg]++;
ipriv->stats[DupBytes] += blocklen(bp);
.
868c
ipriv->stats[OutOfOrder]++;
.
626a
priv = s->p->priv;
priv->stats[InMsgs]++;
.
618a
Ilpriv *priv;
.
515c
ipriv->stats[CsumErrs]++;
.
502c
ipriv->stats[LenErrs]++;
.
495c
ipriv->stats[HlenErrs]++;
.
373,380c
priv = il->priv;
p = buf;
e = p+len;
for(i = 0; i < Nstats; i++)
p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]);
return p - buf;
.
370,371c
Ilpriv *priv;
char *p, *e;
int i;
.
357a
priv->stats[OutMsgs]++;
.
295a
priv = c->p->priv;
.
292a
.
291a
Ilpriv *priv;
.
157d
155a
ulong stats[Nstats];
.
152a
Nstats,
};
static char *statnames[] =
{
[InMsgs] "InMsgs",
[OutMsgs] "OutMsgs",
[CsumErrs] "CsumErrs",
[HlenErrs] "HlenErr",
[LenErrs] "LenErrs",
[OutOfOrder] "OutOfOrder",
[Retrans] "Retrans",
[DupMsg] "DupMsg",
[DupBytes] "DupBytes",
};
.
151a
enum
{
InMsgs,
OutMsgs,
CsumErrs, /* checksum errors */
HlenErrs, /* header length error */
LenErrs, /* short packet */
OutOfOrder, /* out of order */
Retrans, /* retransmissions */
DupMsg,
DupBytes,
.
## diffname ip/il.c 2000/1121
## diff -e /n/emeliedump/2000/0706/sys/src/9/ip/il.c /n/emeliedump/2000/1121/sys/src/9/ip/il.c
61c
DeathTime = 30*QueryTime,
.
## diffname ip/il.c 2000/1220
## diff -e /n/emeliedump/2000/1121/sys/src/9/ip/il.c /n/emeliedump/2000/1220/sys/src/9/ip/il.c
307d
## diffname ip/il.c 2001/0227
## diff -e /n/emeliedump/2000/1220/sys/src/9/ip/il.c /n/emeliedump/2001/0227/sys/src/9/ip/il.c
1244a
if(fasttimeout){
/* timeout if we can't connect quickly */
ic->fasttimeout = 1;
ic->timeout = msec+Iltickms;
ic->rexmit = MaxRexmit - 4;
};
.
1220c
ilstart(Conv *c, int type, int fasttimeout)
.
1208a
ic->fasttimeout = 0;
.
1094a
if(ic->fasttimeout)
ic->timeout = msec+Iltickms;
.
499d
270c
e = ilstart(c, IL_LISTEN, 0);
.
236c
return ilstart(c, IL_CONNECT, fast);
.
232a
fast = argc > 1 && strstr(argv[1], "!fasttimeout") != nil;
.
231a
int fast;
.
213c
char* ilstart(Conv*, int, int);
.
102a
/* if set, fasttimeout causes a connection request to terminate after 4*Iltickms */
int fasttimeout;
.
## diffname ip/il.c 2001/0301
## diff -e /n/emeliedump/2001/0227/sys/src/9/ip/il.c /n/emeliedump/2001/0301/sys/src/9/ip/il.c
1269a
iphtadd(&ipriv->ht, c);
.
1266a
iphtadd(&ipriv->ht, c);
.
870c
illocalclose(s);
.
698,700c
if(id != ic->rstart || ack != 0){
illocalclose(s);
} else {
.
644d
641d
637,638c
ilprocess(s, ih, bp);
qunlock(s);
.
634c
qunlock(s);
.
604,631c
qlock(s);
.
601a
ic = (Ilcb*)s->ptcl;
ic->conv = s;
ic->state = Ilsyncee;
ilcbinit(ic);
ic->rstart = nhgetl(ih->ilid);
iphtadd(&ipriv->ht, s);
.
594,600c
s = Fsnewcall(s, raddr, dp, laddr, sp);
if(s == nil){
qunlock(il);
netlog(il->f, Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
ilsendctl(s, ih, Ilclose, 0, nhgetl(ih->ilid), 0);
goto raise;
.
586,592c
ic = (Ilcb*)s->ptcl;
if(ic->state == Illistening){
if(ih->iltype != Ilsync){
qunlock(il);
if(ih->iltype < 0 || ih->iltype > Ilclose)
st = "?";
else
st = iltype[ih->iltype];
ilreject(il->f, ih); /* no channel and not sync */
netlog(il->f, Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
goto raise;
}
.
576,582d
555,574c
s = iphtlook(&ipriv->ht, raddr, dp, laddr, sp);
if(s == nil){
.
541a
v4tov6(laddr, ih->dst);
.
519c
Conv *s;
.
306,308c
illocalclose(c);
.
282a
void
illocalclose(Conv *c)
{
Ilcb *ic;
Ilpriv *ipriv;
ipriv = c->p->priv;
ic = (Ilcb*)c->ptcl;
ic->state = Ilclosed;
iphtrem(&ipriv->ht, c);
ipmove(c->laddr, IPnoaddr);
c->lport = 0;
}
.
225c
void illocalclose(Conv *c);
.
196c
Rendez ilr;
.
188,194c
ulong csumerr; /* checksum errors */
ulong hlenerr; /* header length error */
ulong lenerr; /* short packet */
ulong order; /* out of order */
ulong rexmit; /* retransmissions */
ulong dup;
ulong dupb;
.
185a
Ipht ht;
.
## diffname ip/il.c 2001/0302
## diff -e /n/emeliedump/2001/0301/sys/src/9/ip/il.c /n/emeliedump/2001/0302/sys/src/9/ip/il.c
687a
ic->fasttimeout = 0;
ic->rexmit = 0;
.
681a
ic->fasttimeout = 0;
ic->rexmit = 0;
.
655a
ic->fasttimeout = 0;
ic->rexmit = 0;
.
571a
if(ih->iltype == Ilsync)
ilreject(il->f, ih); /* no listener */
.
517a
ic->rexmit = 0;
.
## diffname ip/il.c 2001/0303
## diff -e /n/emeliedump/2001/0302/sys/src/9/ip/il.c /n/emeliedump/2001/0303/sys/src/9/ip/il.c
239c
/* huge hack to quickly try an il connection */
fast = 0;
if(argc > 1){
p = strstr(argv[1], "!fasttimeout");
if(p != nil){
*p = 0;
fast = 1;
}
}
.
236c
char *e, *p;
.
## diffname ip/il.c 2001/0306
## diff -e /n/emeliedump/2001/0303/sys/src/9/ip/il.c /n/emeliedump/2001/0306/sys/src/9/ip/il.c
347,349d
338c
ilkick(Conv *c)
.
## diffname ip/il.c 2001/0527
## diff -e /n/emeliedump/2001/0306/sys/src/9/ip/il.c /n/emeliedump/2001/0527/sys/src/9/ip/il.c
1221c
char kpname[KNAMELEN];
.
## diffname ip/il.c 2001/0623
## diff -e /n/emeliedump/2001/0527/sys/src/9/ip/il.c /n/emeliedump/2001/0623/sys/src/9/ip/il.c
531c
iliput(Proto *il, Ipifc*, Block *bp)
.
221c
void iliput(Proto*, Ipifc*, Block*);
.
## diffname ip/il.c 2001/0823
## diff -e /n/emeliedump/2001/0623/sys/src/9/ip/il.c /n/emeliedump/2001/0823/sys/src/9/ip/il.c
1016a
if(ipc==nil)
panic("ipc is nil caller is %.8lux", getcallerpc(&ipc));
if(ipc->p==nil)
panic("ipc->p is nil");
.
606c
s = new;
.
599,600c
new = Fsnewcall(s, raddr, dp, laddr, sp);
if(new == nil){
.
540c
Conv *new, *s;
.
## diffname ip/il.c 2001/0922
## diff -e /n/emeliedump/2001/0823/sys/src/9/ip/il.c /n/emeliedump/2001/0922/sys/src/9/ip/il.c
1389c
il->nc = scalednconv();
.
## diffname ip/il.c 2002/0507
## diff -e /n/emeliedump/2001/0922/sys/src/9/ip/il.c /n/emeliedump/2002/0507/sys/src/9/ip/il.c
1060c
ipoput4(f, bp, 0, MAXTTL, DFLTTOS);
.
1039a
ih->vihl = IP_VER4;
.
1027c
ipoput4(ipc->p->f, bp, 0, ttl, tos);
.
1017a
.
981a
ih->vihl = IP_VER4;
.
822c
ipoput4(c->p->f, nb, 0, ic->conv->ttl, ic->conv->tos);
.
805a
h->vihl = IP_VER4;
.
411c
ipoput4(f, bp, 0, c->ttl, c->tos);
.
369a
ih->vihl = IP_VER4;
.
## diffname ip/il.c 2002/0601
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/il.c /n/emeliedump/2002/0601/sys/src/9/ip/il.c
600c
new = Fsnewcall(s, raddr, dp, laddr, sp, V4);
.
## diffname ip/il.c 2002/0710
## diff -e /n/emeliedump/2002/0601/sys/src/9/ip/il.c /n/emeliedump/2002/0710/sys/src/9/ip/il.c
1256c
ic->timeout = NOW+Iltickms;
.
1221,1222c
ic->querytime = NOW + QueryTime;
ic->lastrecv = NOW; /* or we'll timeout right away */
.
1185c
if(later(NOW, ic->timeout, "timeout2")) {
.
1181c
ic->querytime = NOW + QueryTime;
.
1174,1175c
if(later(NOW, ic->querytime, "querytime")){
if(later(NOW, ic->lastrecv+DeathTime, "deathtime")){
.
1171c
if(later(NOW, ic->acktime, "acktime"))
.
1159c
if(later(NOW, ic->timeout, "timeout1")) {
.
1147c
if(later(NOW, ic->timeout, "timeout0")) {
.
1099c
ic->timeout = NOW+Iltickms;
.
1096c
ic->timeout = NOW + pt;
.
1079c
ic->timeout = NOW + pt;
.
1010c
ic->acktime = NOW;
.
644,645c
ic->lastrecv = NOW;
ic->querytime = NOW + QueryTime;
.
410c
if(later(NOW, ic->timeout, nil))
.
390c
ic->acktime = NOW + AckDelay;
.
## diffname ip/il.c 2002/0711
## diff -e /n/emeliedump/2002/0710/sys/src/9/ip/il.c /n/emeliedump/2002/0711/sys/src/9/ip/il.c
419c
c->rq = qopen(64*1024, Qmsg, 0, c);
.
## diffname ip/il.c 2002/0712
## diff -e /n/emeliedump/2002/0711/sys/src/9/ip/il.c /n/emeliedump/2002/0712/sys/src/9/ip/il.c
1381d
420c
c->wq = qopen(64*1024, Qkick, ilkick, c);
.
339a
Conv *c = x;
.
338c
ilkick(void *x)
.
## diffname ip/il.c 2002/0719
## diff -e /n/emeliedump/2002/0712/sys/src/9/ip/il.c /n/emeliedump/2002/0719/sys/src/9/ip/il.c
420c
c->rq = qopen(64*1024, 0, 0, c);
.
## diffname ip/il.c 2003/0220
## diff -e /n/emeliedump/2002/0719/sys/src/9/ip/il.c /n/emeliedump/2003/0220/sys/src/9/ip/il.c
421c
c->wq = qbypass(ilkick, c);
.
353d
345d
338c
ilkick(void *x, Block *bp)
.
## diffname ip/il.c 2003/0308
## diff -e /n/emeliedump/2003/0220/sys/src/9/ip/il.c /n/emeliedump/2003/0308/sys/src/9/ip/il.c
1064c
ipoput4(f, bp, 0, MAXTTL, DFLTTOS, nil);
.
1030c
ipoput4(ipc->p->f, bp, 0, ttl, tos, ipc);
.
823c
ipoput4(c->p->f, nb, 0, c->ttl, c->tos, c);
.
411c
ipoput4(f, bp, 0, c->ttl, c->tos, c);
.
## diffname ip/il.c 2003/0407
## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/il.c /n/emeliedump/2003/0407/sys/src/9/ip/il.c
1136c
tsleep(&up->sleep, return0, 0, Iltickms);
.
1133d
1130d
198,199d
|