From c291def1cadf58c0aa10c18a53c2fc4d2dee1ad6 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Wed, 5 Feb 2014 22:28:50 +0100 Subject: [PATCH] Fix T1, T2 and T3 timer values in case of infinite time values Honor T1, T2 and T3 timer values from DHCPv6 server in case of infinite values --- src/dhcpv6.c | 27 ++++++++++++++++----------- src/odhcp6c.c | 4 +++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index f18a3e9..4b1ba95 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -474,9 +474,9 @@ int dhcpv6_request(enum dhcpv6_msg type) if (type == DHCPV6_MSG_UNKNOWN) timeout = t1; else if (type == DHCPV6_MSG_RENEW) - timeout = (t2 > t1) ? t2 - t1 : 0; + timeout = (t2 > t1) ? t2 - t1 : ((t1 == UINT32_MAX) ? UINT32_MAX : 0); else if (type == DHCPV6_MSG_REBIND) - timeout = (t3 > t2) ? t3 - t2 : 0; + timeout = (t3 > t2) ? t3 - t2 : ((t2 == UINT32_MAX) ? UINT32_MAX : 0); if (timeout == 0) return -1; @@ -514,8 +514,8 @@ int dhcpv6_request(enum dhcpv6_msg type) uint64_t round_end = round_start + rto; elapsed = round_start - start; - // Don't wait too long - if (round_end - start > timeout * 1000) + // Don't wait too long if timeout differs from infinite + if ((timeout != UINT32_MAX) && (round_end - start > timeout * 1000)) round_end = timeout * 1000 + start; // Built and send package @@ -542,9 +542,9 @@ int dhcpv6_request(enum dhcpv6_msg type) // Set timeout for receiving uint64_t t = round_end - round_start; - struct timeval timeout = {t / 1000, (t % 1000) * 1000}; + struct timeval tv = {t / 1000, (t % 1000) * 1000}; setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, - &timeout, sizeof(timeout)); + &tv, sizeof(tv)); // Receive cycle len = recvmsg(sock, &msg, 0); @@ -589,8 +589,8 @@ int dhcpv6_request(enum dhcpv6_msg type) // Allow if (retx->handler_finish) len = retx->handler_finish(); - } while (len < 0 && ((elapsed / 1000 < timeout) && (!retx->max_rc || rc < retx->max_rc))); - + } while (len < 0 && ((timeout == UINT32_MAX) || (elapsed / 1000 < timeout)) && + (!retx->max_rc || rc < retx->max_rc)); return len; } @@ -861,9 +861,14 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc, uint32_t elapsed = (last_update > 0) ? now - last_update : 0; last_update = now; - t1 -= elapsed; - t2 -= elapsed; - t3 -= elapsed; + if (t1 != UINT32_MAX) + t1 -= elapsed; + + if (t2 != UINT32_MAX) + t2 -= elapsed; + + if (t3 != UINT32_MAX) + t3 -= elapsed; if (t1 < 0) t1 = 0; diff --git a/src/odhcp6c.c b/src/odhcp6c.c index dbe2bdf..3eb37a7 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -592,8 +592,10 @@ bool odhcp6c_update_entry_safe(enum odhcp6c_state state, struct odhcp6c_entry *n if (new->valid > 0) { if (x) { - if (new->valid >= x->valid && new->valid - x->valid < 60 && + if (new->valid >= x->valid && new->valid != UINT32_MAX && + new->valid - x->valid < 60 && new->preferred >= x->preferred && + new->preferred != UINT32_MAX && new->preferred - x->preferred < 60 && x->class == new->class) return false; -- 2.39.2