]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: fix use of ERRNO_IS_DISCONNECT()
authorDmitry V. Levin <ldv@strace.io>
Fri, 7 Jul 2023 08:00:00 +0000 (08:00 +0000)
committerDmitry V. Levin <ldv@strace.io>
Sun, 16 Jul 2023 10:53:30 +0000 (10:53 +0000)
Given that ERRNO_IS_DISCONNECT() also matches positive values,
make sure this macro is not called with arguments that do not have
errno semantics.

In this case the argument passed to ERRNO_IS_DISCONNECT() is the value
returned by manager_recv() which can legitimately return 1 without errno
semantics, so fix this by moving ERRNO_IS_DISCONNECT() invocation to the
branch where the return value is known to be negative.

src/resolve/resolved-dns-transaction.c

index a5293357c01b67a88f05529b58a57f409ba2f7ef..323786896bbc138d5d88caa83f8e049565f542d1 100644 (file)
@@ -1367,25 +1367,22 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use
         assert(t->scope);
 
         r = manager_recv(t->scope->manager, fd, DNS_PROTOCOL_DNS, &p);
-        if (ERRNO_IS_DISCONNECT(r)) {
-                usec_t usec;
-
-                /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
-                 * next recvmsg(). Treat this like a lost packet. */
+        if (r < 0) {
+                if (ERRNO_IS_DISCONNECT(r)) {
+                        usec_t usec;
 
-                log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
-                assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &usec) >= 0);
-                dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level);
+                        /* UDP connection failures get reported via ICMP and then are possibly delivered to us on the
+                         * next recvmsg(). Treat this like a lost packet. */
 
-                dns_transaction_close_connection(t, /* use_graveyard = */ false);
+                        log_debug_errno(r, "Connection failure for DNS UDP packet: %m");
+                        assert_se(sd_event_now(t->scope->manager->event, CLOCK_BOOTTIME, &usec) >= 0);
+                        dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level);
 
-                if (dns_transaction_limited_retry(t)) /* Try a different server */
-                        return 0;
+                        dns_transaction_close_connection(t, /* use_graveyard = */ false);
 
-                dns_transaction_complete_errno(t, r);
-                return 0;
-        }
-        if (r < 0) {
+                        if (dns_transaction_limited_retry(t)) /* Try a different server */
+                                return 0;
+                }
                 dns_transaction_complete_errno(t, r);
                 return 0;
         }