diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index a8f7ca608..bb2dce9c4 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=haproxy PKG_VERSION:=1.6.9 -PKG_RELEASE:=26 +PKG_RELEASE:=31 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.6/src/ @@ -51,7 +51,8 @@ define Package/haproxy/Default/description endef define Package/haproxy - DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl + DEPENDS+= +libpcre +libltdl +zlib +libpthread +libopenssl +ncurses +libreadline +@OPENSSL_WITH_DEPRECATED +@OPENSSL_WITH_EC +@OPENSSL_WITH_EC2M +@OPENSSL_WITH_DTLS +@OPENSSL_WITH_COMPRESSION +@OPENSSL_WITH_NPN +@OPENSSL_WITH_PSK +@OPENSSL_WITH_SRP +@OPENSSL_ENGINE_DIGEST +@OPENSSL_ENGINE_CRYPTO + TITLE+= (with SSL support) VARIANT:=ssl $(call Package/haproxy/Default) @@ -66,6 +67,11 @@ $(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 @@ -95,23 +101,29 @@ ifeq ($(BUILD_VARIANT),ssl) 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" + ADDON+=ADDLIB="-lcrypto -lm " else ADDON+=ADDLIB="-lm" endif + define Build/Compile - make TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR)/lua INSTALL_TOP="$(STAGING_DIR)/lua-5.3.3/" linux install + $(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR)/lua \ + INSTALL_TOP="$(STAGING_DIR)/lua-5.3.3/" \ + CC="$(TARGET_CC)" \ + LDFLAGS="$(TARGET_LDFLAGS) -lncurses -lreadline" \ + LD="$(TARGET_LD)" \ + 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) + 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 \ @@ -119,16 +131,16 @@ define Build/Compile VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \ IGNOREGIT=1 - $(MAKE) TARGET=$(LINUX_TARGET) -C $(PKG_BUILD_DIR) \ + $(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) \ DESTDIR="$(PKG_INSTALL_DIR)" \ + LD="$(TARGET_CC)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + $(MAKE_FLAGS) \ install - $(MAKE) -C $(PKG_BUILD_DIR)/contrib/halog \ + $(MAKE_VARS) $(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)" \ + $(MAKE_FLAGS) \ ADDLIB="-lcrypto" \ VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \ halog diff --git a/net/haproxy/patches/0027-BUG-MEDIUM-systemd-wrapper-return-correct-exit-codes.patch b/net/haproxy/patches/0027-BUG-MEDIUM-systemd-wrapper-return-correct-exit-codes.patch new file mode 100644 index 000000000..76e621667 --- /dev/null +++ b/net/haproxy/patches/0027-BUG-MEDIUM-systemd-wrapper-return-correct-exit-codes.patch @@ -0,0 +1,70 @@ +From 0a2117dc29147ed990732d1b2fc9779835820f3e Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Thu, 3 Nov 2016 20:31:40 +0100 +Subject: [PATCH 27/31] BUG/MEDIUM: systemd-wrapper: return correct exit codes + +Gabriele Cerami reported the the exit codes of the systemd-wrapper are +wrong. In short, it directly returns the output of the wait syscall's +status, which is a composite value made of error code an signal numbers. +In general it contains the signal number on the lower bits and the error +code on the higher bits, but exit() truncates it to the lowest 8 bits, +causing config validations to incorrectly report a success. Example : + + $ ./haproxy-systemd-wrapper -c -f /dev/null + <7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds + Configuration file has no error but will not start (no listener) => exit(2). + <5>haproxy-systemd-wrapper: exit, haproxy RC=512 + $ echo $? + 0 + +If the process is killed however, the signal number is directly reported +in the exit code. + +Let's fix all this to ensure that the exit code matches what the shell does, +which means that codes 0..127 are for exit codes, codes 128..254 for signals, +and code 255 for unknown exit code. Now the return code is correct : + + $ ./haproxy-systemd-wrapper -c -f /dev/null + <7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds + Configuration file has no error but will not start (no listener) => exit(2). + <5>haproxy-systemd-wrapper: exit, haproxy RC=2 + $ echo $? + 2 + + $ ./haproxy-systemd-wrapper -f /tmp/cfg.conf + <7>haproxy-systemd-wrapper: executing /tmp/haproxy -f /dev/null -Ds + ^C + <5>haproxy-systemd-wrapper: exit, haproxy RC=130 + $ echo $? + 130 + +This fix must be backported to 1.6 and 1.5. +(cherry picked from commit f7659cb10cb0420c7ca06fad1067207021d2a078) +--- + src/haproxy-systemd-wrapper.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c +index b426f96..f6a9c85 100644 +--- a/src/haproxy-systemd-wrapper.c ++++ b/src/haproxy-systemd-wrapper.c +@@ -295,6 +295,16 @@ int main(int argc, char **argv) + } + } + ++ /* return either exit code or signal+128 */ ++ if (WIFEXITED(status)) ++ status = WEXITSTATUS(status); ++ else if (WIFSIGNALED(status)) ++ status = 128 + WTERMSIG(status); ++ else if (WIFSTOPPED(status)) ++ status = 128 + WSTOPSIG(status); ++ else ++ status = 255; ++ + fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n", + status); + return status; +-- +2.7.3 + diff --git a/net/haproxy/patches/0028-BUG-MEDIUM-srv-state-properly-restore-the-DRAIN-stat.patch b/net/haproxy/patches/0028-BUG-MEDIUM-srv-state-properly-restore-the-DRAIN-stat.patch new file mode 100644 index 000000000..fb51e7f52 --- /dev/null +++ b/net/haproxy/patches/0028-BUG-MEDIUM-srv-state-properly-restore-the-DRAIN-stat.patch @@ -0,0 +1,72 @@ +From 74ffd0cd0cecaeec3cfa848cbc03beb08999cc72 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Thu, 3 Nov 2016 18:19:49 +0100 +Subject: [PATCH 28/31] BUG/MEDIUM: srv-state: properly restore the DRAIN state + +There were seveal reports about the DRAIN state not being properly +restored upon reload. + +It happens that the condition in the code does exactly the opposite +of what the comment says, and the comment is right so the code is +wrong. + +It's worth noting that the conditions are complex here due to the 2 +available methods to set the drain state (CLI/agent, and config's +weight). To paraphrase the updated comment in the code, there are +two possible reasons for FDRAIN to have been present : + - previous config weight was zero + - "set server b/s drain" was sent to the CLI + +In the first case, we simply want to drop this drain state if the new +weight is not zero anymore, meaning the administrator has intentionally +turned the weight back to a positive value to enable the server again +after an operation. In the second case, the drain state was forced on +the CLI regardless of the config's weight so we don't want a change to +the config weight to lose this status. What this means is : + - if previous weight was 0 and new one is >0, drop the DRAIN state. + - if the previous weight was >0, keep it. + +This fix must be backported to 1.6. +(cherry picked from commit 22cace2f4c3cbeca27c1941c647e7ae38ec8c0c0) +--- + src/server.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/src/server.c b/src/server.c +index 79b3cb2..b9e72b7 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -2093,15 +2093,23 @@ static void srv_update_state(struct server *srv, int version, char **params) + /* apply drain mode if server is currently enabled */ + if (!(srv->admin & SRV_ADMF_FMAINT) && (srv_admin_state & SRV_ADMF_FDRAIN)) { + /* The SRV_ADMF_FDRAIN flag is inherited when srv->iweight is 0 +- * (srv->iweight is the weight set up in configuration) +- * so we don't want to apply it when srv_iweight is 0 and +- * srv->iweight is greater than 0. Purpose is to give the +- * chance to the admin to re-enable this server from configuration +- * file by setting a new weight > 0. ++ * (srv->iweight is the weight set up in configuration). ++ * There are two possible reasons for FDRAIN to have been present : ++ * - previous config weight was zero ++ * - "set server b/s drain" was sent to the CLI ++ * ++ * In the first case, we simply want to drop this drain state ++ * if the new weight is not zero anymore, meaning the administrator ++ * has intentionally turned the weight back to a positive value to ++ * enable the server again after an operation. In the second case, ++ * the drain state was forced on the CLI regardless of the config's ++ * weight so we don't want a change to the config weight to lose this ++ * status. What this means is : ++ * - if previous weight was 0 and new one is >0, drop the DRAIN state. ++ * - if the previous weight was >0, keep it. + */ +- if ((srv_iweight == 0) && (srv->iweight > 0)) { ++ if (srv_iweight > 0 || srv->iweight == 0) + srv_adm_set_drain(srv); +- } + } + + srv->last_change = date.tv_sec - srv_last_time_change; +-- +2.7.3 + diff --git a/net/haproxy/patches/0029-BUG-MINOR-srv-state-allow-to-have-both-CMAINT-and-FD.patch b/net/haproxy/patches/0029-BUG-MINOR-srv-state-allow-to-have-both-CMAINT-and-FD.patch new file mode 100644 index 000000000..60ab33aee --- /dev/null +++ b/net/haproxy/patches/0029-BUG-MINOR-srv-state-allow-to-have-both-CMAINT-and-FD.patch @@ -0,0 +1,33 @@ +From d6649c499b8ca4fb0bf93153c2a149c78e8a76f8 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Thu, 3 Nov 2016 18:33:25 +0100 +Subject: [PATCH 29/31] BUG/MINOR: srv-state: allow to have both CMAINT and + FDRAIN flags + +CMAINT indicates that the server was *initially* disabled in the +configuration via the "disabled" keyword. FDRAIN indicates that the +server was switched to the DRAIN state from the CLI or the agent. +This it's perfectly valid to have both of them in the state file, +so the parser must not reject this combination. + +This fix must be backported to 1.6. +(cherry picked from commit e1bde1492a30f5036ca58248e50c27a9e116d9cc) +--- + src/server.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/server.c b/src/server.c +index b9e72b7..b0c7bbe 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -1961,6 +1961,7 @@ static void srv_update_state(struct server *srv, int version, char **params) + srv_admin_state != SRV_ADMF_IMAINT && + srv_admin_state != SRV_ADMF_CMAINT && + srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) && ++ srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) && + srv_admin_state != SRV_ADMF_FDRAIN && + srv_admin_state != SRV_ADMF_IDRAIN)) { + chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]); +-- +2.7.3 + diff --git a/net/haproxy/patches/0030-BUG-MEDIUM-servers-properly-propagate-the-maintenanc.patch b/net/haproxy/patches/0030-BUG-MEDIUM-servers-properly-propagate-the-maintenanc.patch new file mode 100644 index 000000000..d4815b399 --- /dev/null +++ b/net/haproxy/patches/0030-BUG-MEDIUM-servers-properly-propagate-the-maintenanc.patch @@ -0,0 +1,172 @@ +From c449c9835e7d9e02cf0aeafc482364d5090db543 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Thu, 3 Nov 2016 19:22:19 +0100 +Subject: [PATCH 30/31] BUG/MEDIUM: servers: properly propagate the maintenance + states during startup + +Right now there is an issue with the way the maintenance flags are +propagated upon startup. They are not propagate, just copied from the +tracked server. This implies that depending on the server's order, some +tracking servers may not be marked down. For example this configuration +does not work as expected : + + server s1 1.1.1.1:8000 track s2 + server s2 1.1.1.1:8000 track s3 + server s3 1.1.1.1:8000 track s4 + server s4 wtap:8000 check inter 1s disabled + +It results in s1/s2 being up, and s3/s4 being down, while all of them +should be down. + +The only clean way to process this is to run through all "root" servers +(those not tracking any other server), and to propagate their state down +to all their trackers. This is the same algorithm used to propagate the +state changes. It has to be done both to compute the IDRAIN flag and the +IMAINT flag. However, doing so requires that tracking servers are not +marked as inherited maintenance anymore while parsing the configuration +(and given that it is wrong, better drop it). + +This fix also addresses another side effect of the bug above which is +that the IDRAIN/IMAINT flags are stored in the state files, and if +restored while the tracked server doesn't have the equivalent flag, +the servers may end up in a situation where it's impossible to remove +these flags. For example in the configuration above, after removing +"disabled" on server s4, the other servers would have remained down, +and not anymore with this fix. Similarly, the combination of IMAINT +or IDRAIN with their respective forced modes was not accepted on +reload, which is wrong as well. + +This bug has been present at least since 1.5, maybe even 1.4 (it came +with tracking support). The fix needs to be backported there, though +the srv-state parts are irrelevant. + +This commit relies on previous patch to silence warnings on startup. +(cherry picked from commit 757478e900ebc1e67c1fe060b9b561d276cab3e1) +--- + include/proto/server.h | 1 + + src/cfgparse.c | 7 ------- + src/haproxy.c | 4 ++++ + src/server.c | 42 +++++++++++++++++++++++++++++++++++++++--- + 4 files changed, 44 insertions(+), 10 deletions(-) + +diff --git a/include/proto/server.h b/include/proto/server.h +index d75cc9f..b6572ba 100644 +--- a/include/proto/server.h ++++ b/include/proto/server.h +@@ -44,6 +44,7 @@ struct server *server_find_by_id(struct proxy *bk, int id); + struct server *server_find_by_name(struct proxy *bk, const char *name); + struct server *server_find_best_match(struct proxy *bk, char *name, int id, int *diff); + void apply_server_state(void); ++void srv_compute_all_admin_states(struct proxy *px); + + /* functions related to server name resolution */ + int snr_update_srv_status(struct server *s); +diff --git a/src/cfgparse.c b/src/cfgparse.c +index b8289a2..365b283 100644 +--- a/src/cfgparse.c ++++ b/src/cfgparse.c +@@ -8275,13 +8275,6 @@ out_uri_auth_compat: + goto next_srv; + } + +- /* if the other server is forced disabled, we have to do the same here */ +- if (srv->admin & SRV_ADMF_MAINT) { +- newsrv->admin |= SRV_ADMF_IMAINT; +- newsrv->state = SRV_ST_STOPPED; +- newsrv->check.health = 0; +- } +- + newsrv->track = srv; + newsrv->tracknext = srv->trackers; + srv->trackers = newsrv; +diff --git a/src/haproxy.c b/src/haproxy.c +index 2d476f2..1699132 100644 +--- a/src/haproxy.c ++++ b/src/haproxy.c +@@ -566,6 +566,7 @@ void init(int argc, char **argv) + struct wordlist *wl; + char *progname; + char *change_dir = NULL; ++ struct proxy *px; + + chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize); + alloc_trash_buffers(global.tune.bufsize); +@@ -852,6 +853,9 @@ void init(int argc, char **argv) + /* Apply server states */ + apply_server_state(); + ++ for (px = proxy; px; px = px->next) ++ srv_compute_all_admin_states(px); ++ + global_listener_queue_task = task_new(); + if (!global_listener_queue_task) { + Alert("Out of memory when initializing global task\n"); +diff --git a/src/server.c b/src/server.c +index b0c7bbe..f2923ae 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -705,6 +705,40 @@ void srv_clr_admin_flag(struct server *s, enum srv_admin mode) + srv_clr_admin_flag(srv, mode); + } + ++/* principle: propagate maint and drain to tracking servers. This is useful ++ * upon startup so that inherited states are correct. ++ */ ++static void srv_propagate_admin_state(struct server *srv) ++{ ++ struct server *srv2; ++ ++ if (!srv->trackers) ++ return; ++ ++ for (srv2 = srv->trackers; srv2; srv2 = srv2->tracknext) { ++ if (srv->admin & (SRV_ADMF_MAINT | SRV_ADMF_CMAINT)) ++ srv_set_admin_flag(srv2, SRV_ADMF_IMAINT); ++ ++ if (srv->admin & SRV_ADMF_DRAIN) ++ srv_set_admin_flag(srv2, SRV_ADMF_IDRAIN); ++ } ++} ++ ++/* Compute and propagate the admin states for all servers in proxy . ++ * Only servers *not* tracking another one are considered, because other ++ * ones will be handled when the server they track is visited. ++ */ ++void srv_compute_all_admin_states(struct proxy *px) ++{ ++ struct server *srv; ++ ++ for (srv = px->srv; srv; srv = srv->next) { ++ if (srv->track) ++ continue; ++ srv_propagate_admin_state(srv); ++ } ++} ++ + /* Note: must not be declared as its list will be overwritten. + * Please take care of keeping this list alphabetically sorted, doing so helps + * all code contributors. +@@ -1955,15 +1989,17 @@ static void srv_update_state(struct server *srv, int version, char **params) + p = NULL; + errno = 0; + srv_admin_state = strtol(params[2], &p, 10); ++ ++ /* inherited statuses will be recomputed later */ ++ srv_admin_state &= ~SRV_ADMF_IDRAIN & ~SRV_ADMF_IMAINT; ++ + if ((p == params[2]) || errno == EINVAL || errno == ERANGE || + (srv_admin_state != 0 && + srv_admin_state != SRV_ADMF_FMAINT && +- srv_admin_state != SRV_ADMF_IMAINT && + srv_admin_state != SRV_ADMF_CMAINT && + srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) && + srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) && +- srv_admin_state != SRV_ADMF_FDRAIN && +- srv_admin_state != SRV_ADMF_IDRAIN)) { ++ srv_admin_state != SRV_ADMF_FDRAIN)) { + chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]); + } + +-- +2.7.3 + diff --git a/net/haproxy/patches/0031-BUG-vars-Fix-set-var-converter-because-of-a-typo.patch b/net/haproxy/patches/0031-BUG-vars-Fix-set-var-converter-because-of-a-typo.patch new file mode 100644 index 000000000..248d9a496 --- /dev/null +++ b/net/haproxy/patches/0031-BUG-vars-Fix-set-var-converter-because-of-a-typo.patch @@ -0,0 +1,37 @@ +From 9c017e541bb3cee2e2884cdc53a4cb4627be5dad Mon Sep 17 00:00:00 2001 +From: Christopher Faulet +Date: Wed, 9 Nov 2016 16:15:32 +0100 +Subject: [PATCH 31/31] BUG: vars: Fix 'set-var' converter because of a typo + +The 'set-var' converter uses function smp_conv_store (vars.c). In this function, +we should use the first argument (index 0) to retrieve the variable name and its +scope. But because of a typo, we get the scope of the second argument (index +1). In this case, there is no second argument. So the scope used was always 0 +(SCOPE_SESS), always setting the variable in the session scope. + +So, due to this bug, this rules + + tcp-request content accept if { src,set-var(txn.foo) -m found } + +always set the variable 'sess.foo' instead of 'txn.foo'. +(cherry picked from commit 0099a8ca9d58cb4cff943bf6374b55b42a23fbfb) +--- + src/vars.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/vars.c b/src/vars.c +index a3dd85c..8645905 100644 +--- a/src/vars.c ++++ b/src/vars.c +@@ -379,7 +379,7 @@ static inline int sample_store_stream(const char *name, enum vars_scope scope, s + /* Returns 0 if fails, else returns 1. */ + static int smp_conv_store(const struct arg *args, struct sample *smp, void *private) + { +- return sample_store_stream(args[0].data.var.name, args[1].data.var.scope, smp); ++ return sample_store_stream(args[0].data.var.name, args[0].data.var.scope, smp); + } + + /* This fucntions check an argument entry and fill it with a variable +-- +2.7.3 +