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;
}
}
}
- 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;
}
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;
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) {
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);
-}
int dhcpv6_request(enum dhcpv6_msg type);
int dhcpv6_poll_reconfigure(void);
int dhcpv6_promote_server_cand(void);
-void dhcpv6_clear_all_server_cand(void);
int init_rtnetlink(void);
int set_rtnetlink_addr(int ifindex, const struct in6_addr *addr,