haproxy: Update all patches for HAProxy v1.8.19lilik-openwrt-22.03
@ -0,0 +1,50 @@ | |||||
commit 7c3fd37724c58cf09359e0d381a9be305dd7869b | |||||
Author: Olivier Houchard <cognet@ci0.org> | |||||
Date: Mon Feb 25 16:18:16 2019 +0100 | |||||
BUG/MAJOR: listener: Make sure the listener exist before using it. | |||||
In listener_accept(), make sure we have a listener before attempting to | |||||
use it. | |||||
An another thread may have closed the FD meanwhile, and set fdtab[fd].owner | |||||
to NULL. | |||||
As the listener is not free'd, it is ok to attempt to accept() a new | |||||
connection even if the listener was closed. At worst the fd has been | |||||
reassigned to another connection, and accept() will fail anyway. | |||||
Many thanks to Richard Russo for reporting the problem, and suggesting the | |||||
fix. | |||||
This should be backported to 1.9 and 1.8. | |||||
(cherry picked from commit d16a9dfed80e75d730754b717370515265698cdd) | |||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | |||||
(cherry picked from commit a2511ed1fcdfa8047dbe2268fc0259f9b06cf891) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
diff --git a/src/listener.c b/src/listener.c | |||||
index a30efe03..5f6fafbc 100644 | |||||
--- a/src/listener.c | |||||
+++ b/src/listener.c | |||||
@@ -441,8 +441,8 @@ void delete_listener(struct listener *listener) | |||||
void listener_accept(int fd) | |||||
{ | |||||
struct listener *l = fdtab[fd].owner; | |||||
- struct proxy *p = l->bind_conf->frontend; | |||||
- int max_accept = l->maxaccept ? l->maxaccept : 1; | |||||
+ struct proxy *p; | |||||
+ int max_accept; | |||||
int expire; | |||||
int cfd; | |||||
int ret; | |||||
@@ -450,6 +450,10 @@ void listener_accept(int fd) | |||||
static int accept4_broken; | |||||
#endif | |||||
+ if (!l) | |||||
+ return; | |||||
+ p = l->bind_conf->frontend; | |||||
+ max_accept = l->maxaccept ? l->maxaccept : 1; | |||||
if (HA_SPIN_TRYLOCK(LISTENER_LOCK, &l->lock)) | |||||
return; | |||||
@ -0,0 +1,67 @@ | |||||
commit 78714ea673cefa83d3dff5aa9aa5e97726cfb5cd | |||||
Author: Willy Tarreau <w@1wt.eu> | |||||
Date: Mon Feb 25 15:02:04 2019 +0100 | |||||
BUG/MINOR: listener: keep accept rate counters accurate under saturation | |||||
The test on l->nbconn forces to exit the loop before updating the freq | |||||
counters, so the last session which reaches a listener's limit will not | |||||
be accounted for in the session rate measurement. | |||||
Let's move the test at the beginning of the loop and mark the listener | |||||
as saturated on exit. | |||||
This may be backported to 1.9 and 1.8. | |||||
(cherry picked from commit 741b4d6b7aad1e4a66dd8584b5eff729b08fade7) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
(cherry picked from commit 5c7c7e447df84a04bda88c40382b652cdb77a079) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
diff --git a/src/listener.c b/src/listener.c | |||||
index 5f6fafbc..b94d823c 100644 | |||||
--- a/src/listener.c | |||||
+++ b/src/listener.c | |||||
@@ -457,11 +457,6 @@ void listener_accept(int fd) | |||||
if (HA_SPIN_TRYLOCK(LISTENER_LOCK, &l->lock)) | |||||
return; | |||||
- if (unlikely(l->nbconn >= l->maxconn)) { | |||||
- listener_full(l); | |||||
- goto end; | |||||
- } | |||||
- | |||||
if (!(l->options & LI_O_UNLIMITED) && global.sps_lim) { | |||||
int max = freq_ctr_remain(&global.sess_per_sec, global.sps_lim, 0); | |||||
@@ -520,7 +515,7 @@ void listener_accept(int fd) | |||||
* worst case. If we fail due to system limits or temporary resource | |||||
* shortage, we try again 100ms later in the worst case. | |||||
*/ | |||||
- while (max_accept--) { | |||||
+ while (l->nbconn < l->maxconn && max_accept--) { | |||||
struct sockaddr_storage addr; | |||||
socklen_t laddr = sizeof(addr); | |||||
unsigned int count; | |||||
@@ -627,11 +622,6 @@ void listener_accept(int fd) | |||||
goto transient_error; | |||||
} | |||||
- if (l->nbconn >= l->maxconn) { | |||||
- listener_full(l); | |||||
- goto end; | |||||
- } | |||||
- | |||||
/* increase the per-process number of cumulated connections */ | |||||
if (!(l->options & LI_O_UNLIMITED)) { | |||||
count = update_freq_ctr(&global.sess_per_sec, 1); | |||||
@@ -659,6 +649,9 @@ void listener_accept(int fd) | |||||
limit_listener(l, &global_listener_queue); | |||||
task_schedule(global_listener_queue_task, tick_first(expire, global_listener_queue_task->expire)); | |||||
end: | |||||
+ if (l->nbconn >= l->maxconn) | |||||
+ listener_full(l); | |||||
+ | |||||
HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock); | |||||
} | |||||
@ -0,0 +1,37 @@ | |||||
commit 4c82743abd299f0aa8105e98ec92b76375a7f344 | |||||
Author: Olivier Houchard <ohouchard@haproxy.com> | |||||
Date: Thu Mar 7 14:19:24 2019 +0100 | |||||
BUG/MEDIUM: logs: Only attempt to free startup_logs once. | |||||
deinit_log_buffers() can be called once per thread, however startup_logs | |||||
is common to all threads. So only attempt to free it once. | |||||
This should be backported to 1.9 and 1.8. | |||||
(cherry picked from commit 7c49711d6041d1afc42d5b310ddfd7d6f6817c3c) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
(cherry picked from commit bc3e21b27849275306a0580488613b7dfd4d8eb5) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
diff --git a/src/log.c b/src/log.c | |||||
index b3f33662..9c112255 100644 | |||||
--- a/src/log.c | |||||
+++ b/src/log.c | |||||
@@ -1380,11 +1380,15 @@ int init_log_buffers() | |||||
/* Deinitialize log buffers used for syslog messages */ | |||||
void deinit_log_buffers() | |||||
{ | |||||
+ void *tmp_startup_logs; | |||||
+ | |||||
free(logheader); | |||||
free(logheader_rfc5424); | |||||
free(logline); | |||||
free(logline_rfc5424); | |||||
- free(startup_logs); | |||||
+ tmp_startup_logs = HA_ATOMIC_XCHG(&startup_logs, NULL); | |||||
+ free(tmp_startup_logs); | |||||
+ | |||||
logheader = NULL; | |||||
logheader_rfc5424 = NULL; | |||||
logline = NULL; |
@ -0,0 +1,35 @@ | |||||
commit 63f5dbf1b9fcdc5b10537d733b0e0798905ff1dc | |||||
Author: Dragan Dosen <ddosen@haproxy.com> | |||||
Date: Thu Mar 7 15:24:23 2019 +0100 | |||||
BUG/MEDIUM: 51d: fix possible segfault on deinit_51degrees() | |||||
When haproxy is built with 51Degrees support, but not configured to use | |||||
51Degrees database, a segfault can occur when deinit_51degrees() | |||||
function is called, eg. during soft-stop on SIGUSR1 signal. | |||||
Only builds that use Pattern algorithm are affected. | |||||
This fix must be backported to all stable branches where 51Degrees | |||||
support is available. Additional adjustments are required for some | |||||
branches due to API and naming changes. | |||||
(cherry picked from commit bc6218e1b02860c6cdad0d2bb4dc8874557087f8) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
(cherry picked from commit 4e0363e84cb3f6ca341e1f83c6fd490c76c9ae6b) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
diff --git a/src/51d.c b/src/51d.c | |||||
index a36333ef..03101136 100644 | |||||
--- a/src/51d.c | |||||
+++ b/src/51d.c | |||||
@@ -639,7 +639,8 @@ static void deinit_51degrees(void) | |||||
free(global_51degrees.header_names); | |||||
#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED | |||||
- fiftyoneDegreesWorksetPoolFree(global_51degrees.pool); | |||||
+ if (global_51degrees.pool) | |||||
+ fiftyoneDegreesWorksetPoolFree(global_51degrees.pool); | |||||
#endif | |||||
#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED | |||||
free(global_51degrees.device_offsets.firstOffset); |
@ -0,0 +1,34 @@ | |||||
commit 57e2606f70fa8d26fe4b5563ba72a6c7f2a25655 | |||||
Author: Lukas Tribus <lukas@ltri.eu> | |||||
Date: Tue Mar 5 23:14:32 2019 +0100 | |||||
BUG/MINOR: ssl: fix warning about ssl-min/max-ver support | |||||
In 84e417d8 ("MINOR: ssl: support Openssl 1.1.1 early callback for | |||||
switchctx") the code was extended to also support OpenSSL 1.1.1 | |||||
(code already supported BoringSSL). A configuration check warning | |||||
was updated but with the wrong logic, the #ifdef needs a && instead | |||||
of an ||. | |||||
Reported in #54. | |||||
Should be backported to 1.8. | |||||
(cherry picked from commit 1aabc939780d5eab1f88089d01fb077ad9315c65) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
(cherry picked from commit f407d16b8f4cf2afb148668a23a1ba1cc4dd942a) | |||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org> | |||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||||
index 7736c324..afdb1fce 100644 | |||||
--- a/src/ssl_sock.c | |||||
+++ b/src/ssl_sock.c | |||||
@@ -7418,7 +7418,7 @@ static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_ | |||||
static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err) | |||||
{ | |||||
-#if (OPENSSL_VERSION_NUMBER < 0x10101000L) || !defined(OPENSSL_IS_BORINGSSL) | |||||
+#if (OPENSSL_VERSION_NUMBER < 0x10101000L) && !defined(OPENSSL_IS_BORINGSSL) | |||||
ha_warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n"); | |||||
#endif | |||||
return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err); |
@ -0,0 +1,49 @@ | |||||
commit 62aec002ccd6a7129b4f5e2e88be1957a6b2308b | |||||
Author: Olivier Houchard <ohouchard@haproxy.com> | |||||
Date: Thu Mar 7 18:48:22 2019 +0100 | |||||
MEDIUM: threads: Use __ATOMIC_SEQ_CST when using the newer atomic API. | |||||
When using the new __atomic* API, ask the compiler to generate barriers. | |||||
A variant of those functions that don't generate barriers will be added later. | |||||
Before that, using HA_ATOMIC* would not generate any barrier, and some parts | |||||
of the code should be reviewed and missing barriers should be added. | |||||
This should probably be backported to 1.8 and 1.9. | |||||
(cherry picked from commit 113537967c8680f94977473e18c9e14dc09c3356) | |||||
[wt: this is in fact a real bug fix : all these atomics do not provide | |||||
the slightest sequential consistency by default as the value 0 is | |||||
__ATOMIC_RELAXED, which will definitely cause random issues with | |||||
threads on non-x86 platforms]. | |||||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||||
(cherry picked from commit e5d1670f5fa95972fed6391201c0da8982bb9f94) | |||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | |||||
diff --git a/include/common/hathreads.h b/include/common/hathreads.h | |||||
index 24fb1d1a..8a738aaf 100644 | |||||
--- a/include/common/hathreads.h | |||||
+++ b/include/common/hathreads.h | |||||
@@ -213,14 +213,14 @@ static inline unsigned long thread_isolated() | |||||
}) | |||||
#else | |||||
/* gcc >= 4.7 */ | |||||
-#define HA_ATOMIC_CAS(val, old, new) __atomic_compare_exchange_n(val, old, new, 0, 0, 0) | |||||
-#define HA_ATOMIC_ADD(val, i) __atomic_add_fetch(val, i, 0) | |||||
-#define HA_ATOMIC_XADD(val, i) __atomic_fetch_add(val, i, 0) | |||||
-#define HA_ATOMIC_SUB(val, i) __atomic_sub_fetch(val, i, 0) | |||||
-#define HA_ATOMIC_AND(val, flags) __atomic_and_fetch(val, flags, 0) | |||||
-#define HA_ATOMIC_OR(val, flags) __atomic_or_fetch(val, flags, 0) | |||||
-#define HA_ATOMIC_XCHG(val, new) __atomic_exchange_n(val, new, 0) | |||||
-#define HA_ATOMIC_STORE(val, new) __atomic_store_n(val, new, 0) | |||||
+#define HA_ATOMIC_CAS(val, old, new) __atomic_compare_exchange_n(val, old, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_ADD(val, i) __atomic_add_fetch(val, i, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_XADD(val, i) __atomic_fetch_add(val, i, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_SUB(val, i) __atomic_sub_fetch(val, i, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_AND(val, flags) __atomic_and_fetch(val, flags, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_OR(val, flags) __atomic_or_fetch(val, flags, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_XCHG(val, new) __atomic_exchange_n(val, new, __ATOMIC_SEQ_CST) | |||||
+#define HA_ATOMIC_STORE(val, new) __atomic_store_n(val, new, __ATOMIC_SEQ_CST) | |||||
#endif | |||||
#define HA_ATOMIC_UPDATE_MAX(val, new) \ |
@ -0,0 +1,34 @@ | |||||
commit 1dfa4fd4be313a87f2a4861e81d0ad8ea8214223 | |||||
Author: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu Mar 14 19:10:55 2019 +0100 | |||||
BUG/MEDIUM: threads/fd: do not forget to take into account epoll_fd/pipes | |||||
Each thread uses one epoll_fd or kqueue_fd, and a pipe (thus two FDs). | |||||
These ones have to be accounted for in the maxsock calculation, otherwise | |||||
we can reach maxsock before maxconn. This is difficult to observe but it | |||||
in fact happens when a server connects back to the frontend and has checks | |||||
enabled : the check uses its FD and serves to fill the loop. In this case | |||||
all FDs planed for the datapath are used for this. | |||||
This needs to be backported to 1.9 and 1.8. | |||||
(cherry picked from commit 2c58b41c96e70f567d0f9ae876a80770630c06ee) | |||||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||||
(cherry picked from commit 26d110ba04cba02b337beff53a83847320e4fcdb) | |||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | |||||
diff --git a/src/haproxy.c b/src/haproxy.c | |||||
index 68367627..5c3febdd 100644 | |||||
--- a/src/haproxy.c | |||||
+++ b/src/haproxy.c | |||||
@@ -1828,6 +1828,9 @@ static void init(int argc, char **argv) | |||||
global.hardmaxconn = global.maxconn; /* keep this max value */ | |||||
global.maxsock += global.maxconn * 2; /* each connection needs two sockets */ | |||||
global.maxsock += global.maxpipes * 2; /* each pipe needs two FDs */ | |||||
+ global.maxsock += global.nbthread; /* one epoll_fd/kqueue_fd per thread */ | |||||
+ global.maxsock += 2 * global.nbthread; /* one wake-up pipe (2 fd) per thread */ | |||||
+ | |||||
/* compute fd used by async engines */ | |||||
if (global.ssl_used_async_engines) { | |||||
int sides = !!global.ssl_used_frontend + !!global.ssl_used_backend; |
@ -0,0 +1,54 @@ | |||||
commit a3cfe8f4bc2ec98fdbe25c49f2c21699b6d09d2b | |||||
Author: Christopher Faulet <cfaulet@haproxy.com> | |||||
Date: Mon Mar 18 13:57:42 2019 +0100 | |||||
BUG/MAJOR: spoe: Fix initialization of thread-dependent fields | |||||
A bug was introduced in the commit b0769b ("BUG/MEDIUM: spoe: initialization | |||||
depending on nbthread must be done last"). The code depending on global.nbthread | |||||
was moved from cfg_parse_spoe_agent() to spoe_check() but the pointer on the | |||||
agent configuration was not updated to use the filter's one. The variable | |||||
curagent is a global variable only valid during the configuration parsing. In | |||||
spoe_check(), conf->agent must be used instead. | |||||
This patch must be backported to 1.9 and 1.8. | |||||
(cherry picked from commit fe261551b9980fe33990eb34d2153bf1de24b20f) | |||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | |||||
(cherry picked from commit 7a93d271d549144a8ed8c816f5694a51ab62b90c) | |||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com> | |||||
diff --git a/src/flt_spoe.c b/src/flt_spoe.c | |||||
index e4453882..66d26f34 100644 | |||||
--- a/src/flt_spoe.c | |||||
+++ b/src/flt_spoe.c | |||||
@@ -2937,20 +2937,20 @@ spoe_check(struct proxy *px, struct flt_conf *fconf) | |||||
if (global.nbthread == 1) | |||||
conf->agent->flags |= SPOE_FL_ASYNC; | |||||
- if ((curagent->rt = calloc(global.nbthread, sizeof(*curagent->rt))) == NULL) { | |||||
+ if ((conf->agent->rt = calloc(global.nbthread, sizeof(*conf->agent->rt))) == NULL) { | |||||
ha_alert("Proxy %s : out of memory initializing SPOE agent '%s' declared at %s:%d.\n", | |||||
px->id, conf->agent->id, conf->agent->conf.file, conf->agent->conf.line); | |||||
return 1; | |||||
} | |||||
for (i = 0; i < global.nbthread; ++i) { | |||||
- curagent->rt[i].frame_size = curagent->max_frame_size; | |||||
- curagent->rt[i].applets_act = 0; | |||||
- curagent->rt[i].applets_idle = 0; | |||||
- curagent->rt[i].sending_rate = 0; | |||||
- LIST_INIT(&curagent->rt[i].applets); | |||||
- LIST_INIT(&curagent->rt[i].sending_queue); | |||||
- LIST_INIT(&curagent->rt[i].waiting_queue); | |||||
- HA_SPIN_INIT(&curagent->rt[i].lock); | |||||
+ conf->agent->rt[i].frame_size = conf->agent->max_frame_size; | |||||
+ conf->agent->rt[i].applets_act = 0; | |||||
+ conf->agent->rt[i].applets_idle = 0; | |||||
+ conf->agent->rt[i].sending_rate = 0; | |||||
+ LIST_INIT(&conf->agent->rt[i].applets); | |||||
+ LIST_INIT(&conf->agent->rt[i].sending_queue); | |||||
+ LIST_INIT(&conf->agent->rt[i].waiting_queue); | |||||
+ HA_SPIN_INIT(&conf->agent->rt[i].lock); | |||||
} | |||||
free(conf->agent->b.name); |