summaryrefslogtreecommitdiffstats
path: root/src/privsep-root.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-08-16 18:52:17 +0100
committerRoy Marples <roy@marples.name>2020-08-16 18:52:17 +0100
commite5679c5f411e561c31a30fb9cf730ff54b9242ac (patch)
tree376202e6df9933671ca5f2e84b0879d1cb422be2 /src/privsep-root.c
parentcef90b983f28cbe01b9df2e3ba920dcdbd85b60f (diff)
downloaddhcpcd-e5679c5f411e561c31a30fb9cf730ff54b9242ac.tar.xz
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.
Diffstat (limited to 'src/privsep-root.c')
-rw-r--r--src/privsep-root.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/privsep-root.c b/src/privsep-root.c
index f1b40745..fe6b1aa6 100644
--- a/src/privsep-root.c
+++ b/src/privsep-root.c
@@ -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