X-Git-Url: https://git.decadent.org.uk/gitweb/?p=odhcp6c.git;a=blobdiff_plain;f=src%2Fdhcpv6.c;h=cd8e43800dca33315047cd000262a5697c985be5;hp=e44be4831fcaca3cfd8635a9f7d3d01ce1d54640;hb=3510cb4f1acb27e3ce40b85f557db4a29967f7c3;hpb=3d85fddacbbb0eebd33997382997af442b408b04 diff --git a/src/dhcpv6.c b/src/dhcpv6.c index e44be48..cd8e438 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -60,6 +60,7 @@ static void dhcpv6_handle_ia_status_code(const enum dhcpv6_msg orig, bool handled_status_codes[_DHCPV6_Status_Max], int *ret); static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand); +static void dhcpv6_clear_all_server_cand(void); static reply_handler dhcpv6_handle_reply; static reply_handler dhcpv6_handle_advert; @@ -941,8 +942,13 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc, } } } - else if (ret > 0) + else if (ret > 0) { + // All server candidates can be cleared if not yet bound + if (!odhcp6c_is_bound()) + dhcpv6_clear_all_server_cand(); + t1 = refresh; + } return ret; } @@ -1243,6 +1249,21 @@ static void dhcpv6_add_server_cand(const struct dhcpv6_server_cand *cand) odhcp6c_insert_state(STATE_SERVER_CAND, i * sizeof(*c), cand, sizeof(*cand)); } +static void dhcpv6_clear_all_server_cand(void) +{ + size_t cand_len, i; + struct dhcpv6_server_cand *c = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); + + // Server candidates need deep delete for IA_NA/IA_PD + for (i = 0; i < cand_len / sizeof(*c); ++i) { + if (c[i].ia_na) + free(c[i].ia_na); + if (c[i].ia_pd) + free(c[i].ia_pd); + } + odhcp6c_clear_state(STATE_SERVER_CAND); +} + int dhcpv6_promote_server_cand(void) { size_t cand_len; @@ -1255,7 +1276,7 @@ int dhcpv6_promote_server_cand(void) odhcp6c_clear_state(STATE_IA_NA); odhcp6c_clear_state(STATE_IA_PD); - if (!cand) + if (!cand_len) return -1; if (cand->has_noaddravail && na_mode == IA_MODE_TRY) { @@ -1285,18 +1306,3 @@ int dhcpv6_promote_server_cand(void) return ret; } - -void dhcpv6_clear_all_server_cand(void) -{ - size_t cand_len, i; - struct dhcpv6_server_cand *c = odhcp6c_get_state(STATE_SERVER_CAND, &cand_len); - - // Server candidates need deep delete for IA_NA/IA_PD - for (i = 0; i < cand_len / sizeof(*c); ++i) { - if (c[i].ia_na) - free(c[i].ia_na); - if (c[i].ia_pd) - free(c[i].ia_pd); - } - odhcp6c_clear_state(STATE_SERVER_CAND); -}