X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=src%2Fdhcpv6.c;h=cfa5a407f1408f2d6d03a452121fac9e16ee66c3;hb=98045e630ab1c728e48a6cb8bcacbcd7e09dd085;hp=6a38e8536f5a9232b261ca71fea2b543db95dab8;hpb=a30b75599548b302a2fb829ff18073d9167ba895;p=odhcp6c.git diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 6a38e85..cfa5a40 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -60,7 +60,7 @@ static int dhcpv6_commit_advert(void); static struct dhcpv6_retx dhcpv6_retx[_DHCPV6_MSG_MAX] = { [DHCPV6_MSG_UNKNOWN] = {false, 1, 120, "", dhcpv6_handle_reconfigure, NULL}, - [DHCPV6_MSG_SOLICIT] = {true, 1, 7200, "SOLICIT", + [DHCPV6_MSG_SOLICIT] = {true, 1, 3600, "SOLICIT", dhcpv6_handle_advert, dhcpv6_commit_advert}, [DHCPV6_MSG_REQUEST] = {true, 30, 10, "REQUEST", dhcpv6_handle_reply, NULL}, @@ -136,12 +136,15 @@ int init_dhcpv6(const char *ifname, int request_pd) } // Create ORO - uint16_t oro[] = {htons(DHCPV6_OPT_DNS_SERVERS), + uint16_t oro[] = { + htons(DHCPV6_OPT_SIP_SERVER_D), + htons(DHCPV6_OPT_SIP_SERVER_A), + htons(DHCPV6_OPT_DNS_SERVERS), htons(DHCPV6_OPT_DNS_DOMAIN), htons(DHCPV6_OPT_NTP_SERVER), - htons(DHCPV6_OPT_SIP_SERVER_A), - htons(DHCPV6_OPT_SIP_SERVER_D), - htons(DHCPV6_OPT_PD_EXCLUDE)}; + htons(DHCPV6_OPT_AFTR_NAME), + htons(DHCPV6_OPT_PD_EXCLUDE), + }; odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); @@ -306,7 +309,7 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) {&oro_refresh, 0}, {cl_id, cl_id_len}, {srv_id, srv_id_len}, - {&reconf_accept, 0}, + {&reconf_accept, sizeof(reconf_accept)}, {&fqdn, fqdn_len}, {&hdr_ia_na, sizeof(hdr_ia_na)}, {ia_na, ia_na_len}, @@ -324,9 +327,8 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) } // Disable IAs if not used - if (type == DHCPV6_MSG_SOLICIT) { - iov[5].iov_len = sizeof(reconf_accept); - } else if (type != DHCPV6_MSG_REQUEST) { + if (type != DHCPV6_MSG_REQUEST && type != DHCPV6_MSG_SOLICIT) { + iov[5].iov_len = 0; if (ia_na_len == 0) iov[7].iov_len = 0; if (ia_pd_len == 0) @@ -381,8 +383,9 @@ int dhcpv6_request(enum dhcpv6_msg type) uint64_t start = odhcp6c_get_milli_time(), round_start = start, elapsed; // Generate transaction ID - uint8_t trid[3]; - odhcp6c_random(trid, sizeof(trid)); + uint8_t trid[3] = {0, 0, 0}; + if (type != DHCPV6_MSG_UNKNOWN) + odhcp6c_random(trid, sizeof(trid)); ssize_t len = -1; int64_t rto = 0; @@ -584,7 +587,7 @@ static int dhcpv6_handle_advert(_unused enum dhcpv6_msg orig, } else if (otype == DHCPV6_OPT_RECONF_ACCEPT) { cand.wants_reconfigure = true; } else if (otype == DHCPV6_OPT_IA_PD && request_prefix) { - struct dhcpv6_ia_hdr *h = (void*)odata; + 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) @@ -663,13 +666,15 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, uint8_t *odata; uint16_t otype, olen; - static time_t last_update = 0; - time_t now = odhcp6c_get_milli_time() / 1000; - - uint32_t elapsed = now - last_update; odhcp6c_expire(); if (orig == DHCPV6_MSG_UNKNOWN) { + static time_t last_update = 0; + time_t now = odhcp6c_get_milli_time() / 1000; + + uint32_t elapsed = (last_update > 0) ? now - last_update : 0; + last_update = now; + t1 -= elapsed; t2 -= elapsed; t3 -= elapsed; @@ -693,6 +698,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, odhcp6c_clear_state(STATE_SNTP_FQDN); odhcp6c_clear_state(STATE_SIP_IP); odhcp6c_clear_state(STATE_SIP_FQDN); + odhcp6c_clear_state(STATE_AFTR_NAME); } // Parse and find all matching IAs @@ -778,6 +784,11 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, if (r->protocol == 3 && r->algorithm == 1 && r->reconf_type == 1) memcpy(reconf_key, r->key, sizeof(r->key)); + } else if (otype == DHCPV6_OPT_AFTR_NAME && olen > 3) { + size_t cur_len; + odhcp6c_get_state(STATE_AFTR_NAME, &cur_len); + if (cur_len == 0) + odhcp6c_add_state(STATE_AFTR_NAME, odata, olen); } else if (otype != DHCPV6_OPT_CLIENTID && otype != DHCPV6_OPT_SERVERID) { odhcp6c_add_state(STATE_CUSTOM_OPTS,