haproxy: revert update commits

- Revert "package haproxy: fix typo for buildvariant nossl"
 - Revert "haproxy: bump to version 1.6.9 mainline and pending patches"

Signed-off-by: heil <heil@terminal-consulting.de>
This commit is contained in:
heil 2016-11-10 18:45:24 +01:00
parent 3e74e44c00
commit 33380cf7e2
31 changed files with 271 additions and 1390 deletions

View File

@ -1,6 +1,6 @@
#
# Copyright (C) 2010-2016 OpenWrt.org
# Copyright (C) 2009-2016 Thomas Heil <heil@terminal-consulting.de>
# Copyright (C) 2010-2013 OpenWrt.org
# Copyright (C) 2009-2014 Thomas Heil <heil@terminal-consulting.de>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@ -9,16 +9,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
PKG_VERSION:=1.6.9
PKG_RELEASE:=26
PKG_VERSION:=1.5.18
PKG_RELEASE:=04
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.6/src/
PKG_MD5SUM:=c52eee40eb66f290d6f089c339b9d2b3
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MD5SUM:=21d35f114583ef731bc96af05b46c75a
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
PKG_LICENSE:=GPL-2.0
MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
include $(INCLUDE_DIR)/package.mk
@ -30,18 +28,6 @@ define Package/haproxy/Default
URL:=http://haproxy.1wt.eu/
endef
define Download/lua533
FILE:=lua-5.3.3.tar.gz
URL:=http://www.lua.org/ftp/
MD5SUM:=703f75caa4fdf4a911c1a72e67a27498
endef
define Build/Prepare
$(call Build/Prepare/Default)
tar -zxvf $(DL_DIR)/lua-5.3.3.tar.gz -C $(PKG_BUILD_DIR)
ln -s $(PKG_BUILD_DIR)/lua-5.3.3 $(PKG_BUILD_DIR)/lua
endef
define Package/haproxy/Default/conffiles
/etc/haproxy.cfg
endef
@ -63,14 +49,14 @@ endef
define Package/haproxy/description
$(call Package/haproxy/Default/description)
This package is built with SSL and LUA support.
This package is built with SSL support.
endef
define Package/haproxy-nossl
TITLE+= (without SSL support)
VARIANT:=nossl
DEPENDS+= +libpcre +libltdl +zlib +libpthread
TITLE+= (without SSL support)
TITLE+= (with SSL support)
$(call Package/haproxy/Default)
endef
@ -90,47 +76,28 @@ else
endif
ifeq ($(BUILD_VARIANT),ssl)
ADDON+=USE_OPENSSL=1
ADDON+=USE_LUA=1
ADDON+=LUA_LIB_NAME="lua533"
ADDON+=LUA_INC="$(STAGING_DIR)/lua-5.3.3/include"
ADDON+=LUA_LIB="$(STAGING_DIR)/lua-5.3.3/lib"
ADDON+=ADDLIB="-lcrypto -lm"
USE_OPENSSL=USE_OPENSSL=1
else
ADDON+=ADDLIB="-lm"
USE_OPENSSL=
endif
define Build/Compile
make TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR)/lua INSTALL_TOP="$(STAGING_DIR)/lua-5.3.3/" linux install
mv $(STAGING_DIR)/lua-5.3.3/lib/liblua.a $(STAGING_DIR)/lua-5.3.3/lib/liblua533.a
$(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS) -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -pipe -fomit-frame-pointer -fhonour-copts" \
LD="$(TARGET_CC)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
$(ADDON)
PCREDIR="$(STAGING_DIR)/usr/include" \
PCREDIR="$(STAGING_DIR)/usr" \
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530 " \
USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 USE_REGPARM=1 \
USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 USE_REGPARM=1 $(USE_OPENSSL) \
USE_ZLIB=yes USE_PCRE=1 \
VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
IGNOREGIT=1
$(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
install
$(MAKE) -C $(PKG_BUILD_DIR)/contrib/halog \
DESTDIR="$(PKG_INSTALL_DIR)" \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS) -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -pipe -fomit-frame-pointer -fhonour-copts" \
LD="$(TARGET_CC)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
ADDLIB="-lcrypto" \
VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
CC="$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS)" \
OPTIMIZE="" \
halog
endef
@ -147,10 +114,9 @@ endef
Package/haproxy-nossl/install = $(Package/haproxy/install)
define Package/halog
MENU:=1
$(call Package/haproxy)
$(call Package/haproxy/Default)
TITLE+= halog
DEPENDS:=haproxy
endef
@ -164,8 +130,6 @@ define Package/halog/install
$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/halog/halog $(1)/usr/bin/
endef
$(eval $(call Download,lua533))
$(eval $(call BuildPackage,haproxy-nossl))
$(eval $(call BuildPackage,haproxy))
$(eval $(call BuildPackage,halog))
$(eval $(call BuildPackage,haproxy-nossl))

View File

