mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Avoid hanngs in DHCP ping code when system time goes backwards.
This commit is contained in:
@@ -1755,14 +1755,22 @@ int icmp_ping(struct in_addr addr)
|
|||||||
better not use any resources our caller has in use...)
|
better not use any resources our caller has in use...)
|
||||||
but we remain deaf to signals or further DHCP packets. */
|
but we remain deaf to signals or further DHCP packets. */
|
||||||
|
|
||||||
int fd;
|
/* There can be a problem using dnsmasq_time() to end the loop, since
|
||||||
|
it's not monotonic, and can go backwards if the system clock is
|
||||||
|
tweaked, leading to the code getting stuck in this loop and
|
||||||
|
ignoring DHCP requests. To fix this, we check to see if select returned
|
||||||
|
as a result of a timeout rather than a socket becoming available. We
|
||||||
|
only allow this to happen as many times as it takes to get to the wait time
|
||||||
|
in quarter-second chunks. This provides a fallback way to end loop. */
|
||||||
|
|
||||||
|
int fd, rc;
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
struct {
|
struct {
|
||||||
struct ip ip;
|
struct ip ip;
|
||||||
struct icmp icmp;
|
struct icmp icmp;
|
||||||
} packet;
|
} packet;
|
||||||
unsigned short id = rand16();
|
unsigned short id = rand16();
|
||||||
unsigned int i, j;
|
unsigned int i, j, timeout_count;
|
||||||
int gotreply = 0;
|
int gotreply = 0;
|
||||||
time_t start, now;
|
time_t start, now;
|
||||||
|
|
||||||
@@ -1794,8 +1802,8 @@ int icmp_ping(struct in_addr addr)
|
|||||||
while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
|
while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
|
||||||
(struct sockaddr *)&saddr, sizeof(saddr))));
|
(struct sockaddr *)&saddr, sizeof(saddr))));
|
||||||
|
|
||||||
for (now = start = dnsmasq_time();
|
for (now = start = dnsmasq_time(), timeout_count = 0;
|
||||||
difftime(now, start) < (float)PING_WAIT;)
|
(difftime(now, start) < (float)PING_WAIT) && (timeout_count < PING_WAIT * 4);)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set rset, wset;
|
fd_set rset, wset;
|
||||||
@@ -1820,11 +1828,15 @@ int icmp_ping(struct in_addr addr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
|
rc = select(maxfd+1, &rset, &wset, NULL, &tv);
|
||||||
|
|
||||||
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
FD_ZERO(&rset);
|
FD_ZERO(&rset);
|
||||||
FD_ZERO(&wset);
|
FD_ZERO(&wset);
|
||||||
}
|
}
|
||||||
|
else if (rc == 0)
|
||||||
|
timeout_count++;
|
||||||
|
|
||||||
now = dnsmasq_time();
|
now = dnsmasq_time();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user