]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 years agoMEDIUM: mux-h1: Rely on the H1C to deal with shutdown for reads
Christopher Faulet [Wed, 5 Oct 2022 06:22:33 +0000 (08:22 +0200)] 
MEDIUM: mux-h1: Rely on the H1C to deal with shutdown for reads

read0 is now handled with a H1 connection flag (H1C_F_EOS). Corresponding
flag was removed on the H1 stream and we fully rely on the SE descriptor at
the stream level.

Concretly, it means we rely on the H1 connection flags instead of the
connection one. H1C_F_EOS is only set in h1_recv() or h1_rcv_pipe() after a
read if a read0 was detected.

2 years agoMINOR: mux-h1: Add flag on H1 stream to deal with internal errors
Christopher Faulet [Wed, 5 Oct 2022 05:50:19 +0000 (07:50 +0200)] 
MINOR: mux-h1: Add flag on H1 stream to deal with internal errors

A new error is added on H1 stream to deal with internal errors. For now,
this error is only reported when we fail to create a stream-connector. This
way, the error is reported at the H1 stream level and not the H1 connection
level.

2 years agoCLEANUP: mux-h1: Rename H1C_F_ERR_PENDING into H1C_F_ABRT_PENDING
Christopher Faulet [Tue, 4 Oct 2022 15:45:24 +0000 (17:45 +0200)] 
CLEANUP: mux-h1: Rename H1C_F_ERR_PENDING into H1C_F_ABRT_PENDING

H1C_F_ERR_PENDING flags will be used to refactor error handling at the H1
connection level. It will be used to notify error during sends. Thus, the
flag to notify an error must be sent before closing the connection is now
named H1C_F_ABRT_PENDING.

This introduce a naming convertion: ERROR must be used to notify upper layer
of an event at the lower ones while ABORT must be used in the opposite
direction.

2 years agoMINOR: mux-h1: Don't handle subscribe for reads in h1_process_demux()
Christopher Faulet [Wed, 5 Oct 2022 06:39:14 +0000 (08:39 +0200)] 
MINOR: mux-h1: Don't handle subscribe for reads in h1_process_demux()

When the request headers are not fully received, we must subscribe the H1
connection for reads to be able to receive more data. This was performed in
h1_process_demux(). It is now perfoemd in h1_process_demux().

2 years agoMEDIUM: mux-h1: Handle H1C states via its state field instead of H1C_F_ST_*
Christopher Faulet [Tue, 4 Oct 2022 15:35:19 +0000 (17:35 +0200)] 
MEDIUM: mux-h1: Handle H1C states via its state field instead of H1C_F_ST_*

The H1 connection state is now handled in a dedicated state. H1C_F_ST_*
flags are removed. All states are now exclusives. It is easier to know the
H1 connection states. It is alive, or usable, if it is not CLOSING or
CLOSED. It is CLOSING if it should be closed ASAP but a stream is still
attached and/or the output buffer is not empty. CLOSED is used when the H1
connection is ready to be closed. Other states are quite easy to understand.

There is no special changes in the H1 connection behavior. Except in
h1_send(). When a CLOSING connection is CLOSED, the function now reports an
activity. In addition, when an embryonic H1 stream is aborted, it is
destroyed. This way, the H1 connection can be switched to CLOSED state.

2 years agoMINOR: mux-h1: Add a dedicated enum to deal with H1 connection state
Christopher Faulet [Tue, 4 Oct 2022 15:13:32 +0000 (17:13 +0200)] 
MINOR: mux-h1: Add a dedicated enum to deal with H1 connection state

The H1 connection state will be handled is a dedicated field. To do so,
h1_cs enum was added. The different states are more or less equivalent to
H1C_F_ST_* flags:

 * H1_CS_IDLE      <=> H1C_F_ST_IDLE
 * H1_CS_EMBRYONIC <=> H1C_F_ST_EMBRYONIC
 * H1_CS_UPGRADING <=> H1C_F_ST_ATTACHED && !H1C_F_ST_READY
 * H1_CS_RUNNING   <=> H1C_F_ST_ATTACHED && H1C_F_ST_READY
 * H1_CS_CLOSING   <=> H1C_F_ST_SHUTDOWN && (H1C_F_ST_ATTACHED || b_data(&h1c->ibuf))
 * H1_CS_CLOSED    <=> H1C_F_ST_SHUTDOWN && !H1C_F_ST_ATTACHED && !b_data(&h1c->ibuf)

In addition, in this patch, the h1_is_alive() and h1_close() function are
added. The first one will be used to know if a H1 connection is alive or
not. The second one will be used to set the connection in CLOSING or CLOSED
state, depending on the output buffer state and if there is still a H1
stream or not.

For now, the H1 connection state is not used.

2 years agoCLEANUP: mux-h1: Rename H1C_F_ST_ERROR and H1C_F_ST_SILENT_SHUT flags
Christopher Faulet [Tue, 4 Oct 2022 15:06:52 +0000 (17:06 +0200)] 
CLEANUP: mux-h1: Rename H1C_F_ST_ERROR and H1C_F_ST_SILENT_SHUT flags

_ST_ part is removed from these 2 flags because they don't reflect a
state. In addition, the H1 connection state will be handled in a dedicated
enum.

2 years agoREORG: mux-h1: Reorg the H1C structure
Christopher Faulet [Tue, 4 Oct 2022 09:24:46 +0000 (11:24 +0200)] 
REORG: mux-h1: Reorg the H1C structure

Fields in H1C structure are reorganised to not have the output buffer
straddled between to cache lines. There is 4-bytes hole after the flags, but
it will be partially filled by an enum representing the H1 connection state.

2 years agoCLEANUP: mux-h1; Rename H1S_F_ERROR flag into H1S_F_ERROR_MASK
Christopher Faulet [Thu, 6 Oct 2022 07:24:07 +0000 (09:24 +0200)] 
CLEANUP: mux-h1; Rename H1S_F_ERROR flag into H1S_F_ERROR_MASK

In fact, H1S_F_ERROR is not a flag but a mask. So rename it to make it
clear.

2 years agoMINOR: mux-h1: Remove usless code inside shutr callback
Christopher Faulet [Wed, 5 Oct 2022 08:24:11 +0000 (10:24 +0200)] 
MINOR: mux-h1: Remove usless code inside shutr callback

For now, at the transport-layer level, there is no shutr callback (in
xprt_ops). Thus, to ease the aborts refacotring, the code is removed from
the h1_shutr() function. The callback is not removed for now. It is only
kept to have a trace message. It may be handy for debugging sessions.

2 years agoBUG/MINOR: pool/cli: use ullong to report total pool usage in bytes
Willy Tarreau [Thu, 17 Nov 2022 10:08:03 +0000 (11:08 +0100)] 
BUG/MINOR: pool/cli: use ullong to report total pool usage in bytes

As noticed by Gabriel Tzagkarakis in issue #1903, the total pool size
in bytes is historically still in 32 bits, but at least we should report
the product of the number of objects and their size in 64 bits so that
the value doesn't wrap around 4G.

This may be backported to all versions.

2 years agoDEV: poll: indicate the FD's side in front of its value
Willy Tarreau [Thu, 17 Nov 2022 06:59:49 +0000 (07:59 +0100)] 
DEV: poll: indicate the FD's side in front of its value

