]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Set a zero length receive buffer for write only sockets
authorRoy Marples <roy@marples.name>
Sun, 16 Aug 2020 17:52:17 +0000 (18:52 +0100)
committerRoy Marples <roy@marples.name>
Sun, 16 Aug 2020 17:52:17 +0000 (18:52 +0100)
We cannot use shutdown(2) because they are not connected.
Constantly draining would be a waste of CPU time, so just let
the buffer overflow. To ease the kernel as much as we can, set
a zero length buffer.

The kernel may still allocate a small buffer, but this is kernel
dependant and we're just trying to be helpful.

src/privsep-root.c

index f1b4074531b4593eb7f39dc77af58e8d18f0f119..fe6b1aa616cd84ddd01dd205fe3f55e4bb23468d 100644 (file)
@@ -638,27 +638,46 @@ ps_root_startcb(void *arg)
        /* Open network sockets for sending.
         * This is a small bit wasteful for non sandboxed OS's
         * but makes life very easy for unicasting DHCPv6 in non master
-        * mode as we no longer care about address selection. */
+        * mode as we no longer care about address selection.
+        * We can't call shutdown SHUT_RD on the socket because it's
+        * not connectd. All we can do is try and set a zero sized
+        * receive buffer and just let it overflow.
+        * Reading from it just to drain it is a waste of CPU time. */
 #ifdef INET
        if (ctx->options & DHCPCD_IPV4) {
+               int buflen = 0;
+
                ctx->udp_wfd = xsocket(PF_INET,
                    SOCK_RAW | SOCK_CXNB, IPPROTO_UDP);
                if (ctx->udp_wfd == -1)
                        logerr("%s: dhcp_openraw", __func__);
+               else if (setsockopt(ctx->udp_wfd, SOL_SOCKET, SO_RCVBUF,
+                   &buflen, sizeof(buflen)) == -1)
+                       logerr("%s: setsockopt SO_RCVBUF DHCP", __func__);
        }
 #endif
 #ifdef INET6
        if (ctx->options & DHCPCD_IPV6) {
+               int buflen = 0;
+
                ctx->nd_fd = ipv6nd_open(false);
                if (ctx->nd_fd == -1)
                        logerr("%s: ipv6nd_open", __func__);
+               else if (setsockopt(ctx->nd_fd, SOL_SOCKET, SO_RCVBUF,
+                   &buflen, sizeof(buflen)) == -1)
+                       logerr("%s: setsockopt SO_RCVBUF ND", __func__);
        }
 #endif
 #ifdef DHCP6
        if (ctx->options & DHCPCD_IPV6) {
+               int buflen = 0;
+
                ctx->dhcp6_wfd = dhcp6_openraw();
                if (ctx->dhcp6_wfd == -1)
                        logerr("%s: dhcp6_openraw", __func__);
+               else if (setsockopt(ctx->dhcp6_wfd, SOL_SOCKET, SO_RCVBUF,
+                   &buflen, sizeof(buflen)) == -1)
+                       logerr("%s: setsockopt SO_RCVBUF DHCP6", __func__);
        }
 #endif