From f830032fc81e7b59de346ca2878690da22b47712 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Thu, 12 Mar 1998 02:23:42 +0000 Subject: [PATCH] o Fix a few comment typos. o Fix ``set timeout'' usage message and documentation. o Change ifOutPackets, ifOutOctets and ifOutLQRs to `u_int32_t's so that they wrap correctly. o Put the LQR in network byte order using the correct struct size (sizeof u_int32_t, not sizeof u_long). o Wrap LQR ECHO counters correctly. o Don't increment OutLQR count if the last LQR hasn't been replied to. o Initialise HisLqrData (last received LQR) in StartLqm. o Don't start the LQR timer if we're `disabled' and `accepted'. o Generate LQR responses when both sides are using a timer and we're not going to send our next LQR before the peers max timeout. LQR should now be fully functional. --- usr.sbin/ppp/command.c | 8 ++--- usr.sbin/ppp/hdlc.c | 21 +++++++++---- usr.sbin/ppp/lqr.c | 67 ++++++++++++++++++++++++------------------ usr.sbin/ppp/ppp.8 | 12 ++++---- usr.sbin/ppp/ppp.8.m4 | 12 ++++---- 5 files changed, 71 insertions(+), 49 deletions(-) diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index 622abf704415..274028326870 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.130 1998/01/23 04:36:42 brian Exp $ + * $Id: command.c,v 1.131 1998/01/27 23:14:49 brian Exp $ * */ #include @@ -1189,7 +1189,7 @@ SetPreferredMTU(struct cmdargs const *arg) } static int -SetIdleTimeout(struct cmdargs const *arg) +SetTimeout(struct cmdargs const *arg) { if (arg->argc > 0) { VarIdleTimeout = atoi(arg->argv[0]); @@ -1480,8 +1480,8 @@ static struct cmdtab const SetCommands[] = { "Set server port", "set server|socket TcpPort|LocalName|none [mask]"}, {"speed", NULL, SetModemSpeed, LOCAL_AUTH, "Set modem speed", "set speed value"}, - {"timeout", NULL, SetIdleTimeout, LOCAL_AUTH, - "Set Idle timeout", "set timeout value"}, + {"timeout", NULL, SetTimeout, LOCAL_AUTH, + "Set Idle timeout", "set timeout idle LQR FSM-resend"}, {"vj", NULL, SetInitVJ, LOCAL_AUTH, "Set vj values", "set vj slots|slotcomp"}, {"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH, diff --git a/usr.sbin/ppp/hdlc.c b/usr.sbin/ppp/hdlc.c index ca51a647ea2e..f88d89909e5c 100644 --- a/usr.sbin/ppp/hdlc.c +++ b/usr.sbin/ppp/hdlc.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.c,v 1.27 1998/01/10 01:55:10 brian Exp $ + * $Id: hdlc.c,v 1.28 1998/01/21 02:15:15 brian Exp $ * * TODO: */ @@ -56,9 +56,9 @@ static struct hdlcstat { int unknownproto; } HdlcStat; -static int ifOutPackets; -static int ifOutOctets; -static int ifOutLQRs; +static u_int32_t ifOutPackets; +static u_int32_t ifOutOctets; +static u_int32_t ifOutLQRs; static struct protostat { u_short number; @@ -216,8 +216,17 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp) lqr->PeerInDiscards = HisLqrSave.SaveInDiscards; lqr->PeerInErrors = HisLqrSave.SaveInErrors; lqr->PeerInOctets = HisLqrSave.SaveInOctets; - lqr->PeerOutLQRs = ++ifOutLQRs; - LqrDump("LqrOutput", lqr); + if (HisLqrData.LastOutLQRs == ifOutLQRs) { + /* + * only increment if it's the first time or we've got a reply + * from the last one + */ + lqr->PeerOutLQRs = ++ifOutLQRs; + LqrDump("LqrOutput", lqr); + } else { + lqr->PeerOutLQRs = ifOutLQRs; + LqrDump("LqrOutput (again)", lqr); + } LqrChangeOrder(lqr, (struct lqrdata *) (MBUF_CTOP(bp))); } if (!DEV_IS_SYNC) { diff --git a/usr.sbin/ppp/lqr.c b/usr.sbin/ppp/lqr.c index 2820f105483e..63034536ba58 100644 --- a/usr.sbin/ppp/lqr.c +++ b/usr.sbin/ppp/lqr.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lqr.c,v 1.21 1998/01/11 17:50:40 brian Exp $ + * $Id: lqr.c,v 1.22 1998/01/21 02:15:19 brian Exp $ * * o LQR based on RFC1333 * @@ -29,6 +29,7 @@ #include #include +#include #include "command.h" #include "mbuf.h" @@ -91,7 +92,10 @@ RecvEchoLqr(struct mbuf * bp) if (htonl(lqr->signature) == SIGNATURE) { seq = ntohl(lqr->sequence); LogPrintf(LogLQM, "Got echo LQR [%d]\n", ntohl(lqr->sequence)); - gotseq = seq; + /* careful not to update gotseq with older values */ + if ((gotseq > (u_int32_t)0 - 5 && seq < 5) || + (gotseq <= (u_int32_t)0 - 5 && seq > gotseq)) + gotseq = seq; } } } @@ -104,7 +108,7 @@ LqrChangeOrder(struct lqrdata * src, struct lqrdata * dst) sp = (u_long *) src; dp = (u_long *) dst; - for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_long); n++) + for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_int32_t); n++) *dp++ = ntohl(*sp++); } @@ -117,12 +121,12 @@ SendLqrReport(void *v) if (lqmmethod & LQM_LQR) { if (lqrsendcnt > 5) { - /* * XXX: Should implement LQM strategy */ - LogPrintf(LogPHASE, "** 1 Too many ECHO packets are lost. **\n"); - lqmmethod = 0; /* Prevent rcursion via LcpClose() */ + LogPrintf(LogPHASE, "** Too many LQR packets lost **\n"); + LogPrintf(LogLQM, "LqrOutput: Too many LQR packets lost\n"); + lqmmethod = 0; /* Prevent recursion via LcpClose() */ reconnect(RECON_TRUE); LcpClose(); } else { @@ -131,15 +135,17 @@ SendLqrReport(void *v) lqrsendcnt++; } } else if (lqmmethod & LQM_ECHO) { - if (echoseq - gotseq > 5) { - LogPrintf(LogPHASE, "** 2 Too many ECHO packets are lost. **\n"); - lqmmethod = 0; /* Prevent rcursion via LcpClose() */ + if ((echoseq > 5 && echoseq - 5 > gotseq) || + (echoseq <= 5 && echoseq > gotseq + 5)) { + LogPrintf(LogPHASE, "** Too many ECHO LQR packets lost **\n"); + LogPrintf(LogLQM, "LqrOutput: Too many ECHO LQR packets lost\n"); + lqmmethod = 0; /* Prevent recursion via LcpClose() */ reconnect(RECON_TRUE); LcpClose(); } else SendEchoReq(); } - if (lqmmethod && Enabled(ConfLqr)) + if (lqmmethod && LqrTimer.load) StartTimer(&LqrTimer); } @@ -179,12 +185,15 @@ LqrInput(struct mbuf * bp) lqrsendcnt = 0; /* we have received LQR from peer */ /* - * Generate LQR responce to peer, if i) We are not running LQR timer. ii) - * Two successive LQR's PeerInLQRs are same. + * Generate an LQR response to peer we're not running LQR timer OR + * two successive LQR's PeerInLQRs are same OR we're not going to + * send our next one before the peers max timeout. */ - if (LqrTimer.load == 0 || lastpeerin == HisLqrData.PeerInLQRs) { + if (LqrTimer.load == 0 || lastpeerin == HisLqrData.PeerInLQRs || + (LqrTimer.arg && + LqrTimer.rest * 100 / SECTICKS > (u_int32_t)LqrTimer.arg)) { lqmmethod |= LQM_LQR; - SendLqrReport(0); + SendLqrReport(LqrTimer.arg); } lastpeerin = HisLqrData.PeerInLQRs; } @@ -198,34 +207,34 @@ void StartLqm() { struct lcpstate *lcp = &LcpInfo; - int period; lqrsendcnt = 0; /* start waiting all over for ECHOs */ echoseq = 0; gotseq = 0; + memset(&HisLqrData, '\0', sizeof HisLqrData); lqmmethod = LQM_ECHO; if (Enabled(ConfLqr)) lqmmethod |= LQM_LQR; StopTimer(&LqrTimer); - LogPrintf(LogLQM, "LQM method = %d\n", lqmmethod); - if (lcp->his_lqrperiod || lcp->want_lqrperiod) { + if (lcp->his_lqrperiod) + LogPrintf(LogLQM, "Expecting LQR every %d.%02d secs\n", + lcp->his_lqrperiod / 100, lcp->his_lqrperiod % 100); - /* - * We need to run timer. Let's figure out period. - */ - period = lcp->his_lqrperiod ? lcp->his_lqrperiod : lcp->want_lqrperiod; - StopTimer(&LqrTimer); + if (lcp->want_lqrperiod) { + LogPrintf(LogLQM, "Will send %s every %d.%02d secs\n", + lqmmethod & LQM_LQR ? "LQR" : "ECHO LQR", + lcp->want_lqrperiod / 100, lcp->want_lqrperiod % 100); LqrTimer.state = TIMER_STOPPED; - LqrTimer.load = period * SECTICKS / 100; + LqrTimer.load = lcp->want_lqrperiod * SECTICKS / 100; LqrTimer.func = SendLqrReport; - SendLqrReport(0); - StartTimer(&LqrTimer); - LogPrintf(LogLQM, "Will send LQR every %d.%d secs\n", - period / 100, period % 100); + LqrTimer.arg = (void *)lcp->his_lqrperiod; + SendLqrReport(LqrTimer.arg); } else { - LogPrintf(LogLQM, "LQR is not activated.\n"); + LqrTimer.load = 0; + if (!lcp->his_lqrperiod) + LogPrintf(LogLQM, "LQR/ECHO LQR not negotiated\n"); } } @@ -246,7 +255,7 @@ StopLqr(int method) LogPrintf(LogLQM, "Stop sending LCP ECHO.\n"); lqmmethod &= ~method; if (lqmmethod) - SendLqrReport(0); + SendLqrReport(LqrTimer.arg); else StopTimer(&LqrTimer); } diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index d20c4dc127ce..790fb96d872c 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.96 1998/01/20 22:47:46 brian Exp $ +.\" $Id: ppp.8,v 1.97 1998/01/27 23:14:53 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -839,7 +839,7 @@ ui-gate: set escape 0xff set device ui-gate:ppp-in set dial - set timeout 30 5 4 + set timeout 30 15 5 set log Phase Chat Connect Carrier hdlc LCP IPCP CCP tun set ifaddr 10.0.4.2 10.0.4.1 add 10.0.2.0 255.255.255.0 10.0.4.1 @@ -961,7 +961,7 @@ See To check/set idle timer, use the .Dq show timeout and -.Dq set timeout [lqrtimer [retrytimer]] +.Dq set timeout idle [LQR [FSM-resend]] commands: .Bd -literal -offset indent ppp ON awfulhak> set timeout 600 @@ -2384,9 +2384,11 @@ can also be used, but link encryption may be implemented in the future, so should not be relied upon. .It set speed value This sets the speed of the serial device. -.It set timeout Idle [ lqr [ retry ] ] +.Dq set timeout idle [LQR [FSM-resend]] This command allows the setting of the idle timer, the LQR timer (if -enabled) and the retry timer. +enabled) and the finite state machine +.Pq FSM +retry timer. .It set vj slots nslots This command sets the initial number of .Ar slots diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index d20c4dc127ce..790fb96d872c 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.96 1998/01/20 22:47:46 brian Exp $ +.\" $Id: ppp.8,v 1.97 1998/01/27 23:14:53 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -839,7 +839,7 @@ ui-gate: set escape 0xff set device ui-gate:ppp-in set dial - set timeout 30 5 4 + set timeout 30 15 5 set log Phase Chat Connect Carrier hdlc LCP IPCP CCP tun set ifaddr 10.0.4.2 10.0.4.1 add 10.0.2.0 255.255.255.0 10.0.4.1 @@ -961,7 +961,7 @@ See To check/set idle timer, use the .Dq show timeout and -.Dq set timeout [lqrtimer [retrytimer]] +.Dq set timeout idle [LQR [FSM-resend]] commands: .Bd -literal -offset indent ppp ON awfulhak> set timeout 600 @@ -2384,9 +2384,11 @@ can also be used, but link encryption may be implemented in the future, so should not be relied upon. .It set speed value This sets the speed of the serial device. -.It set timeout Idle [ lqr [ retry ] ] +.Dq set timeout idle [LQR [FSM-resend]] This command allows the setting of the idle timer, the LQR timer (if -enabled) and the retry timer. +enabled) and the finite state machine +.Pq FSM +retry timer. .It set vj slots nslots This command sets the initial number of .Ar slots