]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/dhcpv6.c
Prefer servers with bigger prefixes
[odhcp6c.git] / src / dhcpv6.c
index 0285923a0190dd56d1e783067f3c005c22d18cdf..e9e6aafe0c260394081e067191477dbb5eddacdf 100644 (file)
@@ -62,7 +62,7 @@ static struct dhcpv6_retx dhcpv6_retx[_DHCPV6_MSG_MAX] = {
                        dhcpv6_handle_reconfigure, NULL},
        [DHCPV6_MSG_SOLICIT] = {true, 1, 3600, "SOLICIT",
                        dhcpv6_handle_advert, dhcpv6_commit_advert},
-       [DHCPV6_MSG_REQUEST] = {true, 30, 10, "REQUEST",
+       [DHCPV6_MSG_REQUEST] = {true, 1, 30, "REQUEST",
                        dhcpv6_handle_reply, NULL},
        [DHCPV6_MSG_RENEW] = {false, 10, 600, "RENEW",
                        dhcpv6_handle_reply, NULL},
@@ -369,7 +369,9 @@ int dhcpv6_request(enum dhcpv6_msg type)
                nanosleep(&ts, NULL);
        }
 
-       if (type == DHCPV6_MSG_RELEASE || type == DHCPV6_MSG_DECLINE)
+       if (type == DHCPV6_MSG_REQUEST)
+               timeout = 60;
+       else if (type == DHCPV6_MSG_RELEASE || type == DHCPV6_MSG_DECLINE)
                timeout = 3;
        else if (type == DHCPV6_MSG_UNKNOWN)
                timeout = t1;
@@ -568,7 +570,8 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig,
        uint16_t olen, otype;
        uint8_t *odata;
        struct dhcpv6_server_cand cand = {false, false, 0, 0, {0}, NULL, NULL, 0, 0};
-       bool have_na = false, have_pd = false;
+       bool have_na = false;
+       int have_pd = 0;
 
        dhcpv6_for_each_option(opt, end, otype, olen, odata) {
                if (orig == DHCPV6_MSG_SOLICIT &&
@@ -592,9 +595,13 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig,
                } else if (otype == DHCPV6_OPT_IA_PD && request_prefix) {
                        struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4];
                        uint8_t *oend = odata + olen, *d;
-                       dhcpv6_for_each_option(&h[1], oend, otype, olen, d)
-                               if (otype == DHCPV6_OPT_IA_PREFIX)
-                                       have_pd = true;
+                       dhcpv6_for_each_option(&h[1], oend, otype, olen, d) {
+                               if (otype == DHCPV6_OPT_IA_PREFIX && (olen + 4) >=
+                                               (uint16_t)sizeof(struct dhcpv6_ia_prefix)) {
+                                       struct dhcpv6_ia_prefix *p = (struct dhcpv6_ia_prefix*)&odata[-4];
+                                       have_pd = p->prefix;
+                               }
+                       }
                } else if (otype == DHCPV6_OPT_IA_NA) {
                        struct dhcpv6_ia_hdr *h = (struct dhcpv6_ia_hdr*)&odata[-4];
                        uint8_t *oend = odata + olen, *d;
@@ -615,7 +622,7 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig,
 
        if (pd_mode != IA_MODE_NONE) {
                if (have_pd)
-                       cand.preference += 2000;
+                       cand.preference += 2000 + (128 - have_pd);
                else
                        cand.preference -= 2000;
        }