improved persist mode, we now clear everything we can in the PPP control block structure, ensuring we start a new session from a clean state

This commit is contained in:
Sylvain Rochet 2012-07-21 00:26:23 +02:00
parent c65883a727
commit 4ea5c1d973
3 changed files with 93 additions and 49 deletions

View File

@ -1494,7 +1494,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) {
*/ */
if (f->state != PPP_FSM_OPENED) { if (f->state != PPP_FSM_OPENED) {
if (looped_back) { if (looped_back) {
if (++try.numloops >= pcb->lcp_loopbackfail) { if (++try.numloops >= pcb->settings.lcp_loopbackfail) {
int errcode = PPPERR_LOOPBACK; int errcode = PPPERR_LOOPBACK;
notice("Serial line is looped back."); notice("Serial line is looped back.");
ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode);

View File

@ -187,6 +187,7 @@ struct protent *protocols[] = {
#endif /* PPPOS_SUPPORT */ #endif /* PPPOS_SUPPORT */
/* Prototypes for procedures local to this file. */ /* Prototypes for procedures local to this file. */
static void ppp_clear(ppp_pcb *pcb);
static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */
@ -248,24 +249,16 @@ int ppp_init(void) {
/* Create a new PPP session. */ /* Create a new PPP session. */
ppp_pcb *ppp_new(void) { ppp_pcb *ppp_new(void) {
int i;
ppp_pcb *pcb; ppp_pcb *pcb;
struct protent *protp;
pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB);
if (pcb == NULL) if (pcb == NULL)
return NULL; return NULL;
#if PPP_STATS_SUPPORT
link_stats_valid = 0;
#endif /* PPP_STATS_SUPPORT */
memset(pcb, 0, sizeof(ppp_pcb)); memset(pcb, 0, sizeof(ppp_pcb));
#if PPP_DEBUG #if PPP_DEBUG
pcb->num = ppp_num++; pcb->num = ppp_num++;
#endif /* PPP_DEBUG */ #endif /* PPP_DEBUG */
IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255);
pcb->lcp_loopbackfail = DEFLOOPBACKFAIL;
/* default configuration */ /* default configuration */
pcb->settings.usepeerdns = 1; pcb->settings.usepeerdns = 1;
@ -275,14 +268,11 @@ ppp_pcb *ppp_new(void) {
pcb->settings.chap_timeout_time = 3; pcb->settings.chap_timeout_time = 3;
pcb->settings.chap_max_transmits = 10; pcb->settings.chap_max_transmits = 10;
#endif /* CHAP_SUPPPORT */ #endif /* CHAP_SUPPPORT */
pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL;
pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL;
pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS;
/* ppp_clear(pcb);
* Initialize each protocol.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i)
(*protp->init)(pcb);
if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask,
&pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) {
@ -294,6 +284,25 @@ ppp_pcb *ppp_new(void) {
return pcb; return pcb;
} }
/* Set a PPP PCB to its initial state */
static void ppp_clear(ppp_pcb *pcb) {
struct protent *protp;
int i;
#if PPP_STATS_SUPPORTs
link_stats_valid = 0;
#endif /* PPP_STATS_SUPPORT */
memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) );
IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255);
/*
* Initialize each protocol.
*/
for (i = 0; (protp = protocols[i]) != NULL; ++i)
(*protp->init)(pcb);
}
void ppp_set_default(ppp_pcb *pcb) { void ppp_set_default(ppp_pcb *pcb) {
netif_set_default(&pcb->netif); netif_set_default(&pcb->netif);
} }
@ -371,7 +380,6 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s
* Start the connection and handle incoming events (packet or timeout). * Start the connection and handle incoming events (packet or timeout).
*/ */
PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num)); PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num));
new_phase(pcb, PHASE_INITIALIZE);
ppp_start(pcb); ppp_start(pcb);
#if PPP_INPROC_OWNTHREAD #if PPP_INPROC_OWNTHREAD
sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);
@ -430,7 +438,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic
return PPPERR_OPEN; return PPPERR_OPEN;
} }
new_phase(pcb, PHASE_INITIALIZE);
pppoe_connect(pcb->pppoe_sc); pppoe_connect(pcb->pppoe_sc);
return PPPERR_NONE; return PPPERR_NONE;
} }
@ -454,12 +461,12 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16
pcb->link_status_cb = link_status_cb; pcb->link_status_cb = link_status_cb;
pcb->link_status_ctx = link_status_ctx; pcb->link_status_ctx = link_status_ctx;
wo->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */
wo->neg_asyncmap = 0; wo->neg_asyncmap = 0;
wo->neg_pcompression = 0; wo->neg_pcompression = 0;
wo->neg_accompression = 0; wo->neg_accompression = 0;
ao->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */
ao->neg_asyncmap = 0; ao->neg_asyncmap = 0;
ao->neg_pcompression = 0; ao->neg_pcompression = 0;
ao->neg_accompression = 0; ao->neg_accompression = 0;
@ -468,7 +475,6 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16
return PPPERR_OPEN; return PPPERR_OPEN;
} }
new_phase(pcb, PHASE_INITIALIZE);
if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) {
return PPPERR_OPEN; return PPPERR_OPEN;
} }
@ -525,6 +531,7 @@ ppp_sighup(ppp_pcb *pcb)
/** Initiate LCP open request */ /** Initiate LCP open request */
static void ppp_start(ppp_pcb *pcb) { static void ppp_start(ppp_pcb *pcb) {
PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num));
new_phase(pcb, PHASE_INITIALIZE);
lcp_open(pcb); /* Start protocol */ lcp_open(pcb); /* Start protocol */
lcp_lowerup(pcb); lcp_lowerup(pcb);
PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n"));
@ -1817,9 +1824,24 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) {
/* Reconnect if persist mode is enabled */ /* Reconnect if persist mode is enabled */
if(pcb->settings.persist) { if(pcb->settings.persist) {
lcp_options *wo = &pcb->lcp_wantoptions;
lcp_options *ao = &pcb->lcp_allowoptions;
if(pcb->link_status_cb) if(pcb->link_status_cb)
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx);
new_phase(pcb, PHASE_INITIALIZE);
ppp_clear(pcb);
wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */
wo->neg_asyncmap = 0;
wo->neg_pcompression = 0;
wo->neg_accompression = 0;
ao->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */
ao->neg_asyncmap = 0;
ao->neg_pcompression = 0;
ao->neg_accompression = 0;
pppoe_reconnect(pcb->pppoe_sc); pppoe_reconnect(pcb->pppoe_sc);
return; return;
} }
@ -1860,9 +1882,24 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) {
/* Reconnect if persist mode is enabled */ /* Reconnect if persist mode is enabled */
if(pcb->settings.persist) { if(pcb->settings.persist) {
lcp_options *wo = &pcb->lcp_wantoptions;
lcp_options *ao = &pcb->lcp_allowoptions;
if(pcb->link_status_cb) if(pcb->link_status_cb)
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx);
new_phase(pcb, PHASE_INITIALIZE);
ppp_clear(pcb);
wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */
wo->neg_asyncmap = 0;
wo->neg_pcompression = 0;
wo->neg_accompression = 0;
ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */
ao->neg_asyncmap = 0;
ao->neg_pcompression = 0;
ao->neg_accompression = 0;
pppol2tp_reconnect(pcb->l2tp_pcb); pppol2tp_reconnect(pcb->l2tp_pcb);
return; return;
} }

