From: yasuoka Date: Wed, 24 Jun 2015 05:20:16 +0000 (+0000) Subject: Fix npppd to terminate all PPP sessions properly even in case the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=4781c8ec050ec4491a319bc00417cf128344adcc;p=openbsd Fix npppd to terminate all PPP sessions properly even in case the sending window for L2TP control is full when the control is terminating (by a L2TP keepalive failure or other reasons). In that case, if the L2TP peer didn't respond at all, npppd had kept some PPP sessions forever. --- diff --git a/usr.sbin/npppd/l2tp/l2tp.h b/usr.sbin/npppd/l2tp/l2tp.h index 86698f4af40..c7ecc9409cf 100644 --- a/usr.sbin/npppd/l2tp/l2tp.h +++ b/usr.sbin/npppd/l2tp/l2tp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp.h,v 1.10 2014/03/22 04:32:39 yasuoka Exp $ */ +/* $OpenBSD: l2tp.h,v 1.11 2015/06/24 05:20:16 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -30,7 +30,7 @@ /*@file * header file for the L2TP module */ -/* $Id: l2tp.h,v 1.10 2014/03/22 04:32:39 yasuoka Exp $ */ +/* $Id: l2tp.h,v 1.11 2015/06/24 05:20:16 yasuoka Exp $ */ /************************************************************************ * Protocol Constants @@ -444,6 +444,7 @@ l2tp_call *l2tp_call_create (void); int l2tp_call_init (l2tp_call *, l2tp_ctrl *); void l2tp_call_destroy (l2tp_call *, int); void l2tp_call_admin_disconnect(l2tp_call *); +void l2tp_call_drop (l2tp_call *); int l2tp_call_recv_packet (l2tp_ctrl *, l2tp_call *, int, u_char *, int); void l2tp_call_ppp_input (l2tp_call *, u_char *, int, int); diff --git a/usr.sbin/npppd/l2tp/l2tp_call.c b/usr.sbin/npppd/l2tp/l2tp_call.c index 4d18d226d34..d1c2358bc18 100644 --- a/usr.sbin/npppd/l2tp/l2tp_call.c +++ b/usr.sbin/npppd/l2tp/l2tp_call.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp_call.c,v 1.16 2015/01/19 01:48:59 deraadt Exp $ */ +/* $OpenBSD: l2tp_call.c,v 1.17 2015/06/24 05:20:16 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Id: l2tp_call.c,v 1.16 2015/01/19 01:48:59 deraadt Exp $ */ +/* $Id: l2tp_call.c,v 1.17 2015/06/24 05:20:16 yasuoka Exp $ */ /**@file L2TP LNS call */ #include #include @@ -125,6 +125,12 @@ l2tp_call_admin_disconnect(l2tp_call *_this) NULL, NULL, 0); } +void +l2tp_call_drop(l2tp_call *_this) +{ + l2tp_call_disconnect(_this, 0, 0, NULL, NULL, 0); +} + /* * disconnect l2tp connection * @param result_code disconect without CDN, specify zero diff --git a/usr.sbin/npppd/l2tp/l2tp_ctrl.c b/usr.sbin/npppd/l2tp/l2tp_ctrl.c index 5b652eaaab4..aa32afcd0c1 100644 --- a/usr.sbin/npppd/l2tp/l2tp_ctrl.c +++ b/usr.sbin/npppd/l2tp/l2tp_ctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2tp_ctrl.c,v 1.19 2015/01/19 01:48:59 deraadt Exp $ */ +/* $OpenBSD: l2tp_ctrl.c,v 1.20 2015/06/24 05:20:16 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -26,7 +26,7 @@ * SUCH DAMAGE. */ /**@file Control connection processing functions for L2TP LNS */ -/* $Id: l2tp_ctrl.c,v 1.19 2015/01/19 01:48:59 deraadt Exp $ */ +/* $Id: l2tp_ctrl.c,v 1.20 2015/06/24 05:20:16 yasuoka Exp $ */ #include #include #include @@ -76,7 +76,7 @@ static void l2tp_ctrl_purge_ipsec_sa (l2tp_ctrl *); static void l2tp_ctrl_timeout (int, short, void *); static int l2tp_ctrl_resend_una_packets (l2tp_ctrl *); static void l2tp_ctrl_destroy_all_calls (l2tp_ctrl *); -static int l2tp_ctrl_disconnect_all_calls (l2tp_ctrl *); +static int l2tp_ctrl_disconnect_all_calls (l2tp_ctrl *, int); static void l2tp_ctrl_reset_timeout (l2tp_ctrl *); static inline int l2tp_ctrl_txwin_size (l2tp_ctrl *); static inline int l2tp_ctrl_txwin_is_full (l2tp_ctrl *); @@ -258,14 +258,14 @@ l2tp_ctrl_send_disconnect_notify(l2tp_ctrl *_this) /* Send CDN all Calls */ ncalls = 0; if (slist_length(&_this->call_list) != 0) { - ncalls = l2tp_ctrl_disconnect_all_calls(_this); + ncalls = l2tp_ctrl_disconnect_all_calls(_this, 0); if (ncalls > 0) { /* * Call the function again to check whether the * sending window is fulled. In case ncalls == 0, * it means we've sent CDN for all calls. */ - ncalls = l2tp_ctrl_disconnect_all_calls(_this); + ncalls = l2tp_ctrl_disconnect_all_calls(_this, 0); } } if (ncalls > 0) @@ -320,7 +320,7 @@ l2tp_ctrl_stop(l2tp_ctrl *_this, int result) case L2TP_CTRL_STATE_CLEANUP_WAIT: cleanup: if (slist_length(&_this->call_list) != 0) { - if (l2tp_ctrl_disconnect_all_calls(_this) > 0) + if (l2tp_ctrl_disconnect_all_calls(_this, 1) > 0) break; } #if 0 @@ -650,7 +650,7 @@ l2tp_ctrl_destroy_all_calls(l2tp_ctrl *_this) * @return return # of calls that is not waiting cleanup. */ static int -l2tp_ctrl_disconnect_all_calls(l2tp_ctrl *_this) +l2tp_ctrl_disconnect_all_calls(l2tp_ctrl *_this, int drop) { int i, len, ncalls; l2tp_call *call; @@ -663,12 +663,12 @@ l2tp_ctrl_disconnect_all_calls(l2tp_ctrl *_this) call = slist_get(&_this->call_list, i); if (call->state != L2TP_CALL_STATE_CLEANUP_WAIT) { ncalls++; - if (l2tp_ctrl_txwin_is_full(_this)) { L2TP_CTRL_DBG((_this, LOG_INFO, "Too many calls. Sending window is not " "enough to send CDN to all clients.")); - /* nothing to do */ + if (drop) + l2tp_call_drop(call); } else l2tp_call_admin_disconnect(call); }