@ -0,0 +1,131 @@
From a72d39058a7a5d004e0c6b69a91663591bb3bf89 Mon Sep 17 00:00:00 2001
From: Vincent Bernat <vincent@bernat.im>
Date: Thu, 19 May 2016 11:15:51 +0200
Subject: [PATCH 1/4] BUG/MAJOR: fix listening IP address storage for frontends
When compiled with GCC 6, the IP address specified for a frontend was
ignored and HAProxy was listening on all addresses instead. This is
caused by an incomplete copy of a "struct sockaddr_storage".
With the GNU Libc, "struct sockaddr_storage" is defined as this:
struct sockaddr_storage
{
sa_family_t ss_family;
unsigned long int __ss_align;
char __ss_padding[(128 - (2 * sizeof (unsigned long int)))];
};
Doing an aggregate copy (ss1 = ss2) is different than using memcpy():
only members of the aggregate have to be copied. Notably, padding can be
or not be copied. In GCC 6, some optimizations use this fact and if a
"struct sockaddr_storage" contains a "struct sockaddr_in", the port and
the address are part of the padding (between sa_family and __ss_align)
and can be not copied over.
Therefore, we replace any aggregate copy by a memcpy(). There is another
place using the same pattern. We also fix a function receiving a "struct
sockaddr_storage" by copy instead of by reference. Since it only needs a
read-only copy, the function is converted to request a reference.
This is a backport for 1.5 of 6e6158 and 6e46ff1.
---
src/cfgparse.c | 4 ++--
src/connection.c | 2 +-
src/proto_http.c | 12 ++++++------
src/proto_tcp.c | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 39abf6b..9331415 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -280,7 +280,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
}
/* OK the address looks correct */
- ss = *ss2;
+ memcpy(&ss, ss2, sizeof(ss));
for (; port <= end; port++) {
l = (struct listener *)calloc(1, sizeof(struct listener));
@@ -291,7 +291,7 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
l->bind_conf = bind_conf;
l->fd = fd;
- l->addr = ss;
+ memcpy(&l->addr, &ss, sizeof(ss));
l->xprt = &raw_sock;
l->state = LI_INIT;
diff --git a/src/connection.c b/src/connection.c
index dab1c90..09fd04e 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -620,7 +620,7 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec
const char pp2_signature[] = PP2_SIGNATURE;
int ret = 0;
struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf;
- struct sockaddr_storage null_addr = {0};
+ struct sockaddr_storage null_addr = { .ss_family = 0 };
struct sockaddr_storage *src = &null_addr;
struct sockaddr_storage *dst = &null_addr;
#ifdef USE_OPENSSL
diff --git a/src/proto_http.c b/src/proto_http.c
index b3aa4d8..0b13c5e 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -3220,15 +3220,15 @@ int http_handle_stats(struct session *s, struct channel *req)
/* Sets the TOS header in IPv4 and the traffic class header in IPv6 packets
* (as per RFC3260 #4 and BCP37 #4.2 and #5.2).
*/
-static inline void inet_set_tos(int fd, struct sockaddr_storage from, int tos)
+static inline void inet_set_tos(int fd, struct sockaddr_storage *from, int tos)
{
#ifdef IP_TOS
- if (from.ss_family == AF_INET)
+ if (from->ss_family == AF_INET)
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
#endif
#ifdef IPV6_TCLASS
- if (from.ss_family == AF_INET6) {
- if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&from)->sin6_addr))
+ if (from->ss_family == AF_INET6) {
+ if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)from)->sin6_addr))
/* v4-mapped addresses need IP_TOS */
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
else
@@ -3366,7 +3366,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
case HTTP_REQ_ACT_SET_TOS:
if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
- inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
+ inet_set_tos(cli_conn->t.sock.fd, &cli_conn->addr.from, rule->arg.tos);
break;
case HTTP_REQ_ACT_SET_MARK:
@@ -3563,7 +3563,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session
case HTTP_RES_ACT_SET_TOS:
if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
- inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
+ inet_set_tos(cli_conn->t.sock.fd, &cli_conn->addr.from, rule->arg.tos);
break;
case HTTP_RES_ACT_SET_MARK:
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index cfa62f7..8c06441 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -394,7 +394,7 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
struct sockaddr_storage sa;
ret = 1;
- sa = src->source_addr;
+ memcpy(&sa, &src->source_addr, sizeof(sa));
do {
/* note: in case of retry, we may have to release a previously
--
2.7.3

View File

@ -1,53 +0,0 @@
From 42ccea00f69abdd1bb748494f7e17d8369ccae31 Mon Sep 17 00:00:00 2001
From: Dinko Korunic <dinko.korunic@gmail.com>
Date: Fri, 9 Sep 2016 09:41:15 +0200
Subject: [PATCH 01/26] BUG/MINOR: Fix OSX compilation errors
SOL_IPV6 is not defined on OSX, breaking the compile. Also libcrypt is
not available for installation neither in Macports nor as a Brew recipe,
so we're disabling implicit dependancy.
Signed-off-by: Dinko Korunic <dinko.korunic@gmail.com>
(cherry picked from commit 7276f3aa3d687fca64bb9becc66c8e0dbb8b378a)
---
Makefile | 1 -
src/proto_tcp.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index 1bf778d..1d0f2bc 100644
--- a/Makefile
+++ b/Makefile
@@ -301,7 +301,6 @@ ifeq ($(TARGET),osx)
USE_POLL = implicit
USE_KQUEUE = implicit
USE_TPROXY = implicit
- USE_LIBCRYPT = implicit
else
ifeq ($(TARGET),openbsd)
# This is for OpenBSD >= 3.0
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 2c81fb4..4f5d88d 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -206,7 +206,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
case AF_INET6:
if (flags && ip6_transp_working) {
if (0
-#if defined(IPV6_TRANSPARENT)
+#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|| (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0)
#endif
#if defined(IP_FREEBIND)
@@ -854,7 +854,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
break;
case AF_INET6:
if (1
-#if defined(IPV6_TRANSPARENT)
+#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
&& (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
#endif
#if defined(IP_FREEBIND)
--
2.7.3

View File

@ -1,31 +0,0 @@
From 3a011f15a8d61cd0088cc0e46743bdc7699db1af Mon Sep 17 00:00:00 2001
From: Lukas Tribus <luky-37@hotmail.com>
Date: Mon, 12 Sep 2016 21:42:00 +0000
Subject: [PATCH 02/26] BUG/MINOR: displayed PCRE version is running release
pcre_version() returns the running PCRE release, not the release
haproxy was built with.
This simple string fix should be backported to supported releases,
as the output may be confusing.
(cherry picked from commit d64788d9c610163756cac6c91220875e51cba3ef)
---
src/haproxy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/haproxy.c b/src/haproxy.c
index d70cf63..44d32b9 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -347,7 +347,7 @@ void display_build_opts()
#endif
#ifdef USE_PCRE
- printf("Built with PCRE version : %s", pcre_version());
+ printf("Running on PCRE version : %s", pcre_version());
printf("\nPCRE library supports JIT : ");
#ifdef USE_PCRE_JIT
{
--
2.7.3

View File

@ -0,0 +1,39 @@
From fab41521192c6f62f0284faf53d6ad40955ef3db Mon Sep 17 00:00:00 2001
From: David CARLIER <devnexen@gmail.com>
Date: Thu, 24 Mar 2016 09:22:36 +0000
Subject: [PATCH 2/4] CLEANUP: connection: fix double negation on memcmp()
Nothing harmful in here, just clarify that it applies to the whole
expression.
(cherry picked from commit 42ff05e2d3d10e8a1e070e66e8883c5eabe196d7)
(cherry picked from commit c4809151b4c9ccc312cb451e99fd556e867242fc)
---
src/connection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index 09fd04e..af18878 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -289,7 +289,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
if (trash.len < 9) /* shortest possible line */
goto missing;
- if (!memcmp(line, "TCP4 ", 5) != 0) {
+ if (memcmp(line, "TCP4 ", 5) == 0) {
u32 src3, dst3, sport, dport;
line += 5;
@@ -330,7 +330,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(dport);
conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
}
- else if (!memcmp(line, "TCP6 ", 5) != 0) {
+ else if (memcmp(line, "TCP6 ", 5) == 0) {
u32 sport, dport;
char *src_s;
char *dst_s, *sport_s, *dport_s;
--
2.7.3

View File

@ -0,0 +1,52 @@
From 294c8d2f81847e0e2d26aa0700564ac2f6aaffa6 Mon Sep 17 00:00:00 2001
From: Thierry Fournier <thierry.fournier@ozon.io>
Date: Mon, 6 Jun 2016 18:28:05 +0200
Subject: [PATCH 3/4] BUG/MEDIUM: sticktables: segfault in some configuration
error cases
When a stick table is tracked, and another one is used later on the
configuration, a segfault occurs.
The function "smp_create_src_stkctr" can return a NULL value, and
its value is not tested, so one other function try to dereference
a NULL pointer. This patch just add a verification of the NULL
pointer.
The problem is reproduced with this configuration:
listen www
mode http
bind :12345
tcp-request content track-sc0 src table IPv4
http-request allow if { sc0_inc_gpc0(IPv6) gt 0 }
server dummy 127.0.0.1:80
backend IPv4
stick-table type ip size 10 expire 60s store gpc0
backend IPv6
stick-table type ipv6 size 10 expire 60s store gpc0
Thank to kabefuna@gmail.com for the bug report.
This patch must be backported in the 1.6 and 1.5 version.
(cherry picked from commit 6fc340ff07171bb85d11d835fa4158bbdef240a0)
(cherry picked from commit 4693e2302271252044038c9be38487fb16218e5b)
---
src/session.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/session.c b/src/session.c
index 4e84803..fbd5094 100644
--- a/src/session.c
+++ b/src/session.c
@@ -2908,7 +2908,7 @@ smp_fetch_sc_inc_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned i
smp->flags = SMP_F_VOL_TEST;
smp->type = SMP_T_UINT;
smp->data.uint = 0;
- if (stkctr_entry(stkctr) != NULL) {
+ if (stkctr && stkctr_entry(stkctr)) {
void *ptr;
/* First, update gpc0_rate if it's tracked. Second, update its
--
2.7.3

View File

@ -1,49 +0,0 @@
From dcdd2ae7d6809f45c5f6bbe2ba6fe9c70802bb42 Mon Sep 17 00:00:00 2001
From: Lukas Tribus <luky-37@hotmail.com>
Date: Mon, 12 Sep 2016 21:42:07 +0000
Subject: [PATCH 03/26] MINOR: show Built with PCRE version
Inspired by PCRE's pcre_version.c and improved with Willy's
suggestions. Reusable parts have been added to
include/common/standard.h.
(cherry picked from commit dcbc5c5ecf6506b5ad55b98bbec910b29f011f14)
---
include/common/standard.h | 9 +++++++++
src/haproxy.c | 3 +++
2 files changed, 12 insertions(+)
diff --git a/include/common/standard.h b/include/common/standard.h
index 6098550..26a52ff 100644
--- a/include/common/standard.h
+++ b/include/common/standard.h
@@ -1065,4 +1065,13 @@ static inline void *my_realloc2(void *ptr, size_t size)
return ret;
}
+/* HAP_STRING() makes a string from a literal while HAP_XSTRING() first
+ * evaluates the argument and is suited to pass macros.
+ *
+ * They allow macros like PCRE_MAJOR to be defined without quotes, which
+ * is convenient for applications that want to test its value.
+ */
+#define HAP_STRING(...) #__VA_ARGS__
+#define HAP_XSTRING(...) HAP_STRING(__VA_ARGS__)
+
#endif /* _COMMON_STANDARD_H */
diff --git a/src/haproxy.c b/src/haproxy.c
index 44d32b9..37d700b 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -347,6 +347,9 @@ void display_build_opts()
#endif
#ifdef USE_PCRE
+ printf("Built with PCRE version : %s\n", (HAP_XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
+ HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
+ HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR) HAP_XSTRING(PCRE_PRERELEASE PCRE_DATE));
printf("Running on PCRE version : %s", pcre_version());
printf("\nPCRE library supports JIT : ");
#ifdef USE_PCRE_JIT
--
2.7.3

View File

@ -0,0 +1,32 @@
From cba3bd6e5ce9b0be83c701c3c7a103d01d5b516d Mon Sep 17 00:00:00 2001
From: Thierry Fournier <thierry.fournier@ozon.io>
Date: Wed, 1 Jun 2016 13:36:20 +0200
Subject: [PATCH 4/4] BUG/MINOR: http: add-header: header name copied twice
The header name is copied two time in the buffer. The first copy is a printf-like
function writing the name and the http separators in the buffer, and the second
form is a memcopy. This seems to be inherited from some changes. This patch
removes the printf like, format.
This patch must be backported in 1.6 and 1.5 versions
(cherry picked from commit 53c1a9b7cb8f3fe79b5492218363b6c0ff608fc1)
(cherry picked from commit d281d68d3aa010f7e1a635c92ab486f7f2c666b9)
---
src/proto_http.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index 0b13c5e..8801592 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -3399,7 +3399,6 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
case HTTP_REQ_ACT_SET_HDR:
case HTTP_REQ_ACT_ADD_HDR:
- chunk_printf(&trash, "%s: ", rule->arg.hdr_add.name);
memcpy(trash.str, rule->arg.hdr_add.name, rule->arg.hdr_add.name_len);
trash.len = rule->arg.hdr_add.name_len;
trash.str[trash.len++] = ':';
--
2.7.3

View File

@ -1,25 +0,0 @@
From 9d59ff222cc81ee356594cfa780349dd91376fd9 Mon Sep 17 00:00:00 2001
From: Lukas Tribus <luky-37@hotmail.com>
Date: Mon, 12 Sep 2016 21:42:14 +0000
Subject: [PATCH 04/26] MINOR: show Running on zlib version
(cherry picked from commit 255cc5184dc8483e4377d9de25670bd6e226cdba)
---
src/haproxy.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/haproxy.c b/src/haproxy.c
index 37d700b..9f5878a 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -287,6 +287,7 @@ void display_build_opts()
#ifdef USE_ZLIB
printf("Built with zlib version : " ZLIB_VERSION "\n");
+ printf("Running on zlib version : %s\n", zlibVersion());
#elif defined(USE_SLZ)
printf("Built with libslz for stateless compression.\n");
#else /* USE_ZLIB */
--
2.7.3

View File

@ -1,66 +0,0 @@
From 7397526d0c80251b3006b1b45af754f5ad7adb76 Mon Sep 17 00:00:00 2001
From: Nenad Merdanovic <nmerdan@anine.io>
Date: Mon, 3 Oct 2016 04:57:37 +0200
Subject: [PATCH 05/26] MINOR: Add fe_req_rate sample fetch
The fe_req_rate is similar to fe_sess_rate, but fetches the number
of HTTP requests per second instead of connections/sessions per second.
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
(cherry picked from commit ad9a7e9770e673a70fb56ab95be18bf88666d92a)
---
doc/configuration.txt | 5 +++++
src/frontend.c | 14 ++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index d4b1744..d18c399 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -12253,6 +12253,11 @@ fe_conn([<frontend>]) : integer
statistics to servers in HTTP headers. See also the "dst_conn", "be_conn",
"fe_sess_rate" fetches.
+fe_req_rate([<frontend>]) : integer
+ Returns an integer value corresponding to the number of HTTP requests per
+ second sent to a frontend. This number can differ from "fe_sess_rate" in
+ situations where client-side keep-alive is enabled.
+
fe_sess_rate([<frontend>]) : integer
Returns an integer value corresponding to the sessions creation rate on the
frontend, in number of new sessions per second. This is used with ACLs to
diff --git a/src/frontend.c b/src/frontend.c
index 74ec0ab..5cc6202 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -167,6 +167,19 @@ smp_fetch_fe_id(const struct arg *args, struct sample *smp, const char *kw, void
return 1;
}
+/* set temp integer to the number of HTTP requests per second reaching the frontend.
+ * Accepts exactly 1 argument. Argument is a frontend, other types will cause
+ * an undefined behaviour.
+ */
+static int
+smp_fetch_fe_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ smp->flags = SMP_F_VOL_TEST;
+ smp->data.type = SMP_T_SINT;
+ smp->data.u.sint = read_freq_ctr(&args->data.prx->fe_req_per_sec);
+ return 1;
+}
+
/* set temp integer to the number of connections per second reaching the frontend.
* Accepts exactly 1 argument. Argument is a frontend, other types will cause
* an undefined behaviour.
@@ -200,6 +213,7 @@ smp_fetch_fe_conn(const struct arg *args, struct sample *smp, const char *kw, vo
static struct sample_fetch_kw_list smp_kws = {ILH, {
{ "fe_conn", smp_fetch_fe_conn, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "fe_id", smp_fetch_fe_id, 0, NULL, SMP_T_SINT, SMP_USE_FTEND, },
+ { "fe_req_rate", smp_fetch_fe_req_rate, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "fe_sess_rate", smp_fetch_fe_sess_rate, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ /* END */ },
}};
--
2.7.3

View File

@ -1,134 +0,0 @@
From 3dd981c016ac7ad636ee546c2b9b685f7e8500d4 Mon Sep 17 00:00:00 2001
From: Lukas Tribus <luky-37@hotmail.com>
Date: Mon, 12 Sep 2016 21:42:20 +0000
Subject: [PATCH 06/26] MEDIUM: make SO_REUSEPORT configurable
With Linux officially introducing SO_REUSEPORT support in 3.9 and
its mainstream adoption we have seen more people running into strange
SO_REUSEPORT related issues (a process management issue turning into
hard to diagnose problems because the kernel load-balances between the
new and an obsolete haproxy instance).
Also some people simply want the guarantee that the bind fails when
the old process is still bound.
This change makes SO_REUSEPORT configurable, introducing the command
line argument "-dR" and the noreuseport configuration directive.
A backport to 1.6 should be considered.
(cherry picked from commit a0bcbdcb04d52c3ca71045f90aac33d9dd7965bf)
---
doc/configuration.txt | 5 +++++
include/types/global.h | 1 +
src/cfgparse.c | 5 +++++
src/haproxy.c | 10 ++++++++++
src/proto_tcp.c | 6 +++---
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index d18c399..e725ce2 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -570,6 +570,7 @@ The following keywords are supported in the "global" section :
- nopoll
- nosplice
- nogetaddrinfo
+ - noreuseport
- spread-checks
- server-state-base
- server-state-file
@@ -1090,6 +1091,10 @@ nogetaddrinfo
Disables the use of getaddrinfo(3) for name resolving. It is equivalent to
the command line argument "-dG". Deprecated gethostbyname(3) will be used.
+noreuseport
+ Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the
+ command line argument "-dR".
+
spread-checks <0..50, in percent>
Sometimes it is desirable to avoid sending agent and health checks to
servers at exact intervals, for instance when many logical servers are
diff --git a/include/types/global.h b/include/types/global.h
index 61f0391..2e24d3f 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -63,6 +63,7 @@
/* platform-specific options */
#define GTUNE_USE_SPLICE (1<<4)
#define GTUNE_USE_GAI (1<<5)
+#define GTUNE_USE_REUSEPORT (1<<6)
/* Access level for a stats socket */
#define ACCESS_LVL_NONE 0
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 55086fd..f2a104d 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -662,6 +662,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
goto out;
global.tune.options &= ~GTUNE_USE_GAI;
}
+ else if (!strcmp(args[0], "noreuseport")) {
+ if (alertif_too_many_args(0, file, linenum, args, &err_code))
+ goto out;
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
+ }
else if (!strcmp(args[0], "quiet")) {
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
diff --git a/src/haproxy.c b/src/haproxy.c
index 9f5878a..a657dc4 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -452,6 +452,9 @@ void usage(char *name)
#if defined(USE_GETADDRINFO)
" -dG disables getaddrinfo() usage\n"
#endif
+#if defined(SO_REUSEPORT)
+ " -dR disables SO_REUSEPORT usage\n"
+#endif
" -dV disables SSL verify on servers side\n"
" -sf/-st [pid ]* finishes/terminates old pids.\n"
"\n",
@@ -623,6 +626,9 @@ void init(int argc, char **argv)
#if defined(USE_GETADDRINFO)
global.tune.options |= GTUNE_USE_GAI;
#endif
+#if defined(SO_REUSEPORT)
+ global.tune.options |= GTUNE_USE_REUSEPORT;
+#endif
pid = getpid();
progname = *argv;
@@ -666,6 +672,10 @@ void init(int argc, char **argv)
else if (*flag == 'd' && flag[1] == 'G')
global.tune.options &= ~GTUNE_USE_GAI;
#endif
+#if defined(SO_REUSEPORT)
+ else if (*flag == 'd' && flag[1] == 'R')
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
+#endif
else if (*flag == 'd' && flag[1] == 'V')
global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
else if (*flag == 'V')
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 4f5d88d..0f20fde 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -824,10 +824,10 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
setsockopt(fd, SOL_SOCKET, SO_LINGER, &nolinger, sizeof(struct linger));
#ifdef SO_REUSEPORT
- /* OpenBSD supports this. As it's present in old libc versions of Linux,
- * it might return an error that we will silently ignore.
+ /* OpenBSD and Linux 3.9 support this. As it's present in old libc versions of
+ * Linux, it might return an error that we will silently ignore.
*/
- if (!ext)
+ if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT))
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
#endif
--
2.7.3

