Merge pull request #9272 from gladiac1337/openwrt-18.06
[openwrt-18.06] haproxy: Update HAProxy to v1.8.20
This commit is contained in:
commit
dd927adcec
36 changed files with 2917 additions and 345 deletions
|
@ -1,6 +1,7 @@
|
|||
#
|
||||
# Copyright (C) 2010-2016 OpenWrt.org
|
||||
# Copyright (C) 2009-2016 Thomas Heil <heil@terminal-consulting.de>
|
||||
# Copyright (C) 2018 Christian Lachner <gladiac@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
|
@ -9,16 +10,17 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=haproxy
|
||||
PKG_VERSION:=1.8.4
|
||||
PKG_RELEASE:=02
|
||||
PKG_VERSION:=1.8.20
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://www.haproxy.org/download/1.8/src/
|
||||
PKG_HASH:=e305b0a4e7dec08072841eef6ac6dcd1b5586b1eff09c2d51e152a912e8884a6
|
||||
PKG_HASH:=3228f78d5fe1dfbaccf41bf387e36b08eeef6e16330053cafde5fa303e262b16
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
|
||||
MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
|
||||
Christian Lachner <gladiac@gmail.com>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
@ -30,17 +32,17 @@ define Package/haproxy/Default
|
|||
URL:=https://www.haproxy.org/
|
||||
endef
|
||||
|
||||
define Download/lua534
|
||||
FILE:=lua-5.3.4.tar.gz
|
||||
define Download/lua535
|
||||
FILE:=lua-5.3.5.tar.gz
|
||||
URL:=https://www.lua.org/ftp/
|
||||
HASH:=f681aa518233bc407e23acf0f5887c884f17436f000d453b2491a9f11a52400c
|
||||
HASH:=0c2eed3f960446e1a3e4b9a1ca2f3ff893b6ce41942cf54d5dd59ab4b3b058ac
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
ifeq ($(ENABLE_LUA),y)
|
||||
tar -zxvf $(DL_DIR)/lua-5.3.4.tar.gz -C $(PKG_BUILD_DIR)
|
||||
ln -s $(PKG_BUILD_DIR)/lua-5.3.4 $(PKG_BUILD_DIR)/lua
|
||||
tar -zxvf $(DL_DIR)/lua-5.3.5.tar.gz -C $(PKG_BUILD_DIR)
|
||||
ln -s $(PKG_BUILD_DIR)/lua-5.3.5 $(PKG_BUILD_DIR)/lua
|
||||
endif
|
||||
endef
|
||||
|
||||
|
@ -54,7 +56,6 @@ endef
|
|||
|
||||
define Package/haproxy
|
||||
DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +libncursesw +libreadline +libatomic +@OPENSSL_WITH_COMPRESSION +@OPENSSL_WITH_DTLS +@OPENSSL_ENGINE_CRYPTO
|
||||
|
||||
TITLE+= (with SSL support)
|
||||
VARIANT:=ssl
|
||||
$(call Package/haproxy/Default)
|
||||
|
@ -69,11 +70,6 @@ $(call Package/haproxy/Default/description)
|
|||
This package is built with SSL and LUA support.
|
||||
endef
|
||||
|
||||
define Package/haproxy/config
|
||||
select CONFIG_OPENSSL_WITH_DEPRECATED
|
||||
$(call Package/haproxy/Default/config)
|
||||
endef
|
||||
|
||||
define Package/haproxy-nossl
|
||||
TITLE+= (without SSL support)
|
||||
VARIANT:=nossl
|
||||
|
@ -94,22 +90,11 @@ endef
|
|||
ENABLE_LUA:=y
|
||||
ENABLE_REGPARM:=n
|
||||
|
||||
ifeq ($(CONFIG_mips),y)
|
||||
ENABLE_LUA:=n
|
||||
endif
|
||||
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
|
||||
LINUX_TARGET:=linux2628
|
||||
endif
|
||||
LINUX_TARGET:=linux2628
|
||||
|
||||
ifeq ($(BUILD_VARIANT),ssl)
|
||||
ADDON+=USE_OPENSSL=1
|
||||
|
@ -118,9 +103,9 @@ endif
|
|||
|
||||
ifeq ($(ENABLE_LUA),y)
|
||||
ADDON+=USE_LUA=1
|
||||
ADDON+=LUA_LIB_NAME="lua534"
|
||||
ADDON+=LUA_INC="$(STAGING_DIR)/lua-5.3.4/include"
|
||||
ADDON+=LUA_LIB="$(STAGING_DIR)/lua-5.3.4/lib"
|
||||
ADDON+=LUA_LIB_NAME="lua535"
|
||||
ADDON+=LUA_INC="$(STAGING_DIR)/lua-5.3.5/include"
|
||||
ADDON+=LUA_LIB="$(STAGING_DIR)/lua-5.3.5/lib"
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_REGPARM),y)
|
||||
|
@ -130,14 +115,14 @@ endif
|
|||
ifeq ($(ENABLE_LUA),y)
|
||||
define Build/Compile/lua
|
||||
$(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR)/lua \
|
||||
INSTALL_TOP="$(STAGING_DIR)/lua-5.3.4/" \
|
||||
INSTALL_TOP="$(STAGING_DIR)/lua-5.3.5/" \
|
||||
CC="$(TARGET_CC)" \
|
||||
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS) -lncurses -lreadline" \
|
||||
LD="$(TARGET_LD)" \
|
||||
linux install
|
||||
|
||||
mv $(STAGING_DIR)/lua-5.3.4/lib/liblua.a $(STAGING_DIR)/lua-5.3.4/lib/liblua534.a
|
||||
mv $(STAGING_DIR)/lua-5.3.5/lib/liblua.a $(STAGING_DIR)/lua-5.3.5/lib/liblua535.a
|
||||
endef
|
||||
endif
|
||||
|
||||
|
@ -147,27 +132,28 @@ define Build/Compile
|
|||
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||
CC="$(TARGET_CC)" \
|
||||
PCREDIR="$(STAGING_DIR)/usr/" \
|
||||
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530 " \
|
||||
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530" \
|
||||
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)" \
|
||||
VERSION="$(PKG_VERSION)" SUBVERS="-$(PKG_RELEASE)" \
|
||||
VERDATE="$(shell date -d @$(SOURCE_DATE_EPOCH) '+%Y/%m/%d')" IGNOREGIT=1 \
|
||||
$(ADDON) \
|
||||
CFLAGS="$(TARGET_CFLAGS)" \
|
||||
LD="$(TARGET_CC)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS) -latomic" \
|
||||
IGNOREGIT=1
|
||||
LDFLAGS="$(TARGET_LDFLAGS) -latomic"
|
||||
|
||||
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||
LD="$(TARGET_CC)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||
$(MAKE_FLAGS) \
|
||||
install
|
||||
|
||||
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR)/contrib/halog \
|
||||
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||
$(MAKE_FLAGS) \
|
||||
OPTIMIZE="$(TARGET_CFLAGS)" \
|
||||
ADDLIB="-lcrypto" \
|
||||
VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
|
||||
halog
|
||||
endef
|
||||
|
||||
|
@ -200,7 +186,7 @@ define Package/halog/install
|
|||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/halog/halog $(1)/usr/bin/
|
||||
endef
|
||||
|
||||
$(eval $(call Download,lua534))
|
||||
$(eval $(call Download,lua535))
|
||||
$(eval $(call BuildPackage,haproxy))
|
||||
$(eval $(call BuildPackage,halog))
|
||||
$(eval $(call BuildPackage,haproxy-nossl))
|
||||
|
|
27
net/haproxy/get-latest-patches.sh
Executable file
27
net/haproxy/get-latest-patches.sh
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
|
||||
CLONEURL=http://git.haproxy.org/git/haproxy-1.8.git
|
||||
BASE_TAG=v1.8.20
|
||||
TMP_REPODIR=tmprepo
|
||||
PATCHESDIR=patches
|
||||
|
||||
if test -d "${TMP_REPODIR}"; then rm -rf "${TMP_REPODIR}"; fi
|
||||
|
||||
git clone "${CLONEURL}" "${TMP_REPODIR}"
|
||||
|
||||
printf "Cleaning patches\n"
|
||||
find ${PATCHESDIR} -type f -name "*.patch" -exec rm -f "{}" \;
|
||||
|
||||
i=0
|
||||
for cid in $(git -C "${TMP_REPODIR}" rev-list ${BASE_TAG}..HEAD | tac); do
|
||||
filename="$(printf "%03d" $i)-$(git -C "${TMP_REPODIR}" log --format=%s -n 1 $cid | sed -e"s/[()']//g" -e's/[^_a-zA-Z0-9+-]\+/-/g' -e's/-$//').patch"
|
||||
printf "Creating ${filename}\n"
|
||||
git -C "${TMP_REPODIR}" show $cid > "${PATCHESDIR}/$filename"
|
||||
git add "${PATCHESDIR}/$filename"
|
||||
let i++
|
||||
done
|
||||
|
||||
rm -rf "${TMP_REPODIR}"
|
||||
|
||||
printf "finished\n"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
commit cf2f1243373be97249567ffd259e975cc87068b8
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Mon Apr 29 13:12:02 2019 +0200
|
||||
|
||||
BUG/MINOR: http: Call stream_inc_be_http_req_ctr() only one time per request
|
||||
|
||||
The function stream_inc_be_http_req_ctr() is called at the beginning of the
|
||||
analysers AN_REQ_HTTP_PROCESS_FE/BE. It as an effect only on the backend. But we
|
||||
must be careful to call it only once. If the processing of HTTP rules is
|
||||
interrupted in the middle, when the analyser is resumed, we must not call it
|
||||
again. Otherwise, the tracked counters of the backend are incremented several
|
||||
times.
|
||||
|
||||
This bug was reported in github. See issue #74.
|
||||
|
||||
This fix should be backported as far as 1.6.
|
||||
|
||||
(cherry picked from commit 1907ccc2f75b78ace1ee4acdfc60d48a76e3decd)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 319921866ea9ecc46215fea5679abc8efdfcbea5)
|
||||
[cf: HTX part was removed]
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index ccacd6a4..556cabad 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -3420,8 +3420,10 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
|
||||
req->buf->i,
|
||||
req->analysers);
|
||||
|
||||
- /* just in case we have some per-backend tracking */
|
||||
- stream_inc_be_http_req_ctr(s);
|
||||
+ /* just in case we have some per-backend tracking. Only called the first
|
||||
+ * execution of the analyser. */
|
||||
+ if (!s->current_rule || s->current_rule_list != &px->http_req_rules)
|
||||
+ stream_inc_be_http_req_ctr(s);
|
||||
|
||||
/* evaluate http-request rules */
|
||||
if (!LIST_ISEMPTY(&px->http_req_rules)) {
|
|
@ -1,61 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
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
|
||||
@@ -6565,8 +6565,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);
|
||||
@@ -6610,8 +6610,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)
|
||||
@@ -6636,9 +6636,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;
|
||||
@@ -6661,8 +6660,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)
|
||||
@@ -6732,8 +6731,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)
|
||||
@@ -6758,9 +6757,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;
|
||||
@@ -6902,9 +6900,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
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
commit c1620a52a3def02b4837376385c416c03ca874c4
|
||||
Author: Kevin Zhu <ipandtcp@gmail.com>
|
||||
Date: Fri Apr 26 14:00:01 2019 +0800
|
||||
|
||||
BUG/MEDIUM: spoe: arg len encoded in previous frag frame but len changed
|
||||
|
||||
Fragmented arg will do fetch at every encode time, each fetch may get
|
||||
different result if SMP_F_MAY_CHANGE, for example res.payload, but
|
||||
the length already encoded in first fragment of the frame, that will
|
||||
cause SPOA decode failed and waste resources.
|
||||
|
||||
This patch must be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit f7f54280c8106e92a55243f5d60f8587e79602d1)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 3a838e526cdbc00ded5362e66f1ef3a441abc3c1)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/proto/spoe.h b/include/proto/spoe.h
|
||||
index 002cf7d7..2cdca10b 100644
|
||||
--- a/include/proto/spoe.h
|
||||
+++ b/include/proto/spoe.h
|
||||
@@ -121,7 +121,7 @@ spoe_decode_buffer(char **buf, char *end, char **str, uint64_t *len)
|
||||
* many bytes has been encoded. If <*off> is zero at the end, it means that all
|
||||
* data has been encoded. */
|
||||
static inline int
|
||||
-spoe_encode_data(struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
+spoe_encode_data(unsigned int *len, struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
{
|
||||
char *p = *buf;
|
||||
int ret;
|
||||
@@ -183,15 +183,16 @@ spoe_encode_data(struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
ret = spoe_encode_frag_buffer(chk->str, chk->len, &p, end);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
+ *len = chk->len;
|
||||
}
|
||||
else {
|
||||
/* The sample has been fragmented, encode remaining data */
|
||||
- ret = MIN(chk->len - *off, end - p);
|
||||
+ ret = MIN(*len - *off, end - p);
|
||||
memcpy(p, chk->str + *off, ret);
|
||||
p += ret;
|
||||
}
|
||||
/* Now update <*off> */
|
||||
- if (ret + *off != chk->len)
|
||||
+ if (ret + *off != *len)
|
||||
*off += ret;
|
||||
else
|
||||
*off = 0;
|
||||
diff --git a/include/types/spoe.h b/include/types/spoe.h
|
||||
index 53e7200c..cfaa42f8 100644
|
||||
--- a/include/types/spoe.h
|
||||
+++ b/include/types/spoe.h
|
||||
@@ -304,6 +304,7 @@ struct spoe_context {
|
||||
struct spoe_message *curmsg; /* SPOE message from which to resume encoding */
|
||||
struct spoe_arg *curarg; /* SPOE arg in <curmsg> from which to resume encoding */
|
||||
unsigned int curoff; /* offset in <curarg> from which to resume encoding */
|
||||
+ unsigned int curlen; /* length of <curarg> need to be encode, for SMP_F_MAY_CHANGE data */
|
||||
unsigned int flags; /* SPOE_FRM_FL_* */
|
||||
} frag_ctx; /* Info about fragmented frames, valid on if SPOE_CTX_FL_FRAGMENTED is set */
|
||||
};
|
||||
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
|
||||
index f6109778..0c0b3794 100644
|
||||
--- a/src/flt_spoe.c
|
||||
+++ b/src/flt_spoe.c
|
||||
@@ -2172,6 +2172,7 @@ spoe_encode_message(struct stream *s, struct spoe_context *ctx,
|
||||
list_for_each_entry(arg, &msg->args, list) {
|
||||
ctx->frag_ctx.curarg = arg;
|
||||
ctx->frag_ctx.curoff = UINT_MAX;
|
||||
+ ctx->frag_ctx.curlen = 0;
|
||||
|
||||
encode_argument:
|
||||
if (ctx->frag_ctx.curoff != UINT_MAX)
|
||||
@@ -2186,7 +2187,7 @@ spoe_encode_message(struct stream *s, struct spoe_context *ctx,
|
||||
|
||||
/* Fetch the arguement value */
|
||||
smp = sample_process(s->be, s->sess, s, dir|SMP_OPT_FINAL, arg->expr, NULL);
|
||||
- ret = spoe_encode_data(smp, &ctx->frag_ctx.curoff, buf, end);
|
||||
+ ret = spoe_encode_data(&ctx->frag_ctx.curlen, smp, &ctx->frag_ctx.curoff, buf, end);
|
||||
if (ret == -1 || ctx->frag_ctx.curoff)
|
||||
goto too_big;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
commit 72fdff1fdb5b82685dc3d2db23ece042195a0cbd
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Fri Apr 26 14:30:15 2019 +0200
|
||||
|
||||
MINOR: spoe: Use the sample context to pass frag_ctx info during encoding
|
||||
|
||||
This simplifies the API and hide the details in the sample. This way, only
|
||||
string and binary are aware of these info, because other types cannot be
|
||||
partially encoded.
|
||||
|
||||
This patch may be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit 85db3212b87b33f1a39a688546f4f53a5c4ba4da)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit b93366e3ee44f5de93f01569fcdcd602f6d0703f)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/proto/spoe.h b/include/proto/spoe.h
|
||||
index 2cdca10b..cce13e50 100644
|
||||
--- a/include/proto/spoe.h
|
||||
+++ b/include/proto/spoe.h
|
||||
@@ -117,11 +117,9 @@ spoe_decode_buffer(char **buf, char *end, char **str, uint64_t *len)
|
||||
*
|
||||
* If the value is too big to be encoded, depending on its type, then encoding
|
||||
* failed or the value is partially encoded. Only strings and binaries can be
|
||||
- * partially encoded. In this case, the offset <*off> is updated to known how
|
||||
- * many bytes has been encoded. If <*off> is zero at the end, it means that all
|
||||
- * data has been encoded. */
|
||||
+ * partially encoded. */
|
||||
static inline int
|
||||
-spoe_encode_data(unsigned int *len, struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
+spoe_encode_data(struct sample *smp, char **buf, char *end)
|
||||
{
|
||||
char *p = *buf;
|
||||
int ret;
|
||||
@@ -164,12 +162,16 @@ spoe_encode_data(unsigned int *len, struct sample *smp, unsigned int *off, char
|
||||
|
||||
case SMP_T_STR:
|
||||
case SMP_T_BIN: {
|
||||
+ /* If defined, get length and offset of the sample by reading the sample
|
||||
+ * context. ctx.a[0] is the pointer to the length and ctx.a[1] is the
|
||||
+ * pointer to the offset. If the offset is greater than 0, it means the
|
||||
+ * sample is partially encoded. In this case, we only need to encode the
|
||||
+ * reamining. When all the sample is encoded, the offset is reset to 0.
|
||||
+ * So the caller know it can try to encode the next sample. */
|
||||
struct chunk *chk = &smp->data.u.str;
|
||||
+ unsigned int *len = (smp->ctx.a[0] ? smp->ctx.a[0] : 0);
|
||||
+ unsigned int *off = (smp->ctx.a[1] ? smp->ctx.a[1] : 0);
|
||||
|
||||
- /* Here, we need to know if the sample has already been
|
||||
- * partially encoded. If yes, we only need to encode the
|
||||
- * remaining, <*off> reprensenting the number of bytes
|
||||
- * already encoded. */
|
||||
if (!*off) {
|
||||
/* First evaluation of the sample : encode the
|
||||
* type (string or binary), the buffer length
|
||||
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
|
||||
index 0c0b3794..66d8b045 100644
|
||||
--- a/src/flt_spoe.c
|
||||
+++ b/src/flt_spoe.c
|
||||
@@ -2187,7 +2187,9 @@ spoe_encode_message(struct stream *s, struct spoe_context *ctx,
|
||||
|
||||
/* Fetch the arguement value */
|
||||
smp = sample_process(s->be, s->sess, s, dir|SMP_OPT_FINAL, arg->expr, NULL);
|
||||
- ret = spoe_encode_data(&ctx->frag_ctx.curlen, smp, &ctx->frag_ctx.curoff, buf, end);
|
||||
+ smp->ctx.a[0] = &ctx->frag_ctx.curlen;
|
||||
+ smp->ctx.a[1] = &ctx->frag_ctx.curoff;
|
||||
+ ret = spoe_encode_data(smp, buf, end);
|
||||
if (ret == -1 || ctx->frag_ctx.curoff)
|
||||
goto too_big;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
commit dfc3718f0a302ea3deb5f1a325d35fce0e4cfa48
|
||||
Author: Yann Cézard <ycezard@viareport.com>
|
||||
Date: Thu Apr 25 14:48:38 2019 +0200
|
||||
|
||||
DOC: contrib/modsecurity: Typos and fix the reject example
|
||||
|
||||
Thanks to https://www.mail-archive.com/haproxy@formilux.org/msg30056.html
|
||||
|
||||
This patch may be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit 494ddbff478d880e48de490f2689607addac70bc)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 850896603086877641272d6e4075e66bd91f2e50)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/contrib/modsecurity/README b/contrib/modsecurity/README
|
||||
index e6cb305e..8031389d 100644
|
||||
--- a/contrib/modsecurity/README
|
||||
+++ b/contrib/modsecurity/README
|
||||
@@ -88,15 +88,15 @@ HAProxy configuration. For example:
|
||||
balance roundrobin
|
||||
timeout connect 5s
|
||||
timeout server 3m
|
||||
- server iprep1 127.0.0.1:12345
|
||||
+ server modsec1 127.0.0.1:12345
|
||||
|
||||
The modsecurity action is returned in a variable called txn.modsec.code. It
|
||||
contains the HTTP returned code. If the variable contains 0, the request is
|
||||
clean.
|
||||
|
||||
- tcp-request content reject if { var(txn.modsec.code) -m int gt 0 }
|
||||
+ http-request deny if { var(txn.modsec.code) -m int gt 0 }
|
||||
|
||||
-With this rule, all the request not clean are reected.
|
||||
+With this rule, all the request not clean are rejected.
|
||||
|
||||
|
||||
Known bugs, limitations and TODO list
|
|
@ -0,0 +1,36 @@
|
|||
commit 95cf225d099dcb49eefcf4f5b648be604414ae0c
|
||||
Author: Yann Cézard <ycezard@viareport.com>
|
||||
Date: Thu Apr 25 14:30:23 2019 +0200
|
||||
|
||||
BUG/MEDIUM: contrib/modsecurity: If host header is NULL, don't try to strdup it
|
||||
|
||||
I discovered this bug when running OWASP regression tests against HAProxy +
|
||||
modsecurity-spoa (it's a POC to evaluate how it is working). I found out that
|
||||
modsecurity spoa will crash when the request doesn't have any Host header.
|
||||
|
||||
See the pull request #86 on github for details.
|
||||
|
||||
This patch must be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit bf60f6b8033deddc86de5357d6099c7593fe44cc)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit d988e3dddcbe1f48f3b24d1bb529fc9ecefde180)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/contrib/modsecurity/modsec_wrapper.c b/contrib/modsecurity/modsec_wrapper.c
|
||||
index 271ec15d..2f3987b4 100644
|
||||
--- a/contrib/modsecurity/modsec_wrapper.c
|
||||
+++ b/contrib/modsecurity/modsec_wrapper.c
|
||||
@@ -325,7 +325,11 @@ int modsecurity_process(struct worker *worker, struct modsecurity_parameters *pa
|
||||
req->content_type = apr_table_get(req->headers_in, "Content-Type");
|
||||
req->content_encoding = apr_table_get(req->headers_in, "Content-Encoding");
|
||||
req->hostname = apr_table_get(req->headers_in, "Host");
|
||||
- req->parsed_uri.hostname = chunk_strdup(req, req->hostname, strlen(req->hostname));
|
||||
+ if (req->hostname != NULL) {
|
||||
+ req->parsed_uri.hostname = chunk_strdup(req, req->hostname, strlen(req->hostname));
|
||||
+ } else {
|
||||
+ req->parsed_uri.hostname = NULL;
|
||||
+ }
|
||||
|
||||
lang = apr_table_get(req->headers_in, "Content-Languages");
|
||||
if (lang != NULL) {
|
|
@ -0,0 +1,23 @@
|
|||
commit 86860896dc1841eb59cb95832d76a8093e8dc8c5
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue Apr 30 10:55:38 2019 +0200
|
||||
|
||||
MINOR: examples: Use right locale for the last changelog date in haproxy.spec
|
||||
|
||||
The last changelog entry was stamped with the wrong locale.
|
||||
|
||||
No need to backport, it is specific to 1.8
|
||||
|
||||
diff --git a/examples/haproxy.spec b/examples/haproxy.spec
|
||||
index f3e0c7e0..fe5215d7 100644
|
||||
--- a/examples/haproxy.spec
|
||||
+++ b/examples/haproxy.spec
|
||||
@@ -74,7 +74,7 @@ fi
|
||||
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
|
||||
|
||||
%changelog
|
||||
-* jeu. avril 25 2019 Christopher Faulet <cfaulet@haproxy.com>
|
||||
+* Thu Apr 25 2019 Christopher Faulet <cfaulet@haproxy.com>
|
||||
- updated to 1.8.20
|
||||
|
||||
* Mon Feb 11 2019 Willy Tarreau <w@1wt.eu>
|
|
@ -0,0 +1,67 @@
|
|||
commit 83af1f6b65806982640679823228976deebf5202
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue Apr 30 11:43:43 2019 +0200
|
||||
|
||||
BUG/MAJOR: map/acl: real fix segfault during show map/acl on CLI
|
||||
|
||||
A previous commit 8d85aa44d ("BUG/MAJOR: map: fix segfault during
|
||||
'show map/acl' on cli.") was provided to address a concurrency issue
|
||||
between "show acl" and "clear acl" on the CLI. Sadly the code placed
|
||||
there was copy-pasted without changing the element type (which was
|
||||
struct stream in the original code) and not tested since the crash
|
||||
is still present.
|
||||
|
||||
The reproducer is simple : load a large ACL file (e.g. geolocation
|
||||
addresses), issue "show acl #0" in loops in one window and issue a
|
||||
"clear acl #0" in the other one, haproxy crashes.
|
||||
|
||||
This fix was also tested with threads enabled and looks good since
|
||||
the locking seems to work correctly in these areas though. It will
|
||||
have to be backported as far as 1.6 since the commit above went
|
||||
that far as well...
|
||||
|
||||
(cherry picked from commit 49ee3b2f9a9e5d0b8d394938df527aa645ce72b4)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit ac4be10f62ef72962d9cf0e6f2619e1e1c370d62)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/pattern.c b/src/pattern.c
|
||||
index 7eea9d96..21639569 100644
|
||||
--- a/src/pattern.c
|
||||
+++ b/src/pattern.c
|
||||
@@ -1651,7 +1651,7 @@ int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt)
|
||||
LIST_DEL(&bref->users);
|
||||
LIST_INIT(&bref->users);
|
||||
if (elt->list.n != &ref->head)
|
||||
- LIST_ADDQ(&LIST_ELEM(elt->list.n, struct stream *, list)->back_refs, &bref->users);
|
||||
+ LIST_ADDQ(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
|
||||
bref->ref = elt->list.n;
|
||||
}
|
||||
list_for_each_entry(expr, &ref->pat, list)
|
||||
@@ -1691,7 +1691,7 @@ int pat_ref_delete(struct pat_ref *ref, const char *key)
|
||||
LIST_DEL(&bref->users);
|
||||
LIST_INIT(&bref->users);
|
||||
if (elt->list.n != &ref->head)
|
||||
- LIST_ADDQ(&LIST_ELEM(elt->list.n, struct stream *, list)->back_refs, &bref->users);
|
||||
+ LIST_ADDQ(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
|
||||
bref->ref = elt->list.n;
|
||||
}
|
||||
list_for_each_entry(expr, &ref->pat, list)
|
||||
@@ -2086,7 +2086,7 @@ void pat_ref_reload(struct pat_ref *ref, struct pat_ref *replace)
|
||||
LIST_DEL(&bref->users);
|
||||
LIST_INIT(&bref->users);
|
||||
if (elt->list.n != &ref->head)
|
||||
- LIST_ADDQ(&LIST_ELEM(elt->list.n, struct stream *, list)->back_refs, &bref->users);
|
||||
+ LIST_ADDQ(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
|
||||
bref->ref = elt->list.n;
|
||||
}
|
||||
LIST_DEL(&elt->list);
|
||||
@@ -2175,7 +2175,7 @@ void pat_ref_prune(struct pat_ref *ref)
|
||||
LIST_DEL(&bref->users);
|
||||
LIST_INIT(&bref->users);
|
||||
if (elt->list.n != &ref->head)
|
||||
- LIST_ADDQ(&LIST_ELEM(elt->list.n, struct stream *, list)->back_refs, &bref->users);
|
||||
+ LIST_ADDQ(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
|
||||
bref->ref = elt->list.n;
|
||||
}
|
||||
LIST_DEL(&elt->list);
|
|
@ -0,0 +1,79 @@
|
|||
commit 7bd7a8d2b8889f604b807c21190d2e70328d6674
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue Apr 30 12:17:13 2019 +0200
|
||||
|
||||
BUG/MEDIUM: listener: Fix how unlimited number of consecutive accepts is handled
|
||||
|
||||
There is a bug when global.tune.maxaccept is set to -1 (no limit). It is pretty
|
||||
visible with one process (nbproc sets to 1). The functions listener_accept() and
|
||||
accept_queue_process() don't expect to handle negative maxaccept values. So
|
||||
instead of accepting incoming connections without any limit, none are never
|
||||
accepted and HAProxy loop infinitly in the scheduler.
|
||||
|
||||
When there are 2 or more processes, the bug is a bit more subtile. The limit for
|
||||
a listener is set to 1. So only one connection is accepted at a time by a given
|
||||
listener. This happens because the listener's maxaccept value is an unsigned
|
||||
integer. In check_config_validity(), it is first set to UINT_MAX (-1 casted in
|
||||
an unsigned integer), and then some calculations on it leads to an integer
|
||||
overflow.
|
||||
|
||||
To fix the bug, the listener's maxaccept value is now a signed integer. So, if a
|
||||
negative value is set for global.tune.maxaccept, we keep it untouched for the
|
||||
listener and no calculation is made on it. Then, in the listener code, this
|
||||
signed value is casted to a unsigned one. It simplifies all tests instead of
|
||||
dealing with negative values. So, it limits the number of connections accepted
|
||||
at a time to UINT_MAX at most. But, honestly, it not an issue.
|
||||
|
||||
This patch must be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit 102854cbbaa4d22466dddec9035d411db244082f)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit bca4fb2d9d7f2966d9f8270fa1796fdc0dfc866d)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/types/listener.h b/include/types/listener.h
|
||||
index ea2eadb5..16ef6d7a 100644
|
||||
--- a/include/types/listener.h
|
||||
+++ b/include/types/listener.h
|
||||
@@ -196,7 +196,7 @@ struct listener {
|
||||
int nbconn; /* current number of connections on this listener */
|
||||
int maxconn; /* maximum connections allowed on this listener */
|
||||
unsigned int backlog; /* if set, listen backlog */
|
||||
- unsigned int maxaccept; /* if set, max number of connections accepted at once */
|
||||
+ int maxaccept; /* if set, max number of connections accepted at once (-1 when disabled) */
|
||||
struct list proto_list; /* list in the protocol header */
|
||||
int (*accept)(struct listener *l, int fd, struct sockaddr_storage *addr); /* upper layer's accept() */
|
||||
enum obj_type *default_target; /* default target to use for accepted sessions or NULL */
|
||||
diff --git a/src/listener.c b/src/listener.c
|
||||
index 821c931a..74990c45 100644
|
||||
--- a/src/listener.c
|
||||
+++ b/src/listener.c
|
||||
@@ -406,7 +406,7 @@ void listener_accept(int fd)
|
||||
{
|
||||
struct listener *l = fdtab[fd].owner;
|
||||
struct proxy *p;
|
||||
- int max_accept;
|
||||
+ unsigned int max_accept;
|
||||
int next_conn = 0;
|
||||
int next_feconn = 0;
|
||||
int next_actconn = 0;
|
||||
@@ -420,6 +420,10 @@ void listener_accept(int fd)
|
||||
if (!l)
|
||||
return;
|
||||
p = l->bind_conf->frontend;
|
||||
+
|
||||
+ /* if l->maxaccept is -1, then max_accept is UINT_MAX. It is not really
|
||||
+ * illimited, but it is probably enough.
|
||||
+ */
|
||||
max_accept = l->maxaccept ? l->maxaccept : 1;
|
||||
|
||||
if (!(l->options & LI_O_UNLIMITED) && global.sps_lim) {
|
||||
@@ -480,7 +484,7 @@ void listener_accept(int fd)
|
||||
* worst case. If we fail due to system limits or temporary resource
|
||||
* shortage, we try again 100ms later in the worst case.
|
||||
*/
|
||||
- for (; max_accept-- > 0; next_conn = next_feconn = next_actconn = 0) {
|
||||
+ for (; max_accept; next_conn = next_feconn = next_actconn = 0, max_accept--) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t laddr = sizeof(addr);
|
||||
unsigned int count;
|
|
@ -0,0 +1,44 @@
|
|||
commit 6e580b6e744011e87c337ebe2c082acfd5ca835a
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue Apr 30 14:03:56 2019 +0200
|
||||
|
||||
MINOR: config: Test validity of tune.maxaccept during the config parsing
|
||||
|
||||
Only -1 and positive integers from 0 to INT_MAX are accepted. An error is
|
||||
triggered during the config parsing for any other values.
|
||||
|
||||
This patch may be backported to all supported versions.
|
||||
|
||||
(cherry picked from commit 6b02ab87348090efec73b1dd24f414239669f279)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 2bbc40f8bc9a52ba0d03b25270ac0129cca29bba)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index c178538b..8e325416 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -789,6 +789,8 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
global.tune.maxpollevents = atol(args[1]);
|
||||
}
|
||||
else if (!strcmp(args[0], "tune.maxaccept")) {
|
||||
+ long max;
|
||||
+
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
if (global.tune.maxaccept != 0) {
|
||||
@@ -801,7 +803,13 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
- global.tune.maxaccept = atol(args[1]);
|
||||
+ max = atol(args[1]);
|
||||
+ if (/*max < -1 || */max > INT_MAX) {
|
||||
+ ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
|
||||
+ err_code |= ERR_ALERT | ERR_FATAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ global.tune.maxaccept = max;
|
||||
}
|
||||
else if (!strcmp(args[0], "tune.chksize")) {
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
|
@ -0,0 +1,34 @@
|
|||
commit c6e03c1495fa51f9a98ed0bbe3230313c7c7201c
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue Apr 30 14:08:41 2019 +0200
|
||||
|
||||
CLEANUP: config: Don't alter listener->maxaccept when nbproc is set to 1
|
||||
|
||||
This patch only removes a useless calculation on listener->maxaccept when nbproc
|
||||
is set to 1. Indeed, the following formula has no effet in such case:
|
||||
|
||||
listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
|
||||
|
||||
This patch may be backported as far as 1.5.
|
||||
|
||||
(cherry picked from commit 02f3cf19ed803d20aff9294ce7cb732489951ff5)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 14203e3cf9404e57de5e274b453f0fe4f2174924)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 8e325416..3f6ea352 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -9018,9 +9018,8 @@ out_uri_auth_compat:
|
||||
* is bound to. Rememeber that maxaccept = -1 must be kept as it is
|
||||
* used to disable the limit.
|
||||
*/
|
||||
- if (listener->maxaccept > 0) {
|
||||
- if (nbproc > 1)
|
||||
- listener->maxaccept = (listener->maxaccept + 1) / 2;
|
||||
+ if (listener->maxaccept > 0 && nbproc > 1) {
|
||||
+ listener->maxaccept = (listener->maxaccept + 1) / 2;
|
||||
listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
commit f95cf6ad70565ee2322cf23bc519b7bb0b3831b2
|
||||
Author: Olivier Houchard <ohouchard@haproxy.com>
|
||||
Date: Tue Apr 30 13:38:02 2019 +0200
|
||||
|
||||
MINOR: threads: Implement HA_ATOMIC_LOAD().
|
||||
|
||||
The same way we have HA_ATOMIC_STORE(), implement HA_ATOMIC_LOAD().
|
||||
|
||||
This should be backported to 1.8 and 1.9, as we need it for a bug fix
|
||||
in port ranges.
|
||||
|
||||
(cherry picked from commit 9ce62b5498b27fbf4217d9c25779d5b2ceca23f2)
|
||||
Signed-off-by: Olivier Houchard <cognet@ci0.org>
|
||||
(cherry picked from commit 358c979611370fa2bc3b8e47ed50a325cf9126cf)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/common/hathreads.h b/include/common/hathreads.h
|
||||
index 8134839a..11d7cab6 100644
|
||||
--- a/include/common/hathreads.h
|
||||
+++ b/include/common/hathreads.h
|
||||
@@ -62,6 +62,7 @@ enum { tid = 0 };
|
||||
*(val) = new; \
|
||||
__old_xchg; \
|
||||
})
|
||||
+#define HA_ATOMIC_LOAD(val) *(val)
|
||||
#define HA_ATOMIC_STORE(val, new) ({*(val) = new;})
|
||||
#define HA_ATOMIC_UPDATE_MAX(val, new) \
|
||||
({ \
|
||||
@@ -203,6 +204,16 @@ static inline unsigned long thread_isolated()
|
||||
} while (!__sync_bool_compare_and_swap(__val_xchg, __old_xchg, __new_xchg)); \
|
||||
__old_xchg; \
|
||||
})
|
||||
+
|
||||
+#define HA_ATOMIC_LOAD(val) \
|
||||
+ ({ \
|
||||
+ typeof(*(val)) ret; \
|
||||
+ __sync_synchronize(); \
|
||||
+ ret = *(volatile typeof(val))val; \
|
||||
+ __sync_synchronize(); \
|
||||
+ ret; \
|
||||
+ })
|
||||
+
|
||||
#define HA_ATOMIC_STORE(val, new) \
|
||||
({ \
|
||||
typeof((val)) __val_store = (val); \
|
||||
@@ -221,6 +232,8 @@ static inline unsigned long thread_isolated()
|
||||
#define HA_ATOMIC_OR(val, flags) __atomic_or_fetch(val, flags, __ATOMIC_SEQ_CST)
|
||||
#define HA_ATOMIC_XCHG(val, new) __atomic_exchange_n(val, new, __ATOMIC_SEQ_CST)
|
||||
#define HA_ATOMIC_STORE(val, new) __atomic_store_n(val, new, __ATOMIC_SEQ_CST)
|
||||
+#define HA_ATOMIC_LOAD(val) __atomic_load_n(val, __ATOMIC_SEQ_CST)
|
||||
+
|
||||
#endif
|
||||
|
||||
#define HA_ATOMIC_UPDATE_MAX(val, new) \
|
|
@ -0,0 +1,116 @@
|
|||
commit 31470e2ba2aabb4c6340fbc15cb5486ceb8c69c8
|
||||
Author: Olivier Houchard <ohouchard@haproxy.com>
|
||||
Date: Mon Apr 29 18:52:06 2019 +0200
|
||||
|
||||
BUG/MEDIUM: port_range: Make the ring buffer lock-free.
|
||||
|
||||
Port range uses a ring buffer, and unfortunately, when making haproxy
|
||||
multithreaded, it's been overlooked, and the ring buffer is not thread-safe.
|
||||
When specifying a source range, 2 or more threads could pick the same
|
||||
port, and of course only one of them could use the port, the others would
|
||||
always fail the connection.
|
||||
To fix this, make it a lock-free ring buffer. This is easier than usual
|
||||
because we know the ring buffer can never be full.
|
||||
|
||||
This should be backported to 1.8 and 1.9.
|
||||
|
||||
(cherry picked from commit 07425de71777b688e77a9c70a7088c13e66e41e9)
|
||||
Signed-off-by: Olivier Houchard <cognet@ci0.org>
|
||||
(cherry picked from commit bffb51147a4a5939e344b3c838628f9a944febef)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/proto/port_range.h b/include/proto/port_range.h
|
||||
index 8c63faca..f7e3f1d5 100644
|
||||
--- a/include/proto/port_range.h
|
||||
+++ b/include/proto/port_range.h
|
||||
@@ -24,18 +24,22 @@
|
||||
|
||||
#include <types/port_range.h>
|
||||
|
||||
+#define GET_NEXT_OFF(range, off) ((off) == (range)->size - 1 ? 0 : (off) + 1)
|
||||
+
|
||||
/* return an available port from range <range>, or zero if none is left */
|
||||
static inline int port_range_alloc_port(struct port_range *range)
|
||||
{
|
||||
int ret;
|
||||
+ int get;
|
||||
+ int put;
|
||||
|
||||
- if (!range->avail)
|
||||
- return 0;
|
||||
- ret = range->ports[range->get];
|
||||
- range->get++;
|
||||
- if (range->get >= range->size)
|
||||
- range->get = 0;
|
||||
- range->avail--;
|
||||
+ get = HA_ATOMIC_LOAD(&range->get);
|
||||
+ do {
|
||||
+ put = HA_ATOMIC_LOAD(&range->put_t);
|
||||
+ if (unlikely(put == get))
|
||||
+ return 0;
|
||||
+ ret = range->ports[get];
|
||||
+ } while (!(HA_ATOMIC_CAS(&range->get, &get, GET_NEXT_OFF(range, get))));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -45,14 +49,28 @@ static inline int port_range_alloc_port(struct port_range *range)
|
||||
*/
|
||||
static inline void port_range_release_port(struct port_range *range, int port)
|
||||
{
|
||||
+ int put;
|
||||
+
|
||||
if (!port || !range)
|
||||
return;
|
||||
|
||||
- range->ports[range->put] = port;
|
||||
- range->avail++;
|
||||
- range->put++;
|
||||
- if (range->put >= range->size)
|
||||
- range->put = 0;
|
||||
+ put = range->put_h;
|
||||
+ /* put_h is reserved for producers, so that they can each get a
|
||||
+ * free slot, put_t is what is used by consumers to know if there's
|
||||
+ * elements available or not
|
||||
+ */
|
||||
+ /* First reserve or slot, we know the ring buffer can't be full,
|
||||
+ * as we will only ever release port we allocated before
|
||||
+ */
|
||||
+ while (!(HA_ATOMIC_CAS(&range->put_h, &put, GET_NEXT_OFF(range, put))));
|
||||
+ HA_ATOMIC_STORE(&range->ports[put], port);
|
||||
+ /* Wait until all the threads that got a slot before us are done */
|
||||
+ while ((volatile int)range->put_t != put)
|
||||
+ __ha_compiler_barrier();
|
||||
+ /* Let the world know we're done, and any potential consumer they
|
||||
+ * can use that port.
|
||||
+ */
|
||||
+ HA_ATOMIC_STORE(&range->put_t, GET_NEXT_OFF(range, put));
|
||||
}
|
||||
|
||||
/* return a new initialized port range of N ports. The ports are not
|
||||
@@ -62,8 +80,10 @@ static inline struct port_range *port_range_alloc_range(int n)
|
||||
{
|
||||
struct port_range *ret;
|
||||
ret = calloc(1, sizeof(struct port_range) +
|
||||
- n * sizeof(((struct port_range *)0)->ports[0]));
|
||||
- ret->size = ret->avail = n;
|
||||
+ (n + 1) * sizeof(((struct port_range *)0)->ports[0]));
|
||||
+ ret->size = n + 1;
|
||||
+ /* Start at the first free element */
|
||||
+ ret->put_h = ret->put_t = n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/include/types/port_range.h b/include/types/port_range.h
|
||||
index 1d010f77..33455d2d 100644
|
||||
--- a/include/types/port_range.h
|
||||
+++ b/include/types/port_range.h
|
||||
@@ -25,8 +25,7 @@
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct port_range {
|
||||
- int size, get, put; /* range size, and get/put positions */
|
||||
- int avail; /* number of available ports left */
|
||||
+ int size, get, put_h, put_t; /* range size, and get/put positions */
|
||||
uint16_t ports[0]; /* array of <size> ports, in host byte order */
|
||||
};
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
commit ef9cafc46c13eea2db65152e452607a6566cbeac
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Thu May 16 10:07:30 2019 +0200
|
||||
|
||||
BUG/MINOR: http_fetch: Rely on the smp direction for "cookie()" and "hdr()"
|
||||
|
||||
A regression was introduced in the commit 89dc49935 ("BUG/MAJOR: http_fetch: Get
|
||||
the channel depending on the keyword used") on the samples "cookie()" and
|
||||
"hdr()". Unlike other samples manipulating the HTTP headers, these ones depend
|
||||
on the sample direction. To fix the bug, these samples use now their own
|
||||
functions. Depending on the sample direction, they call smp_fetch_cookie() and
|
||||
smp_fetch_hdr() with the appropriate keyword.
|
||||
|
||||
Thanks to Yves Lafon to report this issue.
|
||||
|
||||
This patch must be backported wherever the commit 89dc49935 was backported. For
|
||||
now, 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit c1f40dd4920050ec5a83b2a5d22a3eb4e4be425a)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 5eaf770abfce56951202cb1ea55a968f5ec8be71)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index 556cabad..32aeef2d 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -10218,6 +10218,17 @@ smp_fetch_hdr(const struct arg *args, struct sample *smp, const char *kw, void *
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Same than smp_fetch_hdr() but only relies on the sample direction to choose
|
||||
+ * the right channel. So instead of duplicating the code, we just change the
|
||||
+ * keyword and then fallback on smp_fetch_hdr().
|
||||
+ */
|
||||
+static int
|
||||
+smp_fetch_chn_hdr(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
+{
|
||||
+ kw = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ ? "req.hdr" : "res.hdr");
|
||||
+ return smp_fetch_hdr(args, smp, kw, private);
|
||||
+}
|
||||
+
|
||||
/* 6. Check on HTTP header count. The number of occurrences is returned.
|
||||
* Accepts exactly 1 argument of type string.
|
||||
*/
|
||||
@@ -10935,6 +10946,17 @@ int smp_fetch_cookie(const struct arg *args, struct sample *smp, const char *kw,
|
||||
return found;
|
||||
}
|
||||
|
||||
+/* Same than smp_fetch_cookie() but only relies on the sample direction to
|
||||
+ * choose the right channel. So instead of duplicating the code, we just change
|
||||
+ * the keyword and then fallback on smp_fetch_cookie().
|
||||
+ */
|
||||
+static int
|
||||
+smp_fetch_chn_cookie(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
+{
|
||||
+ kw = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ ? "req.cook" : "res.cook");
|
||||
+ return smp_fetch_cookie(args, smp, kw, private);
|
||||
+}
|
||||
+
|
||||
/* Iterate over all cookies present in a request to count how many occurrences
|
||||
* match the name in args and args->data.str.len. If <multi> is non-null, then
|
||||
* multiple cookies may be parsed on the same line. The returned sample is of
|
||||
@@ -12855,7 +12877,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
* for ACL compatibility only.
|
||||
*/
|
||||
{ "cook", smp_fetch_cookie, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV },
|
||||
- { "cookie", smp_fetch_cookie, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV|SMP_USE_HRSHV },
|
||||
+ { "cookie", smp_fetch_chn_cookie, ARG1(0,STR), NULL, SMP_T_STR, SMP_USE_HRQHV|SMP_USE_HRSHV },
|
||||
{ "cook_cnt", smp_fetch_cookie_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
|
||||
{ "cook_val", smp_fetch_cookie_val, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
|
||||
|
||||
@@ -12863,7 +12885,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
* only here to match the ACL's name, are request-only and are used for
|
||||
* ACL compatibility only.
|
||||
*/
|
||||
- { "hdr", smp_fetch_hdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_HRQHV|SMP_USE_HRSHV },
|
||||
+ { "hdr", smp_fetch_chn_hdr, ARG2(0,STR,SINT), val_hdr, SMP_T_STR, SMP_USE_HRQHV|SMP_USE_HRSHV },
|
||||
{ "hdr_cnt", smp_fetch_hdr_cnt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_HRQHV },
|
||||
{ "hdr_ip", smp_fetch_hdr_ip, ARG2(0,STR,SINT), val_hdr, SMP_T_IPV4, SMP_USE_HRQHV },
|
||||
{ "hdr_val", smp_fetch_hdr_val, ARG2(0,STR,SINT), val_hdr, SMP_T_SINT, SMP_USE_HRQHV },
|
|
@ -0,0 +1,37 @@
|
|||
commit b50e7fe5e9ae7e8670a467fdd7ece2d08fc02809
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed May 22 20:07:45 2019 +0200
|
||||
|
||||
BUG/MEDIUM: dns: make the port numbers unsigned
|
||||
|
||||
Mustafa Yildirim reported in Discourse that ports >32767 advertised
|
||||
in SRV records are wrong. Given the high value they definitely
|
||||
correspond to a sign extension of a negative number. The cause was
|
||||
indeed that the port is declared as a signed int in the dns_answer_item
|
||||
structure, and Lukas confirmed in github issue #103 that turning it to
|
||||
unsigned addresses the issue.
|
||||
|
||||
It is worth noting that there are other such fields in this structure
|
||||
that don't look right (ttl, priority, class, type) and that someone
|
||||
should audit this part to be certain they are properly typed.
|
||||
|
||||
This fix must be backported to 1.9 and likely to 1.8 as well.
|
||||
|
||||
(cherry picked from commit d1f56c9a0110805c4a5f3afba2990556cb74ec8b)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 01ceb8a9fb0caecb20a12cc6763230cfc9895de5)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/types/dns.h b/include/types/dns.h
|
||||
index e8ab9f06..e2d98169 100644
|
||||
--- a/include/types/dns.h
|
||||
+++ b/include/types/dns.h
|
||||
@@ -144,7 +144,7 @@ struct dns_answer_item {
|
||||
int32_t ttl; /* response TTL */
|
||||
int16_t priority; /* SRV type priority */
|
||||
uint16_t weight; /* SRV type weight */
|
||||
- int16_t port; /* SRV type port */
|
||||
+ uint16_t port; /* SRV type port */
|
||||
uint16_t data_len; /* number of bytes in target below */
|
||||
struct sockaddr address; /* IPv4 or IPv6, network format */
|
||||
char target[DNS_MAX_NAME_SIZE+1]; /* Response data: SRV or CNAME type target */
|
|
@ -0,0 +1,44 @@
|
|||
commit 89ff157c3262c8493ed48e6ac48f614791f446f8
|
||||
Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Thu May 23 22:47:48 2019 +0200
|
||||
|
||||
BUG/MEDIUM: spoe: Don't use the SPOE applet after releasing it
|
||||
|
||||
In spoe_release_appctx(), the SPOE applet may be used after it was released to
|
||||
get its exit status code. Of course, HAProxy crashes when this happens.
|
||||
|
||||
This patch must be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit 55ae8a64e4e1175063463921375b279c31bbc6a4)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit df29d11f522044217ea7c1373f494c2a36515b31)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
|
||||
index 66d8b045..aeb1fde7 100644
|
||||
--- a/src/flt_spoe.c
|
||||
+++ b/src/flt_spoe.c
|
||||
@@ -1292,11 +1292,6 @@ spoe_release_appctx(struct appctx *appctx)
|
||||
task_wakeup(ctx->strm->task, TASK_WOKEN_MSG);
|
||||
}
|
||||
|
||||
- /* Release allocated memory */
|
||||
- spoe_release_buffer(&spoe_appctx->buffer,
|
||||
- &spoe_appctx->buffer_wait);
|
||||
- pool_free(pool_head_spoe_appctx, spoe_appctx);
|
||||
-
|
||||
if (!LIST_ISEMPTY(&agent->rt[tid].applets))
|
||||
goto end;
|
||||
|
||||
@@ -1317,6 +1312,11 @@ spoe_release_appctx(struct appctx *appctx)
|
||||
}
|
||||
|
||||
end:
|
||||
+ /* Release allocated memory */
|
||||
+ spoe_release_buffer(&spoe_appctx->buffer,
|
||||
+ &spoe_appctx->buffer_wait);
|
||||
+ pool_free(pool_head_spoe_appctx, spoe_appctx);
|
||||
+
|
||||
/* Update runtinme agent info */
|
||||
agent->rt[tid].frame_size = agent->max_frame_size;
|
||||
list_for_each_entry(spoe_appctx, &agent->rt[tid].applets, list)
|
925
net/haproxy/patches/015-DOC-fix-typos.patch
Normal file
925
net/haproxy/patches/015-DOC-fix-typos.patch
Normal file
|
@ -0,0 +1,925 @@
|
|||
commit 5aa7b32a94ad7ac38f465f0de279f09ff6d529d3
|
||||
Author: Michael Prokop <haproxy.org@michael-prokop.at>
|
||||
Date: Fri May 24 10:25:45 2019 +0200
|
||||
|
||||
DOC: fix typos
|
||||
|
||||
s/accidently/accidentally/
|
||||
s/any ot these messages/any of theses messages/
|
||||
s/catched/caught/
|
||||
s/completly/completely/
|
||||
s/convertor/converter/
|
||||
s/desribing/describing/
|
||||
s/developper/developer/
|
||||
s/eventhough/even though/
|
||||
s/exectution/execution/
|
||||
s/functionnality/functionality/
|
||||
s/If it receive a/If it receives a/
|
||||
s/In can even/It can even/
|
||||
s/informations/information/
|
||||
s/it will be remove /it will be removed /
|
||||
s/langage/language/
|
||||
s/mentionned/mentioned/
|
||||
s/negociated/negotiated/
|
||||
s/Optionnaly/Optionally/
|
||||
s/ouputs/outputs/
|
||||
s/outweights/outweighs/
|
||||
s/ressources/resources/
|
||||
|
||||
(cherry picked from commit 4438c6061d5a2ffd5b4251027038181af9b8dc22)
|
||||
[wt: removed the wurfl+da notes as well as the part on peers/server]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit a73e4f3d7a617a51551fffd80c5dbddee81e3aaf)
|
||||
[wt: removed a few other keywords like ssl_bc_alpn and show peers]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
diff --git a/doc/DeviceAtlas-device-detection.txt b/doc/DeviceAtlas-device-detection.txt
|
||||
index 4ecb44a4..144ee318 100644
|
||||
--- a/doc/DeviceAtlas-device-detection.txt
|
||||
+++ b/doc/DeviceAtlas-device-detection.txt
|
||||
@@ -39,7 +39,7 @@ All HTTP headers via the sample / fetch
|
||||
|
||||
http-request set-header X-DeviceAtlas-Data %[da-csv-fetch(primaryHardwareType,osName,osVersion,browserName,browserVersion,browserRenderingEngine)]
|
||||
|
||||
-Single HTTP header (e.g. User-Agent) via the convertor
|
||||
+Single HTTP header (e.g. User-Agent) via the converter
|
||||
|
||||
http-request set-header X-DeviceAtlas-Data %[req.fhdr(User-Agent),da-csv-conv(primaryHardwareType,osName,osVersion,browserName,browserVersion,browserRenderingEngine)]
|
||||
|
||||
diff --git a/doc/SPOE.txt b/doc/SPOE.txt
|
||||
index dd36d43a..9602df95 100644
|
||||
--- a/doc/SPOE.txt
|
||||
+++ b/doc/SPOE.txt
|
||||
@@ -96,7 +96,7 @@ for several engines. If no name is provided, the SPOE configuration must not
|
||||
contain any scope directive.
|
||||
|
||||
We use a separate configuration file on purpose. By commenting SPOE filter
|
||||
-line, you completly disable the feature, including the parsing of sections
|
||||
+line, you completely disable the feature, including the parsing of sections
|
||||
reserved to SPOE. This is also a way to keep the HAProxy configuration clean.
|
||||
|
||||
A SPOE configuration file must contains, at least, the SPOA configuration
|
||||
@@ -272,7 +272,7 @@ option set-on-error <var name>
|
||||
|
||||
* 1 a timeout occurred during the event processing.
|
||||
|
||||
- * 2 an error was triggered during the ressources allocation.
|
||||
+ * 2 an error was triggered during the resources allocation.
|
||||
|
||||
* 3 the frame payload exceeds the frame size and it cannot be
|
||||
fragmented.
|
||||
@@ -923,7 +923,7 @@ For more information about known errors, see section "Errors & timeouts"
|
||||
-------------------------------
|
||||
|
||||
If an error occurs, at anytime, from the agent size, a AGENT-DISCONNECT frame
|
||||
-is sent, with information desribing the error. such frame is also sent in reply
|
||||
+is sent, with information describing the error. such frame is also sent in reply
|
||||
to a HAPROXY-DISCONNECT. The agent must close the socket just after sending
|
||||
this frame.
|
||||
|
||||
diff --git a/doc/coding-style.txt b/doc/coding-style.txt
|
||||
index 5f252ed0..9f1bd79e 100644
|
||||
--- a/doc/coding-style.txt
|
||||
+++ b/doc/coding-style.txt
|
||||
@@ -520,7 +520,7 @@ Wrong :
|
||||
| bit = ! ! (~len++ ^ - (unsigned char) * x) ;
|
||||
|
||||
Note that "sizeof" is a unary operator which is sometimes considered as a
|
||||
-langage keyword, but in no case it is a function. It does not require
|
||||
+language keyword, but in no case it is a function. It does not require
|
||||
parenthesis so it is sometimes followed by spaces and sometimes not when
|
||||
there are no parenthesis. Most people do not really care as long as what
|
||||
is written is unambiguous.
|
||||
@@ -814,7 +814,7 @@ common to see such a thing :
|
||||
This is wrong. The man page says that -1 is returned if an error occurred. It
|
||||
does not suggest that any other negative value will be an error. It is possible
|
||||
that a few such issues have been left in existing code. They are bugs for which
|
||||
-fixes are accepted, eventhough they're currently harmless since open() is not
|
||||
+fixes are accepted, even though they're currently harmless since open() is not
|
||||
known for returning negative values at the moment.
|
||||
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index 863508f5..e044639a 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -3051,7 +3051,7 @@ cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
|
||||
|
||||
already have a cookie that would have permitted it to access this
|
||||
server. When used without the "preserve" option, if the server
|
||||
- emits a cookie with the same name, it will be remove before
|
||||
+ emits a cookie with the same name, it will be removed before
|
||||
processing. For this reason, this mode can be used to upgrade
|
||||
existing configurations running in the "rewrite" mode. The cookie
|
||||
will only be a session cookie and will not be stored on the
|
||||
@@ -4786,7 +4786,7 @@ http-reuse { never | safe | aggressive | always }
|
||||
proving that the server correctly supports connection reuse.
|
||||
It should only be used when it's sure that the client can
|
||||
retry a failed request once in a while and where the benefit
|
||||
- of aggressive connection reuse significantly outweights the
|
||||
+ of aggressive connection reuse significantly outweighs the
|
||||
downsides of rare connection failures.
|
||||
|
||||
- "always" : this mode is only recommended when the path to the server is
|
||||
diff --git a/doc/intro.txt b/doc/intro.txt
|
||||
index 7ad92db0..864fb8d6 100644
|
||||
--- a/doc/intro.txt
|
||||
+++ b/doc/intro.txt
|
||||
@@ -1481,7 +1481,7 @@ they are mentioned here even if not directly related to HAProxy.
|
||||
|
||||
Apache is the de-facto standard HTTP server. It's a very complete and modular
|
||||
project supporting both file serving and dynamic contents. It can serve as a
|
||||
-frontend for some application servers. In can even proxy requests and cache
|
||||
+frontend for some application servers. It can even proxy requests and cache
|
||||
responses. In all of these use cases, a front load balancer is commonly needed.
|
||||
Apache can work in various modes, some being heavier than others. Certain
|
||||
modules still require the heavier pre-forked model and will prevent Apache from
|
||||
diff --git a/doc/lua.txt b/doc/lua.txt
|
||||
index 7b257ad8..2e266b03 100644
|
||||
--- a/doc/lua.txt
|
||||
+++ b/doc/lua.txt
|
||||
@@ -412,7 +412,7 @@ The max amount of memory is configured with the option:
|
||||
tune.lua.maxmem
|
||||
|
||||
As many other script languages, Lua uses a garbage collector for reusing its
|
||||
-memory. The Lua developper can work without memory preoccupation. Usually, the
|
||||
+memory. The Lua developer can work without memory preoccupation. Usually, the
|
||||
garbage collector is controlled by the Lua core, but sometimes it will be useful
|
||||
to run when the user/developer requires. So the garbage collector can be called
|
||||
from C part or Lua part.
|
||||
@@ -885,7 +885,7 @@ The task entry point
|
||||
|
||||
The function "core.register_task(fcn)" executes once the function "fcn" when the
|
||||
scheduler starts. This way is used for executing background task. For example,
|
||||
-you can use this functionnality for periodically checking the health of another
|
||||
+you can use this functionality for periodically checking the health of another
|
||||
service, and giving the result to each proxy needing it.
|
||||
|
||||
The task is started once, if you want periodic actions, you can use the
|
||||
diff --git a/doc/management.txt b/doc/management.txt
|
||||
index 1b41558a..8fdea722 100644
|
||||
--- a/doc/management.txt
|
||||
+++ b/doc/management.txt
|
||||
@@ -1634,7 +1634,7 @@ set rate-limit ssl-sessions global <value>
|
||||
|
||||
set server <backend>/<server> addr <ip4 or ip6 address> [port <port>]
|
||||
Replace the current IP address of a server by the one provided.
|
||||
- Optionnaly, the port can be changed using the 'port' parameter.
|
||||
+ Optionally, the port can be changed using the 'port' parameter.
|
||||
Note that changing the port also support switching from/to port mapping
|
||||
(notation with +X or -Y), only if a port is configured for the health check.
|
||||
|
||||
diff --git a/doc/netscaler-client-ip-insertion-protocol.txt b/doc/netscaler-client-ip-insertion-protocol.txt
|
||||
index 559d98a8..dc64327a 100644
|
||||
--- a/doc/netscaler-client-ip-insertion-protocol.txt
|
||||
+++ b/doc/netscaler-client-ip-insertion-protocol.txt
|
||||
@@ -1,4 +1,4 @@
|
||||
-When NetScaler application switch is used as L3+ switch, informations
|
||||
+When NetScaler application switch is used as L3+ switch, information
|
||||
regarding the original IP and TCP headers are lost as a new TCP
|
||||
connection is created between the NetScaler and the backend server.
|
||||
|
||||
diff --git a/doc/peers-v2.0.txt b/doc/peers-v2.0.txt
|
||||
index a7f70dcc..02914743 100644
|
||||
--- a/doc/peers-v2.0.txt
|
||||
+++ b/doc/peers-v2.0.txt
|
||||
@@ -275,11 +275,11 @@ if no available remote peers are found.
|
||||
|
||||
The chosen remote peer will push its all known data ending with a Resync Finished Message or a Resync Partial Message (if it it does not consider itself as full updated).
|
||||
|
||||
-If it receive a Resync Finished Message it will consider itself as fully updated and stops to ask for resync.
|
||||
+If it receives a Resync Finished Message it will consider itself as fully updated and stops to ask for resync.
|
||||
|
||||
-If it receive a Resync Partial Message, the current peer will be flagged to anymore be requested and any other connected peer will be randomly chosen for a resync request (5s).
|
||||
+If it receives a Resync Partial Message, the current peer will be flagged to anymore be requested and any other connected peer will be randomly chosen for a resync request (5s).
|
||||
|
||||
-If the session is broken before receiving any ot these messages any other connected peer will be randomly chosen for a resync request (5s).
|
||||
+If the session is broken before receiving any of these messages any other connected peer will be randomly chosen for a resync request (5s).
|
||||
|
||||
If the timeout expire, the process will consider itself as fully updated
|
||||
|
||||
diff --git a/doc/proxy-protocol.txt b/doc/proxy-protocol.txt
|
||||
index 4969180a..52d7bc71 100644
|
||||
--- a/doc/proxy-protocol.txt
|
||||
+++ b/doc/proxy-protocol.txt
|
||||
@@ -561,7 +561,7 @@ Contains the host name value passed by the client, as an UTF8-encoded string.
|
||||
In case of TLS being used on the client connection, this is the exact copy of
|
||||
the "server_name" extension as defined by RFC3546 [10], section 3.1, often
|
||||
referred to as "SNI". There are probably other situations where an authority
|
||||
-can be mentionned on a connection without TLS being involved at all.
|
||||
+can be mentioned on a connection without TLS being involved at all.
|
||||
|
||||
|
||||
2.2.3. PP2_TYPE_CRC32C
|
||||
diff --git a/doc/regression-testing.txt b/doc/regression-testing.txt
|
||||
new file mode 100644
|
||||
index 00000000..320c51cd
|
||||
--- /dev/null
|
||||
+++ b/doc/regression-testing.txt
|
||||
@@ -0,0 +1,706 @@
|
||||
+ +---------------------------------------+
|
||||
+ | HAProxy regression testing with vtest |
|
||||
+ +---------------------------------------+
|
||||
+
|
||||
+
|
||||
+The information found in this file are a short starting guide to help you to
|
||||
+write VTC (Varnish Test Case) scripts (or VTC files) for haproxy regression testing.
|
||||
+Such VTC files are currently used to test Varnish cache application developed by
|
||||
+Poul-Henning Kamp. A very big thanks you to him for having helped you to add
|
||||
+our haproxy C modules to vtest tool. Note that vtest was formally developed for
|
||||
+varnish cache reg testing and was named varnishtest. vtest is an haproxy specific
|
||||
+version of varnishtest program which reuses the non varnish cache specific code.
|
||||
+
|
||||
+A lot of general information about how to write VTC files may be found in 'man/vtc.7'
|
||||
+manual of varnish cache sources directory or directly on the web here:
|
||||
+
|
||||
+ https://varnish-cache.org/docs/trunk/reference/vtc.html
|
||||
+
|
||||
+It is *highly* recommended to read this manual before asking to haproxy ML. This
|
||||
+documentation only deals with the vtest support for haproxy.
|
||||
+
|
||||
+
|
||||
+vtest installation
|
||||
+------------------------
|
||||
+
|
||||
+To use vtest you will have to download and compile the recent vtest
|
||||
+sources found at https://github.com/vtest/VTest.
|
||||
+
|
||||
+To compile vtest:
|
||||
+
|
||||
+ $ cd VTest
|
||||
+ $ make vtest
|
||||
+
|
||||
+Note that varnishtest may be also compiled but not without the varnish cache
|
||||
+sources already compiled:
|
||||
+
|
||||
+ $ VARNISH_SRC=<...> make varnishtest
|
||||
+
|
||||
+After having compiled these sources, the vtest executable location is at the
|
||||
+root of the vtest sources directory.
|
||||
+
|
||||
+
|
||||
+vtest execution
|
||||
+---------------------
|
||||
+
|
||||
+vtest is able to search for the haproxy executable file it is supposed to
|
||||
+launch thanks to the PATH environment variable. To force the executable to be used by
|
||||
+vtest, the HAPROXY_PROGRAM environment variable for vtest may be
|
||||
+typically set as follows:
|
||||
+
|
||||
+ $ HAPROXY_PROGRAM=~/srcs/haproxy/haproxy vtest ...
|
||||
+
|
||||
+vtest program comes with interesting options. The most interesting are:
|
||||
+
|
||||
+ -t Timeout in seconds to abort the test if some launched program
|
||||
+ -v By default, vtest does not dump the outputs of processus it launched
|
||||
+ when the test passes. With this option the outputs are dumped even
|
||||
+ when the test passes.
|
||||
+ -L to always keep the temporary VTC directories.
|
||||
+ -l to keep the temporary VTC directories only when the test fails.
|
||||
+
|
||||
+About haproxy, when launched by vtest, -d option is enabled by default.
|
||||
+
|
||||
+
|
||||
+How to write VTC files
|
||||
+----------------------
|
||||
+
|
||||
+A VTC file must start with a "varnishtest" or "vtest" command line followed by a
|
||||
+descriptive line enclosed by double quotes. This is not specific to the VTC files
|
||||
+for haproxy.
|
||||
+
|
||||
+The VTC files for haproxy must also contain a "feature ignore_unknown_macro" line
|
||||
+if any macro is used for haproxy in this file. This is due to the fact that
|
||||
+vtest parser code for haproxy commands generates macros the vtest
|
||||
+parser code for varnish cache has no knowledge of. This line prevents vtest from
|
||||
+failing in such cases. As a "cli" macro automatically generated, this
|
||||
+"feature ignore_unknown_macro" is mandatory for each VTC file for haproxy.
|
||||
+
|
||||
+To make vtest capable of testing haproxy, two new VTC commands have been
|
||||
+implemented: "haproxy" and "syslog". "haproxy" is used to start haproxy processus.
|
||||
+"syslog" is used to start syslog servers (at this time, only used by haproxy).
|
||||
+
|
||||
+As haproxy cannot work without configuration file, a VTC file for haproxy must
|
||||
+embed the configuration files contents for the haproxy instances it declares.
|
||||
+This may be done using the following intuitive syntax construction: -conf {...}.
|
||||
+Here -conf is an argument of "haproxy" VTC command to declare the configuration
|
||||
+file of the haproxy instances it also declares (see "Basic HAProxy test" VTC file
|
||||
+below).
|
||||
+
|
||||
+As for varnish VTC files, the parser of VTC files for haproxy automatically
|
||||
+generates macros for the declared frontends to be reused by the clients later
|
||||
+in the script, so after having written the "haproxy" command sections.
|
||||
+The syntax "fd@${my_frontend_fd_name}" must be used to bind the frontend
|
||||
+listeners to localhost address and random ports (see "Environment variables"
|
||||
+section of haproxy documentation). This is mandatory.
|
||||
+
|
||||
+Each time the haproxy command parser finds a "fd@${xyz}" string in a 'ABC'
|
||||
+"haproxy" command section, it generates three macros: 'ABC_xyz_addr', 'ABC_xyz_port'
|
||||
+and 'ABC_xyz_sock', with 'ABC_xyz_sock' being resolved as 'ABC_xyz_addr
|
||||
+ABC_xyz_port' typically used by clients -connect parameter.
|
||||
+
|
||||
+Each haproxy instance works in their own temporary working directories located
|
||||
+at '/tmp/vtc.<varnitest PID>.XXXXXXXX/<haproxy_instance_name>' (with XXXXXXXX
|
||||
+a random 8 digits hexadecimal integer. This is in this temporary directory that
|
||||
+the configuration file is temporarily written.
|
||||
+
|
||||
+A 'stats.sock' UNIX socket is also created in this directory. There is no need
|
||||
+to declare such stats sockets in the -conf {...} section. The name of the parent
|
||||
+directory of the haproxy instances working directories is stored in 'tmpdir'. In
|
||||
+fact this is the working directory of the current vtest processus.
|
||||
+
|
||||
+There also exists 'testdir' macro which is the parent directory of the VTC file.
|
||||
+It may be useful to use other files located in the same directory than the current
|
||||
+VTC file.
|
||||
+
|
||||
+
|
||||
+
|
||||
+VTC file examples
|
||||
+-----------------
|
||||
+
|
||||
+The following first VTC file is a real regression test case file for a bug which has
|
||||
+been fixed by 84c844e commit. We declare a basic configuration for a 'h1' haproxy
|
||||
+instance.
|
||||
+
|
||||
+ varnishtest "SPOE bug: missing configuration file"
|
||||
+
|
||||
+ #commit 84c844eb12b250aa86f2aadaff77c42dfc3cb619
|
||||
+ #Author: Christopher Faulet <cfaulet@haproxy.com>
|
||||
+ #Date: Fri Mar 23 14:37:14 2018 +0100
|
||||
+
|
||||
+ # BUG/MINOR: spoe: Initialize variables used during conf parsing before any check
|
||||
+
|
||||
+ # Some initializations must be done at the beginning of parse_spoe_flt to avoid
|
||||
+ # segmentaion fault when first errors are caught, when the "filter spoe" line is
|
||||
+ # parsed.
|
||||
+
|
||||
+ haproxy h1 -conf-BAD {} {
|
||||
+ defaults
|
||||
+ timeout connect 5000ms
|
||||
+ timeout client 50000ms
|
||||
+ timeout server 50000ms
|
||||
+
|
||||
+ frontend my-front
|
||||
+ filter spoe
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+-conf-BAD haproxy command argument is used. Its role it to launch haproxy with
|
||||
+-c option (configuration file checking) and check that 'h1' exit(3) with 1 as
|
||||
+status. Here is the output when running this VTC file:
|
||||
+
|
||||
+
|
||||
+ **** top 0.0 extmacro def pwd=/home/fred/src/haproxy
|
||||
+ **** top 0.0 extmacro def localhost=127.0.0.1
|
||||
+ **** top 0.0 extmacro def bad_backend=127.0.0.1 39564
|
||||
+ **** top 0.0 extmacro def bad_ip=192.0.2.255
|
||||
+ **** top 0.0 macro def testdir=//home/fred/src/varnish-cache-haproxy
|
||||
+ **** top 0.0 macro def tmpdir=/tmp/vtc.6377.64329194
|
||||
+ * top 0.0 TEST /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc starting
|
||||
+ ** top 0.0 === varnishtest "SPOE bug: missing configuration file"
|
||||
+ * top 0.0 TEST SPOE bug: missing configuration file
|
||||
+ ** top 0.0 === haproxy h1 -conf-BAD {} {
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf|\tstats socket /tmp/vtc.6377.64329194/h1/stats.sock level admin mode 600
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf|\tdefaults
|
||||
+ **** h1 0.0 conf| timeout connect 5000ms
|
||||
+ **** h1 0.0 conf| timeout client 50000ms
|
||||
+ **** h1 0.0 conf| timeout server 50000ms
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf|\tfrontend my-front
|
||||
+ **** h1 0.0 conf|\t\tfilter spoe
|
||||
+ **** h1 0.0 conf|
|
||||
+ ** h1 0.0 haproxy_start
|
||||
+ **** h1 0.0 opt_worker 0 opt_daemon 0 opt_check_mode 1
|
||||
+ **** h1 0.0 argv|exec /home/fred/src/haproxy/haproxy -c -f /tmp/vtc.6377.64329194/h1/cfg
|
||||
+ **** h1 0.0 XXX 5 @277
|
||||
+ *** h1 0.0 PID: 6395
|
||||
+ **** h1 0.0 macro def h1_pid=6395
|
||||
+ **** h1 0.0 macro def h1_name=/tmp/vtc.6377.64329194/h1
|
||||
+ ** h1 0.0 Wait
|
||||
+ ** h1 0.0 Stop HAproxy pid=6395
|
||||
+ **** h1 0.0 STDOUT poll 0x10
|
||||
+ ** h1 0.0 WAIT4 pid=6395 status=0x008b (user 0.000000 sys 0.000000)
|
||||
+ * h1 0.0 Expected exit: 0x1 signal: 0 core: 0
|
||||
+ ---- h1 0.0 Bad exit status: 0x008b exit 0x0 signal 11 core 128
|
||||
+ * top 0.0 RESETTING after /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc
|
||||
+ ** h1 0.0 Reset and free h1 haproxy 6395
|
||||
+ ** h1 0.0 Wait
|
||||
+ ---- h1 0.0 Assert error in haproxy_wait(), vtc_haproxy.c line 326: Condition(*(&h->fds[1]) >= 0) not true.
|
||||
+
|
||||
+ * top 0.0 failure during reset
|
||||
+ # top TEST /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc FAILED (0.008) exit=2
|
||||
+
|
||||
+
|
||||
+'h1' exited with (128 + 11) status and a core file was produced in
|
||||
+/tmp/vtc.6377.64329194/h1 directory.
|
||||
+With the patch provided by 84c844e commit, varnishtest makes this VTC file pass
|
||||
+as expected (verbose mode execution):
|
||||
+
|
||||
+ **** top 0.0 extmacro def pwd=/home/fred/src/haproxy
|
||||
+ **** top 0.0 extmacro def localhost=127.0.0.1
|
||||
+ **** top 0.0 extmacro def bad_backend=127.0.0.1 42264
|
||||
+ **** top 0.0 extmacro def bad_ip=192.0.2.255
|
||||
+ **** top 0.0 macro def testdir=//home/fred/src/varnish-cache-haproxy
|
||||
+ **** top 0.0 macro def tmpdir=/tmp/vtc.25540.59b6ec5d
|
||||
+ * top 0.0 TEST /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc starting
|
||||
+ ** top 0.0 === varnishtest "SPOE bug: missing configuration file"
|
||||
+ * top 0.0 TEST SPOE bug: missing configuration file
|
||||
+ ** top 0.0 === haproxy h1 -conf-BAD {} {
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf|\tstats socket /tmp/vtc.25540.59b6ec5d/h1/stats.sock level admin mode 600
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf|\tdefaults
|
||||
+ **** h1 0.0 conf| timeout connect 5000ms
|
||||
+ **** h1 0.0 conf| timeout client 50000ms
|
||||
+ **** h1 0.0 conf| timeout server 50000ms
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf|\tfrontend my-front
|
||||
+ **** h1 0.0 conf|\t\tfilter spoe
|
||||
+ **** h1 0.0 conf|
|
||||
+ ** h1 0.0 haproxy_start
|
||||
+ **** h1 0.0 opt_worker 0 opt_daemon 0 opt_check_mode 1
|
||||
+ **** h1 0.0 argv|exec /home/fred/src/haproxy/haproxy -c -f /tmp/vtc.25540.59b6ec5d/h1/cfg
|
||||
+ **** h1 0.0 XXX 5 @277
|
||||
+ *** h1 0.0 PID: 25558
|
||||
+ **** h1 0.0 macro def h1_pid=25558
|
||||
+ **** h1 0.0 macro def h1_name=/tmp/vtc.25540.59b6ec5d/h1
|
||||
+ ** h1 0.0 Wait
|
||||
+ ** h1 0.0 Stop HAproxy pid=25558
|
||||
+ *** h1 0.0 debug|[ALERT] 157/135318 (25558) : parsing [/tmp/vtc.25540.59b6ec5d/h1/cfg:10] : 'filter' : ''spoe' : missing config file'
|
||||
+ *** h1 0.0 debug|[ALERT] 157/135318 (25558) : Error(s) found in configuration file : /tmp/vtc.25540.59b6ec5d/h1/cfg
|
||||
+ *** h1 0.0 debug|[ALERT] 157/135318 (25558) : Fatal errors found in configuration.
|
||||
+ **** h1 0.0 STDOUT poll 0x10
|
||||
+ ** h1 0.0 WAIT4 pid=25558 status=0x0100 (user 0.000000 sys 0.000000)
|
||||
+ ** h1 0.0 Found expected ''
|
||||
+ * top 0.0 RESETTING after /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc
|
||||
+ ** h1 0.0 Reset and free h1 haproxy -1
|
||||
+ * top 0.0 TEST /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc completed
|
||||
+ # top TEST /home/fred/src/varnish-cache-haproxy/spoe_bug.vtc passed (0.004)
|
||||
+
|
||||
+
|
||||
+The following VTC file does almost nothing except running a shell to list
|
||||
+the contents of 'tmpdir' directory after having launched a haproxy instance
|
||||
+and 's1' HTTP server. This shell also prints the content of 'cfg' 'h1' configuration
|
||||
+file.
|
||||
+
|
||||
+ varnishtest "List the contents of 'tmpdir'"
|
||||
+ feature ignore_unknown_macro
|
||||
+
|
||||
+ server s1 {
|
||||
+ } -start
|
||||
+
|
||||
+ haproxy h1 -conf {
|
||||
+ defaults
|
||||
+ mode http
|
||||
+ timeout connect 5s
|
||||
+ timeout server 30s
|
||||
+ timeout client 30s
|
||||
+
|
||||
+ backend be1
|
||||
+ server srv1 ${s1_addr}:${s1_port}
|
||||
+
|
||||
+ frontend http1
|
||||
+ use_backend be1
|
||||
+ bind "fd@${my_frontend_fd}"
|
||||
+ } -start
|
||||
+
|
||||
+ shell {
|
||||
+ echo "${tmpdir} working directory content:"
|
||||
+ ls -lR ${tmpdir}
|
||||
+ cat ${tmpdir}/h1/cfg
|
||||
+ }
|
||||
+
|
||||
+We give only the output of the shell to illustrate this example:
|
||||
+
|
||||
+ .
|
||||
+ .
|
||||
+ .
|
||||
+ ** top 0.0 === shell {
|
||||
+ **** top 0.0 shell_cmd|exec 2>&1 ;
|
||||
+ **** top 0.0 shell_cmd| echo "tmpdir: /tmp/vtc.32092.479d521e"
|
||||
+ **** top 0.0 shell_cmd| ls -lR /tmp/vtc.32092.479d521e
|
||||
+ **** top 0.0 shell_cmd| cat /tmp/vtc.32092.479d521e/h1/cfg
|
||||
+ .
|
||||
+ .
|
||||
+ .
|
||||
+ **** top 0.0 shell_out|/tmp/vtc.3808.448cbfe0 working directory content:
|
||||
+ **** top 0.0 shell_out|/tmp/vtc.32092.479d521e:
|
||||
+ **** top 0.0 shell_out|total 8
|
||||
+ **** top 0.0 shell_out|drwxr-xr-x 2 users 4096 Jun 7 11:09 h1
|
||||
+ **** top 0.0 shell_out|-rw-r--r-- 1 me users 84 Jun 7 11:09 INFO
|
||||
+ **** top 0.0 shell_out|
|
||||
+ **** top 0.0 shell_out|/tmp/vtc.32092.479d521e/h1:
|
||||
+ **** top 0.0 shell_out|total 4
|
||||
+ **** top 0.0 shell_out|-rw-r----- 1 fred users 339 Jun 7 11:09 cfg
|
||||
+ **** top 0.0 shell_out|srw------- 1 fred users 0 Jun 7 11:09 stats.sock
|
||||
+ **** top 0.0 shell_out| global
|
||||
+ **** top 0.0 shell_out|\tstats socket /tmp/vtc.32092.479d521e/h1/stats.sock level admin mode 600
|
||||
+ **** top 0.0 shell_out|
|
||||
+ **** top 0.0 shell_out| defaults
|
||||
+ **** top 0.0 shell_out| mode http
|
||||
+ **** top 0.0 shell_out| timeout connect 5s
|
||||
+ **** top 0.0 shell_out| timeout server 30s
|
||||
+ **** top 0.0 shell_out| timeout client 30s
|
||||
+ **** top 0.0 shell_out|
|
||||
+ **** top 0.0 shell_out| backend be1
|
||||
+ **** top 0.0 shell_out| server srv1 127.0.0.1:36984
|
||||
+ **** top 0.0 shell_out|
|
||||
+ **** top 0.0 shell_out| frontend http1
|
||||
+ **** top 0.0 shell_out| use_backend be1
|
||||
+ **** top 0.0 shell_out| bind "fd@${my_frontend_fd}"
|
||||
+ **** top 0.0 shell_status = 0x0000
|
||||
+
|
||||
+
|
||||
+The following example illustrate how to run a basic HTTP transaction between 'c1'
|
||||
+client and 's1' server with 'http1' as haproxy frontend. This frontend listen
|
||||
+on TCP socket with 'my_frontend_fd' as file descriptor.
|
||||
+
|
||||
+ # Mandatory line
|
||||
+ varnishtest "Basic HAproxy test"
|
||||
+
|
||||
+ # As some macros for haproxy are used in this file, this line is mandatory.
|
||||
+ feature ignore_unknown_macro
|
||||
+
|
||||
+ server s1 {
|
||||
+ rxreq
|
||||
+ txresp -body "s1 >>> Hello world!"
|
||||
+ } -start
|
||||
+
|
||||
+ haproxy h1 -conf {
|
||||
+ # Configuration file of 'h1' haproxy instance.
|
||||
+ defaults
|
||||
+ mode http
|
||||
+ timeout connect 5s
|
||||
+ timeout server 30s
|
||||
+ timeout client 30s
|
||||
+
|
||||
+ backend be1
|
||||
+ # declare 'srv1' server to point to 's1' server instance declare above.
|
||||
+ server srv1 ${s1_addr}:${s1_port}
|
||||
+
|
||||
+ frontend http1
|
||||
+ use_backend be1
|
||||
+ bind "fd@${my_frontend_fd}"
|
||||
+ } -start
|
||||
+
|
||||
+ client c1 -connect ${h1_my_frontend_fd_sock} {
|
||||
+ txreq -url "/"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.body == "s1 >>> Hello world!"
|
||||
+ } -run
|
||||
+
|
||||
+
|
||||
+It is possible to shorten the previous VTC file haproxy command section as follows:
|
||||
+
|
||||
+ haproxy h1 -conf {
|
||||
+ # Configuration file of 'h1' haproxy instance.
|
||||
+ defaults
|
||||
+ mode http
|
||||
+ timeout connect 5s
|
||||
+ timeout server 30s
|
||||
+ timeout client 30s
|
||||
+ }
|
||||
+
|
||||
+In this latter example, "backend" and "frontend" sections are automatically
|
||||
+generated depending on the declarations of server instances.
|
||||
+
|
||||
+
|
||||
+Another interesting real regression test case is the following: we declare one
|
||||
+server 's1', a syslog server 'Slg_1' and a basic haproxy configuration for 'h1'
|
||||
+haproxy instance. Here we want to check that the syslog message are correctly
|
||||
+formatted thanks to "expect" "syslog" command (see syslog Slg_1 {...} command)
|
||||
+below.
|
||||
+
|
||||
+ varnishtest "Wrong ip/port logging"
|
||||
+ feature ignore_unknown_macro
|
||||
+
|
||||
+ #commit d02286d6c866e5c0a7eb6fbb127fa57f3becaf16
|
||||
+ #Author: Willy Tarreau <w@1wt.eu>
|
||||
+ #Date: Fri Jun 23 11:23:43 2017 +0200
|
||||
+ #
|
||||
+ # BUG/MINOR: log: pin the front connection when front ip/ports are logged
|
||||
+ #
|
||||
+ # Mathias Weiersmueller reported an interesting issue with logs which Lukas
|
||||
+ # diagnosed as dating back from commit 9b061e332 (1.5-dev9). When front
|
||||
+ # connection information (ip, port) are logged in TCP mode and the log is
|
||||
+ # emitted at the end of the connection (eg: because %B or any log tag
|
||||
+ # requiring LW_BYTES is set), the log is emitted after the connection is
|
||||
+ # closed, so the address and ports cannot be retrieved anymore.
|
||||
+ #
|
||||
+ # It could be argued that we'd make a special case of these to immediately
|
||||
+ # retrieve the source and destination addresses from the connection, but it
|
||||
+ # seems cleaner to simply pin the front connection, marking it "tracked" by
|
||||
+ # adding the LW_XPRT flag to mention that we'll need some of these elements
|
||||
+ # at the last moment. Only LW_FRTIP and LW_CLIP are affected. Note that after
|
||||
+ # this change, LW_FRTIP could simply be removed as it's not used anywhere.
|
||||
+
|
||||
+ # Note that the problem doesn't happen when using %[src] or %[dst] since
|
||||
+ # all sample expressions set LW_XPRT.
|
||||
+
|
||||
+
|
||||
+ server s1 {
|
||||
+ rxreq
|
||||
+ txresp
|
||||
+ } -start
|
||||
+
|
||||
+ syslog Slg_1 -level notice {
|
||||
+ recv
|
||||
+ recv
|
||||
+ recv info
|
||||
+ expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_port}.*\"ts\":\"cD\",\"
|
||||
+ } -start
|
||||
+
|
||||
+ haproxy h1 -conf {
|
||||
+ global
|
||||
+ log ${Slg_1_addr}:${Slg_1_port} local0
|
||||
+
|
||||
+ defaults
|
||||
+ log global
|
||||
+ timeout connect 3000
|
||||
+ timeout client 5
|
||||
+ timeout server 10000
|
||||
+
|
||||
+ frontend fe1
|
||||
+ bind "fd@${fe_1}"
|
||||
+ mode tcp
|
||||
+ log-format {\"dip\":\"%fi\",\"dport\":\"%fp\",\"c_ip\":\"%ci\",\"c_port\":\"%cp\",\"fe_name\":\"%ft\",\"be_name\":\"%b\",\"s_name\":\"%s\",\"ts\":\"%ts\",\"bytes_read\":\"%B\"}
|
||||
+ default_backend be_app
|
||||
+
|
||||
+ backend be_app
|
||||
+ server app1 ${s1_addr}:${s1_port} check
|
||||
+ } -start
|
||||
+
|
||||
+ client c1 -connect ${h1_fe_1_sock} {
|
||||
+ txreq -url "/"
|
||||
+ delay 0.02
|
||||
+ } -run
|
||||
+
|
||||
+ syslog Slg_1 -wait
|
||||
+
|
||||
+
|
||||
+Here is the output produced by varnishtest with the latter VTC file:
|
||||
+
|
||||
+ **** top 0.0 extmacro def pwd=/home/fred/src/haproxy
|
||||
+ **** top 0.0 extmacro def localhost=127.0.0.1
|
||||
+ **** top 0.0 extmacro def bad_backend=127.0.0.1 40386
|
||||
+ **** top 0.0 extmacro def bad_ip=192.0.2.255
|
||||
+ **** top 0.0 macro def testdir=//home/fred/src/varnish-cache-haproxy
|
||||
+ **** top 0.0 macro def tmpdir=/tmp/vtc.15752.560ca66b
|
||||
+ * top 0.0 TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc starting
|
||||
+ ** top 0.0 === varnishtest "HAPEE bug 2788"
|
||||
+ * top 0.0 TEST HAPEE bug 2788
|
||||
+ ** top 0.0 === feature ignore_unknown_macro
|
||||
+ ** top 0.0 === server s1 {
|
||||
+ ** s1 0.0 Starting server
|
||||
+ **** s1 0.0 macro def s1_addr=127.0.0.1
|
||||
+ **** s1 0.0 macro def s1_port=35564
|
||||
+ **** s1 0.0 macro def s1_sock=127.0.0.1 35564
|
||||
+ * s1 0.0 Listen on 127.0.0.1 35564
|
||||
+ ** top 0.0 === syslog Slg_1 -level notice {
|
||||
+ ** Slg_1 0.0 Starting syslog server
|
||||
+ ** s1 0.0 Started on 127.0.0.1 35564
|
||||
+ **** Slg_1 0.0 macro def Slg_1_addr=127.0.0.1
|
||||
+ **** Slg_1 0.0 macro def Slg_1_port=33012
|
||||
+ **** Slg_1 0.0 macro def Slg_1_sock=127.0.0.1 33012
|
||||
+ * Slg_1 0.0 Bound on 127.0.0.1 33012
|
||||
+ ** top 0.0 === haproxy h1 -conf {
|
||||
+ ** Slg_1 0.0 Started on 127.0.0.1 33012 (level: 5)
|
||||
+ ** Slg_1 0.0 === recv
|
||||
+ **** h1 0.0 macro def h1_fe_1_sock=::1 51782
|
||||
+ **** h1 0.0 macro def h1_fe_1_addr=::1
|
||||
+ **** h1 0.0 macro def h1_fe_1_port=51782
|
||||
+ **** h1 0.0 setenv(fe_1, 7)
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf|\tstats socket /tmp/vtc.15752.560ca66b/h1/stats.sock level admin mode 600
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf| log 127.0.0.1:33012 local0
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| defaults
|
||||
+ **** h1 0.0 conf| log global
|
||||
+ **** h1 0.0 conf| timeout connect 3000
|
||||
+ **** h1 0.0 conf| timeout client 5
|
||||
+ **** h1 0.0 conf| timeout server 10000
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| frontend fe1
|
||||
+ **** h1 0.0 conf| bind "fd@${fe_1}"
|
||||
+ **** h1 0.0 conf| mode tcp
|
||||
+ **** h1 0.0 conf| log-format {\"dip\":\"%fi\",\"dport\":\"%fp\",\"c_ip\":\"%ci\",\"c_port\":\"%cp\",\"fe_name\":\"%ft\",\"be_name\":\"%b\",\"s_name\":\"%s\",\"ts\":\"%ts\",\"bytes_read\":\"%B\"}
|
||||
+ **** h1 0.0 conf| default_backend be_app
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| backend be_app
|
||||
+ **** h1 0.0 conf| server app1 127.0.0.1:35564 check
|
||||
+ ** h1 0.0 haproxy_start
|
||||
+ **** h1 0.0 opt_worker 0 opt_daemon 0 opt_check_mode 0
|
||||
+ **** h1 0.0 argv|exec /home/fred/src/haproxy/haproxy -d -f /tmp/vtc.15752.560ca66b/h1/cfg
|
||||
+ **** h1 0.0 XXX 9 @277
|
||||
+ *** h1 0.0 PID: 15787
|
||||
+ **** h1 0.0 macro def h1_pid=15787
|
||||
+ **** h1 0.0 macro def h1_name=/tmp/vtc.15752.560ca66b/h1
|
||||
+ ** top 0.0 === client c1 -connect ${h1_fe_1_sock} {
|
||||
+ ** c1 0.0 Starting client
|
||||
+ ** c1 0.0 Waiting for client
|
||||
+ *** c1 0.0 Connect to ::1 51782
|
||||
+ *** c1 0.0 connected fd 8 from ::1 46962 to ::1 51782
|
||||
+ ** c1 0.0 === txreq -url "/"
|
||||
+ **** c1 0.0 txreq|GET / HTTP/1.1\r
|
||||
+ **** c1 0.0 txreq|Host: 127.0.0.1\r
|
||||
+ **** c1 0.0 txreq|\r
|
||||
+ ** c1 0.0 === delay 0.02
|
||||
+ *** c1 0.0 delaying 0.02 second(s)
|
||||
+ *** h1 0.0 debug|Note: setting global.maxconn to 2000.
|
||||
+ *** h1 0.0 debug|Available polling systems :
|
||||
+ *** h1 0.0 debug| epoll :
|
||||
+ *** h1 0.0 debug|pref=300,
|
||||
+ *** h1 0.0 debug| test result OK
|
||||
+ *** h1 0.0 debug| poll : pref=200, test result OK
|
||||
+ *** h1 0.0 debug| select :
|
||||
+ *** h1 0.0 debug|pref=150, test result FAILED
|
||||
+ *** h1 0.0 debug|Total: 3 (2 usable), will use epoll.
|
||||
+ *** h1 0.0 debug|
|
||||
+ *** h1 0.0 debug|Available filters :
|
||||
+ *** h1 0.0 debug|\t[SPOE] spoe
|
||||
+ *** h1 0.0 debug|\t[COMP] compression
|
||||
+ *** h1 0.0 debug|\t[TRACE] trace
|
||||
+ **** Slg_1 0.0 syslog|<133>Jun 7 14:12:51 haproxy[15787]: Proxy fe1 started.
|
||||
+ ** Slg_1 0.0 === recv
|
||||
+ **** Slg_1 0.0 syslog|<133>Jun 7 14:12:51 haproxy[15787]: Proxy be_app started.
|
||||
+ ** Slg_1 0.0 === recv info
|
||||
+ *** h1 0.0 debug|00000000:fe1.accept(0007)=000a from [::1:46962]
|
||||
+ *** s1 0.0 accepted fd 6 127.0.0.1 56770
|
||||
+ ** s1 0.0 === rxreq
|
||||
+ **** s1 0.0 rxhdr|GET / HTTP/1.1\r
|
||||
+ **** s1 0.0 rxhdr|Host: 127.0.0.1\r
|
||||
+ **** s1 0.0 rxhdr|\r
|
||||
+ **** s1 0.0 rxhdrlen = 35
|
||||
+ **** s1 0.0 http[ 0] |GET
|
||||
+ **** s1 0.0 http[ 1] |/
|
||||
+ **** s1 0.0 http[ 2] |HTTP/1.1
|
||||
+ **** s1 0.0 http[ 3] |Host: 127.0.0.1
|
||||
+ **** s1 0.0 bodylen = 0
|
||||
+ ** s1 0.0 === txresp
|
||||
+ **** s1 0.0 txresp|HTTP/1.1 200 OK\r
|
||||
+ **** s1 0.0 txresp|Content-Length: 0\r
|
||||
+ **** s1 0.0 txresp|\r
|
||||
+ *** s1 0.0 shutting fd 6
|
||||
+ ** s1 0.0 Ending
|
||||
+ *** h1 0.0 debug|00000000:be_app.srvcls[000a:000c]
|
||||
+ *** h1 0.0 debug|00000000:be_app.clicls[000a:000c]
|
||||
+ *** h1 0.0 debug|00000000:be_app.closed[000a:000c]
|
||||
+ **** Slg_1 0.0 syslog|<134>Jun 7 14:12:51 haproxy[15787]: {"dip":"","dport":"0","c_ip":"::1","c_port":"46962","fe_name":"fe1","be_name":"be_app","s_name":"app1","ts":"cD","bytes_read":"38"}
|
||||
+ ** Slg_1 0.0 === expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_p...
|
||||
+ ---- Slg_1 0.0 EXPECT FAILED ~ "\"dip\":\"::1\",\"dport\":\"51782.*\"ts\":\"cD\",\""
|
||||
+ *** c1 0.0 closing fd 8
|
||||
+ ** c1 0.0 Ending
|
||||
+ * top 0.0 RESETTING after /home/fred/src/varnish-cache-haproxy/d02286d.vtc
|
||||
+ ** h1 0.0 Reset and free h1 haproxy 15787
|
||||
+ ** h1 0.0 Wait
|
||||
+ ** h1 0.0 Stop HAproxy pid=15787
|
||||
+ **** h1 0.0 Kill(2)=0: Success
|
||||
+ **** h1 0.0 STDOUT poll 0x10
|
||||
+ ** h1 0.1 WAIT4 pid=15787 status=0x0002 (user 0.000000 sys 0.004000)
|
||||
+ ** s1 0.1 Waiting for server (4/-1)
|
||||
+ ** Slg_1 0.1 Waiting for syslog server (5)
|
||||
+ * top 0.1 TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc FAILED
|
||||
+ # top TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc FAILED (0.131) exit=2
|
||||
+
|
||||
+This test does not pass without the bug fix of d02286d commit. Indeed the third syslog
|
||||
+message received by 'Slg_1' syslog server does not match the regular expression
|
||||
+of the "syslog" "expect" command:
|
||||
+
|
||||
+ expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_port}.*\"ts\":\"cD\",\"
|
||||
+
|
||||
+(the IP address and port are missing), contrary to what happens with the correct bug fix:
|
||||
+
|
||||
+ **** top 0.0 extmacro def pwd=/home/fred/src/haproxy
|
||||
+ **** top 0.0 extmacro def localhost=127.0.0.1
|
||||
+ **** top 0.0 extmacro def bad_backend=127.0.0.1 37284
|
||||
+ **** top 0.0 extmacro def bad_ip=192.0.2.255
|
||||
+ **** top 0.0 macro def testdir=//home/fred/src/varnish-cache-haproxy
|
||||
+ **** top 0.0 macro def tmpdir=/tmp/vtc.12696.186b28b0
|
||||
+ * top 0.0 TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc starting
|
||||
+ ** top 0.0 === varnishtest "HAPEE bug 2788"
|
||||
+ * top 0.0 TEST HAPEE bug 2788
|
||||
+ ** top 0.0 === feature ignore_unknown_macro
|
||||
+ ** top 0.0 === server s1 {
|
||||
+ ** s1 0.0 Starting server
|
||||
+ **** s1 0.0 macro def s1_addr=127.0.0.1
|
||||
+ **** s1 0.0 macro def s1_port=53384
|
||||
+ **** s1 0.0 macro def s1_sock=127.0.0.1 53384
|
||||
+ * s1 0.0 Listen on 127.0.0.1 53384
|
||||
+ ** top 0.0 === syslog Slg_1 -level notice {
|
||||
+ ** Slg_1 0.0 Starting syslog server
|
||||
+ **** Slg_1 0.0 macro def Slg_1_addr=127.0.0.1
|
||||
+ ** s1 0.0 Started on 127.0.0.1 53384
|
||||
+ **** Slg_1 0.0 macro def Slg_1_port=36195
|
||||
+ **** Slg_1 0.0 macro def Slg_1_sock=127.0.0.1 36195
|
||||
+ * Slg_1 0.0 Bound on 127.0.0.1 36195
|
||||
+ ** top 0.0 === haproxy h1 -conf {
|
||||
+ ** Slg_1 0.0 Started on 127.0.0.1 36195 (level: 5)
|
||||
+ ** Slg_1 0.0 === recv
|
||||
+ **** h1 0.0 macro def h1_fe_1_sock=::1 39264
|
||||
+ **** h1 0.0 macro def h1_fe_1_addr=::1
|
||||
+ **** h1 0.0 macro def h1_fe_1_port=39264
|
||||
+ **** h1 0.0 setenv(fe_1, 7)
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf|\tstats socket /tmp/vtc.12696.186b28b0/h1/stats.sock level admin mode 600
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| global
|
||||
+ **** h1 0.0 conf| log 127.0.0.1:36195 local0
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| defaults
|
||||
+ **** h1 0.0 conf| log global
|
||||
+ **** h1 0.0 conf| timeout connect 3000
|
||||
+ **** h1 0.0 conf| timeout client 5
|
||||
+ **** h1 0.0 conf| timeout server 10000
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| frontend fe1
|
||||
+ **** h1 0.0 conf| bind "fd@${fe_1}"
|
||||
+ **** h1 0.0 conf| mode tcp
|
||||
+ **** h1 0.0 conf| log-format {\"dip\":\"%fi\",\"dport\":\"%fp\",\"c_ip\":\"%ci\",\"c_port\":\"%cp\",\"fe_name\":\"%ft\",\"be_name\":\"%b\",\"s_name\":\"%s\",\"ts\":\"%ts\",\"bytes_read\":\"%B\"}
|
||||
+ **** h1 0.0 conf| default_backend be_app
|
||||
+ **** h1 0.0 conf|
|
||||
+ **** h1 0.0 conf| backend be_app
|
||||
+ **** h1 0.0 conf| server app1 127.0.0.1:53384 check
|
||||
+ ** h1 0.0 haproxy_start
|
||||
+ **** h1 0.0 opt_worker 0 opt_daemon 0 opt_check_mode 0
|
||||
+ **** h1 0.0 argv|exec /home/fred/src/haproxy/haproxy -d -f /tmp/vtc.12696.186b28b0/h1/cfg
|
||||
+ **** h1 0.0 XXX 9 @277
|
||||
+ *** h1 0.0 PID: 12728
|
||||
+ **** h1 0.0 macro def h1_pid=12728
|
||||
+ **** h1 0.0 macro def h1_name=/tmp/vtc.12696.186b28b0/h1
|
||||
+ ** top 0.0 === client c1 -connect ${h1_fe_1_sock} {
|
||||
+ ** c1 0.0 Starting client
|
||||
+ ** c1 0.0 Waiting for client
|
||||
+ *** c1 0.0 Connect to ::1 39264
|
||||
+ *** c1 0.0 connected fd 8 from ::1 41245 to ::1 39264
|
||||
+ ** c1 0.0 === txreq -url "/"
|
||||
+ **** c1 0.0 txreq|GET / HTTP/1.1\r
|
||||
+ **** c1 0.0 txreq|Host: 127.0.0.1\r
|
||||
+ **** c1 0.0 txreq|\r
|
||||
+ ** c1 0.0 === delay 0.02
|
||||
+ *** c1 0.0 delaying 0.02 second(s)
|
||||
+ *** h1 0.0 debug|Note: setting global.maxconn to 2000.
|
||||
+ *** h1 0.0 debug|Available polling systems :
|
||||
+ *** h1 0.0 debug| epoll : pref=300,
|
||||
+ *** h1 0.0 debug| test result OK
|
||||
+ *** h1 0.0 debug| poll : pref=200, test result OK
|
||||
+ *** h1 0.0 debug| select : pref=150, test result FAILED
|
||||
+ *** h1 0.0 debug|Total: 3 (2 usable), will use epoll.
|
||||
+ *** h1 0.0 debug|
|
||||
+ *** h1 0.0 debug|Available filters :
|
||||
+ *** h1 0.0 debug|\t[SPOE] spoe
|
||||
+ *** h1 0.0 debug|\t[COMP] compression
|
||||
+ *** h1 0.0 debug|\t[TRACE] trace
|
||||
+ *** h1 0.0 debug|Using epoll() as the polling mechanism.
|
||||
+ **** Slg_1 0.0 syslog|<133>Jun 7 14:10:18 haproxy[12728]: Proxy fe1 started.
|
||||
+ ** Slg_1 0.0 === recv
|
||||
+ **** Slg_1 0.0 syslog|<133>Jun 7 14:10:18 haproxy[12728]: Proxy be_app started.
|
||||
+ ** Slg_1 0.0 === recv info
|
||||
+ *** h1 0.0 debug|00000000:fe1.accept(0007)=000c from [::1:41245] ALPN=<none>
|
||||
+ *** s1 0.0 accepted fd 6 127.0.0.1 49946
|
||||
+ ** s1 0.0 === rxreq
|
||||
+ **** s1 0.0 rxhdr|GET / HTTP/1.1\r
|
||||
+ **** s1 0.0 rxhdr|Host: 127.0.0.1\r
|
||||
+ **** s1 0.0 rxhdr|\r
|
||||
+ **** s1 0.0 rxhdrlen = 35
|
||||
+ **** s1 0.0 http[ 0] |GET
|
||||
+ **** s1 0.0 http[ 1] |/
|
||||
+ **** s1 0.0 http[ 2] |HTTP/1.1
|
||||
+ **** s1 0.0 http[ 3] |Host: 127.0.0.1
|
||||
+ **** s1 0.0 bodylen = 0
|
||||
+ ** s1 0.0 === txresp
|
||||
+ **** s1 0.0 txresp|HTTP/1.1 200 OK\r
|
||||
+ **** s1 0.0 txresp|Content-Length: 0\r
|
||||
+ **** s1 0.0 txresp|\r
|
||||
+ *** s1 0.0 shutting fd 6
|
||||
+ ** s1 0.0 Ending
|
||||
+ *** h1 0.0 debug|00000000:be_app.srvcls[000c:adfd]
|
||||
+ *** h1 0.0 debug|00000000:be_app.clicls[000c:adfd]
|
||||
+ *** h1 0.0 debug|00000000:be_app.closed[000c:adfd]
|
||||
+ **** Slg_1 0.0 syslog|<134>Jun 7 14:10:18 haproxy[12728]: {"dip":"::1","dport":"39264","c_ip":"::1","c_port":"41245","fe_name":"fe1","be_name":"be_app","s_name":"app1","ts":"cD","bytes_read":"38"}
|
||||
+ ** Slg_1 0.0 === expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_p...
|
||||
+ **** Slg_1 0.0 EXPECT MATCH ~ "\"dip\":\"::1\",\"dport\":\"39264.*\"ts\":\"cD\",\""
|
||||
+ *** Slg_1 0.0 shutting fd 5
|
||||
+ ** Slg_1 0.0 Ending
|
||||
+ *** c1 0.0 closing fd 8
|
||||
+ ** c1 0.0 Ending
|
||||
+ ** top 0.0 === syslog Slg_1 -wait
|
||||
+ ** Slg_1 0.0 Waiting for syslog server (-1)
|
||||
+ * top 0.0 RESETTING after /home/fred/src/varnish-cache-haproxy/d02286d.vtc
|
||||
+ ** h1 0.0 Reset and free h1 haproxy 12728
|
||||
+ ** h1 0.0 Wait
|
||||
+ ** h1 0.0 Stop HAproxy pid=12728
|
||||
+ **** h1 0.0 Kill(2)=0: Success
|
||||
+ **** h1 0.0 STDOUT poll 0x10
|
||||
+ ** h1 0.1 WAIT4 pid=12728 status=0x0002 (user 0.000000 sys 0.004000)
|
||||
+ ** s1 0.1 Waiting for server (4/-1)
|
||||
+ * top 0.1 TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc completed
|
||||
+ # top TEST /home/fred/src/varnish-cache-haproxy/d02286d.vtc passed (0.128)
|
||||
+
|
||||
+In this latter execution the third syslog message is correct:
|
||||
+
|
||||
+ **** Slg_1 0.0 syslog|<134>Jun 7 14:10:18 haproxy[12728]: {"dip":"::1","dport":"39264","c_ip":"::1","c_port":"41245","fe_name":"fe1","be_name":"be_app","s_name":"app1","ts":"cD","bytes_read":"38"}
|
|
@ -0,0 +1,53 @@
|
|||
commit b3dae591a4fb47922d4235cf05ac66bcce443cf4
|
||||
Author: Ilya Shipitsin <chipitsine@gmail.com>
|
||||
Date: Sat May 25 03:38:14 2019 +0500
|
||||
|
||||
BUG/MINOR: ssl_sock: Fix memory leak when disabling compression
|
||||
|
||||
according to manpage:
|
||||
|
||||
sk_TYPE_zero() sets the number of elements in sk to zero. It
|
||||
does not free sk so after this call sk is still valid.
|
||||
|
||||
so we need to free all elements
|
||||
|
||||
[wt: seems like it has been there forever and should be backported
|
||||
to all stable branches]
|
||||
|
||||
(cherry picked from commit e242f3dfb8ae2f27de9d10d90a783df05d5c849b)
|
||||
[wt: adjusted context due to libressl detection]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit 273c61dfb45d968eb8b677616130cda6586977f0)
|
||||
[wt: minor adjustments due to version detection and local variables]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index fbb7cf2b..3ab63342 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -8959,11 +8959,10 @@ static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *
|
||||
__attribute__((constructor))
|
||||
static void __ssl_sock_init(void)
|
||||
{
|
||||
+ STACK_OF(SSL_COMP)* cm;
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
- STACK_OF(SSL_COMP)* cm;
|
||||
-
|
||||
if (global_ssl.listen_default_ciphers)
|
||||
global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
|
||||
if (global_ssl.connect_default_ciphers)
|
||||
@@ -8978,7 +8977,11 @@ static void __ssl_sock_init(void)
|
||||
xprt_register(XPRT_SSL, &ssl_sock);
|
||||
SSL_library_init();
|
||||
cm = SSL_COMP_get_compression_methods();
|
||||
- sk_SSL_COMP_zero(cm);
|
||||
+ i = sk_SSL_COMP_num(cm);
|
||||
+ while (i--) {
|
||||
+ (void) sk_SSL_COMP_pop(cm);
|
||||
+ }
|
||||
+
|
||||
#ifdef USE_THREAD
|
||||
ssl_locking_init();
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
commit e834ca5c6914c71a86138362423b9d6e7ce15a78
|
||||
Author: Ilya Shipitsin <chipitsine@gmail.com>
|
||||
Date: Sat May 25 19:30:50 2019 +0500
|
||||
|
||||
BUILD: ssl: fix latest LibreSSL reg-test error
|
||||
|
||||
starting with OpenSSL 1.0.0 recommended way to disable compression is
|
||||
using SSL_OP_NO_COMPRESSION when creating context.
|
||||
|
||||
manipulations with SSL_COMP_get_compression_methods, sk_SSL_COMP_num
|
||||
are only required for OpenSSL < 1.0.0
|
||||
|
||||
(cherry picked from commit 0590f44254da9203a3c9d239836f4703aa6d543b)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit be086d6dc7029aec9349e54ab5cccc499892bd61)
|
||||
[wt: context adjustments]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index 3ab63342..3436459f 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -8959,7 +8959,9 @@ static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *
|
||||
__attribute__((constructor))
|
||||
static void __ssl_sock_init(void)
|
||||
{
|
||||
+#if (!defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION))
|
||||
STACK_OF(SSL_COMP)* cm;
|
||||
+#endif
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
@@ -8976,11 +8978,13 @@ static void __ssl_sock_init(void)
|
||||
|
||||
xprt_register(XPRT_SSL, &ssl_sock);
|
||||
SSL_library_init();
|
||||
+#if (!defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION))
|
||||
cm = SSL_COMP_get_compression_methods();
|
||||
i = sk_SSL_COMP_num(cm);
|
||||
while (i--) {
|
||||
(void) sk_SSL_COMP_pop(cm);
|
||||
}
|
||||
+#endif
|
||||
|
||||
#ifdef USE_THREAD
|
||||
ssl_locking_init();
|
|
@ -0,0 +1,54 @@
|
|||
commit 5d60902ec7883bb05927c648638a009eb930acc7
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon May 27 10:17:05 2019 +0200
|
||||
|
||||
BUG/MAJOR: lb/threads: make sure the avoided server is not full on second pass
|
||||
|
||||
In fwrr_get_next_server(), we optionally pass a server to avoid. It
|
||||
usually points to the current server during a redispatch operation. If
|
||||
this server is usable, an "avoided" pointer is set and we continue to
|
||||
look for another server. If in the end no other server is found, then
|
||||
we fall back to this avoided one, which is still better than nothing.
|
||||
|
||||
The problem that may arise with threads is that in the mean time, this
|
||||
avoided server might have received extra connections and might not be
|
||||
usable anymore. This causes it to be queued a second time in the "full"
|
||||
list and the loop to search for a server again, ending up on this one
|
||||
again and so on.
|
||||
|
||||
This patch makes sure that we break out of the loop when we have to
|
||||
pick the avoided server. It's probably what the code intended to do
|
||||
as the current break statement causes fwrr_update_position() and
|
||||
fwrr_dequeue_srv() to be called again on the avoided server.
|
||||
|
||||
It must be backported to 1.9 and 1.8, and seems appropriate for older
|
||||
versions though it's unclear what the impact of this bug might be
|
||||
there since the race doesn't exist and we're left with the double
|
||||
update of the server's position.
|
||||
|
||||
(cherry picked from commit b6195ef2a6b0cb3f68bc34735313daa640ab3e92)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit 7df15f275af90110e6ab4ec75065cbfabdf764ec)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
diff --git a/src/lb_fwrr.c b/src/lb_fwrr.c
|
||||
index cba7db5f..33181b46 100644
|
||||
--- a/src/lb_fwrr.c
|
||||
+++ b/src/lb_fwrr.c
|
||||
@@ -504,7 +504,7 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
|
||||
if (switched) {
|
||||
if (avoided) {
|
||||
srv = avoided;
|
||||
- break;
|
||||
+ goto take_this_one;
|
||||
}
|
||||
goto requeue_servers;
|
||||
}
|
||||
@@ -534,6 +534,7 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
|
||||
full = srv;
|
||||
}
|
||||
|
||||
+ take_this_one:
|
||||
/* OK, we got the best server, let's update it */
|
||||
fwrr_queue_srv(srv);
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
commit 339e69400f87c34e28c67eaab6e503dc41b29d48
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue May 28 08:26:17 2019 +0200
|
||||
|
||||
BUG/MEDIUM: http: fix "http-request reject" when not final
|
||||
|
||||
When "http-request reject" was introduced in 1.8 with commit 53275e8b0
|
||||
("MINOR: http: implement the "http-request reject" rule"), it was already
|
||||
broken. The code mentions "it always returns ACT_RET_STOP" and obviously
|
||||
a gross copy-paste made it ACT_RET_CONT. If the rule is the last one it
|
||||
properly blocks, but if not the last one it gets ignored, as can be seen
|
||||
with this simple configuration :
|
||||
|
||||
frontend f1
|
||||
bind :8011
|
||||
mode http
|
||||
http-request reject
|
||||
http-request redirect location /
|
||||
|
||||
This trivial fix must be backported to 1.9 and 1.8. It is tracked by
|
||||
github issue #107.
|
||||
|
||||
(cherry picked from commit 11c90fbd92cfaa5695e328481402d62d536456ef)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit f6d5f2b27634cf3f8591016985b9fb81a1caf01c)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
[Cf: The fix was applied in the file src/proto_http.c because, in 1.8, the file
|
||||
src/http_act.c does not exist.]
|
||||
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index 32aeef2d..e5792f8c 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -12157,7 +12157,7 @@ enum act_return http_action_reject(struct act_rule *rule, struct proxy *px,
|
||||
if (!(s->flags & SF_FINST_MASK))
|
||||
s->flags |= SF_FINST_R;
|
||||
|
||||
- return ACT_RET_CONT;
|
||||
+ return ACT_RET_STOP;
|
||||
}
|
||||
|
||||
/* parse the "reject" action:
|
|
@ -0,0 +1,71 @@
|
|||
commit ee60daed3071426242fcacbb1cd9603a825b359e
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Sun Jun 2 11:11:29 2019 +0200
|
||||
|
||||
BUG/MINOR: deinit/threads: make hard-stop-after perform a clean exit
|
||||
|
||||
As reported in GH issue #99, when hard-stop-after triggers and threads
|
||||
are in use, the chance that any thread releases the resources in use by
|
||||
the other ones is non-null. Thus no thread should be allowed to deinit()
|
||||
nor exit by itself.
|
||||
|
||||
Here we take a different approach. We simply use a 3rd possible value
|
||||
for the "killed" variable so that all threads know they must break out
|
||||
of the run-poll-loop and immediately stop.
|
||||
|
||||
This patch was tested by commenting the stream_shutdown() calls in
|
||||
hard_stop() to increase the chances to see a stream use released
|
||||
resources. With this fix applied, it never crashes anymore.
|
||||
|
||||
This fix should be backported to 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit 7067b3a92efc9c9a7c3239245fdc96ea7310f46a)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit daf91d3a5c8d2b47878580a0e0bde654d92ad42a)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/include/types/global.h b/include/types/global.h
|
||||
index bd7761cd..d3721d03 100644
|
||||
--- a/include/types/global.h
|
||||
+++ b/include/types/global.h
|
||||
@@ -213,7 +213,7 @@ extern const int zero;
|
||||
extern const int one;
|
||||
extern const struct linger nolinger;
|
||||
extern int stopping; /* non zero means stopping in progress */
|
||||
-extern int killed; /* non zero means a hard-stop is triggered */
|
||||
+extern int killed; /* >0 means a hard-stop is triggered, >1 means hard-stop immediately */
|
||||
extern char hostname[MAX_HOSTNAME_LEN];
|
||||
extern char localpeer[MAX_HOSTNAME_LEN];
|
||||
extern struct list global_listener_queue; /* list of the temporarily limited listeners */
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 105cde6f..6ea17a0c 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -2431,6 +2431,10 @@ static void run_poll_loop()
|
||||
if (tid == 0 && jobs == 0)
|
||||
THREAD_WANT_SYNC();
|
||||
|
||||
+ /* also stop if we failed to cleanly stop all tasks */
|
||||
+ if (killed > 1)
|
||||
+ break;
|
||||
+
|
||||
/* expire immediately if events are pending */
|
||||
exp = now_ms;
|
||||
if (fd_cache_mask & tid_bit)
|
||||
diff --git a/src/proxy.c b/src/proxy.c
|
||||
index cff6c0aa..ef491aed 100644
|
||||
--- a/src/proxy.c
|
||||
+++ b/src/proxy.c
|
||||
@@ -942,9 +942,9 @@ struct task *hard_stop(struct task *t)
|
||||
if (killed) {
|
||||
ha_warning("Some tasks resisted to hard-stop, exiting now.\n");
|
||||
send_log(NULL, LOG_WARNING, "Some tasks resisted to hard-stop, exiting now.\n");
|
||||
- /* Do some cleanup and explicitely quit */
|
||||
- deinit();
|
||||
- exit(0);
|
||||
+ killed = 2;
|
||||
+ t->expire = TICK_ETERNITY;
|
||||
+ return t;
|
||||
}
|
||||
|
||||
ha_warning("soft-stop running for too long, performing a hard-stop.\n");
|
|
@ -0,0 +1,133 @@
|
|||
commit 30e228120ebc1caad1086d0d90383f472f710375
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon Jun 3 08:17:30 2019 +0200
|
||||
|
||||
BUG/MEDIUM: connection: fix multiple handshake polling issues
|
||||
|
||||
Connection handshakes were rarely stacked on top of each other, but the
|
||||
recent experiments consisting in sending PROXY over SOCKS4 revealed a
|
||||
number of issues in these lower layers. First, each handler waiting for
|
||||
data MUST subscribe to recv events with __conn_sock_want_recv() and MUST
|
||||
unsubscribe from send events using __conn_sock_stop_send() to avoid any
|
||||
wake-up loop in case a previous sender has set this. Second, each handler
|
||||
waiting for sending MUST subscribe to send events with __conn_sock_want_send()
|
||||
and MUST unsubscribe from recv events using __conn_sock_stop_recv() to
|
||||
avoid any wake-up loop in case some data are available on the connection.
|
||||
|
||||
Till now this was done at various random places, and in particular the
|
||||
cases where the FD was not ready for recv forgot to re-enable reading.
|
||||
|
||||
Second, while senders can happily use conn_sock_send() which automatically
|
||||
handles EINTR, loops, and marks the FD as not ready with fd_cant_send(),
|
||||
there is no equivalent for recv so receivers facing EAGAIN MUST call
|
||||
fd_cant_send() to enable polling. It could be argued that implementing
|
||||
an equivalent conn_sock_recv() function could be useful and more
|
||||
long-term proof than the current situation.
|
||||
|
||||
Third, both types of handlers MUST unsubscribe from their respective
|
||||
events once they managed to do their job, and none may even play with
|
||||
__conn_xprt_*(). Here again this was lacking, and one surprizing call
|
||||
to __conn_xprt_stop_recv() was present in the proxy protocol parser
|
||||
for TCP6 messages!
|
||||
|
||||
Thanks to Alexander Liu for his help on this issue.
|
||||
|
||||
This patch must be backported to 1.9 and possibly some older versions,
|
||||
though the SOCKS parts should be dropped.
|
||||
|
||||
(cherry picked from commit 6499b9d996ea8f57749021f56ed635c4688a727e)
|
||||
[wt: dropped SOCKS4]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit a34d37966ed87ffd9924e2b11f8003dc773e1853)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/connection.c b/src/connection.c
|
||||
index f57ef60a..e00c2f81 100644
|
||||
--- a/src/connection.c
|
||||
+++ b/src/connection.c
|
||||
@@ -404,7 +404,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
|
||||
goto fail;
|
||||
|
||||
if (!fd_recv_ready(conn->handle.fd))
|
||||
- return 0;
|
||||
+ goto not_ready;
|
||||
|
||||
do {
|
||||
trash.len = recv(conn->handle.fd, trash.str, trash.size, MSG_PEEK);
|
||||
@@ -413,7 +413,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
|
||||
continue;
|
||||
if (errno == EAGAIN) {
|
||||
fd_cant_recv(conn->handle.fd);
|
||||
- return 0;
|
||||
+ goto not_ready;
|
||||
}
|
||||
goto recv_abort;
|
||||
}
|
||||
@@ -653,8 +653,14 @@ int conn_recv_proxy(struct connection *conn, int flag)
|
||||
|
||||
conn->flags &= ~flag;
|
||||
conn->flags |= CO_FL_RCVD_PROXY;
|
||||
+ __conn_sock_stop_recv(conn);
|
||||
return 1;
|
||||
|
||||
+ not_ready:
|
||||
+ __conn_sock_want_recv(conn);
|
||||
+ __conn_sock_stop_send(conn);
|
||||
+ return 0;
|
||||
+
|
||||
missing:
|
||||
/* Missing data. Since we're using MSG_PEEK, we can only poll again if
|
||||
* we have not read anything. Otherwise we need to fail because we won't
|
||||
@@ -709,7 +715,7 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
|
||||
goto fail;
|
||||
|
||||
if (!fd_recv_ready(conn->handle.fd))
|
||||
- return 0;
|
||||
+ goto not_ready;
|
||||
|
||||
do {
|
||||
trash.len = recv(conn->handle.fd, trash.str, trash.size, MSG_PEEK);
|
||||
@@ -718,7 +724,7 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
|
||||
continue;
|
||||
if (errno == EAGAIN) {
|
||||
fd_cant_recv(conn->handle.fd);
|
||||
- return 0;
|
||||
+ goto not_ready;
|
||||
}
|
||||
goto recv_abort;
|
||||
}
|
||||
@@ -849,8 +855,14 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
|
||||
} while (0);
|
||||
|
||||
conn->flags &= ~flag;
|
||||
+ __conn_sock_stop_recv(conn);
|
||||
return 1;
|
||||
|
||||
+ not_ready:
|
||||
+ __conn_sock_want_recv(conn);
|
||||
+ __conn_sock_stop_send(conn);
|
||||
+ return 0;
|
||||
+
|
||||
missing:
|
||||
/* Missing data. Since we're using MSG_PEEK, we can only poll again if
|
||||
* we have not read anything. Otherwise we need to fail because we won't
|
||||
diff --git a/src/stream_interface.c b/src/stream_interface.c
|
||||
index 47a100d7..8e4df70a 100644
|
||||
--- a/src/stream_interface.c
|
||||
+++ b/src/stream_interface.c
|
||||
@@ -400,6 +400,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
|
||||
if (conn->flags & CO_FL_WAIT_L4_CONN)
|
||||
conn->flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
conn->flags &= ~flag;
|
||||
+ __conn_sock_stop_send(conn);
|
||||
return 1;
|
||||
|
||||
out_error:
|
||||
@@ -409,6 +410,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
|
||||
|
||||
out_wait:
|
||||
__conn_sock_stop_recv(conn);
|
||||
+ __conn_sock_want_send(conn);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
commit 47133bd99225554519c1d32293e0e5c3db83db30
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue Jun 4 16:27:36 2019 +0200
|
||||
|
||||
BUG/MEDIUM: vars: make sure the scope is always valid when accessing vars
|
||||
|
||||
Patrick Hemmer reported that a simple tcp rule involving a variable like
|
||||
this is enough to crash haproxy :
|
||||
|
||||
frontend foo
|
||||
bind :8001
|
||||
tcp-request session set-var(txn.foo) src
|
||||
|
||||
The tests on the variables scopes is not strict enough, it needs to always
|
||||
verify if the stream is valid when accessing a req/res/txn variable. This
|
||||
patch does this by adding a new get_vars() function which does the job
|
||||
instead of open-coding all the lookups everywhere.
|
||||
|
||||
It must be backported to all versions supporting set-var and
|
||||
"tcp-request session" so at least 1.9 and 1.8.
|
||||
|
||||
(cherry picked from commit f37b140b06b9963dea8adaf5e13b5b57cd219c74)
|
||||
[wt: s/_HA_/HA_/]
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit 5dcf8515592602ed0d962e365cbb74a3646727c1)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index 566ead6e..c86f612f 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -34,6 +34,25 @@ static unsigned int var_reqres_limit = 0;
|
||||
|
||||
__decl_hathreads(HA_RWLOCK_T var_names_rwlock);
|
||||
|
||||
+/* returns the struct vars pointer for a session, stream and scope, or NULL if
|
||||
+ * it does not exist.
|
||||
+ */
|
||||
+static inline struct vars *get_vars(struct session *sess, struct stream *strm, enum vars_scope scope)
|
||||
+{
|
||||
+ switch (scope) {
|
||||
+ case SCOPE_PROC:
|
||||
+ return &global.vars;
|
||||
+ case SCOPE_SESS:
|
||||
+ return &sess->vars;
|
||||
+ case SCOPE_TXN:
|
||||
+ return strm ? &strm->vars_txn : NULL;
|
||||
+ case SCOPE_REQ:
|
||||
+ case SCOPE_RES:
|
||||
+ default:
|
||||
+ return strm ? &strm->vars_reqres : NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* This function adds or remove memory size from the accounting. The inner
|
||||
* pointers may be null when setting the outer ones only.
|
||||
*/
|
||||
@@ -42,10 +61,12 @@ static void var_accounting_diff(struct vars *vars, struct session *sess, struct
|
||||
switch (vars->scope) {
|
||||
case SCOPE_REQ:
|
||||
case SCOPE_RES:
|
||||
- HA_ATOMIC_ADD(&strm->vars_reqres.size, size);
|
||||
+ if (strm)
|
||||
+ HA_ATOMIC_ADD(&strm->vars_reqres.size, size);
|
||||
/* fall through */
|
||||
case SCOPE_TXN:
|
||||
- HA_ATOMIC_ADD(&strm->vars_txn.size, size);
|
||||
+ if (strm)
|
||||
+ HA_ATOMIC_ADD(&strm->vars_txn.size, size);
|
||||
/* fall through */
|
||||
case SCOPE_SESS:
|
||||
HA_ATOMIC_ADD(&sess->vars.size, size);
|
||||
@@ -68,11 +89,11 @@ static int var_accounting_add(struct vars *vars, struct session *sess, struct st
|
||||
switch (vars->scope) {
|
||||
case SCOPE_REQ:
|
||||
case SCOPE_RES:
|
||||
- if (var_reqres_limit && strm->vars_reqres.size + size > var_reqres_limit)
|
||||
+ if (var_reqres_limit && strm && strm->vars_reqres.size + size > var_reqres_limit)
|
||||
return 0;
|
||||
/* fall through */
|
||||
case SCOPE_TXN:
|
||||
- if (var_txn_limit && strm->vars_txn.size + size > var_txn_limit)
|
||||
+ if (var_txn_limit && strm && strm->vars_txn.size + size > var_txn_limit)
|
||||
return 0;
|
||||
/* fall through */
|
||||
case SCOPE_SESS:
|
||||
@@ -285,27 +306,8 @@ static int smp_fetch_var(const struct arg *args, struct sample *smp, const char
|
||||
struct vars *vars;
|
||||
|
||||
/* Check the availibity of the variable. */
|
||||
- switch (var_desc->scope) {
|
||||
- case SCOPE_PROC:
|
||||
- vars = &global.vars;
|
||||
- break;
|
||||
- case SCOPE_SESS:
|
||||
- vars = &smp->sess->vars;
|
||||
- break;
|
||||
- case SCOPE_TXN:
|
||||
- if (!smp->strm)
|
||||
- return 0;
|
||||
- vars = &smp->strm->vars_txn;
|
||||
- break;
|
||||
- case SCOPE_REQ:
|
||||
- case SCOPE_RES:
|
||||
- default:
|
||||
- if (!smp->strm)
|
||||
- return 0;
|
||||
- vars = &smp->strm->vars_reqres;
|
||||
- break;
|
||||
- }
|
||||
- if (vars->scope != var_desc->scope)
|
||||
+ vars = get_vars(smp->sess, smp->strm, var_desc->scope);
|
||||
+ if (!vars || vars->scope != var_desc->scope)
|
||||
return 0;
|
||||
|
||||
HA_RWLOCK_RDLOCK(VARS_LOCK, &vars->rwlock);
|
||||
@@ -423,15 +425,8 @@ static inline int sample_store_stream(const char *name, enum vars_scope scope, s
|
||||
struct vars *vars;
|
||||
int ret;
|
||||
|
||||
- switch (scope) {
|
||||
- case SCOPE_PROC: vars = &global.vars; break;
|
||||
- case SCOPE_SESS: vars = &smp->sess->vars; break;
|
||||
- case SCOPE_TXN: vars = &smp->strm->vars_txn; break;
|
||||
- case SCOPE_REQ:
|
||||
- case SCOPE_RES:
|
||||
- default: vars = &smp->strm->vars_reqres; break;
|
||||
- }
|
||||
- if (vars->scope != scope)
|
||||
+ vars = get_vars(smp->sess, smp->strm, scope);
|
||||
+ if (!vars || vars->scope != scope)
|
||||
return 0;
|
||||
|
||||
HA_RWLOCK_WRLOCK(VARS_LOCK, &vars->rwlock);
|
||||
@@ -447,15 +442,8 @@ static inline int sample_clear_stream(const char *name, enum vars_scope scope, s
|
||||
struct var *var;
|
||||
unsigned int size = 0;
|
||||
|
||||
- switch (scope) {
|
||||
- case SCOPE_PROC: vars = &global.vars; break;
|
||||
- case SCOPE_SESS: vars = &smp->sess->vars; break;
|
||||
- case SCOPE_TXN: vars = &smp->strm->vars_txn; break;
|
||||
- case SCOPE_REQ:
|
||||
- case SCOPE_RES:
|
||||
- default: vars = &smp->strm->vars_reqres; break;
|
||||
- }
|
||||
- if (vars->scope != scope)
|
||||
+ vars = get_vars(smp->sess, smp->strm, scope);
|
||||
+ if (!vars || vars->scope != scope)
|
||||
return 0;
|
||||
|
||||
/* Look for existing variable name. */
|
||||
@@ -586,17 +574,8 @@ int vars_get_by_name(const char *name, size_t len, struct sample *smp)
|
||||
return 0;
|
||||
|
||||
/* Select "vars" pool according with the scope. */
|
||||
- switch (scope) {
|
||||
- case SCOPE_PROC: vars = &global.vars; break;
|
||||
- case SCOPE_SESS: vars = &smp->sess->vars; break;
|
||||
- case SCOPE_TXN: vars = &smp->strm->vars_txn; break;
|
||||
- case SCOPE_REQ:
|
||||
- case SCOPE_RES:
|
||||
- default: vars = &smp->strm->vars_reqres; break;
|
||||
- }
|
||||
-
|
||||
- /* Check if the scope is avalaible a this point of processing. */
|
||||
- if (vars->scope != scope)
|
||||
+ vars = get_vars(smp->sess, smp->strm, scope);
|
||||
+ if (!vars || vars->scope != scope)
|
||||
return 0;
|
||||
|
||||
/* Get the variable entry. */
|
||||
@@ -620,17 +599,10 @@ int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp)
|
||||
struct var *var;
|
||||
|
||||
/* Select "vars" pool according with the scope. */
|
||||
- switch (var_desc->scope) {
|
||||
- case SCOPE_PROC: vars = &global.vars; break;
|
||||
- case SCOPE_SESS: vars = &smp->sess->vars; break;
|
||||
- case SCOPE_TXN: vars = &smp->strm->vars_txn; break;
|
||||
- case SCOPE_REQ:
|
||||
- case SCOPE_RES:
|
||||
- default: vars = &smp->strm->vars_reqres; break;
|
||||
- }
|
||||
+ vars = get_vars(smp->sess, smp->strm, var_desc->scope);
|
||||
|
||||
- /* Check if the scope is avalaible a this point of processing. */
|
||||
- if (vars->scope != var_desc->scope)
|
||||
+ /* Check if the scope is available a this point of processing. */
|
||||
+ if (!vars || vars->scope != var_desc->scope)
|
||||
return 0;
|
||||
|
||||
/* Get the variable entry. */
|
|
@ -0,0 +1,44 @@
|
|||
commit a41ac2d710711f3ab91d92415278a73c358aedca
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue Jun 4 16:43:29 2019 +0200
|
||||
|
||||
BUG/MEDIUM: vars: make the tcp/http unset-var() action support conditions
|
||||
|
||||
Patrick Hemmer reported that http-request unset-var(foo) if ... fails to
|
||||
parse. The reason is that it reuses the same parser as "set-var(foo)" which
|
||||
makes a special case of the arguments, supposed to be a sample expression
|
||||
for set-var, but which must not exist for unset-var. Unfortunately the
|
||||
parser finds "if" or "unless" and believes it's an expression. Let's simply
|
||||
drop the test so that the outer rule parser deals with potential extraneous
|
||||
keywords.
|
||||
|
||||
This should be backported to all versions supporting unset-var().
|
||||
|
||||
(cherry picked from commit 4b7531f48b5aa66d11fcee2836c201644bfb6a71)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit a47e745276662db361637914b8558984f091306b)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index c86f612f..d69fb838 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -684,6 +684,7 @@ static int conv_check_var(struct arg *args, struct sample_conv *conv,
|
||||
* the format:
|
||||
*
|
||||
* set-var(<variable-name>) <expression>
|
||||
+ * unset-var(<variable-name>)
|
||||
*
|
||||
* It returns ACT_RET_PRS_ERR if fails and <err> is filled with an error
|
||||
* message. Otherwise, it returns ACT_RET_PRS_OK and the variable <expr>
|
||||
@@ -727,10 +728,6 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
|
||||
/* There is no fetch method when variable is unset. Just set the right
|
||||
* action and return. */
|
||||
if (!set_var) {
|
||||
- if (*args[*arg]) {
|
||||
- memprintf(err, "fetch method not supported");
|
||||
- return ACT_RET_PRS_ERR;
|
||||
- }
|
||||
rule->action = ACT_CUSTOM;
|
||||
rule->action_ptr = action_clear;
|
||||
return ACT_RET_PRS_OK;
|
|
@ -0,0 +1,73 @@
|
|||
commit e7c30a33646f4ec73041ea57bd9fdcdc3e4a80ab
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Fri Jun 7 08:20:46 2019 +0200
|
||||
|
||||
BUG/MEDIUM: mux-h2: make sure the connection timeout is always set
|
||||
|
||||
There seems to be a tricky case in the H2 mux related to stream flow
|
||||
control versus buffer a full situation : is a large response cannot
|
||||
be entirely sent to the client due to the stream window being too
|
||||
small, the stream is paused with the SFCTL flag. Then the upper
|
||||
layer stream might get bored and expire this stream. It will then
|
||||
shut it down first. But the shutdown operation might fail if the
|
||||
mux buffer is full, resulting in the h2s being subscribed to the
|
||||
deferred_shut event with the stream *not* added to the send_list
|
||||
since it's blocked in SFCTL. In the mean time the upper layer completely
|
||||
closes, calling h2_detach(). There we have a send_wait (the pending
|
||||
shutw), the stream is marked with SFCTL so we orphan it.
|
||||
|
||||
Then if the client finally reads all the data that were clogging the
|
||||
buffer, the send_list is run again, but our stream is not there. From
|
||||
this point, the connection's stream list is not empty, the mux buffer
|
||||
is empty, so the connection's timeout is not set. If the client
|
||||
disappears without updating the stream's window, nothing will expire
|
||||
the connection.
|
||||
|
||||
This patch makes sure we always keep the connection timeout updated.
|
||||
There might be finer solutions, such as checking that there are still
|
||||
living streams in the connection (i.e. streams not blocked in SFCTL
|
||||
state), though this is not necessarily trivial nor useful, since the
|
||||
client timeout is the same for the upper level stream and the connection
|
||||
anyway.
|
||||
|
||||
This patch needs to be backported to 1.9 and 1.8 after some observation.
|
||||
|
||||
(cherry picked from commit 7348119fb22bf761c33e06e8a092bd006660cc81)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit e76090f78b6b8c519abf20061bfc5a4423816ea5)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/src/mux_h2.c b/src/mux_h2.c
|
||||
index b2f3096e..985b9742 100644
|
||||
--- a/src/mux_h2.c
|
||||
+++ b/src/mux_h2.c
|
||||
@@ -2406,12 +2406,8 @@ static int h2_wake(struct connection *conn)
|
||||
}
|
||||
|
||||
if (h2c->task) {
|
||||
- if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) {
|
||||
- h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
- task_queue(h2c->task);
|
||||
- }
|
||||
- else
|
||||
- h2c->task->expire = TICK_ETERNITY;
|
||||
+ h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
+ task_queue(h2c->task);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2587,12 +2583,8 @@ static void h2_detach(struct conn_stream *cs)
|
||||
h2_release(h2c->conn);
|
||||
}
|
||||
else if (h2c->task) {
|
||||
- if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) {
|
||||
- h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
- task_queue(h2c->task);
|
||||
- }
|
||||
- else
|
||||
- h2c->task->expire = TICK_ETERNITY;
|
||||
+ h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
+ task_queue(h2c->task);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
commit 8a74cad9b7fe8b9e1f5b140d90360ece838a878e
|
||||
Author: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue Jun 11 16:01:56 2019 +0200
|
||||
|
||||
BUG/MINOR: http-rules: mention "deny_status" for "deny" in the error message
|
||||
|
||||
The error message indicating an unknown keyword on an http-request rule
|
||||
doesn't mention the "deny_status" option which comes with the "deny" rule,
|
||||
this is particularly confusing.
|
||||
|
||||
This can be backported to all versions supporting this option.
|
||||
|
||||
(cherry picked from commit 5abdc760c99a0011607f2cc97e199ef6ce0e8486)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 4e66beaf2a32bd835db9de61a60318648258f649)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
[Cf: The fix was applied on src/proto_http.c because, in 1.8, the file
|
||||
src/http_rules.c does not exist.]
|
||||
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index e5792f8c..689e0e31 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -8830,7 +8830,8 @@ struct act_rule *parse_http_req_cond(const char **args, const char *file, int li
|
||||
rule->cond = cond;
|
||||
}
|
||||
else if (*args[cur_arg]) {
|
||||
- ha_alert("parsing [%s:%d]: 'http-request %s' expects 'realm' for 'auth' or"
|
||||
+ ha_alert("parsing [%s:%d]: 'http-request %s' expects 'realm' for 'auth',"
|
||||
+ " 'deny_status' for 'deny', or"
|
||||
" either 'if' or 'unless' followed by a condition but found '%s'.\n",
|
||||
file, linenum, args[0], args[cur_arg]);
|
||||
goto out_err;
|
|
@ -0,0 +1,30 @@
|
|||
commit 8f2772f5c603168ad3f79adc9e17569f510274ca
|
||||
Author: Kazuo Yagi <kazuo.yagi@gmail.com>
|
||||
Date: Thu Jun 13 17:14:57 2019 +0900
|
||||
|
||||
MINOR: doc: Remove -Ds option in man page
|
||||
|
||||
Remove -Ds option in man page.
|
||||
|
||||
Should be backported in every version since 1.8.
|
||||
|
||||
(cherry picked from commit 971c3943be1283e9d377d68f95ea467304b3a8da)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit a5e78ea5150f31190e4c1cd38fa7c1cadbf1ae8a)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/doc/haproxy.1 b/doc/haproxy.1
|
||||
index 91f58a3b..cfed2cf7 100644
|
||||
--- a/doc/haproxy.1
|
||||
+++ b/doc/haproxy.1
|
||||
@@ -77,10 +77,6 @@ starting up.
|
||||
\fB\-D\fP
|
||||
Start in daemon mode.
|
||||
|
||||
-.TP
|
||||
-\fB\-Ds\fP
|
||||
-Start in systemd daemon mode, keeping a process in foreground.
|
||||
-
|
||||
.TP
|
||||
\fB\-q\fP
|
||||
Disable messages on output.
|
|
@ -0,0 +1,55 @@
|
|||
commit 4fb0b5fb585e7f697914e935fe1001f752da8470
|
||||
Author: William Lallemand <wlallemand@haproxy.org>
|
||||
Date: Thu Jun 13 11:51:09 2019 +0200
|
||||
|
||||
MINOR: doc: add master-worker in the man page
|
||||
|
||||
Add some information about the master-worker in the man page.
|
||||
|
||||
Should be backported in every version since 1.8.
|
||||
|
||||
(cherry picked from commit 95635ddac8c29859d297e8ba33174e71efd5fc47)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit d7a0c4695f00765dc03d7d6f6e17058726e84951)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
diff --git a/doc/haproxy.1 b/doc/haproxy.1
|
||||
index cfed2cf7..2a23674f 100644
|
||||
--- a/doc/haproxy.1
|
||||
+++ b/doc/haproxy.1
|
||||
@@ -6,7 +6,7 @@ HAProxy \- fast and reliable http reverse proxy and load balancer
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
-haproxy \-f <configuration\ file|dir> [\-L\ <name>] [\-n\ maxconn] [\-N\ maxconn] [\-C\ <dir>] [\-v|\-vv] [\-d] [\-D] [\-q] [\-V] [\-c] [\-p\ <pidfile>] [\-dk] [\-ds] [\-de] [\-dp] [\-db] [\-dM[<byte>]] [\-m\ <megs>] [\-x <unix_socket>] [{\-sf|\-st}\ pidlist...]
|
||||
+haproxy \-f <configuration\ file|dir> [\-L\ <name>] [\-n\ maxconn] [\-N\ maxconn] [\-C\ <dir>] [\-v|\-vv] [\-d] [\-D] [\-W] [\-Ws] [\-q] [\-V] [\-c] [\-p\ <pidfile>] [\-dk] [\-ds] [\-de] [\-dp] [\-db] [\-dM[<byte>]] [\-m\ <megs>] [\-x <unix_socket>] [{\-sf|\-st}\ pidlist...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
@@ -77,6 +77,16 @@ starting up.
|
||||
\fB\-D\fP
|
||||
Start in daemon mode.
|
||||
|
||||
+.TP
|
||||
+\fB\-W\fP
|
||||
+Start in master-worker mode. Could be used either with foreground or daemon
|
||||
+mode.
|
||||
+
|
||||
+.TP
|
||||
+\fB\-Ws\fP
|
||||
+Start in master-worker mode with systemd notify support. It tells systemd when
|
||||
+the process is ready. This mode forces foreground.
|
||||
+
|
||||
.TP
|
||||
\fB\-q\fP
|
||||
Disable messages on output.
|
||||
@@ -172,6 +182,9 @@ Some signals have a special meaning for the haproxy daemon. Generally, they are
|
||||
\- \fBSIGUSR1\fP
|
||||
Tells the daemon to stop all proxies and exit once all sessions are closed. It is often referred to as the "soft-stop" signal.
|
||||
.TP
|
||||
+\- \fBSIGUSR2\fP
|
||||
+In master-worker mode, reloads the configuration and sends a soft-stop signal to old processes.
|
||||
+.TP
|
||||
\- \fBSIGTTOU\fP
|
||||
Tells the daemon to stop listening to all sockets. Used internally by \fB\-sf\fP and \fB\-st\fP.
|
||||
.TP
|
|
@ -0,0 +1,249 @@
|
|||
commit a27131f6e1e6c3e16e056915ba5ec2c560051296
|
||||
Author: Tim Duesterhus <tim@bastelstu.be>
|
||||
Date: Mon Jun 17 16:10:07 2019 +0200
|
||||
|
||||
BUG/MEDIUM: compression: Set Vary: Accept-Encoding for compressed responses
|
||||
|
||||
Make HAProxy set the `Vary: Accept-Encoding` response header if it compressed
|
||||
the server response.
|
||||
|
||||
Technically the `Vary` header SHOULD also be set for responses that would
|
||||
normally be compressed based off the current configuration, but are not due
|
||||
to a missing or invalid `Accept-Encoding` request header or due to the
|
||||
maximum compression rate being exceeded.
|
||||
|
||||
Not setting the header in these cases does no real harm, though: An
|
||||
uncompressed response might be returned by a Cache, even if a compressed
|
||||
one could be retrieved from HAProxy. This increases the traffic to the end
|
||||
user if the cache is unable to compress itself, but it saves another
|
||||
roundtrip to HAProxy.
|
||||
|
||||
see the discussion on the mailing list: https://www.mail-archive.com/haproxy@formilux.org/msg34221.html
|
||||
Message-ID: 20190617121708.GA2964@1wt.eu
|
||||
|
||||
A small issue remains: The User-Agent is not added to the `Vary` header,
|
||||
despite being relevant to the response. Adding the User-Agent header would
|
||||
make responses effectively uncacheable and it's unlikely to see a Mozilla/4
|
||||
in the wild in 2019.
|
||||
|
||||
Add a reg-test to ensure the behaviour as described in this commit message.
|
||||
|
||||
see issue #121
|
||||
Should be backported to all branches with compression (i.e. 1.6+).
|
||||
|
||||
(cherry picked from commit 721d686bd10dc6993859f9026ad907753d1d2064)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit eaf650083924a697cde3379703984c5e7a5ebd41)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 96942d657ec7f29a328a5759558dbaa26d8e3e53)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
[Cf: The patch was updated because there is no HTX in 1.8]
|
||||
|
||||
diff --git a/reg-tests/compression/vary.vtc b/reg-tests/compression/vary.vtc
|
||||
new file mode 100644
|
||||
index 00000000..0a060e4b
|
||||
--- /dev/null
|
||||
+++ b/reg-tests/compression/vary.vtc
|
||||
@@ -0,0 +1,187 @@
|
||||
+varnishtest "Compression sets Vary header"
|
||||
+
|
||||
+#REQUIRE_VERSION=1.9
|
||||
+#REQUIRE_OPTION=ZLIB|SLZ
|
||||
+
|
||||
+feature ignore_unknown_macro
|
||||
+
|
||||
+server s1 {
|
||||
+ rxreq
|
||||
+ expect req.url == "/plain/accept-encoding-gzip"
|
||||
+ expect req.http.accept-encoding == "gzip"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/plain" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/plain/accept-encoding-invalid"
|
||||
+ expect req.http.accept-encoding == "invalid"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/plain" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/plain/accept-encoding-null"
|
||||
+ expect req.http.accept-encoding == "<undef>"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/plain" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/html/accept-encoding-gzip"
|
||||
+ expect req.http.accept-encoding == "gzip"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/html" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/html/accept-encoding-invalid"
|
||||
+ expect req.http.accept-encoding == "invalid"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/html" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/html/accept-encoding-null"
|
||||
+ expect req.http.accept-encoding == "<undef>"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/html" \
|
||||
+ -bodylen 100
|
||||
+
|
||||
+ rxreq
|
||||
+ expect req.url == "/dup-etag/accept-encoding-gzip"
|
||||
+ expect req.http.accept-encoding == "gzip"
|
||||
+ txresp \
|
||||
+ -hdr "Content-Type: text/plain" \
|
||||
+ -hdr "ETag: \"123\"" \
|
||||
+ -hdr "ETag: \"123\"" \
|
||||
+ -bodylen 100
|
||||
+} -repeat 2 -start
|
||||
+
|
||||
+
|
||||
+haproxy h1 -conf {
|
||||
+ defaults
|
||||
+ mode http
|
||||
+ ${no-htx} option http-use-htx
|
||||
+ timeout connect 1s
|
||||
+ timeout client 1s
|
||||
+ timeout server 1s
|
||||
+
|
||||
+ frontend fe-gzip
|
||||
+ bind "fd@${fe_gzip}"
|
||||
+ default_backend be-gzip
|
||||
+
|
||||
+ backend be-gzip
|
||||
+ compression algo gzip
|
||||
+ compression type text/plain
|
||||
+ server www ${s1_addr}:${s1_port}
|
||||
+
|
||||
+ frontend fe-nothing
|
||||
+ bind "fd@${fe_nothing}"
|
||||
+ default_backend be-nothing
|
||||
+
|
||||
+ backend be-nothing
|
||||
+ server www ${s1_addr}:${s1_port}
|
||||
+} -start
|
||||
+
|
||||
+client c1 -connect ${h1_fe_gzip_sock} {
|
||||
+ txreq -url "/plain/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.content-encoding == "gzip"
|
||||
+ expect resp.http.vary == "Accept-Encoding"
|
||||
+ gunzip
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/plain/accept-encoding-invalid" \
|
||||
+ -hdr "Accept-Encoding: invalid"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/plain/accept-encoding-null"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-invalid" \
|
||||
+ -hdr "Accept-Encoding: invalid"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-null"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/dup-etag/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+} -run
|
||||
+
|
||||
+# This Client duplicates c1, against the "nothing" frontend, ensuring no Vary header is ever set.
|
||||
+client c2 -connect ${h1_fe_nothing_sock} {
|
||||
+ txreq -url "/plain/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/plain/accept-encoding-invalid" \
|
||||
+ -hdr "Accept-Encoding: invalid"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/plain/accept-encoding-null"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-invalid" \
|
||||
+ -hdr "Accept-Encoding: invalid"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/html/accept-encoding-null"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+
|
||||
+ txreq -url "/dup-etag/accept-encoding-gzip" \
|
||||
+ -hdr "Accept-Encoding: gzip"
|
||||
+ rxresp
|
||||
+ expect resp.status == 200
|
||||
+ expect resp.http.vary == "<undef>"
|
||||
+ expect resp.bodylen == 100
|
||||
+} -run
|
||||
diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c
|
||||
index b93ff69e..b48a4491 100644
|
||||
--- a/src/flt_http_comp.c
|
||||
+++ b/src/flt_http_comp.c
|
||||
@@ -555,6 +555,9 @@ select_compression_response_header(struct comp_state *st, struct stream *s, stru
|
||||
if (!(msg->flags & HTTP_MSGF_TE_CHNK))
|
||||
http_header_add_tail2(&txn->rsp, &txn->hdr_idx, "Transfer-Encoding: chunked", 26);
|
||||
|
||||
+ /* add Vary header */
|
||||
+ if (http_header_add_tail2(&txn->rsp, &txn->hdr_idx, "Vary: Accept-Encoding", 21) < 0)
|
||||
+ goto fail;
|
||||
/*
|
||||
* Add Content-Encoding header when it's not identity encoding.
|
||||
* RFC 2616 : Identity encoding: This content-coding is used only in the
|
|
@ -8,7 +8,7 @@
|
|||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
@@ -61,6 +62,17 @@
|
||||
@@ -60,6 +61,17 @@
|
||||
#include <openssl/async.h>
|
||||
#endif
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
#include <import/lru.h>
|
||||
#include <import/xxhash.h>
|
||||
|
||||
@@ -206,7 +218,7 @@ static struct {
|
||||
@@ -217,7 +229,7 @@ static struct {
|
||||
.capture_cipherlist = 0,
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
static HA_RWLOCK_T *ssl_rwlocks;
|
||||
|
||||
@@ -1675,8 +1687,8 @@ ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL
|
||||
@@ -1716,8 +1728,8 @@ ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(newcrt), HA_ATOMIC_ADD(&ssl_ctx_serial, 1));
|
||||
|
||||
/* Set duration for the certificate */
|
||||
|
@ -46,7 +46,7 @@
|
|||
goto mkcert_error;
|
||||
|
||||
/* set public key in the certificate */
|
||||
@@ -6226,7 +6238,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
|
||||
@@ -6299,7 +6311,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
|
||||
goto out;
|
||||
|
||||
smp_trash = get_trash_chunk();
|
||||
|
@ -55,7 +55,7 @@
|
|||
goto out;
|
||||
|
||||
smp->data.u.str = *smp_trash;
|
||||
@@ -6326,7 +6338,7 @@ smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char
|
||||
@@ -6399,7 +6411,7 @@ smp_fetch_ssl_x_notbefore(const struct a
|
||||
goto out;
|
||||
|
||||
smp_trash = get_trash_chunk();
|
||||
|
@ -64,21 +64,26 @@
|
|||
goto out;
|
||||
|
||||
smp->data.u.str = *smp_trash;
|
||||
@@ -8777,10 +8789,12 @@ static void __ssl_sock_init(void)
|
||||
global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
|
||||
@@ -8977,7 +8989,9 @@ static void __ssl_sock_init(void)
|
||||
#endif
|
||||
|
||||
xprt_register(XPRT_SSL, &ssl_sock);
|
||||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
SSL_library_init();
|
||||
+#endif
|
||||
#if (!defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION))
|
||||
cm = SSL_COMP_get_compression_methods();
|
||||
sk_SSL_COMP_zero(cm);
|
||||
i = sk_SSL_COMP_num(cm);
|
||||
@@ -8986,7 +9000,7 @@ static void __ssl_sock_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
-#ifdef USE_THREAD
|
||||
+#if defined(USE_THREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
ssl_locking_init();
|
||||
#endif
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
|
||||
@@ -8808,8 +8822,8 @@ static void __ssl_sock_init(void)
|
||||
@@ -9015,8 +9029,8 @@ static void __ssl_sock_init(void)
|
||||
#else /* OPENSSL_IS_BORINGSSL */
|
||||
OPENSSL_VERSION_TEXT
|
||||
"\nRunning on OpenSSL version : %s%s",
|
||||
|
@ -89,7 +94,7 @@
|
|||
#endif
|
||||
memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
@@ -8900,12 +8914,14 @@ static void __ssl_sock_deinit(void)
|
||||
@@ -9107,12 +9121,14 @@ static void __ssl_sock_deinit(void)
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue