M port/devip.c => port/devip.c +12 -3
@@ 271,6 271,13 @@ ipwrite(Chan *c, char *a, long n, ulong offset)
ilstart(cp, IL_ACTIVE, 20);
}
+ else if(strcmp(field[0], "disconnect") == 0) {
+ if(cp->stproto != &udpinfo)
+ error(Eperm);
+
+ cp->dst = 0;
+ cp->pdst = 0;
+ }
else if(strcmp(field[0], "announce") == 0) {
if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) ||
(cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed))
@@ 328,7 335,7 @@ udprcvmsg(Ipconv *muxed, Block *bp)
{
Ipconv *ifc, *etab;
Udphdr *uh;
- Port dport;
+ Port dport, sport;
ushort sum, len;
Ipaddr addr;
@@ 352,11 359,13 @@ udprcvmsg(Ipconv *muxed, Block *bp)
}
dport = nhgets(uh->udpdport);
+ sport = nhgets(uh->udpsport);
/* Look for a conversation structure for this port */
etab = &muxed[conf.ip];
for(ifc = muxed; ifc < etab; ifc++) {
- if(ifc->psrc == dport && ifc->ref) {
+ if(ifc->psrc == dport && ifc->ref &&
+ (ifc->pdst == 0 || ifc->pdst == sport)) {
/* Trim the packet down to data size */
len = len - (UDP_HDRSIZE-UDP_PHDRSIZE);
bp = btrim(bp, UDP_EHSIZE+UDP_HDRSIZE, len);
@@ 365,7 374,7 @@ udprcvmsg(Ipconv *muxed, Block *bp)
/* Stuff the src address into the remote file */
ifc->dst = addr;
- ifc->pdst = nhgets(uh->udpsport);
+ ifc->pdst = sport;
PUTNEXT(ifc->readq, bp);
return;
}
M port/segment.c => port/segment.c +4 -4
@@ 339,17 339,17 @@ ibrk(ulong addr, int seg)
if(s == 0)
errors("no segment");
- qlock(&s->lk);
-
if(addr == 0)
return s->base;
+ qlock(&s->lk);
+
if(addr < s->base) {
/* We may start with the bss overlapping the data */
if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) {
qunlock(&s->lk);
- pprint("addr below segment\n");
- }
+ errors("addr below segment");
+ }
addr = s->base;
}
M port/stil.c => port/stil.c +23 -9
@@ 24,15 24,16 @@ static char *etime = "connection timed out";
enum
{
Iltickms = 100,
- Slowtime = 20*Iltickms,
- Fasttime = 5*Iltickms,
- Acktime = 3*Iltickms,
- Ackkeepalive = 1000*Iltickms,
+ Slowtime = 200*Iltickms,
+ Fasttime = 4*Iltickms,
+ Acktime = 2*Iltickms,
+ Ackkeepalive = 6000*Iltickms,
Defaultwin = 20,
};
-#define Backoff(s) (s)*=2
#define Starttimer(s) {(s)->timeout = 0; (s)->fasttime = Fasttime;}
+/* Packet dropping putnext for testing */
+#define DPUTNEXT(q, b) if((MACHP(0)->ticks&7) != 3)PUTNEXT(q, b);else{freeb(b);print(".");}
void ilrcvmsg(Ipconv*, Block*);
void ilackproc(void*);
@@ 43,6 44,7 @@ void ilpullup(Ipconv*);
void ilhangup(Ipconv*, char *);
void ilfreeq(Ilcb*);
void ilrexmit(Ilcb*);
+void ilbackoff(Ilcb*);
void
ilopen(Queue *q, Stream *s)
@@ 183,8 185,11 @@ ilackq(Ilcb *ic, Block *bp)
qlock(&ic->ackq);
if(ic->unacked)
ic->unackedtail->list = np;
- else
+ else {
+ /* Start timer since we may have been idle for some time */
+ Starttimer(ic);
ic->unacked = np;
+ }
ic->unackedtail = np;
qunlock(&ic->ackq);
np->list = 0;
@@ 673,7 678,7 @@ ilackproc(void *a)
case Ilclosing:
if(ic->timeout >= ic->fasttime) {
ilsendctl(s, 0, Ilclose, ic->next, ic->recvd);
- Backoff(ic->fasttime);
+ ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
ic->state = Ilclosed;
@@ 684,7 689,7 @@ ilackproc(void *a)
case Ilsyncer:
if(ic->timeout >= ic->fasttime) {
ilsendctl(s, 0, Ilsync, ic->start, ic->recvd);
- Backoff(ic->fasttime);
+ ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
ic->state = Ilclosed;
@@ 701,7 706,7 @@ ilackproc(void *a)
}
if(ic->timeout >= ic->fasttime) {
ilrexmit(ic);
- Backoff(ic->fasttime);
+ ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
ic->state = Ilclosed;
@@ 715,6 720,15 @@ ilackproc(void *a)
}
void
+ilbackoff(Ilcb *ic)
+{
+ if(ic->fasttime < Slowtime/2)
+ ic->fasttime += Fasttime;
+ else
+ ic->fasttime = (ic->fasttime)*3/2;
+}
+
+void
ilstart(Ipconv *ipc, int type, int window)
{
Ilcb *ic = &ipc->ilctl;
M port/stip.c => port/stip.c +3 -1
@@ 29,6 29,7 @@ Queue *Etherq;
Ipaddr Myip;
Ipaddr Mymask;
uchar Netmyip[4]; /* In Network byte order */
+uchar bcast[4] = { 0xff, 0xff, 0xff, 0xff };
/* Predeclaration */
static void ipetherclose(Queue*);
@@ 309,7 310,8 @@ ipetheriput(Queue *q, Block *bp)
}
/* Look to see if its for me before we waste time checksuming it */
- if(memcmp(h->dst, Netmyip, sizeof(Netmyip)) != 0)
+ if(memcmp(h->dst, Netmyip, sizeof(Netmyip)) != 0 &&
+ memcmp(h->dst, bcast, sizeof(bcast)) != 0)
goto drop;
if(ipcksum && ip_csum(&h->vihl)) {