View File

@ -1,29 +0,0 @@
From 21877a43afd6300518140c415ccec2dba0a0591f Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 21 Oct 2016 17:13:24 +0200
Subject: [PATCH 07/26] BUG/MINOR: vars: use sess and not s->sess in
action_store()
This causes the stream to be dereferenced when not needed. It will
cause trouble when variables are used outside of a stream.
(cherry picked from commit 108a8fd8be0c78a4bf147a2028fd9bda3343c93c)
---
src/vars.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/vars.c b/src/vars.c
index 56fade5..b22c3bf 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -507,7 +507,7 @@ static enum act_return action_store(struct act_rule *rule, struct proxy *px,
/* Process the expression. */
memset(&smp, 0, sizeof(smp));
- if (!sample_process(px, s->sess, s, dir|SMP_OPT_FINAL,
+ if (!sample_process(px, sess, s, dir|SMP_OPT_FINAL,
rule->arg.vars.expr, &smp))
return ACT_RET_CONT;
--
2.7.3

View File

@ -1,47 +0,0 @@
From ff403602edc917b8bef2062dc0d5dec2017e3232 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 21 Oct 2016 17:14:35 +0200
Subject: [PATCH 08/26] BUG/MINOR: vars: make smp_fetch_var() more robust
against misuses
smp_fetch_var() may be called from everywhere since it just reads a
variable. It must ensure that the stream exists before trying to return
a stream-dependant variable. For now there is no impact but it will
cause trouble with tcp-request session rules.
(cherry picked from commit 7513d001c8a6b7d1cf8e7d5469942cd39d6e8160)
---
src/vars.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/vars.c b/src/vars.c
index b22c3bf..4a0c4ed 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -242,11 +242,21 @@ static int smp_fetch_var(const struct arg *args, struct sample *smp, const char
/* Check the availibity of the variable. */
switch (var_desc->scope) {
- case SCOPE_SESS: vars = &smp->sess->vars; break;
- case SCOPE_TXN: vars = &smp->strm->vars_txn; 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: vars = &smp->strm->vars_reqres; break;
+ default:
+ if (!smp->strm)
+ return 0;
+ vars = &smp->strm->vars_reqres;
+ break;
}
if (vars->scope != var_desc->scope)
return 0;
--
2.7.3

View File

@ -1,31 +0,0 @@
From 3810ab9e71a19e7f04a9e18580abc77c276d0ff1 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 21 Oct 2016 17:17:18 +0200
Subject: [PATCH 09/26] BUG/MINOR: vars: smp_fetch_var() doesn't depend on HTTP
but on the session
Thus the SMP_USE_HTTP_ANY dependency is incorrect, we have to depend on
SMP_USE_L5_CLI (the session). It's particularly important for session-wide
variables which are kept across HTTP requests. For now there is no impact
but it will make a difference with tcp-request session rules.
(cherry picked from commit 87846e42a478fe2aa0fbc1e162ba5fb227be49b7)
---
src/vars.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/vars.c b/src/vars.c
index 4a0c4ed..a3dd85c 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -654,7 +654,7 @@ static int vars_max_size_reqres(char **args, int section_type, struct proxy *cur
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
- { "var", smp_fetch_var, ARG1(1,STR), smp_check_var, SMP_T_STR, SMP_USE_HTTP_ANY },
+ { "var", smp_fetch_var, ARG1(1,STR), smp_check_var, SMP_T_STR, SMP_USE_L5CLI },
{ /* END */ },
}};
--
2.7.3

View File

@ -1,29 +0,0 @@
From 2d7ed4ae91383cd35fe07cd34d01c23b4a5d03f5 Mon Sep 17 00:00:00 2001
From: "Thierry FOURNIER / OZON.IO" <thierry.fournier@ozon.io>
Date: Thu, 6 Oct 2016 10:35:29 +0200
Subject: [PATCH 10/26] BUG/MINOR: ssl: Check malloc return code
If malloc() can't allocate memory and return NULL, a segfaut will raises.
This patch should be backported in the 1.6 and 1.5 version.
(cherry picked from commit 7a3bd3b9dc43509bb1869389dcf91e35c0155f9b)
---
src/ssl_sock.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 0535a3b..5f9a203 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1572,6 +1572,8 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
int j, len;
len = strlen(name);
sc = malloc(sizeof(struct sni_ctx) + len + 1);
+ if (!sc)
+ return order;
for (j = 0; j < len; j++)
sc->name.key[j] = tolower(name[j]);
sc->name.key[len] = 0;
--
2.7.3

View File

@ -1,70 +0,0 @@
From b2b0eab46a8ae36f2dd49159e65c90c1089a0f96 Mon Sep 17 00:00:00 2001
From: "Thierry FOURNIER / OZON.IO" <thierry.fournier@ozon.io>
Date: Thu, 6 Oct 2016 10:56:48 +0200
Subject: [PATCH 11/26] BUG/MINOR: ssl: prevent multiple entries for the same
certificate
Today, the certificate are indexed int he SNI tree using their CN and the
list of thier AltNames. So, Some certificates have the same names in the
CN and one of the AltNames entries.
Typically Let's Encrypt duplicate the the DNS name in the CN and the
AltName.
This patch prevents the creation of identical entries in the trees. It
checks the same DNS name and the same SSL context.
If the same certificate is registered two time it will be duplicated.
This patch should be backported in the 1.6 and 1.5 version.
(cherry picked from commit 07c3d78c2c0693ee37db71c34723597638b6ab3f)
---
src/ssl_sock.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 5f9a203..ad8054d 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1556,6 +1556,7 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
{
struct sni_ctx *sc;
int wild = 0, neg = 0;
+ struct ebmb_node *node;
if (*name == '!') {
neg = 1;
@@ -1571,12 +1572,27 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
if (*name) {
int j, len;
len = strlen(name);
+ for (j = 0; j < len && j < trash.size; j++)
+ trash.str[j] = tolower(name[j]);
+ if (j >= trash.size)
+ return order;
+ trash.str[j] = 0;
+
+ /* Check for duplicates. */
+ if (wild)
+ node = ebst_lookup(&s->sni_w_ctx, trash.str);
+ else
+ node = ebst_lookup(&s->sni_ctx, trash.str);
+ for (; node; node = ebmb_next_dup(node)) {
+ sc = ebmb_entry(node, struct sni_ctx, name);
+ if (sc->ctx == ctx && sc->neg == neg)
+ return order;
+ }
+
sc = malloc(sizeof(struct sni_ctx) + len + 1);
if (!sc)
return order;
- for (j = 0; j < len; j++)
- sc->name.key[j] = tolower(name[j]);
- sc->name.key[len] = 0;
+ memcpy(sc->name.key, trash.str, len + 1);
sc->ctx = ctx;
sc->order = order++;
sc->neg = neg;
--
2.7.3

View File

@ -1,31 +0,0 @@
From 03c706d71e2d314670d2ebb4dfa48fd3b793b361 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 25 Oct 2016 15:50:47 +0200
Subject: [PATCH 12/26] BUG/MINOR: systemd: make the wrapper return a non-null
status code on error
When execv() fails to execute the haproxy executable, it's important to
return an error instead of pretending everything is cool. This fix should
be backported to 1.6 and 1.5 in order to improve the overall reliability
under systemd.
(cherry picked from commit 7643d09dca4d0eed97ba3c29d4f4fd1f037f96ae)
---
src/haproxy-systemd-wrapper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index d118ec6..a78e75b 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -94,7 +94,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
fprintf(stderr, "\n");
execv(argv[0], argv);
- exit(0);
+ exit(1);
}
}
--
2.7.3

View File

@ -1,117 +0,0 @@
From 7a7eada6f4ecfc54325a18cf20c3035994a901c4 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 25 Oct 2016 16:49:31 +0200
Subject: [PATCH 13/26] BUG/MINOR: systemd: always restore signals before
execve()
Since signals are inherited, we must restore them before calling execve()
and intercept them again after a failed execve(). In order to cleanly deal
with the SIGUSR2/SIGHUP loops where we re-exec the wrapper, we ignore these
two signals during a re-exec, and restore them to defaults when spawning
haproxy.
This should be backported to 1.6 and 1.5.
(cherry picked from commit 4351ea61fbddf88c960179d60b0e0f1b090f0b70)
---
src/haproxy-systemd-wrapper.c | 49 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 8 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index a78e75b..84d2e17 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -28,6 +28,11 @@ static char *pid_file = "/run/haproxy.pid";
static int wrapper_argc;
static char **wrapper_argv;
+static void setup_signal_handler();
+static void pause_signal_handler();
+static void reset_signal_handler();
+
+
/* returns the path to the haproxy binary into <buffer>, whose size indicated
* in <buffer_size> must be at least 1 byte long.
*/
@@ -76,6 +81,8 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
int i;
int argno = 0;
+
+ reset_signal_handler();
locate_haproxy(haproxy_bin, 512);
argv[argno++] = haproxy_bin;
for (i = 0; i < main_argc; ++i)
@@ -127,6 +134,34 @@ static void signal_handler(int signum)
caught_signal = signum;
}
+static void setup_signal_handler()
+{
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = &signal_handler;
+ sigaction(SIGUSR2, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+}
+
+static void pause_signal_handler()
+{
+ signal(SIGUSR2, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+}
+
+static void reset_signal_handler()
+{
+ signal(SIGUSR2, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+}
+
/* handles SIGUSR2 and SIGHUP only */
static void do_restart(int sig)
{
@@ -134,7 +169,11 @@ static void do_restart(int sig)
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing on %s.\n",
sig == SIGUSR2 ? "SIGUSR2" : "SIGHUP");
+ /* don't let the other process take one of those signals by accident */
+ pause_signal_handler();
execv(wrapper_argv[0], wrapper_argv);
+ /* failed, let's reinstall the signal handler and continue */
+ setup_signal_handler();
}
/* handles SIGTERM and SIGINT only */
@@ -168,7 +207,8 @@ static void init(int argc, char **argv)
int main(int argc, char **argv)
{
int status;
- struct sigaction sa;
+
+ setup_signal_handler();
wrapper_argc = argc;
wrapper_argv = argv;
@@ -176,13 +216,6 @@ int main(int argc, char **argv)
--argc; ++argv;
init(argc, argv);
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = &signal_handler;
- sigaction(SIGUSR2, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
-
if (getenv(REEXEC_FLAG) != NULL) {
/* We are being re-executed: restart HAProxy gracefully */
int i;
--
2.7.3

View File

@ -1,41 +0,0 @@
From 106cb89907ea6eab0073708bb8d6f56d7fc64509 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 25 Oct 2016 17:05:56 +0200
Subject: [PATCH 14/26] BUG/MINOR: systemd: check return value of calloc()
The wrapper is not the best reliable thing in the universe, so start
by adding at least the minimum expected controls :-/
To be backported to 1.5 and 1.6.
(cherry picked from commit 3747ea07ce6b647b86559383f7d09b42550d42f3)
---
src/haproxy-systemd-wrapper.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index 84d2e17..15c48ca 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -77,11 +77,17 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
pid = fork();
if (!pid) {
- /* 3 for "haproxy -Ds -sf" */
- char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
+ char **argv;
int i;
int argno = 0;
+ /* 3 for "haproxy -Ds -sf" */
+ argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
+ if (!argv) {
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to calloc(), please try again later.\n");
+ exit(1);
+ }
+
reset_signal_handler();
locate_haproxy(haproxy_bin, 512);
argv[argno++] = haproxy_bin;
--
2.7.3

View File

@ -1,41 +0,0 @@
From 3bc0a399d2875e9e0627a70906c1403eef60ec60 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 25 Oct 2016 16:51:40 +0200
Subject: [PATCH 15/26] MINOR: systemd: report it when execve() fails
It's important to know that a signal sent to the wrapper had no effect
because something failed during execve(). Ideally more info (strerror)
should be reported. It would be nice to backport this to 1.6 and 1.5.
(cherry picked from commit a785269b4e09114224062081f02b443b6008c524)
---
src/haproxy-systemd-wrapper.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index 15c48ca..f4fcab1 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -107,8 +107,12 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
fprintf(stderr, "\n");
execv(argv[0], argv);
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: execv(%s) failed, please try again later.\n", argv[0]);
exit(1);
}
+ else if (pid == -1) {
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to fork(), please try again later.\n");
+ }
}
static int read_pids(char ***pid_strv)
@@ -180,6 +184,7 @@ static void do_restart(int sig)
execv(wrapper_argv[0], wrapper_argv);
/* failed, let's reinstall the signal handler and continue */
setup_signal_handler();
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-exec(%s) failed.\n", wrapper_argv[0]);
}
/* handles SIGTERM and SIGINT only */
--
2.7.3

View File

@ -1,144 +0,0 @@
From ff81ac47267c4e0227d1e3fbc5b1dedfd81a2a2f Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 25 Oct 2016 17:20:24 +0200
Subject: [PATCH 16/26] BUG/MEDIUM: systemd: let the wrapper know that haproxy
has completed or failed
Pierre Cheynier found that there's a persistent issue with the systemd
wrapper. Too fast reloads can lead to certain old processes not being
signaled at all and continuing to run. The problem was tracked down as
a race between the startup and the signal processing : nothing prevents
the wrapper from starting new processes while others are still starting,
and the resulting pid file will only contain the latest pids in this
case. This can happen with large configs and/or when a lot of SSL
certificates are involved.
In order to solve this we want the wrapper to wait for the new processes
to complete their startup. But we also want to ensure it doesn't wait for
nothing in case of error.
The solution found here is to create a pipe between the wrapper and the
sub-processes. The wrapper waits on the pipe and the sub-processes are
expected to close this pipe once they completed their startup. That way
we don't queue up new processes until the previous ones have registered
their pids to the pid file. And if anything goes wrong, the wrapper is
immediately released. The only thing is that we need the sub-processes
to know the pipe's file descriptor. We pass it in an environment variable
called HAPROXY_WRAPPER_FD.
It was confirmed both by Pierre and myself that this completely solves
the "zombie" process issue so that only the new processes continue to
listen on the sockets.
It seems that in the future this stuff could be moved to the haproxy
master process, also getting rid of an environment variable.
This fix needs to be backported to 1.6 and 1.5.
(cherry picked from commit b957109727f7fed556c049d40bacf45f0df211db)
---
src/haproxy-systemd-wrapper.c | 36 ++++++++++++++++++++++++++++++++++++
src/haproxy.c | 10 ++++++++++
2 files changed, 46 insertions(+)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index f4fcab1..b426f96 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -65,16 +65,30 @@ static void locate_haproxy(char *buffer, size_t buffer_size)
return;
}
+/* Note: this function must not exit in case of error (except in the child), as
+ * it is only dedicated the starting a new haproxy process. By keeping the
+ * process alive it will ensure that future signal delivery may get rid of
+ * the issue. If the first startup fails, the wrapper will notice it and
+ * return an error thanks to wait() returning ECHILD.
+ */
static void spawn_haproxy(char **pid_strv, int nb_pid)
{
char haproxy_bin[512];
pid_t pid;
int main_argc;
char **main_argv;
+ int pipefd[2];
+ char fdstr[20];
+ int ret;
main_argc = wrapper_argc - 1;
main_argv = wrapper_argv + 1;
+ if (pipe(pipefd) != 0) {
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to create a pipe, please try again later.\n");
+ return;
+ }
+
pid = fork();
if (!pid) {
char **argv;
@@ -89,6 +103,15 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
}
reset_signal_handler();
+
+ close(pipefd[0]); /* close the read side */
+
+ snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]);
+ if (setenv("HAPROXY_WRAPPER_FD", fdstr, 1) != 0) {
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to setenv(), please try again later.\n");
+ exit(1);
+ }
+
locate_haproxy(haproxy_bin, 512);
argv[argno++] = haproxy_bin;
for (i = 0; i < main_argc; ++i)
@@ -113,6 +136,19 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
else if (pid == -1) {
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to fork(), please try again later.\n");
}
+
+ /* The parent closes the write side and waits for the child to close it
+ * as well. Also deal the case where the fd would unexpectedly be 1 or 2
+ * by silently draining all data.
+ */
+ close(pipefd[1]);
+
+ do {
+ char c;
+ ret = read(pipefd[0], &c, sizeof(c));
+ } while ((ret > 0) || (ret == -1 && errno == EINTR));
+ /* the child has finished starting up */
+ close(pipefd[0]);
}
static int read_pids(char ***pid_strv)
diff --git a/src/haproxy.c b/src/haproxy.c
index a657dc4..2d476f2 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1843,6 +1843,7 @@ int main(int argc, char **argv)
int ret = 0;
int *children = calloc(global.nbproc, sizeof(int));
int proc;
+ char *wrapper_fd;
/* the father launches the required number of processes */
for (proc = 0; proc < global.nbproc; proc++) {
@@ -1879,6 +1880,15 @@ int main(int argc, char **argv)
close(pidfd);
}
+ /* each child must notify the wrapper that it's ready by closing the requested fd */
+ wrapper_fd = getenv("HAPROXY_WRAPPER_FD");
+ if (wrapper_fd) {
+ int pipe_fd = atoi(wrapper_fd);
+
+ if (pipe_fd >= 0)
+ close(pipe_fd);
+ }
+
/* We won't ever use this anymore */
free(oldpids); oldpids = NULL;
free(global.chroot); global.chroot = NULL;
--
2.7.3

View File

@ -1,32 +0,0 @@
From 4fc2ce4a4bb83862679e40c09c684dbf266099f2 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 10 Aug 2016 18:24:48 +0200
Subject: [PATCH 17/26] BUILD: protocol: fix some build errors on OpenBSD
Building 1.6 and above on OpenBSD 5.2 fails due to protocol.c not
including sys/types.h before sys/socket.h :
In file included from src/protocol.c:14:
/usr/include/sys/socket.h:162: error: expected specifier-qualifier-list before 'u_int8_t'
This fix needs to be backported to 1.6.
(cherry picked from commit a6e3be7ae977ba907ec6ed028c5ab50a6a51886a)
---
src/protocol.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/protocol.c b/src/protocol.c
index 3caccb6..7884ef7 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -10,6 +10,7 @@
*
*/
+#include <sys/types.h>
#include <sys/socket.h>
#include <common/config.h>
--
2.7.3

View File

@ -1,32 +0,0 @@
From 27f28950d4f9e44e776db5a5d2bc8d07df45eb30 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 10 Aug 2016 18:30:56 +0200
Subject: [PATCH 18/26] BUILD: log: iovec requires to include sys/uio.h on
OpenBSD
The following commit merged into 1.6-dev6 broke the build on OpenBSD :
609ac2a ("MEDIUM: log: replace sendto() with sendmsg() in __send_log()")
Including sys/uio.h is enough to fix this. This fix needs to be backported
to 1.6.
(cherry picked from commit 077edcba2e5c25524b720f905417d9f0616cd252)
---
src/log.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/log.c b/src/log.c
index 1ddc06d..293a034 100644
--- a/src/log.c
+++ b/src/log.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <sys/time.h>
+#include <sys/uio.h>
#include <common/config.h>
#include <common/compat.h>
--
2.7.3

View File

@ -1,32 +0,0 @@
From 2a63a2b7e32bba4a33c5f4081647124565929f6a Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 10 Aug 2016 18:42:17 +0200
Subject: [PATCH 19/26] BUILD: tcp: do not include netinet/ip.h for IP_TTL
On OpenBSD, netinet/ip.h fails unless in_systm.h is included. This
include was added by the silent-drop feature introduced with commit
2d392c2 ("MEDIUM: tcp: add new tcp action "silent-drop"") in 1.6-dev6,
but we don't need it, IP_TTL is defined in netinet/in.h, so let's drop
this useless include.
This fix needs to be backported to 1.6.
(cherry picked from commit 7f3e3c0159401cdf47575bc82304696b3a98a2ab)
---
src/proto_tcp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 0f20fde..83b862a 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -31,7 +31,6 @@
#include <netinet/tcp.h>
#include <netinet/in.h>
-#include <netinet/ip.h>
#include <common/cfgparse.h>
#include <common/compat.h>
--
2.7.3

View File

@ -1,48 +0,0 @@
From a581cf03110f13c61faeaf87efa5b4e2777087d0 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 10 Aug 2016 19:29:09 +0200
Subject: [PATCH 20/26] BUILD: checks: remove the last strcat and eliminate a
warning on OpenBSD
OpenBSD emits warnings on usages of strcpy, strcat and sprintf (and
probably a few others). Here we have a single such warning in all the code
reintroduced by commit 0ba0e4a ("MEDIUM: Support sending email alerts") in
1.6-dev1. Let's get rid of it, the open-coding of strcat is as small as its
usage and the the result is even more efficient.
This fix needs to be backported to 1.6.
(cherry picked from commit 64345aaaf0dc2739983902cce4667089ad926a49)
---
src/checks.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/checks.c b/src/checks.c
index 80b2fc3..55c13a9 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -3164,6 +3164,8 @@ static int add_tcpcheck_expect_str(struct list *list, const char *str)
static int add_tcpcheck_send_strs(struct list *list, const char * const *strs)
{
struct tcpcheck_rule *tcpcheck;
+ const char *in;
+ char *dst;
int i;
tcpcheck = calloc(1, sizeof *tcpcheck);
@@ -3181,10 +3183,11 @@ static int add_tcpcheck_send_strs(struct list *list, const char * const *strs)
free(tcpcheck);
return 0;
}
- tcpcheck->string[0] = '\0';
+ dst = tcpcheck->string;
for (i = 0; strs[i]; i++)
- strcat(tcpcheck->string, strs[i]);
+ for (in = strs[i]; (*dst = *in++); dst++);
+ *dst = 0;
LIST_ADDQ(list, &tcpcheck->list);
return 1;
--
2.7.3

View File

@ -1,39 +0,0 @@
From a19f5bfb0d1e606dc2eb80af903c229ca41d5057 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 10 Aug 2016 21:21:57 +0200
Subject: [PATCH 21/26] BUILD: poll: remove unused hap_fd_isset() which causes
a warning with clang
Clang reports that this function is not used :
src/ev_poll.c:34:28: warning: unused function 'hap_fd_isset' [-Wunused-function]
static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
It's been true since the rework of the pollers in 1.5 and it's unlikely we'll
ever need it anymore, so better remove it now to provide clean builds.
This fix can be backported to 1.6 and 1.5 now.
(cherry picked from commit 091e86e1ee8ec51bd5a3c1935666a822a51b9051)
---
src/ev_poll.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/ev_poll.c b/src/ev_poll.c
index 44a2b9b..80d88eb 100644
--- a/src/ev_poll.c
+++ b/src/ev_poll.c
@@ -31,11 +31,6 @@ static unsigned int *fd_evts[2];
static struct pollfd *poll_events = NULL;
-static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
-{
- return evts[fd / (8*sizeof(*evts))] & (1U << (fd & (8*sizeof(*evts) - 1)));
-}
-
static inline void hap_fd_set(int fd, unsigned int *evts)
{
evts[fd / (8*sizeof(*evts))] |= 1U << (fd & (8*sizeof(*evts) - 1));
--
2.7.3

View File

@ -1,48 +0,0 @@
From e871cc2f15ad121e1e840191f59c6c86d6d0580d Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen@gmail.com>
Date: Mon, 22 Aug 2016 23:27:42 +0100
Subject: [PATCH 22/26] MINOR: cfgparse: few memory leaks fixes.
Some minor memory leak during the config parsing.
(cherry picked from commit 70d604593d507f50fd99cebecee4b2c47c1d9b73)
---
src/cfgparse.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index f2a104d..b8289a2 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1597,6 +1597,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
if (logsrv->format < 0) {
Alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
err_code |= ERR_ALERT | ERR_FATAL;
+ free(logsrv);
goto out;
}
@@ -6777,9 +6778,10 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
}
ag->name = strdup(args[1]);
- if (!ag) {
+ if (!ag->name) {
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
+ free(ag);
goto out;
}
@@ -6794,6 +6796,9 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
Alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
+ free(ag->groupusers);
+ free(ag->name);
+ free(ag);
goto out;
}
}
--
2.7.3

View File

@ -1,33 +0,0 @@
From 5370c6774a333b2b3989639275d4093fdc541db9 Mon Sep 17 00:00:00 2001
From: Bertrand Jacquin <bertrand@jacquin.bzh>
Date: Thu, 6 Oct 2016 00:32:39 +0100
Subject: [PATCH 23/26] MINOR: build: Allow linking to device-atlas library
file
DeviceAtlas might be installed in a location where a user might not have
enough permissions to write json.o and dac.o
(cherry picked from commit 3a2661d6b4218704c828c8a712c87d651bfe29b5)
---
Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Makefile b/Makefile
index 1d0f2bc..0242cae 100644
--- a/Makefile
+++ b/Makefile
@@ -615,8 +615,12 @@ endif
DEVICEATLAS_SRC =
DEVICEATLAS_INC = $(DEVICEATLAS_SRC)
DEVICEATLAS_LIB = $(DEVICEATLAS_SRC)
+ifeq ($(DEVICEATLAS_SRC),)
+OPTIONS_LDFLAGS += -lda
+else
OPTIONS_OBJS += $(DEVICEATLAS_LIB)/json.o
OPTIONS_OBJS += $(DEVICEATLAS_LIB)/dac.o
+endif
OPTIONS_OBJS += src/da.o
OPTIONS_CFLAGS += -DUSE_DEVICEATLAS $(if $(DEVICEATLAS_INC),-I$(DEVICEATLAS_INC))
BUILD_OPTIONS += $(call ignore_implicit,USE_DEVICEATLAS)
--
2.7.3

View File

@ -1,32 +0,0 @@
From f95dc972e2e9e3c245862e45336ff4f014ad5666 Mon Sep 17 00:00:00 2001
From: Jorrit Schippers <jorrit@ncode.nl>
Date: Sat, 9 Apr 2016 20:30:38 +0200
Subject: [PATCH 24/26] DOC: Fix typo in description of `-st` parameter in man
page
extra "wait".
(cherry picked from commit 1458fdbe974562158fc40fd72d745d5fd644c939)
---
doc/haproxy.1 | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/haproxy.1 b/doc/haproxy.1
index a836d5d..20c9343 100644
--- a/doc/haproxy.1
+++ b/doc/haproxy.1
@@ -149,9 +149,9 @@ PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGUSR1\fP are sent.
.TP
\fB\-st <pidlist>\fP
Send TERMINATE signal to the pids in pidlist after startup. The processes
-which receive this signal will wait immediately terminate, closing all
-active sessions. This option must be specified last, followed by any number
-of PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGTERM\fP are sent.
+which receive this signal will terminate immediately, closing all active
+sessions. This option must be specified last, followed by any number of
+PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGTERM\fP are sent.
.SH LOGGING
Since HAProxy can run inside a chroot, it cannot reliably access /dev/log.
--
2.7.3

View File

@ -1,39 +0,0 @@
From 6026323cd0c235d6ab7ec039e5d735e7ea2e28bf Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 31 Oct 2016 17:32:20 +0100
Subject: [PATCH 25/26] BUG/MEDIUM: peers: on shutdown, wake up the appctx, not
the stream
This part was missed when peers were ported to the new applet
infrastructure in 1.6, the main stream is woken up instead of the
appctx. This creates a race condition by which it is possible to
wake the stream at the wrong moment and miss an event. This bug
might be at least partially responsible for some of the CLOSE_WAIT
that were reported on peers session upon reload in version 1.6.
This fix must be backported to 1.6.
(cherry picked from commit 78c0c50705a5e9d48607b9377adf030bb9d97b34)
---
src/peers.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/peers.c b/src/peers.c
index 7e1523f..db1f608 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1637,11 +1637,9 @@ static void peer_session_forceshutdown(struct stream * stream)
if (ps)
ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + random() % 2000));
- /* call release to reinit resync states if needed */
- peer_session_release(appctx);
appctx->st0 = PEER_SESS_ST_END;
appctx->ctx.peers.ptr = NULL;
- task_wakeup(stream->task, TASK_WOKEN_MSG);
+ appctx_wakeup(appctx);
}
/* Pre-configures a peers frontend to accept incoming connections */
--
2.7.3

