]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libsystemd-network: ignore -ENETDOWN or friends in recv()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 8 Dec 2021 19:30:54 +0000 (04:30 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 9 Dec 2021 08:10:51 +0000 (09:10 +0100)
And this makes most errors in io events ignored.

src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-ipv4acd.c
src/libsystemd-network/sd-lldp-rx.c
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/sd-radv.c

index 14cbde133f85004b7c3c675773fa08483681b7bc..16574d28c7e7eee689d10eb556e12aa15af7d5de 100644 (file)
@@ -1930,13 +1930,13 @@ static int client_receive_message_udp(
         assert(client);
 
         buflen = next_datagram_size_fd(fd);
-        if (buflen == -ENETDOWN)
-                /* the link is down. Don't return an error or the I/O event
-                   source will be disconnected and we won't be able to receive
-                   packets again when the link comes back. */
+        if (buflen < 0) {
+                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
+                        return 0;
+
+                log_dhcp_client_errno(client, buflen, "Failed to determine datagram size to read, ignoring: %m");
                 return 0;
-        if (buflen < 0)
-                return buflen;
+        }
 
         message = malloc0(buflen);
         if (!message)
@@ -1944,12 +1944,11 @@ static int client_receive_message_udp(
 
         len = recv(fd, message, buflen, 0);
         if (len < 0) {
-                /* see comment above for why we shouldn't error out on ENETDOWN. */
-                if (ERRNO_IS_TRANSIENT(errno) || errno == ENETDOWN)
+                if (ERRNO_IS_TRANSIENT(errno) || ERRNO_IS_DISCONNECT(errno))
                         return 0;
 
-                return log_dhcp_client_errno(client, errno,
-                                             "Could not receive message from UDP socket: %m");
+                log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket, ignoring: %m");
+                return 0;
         }
         if ((size_t) len < sizeof(DHCPMessage)) {
                 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
@@ -1995,7 +1994,8 @@ static int client_receive_message_udp(
                 return 0;
         }
 
-        return client_handle_message(client, message, len);
+        (void) client_handle_message(client, message, len);
+        return 0;
 }
 
 static int client_receive_message_raw(
@@ -2023,10 +2023,13 @@ static int client_receive_message_raw(
         assert(client);
 
         buflen = next_datagram_size_fd(fd);
-        if (buflen == -ENETDOWN)
+        if (buflen < 0) {
+                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
+                        return 0;
+
+                log_dhcp_client_errno(client, buflen, "Failed to determine datagram size to read, ignoring: %m");
                 return 0;
-        if (buflen < 0)
-                return buflen;
+        }
 
         packet = malloc0(buflen);
         if (!packet)
@@ -2036,10 +2039,11 @@ static int client_receive_message_raw(
 
         len = recvmsg_safe(fd, &msg, 0);
         if (len < 0) {
-                if (ERRNO_IS_TRANSIENT(len) || len == -ENETDOWN)
+                if (ERRNO_IS_TRANSIENT(len) || ERRNO_IS_DISCONNECT(len))
                         return 0;
-                return log_dhcp_client_errno(client, len,
-                                             "Could not receive message from raw socket: %m");
+
+                log_dhcp_client_errno(client, len, "Could not receive message from raw socket, ignoring: %m");
+                return 0;
         }
         if ((size_t) len < sizeof(DHCPPacket))
                 return 0;
@@ -2056,7 +2060,8 @@ static int client_receive_message_raw(
 
         len -= DHCP_IP_UDP_SIZE;
 
-        return client_handle_message(client, &packet->dhcp, len);
+        (void) client_handle_message(client, &packet->dhcp, len);
+        return 0;
 }
 
 int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
index f535e316f907063a7a5e2eeca4cb056a59538bd7..ea98060ea2026e6bb0ba17589a2193e8c9ece67e 100644 (file)
@@ -1191,8 +1191,13 @@ static int server_receive_message(sd_event_source *s, int fd,
         assert(server);
 
         datagram_size = next_datagram_size_fd(fd);
-        if (datagram_size < 0)
-                return datagram_size;
+        if (datagram_size < 0) {
+                if (ERRNO_IS_TRANSIENT(datagram_size) || ERRNO_IS_DISCONNECT(datagram_size))
+                        return 0;
+
+                log_dhcp_server_errno(server, datagram_size, "Failed to determine datagram size to read, ignoring: %m");
+                return 0;
+        }
 
         size_t buflen = datagram_size;
         if (sd_dhcp_server_is_in_relay_mode(server))
@@ -1207,9 +1212,11 @@ static int server_receive_message(sd_event_source *s, int fd,
 
         len = recvmsg_safe(fd, &msg, 0);
         if (len < 0) {
-                if (ERRNO_IS_TRANSIENT(len))
+                if (ERRNO_IS_TRANSIENT(len) || ERRNO_IS_DISCONNECT(len))
                         return 0;
-                return len;
+
+                log_dhcp_server_errno(server, len, "Could not receive message, ignoring: %m");
+                return 0;
         }
 
         if ((size_t) len < sizeof(DHCPMessage))
@@ -1233,11 +1240,11 @@ static int server_receive_message(sd_event_source *s, int fd,
         if (sd_dhcp_server_is_in_relay_mode(server)) {
                 r = dhcp_server_relay_message(server, message, len - sizeof(DHCPMessage), buflen);
                 if (r < 0)
-                        log_dhcp_server_errno(server, r, "Couldn't relay message: %m");
+                        log_dhcp_server_errno(server, r, "Couldn't relay message, ignoring: %m");
         } else {
                 r = dhcp_server_handle_message(server, message, (size_t) len);
                 if (r < 0)
-                        log_dhcp_server_errno(server, r, "Couldn't process incoming message: %m");
+                        log_dhcp_server_errno(server, r, "Couldn't process incoming message, ignoring: %m");
         }
         return 0;
 }
index 29c8f78a8f92b6cf98ba5d34696fcdb5dde4be64..d3c667974dccef8be4f59fe383fae45534d3a030 100644 (file)
@@ -1463,12 +1463,13 @@ static int client_receive_message(
         assert(client->event);
 
         buflen = next_datagram_size_fd(fd);
-        if (buflen == -ENETDOWN)
-                /* the link is down. Don't return an error or the I/O event source will be disconnected
-                 * and we won't be able to receive packets again when the link comes back. */
+        if (buflen < 0) {
+                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
+                        return 0;
+
+                log_dhcp6_client_errno(client, buflen, "Failed to determine datagram size to read, ignoring: %m");
                 return 0;
-        if (buflen < 0)
-                return buflen;
+        }
 
         message = malloc(buflen);
         if (!message)
@@ -1478,12 +1479,11 @@ static int client_receive_message(
 
         len = recvmsg_safe(fd, &msg, MSG_DONTWAIT);
         if (len < 0) {
-                /* see comment above for why we shouldn't error out on ENETDOWN. */
-                if (ERRNO_IS_TRANSIENT(len) || len == -ENETDOWN)
+                if (ERRNO_IS_TRANSIENT(len) || ERRNO_IS_DISCONNECT(len))
                         return 0;
 
-                return log_dhcp6_client_errno(client, len, "Could not receive message from UDP socket: %m");
-
+                log_dhcp6_client_errno(client, len, "Could not receive message from UDP socket, ignoring: %m");
+                return 0;
         }
         if ((size_t) len < sizeof(DHCP6Message)) {
                 log_dhcp6_client(client, "Too small to be DHCP6 message: ignoring");
index 9b35d2c48eac5054758a1457dc9443828b03e83f..232b3b03335eb6354a8af1ce7f68f3205e76e6ca 100644 (file)
@@ -362,7 +362,7 @@ static int ipv4acd_on_packet(
 
         n = recv(fd, &packet, sizeof(struct ether_arp), 0);
         if (n < 0) {
-                if (ERRNO_IS_TRANSIENT(errno))
+                if (ERRNO_IS_TRANSIENT(errno) || ERRNO_IS_DISCONNECT(errno))
                         return 0;
 
                 log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m");
index 4caed52a9884e6914c8087bcac52fba62be07cb0..34bdcb644bdc931c7055b1934c3e69d56d72dc66 100644 (file)
@@ -200,6 +200,9 @@ static int lldp_rx_receive_datagram(sd_event_source *s, int fd, uint32_t revents
 
         space = next_datagram_size_fd(fd);
         if (space < 0) {
+                if (ERRNO_IS_TRANSIENT(space) || ERRNO_IS_DISCONNECT(space))
+                        return 0;
+
                 log_lldp_rx_errno(lldp_rx, space, "Failed to determine datagram size to read, ignoring: %m");
                 return 0;
         }
@@ -212,7 +215,7 @@ static int lldp_rx_receive_datagram(sd_event_source *s, int fd, uint32_t revents
 
         length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT);
         if (length < 0) {
-                if (ERRNO_IS_TRANSIENT(errno))
+                if (ERRNO_IS_TRANSIENT(errno) || ERRNO_IS_DISCONNECT(errno))
                         return 0;
 
                 log_lldp_rx_errno(lldp_rx, errno, "Failed to read LLDP datagram, ignoring: %m");
index 424526db9870e28a4bb8e6d6ba7f036c7be88917..7e16f5129996ca34cf9593417bbc1d518dca9615 100644 (file)
@@ -186,10 +186,8 @@ static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
         assert(rt);
 
         r = ndisc_router_parse(nd, rt);
-        if (r == -EBADMSG) /* Bad packet */
-                return 0;
         if (r < 0)
-                return 0;
+                return r;
 
         log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %" PRIu16 " sec",
                   rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
@@ -213,6 +211,9 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
 
         buflen = next_datagram_size_fd(fd);
         if (buflen < 0) {
+                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
+                        return 0;
+
                 log_ndisc_errno(nd, buflen, "Failed to determine datagram size to read, ignoring: %m");
                 return 0;
         }
@@ -223,6 +224,9 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
 
         r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address, &rt->timestamp);
         if (r < 0) {
+                if (ERRNO_IS_TRANSIENT(r) || ERRNO_IS_DISCONNECT(r))
+                        return 0;
+
                 switch (r) {
                 case -EADDRNOTAVAIL:
                         (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &rt->address, &addr);
@@ -237,9 +241,6 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
                         log_ndisc(nd, "Received invalid source address from ICMPv6 socket. Ignoring.");
                         break;
 
-                case -EAGAIN: /* ignore spurious wakeups */
-                        break;
-
                 default:
                         log_ndisc_errno(nd, r, "Unexpected error while reading from ICMPv6, ignoring: %m");
                         break;
@@ -249,8 +250,8 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
         }
 
         (void) event_source_disable(nd->timeout_event_source);
-
-        return ndisc_handle_datagram(nd, rt);
+        (void) ndisc_handle_datagram(nd, rt);
+        return 0;
 }
 
 static usec_t ndisc_timeout_compute_random(usec_t val) {
index 4f5dbf0090b9f4a090950dcefa9d499e81202c85..f8ffb6358f566bc5a07acbb63f6681b2f1a36790 100644 (file)
@@ -258,8 +258,13 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
         assert(ra->event);
 
         buflen = next_datagram_size_fd(fd);
-        if (buflen < 0)
-                return (int) buflen;
+        if (buflen < 0) {
+                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
+                        return 0;
+
+                log_radv_errno(ra, buflen, "Failed to determine datagram size to read, ignoring: %m");
+                return 0;
+        }
 
         buf = new0(char, buflen);
         if (!buf)
@@ -267,6 +272,9 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
 
         r = icmp6_receive(fd, buf, buflen, &src, &timestamp);
         if (r < 0) {
+                if (ERRNO_IS_TRANSIENT(r) || ERRNO_IS_DISCONNECT(r))
+                        return 0;
+
                 switch (r) {
                 case -EADDRNOTAVAIL:
                         (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &src, &addr);
@@ -281,11 +289,8 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
                         log_radv(ra, "Received invalid source address from ICMPv6 socket. Ignoring.");
                         break;
 
-                case -EAGAIN: /* ignore spurious wakeups */
-                        break;
-
                 default:
-                        log_radv_errno(ra, r, "Unexpected error receiving from ICMPv6 socket, Ignoring: %m");
+                        log_radv_errno(ra, r, "Unexpected error receiving from ICMPv6 socket, ignoring: %m");
                         break;
                 }