changeset 5421:0229b76cea16 draft

privsep: Set a zero length receive buffer for write only sockets 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.
author Roy Marples <roy@marples.name>
date Sun, 16 Aug 2020 18:52:17 +0100
parents d9038a8c3241
children 66a1c1c34366
files src/privsep-root.c
diffstat 1 files changed, 20 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/privsep-root.c	Sat Aug 08 20:27:34 2020 +0100
+++ b/src/privsep-root.c	Sun Aug 16 18:52:17 2020 +0100
@@ -638,27 +638,46 @@
 	/* 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