M port/devenv.c => port/devenv.c +4 -3
@@ 268,7 268,8 @@ envwrite(Chan *c, void *a, long n, ulong offset)
if(n <= 0)
return 0;
- if(offset + n > MAXENV)
+ olen = (offset + n + ALIGN - 1) & ~(ALIGN - 1);
+ if(olen > MAXENV)
error(Etoobig);
eg = u->p->egrp;
qlock(&eg->ev);
@@ 338,8 339,8 @@ evalloc(ulong n)
char *b, *lim;
ulong size;
- n = (n - 1) / ALIGN;
- size = (n + 1) * ALIGN;
+ size = (n + ALIGN - 1) & ~(ALIGN - 1);
+ n = (size - 1) / ALIGN;
p = &envalloc.free[n < EVFREE ? n : EVFREE];
for(ev = *p; ev; ev = *p){
if(ev->len == size){
M port/devip.c => port/devip.c +2 -1
@@ 616,6 616,7 @@ iplisten(Chan *c)
for(;;) {
sleep(&s->listenr, iphavecon, s);
+ print("listen wakes\n");
poperror();
new = base;
for(etab = &base[conf.ip]; new < etab; new++) {
@@ 626,6 627,7 @@ iplisten(Chan *c)
return new - base;
}
}
+ print("no newcon\n");
}
}
@@ 713,7 715,6 @@ ptcl_csum(Block *bp, int offset, int len)
break;
blen = BLEN(bp);
addr = bp->rptr;
-
}
losum += hisum>>8;
M port/devlance.c => port/devlance.c +12 -0
@@ 112,6 112,7 @@ typedef struct {
Ethertype e[Ntypes];
int debug;
int kstarted;
+ uchar bcast[6];
Queue self; /* packets turned around at the interface */
@@ 307,6 308,15 @@ lanceoput(Queue *q, Block *bp )
}
return;
}
+ if(memcmp(l.bcast, p->d, sizeof(l.bcast)) == 0){
+ len = blen(bp);
+ nbp = copyb(bp, len = len >= ETHERMINTU ? len : ETHERMINTU);
+ if(nbp){
+ nbp->wptr = nbp->rptr+len;
+ putq(&l.self, nbp);
+ wakeup(&l.rr);
+ }
+ }
/*
* only one transmitter at a time
@@ 387,6 397,8 @@ lancereset(void)
l.net.info[0].fill = lancestatsfill;
l.net.info[1].name = "type";
l.net.info[1].fill = lancetypefill;
+
+ memset(l.bcast, 0xff, sizeof l.bcast);
}
/*
M port/devnonet.c => port/devnonet.c +93 -76
@@ 312,10 312,7 @@ nonetclose(Chan *c)
{
Noifc *ifc;
- /*
- * real closing happens in noclose
- */
- if(c->qid.path != CHDIR)
+ if(c->stream)
streamclose(c);
/*
@@ 446,7 443,12 @@ noopen(Queue *q, Stream *s)
RD(q)->ptr = WR(q)->ptr = (void *)cp;
}
-
+/*
+ * wait until a hangup is received.
+ * then send a hangup message (until one is received).
+ *
+ * State Transitions: * -> Cclosed
+ */
static int
ishungup(void *a)
{
@@ 461,12 463,20 @@ ishungup(void *a)
}
return 0;
}
-/*
- * wait until a hangup is received.
- * then send a hangup message (until one is received).
- *
- * State Transitions: * -> Cclosed
- */
+static int
+isempty(void *a)
+{
+ Noconv *cp;
+
+ cp = (Noconv *)a;
+ switch(cp->state){
+ case Cconnecting:
+ case Cconnected:
+ return cp->first == cp->next;
+ default:
+ return 1;
+ }
+}
static void
noclose(Queue *q)
{
@@ 476,39 486,43 @@ noclose(Queue *q)
cp = (Noconv *)q->ptr;
- if(waserror()){
- cp->rcvcircuit = -1;
- cp->state = Cclosed;
- nexterror();
- }
-
- /*
- * send hangup messages to the other side
- * until it hangs up or we get tired.
- */
- switch(cp->state){
- case Cconnected:
+ if(!waserror()){
/*
- * send close till we get one back
+ * wait till we have nothing to transmit
*/
- nosendctl(cp, NO_HANGUP, 1);
- for(i=0; i<10 && !ishungup(cp); i++){
- nosendctl(cp, NO_HANGUP, 0);
- tsleep(&cp->r, ishungup, cp, MSrexmit);
- }
- break;
- case Chungup:
+ while(!isempty(cp))
+ tsleep(&cp->r, isempty, cp, MSrexmit);
+
/*
- * ack any close
+ * send hangup messages to the other side
+ * until it hangs up or we get tired.
*/
- nosendctl(cp, NO_HANGUP, 1);
- break;
+ switch(cp->state){
+ case Cconnecting:
+ case Cconnected:
+ /*
+ * send close till we get one back
+ */
+ nosendctl(cp, NO_HANGUP, 1);
+ for(i=0; i<10 && !ishungup(cp); i++){
+ nosendctl(cp, NO_HANGUP, 0);
+ tsleep(&cp->r, ishungup, cp, MSrexmit);
+ }
+ break;
+ case Chungup:
+ /*
+ * ack any close
+ */
+ nosendctl(cp, NO_HANGUP, 1);
+ break;
+ }
+ poperror();
}
- qlock(cp);
/*
* we give up, ack any unacked messages
*/
+ qlock(cp);
for(i = cp->first; i != cp->next; i = MSUCC(i))
norack(cp, cp->out[i].mid);
cp->rcvcircuit = -1;
@@ 518,8 532,6 @@ noclose(Queue *q)
cp->media = 0;
}
qunlock(cp);
-
- poperror();
}
/*
@@ 791,6 803,7 @@ nolisten(Chan *c, Noifc *ifc)
char buf[2*NAMELEN+4];
char *user;
long n;
+ Block *bp;
call.msg = 0;
@@ 841,31 854,38 @@ nolisten(Chan *c, Noifc *ifc)
* stuff the connect message into it
*/
f = ((Nohdr *)(call.msg->rptr))->flag;
- DPRINT("call from %d %s\n", call.circuit, call.raddr);
nostartconv(cp, call.circuit, call.raddr, Cconnecting);
- DPRINT("rcving %d byte message\n", call.msg->wptr - call.msg->rptr);
- nonetrcvmsg(cp, call.msg);
+ bp = call.msg;
call.msg = 0;
-
- /*
- * if a service and remote user were specified,
- * grab them
- */
- if(f & NO_SERVICE){
- DPRINT("reading service\n");
- c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid);
- n = streamread(c, buf, sizeof(buf));
- c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid);
- if(n <= 0)
- error(Ebadctl);
- buf[n] = 0;
- user = strchr(buf, ' ');
- if(user){
- *user++ = 0;
- strncpy(cp->ruser, user, NAMELEN);
- } else
- strcpy(cp->ruser, "none");
- strncpy(cp->addr, buf, NAMELEN);
+ switch(nonetrcvmsg(cp, bp)){
+ case -1:
+ print("bad call message");
+ streamclose(c);
+ continue;
+ case 0:
+ if(f & NO_SERVICE){
+ streamclose(c);
+ print("bad call message");
+ continue;
+ }
+ break;
+ default:
+ if(f & NO_SERVICE){
+ c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid);
+ n = streamread(c, buf, sizeof(buf));
+ c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid);
+ if(n <= 0)
+ error(Ebadctl);
+ buf[n] = 0;
+ user = strchr(buf, ' ');
+ if(user){
+ *user++ = 0;
+ strncpy(cp->ruser, user, NAMELEN);
+ } else
+ strcpy(cp->ruser, "none");
+ strncpy(cp->addr, buf, NAMELEN);
+ }
+ break;
}
break;
}
@@ 1132,7 1152,7 @@ nosendctl(Noconv *cp, int flag, int new)
*
* State Transition: (no NO_NEWCALL in msg) Cconnecting -> Cconnected
*/
-void
+int
nonetrcvmsg(Noconv *cp, Block *bp)
{
Block *nbp;
@@ 1161,7 1181,7 @@ nonetrcvmsg(Noconv *cp, Block *bp)
DPRINT("reset received\n");
noreset(cp);
freeb(bp);
- return;
+ return -1;
}
/*
@@ 1179,22 1199,15 @@ nonetrcvmsg(Noconv *cp, Block *bp)
case Creset:
DPRINT("nonetrcvmsg %d %d\n", cp->rcvcircuit, cp - cp->ifc->conv);
freeb(bp);
- return;
+ return -1;
case Chungup:
case Cconnected:
DPRINT("Nonet call on connected/hanging-up circ %d conv %d\n",
cp->rcvcircuit, cp - cp->ifc->conv);
freeb(bp);
noreset(cp);
- return;
+ return -1;
case Cconnecting:
- if(h->mid != mp->mid){
- DPRINT("Nonet call on connecting circ %d conv %d\n",
- cp->rcvcircuit, cp - cp->ifc->conv);
- freeb(bp);
- noreset(cp);
- return;
- }
break;
}
}
@@ 1216,7 1229,7 @@ nonetrcvmsg(Noconv *cp, Block *bp)
cp->bad++;
}
freeb(bp);
- return;
+ return -1;
}
if(r>=0){
@@ 1238,7 1251,7 @@ nonetrcvmsg(Noconv *cp, Block *bp)
DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r);
cp->bad++;
freeb(bp);
- return;
+ return -1;
}
}
@@ 1268,6 1281,7 @@ nonetrcvmsg(Noconv *cp, Block *bp)
noqack(cp, h->mid);
mp->last->flags |= S_DELIM;
PUTNEXT(q, mp->first);
+ r = mp->len;
mp->first = mp->last = 0;
mp->len = 0;
cp->rcvd++;
@@ 1289,10 1303,13 @@ nonetrcvmsg(Noconv *cp, Block *bp)
if(f & NO_HANGUP){
DPRINT("hangup with message\n");
nohangup(cp);
+ return -1;
}
- } else
+ return r;
+ } else {
mp->last->flags &= ~S_DELIM;
-
+ return 0;
+ }
}
@@ 1453,7 1470,7 @@ nokproc(void *arg)
for(cp = ifc->conv; cp < ep; cp++){
if(cp->state<=Copen || !canqlock(cp))
continue;
- if(cp->state <= Copen){
+ if(cp->state != Cconnected && cp->state != Cconnecting){
qunlock(cp);
continue;
}
M port/ipdat.h => port/ipdat.h +0 -1
@@ 436,7 436,6 @@ Fragq *ipfragallo(void);
void ipfragfree(Fragq*);
void iproute(uchar*, uchar*);
void initfrag(int);
-Block *copyb(Block*, int);
int ntohtcp(Tcp*, Block**);
void reset(Ipaddr, Ipaddr, char, ushort, Tcp*);
void proc_syn(Ipconv*, char, Tcp*);
M port/portfns.h => port/portfns.h +1 -0
@@ 29,6 29,7 @@ void closepgrp(Pgrp*);
long clrfpintr(void);
void confinit(void);
int consactive(void);
+Block *copyb(Block*, int);
Env* copyenv(Env*, int);
void copypage(Page*, Page*);
int decref(Ref*);
M port/stil.c => port/stil.c +7 -13
@@ 154,10 154,8 @@ iloput(Queue *q, Block *bp)
/* Checksum of ilheader plus data (not ip & no pseudo header) */
if(ilcksum)
hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE));
-
ilackq(ic, bp);
delay(100);
- print("TX len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), dlen+IL_HDRSIZE);
PUTNEXT(q, bp);
}
@@ 214,7 212,6 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
char *st;
ih = (Ilhdr *)bp->rptr;
-
plen = blen(bp);
if(plen < IL_EHSIZE+IL_HDRSIZE)
goto drop;
@@ 228,7 225,6 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
dst = nhgetl(ih->src);
if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) {
-print("len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), illen);
st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype];
print("il: cksum error, pkt(%s id %d ack %d %d.%d.%d.%d/%d->%d)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), fmtaddr(dst), sp, dp);
@@ 237,9 233,7 @@ print("len = %d BLEN = %d IL %d\n", blen(bp), BLEN(bp), illen);
etab = &ipc[conf.ip];
for(s = ipc; s < etab; s++)
- if(s->psrc == sp)
- if(s->pdst == dp)
- if(s->dst == dst) {
+ if(s->psrc == sp && s->pdst == dp && s->dst == dst) {
ilprocess(s, ih, bp);
return;
}
@@ 315,8 309,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
break;
case Ilsync:
if(ack != ic->start) {
- ilhangup(s);
ic->state = Ilclosed;
+ ilhangup(s);
}
else {
ic->recvd = id;
@@ 405,7 399,7 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
h->ilsum[0] = 0;
h->ilsum[1] = 0;
if(ilcksum)
- hnputs(h->ilsum, ptcl_csum(nb, IL_EHSIZE, IL_HDRSIZE));
+ hnputs(h->ilsum, ptcl_csum(nb, IL_EHSIZE, nhgets(h->illen)));
PUTNEXT(Ipoutput, nb);
}
freeb(bp);
@@ 448,14 442,14 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
Ilcb *ic = &s->ilctl;
USED(ic);
- DBG("%s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
+ DBG("%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
ilstate[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 rcv %d snt %d\n", ilstate[ic->state], ic->recvd, ic->next);
+ DBG("%11s rcv %d snt %d\n", ilstate[ic->state], ic->recvd, ic->next);
}
void
@@ 578,10 572,10 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
if(ilcksum)
hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE));
- DBG("\nctl(%s id %d ack %d %d->%d)\n",
+/* DBG("\nctl(%s id %d ack %d %d->%d)\n",
iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
nhgets(ih->ilsrc), nhgets(ih->ildst));
-
+*/
PUTNEXT(Ipoutput, bp);
}
M port/stnoether.c => port/stnoether.c +2 -2
@@ 220,7 220,7 @@ noetheriput(Queue *q, Block *bp)
/*
* if not a new call, then its misaddressed
*/
- if((nh->flag & NO_NEWCALL) == 0){
+ if((nh->flag & NO_NEWCALL) == 0 || nh->mid != 1){
noetherbad(ifc, bp, circuit);
return;
}
@@ 228,7 228,6 @@ noetheriput(Queue *q, Block *bp)
/*
* Queue call in a circular queue and wakeup a listener.
*/
- DPRINT("call in\n");
lock(&ifc->lock);
next = (ifc->wptr + 1) % Nnocalls;
if(next == ifc->rptr){
@@ 246,6 245,7 @@ noetheriput(Queue *q, Block *bp)
ifc->wptr = next;
unlock(&ifc->lock);
wakeup(&ifc->listenr);
+ DPRINT("call from %s wptr %d\n", clp->raddr, ifc->wptr);
}
/*
M port/stream.c => port/stream.c +4 -1
@@ 625,6 625,7 @@ expandb(Block *bp, int len)
{
Block *nbp, *new;
int i;
+ ulong delim = 0;
new = allocb(len);
if(new == 0){
@@ 636,7 637,8 @@ expandb(Block *bp, int len)
* copy bytes into new block
*/
for(nbp = bp; len>0 && nbp; nbp = nbp->next){
- i = BLEN(bp);
+ delim = nbp->flags & S_DELIM;
+ i = BLEN(nbp);
if(i > len) {
memmove(new->wptr, nbp->rptr, len);
new->wptr += len;
@@ 651,6 653,7 @@ expandb(Block *bp, int len)
memset(new->wptr, 0, len);
new->wptr += len;
}
+ new->flags |= delim;
freeb(bp);
return new;