Hello community, here is the log from the commit of package haproxy for openSUSE:Factory checked in at 2014-07-02 15:05:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/haproxy (Old) and /work/SRC/openSUSE:Factory/.haproxy.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "haproxy" Changes: -------- --- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes 2014-06-25 15:24:39.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.haproxy.new/haproxy.changes 2014-07-02 15:05:26.000000000 +0200 @@ -1,0 +2,18 @@ +Tue Jul 1 12:13:33 UTC 2014 - kgronl...@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 + +------------------------------------------------------------------- New: ---- 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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ haproxy.spec ++++++ --- /var/tmp/diff_new_pack.FthySS/_old 2014-07-02 15:05:28.000000000 +0200 +++ /var/tmp/diff_new_pack.FthySS/_new 2014-07-02 15:05:28.000000000 +0200 @@ -61,6 +61,18 @@ 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 @@ %patch2 %patch3 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 %build %{__make} \ ++++++ 0001-BUG-MEDIUM-http-fetch-base-is-not-compatible-with-se.patch ++++++ >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 ++++++ 0002-BUG-MINOR-ssl-Fix-external-function-in-order-not-to-.patch ++++++ >From 87e56ce15591dbb98046fe9fb923f28769eb6056 Mon Sep 17 00:00:00 2001 From: Emeric Brun <eb...@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 ++++++ 0003-BUG-MINOR-counters-do-not-untrack-counters-before-lo.patch ++++++ >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 ++++++ 0004-BUG-MAJOR-sample-correctly-reinitialize-sample-fetch.patch ++++++ >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 ++++++ 0005-MINOR-stick-table-make-stktable_fetch_key-indicate-w.patch ++++++ >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 ++++++ 0006-BUG-MEDIUM-counters-fix-track-sc-to-wait-on-unstable.patch ++++++ >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 -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org