diff options
author | Vladislav Grishenko <themiron@mail.ru> | 2015-04-25 20:52:57 +0500 |
---|---|---|
committer | Vladislav Grishenko <themiron@mail.ru> | 2015-04-25 21:00:46 +0500 |
commit | 0f72844fc537413df8595ad07ad6ce2b86989521 (patch) | |
tree | 4f7dd2663d5268dab06885fab3d0f9c247afb529 /src | |
parent | b5f6ace7148fda6bf336758d2544a23a90d845bf (diff) | |
download | odhcp6c-0f72844fc537413df8595ad07ad6ce2b86989521.tar.gz |
Avoid of waiting for Advertise in stateless-only mode
Start with Information-request when configured not to ask
IA_NA/IA_PD. It allows to complete the exchange using only
two messages, instead of four, and fixes infinite Advertise
waiting loop with servers that just ignore Solicit messages.
Diffstat (limited to 'src')
-rw-r--r-- | src/dhcpv6.c | 24 | ||||
-rw-r--r-- | src/odhcp6c.c | 5 | ||||
-rw-r--r-- | src/odhcp6c.h | 2 |
3 files changed, 23 insertions, 8 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c index bc403b9..425aee1 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -216,10 +216,19 @@ enum { IOV_TOTAL }; -void dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd) +int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd) { + int mode = DHCPV6_UNKNOWN; + na_mode = na; pd_mode = pd; + + if (na_mode == IA_MODE_NONE && pd_mode == IA_MODE_NONE) + mode = DHCPV6_STATELESS; + else if (na_mode == IA_MODE_FORCE || pd_mode == IA_MODE_FORCE) + mode = DHCPV6_STATEFUL; + + return mode; } static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) @@ -547,10 +556,15 @@ int dhcpv6_request(enum dhcpv6_msg type) round_end = timeout * 1000 + start; // Built and send package - if (type != DHCPV6_MSG_UNKNOWN) { - if (type != DHCPV6_MSG_SOLICIT) - syslog(LOG_NOTICE, "Send %s message (elapsed %llums, rc %d)", - retx->name, (unsigned long long)elapsed, rc); + switch (type) { + case DHCPV6_MSG_UNKNOWN: + break; + default: + syslog(LOG_NOTICE, "Send %s message (elapsed %llums, rc %d)", + retx->name, (unsigned long long)elapsed, rc); + // Fall through + case DHCPV6_MSG_SOLICIT: + case DHCPV6_MSG_INFO_REQ: dhcpv6_send(type, trid, elapsed / 10); rc++; } diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 4605792..a71218c 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -278,13 +278,14 @@ int main(_unused int argc, char* const argv[]) odhcp6c_clear_state(STATE_NTP_FQDN); odhcp6c_clear_state(STATE_SIP_IP); odhcp6c_clear_state(STATE_SIP_FQDN); - dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode); bound = false; syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname); signal_usr1 = signal_usr2 = false; - int mode = dhcpv6_request(DHCPV6_MSG_SOLICIT); + int mode = dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode); + if (mode != DHCPV6_STATELESS) + mode = dhcpv6_request(DHCPV6_MSG_SOLICIT); odhcp6c_signal_process(); if (mode < 0) diff --git a/src/odhcp6c.h b/src/odhcp6c.h index fb572d0..c9a7398 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -308,7 +308,7 @@ struct odhcp6c_request_prefix { }; int init_dhcpv6(const char *ifname, unsigned int client_options, int sol_timeout); -void dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd); +int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd); int dhcpv6_request(enum dhcpv6_msg type); int dhcpv6_poll_reconfigure(void); int dhcpv6_promote_server_cand(void); |