View File

@ -231,6 +231,8 @@ typedef struct ppp_settings_s {
u8_t chap_rechallenge_time; u8_t chap_rechallenge_time;
#endif /* CHAP_SUPPPORT */ #endif /* CHAP_SUPPPORT */
u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer
before deciding the link is looped-back. */
u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ u8_t lcp_echo_interval; /* Interval between LCP echo-requests */
u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */
@ -281,7 +283,7 @@ typedef struct ppp_pcb_rx_s {
u16_t in_protocol; /* The input protocol code. */ u16_t in_protocol; /* The input protocol code. */
u16_t in_fcs; /* Input Frame Check Sequence value. */ u16_t in_fcs; /* Input Frame Check Sequence value. */
ppp_dev_states in_state; /* The input process state. */ ppp_dev_states in_state; /* The input process state. */
char in_escaped; /* Escape next character. */ char in_escaped; /* Escape next character. */
ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ ext_accm in_accm; /* Async-Ctl-Char-Map for input. */
} ppp_pcb_rx; } ppp_pcb_rx;
@ -291,6 +293,35 @@ typedef struct ppp_pcb_rx_s {
* PPP interface control block. * PPP interface control block.
*/ */
struct ppp_pcb_s { struct ppp_pcb_s {
/* -- below are data that will NOT be cleared between two sessions if persist mode is enabled */
#if PPP_DEBUG
u8_t num; /* Interface number - only useful for debugging */
#endif /* PPP_DEBUG */
ppp_settings settings;
#if PPPOS_SUPPORT
sio_fd_t fd; /* File device ID of port. */
#endif /* PPPOS_SUPPORT */
#if PPPOE_SUPPORT
struct netif *ethif;
struct pppoe_softc *pppoe_sc;
#endif /* PPPOE_SUPPORT */
#if PPPOL2TP_SUPPORT
pppol2tp_pcb *l2tp_pcb;
#endif /* PPPOL2TP_SUPPORT */
void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */
void *link_status_ctx; /* Status change callback optional pointer */
struct netif netif; /* PPP interface */
/* -- below are data that will be cleared between two sessions if persist mode is enabled */
/*
* phase must be the first member of cleared members, because it is used to know
* which part must not be cleared.
*/
u8_t phase; /* where the link is at */
u8_t err_code; /* Code indicating why interface is down. */
/* flags */
unsigned int if_up :1; /* True when the interface is up. */ unsigned int if_up :1; /* True when the interface is up. */
unsigned int pcomp :1; /* Does peer accept protocol compression? */ unsigned int pcomp :1; /* Does peer accept protocol compression? */
unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ unsigned int accomp :1; /* Does peer accept addr/ctl compression? */
@ -311,14 +342,7 @@ struct ppp_pcb_s {
#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */
unsigned int :6; /* 5 bits of padding to round out to 16 bits */ unsigned int :6; /* 5 bits of padding to round out to 16 bits */
ppp_settings settings;
#if PPP_DEBUG
u8_t num; /* Interface number - only useful for debugging */
#endif /* PPP_DEBUG */
#if PPPOS_SUPPORT #if PPPOS_SUPPORT
sio_fd_t fd; /* File device ID of port. */
/* FIXME: there is probably one superfluous */ /* FIXME: there is probably one superfluous */
ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ ext_accm out_accm; /* Async-Ctl-Char-Map for output. */
ext_accm xmit_accm; /* extended transmit ACCM */ ext_accm xmit_accm; /* extended transmit ACCM */
@ -328,18 +352,6 @@ struct ppp_pcb_s {
#endif /* VJ_SUPPORT */ #endif /* VJ_SUPPORT */
#endif /* PPPOS_SUPPORT */ #endif /* PPPOS_SUPPORT */
#if PPPOE_SUPPORT
struct netif *ethif;
struct pppoe_softc *pppoe_sc;
#endif /* PPPOE_SUPPORT */
#if PPPOL2TP_SUPPORT
pppol2tp_pcb *l2tp_pcb;
#endif /* PPPOL2TP_SUPPORT */
u8_t phase; /* where the link is at */
u8_t err_code; /* Code indicating why interface is down. */
/* FIXME: maybe we should cleanup one of those MTU variables */ /* FIXME: maybe we should cleanup one of those MTU variables */
u16_t mtu; /* Peer's mru */ u16_t mtu; /* Peer's mru */
u16_t peer_mru; /* currently negotiated peer MRU */ u16_t peer_mru; /* currently negotiated peer MRU */
@ -347,10 +359,6 @@ struct ppp_pcb_s {
u32_t last_xmit; /* Time of last transmission. */ u32_t last_xmit; /* Time of last transmission. */
struct ppp_addrs addrs; /* PPP addresses */ struct ppp_addrs addrs; /* PPP addresses */
struct netif netif; /* PPP interface */
void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */
void *link_status_ctx; /* Status change callback optional pointer */
/* auth data */ /* auth data */
#if PPP_SERVER #if PPP_SERVER
@ -358,11 +366,11 @@ struct ppp_pcb_s {
#endif /* PPP_SERVER */ #endif /* PPP_SERVER */
u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ u16_t auth_pending; /* Records which authentication operations haven't completed yet. */
u16_t auth_done; /* Records which authentication operations have been completed. */ u16_t auth_done; /* Records which authentication operations have been completed. */
u8_t num_np_open; /* Number of network protocols which we have opened. */ u8_t num_np_open; /* Number of network protocols which we have opened. */
u8_t num_np_up; /* Number of network protocols which have come up. */ u8_t num_np_up; /* Number of network protocols which have come up. */
#if PAP_SUPPORT #if PAP_SUPPORT
upap_state upap; /* PAP data */ upap_state upap; /* PAP data */
#endif /* PAP_SUPPORT */ #endif /* PAP_SUPPORT */
#if CHAP_SUPPORT #if CHAP_SUPPORT
@ -383,7 +391,6 @@ struct ppp_pcb_s {
lcp_options lcp_hisoptions; /* Options that we ack'd */ lcp_options lcp_hisoptions; /* Options that we ack'd */
u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ u8_t lcp_echos_pending; /* Number of outstanding echo msgs */
u8_t lcp_echo_number; /* ID number of next echo frame */ u8_t lcp_echo_number; /* ID number of next echo frame */
u8_t lcp_loopbackfail;
fsm ipcp_fsm; /* IPCP fsm structure */ fsm ipcp_fsm; /* IPCP fsm structure */
ipcp_options ipcp_wantoptions; /* Options that we want to request */ ipcp_options ipcp_wantoptions; /* Options that we want to request */