- integrate pending patches Signed-off-by: heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -0,0 +1,34 @@ | |||||
From 4818bc3035bccc00d8c3fc9b14ec37366cac3059 Mon Sep 17 00:00:00 2001 | |||||
From: Jerome Duval <jerome.duval@gmail.com> | |||||
Date: Mon, 2 Nov 2015 17:47:43 +0000 | |||||
Subject: [PATCH 01/10] BUG/BUILD: replace haproxy-systemd-wrapper with | |||||
$(EXTRA) in install-bin. | |||||
[wt: this should be backported to 1.6 and 1.5 as well since some platforms | |||||
don't build the systemd-wrapper] | |||||
(cherry picked from commit 796d2fc136359c31c5c35f00c0751890ab42a016) | |||||
(cherry picked from commit 9d0b47d96825b0584ea81c826a96ed8babcc016b) | |||||
--- | |||||
Makefile | 5 ++--- | |||||
1 file changed, 2 insertions(+), 3 deletions(-) | |||||
diff --git a/Makefile b/Makefile | |||||
index 9556069..e3199b2 100644 | |||||
--- a/Makefile | |||||
+++ b/Makefile | |||||
@@ -719,10 +719,9 @@ install-doc: | |||||
install -m 644 doc/$$x.txt "$(DESTDIR)$(DOCDIR)" ; \ | |||||
done | |||||
-install-bin: haproxy haproxy-systemd-wrapper | |||||
+install-bin: haproxy $(EXTRA) | |||||
install -d "$(DESTDIR)$(SBINDIR)" | |||||
- install haproxy "$(DESTDIR)$(SBINDIR)" | |||||
- install haproxy-systemd-wrapper "$(DESTDIR)$(SBINDIR)" | |||||
+ install haproxy $(EXTRA) "$(DESTDIR)$(SBINDIR)" | |||||
install: install-bin install-man install-doc | |||||
-- | |||||
2.4.10 | |||||
@ -1,64 +0,0 @@ | |||||
From df0a5960987b3cb663dcfa93d29c21acc13cd3e3 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 9 Jul 2015 11:20:00 +0200 | |||||
Subject: [PATCH 1/4] BUG/MINOR: log: missing some ARGC_* entries in | |||||
fmt_directives() | |||||
ARGC_CAP was not added to fmt_directives() which is used to format | |||||
error messages when failing to parse log format expressions. The | |||||
whole switch/case has been reorganized to match the declaration | |||||
order making it easier to spot missing values. The default is not | |||||
the "log" directive anymore but "undefined" asking to report the | |||||
bug. | |||||
Backport to 1.5 is not strictly needed but is desirable at least | |||||
for code sanity. | |||||
(cherry picked from commit 53e1a6d31743b1bef6063ff30b812521391ae3c3) | |||||
--- | |||||
src/log.c | 24 ++++++++++++++---------- | |||||
1 file changed, 14 insertions(+), 10 deletions(-) | |||||
diff --git a/src/log.c b/src/log.c | |||||
index 1a5ad25..f0a3072 100644 | |||||
--- a/src/log.c | |||||
+++ b/src/log.c | |||||
@@ -167,22 +167,26 @@ struct logformat_var_args var_args_list[] = { | |||||
static inline const char *fmt_directive(const struct proxy *curproxy) | |||||
{ | |||||
switch (curproxy->conf.args.ctx) { | |||||
- case ARGC_UIF: | |||||
- return "unique-id-format"; | |||||
+ case ARGC_ACL: | |||||
+ return "acl"; | |||||
+ case ARGC_STK: | |||||
+ return "stick"; | |||||
+ case ARGC_TRK: | |||||
+ return "track-sc"; | |||||
+ case ARGC_LOG: | |||||
+ return "log-format"; | |||||
case ARGC_HRQ: | |||||
return "http-request"; | |||||
case ARGC_HRS: | |||||
return "http-response"; | |||||
- case ARGC_STK: | |||||
- return "stick"; | |||||
- case ARGC_TRK: | |||||
- return "track-sc"; break; | |||||
+ case ARGC_UIF: | |||||
+ return "unique-id-format"; | |||||
case ARGC_RDR: | |||||
- return "redirect"; break; | |||||
- case ARGC_ACL: | |||||
- return "acl"; break; | |||||
+ return "redirect"; | |||||
+ case ARGC_CAP: | |||||
+ return "capture"; | |||||
default: | |||||
- return "log-format"; | |||||
+ return "undefined(please report this bug)"; /* must never happen */ | |||||
} | |||||
} | |||||
-- | |||||
2.3.6 | |||||
@ -0,0 +1,69 @@ | |||||
From 1af6a324c3206902f69bd2c9838e94ffb4cee3ae Mon Sep 17 00:00:00 2001 | |||||
From: Lukas Tribus <luky-37@hotmail.com> | |||||
Date: Thu, 5 Nov 2015 13:59:30 +0100 | |||||
Subject: [PATCH 02/10] BUG/MINOR: acl: don't use record layer in req_ssl_ver | |||||
MIME-Version: 1.0 | |||||
Content-Type: text/plain; charset=UTF-8 | |||||
Content-Transfer-Encoding: 8bit | |||||
The initial record layer version in a SSL handshake may be set to TLSv1.0 | |||||
or similar for compatibility reasons, this is allowed as per RFC5246 | |||||
Appendix E.1 [1]. Some implementations are Openssl [2] and NSS [3]. | |||||
A related issue has been fixed some time ago in commit 57d229747 | |||||
("BUG/MINOR: acl: req_ssl_sni fails with SSLv3 record version"). | |||||
Fix this by using the real client hello version instead of the record | |||||
layer version. | |||||
This was reported by Julien Vehent and analyzed by Cyril Bonté. | |||||
The initial patch is from Julien Vehent as well. | |||||
This should be backported to stable series, the req_ssl_ver keyword was | |||||
first introduced in 1.3.16. | |||||
[1] https://tools.ietf.org/html/rfc5246#appendix-E.1 | |||||
[2] https://github.com/openssl/openssl/commit/4a1cf50187659e60c5867ecbbc36e37b2605d2c3 | |||||
[3] https://bugzilla.mozilla.org/show_bug.cgi?id=774547 | |||||
(cherry picked from commit c93242cab986087f06a4655d14fec18eecb7f5f4) | |||||
(cherry picked from commit b048a6eb3d9cb518e4a378e20ba2a801afec553c) | |||||
--- | |||||
src/payload.c | 11 +++++++---- | |||||
1 file changed, 7 insertions(+), 4 deletions(-) | |||||
diff --git a/src/payload.c b/src/payload.c | |||||
index f62163c..b8f1ca3 100644 | |||||
--- a/src/payload.c | |||||
+++ b/src/payload.c | |||||
@@ -148,21 +148,24 @@ smp_fetch_req_ssl_ver(struct proxy *px, struct session *s, void *l7, unsigned in | |||||
data = (const unsigned char *)s->req->buf->p; | |||||
if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) { | |||||
/* SSLv3 header format */ | |||||
- if (bleft < 5) | |||||
+ if (bleft < 11) | |||||
goto too_short; | |||||
- version = (data[1] << 16) + data[2]; /* version: major, minor */ | |||||
+ version = (data[1] << 16) + data[2]; /* record layer version: major, minor */ | |||||
msg_len = (data[3] << 8) + data[4]; /* record length */ | |||||
/* format introduced with SSLv3 */ | |||||
if (version < 0x00030000) | |||||
goto not_ssl; | |||||
- /* message length between 1 and 2^14 + 2048 */ | |||||
- if (msg_len < 1 || msg_len > ((1<<14) + 2048)) | |||||
+ /* message length between 6 and 2^14 + 2048 */ | |||||
+ if (msg_len < 6 || msg_len > ((1<<14) + 2048)) | |||||
goto not_ssl; | |||||
bleft -= 5; data += 5; | |||||
+ | |||||
+ /* return the client hello client version, not the record layer version */ | |||||
+ version = (data[4] << 16) + data[5]; /* client hello version: major, minor */ | |||||
} else { | |||||
/* SSLv2 header format, only supported for hello (msg type 1) */ | |||||
int rlen, plen, cilen, silen, chlen; | |||||
-- | |||||
2.4.10 | |||||
@ -1,27 +0,0 @@ | |||||
From ea31f225c2c93a25b8bef7a9241a89cecfd9d350 Mon Sep 17 00:00:00 2001 | |||||
From: Baptiste Assmann <bedis9@gmail.com> | |||||
Date: Fri, 17 Jul 2015 21:59:42 +0200 | |||||
Subject: [PATCH 2/4] DOC: usesrc root privileges requirements | |||||
The "usesrc" parameter of the source statement requires root privileges. | |||||
(cherry picked from commit 91bd337d90cb347feda34b01402f3471c8a4833c) | |||||
--- | |||||
doc/configuration.txt | 2 ++ | |||||
1 file changed, 2 insertions(+) | |||||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||||
index 6714afb..64697a4 100644 | |||||
--- a/doc/configuration.txt | |||||
+++ b/doc/configuration.txt | |||||
@@ -6117,6 +6117,8 @@ source <addr>[:<port>] [interface <name>] | |||||
is possible at the server level using the "source" server option. Refer to | |||||
section 5 for more information. | |||||
+ In order to work, "usesrc" requires root privileges. | |||||
+ | |||||
Examples : | |||||
backend private | |||||
# Connect to the servers using our 192.168.1.200 source address | |||||
-- | |||||
2.3.6 | |||||
@ -0,0 +1,37 @@ | |||||
From ef8a113d59e89b2214adf7ab9f9b0b75905a7050 Mon Sep 17 00:00:00 2001 | |||||
From: lsenta <laurent.senta@gmail.com> | |||||
Date: Fri, 13 Nov 2015 10:44:22 +0100 | |||||
Subject: [PATCH 03/10] BUG: http: do not abort keep-alive connections on | |||||
server timeout | |||||
When a server timeout is detected on the second or nth request of a keep-alive | |||||
connection, HAProxy closes the connection without writing a response. | |||||
Some clients would fail with a remote disconnected exception and some | |||||
others would retry potentially unsafe requests. | |||||
This patch removes the special case and makes sure a 504 timeout is | |||||
written back whenever a server timeout is handled. | |||||
Signed-off-by: lsenta <laurent.senta@gmail.com> | |||||
(cherry picked from commit 1e1f41d0f3473d86da84dc3785b7d7cbef6e9044) | |||||
(cherry picked from commit 1f279c0b116f7fbc208793fffbd256c3c736fc52) | |||||
--- | |||||
src/proto_http.c | 2 -- | |||||
1 file changed, 2 deletions(-) | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index 17742c6..e7e1785 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -5782,8 +5782,6 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit) | |||||
else if (rep->flags & CF_READ_TIMEOUT) { | |||||
if (msg->err_pos >= 0) | |||||
http_capture_bad_message(&s->be->invalid_rep, s, msg, msg->msg_state, s->fe); | |||||
- else if (txn->flags & TX_NOT_FIRST) | |||||
- goto abort_keep_alive; | |||||
s->be->be_counters.failed_resp++; | |||||
if (objt_server(s->target)) { | |||||
-- | |||||
2.4.10 | |||||
@ -1,51 +0,0 @@ | |||||
From eee374c28ea8ea22834ff14515b5584bc3e0c7b5 Mon Sep 17 00:00:00 2001 | |||||
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Courr=C3=A8ges-Anglas?= <jca@wxcvbn.org> | |||||
Date: Sat, 25 Jul 2015 16:50:52 -0600 | |||||
Subject: [PATCH 3/4] BUILD: ssl: Allow building against libssl without SSLv3. | |||||
If SSLv3 is explicitely requested but not available, warn the user and | |||||
bail out. | |||||
(cherry picked from commit 17c3f6284cf605e47f6525c077bc644c45272849) | |||||
--- | |||||
src/ssl_sock.c | 16 ++++++++++++++-- | |||||
1 file changed, 14 insertions(+), 2 deletions(-) | |||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||||
index 7d77d36..2ae45ec 100644 | |||||
--- a/src/ssl_sock.c | |||||
+++ b/src/ssl_sock.c | |||||
@@ -1405,8 +1405,14 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy | |||||
ssloptions |= SSL_OP_NO_TLSv1_2; | |||||
if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS) | |||||
ssloptions |= SSL_OP_NO_TICKET; | |||||
- if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) | |||||
+ if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) { | |||||
+#ifndef OPENSSL_NO_SSL3 | |||||
SSL_CTX_set_ssl_version(ctx, SSLv3_server_method()); | |||||
+#else | |||||
+ Alert("SSLv3 support requested but unavailable.\n"); | |||||
+ cfgerr++; | |||||
+#endif | |||||
+ } | |||||
if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10) | |||||
SSL_CTX_set_ssl_version(ctx, TLSv1_server_method()); | |||||
#if SSL_OP_NO_TLSv1_1 | |||||
@@ -1750,8 +1756,14 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy) | |||||
options |= SSL_OP_NO_TLSv1_2; | |||||
if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS) | |||||
options |= SSL_OP_NO_TICKET; | |||||
- if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) | |||||
+ if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) { | |||||
+#ifndef OPENSSL_NO_SSL3 | |||||
SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method()); | |||||
+#else | |||||
+ Alert("SSLv3 support requested but unavailable."); | |||||
+ cfgerr++; | |||||
+#endif | |||||
+ } | |||||
if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10) | |||||
SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method()); | |||||
#if SSL_OP_NO_TLSv1_1 | |||||
-- | |||||
2.3.6 | |||||
@ -0,0 +1,112 @@ | |||||
From c0d56134320e507c82952f3d2a03f76b701945cb Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Wed, 18 Nov 2015 11:59:55 +0100 | |||||
Subject: [PATCH 04/10] BUG/MEDIUM: http: switch the request channel to | |||||
no-delay once done. | |||||
There's an issue when sending POST data that came in a second packet, | |||||
the CF_NEVER_WAIT flag is not always set on the request channel, while | |||||
the server is waiting for the request. We must always set this flag in | |||||
this case since we're not going to shut down after sending, contrary | |||||
to the response side. | |||||
Note that option http-no-delay works around this issue. | |||||
Reproducer : | |||||
listen px | |||||
mode http | |||||
timeout client 10s | |||||
timeout server 5s | |||||
timeout connect 3s | |||||
option http-server-close | |||||
#option http-no-delay | |||||
bind :8001 | |||||
server s1 127.0.0.1:8003 | |||||
$ (printf "POST / HTTP/1.1\r\nTransfer-encoding: chunked\r\n\r\n"; sleep 0.01; printf "10\r\nAZERTYUIOPQSDFGH\r\n0\r\n\r\n") | nc6 0 8001 | |||||
Before this fix : | |||||
12:03:31.946763 epoll_wait(3, {{EPOLLIN, {u32=5, u64=5}}}, 200, 1000) = 1 | |||||
12:03:32.634175 accept4(5, {sa_family=AF_INET, sin_port=htons(53849), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_NONBLOCK) = 6 | |||||
12:03:32.634318 setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 | |||||
12:03:32.634434 accept4(5, 0x7ffccfbb2cf0, [128], SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable) | |||||
12:03:32.634574 recvfrom(6, "POST / HTTP/1.1\r\nTransfer-encodi"..., 8192, 0, NULL, NULL) = 47 | |||||
12:03:32.634809 setsockopt(6, SOL_TCP, TCP_QUICKACK, [1], 4) = 0 | |||||
12:03:32.634952 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 7 | |||||
12:03:32.635031 fcntl(7, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 | |||||
12:03:32.635089 setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0 | |||||
12:03:32.635153 connect(7, {sa_family=AF_INET, sin_port=htons(8003), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) | |||||
12:03:32.635315 epoll_wait(3, {}, 200, 0) = 0 | |||||
12:03:32.635394 sendto(7, "POST / HTTP/1.1\r\nTransfer-encodi"..., 66, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 66 | |||||
12:03:32.635527 recvfrom(6, 0x7f0224e66024, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) | |||||
12:03:32.635651 epoll_ctl(3, EPOLL_CTL_ADD, 6, {EPOLLIN|0x2000, {u32=6, u64=6}}) = 0 | |||||
12:03:32.635782 epoll_wait(3, {}, 200, 0) = 0 | |||||
12:03:32.635842 recvfrom(7, 0x7f0224e66024, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) | |||||
12:03:32.635924 epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|0x2000, {u32=7, u64=7}}) = 0 | |||||
12:03:32.636027 epoll_wait(3, {{EPOLLIN, {u32=6, u64=6}}}, 200, 1000) = 1 | |||||
12:03:32.644892 recvfrom(6, "10\r\nAZERTYUIOPQSDFGH\r\n0\r\n\r\n", 8192, 0, NULL, NULL) = 27 | |||||
12:03:32.645016 epoll_wait(3, {}, 200, 0) = 0 | |||||
12:03:32.645105 sendto(7, "10\r\nAZERTYUIOPQSDFGH\r\n0\r\n\r\n", 27, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE, NULL, 0) = 27 | |||||
After the fix : | |||||
11:59:12.538617 connect(7, {sa_family=AF_INET, sin_port=htons(8003), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) | |||||
11:59:12.538787 epoll_wait(3, {}, 200, 0) = 0 | |||||
11:59:12.538867 sendto(7, "POST / HTTP/1.1\r\nTransfer-encodi"..., 66, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 66 | |||||
11:59:12.539031 recvfrom(6, 0x7f832ce45024, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) | |||||
11:59:12.539161 epoll_ctl(3, EPOLL_CTL_ADD, 6, {EPOLLIN|0x2000, {u32=6, u64=6}}) = 0 | |||||
11:59:12.539259 epoll_wait(3, {}, 200, 0) = 0 | |||||
11:59:12.539337 recvfrom(7, 0x7f832ce45024, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) | |||||
11:59:12.539421 epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|0x2000, {u32=7, u64=7}}) = 0 | |||||
11:59:12.539499 epoll_wait(3, {{EPOLLIN, {u32=6, u64=6}}}, 200, 1000) = 1 | |||||
11:59:12.548519 recvfrom(6, "10\r\nAZERTYUIOPQSDFGH\r\n0\r\n\r\n", 8192, 0, NULL, NULL) = 27 | |||||
11:59:12.548844 epoll_wait(3, {}, 200, 0) = 0 | |||||
11:59:12.549012 sendto(7, "10\r\nAZERTYUIOPQSDFGH\r\n0\r\n\r\n", 27, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 27 | |||||
11:59:12.549454 epoll_wait(3, {}, 200, 1000) = 0 | |||||
This fix must be backported to 1.6, 1.5 and 1.4. | |||||
(cherry picked from commit 7f876a1eeb14ffae708327aad8a0b4b029da5e26) | |||||
(cherry picked from commit 712a5339f384db62796aa4d4901e091dd7fd24dd) | |||||
--- | |||||
src/proto_http.c | 9 +++++++-- | |||||
1 file changed, 7 insertions(+), 2 deletions(-) | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index e7e1785..b32e778 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -5001,6 +5001,13 @@ int http_sync_req_state(struct session *s) | |||||
*/ | |||||
chn->cons->flags |= SI_FL_NOHALF; | |||||
+ /* In any case we've finished parsing the request so we must | |||||
+ * disable Nagle when sending data because 1) we're not going | |||||
+ * to shut this side, and 2) the server is waiting for us to | |||||
+ * send pending data. | |||||
+ */ | |||||
+ chn->flags |= CF_NEVER_WAIT; | |||||
+ | |||||
if (txn->rsp.msg_state == HTTP_MSG_ERROR) | |||||
goto wait_other_side; | |||||
@@ -5015,7 +5022,6 @@ int http_sync_req_state(struct session *s) | |||||
/* if any side switches to tunnel mode, the other one does too */ | |||||
channel_auto_read(chn); | |||||
txn->req.msg_state = HTTP_MSG_TUNNEL; | |||||
- chn->flags |= CF_NEVER_WAIT; | |||||
goto wait_other_side; | |||||
} | |||||
@@ -5048,7 +5054,6 @@ int http_sync_req_state(struct session *s) | |||||
if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) { | |||||
channel_auto_read(chn); | |||||
txn->req.msg_state = HTTP_MSG_TUNNEL; | |||||
- chn->flags |= CF_NEVER_WAIT; | |||||
} | |||||
} | |||||
-- | |||||
2.4.10 | |||||
@ -1,26 +0,0 @@ | |||||
From e4766ba031e1fea8f2ca139316dc4e8209e960c2 Mon Sep 17 00:00:00 2001 | |||||
From: Daniel Jakots <vigdis@chown.me> | |||||
Date: Wed, 29 Jul 2015 08:03:08 +0200 | |||||
Subject: [PATCH 4/4] DOC/MINOR: fix OpenBSD versions where haproxy works | |||||
(cherry picked from commit 17d228be14762b282e5262262c45ecee4c265552) | |||||
--- | |||||
README | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/README b/README | |||||
index add7f06..e267730 100644 | |||||
--- a/README | |||||
+++ b/README | |||||
@@ -39,7 +39,7 @@ and assign it to the TARGET variable : | |||||
- solaris for Solaris 8 or 10 (others untested) | |||||
- freebsd for FreeBSD 5 to 10 (others untested) | |||||
- osx for Mac OS/X | |||||
- - openbsd for OpenBSD 3.1 to 5.2 (others untested) | |||||
+ - openbsd for OpenBSD 3.1 and above | |||||
- aix51 for AIX 5.1 | |||||
- aix52 for AIX 5.2 | |||||
- cygwin for Cygwin | |||||
-- | |||||
2.3.6 | |||||
@ -1,33 +0,0 @@ | |||||
From 955587271031d66e9b7a768e3bb18dae00b60cc6 Mon Sep 17 00:00:00 2001 | |||||
From: Thierry FOURNIER <tfournier@arpalert.org> | |||||
Date: Wed, 8 Jul 2015 00:15:20 +0200 | |||||
Subject: [PATCH 05/13] BUG/MINOR: http/sample: gmtime/localtime can fail | |||||
The man said that gmtime() and localtime() can return a NULL value. | |||||
This is not tested. It appears that all the values of a 32 bit integer | |||||
are valid, but it is better to check the return of these functions. | |||||
However, if the integer move from 32 bits to 64 bits, some 64 values | |||||
can be unsupported. | |||||
(cherry picked from commit fac9ccfb705702f211f99e67d5f5d5129002086a) | |||||
[wt: we only have sample_conv_date() in 1.5] | |||||
--- | |||||
src/proto_http.c | 2 ++ | |||||
1 file changed, 2 insertions(+) | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index 5db64b5..02dc42b 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -11249,6 +11249,8 @@ static int sample_conv_http_date(const struct arg *args, struct sample *smp) | |||||
curr_date += args[0].data.sint; | |||||
tm = gmtime(&curr_date); | |||||
+ if (!tm) | |||||
+ return 0; | |||||
temp = get_trash_chunk(); | |||||
temp->len = snprintf(temp->str, temp->size - temp->len, | |||||
-- | |||||
2.4.6 | |||||
@ -0,0 +1,52 @@ | |||||
From e77015cdc18ab74aba61cdf57de56d06be5c2a4d Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Wed, 14 Jan 2015 11:48:58 +0100 | |||||
Subject: [PATCH 05/10] MINOR: config: extend the default max hostname length | |||||
to 64 and beyond | |||||
Some users reported that the default max hostname length of 32 is too | |||||
short in some environments. This patch does two things : | |||||
- it relies on the system's max hostname length as found in MAXHOSTNAMELEN | |||||
if it is set. This is the most logical thing to do as the system libs | |||||
generally present the appropriate value supported by the system. This | |||||
value is 64 on Linux and 256 on Solaris, to give a few examples. | |||||
- otherwise it defaults to 64 | |||||
It is still possible to override this value by defining MAX_HOSTNAME_LEN at | |||||
build time. After some observation time, this patch may be backported to | |||||
1.5 if it does not cause any build issue, as it is harmless and may help | |||||
some users. | |||||
(cherry picked from commit 75abcb3106e2c27ef983df885558cf94e01f717a) | |||||
Cc: Lukas Tribus <luky-37@hotmail.com> | |||||
Cc: jose.castro.leon@cern.ch | |||||
[wt: no issue reported so far and Jose rightfully asked for it in 1.5] | |||||
--- | |||||
include/common/defaults.h | 8 ++++++-- | |||||
1 file changed, 6 insertions(+), 2 deletions(-) | |||||
diff --git a/include/common/defaults.h b/include/common/defaults.h | |||||
index 0075509..a191b8a 100644 | |||||
--- a/include/common/defaults.h | |||||
+++ b/include/common/defaults.h | |||||
@@ -190,8 +190,12 @@ | |||||
/* Maximum host name length */ | |||||
#ifndef MAX_HOSTNAME_LEN | |||||
-#define MAX_HOSTNAME_LEN 32 | |||||
-#endif | |||||
+#if MAXHOSTNAMELEN | |||||
+#define MAX_HOSTNAME_LEN MAXHOSTNAMELEN | |||||
+#else | |||||
+#define MAX_HOSTNAME_LEN 64 | |||||
+#endif // MAXHOSTNAMELEN | |||||
+#endif // MAX_HOSTNAME_LEN | |||||
/* Maximum health check description length */ | |||||
#ifndef HCHK_DESC_LEN | |||||
-- | |||||
2.4.10 | |||||
@ -0,0 +1,49 @@ | |||||
From 3de8e7ab8d9125402cc1a8fb48ee475ee21d7d4c Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Wed, 25 Nov 2015 20:11:11 +0100 | |||||
Subject: [PATCH 06/10] BUG/MEDIUM: http: don't enable auto-close on the | |||||
response side | |||||
There is a bug where "option http-keep-alive" doesn't force a response | |||||
to stay in keep-alive if the server sends the FIN along with the response | |||||
on the second or subsequent response. The reason is that the auto-close | |||||
was forced enabled when recycling the HTTP transaction and it's never | |||||
disabled along the response processing chain before the SHUTR gets a | |||||
chance to be forwarded to the client side. The MSG_DONE state of the | |||||
HTTP response properly disables it but too late. | |||||
There's no more reason for enabling auto-close here, because either it | |||||
doesn't matter in non-keep-alive modes because the connection is closed, | |||||
or it is automatically enabled by process_stream() when it sees there's | |||||
no analyser on the stream. | |||||
This bug also affects 1.5 so a backport is desired. | |||||
(cherry picked from commit 714ea78c9a09fe6a35a1f2d86af8f7fc9abb64d1) | |||||
(cherry picked from commit a15091be17f27fcf4e3a84338df1a8b732e396a1) | |||||
--- | |||||
src/proto_http.c | 6 ++++-- | |||||
1 file changed, 4 insertions(+), 2 deletions(-) | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index b32e778..5facfbb 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -4946,11 +4946,13 @@ void http_end_txn_clean_session(struct session *s) | |||||
s->rep->flags |= CF_EXPECT_MORE; | |||||
} | |||||
- /* we're removing the analysers, we MUST re-enable events detection */ | |||||
+ /* we're removing the analysers, we MUST re-enable events detection. | |||||
+ * We don't enable close on the response channel since it's either | |||||
+ * already closed, or in keep-alive with an idle connection handler. | |||||
+ */ | |||||
channel_auto_read(s->req); | |||||
channel_auto_close(s->req); | |||||
channel_auto_read(s->rep); | |||||
- channel_auto_close(s->rep); | |||||
/* we're in keep-alive with an idle connection, monitor it */ | |||||
si_idle_conn(s->req->cons); | |||||
-- | |||||
2.4.10 | |||||
@ -1,27 +0,0 @@ | |||||
From 6c7351bdd0778bc171a2b54faed058eadc8c9d0d Mon Sep 17 00:00:00 2001 | |||||
From: Baptiste Assmann <bedis9@gmail.com> | |||||
Date: Mon, 3 Aug 2015 11:42:50 +0200 | |||||
Subject: [PATCH 06/13] DOC: typo in 'redirect', 302 code meaning | |||||
302 means a temprary move, not a permanent one | |||||
(cherry picked from commit ea849c0cca63b1b56c9c36f9c3504caa5e826816) | |||||
--- | |||||
doc/configuration.txt | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||||
index 64697a4..e8d8b2a 100644 | |||||
--- a/doc/configuration.txt | |||||
+++ b/doc/configuration.txt | |||||
@@ -5443,7 +5443,7 @@ redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>] | |||||
is desired. Only codes 301, 302, 303, 307 and 308 are supported, | |||||
with 302 used by default if no code is specified. 301 means | |||||
"Moved permanently", and a browser may cache the Location. 302 | |||||
- means "Moved permanently" and means that the browser should not | |||||
+ means "Moved temporarily" and means that the browser should not | |||||
cache the redirection. 303 is equivalent to 302 except that the | |||||
browser will fetch the location with a GET method. 307 is just | |||||
like 302 but makes it clear that the same method must be reused. | |||||
-- | |||||
2.4.6 | |||||
@ -0,0 +1,88 @@ | |||||
From 9154bc92ed11c6de75573dec341b6a0ce68bd0eb Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Wed, 25 Nov 2015 20:17:27 +0100 | |||||
Subject: [PATCH 07/10] BUG/MEDIUM: stream: fix half-closed timeout handling | |||||
client-fin and server-fin are bogus. They are applied on the write | |||||
side after a SHUTR was seen. The immediate effect is that sometimes | |||||
if a SHUTR was seen after a SHUTW on the same side, the timeout is | |||||
enabled again regardless of the fact that the output is already | |||||
closed. This results in the timeout event not to be processed and | |||||
a busy poll loop to happen until another timeout on the stream gets | |||||
rid of it. Note that haproxy continues its job during this, it's just | |||||
that it eats all the CPU trying to handle an event that it ignores. | |||||
An reproducible case consists in having a client stop reading data from | |||||
a server to ensure data remain in the response buffer, then the client | |||||
sends a shutdown(write). If abortonclose is enabled on haproxy, the | |||||
shutdown is passed to the server side and the server responds with a | |||||
SHUTR that cannot immediately be forwarded to the client since the | |||||
buffer is full. During this time the event is ignored and the task is | |||||
woken again in loops. | |||||
It is worth noting that the timeout handling since 1.5 is a bit fragile | |||||
and that it might be possible that other similar conditions still exist, | |||||
so the timeout handling should be audited regarding this issue. | |||||
Many thanks to BaiYang for providing detailed information showing the | |||||
problem in action. | |||||
This bug also affects 1.5 thus the fix must be backported. | |||||
(cherry picked from commit f25b3573d65fd2411c7537b7b0a4817b478df909) | |||||
[Note for 1.5, it's in session.c here] | |||||
(cherry picked from commit 44e86286159474a52dc74f80d3271504cc6f1550) | |||||
--- | |||||
src/session.c | 16 ---------------- | |||||
1 file changed, 16 deletions(-) | |||||
diff --git a/src/session.c b/src/session.c | |||||
index 7520a85..2b2ad78 100644 | |||||
--- a/src/session.c | |||||
+++ b/src/session.c | |||||
@@ -2213,10 +2213,6 @@ struct task *process_session(struct task *t) | |||||
if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) == | |||||
(CF_AUTO_CLOSE|CF_SHUTR))) { | |||||
channel_shutw_now(s->req); | |||||
- if (tick_isset(s->fe->timeout.clientfin)) { | |||||
- s->rep->wto = s->fe->timeout.clientfin; | |||||
- s->rep->wex = tick_add(now_ms, s->rep->wto); | |||||
- } | |||||
} | |||||
/* shutdown(write) pending */ | |||||
@@ -2241,10 +2237,6 @@ struct task *process_session(struct task *t) | |||||
if (s->req->prod->flags & SI_FL_NOHALF) | |||||
s->req->prod->flags |= SI_FL_NOLINGER; | |||||
si_shutr(s->req->prod); | |||||
- if (tick_isset(s->fe->timeout.clientfin)) { | |||||
- s->rep->wto = s->fe->timeout.clientfin; | |||||
- s->rep->wex = tick_add(now_ms, s->rep->wto); | |||||
- } | |||||
} | |||||
/* it's possible that an upper layer has requested a connection setup or abort. | |||||
@@ -2391,10 +2383,6 @@ struct task *process_session(struct task *t) | |||||
if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) == | |||||
(CF_AUTO_CLOSE|CF_SHUTR))) { | |||||
channel_shutw_now(s->rep); | |||||
- if (tick_isset(s->be->timeout.serverfin)) { | |||||
- s->req->wto = s->be->timeout.serverfin; | |||||
- s->req->wex = tick_add(now_ms, s->req->wto); | |||||
- } | |||||
} | |||||
/* shutdown(write) pending */ | |||||
@@ -2417,10 +2405,6 @@ struct task *process_session(struct task *t) | |||||
if (s->rep->prod->flags & SI_FL_NOHALF) | |||||
s->rep->prod->flags |= SI_FL_NOLINGER; | |||||
si_shutr(s->rep->prod); | |||||
- if (tick_isset(s->be->timeout.serverfin)) { | |||||
- s->req->wto = s->be->timeout.serverfin; | |||||
- s->req->wex = tick_add(now_ms, s->req->wto); | |||||
- } | |||||
} | |||||
if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS) | |||||
-- | |||||
2.4.10 | |||||
@ -1,27 +0,0 @@ | |||||
From c3453d53f2862b22d8c8e7d2399dfc38ec966aa4 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Sun, 9 Aug 2015 10:56:35 +0200 | |||||
Subject: [PATCH 07/13] DOC: mention that %ms is left-padded with zeroes. | |||||
That's important to emit logs. | |||||
(cherry picked from commit 812c88ec126e8fc4fc0f7853f265594d03c63956) | |||||
--- | |||||
doc/configuration.txt | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||||
index e8d8b2a..1d95b5b 100644 | |||||
--- a/doc/configuration.txt | |||||
+++ b/doc/configuration.txt | |||||
@@ -12381,7 +12381,7 @@ Please refer to the table below for currently defined variables : | |||||
| | %hrl | captured_request_headers CLF style | string list | | |||||
| | %hs | captured_response_headers default style | string | | |||||
| | %hsl | captured_response_headers CLF style | string list | | |||||
- | | %ms | accept date milliseconds | numeric | | |||||
+ | | %ms | accept date milliseconds (left-padded with 0) | numeric | | |||||
| | %pid | PID | numeric | | |||||
| H | %r | http_request | string | | |||||
| | %rc | retries | numeric | | |||||
-- | |||||
2.4.6 | |||||
@ -0,0 +1,36 @@ | |||||
From 07ccb48add8c8cb0dd8a0f7d3f4994866d0ef32e Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 26 Nov 2015 18:32:39 +0100 | |||||
Subject: [PATCH 08/10] BUG/MEDIUM: cli: changing compression rate-limiting | |||||
must require admin level | |||||
Right now it's possible to change the global compression rate limiting | |||||
without the CLI being at the admin level. | |||||
This fix must be backported to 1.6 and 1.5. | |||||
(cherry picked from commit a1c2b2c4f3e65d198a0a4b25a4f655f7b307a855) | |||||
(cherry picked from commit 9e5f1489c9f2d6926729890f249f7ebb9d3bfd43) | |||||
--- | |||||
src/dumpstats.c | 6 ++++++ | |||||
1 file changed, 6 insertions(+) | |||||
diff --git a/src/dumpstats.c b/src/dumpstats.c | |||||
index b4be2cd..b1bbf31 100644 | |||||
--- a/src/dumpstats.c | |||||
+++ b/src/dumpstats.c | |||||
@@ -1695,6 +1695,12 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) | |||||
if (strcmp(args[3], "global") == 0) { | |||||
int v; | |||||
+ if (s->listener->bind_conf->level < ACCESS_LVL_ADMIN) { | |||||
+ appctx->ctx.cli.msg = stats_permission_denied_msg; | |||||
+ appctx->st0 = STAT_CLI_PRINT; | |||||
+ return 1; | |||||
+ } | |||||
+ | |||||
if (!*args[4]) { | |||||
appctx->ctx.cli.msg = "Expects a maximum input byte rate in kB/s.\n"; | |||||
appctx->st0 = STAT_CLI_PRINT; | |||||
-- | |||||
2.4.10 | |||||
@ -1,50 +0,0 @@ | |||||
From 1104336c0ba5f474fce8fe7c0125511b59f4dd3d Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Tue, 11 Aug 2015 11:20:45 +0200 | |||||
Subject: [PATCH 08/13] CLEANUP: .gitignore: ignore more test files | |||||
Exclude from "git status" many of the files that often result from | |||||
development tests and bug reports reproducers. | |||||
(cherry picked from commit de365a320ead43168e78facfa337130759783515) | |||||
--- | |||||
.gitignore | 27 +++++++++++++++++++++++++++ | |||||
1 file changed, 27 insertions(+) | |||||
diff --git a/.gitignore b/.gitignore | |||||
index 762f5ad..f6ccd0e 100644 | |||||
--- a/.gitignore | |||||
+++ b/.gitignore | |||||
@@ -18,3 +18,30 @@ make-* | |||||
dlmalloc.c | |||||
00*.patch | |||||
*.service | |||||
+*.bak | |||||
+contrib/base64/base64rev | |||||
+contrib/halog/halog | |||||
+contrib/ip6range/ip6range | |||||
+contrib/iprange/iprange | |||||
+tests/test_hashes | |||||
+/*.cfg | |||||
+/*.conf | |||||
+/*.diff | |||||
+/*.patch | |||||
+/*.c | |||||
+/*.o | |||||
+/*.so | |||||
+/*.txt | |||||
+/*.TXT | |||||
+/*.txt.* | |||||
+/*.prof | |||||
+/*.gprof | |||||
+/*.prof.* | |||||
+/*.gprof.* | |||||
+/*.tar | |||||
+/*.tar.gz | |||||
+/*.tgz | |||||
+/*.mbox | |||||
+/*.sh | |||||
+/bug* | |||||
+/TAGS | |||||
-- | |||||
2.4.6 | |||||
@ -0,0 +1,31 @@ | |||||
From 97ef6f99b8426ffdc97864fc8bb2d85c87cfdad0 Mon Sep 17 00:00:00 2001 | |||||
From: Thierry FOURNIER <tfournier@arpalert.org> | |||||
Date: Tue, 3 Nov 2015 19:17:37 +0100 | |||||
Subject: [PATCH 09/10] BUILD: freebsd: double declaration | |||||
On freebsd, the macro LIST_PREV already exists in the header file | |||||
<sys/queue.h>, and this makes a build error. | |||||
This patch removes the macros before declaring it. This ensure | |||||
that the error doesn't occurs. | |||||
(cherry picked from commit 1db96672c4cd264ebca8197bec93a5ce1b23aaa9) | |||||
(cherry picked from commit 6cf9c6b270e57f05abf72cd61f4facb5b6980d57) | |||||
--- | |||||
include/common/mini-clist.h | 1 + | |||||
1 file changed, 1 insertion(+) | |||||
diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h | |||||
index 3c3f001..404b6fa 100644 | |||||
--- a/include/common/mini-clist.h | |||||
+++ b/include/common/mini-clist.h | |||||
@@ -144,6 +144,7 @@ struct cond_wordlist { | |||||
* which contains list head <lh>, which is known as element <el> in | |||||
* struct pt. | |||||
*/ | |||||
+#undef LIST_PREV | |||||
#define LIST_PREV(lh, pt, el) (LIST_ELEM((lh)->p, pt, el)) | |||||
/* | |||||
-- | |||||
2.4.10 | |||||
@ -1,44 +0,0 @@ | |||||
From 5e077624951a65e6aae381c7213fc54984768dd4 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Tue, 11 Aug 2015 11:21:47 +0200 | |||||
Subject: [PATCH 09/13] CLEANUP: .gitignore: finally ignore everything but what | |||||
is known. | |||||
Still too many files remain, it's easier to block everything but | |||||
what we know. | |||||
(cherry picked from commit d71f1766bdbb041f80394662b0d293f033f93005) | |||||
--- | |||||
.gitignore | 20 ++++++++++++++++++++ | |||||
1 file changed, 20 insertions(+) | |||||
diff --git a/.gitignore b/.gitignore | |||||
index f6ccd0e..1953ba3 100644 | |||||
--- a/.gitignore | |||||
+++ b/.gitignore | |||||
@@ -45,3 +45,23 @@ tests/test_hashes | |||||
/*.sh | |||||
/bug* | |||||
/TAGS | |||||
+# Below we forbid everything and only allow what we know, that's much easier | |||||
+# than blocking about 500 different test files and bug report outputs. | |||||
+/.* | |||||
+/* | |||||
+!/.gitignore | |||||
+!/CHANGELOG | |||||
+!/LICENSE | |||||
+!/Makefile | |||||
+!/README | |||||
+!/ROADMAP | |||||
+!/SUBVERS | |||||
+!/VERDATE | |||||
+!/VERSION | |||||
+!/contrib | |||||
+!/doc | |||||
+!/ebtree | |||||
+!/examples | |||||
+!/include | |||||
+!/src | |||||
+!/tests | |||||
-- | |||||
2.4.6 | |||||
@ -0,0 +1,53 @@ | |||||
From 0f836e1361933721c5689c7943143fd6cd260148 Mon Sep 17 00:00:00 2001 | |||||
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr> | |||||
Date: Thu, 26 Nov 2015 21:39:56 +0100 | |||||
Subject: [PATCH 10/10] BUG/MEDIUM: sample: urlp can't match an empty value | |||||
Currently urlp fetching samples were able to find parameters with an empty | |||||
value, but the return code depended on the value length. The final result was | |||||
that acls using urlp couldn't match empty values. | |||||
Example of acl which always returned "false": | |||||
acl MATCH_EMPTY urlp(foo) -m len 0 | |||||
The fix consists in unconditionally return 1 when the parameter is found. | |||||
This fix must be backported to 1.6 and 1.5. | |||||
(cherry picked from commit ce1ef4df0135f9dc1cb6691395eacb487015fe3e) | |||||
(cherry picked from commit 6bd426cf35c95985712369ed528c10a5f80ad8fd) | |||||
[ note: in 1.5 we have value+value_l instead of vstart+vend ] | |||||
--- | |||||
src/proto_http.c | 10 ++++++---- | |||||
1 file changed, 6 insertions(+), 4 deletions(-) | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index 5facfbb..3af7880 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -11050,9 +11050,11 @@ find_url_param_pos(char* query_string, size_t query_string_l, | |||||
} | |||||
/* | |||||
- * Given a url parameter name, returns its value and size into *value and | |||||
- * *value_l respectively, and returns non-zero. If the parameter is not found, | |||||
- * zero is returned and value/value_l are not touched. | |||||
+ * Given a url parameter name and a query string, find the next value. | |||||
+ * An empty url_param_name matches the first available parameter. | |||||
+ * If the parameter is found, 1 is returned and *value / *value_l are updated | |||||
+ * to respectively provide a pointer to the value and its length. | |||||
+ * Otherwise, 0 is returned and value/value_l are not modified. | |||||
*/ | |||||
static int | |||||
find_url_param_value(char* path, size_t path_l, | |||||
@@ -11082,7 +11084,7 @@ find_url_param_value(char* path, size_t path_l, | |||||
*value = value_start; | |||||
*value_l = value_end - value_start; | |||||
- return value_end != value_start; | |||||
+ return 1; | |||||
} | |||||
static int | |||||
-- | |||||
2.4.10 | |||||
@ -1,46 +0,0 @@ | |||||
From c7c1e55f09839727ba7defd37347fc500dabb202 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Tue, 11 Aug 2015 11:36:45 +0200 | |||||
Subject: [PATCH 10/13] MEDIUM: config: emit a warning on a frontend without | |||||
listener | |||||
Commit c6678e2 ("MEDIUM: config: authorize frontend and listen without bind") | |||||
completely removed the test for bind lines in frontends in order to make it | |||||
easier for automated tools to generate configs (eg: replacing a bind with | |||||
another one passing via a temporary config without any bind line). The | |||||
problem is that some common mistakes are totally hidden now. For example, | |||||
this apparently valid entry is silently ignored : | |||||
listen 1.2.3.4:8000 | |||||
server s1 127.0.0.1:8000 | |||||
Hint: 1.2.3.4:8000 is mistakenly the proxy name here. | |||||
Thus instead we now emit a warning to indicate that a frontend was found | |||||
with no listener. This should be backported to 1.5 to help spot abnormal | |||||
configurations. | |||||
(cherry picked from commit f82d1ca2d7ec83804d6b54e61a35747ad2f85188) | |||||
--- | |||||
src/cfgparse.c | 6 ++++++ | |||||
1 file changed, 6 insertions(+) | |||||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||||
index 2a5f178..d67edc5 100644 | |||||
--- a/src/cfgparse.c | |||||
+++ b/src/cfgparse.c | |||||
@@ -6193,6 +6193,12 @@ int check_config_validity() | |||||
break; | |||||
} | |||||
+ if ((curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) { | |||||
+ Warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n", | |||||
+ proxy_type_str(curproxy), curproxy->id); | |||||
+ err_code |= ERR_WARN; | |||||
+ } | |||||
+ | |||||
if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) { | |||||
if (curproxy->lbprm.algo & BE_LB_KIND) { | |||||
if (curproxy->options & PR_O_TRANSP) { | |||||
-- | |||||
2.4.6 | |||||
@ -1,93 +0,0 @@ | |||||
From ee12145d38a7dee81a20cf232c724ccb7a46ad8b Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Tue, 18 Aug 2015 17:15:20 +0200 | |||||
Subject: [PATCH 11/13] BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 | |||||
creates a missing entry | |||||
During 1.5-dev20 there was some code refactoring to make the src_* fetch | |||||
function use the same code as sc_*. Unfortunately this introduced a | |||||
regression where src_* doesn't create an entry anymore if it does not | |||||
exist in the table. The reason is that smp_fetch_sc_stkctr() only calls | |||||
stktable_lookup_key() while src_inc_*/src_clr_* used to make use of | |||||
stktable_update_key() which additionally create the entry if it does | |||||
not exist. | |||||
There's no point modifying the common function for these two exceptions, | |||||
so instead we now have a function dedicated to the creation of this entry | |||||
for src_* only. It is called when the entry didn't exist, so that requires | |||||
minimal modifications to existing code. | |||||
Thanks to Thierry Fournier for helping diagnose the issue. | |||||
This fix must be backported to 1.5. | |||||
(cherry picked from commit 0f4eadd4830279f5ee83aa545728fb750f5c8185) | |||||
[Note: the backport to 1.5 significantly differs from the version in 1.6 | |||||
since we need to use the table's type and to retrieve the source address | |||||
directly from the connection. At least it matches the way other src_* | |||||
fetch functions work, and it's been verified to work fine] | |||||
--- | |||||
src/session.c | 33 +++++++++++++++++++++++++++++++++ | |||||
1 file changed, 33 insertions(+) | |||||
diff --git a/src/session.c b/src/session.c | |||||
index 5b9e407..6d62e36 100644 | |||||
--- a/src/session.c | |||||
+++ b/src/session.c | |||||
@@ -2806,6 +2806,33 @@ smp_fetch_sc_stkctr(struct session *l4, const struct arg *args, const char *kw) | |||||
return &l4->stkctr[num]; | |||||
} | |||||
+/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create | |||||
+ * the entry if it doesn't exist yet. This is needed for a few fetch | |||||
+ * functions which need to create an entry, such as src_inc_gpc* and | |||||
+ * src_clr_gpc*. | |||||
+ */ | |||||
+struct stkctr * | |||||
+smp_create_src_stkctr(struct session *sess, const struct arg *args, const char *kw) | |||||
+{ | |||||
+ static struct stkctr stkctr; | |||||
+ struct stktable_key *key; | |||||
+ struct connection *conn = objt_conn(sess->si[0].end); | |||||
+ | |||||
+ if (strncmp(kw, "src_", 4) != 0) | |||||
+ return NULL; | |||||
+ | |||||
+ if (!conn) | |||||
+ return NULL; | |||||
+ | |||||
+ key = addr_to_stktable_key(&conn->addr.from, args->data.prx->table.type); | |||||
+ if (!key) | |||||
+ return NULL; | |||||
+ | |||||
+ stkctr.table = &args->data.prx->table; | |||||
+ stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key)); | |||||
+ return &stkctr; | |||||
+} | |||||
+ | |||||
/* set return a boolean indicating if the requested session counter is | |||||
* currently being tracked or not. | |||||
* Supports being called as "sc[0-9]_tracked" only. | |||||
@@ -2887,6 +2914,9 @@ smp_fetch_sc_inc_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned i | |||||
if (!stkctr) | |||||
return 0; | |||||
+ if (stkctr_entry(stkctr) == NULL) | |||||
+ stkctr = smp_create_src_stkctr(l4, args, kw); | |||||
+ | |||||
smp->flags = SMP_F_VOL_TEST; | |||||
smp->type = SMP_T_UINT; | |||||
smp->data.uint = 0; | |||||
@@ -2924,6 +2954,9 @@ smp_fetch_sc_clr_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned i | |||||
if (!stkctr) | |||||
return 0; | |||||
+ if (stkctr_entry(stkctr) == NULL) | |||||
+ stkctr = smp_create_src_stkctr(l4, args, kw); | |||||
+ | |||||
smp->flags = SMP_F_VOL_TEST; | |||||
smp->type = SMP_T_UINT; | |||||
smp->data.uint = 0; | |||||
-- | |||||
2.4.6 | |||||
@ -1,27 +0,0 @@ | |||||
From 2272b4ffde38c836adfd9a9b43ff5c019ef4190a Mon Sep 17 00:00:00 2001 | |||||
From: Thierry FOURNIER <tfournier@arpalert.org> | |||||
Date: Wed, 26 Aug 2015 08:21:26 +0200 | |||||
Subject: [PATCH 12/13] DOC: ssl: missing LF | |||||
An error message miss LF | |||||
(cherry picked from commit bc965348d7ccc0a306504232ab85dc240fd31fbf) | |||||
--- | |||||
src/ssl_sock.c | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||||
index 2ae45ec..8f698c0 100644 | |||||
--- a/src/ssl_sock.c | |||||
+++ b/src/ssl_sock.c | |||||
@@ -1760,7 +1760,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy) | |||||
#ifndef OPENSSL_NO_SSL3 | |||||
SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method()); | |||||
#else | |||||
- Alert("SSLv3 support requested but unavailable."); | |||||
+ Alert("SSLv3 support requested but unavailable.\n"); | |||||
cfgerr++; | |||||
#endif | |||||
} | |||||
-- | |||||
2.4.6 | |||||
@ -1,30 +0,0 @@ | |||||
From d3a93a932430bc1a4cd5d1350820c2bec706e26d Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 27 Aug 2015 17:15:05 +0200 | |||||
Subject: [PATCH 13/13] DOC: fix example of http-request using | |||||
ssl_fc_session_id | |||||
It was missing the ",hex" resulting in raw binary data being dumped in | |||||
the header or the logs. Now we know where these crazy logs originated | |||||
from! | |||||
(cherry picked from commit fca4261dacab51db960d30120f4bb4201f7e4a51) | |||||
--- | |||||
doc/configuration.txt | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||||
index 1d95b5b..67d273b 100644 | |||||
--- a/doc/configuration.txt | |||||
+++ b/doc/configuration.txt | |||||
@@ -3135,7 +3135,7 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> | | |||||
Example: | |||||
http-request set-header X-Haproxy-Current-Date %T | |||||
http-request set-header X-SSL %[ssl_fc] | |||||
- http-request set-header X-SSL-Session_ID %[ssl_fc_session_id] | |||||
+ http-request set-header X-SSL-Session_ID %[ssl_fc_session_id,hex] | |||||
http-request set-header X-SSL-Client-Verify %[ssl_c_verify] | |||||
http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn] | |||||
http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)] | |||||
-- | |||||
2.4.6 | |||||
@ -1,78 +0,0 @@ | |||||
From bcd033699c5a4904967652de4980e4f35f17ee34 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 3 Sep 2015 17:15:21 +0200 | |||||
Subject: [PATCH 14/16] BUG/MINOR: http: remove stupid HTTP_METH_NONE entry | |||||
When converting the "method" fetch to a string, we used to get an empty | |||||
string if the first character was not an upper case. This was caused by | |||||
the lookup function which returns HTTP_METH_NONE when a lookup is not | |||||
possible, and this method being mapped to an empty string in the array. | |||||
This is a totally stupid mechanism, there's no reason for having the | |||||
result depend on the first char. In fact the message parser already | |||||
checks that the syntax matches an HTTP token so we can only land there | |||||
with a valid token, hence only HTTP_METH_OTHER should be returned. | |||||
This fix should be backported to all actively supported branches. | |||||
(cherry picked from commit b7ce424be2bc9df73a3b971fa9dd6daea0332bf1) | |||||
--- | |||||
include/types/proto_http.h | 1 - | |||||
src/proto_http.c | 11 ++++------- | |||||
2 files changed, 4 insertions(+), 8 deletions(-) | |||||
diff --git a/include/types/proto_http.h b/include/types/proto_http.h | |||||
index a5a5d31..dbce972 100644 | |||||
--- a/include/types/proto_http.h | |||||
+++ b/include/types/proto_http.h | |||||
@@ -219,7 +219,6 @@ enum { | |||||
/* Known HTTP methods */ | |||||
enum http_meth_t { | |||||
- HTTP_METH_NONE = 0, | |||||
HTTP_METH_OPTIONS, | |||||
HTTP_METH_GET, | |||||
HTTP_METH_HEAD, | |||||
diff --git a/src/proto_http.c b/src/proto_http.c | |||||
index 02dc42b..46694cb 100644 | |||||
--- a/src/proto_http.c | |||||
+++ b/src/proto_http.c | |||||
@@ -361,12 +361,11 @@ const struct http_method_desc http_methods[26][3] = { | |||||
[0] = { .meth = HTTP_METH_TRACE , .len=5, .text="TRACE" }, | |||||
}, | |||||
/* rest is empty like this : | |||||
- * [1] = { .meth = HTTP_METH_NONE , .len=0, .text="" }, | |||||
+ * [0] = { .meth = HTTP_METH_OTHER , .len=0, .text="" }, | |||||
*/ | |||||
}; | |||||
const struct http_method_name http_known_methods[HTTP_METH_OTHER] = { | |||||
- [HTTP_METH_NONE] = { "", 0 }, | |||||
[HTTP_METH_OPTIONS] = { "OPTIONS", 7 }, | |||||
[HTTP_METH_GET] = { "GET", 3 }, | |||||
[HTTP_METH_HEAD] = { "HEAD", 4 }, | |||||
@@ -793,8 +792,8 @@ struct chunk *http_error_message(struct session *s, int msgnum) | |||||
} | |||||
/* | |||||
- * returns HTTP_METH_NONE if there is nothing valid to read (empty or non-text | |||||
- * string), HTTP_METH_OTHER for unknown methods, or the identified method. | |||||
+ * returns a known method among HTTP_METH_* or HTTP_METH_OTHER for all unknown | |||||
+ * ones. | |||||
*/ | |||||
enum http_meth_t find_http_meth(const char *str, const int len) | |||||
{ | |||||
@@ -810,10 +809,8 @@ enum http_meth_t find_http_meth(const char *str, const int len) | |||||
if (likely(memcmp(str, h->text, h->len) == 0)) | |||||
return h->meth; | |||||
}; | |||||
- return HTTP_METH_OTHER; | |||||
} | |||||
- return HTTP_METH_NONE; | |||||
- | |||||
+ return HTTP_METH_OTHER; | |||||
} | |||||
/* Parse the URI from the given transaction (which is assumed to be in request | |||||
-- | |||||
2.4.6 | |||||
@ -1,49 +0,0 @@ | |||||
From 3f34b5539e7ba31e44055d853b9ba496e73e0bae Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Mon, 7 Sep 2015 19:32:33 +0200 | |||||
Subject: [PATCH 15/16] BUG/MAJOR: http: don't call http_send_name_header() | |||||
after an error | |||||
A crash was reported when using the "famous" http-send-name-header | |||||
directive. This time it's a bit tricky, it requires a certain number of | |||||
conditions to be met including maxconn on a server, queuing, timeout in | |||||
the queue and cookie-based persistence. | |||||
The problem is that in stream.c, before calling http_send_name_header(), | |||||
we check a number of conditions to know if we have to replace the header | |||||
name. But prior to reaching this place, it's possible for | |||||
sess_update_stream_int() to fail and change the stream-int's state to | |||||
SI_ST_CLO, send an error 503 to the client, and flush all buffers. But | |||||
http_send_name_header() can only be called with valid buffer contents | |||||
matching the http_msg's description. So when it rewinds the stream to | |||||
modify the header, buf->o becomes negative by the size of the incoming | |||||
request and is used as the argument to memmove() which basically | |||||
displaces 4GB of memory off a few bytes to write the new name, resulting | |||||
in a core and a core file that's really not fun to play with. | |||||
The solution obviously consists in refraining from calling this nasty | |||||
function when the stream interface is already closed. | |||||
This bug also affects 1.5 and possibly 1.4, so the fix must be backported | |||||
there. | |||||
(cherry picked from commit 9c03b33329cb4924716edc1c851913a18b0670dc) | |||||
--- | |||||
src/session.c | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/src/session.c b/src/session.c | |||||
index 6d62e36..7520a85 100644 | |||||
--- a/src/session.c | |||||
+++ b/src/session.c | |||||
@@ -2293,7 +2293,7 @@ struct task *process_session(struct task *t) | |||||
/* Now we can add the server name to a header (if requested) */ | |||||
/* check for HTTP mode and proxy server_name_hdr_name != NULL */ | |||||
- if ((s->si[1].state >= SI_ST_CON) && | |||||
+ if ((s->si[1].state >= SI_ST_CON) && (s->si[1].state < SI_ST_CLO) && | |||||
(s->be->server_id_hdr_name != NULL) && | |||||
(s->be->mode == PR_MODE_HTTP) && | |||||
objt_server(s->target)) { | |||||
-- | |||||
2.4.6 | |||||
@ -1,36 +0,0 @@ | |||||
From 36456071ea34546d98d3b66a696cd4c4c4643de5 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Tue, 8 Sep 2015 16:01:25 +0200 | |||||
Subject: [PATCH 16/16] BUG/MINOR: tools: make str2sa_range() report | |||||
unresolvable addresses | |||||
If an environment variable is used in an address, and is not set, it's | |||||
silently considered as ":" or "0.0.0.0:0" which is not correct as it | |||||
can hide environment issues and lead to unexpected behaviours. Let's | |||||
report this case when it happens. | |||||
This fix should be backported to 1.5. | |||||
(cherry picked from commit 9f69f46d1f1b1d116c00b4b0483c519747f977b7) | |||||
--- | |||||
src/standard.c | 5 +++++ | |||||
1 file changed, 5 insertions(+) | |||||
diff --git a/src/standard.c b/src/standard.c | |||||
index f57724c..9299882 100644 | |||||
--- a/src/standard.c | |||||
+++ b/src/standard.c | |||||
@@ -709,6 +709,11 @@ struct sockaddr_storage *str2sa_range(const char *str, int *low, int *high, char | |||||
goto out; | |||||
} | |||||
+ if (!*str2) { | |||||
+ memprintf(err, "'%s' resolves to an empty address (environment variable missing?)\n", str); | |||||
+ goto out; | |||||
+ } | |||||
+ | |||||
memset(&ss, 0, sizeof(ss)); | |||||
if (strncmp(str2, "unix@", 5) == 0) { | |||||
-- | |||||
2.4.6 | |||||