mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-15 13:20:57 +00:00
Do not destroy the PPP control block automatically anymore, added ppp_delete() API function.
Without that, PPP user don't know when and how the PPP control block is free()ed, which can lead to hard fault.
This commit is contained in:
parent
4ea5c1d973
commit
bc724ea206
@ -694,7 +694,7 @@ void link_terminated(ppp_pcb *pcb) {
|
||||
void link_down(ppp_pcb *pcb) {
|
||||
#if PPP_NOTIFY
|
||||
notify(link_down_notifier, 0);
|
||||
#endif /* #if PPP_NOTIFY */
|
||||
#endif /* PPP_NOTIFY */
|
||||
|
||||
if (!doing_multilink) {
|
||||
upper_layers_down(pcb);
|
||||
|
@ -229,8 +229,6 @@ static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short pr
|
||||
static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p);
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
static void ppp_destroy(ppp_pcb *pcb);
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
@ -272,8 +270,6 @@ ppp_pcb *ppp_new(void) {
|
||||
pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL;
|
||||
pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS;
|
||||
|
||||
ppp_clear(pcb);
|
||||
|
||||
if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask,
|
||||
&pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) {
|
||||
memp_free(MEMP_PPP_PCB, pcb);
|
||||
@ -281,6 +277,7 @@ ppp_pcb *ppp_new(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_phase(pcb, PHASE_DEAD);
|
||||
return pcb;
|
||||
}
|
||||
|
||||
@ -289,6 +286,8 @@ static void ppp_clear(ppp_pcb *pcb) {
|
||||
struct protent *protp;
|
||||
int i;
|
||||
|
||||
LWIP_ASSERT("pcb->phase == PHASE_DEAD", pcb->phase == PHASE_DEAD);
|
||||
|
||||
#if PPP_STATS_SUPPORTs
|
||||
link_stats_valid = 0;
|
||||
#endif /* PPP_STATS_SUPPORT */
|
||||
@ -357,6 +356,9 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s
|
||||
/* input pbuf left over from last session? */
|
||||
ppp_free_current_input_packet(&pcb->rx);
|
||||
|
||||
ppp_clear(pcb);
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
|
||||
pcb->fd = fd;
|
||||
|
||||
pcb->rx.pcb = pcb;
|
||||
@ -419,6 +421,9 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic
|
||||
if (link_status_cb == NULL)
|
||||
return PPPERR_PARAM;
|
||||
|
||||
ppp_clear(pcb);
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
|
||||
pcb->ethif = ethif;
|
||||
|
||||
pcb->link_status_cb = link_status_cb;
|
||||
@ -434,7 +439,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic
|
||||
ao->neg_pcompression = 0;
|
||||
ao->neg_accompression = 0;
|
||||
|
||||
if(pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) {
|
||||
if (pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) {
|
||||
return PPPERR_OPEN;
|
||||
}
|
||||
|
||||
@ -458,6 +463,9 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16
|
||||
if (link_status_cb == NULL)
|
||||
return PPPERR_PARAM;
|
||||
|
||||
ppp_clear(pcb);
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
|
||||
pcb->link_status_cb = link_status_cb;
|
||||
pcb->link_status_ctx = link_status_ctx;
|
||||
|
||||
@ -471,20 +479,22 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16
|
||||
ao->neg_pcompression = 0;
|
||||
ao->neg_accompression = 0;
|
||||
|
||||
if(pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) {
|
||||
if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) {
|
||||
return PPPERR_OPEN;
|
||||
}
|
||||
|
||||
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_NONE;
|
||||
}
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
/* Close a PPP connection and release the descriptor.
|
||||
/*
|
||||
* Initiate the end of a PPP connection.
|
||||
* Any outstanding packets in the queues are dropped.
|
||||
* Return 0 on success, an error code on failure. */
|
||||
* Return 0 on success, an error code on failure.
|
||||
*/
|
||||
int
|
||||
ppp_close(ppp_pcb *pcb)
|
||||
{
|
||||
@ -495,7 +505,7 @@ ppp_close(ppp_pcb *pcb)
|
||||
|
||||
/* Disconnect */
|
||||
#if PPPOE_SUPPORT
|
||||
if(pcb->ethif) {
|
||||
if (pcb->ethif) {
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num));
|
||||
pcb->err_code = PPPERR_USER;
|
||||
/* This will leave us at PHASE_DEAD. */
|
||||
@ -525,13 +535,46 @@ ppp_sighup(ppp_pcb *pcb)
|
||||
ppp_hup(pcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the control block.
|
||||
*
|
||||
* This can only be called if PPP is in the dead phase.
|
||||
*
|
||||
* You must use ppp_close() before if you wish to terminate
|
||||
* an established PPP session.
|
||||
*
|
||||
* Return 0 on success, an error code on failure.
|
||||
*/
|
||||
int ppp_delete(ppp_pcb *pcb) {
|
||||
if (pcb->phase != PHASE_DEAD) {
|
||||
return PPPERR_PARAM;
|
||||
}
|
||||
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_delete: unit %d\n", pcb->num));
|
||||
netif_remove(&pcb->netif);
|
||||
|
||||
#if PPPOE_SUPPORT
|
||||
if (pcb->ethif) {
|
||||
pppoe_destroy(&pcb->netif);
|
||||
}
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
#if PPPOL2TP_SUPPORT
|
||||
if (pcb->l2tp_pcb) {
|
||||
pppol2tp_destroy(pcb->l2tp_pcb);
|
||||
}
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
memp_free(MEMP_PPP_PCB, pcb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Initiate LCP open request */
|
||||
static void ppp_start(ppp_pcb *pcb) {
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num));
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
lcp_open(pcb); /* Start protocol */
|
||||
lcp_lowerup(pcb);
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n"));
|
||||
@ -1806,6 +1849,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
/* PPPoE link is established, starting PPP negotiation */
|
||||
case PPPOE_CB_STATE_UP:
|
||||
PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->num));
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
ppp_start(pcb);
|
||||
return;
|
||||
|
||||
@ -1827,9 +1871,6 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
lcp_options *wo = &pcb->lcp_wantoptions;
|
||||
lcp_options *ao = &pcb->lcp_allowoptions;
|
||||
|
||||
if(pcb->link_status_cb)
|
||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx);
|
||||
|
||||
ppp_clear(pcb);
|
||||
|
||||
wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */
|
||||
@ -1842,16 +1883,24 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
ao->neg_pcompression = 0;
|
||||
ao->neg_accompression = 0;
|
||||
|
||||
new_phase(pcb, PHASE_HOLDOFF);
|
||||
|
||||
/* Callback must be called after phase changed to holdoff. It prevents
|
||||
* the user to call ppp_delete() while we are going to reconnect.
|
||||
*/
|
||||
if (pcb->link_status_cb) {
|
||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx);
|
||||
}
|
||||
|
||||
pppoe_reconnect(pcb->pppoe_sc);
|
||||
return;
|
||||
}
|
||||
|
||||
ppp_hup(pcb);
|
||||
ppp_stop(pcb);
|
||||
pppoe_destroy(&pcb->netif);
|
||||
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);
|
||||
ppp_destroy(pcb);
|
||||
}
|
||||
}
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
@ -1864,6 +1913,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
/* PPPoL2TP link is established, starting PPP negotiation */
|
||||
case PPPOL2TP_CB_STATE_UP:
|
||||
PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: UP, connecting\n", pcb->num));
|
||||
new_phase(pcb, PHASE_INITIALIZE);
|
||||
ppp_start(pcb);
|
||||
return;
|
||||
|
||||
@ -1885,9 +1935,6 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
lcp_options *wo = &pcb->lcp_wantoptions;
|
||||
lcp_options *ao = &pcb->lcp_allowoptions;
|
||||
|
||||
if(pcb->link_status_cb)
|
||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx);
|
||||
|
||||
ppp_clear(pcb);
|
||||
|
||||
wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */
|
||||
@ -1900,16 +1947,24 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) {
|
||||
ao->neg_pcompression = 0;
|
||||
ao->neg_accompression = 0;
|
||||
|
||||
new_phase(pcb, PHASE_HOLDOFF);
|
||||
|
||||
/* Callback must be called after phase changed to holdoff. It prevents
|
||||
* the user to call ppp_delete() while we are going to reconnect.
|
||||
*/
|
||||
if (pcb->link_status_cb) {
|
||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx);
|
||||
}
|
||||
|
||||
pppol2tp_reconnect(pcb->l2tp_pcb);
|
||||
return;
|
||||
}
|
||||
|
||||
ppp_hup(pcb);
|
||||
ppp_stop(pcb);
|
||||
pppol2tp_destroy(pcb->l2tp_pcb);
|
||||
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);
|
||||
ppp_destroy(pcb);
|
||||
}
|
||||
}
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
@ -1944,19 +1999,11 @@ void ppp_link_terminated(ppp_pcb *pcb) {
|
||||
if (pcb->link_status_cb) {
|
||||
pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx);
|
||||
}
|
||||
ppp_destroy(pcb);
|
||||
#endif /* PPPOS_SUPPORT */
|
||||
}
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n"));
|
||||
}
|
||||
|
||||
static void ppp_destroy(ppp_pcb *pcb) {
|
||||
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp_destroy: unit %d\n", pcb->num));
|
||||
netif_remove(&pcb->netif);
|
||||
memp_free(MEMP_PPP_PCB, pcb);
|
||||
}
|
||||
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
/** Set the status callback of a PPP's netif
|
||||
*
|
||||
@ -1996,9 +2043,11 @@ ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback)
|
||||
* new_phase - signal the start of a new phase of pppd's operation.
|
||||
*/
|
||||
void new_phase(ppp_pcb *pcb, int p) {
|
||||
pcb->phase = p;
|
||||
pcb->phase = p;
|
||||
PPPDEBUG(LOG_DEBUG, ("ppp phase changed: unit %d: phase=%d\n", pcb->num, pcb->phase));
|
||||
printf("ppp phase changed: phase=%d\n", pcb->phase);
|
||||
#if PPP_NOTIFY
|
||||
/* The one willing notify support should add here the code to be notified of phase changes */
|
||||
/* The one willing notify support should add here the code to be notified of phase changes */
|
||||
#endif /* PPP_NOTIFY */
|
||||
}
|
||||
|
||||
@ -2179,9 +2228,9 @@ int sifup(ppp_pcb *pcb) {
|
||||
pcb->err_code = PPPERR_NONE;
|
||||
|
||||
PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code));
|
||||
if (pcb->link_status_cb)
|
||||
if (pcb->link_status_cb) {
|
||||
pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx);
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2199,9 +2248,6 @@ int sifdown(ppp_pcb *pcb) {
|
||||
/* make sure the netif status callback is called */
|
||||
netif_set_down(&pcb->netif);
|
||||
PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code));
|
||||
if (pcb->link_status_cb)
|
||||
pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -499,9 +499,9 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
/*
|
||||
* Close a PPP connection and release the control block.
|
||||
* Initiate the end of a PPP connection.
|
||||
* Any outstanding packets in the queues are dropped.
|
||||
* Return 0 on success, an error code on failure.
|
||||
* Return 0 on success, an error code on failure.
|
||||
*/
|
||||
int ppp_close(ppp_pcb *pcb);
|
||||
|
||||
@ -510,6 +510,18 @@ int ppp_close(ppp_pcb *pcb);
|
||||
*/
|
||||
void ppp_sighup(ppp_pcb *pcb);
|
||||
|
||||
/*
|
||||
* Release the control block.
|
||||
*
|
||||
* This can only be called if PPP is in the dead phase.
|
||||
*
|
||||
* You must use ppp_close() before if you wish to terminate
|
||||
* an established PPP session.
|
||||
*
|
||||
* Return 0 on success, an error code on failure.
|
||||
*/
|
||||
int ppp_delete(ppp_pcb *pcb);
|
||||
|
||||
/*
|
||||
* Get and set parameters for the given connection.
|
||||
* Return 0 on success, an error code on failure.
|
||||
|
@ -192,6 +192,8 @@ void pppol2tp_reconnect(pppol2tp_pcb *l2tp) {
|
||||
static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp) {
|
||||
err_t err;
|
||||
|
||||
/* FIXME: bind to a new source port so that we don't get packet from the previous session ? */
|
||||
|
||||
do {
|
||||
l2tp->remote_tunnel_id = magic();
|
||||
} while(l2tp->remote_tunnel_id == 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user