diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2012-09-07 12:36:26 +0200 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2012-09-07 14:53:21 +0400 |
commit | 795346e2bb5d4f3dea29719d9677c1c0c2031987 (patch) | |
tree | 929fbdafbfd3d59854ec357e7bec645f0c70be78 /accel-pppd/ctrl | |
parent | ea617abeca51963810b727513a14d3a69756819e (diff) | |
download | accel-ppp-xebd-795346e2bb5d4f3dea29719d9677c1c0c2031987.tar.gz accel-ppp-xebd-795346e2bb5d4f3dea29719d9677c1c0c2031987.zip |
L2TP: Use different connection timers for tunnels and sessions
Deactivate the tunnel connection establishment timer upon
reception of SCCCN messages and use a new session specific
timer for session establishment.
This new session timer follows the same behaviour as the
tunnel timeout timer: it is activated when sending the ICRP
message and deactivated upon reception of the corresponding
ICCN message.
This approach is necessary for handling several sessions per
tunnel, but it generates the following side effect: if a
tunnel is created but no session establishment is requested
from the LAC, the tunnel will no longer be automatically torn
down (since the tunnel is correctly set up, its timer is no
longer running, but since no session establishment process
has been started, there is no session timer neither).
Later on, tunnel and session timers could be turned into
inactivity timeouts to address this limitation.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r-- | accel-pppd/ctrl/l2tp/l2tp.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index 2d55691..33f08dc 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -76,6 +76,7 @@ struct l2tp_sess_t int state1; int state2; + struct triton_timer_t timeout_timer; struct ap_ctrl ctrl; struct ppp_t ppp; }; @@ -194,6 +195,9 @@ static void l2tp_session_free(struct l2tp_sess_t *sess) if (sess->ppp.ses.chan_name) _free(sess->ppp.ses.chan_name); + if (sess->timeout_timer.tpd) + triton_timer_del(&sess->timeout_timer); + _free(sess->ctrl.calling_station_id); _free(sess->ctrl.called_station_id); @@ -294,6 +298,18 @@ static void l2tp_ppp_finished(struct ap_session *ses) l2tp_ppp_session_disconnect, sess); } +static void l2tp_session_timeout(struct triton_timer_t *t) +{ + struct l2tp_sess_t *sess = container_of(t, typeof(*sess), + timeout_timer); + log_ppp_debug("l2tp: session timeout\n"); + l2tp_session_free(sess); + + /* Disconnect the tunnel when all sessions have been closed */ + l2tp_tunnel_disconnect(sess->paren_conn, 1, 0); + sess->paren_conn->state = STATE_FIN; +} + static struct l2tp_sess_t *l2tp_session_alloc(struct l2tp_conn_t *conn) { struct l2tp_sess_t *sess = &conn->sess; @@ -322,6 +338,8 @@ static struct l2tp_sess_t *l2tp_session_alloc(struct l2tp_conn_t *conn) sess->ctrl.calling_station_id); u_inet_ntoa(conn->lns_addr.sin_addr.s_addr, sess->ctrl.called_station_id); + sess->timeout_timer.expire = l2tp_session_timeout; + sess->timeout_timer.period = conf_timeout * 1000; ppp_init(&sess->ppp); sess->ppp.ses.ctrl = &sess->ctrl; @@ -731,11 +749,11 @@ static int l2tp_send_ICRP(struct l2tp_sess_t *sess) l2tp_send(sess->paren_conn, pack, 0); - if (!sess->paren_conn->timeout_timer.tpd) + if (!sess->timeout_timer.tpd) triton_timer_add(&sess->paren_conn->ctx, - &sess->paren_conn->timeout_timer, 0); + &sess->timeout_timer, 0); else - triton_timer_mod(&sess->paren_conn->timeout_timer, 0); + triton_timer_mod(&sess->timeout_timer, 0); sess->state1 = STATE_WAIT_ICCN; @@ -873,7 +891,7 @@ static int l2tp_recv_SCCRQ(struct l2tp_serv_t *serv, struct l2tp_packet_t *pack, static int l2tp_recv_SCCCN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) { if (conn->state == STATE_WAIT_SCCCN) { - triton_timer_mod(&conn->timeout_timer, 0); + triton_timer_del(&conn->timeout_timer); if (l2tp_tunnel_connect(conn) < 0) { l2tp_tunnel_disconnect(conn, 2, 0); return -1; @@ -978,7 +996,7 @@ static int l2tp_recv_ICCN(struct l2tp_sess_t *sess, struct l2tp_packet_t *pack) if (l2tp_send_ZLB(sess->paren_conn)) return -1; - triton_timer_del(&sess->paren_conn->timeout_timer); + triton_timer_del(&sess->timeout_timer); return 0; } |