Some interleaved dumps were hard to follow. By indicating which side
we're talking about it's easier. E.g:

  $ dev/poll/poll -v -s pol,clo -c pol
  #### BEGIN ####
  cmd #1 stp #0: con(c=4): ret=0
  cmd #1 stp #0: acc(l=3): ret=5
  cmd #1 stp #1: pol(s=5): ret=1 ev=0x4 (OUT)
  cmd #1 stp #2: clo(s=5): ret=0
  cmd #2 stp #1: pol(c=4): ret=1 ev=0x2005 (IN OUT RDHUP)

2 years agoDEV: poll: strip the "do_" prefix from reported function names
Willy Tarreau [Thu, 17 Nov 2022 06:55:44 +0000 (07:55 +0100)] 
DEV: poll: strip the "do_" prefix from reported function names

This doesn't bring anything and makes the output less readable. Let's
just keep the action name.

2 years agoDEV: poll: make the connect() step an action as well
Willy Tarreau [Thu, 17 Nov 2022 06:44:27 +0000 (07:44 +0100)] 
DEV: poll: make the connect() step an action as well

Now the connect() step becomes an action. It's still implicit before
any -c/-s but it allows the listener to close() before connect()
happens, showing the polling status for this condition:

  $ dev/poll/poll -v -l clo -c pol
  #### BEGIN ####
  cmd #1 stp #1: do_clo(3): ret=0
  cmd #2 stp #0: do_con(4): ret=-1 (Connection refused)
  cmd #2 stp #1: do_pol(4): ret=1 ev=0x14 (OUT HUP)
  #### END ####

which differs from a case where the server closes the just accepted
connection:

  $ dev/poll/poll -v -s clo -c pol
  #### BEGIN ####
  cmd #1 stp #0: do_con(4): ret=0
  cmd #1 stp #0: do_acc(3): ret=5
  cmd #1 stp #1: do_clo(5): ret=0
  cmd #2 stp #1: do_pol(4): ret=1 ev=0x2005 (IN OUT RDHUP)
  #### END ####

It's interesting to see OUT+HUP since HUP indicates that both directions
were closed, hence nothing may be written now, thus OUT just wants the
write handler to be notified.

2 years agoBUILD: makefile: move the compiler option detection stuff to compiler.mk
Willy Tarreau [Thu, 17 Nov 2022 08:02:56 +0000 (09:02 +0100)] 
BUILD: makefile: move the compiler option detection stuff to compiler.mk

There's quite a large barely readable functions block in the makefile
dedicated to compiler option support. It provides no value here and
makes it harder to find user-configurable stuff, so let's move it to
include/make/compiler.mk to keep the makefile a bit cleaner. It's better
to keep the options themselves in the makefile however.

2 years agoBUILD: makefile: use $(cmd_MAKE) in quiet mode
Willy Tarreau [Thu, 17 Nov 2022 07:34:37 +0000 (08:34 +0100)] 
BUILD: makefile: use $(cmd_MAKE) in quiet mode

It's better to see "make" entering a subdir than seeing nothing, so
let's use a command name for make. Since make 3.81, "+" needs to be
prepended in front of the command to pass the job server to the subdir.

2 years agoBUILD: makefile: move default verbosity settings to include/make/verbose.mk
Willy Tarreau [Thu, 17 Nov 2022 07:23:10 +0000 (08:23 +0100)] 
BUILD: makefile: move default verbosity settings to include/make/verbose.mk

The $(Q), $(V), $(cmd_xx) handling needs to be reused in sub-project
makefiles and it's a pain to maintain inside the main makefile. Let's
just move that into a new subdir include/make/ with a dedicated file
"verbose.mk". It slightly cleans up the makefile in addition.

2 years agoBUILD: makefile: properly pass CC to sub-projects
Willy Tarreau [Thu, 17 Nov 2022 07:15:27 +0000 (08:15 +0100)] 
BUILD: makefile: properly pass CC to sub-projects

The "poll" and "tcploop" sub-projects have their own makefiles. But
since the cmd_* commands were migrated from "echo" to $(info) with
make 3.81, the command is confusingly displayed in the top-level
makefile before entering the directory, even making one think that
the build occurred.

Let's instead propagate the verbosity level through the sub-projects
and let them adapt their own cmd_CC. For now this peans a little bit
of duplication for poll and tcploop.

2 years agoBUILD: makefile: mark poll and tcploop targets as phony
Willy Tarreau [Thu, 17 Nov 2022 07:06:16 +0000 (08:06 +0100)] 
BUILD: makefile: mark poll and tcploop targets as phony

Since these ones come with their own makefiles, the top-level makefile
cannot decide when they have to be rebuilt, it should always defer the
decision to the compoent's makefile, so we must mark them as phony.
Because of these, they were not updated after a change without calling
a "clean" first.

2 years agoBUILD: quic: fix dubious 0-byte overflow on qc_release_lost_pkts
Amaury Denoyelle [Mon, 14 Nov 2022 10:41:34 +0000 (11:41 +0100)] 
BUILD: quic: fix dubious 0-byte overflow on qc_release_lost_pkts

With GCC 12.2.0 and O2 optimization activated, compiler reports the
following warning for qc_release_lost_pkts().

In function ‘quic_tx_packet_refdec’,
    inlined from ‘qc_release_lost_pkts.constprop’ at src/quic_conn.c:2056:3:
include/haproxy/atomic.h:320:41: error: ‘__atomic_sub_fetch_4’ writing 4 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
  320 | #define HA_ATOMIC_SUB_FETCH(val, i)     __atomic_sub_fetch(val, i, __ATOMIC_SEQ_CST)
      |                                         ^~~~~~~~~~~~~~~~~~
