summaryrefslogtreecommitdiffstats
path: root/usr.sbin/npppd
diff options
context:
space:
mode:
authorgoda <goda@openbsd.org>2017-08-12 11:20:34 +0000
committergoda <goda@openbsd.org>2017-08-12 11:20:34 +0000
commit2a5607d281589e868270802a7213176366ed63ab (patch)
tree8258cbbffc500ee36ef794749fb286c35a5ea580 /usr.sbin/npppd
parentIn iwn(4), fix CID 1199266 "Missing comma in a string array"; only affects (diff)
downloadwireguard-openbsd-2a5607d281589e868270802a7213176366ed63ab.tar.xz
wireguard-openbsd-2a5607d281589e868270802a7213176366ed63ab.zip
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.c121
-rw-r--r--usr.sbin/npppd/npppd/npppd.conf.511
-rw-r--r--usr.sbin/npppd/npppd/npppd.h11
-rw-r--r--usr.sbin/npppd/npppd/npppd_local.h4
-rw-r--r--usr.sbin/npppd/npppd/parse.y5
-rw-r--r--usr.sbin/npppd/npppd/ppp.h6
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 */