Merge ~ahasenack/ubuntu/+source/haproxy:jammy-haproxy-2414-merge into ubuntu/+source/haproxy:ubuntu/devel

Proposed by Andreas Hasenack
Status: Superseded
Proposed branch: ~ahasenack/ubuntu/+source/haproxy:jammy-haproxy-2414-merge
Merge into: ubuntu/+source/haproxy:ubuntu/devel
Diff against target: 1115 lines (+309/-157) (has conflicts)
31 files modified
.github/matrix.py (+3/-0)
.github/workflows/compliance.yml (+1/-1)
.github/workflows/vtest.yml (+1/-1)
.github/workflows/windows.yml (+1/-1)
CHANGELOG (+28/-0)
SUBVERS (+1/-1)
VERDATE (+2/-2)
VERSION (+1/-1)
debian/changelog (+22/-0)
doc/configuration.txt (+1/-1)
include/haproxy/compiler.h (+25/-0)
include/haproxy/htx.h (+2/-2)
include/haproxy/mworker.h (+1/-0)
include/haproxy/server-t.h (+4/-4)
include/haproxy/sock-t.h (+0/-17)
include/haproxy/sock.h (+1/-2)
reg-tests/checks/40be_2srv_odd_health_checks.vtc (+91/-84)
scripts/build-ssl.sh (+11/-4)
src/fd.c (+7/-3)
src/haproxy.c (+5/-8)
src/mailers.c (+1/-1)
src/mux_h1.c (+1/-1)
src/mux_h2.c (+1/-1)
src/mworker.c (+30/-0)
src/proxy.c (+1/-1)
src/resolvers.c (+1/-3)
src/sink.c (+1/-1)
src/sock.c (+35/-1)
src/ssl_sock.c (+2/-2)
src/stream.c (+16/-12)
src/tools.c (+12/-2)
Conflict in debian/changelog
Reviewer Review Type Date Requested Status
Canonical Server Pending
Canonical Server Core Reviewers Pending
Review via email: mp+416139@code.launchpad.net

This proposal has been superseded by a proposal from 2022-02-28.

Description of the change

New upstream release.

The upstream changelog[1] only mentions bugfixes and CI changes, so I think this does not need a feature freeze exception.

With this new upstream release, we are able to drop one of the delta bits we have, which was openssl3 compatibility.

PPA: https://launchpad.net/~ahasenack/+archive/ubuntu/haproxy-merge/+packages

1, http://www.haproxy.org/download/2.4/src/CHANGELOG

To post a comment you must log in.

Unmerged commits

7c8df16... by Andreas Hasenack

update-maintainer

5b165d6... by Andreas Hasenack

reconstruct-changelog

a36d43f... by Andreas Hasenack

merge-changelogs

