* 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:
#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,
*/
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 */
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,
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);
+ }
}
{
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]);
}
if (f->flags & DELAYED_UP) {
f->flags &= ~DELAYED_UP;
+ untimeout(lcp_delayed_up, f);
fsm_lowerup(f);
}
fsm_input(f, p, len);
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;
printer(arg, " MD5");
++p;
break;
-#ifdef CHAPMS
case CHAP_MICROSOFT:
printer(arg, " MS");
++p;
printer(arg, " MS-v2");
++p;
break;
-#endif
}
}
break;
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");
}
}
}
}
+ /*
+ * 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.
*/