haproxy: Update HAProxy to v1.8.4 (+patches)
authorChristian Lachner <gladiac@gmail.com>
Sun, 4 Mar 2018 11:21:28 +0000 (12:21 +0100)
committerChristian Lachner <gladiac@gmail.com>
Sun, 4 Mar 2018 11:42:10 +0000 (12:42 +0100)
- Update haproxy download URL and hash
- Update the haproxy homepage
- Add libatomic to the dependencies as 1.8 needs it
- Make USE_REGPARM an x86-only option as this fixes many warnings and does not do much on non-x86 platforms
- Add USE_GETADDRINFO=1 to use getaddrinfo() to resolve IPv6 host names
- Add USE_TFO=1 to enable TCP fast open
- Unbreak CFLAGS, LD and LDFLAGS by adding the missing backslash after $(ADDON)
- Unbreak IGNOREGIT=1 option (typo)
- Rework LDFLAGS and add libatomic
- Add MEDIUM+ patches (see https://www.haproxy.org/bugs/bugs-1.8.4.html)

Signed-off-by: Christian Lachner <gladiac@gmail.com>
net/haproxy/Makefile
net/haproxy/patches/0001-BUG-MEDIUM-connection-remove-useless-flag-CO_FL_DATA.patch [deleted file]
net/haproxy/patches/0001-BUG-MEDIUM-ssl-Dont-always-treat-SSL_ERROR_SYSCALL-as-unrecovarable.patch [new file with mode: 0644]
net/haproxy/patches/0002-BUG-MEDIUM-ssl-Shutdown-the-connection-for-reading-on-SSL_ERROR_SYSCALL.patch [new file with mode: 0644]
net/haproxy/patches/0003-BUG-MEDIUM-http-Switch-the-HTTP-response-in-tunnel-mode-as-earlier-as-possible.patch [new file with mode: 0644]
net/haproxy/patches/0004-BUG-MEDIUM-ssl-sample-ssl_bc_-fetch-keywords-are-broken.patch [new file with mode: 0644]

index 4a77b59872622dfa9d89a4aec859cbcf95534ad7..511ceca1fc96e19c849fe5d8b8acee0469cf24d6 100644 (file)
@@ -9,12 +9,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=haproxy
-PKG_VERSION:=1.7.9
-PKG_RELEASE:=02
+PKG_VERSION:=1.8.4
+PKG_RELEASE:=01
 
 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://www.haproxy.org/download/1.7/src/
-PKG_HASH:=1072337e54fa188dc6e0cfe3ba4c2200b07082e321cbfe5a0882d85d54db068e
+PKG_SOURCE_URL:=https://www.haproxy.org/download/1.8/src/
+PKG_HASH:=e305b0a4e7dec08072841eef6ac6dcd1b5586b1eff09c2d51e152a912e8884a6
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_LICENSE:=GPL-2.0
@@ -27,7 +27,7 @@ define Package/haproxy/Default
   SECTION:=net
   CATEGORY:=Network
   TITLE:=The Reliable, High Performance TCP/HTTP Load Balancer
-  URL:=http://haproxy.1wt.eu/
+  URL:=https://www.haproxy.org/
 endef
 
 define Download/lua534
@@ -53,7 +53,7 @@ define Package/haproxy/Default/description
 endef
 
 define Package/haproxy
-  DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +libncursesw +libreadline +@OPENSSL_WITH_DEPRECATED +@OPENSSL_WITH_EC +@OPENSSL_WITH_EC2M  +@OPENSSL_WITH_DTLS +@OPENSSL_WITH_COMPRESSION +@OPENSSL_WITH_NPN  +@OPENSSL_WITH_PSK +@OPENSSL_WITH_SRP +@OPENSSL_ENGINE_DIGEST +@OPENSSL_ENGINE_CRYPTO
+  DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +libncursesw +libreadline +libatomic +@OPENSSL_WITH_DEPRECATED +@OPENSSL_WITH_EC +@OPENSSL_WITH_EC2M  +@OPENSSL_WITH_DTLS +@OPENSSL_WITH_COMPRESSION +@OPENSSL_WITH_NPN  +@OPENSSL_WITH_PSK +@OPENSSL_WITH_SRP +@OPENSSL_ENGINE_DIGEST +@OPENSSL_ENGINE_CRYPTO
 
   TITLE+= (with SSL support)
   VARIANT:=ssl
@@ -92,6 +92,8 @@ $(call Package/haproxy/Default/description)
 endef
 
 ENABLE_LUA:=y
+ENABLE_REGPARM:=n
+
 ifeq ($(CONFIG_mips),y)
   ENABLE_LUA:=n
 endif
@@ -99,6 +101,10 @@ ifeq ($(CONFIG_mipsel),y)
   ENABLE_LUA:=n
 endif
 
+ifeq ($(CONFIG_TARGET_x86),y)
+  ENABLE_REGPARM:=y
+endif
+
 ifeq ($(CONFIG_avr32),y)
   LINUX_TARGET:=linux26
 else
@@ -117,6 +123,10 @@ ifeq ($(ENABLE_LUA),y)
        ADDON+=LUA_LIB="$(STAGING_DIR)/lua-5.3.4/lib"
 endif
 
+ifeq ($(ENABLE_REGPARM),y)
+       ADDON+=USE_REGPARM=1
+endif
+
 ifeq ($(ENABLE_LUA),y)
 define Build/Compile/lua
        $(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR)/lua \
@@ -138,14 +148,13 @@ define Build/Compile
                CC="$(TARGET_CC)" \
                PCREDIR="$(STAGING_DIR)/usr/" \
                SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530 " \
-               USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 USE_REGPARM=1 \
-               USE_ZLIB=yes USE_PCRE=1 USE_PCRE_JIT=1\
+               USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 USE_TFO=1 \
+               USE_ZLIB=yes USE_PCRE=1 USE_PCRE_JIT=1 USE_GETADDRINFO=1 \
                VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
-               $(ADDON)
-               CFLAGS="$(TARGET_CFLAGS) -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -pipe -fomit-frame-pointer -fhonour-copts" \
-               LD="$(TARGET_LD)" \
-               LDFLAGS="$(TARGET_LDFLAGS) -lcurses -lreadline" \
-               GNOREGIT=1
+               $(ADDON) \
+               LD="$(TARGET_CC)" \
+               LDFLAGS="$(TARGET_LDFLAGS) -latomic" \
+               IGNOREGIT=1
 
        $(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) \
                DESTDIR="$(PKG_INSTALL_DIR)" \
diff --git a/net/haproxy/patches/0001-BUG-MEDIUM-connection-remove-useless-flag-CO_FL_DATA.patch b/net/haproxy/patches/0001-BUG-MEDIUM-connection-remove-useless-flag-CO_FL_DATA.patch
deleted file mode 100644 (file)
index dcbef61..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-From 912e8f18ef274fdda0a522b2aa8255bddd00fb7b Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Wed, 30 Aug 2017 07:35:35 +0200
-Subject: [PATCH] BUG/MEDIUM: connection: remove useless flag CO_FL_DATA_RD_SH
-
-This flag is both confusing and wrong. It is supposed to report the
-fact that the data layer has received a shutdown, but in fact this is
-reported by CO_FL_SOCK_RD_SH which is set by the transport layer after
-this condition is detected. The only case where the flag above is set
-is in the stream interface where CF_SHUTR is also set on the receiving
-channel.
-
-In addition, it was checked in the health checks code (while never set)
-and was always test jointly with CO_FL_SOCK_RD_SH everywhere, except in
-conn_data_read0_pending() which incorrectly doesn't match the second
-time it's called and is fortunately protected by an extra check on
-(ic->flags & CF_SHUTR).
-
-This patch gets rid of the flag completely. Now conn_data_read0_pending()
-accurately reports the fact that the transport layer has detected the end
-of the stream, regardless of the fact that this state was already consumed,
-and the stream interface watches ic->flags&CF_SHUTR to know if the channel
-was already closed by the upper layer (which it already used to do).
-
-The now unused conn_data_read0() function was removed.
-(cherry picked from commit 54e917cfa1e7b0539550ae32c48c76da2f169041)
-
-[wt: this happens to fix a real bug which occasionally strikes when
-     using http-reuse in the rare case where a server shuts down after
-     providing its response but before the connection is put back into
-     the idle pool, and it gets immediately recycled for another request,
-     without first passing through the idle handler, and the already
-     reported shutdown is never reported to the second transaction,
-     causing a loop to last for as long as the server timeout]
----
- contrib/debug/flags.c      |  1 -
- include/proto/connection.h |  8 +-------
- include/types/connection.h |  2 +-
- src/checks.c               |  4 ++--
- src/stream_interface.c     | 11 +++++------
- 5 files changed, 9 insertions(+), 17 deletions(-)
-
-diff --git a/contrib/debug/flags.c b/contrib/debug/flags.c
-index bc71bde9..19327f34 100644
---- a/contrib/debug/flags.c
-+++ b/contrib/debug/flags.c
-@@ -117,7 +117,6 @@ void show_conn_flags(unsigned int f)
-       SHOW_FLAG(f, CO_FL_SOCK_WR_SH);
-       SHOW_FLAG(f, CO_FL_SOCK_RD_SH);
-       SHOW_FLAG(f, CO_FL_DATA_WR_SH);
--      SHOW_FLAG(f, CO_FL_DATA_RD_SH);
-       SHOW_FLAG(f, CO_FL_WAKE_DATA);
-       SHOW_FLAG(f, CO_FL_INIT_DATA);
-       SHOW_FLAG(f, CO_FL_ADDR_TO_SET);
-diff --git a/include/proto/connection.h b/include/proto/connection.h
-index fce60259..eb68322a 100644
---- a/include/proto/connection.h
-+++ b/include/proto/connection.h
-@@ -413,12 +413,6 @@ static inline void conn_sock_read0(struct connection *c)
-               fdtab[c->t.sock.fd].linger_risk = 0;
- }
--static inline void conn_data_read0(struct connection *c)
--{
--      c->flags |= CO_FL_DATA_RD_SH;
--      __conn_data_stop_recv(c);
--}
--
- static inline void conn_sock_shutw(struct connection *c)
- {
-       c->flags |= CO_FL_SOCK_WR_SH;
-@@ -450,7 +444,7 @@ static inline void conn_data_shutw_hard(struct connection *c)
- /* detect sock->data read0 transition */
- static inline int conn_data_read0_pending(struct connection *c)
- {
--      return (c->flags & (CO_FL_DATA_RD_SH | CO_FL_SOCK_RD_SH)) == CO_FL_SOCK_RD_SH;
-+      return (c->flags & CO_FL_SOCK_RD_SH) != 0;
- }
- /* detect data->sock shutw transition */
-diff --git a/include/types/connection.h b/include/types/connection.h
-index 02eac932..90e8e073 100644
---- a/include/types/connection.h
-+++ b/include/types/connection.h
-@@ -90,7 +90,7 @@ enum {
-       CO_FL_WAKE_DATA     = 0x00008000,  /* wake-up data layer upon activity at the transport layer */
-       /* flags used to remember what shutdown have been performed/reported */
--      CO_FL_DATA_RD_SH    = 0x00010000,  /* DATA layer was notified about shutr/read0 */
-+      /* unused : 0x00010000 */
-       CO_FL_DATA_WR_SH    = 0x00020000,  /* DATA layer asked for shutw */
-       CO_FL_SOCK_RD_SH    = 0x00040000,  /* SOCK layer was notified about shutr/read0 */
-       CO_FL_SOCK_WR_SH    = 0x00080000,  /* SOCK layer asked for shutw */
-diff --git a/src/checks.c b/src/checks.c
-index ca3881a5..6c5e3cbc 100644
---- a/src/checks.c
-+++ b/src/checks.c
-@@ -839,7 +839,7 @@ static void event_srv_chk_r(struct connection *conn)
-       done = 0;
-       conn->xprt->rcv_buf(conn, check->bi, check->bi->size);
--      if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH)) {
-+      if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
-               done = 1;
-               if ((conn->flags & CO_FL_ERROR) && !check->bi->i) {
-                       /* Report network errors only if we got no other data. Otherwise
-@@ -2892,7 +2892,7 @@ static void tcpcheck_main(struct connection *conn)
-                               goto out_end_tcpcheck;
-                       if (conn->xprt->rcv_buf(conn, check->bi, check->bi->size) <= 0) {
--                              if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH)) {
-+                              if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
-                                       done = 1;
-                                       if ((conn->flags & CO_FL_ERROR) && !check->bi->i) {
-                                               /* Report network errors only if we got no other data. Otherwise
-diff --git a/src/stream_interface.c b/src/stream_interface.c
-index 836487bd..aba49c94 100644
---- a/src/stream_interface.c
-+++ b/src/stream_interface.c
-@@ -1060,14 +1060,14 @@ static void si_conn_recv_cb(struct connection *conn)
-       if (conn->flags & CO_FL_ERROR)
-               return;
--      /* stop here if we reached the end of data */
--      if (conn_data_read0_pending(conn))
--              goto out_shutdown_r;
--
-       /* maybe we were called immediately after an asynchronous shutr */
-       if (ic->flags & CF_SHUTR)
-               return;
-+      /* stop here if we reached the end of data */
-+      if (conn_data_read0_pending(conn))
-+              goto out_shutdown_r;
-+
-       cur_read = 0;
-       if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !ic->buf->o &&
-@@ -1153,7 +1153,7 @@ static void si_conn_recv_cb(struct connection *conn)
-        * that if such an event is not handled above in splice, it will be handled here by
-        * recv().
-        */
--      while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
-+      while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE)) && !(ic->flags & CF_SHUTR)) {
-               max = channel_recv_max(ic);
-               if (!max) {
-@@ -1267,7 +1267,6 @@ static void si_conn_recv_cb(struct connection *conn)
-       if (ic->flags & CF_AUTO_CLOSE)
-               channel_shutw_now(ic);
-       stream_sock_read0(si);
--      conn_data_read0(conn);
-       return;
- }
--- 
-2.13.5
-
diff --git a/net/haproxy/patches/0001-BUG-MEDIUM-ssl-Dont-always-treat-SSL_ERROR_SYSCALL-as-unrecovarable.patch b/net/haproxy/patches/0001-BUG-MEDIUM-ssl-Dont-always-treat-SSL_ERROR_SYSCALL-as-unrecovarable.patch
new file mode 100644 (file)
index 0000000..93b51dc
--- /dev/null
@@ -0,0 +1,61 @@
+From 2fcd544272a5498ffa49544e9f06b51bc93e55d1 Mon Sep 17 00:00:00 2001
+From: Olivier Houchard <ohouchard@haproxy.com>
+Date: Tue, 13 Feb 2018 15:17:23 +0100
+Subject: [PATCH] BUG/MEDIUM: ssl: Don't always treat SSL_ERROR_SYSCALL as
+ unrecovarable.
+
+Bart Geesink reported some random errors appearing under the form of
+termination flags SD in the logs for connections involving SSL traffic
+to reach the servers.
+
+Tomek Gacek and Mateusz Malek finally narrowed down the problem to commit
+c2aae74 ("MEDIUM: ssl: Handle early data with OpenSSL 1.1.1"). It happens
+that the special case of SSL_ERROR_SYSCALL isn't handled anymore since
+this commit.
+
+SSL_read() might return <= 0, and SSL_get_erro() return SSL_ERROR_SYSCALL,
+without meaning the connection is gone. Before flagging the connection
+as in error, check the errno value.
+
+This should be backported to 1.8.
+
+(cherry picked from commit 7e2e505006feb8f3b4a7f9e0ac5e89b5a8c4895e)
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+---
+ src/ssl_sock.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
+index aecf3dd..f118724 100644
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -5437,6 +5437,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
+                               break;
+                       } else if (ret == SSL_ERROR_ZERO_RETURN)
+                               goto read0;
++                      /* For SSL_ERROR_SYSCALL, make sure the error is
++                       * unrecoverable before flagging the connection as
++                       * in error.
++                       */
++                      if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN))
++                              goto clear_ssl_error;
+                       /* otherwise it's a real error */
+                       goto out_error;
+               }
+@@ -5451,11 +5457,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
+       conn_sock_read0(conn);
+       goto leave;
+  out_error:
++      conn->flags |= CO_FL_ERROR;
++clear_ssl_error:
+       /* Clear openssl global errors stack */
+       ssl_sock_dump_errors(conn);
+       ERR_clear_error();
+-      conn->flags |= CO_FL_ERROR;
+       goto leave;
+ }
+-- 
+1.7.10.4
+
diff --git a/net/haproxy/patches/0002-BUG-MEDIUM-ssl-Shutdown-the-connection-for-reading-on-SSL_ERROR_SYSCALL.patch b/net/haproxy/patches/0002-BUG-MEDIUM-ssl-Shutdown-the-connection-for-reading-on-SSL_ERROR_SYSCALL.patch
new file mode 100644 (file)
index 0000000..22274d3
--- /dev/null
@@ -0,0 +1,63 @@
+From f7fa1d461aa71bbc8a6c23fdcfc305f2e52ce5dd Mon Sep 17 00:00:00 2001
+From: Christopher Faulet <cfaulet@haproxy.com>
+Date: Mon, 19 Feb 2018 14:25:15 +0100
+Subject: [PATCH] BUG/MEDIUM: ssl: Shutdown the connection for reading on
+ SSL_ERROR_SYSCALL
+
+When SSL_read returns SSL_ERROR_SYSCALL and errno is unset or set to EAGAIN, the
+connection must be shut down for reading. Else, the connection loops infinitly,
+consuming all the CPU.
+
+The bug was introduced in the commit 7e2e50500 ("BUG/MEDIUM: ssl: Don't always
+treat SSL_ERROR_SYSCALL as unrecovarable."). This patch must be backported in
+1.8 too.
+
+(cherry picked from commit 4ac77a98cda3d0f9b1d9de7bbbda2c91357f0767)
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+---
+ src/ssl_sock.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
+index f118724..a065bbb 100644
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -5437,10 +5437,9 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
+                               break;
+                       } else if (ret == SSL_ERROR_ZERO_RETURN)
+                               goto read0;
+-                      /* For SSL_ERROR_SYSCALL, make sure the error is
+-                       * unrecoverable before flagging the connection as
+-                       * in error.
+-                       */
++                      /* For SSL_ERROR_SYSCALL, make sure to clear the error
++                       * stack before shutting down the connection for
++                       * reading. */
+                       if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN))
+                               goto clear_ssl_error;
+                       /* otherwise it's a real error */
+@@ -5453,16 +5452,19 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
+       conn_cond_update_sock_polling(conn);
+       return done;
++ clear_ssl_error:
++      /* Clear openssl global errors stack */
++      ssl_sock_dump_errors(conn);
++      ERR_clear_error();
+  read0:
+       conn_sock_read0(conn);
+       goto leave;
++
+  out_error:
+       conn->flags |= CO_FL_ERROR;
+-clear_ssl_error:
+       /* Clear openssl global errors stack */
+       ssl_sock_dump_errors(conn);
+       ERR_clear_error();
+-
+       goto leave;
+ }
+-- 
+1.7.10.4
+
diff --git a/net/haproxy/patches/0003-BUG-MEDIUM-http-Switch-the-HTTP-response-in-tunnel-mode-as-earlier-as-possible.patch b/net/haproxy/patches/0003-BUG-MEDIUM-http-Switch-the-HTTP-response-in-tunnel-mode-as-earlier-as-possible.patch
new file mode 100644 (file)
index 0000000..446a610
--- /dev/null
@@ -0,0 +1,69 @@
+From 8a5949f2d74c3a3a6c6da25449992c312b183ef3 Mon Sep 17 00:00:00 2001
+From: Christopher Faulet <cfaulet@haproxy.com>
+Date: Fri, 2 Feb 2018 15:54:15 +0100
+Subject: [PATCH] BUG/MEDIUM: http: Switch the HTTP response in tunnel mode as
+ earlier as possible
+
+When the body length is undefined (no Content-Length or Transfer-Encoding
+headers), The reponse remains in ending mode, waiting the request is done. So,
+most of time this is not a problem because the resquest is done before the
+response. But when a client sends data to a server that replies without waiting
+all the data, it is really not desirable to wait the end of the request to
+finish the response.
+
+This bug was introduced when the tunneling of the request and the reponse was
+refactored, in commit 4be980391 ("MINOR: http: Switch requests/responses in
+TUNNEL mode only by checking txn flag").
+
+This patch should be backported in 1.8 and 1.7.
+
+(cherry picked from commit fd04fcf5edb0a24cd29ce8f4d4dc2aa3a0e2e82c)
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+---
+ src/proto_http.c |   15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/src/proto_http.c b/src/proto_http.c
+index 64bd410..29880ea 100644
+--- a/src/proto_http.c
++++ b/src/proto_http.c
+@@ -4634,16 +4634,8 @@ int http_sync_res_state(struct stream *s)
+                        * let's enforce it now that we're not expecting any new
+                        * data to come. The caller knows the stream is complete
+                        * once both states are CLOSED.
+-                       *
+-                       * However, there is an exception if the response length
+-                       * is undefined. In this case, we switch in TUNNEL mode.
+                        */
+-                      if (!(txn->rsp.flags & HTTP_MSGF_XFER_LEN)) {
+-                              channel_auto_read(chn);
+-                              txn->rsp.msg_state = HTTP_MSG_TUNNEL;
+-                              chn->flags |= CF_NEVER_WAIT;
+-                      }
+-                      else if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
++                      if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
+                               channel_shutr_now(chn);
+                               channel_shutw_now(chn);
+                       }
+@@ -6241,6 +6233,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
+               /* The server still sending data that should be filtered */
+               if (!(chn->flags & CF_SHUTR) && HAS_DATA_FILTERS(s, chn))
+                       goto missing_data_or_waiting;
++              msg->msg_state = HTTP_MSG_TUNNEL;
++              goto ending;
+       }
+       msg->msg_state = HTTP_MSG_ENDING;
+@@ -6262,7 +6256,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
+                        /* default_ret */ 1,
+                        /* on_error    */ goto error,
+                        /* on_wait     */ goto waiting);
+-      msg->msg_state = HTTP_MSG_DONE;
++      if (msg->msg_state == HTTP_MSG_ENDING)
++              msg->msg_state = HTTP_MSG_DONE;
+       return 1;
+   missing_data_or_waiting:
+-- 
+1.7.10.4
+
diff --git a/net/haproxy/patches/0004-BUG-MEDIUM-ssl-sample-ssl_bc_-fetch-keywords-are-broken.patch b/net/haproxy/patches/0004-BUG-MEDIUM-ssl-sample-ssl_bc_-fetch-keywords-are-broken.patch
new file mode 100644 (file)
index 0000000..11d2ef9
--- /dev/null
@@ -0,0 +1,103 @@
+From 7ccf7c9791f2b2329f3940d1347618af3a77bebc Mon Sep 17 00:00:00 2001
+From: Emeric Brun <ebrun@haproxy.com>
+Date: Mon, 19 Feb 2018 15:59:48 +0100
+Subject: [PATCH] BUG/MEDIUM: ssl/sample: ssl_bc_* fetch keywords are broken.
+
+Since the split between connections and conn-stream objects, this
+keywords are broken.
+
+This patch must be backported in 1.8
+
+(cherry picked from commit eb8def9f34c37537d56a69fcd211d4c4c8006bea)
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+---
+ src/ssl_sock.c |   31 ++++++++++++++-----------------
+ 1 file changed, 14 insertions(+), 17 deletions(-)
+
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
+index 4d0d5db..d832d76 100644
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -6580,8 +6580,8 @@ smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *
+ static int
+ smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       smp->data.type = SMP_T_BOOL;
+       smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
+@@ -6625,8 +6625,8 @@ smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const ch
+ static int
+ smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       smp->flags = 0;
+       if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
+@@ -6651,9 +6651,8 @@ smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *
+ static int
+ smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
+-
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       int sint;
+       smp->flags = 0;
+@@ -6676,8 +6675,8 @@ smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const c
+ static int
+ smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       smp->flags = 0;
+       if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
+@@ -6747,8 +6746,8 @@ smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw
+ static int
+ smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       smp->flags = 0;
+       if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
+@@ -6773,9 +6772,8 @@ static int
+ smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+ #if OPENSSL_VERSION_NUMBER > 0x0090800fL
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
+-
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       SSL_SESSION *ssl_sess;
+       smp->flags = SMP_F_CONST;
+@@ -6917,9 +6915,8 @@ static int
+ smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
+ {
+ #if OPENSSL_VERSION_NUMBER > 0x0090800fL
+-      struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
+-                                          smp->strm ? smp->strm->si[1].end : NULL);
+-
++      struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
++                                          smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       int finished_len;
+       struct chunk *finished_trash;
+-- 
+1.7.10.4
+