2eb4322... by Andreas Hasenack

  * Dropped:
    - d/p/fix-ftbfs-openssl3.patch: Cherry-picked from upstream to fix
      the build against OpenSSL3 (LP: #1945773)
      [Fixed upstream]

cc5fa1b... by Miriam EspaƱa Acebal

    - d/{control,rules}: Removing support for OpenTracing due to it is
      in universe.

233891c... by Vincent Bernat

2.4.14-1 (patches unapplied)

Imported using git-ubuntu import.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.github/matrix.py b/.github/matrix.py
2index 9900314..116ea98 100644
3--- a/.github/matrix.py
4+++ b/.github/matrix.py
5@@ -104,6 +104,7 @@ for CC in ["gcc", "clang"]:
6 for ssl in [
7 "stock",
8 "OPENSSL_VERSION=1.0.2u",
9+ "OPENSSL_VERSION=3.0.1",
10 "LIBRESSL_VERSION=2.9.2",
11 "LIBRESSL_VERSION=3.3.3",
12 # "BORINGSSL=yes",
13@@ -111,6 +112,8 @@ for CC in ["gcc", "clang"]:
14 flags = ["USE_OPENSSL=1"]
15 if ssl == "BORINGSSL=yes":
16 flags.append("USE_QUIC=1")
17+ if "OPENSSL_VERSION=3.0." in ssl:
18+ flags.append('DEBUG_CFLAGS="-g -Wno-deprecated-declarations"')
19 if ssl != "stock":
20 flags.append("SSL_LIB=${HOME}/opt/lib")
21 flags.append("SSL_INC=${HOME}/opt/include")
22diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml
23index 9f2bec2..4696c06 100644
24--- a/.github/workflows/compliance.yml
25+++ b/.github/workflows/compliance.yml
26@@ -30,7 +30,7 @@ jobs:
27 ERR=1 \
28 TARGET=${{ matrix.TARGET }} \
29 CC=${{ matrix.CC }} \
30- DEBUG=-DDEBUG_STRICT=1 \
31+ DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \
32 USE_OPENSSL=1
33 sudo make install
34 - name: Show HAProxy version
35diff --git a/.github/workflows/vtest.yml b/.github/workflows/vtest.yml
36index cb52f27..8e64995 100644
37--- a/.github/workflows/vtest.yml
38+++ b/.github/workflows/vtest.yml
39@@ -77,7 +77,7 @@ jobs:
40 ERR=1 \
41 TARGET=${{ matrix.TARGET }} \
42 CC=${{ matrix.CC }} \
43- DEBUG=-DDEBUG_STRICT=1 \
44+ DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \
45 ${{ join(matrix.FLAGS, ' ') }} \
46 ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/"
47 sudo make install
48diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
49index b5a198a..0449808 100644
50--- a/.github/workflows/windows.yml
51+++ b/.github/workflows/windows.yml
52@@ -52,7 +52,7 @@ jobs:
53 ERR=1 \
54 TARGET=${{ matrix.TARGET }} \
55 CC=${{ matrix.CC }} \
56- DEBUG=-DDEBUG_STRICT=1 \
57+ DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \
58 ${{ join(matrix.FLAGS, ' ') }}
59 - name: Show HAProxy version
60 id: show-version
61diff --git a/CHANGELOG b/CHANGELOG
62index 163070a..341776f 100644
63--- a/CHANGELOG
64+++ b/CHANGELOG
65@@ -1,6 +1,34 @@
66 ChangeLog :
67 ===========
68
69+2022/02/25 : 2.4.14
70+ - MINOR: sock: move the unused socket cleaning code into its own function
71+ - BUG/MEDIUM: mworker: close unused transferred FDs on load failure
72+ - BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload
73+ - BUG/MINOR: sink: Use the right field in appctx context in release callback
74+ - BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names
75+ - BUG/MEDIUM: fd: always align fdtab[] to 64 bytes
76+ - BUG/MAJOR: compiler: relax alignment constraints on certain structures
77+ - CI: ssl: enable parallel builds for OpenSSL on Linux
78+ - CI: ssl: do not needlessly build the OpenSSL docs
79+ - CI: ssl: keep the old method for ancient OpenSSL versions
80+ - BUILD: fix compilation for OpenSSL-3.0.0-alpha17
81+ - BUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2
82+ - CI: github actions: add OpenSSL-3.0.0 builds
83+ - CI: github actions: -Wno-deprecated-declarations with OpenSSL 3.0.0
84+ - CI: github actions: relax OpenSSL-3.0.0 version comparision
85+ - CI: github: switch to OpenSSL 3.0.0
86+ - CI: github actions: update OpenSSL to 3.0.1
87+ - BUG/MINOR: mailers: negotiate SMTP, not ESMTP
88+ - BUG/MINOR: tools: url2sa reads ipv4 too far
89+ - BUG/MEDIUM: htx: Be sure to have a buffer to perform a raw copy of a message
90+ - BUG/MEDIUM: mux-h1: Don't wake h1s if mux is blocked on lack of output buffer
91+ - BUG/MAJOR: mux-h2: Be sure to always report HTX parsing error to the app layer
92+ - BUG/MINOR: proxy: preset the error message pointer to NULL in parse_new_proxy()
93+ - REGTESTS: fix the race conditions in 40be_2srv_odd_health_checks
94+ - CI: github: enable pool debugging by default
95+ - BUG/MEDIUM: stream: Abort processing if response buffer allocation fails
96+
97 2022/02/16 : 2.4.13
98 - BUG/MEDIUM: connection: properly leave stopping list on error
99 - BUG/MEDIUM: htx: Adjust length to add DATA block in an empty HTX buffer
100diff --git a/SUBVERS b/SUBVERS
101index f9dfc31..3c7b54b 100644
102--- a/SUBVERS
103+++ b/SUBVERS
104@@ -1,2 +1,2 @@
105--095275f
106+-eaa786f
107
108diff --git a/VERDATE b/VERDATE
109index 550bed4..cd15a46 100644
110--- a/VERDATE
111+++ b/VERDATE
112@@ -1,2 +1,2 @@
113-2022-02-16 16:29:03 +0100
114-2022/02/16
115+2022-02-25 17:10:23 +0100
116+2022/02/25
117diff --git a/VERSION b/VERSION
118index b40e924..e5f3129 100644
119--- a/VERSION
120+++ b/VERSION
121@@ -1 +1 @@
122-2.4.13
123+2.4.14
124diff --git a/debian/changelog b/debian/changelog
125index 5e4e436..edba303 100644
126--- a/debian/changelog
127+++ b/debian/changelog
128@@ -1,3 +1,25 @@
129+<<<<<<< debian/changelog
130+=======
131+haproxy (2.4.14-1ubuntu1) jammy; urgency=medium
132+
133+ * Merge with Debian unstable. Remaining changes:
134+ - d/{control,rules}: Removing support for OpenTracing due to it is
135+ in universe.
136+ * Dropped:
137+ - d/p/fix-ftbfs-openssl3.patch: Cherry-picked from upstream to fix
138+ the build against OpenSSL3 (LP: #1945773)
139+ [Fixed upstream]
140+
141+ -- Andreas Hasenack <andreas@canonical.com> Mon, 28 Feb 2022 09:48:35 -0300
142+
143+haproxy (2.4.14-1) unstable; urgency=medium
144+
145+ * New upstream release.
146+ - Fix compilation with OpenSSL 3.0. Closes: #996423, #1006007.
147+
148+ -- Vincent Bernat <bernat@debian.org> Fri, 25 Feb 2022 18:38:27 +0100
149+
150+>>>>>>> debian/changelog
151 haproxy (2.4.13-1ubuntu1) jammy; urgency=medium
152
153 * Merge with Debian unstable (LP: #1961195). Remaining changes:
154diff --git a/doc/configuration.txt b/doc/configuration.txt
155index b48b8ad..03420c9 100644
156--- a/doc/configuration.txt
157+++ b/doc/configuration.txt
158@@ -4,7 +4,7 @@
159 ----------------------
160 version 2.4
161 willy tarreau
162- 2022/02/16
163+ 2022/02/25
164
165
166 This document covers the configuration language as implemented in the version
167diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h
168index 352da8e..b975412 100644
169--- a/include/haproxy/compiler.h
170+++ b/include/haproxy/compiler.h
171@@ -203,6 +203,17 @@
172 #define HA_HAVE_CAS_DW
173 #endif
174
175+/*********************** IMPORTANT NOTE ABOUT ALIGNMENT **********************\
176+ * Alignment works fine for variables. It also works on types and struct *
177+ * members by propagating the alignment to the container struct itself, *
178+ * but this requires that variables of the affected type are properly *
179+ * aligned themselves. While regular variables will always abide, those *
180+ * allocated using malloc() will not! Most platforms provide posix_memalign()*
181+ * for this, but it's not available everywhere. As such one ought not to use *
182+ * these alignment declarations inside structures that are dynamically *
183+ * allocated. If the purpose is only to avoid false sharing of cache lines *
184+ * for multi_threading, see THREAD_PAD() below. *
185+\*****************************************************************************/
186
187 /* sets alignment for current field or variable */
188 #ifndef ALIGNED
189@@ -277,6 +288,20 @@
190 #endif
191 #endif
192
193+/* add optional padding of the specified size between fields in a structure,
194+ * only when threads are enabled. This is used to avoid false sharing of cache
195+ * lines for dynamically allocated structures which cannot guarantee alignment.
196+ */
197+#ifndef THREAD_PAD
198+# ifdef USE_THREAD
199+# define __THREAD_PAD(x,l) char __pad_##l[x]
200+# define _THREAD_PAD(x,l) __THREAD_PAD(x, l)
201+# define THREAD_PAD(x) _THREAD_PAD(x, __LINE__)
202+# else
203+# define THREAD_PAD(x)
204+# endif
205+#endif
206+
207 /* The THREAD_LOCAL type attribute defines thread-local storage and is defined
208 * to __thread when threads are enabled or empty when disabled.
209 */
210diff --git a/include/haproxy/htx.h b/include/haproxy/htx.h
211index ef9a1bc..ca24213 100644
212--- a/include/haproxy/htx.h
213+++ b/include/haproxy/htx.h
214@@ -749,8 +749,8 @@ static inline int htx_expect_more(const struct htx *htx)
215 */
216 static inline int htx_copy_msg(struct htx *htx, const struct buffer *msg)
217 {
218- /* The destination HTX message is empty, we can do a raw copy */
219- if (htx_is_empty(htx)) {
220+ /* The destination HTX message is allocated and empty, we can do a raw copy */
221+ if (htx_is_empty(htx) && htx_free_space(htx)) {
222 memcpy(htx, msg->area, msg->size);
223 return 1;
224 }
225diff --git a/include/haproxy/mworker.h b/include/haproxy/mworker.h
226index 279fb08..acabdd3 100644
227--- a/include/haproxy/mworker.h
228+++ b/include/haproxy/mworker.h
229@@ -42,5 +42,6 @@ int mworker_ext_launch_all();
230 void mworker_kill_max_reloads(int sig);
231
232 void mworker_free_child(struct mworker_proc *);
233+void mworker_cleanup_proc();
234
235 #endif /* _HAPROXY_MWORKER_H_ */
236diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h
237index 200385f..8882388 100644
238--- a/include/haproxy/server-t.h
239+++ b/include/haproxy/server-t.h
240@@ -275,7 +275,7 @@ struct server {
241 /* The elements below may be changed on every single request by any
242 * thread, and generally at the same time.
243 */
244- ALWAYS_ALIGN(64);
245+ THREAD_PAD(63);
246 struct eb32_node idle_node; /* When to next do cleanup in the idle connections */
247 unsigned int curr_idle_conns; /* Current number of orphan idling connections, both the idle and the safe lists */
248 unsigned int curr_idle_nb; /* Current number of connections in the idle list */
249@@ -290,14 +290,14 @@ struct server {
250 /* Element below are usd by LB algorithms and must be doable in
251 * parallel to other threads reusing connections above.
252 */
253- ALWAYS_ALIGN(64);
254+ THREAD_PAD(63);
255 __decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */
256 unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
257 struct eb32_node lb_node; /* node used for tree-based load balancing */
258 struct server *next_full; /* next server in the temporary full list */
259
260 /* usually atomically updated by any thread during parsing or on end of request */
261- ALWAYS_ALIGN(64);
262+ THREAD_PAD(63);
263 int cur_sess; /* number of currently active sessions (including syn_sent) */
264 int served; /* # of active sessions currently being served (ie not pending) */
265 int nbpend; /* number of pending connections */
266@@ -307,7 +307,7 @@ struct server {
267 struct be_counters counters; /* statistics counters */
268
269 /* Below are some relatively stable settings, only changed under the lock */
270- ALWAYS_ALIGN(64);
271+ THREAD_PAD(63);
272
273 struct eb_root *lb_tree; /* we want to know in what tree the server is */
274 struct tree_occ *lb_nodes; /* lb_nodes_tot * struct tree_occ */
275diff --git a/include/haproxy/sock-t.h b/include/haproxy/sock-t.h
276index 1a49dfa..b843d44 100644
277--- a/include/haproxy/sock-t.h
278+++ b/include/haproxy/sock-t.h
279@@ -27,23 +27,6 @@
280
281 #include <haproxy/api-t.h>
282
283-#define SOCK_XFER_OPT_FOREIGN 0x000000001
284-#define SOCK_XFER_OPT_V6ONLY 0x000000002
285-#define SOCK_XFER_OPT_DGRAM 0x000000004
286-
287-/* The list used to transfer sockets between old and new processes */
288-struct xfer_sock_list {
289- int fd;
290- int options; /* socket options as SOCK_XFER_OPT_* */
291- char *iface;
292- char *namespace;
293- int if_namelen;
294- int ns_namelen;
295- struct xfer_sock_list *prev;
296- struct xfer_sock_list *next;
297- struct sockaddr_storage addr;
298-};
299-
300 #endif /* _HAPROXY_SOCK_T_H */
301
302 /*
303diff --git a/include/haproxy/sock.h b/include/haproxy/sock.h
304index 1a5b68c..49dffa9 100644
305--- a/include/haproxy/sock.h
306+++ b/include/haproxy/sock.h
307@@ -30,8 +30,6 @@
308 #include <haproxy/listener-t.h>
309 #include <haproxy/sock-t.h>
310
311-extern struct xfer_sock_list *xfer_sock_list;
312-
313 int sock_create_server_socket(struct connection *conn);
314 void sock_enable(struct receiver *rx);
315 void sock_disable(struct receiver *rx);
316@@ -40,6 +38,7 @@ int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
317 int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
318 int sock_get_old_sockets(const char *unixsocket);
319 int sock_find_compatible_fd(const struct receiver *rx);
320+void sock_drop_unused_old_sockets();
321 int sock_accepting_conn(const struct receiver *rx);
322 struct connection *sock_accept_conn(struct listener *l, int *status);
323 void sock_accept_iocb(int fd);
324diff --git a/reg-tests/checks/40be_2srv_odd_health_checks.vtc b/reg-tests/checks/40be_2srv_odd_health_checks.vtc
325index 22f80cd..0065c9c 100644
326--- a/reg-tests/checks/40be_2srv_odd_health_checks.vtc
327+++ b/reg-tests/checks/40be_2srv_odd_health_checks.vtc
328@@ -14,6 +14,8 @@ feature ignore_unknown_macro
329 # - so that to ensure that health-checks do not consume any connection
330 # (any varnishtest server without -repeat <n> with n > 1 accepts
331 # only one connection).
332+# - we take care of sending the clients to the unchecked servers using the
333+# "first" lb algo so that servers always receive a valid request
334
335 syslog S1 -level notice {
336 recv
337@@ -115,254 +117,254 @@ syslog S39 -level notice {
338 expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be39/srv39 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP"
339 } -start
340
341-server s0 {} -start
342-server s2 {} -start
343-server s4 {} -start
344-server s6 {} -start
345-server s8 {} -start
346-server s10 {} -start
347-server s12 {} -start
348-server s14 {} -start
349-server s16 {} -start
350-server s18 {} -start
351-server s20 {} -start
352-server s22 {} -start
353-server s24 {} -start
354-server s26 {} -start
355-server s28 {} -start
356-server s30 {} -start
357-server s32 {} -start
358-server s34 {} -start
359-server s36 {} -start
360-server s38 {} -start
361-
362-server s1 {
363+server s0 {
364 rxreq
365 txresp
366 } -start
367
368-server s3 {
369+server s2 {
370 rxreq
371 txresp
372 } -start
373
374-server s5 {
375+server s4 {
376 rxreq
377 txresp
378 } -start
379
380-server s7 {
381+server s6 {
382 rxreq
383 txresp
384 } -start
385
386-server s9 {
387+server s8 {
388 rxreq
389 txresp
390 } -start
391
392-server s11 {
393+server s10 {
394 rxreq
395 txresp
396 } -start
397
398-server s13 {
399+server s12 {
400 rxreq
401 txresp
402 } -start
403
404-server s15 {
405+server s14 {
406 rxreq
407 txresp
408 } -start
409
410-server s17 {
411+server s16 {
412 rxreq
413 txresp
414 } -start
415
416-server s19 {
417+server s18 {
418 rxreq
419 txresp
420 } -start
421
422-server s21 {
423+server s20 {
424 rxreq
425 txresp
426 } -start
427
428-server s23 {
429+server s22 {
430 rxreq
431 txresp
432 } -start
433
434-server s25 {
435+server s24 {
436 rxreq
437-txresp
438+ txresp
439 } -start
440
441-server s27 {
442+server s26 {
443 rxreq
444 txresp
445 } -start
446
447-server s29 {
448+server s28 {
449 rxreq
450 txresp
451 } -start
452
453-server s31 {
454+server s30 {
455 rxreq
456 txresp
457 } -start
458
459-server s33 {
460+server s32 {
461 rxreq
462 txresp
463 } -start
464
465-server s35 {
466+server s34 {
467 rxreq
468 txresp
469 } -start
470
471-server s37 {
472+server s36 {
473 rxreq
474 txresp
475 } -start
476
477-server s39 {
478+server s38 {
479 rxreq
480 txresp
481 } -start
482
483+server s1 {} -start
484+server s3 {} -start
485+server s5 {} -start
486+server s7 {} -start
487+server s9 {} -start
488+server s11 {} -start
489+server s13 {} -start
490+server s15 {} -start
491+server s17 {} -start
492+server s19 {} -start
493+server s21 {} -start
494+server s23 {} -start
495+server s25 {} -start
496+server s27 {} -start
497+server s29 {} -start
498+server s31 {} -start
499+server s33 {} -start
500+server s35 {} -start
501+server s37 {} -start
502+server s39 {} -start
503+
504 haproxy h1 -conf {
505 defaults
506 timeout client 1s
507 timeout server 1s
508 timeout connect 1s
509 balance first
510- default-server no-check inter 5ms downinter 1s rise 1 fall 1
511+ default-server no-check inter 20ms downinter 1s rise 1 fall 1
512
513 backend be1
514 option log-health-checks
515 log ${S1_addr}:${S1_port} daemon
516- server srv1 ${s1_addr}:${s1_port} check
517 server srv0 ${s0_addr}:${s0_port}
518+ server srv1 ${s1_addr}:${s1_port} check
519
520 backend be3
521 option log-health-checks
522 log ${S3_addr}:${S3_port} daemon
523- server srv3 ${s3_addr}:${s3_port} check
524 server srv2 ${s2_addr}:${s2_port}
525+ server srv3 ${s3_addr}:${s3_port} check
526
527 backend be5
528 option log-health-checks
529 log ${S5_addr}:${S5_port} daemon
530- server srv5 ${s5_addr}:${s5_port} check
531 server srv4 ${s4_addr}:${s4_port}
532+ server srv5 ${s5_addr}:${s5_port} check
533
534 backend be7
535 option log-health-checks
536 log ${S7_addr}:${S7_port} daemon
537- server srv7 ${s7_addr}:${s7_port} check
538 server srv6 ${s6_addr}:${s6_port}
539+ server srv7 ${s7_addr}:${s7_port} check
540
541 backend be9
542 option log-health-checks
543 log ${S9_addr}:${S9_port} daemon
544- server srv9 ${s9_addr}:${s9_port} check
545 server srv8 ${s8_addr}:${s8_port}
546+ server srv9 ${s9_addr}:${s9_port} check
547
548 backend be11
549 option log-health-checks
550 log ${S11_addr}:${S11_port} daemon
551- server srv11 ${s11_addr}:${s11_port} check
552 server srv10 ${s10_addr}:${s10_port}
553+ server srv11 ${s11_addr}:${s11_port} check
554
555 backend be13
556 option log-health-checks
557 log ${S13_addr}:${S13_port} daemon
558- server srv13 ${s13_addr}:${s13_port} check
559 server srv12 ${s12_addr}:${s12_port}
560+ server srv13 ${s13_addr}:${s13_port} check
561
562 backend be15
563 option log-health-checks
564 log ${S15_addr}:${S15_port} daemon
565- server srv15 ${s15_addr}:${s15_port} check
566 server srv14 ${s14_addr}:${s14_port}
567+ server srv15 ${s15_addr}:${s15_port} check
568
569 backend be17
570 option log-health-checks
571 log ${S17_addr}:${S17_port} daemon
572- server srv17 ${s17_addr}:${s17_port} check
573 server srv16 ${s16_addr}:${s16_port}
574+ server srv17 ${s17_addr}:${s17_port} check
575
576 backend be19
577 option log-health-checks
578 log ${S19_addr}:${S19_port} daemon
579- server srv19 ${s19_addr}:${s19_port} check
580 server srv18 ${s18_addr}:${s18_port}
581+ server srv19 ${s19_addr}:${s19_port} check
582
583 backend be21
584 option log-health-checks
585 log ${S21_addr}:${S21_port} daemon
586- server srv21 ${s21_addr}:${s21_port} check
587 server srv20 ${s20_addr}:${s20_port}
588+ server srv21 ${s21_addr}:${s21_port} check
589
590 backend be23
591 option log-health-checks
592 log ${S23_addr}:${S23_port} daemon
593- server srv23 ${s23_addr}:${s23_port} check
594 server srv22 ${s22_addr}:${s22_port}
595+ server srv23 ${s23_addr}:${s23_port} check
596
597 backend be25
598 option log-health-checks
599 log ${S25_addr}:${S25_port} daemon
600- server srv25 ${s25_addr}:${s25_port} check
601 server srv24 ${s24_addr}:${s24_port}
602+ server srv25 ${s25_addr}:${s25_port} check
603
604 backend be27
605 option log-health-checks
606 log ${S27_addr}:${S27_port} daemon
607- server srv27 ${s27_addr}:${s27_port} check
608 server srv26 ${s26_addr}:${s26_port}
609+ server srv27 ${s27_addr}:${s27_port} check
610
611 backend be29
612 option log-health-checks
613 log ${S29_addr}:${S29_port} daemon
614- server srv29 ${s29_addr}:${s29_port} check
615 server srv28 ${s28_addr}:${s28_port}
616+ server srv29 ${s29_addr}:${s29_port} check
617
618 backend be31
619 option log-health-checks
620 log ${S31_addr}:${S31_port} daemon
621- server srv31 ${s31_addr}:${s31_port} check
622 server srv30 ${s30_addr}:${s30_port}
623+ server srv31 ${s31_addr}:${s31_port} check
624
625 backend be33
626 option log-health-checks
627 log ${S33_addr}:${S33_port} daemon
628- server srv33 ${s33_addr}:${s33_port} check
629 server srv32 ${s32_addr}:${s32_port}
630+ server srv33 ${s33_addr}:${s33_port} check
631
632 backend be35
633 option log-health-checks
634 log ${S35_addr}:${S35_port} daemon
635- server srv35 ${s35_addr}:${s35_port} check
636 server srv34 ${s34_addr}:${s34_port}
637+ server srv35 ${s35_addr}:${s35_port} check
638
639 backend be37
640 option log-health-checks
641 log ${S37_addr}:${S37_port} daemon
642- server srv37 ${s37_addr}:${s37_port} check
643 server srv36 ${s36_addr}:${s36_port}
644+ server srv37 ${s37_addr}:${s37_port} check
645
646 backend be39
647 option log-health-checks
648 log ${S39_addr}:${S39_port} daemon
649- server srv39 ${s39_addr}:${s39_port} check
650 server srv38 ${s38_addr}:${s38_port}
651+ server srv39 ${s39_addr}:${s39_port} check
652
653 frontend fe1
654 bind "fd@${fe1}"
655@@ -609,30 +611,35 @@ client c35 -wait
656 client c37 -wait
657 client c39 -wait
658
659-server s1 -wait
660-server s3 -wait
661-server s5 -wait
662-server s7 -wait
663-server s9 -wait
664-server s11 -wait
665-server s13 -wait
666-server s15 -wait
667-server s17 -wait
668-server s19 -wait
669-server s21 -wait
670-server s23 -wait
671-server s25 -wait
672-server s27 -wait
673-server s29 -wait
674-server s31 -wait
675-server s33 -wait
676-server s35 -wait
677-server s37 -wait
678-server s39 -wait
679+server s0 -wait
680+server s2 -wait
681+server s4 -wait
682+server s6 -wait
683+server s8 -wait
684+server s10 -wait
685+server s12 -wait
686+server s14 -wait
687+server s16 -wait
688+server s18 -wait
689+server s20 -wait
690+server s22 -wait
691+server s24 -wait
692+server s26 -wait
693+server s28 -wait
694+server s30 -wait
695+server s32 -wait
696+server s34 -wait
697+server s36 -wait
698+server s38 -wait
699
700
701 haproxy h1 -cli {
702 send "show servers state"
703- 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"
704+ # output produced using the command below (warning, a bug inserts a "be0" every other line:
705+ # for ((i=0;i<40;i++)); do id=$((i/2+2)); be=$((i|1)); si=$(((i&1)+1));
706+ # if ((i&1)); then chk="6 ([[:digit:]]+ ){3}"; else chk="1 0 1 0 ";fi;
707+ # 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" ;
708+ # done|grep -v be0|sed 's,$,\\n,'| tr -d '\n'
709+ 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"
710 }
711
712diff --git a/scripts/build-ssl.sh b/scripts/build-ssl.sh
713index 9a6a2b2..e1d89a0 100755
714--- a/scripts/build-ssl.sh
715+++ b/scripts/build-ssl.sh
716@@ -17,11 +17,18 @@ download_openssl () {
717 fi
718 }
719
720+# recent openssl versions support parallel builds and skipping the docs,
721+# while older ones require to build everything sequentially.
722 build_openssl_linux () {
723 (
724 cd "openssl-${OPENSSL_VERSION}/"
725- ./config shared --prefix="${HOME}/opt" --openssldir="${HOME}/opt" -DPURIFY
726- make all install_sw
727+ ./config shared --prefix="${HOME}/opt" --openssldir="${HOME}/opt" --libdir=lib -DPURIFY
728+ if [ -z "${OPENSSL_VERSION##1.*}" ]; then
729+ make all
730+ else
731+ make -j$(nproc) build_sw
732+ fi
733+ make install_sw
734 )
735 }
736
737@@ -29,8 +36,8 @@ build_openssl_osx () {
738 (
739 cd "openssl-${OPENSSL_VERSION}/"
740 ./Configure darwin64-x86_64-cc shared \
741- --prefix="${HOME}/opt" --openssldir="${HOME}/opt" -DPURIFY
742- make depend all install_sw
743+ --prefix="${HOME}/opt" --openssldir="${HOME}/opt" --libdir=lib -DPURIFY
744+ make depend build_sw install_sw
745 )
746 }
747
748diff --git a/src/fd.c b/src/fd.c
749index 733658c..5f465f0 100644
750--- a/src/fd.c
751+++ b/src/fd.c
752@@ -114,6 +114,7 @@ THREAD_LOCAL int poller_rd_pipe = -1; // Pipe to wake the thread
753 int poller_wr_pipe[MAX_THREADS] __read_mostly; // Pipe to wake the threads
754
755 volatile int ha_used_fds = 0; // Number of FD we're currently using
756+static struct fdtab *fdtab_addr; /* address of the allocated area containing fdtab */
757
758 #define _GET_NEXT(fd, off) ((volatile struct fdlist_entry *)(void *)((char *)(&fdtab[fd]) + off))->next
759 #define _GET_PREV(fd, off) ((volatile struct fdlist_entry *)(void *)((char *)(&fdtab[fd]) + off))->prev
760@@ -685,11 +686,14 @@ int init_pollers()
761 int p;
762 struct poller *bp;
763
764- if ((fdtab = calloc(global.maxsock, sizeof(*fdtab))) == NULL) {
765+ if ((fdtab_addr = calloc(global.maxsock, sizeof(*fdtab) + 64)) == NULL) {
766 ha_alert("Not enough memory to allocate %d entries for fdtab!\n", global.maxsock);
767 goto fail_tab;
768 }
769
770+ /* always provide an aligned fdtab */
771+ fdtab = (struct fdtab*)((((size_t)fdtab_addr) + 63) & -(size_t)64);
772+
773 if ((polled_mask = calloc(global.maxsock, sizeof(*polled_mask))) == NULL) {
774 ha_alert("Not enough memory to allocate %d entries for polled_mask!\n", global.maxsock);
775 goto fail_polledmask;
776@@ -726,7 +730,7 @@ int init_pollers()
777 fail_info:
778 free(polled_mask);
779 fail_polledmask:
780- free(fdtab);
781+ free(fdtab_addr);
782 fail_tab:
783 return 0;
784 }
785@@ -747,7 +751,7 @@ void deinit_pollers() {
786 }
787
788 ha_free(&fdinfo);
789- ha_free(&fdtab);
790+ ha_free(&fdtab_addr);
791 ha_free(&polled_mask);
792 }
793
794diff --git a/src/haproxy.c b/src/haproxy.c
795index ef5021a..d64c0e4 100644
796--- a/src/haproxy.c
797+++ b/src/haproxy.c
798@@ -714,6 +714,7 @@ void mworker_reload()
799 #endif
800 setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
801
802+ mworker_cleanup_proc();
803 mworker_proc_list_to_env(); /* put the children description in the env */
804
805 /* during the reload we must ensure that every FDs that can't be
806@@ -860,6 +861,9 @@ void reexec_on_failure()
807
808 setenv("HAPROXY_MWORKER_WAIT_ONLY", "1", 1);
809
810+ /* do not keep unused FDs retrieved from the previous process */
811+ sock_drop_unused_old_sockets();
812+
813 ha_warning("Reexecuting Master process in waitpid mode\n");
814 mworker_reload();
815 }
816@@ -3029,14 +3033,7 @@ int main(int argc, char **argv)
817 /* Ok, all listeners should now be bound, close any leftover sockets
818 * the previous process gave us, we don't need them anymore
819 */
820- while (xfer_sock_list != NULL) {
821- struct xfer_sock_list *tmpxfer = xfer_sock_list->next;
822- close(xfer_sock_list->fd);
823- free(xfer_sock_list->iface);
824- free(xfer_sock_list->namespace);
825- free(xfer_sock_list);
826- xfer_sock_list = tmpxfer;
827- }
828+ sock_drop_unused_old_sockets();
829
830 /* prepare pause/play signals */
831 signal_register_fct(SIGTTOU, sig_pause, SIGTTOU);
832diff --git a/src/mailers.c b/src/mailers.c
833index 3df02f0..4138bae 100644
834--- a/src/mailers.c
835+++ b/src/mailers.c
836@@ -195,7 +195,7 @@ static int enqueue_one_email_alert(struct proxy *p, struct server *s,
837 goto error;
838
839 {
840- const char * const strs[4] = { "EHLO ", p->email_alert.myhostname, "\r\n" };
841+ const char * const strs[4] = { "HELO ", p->email_alert.myhostname, "\r\n" };
842 if (!add_tcpcheck_send_strs(&alert->rules, strs))
843 goto error;
844 }
845diff --git a/src/mux_h1.c b/src/mux_h1.c
846index 41bd4dc..c362dfd 100644
847--- a/src/mux_h1.c
848+++ b/src/mux_h1.c
849@@ -2683,7 +2683,7 @@ static int h1_send(struct h1c *h1c)
850 }
851
852 end:
853- if (!(h1c->flags & H1C_F_OUT_FULL))
854+ if (!(h1c->flags & (H1C_F_OUT_FULL|H1C_F_OUT_ALLOC)))
855 h1_wake_stream_for_send(h1c->h1s);
856
857 /* We're done, no more to send */
858diff --git a/src/mux_h2.c b/src/mux_h2.c
859index 0476bc3..11c660e 100644
860--- a/src/mux_h2.c
861+++ b/src/mux_h2.c
862@@ -6357,7 +6357,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
863
864 /* transfer possibly pending data to the upper layer */
865 h2s_htx = htx_from_buf(&h2s->rxbuf);
866- if (htx_is_empty(h2s_htx)) {
867+ if (htx_is_empty(h2s_htx) && !(h2s_htx->flags & HTX_FL_PARSING_ERROR)) {
868 /* Here htx_to_buf() will set buffer data to 0 because
869 * the HTX is empty.
870 */
871diff --git a/src/mworker.c b/src/mworker.c
872index 991394c..7a8feda 100644
873--- a/src/mworker.c
874+++ b/src/mworker.c
875@@ -449,6 +449,36 @@ void mworker_cleanlisteners()
876 }
877 }
878
879+/* Upon a configuration loading error some mworker_proc and FDs/server were
880+ * assigned but the worker was never forked, we must close the FDs and
881+ * remove the server
882+ */
883+void mworker_cleanup_proc()
884+{
885+ struct mworker_proc *child, *it;
886+
887+ list_for_each_entry_safe(child, it, &proc_list, list) {
888+
889+ if (child->pid == -1) {
890+ /* Close the socketpair master side. We don't need to
891+ * close the worker side, because it's stored in the
892+ * GLOBAL cli listener which was supposed to be in the
893+ * worker and which will be closed in
894+ * mworker_cleanlisteners()
895+ */
896+ if (child->ipc_fd[0] > -1)
897+ close(child->ipc_fd[0]);
898+ if (child->srv) {
899+ /* only exists if we created a master CLI listener */
900+ free_server(child->srv);
901+ }
902+ LIST_DELETE(&child->list);
903+ mworker_free_child(child);
904+ }
905+ }
906+}
907+
908+
909 /* Displays workers and processes */
910 static int cli_io_handler_show_proc(struct appctx *appctx)
911 {
912diff --git a/src/proxy.c b/src/proxy.c
913index 4e866b1..92b84ef 100644
914--- a/src/proxy.c
915+++ b/src/proxy.c
916@@ -1754,7 +1754,7 @@ struct proxy *parse_new_proxy(const char *name, unsigned int cap,
917 const struct proxy *defproxy)
918 {
919 struct proxy *curproxy = NULL;
920- char *errmsg;
921+ char *errmsg = NULL;
922
923 if (!(curproxy = alloc_new_proxy(name, cap, &errmsg))) {
924 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
925diff --git a/src/resolvers.c b/src/resolvers.c
926index 4a306fa..49e16f6 100644
927--- a/src/resolvers.c
928+++ b/src/resolvers.c
929@@ -1741,10 +1741,8 @@ int resolv_str_to_dn_label(const char *str, int str_len, char *dn, int dn_len)
930 return -1;
931
932 /* ignore trailing dot */
933- if (i + 1 == str_len) {
934- i++;
935+ if (i + 1 == str_len)
936 break;
937- }
938
939 dn[offset] = (i - offset);
940 offset = i+1;
941diff --git a/src/sink.c b/src/sink.c
942index 6358da5..0f421cc 100644
943--- a/src/sink.c
944+++ b/src/sink.c
945@@ -604,7 +604,7 @@ void __sink_forward_session_deinit(struct sink_forward_target *sft)
946
947 static void sink_forward_session_release(struct appctx *appctx)
948 {
949- struct sink_forward_target *sft = appctx->ctx.peers.ptr;
950+ struct sink_forward_target *sft = appctx->ctx.sft.ptr;
951
952 if (!sft)
953 return;
954diff --git a/src/sock.c b/src/sock.c
955index 9d272cc..399f7b7 100644
956--- a/src/sock.c
957+++ b/src/sock.c
958@@ -34,8 +34,24 @@
959 #include <haproxy/sock_inet.h>
960 #include <haproxy/tools.h>
961
962+#define SOCK_XFER_OPT_FOREIGN 0x000000001
963+#define SOCK_XFER_OPT_V6ONLY 0x000000002
964+#define SOCK_XFER_OPT_DGRAM 0x000000004
965+
966 /* the list of remaining sockets transferred from an older process */
967-struct xfer_sock_list *xfer_sock_list = NULL;
968+struct xfer_sock_list {
969+ int fd;
970+ int options; /* socket options as SOCK_XFER_OPT_* */
971+ char *iface;
972+ char *namespace;
973+ int if_namelen;
974+ int ns_namelen;
975+ struct xfer_sock_list *prev;
976+ struct xfer_sock_list *next;
977+ struct sockaddr_storage addr;
978+};
979+
980+static struct xfer_sock_list *xfer_sock_list;
981
982
983 /* Accept an incoming connection from listener <l>, and return it, as well as
984@@ -595,6 +611,24 @@ int sock_find_compatible_fd(const struct receiver *rx)
985 return ret;
986 }
987
988+/* After all protocols are bound, there may remain some old sockets that have
989+ * been removed between the previous config and the new one. These ones must
990+ * be dropped, otherwise they will remain open and may prevent a service from
991+ * restarting.
992+ */
993+void sock_drop_unused_old_sockets()
994+{
995+ while (xfer_sock_list != NULL) {
996+ struct xfer_sock_list *tmpxfer = xfer_sock_list->next;
997+
998+ close(xfer_sock_list->fd);
999+ free(xfer_sock_list->iface);
1000+ free(xfer_sock_list->namespace);
1001+ free(xfer_sock_list);
1002+ xfer_sock_list = tmpxfer;
1003+ }
1004+}
1005+
1006 /* Tests if the receiver supports accepting connections. Returns positive on
1007 * success, 0 if not possible, negative if the socket is non-recoverable. The
1008 * rationale behind this is that inherited FDs may be broken and that shared
1009diff --git a/src/ssl_sock.c b/src/ssl_sock.c
1010index b82ab18..233b520 100644
1011--- a/src/ssl_sock.c
1012+++ b/src/ssl_sock.c
1013@@ -2270,13 +2270,13 @@ static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1014 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1015 }
1016 static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
1017-#if SSL_OP_NO_TLSv1_3
1018+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L)
1019 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
1020 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1021 #endif
1022 }
1023 static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1024-#if SSL_OP_NO_TLSv1_3
1025+#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L)
1026 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1027 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
1028 #endif
1029diff --git a/src/stream.c b/src/stream.c
1030index e0ba75e..ea997e0 100644
1031--- a/src/stream.c
1032+++ b/src/stream.c
1033@@ -775,13 +775,8 @@ static void stream_free(struct stream *s)
1034 */
1035 static int stream_alloc_work_buffer(struct stream *s)
1036 {
1037- if (LIST_INLIST(&s->buffer_wait.list))
1038- LIST_DEL_INIT(&s->buffer_wait.list);
1039-
1040 if (b_alloc(&s->res.buf))
1041 return 1;
1042-
1043- LIST_APPEND(&ti->buffer_wq, &s->buffer_wait.list);
1044 return 0;
1045 }
1046
1047@@ -1710,15 +1705,24 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
1048
1049 resync_stream_interface:
1050 /* below we may emit error messages so we have to ensure that we have
1051- * our buffers properly allocated.
1052+ * our buffers properly allocated. If the allocation failed, an error is
1053+ * triggered.
1054+ *
1055+ * NOTE: An error is returned because the mechanism to queue entities
1056+ * waiting for a buffer is totally broken for now. However, this
1057+ * part must be refactored. When it will be handled, this part
1058+ * must be be reviewed too.
1059 */
1060 if (!stream_alloc_work_buffer(s)) {
1061- /* No buffer available, we've been subscribed to the list of
1062- * buffer waiters, let's wait for our turn.
1063- */
1064- si_f->flags &= ~SI_FL_DONT_WAKE;
1065- si_b->flags &= ~SI_FL_DONT_WAKE;
1066- goto update_exp_and_leave;
1067+ si_f->flags |= SI_FL_ERR;
1068+ si_f->err_type = SI_ET_CONN_RES;
1069+
1070+ si_b->flags |= SI_FL_ERR;
1071+ si_b->err_type = SI_ET_CONN_RES;
1072+
1073+ if (!(s->flags & SF_ERR_MASK))
1074+ s->flags |= SF_ERR_RESOURCE;
1075+ sess_set_term_flags(s);
1076 }
1077
1078 /* 1b: check for low-level errors reported at the stream interface.
1079diff --git a/src/tools.c b/src/tools.c
1080index d14286c..bdf78ff 100644
1081--- a/src/tools.c
1082+++ b/src/tools.c
1083@@ -1673,12 +1673,20 @@ int url2sa(const char *url, int ulen, struct sockaddr_storage *addr, struct spli
1084 return end - url;
1085 }
1086 else {
1087+ /* we need to copy the string into the trash because url2ipv4
1088+ * needs a \0 at the end of the string */
1089+ if (trash.size < ulen)
1090+ return -1;
1091+
1092+ memcpy(trash.area, curr, ulen - (curr - url));
1093+ trash.area[ulen - (curr - url)] = '\0';
1094+
1095 /* We are looking for IP address. If you want to parse and
1096 * resolve hostname found in url, you can use str2sa_range(), but
1097 * be warned this can slow down global daemon performances
1098 * while handling lagging dns responses.
1099 */
1100- ret = url2ipv4(curr, &((struct sockaddr_in *)addr)->sin_addr);
1101+ ret = url2ipv4(trash.area, &((struct sockaddr_in *)addr)->sin_addr);
1102 if (ret) {
1103 /* Update out. */
1104 if (out) {
1105@@ -1686,7 +1694,9 @@ int url2sa(const char *url, int ulen, struct sockaddr_storage *addr, struct spli
1106 out->host_len = ret;
1107 }
1108
1109- curr += ret;
1110+ /* we need to assign again curr and end from the trash */
1111+ url = trash.area;
1112+ curr = trash.area + ret;
1113
1114 /* Decode port. */
1115 if (*curr == ':') {

Subscribers

People subscribed via source and target branches