package: haproxy
- fix a possible crash when using negative header occurrences git-svn-id: svn://svn.openwrt.org/openwrt/packages@36945 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
868bc27cbc
commit
6ec3f47552
@ -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
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
From d16a1b2a818359e8c3ade85f789e66ed7ca9488c Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
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
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 1181ad3ea9d73908b0238702032eccaeb8834a1a Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
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
|
||||
|
@ -1,3 +1,21 @@
|
||||
From af2038557a14bf6e2915bed545e216a0f1a95fc5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
|
||||
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 [<address>]:<port_range> [, ...] 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 <proto/proxy.h>
|
||||
#include <proto/queue.h>
|
||||
#include <proto/server.h>
|
||||
+#include <proto/client.h>
|
||||
#include <proto/stick_table.h>
|
||||
#include <proto/stream_interface.h>
|
||||
#include <proto/stream_sock.h>
|
||||
@@ -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 <ret> 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user