include/haproxy/quic_conn.h:499:14: note: in expansion of macro ‘HA_ATOMIC_SUB_FETCH’
  499 |         if (!HA_ATOMIC_SUB_FETCH(&pkt->refcnt, 1)) {
      |              ^~~~~~~~~~~~~~~~~~~

GCC thinks that quic_tx_packet_refdec() can be called with a NULL
argument from qc_release_lost_pkts() with <oldest_lost> as arg.

This warning is a false positive as <oldest_lost> cannot be NULL in
qc_release_lost_pkts() at this stage. This is due to the previous check
to ensure that <pkts> list is not empty.

This warning is silenced by using ALREADY_CHECKED() macro.

This should be backported up to 2.6.

This should fix github issue #1852.

2 years agoBUG/MEDIUM: ring: fix creation of server in uninitialized ring
Willy Tarreau [Wed, 16 Nov 2022 17:56:34 +0000 (18:56 +0100)] 
BUG/MEDIUM: ring: fix creation of server in uninitialized ring

If a "ring" section initialization fails (e.g. due to a duplicate name,
invalid chars, or missing memory), any subsequent "server" statement that
appears in the same section will crash the config parser by dereferencing
the currently NULL cfg_sink. E.g:

    ring x
    ring x                 # fails on "already exists"
       server srv 1.1.1.1  # crashes on cfg_sink==NULL

All other statements have a test for this but "server" was missing it,
so this patch adds it.

Thanks to Joel Hutchinson for reporting this issue.

This must be backported as far as 2.2.

2 years agoMEDIUM: trace: create a new "trace" statement in the "global" section
Willy Tarreau [Wed, 16 Nov 2022 16:29:12 +0000 (17:29 +0100)] 
MEDIUM: trace: create a new "trace" statement in the "global" section

The exact same commands as those from the CLI may be pre-loaded at boot
time by passing them one per line after the "trace" keyword in the global
section; i.e. just copy-pasting all commands directly there will do the
job. Note that if a ring is mentioned, it needs to be declared before the
global section. Another option is to append another global section after
"ring".

For now the keyword is marked as experimental to discourage its broad
adoption by default. "expose-experimental-directives" needs to be placed
in the global section to expose it.

2 years agoMINOR: trace: split the CLI "trace" parser in CLI vs statement
Willy Tarreau [Wed, 16 Nov 2022 16:18:04 +0000 (17:18 +0100)] 
MINOR: trace: split the CLI "trace" parser in CLI vs statement

In order to be able to reuse the "trace" statements elsewhere (e.g.
global section), we'll first need to split its parser. It turns out
that the whole thing is self-contained inside a single function that
emits a single message on warning/error or nothing on success. That's
quite easy to split in two parts, the one that does the job and produces
the status message and the one that sends it to the CLI. That's what
this patch does.

2 years agoDOC: config: fix alphabetical ordering of global section
Willy Tarreau [Wed, 16 Nov 2022 16:42:34 +0000 (17:42 +0100)] 
DOC: config: fix alphabetical ordering of global section

the global section keywords were seriously misordered, and it's visible
that some mistakes have induced other ones over time, so it was about
time to fix this. Roughly 20% of the keywords were misplaced.

This commit only reordered the keywords index and their description,
nothing else was changed. It might be backported because it's a real
pain to find certain options there.

2 years agoREG-TESTS: cache: Remove T-E header for 304-Not-Modified responses
Christopher Faulet [Wed, 16 Nov 2022 16:19:42 +0000 (17:19 +0100)] 
REG-TESTS: cache: Remove T-E header for 304-Not-Modified responses

VTEST does not properly handle 304-Not-Modified responses. If a
Transfer-Encoding header (and probably a Content-Lenght header too), it
waits for a body. Waiting for a fix, the Transfer-Encoding encoding of
cached responses in 2 VTEST scripts are removed.

Note it is now an issue because of a fix in the H1 multiplexer :

  * 226082d13a "BUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers"

This patch must be backported with the above commit.

2 years agoBUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers
Mickael Torres [Wed, 16 Nov 2022 13:29:37 +0000 (14:29 +0100)] 
BUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers

HEAD answers should not contain any body data. Currently when a
"transfer-encoding: chunked" header is returned, a last null-chunk is added to
the answer. Some clients choke on it and fail when trying to reuse the
connection. Check that the response should not be body-less before sending the
null-chunk.

This patch should fix #1932. It must be backported as far as 2.4.

2 years agoMINOR: dynbuf: switch allocation and release to macros to better track users
Willy Tarreau [Wed, 16 Nov 2022 10:37:29 +0000 (11:37 +0100)] 
MINOR: dynbuf: switch allocation and release to macros to better track users

When building with DEBUG_MEM_STATS, we only see b_alloc() and b_free() as
users of the "buffer" pool, because all call places rely on these more
convenient functions. It's annoying because it makes it very hard to see
which parts of the code are consuming buffers.

By switching the b_alloc() and b_free() inline functions to macros, we
can now finally track the users of struct buffer, e.g:

  mux_h1.c:513            P_FREE  size:   1275002880  calls:     38910  size/call:  32768 buffer
  mux_h1.c:498           P_ALLOC  size:   1912438784  calls:     58363  size/call:  32768 buffer
  stream.c:763            P_FREE  size:   4121493504  calls:    125778  size/call:  32768 buffer
  stream.c:759            P_FREE  size:   2061697024  calls:     62918  size/call:  32768 buffer
  stream.c:742           P_ALLOC  size:   3341123584  calls:    101963  size/call:  32768 buffer
  stream.c:632            P_FREE  size:   1275068416  calls:     38912  size/call:  32768 buffer
  stream.c:631            P_FREE  size:    637435904  calls:     19453  size/call:  32768 buffer
  channel.h:850          P_ALLOC  size:   4116480000  calls:    125625  size/call:  32768 buffer
  channel.h:850          P_ALLOC  size:       720896  calls:        22  size/call:  32768 buffer
  dynbuf.c:55             P_FREE  size:        65536  calls:         2  size/call:  32768 buffer

Let's do this since it doesn't change anything for the output code
(beyond adding the call places). Interestingly the code even got
slightly smaller now.

2 years agoMINOR: pool/debug: create a new pool_alloc_flag() macro
Willy Tarreau [Wed, 16 Nov 2022 10:30:04 +0000 (11:30 +0100)] 
MINOR: pool/debug: create a new pool_alloc_flag() macro

This macro just serves as an intermediary for __pool_alloc() and forwards
the flag. When DEBUG_MEM_STATS is set, it will be used to collect all
pool allocations including those which need to pass an explicit flag.

It's now used by b_alloc() which previously couldn't be tracked by
DEBUG_MEM_STATS, causing some free() calls to have no corresponding
allocations.

2 years agoBUG/MINOR: ssl: SSL_load_error_strings might not be defined
Remi Tricot-Le Breton [Thu, 15 Sep 2022 14:22:57 +0000 (16:22 +0200)] 
BUG/MINOR: ssl: SSL_load_error_strings might not be defined

The SSL_load_error_strings function was marked as deprecated in OpenSSL
1.1.0 so compiling HAProxy with OPENSSL_NO_DEPRECATED set and a recent
OpenSSL library would fail.
The manpages say that this function was replaced by OPENSSL_init_crypto
and OPENSSL_init_ssl which are already called at start up by the SSL
lib. We do not seem to be in a case where explicit call of those
functions is required.

This patch fixes GitHub issue #1813.
It can be backported to 2.6.

2 years agoBUG/MEDIUM: mux-fcgi: Avoid value length overflow when it doesn't fit at once
Christopher Faulet [Tue, 15 Nov 2022 09:46:28 +0000 (10:46 +0100)] 
BUG/MEDIUM: mux-fcgi: Avoid value length overflow when it doesn't fit at once

When the request data are copied in a mbuf, if the free space is too small
to copy all data at once, the data length is shortened. When this is
performed, we reserve the size of the STDIN recod header and eventually the
same for the empty STDIN record if it is the last HTX block of the request.

However, there is no test to be sure the free space is large enough. Thus,
on this special case, when the mbuf is almost full, it is possible to
overflow the value length. Because of this bug, it is possible to experience
crashes from time to time.

This patch should fix the issue #1923. It must be backported as far as 2.4.

2 years agoBUG/MINOR: mux-fcgi: Be sure to send empty STDING record in case of zero-copy
Christopher Faulet [Tue, 15 Nov 2022 09:36:31 +0000 (10:36 +0100)] 
BUG/MINOR: mux-fcgi: Be sure to send empty STDING record in case of zero-copy

When the last HTX DATA block was copied in zero-copy, the empty STDIN
record, marking the end of the request data was never sent. Thanks to this
patch, it is now sent.

This patch must be backported as far as 2.4.

2 years agoBUG/MINOR: resolvers: Set port before IP address when processing SRV records
Christopher Faulet [Thu, 3 Nov 2022 15:41:46 +0000 (16:41 +0100)] 
BUG/MINOR: resolvers: Set port before IP address when processing SRV records

For a server subject to SRV resolution, when the server's address is set,
its dynamic cookie, if any, and its server key are computed. Both are based
on the ip/port pair. However, this happens before the server's port is
set. Thus the port is equal to 0 at this stage. It is a problem if several
servers share the same IP but with different ports because they will share
the same dynamic cookie and the same server key, disturbing this way the
connection persistency and the session stickiness.

This patch must be backported as far as 2.2.

2 years agoBUG/MINOR: resolvers: Don't wait periodic resolution on healthcheck failure
Christopher Faulet [Mon, 24 Oct 2022 06:59:59 +0000 (08:59 +0200)] 
BUG/MINOR: resolvers: Don't wait periodic resolution on healthcheck failure

DNS resoltions may be triggered via a "do-resolve" action or when a connection
failure is experienced during a healthcheck. Cached valid responses are used, if
possible. But if the entry is expired or if there is no valid response, a new
reolution should be performed. However, an resolution is only performed if the
"resolve" timeout is expired. Thus, when this comes from a healthcheck, it means
no extra resolution is performed at all.

Now, when the resolution is performed for a server (SRV or SRVEQ) and no valid
response is found, the resolution timer is reset (last_resolution is set to
TICK_ETERNITY). Of course, it is only performed if no resolution is already
running.

Note that this feature was broken 5 years ago when the resolvers code was
refactored (67957bd59e).

This patch should fix the issue #1906. It affects all stable versions. However,
it is probably a good idea to not backport it too far (2.6, maybe 2.4) and with
some delay.

2 years agoBUG/MINOR: http-htx: Fix error handling during parsing http replies
Christopher Faulet [Mon, 14 Nov 2022 07:49:28 +0000 (08:49 +0100)] 
BUG/MINOR: http-htx: Fix error handling during parsing http replies

When an error is triggered during arguments parsing of an http reply (for
instance, from a "return" rule), while a log-format body was expected but
not evaluated yet, HAproxy crashes when the body log-format string is
released because it was not properly initialized.

The list used for the log-format string must be initialized earlier.

This patch should fix the issue #1925. It must be backported as far as 2.2.

2 years agoMINOR: ssl: reintroduce ERR_GET_LIB(ret) == ERR_LIB_PEM in ssl_sock_load_pem_into_ckch()
William Lallemand [Tue, 15 Nov 2022 16:12:03 +0000 (17:12 +0100)] 
MINOR: ssl: reintroduce ERR_GET_LIB(ret) == ERR_LIB_PEM in ssl_sock_load_pem_into_ckch()

Commit 432cd1a ("MEDIUM: ssl: be stricter about chain error") removed
the ERR_GET_LIB(ret) != ERR_LIB_PEM to be stricter about errors.

However, PEM_R_NO_START_LINE is better be checked with ERR_LIB_PEM.
So this patch complete the previous one.

The original problem was that the condition was wrongly inversed. This
original code from openssl:

  if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
      ERR_GET_REASON(err) == PEM_R_NO_START_LINE)

became:

  if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM &&
              ERR_GET_REASON(ret) != PEM_R_NO_START_LINE))

instead of:

  if (ret && !(ERR_GET_LIB(ret) == ERR_LIB_PEM &&
               ERR_GET_REASON(ret) == PEM_R_NO_START_LINE))

This must not be backported as it will break a lot of setup. That's too
bad because a lot of errors are lost. Not marked as a bug because of the
breakage it could cause on working setups.

2 years agoMINOR: ssl: ssl_sock_load_cert_chain() display error strings
William Lallemand [Tue, 15 Nov 2022 15:56:03 +0000 (16:56 +0100)] 
MINOR: ssl: ssl_sock_load_cert_chain() display error strings

Display error strings when SSL_CTX_use_certificate()  or
SSL_CTX_set1_chain() doesn't work.

2 years agoOPTIM: ebtree: make ebmb_insert_prefix() keep a copy the new node's key
Willy Tarreau [Tue, 15 Nov 2022 07:08:31 +0000 (08:08 +0100)] 
OPTIM: ebtree: make ebmb_insert_prefix() keep a copy the new node's key

Similarly to the previous patch, it's better to keep a local copy of
the new node's key instead of accessing it every time. This slightly
reduces the code's size in the descent and further improves the load
time to 7.45s.

2 years agoOPTIM: ebtree: make ebmb_insert_prefix() keep a copy the new node's pfx
Willy Tarreau [Tue, 15 Nov 2022 07:08:24 +0000 (08:08 +0100)] 
OPTIM: ebtree: make ebmb_insert_prefix() keep a copy the new node's pfx

looking at a perf profile while loading a conf with a huge map, it
appeared that there was a hot spot on the access to the new node's
prefix, which is unexpectedly being reloaded for each visited node
during the tree descent. Better keep a copy of it because with large
trees that don't fit into the L3 cache the memory bandwidth is scarce.
Doing so reduces the load time from 8.0 to 7.5 seconds.

2 years agoMINOR: deinit: add a "quick-exit" option to bypass the deinit step
Willy Tarreau [Tue, 15 Nov 2022 08:34:07 +0000 (09:34 +0100)] 
MINOR: deinit: add a "quick-exit" option to bypass the deinit step

Once in a while we spot a bug in the deinit code that is complex,
especially when it has to deal with incomplete initializations, and the
ability to bypass this step has regularly been raised. In addition for
fast-reloading setups it could theoretically save some time. Tests have
shown that very large configs can barely save ~100-150ms by skipping the
deinit step. However the ability not to crash if a bug is encountered can
occasionally help.

This patch adds an option to do exactly this. It's obviously not enabled
by default and the documentation discourages from using it, but this might
be useful in the future.

2 years agoBUG/MEDIUM: wdt/clock: properly handle early task hangs
Aurelien DARRAGON [Thu, 10 Nov 2022 10:47:47 +0000 (11:47 +0100)] 
BUG/MEDIUM: wdt/clock: properly handle early task hangs

In ae053b30 - BUG/MEDIUM: wdt: don't trigger the watchdog when p is unitialized:
wdt is not triggering until prev_cpu_time
is initialized to prevent unexpected process
termination.

Unfortunately this is not enough, some tasks could start
immediately after process startup, and in such cases
prev_cpu_time could be uninitialized, because
prev_cpu_time is set after the polling loop while
process_runnable_tasks() is executed before the polling loop.

It happens to be the case with lua tasks registered using
register_task function from lua script.

Those tasks are registered in early init stage of haproxy and
they are scheduled to run before the first polling loop,
leading to prev_cpu_time being uninitialized (equals 0)
on the thread when the task is first executed.

Because of this, if such tasks get stuck right away
(e.g: blocking IO) the watchdog won't behave as expected
and the thread will remain stuck indefinitely.
(polling loop for the thread won't run at all as
the thread is already stuck)

To solve this, we're now making sure that prev_cpu_time is first
set before any tasks are processed on the thread.
This is done by setting initial prev_cpu_time value directly
in clock_init_thread_date()

Thanks to Abhijeet Rastogi for reporting this unexpected behavior.

It could be backported in every stable versions.
(everywhere ae053b30 is, because both are related)

2 years agoMEDIUM: http-ana: remove set-cookie2 support
Willy Tarreau [Mon, 14 Nov 2022 17:58:35 +0000 (18:58 +0100)] 
MEDIUM: http-ana: remove set-cookie2 support

This has never really been implemented in clients nor servers. We wanted
to drop it from 2.5 already but forgot, so let's do it now. The code was
only minimally changed. It could possibly be slightly simplified but it
would only be marginal, at the great risk of breaking something, thus
let's keep it in its proven state instead.

Tracked in github issue #1551.

2 years agoBUG/MEDIUM: stick-table: fix a race condition when updating the expiration task
Willy Tarreau [Mon, 14 Nov 2022 17:02:44 +0000 (18:02 +0100)] 
BUG/MEDIUM: stick-table: fix a race condition when updating the expiration task

Pierre Cheynier reported a rare crash that can affect stick-tables. When
a entry is created, the stick-table's expiration date is updated. But if
at exactly the same time the expiration task runs, it finishes by updating
its expiration timer without any protection, which may collide with the
call to task_queue() in another thread. In this case, it sometimes happens
that the first test for TICK_ETERNITY in task_queue() passes, then the
"expire" field is reset, then the BUG_ON() triggers, like below:

  FATAL: bug condition "task->expire == 0" matched at src/task.c:279
    call trace(13):
    |       0x649d86 [c6 04 25 01 00 00 00 00]: __task_queue+0xc6/0xce
    |       0x596bef [eb 90 ba 03 00 00 00 be]: stktable_requeue_exp+0x1ef/0x258
    |       0x596c87 [48 83 bb 90 00 00 00 00]: stktable_touch_with_exp+0x27/0x312
    |       0x563698 [48 8b 4c 24 18 4c 8b 4c]: stream_process_counters+0x3a8/0x6a2
    |       0x569344 [49 8b 87 f8 00 00 00 48]: process_stream+0x3964/0x3b4f
    |       0x64a80b [49 89 c7 e9 23 ff ff ff]: run_tasks_from_lists+0x3ab/0x566
    |       0x64ad66 [29 44 24 14 8b 7c 24 14]: process_runnable_tasks+0x396/0x71e
    |       0x6184b2 [83 3d 47 b3 a6 00 01 0f]: run_poll_loop+0x92/0x4ff
    |       0x618acf [48 8b 1d aa 20 7d 00 48]: main+0x1877ef
    | 0x7fc7d6ec1e45 [64 48 89 04 25 30 06 00]: libpthread:+0x7e45
    | 0x7fc7d6c9e4af [48 89 c7 b8 3c 00 00 00]: libc:clone+0x3f/0x5a

This one is extremely difficult to reproduce in practice, but adding a
printf() in process_table_expire() before assigning the value, while
running with an expire delay of 1ms helps a lot and may trigger the
crash in less than one minute on a 8-thread machine. Interestingly,
depending on the sequencing, this bug could also have made a table fail
to expire if the expire field got reset after the last update but before
the call to task_queue(). It would require to be quite unlucky so that
the table is never touched anymore after the race though.

The solution taken by this patch is to take the table's lock when
updating its expire value in stktable_requeue_exp(), enclosing the call
to task_queue(), and to update the task->expire field while still under
the lock in process_table_expire(). Note that thanks to previous changes,
taking the table's lock for the update in stktable_requeue_exp() costs
almost nothing since we now have the guarantee that this is not done more
than 1000 times a second.

Since process_table_expire() sets the timeout after returning from
stktable_trash_expired() which just released the lock, the two functions
were merged so that the task's expire field is updated while still under
the lock. Note that this heavily depends on the two previous patches
below:

  CLEANUP: stick-table: remove the unused table->exp_next
  OPTIM: stick-table: avoid atomic ops in stktable_requeue_exp() when possible

This is a bit complicated due to the fact that in 2.7 some parts were
made lockless. In 2.6 and older, the second part (the merge of the
two functions) will be sufficient since the task_queue() call was
already performed under the table's lock, and the patches above are
not needed.

This needs to be backported as far as 1.8 scrupulously following
instructions above.

2 years agoOPTIM: stick-table: avoid atomic ops in stktable_requeue_exp() when possible
Willy Tarreau [Mon, 14 Nov 2022 16:54:07 +0000 (17:54 +0100)] 
OPTIM: stick-table: avoid atomic ops in stktable_requeue_exp() when possible

Since the task's time resolution is the millisecond we know there
will not be more than 1000 useful updates per second, so there's no
point in doing a CAS and a task_queue() for each call, better first
check if we're going to change the date. Now we're certain not to
perform such operations more than 1000 times a second for a given
table.

The loop was modified because this improvement will also be used to fix a
bug later.

2 years agoCLEANUP: stick-table: remove the unused table->exp_next
Willy Tarreau [Mon, 14 Nov 2022 16:33:02 +0000 (17:33 +0100)] 
CLEANUP: stick-table: remove the unused table->exp_next

The ->exp_next field of the stick-table was probably useful in 1.5 but
it currently only carries a copy of what the future value of the table's
task's expire value will be, while it's systematically copied over there
immediately after being assigned. As such it provides exactly a local
variable. Let's remove it, as it costs atomic operations.

2 years agoBUG/MINOR: ssl: Fix potential overflow
Remi Tricot-Le Breton [Mon, 14 Nov 2022 14:15:52 +0000 (15:15 +0100)] 
BUG/MINOR: ssl: Fix potential overflow

Coverity raised a potential overflow issue in these new functions that
work on unsigned long long objects. They were added in commit 9b25982
"BUG/MEDIUM: ssl: Verify error codes can exceed 63".

This patch needs to be backported alongside 9b25982.

2 years agoBUG/MINOR: ssl: crt-ignore-err memory leak with 'all' parameter
William Lallemand [Mon, 14 Nov 2022 10:36:11 +0000 (11:36 +0100)] 
BUG/MINOR: ssl:  crt-ignore-err memory leak with 'all' parameter

Only allocate "str" if the parameter is not "all" in order to avoid any
memory leak.

No backport needed.

2 years agoCLEANUP: ssl: remove printf in bind_parse_ignore_err
William Lallemand [Mon, 14 Nov 2022 10:34:07 +0000 (11:34 +0100)] 
CLEANUP: ssl: remove printf in bind_parse_ignore_err

Remove debug printf.

No backport needed.

2 years agoBUILD: prometheus: use __fallthrough in promex_dump_metrics() and IO handler()
Willy Tarreau [Mon, 14 Nov 2022 06:37:45 +0000 (07:37 +0100)] 
BUILD: prometheus: use __fallthrough in promex_dump_metrics() and IO handler()

This avoids 11 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: stconn: use __fallthrough in various shutw() functions
Willy Tarreau [Mon, 14 Nov 2022 06:36:42 +0000 (07:36 +0100)] 
BUILD: stconn: use __fallthrough in various shutw() functions

This avoids 7 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: compression: use __fallthrough in comp_http_payload()
Willy Tarreau [Mon, 14 Nov 2022 06:36:05 +0000 (07:36 +0100)] 
BUILD: compression: use __fallthrough in comp_http_payload()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: map: use __fallthrough in cli_io_handler_*()
Willy Tarreau [Mon, 14 Nov 2022 06:35:24 +0000 (07:35 +0100)] 
BUILD: map: use __fallthrough in cli_io_handler_*()

This avoids 6 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: vars: use __fallthrough in var_accounting_{diff,add}()
Willy Tarreau [Mon, 14 Nov 2022 06:33:48 +0000 (07:33 +0100)] 
BUILD: vars: use __fallthrough in var_accounting_{diff,add}()

This avoids 6 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: h1_htx: use __fallthrough in h1_parse_chunk()
Willy Tarreau [Mon, 14 Nov 2022 06:32:50 +0000 (07:32 +0100)] 
BUILD: h1_htx: use __fallthrough in h1_parse_chunk()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: http_act: use __fallthrough in parse_http_del_header()
Willy Tarreau [Mon, 14 Nov 2022 06:32:04 +0000 (07:32 +0100)] 
BUILD: http_act: use __fallthrough in parse_http_del_header()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: check: use __fallthrough in __health_adjust()
Willy Tarreau [Mon, 14 Nov 2022 06:31:36 +0000 (07:31 +0100)] 
BUILD: check: use __fallthrough in __health_adjust()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: logs: use __fallthrough in build_log_header()
Willy Tarreau [Mon, 14 Nov 2022 06:22:57 +0000 (07:22 +0100)] 
BUILD: logs: use __fallthrough in build_log_header()

This avoids 4 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: spoe: use __fallthrough in spoe_handle_appctx()
Willy Tarreau [Mon, 14 Nov 2022 06:22:14 +0000 (07:22 +0100)] 
BUILD: spoe: use __fallthrough in spoe_handle_appctx()

This avoids two build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: acl: use __fallthrough in parse_acl_expr()
Willy Tarreau [Mon, 14 Nov 2022 06:21:22 +0000 (07:21 +0100)] 
BUILD: acl: use __fallthrough in parse_acl_expr()

This avoids two build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: args: use __fallthrough in make_arg_list()
Willy Tarreau [Mon, 14 Nov 2022 06:20:54 +0000 (07:20 +0100)] 
BUILD: args: use __fallthrough in make_arg_list()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: tools: use __fallthrough in url_decode()
Willy Tarreau [Mon, 14 Nov 2022 06:20:09 +0000 (07:20 +0100)] 
BUILD: tools: use __fallthrough in url_decode()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: hash: use __fallthrough in hash_djb2()
Willy Tarreau [Mon, 14 Nov 2022 06:18:42 +0000 (07:18 +0100)] 
BUILD: hash: use __fallthrough in hash_djb2()

This avoids 5 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: peers: use __fallthrough in peer_io_handler()
Willy Tarreau [Mon, 14 Nov 2022 06:13:22 +0000 (07:13 +0100)] 
BUILD: peers: use __fallthrough in peer_io_handler()

This avoids 7 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: stats: use __fallthrough in stats_dump_proxy_to_buffer()
Willy Tarreau [Mon, 14 Nov 2022 06:12:05 +0000 (07:12 +0100)] 
BUILD: stats: use __fallthrough in stats_dump_proxy_to_buffer()

This avoids 12 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: tcpcheck: use __fallthrough in check_proxy_tcpcheck()
Willy Tarreau [Mon, 14 Nov 2022 06:10:33 +0000 (07:10 +0100)] 
BUILD: tcpcheck: use __fallthrough in check_proxy_tcpcheck()

This avoids 1 build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: stream: use __fallthrough in stats_dump_full_strm_to_buffer()
Willy Tarreau [Mon, 14 Nov 2022 06:09:39 +0000 (07:09 +0100)] 
BUILD: stream: use __fallthrough in stats_dump_full_strm_to_buffer()

This avoids 1 build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: hlua: use __fallthrough in hlua_post_init_state()
Willy Tarreau [Mon, 14 Nov 2022 06:08:28 +0000 (07:08 +0100)] 
BUILD: hlua: use __fallthrough in hlua_post_init_state()

This avoids 5 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: ssl: use __fallthrough in cli_io_handler_tlskeys_files()
Willy Tarreau [Mon, 14 Nov 2022 06:34:43 +0000 (07:34 +0100)] 
BUILD: ssl: use __fallthrough in cli_io_handler_tlskeys_files()

This avoids two build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: ssl: use __fallthrough in cli_io_handler_commit_{cert,cafile_crlfile}()
Willy Tarreau [Mon, 14 Nov 2022 06:05:31 +0000 (07:05 +0100)] 
BUILD: ssl: use __fallthrough in cli_io_handler_commit_{cert,cafile_crlfile}()

This avoids 8 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: ssl/crt-list: use __fallthrough in cli_io_handler_add_crtlist()
Willy Tarreau [Mon, 14 Nov 2022 06:03:16 +0000 (07:03 +0100)] 
BUILD: ssl/crt-list: use __fallthrough in cli_io_handler_add_crtlist()

This avoids 3 build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: quic: use __fallthrough in quic_connect_server()
Willy Tarreau [Mon, 14 Nov 2022 06:02:00 +0000 (07:02 +0100)] 
BUILD: quic: use __fallthrough in quic_connect_server()

This avoids one build warning when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: sample: use __fallthrough in smp_is_rw() and smp_dup()
Willy Tarreau [Mon, 14 Nov 2022 05:59:59 +0000 (06:59 +0100)] 
BUILD: sample: use __fallthrough in smp_is_rw() and smp_dup()

This avoids three build warnings when preprocessing happens before compiling
with gcc >= 7.

2 years agoBUILD: compiler: define a __fallthrough statement for switch/case
Willy Tarreau [Sun, 13 Nov 2022 11:21:22 +0000 (12:21 +0100)] 
BUILD: compiler: define a __fallthrough statement for switch/case

When the code is preprocessed first and compiled later, such as when
built under distcc, a lot of fallthrough warnings are emitted because
the preprocessor has already stripped the comments.

As an alternative, a "fallthrough" attribute was added with the same
compilers as those which started to emit those warnings. However it's
not portable to older compilers. Let's just define a __fallthrough
statement that corresponds to this attribute on supported compilers
and only switches to the classical empty do {} while (0) on other ones.

This way the code will support being cleaned up using __fallthrough.

2 years agoBUILD: compiler: add a default definition for __has_attribute()
Willy Tarreau [Sun, 13 Nov 2022 10:39:18 +0000 (11:39 +0100)] 
BUILD: compiler: add a default definition for __has_attribute()

It happens that gcc since 5.x has this macro which is only mentioned
once in the doc, associated with __builtin_has_attribute(). Clang had
it at least since 3.0. In addition it validates #ifdef when present,
so it's easy to detect it. Here we're providing a fallback to another
macro __has_attribute_<name> so that it's possible to define that macro
to the value 1 for older compilers when the attribute is supported.

2 years agoBUILD: compiler: add a macro to detect if another one is set and equals 1
Willy Tarreau [Sun, 13 Nov 2022 10:32:45 +0000 (11:32 +0100)] 
BUILD: compiler: add a macro to detect if another one is set and equals 1

In order to simplify compiler-specific checks, we'll need to check if some
attributes exist. In order to ease declarations, we'll only focus on those
that exist and will set them to 1. Let's first add a macro aimed at doing
this. Passed a macro name in argument, it will return 1 if the macro is
defined and equals 1, otherwise it will return 0. This is based on the
concatenation of the macro's value with a name to form the name of a macro
which contains one comma, resulting in some other macros arguments being
shifted by one when the macro is defined. As such it's only a matter of
pushing both a 1 and a 0 and picking the correct argument to see the
desired one. It was verified to work since at least gcc-3.4 so it should
be portable enough.