View File

@ -1,64 +0,0 @@
From ab45181e36b6c4f7d31c5284035937c2d0be37eb Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 31 Oct 2016 17:46:57 +0100
Subject: [PATCH 26/26] BUG/MEDIUM: peers: fix use after free in
peer_session_create()
In case of resource allocation error, peer_session_create() frees
everything allocated and returns a pointer to the stream/session that
was put back into the free pool. This stream/session is then assigned
to ps->{stream,session} with no error control. This means that it is
perfectly possible to have a new stream or session being both used for
a regular communication and for a peer at the same time.
In fact it is the only way (for now) to explain a CLOSE_WAIT on peers
connections that was caught in this dump with the stream interface in
SI_ST_CON state while the error field proves the state ought to have
been SI_ST_DIS, very likely indicating two concurrent accesses on the
same area :
0x7dbd50: [31/Oct/2016:17:53:41.267510] id=0 proto=tcpv4
flags=0x23006, conn_retries=0, srv_conn=(nil), pend_pos=(nil)
frontend=myhost2 (id=4294967295 mode=tcp), listener=? (id=0)
backend=<NONE> (id=-1 mode=-) addr=127.0.0.1:41432
server=<NONE> (id=-1) addr=127.0.0.1:8521
task=0x7dbcd8 (state=0x08 nice=0 calls=2 exp=<NEVER> age=1m5s)
si[0]=0x7dbf48 (state=CLO flags=0x4040 endp0=APPCTX:0x7d99c8 exp=<NEVER>, et=0x000)
si[1]=0x7dbf68 (state=CON flags=0x50 endp1=CONN:0x7dc0b8 exp=<NEVER>, et=0x020)
app0=0x7d99c8 st0=11 st1=0 st2=0 applet=<PEER>
co1=0x7dc0b8 ctrl=tcpv4 xprt=RAW data=STRM target=PROXY:0x7fe62028a010
flags=0x0020b310 fd=7 fd.state=22 fd.cache=0 updt=0
req=0x7dbd60 (f=0x80a020 an=0x0 pipe=0 tofwd=0 total=0)
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
buf=0x78a3c0 data=0x78a3d4 o=0 p=0 req.next=0 i=0 size=0
res=0x7dbda0 (f=0x80402020 an=0x0 pipe=0 tofwd=0 total=0)
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
buf=0x78a3c0 data=0x78a3d4 o=0 p=0 rsp.next=0 i=0 size=0
Special thanks to Arnaud Gavara who provided lots of valuable input and
ran some validation testing on this patch.
This fix must be backported to 1.6 and 1.5. Note that in 1.5 the
session is not assigned from within the function so some extra checks
may be needed in the callers.
(cherry picked from commit b21d08e2492bfbf9d2341ce9f148cb9845927862)
---
src/peers.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/peers.c b/src/peers.c
index db1f608..c8be59a 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1747,7 +1747,7 @@ static struct stream *peer_session_create(struct peers *peers, struct peer *peer
out_free_appctx:
appctx_free(appctx);
out_close:
- return s;
+ return NULL;
}
/*
--
2.7.3