Fix more problems with DHCP timers
- Number of retries could overflow. If we retry something more than 255 times and it fails, just stop, instead of flooding the network with bogus requests - The timeout could also overflow. It was stored in microseconds in a time_t, which allows a bit more than an hour. This is fine for the initial timeout (which starts at a few seconds and will go up to 64 seconds), but after that we switch to a slower rate driven by the "state time". In particular, this can be the lease time, which DHCP servers may set to several days, or at least easily more than an hour. - The computaiton of the timeout in the "slow lease" case attempted to do "not less than a minute", but missed a conversion from microseconds to seconds so it ended up doing "not less than 60 microseconds" The combination of all these things means we can end up with a negative timeout, and we will send a burst of requests without ever stopping, flooding the network. Change-Id: I0eb811c90f4a4dd8c9d92bff728bc2bbb52fbd56 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4826 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
50a4c18678
commit
a8b90daa8a
@@ -163,7 +163,7 @@ struct socket_timeout {
|
|||||||
UpdateSocket(socket);
|
UpdateSocket(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t timeout; // in micro secs
|
bigtime_t timeout; // in micro secs
|
||||||
uint8 tries;
|
uint8 tries;
|
||||||
|
|
||||||
bool Shift(int socket, bigtime_t stateMaxTime, const char* device);
|
bool Shift(int socket, bigtime_t stateMaxTime, const char* device);
|
||||||
@@ -448,17 +448,22 @@ socket_timeout::UpdateSocket(int socket) const
|
|||||||
bool
|
bool
|
||||||
socket_timeout::Shift(int socket, bigtime_t stateMaxTime, const char* device)
|
socket_timeout::Shift(int socket, bigtime_t stateMaxTime, const char* device)
|
||||||
{
|
{
|
||||||
|
if (tries == UINT8_MAX)
|
||||||
|
return false;
|
||||||
|
|
||||||
tries++;
|
tries++;
|
||||||
timeout += timeout;
|
|
||||||
if (timeout > AS_USECS(MAX_TIMEOUT))
|
|
||||||
timeout = AS_USECS(MAX_TIMEOUT);
|
|
||||||
|
|
||||||
if (tries > MAX_RETRIES) {
|
if (tries > MAX_RETRIES) {
|
||||||
if (stateMaxTime == -1)
|
bigtime_t now = system_time();
|
||||||
|
if (stateMaxTime == -1 || stateMaxTime < now)
|
||||||
return false;
|
return false;
|
||||||
bigtime_t remaining = (stateMaxTime - system_time()) / 2 + 1;
|
bigtime_t remaining = (stateMaxTime - now) / 2 + 1;
|
||||||
timeout = std::max(remaining, bigtime_t(60));
|
timeout = std::max(remaining, bigtime_t(AS_USECS(60)));
|
||||||
}
|
} else
|
||||||
|
timeout += timeout;
|
||||||
|
|
||||||
|
if (timeout > AS_USECS(MAX_TIMEOUT))
|
||||||
|
timeout = AS_USECS(MAX_TIMEOUT);
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "%s: Timeout shift: %" B_PRIdTIME " msecs (try %" B_PRIu8 ")\n",
|
syslog(LOG_DEBUG, "%s: Timeout shift: %" B_PRIdTIME " msecs (try %" B_PRIu8 ")\n",
|
||||||
device, timeout / 1000, tries);
|
device, timeout / 1000, tries);
|
||||||
|
|||||||
Reference in New Issue
Block a user