summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-apps/systemd/files/242-socket-util-flush-accept.patch')
-rw-r--r--sys-apps/systemd/files/242-socket-util-flush-accept.patch46
1 files changed, 46 insertions, 0 deletions
diff --git a/sys-apps/systemd/files/242-socket-util-flush-accept.patch b/sys-apps/systemd/files/242-socket-util-flush-accept.patch
new file mode 100644
index 000000000000..4849c4c0789e
--- /dev/null
+++ b/sys-apps/systemd/files/242-socket-util-flush-accept.patch
@@ -0,0 +1,46 @@
+From f3d75364fbebf2ddb6393e54db5e10b6f6234e14 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 18 Apr 2019 15:13:54 +0200
+Subject: [PATCH] socket-util: make sure flush_accept() doesn't hang on
+ unexpected EOPNOTSUPP
+
+So apparently there are two reasons why accept() can return EOPNOTSUPP:
+because the socket is not a listening stream socket (or similar), or
+because the incoming TCP connection for some reason wasn't acceptable to
+the host. THe latter should be a transient error, as suggested on
+accept(2). The former however should be considered fatal for
+flush_accept(). Let's fix this by explicitly checking whether the socket
+is a listening socket beforehand.
+---
+ src/basic/socket-util.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
+index 904bafb76f9..e787d53d8f4 100644
+--- a/src/basic/socket-util.c
++++ b/src/basic/socket-util.c
+@@ -1225,9 +1225,22 @@ int flush_accept(int fd) {
+ .fd = fd,
+ .events = POLLIN,
+ };
+- int r;
++ int r, b;
++ socklen_t l = sizeof(b);
++
++ /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately
++ * closing them. */
++
++ if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
++ return -errno;
+
+- /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
++ assert(l == sizeof(b));
++ if (!b) /* Let's check if this is a socket accepting connections before calling accept(). That's
++ * because accept4() can return EOPNOTSUPP in the fd we are called on is not a listening
++ * socket, or in case the incoming TCP connection transiently triggered that (see accept(2)
++ * man page for details). The latter case is a transient error we should continue looping
++ * on. The former case however is fatal. */
++ return -ENOTTY;
+
+ for (;;) {
+ int cfd;