diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2016-05-09 21:40:58 +0200 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-05-11 13:26:00 +0300 |
commit | 448d99b34e18c94cabe9c41e12fd678212acf103 (patch) | |
tree | f541f36c038e91565f0494bca7a89e76fc45719e /accel-pppd/iprange.c | |
parent | c6c1d7633f5c4ca3ac5f82caf0bffe811307e293 (diff) | |
download | accel-ppp-448d99b34e18c94cabe9c41e12fd678212acf103.tar.gz accel-ppp-448d99b34e18c94cabe9c41e12fd678212acf103.zip |
iprange: implement config reload
Protect conf_disable and client_ranges with a mutex.
Instead of directly setting conf_disable, load_ranges() now returns
a disable flag. The caller is in charge of propagating its value
in conf_disable.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/iprange.c')
-rw-r--r-- | accel-pppd/iprange.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/accel-pppd/iprange.c b/accel-pppd/iprange.c index 608574e3..6281a745 100644 --- a/accel-pppd/iprange.c +++ b/accel-pppd/iprange.c @@ -1,3 +1,4 @@ +#include <pthread.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> @@ -8,6 +9,7 @@ #include <netinet/in.h> #include "triton.h" +#include "events.h" #include "list.h" #include "log.h" #include "utils.h" @@ -23,8 +25,8 @@ struct iprange_t uint32_t end; }; -static int conf_disable = 0; - +static pthread_mutex_t iprange_lock = PTHREAD_MUTEX_INITIALIZER; +static bool conf_disable = false; static LIST_HEAD(client_ranges); /* Maximum IPv4 address length with CIDR notation but no extra 0, @@ -160,7 +162,7 @@ disable: return 0; } -static void load_ranges(struct list_head *list, const char *conf_sect) +static bool load_ranges(struct list_head *list, const char *conf_sect) { struct conf_sect_t *s = conf_get_section(conf_sect); struct conf_option_t *opt; @@ -168,7 +170,8 @@ static void load_ranges(struct list_head *list, const char *conf_sect) if (!s) { log_emerg("iprange: section '%s' not found in config file, pptp and l2tp probably will not work...\n", conf_sect); - return; + + return false; } list_for_each_entry(opt, &s->items, entry) { @@ -181,13 +184,14 @@ static void load_ranges(struct list_head *list, const char *conf_sect) if (!r) { log_warn("iprange: iprange module disabled, improper IP address assignment may cause kernel soft lockup!\n"); free_ranges(list); - conf_disable = 1; - return; + return true; } list_add_tail(&r->entry, list); } + + return false; } static int check_range(struct list_head *list, in_addr_t ipaddr) @@ -205,22 +209,56 @@ static int check_range(struct list_head *list, in_addr_t ipaddr) int __export iprange_client_check(in_addr_t ipaddr) { + int res; + + pthread_mutex_lock(&iprange_lock); if (conf_disable) - return 0; + res = 0; + else + res = check_range(&client_ranges, ipaddr); + pthread_mutex_unlock(&iprange_lock); - return check_range(&client_ranges, ipaddr); + return res; } + int __export iprange_tunnel_check(in_addr_t ipaddr) { + int res; + + pthread_mutex_lock(&iprange_lock); if (conf_disable) - return 0; + res = 0; + else + res = !check_range(&client_ranges, ipaddr); + pthread_mutex_unlock(&iprange_lock); + + return res; +} + +static void iprange_load_config(void *data) +{ + LIST_HEAD(new_ranges); + LIST_HEAD(old_ranges); + bool disable; + + disable = load_ranges(&new_ranges, "client-ip-range"); + + pthread_mutex_lock(&iprange_lock); + list_replace(&client_ranges, &old_ranges); + list_replace(&new_ranges, &client_ranges); + conf_disable = disable; + pthread_mutex_unlock(&iprange_lock); - return !check_range(&client_ranges, ipaddr); + free_ranges(&old_ranges); } static void iprange_init(void) { - load_ranges(&client_ranges, "client-ip-range"); + iprange_load_config(NULL); + if (triton_event_register_handler(EV_CONFIG_RELOAD, + iprange_load_config) < 0) + log_error("iprange: registration of CONFIG_RELOAD event failed," + " iprange will not be able to reload its configuration\n"); } DEFINE_INIT(10, iprange_init); |