From 4dd9c7fea3bca108952e9347e15702628bfa4582 Mon Sep 17 00:00:00 2001 From: Thomas Heil Date: Mon, 17 Jun 2013 13:53:49 +0000 Subject: [PATCH] package: haproxy - fix a possible crash when using negative header occurrences SVN-Revision: 36945 --- net/haproxy/Makefile | 6 +- ...d-consistent-hash-can-loop-forever-i.patch | 57 ------------------- ...s-disable-TCP-quickack-when-pure-TCP.patch | 45 --------------- .../patches/001-haproxy-1.4.x-sendproxy.patch | 53 +++++++++++++++-- 4 files changed, 52 insertions(+), 109 deletions(-) delete mode 100644 net/haproxy/patches/0001-BUG-MAJOR-backend-consistent-hash-can-loop-forever-i.patch delete mode 100644 net/haproxy/patches/0002-BUG-MEDIUM-checks-disable-TCP-quickack-when-pure-TCP.patch diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index bc6f805b1..f67ed1227 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=haproxy -PKG_VERSION:=1.4.23 -PKG_RELEASE:=04 +PKG_VERSION:=1.4.24 +PKG_RELEASE:=01 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.4/src -PKG_MD5SUM:=6535d5e58037ada4b58b439cebe03c79 +PKG_MD5SUM:=86422620faa9759907563d5e0524b98c include $(INCLUDE_DIR)/package.mk diff --git a/net/haproxy/patches/0001-BUG-MAJOR-backend-consistent-hash-can-loop-forever-i.patch b/net/haproxy/patches/0001-BUG-MAJOR-backend-consistent-hash-can-loop-forever-i.patch deleted file mode 100644 index da8df396e..000000000 --- a/net/haproxy/patches/0001-BUG-MAJOR-backend-consistent-hash-can-loop-forever-i.patch +++ /dev/null @@ -1,57 +0,0 @@ -From d16a1b2a818359e8c3ade85f789e66ed7ca9488c Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Fri, 12 Apr 2013 14:46:51 +0200 -Subject: BUG/MAJOR: backend: consistent hash can loop forever in certain - circumstances - -When the parameter passed to a consistent hash is not found, we fall back to -round-robin using chash_get_next_server(). This one stores the last visited -server in lbprm.chash.last, which can be NULL upon the first invocation or if -the only server was recently brought up. - -The loop used to scan for a server is able to skip the previously attempted -server in case of a redispatch, by passing this previous server in srvtoavoid. -For this reason, the loop stops when the currently considered server is -different from srvtoavoid and different from the original chash.last. - -A problem happens in a special sequence : if a connection to a server fails, -then all servers are removed from the farm, then the original server is added -again before the redispatch happens, we have chash.last = NULL and srvtoavoid -set to the only server in the farm. Then this server is always equal to -srvtoavoid and never to NULL, and the loop never stops. - -The fix consists in assigning the stop point to the first encountered node if -it was not yet set. - -This issue cannot happen with the map-based algorithm since it's based on an -index and not a stop point. - -This issue was reported by Henry Qian who kindly provided lots of critically -useful information to figure out the conditions to reproduce the issue. - -The fix needs to be backported to 1.4 which is also affected. ---- - src/lb_chash.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/lb_chash.c b/src/lb_chash.c -index 58f1c9e..d65de74 100644 ---- a/src/lb_chash.c -+++ b/src/lb_chash.c -@@ -332,6 +332,13 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid) - /* no node is available */ - return NULL; - -+ /* Note: if we came here after a down/up cycle with no last -+ * pointer, and after a redispatch (srvtoavoid is set), we -+ * must set stop to non-null otherwise we can loop forever. -+ */ -+ if (!stop) -+ stop = node; -+ - /* OK, we have a server. However, it may be saturated, in which - * case we don't want to reconsider it for now, so we'll simply - * skip it. Same if it's the server we try to avoid, in which --- -1.7.12.4.dirty - diff --git a/net/haproxy/patches/0002-BUG-MEDIUM-checks-disable-TCP-quickack-when-pure-TCP.patch b/net/haproxy/patches/0002-BUG-MEDIUM-checks-disable-TCP-quickack-when-pure-TCP.patch deleted file mode 100644 index 35108435f..000000000 --- a/net/haproxy/patches/0002-BUG-MEDIUM-checks-disable-TCP-quickack-when-pure-TCP.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 1181ad3ea9d73908b0238702032eccaeb8834a1a Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Fri, 26 Apr 2013 11:43:56 +0200 -Subject: [PATCH 2/2] BUG/MEDIUM: checks: disable TCP quickack when pure TCP - checks are used -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Cyril Bonté reported an issue with some services when pure port probes are -used since 1.4.23, because of the RST which is sent and sometimes caught by -the checked service. The result is that the service detects an error and may -sometimes log this error or complain about it. This issue does not appear -when "option tcp-smart-connect" is set. - -So we now perform exactly like 1.5 with port probes, which means that we set -the TCP quickack mode on the socket before connecting, so that the final ACK -is never sent. So the sequence is now a clean SYN-SYN/ACK-RST which never -wakes the application up and that only checks that the port is open. ---- - src/checks.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/checks.c b/src/checks.c -index e586e4c..9813914 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -1388,8 +1388,13 @@ struct task *process_chk(struct task *t) - /* disabling tcp quick ack now allows - * the request to leave the machine with - * the first ACK. -+ * We also want to do this to perform a -+ * SYN-SYN/ACK-RST sequence when raw TCP -+ * checks are configured. - */ -- if (s->proxy->options2 & PR_O2_SMARTCON) -+ if ((s->proxy->options2 & PR_O2_SMARTCON) || -+ (!(s->proxy->options & (PR_O_HTTP_CHK|PR_O_SMTP_CHK)) && -+ !(s->proxy->options2 & (PR_O2_SSL3_CHK|PR_O2_MYSQL_CHK|PR_O2_LDAP_CHK)))) - setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, (char *) &zero, sizeof(zero)); - #endif - if ((connect(fd, (struct sockaddr *)&sa, sizeof(sa)) != -1) || (errno == EINPROGRESS)) { --- -1.8.1.5 - diff --git a/net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch b/net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch index a14a0e202..66e6acdb1 100644 --- a/net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch +++ b/net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch @@ -1,3 +1,21 @@ +From af2038557a14bf6e2915bed545e216a0f1a95fc5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cyril=20Bont=C3=A9?= +Date: Mon, 15 Apr 2013 22:05:00 +0200 +Subject: [PATCH] Proxy Protocol based on haproxy 1.4.23 + +--- + doc/configuration.txt | 26 ++++++- + include/common/standard.h | 25 ++++++- + include/proto/client.h | 1 + + include/types/buffers.h | 20 ++--- + include/types/protocols.h | 1 + + src/cfgparse.c | 15 +++- + src/client.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++ + src/proto_http.c | 4 +- + src/session.c | 7 ++ + src/standard.c | 9 ++- + 10 files changed, 275 insertions(+), 19 deletions(-) + --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1343,6 +1343,7 @@ bind [
]: [, ...] tr @@ -93,14 +111,18 @@ extern unsigned int str2ui(const char *s); extern unsigned int str2uic(const char *s); extern unsigned int strl2ui(const char *s, int len); -@@ -276,6 +298,7 @@ extern unsigned int strl2uic(const char +@@ -276,9 +298,10 @@ extern unsigned int strl2uic(const char extern int strl2ic(const char *s, int len); extern int strl2irc(const char *s, int len, int *ret); extern int strl2llrc(const char *s, int len, long long *ret); +extern unsigned int read_uint(const char **s, const char *end); unsigned int inetaddr_host(const char *text); unsigned int inetaddr_host_lim(const char *text, const char *stop); - unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret); +-unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret); ++unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret); + + static inline char *cut_crlf(char *s) { + --- a/include/proto/client.h +++ b/include/proto/client.h @@ -25,6 +25,7 @@ @@ -402,7 +424,7 @@ s->rep->analysers = 0; http_silent_debug(__LINE__, s); -@@ -7739,7 +7740,6 @@ void http_reset_txn(struct session *s) +@@ -7741,7 +7742,6 @@ void http_reset_txn(struct session *s) http_init_txn(s); s->be = s->fe; @@ -412,7 +434,15 @@ /* re-init store persistence */ --- a/src/session.c +++ b/src/session.c -@@ -1071,6 +1071,12 @@ resync_stream_interface: +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1071,6 +1072,12 @@ resync_stream_interface: while (ana_list && max_loops--) { /* Warning! ensure that analysers are always placed in ascending order! */ @@ -439,3 +469,18 @@ /* This one is 7 times faster than strtol() on athlon with checks. * It returns the value of the number composed of all valid digits read, * and can process negative numbers too. +@@ -993,12 +998,12 @@ unsigned int inetaddr_host_lim(const cha + * Idem except the pointer to first unparsed byte is returned into which + * must not be NULL. + */ +-unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret) ++unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret) + { + const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0'; + register unsigned int dig100, dig10, dig1; + int s; +- const char *p, *d; ++ char *p, *d; + + dig1 = dig10 = dig100 = ascii_zero; + s = 24; -- 2.30.2