- Update haproxy download URL and hash - Remove all already included patches Signed-off-by: Christian Lachner <gladiac@gmail.com>lilik-openwrt-22.03
@ -1,61 +0,0 @@ | |||
From 2fcd544272a5498ffa49544e9f06b51bc93e55d1 Mon Sep 17 00:00:00 2001 | |||
From: Olivier Houchard <ohouchard@haproxy.com> | |||
Date: Tue, 13 Feb 2018 15:17:23 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: ssl: Don't always treat SSL_ERROR_SYSCALL as | |||
unrecovarable. | |||
Bart Geesink reported some random errors appearing under the form of | |||
termination flags SD in the logs for connections involving SSL traffic | |||
to reach the servers. | |||
Tomek Gacek and Mateusz Malek finally narrowed down the problem to commit | |||
c2aae74 ("MEDIUM: ssl: Handle early data with OpenSSL 1.1.1"). It happens | |||
that the special case of SSL_ERROR_SYSCALL isn't handled anymore since | |||
this commit. | |||
SSL_read() might return <= 0, and SSL_get_erro() return SSL_ERROR_SYSCALL, | |||
without meaning the connection is gone. Before flagging the connection | |||
as in error, check the errno value. | |||
This should be backported to 1.8. | |||
(cherry picked from commit 7e2e505006feb8f3b4a7f9e0ac5e89b5a8c4895e) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/ssl_sock.c | 9 ++++++++- | |||
1 file changed, 8 insertions(+), 1 deletion(-) | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index aecf3dd..f118724 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -5437,6 +5437,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun | |||
break; | |||
} else if (ret == SSL_ERROR_ZERO_RETURN) | |||
goto read0; | |||
+ /* For SSL_ERROR_SYSCALL, make sure the error is | |||
+ * unrecoverable before flagging the connection as | |||
+ * in error. | |||
+ */ | |||
+ if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN)) | |||
+ goto clear_ssl_error; | |||
/* otherwise it's a real error */ | |||
goto out_error; | |||
} | |||
@@ -5451,11 +5457,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun | |||
conn_sock_read0(conn); | |||
goto leave; | |||
out_error: | |||
+ conn->flags |= CO_FL_ERROR; | |||
+clear_ssl_error: | |||
/* Clear openssl global errors stack */ | |||
ssl_sock_dump_errors(conn); | |||
ERR_clear_error(); | |||
- conn->flags |= CO_FL_ERROR; | |||
goto leave; | |||
} | |||
-- | |||
1.7.10.4 | |||
@ -1,63 +0,0 @@ | |||
From f7fa1d461aa71bbc8a6c23fdcfc305f2e52ce5dd Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Mon, 19 Feb 2018 14:25:15 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: ssl: Shutdown the connection for reading on | |||
SSL_ERROR_SYSCALL | |||
When SSL_read returns SSL_ERROR_SYSCALL and errno is unset or set to EAGAIN, the | |||
connection must be shut down for reading. Else, the connection loops infinitly, | |||
consuming all the CPU. | |||
The bug was introduced in the commit 7e2e50500 ("BUG/MEDIUM: ssl: Don't always | |||
treat SSL_ERROR_SYSCALL as unrecovarable."). This patch must be backported in | |||
1.8 too. | |||
(cherry picked from commit 4ac77a98cda3d0f9b1d9de7bbbda2c91357f0767) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/ssl_sock.c | 14 ++++++++------ | |||
1 file changed, 8 insertions(+), 6 deletions(-) | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index f118724..a065bbb 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -5437,10 +5437,9 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun | |||
break; | |||
} else if (ret == SSL_ERROR_ZERO_RETURN) | |||
goto read0; | |||
- /* For SSL_ERROR_SYSCALL, make sure the error is | |||
- * unrecoverable before flagging the connection as | |||
- * in error. | |||
- */ | |||
+ /* For SSL_ERROR_SYSCALL, make sure to clear the error | |||
+ * stack before shutting down the connection for | |||
+ * reading. */ | |||
if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN)) | |||
goto clear_ssl_error; | |||
/* otherwise it's a real error */ | |||
@@ -5453,16 +5452,19 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun | |||
conn_cond_update_sock_polling(conn); | |||
return done; | |||
+ clear_ssl_error: | |||
+ /* Clear openssl global errors stack */ | |||
+ ssl_sock_dump_errors(conn); | |||
+ ERR_clear_error(); | |||
read0: | |||
conn_sock_read0(conn); | |||
goto leave; | |||
+ | |||
out_error: | |||
conn->flags |= CO_FL_ERROR; | |||
-clear_ssl_error: | |||
/* Clear openssl global errors stack */ | |||
ssl_sock_dump_errors(conn); | |||
ERR_clear_error(); | |||
- | |||
goto leave; | |||
} | |||
-- | |||
1.7.10.4 | |||
@ -1,69 +0,0 @@ | |||
From 8a5949f2d74c3a3a6c6da25449992c312b183ef3 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Fri, 2 Feb 2018 15:54:15 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: http: Switch the HTTP response in tunnel mode as | |||
earlier as possible | |||
When the body length is undefined (no Content-Length or Transfer-Encoding | |||
headers), The reponse remains in ending mode, waiting the request is done. So, | |||
most of time this is not a problem because the resquest is done before the | |||
response. But when a client sends data to a server that replies without waiting | |||
all the data, it is really not desirable to wait the end of the request to | |||
finish the response. | |||
This bug was introduced when the tunneling of the request and the reponse was | |||
refactored, in commit 4be980391 ("MINOR: http: Switch requests/responses in | |||
TUNNEL mode only by checking txn flag"). | |||
This patch should be backported in 1.8 and 1.7. | |||
(cherry picked from commit fd04fcf5edb0a24cd29ce8f4d4dc2aa3a0e2e82c) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/proto_http.c | 15 +++++---------- | |||
1 file changed, 5 insertions(+), 10 deletions(-) | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index 64bd410..29880ea 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -4634,16 +4634,8 @@ int http_sync_res_state(struct stream *s) | |||
* let's enforce it now that we're not expecting any new | |||
* data to come. The caller knows the stream is complete | |||
* once both states are CLOSED. | |||
- * | |||
- * However, there is an exception if the response length | |||
- * is undefined. In this case, we switch in TUNNEL mode. | |||
*/ | |||
- if (!(txn->rsp.flags & HTTP_MSGF_XFER_LEN)) { | |||
- channel_auto_read(chn); | |||
- txn->rsp.msg_state = HTTP_MSG_TUNNEL; | |||
- chn->flags |= CF_NEVER_WAIT; | |||
- } | |||
- else if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) { | |||
+ if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) { | |||
channel_shutr_now(chn); | |||
channel_shutw_now(chn); | |||
} | |||
@@ -6241,6 +6233,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg) | |||
/* The server still sending data that should be filtered */ | |||
if (!(chn->flags & CF_SHUTR) && HAS_DATA_FILTERS(s, chn)) | |||
goto missing_data_or_waiting; | |||
+ msg->msg_state = HTTP_MSG_TUNNEL; | |||
+ goto ending; | |||
} | |||
msg->msg_state = HTTP_MSG_ENDING; | |||
@@ -6262,7 +6256,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg) | |||
/* default_ret */ 1, | |||
/* on_error */ goto error, | |||
/* on_wait */ goto waiting); | |||
- msg->msg_state = HTTP_MSG_DONE; | |||
+ if (msg->msg_state == HTTP_MSG_ENDING) | |||
+ msg->msg_state = HTTP_MSG_DONE; | |||
return 1; | |||
missing_data_or_waiting: | |||
-- | |||
1.7.10.4 | |||
@ -1,103 +0,0 @@ | |||
From 7ccf7c9791f2b2329f3940d1347618af3a77bebc Mon Sep 17 00:00:00 2001 | |||
From: Emeric Brun <ebrun@haproxy.com> | |||
Date: Mon, 19 Feb 2018 15:59:48 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: ssl/sample: ssl_bc_* fetch keywords are broken. | |||
Since the split between connections and conn-stream objects, this | |||
keywords are broken. | |||
This patch must be backported in 1.8 | |||
(cherry picked from commit eb8def9f34c37537d56a69fcd211d4c4c8006bea) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/ssl_sock.c | 31 ++++++++++++++----------------- | |||
1 file changed, 14 insertions(+), 17 deletions(-) | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index 4d0d5db..d832d76 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -6580,8 +6580,8 @@ smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char * | |||
static int | |||
smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
smp->data.type = SMP_T_BOOL; | |||
smp->data.u.sint = (conn && conn->xprt == &ssl_sock); | |||
@@ -6625,8 +6625,8 @@ smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const ch | |||
static int | |||
smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
smp->flags = 0; | |||
if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock) | |||
@@ -6651,9 +6651,8 @@ smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char * | |||
static int | |||
smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
- | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
int sint; | |||
smp->flags = 0; | |||
@@ -6676,8 +6675,8 @@ smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const c | |||
static int | |||
smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
smp->flags = 0; | |||
if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock) | |||
@@ -6747,8 +6746,8 @@ smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw | |||
static int | |||
smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
smp->flags = 0; | |||
if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock) | |||
@@ -6773,9 +6772,8 @@ static int | |||
smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
#if OPENSSL_VERSION_NUMBER > 0x0090800fL | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
- | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
SSL_SESSION *ssl_sess; | |||
smp->flags = SMP_F_CONST; | |||
@@ -6917,9 +6915,8 @@ static int | |||
smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private) | |||
{ | |||
#if OPENSSL_VERSION_NUMBER > 0x0090800fL | |||
- struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : | |||
- smp->strm ? smp->strm->si[1].end : NULL); | |||
- | |||
+ struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) : | |||
+ smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL; | |||
int finished_len; | |||
struct chunk *finished_trash; | |||
-- | |||
1.7.10.4 | |||
@ -1,71 +0,0 @@ | |||
From 6fc36785addd45cc76a029a023296def53cff135 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Tue, 27 Feb 2018 15:37:25 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: h2: always consume any trailing data after end | |||
of output buffers | |||
In case a stream tries to emit more data than advertised by the chunks | |||
or content-length headers, the extra data remains in the channel's output | |||
buffer until the channel's timeout expires. It can easily happen when | |||
sending malformed error files making use of a wrong content-length or | |||
having extra CRLFs after the empty chunk. It may also be possible to | |||
forge such a bad response using Lua. | |||
The H1 to H2 encoder must protect itself against this by marking the data | |||
presented to it as consumed if it decides to discard them, so that the | |||
sending stream doesn't wait for the timeout to trigger. | |||
The visible effect of this problem is a huge memory usage and a high | |||
concurrent connection count during benchmarks when using such bad data | |||
(a typical place where this easily happens). | |||
This fix must be backported to 1.8. | |||
(cherry picked from commit 35a62705df65632e2717ae0d20a93e0cb3f8f163) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/mux_h2.c | 13 ++++++++++++- | |||
1 file changed, 12 insertions(+), 1 deletion(-) | |||
diff --git a/src/mux_h2.c b/src/mux_h2.c | |||
index caae041..4303a06 100644 | |||
--- a/src/mux_h2.c | |||
+++ b/src/mux_h2.c | |||
@@ -3020,6 +3020,9 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf) | |||
* body or directly end in TRL2. | |||
*/ | |||
if (es_now) { | |||
+ // trim any possibly pending data (eg: inconsistent content-length) | |||
+ bo_del(buf, buf->o); | |||
+ | |||
h1m->state = HTTP_MSG_DONE; | |||
h2s->flags |= H2_SF_ES_SENT; | |||
if (h2s->st == H2_SS_OPEN) | |||
@@ -3269,8 +3272,12 @@ static int h2s_frt_make_resp_data(struct h2s *h2s, struct buffer *buf) | |||
else | |||
h2c_stream_close(h2c, h2s); | |||
- if (!(h1m->flags & H1_MF_CHNK)) | |||
+ if (!(h1m->flags & H1_MF_CHNK)) { | |||
+ // trim any possibly pending data (eg: inconsistent content-length) | |||
+ bo_del(buf, buf->o); | |||
+ | |||
h1m->state = HTTP_MSG_DONE; | |||
+ } | |||
h2s->flags |= H2_SF_ES_SENT; | |||
} | |||
@@ -3319,6 +3326,10 @@ static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags) | |||
} | |||
total += count; | |||
bo_del(buf, count); | |||
+ | |||
+ // trim any possibly pending data (eg: extra CR-LF, ...) | |||
+ bo_del(buf, buf->o); | |||
+ | |||
h2s->res.state = HTTP_MSG_DONE; | |||
break; | |||
} | |||
-- | |||
1.7.10.4 | |||
@ -1,33 +0,0 @@ | |||
From fefb8592821ff0fa56f435c581d6e92e563e7ad7 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Mon, 26 Feb 2018 10:47:03 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: buffer: Fix the wrapping case in bo_putblk | |||
When the block of data need to be split to support the wrapping, the start of | |||
the second block of data was wrong. We must be sure to skip data copied during | |||
the first memcpy. | |||
This patch must be backported to 1.8, 1.7, 1.6 and 1.5. | |||
(cherry picked from commit b2b279464c5c0f3dfadf02333e06eb0ae8ae8793) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
include/common/buffer.h | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/include/common/buffer.h b/include/common/buffer.h | |||
index 976085e..ae9aafd 100644 | |||
--- a/include/common/buffer.h | |||
+++ b/include/common/buffer.h | |||
@@ -468,7 +468,7 @@ static inline int bo_putblk(struct buffer *b, const char *blk, int len) | |||
memcpy(b->p, blk, half); | |||
b->p = b_ptr(b, half); | |||
if (len > half) { | |||
- memcpy(b->p, blk, len - half); | |||
+ memcpy(b->p, blk + half, len - half); | |||
b->p = b_ptr(b, half); | |||
} | |||
b->o += len; | |||
-- | |||
1.7.10.4 | |||
@ -1,33 +0,0 @@ | |||
From 14f325000b91649b9d117c4d53d6b194ed3c7b11 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Mon, 26 Feb 2018 10:51:28 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: buffer: Fix the wrapping case in bi_putblk | |||
When the block of data need to be split to support the wrapping, the start of | |||
the second block of data was wrong. We must be sure to skup data copied during | |||
the first memcpy. | |||
This patch must be backported to 1.8. | |||
(cherry picked from commit ca6ef506610e9d78f99b7ab2095ce0f8a47e18df) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
include/common/buffer.h | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/include/common/buffer.h b/include/common/buffer.h | |||
index ae9aafd..0e63913 100644 | |||
--- a/include/common/buffer.h | |||
+++ b/include/common/buffer.h | |||
@@ -577,7 +577,7 @@ static inline int bi_putblk(struct buffer *b, const char *blk, int len) | |||
memcpy(bi_end(b), blk, half); | |||
if (len > half) | |||
- memcpy(b_ptr(b, b->i + half), blk, len - half); | |||
+ memcpy(b_ptr(b, b->i + half), blk + half, len - half); | |||
b->i += len; | |||
return len; | |||
} | |||
-- | |||
1.7.10.4 | |||
@ -1,46 +0,0 @@ | |||
From ccfb5d755f1708f890b197375d962d8c938e78bd Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Mon, 5 Mar 2018 16:10:54 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: h2: also arm the h2 timeout when sending | |||
Right now the h2 idle timeout is only set when there is no stream. If we | |||
fail to send because the socket buffers are full (generally indicating | |||
the client has left), we also need to arm it so that we can properly | |||
expire such connections, otherwise some failed transfers might leave | |||
H2 connections pending forever. | |||
Thanks to Thierry Fournier for the diag and the traces. | |||
This patch needs to be backported to 1.8. | |||
(cherry picked from commit 84b118f3120b3c61156f0ada12ae6456bd1a0b5a) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/mux_h2.c | 4 ++-- | |||
1 file changed, 2 insertions(+), 2 deletions(-) | |||
diff --git a/src/mux_h2.c b/src/mux_h2.c | |||
index 4303a06..5446fd4 100644 | |||
--- a/src/mux_h2.c | |||
+++ b/src/mux_h2.c | |||
@@ -2329,7 +2329,7 @@ static int h2_wake(struct connection *conn) | |||
} | |||
if (h2c->task) { | |||
- if (eb_is_empty(&h2c->streams_by_id)) { | |||
+ if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) { | |||
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout); | |||
task_queue(h2c->task); | |||
} | |||
@@ -2501,7 +2501,7 @@ static void h2_detach(struct conn_stream *cs) | |||
h2_release(h2c->conn); | |||
} | |||
else if (h2c->task) { | |||
- if (eb_is_empty(&h2c->streams_by_id)) { | |||
+ if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) { | |||
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout); | |||
task_queue(h2c->task); | |||
} | |||
-- | |||
1.7.10.4 | |||
@ -1,55 +0,0 @@ | |||
From 5149cd3c7abad68ddb19a0a5b3b604786d5f1b95 Mon Sep 17 00:00:00 2001 | |||
From: =?utf8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr> | |||
Date: Mon, 12 Mar 2018 21:47:39 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: fix a 100% cpu usage with cpu-map and | |||
nbthread/nbproc | |||
Krishna Kumar reported a 100% cpu usage with a configuration using | |||
cpu-map and a high number of threads, | |||
Indeed, this minimal configuration to reproduce the issue : | |||
global | |||
nbthread 40 | |||
cpu-map auto:1/1-40 0-39 | |||
frontend test | |||
bind :8000 | |||
This is due to a wrong type in a shift operator (int vs unsigned long int), | |||
causing an endless loop while applying the cpu affinity on threads. The same | |||
issue may also occur with nbproc under FreeBSD. This commit addresses both | |||
cases. | |||
This patch must be backported to 1.8. | |||
(cherry picked from commit d400ab3a369523538c426cb70e059954c76b69c3) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/haproxy.c | 4 ++-- | |||
1 file changed, 2 insertions(+), 2 deletions(-) | |||
diff --git a/src/haproxy.c b/src/haproxy.c | |||
index 09f7b5e..7d6e019 100644 | |||
--- a/src/haproxy.c | |||
+++ b/src/haproxy.c | |||
@@ -2838,7 +2838,7 @@ int main(int argc, char **argv) | |||
CPU_ZERO(&cpuset); | |||
while ((i = ffsl(cpu_map)) > 0) { | |||
CPU_SET(i - 1, &cpuset); | |||
- cpu_map &= ~(1 << (i - 1)); | |||
+ cpu_map &= ~(1UL << (i - 1)); | |||
} | |||
ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset), &cpuset); | |||
} | |||
@@ -3038,7 +3038,7 @@ int main(int argc, char **argv) | |||
while ((j = ffsl(cpu_map)) > 0) { | |||
CPU_SET(j - 1, &cpuset); | |||
- cpu_map &= ~(1 << (j - 1)); | |||
+ cpu_map &= ~(1UL << (j - 1)); | |||
} | |||
pthread_setaffinity_np(threads[i], | |||
sizeof(cpuset), &cpuset); | |||
-- | |||
1.7.10.4 | |||
@ -1,43 +0,0 @@ | |||
From 7034083b5063d28276b986d645d18071aba5f4d5 Mon Sep 17 00:00:00 2001 | |||
From: Christopher Faulet <cfaulet@haproxy.com> | |||
Date: Wed, 28 Feb 2018 13:33:26 +0100 | |||
Subject: [PATCH] BUG/MEDIUM: spoe: Remove idle applets from idle list when | |||
HAProxy is stopping | |||
In the SPOE applet's handler, when an applet is switched from the state IDLE to | |||
PROCESSING, it is removed for the list of idle applets. But when HAProxy is | |||
stopping, this applet can be switched to DISCONNECT. In this case, we also need | |||
to remove it from the list of idle applets. Else the applet is removed but still | |||
present in the list. It could lead to a segmentation fault or an infinite loop, | |||
depending the code path. | |||
(cherry picked from commit 7d9f1ba246055046eed547fa35aa546683021dce) | |||
[wt: adapted context for 1.8] | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
--- | |||
src/flt_spoe.c | 2 +- | |||
1 file changed, 1 insertion(+), 1 deletion(-) | |||
diff --git a/src/flt_spoe.c b/src/flt_spoe.c | |||
index 8fb6e0b..e76a352 100644 | |||
--- a/src/flt_spoe.c | |||
+++ b/src/flt_spoe.c | |||
@@ -1866,6 +1866,7 @@ spoe_handle_appctx(struct appctx *appctx) | |||
goto switchstate; | |||
case SPOE_APPCTX_ST_IDLE: | |||
+ agent->rt[tid].applets_idle--; | |||
if (stopping && | |||
LIST_ISEMPTY(&agent->rt[tid].sending_queue) && | |||
LIST_ISEMPTY(&SPOE_APPCTX(appctx)->waiting_queue)) { | |||
@@ -1874,7 +1875,6 @@ spoe_handle_appctx(struct appctx *appctx) | |||
appctx->st0 = SPOE_APPCTX_ST_DISCONNECT; | |||
goto switchstate; | |||
} | |||
- agent->rt[tid].applets_idle--; | |||
appctx->st0 = SPOE_APPCTX_ST_PROCESSING; | |||
/* fall through */ | |||
-- | |||
1.7.10.4 | |||