diff -Nru haproxy-2.4.13/CHANGELOG haproxy-2.4.14/CHANGELOG --- haproxy-2.4.13/CHANGELOG 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/CHANGELOG 2022-02-25 16:10:23.000000000 +0000 @@ -1,6 +1,34 @@ ChangeLog : =========== +2022/02/25 : 2.4.14 + - MINOR: sock: move the unused socket cleaning code into its own function + - BUG/MEDIUM: mworker: close unused transferred FDs on load failure + - BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload + - BUG/MINOR: sink: Use the right field in appctx context in release callback + - BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names + - BUG/MEDIUM: fd: always align fdtab[] to 64 bytes + - BUG/MAJOR: compiler: relax alignment constraints on certain structures + - CI: ssl: enable parallel builds for OpenSSL on Linux + - CI: ssl: do not needlessly build the OpenSSL docs + - CI: ssl: keep the old method for ancient OpenSSL versions + - BUILD: fix compilation for OpenSSL-3.0.0-alpha17 + - BUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2 + - CI: github actions: add OpenSSL-3.0.0 builds + - CI: github actions: -Wno-deprecated-declarations with OpenSSL 3.0.0 + - CI: github actions: relax OpenSSL-3.0.0 version comparision + - CI: github: switch to OpenSSL 3.0.0 + - CI: github actions: update OpenSSL to 3.0.1 + - BUG/MINOR: mailers: negotiate SMTP, not ESMTP + - BUG/MINOR: tools: url2sa reads ipv4 too far + - BUG/MEDIUM: htx: Be sure to have a buffer to perform a raw copy of a message + - BUG/MEDIUM: mux-h1: Don't wake h1s if mux is blocked on lack of output buffer + - BUG/MAJOR: mux-h2: Be sure to always report HTX parsing error to the app layer + - BUG/MINOR: proxy: preset the error message pointer to NULL in parse_new_proxy() + - REGTESTS: fix the race conditions in 40be_2srv_odd_health_checks + - CI: github: enable pool debugging by default + - BUG/MEDIUM: stream: Abort processing if response buffer allocation fails + 2022/02/16 : 2.4.13 - BUG/MEDIUM: connection: properly leave stopping list on error - BUG/MEDIUM: htx: Adjust length to add DATA block in an empty HTX buffer diff -Nru haproxy-2.4.13/debian/changelog haproxy-2.4.14/debian/changelog --- haproxy-2.4.13/debian/changelog 2022-02-18 18:27:14.000000000 +0000 +++ haproxy-2.4.14/debian/changelog 2022-02-28 16:48:21.000000000 +0000 @@ -1,3 +1,22 @@ +haproxy (2.4.14-1ubuntu1) jammy; urgency=medium + + * Merge with Debian unstable. Remaining changes: + - d/{control,rules}: Removing support for OpenTracing due to it is + in universe. + * Dropped: + - d/p/fix-ftbfs-openssl3.patch: Cherry-picked from upstream to fix + the build against OpenSSL3 (LP #1945773) + [Fixed upstream] + + -- Andreas Hasenack Mon, 28 Feb 2022 13:48:21 -0300 + +haproxy (2.4.14-1) unstable; urgency=medium + + * New upstream release. + - Fix compilation with OpenSSL 3.0. Closes: #996423, #1006007. + + -- Vincent Bernat Fri, 25 Feb 2022 18:38:27 +0100 + haproxy (2.4.13-1ubuntu1) jammy; urgency=medium * Merge with Debian unstable (LP: #1961195). Remaining changes: diff -Nru haproxy-2.4.13/debian/patches/fix-ftbfs-openssl3.patch haproxy-2.4.14/debian/patches/fix-ftbfs-openssl3.patch --- haproxy-2.4.13/debian/patches/fix-ftbfs-openssl3.patch 2022-02-18 18:25:07.000000000 +0000 +++ haproxy-2.4.14/debian/patches/fix-ftbfs-openssl3.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -From f22b032956bc492dcf47b2a909f91a6fb2c6e49b Mon Sep 17 00:00:00 2001 -From: William Lallemand -Date: Wed, 2 Jun 2021 16:09:11 +0200 -Subject: [PATCH] BUILD: fix compilation for OpenSSL-3.0.0-alpha17 - -Some changes in the OpenSSL syntax API broke this syntax: - #if SSL_OP_NO_TLSv1_3 - -OpenSSL made this change which broke our usage in commit f04bb0bce490de847ed0482b8ec9eabedd173852: - --# define SSL_OP_NO_TLSv1_3 (uint64_t)0x20000000 -+#define SSL_OP_BIT(n) ((uint64_t)1 << (uint64_t)n) -+# define SSL_OP_NO_TLSv1_3 SSL_OP_BIT(29) - -Which can't be evaluated by the preprocessor anymore. -This patch replace the test by an openssl version test. - -This fix part of #1276 issue. - -Origin: upstream, https://github.com/haproxy/haproxy/commit/f22b032956bc492 -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/haproxy/+bug/1945773 -Last-Updated: 2021-11-22 ---- - src/ssl_sock.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/ssl_sock.c b/src/ssl_sock.c -index f596a831de..27a4c3531e 100644 ---- a/src/ssl_sock.c -+++ b/src/ssl_sock.c -@@ -2217,13 +2217,13 @@ static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) { - : SSL_set_min_proto_version(ssl, TLS1_2_VERSION); - } - static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) { --#if SSL_OP_NO_TLSv1_3 -+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) - c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) - : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION); - #endif - } - static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) { --#if SSL_OP_NO_TLSv1_3 -+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) - c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION) - : SSL_set_min_proto_version(ssl, TLS1_3_VERSION); - #endif diff -Nru haproxy-2.4.13/debian/patches/series haproxy-2.4.14/debian/patches/series --- haproxy-2.4.13/debian/patches/series 2022-02-18 18:25:07.000000000 +0000 +++ haproxy-2.4.14/debian/patches/series 2022-02-28 12:44:58.000000000 +0000 @@ -4,5 +4,3 @@ # applied during the build process: # debianize-dconv.patch reproducible.patch - -fix-ftbfs-openssl3.patch diff -Nru haproxy-2.4.13/doc/configuration.txt haproxy-2.4.14/doc/configuration.txt --- haproxy-2.4.13/doc/configuration.txt 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/doc/configuration.txt 2022-02-25 16:10:23.000000000 +0000 @@ -4,7 +4,7 @@ ---------------------- version 2.4 willy tarreau - 2022/02/16 + 2022/02/25 This document covers the configuration language as implemented in the version diff -Nru haproxy-2.4.13/.github/matrix.py haproxy-2.4.14/.github/matrix.py --- haproxy-2.4.13/.github/matrix.py 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/.github/matrix.py 2022-02-25 16:10:23.000000000 +0000 @@ -104,6 +104,7 @@ for ssl in [ "stock", "OPENSSL_VERSION=1.0.2u", + "OPENSSL_VERSION=3.0.1", "LIBRESSL_VERSION=2.9.2", "LIBRESSL_VERSION=3.3.3", # "BORINGSSL=yes", @@ -111,6 +112,8 @@ flags = ["USE_OPENSSL=1"] if ssl == "BORINGSSL=yes": flags.append("USE_QUIC=1") + if "OPENSSL_VERSION=3.0." in ssl: + flags.append('DEBUG_CFLAGS="-g -Wno-deprecated-declarations"') if ssl != "stock": flags.append("SSL_LIB=${HOME}/opt/lib") flags.append("SSL_INC=${HOME}/opt/include") diff -Nru haproxy-2.4.13/.github/workflows/compliance.yml haproxy-2.4.14/.github/workflows/compliance.yml --- haproxy-2.4.13/.github/workflows/compliance.yml 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/.github/workflows/compliance.yml 2022-02-25 16:10:23.000000000 +0000 @@ -30,7 +30,7 @@ ERR=1 \ TARGET=${{ matrix.TARGET }} \ CC=${{ matrix.CC }} \ - DEBUG=-DDEBUG_STRICT=1 \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ USE_OPENSSL=1 sudo make install - name: Show HAProxy version diff -Nru haproxy-2.4.13/.github/workflows/vtest.yml haproxy-2.4.14/.github/workflows/vtest.yml --- haproxy-2.4.13/.github/workflows/vtest.yml 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/.github/workflows/vtest.yml 2022-02-25 16:10:23.000000000 +0000 @@ -77,7 +77,7 @@ ERR=1 \ TARGET=${{ matrix.TARGET }} \ CC=${{ matrix.CC }} \ - DEBUG=-DDEBUG_STRICT=1 \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ ${{ join(matrix.FLAGS, ' ') }} \ ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/" sudo make install diff -Nru haproxy-2.4.13/.github/workflows/windows.yml haproxy-2.4.14/.github/workflows/windows.yml --- haproxy-2.4.13/.github/workflows/windows.yml 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/.github/workflows/windows.yml 2022-02-25 16:10:23.000000000 +0000 @@ -52,7 +52,7 @@ ERR=1 \ TARGET=${{ matrix.TARGET }} \ CC=${{ matrix.CC }} \ - DEBUG=-DDEBUG_STRICT=1 \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ ${{ join(matrix.FLAGS, ' ') }} - name: Show HAProxy version id: show-version diff -Nru haproxy-2.4.13/include/haproxy/compiler.h haproxy-2.4.14/include/haproxy/compiler.h --- haproxy-2.4.13/include/haproxy/compiler.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/compiler.h 2022-02-25 16:10:23.000000000 +0000 @@ -203,6 +203,17 @@ #define HA_HAVE_CAS_DW #endif +/*********************** IMPORTANT NOTE ABOUT ALIGNMENT **********************\ + * Alignment works fine for variables. It also works on types and struct * + * members by propagating the alignment to the container struct itself, * + * but this requires that variables of the affected type are properly * + * aligned themselves. While regular variables will always abide, those * + * allocated using malloc() will not! Most platforms provide posix_memalign()* + * for this, but it's not available everywhere. As such one ought not to use * + * these alignment declarations inside structures that are dynamically * + * allocated. If the purpose is only to avoid false sharing of cache lines * + * for multi_threading, see THREAD_PAD() below. * +\*****************************************************************************/ /* sets alignment for current field or variable */ #ifndef ALIGNED @@ -277,6 +288,20 @@ #endif #endif +/* add optional padding of the specified size between fields in a structure, + * only when threads are enabled. This is used to avoid false sharing of cache + * lines for dynamically allocated structures which cannot guarantee alignment. + */ +#ifndef THREAD_PAD +# ifdef USE_THREAD +# define __THREAD_PAD(x,l) char __pad_##l[x] +# define _THREAD_PAD(x,l) __THREAD_PAD(x, l) +# define THREAD_PAD(x) _THREAD_PAD(x, __LINE__) +# else +# define THREAD_PAD(x) +# endif +#endif + /* The THREAD_LOCAL type attribute defines thread-local storage and is defined * to __thread when threads are enabled or empty when disabled. */ diff -Nru haproxy-2.4.13/include/haproxy/htx.h haproxy-2.4.14/include/haproxy/htx.h --- haproxy-2.4.13/include/haproxy/htx.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/htx.h 2022-02-25 16:10:23.000000000 +0000 @@ -749,8 +749,8 @@ */ static inline int htx_copy_msg(struct htx *htx, const struct buffer *msg) { - /* The destination HTX message is empty, we can do a raw copy */ - if (htx_is_empty(htx)) { + /* The destination HTX message is allocated and empty, we can do a raw copy */ + if (htx_is_empty(htx) && htx_free_space(htx)) { memcpy(htx, msg->area, msg->size); return 1; } diff -Nru haproxy-2.4.13/include/haproxy/mworker.h haproxy-2.4.14/include/haproxy/mworker.h --- haproxy-2.4.13/include/haproxy/mworker.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/mworker.h 2022-02-25 16:10:23.000000000 +0000 @@ -42,5 +42,6 @@ void mworker_kill_max_reloads(int sig); void mworker_free_child(struct mworker_proc *); +void mworker_cleanup_proc(); #endif /* _HAPROXY_MWORKER_H_ */ diff -Nru haproxy-2.4.13/include/haproxy/server-t.h haproxy-2.4.14/include/haproxy/server-t.h --- haproxy-2.4.13/include/haproxy/server-t.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/server-t.h 2022-02-25 16:10:23.000000000 +0000 @@ -275,7 +275,7 @@ /* The elements below may be changed on every single request by any * thread, and generally at the same time. */ - ALWAYS_ALIGN(64); + THREAD_PAD(63); struct eb32_node idle_node; /* When to next do cleanup in the idle connections */ unsigned int curr_idle_conns; /* Current number of orphan idling connections, both the idle and the safe lists */ unsigned int curr_idle_nb; /* Current number of connections in the idle list */ @@ -290,14 +290,14 @@ /* Element below are usd by LB algorithms and must be doable in * parallel to other threads reusing connections above. */ - ALWAYS_ALIGN(64); + THREAD_PAD(63); __decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */ unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */ struct eb32_node lb_node; /* node used for tree-based load balancing */ struct server *next_full; /* next server in the temporary full list */ /* usually atomically updated by any thread during parsing or on end of request */ - ALWAYS_ALIGN(64); + THREAD_PAD(63); int cur_sess; /* number of currently active sessions (including syn_sent) */ int served; /* # of active sessions currently being served (ie not pending) */ int nbpend; /* number of pending connections */ @@ -307,7 +307,7 @@ struct be_counters counters; /* statistics counters */ /* Below are some relatively stable settings, only changed under the lock */ - ALWAYS_ALIGN(64); + THREAD_PAD(63); struct eb_root *lb_tree; /* we want to know in what tree the server is */ struct tree_occ *lb_nodes; /* lb_nodes_tot * struct tree_occ */ diff -Nru haproxy-2.4.13/include/haproxy/sock.h haproxy-2.4.14/include/haproxy/sock.h --- haproxy-2.4.13/include/haproxy/sock.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/sock.h 2022-02-25 16:10:23.000000000 +0000 @@ -30,8 +30,6 @@ #include #include -extern struct xfer_sock_list *xfer_sock_list; - int sock_create_server_socket(struct connection *conn); void sock_enable(struct receiver *rx); void sock_disable(struct receiver *rx); @@ -40,6 +38,7 @@ int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir); int sock_get_old_sockets(const char *unixsocket); int sock_find_compatible_fd(const struct receiver *rx); +void sock_drop_unused_old_sockets(); int sock_accepting_conn(const struct receiver *rx); struct connection *sock_accept_conn(struct listener *l, int *status); void sock_accept_iocb(int fd); diff -Nru haproxy-2.4.13/include/haproxy/sock-t.h haproxy-2.4.14/include/haproxy/sock-t.h --- haproxy-2.4.13/include/haproxy/sock-t.h 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/include/haproxy/sock-t.h 2022-02-25 16:10:23.000000000 +0000 @@ -27,23 +27,6 @@ #include -#define SOCK_XFER_OPT_FOREIGN 0x000000001 -#define SOCK_XFER_OPT_V6ONLY 0x000000002 -#define SOCK_XFER_OPT_DGRAM 0x000000004 - -/* The list used to transfer sockets between old and new processes */ -struct xfer_sock_list { - int fd; - int options; /* socket options as SOCK_XFER_OPT_* */ - char *iface; - char *namespace; - int if_namelen; - int ns_namelen; - struct xfer_sock_list *prev; - struct xfer_sock_list *next; - struct sockaddr_storage addr; -}; - #endif /* _HAPROXY_SOCK_T_H */ /* diff -Nru haproxy-2.4.13/reg-tests/checks/40be_2srv_odd_health_checks.vtc haproxy-2.4.14/reg-tests/checks/40be_2srv_odd_health_checks.vtc --- haproxy-2.4.13/reg-tests/checks/40be_2srv_odd_health_checks.vtc 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/reg-tests/checks/40be_2srv_odd_health_checks.vtc 2022-02-25 16:10:23.000000000 +0000 @@ -14,6 +14,8 @@ # - so that to ensure that health-checks do not consume any connection # (any varnishtest server without -repeat with n > 1 accepts # only one connection). +# - we take care of sending the clients to the unchecked servers using the +# "first" lb algo so that servers always receive a valid request syslog S1 -level notice { recv @@ -115,254 +117,254 @@ expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be39/srv39 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" } -start -server s0 {} -start -server s2 {} -start -server s4 {} -start -server s6 {} -start -server s8 {} -start -server s10 {} -start -server s12 {} -start -server s14 {} -start -server s16 {} -start -server s18 {} -start -server s20 {} -start -server s22 {} -start -server s24 {} -start -server s26 {} -start -server s28 {} -start -server s30 {} -start -server s32 {} -start -server s34 {} -start -server s36 {} -start -server s38 {} -start - -server s1 { +server s0 { rxreq txresp } -start -server s3 { +server s2 { rxreq txresp } -start -server s5 { +server s4 { rxreq txresp } -start -server s7 { +server s6 { rxreq txresp } -start -server s9 { +server s8 { rxreq txresp } -start -server s11 { +server s10 { rxreq txresp } -start -server s13 { +server s12 { rxreq txresp } -start -server s15 { +server s14 { rxreq txresp } -start -server s17 { +server s16 { rxreq txresp } -start -server s19 { +server s18 { rxreq txresp } -start -server s21 { +server s20 { rxreq txresp } -start -server s23 { +server s22 { rxreq txresp } -start -server s25 { +server s24 { rxreq -txresp + txresp } -start -server s27 { +server s26 { rxreq txresp } -start -server s29 { +server s28 { rxreq txresp } -start -server s31 { +server s30 { rxreq txresp } -start -server s33 { +server s32 { rxreq txresp } -start -server s35 { +server s34 { rxreq txresp } -start -server s37 { +server s36 { rxreq txresp } -start -server s39 { +server s38 { rxreq txresp } -start +server s1 {} -start +server s3 {} -start +server s5 {} -start +server s7 {} -start +server s9 {} -start +server s11 {} -start +server s13 {} -start +server s15 {} -start +server s17 {} -start +server s19 {} -start +server s21 {} -start +server s23 {} -start +server s25 {} -start +server s27 {} -start +server s29 {} -start +server s31 {} -start +server s33 {} -start +server s35 {} -start +server s37 {} -start +server s39 {} -start + haproxy h1 -conf { defaults timeout client 1s timeout server 1s timeout connect 1s balance first - default-server no-check inter 5ms downinter 1s rise 1 fall 1 + default-server no-check inter 20ms downinter 1s rise 1 fall 1 backend be1 option log-health-checks log ${S1_addr}:${S1_port} daemon - server srv1 ${s1_addr}:${s1_port} check server srv0 ${s0_addr}:${s0_port} + server srv1 ${s1_addr}:${s1_port} check backend be3 option log-health-checks log ${S3_addr}:${S3_port} daemon - server srv3 ${s3_addr}:${s3_port} check server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} check backend be5 option log-health-checks log ${S5_addr}:${S5_port} daemon - server srv5 ${s5_addr}:${s5_port} check server srv4 ${s4_addr}:${s4_port} + server srv5 ${s5_addr}:${s5_port} check backend be7 option log-health-checks log ${S7_addr}:${S7_port} daemon - server srv7 ${s7_addr}:${s7_port} check server srv6 ${s6_addr}:${s6_port} + server srv7 ${s7_addr}:${s7_port} check backend be9 option log-health-checks log ${S9_addr}:${S9_port} daemon - server srv9 ${s9_addr}:${s9_port} check server srv8 ${s8_addr}:${s8_port} + server srv9 ${s9_addr}:${s9_port} check backend be11 option log-health-checks log ${S11_addr}:${S11_port} daemon - server srv11 ${s11_addr}:${s11_port} check server srv10 ${s10_addr}:${s10_port} + server srv11 ${s11_addr}:${s11_port} check backend be13 option log-health-checks log ${S13_addr}:${S13_port} daemon - server srv13 ${s13_addr}:${s13_port} check server srv12 ${s12_addr}:${s12_port} + server srv13 ${s13_addr}:${s13_port} check backend be15 option log-health-checks log ${S15_addr}:${S15_port} daemon - server srv15 ${s15_addr}:${s15_port} check server srv14 ${s14_addr}:${s14_port} + server srv15 ${s15_addr}:${s15_port} check backend be17 option log-health-checks log ${S17_addr}:${S17_port} daemon - server srv17 ${s17_addr}:${s17_port} check server srv16 ${s16_addr}:${s16_port} + server srv17 ${s17_addr}:${s17_port} check backend be19 option log-health-checks log ${S19_addr}:${S19_port} daemon - server srv19 ${s19_addr}:${s19_port} check server srv18 ${s18_addr}:${s18_port} + server srv19 ${s19_addr}:${s19_port} check backend be21 option log-health-checks log ${S21_addr}:${S21_port} daemon - server srv21 ${s21_addr}:${s21_port} check server srv20 ${s20_addr}:${s20_port} + server srv21 ${s21_addr}:${s21_port} check backend be23 option log-health-checks log ${S23_addr}:${S23_port} daemon - server srv23 ${s23_addr}:${s23_port} check server srv22 ${s22_addr}:${s22_port} + server srv23 ${s23_addr}:${s23_port} check backend be25 option log-health-checks log ${S25_addr}:${S25_port} daemon - server srv25 ${s25_addr}:${s25_port} check server srv24 ${s24_addr}:${s24_port} + server srv25 ${s25_addr}:${s25_port} check backend be27 option log-health-checks log ${S27_addr}:${S27_port} daemon - server srv27 ${s27_addr}:${s27_port} check server srv26 ${s26_addr}:${s26_port} + server srv27 ${s27_addr}:${s27_port} check backend be29 option log-health-checks log ${S29_addr}:${S29_port} daemon - server srv29 ${s29_addr}:${s29_port} check server srv28 ${s28_addr}:${s28_port} + server srv29 ${s29_addr}:${s29_port} check backend be31 option log-health-checks log ${S31_addr}:${S31_port} daemon - server srv31 ${s31_addr}:${s31_port} check server srv30 ${s30_addr}:${s30_port} + server srv31 ${s31_addr}:${s31_port} check backend be33 option log-health-checks log ${S33_addr}:${S33_port} daemon - server srv33 ${s33_addr}:${s33_port} check server srv32 ${s32_addr}:${s32_port} + server srv33 ${s33_addr}:${s33_port} check backend be35 option log-health-checks log ${S35_addr}:${S35_port} daemon - server srv35 ${s35_addr}:${s35_port} check server srv34 ${s34_addr}:${s34_port} + server srv35 ${s35_addr}:${s35_port} check backend be37 option log-health-checks log ${S37_addr}:${S37_port} daemon - server srv37 ${s37_addr}:${s37_port} check server srv36 ${s36_addr}:${s36_port} + server srv37 ${s37_addr}:${s37_port} check backend be39 option log-health-checks log ${S39_addr}:${S39_port} daemon - server srv39 ${s39_addr}:${s39_port} check server srv38 ${s38_addr}:${s38_port} + server srv39 ${s39_addr}:${s39_port} check frontend fe1 bind "fd@${fe1}" @@ -609,30 +611,35 @@ client c37 -wait client c39 -wait -server s1 -wait -server s3 -wait -server s5 -wait -server s7 -wait -server s9 -wait -server s11 -wait -server s13 -wait -server s15 -wait -server s17 -wait -server s19 -wait -server s21 -wait -server s23 -wait -server s25 -wait -server s27 -wait -server s29 -wait -server s31 -wait -server s33 -wait -server s35 -wait -server s37 -wait -server s39 -wait +server s0 -wait +server s2 -wait +server s4 -wait +server s6 -wait +server s8 -wait +server s10 -wait +server s12 -wait +server s14 -wait +server s16 -wait +server s18 -wait +server s20 -wait +server s22 -wait +server s24 -wait +server s26 -wait +server s28 -wait +server s30 -wait +server s32 -wait +server s34 -wait +server s36 -wait +server s38 -wait haproxy h1 -cli { send "show servers state" - expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n2 be1 1 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s1_port} - 0 0 - - 0\n2 be1 2 srv0 ${s0_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s0_port} - 0 0 - - 0\n3 be3 1 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s3_port} - 0 0 - - 0\n3 be3 2 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s2_port} - 0 0 - - 0\n4 be5 1 srv5 ${s5_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s5_port} - 0 0 - - 0\n4 be5 2 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s4_port} - 0 0 - - 0\n5 be7 1 srv7 ${s7_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s7_port} - 0 0 - - 0\n5 be7 2 srv6 ${s6_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s6_port} - 0 0 - - 0\n6 be9 1 srv9 ${s9_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s9_port} - 0 0 - - 0\n6 be9 2 srv8 ${s8_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s8_port} - 0 0 - - 0\n7 be11 1 srv11 ${s11_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s11_port} - 0 0 - - 0\n7 be11 2 srv10 ${s10_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s10_port} - 0 0 - - 0\n8 be13 1 srv13 ${s13_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s13_port} - 0 0 - - 0\n8 be13 2 srv12 ${s12_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s12_port} - 0 0 - - 0\n9 be15 1 srv15 ${s15_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s15_port} - 0 0 - - 0\n9 be15 2 srv14 ${s14_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s14_port} - 0 0 - - 0\n10 be17 1 srv17 ${s17_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s17_port} - 0 0 - - 0\n10 be17 2 srv16 ${s16_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s16_port} - 0 0 - - 0\n11 be19 1 srv19 ${s19_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s19_port} - 0 0 - - 0\n11 be19 2 srv18 ${s18_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s18_port} - 0 0 - - 0\n12 be21 1 srv21 ${s21_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s21_port} - 0 0 - - 0\n12 be21 2 srv20 ${s20_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s20_port} - 0 0 - - 0\n13 be23 1 srv23 ${s23_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s23_port} - 0 0 - - 0\n13 be23 2 srv22 ${s22_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s22_port} - 0 0 - - 0\n14 be25 1 srv25 ${s25_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s25_port} - 0 0 - - 0\n14 be25 2 srv24 ${s24_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s24_port} - 0 0 - - 0\n15 be27 1 srv27 ${s27_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s27_port} - 0 0 - - 0\n15 be27 2 srv26 ${s26_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s26_port} - 0 0 - - 0\n16 be29 1 srv29 ${s29_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s29_port} - 0 0 - - 0\n16 be29 2 srv28 ${s28_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s28_port} - 0 0 - - 0\n17 be31 1 srv31 ${s31_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s31_port} - 0 0 - - 0\n17 be31 2 srv30 ${s30_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s30_port} - 0 0 - - 0\n18 be33 1 srv33 ${s33_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s33_port} - 0 0 - - 0\n18 be33 2 srv32 ${s32_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s32_port} - 0 0 - - 0\n19 be35 1 srv35 ${s35_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s35_port} - 0 0 - - 0\n19 be35 2 srv34 ${s34_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s34_port} - 0 0 - - 0\n20 be37 1 srv37 ${s37_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s37_port} - 0 0 - - 0\n20 be37 2 srv36 ${s36_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s36_port} - 0 0 - - 0\n21 be39 1 srv39 ${s39_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s39_port} - 0 0 - - 0\n21 be39 2 srv38 ${s38_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s38_port} - 0 0 - - 0\n" + # output produced using the command below (warning, a bug inserts a "be0" every other line: + # for ((i=0;i<40;i++)); do id=$((i/2+2)); be=$((i|1)); si=$(((i&1)+1)); + # if ((i&1)); then chk="6 ([[:digit:]]+ ){3}"; else chk="1 0 1 0 ";fi; + # printf "%d be%d %d srv%d \${s%d_addr} 2 0 1 1 [[:digit:]]+ %s0 0 0 - \${s%d_port} - 0 0 - - 0\n" "$id" "$be" "$si" "$i" "$i" "$chk" "$i" "$i" ; + # done|grep -v be0|sed 's,$,\\n,'| tr -d '\n' + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n2 be1 1 srv0 ${s0_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s0_port} - 0 0 - - 0\n2 be1 2 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s1_port} - 0 0 - - 0\n3 be3 1 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s2_port} - 0 0 - - 0\n3 be3 2 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s3_port} - 0 0 - - 0\n4 be5 1 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s4_port} - 0 0 - - 0\n4 be5 2 srv5 ${s5_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s5_port} - 0 0 - - 0\n5 be7 1 srv6 ${s6_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s6_port} - 0 0 - - 0\n5 be7 2 srv7 ${s7_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s7_port} - 0 0 - - 0\n6 be9 1 srv8 ${s8_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s8_port} - 0 0 - - 0\n6 be9 2 srv9 ${s9_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s9_port} - 0 0 - - 0\n7 be11 1 srv10 ${s10_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s10_port} - 0 0 - - 0\n7 be11 2 srv11 ${s11_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s11_port} - 0 0 - - 0\n8 be13 1 srv12 ${s12_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s12_port} - 0 0 - - 0\n8 be13 2 srv13 ${s13_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s13_port} - 0 0 - - 0\n9 be15 1 srv14 ${s14_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s14_port} - 0 0 - - 0\n9 be15 2 srv15 ${s15_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s15_port} - 0 0 - - 0\n10 be17 1 srv16 ${s16_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s16_port} - 0 0 - - 0\n10 be17 2 srv17 ${s17_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s17_port} - 0 0 - - 0\n11 be19 1 srv18 ${s18_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s18_port} - 0 0 - - 0\n11 be19 2 srv19 ${s19_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s19_port} - 0 0 - - 0\n12 be21 1 srv20 ${s20_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s20_port} - 0 0 - - 0\n12 be21 2 srv21 ${s21_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s21_port} - 0 0 - - 0\n13 be23 1 srv22 ${s22_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s22_port} - 0 0 - - 0\n13 be23 2 srv23 ${s23_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s23_port} - 0 0 - - 0\n14 be25 1 srv24 ${s24_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s24_port} - 0 0 - - 0\n14 be25 2 srv25 ${s25_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s25_port} - 0 0 - - 0\n15 be27 1 srv26 ${s26_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s26_port} - 0 0 - - 0\n15 be27 2 srv27 ${s27_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s27_port} - 0 0 - - 0\n16 be29 1 srv28 ${s28_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s28_port} - 0 0 - - 0\n16 be29 2 srv29 ${s29_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s29_port} - 0 0 - - 0\n17 be31 1 srv30 ${s30_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s30_port} - 0 0 - - 0\n17 be31 2 srv31 ${s31_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s31_port} - 0 0 - - 0\n18 be33 1 srv32 ${s32_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s32_port} - 0 0 - - 0\n18 be33 2 srv33 ${s33_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s33_port} - 0 0 - - 0\n19 be35 1 srv34 ${s34_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s34_port} - 0 0 - - 0\n19 be35 2 srv35 ${s35_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s35_port} - 0 0 - - 0\n20 be37 1 srv36 ${s36_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s36_port} - 0 0 - - 0\n20 be37 2 srv37 ${s37_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s37_port} - 0 0 - - 0\n21 be39 1 srv38 ${s38_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s38_port} - 0 0 - - 0\n21 be39 2 srv39 ${s39_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s39_port} - 0 0 - - 0\n" } diff -Nru haproxy-2.4.13/scripts/build-ssl.sh haproxy-2.4.14/scripts/build-ssl.sh --- haproxy-2.4.13/scripts/build-ssl.sh 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/scripts/build-ssl.sh 2022-02-25 16:10:23.000000000 +0000 @@ -17,11 +17,18 @@ fi } +# recent openssl versions support parallel builds and skipping the docs, +# while older ones require to build everything sequentially. build_openssl_linux () { ( cd "openssl-${OPENSSL_VERSION}/" - ./config shared --prefix="${HOME}/opt" --openssldir="${HOME}/opt" -DPURIFY - make all install_sw + ./config shared --prefix="${HOME}/opt" --openssldir="${HOME}/opt" --libdir=lib -DPURIFY + if [ -z "${OPENSSL_VERSION##1.*}" ]; then + make all + else + make -j$(nproc) build_sw + fi + make install_sw ) } @@ -29,8 +36,8 @@ ( cd "openssl-${OPENSSL_VERSION}/" ./Configure darwin64-x86_64-cc shared \ - --prefix="${HOME}/opt" --openssldir="${HOME}/opt" -DPURIFY - make depend all install_sw + --prefix="${HOME}/opt" --openssldir="${HOME}/opt" --libdir=lib -DPURIFY + make depend build_sw install_sw ) } diff -Nru haproxy-2.4.13/src/fd.c haproxy-2.4.14/src/fd.c --- haproxy-2.4.13/src/fd.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/fd.c 2022-02-25 16:10:23.000000000 +0000 @@ -114,6 +114,7 @@ int poller_wr_pipe[MAX_THREADS] __read_mostly; // Pipe to wake the threads volatile int ha_used_fds = 0; // Number of FD we're currently using +static struct fdtab *fdtab_addr; /* address of the allocated area containing fdtab */ #define _GET_NEXT(fd, off) ((volatile struct fdlist_entry *)(void *)((char *)(&fdtab[fd]) + off))->next #define _GET_PREV(fd, off) ((volatile struct fdlist_entry *)(void *)((char *)(&fdtab[fd]) + off))->prev @@ -685,11 +686,14 @@ int p; struct poller *bp; - if ((fdtab = calloc(global.maxsock, sizeof(*fdtab))) == NULL) { + if ((fdtab_addr = calloc(global.maxsock, sizeof(*fdtab) + 64)) == NULL) { ha_alert("Not enough memory to allocate %d entries for fdtab!\n", global.maxsock); goto fail_tab; } + /* always provide an aligned fdtab */ + fdtab = (struct fdtab*)((((size_t)fdtab_addr) + 63) & -(size_t)64); + if ((polled_mask = calloc(global.maxsock, sizeof(*polled_mask))) == NULL) { ha_alert("Not enough memory to allocate %d entries for polled_mask!\n", global.maxsock); goto fail_polledmask; @@ -726,7 +730,7 @@ fail_info: free(polled_mask); fail_polledmask: - free(fdtab); + free(fdtab_addr); fail_tab: return 0; } @@ -747,7 +751,7 @@ } ha_free(&fdinfo); - ha_free(&fdtab); + ha_free(&fdtab_addr); ha_free(&polled_mask); } diff -Nru haproxy-2.4.13/src/haproxy.c haproxy-2.4.14/src/haproxy.c --- haproxy-2.4.13/src/haproxy.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/haproxy.c 2022-02-25 16:10:23.000000000 +0000 @@ -714,6 +714,7 @@ #endif setenv("HAPROXY_MWORKER_REEXEC", "1", 1); + mworker_cleanup_proc(); mworker_proc_list_to_env(); /* put the children description in the env */ /* during the reload we must ensure that every FDs that can't be @@ -860,6 +861,9 @@ setenv("HAPROXY_MWORKER_WAIT_ONLY", "1", 1); + /* do not keep unused FDs retrieved from the previous process */ + sock_drop_unused_old_sockets(); + ha_warning("Reexecuting Master process in waitpid mode\n"); mworker_reload(); } @@ -3029,14 +3033,7 @@ /* Ok, all listeners should now be bound, close any leftover sockets * the previous process gave us, we don't need them anymore */ - while (xfer_sock_list != NULL) { - struct xfer_sock_list *tmpxfer = xfer_sock_list->next; - close(xfer_sock_list->fd); - free(xfer_sock_list->iface); - free(xfer_sock_list->namespace); - free(xfer_sock_list); - xfer_sock_list = tmpxfer; - } + sock_drop_unused_old_sockets(); /* prepare pause/play signals */ signal_register_fct(SIGTTOU, sig_pause, SIGTTOU); diff -Nru haproxy-2.4.13/src/mailers.c haproxy-2.4.14/src/mailers.c --- haproxy-2.4.13/src/mailers.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/mailers.c 2022-02-25 16:10:23.000000000 +0000 @@ -195,7 +195,7 @@ goto error; { - const char * const strs[4] = { "EHLO ", p->email_alert.myhostname, "\r\n" }; + const char * const strs[4] = { "HELO ", p->email_alert.myhostname, "\r\n" }; if (!add_tcpcheck_send_strs(&alert->rules, strs)) goto error; } diff -Nru haproxy-2.4.13/src/mux_h1.c haproxy-2.4.14/src/mux_h1.c --- haproxy-2.4.13/src/mux_h1.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/mux_h1.c 2022-02-25 16:10:23.000000000 +0000 @@ -2683,7 +2683,7 @@ } end: - if (!(h1c->flags & H1C_F_OUT_FULL)) + if (!(h1c->flags & (H1C_F_OUT_FULL|H1C_F_OUT_ALLOC))) h1_wake_stream_for_send(h1c->h1s); /* We're done, no more to send */ diff -Nru haproxy-2.4.13/src/mux_h2.c haproxy-2.4.14/src/mux_h2.c --- haproxy-2.4.13/src/mux_h2.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/mux_h2.c 2022-02-25 16:10:23.000000000 +0000 @@ -6357,7 +6357,7 @@ /* transfer possibly pending data to the upper layer */ h2s_htx = htx_from_buf(&h2s->rxbuf); - if (htx_is_empty(h2s_htx)) { + if (htx_is_empty(h2s_htx) && !(h2s_htx->flags & HTX_FL_PARSING_ERROR)) { /* Here htx_to_buf() will set buffer data to 0 because * the HTX is empty. */ diff -Nru haproxy-2.4.13/src/mworker.c haproxy-2.4.14/src/mworker.c --- haproxy-2.4.13/src/mworker.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/mworker.c 2022-02-25 16:10:23.000000000 +0000 @@ -449,6 +449,36 @@ } } +/* Upon a configuration loading error some mworker_proc and FDs/server were + * assigned but the worker was never forked, we must close the FDs and + * remove the server + */ +void mworker_cleanup_proc() +{ + struct mworker_proc *child, *it; + + list_for_each_entry_safe(child, it, &proc_list, list) { + + if (child->pid == -1) { + /* Close the socketpair master side. We don't need to + * close the worker side, because it's stored in the + * GLOBAL cli listener which was supposed to be in the + * worker and which will be closed in + * mworker_cleanlisteners() + */ + if (child->ipc_fd[0] > -1) + close(child->ipc_fd[0]); + if (child->srv) { + /* only exists if we created a master CLI listener */ + free_server(child->srv); + } + LIST_DELETE(&child->list); + mworker_free_child(child); + } + } +} + + /* Displays workers and processes */ static int cli_io_handler_show_proc(struct appctx *appctx) { diff -Nru haproxy-2.4.13/src/proxy.c haproxy-2.4.14/src/proxy.c --- haproxy-2.4.13/src/proxy.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/proxy.c 2022-02-25 16:10:23.000000000 +0000 @@ -1754,7 +1754,7 @@ const struct proxy *defproxy) { struct proxy *curproxy = NULL; - char *errmsg; + char *errmsg = NULL; if (!(curproxy = alloc_new_proxy(name, cap, &errmsg))) { ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); diff -Nru haproxy-2.4.13/src/resolvers.c haproxy-2.4.14/src/resolvers.c --- haproxy-2.4.13/src/resolvers.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/resolvers.c 2022-02-25 16:10:23.000000000 +0000 @@ -1741,10 +1741,8 @@ return -1; /* ignore trailing dot */ - if (i + 1 == str_len) { - i++; + if (i + 1 == str_len) break; - } dn[offset] = (i - offset); offset = i+1; diff -Nru haproxy-2.4.13/src/sink.c haproxy-2.4.14/src/sink.c --- haproxy-2.4.13/src/sink.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/sink.c 2022-02-25 16:10:23.000000000 +0000 @@ -604,7 +604,7 @@ static void sink_forward_session_release(struct appctx *appctx) { - struct sink_forward_target *sft = appctx->ctx.peers.ptr; + struct sink_forward_target *sft = appctx->ctx.sft.ptr; if (!sft) return; diff -Nru haproxy-2.4.13/src/sock.c haproxy-2.4.14/src/sock.c --- haproxy-2.4.13/src/sock.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/sock.c 2022-02-25 16:10:23.000000000 +0000 @@ -34,8 +34,24 @@ #include #include +#define SOCK_XFER_OPT_FOREIGN 0x000000001 +#define SOCK_XFER_OPT_V6ONLY 0x000000002 +#define SOCK_XFER_OPT_DGRAM 0x000000004 + /* the list of remaining sockets transferred from an older process */ -struct xfer_sock_list *xfer_sock_list = NULL; +struct xfer_sock_list { + int fd; + int options; /* socket options as SOCK_XFER_OPT_* */ + char *iface; + char *namespace; + int if_namelen; + int ns_namelen; + struct xfer_sock_list *prev; + struct xfer_sock_list *next; + struct sockaddr_storage addr; +}; + +static struct xfer_sock_list *xfer_sock_list; /* Accept an incoming connection from listener , and return it, as well as @@ -595,6 +611,24 @@ return ret; } +/* After all protocols are bound, there may remain some old sockets that have + * been removed between the previous config and the new one. These ones must + * be dropped, otherwise they will remain open and may prevent a service from + * restarting. + */ +void sock_drop_unused_old_sockets() +{ + while (xfer_sock_list != NULL) { + struct xfer_sock_list *tmpxfer = xfer_sock_list->next; + + close(xfer_sock_list->fd); + free(xfer_sock_list->iface); + free(xfer_sock_list->namespace); + free(xfer_sock_list); + xfer_sock_list = tmpxfer; + } +} + /* Tests if the receiver supports accepting connections. Returns positive on * success, 0 if not possible, negative if the socket is non-recoverable. The * rationale behind this is that inherited FDs may be broken and that shared diff -Nru haproxy-2.4.13/src/ssl_sock.c haproxy-2.4.14/src/ssl_sock.c --- haproxy-2.4.13/src/ssl_sock.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/ssl_sock.c 2022-02-25 16:10:23.000000000 +0000 @@ -2270,13 +2270,13 @@ : SSL_set_min_proto_version(ssl, TLS1_2_VERSION); } static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) { -#if SSL_OP_NO_TLSv1_3 +#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION); #endif } static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) { -#if SSL_OP_NO_TLSv1_3 +#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION) : SSL_set_min_proto_version(ssl, TLS1_3_VERSION); #endif diff -Nru haproxy-2.4.13/src/stream.c haproxy-2.4.14/src/stream.c --- haproxy-2.4.13/src/stream.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/stream.c 2022-02-25 16:10:23.000000000 +0000 @@ -775,13 +775,8 @@ */ static int stream_alloc_work_buffer(struct stream *s) { - if (LIST_INLIST(&s->buffer_wait.list)) - LIST_DEL_INIT(&s->buffer_wait.list); - if (b_alloc(&s->res.buf)) return 1; - - LIST_APPEND(&ti->buffer_wq, &s->buffer_wait.list); return 0; } @@ -1710,15 +1705,24 @@ resync_stream_interface: /* below we may emit error messages so we have to ensure that we have - * our buffers properly allocated. + * our buffers properly allocated. If the allocation failed, an error is + * triggered. + * + * NOTE: An error is returned because the mechanism to queue entities + * waiting for a buffer is totally broken for now. However, this + * part must be refactored. When it will be handled, this part + * must be be reviewed too. */ if (!stream_alloc_work_buffer(s)) { - /* No buffer available, we've been subscribed to the list of - * buffer waiters, let's wait for our turn. - */ - si_f->flags &= ~SI_FL_DONT_WAKE; - si_b->flags &= ~SI_FL_DONT_WAKE; - goto update_exp_and_leave; + si_f->flags |= SI_FL_ERR; + si_f->err_type = SI_ET_CONN_RES; + + si_b->flags |= SI_FL_ERR; + si_b->err_type = SI_ET_CONN_RES; + + if (!(s->flags & SF_ERR_MASK)) + s->flags |= SF_ERR_RESOURCE; + sess_set_term_flags(s); } /* 1b: check for low-level errors reported at the stream interface. diff -Nru haproxy-2.4.13/src/tools.c haproxy-2.4.14/src/tools.c --- haproxy-2.4.13/src/tools.c 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/src/tools.c 2022-02-25 16:10:23.000000000 +0000 @@ -1673,12 +1673,20 @@ return end - url; } else { + /* we need to copy the string into the trash because url2ipv4 + * needs a \0 at the end of the string */ + if (trash.size < ulen) + return -1; + + memcpy(trash.area, curr, ulen - (curr - url)); + trash.area[ulen - (curr - url)] = '\0'; + /* We are looking for IP address. If you want to parse and * resolve hostname found in url, you can use str2sa_range(), but * be warned this can slow down global daemon performances * while handling lagging dns responses. */ - ret = url2ipv4(curr, &((struct sockaddr_in *)addr)->sin_addr); + ret = url2ipv4(trash.area, &((struct sockaddr_in *)addr)->sin_addr); if (ret) { /* Update out. */ if (out) { @@ -1686,7 +1694,9 @@ out->host_len = ret; } - curr += ret; + /* we need to assign again curr and end from the trash */ + url = trash.area; + curr = trash.area + ret; /* Decode port. */ if (*curr == ':') { diff -Nru haproxy-2.4.13/SUBVERS haproxy-2.4.14/SUBVERS --- haproxy-2.4.13/SUBVERS 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/SUBVERS 2022-02-25 16:10:23.000000000 +0000 @@ -1,2 +1,2 @@ --095275f +-eaa786f diff -Nru haproxy-2.4.13/VERDATE haproxy-2.4.14/VERDATE --- haproxy-2.4.13/VERDATE 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/VERDATE 2022-02-25 16:10:23.000000000 +0000 @@ -1,2 +1,2 @@ -2022-02-16 16:29:03 +0100 -2022/02/16 +2022-02-25 17:10:23 +0100 +2022/02/25 diff -Nru haproxy-2.4.13/VERSION haproxy-2.4.14/VERSION --- haproxy-2.4.13/VERSION 2022-02-16 15:29:03.000000000 +0000 +++ haproxy-2.4.14/VERSION 2022-02-25 16:10:23.000000000 +0000 @@ -1 +1 @@ -2.4.13 +2.4.14