From 7af6c0ef6354288f8a8240e5ca44a55ab4c6cf91 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 15 Jun 2023 18:04:50 +0200
Subject: [PATCH]
https://github.com/c-ares/c-ares/commit/b9b8413cfdb70a3f99e1573333b23052d57ec1ae
---
ares_process.c | 41 ++++++++++++++++++++++++-----------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/ares_process.c b/ares_process.c
index bbeca5e..ad7e862 100644
--- a/ares_process.c
+++ b/ares_process.c
@@ -416,7 +416,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
{
struct server_state *server;
int i;
- ssize_t count;
+ ssize_t read_len;
unsigned char buf[MAXENDSSZ + 1];
#ifdef HAVE_RECVFROM
ares_socklen_t fromlen;
@@ -459,36 +459,43 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
/* To reduce event loop overhead, read and process as many
* packets as we can. */
do {
- if (server->udp_socket == ARES_SOCKET_BAD)
- count = 0;
-
- else {
+ if (server->udp_socket == ARES_SOCKET_BAD) {
+ read_len = -1;
+ } else {
#ifdef HAVE_RECVFROM
- if (server->addr.family == AF_INET)
+ if (server->addr.family == AF_INET) {
fromlen = sizeof(from.sa4);
- else
+ } else {
fromlen = sizeof(from.sa6);
- count = (ssize_t)recvfrom(server->udp_socket, (void *)buf,
- sizeof(buf), 0, &from.sa, &fromlen);
+ }
+ read_len = (ssize_t)recvfrom(server->udp_socket, (void *)buf,
+ sizeof(buf), 0, &from.sa, &fromlen);
#else
- count = sread(server->udp_socket, buf, sizeof(buf));
+ read_len = sread(server->udp_socket, buf, sizeof(buf));
#endif
}
- if (count == -1 && try_again(SOCKERRNO))
+ if (read_len == 0) {
+ /* UDP is connectionless, so result code of 0 is a 0-length UDP
+ * packet, and not an indication the connection is closed like on
+ * tcp */
continue;
- else if (count <= 0)
+ } else if (read_len < 0) {
+ if (try_again(SOCKERRNO))
+ continue;
+
handle_error(channel, i, now);
#ifdef HAVE_RECVFROM
- else if (!same_address(&from.sa, &server->addr))
+ } else if (!same_address(&from.sa, &server->addr)) {
/* The address the response comes from does not match the address we
* sent the request to. Someone may be attempting to perform a cache
* poisoning attack. */
- break;
+ continue;
#endif
- else
- process_answer(channel, buf, (int)count, i, 0, now);
- } while (count > 0);
+ } else {
+ process_answer(channel, buf, (int)read_len, i, 0, now);
+ }
+ } while (read_len >= 0);
}
}
--
2.38.1