diff options
author | Kazuya Goda <goda@cvs.openbsd.org> | 2017-08-12 11:20:35 +0000 |
---|---|---|
committer | Kazuya Goda <goda@cvs.openbsd.org> | 2017-08-12 11:20:35 +0000 |
commit | a02d7aa0c1d30c13f6b9b9736d6a9462d8ac2c31 (patch) | |
tree | d38fb7e4d9d28e723fa77ff3dc4ef805176cb990 /usr.sbin/npppd | |
parent | b6e551b4a39f587e9d2878ec9b2bc251d1d1a2c0 (diff) |
add a new option to set limits on max-sessions each IPCP.
It can set limits on different max-sessions if there're using several protocols
such as PPPoE and L2TP/IPsec.
ok yasuoka@
Diffstat (limited to 'usr.sbin/npppd')
-rw-r--r-- | usr.sbin/npppd/npppd/npppd.c | 121 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd.conf.5 | 11 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd.h | 11 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/npppd_local.h | 4 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/parse.y | 5 | ||||
-rw-r--r-- | usr.sbin/npppd/npppd/ppp.h | 6 |
6 files changed, 148 insertions, 10 deletions
diff --git a/usr.sbin/npppd/npppd/npppd.c b/usr.sbin/npppd/npppd/npppd.c index 9f463886918..7f474030869 100644 --- a/usr.sbin/npppd/npppd/npppd.c +++ b/usr.sbin/npppd/npppd/npppd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd.c,v 1.46 2017/08/11 16:41:47 goda Exp $ */ +/* $OpenBSD: npppd.c,v 1.47 2017/08/12 11:20:34 goda Exp $ */ /*- * Copyright (c) 2005-2008,2009 Internet Initiative Japan Inc. @@ -29,7 +29,7 @@ * Next pppd(nppd). This file provides a npppd daemon process and operations * for npppd instance. * @author Yasuoka Masahiko - * $Id: npppd.c,v 1.46 2017/08/11 16:41:47 goda Exp $ + * $Id: npppd.c,v 1.47 2017/08/12 11:20:34 goda Exp $ */ #include "version.h" #include <sys/param.h> /* ALIGNED_POINTER */ @@ -105,6 +105,10 @@ static int rd2slist_walk (struct radish *, void *); static int rd2slist (struct radish_head *, slist *); static slist *npppd_get_ppp_by_user (npppd *, const char *); static int npppd_get_all_users (npppd *, slist *); +static struct ipcpstat + *npppd_get_ipcp_stat(struct ipcpstat_head *, const char *); +static void npppd_destroy_ipcp_stats(struct ipcpstat_head *); +static void npppd_ipcp_stats_reload(npppd *); #ifndef NO_ROUTE_FOR_POOLED_ADDRESS static struct in_addr loop; /* initialize at npppd_init() */ @@ -239,6 +243,8 @@ npppd_init(npppd *_this, const char *config_file) const char *pidpath0; FILE *pidfp = NULL; struct tunnconf *tunn; + struct ipcpconf *ipcpconf; + struct ipcpstat *ipcpstat; int mib[] = { CTL_NET, PF_PIPEX, PIPEXCTL_ENABLE }; size_t size; @@ -286,6 +292,8 @@ npppd_init(npppd *_this, const char *config_file) if (pppoed_init(&_this->pppoed) != 0) return (-1); #endif + LIST_INIT(&_this->ipcpstats); + /* load configuration */ if ((status = npppd_reload_config(_this)) != 0) return status; @@ -313,6 +321,18 @@ npppd_init(npppd *_this, const char *config_file) return -1; } + TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry) { + ipcpstat = malloc(sizeof(*ipcpstat)); + if (ipcpstat == NULL) { + log_printf(LOG_ERR, "initializing ipcp_stats failed : %m"); + npppd_destroy_ipcp_stats(&_this->ipcpstats); + return -1; + } + memset(ipcpstat, 0, sizeof(*ipcpstat)); + strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpstat->name)); + LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry); + } + pidpath0 = DEFAULT_NPPPD_PIDFILE; /* initialize event(3) */ @@ -489,6 +509,8 @@ npppd_fini(npppd *_this) npppd_pool_uninit(&_this->pool[i]); } + npppd_destroy_ipcp_stats(&_this->ipcpstats); + signal_del(&_this->ev_sigterm); signal_del(&_this->ev_sigint); signal_del(&_this->ev_sighup); @@ -791,6 +813,68 @@ npppd_get_ppp_by_id(npppd *_this, u_int ppp_id) return ppp; } +static struct ipcpstat * +npppd_get_ipcp_stat(struct ipcpstat_head *head , const char *ipcp_name) +{ + struct ipcpstat *ipcpstat = NULL; + + LIST_FOREACH(ipcpstat, head, entry) { + if (strncmp(ipcpstat->name, ipcp_name, + sizeof(ipcpstat->name)) == 0) + return ipcpstat; + } + + return NULL; +} + +static void +npppd_destroy_ipcp_stats(struct ipcpstat_head *head) +{ + struct ipcpstat *ipcpstat, *tipcpstat; + npppd_ppp *ppp, *tppp; + + LIST_FOREACH_SAFE(ipcpstat, head, entry, tipcpstat) { + LIST_FOREACH_SAFE(ppp, &ipcpstat->ppp, ipcpstat_entry, tppp) { + ppp->ipcpstat = NULL; + LIST_REMOVE(ppp, ipcpstat_entry); + } + free(ipcpstat); + } +} + +static void +npppd_ipcp_stats_reload(npppd *_this) +{ + struct ipcpstat *ipcpstat, *tipcpstat; + struct ipcpconf *ipcpconf; + struct ipcpstat_head destroy_list; + + LIST_INIT(&destroy_list); + LIST_FOREACH_SAFE(ipcpstat, &_this->ipcpstats, entry, tipcpstat) { + LIST_REMOVE(ipcpstat, entry); + LIST_INSERT_HEAD(&destroy_list, ipcpstat, entry); + } + + TAILQ_FOREACH(ipcpconf, &_this->conf.ipcpconfs, entry) { + ipcpstat = npppd_get_ipcp_stat(&destroy_list, ipcpconf->name); + if (ipcpstat != NULL) { + LIST_REMOVE(ipcpstat, entry); + LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry); + continue; + } + + ipcpstat = malloc(sizeof(*ipcpstat)); + if (ipcpstat == NULL) { + log_printf(LOG_ERR, "initializing ipcp_stats failed : %m"); + continue; + } + memset(ipcpstat, 0, sizeof(*ipcpstat)); + strlcpy(ipcpstat->name, ipcpconf->name, sizeof(ipcpconf->name)); + LIST_INSERT_HEAD(&_this->ipcpstats, ipcpstat, entry); + } + npppd_destroy_ipcp_stats(&destroy_list); +} + /** * Checks whether the user reaches the maximum session limit * (user_max_serssion). @@ -1864,6 +1948,7 @@ npppd_reload0(npppd *_this) npppd_ifaces_load_config(_this); npppd_update_pool_reference(_this); npppd_auth_finalizer_periodic(_this); + npppd_ipcp_stats_reload(_this); for (i = 0; i < countof(_this->iface); i++) { if (_this->iface[i].initialized != 0 && @@ -2117,6 +2202,7 @@ npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp) { int i, ifidx; struct confbind *bind; + struct ipcpstat *ipcpstat; NPPPD_ASSERT(_this != NULL); NPPPD_ASSERT(ppp != NULL); @@ -2148,16 +2234,38 @@ npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp) if (ifidx < 0) return 1; + ppp->ifidx = ifidx; + NPPPD_ASSERT(ppp_ipcp(ppp) != NULL); + ipcpstat = npppd_get_ipcp_stat(&_this->ipcpstats, ppp_ipcp(ppp)->name); + if (ipcpstat == NULL) { + ppp_log(ppp, LOG_WARNING, "Unknown IPCP %s", + ppp_ipcp(ppp)->name); + ppp->ifidx = -1; /* unbind inteface */ + return 1; + } + if (ppp_ipcp(ppp)->max_session > 0 && + ipcpstat->nsession >= ppp_ipcp(ppp)->max_session) { + ppp_log(ppp, LOG_WARNING, + "Number of sessions per IPCP reaches out of the limit=%d", + ppp_ipcp(ppp)->max_session); + ppp->ifidx = -1; /* unbind inteface */ + return 1; + } + if (_this->conf.max_session > 0 && _this->nsession >= _this->conf.max_session) { ppp_log(ppp, LOG_WARNING, "Number of sessions reaches out of the limit=%d", _this->conf.max_session); + ppp->ifidx = -1; /* unbind inteface */ return 1; } - ppp->ifidx = ifidx; _this->nsession++; + LIST_INSERT_HEAD(&ipcpstat->ppp, ppp, ipcpstat_entry); + ppp->ipcpstat = ipcpstat; + ipcpstat->nsession++; + return 0; } @@ -2165,8 +2273,13 @@ npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp) void npppd_ppp_unbind_iface(npppd *_this, npppd_ppp *ppp) { - if (ppp->ifidx >= 0) + if (ppp->ifidx >= 0) { _this->nsession--; + if (ppp->ipcpstat!= NULL) { + ppp->ipcpstat->nsession--; + LIST_REMOVE(ppp, ipcpstat_entry); + } + } ppp->ifidx = -1; } diff --git a/usr.sbin/npppd/npppd/npppd.conf.5 b/usr.sbin/npppd/npppd/npppd.conf.5 index 3347c573a4a..6d9dbad6860 100644 --- a/usr.sbin/npppd/npppd/npppd.conf.5 +++ b/usr.sbin/npppd/npppd/npppd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: npppd.conf.5,v 1.20 2017/08/11 16:41:47 goda Exp $ +.\" $OpenBSD: npppd.conf.5,v 1.21 2017/08/12 11:20:34 goda Exp $ .\" .\" Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 11 2017 $ +.Dd $Mdocdate: August 12 2017 $ .Dt NPPPD.CONF 5 .Os .Sh NAME @@ -506,6 +506,13 @@ Specify whether is allowed to assign an address selected by the user. The default is .Dq yes . +.It Ic max-session Ar number +Specify the maximum number of sessions for this +.Ic ipcp +setting. +.Sq 0 +means no limit. +The default value is 0. .El .Sh INTERFACE The diff --git a/usr.sbin/npppd/npppd/npppd.h b/usr.sbin/npppd/npppd/npppd.h index a1dd27a0133..3fc4e96771c 100644 --- a/usr.sbin/npppd/npppd/npppd.h +++ b/usr.sbin/npppd/npppd/npppd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd.h,v 1.18 2017/08/11 16:41:47 goda Exp $ */ +/* $OpenBSD: npppd.h,v 1.19 2017/08/12 11:20:34 goda Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -179,6 +179,7 @@ struct ipcpconf { bool allow_user_select; struct in_addr_range *dynamic_pool; struct in_addr_range *static_pool; + int max_session; }; struct iface { @@ -227,6 +228,14 @@ struct sockaddr_npppd { #define SNP_DYN_POOL 2 #define SNP_PPP 3 +struct ipcpstat { + LIST_ENTRY(ipcpstat) entry; + char name[NPPPD_GENERIC_NAME_LEN]; + int nsession; + LIST_HEAD(, _npppd_ppp) ppp; +}; +LIST_HEAD(ipcpstat_head, ipcpstat); + typedef struct _npppd npppd; #include "ppp.h" diff --git a/usr.sbin/npppd/npppd/npppd_local.h b/usr.sbin/npppd/npppd/npppd_local.h index fe20aa6a62d..06331759e31 100644 --- a/usr.sbin/npppd/npppd/npppd_local.h +++ b/usr.sbin/npppd/npppd/npppd_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: npppd_local.h,v 1.16 2016/03/08 01:38:04 yasuoka Exp $ */ +/* $OpenBSD: npppd_local.h,v 1.17 2017/08/12 11:20:34 goda Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -165,6 +165,8 @@ struct _npppd { int nsession; + struct ipcpstat_head ipcpstats; + struct control_sock ctl_sock; u_int /** whether finalizing or not */ diff --git a/usr.sbin/npppd/npppd/parse.y b/usr.sbin/npppd/npppd/parse.y index 6b4c1291396..2872c71f3b0 100644 --- a/usr.sbin/npppd/npppd/parse.y +++ b/usr.sbin/npppd/npppd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.18 2017/08/11 16:41:47 goda Exp $ */ +/* $OpenBSD: parse.y,v 1.19 2017/08/12 11:20:34 goda Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -839,6 +839,9 @@ ipcpopt : POOL_ADDRESS STRING ipcppooltype { | ALLOW_USER_SELECTED_ADDRESS yesno { curr_ipcpconf->allow_user_select = $2; } + | MAX_SESSION NUMBER { + curr_ipcpconf->max_session = $2; + } ; ipcppooltype : /* empty */ { $$ = 0; } diff --git a/usr.sbin/npppd/npppd/ppp.h b/usr.sbin/npppd/npppd/ppp.h index 7afa96d6aee..1bb8bfc6cf3 100644 --- a/usr.sbin/npppd/npppd/ppp.h +++ b/usr.sbin/npppd/npppd/ppp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ppp.h,v 1.20 2017/05/30 17:22:00 yasuoka Exp $ */ +/* $OpenBSD: ppp.h,v 1.21 2017/08/12 11:20:34 goda Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -601,6 +601,10 @@ struct _npppd_ppp { int8_t disconnect_direction; /** disconnect message */ const char *disconnect_message; + + /** back pointer to ipcpsstats */ + struct ipcpstat *ipcpstat; + LIST_ENTRY(_npppd_ppp) ipcpstat_entry; }; /** proxied dialin */ |