include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
-PKG_VERSION:=1.7.2
-PKG_RELEASE:=01
+PKG_VERSION:=1.7.3
+PKG_RELEASE:=07
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.7/src/
-PKG_MD5SUM:=7330b36f3764ebe409e9305803dc30e2
+PKG_MD5SUM:=e529c240c08e4004c6e9dcf3fd6b3ab
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0
$(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
CC="$(TARGET_CC)" \
- $(ADDON)
- CFLAGS="$(TARGET_CFLAGS) -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -pipe -fomit-frame-pointer -fhonour-copts" \
- LD="$(TARGET_LD)" \
- LDFLAGS="$(TARGET_LDFLAGS) -lcurses -lreadline" \
PCREDIR="$(STAGING_DIR)/usr/include" \
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530 " \
USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 USE_REGPARM=1 \
- USE_ZLIB=yes USE_PCRE=1 \
+ USE_ZLIB=yes USE_PCRE=1 USE_PCRE_JIT=1\
VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
- IGNOREGIT=1
+ $(ADDON)
+ CFLAGS="$(TARGET_CFLAGS) -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -pipe -fomit-frame-pointer -fhonour-copts" \
+ LD="$(TARGET_LD)" \
+ LDFLAGS="$(TARGET_LDFLAGS) -lcurses -lreadline" \
+ GNOREGIT=1
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
+++ /dev/null
-From 7a03968243dbad8cab1a3bdd75794c4d7cc18d96 Mon Sep 17 00:00:00 2001
-From: Christopher Faulet <cfaulet@haproxy.com>
-Date: Mon, 9 Jan 2017 16:33:19 +0100
-Subject: [PATCH] BUG/MINOR: stream: Fix how backend-specific analyzers are set
- on a stream
-
-When the stream's backend was defined, the request's analyzers flag was always
-set to 0 if the stream had no listener. This bug was introduced with the filter
-API but never triggered (I think so).
-
-Because of the commit 5820a366, it is now possible to encountered it. For
-example, this happens when the trace filter is enabled on a SPOE backend. The
-fix is pretty trivial.
-
-This fix must be backported to 1.7.
-(cherry picked from commit 70e2f272127a931a7b245a95e3a022879145e1dd)
----
- src/proxy.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/proxy.c b/src/proxy.c
-index fec2555..a84a08f 100644
---- a/src/proxy.c
-+++ b/src/proxy.c
-@@ -1156,7 +1156,7 @@ int stream_set_backend(struct stream *s, struct proxy *be)
- * be more reliable to store the list of analysers that have been run,
- * but what we do here is OK for now.
- */
-- s->req.analysers |= be->be_req_ana & (strm_li(s) ? ~strm_li(s)->analysers : 0);
-+ s->req.analysers |= be->be_req_ana & ~(strm_li(s) ? strm_li(s)->analysers : 0);
-
- /* If the target backend requires HTTP processing, we have to allocate
- * the HTTP transaction and hdr_idx if we did not have one.
---
-2.10.2
-
--- /dev/null
+From 91715c09a4595af6451ad97c43bf41fec107c69e Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Fri, 10 Mar 2017 11:49:21 +0100
+Subject: [PATCH 1/7] MINOR: config: warn when some HTTP rules are used in a
+ TCP proxy
+
+Surprizingly, http-request, http-response, block, redirect, and capture
+rules did not cause a warning to be emitted when used in a TCP proxy, so
+let's fix this.
+
+This patch may be backported to older versions as it helps spotting
+configuration issues.
+(cherry picked from commit de7dc88c517e22d3ae02ce8a8a23046ab2c62238)
+---
+ src/cfgparse.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/src/cfgparse.c b/src/cfgparse.c
+index fc6e149..d8d2fda 100644
+--- a/src/cfgparse.c
++++ b/src/cfgparse.c
+@@ -8681,6 +8681,36 @@ out_uri_auth_compat:
+ curproxy->uri_auth = NULL;
+ }
+
++ if (curproxy->capture_name) {
++ Warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
++ proxy_type_str(curproxy), curproxy->id);
++ err_code |= ERR_WARN;
++ }
++
++ if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
++ Warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
++ proxy_type_str(curproxy), curproxy->id);
++ err_code |= ERR_WARN;
++ }
++
++ if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
++ Warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
++ proxy_type_str(curproxy), curproxy->id);
++ err_code |= ERR_WARN;
++ }
++
++ if (!LIST_ISEMPTY(&curproxy->block_rules)) {
++ Warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
++ proxy_type_str(curproxy), curproxy->id);
++ err_code |= ERR_WARN;
++ }
++
++ if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
++ Warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
++ proxy_type_str(curproxy), curproxy->id);
++ err_code |= ERR_WARN;
++ }
++
+ if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
+ Warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
+ "forwardfor", proxy_type_str(curproxy), curproxy->id);
+--
+2.10.2
+
--- /dev/null
+From 8253b517585a664be53718f1522e24291f553d95 Mon Sep 17 00:00:00 2001
+From: Christopher Faulet <cfaulet@haproxy.com>
+Date: Thu, 23 Feb 2017 10:17:15 +0100
+Subject: [PATCH 2/7] BUG/MINOR: spoe: Fix soft stop handler using a specific
+ id for spoe filters
+
+During a soft stop, we need to wakeup all SPOE applets to stop them. So we loop
+on all proxies, and for each proxy, on all filters. But we must be sure to only
+handle SPOE filters here. To do so, we use a specific id.
+(cherry picked from commit 3b386a318f699def6f37b4d3199cd1d72c481a0f)
+---
+ src/flt_spoe.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/src/flt_spoe.c b/src/flt_spoe.c
+index aa6414a..2a96c65 100644
+--- a/src/flt_spoe.c
++++ b/src/flt_spoe.c
+@@ -235,6 +235,9 @@ struct spoe_context {
+ unsigned int process_exp; /* expiration date to process an event */
+ };
+
++/* SPOE filter id. Used to identify SPOE filters */
++const char *spoe_filter_id = "SPOE filter";
++
+ /* Set if the handle on SIGUSR1 is registered */
+ static int sighandler_registered = 0;
+
+@@ -2286,10 +2289,16 @@ sig_stop_spoe(struct sig_handler *sh)
+ struct flt_conf *fconf;
+
+ list_for_each_entry(fconf, &p->filter_configs, list) {
+- struct spoe_config *conf = fconf->conf;
+- struct spoe_agent *agent = conf->agent;
++ struct spoe_config *conf;
++ struct spoe_agent *agent;
+ struct appctx *appctx;
+
++ if (fconf->id != spoe_filter_id)
++ continue;
++
++ conf = fconf->conf;
++ agent = conf->agent;
++
+ list_for_each_entry(appctx, &agent->cache, ctx.spoe.list) {
+ si_applet_want_get(appctx->owner);
+ si_applet_want_put(appctx->owner);
+@@ -3178,6 +3187,7 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
+ }
+
+ *cur_arg = pos;
++ fconf->id = spoe_filter_id;
+ fconf->ops = &spoe_ops;
+ fconf->conf = conf;
+ return 0;
+--
+2.10.2
+
--- /dev/null
+From a208d4dd73794b67a59dae7e3077378473650d6c Mon Sep 17 00:00:00 2001
+From: Christopher Faulet <cfaulet@haproxy.com>
+Date: Thu, 23 Feb 2017 22:41:09 +0100
+Subject: [PATCH 3/7] BUG/MINOR: spoe: Fix parsing of arguments in spoe-message
+ section
+
+The array of pointers passed to sample_parse_expr was not really an array but a
+pointer to pointer. So it can easily lead to a segfault during the configuration
+parsing.
+(cherry picked from commit b0b42388259224be54bf504fa559803b39d6453c)
+---
+ src/flt_spoe.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/flt_spoe.c b/src/flt_spoe.c
+index 2a96c65..57fb1da 100644
+--- a/src/flt_spoe.c
++++ b/src/flt_spoe.c
+@@ -2966,8 +2966,9 @@ cfg_parse_spoe_message(const char *file, int linenum, char **args, int kwm)
+ arg->name_len = delim - args[cur_arg];
+ delim++;
+ }
+-
+- arg->expr = sample_parse_expr(&delim, &idx, file, linenum, &errmsg, &curproxy->conf.args);
++ arg->expr = sample_parse_expr((char*[]){delim, NULL},
++ &idx, file, linenum, &errmsg,
++ &curproxy->conf.args);
+ if (arg->expr == NULL) {
+ Alert("parsing [%s:%d] : '%s': %s.\n", file, linenum, args[0], errmsg);
+ err_code |= ERR_ALERT | ERR_FATAL;
+--
+2.10.2
+
--- /dev/null
+From 821d3a9f513a63b06f1696352392996391807c16 Mon Sep 17 00:00:00 2001
+From: Janusz Dziemidowicz <rraptorr@nails.eu.org>
+Date: Wed, 8 Mar 2017 16:59:41 +0100
+Subject: [PATCH 4/7] BUG/MEDIUM: ssl: Clear OpenSSL error stack after trying
+ to parse OCSP file
+
+Invalid OCSP file (for example empty one that can be used to enable
+OCSP response to be set dynamically later) causes errors that are
+placed on OpenSSL error stack. Those errors are not cleared so
+anything that checks this stack later will fail.
+
+Following configuration:
+ bind :443 ssl crt crt1.pem crt crt2.pem
+
+With following files:
+ crt1.pem
+ crt1.pem.ocsp - empty one
+ crt2.pem.rsa
+ crt2.pem.ecdsa
+
+Will fail to load.
+
+This patch should be backported to 1.7.
+(cherry picked from commit 8d7104982e1c41f7dc4d75ae7f7d2bbb96052d40)
+---
+ src/ssl_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
+index cc2dc12..daa584c 100644
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -433,6 +433,8 @@ static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certi
+
+ ret = 0;
+ out:
++ ERR_clear_error();
++
+ if (bs)
+ OCSP_BASICRESP_free(bs);
+
+--
+2.10.2
+
--- /dev/null
+From e9607769d56373cf29c4df040f605191603beb50 Mon Sep 17 00:00:00 2001
+From: Nenad Merdanovic <nmerdan@haproxy.com>
+Date: Sun, 12 Mar 2017 22:01:35 +0100
+Subject: [PATCH 5/7] BUG/MEDIUM: cli: Prevent double free in CLI ACL lookup
+
+The memory is released by cli_release_mlook, which also properly sets the
+pointer to NULL. This was introduced with a big code reorganization
+involving moving to the new keyword registration form in commit ad8be61c7.
+
+This fix needs to be backported to 1.7.
+
+Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
+(cherry picked from commit 24f45d8e34797ed9c16ac3fa6d89f3eed435e706)
+---
+ src/map.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/map.c b/src/map.c
+index b6fce4d..90deb08 100644
+--- a/src/map.c
++++ b/src/map.c
+@@ -524,7 +524,6 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
+
+ default:
+ appctx->st2 = STAT_ST_FIN;
+- free(appctx->ctx.map.chunk.str);
+ return 1;
+ }
+ }
+--
+2.10.2
+
--- /dev/null
+From e1008f22fbb9c08080aad9f998a557170b96f3f9 Mon Sep 17 00:00:00 2001
+From: Nenad Merdanovic <nmerdan@haproxy.com>
+Date: Sun, 12 Mar 2017 22:01:36 +0100
+Subject: [PATCH 6/7] BUG/MINOR: Fix "get map <map> <value>" CLI command
+
+The said form of the CLI command didn't return anything since commit
+ad8be61c7.
+
+This fix needs to be backported to 1.7.
+
+Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
+(cherry picked from commit 96c15719434a4eb46e191fcf1dafcb051065a76e)
+---
+ src/map.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/map.c b/src/map.c
+index 90deb08..e8c6a2a 100644
+--- a/src/map.c
++++ b/src/map.c
+@@ -906,7 +906,7 @@ static struct cli_kw_list cli_kws = {{ },{
+ { { "add", "map", NULL }, "add map : add map entry", cli_parse_add_map, NULL },
+ { { "clear", "map", NULL }, "clear map <id> : clear the content of this map", cli_parse_clear_map, NULL },
+ { { "del", "map", NULL }, "del map : delete map entry", cli_parse_del_map, NULL },
+- { { "get", "map", NULL }, "get map : report the keys and values matching a sample for a map", cli_parse_get_map, NULL },
++ { { "get", "map", NULL }, "get map : report the keys and values matching a sample for a map", cli_parse_get_map, cli_io_handler_map_lookup, cli_release_mlook },
+ { { "set", "map", NULL }, "set map : modify map entry", cli_parse_set_map, NULL },
+ { { "show", "map", NULL }, "show map [id] : report available maps or dump a map's contents", cli_parse_show_map, NULL },
+ { { NULL }, NULL, NULL, NULL }
+--
+2.10.2
+
--- /dev/null
+From afbf56b951967e8fa4d509e423fdcb11c27d40e2 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 14 Mar 2017 20:19:29 +0100
+Subject: [PATCH 7/7] BUG/MAJOR: connection: update CO_FL_CONNECTED before
+ calling the data layer
+
+Matthias Fechner reported a regression in 1.7.3 brought by the backport
+of commit 819efbf ("BUG/MEDIUM: tcp: don't poll for write when connect()
+succeeds"), causing some connections to fail to establish once in a while.
+While this commit itself was a fix for a bad sequencing of connection
+events, it in fact unveiled a much deeper bug going back to the connection
+rework era in v1.5-dev12 : 8f8c92f ("MAJOR: connection: add a new
+CO_FL_CONNECTED flag").
+
+It's worth noting that in a lab reproducing a similar environment as
+Matthias' about only 1 every 19000 connections exhibit this behaviour,
+making the issue not so easy to observe. A trick to make the problem
+more observable consists in disabling non-blocking mode on the socket
+before calling connect() and re-enabling it later, so that connect()
+always succeeds. Then it becomes 100% reproducible.
+
+The problem is that this CO_FL_CONNECTED flag is tested after deciding to
+call the data layer (typically the stream interface but might be a health
+check as well), and that the decision to call the data layer relies on a
+change of one of the flags covered by the CO_FL_CONN_STATE set, which is
+made of CO_FL_CONNECTED among others.
+
+Before the fix above, this bug couldn't appear with TCP but it could
+appear with Unix sockets. Indeed, connect() was always considered
+blocking so the CO_FL_WAIT_L4_CONN connection flag was always set, and
+polling for write events was always enabled. This used to guarantee that
+the conn_fd_handler() could detect a change among the CO_FL_CONN_STATE
+flags.
+
+Now with the fix above, if a connect() immediately succeeds for non-ssl
+connection with send-proxy enabled, and no data in the buffer (thus TCP
+mode only), the CO_FL_WAIT_L4_CONN flag is not set, the lack of data in
+the buffer doesn't enable polling flags for the data layer, the
+CO_FL_CONNECTED flag is not set due to send-proxy still being pending,
+and once send-proxy is done, its completion doesn't cause the data layer
+to be woken up due to the fact that CO_FL_CONNECT is still not present
+and that the CO_FL_SEND_PROXY flag is not watched in CO_FL_CONN_STATE.
+
+Then no progress is made when data are received from the client (and
+attempted to be forwarded), because a CF_WRITE_NULL (or CF_WRITE_PARTIAL)
+flag is needed for the stream-interface state to turn from SI_ST_CON to
+SI_ST_EST, allowing ->chk_snd() to be called when new data arrive. And
+the only way to set this flag is to call the data layer of course.
+
+After the connect timeout, the connection gets killed and if in the mean
+time some data have accumulated in the buffer, the retry will succeed.
+
+This patch fixes this situation by simply placing the update of
+CO_FL_CONNECTED where it should have been, before the check for a flag
+change needed to wake up the data layer and not after.
+
+This fix must be backported to 1.7, 1.6 and 1.5. Versions not having
+the patch above are still affected for unix sockets.
+
+Special thanks to Matthias Fechner who provided a very detailed bug
+report with a bisection designating the faulty patch, and to Olivier
+Houchard for providing full access to a pretty similar environment where
+the issue could first be reproduced.
+(cherry picked from commit 7bf3fa3c23f6a1b7ed1212783507ac50f7e27544)
+---
+ src/connection.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/connection.c b/src/connection.c
+index 26fc5f6..1e4c9aa 100644
+--- a/src/connection.c
++++ b/src/connection.c
+@@ -131,6 +131,13 @@ void conn_fd_handler(int fd)
+ }
+
+ leave:
++ /* Verify if the connection just established. The CO_FL_CONNECTED flag
++ * being included in CO_FL_CONN_STATE, its change will be noticed by
++ * the next block and be used to wake up the data layer.
++ */
++ if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
++ conn->flags |= CO_FL_CONNECTED;
++
+ /* The wake callback may be used to process a critical error and abort the
+ * connection. If so, we don't want to go further as the connection will
+ * have been released and the FD destroyed.
+@@ -140,10 +147,6 @@ void conn_fd_handler(int fd)
+ conn->data->wake(conn) < 0)
+ return;
+
+- /* Last check, verify if the connection just established */
+- if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
+- conn->flags |= CO_FL_CONNECTED;
+-
+ /* remove the events before leaving */
+ fdtab[fd].ev &= FD_POLL_STICKY;
+
+--
+2.10.2
+