Browse Source

haproxy: bump to version 1.5.2

- [RELEASE] Released version 1.5.2
 - [PATCH 1/2] DOC: mention that Squid correctly responds 400 to PPv2
 - [PATCH 2/2] DOC: fix typo in Unix Socket commands

Signed-off-by: Thomas Heil <heil@terminal-consulting.de>
lilik-openwrt-22.03
Thomas Heil 11 years ago
parent
commit
48438302f5
28 changed files with 61 additions and 2236 deletions
  1. +3
    -3
      net/haproxy/Makefile
  2. +0
    -45
      net/haproxy/patches/0001-BUG-MEDIUM-http-fetch-base-is-not-compatible-with-se.patch
  3. +29
    -0
      net/haproxy/patches/0001-DOC-mention-that-Squid-correctly-responds-400-to-PPv.patch
  4. +0
    -101
      net/haproxy/patches/0002-BUG-MINOR-ssl-Fix-external-function-in-order-not-to-.patch
  5. +29
    -0
      net/haproxy/patches/0002-DOC-fix-typo-in-Unix-Socket-commands.patch
  6. +0
    -42
      net/haproxy/patches/0003-BUG-MINOR-counters-do-not-untrack-counters-before-lo.patch
  7. +0
    -65
      net/haproxy/patches/0004-BUG-MAJOR-sample-correctly-reinitialize-sample-fetch.patch
  8. +0
    -109
      net/haproxy/patches/0005-MINOR-stick-table-make-stktable_fetch_key-indicate-w.patch
  9. +0
    -57
      net/haproxy/patches/0006-BUG-MEDIUM-counters-fix-track-sc-to-wait-on-unstable.patch
  10. +0
    -28
      net/haproxy/patches/0007-BUILD-remove-TODO-from-the-spec-file-and-add-README.patch
  11. +0
    -44
      net/haproxy/patches/0008-MINOR-log-make-MAX_SYSLOG_LEN-overridable-at-build-t.patch
  12. +0
    -360
      net/haproxy/patches/0009-MEDIUM-log-support-a-user-configurable-max-log-line-.patch
  13. +0
    -28
      net/haproxy/patches/0010-MINOR-stats-fix-minor-typo-in-HTML-page.patch
  14. +0
    -45
      net/haproxy/patches/0011-BUG-MEDIUM-unix-do-not-unlink-abstract-namespace-soc.patch
  15. +0
    -29
      net/haproxy/patches/0012-DOC-provide-an-example-of-how-to-use-ssl_c_sha1.patch
  16. +0
    -102
      net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch
  17. +0
    -32
      net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch
  18. +0
    -153
      net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch
  19. +0
    -124
      net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch
  20. +0
    -48
      net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch
  21. +0
    -71
      net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch
  22. +0
    -40
      net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch
  23. +0
    -198
      net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch
  24. +0
    -138
      net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch
  25. +0
    -75
      net/haproxy/patches/0022-DOC-minor-fix-on-sc-src-_kbytes_-in-out.patch
  26. +0
    -84
      net/haproxy/patches/0023-DOC-fix-alphabetical-sort-of-converters.patch
  27. +0
    -167
      net/haproxy/patches/0024-BUG-MAJOR-http-correctly-rewind-the-request-body-aft.patch
  28. +0
    -48
      net/haproxy/patches/0025-DOC-remove-references-to-CPU-native-in-the-README.patch

+ 3
- 3
net/haproxy/Makefile View File

@ -9,11 +9,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
PKG_VERSION:=1.5.1
PKG_RELEASE:=25
PKG_VERSION:=1.5.2
PKG_RELEASE:=02
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
PKG_MD5SUM:=49640cf3ddd793a05fbd3394481a1ed4
PKG_MD5SUM:=e854fed32ea751d6db7f366cb910225a
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
PKG_LICENSE:=GPL-2.0


+ 0
- 45
net/haproxy/patches/0001-BUG-MEDIUM-http-fetch-base-is-not-compatible-with-se.patch View File

