From 6ef3b657c7d8c477153ab796b8622587b08913afd88e44f0a0c860305722e1a4 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Tue, 30 Jun 2015 08:19:18 +0000 Subject: [PATCH] Accepting request 314323 from network:ha-clustering:Factory 1 OBS-URL: https://build.opensuse.org/request/show/314323 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/haproxy?expand=0&rev=30 --- ...-properly-initialize-the-scope-befor.patch | 32 ---- ...don-t-forward-client-shutdown-withou.patch | 82 -------- ...NOR-check-fix-tcpcheck-error-message.patch | 28 --- ...ix-double-usage-of-cur-current_step-.patch | 178 ------------------ ...s-do-not-dereference-head-of-a-tcp-c.patch | 53 ------ ...implify-the-loop-processing-of-tcp-c.patch | 82 -------- ...-always-check-for-end-of-list-before.patch | 90 --------- ...s-do-not-dereference-a-list-as-a-tcp.patch | 116 ------------ ...-apply-a-random-reconnection-timeout.patch | 77 -------- haproxy-1.5.12.tar.gz | 3 - haproxy-1.5.13.tar.gz | 3 + haproxy.changes | 85 +++++++++ haproxy.spec | 28 +-- 13 files changed, 90 insertions(+), 767 deletions(-) delete mode 100644 0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch delete mode 100644 0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch delete mode 100644 0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch delete mode 100644 0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch delete mode 100644 0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch delete mode 100644 0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch delete mode 100644 0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch delete mode 100644 0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch delete mode 100644 0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch delete mode 100644 haproxy-1.5.12.tar.gz create mode 100644 haproxy-1.5.13.tar.gz diff --git a/0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch b/0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch deleted file mode 100644 index 38b9fd9..0000000 --- a/0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0aa5899911bbc765ba16ce52a80fa76230781779 Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Mon, 4 May 2015 18:07:56 +0200 -Subject: [PATCH 1/2] BUG/MEDIUM: stats: properly initialize the scope before - dumping stats - -Issuing a "show sess all" prior to a "show stat" on the CLI results in no -proxy being dumped because the scope_len union member was not properly -reinitialized. - -This fix must be backported into 1.5. -(cherry picked from commit 6bcb95da5b9cb143088102b460c7bcb37c1b3d81) ---- - src/dumpstats.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/dumpstats.c b/src/dumpstats.c -index b616478..ca084ac 100644 ---- a/src/dumpstats.c -+++ b/src/dumpstats.c -@@ -1109,6 +1109,8 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) - arg++; - } - -+ appctx->ctx.stats.scope_str = 0; -+ appctx->ctx.stats.scope_len = 0; - appctx->ctx.stats.flags = 0; - if (strcmp(args[0], "show") == 0) { - if (strcmp(args[1], "stat") == 0) { --- -2.1.4 - diff --git a/0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch b/0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch deleted file mode 100644 index 7ccd0a4..0000000 --- a/0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 294e4676a3b775a7accb50eb8428f293c218b5e2 Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Mon, 11 May 2015 18:30:33 +0200 -Subject: [PATCH 2/2] BUG/MEDIUM: http: don't forward client shutdown without - NOLINGER except for tunnels - -There's an issue related with shutting down POST transfers or closing the -connection after the end of the upload : the shutdown is forwarded to the -server regardless of the abortonclose option. The problem it causes is that -during a scan, brute force or whatever, it becomes possible that all source -ports are exhausted with all sockets in TIME_WAIT state. - -There are multiple issues at once in fact : - - no action is done for the close, it automatically happens at the lower - layers thanks for channel_auto_close(), so we cannot act on NOLINGER ; - - - we *do* want to continue to send a clean shutdown in tunnel mode because - some protocols transported over HTTP may need this, regardless of option - abortonclose, thus we can't set the option inconditionally - - - for all other modes, we do want to close the dirty way because we're - certain whether we've sent everything or not, and we don't want to eat - all source ports. - -The solution is a bit complex and applies to DONE/TUNNEL states : - - 1) disable automatic close for everything not a tunnel and not just - keep-alive / server-close. Force-close is now covered, as is HTTP/1.0 - which implicitly works in force-close mode ; - - 2) when processing option abortonclose, we know we can disable lingering - if the client has closed and the connection is not in tunnel mode. - -Since the last case above leads to a situation where the client side reports -an error, we know the connection will not be reused, so leaving the flag on -the stream-interface is safe. A client closing in the middle of the data -transmission already aborts the transaction so this case is not a problem. - -This fix must be backported to 1.5 where the problem was detected. -(cherry picked from commit bbfb6c40854925367ae5f9e8b22c5c9a18dc69d5) ---- - src/proto_http.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/src/proto_http.c b/src/proto_http.c -index 0ac3a47..5db64b5 100644 ---- a/src/proto_http.c -+++ b/src/proto_http.c -@@ -5452,9 +5452,10 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit - msg->sov -= msg->next; - msg->next = 0; - -- /* for keep-alive we don't want to forward closes on DONE */ -- if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL || -- (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) -+ /* we don't want to forward closes on DONE except in -+ * tunnel mode. -+ */ -+ if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) - channel_dont_close(req); - if (http_resync_states(s)) { - /* some state changes occurred, maybe the analyser -@@ -5478,10 +5479,15 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit - * want to monitor the client's connection and forward - * any shutdown notification to the server, which will - * decide whether to close or to go on processing the -- * request. -+ * request. We only do that in tunnel mode, and not in -+ * other modes since it can be abused to exhaust source -+ * ports. - */ - if (s->be->options & PR_O_ABRT_CLOSE) { - channel_auto_read(req); -+ if ((req->flags & (CF_SHUTR|CF_READ_NULL)) && -+ ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)) -+ s->si[1].flags |= SI_FL_NOLINGER; - channel_auto_close(req); - } - else if (s->txn.meth == HTTP_METH_POST) { --- -2.1.4 - diff --git a/0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch b/0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch deleted file mode 100644 index 581ab32..0000000 --- a/0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 68e4fc2b9910dd090c5e729203b72444f75aaa75 Mon Sep 17 00:00:00 2001 -From: Baptiste Assmann -Date: Fri, 1 May 2015 08:09:29 +0200 -Subject: [PATCH 3/9] BUG/MINOR: check: fix tcpcheck error message - -add the keyword 'string' when required (error in a tcpcheck expect -string) -(cherry picked from commit 96a5c9b57738c05ecce7822093b9c4118123dc1e) ---- - src/checks.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/checks.c b/src/checks.c -index 71debb6..8b53f97 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -614,7 +614,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi - } - else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) { - if (check->last_started_step->string) -- chunk_appendf(chk, " (string '%s')", check->last_started_step->string); -+ chunk_appendf(chk, " (expect string '%s')", check->last_started_step->string); - else if (check->last_started_step->expect_regex) - chunk_appendf(chk, " (expect regex)"); - } --- -2.3.7 - diff --git a/0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch b/0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch deleted file mode 100644 index bd9dbcf..0000000 --- a/0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 4f889006269e4d3f802de46f280ed198a15e3a69 Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 13 May 2015 11:23:01 +0200 -Subject: [PATCH 4/9] CLEANUP: checks: fix double usage of cur / current_step - in tcp-checks - -This cleanup is a preliminary requirement to the upcoming fixes for -the bug that affect tcp-check's improper use of lists. It will have -to be backported to 1.5 though it will not easily apply. - -There are two variables pointing to the current rule within the loop, -and either one or the other is used depending on the code blocks, -making it much harder to apply checks to fix the list walking bug. -So first get rid of "cur" and only focus on current_step. -(cherry picked from commit ce8c42a37a44a1e0cb94e81abb7cc2baf3d0ef80) - -[wt: 1.5 doesn't have comments so this patch differs significantly - from 1.6, but it's needed for the next batch of fixes] ---- - src/checks.c | 57 ++++++++++++++++++++++++++++----------------------------- - 1 file changed, 28 insertions(+), 29 deletions(-) - -diff --git a/src/checks.c b/src/checks.c -index 8b53f97..cfdfe8c 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -1859,7 +1859,7 @@ static int tcpcheck_get_step_id(struct server *s) - static void tcpcheck_main(struct connection *conn) - { - char *contentptr; -- struct tcpcheck_rule *cur, *next; -+ struct tcpcheck_rule *next; - int done = 0, ret = 0; - struct check *check = conn->owner; - struct server *s = check->server; -@@ -1916,15 +1916,11 @@ static void tcpcheck_main(struct connection *conn) - check->bo->o = 0; - check->bi->p = check->bi->data; - check->bi->i = 0; -- cur = check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list); -+ check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list); - t->expire = tick_add(now_ms, MS_TO_TICKS(check->inter)); - if (s->proxy->timeout.check) - t->expire = tick_add_ifset(now_ms, s->proxy->timeout.check); - } -- /* keep on processing step */ -- else { -- cur = check->current_step; -- } - - /* It's only the rules which will enable send/recv */ - __conn_data_stop_both(conn); -@@ -1934,7 +1930,7 @@ static void tcpcheck_main(struct connection *conn) - * or if we're about to send a string that does not fit in the remaining space. - */ - if (check->bo->o && -- (&cur->list == head || -+ (&check->current_step->list == head || - check->current_step->action != TCPCHK_ACT_SEND || - check->current_step->string_len >= buffer_total_space(check->bo))) { - -@@ -1949,14 +1945,17 @@ static void tcpcheck_main(struct connection *conn) - } - - /* did we reach the end ? If so, let's check that everything was sent */ -- if (&cur->list == head) { -+ if (&check->current_step->list == head) { - if (check->bo->o) - goto out_need_io; - break; - } - -- /* have 'next' point to the next rule or NULL if we're on the last one */ -- next = (struct tcpcheck_rule *)cur->list.n; -+ /* have 'next' point to the next rule or NULL if we're on the -+ * last one, connect() needs this. -+ */ -+ next = (struct tcpcheck_rule *)check->current_step->list.n; -+ - if (&next->list == head) - next = NULL; - -@@ -2058,8 +2057,7 @@ static void tcpcheck_main(struct connection *conn) - } - - /* allow next rule */ -- cur = (struct tcpcheck_rule *)cur->list.n; -- check->current_step = cur; -+ check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; - - /* don't do anything until the connection is established */ - if (!(conn->flags & CO_FL_CONNECTED)) { -@@ -2113,8 +2111,7 @@ static void tcpcheck_main(struct connection *conn) - *check->bo->p = '\0'; /* to make gdb output easier to read */ - - /* go to next rule and try to send */ -- cur = (struct tcpcheck_rule *)cur->list.n; -- check->current_step = cur; -+ check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; - } /* end 'send' */ - else if (check->current_step->action == TCPCHK_ACT_EXPECT) { - if (unlikely(check->result == CHK_RES_FAILED)) -@@ -2167,14 +2164,14 @@ static void tcpcheck_main(struct connection *conn) - goto out_end_tcpcheck; - } - -- if (!done && (cur->string != NULL) && (check->bi->i < cur->string_len) ) -+ if (!done && (check->current_step->string != NULL) && (check->bi->i < check->current_step->string_len) ) - continue; /* try to read more */ - - tcpcheck_expect: -- if (cur->string != NULL) -- ret = my_memmem(contentptr, check->bi->i, cur->string, cur->string_len) != NULL; -- else if (cur->expect_regex != NULL) -- ret = regex_exec(cur->expect_regex, contentptr); -+ if (check->current_step->string != NULL) -+ ret = my_memmem(contentptr, check->bi->i, check->current_step->string, check->current_step->string_len) != NULL; -+ else if (check->current_step->expect_regex != NULL) -+ ret = regex_exec(check->current_step->expect_regex, contentptr); - - if (!ret && !done) - continue; /* try to read more */ -@@ -2182,11 +2179,11 @@ static void tcpcheck_main(struct connection *conn) - /* matched */ - if (ret) { - /* matched but we did not want to => ERROR */ -- if (cur->inverse) { -+ if (check->current_step->inverse) { - /* we were looking for a string */ -- if (cur->string != NULL) { -+ if (check->current_step->string != NULL) { - chunk_printf(&trash, "TCPCHK matched unwanted content '%s' at step %d", -- cur->string, tcpcheck_get_step_id(s)); -+ check->current_step->string, tcpcheck_get_step_id(s)); - } - else { - /* we were looking for a regex */ -@@ -2198,8 +2195,9 @@ static void tcpcheck_main(struct connection *conn) - } - /* matched and was supposed to => OK, next step */ - else { -- cur = (struct tcpcheck_rule*)cur->list.n; -- check->current_step = cur; -+ /* allow next rule */ -+ check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ - if (check->current_step->action == TCPCHK_ACT_EXPECT) - goto tcpcheck_expect; - __conn_data_stop_recv(conn); -@@ -2208,9 +2206,10 @@ static void tcpcheck_main(struct connection *conn) - else { - /* not matched */ - /* not matched and was not supposed to => OK, next step */ -- if (cur->inverse) { -- cur = (struct tcpcheck_rule*)cur->list.n; -- check->current_step = cur; -+ if (check->current_step->inverse) { -+ /* allow next rule */ -+ check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ - if (check->current_step->action == TCPCHK_ACT_EXPECT) - goto tcpcheck_expect; - __conn_data_stop_recv(conn); -@@ -2218,9 +2217,9 @@ static void tcpcheck_main(struct connection *conn) - /* not matched but was supposed to => ERROR */ - else { - /* we were looking for a string */ -- if (cur->string != NULL) { -+ if (check->current_step->string != NULL) { - chunk_printf(&trash, "TCPCHK did not match content '%s' at step %d", -- cur->string, tcpcheck_get_step_id(s)); -+ check->current_step->string, tcpcheck_get_step_id(s)); - } - else { - /* we were looking for a regex */ --- -2.3.7 - diff --git a/0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch b/0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch deleted file mode 100644 index a115716..0000000 --- a/0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b94a6d5a37499ce6649ad58f4a8c4664779abd8b Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 13 May 2015 11:38:17 +0200 -Subject: [PATCH 5/9] BUG/MEDIUM: checks: do not dereference head of a - tcp-check at the end - -When the end of the list is reached, the current step's action is checked -to know if we must poll or not. Unfortunately, the main reason for going -there is that we walked past the end of list and current_step points to -the head. We cannot dereference ->action since it does not belong to this -structure and can definitely crash if the address is not mapped. - -This bug is unlikely to cause a crash since the action appears just after -the list, and corresponds to the "char *check_req" pointer in the proxy -struct, and it seems that we can't go there with current_step being null. -At worst it can cause the check to register for recv events. - -This fix needs to be backported to 1.5 since the code is incorrect there -as well. -(cherry picked from commit 53c5a049e1f4dbf67412472e23690dc6b3c8d0f8) ---- - src/checks.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/checks.c b/src/checks.c -index cfdfe8c..a887be1 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -2237,10 +2237,12 @@ static void tcpcheck_main(struct connection *conn) - goto out_end_tcpcheck; - - out_need_io: -+ /* warning, current_step may now point to the head */ - if (check->bo->o) - __conn_data_want_send(conn); - -- if (check->current_step->action == TCPCHK_ACT_EXPECT) -+ if (&check->current_step->list != head && -+ check->current_step->action == TCPCHK_ACT_EXPECT) - __conn_data_want_recv(conn); - return; - -@@ -2256,7 +2258,6 @@ static void tcpcheck_main(struct connection *conn) - conn->flags |= CO_FL_ERROR; - - __conn_data_stop_both(conn); -- - return; - } - --- -2.3.7 - diff --git a/0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch b/0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch deleted file mode 100644 index 724286c..0000000 --- a/0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ebb2bceb34d7787453548627ed0e99c60354672b Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 13 May 2015 11:59:14 +0200 -Subject: [PATCH 6/9] CLEANUP: checks: simplify the loop processing of - tcp-checks - -There is some unobvious redundancy between the various ways we can leave -the loop. Some of them can be factored out. So now we leave the loop when -we can't go further, whether it's caused by reaching the end of the rules -or by a blocking I/O. -(cherry picked from commit 263013d031d754c9f96de0d0cb5afcc011af6441) -[wt: this patch is required for the next fix] ---- - src/checks.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/src/checks.c b/src/checks.c -index a887be1..a0c42f2 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -1926,8 +1926,10 @@ static void tcpcheck_main(struct connection *conn) - __conn_data_stop_both(conn); - - while (1) { -- /* we have to try to flush the output buffer before reading, at the end, -- * or if we're about to send a string that does not fit in the remaining space. -+ /* We have to try to flush the output buffer before reading, at -+ * the end, or if we're about to send a string that does not fit -+ * in the remaining space. That explains why we break out of the -+ * loop after this control. - */ - if (check->bo->o && - (&check->current_step->list == head || -@@ -1940,16 +1942,12 @@ static void tcpcheck_main(struct connection *conn) - __conn_data_stop_both(conn); - goto out_end_tcpcheck; - } -- goto out_need_io; -+ break; - } - } - -- /* did we reach the end ? If so, let's check that everything was sent */ -- if (&check->current_step->list == head) { -- if (check->bo->o) -- goto out_need_io; -+ if (&check->current_step->list == head) - break; -- } - - /* have 'next' point to the next rule or NULL if we're on the - * last one, connect() needs this. -@@ -2131,7 +2129,7 @@ static void tcpcheck_main(struct connection *conn) - } - } - else -- goto out_need_io; -+ break; - } - - /* mark the step as started */ -@@ -2233,10 +2231,14 @@ static void tcpcheck_main(struct connection *conn) - } /* end expect */ - } /* end loop over double chained step list */ - -- set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)"); -- goto out_end_tcpcheck; -+ /* We're waiting for some I/O to complete, we've reached the end of the -+ * rules, or both. Do what we have to do, otherwise we're done. -+ */ -+ if (&check->current_step->list == head && !check->bo->o) { -+ set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)"); -+ goto out_end_tcpcheck; -+ } - -- out_need_io: - /* warning, current_step may now point to the head */ - if (check->bo->o) - __conn_data_want_send(conn); --- -2.3.7 - diff --git a/0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch b/0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch deleted file mode 100644 index 8389a58..0000000 --- a/0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 97fccc87f1297d189ee80735e5b8746c34956eda Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 13 May 2015 12:08:21 +0200 -Subject: [PATCH 7/9] BUG/MAJOR: checks: always check for end of list before - proceeding - -This is the most important fix of this series. There's a risk of endless -loop and crashes caused by the fact that we go past the head of the list -when skipping to next rule, without checking if it's still a valid element. -Most of the time, the ->action field is checked, which points to the proxy's -check_req pointer (generally NULL), meaning the element is confused with a -TCPCHK_ACT_SEND action. - -The situation was accidently made worse with the addition of tcp-check -comment since it also skips list elements. However, since the action that -makes it go forward is TCPCHK_ACT_COMMENT (3), there's little chance to -see this as a valid pointer, except on 64-bit machines where it can match -the end of a check_req string pointer. - -This fix heavily depends on previous cleanup and both must be backported -to 1.5 where the bug is present. -(cherry picked from commit f2c87353a7f8160930b5f342bb6d6ad0991ee3d1) -[wt: this patch differs significantly from 1.6 since we don't have comments] ---- - src/cfgparse.c | 4 +++- - src/checks.c | 12 ++++++++++++ - 2 files changed, 15 insertions(+), 1 deletion(-) - -diff --git a/src/cfgparse.c b/src/cfgparse.c -index 746c7eb..dba59d1 100644 ---- a/src/cfgparse.c -+++ b/src/cfgparse.c -@@ -4368,7 +4368,9 @@ stats_error_parsing: - l = (struct list *)&curproxy->tcpcheck_rules; - if (l->p != l->n) { - tcpcheck = (struct tcpcheck_rule *)l->n; -- if (tcpcheck && tcpcheck->action != TCPCHK_ACT_CONNECT) { -+ -+ if (&tcpcheck->list != &curproxy->tcpcheck_rules -+ && tcpcheck->action != TCPCHK_ACT_CONNECT) { - Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n", - file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; -diff --git a/src/checks.c b/src/checks.c -index a0c42f2..e13d561 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -2057,6 +2057,9 @@ static void tcpcheck_main(struct connection *conn) - /* allow next rule */ - check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; - -+ if (&check->current_step->list == head) -+ break; -+ - /* don't do anything until the connection is established */ - if (!(conn->flags & CO_FL_CONNECTED)) { - /* update expire time, should be done by process_chk */ -@@ -2110,6 +2113,9 @@ static void tcpcheck_main(struct connection *conn) - - /* go to next rule and try to send */ - check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ -+ if (&check->current_step->list == head) -+ break; - } /* end 'send' */ - else if (check->current_step->action == TCPCHK_ACT_EXPECT) { - if (unlikely(check->result == CHK_RES_FAILED)) -@@ -2196,6 +2202,9 @@ static void tcpcheck_main(struct connection *conn) - /* allow next rule */ - check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; - -+ if (&check->current_step->list == head) -+ break; -+ - if (check->current_step->action == TCPCHK_ACT_EXPECT) - goto tcpcheck_expect; - __conn_data_stop_recv(conn); -@@ -2208,6 +2217,9 @@ static void tcpcheck_main(struct connection *conn) - /* allow next rule */ - check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; - -+ if (&check->current_step->list == head) -+ break; -+ - if (check->current_step->action == TCPCHK_ACT_EXPECT) - goto tcpcheck_expect; - __conn_data_stop_recv(conn); --- -2.3.7 - diff --git a/0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch b/0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch deleted file mode 100644 index af6dbd2..0000000 --- a/0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 5bff05986c501d9ffb67873b60472f9c2a2e41be Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 13 May 2015 12:24:53 +0200 -Subject: [PATCH 8/9] BUG/MEDIUM: checks: do not dereference a list as a - tcpcheck struct - -The method used to skip to next rule in the list is wrong, it assumes -that the list element starts at the same offset as the rule. It happens -to be true on most architectures since the list is the first element for -now but it's definitely wrong. Now the code doesn't crash anymore when -the struct list is moved anywhere else in the struct tcpcheck_rule. - -This fix must be backported to 1.5. -(cherry picked from commit 5581c27b579cbfc53afb0ca04cdeebe7e2200131) -[wt: changes from 1.6 : no tcp-check comments, check becomes s->proxy] ---- - src/cfgparse.c | 18 +++++++----------- - src/checks.c | 15 +++++++++------ - 2 files changed, 16 insertions(+), 17 deletions(-) - -diff --git a/src/cfgparse.c b/src/cfgparse.c -index dba59d1..e04eff8 100644 ---- a/src/cfgparse.c -+++ b/src/cfgparse.c -@@ -4362,20 +4362,16 @@ stats_error_parsing: - const char *ptr_arg; - int cur_arg; - struct tcpcheck_rule *tcpcheck; -- struct list *l; - - /* check if first rule is also a 'connect' action */ -- l = (struct list *)&curproxy->tcpcheck_rules; -- if (l->p != l->n) { -- tcpcheck = (struct tcpcheck_rule *)l->n; -+ tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list); - -- if (&tcpcheck->list != &curproxy->tcpcheck_rules -- && tcpcheck->action != TCPCHK_ACT_CONNECT) { -- Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n", -- file, linenum); -- err_code |= ERR_ALERT | ERR_FATAL; -- goto out; -- } -+ if (&tcpcheck->list != &curproxy->tcpcheck_rules -+ && tcpcheck->action != TCPCHK_ACT_CONNECT) { -+ Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n", -+ file, linenum); -+ err_code |= ERR_ALERT | ERR_FATAL; -+ goto out; - } - - cur_arg = 2; -diff --git a/src/checks.c b/src/checks.c -index e13d561..27a23b2 100644 ---- a/src/checks.c -+++ b/src/checks.c -@@ -1444,7 +1444,10 @@ static int connect_chk(struct task *t) - quickack = check->type == 0 || check->type == PR_O2_TCPCHK_CHK; - - if (check->type == PR_O2_TCPCHK_CHK && !LIST_ISEMPTY(&s->proxy->tcpcheck_rules)) { -- struct tcpcheck_rule *r = (struct tcpcheck_rule *) s->proxy->tcpcheck_rules.n; -+ struct tcpcheck_rule *r; -+ -+ r = LIST_NEXT(&s->proxy->tcpcheck_rules, struct tcpcheck_rule *, list); -+ - /* if first step is a 'connect', then tcpcheck_main must run it */ - if (r->action == TCPCHK_ACT_CONNECT) { - tcpcheck_main(conn); -@@ -1952,7 +1955,7 @@ static void tcpcheck_main(struct connection *conn) - /* have 'next' point to the next rule or NULL if we're on the - * last one, connect() needs this. - */ -- next = (struct tcpcheck_rule *)check->current_step->list.n; -+ next = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); - - if (&next->list == head) - next = NULL; -@@ -2055,7 +2058,7 @@ static void tcpcheck_main(struct connection *conn) - } - - /* allow next rule */ -- check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); - - if (&check->current_step->list == head) - break; -@@ -2112,7 +2115,7 @@ static void tcpcheck_main(struct connection *conn) - *check->bo->p = '\0'; /* to make gdb output easier to read */ - - /* go to next rule and try to send */ -- check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); - - if (&check->current_step->list == head) - break; -@@ -2200,7 +2203,7 @@ static void tcpcheck_main(struct connection *conn) - /* matched and was supposed to => OK, next step */ - else { - /* allow next rule */ -- check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); - - if (&check->current_step->list == head) - break; -@@ -2215,7 +2218,7 @@ static void tcpcheck_main(struct connection *conn) - /* not matched and was not supposed to => OK, next step */ - if (check->current_step->inverse) { - /* allow next rule */ -- check->current_step = (struct tcpcheck_rule *)check->current_step->list.n; -+ check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list); - - if (&check->current_step->list == head) - break; --- -2.3.7 - diff --git a/0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch b/0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch deleted file mode 100644 index 8eaa439..0000000 --- a/0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 76a06b2804bcdba0fb2c19f834bdb511ce3cf344 Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Wed, 20 May 2015 10:39:04 +0200 -Subject: [PATCH 9/9] BUG/MEDIUM: peers: apply a random reconnection timeout - -Commit 9ff95bb ("BUG/MEDIUM: peers: correctly configure the client timeout") -uncovered an old bug in the peers : upon disconnect, we reconnect immediately. -This sometimes results in both ends to do the same thing in parallel causing -a loop of connect/accept/close/close that can last several seconds. The risk -of occurrence of the trouble increases with latency, and is emphasized by the -fact that idle connections are now frequently recycled (after 5s of idle). - -In order to avoid this we must apply a random delay before reconnecting. -Fortunately the mechanism already supports a reconnect delay, so here we -compute the random timeout when killing a session. The delay is 50ms plus -a random between 0 and 2 seconds. Ideally an exponential back-off would -be preferred but it's preferable to keep the fix simple. - -This bug was reported by Marco Corte. - -This fix must be backported to 1.5 since the fix above was backported into -1.5.12. -(cherry picked from commit b4e34da692d8a7f6837ad16b3389f5830dbc11d2) ---- - src/peers.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/src/peers.c b/src/peers.c -index b196d88..159f0a4 100644 ---- a/src/peers.c -+++ b/src/peers.c -@@ -1063,6 +1063,7 @@ static void peer_session_forceshutdown(struct session * session) - { - struct stream_interface *oldsi = NULL; - struct appctx *appctx = NULL; -+ struct peer_session *ps; - int i; - - for (i = 0; i <= 1; i++) { -@@ -1079,6 +1080,14 @@ static void peer_session_forceshutdown(struct session * session) - if (!appctx) - return; - -+ ps = (struct peer_session *)appctx->ctx.peers.ptr; -+ /* we're killing a connection, we must apply a random delay before -+ * retrying otherwise the other end will do the same and we can loop -+ * for a while. -+ */ -+ if (ps) -+ ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + random() % 2000)); -+ - /* call release to reinit resync states if needed */ - peer_session_release(oldsi); - appctx->st0 = PEER_SESS_ST_END; -@@ -1352,8 +1361,8 @@ static struct task *process_peer_sync(struct task * task) - if (!ps->session) { - /* no active session */ - if (ps->statuscode == 0 || -- ps->statuscode == PEER_SESS_SC_SUCCESSCODE || - ((ps->statuscode == PEER_SESS_SC_CONNECTCODE || -+ ps->statuscode == PEER_SESS_SC_SUCCESSCODE || - ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) && - tick_is_expired(ps->reconnect, now_ms))) { - /* connection never tried -@@ -1364,8 +1373,7 @@ static struct task *process_peer_sync(struct task * task) - /* retry a connect */ - ps->session = peer_session_create(ps->peer, ps); - } -- else if (ps->statuscode == PEER_SESS_SC_CONNECTCODE || -- ps->statuscode == PEER_SESS_SC_CONNECTEDCODE) { -+ else if (!tick_is_expired(ps->reconnect, now_ms)) { - /* If previous session failed during connection - * but reconnection timer is not expired */ - --- -2.3.7 - diff --git a/haproxy-1.5.12.tar.gz b/haproxy-1.5.12.tar.gz deleted file mode 100644 index 31b536a..0000000 --- a/haproxy-1.5.12.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6648dd7d6b958d83dd7101eab5792178212a66c884bec0ebcd8abc39df83bb78 -size 1344813 diff --git a/haproxy-1.5.13.tar.gz b/haproxy-1.5.13.tar.gz new file mode 100644 index 0000000..ab8d807 --- /dev/null +++ b/haproxy-1.5.13.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de901c23d976cb21b816dc671924176918b691a430fb5a52e0f1afbc6faeb5f9 +size 1345323 diff --git a/haproxy.changes b/haproxy.changes index c35d510..edfac34 100644 --- a/haproxy.changes +++ b/haproxy.changes @@ -1,3 +1,88 @@ +------------------------------------------------------------------- +Fri Jun 26 11:45:33 UTC 2015 - kgronlund@suse.com + +- Update to 1.5.13 + - Dropped all patches backported from git, no further changes + than those patches provided. + +- Removed patches: + + Remove 0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch + + Remove 0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch + + Remove 0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch + + Remove 0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch + + Remove 0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch + + Remove 0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch + + Remove 0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch + + Remove 0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch + + Remove 0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch + + Remove 0010-DOC-Update-doc-about-weight-act-and-bck-fields-in-th.patch + + Remove 0011-MINOR-ssl-add-a-destructor-to-free-allocated-SSL-res.patch + + Remove 0012-BUG-MEDIUM-ssl-fix-tune.ssl.default-dh-param-value-b.patch + + Remove 0013-BUG-MINOR-cfgparse-fix-typo-in-option-httplog-error-.patch + + Remove 0014-BUG-MEDIUM-cfgparse-segfault-when-userlist-is-misuse.patch + + Remove 0015-MEDIUM-ssl-replace-standards-DH-groups-with-custom-o.patch + + Remove 0016-BUG-MINOR-debug-display-null-in-place-of-meth.patch + + Remove 0017-CLEANUP-deinit-remove-codes-for-cleaning-p-block_rul.patch + + Remove 0018-BUG-MINOR-ssl-fix-smp_fetch_ssl_fc_session_id.patch + + Remove 0019-MEDIUM-init-don-t-stop-proxies-in-parent-process-whe.patch + + Remove 0020-MINOR-peers-store-the-pointer-to-the-signal-handler.patch + + Remove 0021-MEDIUM-peers-unregister-peers-that-were-never-starte.patch + + Remove 0022-MEDIUM-config-propagate-the-table-s-process-list-to-.patch + + Remove 0023-MEDIUM-init-stop-any-peers-section-not-bound-to-the-.patch + + Remove 0024-MEDIUM-config-validate-that-peers-sections-are-bound.patch + + Remove 0025-MAJOR-peers-allow-peers-section-to-be-used-with-nbpr.patch + + Remove 0026-DOC-relax-the-peers-restriction-to-single-process.patch + + Remove 0027-CLEANUP-config-fix-misleading-information-in-error-m.patch + + Remove 0028-MINOR-config-report-the-number-of-processes-using-a-.patch + + Remove 0029-BUG-MEDIUM-config-properly-compute-the-default-numbe.patch + +------------------------------------------------------------------- +Thu Jun 25 15:01:34 UTC 2015 - kgronlund@suse.com + +- Backport upstream patches: + + DOC: Update doc about weight, act and bck fields in the statistics + + MINOR: ssl: add a destructor to free allocated SSL ressources + + BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value being overwritten + + BUG/MINOR: cfgparse: fix typo in 'option httplog' error message + + BUG/MEDIUM: cfgparse: segfault when userlist is misused + + MEDIUM: ssl: replace standards DH groups with custom ones + + BUG/MINOR: debug: display (null) in place of "meth" + + CLEANUP: deinit: remove codes for cleaning p->block_rules + + BUG/MINOR: ssl: fix smp_fetch_ssl_fc_session_id + + MEDIUM: init: don't stop proxies in parent process when exiting + + MINOR: peers: store the pointer to the signal handler + + MEDIUM: peers: unregister peers that were never started + + MEDIUM: config: propagate the table's process list to the peers sections + + MEDIUM: init: stop any peers section not bound to the correct process + + MEDIUM: config: validate that peers sections are bound to exactly one process + + MAJOR: peers: allow peers section to be used with nbproc > 1 + + DOC: relax the peers restriction to single-process + + CLEANUP: config: fix misleading information in error message. + + MINOR: config: report the number of processes using a peers section in the error case + + BUG/MEDIUM: config: properly compute the default number of processes for a proxy + +- Added patches: + + Add 0010-DOC-Update-doc-about-weight-act-and-bck-fields-in-th.patch + + Add 0011-MINOR-ssl-add-a-destructor-to-free-allocated-SSL-res.patch + + Add 0012-BUG-MEDIUM-ssl-fix-tune.ssl.default-dh-param-value-b.patch + + Add 0013-BUG-MINOR-cfgparse-fix-typo-in-option-httplog-error-.patch + + Add 0014-BUG-MEDIUM-cfgparse-segfault-when-userlist-is-misuse.patch + + Add 0015-MEDIUM-ssl-replace-standards-DH-groups-with-custom-o.patch + + Add 0016-BUG-MINOR-debug-display-null-in-place-of-meth.patch + + Add 0017-CLEANUP-deinit-remove-codes-for-cleaning-p-block_rul.patch + + Add 0018-BUG-MINOR-ssl-fix-smp_fetch_ssl_fc_session_id.patch + + Add 0019-MEDIUM-init-don-t-stop-proxies-in-parent-process-whe.patch + + Add 0020-MINOR-peers-store-the-pointer-to-the-signal-handler.patch + + Add 0021-MEDIUM-peers-unregister-peers-that-were-never-starte.patch + + Add 0022-MEDIUM-config-propagate-the-table-s-process-list-to-.patch + + Add 0023-MEDIUM-init-stop-any-peers-section-not-bound-to-the-.patch + + Add 0024-MEDIUM-config-validate-that-peers-sections-are-bound.patch + + Add 0025-MAJOR-peers-allow-peers-section-to-be-used-with-nbpr.patch + + Add 0026-DOC-relax-the-peers-restriction-to-single-process.patch + + Add 0027-CLEANUP-config-fix-misleading-information-in-error-m.patch + + Add 0028-MINOR-config-report-the-number-of-processes-using-a-.patch + + Add 0029-BUG-MEDIUM-config-properly-compute-the-default-numbe.patch + ------------------------------------------------------------------- Mon May 25 09:34:58 UTC 2015 - kgronlund@suse.com diff --git a/haproxy.spec b/haproxy.spec index af68597..9710710 100644 --- a/haproxy.spec +++ b/haproxy.spec @@ -33,7 +33,7 @@ %bcond_without apparmor Name: haproxy -Version: 1.5.12 +Version: 1.5.13 Release: 0 # # @@ -61,22 +61,6 @@ Patch1: haproxy-1.2.16_config_haproxy_user.patch Patch2: haproxy-makefile_lib.patch Patch3: sec-options.patch Patch4: haproxy-1.5.8-fix-bashisms.patch -Patch5: 0001-BUG-MEDIUM-stats-properly-initialize-the-scope-befor.patch -Patch6: 0002-BUG-MEDIUM-http-don-t-forward-client-shutdown-withou.patch -# PATCH-FIX-UPSTREAM: BUG/MINOR: check: fix tcpcheck error message -Patch7: 0003-BUG-MINOR-check-fix-tcpcheck-error-message.patch -# PATCH-FIX-UPSTREAM: CLEANUP: checks: fix double usage of cur / current_step in tcp-checks -Patch8: 0004-CLEANUP-checks-fix-double-usage-of-cur-current_step-.patch -# PATCH-FIX-UPSTREAM: BUG/MEDIUM: checks: do not dereference head of a tcp-check at the end -Patch9: 0005-BUG-MEDIUM-checks-do-not-dereference-head-of-a-tcp-c.patch -# PATCH-FIX-UPSTREAM: CLEANUP: checks: simplify the loop processing of tcp-checks -Patch10: 0006-CLEANUP-checks-simplify-the-loop-processing-of-tcp-c.patch -# PATCH-FIX-UPSTREAM: BUG/MAJOR: checks: always check for end of list before proceeding -Patch11: 0007-BUG-MAJOR-checks-always-check-for-end-of-list-before.patch -# PATCH-FIX-UPSTREAM: BUG/MEDIUM: checks: do not dereference a list as a tcpcheck struct -Patch12: 0008-BUG-MEDIUM-checks-do-not-dereference-a-list-as-a-tcp.patch -# PATCH-FIX-UPSTREAM: BUG/MEDIUM: peers: apply a random reconnection timeout -Patch13: 0009-BUG-MEDIUM-peers-apply-a-random-reconnection-timeout.patch # Source99: haproxy-rpmlintrc @@ -112,15 +96,7 @@ the most work done from every CPU cycle. %patch2 %patch3 %patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 + %build %{__make} \