]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/lcp.c
pppd: Do not call update_link_stats() for every LcpSendEchoRequest() call
[ppp.git] / pppd / lcp.c
index e70dcec525507b9ddcfba06542941f8bcca24619..d7ea47106376cc3e3a43a6c7d55ed40a137994c2 100644 (file)
@@ -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,20 @@ 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;
+       struct pppd_stats cur_stats;
+
+       if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) {
+           last_pkts_in = cur_stats.pkts_in;
+           return;
+       }
+    }
+
     /*
      * Make and send the echo request frame.
      */