2 years agoIMPORT: slz: define and use a __fallthrough statement for switch/case
Willy Tarreau [Sun, 13 Nov 2022 12:06:02 +0000 (13:06 +0100)] 
IMPORT: slz: define and use a __fallthrough statement for switch/case

When the code is preprocessed first and compiled later, such as when
built under distcc, the "fall through" comments are dropped and warnings
are emitted. Let's use the alternative "fallthrough" attribute instead,
that is supported by versions of gcc and clang that also produce this
warning.

This is libslz upstream commit 0fdf8ae218f3ecb0b7f22afd1a6b35a4f94053e2

2 years agoIMPORT: slz: mention the potential header in slz_finish()
Dridi Boukelmoune [Wed, 30 Mar 2022 05:58:23 +0000 (07:58 +0200)] 
IMPORT: slz: mention the potential header in slz_finish()

There may be 2 or 10 bytes sent respectively for zlib and gzip.

This is libslz upstream commit de1cac155ac730ba0491a6c866a510760c01fa9b

2 years agoIMPORT: slz: declare len to fix debug build when optimal match is enabled
Willy Tarreau [Mon, 13 Dec 2021 08:07:05 +0000 (09:07 +0100)] 
IMPORT: slz: declare len to fix debug build when optimal match is enabled

Building with -DFIND_OPTIMAL_MATCH would fail on undeclared "len".
This one likely vanished in some cleanup.

This is libslz upstream commit 1ea20360715e1ad0cd81db83fa4361310716b8cc

2 years agoIMPORT: xxhash: update xxHash to version 0.8.1
Willy Tarreau [Sun, 13 Nov 2022 12:21:56 +0000 (13:21 +0100)] 
IMPORT: xxhash: update xxHash to version 0.8.1

This is the latest released version and a minor update on top of the
current one (0.8.0). It addresses a few build issues (some for which
patches were already backported), and particularly the fallthrough
issue by using an attribute instead of a comment.

2 years agoCI: emit the compiler's version in the build reports
Willy Tarreau [Mon, 14 Nov 2022 10:03:18 +0000 (11:03 +0100)] 
CI: emit the compiler's version in the build reports

Some occasional builds fail only on a specific platform and being able
to figure the exact compiler version used there is crucial. It's not
easy to guess from the rest of the output, so let's add it before the
platform-specific defines, which suit the same needs.

2 years agoBUILD: debug: remove unnecessary quotes in HA_WEAK() calls
Willy Tarreau [Sun, 13 Nov 2022 11:14:10 +0000 (12:14 +0100)] 
BUILD: debug: remove unnecessary quotes in HA_WEAK() calls

HA_WEAK() is supposed to take a symbol in argument, not a string, since
the asm statements it produces already quote the argument. Having it
quoted twice doesn't work on older compilers and was the only reason
why DEBUG_MEM_STATS didn't work on older compilers.

2 years agoBUILD: ssl_utils: fix build on gcc versions before 8
Willy Tarreau [Mon, 14 Nov 2022 07:11:32 +0000 (08:11 +0100)] 
BUILD: ssl_utils: fix build on gcc versions before 8

