summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2013-01-24 16:14:18 +0100
committerKozlov Dmitry <xeb@mail.ru>2013-01-25 00:04:53 +0400
commit459720a96d868e31b8ab859fdf488c1c208b2647 (patch)
treebfd574523f3027cd4bc4127189f1fd9a97717031 /accel-pppd
parenta478611de8d0454389225d296a0c210d261a1b5b (diff)
downloadaccel-ppp-xebd-459720a96d868e31b8ab859fdf488c1c208b2647.tar.gz
accel-ppp-xebd-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.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index f09aaed..4292aca 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 {