Accepting request 239167 from network:ha-clustering:Factory

1

OBS-URL: https://build.opensuse.org/request/show/239167
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/haproxy?expand=0&rev=7
This commit is contained in:
Stephan Kulow 2014-07-02 13:05:11 +00:00 committed by Git OBS Bridge
parent 815be0e3e6
commit 23e7c6db83
8 changed files with 449 additions and 0 deletions

View File

@ -0,0 +1,44 @@
From f86d9bb6dd56d56e7425246f91a6c105a5f38659 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 24 Jun 2014 17:27:02 +0200
Subject: [PATCH 1/6] 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.
---
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 231d49a12875..5321f7d53e6a 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.4.5

View File

@ -0,0 +1,100 @@
From 87e56ce15591dbb98046fe9fb923f28769eb6056 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.
---
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 0902fde989bb..3e111cd68490 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 0b154d802a80..20a911bcd41f 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 328b97880b8d..375225d19f72 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.4.5

View File

@ -0,0 +1,41 @@
From ecde57996941ab79f8e3ee5d6114ede49adaaf17 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.
---
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 5321f7d53e6a..d566bcc819ec 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.4.5

View File

@ -0,0 +1,64 @@
From 6747e44f116b7f20c96514454174cf0c0a2e1a4b 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.
---
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 d566bcc819ec..01fe62d09246 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 9f22ef97156f..3a0f3fbbcff2 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.4.5

View File

@ -0,0 +1,108 @@
From f0b3bcc98e0d3fc372f0ec658e6c402af8b98412 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.
---
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 0c26fbea3052..57ca2234317c 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 65c4fdad379e..1aac0d9225d9 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 e26f5ad17a6b..df85170cd13a 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 c6463ec7b95a..a708d3c53386 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.4.5

View File

@ -0,0 +1,56 @@
From 08901b038aa0837786fbb1049508fb28c92a15d7 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.
---
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 1aac0d9225d9..e9dbc9c0b6de 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.4.5

View File

@ -1,3 +1,21 @@
-------------------------------------------------------------------
Tue Jul 1 12:13:33 UTC 2014 - kgronlund@suse.com
- BUG/MEDIUM: counters: fix track-sc* to wait on unstable contents
- MINOR: stick-table: make stktable_fetch_key() indicate why it failed
- BUG/MAJOR: sample: correctly reinitialize sample fetch context before calling sample_process()
- BUG/MINOR: counters: do not untrack counters before logging
- BUG/MINOR: ssl: Fix external function in order not to return a pointer on an internal trash buffer.
- BUG/MEDIUM: http: fetch "base" is not compatible with set-header
- Add patches:
- 0001-BUG-MEDIUM-http-fetch-base-is-not-compatible-with-se.patch
- 0002-BUG-MINOR-ssl-Fix-external-function-in-order-not-to-.patch
- 0003-BUG-MINOR-counters-do-not-untrack-counters-before-lo.patch
- 0004-BUG-MAJOR-sample-correctly-reinitialize-sample-fetch.patch
- 0005-MINOR-stick-table-make-stktable_fetch_key-indicate-w.patch
- 0006-BUG-MEDIUM-counters-fix-track-sc-to-wait-on-unstable.patch
-------------------------------------------------------------------
Tue Jun 24 15:55:48 UTC 2014 - mrueckert@suse.de

View File

@ -61,6 +61,18 @@ Patch1: haproxy-1.2.16_config_haproxy_user.patch
Patch2: haproxy-makefile_lib.patch
Patch3: sec-options.patch
Patch4: haproxy-1.5_check_config_before_start.patch
# PATCH-FIX-UPSTREAM: http: fetch "base" is not compatible with set-header
Patch5: 0001-BUG-MEDIUM-http-fetch-base-is-not-compatible-with-se.patch
# PATCH-FIX-UPSTREAM: ssl: Fix external function in order not to return a pointer on an internal trash buffer.
Patch6: 0002-BUG-MINOR-ssl-Fix-external-function-in-order-not-to-.patch
# PATCH-FIX-UPSTREAM: counters: do not untrack counters before logging
Patch7: 0003-BUG-MINOR-counters-do-not-untrack-counters-before-lo.patch
# PATCH-FIX-UPSTREAM: sample: correctly reinitialize sample fetch context before calling sample_process()
Patch8: 0004-BUG-MAJOR-sample-correctly-reinitialize-sample-fetch.patch
# PATCH-FIX-UPSTREAM: stick-table: make stktable_fetch_key() indicate why it failed
Patch9: 0005-MINOR-stick-table-make-stktable_fetch_key-indicate-w.patch
# PATCH-FIX-UPSTREAM: counters: fix track-sc* to wait on unstable contents
Patch10: 0006-BUG-MEDIUM-counters-fix-track-sc-to-wait-on-unstable.patch
Source99: haproxy-rpmlintrc
#
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
@ -94,6 +106,12 @@ the most work done from every CPU cycle.
%patch2
%patch3
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%build
%{__make} \