ref: 7742661aebb96a26f1cb34a68bcf631065913806
parent: 9702f740ab5532e392fc9c1fd83000d206af4dc5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed May 10 13:25:20 EDT 2023
ip/ppp: Implement echo request timeout, terminate Send lcp echo request every 5 seconds and terminate if we do not get any reply after 12 seconds. On protocol termination, exit all the processes using a note and log a reason. Cleanup.
--- a/sys/src/cmd/ip/ppp/mppc.c
+++ b/sys/src/cmd/ip/ppp/mppc.c
@@ -487,7 +487,7 @@
*protop = 0;
s = ppp->uncstate;
if(BLEN(b) < 2){
- syslog(0, "ppp", ": mppc: short packet");
+ syslog(0, LOG, ": mppc: short packet");
freeb(b);
return nil;
}
@@ -506,7 +506,7 @@
}
if(BLEN(b) < 2){
- syslog(0, "ppp", ": mppc: short packet");
+ syslog(0, LOG, ": mppc: short packet");
freeb(b);
*protop = 0;
return nil;
@@ -559,7 +559,7 @@
n += 16;
//netlog("mppc count = %ux oldcount %ux n = %d\n", count, s->count, n);
if(n < 0 || n > 1) {
- syslog(0, "ppp", ": mppc bad count %ux, %ux", count, s->count);
+ syslog(0, LOG, ": mppc bad count %ux, %ux", count, s->count);
freeb(b);
return nil;
}
--- a/sys/src/cmd/ip/ppp/ppp.c
+++ b/sys/src/cmd/ip/ppp/ppp.c
@@ -111,7 +111,7 @@
static void sendechoreq(PPP*, Pstate*);
static void sendtermreq(PPP*, Pstate*);
static void setphase(PPP*, int);
-static void terminate(PPP*, int);
+static void terminate(PPP*, char *);
static int validv4(Ipaddr);
static void dmppkt(char *s, uchar *a, int na);
@@ -152,8 +152,8 @@
sysfatal("forking mediainproc");
case 0:
mediainproc(ppp);
- terminate(ppp, 1);
- _exits(0);
+ terminate(ppp, "mediainproc");
+ exits(nil);
}
}
@@ -200,7 +200,7 @@
sysfatal("forking ppptimer");
case 0:
ppptimer(ppp);
- _exits(0);
+ exits(nil);
}
}
@@ -221,9 +221,7 @@
default:
sysfatal("ppp: unknown phase %d", phase);
case Pdead:
- /* restart or exit? */
- pinit(ppp, ppp->lcp);
- setphase(ppp, Plink);
+ terminate(ppp, "protocol");
break;
case Plink:
/* link down */
@@ -263,9 +261,6 @@
pinit(ppp, ppp->ccp);
pinit(ppp, ppp->ipcp);
break;
- case Pterm:
- /* what? */
- break;
}
}
@@ -293,6 +288,7 @@
p->optmask &= ~Fpc;
ppp->ipcp->optmask &= ~Fipcompress;
}
+ p->echoack = 0;
p->echotimeout = 0;
/* quality goo */
@@ -342,7 +338,7 @@
p->proto, snames[p->state], snames[state], ppp->rctlmap,
ppp->xctlmap, p->flags,
ppp->mtu, ppp->mru);
- syslog(0, "ppp", "%ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld",
+ syslog(0, LOG, "%ux %s->%s ctlmap %lux/%lux flags %lux mtu %ld mru %ld",
p->proto, snames[p->state], snames[state], ppp->rctlmap,
ppp->xctlmap, p->flags,
ppp->mtu, ppp->mru);
@@ -710,7 +706,7 @@
break;
case Pipcp:
if(p->optmask & Fipaddr){
- syslog(0, "ppp", "requesting %I", ppp->local);
+ syslog(0, LOG, "requesting %I", ppp->local);
putv4o(b, Oipaddr, ppp->local);
}
primary = 1;
@@ -1117,7 +1113,7 @@
case Pipcp:
switch(o->type){
case Oipaddr:
-syslog(0, "ppp", "rejected addr %I with %V", ppp->local, o->data);
+ syslog(0, LOG, "rejected addr %I with %V", ppp->local, o->data);
/* if we're a server, don't let other end change our addr */
if(ppp->localfrozen){
dropoption(p, o);
@@ -1456,12 +1452,26 @@
if(ppp->chap->id < 21)
putpaprequest(ppp);
else {
- terminate(ppp, 0);
netlog("ppp: pap timed out--not authorized\n");
+ terminate(ppp, "pap timeout");
}
}
+static void
+pingtimer(PPP* ppp)
+{
+ if(ppp->lcp->echotimeout == 0 || ppp->lcp->echoack)
+ ppp->lcp->echotimeout = (3*4*1000+Period-1)/Period;
+ else if(--(ppp->lcp->echotimeout) <= 0){
+ netlog("ppp: echo request timeout\n");
+ terminate(ppp, "echo timeout");
+ return;
+ }
+ ppp->lcp->echoack = 0;
+ sendechoreq(ppp, ppp->lcp);
+}
+
/*
* timer for ppp
*/
@@ -1479,6 +1489,8 @@
case Pnet:
ptimer(ppp, ppp->ccp);
ptimer(ppp, ppp->ipcp);
+
+ pingtimer(ppp);
break;
case Pauth:
authtimer(ppp);
@@ -1567,8 +1579,8 @@
sysfatal("forking ipinproc");
case 0:
ipinproc(ppp);
- terminate(ppp, 1);
- _exits(0);
+ terminate(ppp, "ipinproc");
+ exits(nil);
}
} else {
/* we may have changed addresses */
@@ -1578,14 +1590,14 @@
snprint(buf, sizeof buf, "remove %I 255.255.255.255 %I",
ppp->curlocal, ppp->curremote);
if(fprint(ppp->ipcfd, "%s", buf) < 0)
- syslog(0, "ppp", "can't %s: %r", buf);
+ syslog(0, LOG, "can't %s: %r", buf);
snprint(buf, sizeof buf, "add %I 255.255.255.255 %I %lud proxy",
ppp->local, ppp->remote, ppp->mtu-10);
if(fprint(ppp->ipcfd, "%s", buf) < 0)
- syslog(0, "ppp", "can't %s: %r", buf);
+ syslog(0, LOG, "can't %s: %r", buf);
defroute(ppp->net, "add", ppp->remote, ppp->local);
}
- syslog(0, "ppp", "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote,
+ syslog(0, LOG, "%I/%I -> %I/%I", ppp->curlocal, ppp->curremote,
ppp->local, ppp->remote);
}
ipmove(ppp->curlocal, ppp->local);
@@ -1744,8 +1756,16 @@
}
static void
-terminate(PPP *ppp, int kill)
+terminate(PPP *ppp, char *why)
{
+ if(dying++)
+ return;
+
+ syslog(0, LOG, "ppp: terminated: %s", why);
+
+ if(ppp->net != nil && validv4(ppp->curremote) && validv4(ppp->curlocal))
+ defroute(ppp->net, "remove", ppp->curremote, ppp->curlocal);
+
close(ppp->ipfd);
ppp->ipfd = -1;
close(ppp->ipcfd);
@@ -1754,10 +1774,7 @@
close(ppp->mediaout);
ppp->mediain = -1;
ppp->mediaout = -1;
- dying = 1;
-
- if(kill)
- postnote(PNGROUP, getpid(), "die");
+ postnote(PNGROUP, getpid(), "die");
}
typedef struct Iphdr Iphdr;
@@ -2172,7 +2189,7 @@
n = snprint((char*)resp, sizeof(resp), "S=%.20H", c->ai->secret+16);
if(len - 4 < n || tsmemcmp(m->data, resp, n) != 0){
netlog("ppp: chap: bad authenticator\n");
- terminate(ppp, 0);
+ terminate(ppp, "chap: bad authenticator");
break;
}
}
@@ -2182,7 +2199,7 @@
break;
case Cfailure:
netlog("ppp: chap failed\n");
- terminate(ppp, 0);
+ terminate(ppp, "chap failed");
break;
default:
syslog(0, LOG, "chap code %d?", m->code);
@@ -2270,7 +2287,7 @@
&& m->id <= ppp-> chap->id){
netlog("ppp: pap failed (%d:%.*s)\n",
m->data[0], utfnlen((char*)m->data+1, m->data[0]), (char*)m->data+1);
- terminate(ppp, 0);
+ terminate(ppp, "pap failed");
}
break;
default:
@@ -2447,8 +2464,10 @@
Lcpmsg *m;
p->termid = ++(p->id);
- b = alloclcp(Lechoreq, p->id, 4, &m);
- hnputs(m->len, 4);
+ b = alloclcp(Lechoreq, p->id, 8, &m);
+ hnputl(b->wptr, ppp->magic);
+ b->wptr += 4;
+ hnputs(m->len, 8);
putframe(ppp, p->proto, b);
freeb(b);
}
@@ -2593,7 +2612,7 @@
sysfatal("forking xfer");
case 0:
xfer(fd);
- _exits(nil);
+ exits(nil);
}
for(;;){
@@ -2801,7 +2820,7 @@
if(primary)
putndb(ppp, net);
- exits(0);
+ exits(nil);
}
void
--- a/sys/src/cmd/ip/ppp/ppp.h
+++ b/sys/src/cmd/ip/ppp/ppp.h
@@ -70,7 +70,6 @@
Plink, /* doing LCP */
Pauth, /* doing chap */
Pnet, /* doing IPCP, CCP */
- Pterm, /* closing down */
/* PPP protocol types */
Pip= 0x21, /* ip v4 */
--- a/sys/src/cmd/ip/ppp/testppp.c
+++ b/sys/src/cmd/ip/ppp/testppp.c
@@ -20,7 +20,7 @@
switch(fork()){
case -1:
fprint(2, "testppp: can't fork: %r\n");
- exits(0);
+ exits("fork");
case 0:
return;
default:
@@ -89,7 +89,7 @@
n = read(from, buf, sizeof(buf));
if(n <= 0){
fprint(2, "%d -> %d EOF\n", from, to);
- exits(0);
+ exits("read");
}
modified = 0;
if(errrate){
@@ -121,7 +121,7 @@
n = write(to, buf, n);
if(n < 0){
fprint(2, "%d -> %d write err\n", from, to);
- exits(0);
+ exits("write");
}
}
}
@@ -193,6 +193,6 @@
xfer(pfd1[1], pfd2[1]);
xfer(pfd2[1], pfd1[1]);
- exits(0);
+ exits(nil);
}
--- a/sys/src/cmd/ip/ppp/thw.c
+++ b/sys/src/cmd/ip/ppp/thw.c
@@ -253,7 +253,7 @@
uncs = ppp->uncstate;
if(BLEN(bb) < 4){
- syslog(0, "ppp", ": thwack: short packet");
+ syslog(0, LOG, ": thwack: short packet");
freeb(bb);
return nil;
}
@@ -279,7 +279,7 @@
n = unthwack(&uncs->ut, b->wptr, ThwMaxBlock, bb->rptr, BLEN(bb), seq & ThwSeqMask);
freeb(bb);
if(n < 2){
- syslog(0, "ppp", ": unthwack: short or corrupted packet %d seq=%ld", n, seq);
+ syslog(0, LOG, ": unthwack: short or corrupted packet %d seq=%ld", n, seq);
netlog("unthwack: short or corrupted packet n=%d seq=%ld: %s\n", n, seq, uncs->ut.err);
freeb(b);