diff options
author | Steven Barth <steven@midlink.org> | 2013-05-05 15:56:42 +0200 |
---|---|---|
committer | Steven Barth <steven@midlink.org> | 2013-05-05 15:56:42 +0200 |
commit | d09e94fff82440cedf04f2e0cfe1ede8a0ab0600 (patch) | |
tree | 123348f359cb9af02bf6c1d76c3bfbca2b2d4562 /src | |
parent | 2515dbce13746bb1633cfa4b8e22424946a7f007 (diff) | |
download | odhcp6c-d09e94fff82440cedf04f2e0cfe1ede8a0ab0600.tar.gz |
Set a global default DHCPv6 exchange timeout
This delays SLAAC-updates before any DHCPv6-binding is established.
Diffstat (limited to 'src')
-rw-r--r-- | src/odhcp6c.c | 23 | ||||
-rw-r--r-- | src/odhcp6c.h | 1 | ||||
-rw-r--r-- | src/script.c | 23 |
3 files changed, 35 insertions, 12 deletions
diff --git a/src/odhcp6c.c b/src/odhcp6c.c index a97e4c9..6ce9adf 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -40,8 +40,8 @@ static uint8_t *state_data[_STATE_MAX] = {NULL}; static size_t state_len[_STATE_MAX] = {0}; static volatile int do_signal = 0; -static int urandom_fd = -1; -static bool bound = false, allow_slaac_only = true, release = true; +static int urandom_fd = -1, allow_slaac_only = 15; +static bool bound = false, release = true; int main(_unused int argc, char* const argv[]) @@ -58,10 +58,10 @@ int main(_unused int argc, char* const argv[]) bool help = false, daemonize = false; int logopt = LOG_PID; int c, request_pd = 0; - while ((c = getopt(argc, argv, "SN:P:c:r:s:khedp:")) != -1) { + while ((c = getopt(argc, argv, "S::N:P:c:r:s:khedp:")) != -1) { switch (c) { case 'S': - allow_slaac_only = false; + allow_slaac_only = (optarg) ? atoi(optarg) : -1; break; case 'N': @@ -76,7 +76,6 @@ int main(_unused int argc, char* const argv[]) break; case 'P': - allow_slaac_only = false; request_pd = strtoul(optarg, NULL, 10); if (request_pd == 0) request_pd = -1; @@ -307,7 +306,7 @@ static int usage(void) const char buf[] = "Usage: odhcp6c [options] <interface>\n" "\nFeature options:\n" - " -S Don't allow SLAAC-only (implied by -P)\n" + " -S <time> Wait at least <time> sec for a DHCP-server (15)\n" " -N <mode> Mode for requesting addresses [try|force|none]\n" " -P <length> Request IPv6-Prefix (0 = auto)\n" " -c <clientid> Override client-ID (base-16 encoded)\n" @@ -355,12 +354,12 @@ bool odhcp6c_signal_process(void) { if (do_signal == SIGIO) { do_signal = 0; - bool updated = ra_process(); - updated |= ra_rtnl_process(); - if (updated && (bound || allow_slaac_only)) { - odhcp6c_expire(); - script_call("ra-updated"); - } + bool ra_updated = ra_process(); + + if (ra_rtnl_process() || (ra_updated && (bound || allow_slaac_only == 0))) + script_call("ra-updated"); // Immediate process urgent events + else if (ra_updated && !bound && allow_slaac_only > 0) + script_delay_call("ra-updated", allow_slaac_only); } return do_signal != 0; diff --git a/src/odhcp6c.h b/src/odhcp6c.h index fd3b07a..cfd1a53 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -224,6 +224,7 @@ int set_rtnetlink_addr(int ifindex, const struct in6_addr *addr, int script_init(const char *path, const char *ifname); ssize_t script_unhexlify(uint8_t *dst, size_t len, const char *src); void script_call(const char *status); +void script_delay_call(const char *status, int timeout); bool odhcp6c_signal_process(void); uint64_t odhcp6c_get_milli_time(void); diff --git a/src/script.c b/src/script.c index ffb39f3..a56d9b4 100644 --- a/src/script.c +++ b/src/script.c @@ -17,6 +17,7 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <signal.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> @@ -38,6 +39,7 @@ static const int8_t hexvals[] = { static char *argv[4] = {NULL, NULL, NULL, NULL}; +static volatile char *delayed_call = NULL; int script_init(const char *path, const char *ifname) @@ -176,11 +178,32 @@ static void entry_to_env(const char *name, const void *data, size_t len, enum en } +static void script_call_delayed(int signal __attribute__((unused))) +{ + if (delayed_call) + script_call((char*)delayed_call); +} + + +void script_delay_call(const char *status, int timeout) +{ + if (!delayed_call) { + delayed_call = strdup(status); + signal(SIGALRM, script_call_delayed); + alarm(timeout); + } +} + + void script_call(const char *status) { size_t dns_len, search_len, custom_len, sntp_ip_len, sntp_dns_len; size_t sip_ip_len, sip_fqdn_len; + odhcp6c_expire(); + if (delayed_call) + alarm(0); + struct in6_addr *dns = odhcp6c_get_state(STATE_DNS, &dns_len); uint8_t *search = odhcp6c_get_state(STATE_SEARCH, &search_len); uint8_t *custom = odhcp6c_get_state(STATE_CUSTOM_OPTS, &custom_len); |