M port/devarp.c => port/devarp.c +6 -4
@@ 282,7 282,6 @@ arpoput(Queue *q, Block *bp)
if(bp->type != M_DATA) {
if(Servq == 0 && streamparse("arpd", bp)) {
-print("setting arp channel\n");
Servq = RD(q);
freeb(bp);
}
@@ 298,17 297,20 @@ print("setting arp channel\n");
}
eh = (Etherhdr *)bp->rptr;
+ if(nhgets(eh->type) != ET_IP) {
+ PUTNEXT(q, bp);
+ return;
+ }
+
iproute(eh->dst, ip);
/* Send downstream to the ethernet */
if(arplookup(ip, eh->d)) {
-print("arp hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
PUTNEXT(q, bp);
return;
}
-print("arp miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
- /* Return the packet to the arp server for address resolution */
+ /* Push the packet up to the arp server for address resolution */
memmove(eh->d, ip, sizeof(ip));
PUTNEXT(Servq, bp);
}
M port/devenv.c => port/devenv.c +11 -0
@@ 433,6 433,17 @@ envdump(void)
for(i = 0; i < EVHASH; i++){
j = 0;
for(ev = evhash[i].next; ev; ev = ev->next){
+ uchar *t, *s;
+ int h, n;
+
+ s = (uchar*)ev->val;
+ n = ev->len;
+ h = 0;
+ for(t = s; t - s < n; t++)
+ h = (h << 1) ^ *t;
+ h &= EVHASH - 1;
+ if(h != i)
+ print("hash conflict: %d %d\n", i, h);
if(j++ == 1000){
print("hash bucket %d circular\n", i);
break;
M port/devip.c => port/devip.c +3 -7
@@ 15,8 15,7 @@ enum
Nipsubdir = 4, /* Number of subdirectory entries per connection */
};
-int udpsum = 1;
-
+int udpsum = 1;
Queue *Ipoutput; /* Control message stream for tcp/il */
Ipifc *ipifc; /* IP protocol interfaces for stip */
Ipconv *ipconv[Nrprotocol]; /* Connections for each protocol */
@@ 389,8 388,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
qunlock(&ipalloc);
}
- else if(strcmp(field[0], "announce") == 0 ||
- strcmp(field[0], "reserve") == 0) {
+ else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) {
if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
(cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
error(Edevbusy);
@@ 682,11 680,10 @@ iplisten(Chan *c, Ipconv *s, Ipconv *base)
qunlock(&s->listenq);
nexterror();
}
-print("listener on %lux R 0x%lux\n", s, &s->listenr);
+
for(;;) {
sleep(&s->listenr, iphavecon, s);
poperror();
-print("listen awoke\n");
new = base;
for(etab = &base[conf.ip]; new < etab; new++) {
if(new->newcon) {
@@ 704,7 701,6 @@ print("listen awoke\n");
pushq(c->stream, new->stproto);
new->ref--;
qunlock(&s->listenq);
-print("ip listener!\n");
return;
}
}
M port/qlock.c => port/qlock.c +1 -1
@@ 33,7 33,7 @@ int
canqlock(QLock *q)
{
lock(&q->use);
- if(q->locked) {
+ if(q->locked){
unlock(&q->use);
return 0;
}
M port/stil.c => port/stil.c +48 -36
@@ 28,10 28,8 @@ ilopen(Queue *q, Stream *s)
Ipconv *ipc;
static int ilkproc;
- /* Start il service processes */
if(!Ipoutput) {
Ipoutput = WR(q);
- /* This never goes away - we use this queue to send acks/rejects */
s->opens++;
s->inuse++;
}
@@ 57,6 55,13 @@ ilopen(Queue *q, Stream *s)
void
ilclose(Queue *q)
{
+ Ipconv *s;
+
+ s = (Ipconv *)(q->ptr);
+ qlock(s);
+ s->ref--;
+ qunlock(s);
+ s->readq = 0;
}
void
@@ 74,7 79,6 @@ iloput(Queue *q, Block *bp)
switch(ipc->ilctl.state) {
case Ilclosed:
- case Ilsyncee:
case Illistening:
case Ilclosing:
error(Ehungup);
@@ 123,7 127,6 @@ iloput(Queue *q, Block *bp)
hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE));
ilackq(ic, bp);
-
PUTNEXT(q, bp);
}
@@ 135,14 138,11 @@ ilackq(Ilcb *ic, Block *bp)
/* Enqueue a copy on the unacked queue in case this one gets lost */
np = copyb(bp, blen(bp));
- if(ic->unacked) {
+ if(ic->unacked)
ic->unackedtail->next = np;
- ic->unackedtail = np;
- }
- else {
+ else
ic->unacked = np;
- ic->unackedtail = np;
- }
+ ic->unackedtail = np;
np->next = 0;
}
@@ 158,6 158,7 @@ ilackto(Ilcb *ic, ulong ackto)
break;
bp = ic->unacked;
ic->unacked = bp->next;
+ bp->next = 0;
freeb(bp);
}
}
@@ 172,7 173,7 @@ void
ilrcvmsg(Ipconv *ipc, Block *bp)
{
Ilhdr *ih;
- int plen;
+ int plen, illen;
Ipconv *s, *etab, *new;
short sp, dp;
Ipaddr dst;
@@ 183,7 184,11 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
if(plen < IL_EHSIZE+IL_HDRSIZE)
goto drop;
- if(ilcksum && ptcl_csum(bp, IL_EHSIZE, plen) != 0) {
+ illen = nhgets(ih->illen);
+ if(illen+IL_EHSIZE > plen)
+ goto drop;
+
+ if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) {
print("il: cksum error\n");
goto drop;
}
@@ 192,28 197,26 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
dp = nhgets(ih->ilsrc);
dst = nhgetl(ih->src);
-print("got packet from %d.%d.%d.%d %d %d\n", fmtaddr(dst), sp, dp);
-
etab = &ipc[conf.ip];
for(s = ipc; s < etab; s++) {
if(s->psrc == sp && s->pdst == dp && s->dst == dst) {
ilprocess(s, ih, bp);
return;
}
-
}
+ if(ih->iltype != Ilsync)
+ goto drop;
+
if(s->curlog > s->backlog)
goto reset;
+ /* Look for a listener */
for(s = ipc; s < etab; s++) {
if(s->ilctl.state == Illistening && s->pdst == 0 && s->dst == 0) {
- /* Do the listener stuff */
new = ipincoming(ipc);
if(new == 0)
goto reset;
- if(ih->iltype != Ilsync)
- goto reset;
new->newcon = 1;
new->ipinterface = s->ipinterface;
@@ 243,7 246,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
Block *nb;
Ilcb *ic;
Ilhdr *oh;
- ulong id, ack, oid;
+ ulong id, ack, oid, dlen;
+ int sendack = 0;
id = nhgetl(h->ilid);
ack = nhgetl(h->ilack);
@@ 264,8 268,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
break;
case Ilsyncer:
if(h->iltype == Ilsync && ic->start == ack) {
- ic->recvd = id;
- ilsendctl(s, 0, Ilack, 0);
+ ic->recvd = id+1;
+ sendack = 1;
ic->state = Ilestablished;
}
break;
@@ 288,6 292,7 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
freeb(bp);
break;
case Ildataquery:
+ sendack = 1;
case Ildata:
ilackto(&s->ilctl, ack);
switch(s->ilctl.state) {
@@ 301,7 306,8 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
iloutoforder(s, h, bp);
else {
s->ilctl.recvd++;
- bp->rptr += IL_EHSIZE+IL_HDRSIZE;
+ dlen = nhgets(h->illen)-IL_HDRSIZE;
+ bp = btrim(bp, IL_EHSIZE+IL_HDRSIZE, dlen);
PUTNEXT(s->readq, bp);
}
}
@@ 319,7 325,7 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
}
/* Process out of order packets */
- if(ic->state == Ilestablished) {
+ if(ic->state == Ilestablished && s->readq) {
while(ic->outoforder) {
bp = ic->outoforder;
oh = (Ilhdr*)bp->rptr;
@@ 335,11 341,18 @@ print("recvd = %d outoforder = %d\n", ic->recvd, oid);
print("outoforder %d\n", oid);
ic->recvd++;
ic->outoforder = bp->next;
- bp->rptr += IL_EHSIZE+IL_HDRSIZE;
+ bp->next = 0;
+ dlen = nhgets(oh->illen)-IL_HDRSIZE;
+ bp = btrim(bp, IL_EHSIZE+IL_HDRSIZE, dlen);
PUTNEXT(s->readq, bp);
}
}
}
+
+ if(sendack)
+ ilsendctl(s, 0, Ilack, 1);
+
+ print("revd = %d sent = %d\n", ic->recvd, ic->sent);
}
@@ 352,23 365,22 @@ iloutoforder(Ipconv *s, Ilhdr *h, Block *bp)
uchar *lid;
ic = &s->ilctl;
-
if(ic->outoforder == 0) {
ic->outoforder = bp;
bp->next = 0;
- return;
}
-
- id = nhgetl(h->id);
- l = &ic->outoforder;
- for(f = *l; f; f = f->next) {
- lid = ((Ilhdr*)(bp->rptr))->ilid;
- if(id < nhgetl(lid))
- break;
- l = &f->next;
+ else {
+ id = nhgetl(h->id);
+ l = &ic->outoforder;
+ for(f = *l; f; f = f->next) {
+ lid = ((Ilhdr*)(bp->rptr))->ilid;
+ if(id > nhgetl(lid))
+ break;
+ l = &f->next;
+ }
+ bp->next = *l;
+ *l = bp;
}
- bp->next = *l;
- *l = bp;
}
void
M port/tcpinput.c => port/tcpinput.c +13 -67
@@ 39,7 39,6 @@ tcp_input(Ipconv *ipc, Block *bp)
Tcphdr *h;
Tcp seg;
int hdrlen;
- Block *oobbp;
Ipaddr source, dest;
char tos;
ushort length;
@@ 293,22 292,9 @@ tcp_input(Ipconv *ipc, Block *bp)
}
if ((seg.flags&URG) && seg.up) {
- DPRINT("tcpin: oob: up = %u seq = %u rcv.up = %u\n",
- seg.up, seg.seq, tcb->rcv.up);
if (seq_gt(seg.up + seg.seq, tcb->rcv.up)) {
tcb->rcv.up = seg.up + seg.seq;
- tcb->oobflags &= ~(TCPOOB_HAVEDATA|TCPOOB_HADDATA);
- extract_oob(&bp, &oobbp, &seg);
- if (oobbp) {
- DPRINT("tcpin: oob delivered\n");
- appendb(&tcb->rcvoobq, oobbp);
- tcb->rcvoobcnt += blen(oobbp);
- tcb->oobmark = tcb->rcvcnt;
- tcb->oobflags |= TCPOOB_HAVEDATA;
-#ifdef NOTIFY
- urg_signal(s);
-#endif
- }
+ copyupb(&bp, 0, seg.up);
}
}
else if (seq_gt(tcb->rcv.nxt, tcb->rcv.up))
@@ 386,7 372,7 @@ tcp_input(Ipconv *ipc, Block *bp)
goto gotone;
}
break;
-gotone:;
+ gotone:;
}
output:
tcp_output(s);
@@ 490,9 476,10 @@ void
update(Ipconv *s, Tcp *seg)
{
ushort acked;
- ushort oobacked;
ushort expand;
Tcpctl *tcb = &s->tcpctl;
+ int rtt;
+ int abserr;
if(seq_gt(seg->ack, tcb->snd.nxt)) {
tcb->flags |= FORCE;
@@ 512,7 499,6 @@ update(Ipconv *s, Tcp *seg)
return;
acked = seg->ack - tcb->snd.una;
-
if(tcb->cwind < tcb->snd.wnd) {
if(tcb->cwind < tcb->ssthresh)
expand = MIN(acked,tcb->mss);
@@ 521,25 507,19 @@ update(Ipconv *s, Tcp *seg)
if(tcb->cwind + expand < tcb->cwind)
expand = 65535 - tcb->cwind;
-
if(tcb->cwind + expand > tcb->snd.wnd)
expand = tcb->snd.wnd - tcb->cwind;
-
if(expand != 0)
tcb->cwind += expand;
-
}
/* Round trip time estimation */
if(run_timer(&tcb->rtt_timer) && seq_ge(seg->ack, tcb->rttseq)) {
stop_timer(&tcb->rtt_timer);
if(!(tcb->flags & RETRAN)) {
- int rtt; /* measured round trip time */
- int abserr; /* abs(rtt - srtt) */
rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
rtt *= MSPTICK;
-
if(rtt > tcb->srtt &&
(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED))
tcb->srtt = rtt;
@@ 556,28 536,16 @@ update(Ipconv *s, Tcp *seg)
}
/* If we're waiting for an ack of our SYN, note it and adjust count */
- if(!(tcb->flags & SYNACK)){
+ if((tcb->flags & SYNACK) == 0){
tcb->flags |= SYNACK;
acked--;
tcb->sndcnt--;
}
- /* Acking some oob data if relevant */
- if(tcb->sndoobq && seq_ge(tcb->snd.up,tcb->snd.una) &&
- seq_gt(seg->ack, tcb->snd.up)) {
- oobacked = seg->ack - tcb->snd.up;
- acked -= oobacked;
- copyupb(&tcb->sndoobq, 0, oobacked);
- tcb->sndoobcnt -= oobacked;
- DPRINT("update: oobacked = %d\n", oobacked);
- }
-
copyupb(&tcb->sndq, 0, acked);
- /* This will include the FIN if there is one */
tcb->sndcnt -= acked;
tcb->snd.una = seg->ack;
- /* If ack includes some out-of-band data then update urgent pointer */
if (seq_gt(seg->ack, tcb->snd.up))
tcb->snd.up = seg->ack;
@@ 588,9 556,6 @@ update(Ipconv *s, Tcp *seg)
if(tcb->snd.una != tcb->snd.nxt)
start_timer(&tcb->timer);
- /* If retransmissions have been occurring, make sure the
- * send pointer doesn't repeat ancient history
- */
if(seq_lt(tcb->snd.ptr, tcb->snd.una))
tcb->snd.ptr = tcb->snd.una;
@@ 605,8 570,7 @@ update(Ipconv *s, Tcp *seg)
int
in_window(Tcpctl *tcb, int seq)
{
- return seq_within(seq, tcb->rcv.nxt,
- (int)(tcb->rcv.nxt+tcb->rcv.wnd-1));
+ return seq_within(seq, tcb->rcv.nxt, (int)(tcb->rcv.nxt+tcb->rcv.wnd-1));
}
void
@@ 629,7 593,6 @@ proc_syn(Ipconv *s, char tos, Tcp *seg)
tcb->mss = seg->mss;
tcb->max_snd = seg->wnd;
-
if((mtu = s->ipinterface->maxmtu) != 0) {
mtu -= TCP_HDRSIZE + TCP_EHSIZE + TCP_PHDRSIZE;
tcb->cwind = tcb->mss = MIN(mtu, tcb->mss);
@@ 677,8 640,7 @@ add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length)
}
else {
for(;;){
- if(rp1->next == 0 ||
- seq_lt(seg->seq, rp1->next->seg.seq)) {
+ if(rp1->next == 0 || seq_lt(seg->seq, rp1->next->seg.seq)) {
rp->next = rp1->next;
rp1->next = rp;
break;
@@ 688,7 650,6 @@ add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length)
}
}
-
void
get_reseq(Tcpctl *tcb, char *tos, Tcp *seg, Block **bp, ushort *length)
{
@@ 729,7 690,8 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
if(tcb->rcv.wnd == 0) {
if(seg->seq == tcb->rcv.nxt && len == 0)
return 0;
- } else {
+ }
+ else {
/* Some part of the segment must be in the window */
if(in_window(tcb,seg->seq)) {
accept++;
@@ 771,7 733,7 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
}
}
excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd);
- if(excess > 0){
+ if(excess > 0) {
tcb->rerecv += excess;
*length -= excess;
nbp = copyb(*bp, *length);
@@ 782,19 744,6 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
return 0;
}
-void
-extract_oob(Block **bp, Block **oobbp, Tcp *seg)
-
-{
- DPRINT("extract_oob: size = %u\n", seg->up);
-
- if (*oobbp = allocb(seg->up))
- (*oobbp)->wptr = (*oobbp)->wptr +
- copyupb(bp, (*oobbp)->rptr, seg->up);
- else
- copyupb(bp, 0, seg->up);
-}
-
int
copyupb(Block **bph, uchar *data, int count)
{
@@ 821,7 770,6 @@ copyupb(Block **bph, uchar *data, int count)
freeb(bp);
}
}
-
return bytes;
}
@@ 949,7 897,6 @@ close_self(Ipconv *s, int reason)
tcb->reseq = 0;
s->err = reason;
-
setstate(s, CLOSED);
}
@@ 968,7 915,8 @@ seq_within(int x, int low, int high)
if(low <= high){
if(low <= x && x <= high)
return 1;
- } else {
+ }
+ else {
if(low >= x && x >= high)
return 1;
}
@@ 1007,7 955,6 @@ setstate(Ipconv *s, char newstate)
oldstate = tcb->state;
tcb->state = newstate;
-
state_upcall(s, oldstate, newstate);
}
@@ 1107,7 1054,7 @@ ntohtcp(Tcp *tcph, Block **bpp)
for(optr = h->tcpopt, i = TCP_HDRSIZE; i < hdrlen;) {
switch(*optr++){
case EOL_KIND:
- goto eol;
+ return hdrlen;
case NOOP_KIND:
i++;
break;
@@ 1119,6 1066,5 @@ ntohtcp(Tcp *tcph, Block **bpp)
break;
}
}
-eol:
return hdrlen;
}
M port/tcpoutput.c => port/tcpoutput.c +9 -42
@@ 8,19 8,16 @@
#include "ipdat.h"
extern int tcpdbg;
+#define DPRINT if(tcpdbg) print
extern ushort tcp_mss;
int tcptimertype = 0;
-
-#define DPRINT if(tcpdbg) print
-
void
tcp_output(Ipconv *s)
{
Block *hbp,*dbp, *sndq;
- ushort ssize, dsize, usable, sent, oobsent;
+ ushort ssize, dsize, usable, sent;
int qlen;
- char doing_oob;
Tcphdr ph;
Tcp seg;
Tcpctl *tcb;
@@ 32,29 29,11 @@ tcp_output(Ipconv *s)
case CLOSED:
return;
}
+
for(;;){
- if (tcb->sndoobq) {
- /* We have pending out-of-band data - use it */
- qlen = tcb->sndoobcnt;
- oobsent = tcb->snd.ptr - tcb->snd.up;
- if (oobsent >= qlen) {
- oobsent = qlen;
- goto normal;
- }
- sndq = tcb->sndoobq;
- sent = oobsent;
- doing_oob = 1;
- DPRINT("tcp_out: oob: qlen = %lux sent = %lux\n",
- qlen, sent);
- } else {
- oobsent = 0;
- normal:
- qlen = tcb->sndcnt;
- sent = tcb->snd.ptr - tcb->snd.una - oobsent;
- sndq = tcb->sndq;
- doing_oob = 0;
- DPRINT("tcp_out: norm: qlen = %lux sent = %lux\n", qlen, sent);
- }
+ qlen = tcb->sndcnt;
+ sent = tcb->snd.ptr - tcb->snd.una;
+ sndq = tcb->sndq;
/* Don't send anything else until our SYN has been acked */
if(sent != 0 && !(tcb->flags & SYNACK))
@@ 78,16 57,10 @@ tcp_output(Ipconv *s)
ssize = MIN(qlen - sent, usable);
ssize = MIN(ssize, tcb->mss);
dsize = ssize;
-
- if (!doing_oob)
- seg.up = 0;
- else {
- seg.up = ssize;
- DPRINT("tcp_out: oob seg.up = %d\n", seg.up);
- }
+ seg.up = 0;
DPRINT("tcp_out: ssize = %lux\n", ssize);
- if(ssize == 0 && !(tcb->flags & FORCE))
+ if(ssize == 0 && (tcb->flags & FORCE) == 0)
break;
/* Stop ack timer if one will be piggy backed on data */
@@ 110,7 83,6 @@ tcp_output(Ipconv *s)
if(tcb->snd.ptr == tcb->iss){
seg.flags |= SYN;
dsize--;
- /* Also send MSS */
seg.mss = tcp_mss;
}
break;
@@ 119,11 91,6 @@ tcp_output(Ipconv *s)
seg.ack = tcb->last_ack = tcb->rcv.nxt;
seg.wnd = tcb->rcv.wnd;
- if (doing_oob) {
- DPRINT("tcp_out: Setting URG (up = %u)\n", seg.up);
- seg.flags |= URG;
- }
-
/* Now try to extract some data from the send queue.
* Since SYN and FIN occupy sequence space and are reflected
* in sndcnt but don't actually sit in the send queue,
@@ 259,7 226,7 @@ void
tcp_acktimer(Ipconv *s)
{
Tcpctl *tcb = &s->tcpctl;
-
+print("Acktimer!\n");
qlock(tcb);
tcb->flags |= FORCE;
tcprcvwin(s);
M ss/main.c => ss/main.c +1 -1
@@ 266,7 266,7 @@ lancesetup(Lance *lp)
lp->ea[i] = *cp++;
kunmap(k);
- lp->lognrrb = 5;
+ lp->lognrrb = 7;
lp->logntrb = 5;
lp->nrrb = 1<<lp->lognrrb;
lp->ntrb = 1<<lp->logntrb;