mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Finesse TCP timeouts for upstream connections.
Timeouts for TCP connections to non-responive servers are very long. This in not appropriate for DNS connections. Set timeouts for connection setup, sending data and recieving data. The timeouts for connection setup and sending data are set at 5 seconds. For recieving the reply this is doubled, to take into account the time for usptream to actually get the answer. Thanks to Petr Menšík for pointing out this problem, and finding a better and more portable solution than the one in place heretofore.
This commit is contained in:
28
src/util.c
28
src/util.c
@@ -46,8 +46,8 @@ void rand_init()
|
||||
int fd = open(RANDFILE, O_RDONLY);
|
||||
|
||||
if (fd == -1 ||
|
||||
!read_write(fd, (unsigned char *)&seed, sizeof(seed), 1) ||
|
||||
!read_write(fd, (unsigned char *)&in, sizeof(in), 1))
|
||||
!read_write(fd, (unsigned char *)&seed, sizeof(seed), RW_READ) ||
|
||||
!read_write(fd, (unsigned char *)&in, sizeof(in), RW_READ))
|
||||
die(_("failed to seed the random number generator: %s"), NULL, EC_MISC);
|
||||
|
||||
close(fd);
|
||||
@@ -765,6 +765,14 @@ int retry_send(ssize_t rc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rw = 0 -> write
|
||||
rw = 1 -> read
|
||||
rw = 2 -> read once
|
||||
rw = 3 -> write once
|
||||
|
||||
"once" fail if all the data doesn't arrive/go in a single read/write.
|
||||
This indicates a timeout of a TCP socket.
|
||||
*/
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||
{
|
||||
ssize_t n, done;
|
||||
@@ -772,17 +780,25 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||
for (done = 0; done < size; done += n)
|
||||
{
|
||||
do {
|
||||
if (rw)
|
||||
if (rw & 1)
|
||||
n = read(fd, &packet[done], (size_t)(size - done));
|
||||
else
|
||||
n = write(fd, &packet[done], (size_t)(size - done));
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
} while (retry_send(n) || errno == ENOMEM || errno == ENOBUFS);
|
||||
|
||||
if (errno != 0)
|
||||
if (n == -1 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
/* "once" variant */
|
||||
if ((rw & 2) && n != size)
|
||||
return 0;
|
||||
|
||||
} while (n == -1 && (errno == EINTR || errno == ENOMEM || errno == ENOBUFS ||
|
||||
errno == EAGAIN || errno == EWOULDBLOCK));
|
||||
|
||||
if (n == -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user