diff options
-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; } |