X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Flcp.c;h=902b64a565c21d11940c39cb0fe5e10cf911848f;hb=0678d3bf69116af58b00fbc64bd4185acb4d5c37;hp=e70dcec525507b9ddcfba06542941f8bcca24619;hpb=f9f667ee187be5d34ac94f11bf366dd218191122;p=ppp.git diff --git a/pppd/lcp.c b/pppd/lcp.c index e70dcec..902b64a 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -40,7 +40,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: lcp.c,v 1.75 2004/11/14 22:53:42 carlsonj Exp $" +#define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $" /* * TODO: @@ -56,7 +56,6 @@ #include "chap-new.h" #include "magic.h" -static const char rcsid[] = RCSID; /* * When the link comes up we want to be able to wait for a short while, @@ -73,6 +72,7 @@ static void lcp_delayed_up __P((void *)); */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ @@ -151,6 +151,8 @@ static option_t lcp_option_list[] = { OPT_PRIO }, { "lcp-echo-interval", o_int, &lcp_echo_interval, "Set time in seconds between LCP echo requests", OPT_PRIO }, + { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, + "Suppress LCP echo requests if traffic was received", 1 }, { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, "Set time in seconds between LCP retransmissions", OPT_PRIO }, { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, @@ -397,21 +399,29 @@ lcp_close(unit, reason) char *reason; { fsm *f = &lcp_fsm[unit]; + int oldstate; if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_TERMINATE); - if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { + + if (f->flags & DELAYED_UP) { + untimeout(lcp_delayed_up, f); + f->state = STOPPED; + } + oldstate = f->state; + + fsm_close(f, reason); + if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) { /* * This action is not strictly according to the FSM in RFC1548, * but it does mean that the program terminates if you do a - * lcp_close() in passive/silent mode when a connection hasn't - * been established. + * lcp_close() when a connection hasn't been established + * because we are in passive/silent mode or because we have + * delayed the fsm_lowerup() call and it hasn't happened yet. */ - f->state = CLOSED; + f->flags &= ~DELAYED_UP; lcp_finished(f); - - } else - fsm_close(f, reason); + } } @@ -453,9 +463,10 @@ lcp_lowerdown(unit) { fsm *f = &lcp_fsm[unit]; - if (f->flags & DELAYED_UP) + if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; - else + untimeout(lcp_delayed_up, f); + } else fsm_lowerdown(&lcp_fsm[unit]); } @@ -489,6 +500,7 @@ lcp_input(unit, p, len) if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; + untimeout(lcp_delayed_up, f); fsm_lowerup(f); } fsm_input(f, p, len); @@ -1305,8 +1317,8 @@ lcp_nakci(f, p, len, treat_as_reject) if (looped_back) { if (++try.numloops >= lcp_loopbackfail) { notice("Serial line is looped back."); - lcp_close(f->unit, "Loopback detected"); status = EXIT_LOOPBACK; + lcp_close(f->unit, "Loopback detected"); } } else try.numloops = 0; @@ -2056,7 +2068,6 @@ lcp_printpkt(p, plen, printer, arg) printer(arg, " MD5"); ++p; break; -#ifdef CHAPMS case CHAP_MICROSOFT: printer(arg, " MS"); ++p; @@ -2066,7 +2077,6 @@ lcp_printpkt(p, plen, printer, arg) printer(arg, " MS-v2"); ++p; break; -#endif } } break; @@ -2233,8 +2243,8 @@ void LcpLinkFailure (f) if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); - lcp_close(f->unit, "Peer not responding"); status = EXIT_PEER_DEAD; + lcp_close(f->unit, "Peer not responding"); } } @@ -2323,6 +2333,22 @@ LcpSendEchoRequest (f) } } + /* + * If adaptive echos have been enabled, only send the echo request if + * no traffic was received since the last one. + */ + if (lcp_echo_adaptive) { + static unsigned int last_pkts_in = 0; + + update_link_stats(f->unit); + link_stats_valid = 0; + + if (link_stats.pkts_in != last_pkts_in) { + last_pkts_in = link_stats.pkts_in; + return; + } + } + /* * Make and send the echo request frame. */