diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2013-01-24 16:14:18 +0100 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-01-25 00:04:53 +0400 |
commit | 459720a96d868e31b8ab859fdf488c1c208b2647 (patch) | |
tree | bfd574523f3027cd4bc4127189f1fd9a97717031 /accel-pppd | |
parent | a478611de8d0454389225d296a0c210d261a1b5b (diff) | |
download | accel-ppp-459720a96d868e31b8ab859fdf488c1c208b2647.tar.gz accel-ppp-459720a96d868e31b8ab859fdf488c1c208b2647.zip |
l2tp: Fix PPP session disconnection
When a PPP session terminates on its own (i.e. not on behalf of a L2TP
tunnel/session request), the l2tp_ppp_finished() callback calls the
L2TP session disconnection function without updating the session's
state.
Session disconnection code then works like if the PPP session was still
up: it tries to disconnect the PPP by calling ap_session_terminate().
But since the PPP is already terminated, it returns immediately,
without calling the l2tp_ppp_finished() callback; so session cleanup
won't happen.
This patch updates the session's state upon PPP disconnection, so that
the session disconnection code won't try to disconnect the PPP in
__l2tp_session_free().
The stat_active counter is now updated inside the l2tp_ppp_finished()
callback so that it gets called upon any PPP disconnection.
Sending of the EV_CTRL_FINISHED event has also been moved. It is now
performed in the generic part of __l2tp_session_free() because it has
to be done every time the session really terminates.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ctrl/l2tp/l2tp.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index f09aaedc..4292aca7 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -235,11 +235,9 @@ static void __l2tp_session_free(void *data) switch (sess->state1) { case STATE_PPP: - __sync_sub_and_fetch(&stat_active, 1); sess->state1 = STATE_CLOSE; ap_session_terminate(&sess->ppp.ses, TERM_USER_REQUEST, 1); - triton_event_fire(EV_CTRL_FINISHED, &sess->ppp.ses); /* No cleanup here, "sess" must remain a valid session pointer (even if it no l2tp_conn_t points to it anymore). This is because the above call to ap_session_terminate() @@ -252,10 +250,11 @@ static void __l2tp_session_free(void *data) case STATE_WAIT_ICCN: case STATE_ESTB: __sync_sub_and_fetch(&stat_starting, 1); - triton_event_fire(EV_CTRL_FINISHED, &sess->ppp.ses); break; } + triton_event_fire(EV_CTRL_FINISHED, &sess->ppp.ses); + log_ppp_info1("disconnected\n"); triton_context_unregister(&sess->sctx); @@ -408,7 +407,9 @@ static void l2tp_ppp_finished(struct ap_session *ses) struct l2tp_sess_t *sess = l2tp_session_self(); log_ppp_debug("l2tp: ppp finished\n"); + __sync_sub_and_fetch(&stat_active, 1); if (sess->state1 != STATE_CLOSE) { + sess->state1 = STATE_CLOSE; l2tp_send_CDN(sess, 2, 0); l2tp_session_free(sess); } else { |