]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket-util: make sure flush_accept() doesn't hang on unexpected EOPNOTSUPP
authorLennart Poettering <lennart@poettering.net>
Thu, 18 Apr 2019 13:13:54 +0000 (15:13 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 18 Apr 2019 13:18:12 +0000 (15:18 +0200)
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

index 904bafb76f92362d29e0343d791cbfe8df6760b1..e787d53d8f4e397832e27ace246ff3d06185cac2 100644 (file)
@@ -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;