]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/odhcp6c.c
Reverse SLAAC-only logic
[odhcp6c.git] / src / odhcp6c.c
index e4da1ab2767b36ef067e4cb314f413ff40f779c8..f7ae2fb917e73b8d3be1d3dd6d810386dd3440d3 100644 (file)
@@ -41,7 +41,7 @@ static size_t state_len[_STATE_MAX] = {0};
 
 static volatile int do_signal = 0;
 static int urandom_fd = -1;
-static bool bound = false;
+static bool bound = false, allow_slaac_only = true;
 
 
 int main(_unused int argc, char* const argv[])
@@ -59,8 +59,12 @@ int main(_unused int argc, char* const argv[])
 
        bool help = false, daemonize = false;
        int c, request_pd = 0;
-       while ((c = getopt(argc, argv, "N:P:c:r:s:hdp:")) != -1) {
+       while ((c = getopt(argc, argv, "SN:P:c:r:s:hdp:")) != -1) {
                switch (c) {
+               case 'S':
+                       allow_slaac_only = false;
+                       break;
+
                case 'N':
                        if (!strcmp(optarg, "force"))
                                ia_na_mode = IA_MODE_FORCE;
@@ -73,6 +77,7 @@ 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;
@@ -180,6 +185,7 @@ int main(_unused int argc, char* const argv[])
 
                do_signal = 0;
                int res = dhcpv6_request(DHCPV6_MSG_SOLICIT);
+               odhcp6c_signal_process();
 
                if (res < 0) {
                        continue; // Might happen if we got a signal
@@ -188,6 +194,7 @@ int main(_unused int argc, char* const argv[])
                                do_signal = 0;
 
                                res = dhcpv6_request(DHCPV6_MSG_INFO_REQ);
+                               odhcp6c_signal_process();
                                if (do_signal == SIGUSR1)
                                        continue;
                                else if (res < 0)
@@ -208,6 +215,7 @@ int main(_unused int argc, char* const argv[])
                if (dhcpv6_request(DHCPV6_MSG_REQUEST) < 0)
                        continue;
 
+               odhcp6c_signal_process();
                script_call("bound");
                bound = true;
 
@@ -215,6 +223,7 @@ int main(_unused int argc, char* const argv[])
                        // Renew Cycle
                        // Wait for T1 to expire or until we get a reconfigure
                        int res = dhcpv6_poll_reconfigure();
+                       odhcp6c_signal_process();
                        if (res >= 0) {
                                if (res > 0)
                                        script_call("updated");
@@ -238,6 +247,7 @@ int main(_unused int argc, char* const argv[])
                                r = dhcpv6_request(DHCPV6_MSG_REQUEST);
                        else
                                r = dhcpv6_request(DHCPV6_MSG_RENEW);
+                       odhcp6c_signal_process();
                        if (r > 0) // Publish updates
                                script_call("updated");
                        if (r >= 0)
@@ -247,6 +257,7 @@ int main(_unused int argc, char* const argv[])
 
                        // If we have IAs, try rebind otherwise restart
                        res = dhcpv6_request(DHCPV6_MSG_REBIND);
+                       odhcp6c_signal_process();
 
                        odhcp6c_get_state(STATE_IA_PD, &ia_pd_new);
                        odhcp6c_get_state(STATE_IA_NA, &ia_na_new);
@@ -284,6 +295,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"
        "       -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"
@@ -312,6 +324,8 @@ static uint8_t* odhcp6c_resize_state(enum odhcp6c_state state, ssize_t len)
 {
        if (len == 0)
                return state_data[state] + state_len[state];
+       else if (state_len[state] + len > 1024)
+               return NULL;
 
        uint8_t *n = realloc(state_data[state], state_len[state] + len);
        if (n || state_len[state] + len == 0) {
@@ -329,7 +343,7 @@ bool odhcp6c_signal_process(void)
                do_signal = 0;
                bool updated = ra_process();
                updated |= ra_rtnl_process();
-               if (updated && bound) {
+               if (updated && (bound || allow_slaac_only)) {
                        odhcp6c_expire();
                        script_call("ra-updated");
                }
@@ -386,7 +400,7 @@ struct odhcp6c_entry* odhcp6c_find_entry(enum odhcp6c_state state, const struct
 }
 
 
-void odhcp6c_update_entry_safe(enum odhcp6c_state state, const struct odhcp6c_entry *new, uint32_t safe)
+void odhcp6c_update_entry_safe(enum odhcp6c_state state, struct odhcp6c_entry *new, uint32_t safe)
 {
        size_t len;
        struct odhcp6c_entry *x = odhcp6c_find_entry(state, new);
@@ -396,17 +410,19 @@ void odhcp6c_update_entry_safe(enum odhcp6c_state state, const struct odhcp6c_en
                new->valid = safe;
 
        if (new->valid > 0) {
-               if (x)
-                       *x = *new;
-               else
+               if (x) {
+                       x->valid = new->valid;
+                       x->preferred = new->preferred;
+               } else {
                        odhcp6c_add_state(state, new, sizeof(*new));
+               }
        } else if (x) {
                odhcp6c_remove_state(state, (x - start) * sizeof(*x), sizeof(*x));
        }
 }
 
 
-void odhcp6c_update_entry(enum odhcp6c_state state, const struct odhcp6c_entry *new)
+void odhcp6c_update_entry(enum odhcp6c_state state, struct odhcp6c_entry *new)
 {
        odhcp6c_update_entry_safe(state, new, 0);
 }
@@ -443,6 +459,7 @@ void odhcp6c_expire(void)
 
        odhcp6c_expire_list(STATE_RA_PREFIX, elapsed);
        odhcp6c_expire_list(STATE_RA_ROUTE, elapsed);
+       odhcp6c_expire_list(STATE_RA_DNS, elapsed);
        odhcp6c_expire_list(STATE_IA_NA, elapsed);
        odhcp6c_expire_list(STATE_IA_PD, elapsed);
 }