Commit 960fb74ca ("MEDIUM: ssl: {ca,crt}-ignore-err can now use error
constant name") provided a very convenient way to initialize only desired
macros. Unfortunately with gcc versions older than 8, it breaks with:

  src/ssl_utils.c:473:12: error: initializer element is not constant

because it seems that the compiler cannot resolve strings to constants
at build time.

This patch takes a different approach, it stores the value of the macro
as a string and this string is converted to integer at boot time. This
way it works everywhere.

2 years agoBUG/MINOR: ssl: bind_conf is uncorrectly accessed when using QUIC
William Lallemand [Thu, 10 Nov 2022 15:45:24 +0000 (16:45 +0100)] 
BUG/MINOR: ssl: bind_conf is uncorrectly accessed when using QUIC

Since commit 9b2598 ("BUG/MEDIUM: ssl: Verify error codes can exceed
63"), the ca_ignerr_bitfield and crt_ignerr_bietfield are incorrecly
accessed from __objt_listener(conn->target)->bind_conf which is not
avaiable from QUIC. The bind_conf variable was mistakenly replaced.

This patch fixes the issue by using again the bind_conf variable.

Must be backported where 9b2598 was backported.

2 years agoMINOR: server: clear prefix on stderr logs after add server
Amaury Denoyelle [Thu, 10 Nov 2022 14:16:49 +0000 (15:16 +0100)] 
MINOR: server: clear prefix on stderr logs after add server

cli_parse_add_server() is the CLI handler for 'add server' command. This
functions uses usermsgs_ctx to retrieve logs messages from internal
ha_alert() calls and display it at the end of the handler.

At the beginning of the handler, stderr prefix is defined to "CLI" via
usermsgs_clr() function. However, this is not resetted at the end. This
causes inconsistency for stderr output :
1. each ha_alert() invocation will reuse "CLI" prefix if 'add server'
   command was executed before, even in non-CLI context
2. usermsgs_ctx is thread local, so this is only true if this runs on
   the same thread as 'add server' handler.

To fix this, ensure that "CLI" prefix is now resetted after
cli_parse_add_server(). This is done thanks to the addition to
cli_umsg()/cli_umsgerr() functions.

This can be backported up to 2.5 if we prefer to ensure output
consistency at the risk of changing stderr behaviors in stable versions.
In this case, the previous commit should be backported before :
  MINOR: cli: define usermsgs print context

2 years agoMINOR: cli: define usermsgs print context
Amaury Denoyelle [Thu, 10 Nov 2022 13:24:51 +0000 (14:24 +0100)] 
MINOR: cli: define usermsgs print context

CLI 'add server' handler relies on usermsgs_ctx to display errors in
internal function on CLI output. This may be also extended to other
handlers.

However, to not clutter stderr from another contextes, usermsgs_ctx must
be resetted when it is not needed anymore. This operation cannot be
conducted in the CLI parse handler as display is conducted after it.

To achieve this, define new CLI states CLI_ST_PRINT_UMSG /
CLI_ST_PRINT_UMSGERR. Their principles is nearly identical to states for
dynamic messages printing.

2 years agoCLEANUP: cli: rename dynamic error printing state
Amaury Denoyelle [Thu, 10 Nov 2022 10:47:36 +0000 (11:47 +0100)] 
CLEANUP: cli: rename dynamic error printing state

Rename CLI_ST_PRINT_FREE to CLI_ST_PRINT_DYNERR.

Most notably, this highlights that this is reserved to error printing.

This is done to ensure consistency between CLI_ST_PRINT/CLI_ST_PRINT_DYN
and CLI_ST_PRINT_ERR/CLI_ST_PRINT_DYNERR. The name is also consistent
with the function cli_dynerr() which activates it.

2 years agoMINOR: ssl: x509_v_err_str converter transforms an integer to a X509_V_ERR name
William Lallemand [Thu, 3 Nov 2022 17:56:37 +0000 (18:56 +0100)] 
MINOR: ssl: x509_v_err_str converter transforms an integer to a X509_V_ERR name

The x509_v_err_str converter transforms a numerical X509 verify error
to its constant name.

2 years agoMEDIUM: ssl: {ca,crt}-ignore-err can now use error constant name
William Lallemand [Thu, 3 Nov 2022 15:31:50 +0000 (16:31 +0100)] 
MEDIUM: ssl: {ca,crt}-ignore-err can now use error constant name

The ca-ignore-err and crt-ignore-err directives are now able to use the
openssl X509_V_ERR constant names instead of the numerical values.

This allow a configuration to survive an OpenSSL upgrade, because the
numerical ID can change between versions. For example
X509_V_ERR_INVALID_CA was 24 in OpenSSL 1 and is 79 in OpenSSL 3.

The list of errors must be updated when a new major OpenSSL version is
released.

2 years agoBUG/MEDIUM: ssl: Verify error codes can exceed 63
Remi Tricot-Le Breton [Thu, 10 Nov 2022 09:48:58 +0000 (10:48 +0100)] 
BUG/MEDIUM: ssl: Verify error codes can exceed 63

The CRT and CA verify error codes were stored in 6 bits each in the
xprt_st field of the ssl_sock_ctx meaning that only error code up to 63
could be stored. Likewise, the ca-ignore-err and crt-ignore-err options
relied on two unsigned long longs that were used as bitfields for all
the ignored error codes. On the latest OpenSSL1.1.1 and with OpenSSLv3
and newer, verify errors have exceeded this value so these two storages
must be increased. The error codes will now be stored on 7 bits each and
the ignore-err bitfields are replaced by a big enough array and
dedicated bit get and set functions.

It can be backported on all stable branches.

[wla: let it be tested a little while before backport]
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
2 years agoCI: enable QUIC for LibreSSL builds
Ilya Shipitsin [Wed, 2 Nov 2022 06:59:37 +0000 (11:59 +0500)] 
CI: enable QUIC for LibreSSL builds

since LibreSSL-3.6.x supports QUIC, let us enable it

2 years agoCI: switch to the "latest" LibreSSL
Ilya Shipitsin [Wed, 2 Nov 2022 06:57:03 +0000 (11:57 +0500)] 
CI: switch to the "latest" LibreSSL

LibreSSL-3.6.0 had some regression, it was fixed in 3.6.1, let us
switch back to the latest LibreSSL available

2 years agoBUG/MINOR: ssl: ocsp structure not freed properly in case of error
Remi Tricot-Le Breton [Thu, 3 Nov 2022 14:16:49 +0000 (15:16 +0100)] 
BUG/MINOR: ssl: ocsp structure not freed properly in case of error

In case of error, the ocsp item might already be in the ocsp certificate
tree but simply freed instead of destroyed through ssl_sock_free_ocsp.

This patch can be backported to all stable versions.

2 years agoBUG/MINOR: ssl: Memory leak of AUTHORITY_KEYID struct when loading issuer
Remi Tricot-Le Breton [Thu, 3 Nov 2022 14:16:48 +0000 (15:16 +0100)] 
BUG/MINOR: ssl: Memory leak of AUTHORITY_KEYID struct when loading issuer

When calling ssl_get0_issuer_chain, if akid is not NULL but its keyid
is, then the AUTHORITY_KEYID is not freed.

This patch can be backported to all stable branches.

2 years agoBUG/MINOR: ssl: Memory leak of DH BIGNUM fields
Remi Tricot-Le Breton [Thu, 3 Nov 2022 14:16:47 +0000 (15:16 +0100)] 
BUG/MINOR: ssl: Memory leak of DH BIGNUM fields

When running HAProxy with OpenSSLv3, the two BIGNUMs used to build our
own DH parameters are not freed. It was not necessary previously because
ownership of those parameters was transferred to OpenSSL through the
DH_set0_pqg call.

This patch should be backported to 2.6.

2 years agoBUG/MINOR: httpclient: fixed memory allocation for the SSL ca_file
Miroslav Zagorac [Wed, 2 Nov 2022 15:11:50 +0000 (16:11 +0100)] 
BUG/MINOR: httpclient: fixed memory allocation for the SSL ca_file

The memory for the SSL ca_file was allocated only once (in the function
httpclient_create_proxy()) and that pointer was assigned to each created
proxy that the HTTP client uses.  This would not be a problem if this
memory was not freed in each individual proxy when it was deinitialized
in the function ssl_sock_free_srv_ctx().

  Memory allocation:
    src/http_client.c, function httpclient_create_proxy():
      1277: if (!httpclient_ssl_ca_file)
      1278: httpclient_ssl_ca_file = strdup("@system-ca");
      1280: srv_ssl->ssl_ctx.ca_file = httpclient_ssl_ca_file;

  Memory deallocation:
    src/ssl_sock.c, function ssl_sock_free_srv_ctx():
      5613: ha_free(&srv->ssl_ctx.ca_file);

This should be backported to version 2.6.

2 years agoCLEANUP: ssl: remove dead code in ssl_sock_load_pem_into_ckch()
William Lallemand [Sun, 30 Oct 2022 18:00:06 +0000 (19:00 +0100)] 
CLEANUP: ssl: remove dead code in ssl_sock_load_pem_into_ckch()

Commit 432cd1a ("MEDIUM: ssl: be stricter about chain error")
introduced some dead code, let's remove it.

Should fix issue #1909.

2 years agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Sat, 29 Oct 2022 04:34:32 +0000 (09:34 +0500)] 
CLEANUP: assorted typo fixes in the code and comments

This is 32nd iteration of typo fixes

2 years agoCI: add monthly gcc cross compile jobs
Ilya Shipitsin [Tue, 18 Oct 2022 14:13:45 +0000 (19:13 +0500)] 
CI: add monthly gcc cross compile jobs

Build only gcc cross compile jobs are added with monthly run to catch
rare errors, mostly 32bit <--> 64bit

2 years agoBUG/MINOR: quic: fix race condition on datagram purging
Amaury Denoyelle [Tue, 25 Oct 2022 09:38:21 +0000 (11:38 +0200)] 
BUG/MINOR: quic: fix race condition on datagram purging

Each datagram is received by a random thread and dispatch to its
destination thread linked to the connection. Then, the datagram is
handled by the connection thread. Once this is done, datagram buffer
pointer is atomically set to NULL to mark it as consumed.

Consumed datagrams are purged before recvfrom() invocation on random
receiver threads. The check for NULL buffer must thus be done
atomically. This was not the case before this patch, which may have
triggered race conditions.

This bug has been introduced by commit
  91b2305ad79bb7086840797b6e98bd791992444f
  MINOR: quic: implement datagram cleanup for quic_receiver_buf

This should be backported up to 2.6 after previously mentionned commit.

2 years agoMINOR: quic: add counter for interrupted reception
Amaury Denoyelle [Thu, 27 Oct 2022 15:56:27 +0000 (17:56 +0200)] 
MINOR: quic: add counter for interrupted reception

Add a new counter "quic_rxbuf_full". It is incremented each time
quic_sock_fd_iocb() is interrupted on full buffer.

This should help to debug github issue #1903. It is suspected that
QUIC receiver buffers are full which in turn cause quic_sock_fd_iocb()
to be called repeatedly resulting in a high CPU consumption.

2 years agoMINOR: ssl: dump the SSL string error when SSL_CTX_use_PrivateKey() failed.
William Lallemand [Thu, 27 Oct 2022 12:41:07 +0000 (14:41 +0200)] 
MINOR: ssl: dump the SSL string error when SSL_CTX_use_PrivateKey() failed.

Display the OpenSSL reason error string when SSL_CTX_use_PrivateKey()
failed.