@ -1,45 +0,0 @@
From c1fbbd4a3dd480b4eebbd8b32ca6cdf08791477a Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 24 Jun 2014 17:27:02 +0200
Subject: [PATCH] BUG/MEDIUM: http: fetch "base" is not compatible with
set-header
The sample fetch function "base" makes use of the trash which is also
used by set-header/add-header etc... everything which builds a formated
line. So we end up with some junk in the header if base is in use. Let's
fix this as all other fetches by using a trash chunk instead.
This bug was reported by Baptiste Assmann, and also affects 1.5.
(cherry picked from commit 3caf2afabe89fb0ef0886cd1d8ea99ef21ec3491)
---
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 231d49a..5321f7d 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -10247,6 +10247,7 @@ smp_fetch_base(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
struct http_txn *txn = l7;
char *ptr, *end, *beg;
struct hdr_ctx ctx;
+ struct chunk *temp;
CHECK_HTTP_MESSAGE_FIRST();
@@ -10255,9 +10256,10 @@ smp_fetch_base(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
return smp_fetch_path(px, l4, l7, opt, args, smp, kw);
/* OK we have the header value in ctx.line+ctx.val for ctx.vlen bytes */
- memcpy(trash.str, ctx.line + ctx.val, ctx.vlen);
+ temp = get_trash_chunk();
+ memcpy(temp->str, ctx.line + ctx.val, ctx.vlen);
smp->type = SMP_T_STR;
- smp->data.str.str = trash.str;
+ smp->data.str.str = temp->str;
smp->data.str.len = ctx.vlen;
/* now retrieve the path */
--
1.8.5.5

+ 29
- 0
net/haproxy/patches/0001-DOC-mention-that-Squid-correctly-responds-400-to-PPv.patch View File

@ -0,0 +1,29 @@
From a124eb6d7838eff2c52cc9bf027594c11e87fae9 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Sat, 12 Jul 2014 17:31:07 +0200
Subject: [PATCH 1/2] DOC: mention that Squid correctly responds 400 to PPv2
header
Amos reported that Squid builds 3.5.0.0_20140624 and 3.5.0.0_20140630
were confirmed to respond correctly here and that any version will do
the same.
(cherry picked from commit 9e1382002aa1ba12dcc637870befd077ff887aad)
---
doc/proxy-protocol.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/proxy-protocol.txt b/doc/proxy-protocol.txt
index a2dbcea..a3925a4 100644
--- a/doc/proxy-protocol.txt
+++ b/doc/proxy-protocol.txt
@@ -692,6 +692,7 @@ presented, even with minimal implementations :
- thttpd 2.20c : 400 Bad Request + abort => pass/optimal
- mini-httpd-1.19 : 400 Bad Request + abort => pass/optimal
- haproxy 1.4.21 : 400 Bad Request + abort => pass/optimal
+ - Squid 3 : 400 Bad Request + abort => pass/optimal
- SSL :
- stud 0.3.47 : connection abort => pass/optimal
- stunnel 4.45 : connection abort => pass/optimal
--
1.8.5.5

+ 0
- 101
net/haproxy/patches/0002-BUG-MINOR-ssl-Fix-external-function-in-order-not-to-.patch View File

@ -1,101 +0,0 @@
From 4910098653e356f814924663b4ddf71c971a71d6 Mon Sep 17 00:00:00 2001
From: Emeric Brun <ebrun@haproxy.com>
Date: Tue, 24 Jun 2014 18:26:41 +0200
Subject: [PATCH 2/6] BUG/MINOR: ssl: Fix external function in order not to
return a pointer on an internal trash buffer.
'ssl_sock_get_common_name' applied to a connection was also renamed
'ssl_sock_get_remote_common_name'. Currently, this function is only used
with protocol PROXYv2 to retrieve the client certificate's common name.
A further usage could be to retrieve the server certificate's common name
on an outgoing connection.
(cherry picked from commit 0abf836ecb32767fa1f9ad598f3e236e073491bd)
---
include/proto/ssl_sock.h | 2 +-
src/connection.c | 5 ++---
src/ssl_sock.c | 23 +++++++++++------------
3 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
index 0902fde..3e111cd 100644
--- a/include/proto/ssl_sock.h
+++ b/include/proto/ssl_sock.h
@@ -52,7 +52,7 @@ const char *ssl_sock_get_cipher_name(struct connection *conn);
const char *ssl_sock_get_proto_version(struct connection *conn);
char *ssl_sock_get_version(struct connection *conn);
int ssl_sock_get_cert_used(struct connection *conn);
-char *ssl_sock_get_common_name(struct connection *conn);
+int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *out);
unsigned int ssl_sock_get_verify_result(struct connection *conn);
#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err);
diff --git a/src/connection.c b/src/connection.c
index 0b154d8..20a911b 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -682,9 +682,8 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec
tlv->verify = htonl(ssl_sock_get_verify_result(remote));
}
if (srv->pp_opts & SRV_PP_V2_SSL_CN) {
- value = ssl_sock_get_common_name(remote);
- if (value) {
- tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, strlen(value), value);
+ if (ssl_sock_get_remote_common_name(remote, &trash) > 0) {
+ tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, trash.len, trash.str);
ssl_tlv_len += tlv_len;
}
}
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 328b978..375225d 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -2654,21 +2654,25 @@ char *ssl_sock_get_version(struct connection *conn)
return (char *)SSL_get_version(conn->xprt_ctx);
}
-/* returns common name, NULL terminated, from client certificate, or NULL if none */
-char *ssl_sock_get_common_name(struct connection *conn)
+/* Extract peer certificate's common name into the chunk dest
+ * Returns
+ * the len of the extracted common name
+ * or 0 if no CN found in DN
+ * or -1 on error case (i.e. no peer certificate)
+ */
+int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
{
X509 *crt = NULL;
X509_NAME *name;
- struct chunk *cn_trash;
const char find_cn[] = "CN";
const struct chunk find_cn_chunk = {
.str = (char *)&find_cn,
.len = sizeof(find_cn)-1
};
- char *result = NULL;
+ int result = -1;
if (!ssl_sock_is_ssl(conn))
- return NULL;
+ goto out;
/* SSL_get_peer_certificate, it increase X509 * ref count */
crt = SSL_get_peer_certificate(conn->xprt_ctx);
@@ -2679,13 +2683,8 @@ char *ssl_sock_get_common_name(struct connection *conn)
if (!name)
goto out;
- cn_trash = get_trash_chunk();
- if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
- goto out;
- cn_trash->str[cn_trash->len] = '\0';
- result = cn_trash->str;
-
- out:
+ result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
+out:
if (crt)
X509_free(crt);
--
1.8.5.5

+ 29
- 0
net/haproxy/patches/0002-DOC-fix-typo-in-Unix-Socket-commands.patch View File

@ -0,0 +1,29 @@
From de9789b37466c37547d8c5d52d96a9d4466eb431 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
Date: Sat, 12 Jul 2014 18:22:42 +0200
Subject: [PATCH 2/2] DOC: fix typo in Unix Socket commands
Konstantin Romanenko reported a typo in the HTML documentation. The typo is
already present in the raw text version : the "shutdown sessions" command
should be "shutdown sessions server".
(cherry picked from commit e63a1eb290a1c407453dbcaa16535c85a1904f9e)
---
doc/configuration.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index ca21f7d..2d71555 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -13869,7 +13869,7 @@ shutdown session <id>
endless transfer is ongoing. Such terminated sessions are reported with a 'K'
flag in the logs.
-shutdown sessions <backend>/<server>
+shutdown sessions server <backend>/<server>
Immediately terminate all the sessions attached to the specified server. This
can be used to terminate long-running sessions after a server is put into
maintenance mode, for instance. Such terminated sessions are reported with a
--
1.8.5.5

+ 0
- 42
net/haproxy/patches/0003-BUG-MINOR-counters-do-not-untrack-counters-before-lo.patch View File

@ -1,42 +0,0 @@
From c177ea7187bc1918a1900c1b0e3fc67c559987a2 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 25 Jun 2014 15:36:04 +0200
Subject: [PATCH 3/6] BUG/MINOR: counters: do not untrack counters before
logging
Baptiste Assmann reported a corner case in the releasing of stick-counters:
we release content-aware counters before logging. In the past it was not a
problem, but since now we can log them it, it prevents one from logging
their value. Simply switching the log production and the release of the
counter fixes the issue.
This should be backported into 1.5.
(cherry picked from commit d713bcc326da5d1ac80adab666d7710f3e37650c)
---
src/proto_http.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index 5321f7d..d566bcc 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4808,7 +4808,6 @@ void http_end_txn_clean_session(struct session *s)
s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
session_process_counters(s);
- session_stop_content_counters(s);
if (s->txn.status) {
int n;
@@ -4842,6 +4841,8 @@ void http_end_txn_clean_session(struct session *s)
s->do_log(s);
}
+ /* stop tracking content-based counters */
+ session_stop_content_counters(s);
session_update_time_stats(s);
s->logs.accept_date = date; /* user-visible date for logging */
--
1.8.5.5

+ 0
- 65
net/haproxy/patches/0004-BUG-MAJOR-sample-correctly-reinitialize-sample-fetch.patch View File

@ -1,65 +0,0 @@
From a4ba9dbfc688576ffb7e0a3ce43ac0b420211bf6 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 25 Jun 2014 16:56:41 +0200
Subject: [PATCH 4/6] BUG/MAJOR: sample: correctly reinitialize sample fetch
context before calling sample_process()
We used to only clear flags when reusing the static sample before calling
sample_process(), but that's not enough because there's a context in samples
that can be used by some fetch functions such as auth, headers and cookies,
and not reinitializing it risks that a pointer of a different type is used
in the wrong context.
An example configuration which triggers the case consists in mixing hdr()
and http_auth_group() which both make use of contexts :
http-request add-header foo2 %[hdr(host)],%[http_auth_group(foo)]
The solution is simple, initialize all the sample and not just the flags.
This fix must be backported into 1.5 since it was introduced in 1.5-dev19.
(cherry picked from commit 6c616e0b96106dd33d183afbda31e72799e967c3)
---
src/proto_http.c | 3 +++
src/sample.c | 5 +++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index d566bcc..01fe62d 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -9748,6 +9748,9 @@ smp_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
return 1;
}
+/* Note: these functinos *do* modify the sample. Even in case of success, at
+ * least the type and uint value are modified.
+ */
#define CHECK_HTTP_MESSAGE_FIRST() \
do { int r = smp_prefetch_http(px, l4, l7, opt, args, smp, 1); if (r <= 0) return r; } while (0)
diff --git a/src/sample.c b/src/sample.c
index 9f22ef9..3a0f3fb 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -905,7 +905,7 @@ struct sample *sample_process(struct proxy *px, struct session *l4, void *l7,
if (p == NULL) {
p = &temp_smp;
- p->flags = 0;
+ memset(p, 0, sizeof(*p));
}
if (!expr->fetch->process(px, l4, l7, opt, expr->arg_p, p, expr->fetch->kw))
@@ -1160,7 +1160,8 @@ struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l
{
struct sample *smp = &temp_smp;
- smp->flags = 0;
+ memset(smp, 0, sizeof(*smp));
+
if (!sample_process(px, l4, l7, opt, expr, smp)) {
if ((smp->flags & SMP_F_MAY_CHANGE) && !(opt & SMP_OPT_FINAL))
return smp;
--
1.8.5.5

+ 0
- 109
net/haproxy/patches/0005-MINOR-stick-table-make-stktable_fetch_key-indicate-w.patch View File

@ -1,109 +0,0 @@
From d008394057c4fe46ca6eb775c66cc0ff986a5495 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 25 Jun 2014 16:20:53 +0200
Subject: [PATCH 5/6] MINOR: stick-table: make stktable_fetch_key() indicate
why it failed
stktable_fetch_key() does not indicate whether it returns NULL because
the input sample was not found or because it's unstable. It causes trouble
with track-sc* rules. Just like with sample_fetch_string(), we want it to
be able to give more information to the caller about what it found. Thus,
now we use the pointer to a sample passed by the caller, and fill it with
the information we have about the sample. That way, even if we return NULL,
the caller has the ability to check whether a sample was found and if it is
still changing or not.
(cherry picked from commit b5975defba61e7ef37ae771614166d0970ede04e)
---
include/proto/stick_table.h | 2 +-
src/proto_tcp.c | 4 ++--
src/session.c | 4 ++--
src/stick_table.c | 12 +++++++-----
4 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h
index 0c26fbe..57ca223 100644
--- a/include/proto/stick_table.h
+++ b/include/proto/stick_table.h
@@ -48,7 +48,7 @@ struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key
struct stksess *stktable_update_key(struct stktable *table, struct stktable_key *key);
struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px,
struct session *l4, void *l7, unsigned int opt,
- struct sample_expr *expr);
+ struct sample_expr *expr, struct sample *smp);
int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_type);
int stktable_get_data_type(char *name);
struct proxy *find_stktable(const char *name);
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 65c4fda..1aac0d9 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1027,7 +1027,7 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
continue;
t = rule->act_prm.trk_ctr.table.t;
- key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr);
+ key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr, NULL);
if (key && (ts = stktable_get_entry(t, key))) {
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
@@ -1228,7 +1228,7 @@ int tcp_exec_req_rules(struct session *s)
continue;
t = rule->act_prm.trk_ctr.table.t;
- key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr);
+ key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr, NULL);
if (key && (ts = stktable_get_entry(t, key)))
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
diff --git a/src/session.c b/src/session.c
index e26f5ad..df85170 100644
--- a/src/session.c
+++ b/src/session.c
@@ -1458,7 +1458,7 @@ static int process_sticking_rules(struct session *s, struct channel *req, int an
if (ret) {
struct stktable_key *key;
- key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->expr);
+ key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->expr, NULL);
if (!key)
continue;
@@ -1561,7 +1561,7 @@ static int process_store_rules(struct session *s, struct channel *rep, int an_bi
if (ret) {
struct stktable_key *key;
- key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->expr);
+ key = stktable_fetch_key(rule->table.t, px, s, &s->txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->expr, NULL);
if (!key)
continue;
diff --git a/src/stick_table.c b/src/stick_table.c
index c6463ec..a708d3c 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -601,15 +601,17 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
* Process a fetch + format conversion as defined by the sample expression <expr>
* on request or response considering the <opt> parameter. Returns either NULL if
* no key could be extracted, or a pointer to the converted result stored in
- * static_table_key in format <table_type>.
+ * static_table_key in format <table_type>. If <smp> is not NULL, it will be reset
+ * and its flags will be initialized so that the caller gets a copy of the input
+ * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present).
*/
struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *l4, void *l7,
- unsigned int opt,
- struct sample_expr *expr)
+ unsigned int opt, struct sample_expr *expr, struct sample *smp)
{
- struct sample *smp;
+ if (smp)
+ memset(smp, 0, sizeof(*smp));
- smp = sample_process(px, l4, l7, opt, expr, NULL);
+ smp = sample_process(px, l4, l7, opt, expr, smp);
if (!smp)
return NULL;
--
1.8.5.5

+ 0
- 57
net/haproxy/patches/0006-BUG-MEDIUM-counters-fix-track-sc-to-wait-on-unstable.patch View File

@ -1,57 +0,0 @@
From 86bd33a9f842caf1788b61d1f99e95f8ad866660 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 25 Jun 2014 17:01:56 +0200
Subject: [PATCH 6/6] BUG/MEDIUM: counters: fix track-sc* to wait on unstable
contents
I've been facing multiple configurations which involved track-sc* rules
in tcp-request content without the "if ..." to force it to wait for the
contents, resulting in random behaviour with contents sometimes retrieved
and sometimes not.
Reading the doc doesn't make it clear either that the tracking will be
performed only if data are already there and that waiting on an ACL is
the only way to avoid this.
Since this behaviour is not natural and we now have the ability to fix
it, this patch ensures that if input data are still moving, instead of
silently dropping them, we naturally wait for them to stabilize up to
the inspect-delay. This way it's not needed anymore to implement an
ACL-based condition to force to wait for data, eventhough the behaviour
is not changed for when an ACL is present.
The most obvious usage will be when track-sc is followed by any HTTP
sample expression, there's no need anymore for adding "if HTTP".
It's probably worth backporting this to 1.5 to avoid further configuration
issues. Note that it requires previous patch.
(cherry picked from commit 1b71eb581ec1637879f725421efb95ad69f0ea4f)
---
src/proto_tcp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 1aac0d9..e9dbc9c 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1022,12 +1022,16 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
* applies.
*/
struct stktable_key *key;
+ struct sample smp;
if (stkctr_entry(&s->stkctr[tcp_trk_idx(rule->action)]))
continue;
t = rule->act_prm.trk_ctr.table.t;
- key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr, NULL);
+ key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.trk_ctr.expr, &smp);
+
+ if (smp.flags & SMP_F_MAY_CHANGE)
+ goto missing_data;
if (key && (ts = stktable_get_entry(t, key))) {
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
--
1.8.5.5

+ 0
- 28
net/haproxy/patches/0007-BUILD-remove-TODO-from-the-spec-file-and-add-README.patch View File

@ -1,28 +0,0 @@
From e726fd6571f684d0e92b8d97de8ca7a68d30f708 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 26 Jun 2014 08:20:38 +0200
Subject: [PATCH 7/9] BUILD: remove TODO from the spec file and add README
This used to cause a build failure since 1.5.0, as reported by
Timothy Shelton. The proxy protocol doc was also added.
(cherry picked from commit ca3094d0b1531ce62fc1970aa7396a01330bb5c1)
---
examples/haproxy.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/haproxy.spec b/examples/haproxy.spec
index 4ee3aa5..2fdb1a7 100644
--- a/examples/haproxy.spec
+++ b/examples/haproxy.spec
@@ -67,7 +67,7 @@ fi
%files
%defattr(-,root,root)
-%doc CHANGELOG TODO examples/*.cfg doc/haproxy-en.txt doc/haproxy-fr.txt doc/architecture.txt doc/configuration.txt
+%doc CHANGELOG README examples/*.cfg doc/haproxy-en.txt doc/haproxy-fr.txt doc/architecture.txt doc/configuration.txt doc/proxy-protocol.txt
%doc %{_mandir}/man1/%{name}.1*
%attr(0755,root,root) %{_sbindir}/%{name}
--
1.8.5.5

+ 0
- 44
net/haproxy/patches/0008-MINOR-log-make-MAX_SYSLOG_LEN-overridable-at-build-t.patch View File

@ -1,44 +0,0 @@
From b4cbc1e2227754ff384da1437e7d3448f91571b2 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 27 Jun 2014 18:08:49 +0200
Subject: [PATCH 8/9] MINOR: log: make MAX_SYSLOG_LEN overridable at build time
This value was set in log.h without any #ifndef around, so when one
wanted to change it, a patch was needed. Let's move it to defaults.h
with the usual #ifndef so that it's easier to change it.
(cherry picked from commit 4e957907aa117c07214ab84ba2a58f2fc1666931)
---
include/common/defaults.h | 4 ++++
include/types/log.h | 1 -
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/common/defaults.h b/include/common/defaults.h
index c53db08..0075509 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -48,6 +48,10 @@
#define CAPTURE_LEN 64
#endif
+#ifndef MAX_SYSLOG_LEN
+#define MAX_SYSLOG_LEN 1024
+#endif
+
// maximum line size when parsing config
#ifndef LINESIZE
#define LINESIZE 2048
diff --git a/include/types/log.h b/include/types/log.h
index 8ee8d7c..b3288bd 100644
--- a/include/types/log.h
+++ b/include/types/log.h
@@ -28,7 +28,6 @@
#include <common/config.h>
#include <common/mini-clist.h>
-#define MAX_SYSLOG_LEN 1024
#define NB_LOG_FACILITIES 24
#define NB_LOG_LEVELS 8
#define SYSLOG_PORT 514
--
1.8.5.5

+ 0
- 360
net/haproxy/patches/0009-MEDIUM-log-support-a-user-configurable-max-log-line-.patch View File

@ -1,360 +0,0 @@
From dc2695cc531bd7fc98f09df5f6e1e57290ab1a14 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 27 Jun 2014 18:10:07 +0200
Subject: [PATCH 9/9] MEDIUM: log: support a user-configurable max log line
length
With all the goodies supported by logformat, people find that the limit
of 1024 chars for log lines is too short. Some servers do not support
larger lines and can simply drop them, so changing the default value is
not always the best choice.
This patch takes a different approach. Log line length is specified per
log server on the "log" line, with a value between 80 and 65535. That
way it's possibly to satisfy all needs, even with some fat local servers
and small remote ones.
(cherry picked from commit 18324f574f349d510622ff45635de899437a3a11)
---
doc/configuration.txt | 28 ++++++++++++++++--
include/proto/log.h | 1 +
include/types/global.h | 1 +
include/types/log.h | 1 +
src/cfgparse.c | 80 ++++++++++++++++++++++++++++++++++++++++----------
src/log.c | 36 ++++++++++++++++-------
6 files changed, 118 insertions(+), 29 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 080d8fc..e53bb21 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -559,7 +559,7 @@ group <group name>
Similar to "gid" but uses the GID of group name <group name> from /etc/group.
See also "gid" and "user".
-log <address> <facility> [max level [min level]]
+log <address> [len <length>] <facility> [max level [min level]]
Adds a global syslog server. Up to two global servers can be defined. They
will receive logs for startups and exits, as well as all logs from proxies
configured with "log global".
@@ -584,6 +584,18 @@ log <address> <facility> [max level [min level]]
optionally enclosing them with braces ('{}'), similarly to what is done
in Bourne shell.
+ <length> is an optional maximum line length. Log lines larger than this value
+ will be truncated before being sent. The reason is that syslog
+ servers act differently on log line length. All servers support the
+ default value of 1024, but some servers simply drop larger lines
+ while others do log them. If a server supports long lines, it may
+ make sense to set this value here in order to avoid truncating long
+ lines. Similarly, if a server drops long lines, it is preferable to
+ truncate them before sending them. Accepted values are 80 to 65535
+ inclusive. The default value of 1024 is generally fine for all
+ standard usages. Some specific cases of long captures or
+ JSON-formated logs may require larger values.
+
<facility> must be one of the 24 standard syslog facilities :
kern user mail daemon auth syslog lpr news
@@ -3349,7 +3361,7 @@ ignore-persist { if | unless } <condition>
log global
-log <address> <facility> [<level> [<minlevel>]]
+log <address> [len <length>] <facility> [<level> [<minlevel>]]
no log
Enable per-instance logging of events and traffic.
May be used in sections : defaults | frontend | listen | backend
@@ -3389,6 +3401,18 @@ no log
sign ('$') and optionally enclosing them with braces ('{}'),
similarly to what is done in Bourne shell.
+ <length> is an optional maximum line length. Log lines larger than this
+ value will be truncated before being sent. The reason is that
+ syslog servers act differently on log line length. All servers
+ support the default value of 1024, but some servers simply drop
+ larger lines while others do log them. If a server supports long
+ lines, it may make sense to set this value here in order to avoid
+ truncating long lines. Similarly, if a server drops long lines,
+ it is preferable to truncate them before sending them. Accepted
+ values are 80 to 65535 inclusive. The default value of 1024 is
+ generally fine for all standard usages. Some specific cases of
+ long captures or JSON-formated logs may require larger values.
+
<facility> must be one of the 24 standard syslog facilities :
kern user mail daemon auth syslog lpr news
diff --git a/include/proto/log.h b/include/proto/log.h
index e3c1a75..54c51d1 100644
--- a/include/proto/log.h
+++ b/include/proto/log.h
@@ -39,6 +39,7 @@ extern char *log_format;
extern char default_tcp_log_format[];
extern char default_http_log_format[];
extern char clf_http_log_format[];
+extern char *logline;
int build_logline(struct session *s, char *dst, size_t maxsize, struct list *list_format);
diff --git a/include/types/global.h b/include/types/global.h
index 23e3f3d..77df1dd 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -110,6 +110,7 @@ struct global {
int last_checks;
int spread_checks;
int max_spread_checks;
+ int max_syslog_len;
char *chroot;
char *pidfile;
char *node, *desc; /* node name & description */
diff --git a/include/types/log.h b/include/types/log.h
index b3288bd..c7e47ea 100644
--- a/include/types/log.h
+++ b/include/types/log.h
@@ -152,6 +152,7 @@ struct logsrv {
int facility;
int level;
int minlvl;
+ int maxlen;
};
#endif /* _TYPES_LOG_H */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 762978a..e6e65b4 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1254,6 +1254,8 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
struct sockaddr_storage *sk;
int port1, port2;
struct logsrv *logsrv;
+ int arg = 0;
+ int len = 0;
if (*(args[1]) == 0 || *(args[2]) == 0) {
Alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
@@ -1263,28 +1265,50 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
logsrv = calloc(1, sizeof(struct logsrv));
- logsrv->facility = get_log_facility(args[2]);
+ /* just after the address, a length may be specified */
+ if (strcmp(args[arg+2], "len") == 0) {
+ len = atoi(args[arg+3]);
+ if (len < 80 || len > 65535) {
+ Alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
+ file, linenum, args[arg+3]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv->maxlen = len;
+
+ /* skip these two args */
+ arg += 2;
+ }
+ else
+ logsrv->maxlen = MAX_SYSLOG_LEN;
+
+ if (logsrv->maxlen > global.max_syslog_len) {
+ global.max_syslog_len = logsrv->maxlen;
+ logline = realloc(logline, global.max_syslog_len + 1);
+ }
+
+ logsrv->facility = get_log_facility(args[arg+2]);
if (logsrv->facility < 0) {
- Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
+ Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
err_code |= ERR_ALERT | ERR_FATAL;
logsrv->facility = 0;
}
logsrv->level = 7; /* max syslog level = debug */
- if (*(args[3])) {
- logsrv->level = get_log_level(args[3]);
+ if (*(args[arg+3])) {
+ logsrv->level = get_log_level(args[arg+3]);
if (logsrv->level < 0) {
- Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
+ Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
err_code |= ERR_ALERT | ERR_FATAL;
logsrv->level = 0;
}
}
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
- if (*(args[4])) {
- logsrv->minlvl = get_log_level(args[4]);
+ if (*(args[arg+4])) {
+ logsrv->minlvl = get_log_level(args[arg+4]);
if (logsrv->minlvl < 0) {
- Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
+ Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
err_code |= ERR_ALERT | ERR_FATAL;
logsrv->minlvl = 0;
}
@@ -4791,22 +4815,46 @@ stats_error_parsing:
else if (*(args[1]) && *(args[2])) {
struct sockaddr_storage *sk;
int port1, port2;
+ int arg = 0;
+ int len = 0;
logsrv = calloc(1, sizeof(struct logsrv));
- logsrv->facility = get_log_facility(args[2]);
+ /* just after the address, a length may be specified */
+ if (strcmp(args[arg+2], "len") == 0) {
+ len = atoi(args[arg+3]);
+ if (len < 80 || len > 65535) {
+ Alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
+ file, linenum, args[arg+3]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ logsrv->maxlen = len;
+
+ /* skip these two args */
+ arg += 2;
+ }
+ else
+ logsrv->maxlen = MAX_SYSLOG_LEN;
+
+ if (logsrv->maxlen > global.max_syslog_len) {
+ global.max_syslog_len = logsrv->maxlen;
+ logline = realloc(logline, global.max_syslog_len + 1);
+ }
+
+ logsrv->facility = get_log_facility(args[arg+2]);
if (logsrv->facility < 0) {
- Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
+ Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
logsrv->level = 7; /* max syslog level = debug */
- if (*(args[3])) {
- logsrv->level = get_log_level(args[3]);
+ if (*(args[arg+3])) {
+ logsrv->level = get_log_level(args[arg+3]);
if (logsrv->level < 0) {
- Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
+ Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
@@ -4814,10 +4862,10 @@ stats_error_parsing:
}
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
- if (*(args[4])) {
- logsrv->minlvl = get_log_level(args[4]);
+ if (*(args[arg+4])) {
+ logsrv->minlvl = get_log_level(args[arg+4]);
if (logsrv->minlvl < 0) {
- Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
+ Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
diff --git a/src/log.c b/src/log.c
index 114ab7b..3e3acb4 100644
--- a/src/log.c
+++ b/src/log.c
@@ -146,7 +146,7 @@ char *log_format = NULL;
/* This is a global syslog line, common to all outgoing messages. It begins
* with the syslog tag and the date that are updated by update_log_hdr().
*/
-static char logline[MAX_SYSLOG_LEN];
+char *logline = NULL;
struct logformat_var_args {
char *name;
@@ -736,7 +736,7 @@ static char *update_log_hdr()
tvsec = date.tv_sec;
get_localtime(tvsec, &tm);
- hdr_len = snprintf(logline, MAX_SYSLOG_LEN,
+ hdr_len = snprintf(logline, global.max_syslog_len,
"<<<<>%s %2d %02d:%02d:%02d %s%s[%d]: ",
monthname[tm.tm_mon],
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
@@ -746,8 +746,8 @@ static char *update_log_hdr()
* either -1 or the number of bytes that would be needed to store
* the total message. In both cases, we must adjust it.
*/
- if (hdr_len < 0 || hdr_len > MAX_SYSLOG_LEN)
- hdr_len = MAX_SYSLOG_LEN;
+ if (hdr_len < 0 || hdr_len > global.max_syslog_len)
+ hdr_len = global.max_syslog_len;
dataptr = logline + hdr_len;
}
@@ -772,9 +772,9 @@ void send_log(struct proxy *p, int level, const char *format, ...)
data_len = dataptr - logline;
va_start(argp, format);
- data_len += vsnprintf(dataptr, logline + sizeof(logline) - dataptr, format, argp);
- if (data_len < 0 || data_len > MAX_SYSLOG_LEN)
- data_len = MAX_SYSLOG_LEN;
+ data_len += vsnprintf(dataptr, logline + global.max_syslog_len - dataptr, format, argp);
+ if (data_len < 0 || data_len > global.max_syslog_len)
+ data_len = global.max_syslog_len;
va_end(argp);
__send_log(p, level, logline, data_len);
@@ -811,8 +811,6 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
if (!logsrvs)
return;
- message[size - 1] = '\n';
-
/* Send log messages to syslog server. */
nblogger = 0;
list_for_each_entry(tmp, logsrvs, list) {
@@ -820,6 +818,8 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
&logfdunix : &logfdinet;
int sent;
+ int max;
+ char backup;
nblogger++;
@@ -858,9 +858,23 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
} while (fac_level && log_ptr > dataptr);
*log_ptr = '<';
- sent = sendto(*plogfd, log_ptr, size - (log_ptr - dataptr),
+ max = size - (log_ptr - dataptr);
+ if (max > logsrv->maxlen)
+ max = logsrv->maxlen;
+
+ /* insert a \n at the end of the message, but save what was
+ * there first because we could have different max lengths
+ * for different log targets.
+ */
+ backup = log_ptr[max - 1];
+ log_ptr[max - 1] = '\n';
+
+ sent = sendto(*plogfd, log_ptr, max,
MSG_DONTWAIT | MSG_NOSIGNAL,
(struct sockaddr *)&logsrv->addr, get_addr_len(&logsrv->addr));
+
+ log_ptr[max - 1] = backup;
+
if (sent < 0) {
Alert("sendto logger #%d failed: %s (errno=%d)\n",
nblogger, strerror(errno), errno);
@@ -1604,7 +1618,7 @@ void sess_log(struct session *s)
tmplog = update_log_hdr();
size = tmplog - logline;
- size += build_logline(s, tmplog, sizeof(logline) - size, &s->fe->logformat);
+ size += build_logline(s, tmplog, global.max_syslog_len - size, &s->fe->logformat);
if (size > 0) {
__send_log(s->fe, level, logline, size + 1);
s->logs.logwait = 0;
--
1.8.5.5

+ 0
- 28
net/haproxy/patches/0010-MINOR-stats-fix-minor-typo-in-HTML-page.patch View File

@ -1,28 +0,0 @@
From d38f5c0c1cbba00d80cad2640c005794fa5bc4f9 Mon Sep 17 00:00:00 2001
From: Marco Corte <marco@marcocorte.it>
Date: Wed, 2 Jul 2014 17:49:34 +0200
Subject: [PATCH 10/12] MINOR: stats: fix minor typo in HTML page
There is a very small typo in the statistics interface: a "set" in
lowercase where allothers are uppercase "Set".
(cherry picked from commit 8c27bcaea0116247ee055c5481a63507de4fe6e4)
---
src/dumpstats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dumpstats.c b/src/dumpstats.c
index c8bac08..5365042 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -3710,7 +3710,7 @@ static void stats_dump_html_px_end(struct stream_interface *si, struct proxy *px
"<option value=\"\"></option>"
"<option value=\"ready\">Set state to READY</option>"
"<option value=\"drain\">Set state to DRAIN</option>"
- "<option value=\"maint\">set state to MAINT</option>"
+ "<option value=\"maint\">Set state to MAINT</option>"
"<option value=\"dhlth\">Health: disable checks</option>"
"<option value=\"ehlth\">Health: enable checks</option>"
"<option value=\"hrunn\">Health: force UP</option>"
--
1.8.5.5

+ 0
- 45
net/haproxy/patches/0011-BUG-MEDIUM-unix-do-not-unlink-abstract-namespace-soc.patch View File

@ -1,45 +0,0 @@
From 76ad998e2b6ae852567ff53edb84a0b467c0c9cb Mon Sep 17 00:00:00 2001
From: Jan Seda <hodor@hodor.cz>
Date: Thu, 26 Jun 2014 20:44:05 +0200
Subject: [PATCH 11/12] BUG/MEDIUM: unix: do not unlink() abstract namespace
sockets upon failure.
When bind() fails (function uxst_bind_listener()), the fail path doesn't
consider the abstract namespace and tries to unlink paths held in
uninitiliazed memory (tempname and backname). See the strace excerpt;
the strings still hold the path from test1.
===============================================================================================
23722 bind(5, {sa_family=AF_FILE, path=@"test2"}, 110) = -1 EADDRINUSE (Address already in use)
23722 unlink("/tmp/test1.sock.23722.tmp") = -1 ENOENT (No such file or directory)
23722 close(5) = 0
23722 unlink("/tmp/test1.sock.23722.bak") = -1 ENOENT (No such file or directory)
===============================================================================================
This patch should be backported to 1.5.
(cherry picked from commit 7319b64fc4c9b7e04726816c6cc02f6ecf66a0a4)
---
src/proto_uxst.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index f83d34e..c9a52ff 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -309,11 +309,11 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
if (ret < 0 && errno == ENOENT)
unlink(path);
err_unlink_temp:
- if (!ext)
+ if (!ext && path[0])
unlink(tempname);
close(fd);
err_unlink_back:
- if (!ext)
+ if (!ext && path[0])
unlink(backname);
err_return:
if (msg && errlen) {
--
1.8.5.5

+ 0
- 29
net/haproxy/patches/0012-DOC-provide-an-example-of-how-to-use-ssl_c_sha1.patch View File

@ -1,29 +0,0 @@
From 9fe4cb64cd9514a72bcd4b2fd8781620da9e1f76 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 2 Jul 2014 19:01:22 +0200
Subject: [PATCH 12/12] DOC: provide an example of how to use ssl_c_sha1
As suggested by Aydan Yumerefendi, a little bit of examples never hurts.
(cherry picked from commit 2d0caa38e040b081903e50faa56bae52599b3949)
---
doc/configuration.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index e53bb21..fcc6454 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10722,6 +10722,10 @@ ssl_c_sha1 : binary
Returns the SHA-1 fingerprint of the certificate presented by the client when
the incoming connection was made over an SSL/TLS transport layer. This can be
used to stick a client to a server, or to pass this information to a server.
+ Note that the output is binary, so if you want to pass that signature to the
+ server, you need to encode it in hex or base64, such as in the example below:
+
+ http-request set-header X-SSL-Client-SHA1 %[ssl_c_sha1,hex]
ssl_c_sig_alg : string
Returns the name of the algorithm used to sign the certificate presented by
--
1.8.5.5

+ 0
- 102
net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch View File

@ -1,102 +0,0 @@
From 463ae6f09e485faf3d1cdc4daceefe4bcd50b50e Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 8 Jul 2014 00:59:48 +0200
Subject: [PATCH 13/21] BUILD: http: fix isdigit & isspace warnings on Solaris
As usual, when touching any is* function, Solaris complains about the
type of the element being checked. Better backport this to 1.5 since
nobody knows what the emitted code looks like since macros are used
instead of functions.
(cherry picked from commit 506c69a50e8d434b6b0c2c89b0402f220830644d)
---
src/proto_http.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index 01fe62d..4a862b0 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2143,22 +2143,22 @@ int parse_qvalue(const char *qvalue, const char **end)
{
int q = 1000;
- if (!isdigit(*qvalue))
+ if (!isdigit((unsigned char)*qvalue))
goto out;
q = (*qvalue++ - '0') * 1000;
if (*qvalue++ != '.')
goto out;
- if (!isdigit(*qvalue))
+ if (!isdigit((unsigned char)*qvalue))
goto out;
q += (*qvalue++ - '0') * 100;
- if (!isdigit(*qvalue))
+ if (!isdigit((unsigned char)*qvalue))
goto out;
q += (*qvalue++ - '0') * 10;
- if (!isdigit(*qvalue))
+ if (!isdigit((unsigned char)*qvalue))
goto out;
q += (*qvalue++ - '0') * 1;
out:
@@ -11226,7 +11226,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
while (1) {
/* Jump spaces, quit if the end is detected. */
- while (al < end && isspace(*al))
+ while (al < end && isspace((unsigned char)*al))
al++;
if (al >= end)
break;
@@ -11235,7 +11235,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
token = al;
/* Look for separator: isspace(), ',' or ';'. Next value if 0 length word. */
- while (al < end && *al != ';' && *al != ',' && !isspace(*al))
+ while (al < end && *al != ';' && *al != ',' && !isspace((unsigned char)*al))
al++;
if (al == token)
goto expect_comma;
@@ -11264,7 +11264,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
look_for_q:
/* Jump spaces, quit if the end is detected. */
- while (al < end && isspace(*al))
+ while (al < end && isspace((unsigned char)*al))
al++;
if (al >= end)
goto process_value;
@@ -11283,7 +11283,7 @@ look_for_q:
al++;
/* Jump spaces, process value if the end is detected. */
- while (al < end && isspace(*al))
+ while (al < end && isspace((unsigned char)*al))
al++;
if (al >= end)
goto process_value;
@@ -11294,7 +11294,7 @@ look_for_q:
al++;
/* Jump spaces, process value if the end is detected. */
- while (al < end && isspace(*al))
+ while (al < end && isspace((unsigned char)*al))
al++;
if (al >= end)
goto process_value;
@@ -11305,7 +11305,7 @@ look_for_q:
al++;
/* Jump spaces, process value if the end is detected. */
- while (al < end && isspace(*al))
+ while (al < end && isspace((unsigned char)*al))
al++;
if (al >= end)
goto process_value;
--
1.8.5.5

+ 0
- 32
net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch View File

@ -1,32 +0,0 @@
From fb8bf6324bfe9f36d0be5110fcc13facba4389a8 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 7 Jul 2014 18:24:48 +0200
Subject: [PATCH 14/21] BUG/MINOR: listener: set the listener's fd to -1 after
deletion
This is currently harmless, but when stopping a listener, its fd is
closed but not set to -1, so it is not possible to re-open it again.
Currently this has no impact but can have after the abstract sockets
are modified to perform a complete close on soft-reload.
The fix can be backported to 1.5 and may even apply to 1.4 (protocols.c).
(cherry picked from commit 39447b6a5799a160eae452db920fd0735a78638b)
---
src/listener.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/listener.c b/src/listener.c
index ec3a39b..a82ce81 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -236,6 +236,7 @@ int unbind_listener(struct listener *listener)
if (listener->state >= LI_PAUSED) {
fd_delete(listener->fd);
+ listener->fd = -1;
listener->state = LI_ASSIGNED;
}
return ERR_NONE;
--
1.8.5.5

+ 0
- 153
net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch View File

@ -1,153 +0,0 @@
From 58dd0f33fa908e83199d28775bad8ee2f24151a9 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 7 Jul 2014 18:36:45 +0200
Subject: [PATCH 15/21] BUG/MEDIUM: unix: failed abstract socket binding is
retryable
Jan Seda noticed that abstract sockets are incompatible with soft reload,
because the new process cannot bind and immediately fails. This patch marks
the binding as retryable and not fatal so that the new process can try to
bind again after sending a signal to the old process.
Note that this fix is not enough to completely solve the problem, but it
is necessary. This patch should be backported to 1.5.
(cherry picked from commit 3c5efa2b3268f31cffc2c18887010d4bc906a066)
---
src/proto_uxst.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index c9a52ff..409c659 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -166,9 +166,11 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
const char *path;
int ext, ready;
socklen_t ready_len;
-
+ int err;
int ret;
+ err = ERR_NONE;
+
/* ensure we never return garbage */
if (errlen)
*errmsg = 0;
@@ -191,29 +193,34 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
if (path[0]) {
ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
if (ret < 0 || ret >= MAXPATHLEN) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "name too long for UNIX socket";
goto err_return;
}
ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
if (ret < 0 || ret >= MAXPATHLEN) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "name too long for UNIX socket";
goto err_return;
}
/* 2. clean existing orphaned entries */
if (unlink(tempname) < 0 && errno != ENOENT) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "error when trying to unlink previous UNIX socket";
goto err_return;
}
if (unlink(backname) < 0 && errno != ENOENT) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "error when trying to unlink previous UNIX socket";
goto err_return;
}
/* 3. backup existing socket */
if (link(path, backname) < 0 && errno != ENOENT) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "error when trying to preserve previous UNIX socket";
goto err_return;
}
@@ -231,24 +238,35 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "cannot create UNIX socket";
goto err_unlink_back;
}
fd_ready:
if (fd >= global.maxsock) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "socket(): not enough free sockets, raise -n argument";
goto err_unlink_temp;
}
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "cannot make UNIX socket non-blocking";
goto err_unlink_temp;
}
if (!ext && bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
/* note that bind() creates the socket <tempname> on the file system */
- msg = "cannot bind UNIX socket";
+ if (errno == EADDRINUSE) {
+ /* the old process might still own it, let's retry */
+ err |= ERR_RETRYABLE | ERR_ALERT;
+ msg = "cannot listen to socket";
+ }
+ else {
+ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot bind UNIX socket";
+ }
goto err_unlink_temp;
}
@@ -261,6 +279,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
(((listener->bind_conf->ux.uid != -1 || listener->bind_conf->ux.gid != -1) &&
(chown(tempname, listener->bind_conf->ux.uid, listener->bind_conf->ux.gid) == -1)) ||
(listener->bind_conf->ux.mode != 0 && chmod(tempname, listener->bind_conf->ux.mode) == -1))) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "cannot change UNIX socket ownership";
goto err_unlink_temp;
}
@@ -272,6 +291,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
if (!(ext && ready) && /* only listen if not already done by external process */
listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "cannot listen to UNIX socket";
goto err_unlink_temp;
}
@@ -281,6 +301,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
* backname. Abstract sockets are not renamed.
*/
if (!ext && path[0] && rename(tempname, path) < 0) {
+ err |= ERR_FATAL | ERR_ALERT;
msg = "cannot switch final and temporary UNIX sockets";
goto err_rename;
}
@@ -303,7 +324,8 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
fd_insert(fd);
fdtab[fd].iocb = listener->proto->accept;
fdtab[fd].owner = listener; /* reference the listener instead of a task */
- return ERR_NONE;
+ return err;
+
err_rename:
ret = rename(backname, path);
if (ret < 0 && errno == ENOENT)
@@ -322,7 +344,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
else
snprintf(errmsg, errlen, "%s [fd %d]", msg, fd);
}
- return ERR_FATAL | ERR_ALERT;
+ return err;
}
/* This function closes the UNIX sockets for the specified listener.
--
1.8.5.5

+ 0
- 124
net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch View File

@ -1,124 +0,0 @@
From d903bb345dcf6ed058ccf84f476f066b3dc08d47 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 7 Jul 2014 20:22:12 +0200
Subject: [PATCH 16/21] MEDIUM: listener: implement a per-protocol pause()
function
In order to fix the abstact socket pause mechanism during soft restarts,
we'll need to proceed differently depending on the socket protocol. The
pause_listener() function already supports some protocol-specific handling
for the TCP case.
This commit makes this cleaner by adding a new ->pause() function to the
protocol struct, which, if defined, may be used to pause a listener of a
given protocol.
For now, only TCP has been adapted, with the specific code moved from
pause_listener() to tcp_pause_listener().
(cherry picked from commit 092d865c53de80afc847c5ff0a079b414041ce2a)
---
include/proto/proto_tcp.h | 1 +
include/types/protocol.h | 1 +
src/listener.c | 17 +++++++++--------
src/proto_tcp.c | 18 ++++++++++++++++++
4 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h
index 4adf4d2..ac8b711 100644
--- a/include/proto/proto_tcp.h
+++ b/include/proto/proto_tcp.h
@@ -30,6 +30,7 @@
int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
void tcpv4_add_listener(struct listener *listener);
void tcpv6_add_listener(struct listener *listener);
+int tcp_pause_listener(struct listener *l);
int tcp_connect_server(struct connection *conn, int data, int delack);
int tcp_connect_probe(struct connection *conn);
int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
diff --git a/include/types/protocol.h b/include/types/protocol.h
index e03692a..74b20e8 100644
--- a/include/types/protocol.h
+++ b/include/types/protocol.h
@@ -60,6 +60,7 @@ struct protocol {
int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
int (*drain)(int fd); /* indicates whether we can safely close the fd */
+ int (*pause)(struct listener *l); /* temporarily pause this listener for a soft restart */
struct list listeners; /* list of listeners using this protocol */
int nb_listeners; /* number of listeners */
diff --git a/src/listener.c b/src/listener.c
index a82ce81..67f8ca7 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -95,15 +95,16 @@ int pause_listener(struct listener *l)
if (l->state <= LI_PAUSED)
return 1;
- if (l->proto->sock_prot == IPPROTO_TCP) {
- if (shutdown(l->fd, SHUT_WR) != 0)
- return 0; /* Solaris dies here */
-
- if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
- return 0; /* OpenBSD dies here */
+ if (l->proto->pause) {
+ /* Returns < 0 in case of failure, 0 if the listener
+ * was totally stopped, or > 0 if correctly paused.
+ */
+ int ret = l->proto->pause(l);
- if (shutdown(l->fd, SHUT_RD) != 0)
- return 0; /* should always be OK */
+ if (ret < 0)
+ return 0;
+ else if (ret == 0)
+ return 1;
}
if (l->state == LI_LIMITED)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index e9dbc9c..9778856 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -80,6 +80,7 @@ static struct protocol proto_tcpv4 = {
.get_src = tcp_get_src,
.get_dst = tcp_get_dst,
.drain = tcp_drain,
+ .pause = tcp_pause_listener,
.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
.nb_listeners = 0,
};
@@ -102,6 +103,7 @@ static struct protocol proto_tcpv6 = {
.get_src = tcp_get_src,
.get_dst = tcp_get_dst,
.drain = tcp_drain,
+ .pause = tcp_pause_listener,
.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
.nb_listeners = 0,
};
@@ -947,6 +949,22 @@ void tcpv6_add_listener(struct listener *listener)
proto_tcpv6.nb_listeners++;
}
+/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
+ * was totally stopped, or > 0 if correctly paused.
+ */
+int tcp_pause_listener(struct listener *l)
+{
+ if (shutdown(l->fd, SHUT_WR) != 0)
+ return -1; /* Solaris dies here */
+
+ if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
+ return -1; /* OpenBSD dies here */
+
+ if (shutdown(l->fd, SHUT_RD) != 0)
+ return -1; /* should always be OK */
+ return 1;
+}
+
/* This function performs the TCP request analysis on the current request. It
* returns 1 if the processing can continue on next analysers, or zero if it
* needs more data, encounters an error, or wants to immediately abort the
--
1.8.5.5

+ 0
- 48
net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch View File

@ -1,48 +0,0 @@
From ff12090bf067a1ddd56bed14cf27371cdf2e77cb Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 7 Jul 2014 21:06:24 +0200
Subject: [PATCH 17/21] MEDIUM: listener: support rebinding during resume()
When a listener resumes operations, supporting a full rebind makes it
possible to perform a full stop as a pause(). This will be used for
pausing abstract namespace unix sockets.
(cherry picked from commit 1c4b814087189b4b0225a473b7cb0a844bc30839)
---
src/listener.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/listener.c b/src/listener.c
index 67f8ca7..11df69f 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -120,10 +120,26 @@ int pause_listener(struct listener *l)
* may replace enable_listener(). The resulting state will either be LI_READY
* or LI_FULL. 0 is returned in case of failure to resume (eg: dead socket).
* Listeners bound to a different process are not woken up unless we're in
- * foreground mode.
+ * foreground mode. If the listener was only in the assigned state, it's totally
+ * rebound. This can happen if a pause() has completely stopped it. If the
+ * resume fails, 0 is returned and an error might be displayed.
*/
int resume_listener(struct listener *l)
{
+ if (l->state == LI_ASSIGNED) {
+ char msg[100];
+ int err;
+
+ err = l->proto->bind(l, msg, sizeof(msg));
+ if (err & ERR_ALERT)
+ Alert("Resuming listener: %s\n", msg);
+ else if (err & ERR_WARN)
+ Warning("Resuming listener: %s\n", msg);
+
+ if (err & (ERR_FATAL | ERR_ABORT))
+ return 0;
+ }
+
if (l->state < LI_PAUSED)
return 0;
--
1.8.5.5

+ 0
- 71
net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch View File

@ -1,71 +0,0 @@
From 631a70f8baff6d26a2a6692ccd368de8d3948bf9 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 7 Jul 2014 21:07:51 +0200
Subject: [PATCH 18/21] BUG/MEDIUM: unix: completely unbind abstract sockets
during a pause()
Abstract namespace sockets ignore the shutdown() call and do not make
it possible to temporarily stop listening. The issue it causes is that
during a soft reload, the new process cannot bind, complaining that the
address is already in use.
This change registers a new pause() function for unix sockets and
completely unbinds the abstract ones since it's possible to rebind
them later. It requires the two previous patches as well as preceeding
fixes.
This fix should be backported into 1.5 since the issue apperas there.
(cherry picked from commit fd0e008d9d4db2f860b739bd28f6cd31d9aaf2b5)
---
include/proto/proto_uxst.h | 1 +
src/proto_uxst.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/proto/proto_uxst.h b/include/proto/proto_uxst.h
index 9422ea7..8e796ec 100644
--- a/include/proto/proto_uxst.h
+++ b/include/proto/proto_uxst.h
@@ -27,6 +27,7 @@
#include <types/task.h>
void uxst_add_listener(struct listener *listener);
+int uxst_pause_listener(struct listener *l);
int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 409c659..adc1b46 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -68,6 +68,7 @@ static struct protocol proto_unix = {
.disable_all = disable_all_listeners,
.get_src = uxst_get_src,
.get_dst = uxst_get_dst,
+ .pause = uxst_pause_listener,
.listeners = LIST_HEAD_INIT(proto_unix.listeners),
.nb_listeners = 0,
};
@@ -373,6 +374,20 @@ void uxst_add_listener(struct listener *listener)
proto_unix.nb_listeners++;
}
+/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
+ * was totally stopped, or > 0 if correctly paused. Nothing is done for
+ * plain unix sockets since currently it's the new process which handles
+ * the renaming. Abstract sockets are completely unbound.
+ */
+int uxst_pause_listener(struct listener *l)
+{
+ if (((struct sockaddr_un *)&l->addr)->sun_path[0])
+ return 1;
+
+ unbind_listener(l);
+ return 0;
+}
+
/*
* This function initiates a UNIX connection establishment to the target assigned
--
1.8.5.5

+ 0
- 40
net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch View File

@ -1,40 +0,0 @@
From b4fca5dbf0cfe887b88d6213b014e2f73e02a5e6 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 8 Jul 2014 00:37:50 +0200
Subject: [PATCH 19/21] DOC: explicitly mention the limits of abstract
namespace sockets
Listening to an abstract namespace socket is quite convenient but
comes with some drawbacks that must be clearly understood when the
socket is being listened to by multiple processes. The trouble is
that the socket cannot be rebound if a new process attempts a soft
restart and fails, so only one of the initially bound processes
will still be bound to it, the other ones will fail to rebind. For
most situations it's not an issue but it needs to be indicated.
(cherry picked from commit 70f72e0c90691c72cb72306b718f785902270015)
---
doc/configuration.txt | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index fcc6454..73195ba 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1791,7 +1791,13 @@ bind /<path> [, ...] [param*]
- 'ipv4@' -> address is always IPv4
- 'ipv6@' -> address is always IPv6
- 'unix@' -> address is a path to a local unix socket
- - 'abns@' -> address is in abstract namespace (Linux only)
+ - 'abns@' -> address is in abstract namespace (Linux only).
+ Note: since abstract sockets are not "rebindable", they
+ do not cope well with multi-process mode during
+ soft-restart, so it is better to avoid them if
+ nbproc is greater than 1. The effect is that if the
+ new process fails to start, only one of the old ones
+ will be able to rebind to the socket.
- 'fd@<n>' -> use file descriptor <n> inherited from the
parent. The fd must be bound and may or may not already
be listening.
--
1.8.5.5

+ 0
- 198
net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch View File

@ -1,198 +0,0 @@
From 75c98ad211c9e1b7304033b9d3eb4fe552d725d2 Mon Sep 17 00:00:00 2001
From: James Westby <james.westby@canonical.com>
Date: Tue, 8 Jul 2014 10:14:57 -0400
Subject: [PATCH 20/21] DOC: expand the docs for the provided stats.
Indicate for each statistic which types may have a value for
that statistic.
Explain some of the provided statistics a little more deeply.
(cherry picked from commit ebe62d645b45aa2210ef848fa16805a0aba7d75a)
---
doc/configuration.txt | 163 +++++++++++++++++++++++++++++++-------------------
1 file changed, 100 insertions(+), 63 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 73195ba..8407500 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -13075,44 +13075,76 @@ text is doubled ('""'), which is the format that most tools recognize. Please
do not insert any column before these ones in order not to break tools which
use hard-coded column positions.
- 0. pxname: proxy name
- 1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
- for server)
- 2. qcur: current queued requests
- 3. qmax: max queued requests
- 4. scur: current sessions
- 5. smax: max sessions
- 6. slim: sessions limit
- 7. stot: total sessions
- 8. bin: bytes in
- 9. bout: bytes out
- 10. dreq: denied requests
- 11. dresp: denied responses
- 12. ereq: request errors
- 13. econ: connection errors
- 14. eresp: response errors (among which srv_abrt)
- 15. wretr: retries (warning)
- 16. wredis: redispatches (warning)
- 17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
- 18. weight: server weight (server), total weight (backend)
- 19. act: server is active (server), number of active servers (backend)
- 20. bck: server is backup (server), number of backup servers (backend)
- 21. chkfail: number of failed checks
- 22. chkdown: number of UP->DOWN transitions
- 23. lastchg: last status change (in seconds)
- 24. downtime: total downtime (in seconds)
- 25. qlimit: queue limit
- 26. pid: process id (0 for first instance, 1 for second, ...)
- 27. iid: unique proxy id
- 28. sid: service id (unique inside a proxy)
- 29. throttle: warm up status
- 30. lbtot: total number of times a server was selected
- 31. tracked: id of proxy/server if tracking is enabled
- 32. type (0=frontend, 1=backend, 2=server, 3=socket)
- 33. rate: number of sessions per second over last elapsed second
- 34. rate_lim: limit on new sessions per second
- 35. rate_max: max number of new sessions per second
- 36. check_status: status of last health check, one of:
+In brackets after each field name are the types which may have a value for
+that field. The types are L (Listeners), F (Frontends), B (Backends), and
+S (Servers).
+
+ 0. pxname [LFBS]: proxy name
+ 1. svname [LFBS]: service name (FRONTEND for frontend, BACKEND for backend,
+ any name for server/listener)
+ 2. qcur [..BS]: current queued requests. For the backend this reports the
+ number queued without a server assigned.
+ 3. qmax [..BS]: max value of qcur
+ 4. scur [LFBS]: current sessions
+ 5. smax [LFBS]: max sessions
+ 6. slim [LFBS]: configured session limit
+ 7. stot [LFBS]: cumulative number of connections
+ 8. bin [LFBS]: bytes in
+ 9. bout [LFBS]: bytes out
+ 10. dreq [LFB.]: requests denied because of security concerns.
+ - For tcp this is because of a matched tcp-request content rule.
+ - For http this is because of a matched http-request or tarpit rule.
+ 11. dresp [LFBS]: responses denied because of security concerns.
+ - For http this is because of a matched http-request rule, or
+ "option checkcache".
+ 12. ereq [LF..]: request errors. Some of the possible causes are:
+ - early termination from the client, before the request has been sent.
+ - read error from the client
+ - client timeout
+ - client closed connection
+ - various bad requests from the client.
+ - request was tarpitted.
+ 13. econ [..BS]: number of requests that encountered an error trying to
+ connect to a backend server. The backend stat is the sum of the stat
+ for all servers of that backend, plus any connection errors not
+ associated with a particular server (such as the backend having no
+ active servers).
+ 14. eresp [..BS]: response errors. srv_abrt will be counted here also.
+ Some other errors are:
+ - write error on the client socket (won't be counted for the server stat)
+ - failure applying filters to the response.
+ 15. wretr [..BS]: number of times a connection to a server was retried.
+ 16. wredis [..BS]: number of times a request was redispatched to another
+ server. The server value counts the number of times that server was
+ switched away from.
+ 17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
+ 18. weight [..BS]: server weight (server), total weight (backend)
+ 19. act [..BS]: server is active (server), number of active servers (backend)
+ 20. bck [..BS]: server is backup (server), number of backup servers (backend)
+ 21. chkfail [...S]: number of failed checks. (Only counts checks failed when
+ the server is up.)
+ 22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts
+ transitions to the whole backend being down, rather than the sum of the
+ counters for each server.
+ 23. lastchg [..BS]: number of seconds since the last UP<->DOWN transition
+ 24. downtime [..BS]: total downtime (in seconds). The value for the backend
+ is the downtime for the whole backend, not the sum of the server downtime.
+ 25. qlimit [...S]: configured maxqueue for the server, or nothing in the
+ value is 0 (default, meaning no limit)
+ 26. pid [LFBS]: process id (0 for first instance, 1 for second, ...)
+ 27. iid [LFBS]: unique proxy id
+ 28. sid [L..S]: server id (unique inside a proxy)
+ 29. throttle [...S]: current throttle percentage for the server, when
+ slowstart is active, or no value if not in slowstart.
+ 30. lbtot [..BS]: total number of times a server was selected, either for new
+ sessions, or when re-dispatching. The server counter is the number
+ of times that server was selected.
+ 31. tracked [...S]: id of proxy/server if tracking is enabled.
+ 32. type [LFBS]: (0=frontend, 1=backend, 2=server, 3=socket/listener)
+ 33. rate [.FBS]: number of sessions per second over last elapsed second
+ 34. rate_lim [.F..]: configured limit on new sessions per second
+ 35. rate_max [.FBS]: max number of new sessions per second
+ 36. check_status [...S]: status of last health check, one of:
UNK -> unknown
INI -> initializing
SOCKERR -> socket error
@@ -13129,31 +13161,36 @@ use hard-coded column positions.
L7TOUT -> layer 7 (HTTP/SMTP) timeout
L7RSP -> layer 7 invalid response - protocol error
L7STS -> layer 7 response error, for example HTTP 5xx
- 37. check_code: layer5-7 code, if available
- 38. check_duration: time in ms took to finish last health check
- 39. hrsp_1xx: http responses with 1xx code
- 40. hrsp_2xx: http responses with 2xx code
- 41. hrsp_3xx: http responses with 3xx code
- 42. hrsp_4xx: http responses with 4xx code
- 43. hrsp_5xx: http responses with 5xx code
- 44. hrsp_other: http responses with other codes (protocol error)
- 45. hanafail: failed health checks details
- 46. req_rate: HTTP requests per second over last elapsed second
- 47. req_rate_max: max number of HTTP requests per second observed
- 48. req_tot: total number of HTTP requests received
- 49. cli_abrt: number of data transfers aborted by the client
- 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
- 51. comp_in: number of HTTP response bytes fed to the compressor
- 52. comp_out: number of HTTP response bytes emitted by the compressor
- 53. comp_byp: number of bytes that bypassed the HTTP compressor (CPU/BW limit)
- 54. comp_rsp: number of HTTP responses that were compressed
- 55. lastsess: number of seconds since last session assigned to server/backend
- 56. last_chk: last health check contents or textual error
- 57. last_agt: last agent check contents or textual error
- 58. qtime: the average queue time in ms over the 1024 last requests
- 59. ctime: the average connect time in ms over the 1024 last requests
- 60. rtime: the average response time in ms over the 1024 last requests (0 for TCP)
- 61. ttime: the average total session time in ms over the 1024 last requests
+ 37. check_code [...S]: layer5-7 code, if available
+ 38. check_duration [...S]: time in ms took to finish last health check
+ 39. hrsp_1xx [.FBS]: http responses with 1xx code
+ 40. hrsp_2xx [.FBS]: http responses with 2xx code
+ 41. hrsp_3xx [.FBS]: http responses with 3xx code
+ 42. hrsp_4xx [.FBS]: http responses with 4xx code
+ 43. hrsp_5xx [.FBS]: http responses with 5xx code
+ 44. hrsp_other [.FBS]: http responses with other codes (protocol error)
+ 45. hanafail [...S]: failed health checks details
+ 46. req_rate [.F..]: HTTP requests per second over last elapsed second
+ 47. req_rate_max [.F..]: max number of HTTP requests per second observed
+ 48. req_tot [.F..]: total number of HTTP requests received
+ 49. cli_abrt [..BS]: number of data transfers aborted by the client
+ 50. srv_abrt [..BS]: number of data transfers aborted by the server
+ (inc. in eresp)
+ 51. comp_in [.FB.]: number of HTTP response bytes fed to the compressor
+ 52. comp_out [.FB.]: number of HTTP response bytes emitted by the compressor
+ 53. comp_byp [.FB.]: number of bytes that bypassed the HTTP compressor
+ (CPU/BW limit)
+ 54. comp_rsp [.FB.]: number of HTTP responses that were compressed
+ 55. lastsess [..BS]: number of seconds since last session assigned to
+ server/backend
+ 56. last_chk [...S]: last health check contents or textual error
+ 57. last_agt [...S]: last agent check contents or textual error
+ 58. qtime [..BS]: the average queue time in ms over the 1024 last requests
+ 59. ctime [..BS]: the average connect time in ms over the 1024 last requests
+ 60. rtime [..BS]: the average response time in ms over the 1024 last requests
+ (0 for TCP)
+ 61. ttime [..BS]: the average total session time in ms over the 1024 last
+ requests
9.2. Unix Socket commands
--
1.8.5.5

+ 0
- 138
net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch View File

@ -1,138 +0,0 @@
From 82456753cae9200aa1f4031f64c22c08e130f072 Mon Sep 17 00:00:00 2001
From: Dan Dubovik <ddubovik@godaddy.com>
Date: Tue, 8 Jul 2014 08:51:03 -0700
Subject: [PATCH 21/21] BUG/MEDIUM: backend: Update hash to use unsigned int
throughout
When we were generating a hash, it was done using an unsigned long. When the hash was used
to select a backend, it was sent as an unsigned int. This made it difficult to predict which
backend would be selected.
This patch updates get_hash, and the hash methods to use an unsigned int, to remain consistent
throughout the codebase.
This fix should be backported to 1.5 and probably in part to 1.4.
(cherry picked from commit bd57a9f977f60fcf7818f462953da3740e3bd010)
---
include/common/hash.h | 6 +++---
src/backend.c | 14 +++++++-------
src/hash.c | 10 +++++-----
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/common/hash.h b/include/common/hash.h
index 379bf89..7039ba5 100644
--- a/include/common/hash.h
+++ b/include/common/hash.h
@@ -22,8 +22,8 @@
#ifndef _COMMON_HASH_H_
#define _COMMON_HASH_H_
-unsigned long hash_djb2(const char *key, int len);
-unsigned long hash_wt6(const char *key, int len);
-unsigned long hash_sdbm(const char *key, int len);
+unsigned int hash_djb2(const char *key, int len);
+unsigned int hash_wt6(const char *key, int len);
+unsigned int hash_sdbm(const char *key, int len);
#endif /* _COMMON_HASH_H_ */
diff --git a/src/backend.c b/src/backend.c
index 5ddb88c..a96b767 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -63,9 +63,9 @@ int be_lastsession(const struct proxy *be)
}
/* helper function to invoke the correct hash method */
-static unsigned long gen_hash(const struct proxy* px, const char* key, unsigned long len)
+static unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len)
{
- unsigned long hash;
+ unsigned int hash;
switch (px->lbprm.algo & BE_LB_HASH_FUNC) {
case BE_LB_HFCN_DJB2:
@@ -183,7 +183,7 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len)
*/
struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
int c;
int slashes = 0;
const char *start, *end;
@@ -232,7 +232,7 @@ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
*/
struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
const char *start, *end;
const char *p;
const char *params;
@@ -294,7 +294,7 @@ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
*/
struct server *get_server_ph_post(struct session *s)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
struct http_txn *txn = &s->txn;
struct channel *req = s->req;
struct http_msg *msg = &txn->req;
@@ -372,7 +372,7 @@ struct server *get_server_ph_post(struct session *s)
*/
struct server *get_server_hh(struct session *s)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
struct http_txn *txn = &s->txn;
struct proxy *px = s->be;
unsigned int plen = px->hh_len;
@@ -444,7 +444,7 @@ struct server *get_server_hh(struct session *s)
/* RDP Cookie HASH. */
struct server *get_server_rch(struct session *s)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
struct proxy *px = s->be;
unsigned long len;
int ret;
diff --git a/src/hash.c b/src/hash.c
index 034685e..aa236cb 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -17,7 +17,7 @@
#include <common/hash.h>
-unsigned long hash_wt6(const char *key, int len)
+unsigned int hash_wt6(const char *key, int len)
{
unsigned h0 = 0xa53c965aUL;
unsigned h1 = 0x5ca6953aUL;
@@ -44,9 +44,9 @@ unsigned long hash_wt6(const char *key, int len)
return h0 ^ h1;
}
-unsigned long hash_djb2(const char *key, int len)
+unsigned int hash_djb2(const char *key, int len)
{
- unsigned long hash = 5381;
+ unsigned int hash = 5381;
/* the hash unrolled eight times */
for (; len >= 8; len -= 8) {
@@ -72,9 +72,9 @@ unsigned long hash_djb2(const char *key, int len)
return hash;
}
-unsigned long hash_sdbm(const char *key, int len)
+unsigned int hash_sdbm(const char *key, int len)
{
- unsigned long hash = 0;
+ unsigned int hash = 0;
int c;
while (len--) {
--
1.8.5.5

+ 0
- 75
net/haproxy/patches/0022-DOC-minor-fix-on-sc-src-_kbytes_-in-out.patch View File

@ -1,75 +0,0 @@
From 911780c5f0e20760164cb0f9b92318185651237c Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 10 Jul 2014 15:29:24 +0200
Subject: [PATCH 22/25] DOC: minor fix on {sc,src}_kbytes_{in,out}
These ones report total amount of bytes, not byte rates.
This fix should be backported into 1.5 which has the same error.
(cherry picked from commit a01b974d5f5a067d99f288dcb3e05b78fe780a76)
---
doc/configuration.txt | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 8407500..b6d1b3b 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10386,19 +10386,17 @@ sc_kbytes_in(<ctr>[,<table>]) : integer
sc0_kbytes_in([<table>]) : integer
sc1_kbytes_in([<table>]) : integer
sc2_kbytes_in([<table>]) : integer
- Returns the amount of client-to-server data from the currently tracked
- counters, measured in kilobytes over the period configured in the table. The
- test is currently performed on 32-bit integers, which limits values to 4
- terabytes. See also src_kbytes_in.
+ Returns the total amount of client-to-server data from the currently tracked
+ counters, measured in kilobytes. The test is currently performed on 32-bit
+ integers, which limits values to 4 terabytes. See also src_kbytes_in.
sc_kbytes_out(<ctr>[,<table>]) : integer
sc0_kbytes_out([<table>]) : integer
sc1_kbytes_out([<table>]) : integer
sc2_kbytes_out([<table>]) : integer
- Returns the amount of server-to-client data from the currently tracked
- counters, measured in kilobytes over the period configured in the table. The
- test is currently performed on 32-bit integers, which limits values to 4
- terabytes. See also src_kbytes_out.
+ Returns the total amount of server-to-client data from the currently tracked
+ counters, measured in kilobytes. The test is currently performed on 32-bit
+ integers, which limits values to 4 terabytes. See also src_kbytes_out.
sc_sess_cnt(<ctr>[,<table>]) : integer
sc0_sess_cnt([<table>]) : integer
@@ -10562,19 +10560,18 @@ src_inc_gpc0([<table>]) : integer
tcp-request connection reject if abuse kill
src_kbytes_in([<table>]) : integer
- Returns the amount of data received from the incoming connection's source
- address in the current proxy's stick-table or in the designated stick-table,
- measured in kilobytes over the period configured in the table. If the address
- is not found, zero is returned. The test is currently performed on 32-bit
- integers, which limits values to 4 terabytes. See also
- sc/sc0/sc1/sc2_kbytes_in.
+ Returns the total amount of data received from the incoming connection's
+ source address in the current proxy's stick-table or in the designated
+ stick-table, measured in kilobytes. If the address is not found, zero is
+ returned. The test is currently performed on 32-bit integers, which limits
+ values to 4 terabytes. See also sc/sc0/sc1/sc2_kbytes_in.
src_kbytes_out([<table>]) : integer
- Returns the amount of data sent to the incoming connection's source address
- in the current proxy's stick-table or in the designated stick-table, measured
- in kilobytes over the period configured in the table. If the address is not
- found, zero is returned. The test is currently performed on 32-bit integers,
- which limits values to 4 terabytes. See also sc/sc0/sc1/sc2_kbytes_out.
+ Returns the total amount of data sent to the incoming connection's source
+ address in the current proxy's stick-table or in the designated stick-table,
+ measured in kilobytes. If the address is not found, zero is returned. The
+ test is currently performed on 32-bit integers, which limits values to 4
+ terabytes. See also sc/sc0/sc1/sc2_kbytes_out.
src_port : integer
Returns an integer value corresponding to the TCP source port of the
--
1.8.5.5

+ 0
- 84
net/haproxy/patches/0023-DOC-fix-alphabetical-sort-of-converters.patch View File

@ -1,84 +0,0 @@
From 644d9ef5af4f8010412007374c345f7465c97391 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 10 Jul 2014 16:29:08 +0200
Subject: [PATCH 23/25] DOC: fix alphabetical sort of converters
For an unknown reason, these ones were not sorted.
(cherry picked from commit ffcb2e4b42acd710121a57eb39651a373d904e5b)
---
doc/configuration.txt | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index b6d1b3b..f8199b9 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -9887,28 +9887,12 @@ base64
transfer binary content in a way that can be reliably transferred (eg:
an SSL ID can be copied in a header).
-lower
- Convert a string sample to lower case. This can only be placed after a string
- sample fetch function or after a transformation keyword returning a string
- type. The result is of type string.
-
-upper
- Convert a string sample to upper case. This can only be placed after a string
- sample fetch function or after a transformation keyword returning a string
- type. The result is of type string.
-
hex
Converts a binary input sample to an hex string containing two hex digits per
input byte. It is used to log or transfer hex dumps of some binary input data
in a way that can be reliably transferred (eg: an SSL ID can be copied in a
header).
-ipmask(<mask>)
- Apply a mask to an IPv4 address, and use the result for lookups and storage.
- This can be used to make all hosts within a certain mask to share the same
- table entries and as such use the same server. The mask can be passed in
- dotted form (eg: 255.255.255.0) or in CIDR form (eg: 24).
-
http_date([<offset>])
Converts an integer supposed to contain a date since epoch to a string
representing this date in a format suitable for use in HTTP header fields. If
@@ -9917,6 +9901,12 @@ http_date([<offset>])
emit Date header fields, Expires values in responses when combined with a
positive offset, or Last-Modified values when the offset is negative.
+ipmask(<mask>)
+ Apply a mask to an IPv4 address, and use the result for lookups and storage.
+ This can be used to make all hosts within a certain mask to share the same
+ table entries and as such use the same server. The mask can be passed in
+ dotted form (eg: 255.255.255.0) or in CIDR form (eg: 24).
+
language(<value>[,<default>])
Returns the value with the highest q-factor from a list as extracted from the
"accept-language" header using "req.fhdr". Values with no q-factor have a
@@ -9944,6 +9934,11 @@ language(<value>[,<default>])
use_backend english if en
default_backend choose_your_language
+lower
+ Convert a string sample to lower case. This can only be placed after a string
+ sample fetch function or after a transformation keyword returning a string
+ type. The result is of type string.
+
map(<map_file>[,<default_value>])
map_<match_type>(<map_file>[,<default_value>])
map_<match_type>_<output_type>(<map_file>[,<default_value>])
@@ -10001,6 +9996,11 @@ map_<match_type>_<output_type>(<map_file>[,<default_value>])
| `---------------------------- key
`------------------------------------ leading spaces ignored
+upper
+ Convert a string sample to upper case. This can only be placed after a string
+ sample fetch function or after a transformation keyword returning a string
+ type. The result is of type string.
+
7.3.2. Fetching samples from internal states
--------------------------------------------
--
1.8.5.5

+ 0
- 167
net/haproxy/patches/0024-BUG-MAJOR-http-correctly-rewind-the-request-body-aft.patch View File

@ -1,167 +0,0 @@
From 5bebcd06287be9024f0fba25f350393f02e050c1 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 10 Jul 2014 19:06:10 +0200
Subject: [PATCH 24/25] BUG/MAJOR: http: correctly rewind the request body
after start of forwarding
Daniel Dubovik reported an interesting bug showing that the request body
processing was still not 100% fixed. If a POST request contained short
enough data to be forwarded at once before trying to establish the
connection to the server, we had no way to correctly rewind the body.
The first visible case is that balancing on a header does not always work
on such POST requests since the header cannot be found. But there are even
nastier implications which are that http-send-name-header would apply to
the wrong location and possibly even affect part of the request's body
due to an incorrect rewinding.
There are two options to fix the problem :
- first one is to force the HTTP_MSG_F_WAIT_CONN flag on all hash-based
balancing algorithms and http-send-name-header, but there's always a
risk that any new algorithm forgets to set it ;
- the second option is to account for the amount of skipped data before
the connection establishes so that we always know the position of the
request's body relative to the buffer's origin.
The second option is much more reliable and fits very well in the spirit
of the past changes to fix forwarding. Indeed, at the moment we have
msg->sov which points to the start of the body before headers are forwarded
and which equals zero afterwards (so it still points to the start of the
body before forwarding data). A minor change consists in always making it
point to the start of the body even after data have been forwarded. It means
that it can get a negative value (so we need to change its type to signed)..
In order to avoid wrapping, we only do this as long as the other side of
the buffer is not connected yet.
Doing this definitely fixes the issues above for the requests. Since the
response cannot be rewound we don't need to perform any change there.
This bug was introduced/remained unfixed in 1.5-dev23 so the fix must be
backported to 1.5.
(cherry picked from commit bb2e669f9e73531ac9cc9277b40066b701eec918)
---
doc/internals/body-parsing.txt | 20 +++++++++++++-------
include/types/proto_http.h | 11 ++++++-----
src/proto_http.c | 9 +++++++--
3 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/doc/internals/body-parsing.txt b/doc/internals/body-parsing.txt
index e9c8b4b..5baa549 100644
--- a/doc/internals/body-parsing.txt
+++ b/doc/internals/body-parsing.txt
@@ -67,12 +67,17 @@ msg.next : points to the next byte to inspect. This offset is automatically
automatically adjusted to the number of bytes already inspected.
msg.sov : start of value. First character of the header's value in the header
- states, start of the body in the data states until headers are
- forwarded. This offset is automatically adjusted when inserting or
- removing some headers. In data states, it always constains the size
- of the whole HTTP headers (including the trailing CRLF) that needs
- to be forwarded before the first byte of body. Once the headers are
- forwarded, this value drops to zero.
+ states, start of the body in the data states. Strictly positive
+ values indicate that headers were not forwarded yet (<buf.p> is
+ before the start of the body), and null or positive values are seen
+ after headers are forwarded (<buf.p> is at or past the start of the
+ body). The value stops changing when data start to leave the buffer
+ (in order to avoid integer overflows). So the maximum possible range
+ is -<buf.size> to +<buf.size>. This offset is automatically adjusted
+ when inserting or removing some headers. It is useful to rewind the
+ request buffer to the beginning of the body at any phase. The
+ response buffer does not really use it since it is immediately
+ forwarded to the client.
msg.sol : start of line. Points to the beginning of the current header line
while parsing headers. It is cleared to zero in the BODY state,
@@ -97,7 +102,8 @@ msg.eol : end of line. Points to the CRLF or LF of the current header line
states nor by forwarding.
The beginning of the message headers can always be found this way even after
-headers have been forwarded :
+headers or data have been forwarded, provided that everything is still present
+in the buffer :
headers = buf.p + msg->sov - msg->eoh - msg->eol
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 12e1141..c53c7fd 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -329,7 +329,8 @@ enum {
* message or a response message.
*
* The values there are a little bit obscure, because their meaning can change
- * during the parsing :
+ * during the parsing. Please read carefully doc/internal/body-parsing.txt if
+ * you need to manipulate them. Quick reminder :
*
* - eoh (End of Headers) : relative offset in the buffer of first byte that
* is not part of a completely processed header.
@@ -344,9 +345,9 @@ enum {
* - sov (start of value) : Before HTTP_MSG_BODY, points to the value of
* the header being parsed. Starting from
* HTTP_MSG_BODY, will point to the start of the
- * body (relative to buffer's origin), or to data
- * following a chunk size. Thus <sov> bytes of
- * headers will have to be sent only once.
+ * body (relative to buffer's origin). It can be
+ * negative when forwarding data. It stops growing
+ * once data start to leave the buffer.
*
* - next (parse pointer) : next relative byte to be parsed. Always points
* to a byte matching the current state.
@@ -372,7 +373,7 @@ struct http_msg {
/* 6 bytes unused here */
struct channel *chn; /* pointer to the channel transporting the message */
unsigned int next; /* pointer to next byte to parse, relative to buf->p */
- unsigned int sov; /* current header: start of value */
+ int sov; /* current header: start of value ; data: start of body */
unsigned int eoh; /* End Of Headers, relative to buffer */
unsigned int sol; /* start of current line during parsing otherwise zero */
unsigned int eol; /* end of line */
diff --git a/src/proto_http.c b/src/proto_http.c
index 4a862b0..94afed7 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5315,7 +5315,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
* an "Expect: 100-continue" header.
*/
- if (msg->sov) {
+ if (msg->sov > 0) {
/* we have msg->sov which points to the first byte of message
* body, and req->buf.p still points to the beginning of the
* message. We forward the headers now, as we don't need them
@@ -5429,6 +5429,8 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
* such as last chunk of data or trailers.
*/
b_adv(req->buf, msg->next);
+ if (unlikely(!(s->rep->flags & CF_READ_ATTACHED)))
+ msg->sov -= msg->next;
msg->next = 0;
/* for keep-alive we don't want to forward closes on DONE */
@@ -5479,6 +5481,9 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
missing_data:
/* we may have some pending data starting at req->buf->p */
b_adv(req->buf, msg->next);
+ if (unlikely(!(s->rep->flags & CF_READ_ATTACHED)))
+ msg->sov -= msg->next + MIN(msg->chunk_len, req->buf->i);
+
msg->next = 0;
msg->chunk_len -= channel_forward(req, msg->chunk_len);
@@ -6493,7 +6498,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
/* in most states, we should abort in case of early close */
channel_auto_close(res);
- if (msg->sov) {
+ if (msg->sov > 0) {
/* we have msg->sov which points to the first byte of message
* body, and res->buf.p still points to the beginning of the
* message. We forward the headers now, as we don't need them
--
1.8.5.5

+ 0
- 48
net/haproxy/patches/0025-DOC-remove-references-to-CPU-native-in-the-README.patch View File

@ -1,48 +0,0 @@
From 94fb38fbb77e664e4f41343257a26ae5bab40d1d Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 10 Jul 2014 20:24:25 +0200
Subject: [PATCH 25/25] DOC: remove references to CPU=native in the README
Certain compilers running in virtualized environments may produce code
that the same processor cannot execute with -march=native, either because
of hypervisor bugs reporting wrong CPU features, or because of compiler
bugs forgetting to check CPU features. So better stop recommending this
combination so that users don't get trapped anymore.
(cherry picked from commit 817dad50b02d1a82d495dfea4eab9e3a91127391)
---
README | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/README b/README
index 0ef0179..e2b8570 100644
--- a/README
+++ b/README
@@ -53,8 +53,9 @@ one of the following choices to the CPU variable :
- i686 for intel PentiumPro, Pentium 2 and above, AMD Athlon
- i586 for intel Pentium, AMD K6, VIA C3.
- ultrasparc : Sun UltraSparc I/II/III/IV processor
- - native : use the build machine's specific processor optimizations
- - generic : any other processor or no specific optimization. (default)
+ - native : use the build machine's specific processor optimizations. Use with
+ extreme care, and never in virtualized environments (known to break).
+ - generic : any other processor or no CPU-specific optimization. (default)
Alternatively, you may just set the CPU_CFLAGS value to the optimal GCC options
for your platform.
@@ -132,11 +133,11 @@ And I build it this way on OpenBSD or FreeBSD :
And on a classic Linux with SSL and ZLIB support (eg: Red Hat 5.x) :
- $ make TARGET=linux26 CPU=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
+ $ make TARGET=linux26 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
And on a recent Linux >= 2.6.28 with SSL and ZLIB support :
- $ make TARGET=linux2628 CPU=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
+ $ make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
In order to build a 32-bit binary on an x86_64 Linux system with SSL support
without support for compression but when OpenSSL requires ZLIB anyway :
--
1.8.5.5

Loading…
Cancel
Save