]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: raw_sock: remove support for very old linux splice bug workaround
authorWilly Tarreau <w@1wt.eu>
Wed, 22 May 2019 17:55:24 +0000 (19:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 22 May 2019 18:02:15 +0000 (20:02 +0200)
We've been dealing with a workaround for a bug in splice that used to
affect version 2.6.25 to 2.6.27.12 and which was fixed 10 years ago
in kernel versions which are not supported anymore. Given that people
who would use a kernel in such a range would face much more serious
stability and security issues, it's about time to get rid of this
workaround and of the ASSUME_SPLICE_WORKS build option used to disable
it.

Makefile
src/raw_sock.c

index a0e3bb32cce9799da38d107e617eee814f0b775c..cf4a3d9e6987b196791b294cac0fb9696e9ca3f8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -345,7 +345,7 @@ ifeq ($(TARGET),linux2628)
   set_target_defaults = $(call default_opts, \
     USE_POLL USE_TPROXY USE_LIBCRYPT USE_DL USE_RT USE_CRYPT_H USE_NETFILTER  \
     USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_FUTEX USE_LINUX_TPROXY          \
-    USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL ASSUME_SPLICE_WORKS USE_THREAD_DUMP)
+    USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP)
 endif
 
 # Solaris 8 and above
@@ -504,10 +504,6 @@ ifneq ($(USE_VSYSCALL),)
 OPTIONS_OBJS   += src/i386-linux-vsys.o
 endif
 
-ifneq ($(ASSUME_SPLICE_WORKS),)
-OPTIONS_CFLAGS += -DASSUME_SPLICE_WORKS
-endif
-
 ifneq ($(USE_REGPARM),)
 OPTIONS_CFLAGS += -DCONFIG_REGPARM=3
 endif
index 59a7cbc2fe6cac2d03411b5f8b907bc0fde518b7..1090dfc673dbf0f76bb93b0ddd543037b676b978 100644 (file)
  * infinite forwarding */
 #define MAX_SPLICE_AT_ONCE     (1<<30)
 
-/* Versions of splice between 2.6.25 and 2.6.27.12 were bogus and would return EAGAIN
- * on incoming shutdowns. On these versions, we have to call recv() after such a return
- * in order to find whether splice is OK or not. Since 2.6.27.13 we don't need to do
- * this anymore, and we can avoid this logic by defining ASSUME_SPLICE_WORKS.
- */
-
 /* Returns :
  *   -1 if splice() is not supported
  *   >= 0 to report the amount of spliced bytes.
@@ -68,9 +62,6 @@
  */
 int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count)
 {
-#ifndef ASSUME_SPLICE_WORKS
-       static THREAD_LOCAL int splice_detects_close;
-#endif
        int ret;
        int retval = 0;
 
@@ -109,28 +100,18 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
                             SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
 
                if (ret <= 0) {
-                       if (ret == 0) {
-                               /* connection closed. This is only detected by
-                                * recent kernels (>= 2.6.27.13). If we notice
-                                * it works, we store the info for later use.
-                                */
-#ifndef ASSUME_SPLICE_WORKS
-                               splice_detects_close = 1;
-#endif
+                       if (ret == 0)
                                goto out_read0;
-                       }
 
                        if (errno == EAGAIN) {
                                /* there are two reasons for EAGAIN :
                                 *   - nothing in the socket buffer (standard)
                                 *   - pipe is full
-                                *   - the connection is closed (kernel < 2.6.27.13)
-                                * The last case is annoying but know if we can detect it
-                                * and if we can't then we rely on the call to recv() to
-                                * get a valid verdict. The difference between the first
-                                * two situations is problematic. Since we don't know if
-                                * the pipe is full, we'll stop if the pipe is not empty.
-                                * Anyway, we will almost always fill/empty the pipe.
+                                * The difference between these two situations
+                                * is problematic. Since we don't know if the
+                                * pipe is full, we'll stop if the pipe is not
+                                * empty. Anyway, we will almost always fill or
+                                * empty the pipe.
                                 */
                                if (pipe->data) {
                                        /* alway stop reading until the pipe is flushed */
@@ -138,18 +119,7 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
                                        break;
                                }
 
-                               /* We don't know if the connection was closed,
-                                * but if we know splice detects close, then we
-                                * know it for sure.
-                                * But if we're called upon POLLIN with an empty
-                                * pipe and get EAGAIN, it is suspect enough to
-                                * try to fall back to the normal recv scheme
-                                * which will be able to deal with the situation.
-                                */
-#ifndef ASSUME_SPLICE_WORKS
-                               if (splice_detects_close)
-#endif
-                                       fd_cant_recv(conn->handle.fd); /* we know for sure that it's EAGAIN */
+                               fd_cant_recv(conn->handle.fd);
                                break;
                        }
                        else if (errno == ENOSYS || errno == EINVAL || errno == EBADF) {