mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix read_write() changes for TCP timeout.
I misread the man page for socket(7) and TCP timeouts. A timeout generates a -1 return and EAGAIN errno, NOT a short read. Short reads are legit, and aborting when they are seen creates hard-to-reproduce errors.
This commit is contained in:
19
src/util.c
19
src/util.c
@@ -770,7 +770,7 @@ int retry_send(ssize_t rc)
|
|||||||
rw = 2 -> write once
|
rw = 2 -> write once
|
||||||
rw = 3 -> read once
|
rw = 3 -> read once
|
||||||
|
|
||||||
"once" fail if all the data doesn't arrive/go in a single read/write.
|
"once" fails on EAGAIN, as this a timeout.
|
||||||
This indicates a timeout of a TCP socket.
|
This indicates a timeout of a TCP socket.
|
||||||
*/
|
*/
|
||||||
int read_write(int fd, unsigned char *packet, int size, int rw)
|
int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||||
@@ -779,7 +779,6 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
|||||||
|
|
||||||
for (done = 0; done < size; done += n)
|
for (done = 0; done < size; done += n)
|
||||||
{
|
{
|
||||||
do {
|
|
||||||
if (rw & 1)
|
if (rw & 1)
|
||||||
n = read(fd, &packet[done], (size_t)(size - done));
|
n = read(fd, &packet[done], (size_t)(size - done));
|
||||||
else
|
else
|
||||||
@@ -788,19 +787,25 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
|||||||
if (n == 0)
|
if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n == -1 && errno == EINTR)
|
if (n == -1)
|
||||||
|
{
|
||||||
|
n = 0; /* don't mess with counter when we loop. */
|
||||||
|
|
||||||
|
if (errno == EINTR || errno == ENOMEM || errno == ENOBUFS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
/* "once" variant */
|
/* "once" variant */
|
||||||
if ((rw & 2) && n != size)
|
if (rw & 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
} while (n == -1 && (errno == EINTR || errno == ENOMEM || errno == ENOBUFS ||
|
continue;
|
||||||
errno == EAGAIN || errno == EWOULDBLOCK));
|
}
|
||||||
|
|
||||||
if (n == -1)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user