]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 years agoBUG/MEDIUM: http-ana: Properly switch the request in tunnel mode on upgrade
Christopher Faulet [Mon, 17 Apr 2023 06:52:10 +0000 (08:52 +0200)] 
BUG/MEDIUM: http-ana: Properly switch the request in tunnel mode on upgrade

Since the commit f2b02cfd9 ("MAJOR: http-ana: Review error handling during
HTTP payload forwarding"), during the payload forwarding, we are analyzing a
side, we stop to test the opposite side. It means when the HTTP request
forwarding analyzer is called, we no longer check the response side and vice
versa.

Unfortunately, since then, the HTTP tunneling is broken after a protocol
upgrade. On the response is switch in TUNNEL mode. The request remains in
DONE state. As a consequence, data received from the server are forwarded to
the client but not data received from the client.

To fix the bug, when both sides are in DONE state, both are switched in same
time in TUNNEL mode if it was requested. It is performed in the same way in
http_end_request() and http_end_response().

This patch should fix the issue #2125. It is 2.8-specific. No backport
needed.

2 years agoMINOR: ssl: remove OpenSSL 1.0.2 mention into certificate loading error
William Lallemand [Mon, 17 Apr 2023 12:32:25 +0000 (14:32 +0200)] 
MINOR: ssl: remove OpenSSL 1.0.2 mention into certificate loading error

Remove the mention to OpenSSL 1.0.2 in the certificate chain loading
error, which is not relevant.

Could be backported in 2.7.

2 years agoCLEANUP: use "offsetof" where appropriate
Ilya Shipitsin [Sat, 15 Apr 2023 21:39:43 +0000 (23:39 +0200)] 
CLEANUP: use "offsetof" where appropriate

let's use the C library macro "offsetof"

2 years agoBUG/MINOR: quic: Do not use ack delay during the handshakes
Frédéric Lécaille [Fri, 14 Apr 2023 07:56:17 +0000 (09:56 +0200)] 
BUG/MINOR: quic: Do not use ack delay during the handshakes

As revealed by GH #2120 opened by @Tristan971, there are cases where ACKs
have to be sent without packet to acknowledge because the ACK timer has
been triggered and the connection needs to probe the peer at the same time.
Indeed

Thank you to @Tristan971 for having reported this issue.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: stconn: Don't set SE_FL_ERROR at the end of sc_conn_send()
Christopher Faulet [Fri, 14 Apr 2023 15:32:39 +0000 (17:32 +0200)] 
BUG/MINOR: stconn: Don't set SE_FL_ERROR at the end of sc_conn_send()

When I reworked my series, this code was first removed and reinserted by
error. So let's remove it again.

2 years agoMEDIUM: stconn: Rely on SC flags to handle errors instead of SE flags
Christopher Faulet [Fri, 14 Apr 2023 10:09:35 +0000 (12:09 +0200)] 
MEDIUM: stconn: Rely on SC flags to handle errors instead of SE flags

It is the last commit on this subject. we stop to use SE_FL_ERROR flag from
the SC, except at the I/O level. Otherwise, we rely on SC_FL_ERROR
flag. Now, there should be a real separation between SE flags and SC flags.

2 years agoMEDIUM: stream: Stop to use SE flags to detect endpoint errors
Christopher Faulet [Fri, 14 Apr 2023 10:07:26 +0000 (12:07 +0200)] 
MEDIUM: stream: Stop to use SE flags to detect endpoint errors

Here again, we stop to use SE_FL_ERROR flag from process_stream() and
sub-functions and we fully rely on SC_FL_ERROR to do so.

2 years agoMEDIUM: stream: Stop to use SE flags to detect read errors from analyzers
Christopher Faulet [Fri, 14 Apr 2023 10:05:55 +0000 (12:05 +0200)] 
MEDIUM: stream: Stop to use SE flags to detect read errors from analyzers

In the same way the previous commit, we stop to use SE_FL_ERROR flag from
analyzers and their sub-functions. We now fully rely on SC_FL_ERROR to do so.

2 years agoMEDIUM: backend: Stop to use SE flags to detect connection errors
Christopher Faulet [Fri, 14 Apr 2023 10:05:25 +0000 (12:05 +0200)] 
MEDIUM: backend: Stop to use SE flags to detect connection errors

SE_FL_ERROR flag is no longer set when an error is detected durign the
connection establishment. SC_FL_ERROR flag is set instead. So it is safe to
remove test on SE_FL_ERROR to detect connection establishment error.

2 years agoMEDIUM: tree-wide: Stop to set SE_FL_ERROR from upper layer
Christopher Faulet [Fri, 14 Apr 2023 10:03:50 +0000 (12:03 +0200)] 
MEDIUM: tree-wide: Stop to set SE_FL_ERROR from upper layer

We can now fully rely on SC_FL_ERROR flag from the stream. The first step is
to stop to set the SE_FL_ERROR flag. Only endpoints are responsible to set
this flag. It was a design limitation. It is now fixed.

2 years agoMINOR: tree-wide: Test SC_FL_ERROR with SE_FL_ERROR from upper layer
Christopher Faulet [Fri, 14 Apr 2023 09:59:15 +0000 (11:59 +0200)] 
MINOR: tree-wide: Test SC_FL_ERROR with SE_FL_ERROR from upper layer

From the stream, when SE_FL_ERROR flag is tested, we now also test the
SC_FL_ERROR flag. Idea is to stop to rely on the SE descriptor to detect
errors.

2 years agoMINOR: stream: Set SC_FL_ERROR on channels' buffer allocation error
Christopher Faulet [Fri, 14 Apr 2023 09:36:29 +0000 (11:36 +0200)] 
MINOR: stream: Set SC_FL_ERROR on channels' buffer allocation error

Set SC_FL_ERROR flag when we fail to allocate a buffer for a stream.

2 years agoMINOR: backend: Set SC_FL_ERROR on connection error
Christopher Faulet [Fri, 14 Apr 2023 09:35:07 +0000 (11:35 +0200)] 
MINOR: backend: Set SC_FL_ERROR on connection error

During connection establishement, if an error occurred, the SC_FL_ERROR flag
is now set. Concretely, it is set when SE_FL_ERROR is also set.

2 years agoMINOR: stconn: Add a flag to ack endpoint errors at SC level
Christopher Faulet [Fri, 14 Apr 2023 08:42:08 +0000 (10:42 +0200)] 
MINOR: stconn: Add a flag to ack endpoint errors at SC level

The flag SC_FL_ERROR is added to ack errors on the endpoint. When
SE_FL_ERROR flag is detected on the SE descriptor, the corresponding is set
on the SC. Idea is to avoid, as far as possible, to manipulated the SE
descriptor in upper layers and know when an error in the endpoint is handled
by the SC.

For now, this flag is only set and cleared but never tested.

2 years agoMINOR: stconn: Don't clear SE_FL_ERROR when endpoint is reset
Christopher Faulet [Fri, 14 Apr 2023 08:28:28 +0000 (10:28 +0200)] 
MINOR: stconn: Don't clear SE_FL_ERROR when endpoint is reset

There is no reason to remove this flag. When the SC endpoint is reset, it is
replaced by a new one. The old one is released. It was useful when the new
endpoint inherited some flags from the old one.  But it is no longer
performed. Thus there is no reason still unset this flag.

2 years agoMEDIUM: stconn: Forbid applets with more to deliver if EOI was reached
Christopher Faulet [Fri, 14 Apr 2023 07:45:41 +0000 (09:45 +0200)] 
MEDIUM: stconn: Forbid applets with more to deliver if EOI was reached

When an applet is woken up, before calling its io_handler, we pretend it has
no more data to deliver. So, after the io_handler execution, it is a bug if
an applet states it has more data to deliver while the end of input is
reached.

So a BUG_ON() is added to be sure it never happens.

2 years agoMINOR: stconn: Stop to set SE_FL_ERROR on sending path
Christopher Faulet [Fri, 14 Apr 2023 07:42:59 +0000 (09:42 +0200)] 
MINOR: stconn: Stop to set SE_FL_ERROR on sending path

It is not the SC responsibility to report errors on the SE descriptor. It is
the endpoint responsibility. It must switch SE_FL_ERR_PENDING into
SE_FL_ERROR if the end of stream was detected. It can even be considered as
a bug if it is not done by he endpoint.

So now, on sending path, a BUG_ON() is added to abort if SE_FL_EOS and
SE_FL_ERR_PENDING flags are set but not SE_FL_ERROR. It is trully important
to handle this case in the endpoint to be able to properly shut the endpoint
down.

2 years agoBUG/MINOR: cli: Don't close when SE_FL_ERR_PENDING is set in cli analyzer
Christopher Faulet [Fri, 14 Apr 2023 05:49:45 +0000 (07:49 +0200)] 
BUG/MINOR: cli: Don't close when SE_FL_ERR_PENDING is set in cli analyzer

SE_FL_ERR_PENDING is used to report an error on the write side. But it is
not a terminal error. Some incoming data may still be available. In the cli
analyzers, it is important to not close the stream when this flag is
set. Otherwise the response to a command can be truncated. It is probably
hard to observe. But it remains a bug.

While this patch could be backported to 2.7, there is no real reason to do
so, except if someone reports a bug about truncated responses.

2 years agoMINOR: tree-wide: Replace several chn_prod() by the corresponding SC
Christopher Faulet [Thu, 13 Apr 2023 14:44:18 +0000 (16:44 +0200)] 
MINOR: tree-wide: Replace several chn_prod() by the corresponding SC

At many places, call to chn_prod() can be easily replaced by the
corresponding SC. It is a bit easier to understand which side is
manipulated.

2 years agoMINOR: tree-wide: Replace several chn_cons() by the corresponding SC
Christopher Faulet [Thu, 13 Apr 2023 14:37:37 +0000 (16:37 +0200)] 
MINOR: tree-wide: Replace several chn_cons() by the corresponding SC

At many places, call to chn_cons() can be easily replaced by the
corresponding SC. It is a bit easier to understand which side is
manipulated.

2 years agoMINOR: channel/stconn: Replace sc_shutw() by sc_shutdown()
Christopher Faulet [Thu, 13 Apr 2023 14:23:48 +0000 (16:23 +0200)] 
MINOR: channel/stconn: Replace sc_shutw() by sc_shutdown()

All reference to a shutw is replaced by an abort. So sc_shutw() is renamed
sc_shutdown(). SC app ops functions are renamed accordingly.

2 years agoMINOR: stconn: Rename SC_FL_SHUTW in SC_FL_SHUT_DONE
Christopher Faulet [Thu, 13 Apr 2023 14:16:15 +0000 (16:16 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTW in SC_FL_SHUT_DONE

Here again, it is just a flag renaming. In SC flags, there is no longer
shutdown for writes but shutdowns.

2 years agoMINOR: channel/stconn: Replace sc_shutr() by sc_abort()
Christopher Faulet [Thu, 13 Apr 2023 14:10:23 +0000 (16:10 +0200)] 
MINOR: channel/stconn: Replace sc_shutr() by sc_abort()

All reference to a shutr is replaced by an abort. So sc_shutr() is renamed
sc_abort(). SC app ops functions are renamed accordingly.

2 years agoMINOR: stconn: Rename SC_FL_SHUTR in SC_FL_ABRT_DONE
Christopher Faulet [Thu, 13 Apr 2023 14:05:13 +0000 (16:05 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTR in SC_FL_ABRT_DONE

Here again, it is just a flag renaming. In SC flags, there is no longer
shutdown for reads but aborts. For now this flag is set when a read0 is
detected. It is of couse not accurate. This will be changed later.

2 years agoMINOR: channel/stconn: Replace channel_shutw_now() by sc_schedule_shutdown()
Christopher Faulet [Thu, 13 Apr 2023 13:56:26 +0000 (15:56 +0200)] 
MINOR: channel/stconn: Replace channel_shutw_now() by sc_schedule_shutdown()

After the flag renaming, it is now the turn for the channel function to be
renamed and moved in the SC scope. channel_shutw_now() is replaced by
sc_schedule_shutdown(). The request channel is replaced by the front SC and
the response is replace by the back SC.

2 years agoMINOR: stconn: Rename SC_FL_SHUTW_NOW in SC_FL_SHUT_WANTED
Christopher Faulet [Thu, 13 Apr 2023 13:45:24 +0000 (15:45 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTW_NOW in SC_FL_SHUT_WANTED

Because shutowns for reads are now considered as aborts, the shudowns for
writes can now be considered as shutdowns. Here it is just a flag
renaming. SC_FL_SHUTW_NOW is renamed SC_FL_SHUT_WANTED.

2 years agoMINOR: channel/stconn: Replace channel_shutr_now() by sc_schedule_abort()
Christopher Faulet [Thu, 13 Apr 2023 13:40:10 +0000 (15:40 +0200)] 
MINOR: channel/stconn: Replace channel_shutr_now() by sc_schedule_abort()

After the flag renaming, it is now the turn for the channel function to be
renamed and moved in the SC scope. channel_shutr_now() is replaced by
sc_schedule_abort(). The request channel is replaced by the front SC and the
response is replace by the back SC.

2 years agoMINOR: stconn: Rename SC_FL_SHUTR_NOW in SC_FL_ABRT_WANTED
Christopher Faulet [Thu, 13 Apr 2023 13:39:30 +0000 (15:39 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTR_NOW in SC_FL_ABRT_WANTED

It is the first step to transform shutdown for reads for the upper layer
into aborts. This patch is quite simple, it is just a flag renaming.

2 years agoMINOR: stream: Introduce stream_abort() to abort on both sides in same time
Christopher Faulet [Thu, 13 Apr 2023 13:22:29 +0000 (15:22 +0200)] 
MINOR: stream: Introduce stream_abort() to abort on both sides in same time

The function stream_abort() should now be called when an abort is performed
on the both channels in same time.

2 years agoMINOR: channel: Forwad close to other side on abort
Christopher Faulet [Thu, 13 Apr 2023 13:13:12 +0000 (15:13 +0200)] 
MINOR: channel: Forwad close to other side on abort

Most of calls to channel_abort() are associated to a call to
channel_auto_close(). Others are in areas where the auto close is the
default. So, it is now systematically enabled when an abort is performed on
a channel, as part of channel_abort() function.

2 years agoREGTESTS: fix the race conditions in log_uri.vtc
Christopher Faulet [Thu, 13 Apr 2023 13:11:23 +0000 (15:11 +0200)] 
REGTESTS: fix the race conditions in log_uri.vtc

A "Connection: close" header is added to responses to avoid any connection
reuse. This should avoid any "HTTP header incomplete" errors.

2 years agoMINOR: filters: Review and simplify errors handling
Christopher Faulet [Thu, 13 Apr 2023 12:49:04 +0000 (14:49 +0200)] 
MINOR: filters: Review and simplify errors handling

First, it is useless to abort the both channel explicitly. For HTTP streams,
http_reply_and_close() is called. This function already take care to abort
processing. For TCP streams, we can rely on stream_retnclose().

To set termination flags, we can also rely on http_set_term_flags() for HTTP
streams and sess_set_term_flags() for TCP streams. Thus no reason to handle
them by hand.

At the end, the error handling after filters evaluation is now quite simple.

2 years agoMINOR: stream: Uninline and export sess_set_term_flags() function
Christopher Faulet [Thu, 13 Apr 2023 12:46:01 +0000 (14:46 +0200)] 
MINOR: stream: Uninline and export sess_set_term_flags() function

This function will be used to set termination flags on TCP streams from
outside of process_stream(). Thus, it must be uninlined and exported.

2 years agoBUG/MEDIUM: stconn: Do nothing in sc_conn_recv() when the SC needs more room
Christopher Faulet [Wed, 12 Apr 2023 16:35:18 +0000 (18:35 +0200)] 
BUG/MEDIUM: stconn: Do nothing in sc_conn_recv() when the SC needs more room

We erroneously though that an attempt to receive data was not possible if the SC
was waiting for more room in the channel buffer. A BUG_ON() was added to detect
bugs. And in fact, it is possible.

The regression was added in commit 341a5783b ("BUG/MEDIUM: stconn: stop to
enable/disable reads from streams via si_update_rx").

This patch should fix the issue #2115. It must be backported if the commit
above is backported.

2 years agoBUG/MEDIUM: stream: Report write timeouts before testing the flags
Christopher Faulet [Wed, 12 Apr 2023 16:23:15 +0000 (18:23 +0200)] 
BUG/MEDIUM: stream: Report write timeouts before testing the flags

A regression was introduced when stream's timeouts were refactored. Write
timeouts are not testing is the right order. When timeous of the front SC
are handled, we must then test the read timeout on the request channel and
the write timeout on the response channel. But write timeout is tested on
the request channel instead. On the back SC, the same mix-up is performed.

We must be careful to handle timeouts before checking channel flags. To
avoid any confusions, all timeuts are handled first, on front and back SCs.
Then flags of the both channels are tested.

It is a 2.8-specific issue. No backport needed.

2 years agoBUG/MINOR: stream: Fix test on SE_FL_ERROR on the wrong entity
Christopher Faulet [Wed, 12 Apr 2023 12:20:36 +0000 (14:20 +0200)] 
BUG/MINOR: stream: Fix test on SE_FL_ERROR on the wrong entity

There is a bug at begining of process_stream(). The SE_FL_ERROR flag is
tested against backend stream-connector's flags instead of its SE
descriptor's flags. It is an old typo, introduced when the stream-interfaces
were replaced by the conn-streams.

This patch must be backported as far as 2.6.

2 years agoCI: enable monthly test on Fedora Rawhide
Ilya Shipitsin [Sat, 8 Apr 2023 11:30:42 +0000 (13:30 +0200)] 
CI: enable monthly test on Fedora Rawhide

Fedora Rawhide is shipped with the most recent compilers, not yet released with
more conservative distro. It is good to catch compile errors on those compilers.

2 years agoCI: bump "actions/checkout" to v3 for cross zoo matrix
Ilya Shipitsin [Sat, 8 Apr 2023 11:32:31 +0000 (13:32 +0200)] 
CI: bump "actions/checkout" to v3 for cross zoo matrix

actions/checkout@v2 is deprecated, accidently it was not updated in our
build definition

2 years agoBUG/MINOR: quic: Wrong Application encryption level selection when probing
Frédéric Lécaille [Thu, 13 Apr 2023 16:30:16 +0000 (18:30 +0200)] 
BUG/MINOR: quic: Wrong Application encryption level selection when probing

This bug arrived with this commit:

    MEDIUM: quic: Ack delay implementation

After having probed the Handshake packet number space, one must not select the
Application encryption level to continue trying building packets as this is done
when the connection is not probing. Indeed, if the ACK timer has been triggered
in the meantime, the packet builder will try to build a packet at the Application
encryption level to acknowledge the received packet. But there is very often
no 01RTT packet to acknowledge when the connection is probing before the
handshake is completed. This triggers a BUG_ON() in qc_do_build_pkt() which
checks that the tree of ACK ranges to be used is not empty.

Thank you to @Tristan971 for having reported this issue in GH #2109.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Remove a useless test about probing in qc_prep_pkts()
Frédéric Lécaille [Thu, 13 Apr 2023 13:59:02 +0000 (15:59 +0200)] 
MINOR: quic: Remove a useless test about probing in qc_prep_pkts()

qel->pktns->tx.pto_probe is set to 0 after having prepared a probing
datagram. There is no reason to check this parameter. Furthermore
it is always 0 when the connection does not probe the peer.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Display the packet number space flags in traces
Frédéric Lécaille [Thu, 13 Apr 2023 13:55:49 +0000 (15:55 +0200)] 
MINOR: quic: Display the packet number space flags in traces

Display this information when the encryption level is also displayed.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: quic: SIGFPE in quic_cubic_update()
Frédéric Lécaille [Thu, 13 Apr 2023 08:46:42 +0000 (10:46 +0200)] 
BUG/MINOR: quic: SIGFPE in quic_cubic_update()

As reported by @Tristan971 in GH #2116, the congestion control window could be zero
due to an inversion in the code about the reduction factor to be applied.
On a new loss event, it must be applied to the slow start threshold and the window
should never be below ->min_cwnd (2*max_udp_payload_sz).

Same issue in both newReno and cubic algorithm. Furthermore in newReno, only the
threshold was decremented.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: quic: Possible wrapped values used as ACK tree purging limit.
Frédéric Lécaille [Wed, 12 Apr 2023 18:49:29 +0000 (20:49 +0200)] 
BUG/MINOR: quic: Possible wrapped values used as ACK tree purging limit.

Add two missing checks not to substract too big values from another too little
one. In this case the resulted wrapped huge values could be passed to the function
which has to remove the last range of a tree of ACK ranges as encoded limit size
not to go below, cancelling the ACK ranges deletion. The consequence could be that
no ACK were sent.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MEDIUM: quic: Code sanitization about acknowledgements requirements
Frédéric Lécaille [Wed, 12 Apr 2023 16:51:49 +0000 (18:51 +0200)] 
BUG/MEDIUM: quic: Code sanitization about acknowledgements requirements

qc_may_build_pkt() has been modified several times regardless of the conditions
the functions it is supposed to allow to send packets (qc_build_pkt()/qc_do_build_pkt())
really use to finally send packets just after having received others, leading
to contraditions and possible very long loops sending empty packets (PADDING only packets)
because qc_may_build_pkt() could allow qc_build_pkt()/qc_do_build_pkt to build packet,
and the latter did nothing except sending PADDING frames, because from its point
of view they had nothing to send.

For now on, this is the job of qc_may_build_pkt() to decide to if there is
packets to send just after having received others AND to provide this information
to the qc_build_pkt()/qc_do_build_pkt()

Note that the unique case where the acknowledgements are completely ignored is
when the endpoint must probe. But at least this is when sending at most two datagrams!

This commit also fixes the issue reported by Willy about a very low throughput
performance when the client serialized its requests.

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add connection flags to traces
Frédéric Lécaille [Wed, 12 Apr 2023 11:41:54 +0000 (13:41 +0200)] 
MINOR: quic: Add connection flags to traces

This should help in diagnosing issues.

Some adjustments have to be done to avoid deferencing a quic_conn objects from
TRACE_*() calls.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: quic: Ignored less than 1ms RTTs
Frédéric Lécaille [Thu, 6 Apr 2023 11:13:08 +0000 (13:13 +0200)] 
BUG/MINOR: quic: Ignored less than 1ms RTTs

Do not ignore very short RTTs (less than 1ms) before computing the smoothed
RTT initializing it to an "infinite" value (UINT_MAX).

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add packet loss and maximum cc window to "show quic"
Frédéric Lécaille [Thu, 6 Apr 2023 08:19:17 +0000 (10:19 +0200)] 
MINOR: quic: Add packet loss and maximum cc window to "show quic"

Add the number of packet losts and the maximum congestion control window computed
by the algorithms to "show quic".
Same thing for the traces of existent congestion control algorithms.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MEDIUM: fd: don't wait for tmask to stabilize if we're not in it.
Olivier Houchard [Thu, 13 Apr 2023 14:12:38 +0000 (16:12 +0200)] 
BUG/MEDIUM: fd: don't wait for tmask to stabilize if we're not in it.

In fd_update_events(), we loop until there's no bit in the running_mask
that is not in the thread_mask. Problem is, the thread sets its
running_mask bit before that loop, and so if 2 threads do the same, and
a 3rd one just closes the FD and sets the thread_mask to 0, then
running_mask will always be non-zero, and we will loop forever. This is
trivial to reproduce when using a DNS resolver that will just answer
"port unreachable", but could theoretically happen with other types of
file descriptors too.

To fix that, just don't bother looping if we're no longer in the
thread_mask, if that happens we know we won't have to take care of the
FD, anyway.

This should be backported to 2.7, 2.6 and 2.5.

2 years agoMINOR: bind-conf: support a new shards value: "by-group"
Willy Tarreau [Thu, 13 Apr 2023 15:25:43 +0000 (17:25 +0200)] 
MINOR: bind-conf: support a new shards value: "by-group"

Setting "shards by-group" will create one shard per thread group. This
can often be a reasonable tradeoff between a single one that can be
suboptimal on CPUs with many cores, and too many that will eat a lot
of file descriptors. It was shown to provide good results on a 224
thread machine, with a distribution that was even smoother than the
system's since here it can take into account the number of connections
per thread in the group. Depending on how popular it becomes, it could
even become the default setting in a future version.

2 years agoMINOR: receiver: reserve special values for "shards"
Willy Tarreau [Thu, 13 Apr 2023 15:11:23 +0000 (17:11 +0200)] 
MINOR: receiver: reserve special values for "shards"

Instead of artificially setting the shards count to MAX_THREAD when
"by-thread" is used, let's reserve special values for symbolic names
so that we can add more in the future. For now we use value -1 for
"by-thread", which requires to turn the type to signed int but it was
already used as such everywhere anyway.

2 years agoMINOR: fd: implement fd_migrate_on() to migrate on a non-local thread
Amaury Denoyelle [Mon, 3 Apr 2023 13:27:13 +0000 (15:27 +0200)] 
MINOR: fd: implement fd_migrate_on() to migrate on a non-local thread

fd_migrate_on() can be used to migrate an existing FD to any thread, even
one belonging to a different group from the current one and from the
caller's. All that is needed is to make sure the FD is still valid when
the operation is performed (which is the case when such operations happen).

This is potentially slightly expensive since it locks the tgid during the
delicate operation, but it is normally performed only from an owning
thread to offer the FD to another one (e.g. reassign a better thread upon
accept()).

2 years agoMINOR: fd: add a lock bit with the tgid
Willy Tarreau [Thu, 13 Apr 2023 12:27:48 +0000 (14:27 +0200)] 
MINOR: fd: add a lock bit with the tgid

In order to permit to migrate FDs from one thread group to another,
we'll need to be able to set a TGID that is compatible with no other
thread group. Either we use a special value or we dedicate a special
bit. Given that we already have way more bits than needed, let's just
sacrifice the topmost one to serve as a lock bit, indicating the tgid
is not valid anymore. This will make all fd_grab_tgid() fail to grab
it.

The new fd_lock_tgid() function now tries to assign a locked tgid to
an idle FD, and fd_unlock_tgid() simply drops the lock bit, revealing
the target tgid.

For now it's still unused so it must not have any effect.

2 years agoMINOR: fd: optimize fd_claim_tgid() for use in fd_insert()
Willy Tarreau [Thu, 13 Apr 2023 13:22:42 +0000 (15:22 +0200)] 
MINOR: fd: optimize fd_claim_tgid() for use in fd_insert()

fd_claim_tgid() uses a CAS to set the desired TGID on the FD. It's only
called from fd_insert() where in the vast majority of cases, the tgid
and refcount are zero before the call. However the loop was optimized
for the case where it was equal to the desired TGID, systematically
causing one extra round in the loop there. Better start assuming a
zero value.

2 years agoMINOR: thread: keep a bitmask of enabled groups in thread_set
Willy Tarreau [Wed, 1 Mar 2023 10:24:29 +0000 (11:24 +0100)] 
MINOR: thread: keep a bitmask of enabled groups in thread_set

We're only checking for 0, 1, or >1 groups enabled there, and we'll soon
need to be more precise and know quickly which groups are non-empty.
Let's just replace the count with a mask of enabled groups. This will
allow to quickly spot the presence of any such group in a set.

2 years agoBUG/MINOR: stick_table: alert when type len has incorrect characters
William Lallemand [Thu, 13 Apr 2023 12:33:52 +0000 (14:33 +0200)] 
BUG/MINOR: stick_table: alert when type len has incorrect characters

Alert when the len argument of a stick table type contains incorrect
characters.

Replace atol by strtol.

Could be backported in every maintained versions.

2 years agoMINOR: activity: add a line reporting the average CPU usage to "show activity"
Willy Tarreau [Tue, 11 Apr 2023 13:26:24 +0000 (15:26 +0200)] 
MINOR: activity: add a line reporting the average CPU usage to "show activity"

It was missing from the output but is sometimes convenient to observe
and understand how incoming connections are distributed. The CPU usage
is reported as the instant measurement of 100-idle_pct for each thread,
and the average value is shown for the aggregated value.

This could be backported as it's helpful in certain troublehsooting
sessions.

2 years agoMINOR: quic: Add a trace for packet with an ACK frame
Frédéric Lécaille [Fri, 7 Apr 2023 17:01:33 +0000 (19:01 +0200)] 
MINOR: quic: Add a trace for packet with an ACK frame

As the ACK frames are not added to the packet list of ack-eliciting frames,
it could not be traced. But there is a flag to identify such packet.
Let's use it to add this information to the traces of TX packets.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Dump more information at proto level when building packets
Frédéric Lécaille [Fri, 7 Apr 2023 16:12:00 +0000 (18:12 +0200)] 
MINOR: quic: Dump more information at proto level when building packets

This should be helpful to debug issues at without too much traces.

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Modify qc_try_rm_hp() traces
Frédéric Lécaille [Fri, 7 Apr 2023 15:58:49 +0000 (17:58 +0200)] 
MINOR: quic: Modify qc_try_rm_hp() traces

Dump at proto level the packet information when its header protection was removed.
Remove no more use qpkt_trace variable.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: quic: Wrong packet number space probing before confirmed handshake
Frédéric Lécaille [Fri, 7 Apr 2023 14:28:46 +0000 (16:28 +0200)] 
BUG/MINOR: quic: Wrong packet number space probing before confirmed handshake

It is possible that the handshake was not confirmed and there was no more
packet in flight to probe with. It this case the server must wait for
the client to be unblocked without probing any packet number space contrary
to what was revealed by interop tests as follows:

[01|quic|2|uic_loss.c:65] TX loss pktns : qc@0x7fac301cd390 pktns=I pp=0
[01|quic|2|uic_loss.c:67] TX loss pktns : qc@0x7fac301cd390 pktns=H pp=0 tole=-102ms
[01|quic|2|uic_loss.c:67] TX loss pktns : qc@0x7fac301cd390 pktns=01RTT pp=0 if=1054 tole=-1987ms
[01|quic|5|uic_loss.c:73] quic_loss_pktns(): leaving : qc@0x7fac301cd390
[01|quic|5|uic_loss.c:91] quic_pto_pktns(): entering : qc@0x7fac301cd390
[01|quic|3|ic_loss.c:121] TX PTO handshake not already completed : qc@0x7fac301cd390
[01|quic|2|ic_loss.c:141] TX PTO : qc@0x7fac301cd390 pktns=I pp=0 dur=83ms
[01|quic|5|ic_loss.c:142] quic_pto_pktns(): leaving : qc@0x7fac301cd390
[01|quic|3|c_conn.c:5179] needs to probe Initial packet number space : qc@0x7fac301cd390

This bug was not visible before this commit:
     BUG/MINOR: quic: wake up MUX on probing only for 01RTT

This means that before it, one could do bad things (probing the 01RTT packet number
space before the handshake was confirmed).

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Trace fix in quic_pto_pktns() (handshaske status)
Frédéric Lécaille [Fri, 7 Apr 2023 13:39:17 +0000 (15:39 +0200)] 
MINOR: quic: Trace fix in quic_pto_pktns() (handshaske status)

The handshake must be confirmed before probing the 01RTT packet number space.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MEDIUM: mux-h2: Never set SE_FL_EOS without SE_FL_EOI or SE_FL_ERROR
Christopher Faulet [Tue, 11 Apr 2023 06:59:08 +0000 (08:59 +0200)] 
BUG/MEDIUM: mux-h2: Never set SE_FL_EOS without SE_FL_EOI or SE_FL_ERROR

When end-of-stream is reported by a H2 stream, we must take care to also
report an error is end-of-input was not reported. Indeed, it is now
mandatory to set SE_FL_EOI or SE_FL_ERROR flags when SE_FL_EOS is set.

It is a 2.8-specific issue. No backport needed.

2 years agoBUG/MEDIUM: mux-h1: Report EOI when a TCP connection is upgraded to H2
Christopher Faulet [Tue, 11 Apr 2023 06:32:13 +0000 (08:32 +0200)] 
BUG/MEDIUM: mux-h1: Report EOI when a TCP connection is upgraded to H2

When TCP connection is first upgrade to H1 then to H2, the stream-connector,
created by the PT mux, must be destroyed because the H2 mux cannot inherit
from it. When it is performed, the SE_FL_EOS flag is set but SE_FL_EOI must
also be set. It is now required to never set SE_FL_EOS without SE_FL_EOI or
SE_FL_ERROR.

It is a 2.8-specific issue. No backport needed.

2 years agoMINOR: hlua: Stop to check the SC state when executing a hlua cli command
Christopher Faulet [Tue, 11 Apr 2023 06:16:52 +0000 (08:16 +0200)] 
MINOR: hlua: Stop to check the SC state when executing a hlua cli command

This part has changed but it was already handled by the CLI applet. There is
no reason to performe this test when a hlua cli command is executed.

2 years agoBUG/MEDIUM: resolvers: Force the connect timeout for DNS resolutions
Christopher Faulet [Tue, 11 Apr 2023 06:04:04 +0000 (08:04 +0200)] 
BUG/MEDIUM: resolvers: Force the connect timeout for DNS resolutions

Timeouts for dynamic resolutions are not handled at the stream level but by
the resolvers themself. It means there is no connect, client and server
timeouts defined on the internal proxy used by a resolver.

While it is not an issue for DNS resolution over UDP, it can be a problem
for resolution over TCP. New sessions are automatically created when
required, and killed on excess. But only established connections are
considered. Connecting ones are never killed. Because there is no conncet
timeout, we rely on the kernel to report a connection error. And this may be
quite long.

Because resolutions are periodically triggered, this may lead to an excess
of unusable sessions in connecting state. This also prevents HAProxy to
quickly exit on soft-stop. It is annoying, especially because there is no
reason to not set a connect timeout.

So to mitigate the issue, we now use the "resolve" timeout as connect
timeout for the internal proxy attached to a resolver.

This patch should be backported as far as 2.4.

2 years agoBUG/MINOR: resolvers: Wakeup DNS idle task on stopping
Christopher Faulet [Tue, 11 Apr 2023 05:58:27 +0000 (07:58 +0200)] 
BUG/MINOR: resolvers: Wakeup DNS idle task on stopping

Thanks to previous commit ("BUG/MEDIUM: dns: Kill idle DNS sessions during
stopping stage"), DNS idle sessions are killed on stopping staged. But the
task responsible to kill these sessions is running every 5 seconds. It
means, when HAProxy is stopped, we can observe a delay before the process
exits.

To reduce this delay, when the resolvers task is executed, all DNS idle
tasks are woken up.

This patch must be backported as far as 2.6.

2 years agoBUG/MEDIUM: dns: Kill idle DNS sessions during stopping stage
Christopher Faulet [Tue, 11 Apr 2023 05:44:34 +0000 (07:44 +0200)] 
BUG/MEDIUM: dns: Kill idle DNS sessions during stopping stage

There is no server timeout for DNS sessions over TCP. It means idle session
cannot be killed by itself. There is a task running peridically, every 5s,
to kill the excess of idle sessions. But the last one is never
killed. During the stopping stage, it is an issue since the dynamic
resolutions are no longer performed (2ec6f14c "BUG/MEDIUM: resolvers:
Properly stop server resolutions on soft-stop").

Before the above commit, during stopping stage, the DNS sessions were killed
when a resolution was triggered. Now, nothing kills these sessions. This
prevents the process to finish on soft-stop.

To fix this bug, the task killing excess of idle sessions now kill all idle
sessions on stopping stage.

This patch must be backported as far as 2.6.

2 years agoBUG/MEDIUM: log: Eat output data when waiting for appctx shutdown
Christopher Faulet [Tue, 11 Apr 2023 05:56:50 +0000 (07:56 +0200)] 
BUG/MEDIUM: log: Eat output data when waiting for appctx shutdown

When the log applet is executed while a shut is pending, the remaining
output data must always be consumed. Otherwise, this can prevent the stream
to exit, leading to a spinning loop on the applet.

It is 2.8-specific. No backport needed.

2 years agoBUG/MEDIUM: stats: Eat output data when waiting for appctx shutdown
Christopher Faulet [Tue, 11 Apr 2023 05:41:30 +0000 (07:41 +0200)] 
BUG/MEDIUM: stats: Eat output data when waiting for appctx shutdown

When the stats applet is executed while a shut is pending, the remaining
output data must always be consumed. Otherwise, this can prevent the stream
to exit, leading to a spinning loop on the applet.

It is 2.8-specific. No backport needed.

2 years agoBUG/MEDIUM: http-client: Eat output data when waiting for appctx shutdown
Christopher Faulet [Tue, 11 Apr 2023 05:38:34 +0000 (07:38 +0200)] 
BUG/MEDIUM: http-client: Eat output data when waiting for appctx shutdown

When the http-client applet is executed while a shut is pending, the
remaining output data must always be consumed. Otherwise, this can prevent
the stream to exit, leading to a spinning loop on the applet.

It is 2.8-specific. No backport needed.

2 years agoBUG/MEDIUM: cli: Eat output data when waiting for appctx shutdown
Christopher Faulet [Fri, 7 Apr 2023 16:07:51 +0000 (18:07 +0200)] 
BUG/MEDIUM: cli: Eat output data when waiting for appctx shutdown

When the cli applet is executed while a shut is pending, the remaining
output data must always be consumed. Otherwise, this can prevent the stream
to exit, leading to a spinning loop on the applet.

This patch should fix the issue #2107. It is 2.8-specific. No backport
needed.

2 years agoBUG/MEDIUM: cli: Set SE_FL_EOI flag for '_getsocks' and 'quit' commands
Christopher Faulet [Fri, 7 Apr 2023 15:58:21 +0000 (17:58 +0200)] 
BUG/MEDIUM: cli: Set SE_FL_EOI flag for '_getsocks' and 'quit' commands

An applet must never set SE_FL_EOS flag without SE_FL_EOI or SE_FL_ERROR
flags. Here, SE_FL_EOI flag was missing for "quit" or "_getsocks"
commands. Indeed, these commands are terminal.

This bug triggers a BUG_ON() recently added.

This patch is related to the issue #2107. It is 2.8-specific. No backport
needed.

2 years ago[RELEASE] Released version 2.8-dev7 v2.8-dev7
Willy Tarreau [Sat, 8 Apr 2023 15:38:39 +0000 (17:38 +0200)] 
[RELEASE] Released version 2.8-dev7

Released version 2.8-dev7 with the following main changes :
    - BUG/MINOR: stats: Don't replace sc_shutr() by SE_FL_EOS flag yet
    - BUG/MEDIUM: mux-h2: Be able to detect connection error during handshake
    - BUG/MINOR: quic: Missing padding in very short probe packets
    - MINOR: proxy/pool: prevent unnecessary calls to pool_gc()
    - CLEANUP: proxy: remove stop_time related dead code
    - DOC/MINOR: reformat configuration.txt's "quoting and escaping" table
    - MINOR: http_fetch: Add support for empty delim in url_param
    - MINOR: http_fetch: add case insensitive support for smp_fetch_url_param
    - MINOR: http_fetch: Add case-insensitive argument for url_param/urlp_val
    - REGTESTS : Add test support for case insentitive for url_param
    - BUG/MEDIUM: proxy/sktable: prevent watchdog trigger on soft-stop
    - BUG/MINOR: backend: make be_usable_srv() consistent when stopping
    - BUG/MINOR: ssl: Remove dead code in cli_parse_update_ocsp_response
    - BUG/MINOR: ssl: Fix potential leak in cli_parse_update_ocsp_response
    - BUG/MINOR: ssl: ssl-(min|max)-ver parameter not duplicated for bundles in crt-list
    - BUG/MINOR: quic: Wrong use of now_ms timestamps (cubic algo)
    - MINOR: quic: Add recovery related information to "show quic"
    - BUG/MINOR: quic: Wrong use of now_ms timestamps (newreno algo)
    - BUG/MINOR: quic: Missing max_idle_timeout initialization for the connection
    - MINOR: quic: Implement cubic state trace callback
    - MINOR: quic: Adjustments for generic control congestion traces
    - MINOR: quic: Traces adjustments at proto level.
    - MEDIUM: quic: Ack delay implementation
    - BUG/MINOR: quic: Wrong rtt variance computing
    - MINOR: cli: support filtering on FD types in "show fd"
    - MINOR: quic: Add a fake congestion control algorithm named "nocc"
    - CI: run smoke tests on config syntax to check memory related issues
    - CLEANUP: assorted typo fixes in the code and comments
    - CI: exclude doc/{design-thoughts,internals} from spell check
    - BUG/MINOR: quic: Remaining useless statements in cubic slow start callback
    - BUG/MINOR: quic: Cubic congestion control window may wrap
    - MINOR: quic: Add missing traces in cubic algorithm implementation
    - BUG/MAJOR: quic: Congestion algorithms states shared between the connection
    - BUG/MINOR: ssl: Undefined reference when building with OPENSSL_NO_DEPRECATED
    - BUG/MINOR: quic: Remove useless BUG_ON() in newreno and cubic algo implementation
    - MINOR: http-act: emit a warning when a header field name contains forbidden chars
    - DOC: config: strict-sni allows to start without certificate
    - MINOR: quic: Add trace to debug idle timer task issues
    - BUG/MINOR: quic: Unexpected connection closures upon idle timer task execution
    - BUG/MINOR: quic: Wrong idle timer expiration (during 20s)
    - BUILD: quic: 32bits compilation issue in cli_io_handler_dump_quic()
    - BUG/MINOR: quic: Possible wrong PTO computing
    - BUG/MINOR: tcpcheck: Be able to expect an empty response
    - BUG/MEDIUM: stconn: Add a missing return statement in sc_app_shutr()
    - BUG/MINOR: stream: Fix test on channels flags to set clientfin/serverfin touts
    - MINOR: applet: Uninline appctx_free()
    - MEDIUM: applet/trace: Register a new trace source with its events
    - CLEANUP: stconn: Remove remaining debug messages
    - BUG/MEDIUM: channel: Improve reports for shut in co_getblk()
    - BUG/MEDIUM: dns: Properly handle error when a response consumed
    - MINOR: stconn: Remove unecessary test on SE_FL_EOS before receiving data
    - MINOR: stconn/channel: Move CF_READ_DONTWAIT into the SC and rename it
    - MINOR: stconn/channel: Move CF_SEND_DONTWAIT into the SC and rename it
    - MINOR: stconn/channel: Move CF_NEVER_WAIT into the SC and rename it
    - MINOR: stconn/channel: Move CF_EXPECT_MORE into the SC and rename it
    - MINOR: mux-pt: Report end-of-input with the end-of-stream after a read
    - BUG/MINOR: mux-h1: Properly report EOI/ERROR on read0 in h1_rcv_pipe()
    - CLEANUP: mux-h1/mux-pt: Remove useless test on SE_FL_SHR/SE_FL_SHW flags
    - MINOR: mux-h1: Report an error to the SE descriptor on truncated message
    - MINOR: stconn: Always ack EOS at the end of sc_conn_recv()
    - MINOR: stconn/applet: Handle EOI in the applet .wake callback function
    - MINOR: applet: No longer set EOI on the SC
    - MINOR: stconn/applet: Handle EOS in the applet .wake callback function
    - MEDIUM: cache: Use the sedesc to report and detect end of processing
    - MEDIUM: cli: Use the sedesc to report and detect end of processing
    - MINOR: dns: Remove the test on the opposite SC state to send requests
    - MEDIUM: dns: Use the sedesc to report and detect end of processing
    - MEDIUM: spoe: Use the sedesc to report and detect end of processing
    - MEDIUM: hlua/applet: Use the sedesc to report and detect end of processing
    - MEDIUM: log: Use the sedesc to report and detect end of processing
    - MEDIUM: peers: Use the sedesc to report and detect end of processing
    - MINOR: sink: Remove the tests on the opposite SC state to process messages
    - MEDIUM: sink: Use the sedesc to report and detect end of processing
    - MEDIUM: stats: Use the sedesc to report and detect end of processing
    - MEDIUM: promex: Use the sedesc to report and detect end of processing
    - MEDIUM: http_client: Use the sedesc to report and detect end of processing
    - MINOR: stconn/channel: Move CF_EOI into the SC and rename it
    - MEDIUM: tree-wide: Move flags about shut from the channel to the SC
    - MINOR: tree-wide: Simplifiy some tests on SHUT flags by accessing SCs directly
    - MINOR: stconn/applet: Add BUG_ON_HOT() to be sure SE_FL_EOS is never set alone
    - MINOR: server: add SRV_F_DELETED flag
    - BUG/MINOR: server/del: fix srv->next pointer consistency
    - BUG/MINOR: stats: properly handle server stats dumping resumption
    - BUG/MINOR: sink: free forward_px on deinit()
    - BUG/MINOR: log: free log forward proxies on deinit()
    - MINOR: server: always call ssl->destroy_srv when available
    - MINOR: server: correctly free servers on deinit()
    - BUG/MINOR: hlua: hook yield does not behave as expected
    - MINOR: hlua: properly handle hlua_process_task HLUA_E_ETMOUT
    - BUG/MINOR: hlua: enforce proper running context for register_x functions
    - MINOR: hlua: Fix two functions that return nothing useful
    - MEDIUM: hlua: Dynamic list of frontend/backend in Lua
    - MINOR: hlua_fcn: alternative to old proxy and server attributes
    - MEDIUM: hlua_fcn: dynamic server iteration and indexing
    - MEDIUM: hlua_fcn/api: remove some old server and proxy attributes
    - CLEANUP: hlua: fix conflicting comment in hlua_ctx_destroy()
    - MINOR: hlua: add simple hlua reference handling API
    - MINOR: hlua: fix return type for hlua_checkfunction() and hlua_checktable()
    - BUG/MINOR: hlua: fix reference leak in core.register_task()
    - BUG/MINOR: hlua: fix reference leak in hlua_post_init_state()
    - BUG/MINOR: hlua: prevent function and table reference leaks on errors
    - CLEANUP: hlua: use hlua_ref() instead of luaL_ref()
    - CLEANUP: hlua: use hlua_pushref() instead of lua_rawgeti()
    - CLEANUP: hlua: use hlua_unref() instead of luaL_unref()
    - MINOR: hlua: simplify lua locking
    - BUG/MEDIUM: hlua: prevent deadlocks with main lua lock
    - MINOR: hlua_fcn: add server->get_rid() method
    - MINOR: hlua: support for optional arguments to core.register_task()
    - DOC: lua: silence "literal block ends without a blank line" Sphinx warnings
    - DOC: lua: silence "Unexpected indentation" Sphinx warnings
    - BUG/MINOR: event_hdl: fix rid storage type
    - BUG/MINOR: event_hdl: make event_hdl_subscribe thread-safe
    - MINOR: event_hdl: global sublist management clarification
    - BUG/MEDIUM: event_hdl: clean soft-stop handling
    - BUG/MEDIUM: event_hdl: fix async data refcount issue
    - MINOR: event_hdl: normal tasks support for advanced async mode
    - MINOR: event_hdl: add event_hdl_async_equeue_isempty() function
    - MINOR: event_hdl: add event_hdl_async_equeue_size() function
    - MINOR: event_hdl: pause/resume for subscriptions
    - MINOR: proxy: add findserver_unique_id() and findserver_unique_name()
    - MEDIUM: hlua/event_hdl: initial support for event handlers
    - MINOR: hlua/event_hdl: per-server event subscription
    - EXAMPLES: add basic event_hdl lua example script
    - MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked
    - BUG/MINOR: http-ana: Don't switch message to DATA when waiting for payload
    - BUG/MINOR: quic: Possible crashes in qc_idle_timer_task()
    - MINOR: quic: derive first DCID from client ODCID
    - MINOR: quic: remove ODCID dedicated tree
    - MINOR: quic: remove address concatenation to ODCID
    - BUG/MINOR: mworker: unset more internal variables from program section
    - BUG/MINOR: errors: invalid use of memprintf in startup_logs_init()
    - MINOR: applet: Use unsafe version to get stream from SC in the trace function
    - BUG/MUNOR: http-ana: Use an unsigned integer for http_msg flags
    - MINOR: compression: Make compression offload a flag
    - MINOR: compression: Prepare compression code for request compression
    - MINOR: compression: Store algo and type for both request and response
    - MINOR: compression: Count separately request and response compression
    - MEDIUM: compression: Make it so we can compress requests as well.
    - BUG/MINOR: lua: remove incorrect usage of strncat()
    - CLEANUP: tcpcheck: remove the only occurrence of sprintf() in the code
    - CLEANUP: ocsp: do no use strpcy() to copy a path!
    - CLEANUP: tree-wide: remove strpcy() from constant strings
    - CLEANUP: opentracing: remove the last two occurrences of strncat()
    - BUILD: compiler: fix __equals_1() on older compilers
    - MINOR: compiler: define a __attribute__warning() macro
    - BUILD: bug.h: add a warning in the base API when unsafe functions are used
    - BUG/MEDIUM: listeners: Use the right parameters for strlcpy2().

2 years agoBUG/MEDIUM: listeners: Use the right parameters for strlcpy2().
Olivier Houchard [Sat, 8 Apr 2023 12:58:53 +0000 (14:58 +0200)] 
BUG/MEDIUM: listeners: Use the right parameters for strlcpy2().

When calls to strcpy() were replaced with calls to strlcpy2(), one of them
was replaced wrong, and the source and size were inverted. Correct that.

This should fix issue #2110.

2 years agoBUILD: bug.h: add a warning in the base API when unsafe functions are used
Willy Tarreau [Fri, 7 Apr 2023 12:57:13 +0000 (14:57 +0200)] 
BUILD: bug.h: add a warning in the base API when unsafe functions are used

Once in a while we introduce an sprintf() or strncat() function by
accident. These ones are particularly dangerous and must never ever
be used because the only way to use them safely is at least as
complicated if not more, than their safe counterparts. By redefining
a few of these functions with an attribute_warning() we can deliver a
message to the developer who is tempted to use them. This commit does
it for strcat(), strcpy(), strncat(), sprintf(), vsprintf(). More could
come later if needed, such as strtok() and maybe a few others, but these
are less common.

2 years agoMINOR: compiler: define a __attribute__warning() macro
Willy Tarreau [Fri, 7 Apr 2023 12:54:36 +0000 (14:54 +0200)] 
MINOR: compiler: define a __attribute__warning() macro

__attribute__((deprecated)) is convenient to discourage from using
something deprecated, but gcc >= 4.3 provides __attribute__((warning(x)))
that allows to display a specific warning if something is used. This is
particularly convenient to give indications when some API parts need to
be adapted. Let's just define it as a macro that falls back to the older
deprecated attribute when not available.

It's supported on clang 14 as well but works differently and errors
out when redefined (while the main purpose precisely is to add such a
redefinition). Thus instead on clang we use deprecated(msg) which is
OK. See https://github.com/llvm/llvm-project/issues/56519

2 years agoBUILD: compiler: fix __equals_1() on older compilers
Willy Tarreau [Fri, 7 Apr 2023 12:34:38 +0000 (14:34 +0200)] 
BUILD: compiler: fix __equals_1() on older compilers

It appeared that __has_attribute() doesn't work on gcc 4.4 and older
because the concatenation of __has_attribute##x isn't resolved as a one
before being passed to __equals_1() which immediately concatenates it to
comma_for_one. We first need to pass it through an extra layer to resolve
this name to a value. The new version was tested with gcc 4.2 to 11.3.

This may be backported though it's pretty minor.

2 years agoCLEANUP: opentracing: remove the last two occurrences of strncat()
Willy Tarreau [Fri, 7 Apr 2023 13:38:58 +0000 (15:38 +0200)] 
CLEANUP: opentracing: remove the last two occurrences of strncat()

In flt_ot_sample_to_str() there were two occurrences of strncat() which
are used to copy N chars from the source and append a zero. For the sake
of definitely getting rid of this nasty function let's replace them by
memcpy() instead. It's worth noting that the length test there appeared
to be incorrect as it didn't make provisions for the trailing zero,
unless the size argument doesn't take it into account (seems unlikely).
Nothing was changed regarding this. If the code was good, it still is,
otherwise if it was bad it still is. At least this is more obvious now
than when using a function that needs n+1 chars to work.

2 years agoCLEANUP: tree-wide: remove strpcy() from constant strings
Willy Tarreau [Fri, 7 Apr 2023 16:11:39 +0000 (18:11 +0200)] 
CLEANUP: tree-wide: remove strpcy() from constant strings

These ones are genenerally harmless on modern compilers because the
compiler checks them. While gcc optimizes them away without even
referencing strcpy(), clang prefers to call strcpy(). Nevertheless they
prevent from enabling stricter checks so better remove them altogether.
They were all replaced by strlcpy2() and the size of the destination
which is always known there.

2 years agoCLEANUP: ocsp: do no use strpcy() to copy a path!
Willy Tarreau [Fri, 7 Apr 2023 15:49:37 +0000 (17:49 +0200)] 
CLEANUP: ocsp: do no use strpcy() to copy a path!

strcpy() is quite nasty but tolerable to copy constants, but here
it copies a variable path into a node in a code path that's not
trivial to follow given that it takes the node as the result of
a tree lookup. Let's get rid of it and mention where the entry
is retrieved.

2 years agoCLEANUP: tcpcheck: remove the only occurrence of sprintf() in the code
Willy Tarreau [Fri, 7 Apr 2023 13:06:42 +0000 (15:06 +0200)] 
CLEANUP: tcpcheck: remove the only occurrence of sprintf() in the code

There's a single sprintf() in the whole code, in the "option smtpchk"
parser in tcpcheck.c. Let's turn it to a safer snprintf().

2 years agoBUG/MINOR: lua: remove incorrect usage of strncat()
Willy Tarreau [Fri, 7 Apr 2023 13:27:55 +0000 (15:27 +0200)] 
BUG/MINOR: lua: remove incorrect usage of strncat()

As every time strncat() is used, it's wrong, and this one is no exception.
Users often think that the length applies to the destination except it
applies to the source and makes it hard to use correctly. The bug did not
have an impact because the length was preallocated from the sum of all
the individual lengths as measured by strlen() so there was no chance one
of them would change in between. But it could change in the future. Let's
fix it to use memcpy() instead for strings, or byte copies for delimiters.

No backport is needed, though it can be done if it helps to apply other
fixes.

2 years agoMEDIUM: compression: Make it so we can compress requests as well.
Olivier Houchard [Wed, 5 Apr 2023 22:33:48 +0000 (00:33 +0200)] 
MEDIUM: compression: Make it so we can compress requests as well.

Add code so that compression can be used for requests as well.
New compression keywords are introduced :
"direction" that specifies what we want to compress. Valid values are
"request", "response", or "both".
"type-req" and "type-res" define content-type to be compressed for
requests and responses, respectively. "type" is kept as an alias for
"type-res" for backward compatibilty.
"algo-req" specifies the compression algorithm to be used for requests.
Only one algorithm can be provided.
"algo-res" provides the list of algorithm that can be used to compress
responses. "algo" is kept as an alias for "algo-res" for backward
compatibility.

2 years agoMINOR: compression: Count separately request and response compression
Olivier Houchard [Wed, 5 Apr 2023 22:33:01 +0000 (00:33 +0200)] 
MINOR: compression: Count separately request and response compression

Duplicate the compression counters, so that we have separate counters
for request and response compression.

2 years agoMINOR: compression: Store algo and type for both request and response
Olivier Houchard [Wed, 5 Apr 2023 15:32:36 +0000 (17:32 +0200)] 
MINOR: compression: Store algo and type for both request and response

Make provision for being able to store both compression algorithms and
content-types to compress for both requests and responses. For now only
the responses one are used.

2 years agoMINOR: compression: Prepare compression code for request compression
Olivier Houchard [Wed, 5 Apr 2023 14:25:57 +0000 (16:25 +0200)] 
MINOR: compression: Prepare compression code for request compression

Make provision for storing the compression algorithm and the compression
context twice, one for requests, and the other for responses. Only the
response ones are used for now.

2 years agoMINOR: compression: Make compression offload a flag
Olivier Houchard [Mon, 3 Apr 2023 20:22:24 +0000 (22:22 +0200)] 
MINOR: compression: Make compression offload a flag

Turn compression offload into a flag in struct comp, instead of using
an int just for it.

2 years agoBUG/MUNOR: http-ana: Use an unsigned integer for http_msg flags
Christopher Faulet [Thu, 6 Apr 2023 06:58:42 +0000 (08:58 +0200)] 
BUG/MUNOR: http-ana: Use an unsigned integer for http_msg flags

In the commit 2954bcc1e (BUG/MINOR: http-ana: Don't switch message to DATA
when waiting for payload), the HTTP message flags were extended and don't
fit anymore in an unsigned char. So, we must use an unsigned integer now. It
is not a big deal because there was already a 6-bytes hole in the structure,
just after the flags. Now, there are a 3-bytes hold before.

This patch should fix the issue #2105. It is 2.8-specific, no backport
needed.

2 years agoMINOR: applet: Use unsafe version to get stream from SC in the trace function
Christopher Faulet [Thu, 6 Apr 2023 06:48:16 +0000 (08:48 +0200)] 
MINOR: applet: Use unsafe version to get stream from SC in the trace function

When a trace message for an applet is dumped, if the SC exists, the stream
always exists too. There is no way to attached an applet to a health-check.
So, we can use the unsafe version __sc_strm() to get the stream.

This patch is related to #2106. Not sure it will be enough for
Coverity. However, there is no bug here.

2 years agoBUG/MINOR: errors: invalid use of memprintf in startup_logs_init()
Aurelien DARRAGON [Wed, 5 Apr 2023 14:18:40 +0000 (16:18 +0200)] 
BUG/MINOR: errors: invalid use of memprintf in startup_logs_init()

On startup/reload, startup_logs_init() will try to export startup logs shm
filedescriptor through the internal HAPROXY_STARTUPLOGS_FD env variable.

While memprintf() is used to prepare the string to be exported via
setenv(), str_fd argument (first argument passed to memprintf()) could
be non NULL as a result of HAPROXY_STARTUPLOGS_FD env variable being
already set.

Indeed: str_fd is already used earlier in the function to store the result
of getenv("HAPROXY_STARTUPLOGS_FD").

The issue here is that memprintf() is designed to free the 'out' argument
if out != NULL, and here we don't expect str_fd to be freed since it was
provided by getenv() and would result in memory violation.

To prevent any invalid free, we must ensure that str_fd is set to NULL
prior to calling memprintf().

This must be backported in 2.7 with eba6a54cd4 ("MINOR: logs: startup-logs
can use a shm for logging the reload")

2 years agoBUG/MINOR: mworker: unset more internal variables from program section
William Lallemand [Wed, 5 Apr 2023 13:50:57 +0000 (15:50 +0200)] 
BUG/MINOR: mworker: unset more internal variables from program section

People who use HAProxy as a process 1 in containers sometimes starts
other things from the program section. This is still not recommend as
the master process has minimal features regarding process management.

Environment variables are still inherited, even internal ones.

Since 2.7, it could provoke a crash when inheriting the
HAPROXY_STARTUPLOGS_FD variable.

Note: for future releases it should be better to clean the env and sets
a list of variable to be exported. We need to determine which variables
are used by users before.

Must be backported in 2.7.

2 years agoMINOR: quic: remove address concatenation to ODCID
Amaury Denoyelle [Wed, 5 Apr 2023 07:50:17 +0000 (09:50 +0200)] 
MINOR: quic: remove address concatenation to ODCID

Previously, ODCID were concatenated with the client address. This was
done to prevent a collision between two endpoints which used the same
ODCID.

Thanks to the two previous patches, first connection generated CID is
now directly derived from the client ODCID using a hash function which
uses the client source address from the same purpose. Thus, it is now
unneeded to concatenate client address to <odcid> quic-conn member.

This change allows to simplify the quic_cid structure management and
reduce its size which is important as it is embedded several times in
various structures such as quic_conn and quic_rx_packet.

This should be backported up to 2.7.

2 years agoMINOR: quic: remove ODCID dedicated tree
Amaury Denoyelle [Mon, 3 Apr 2023 16:50:58 +0000 (18:50 +0200)] 
MINOR: quic: remove ODCID dedicated tree

First connection CID generation has been altered. It is now directly
derived from client ODCID since previous commit :
  commit 162baaff7ab761c411800f4ca6bef45315d7afcb
  MINOR: quic: derive first DCID from client ODCID

This patch removes the ODCID tree which is now unneeded. On connection
lookup via CID, if a DCID is not found the hash derivation is performed
for an INITIAL/0-RTT packet only. In case a client has used multiple
times an ODCID, this will allow to retrieve our generated DCID in the
CID tree without storing the ODCID node.

The impact of this two combined patch is that it may improve slightly
haproxy memory footprint by removing a tree node from quic_conn
structure. The cpu calculation induced by hash derivation should only be
performed only a few times per connection as the client will start to
use our generated CID as soon as it received it.

This should be backported up to 2.7.

2 years agoMINOR: quic: derive first DCID from client ODCID
Amaury Denoyelle [Mon, 3 Apr 2023 16:49:39 +0000 (18:49 +0200)] 
MINOR: quic: derive first DCID from client ODCID

Change the generation of the first CID of a connection. It is directly
derived from the client ODCID using a 64-bits hash function. Client
address is added to avoid collision between clients which could use the
same ODCID.

For the moment, this change as no functional impact. However, it will be
directly used for the next commit to be able to remove the ODCID tree.

This should be backported up to 2.7.

2 years agoBUG/MINOR: quic: Possible crashes in qc_idle_timer_task()
Frédéric Lécaille [Wed, 5 Apr 2023 07:44:21 +0000 (09:44 +0200)] 
BUG/MINOR: quic: Possible crashes in qc_idle_timer_task()

This is due to this commit:

    MINOR: quic: Add trace to debug idle timer task issues

where has been added without having been tested at developer level.
<qc> was dereferenced after having been released by qc_conn_release().

Set qc to NULL value after having been released to forbid its dereferencing.
Add a check for qc->idle_timer_task in the traces added by the mentionned
commit above to prevent its dereferencing if NULL.
Take the opportunity of this patch to modify trace events from
QUIC_EV_CONN_SSLALERT to QUIC_EV_CONN_IDLE_TIMER.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: http-ana: Don't switch message to DATA when waiting for payload
Christopher Faulet [Wed, 5 Apr 2023 08:42:03 +0000 (10:42 +0200)] 
BUG/MINOR: http-ana: Don't switch message to DATA when waiting for payload

The HTTP message must remains in BODY state during the analysis, to be able
to report accurate termination state in logs. It is also important to know
the HTTP analysis is still in progress. Thus, when we are waiting for the
message payload, the message is no longer switch to DATA state. This was
used to not process "Expect: " header at each evaluation. But thanks to the
previous patch, it is no long necessary.

This patch also fixes a bug in the lua filter api. Some functions must be
called during the message analysis and not during the payload forwarding. It
is not valid to try to manipulate headers during the forward stage because
headers are already forwarded. We rely on the message state to detect
errors. So the api was unusable if a "wait-for-body" action was used.

This patch shoud fix the issue #2093. It relies on the commit:

  * MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked

Both must be backported as far as 2.5.

2 years agoMINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked
Christopher Faulet [Wed, 5 Apr 2023 08:33:31 +0000 (10:33 +0200)] 
MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked

HTTP_MSGF_EXPECT_CHECKED is now set on the request message to know the
"Expect: " header was already handled, if any. The flag is set from the
moment we try to handle the header to send a "100-continue" response,
whether it was found or not.

This way, when we are waiting for the request payload, thanks to this flag,
we only try to handle "Expect: " header only once. Before it was performed
by changing the message state from BODY to DATA. But this has some side
effects and it is no accurate. So, it is better to rely on a flag to do so.

2 years agoEXAMPLES: add basic event_hdl lua example script
Aurelien DARRAGON [Fri, 17 Mar 2023 18:50:35 +0000 (19:50 +0100)] 
EXAMPLES: add basic event_hdl lua example script

For now: basic server event handling from lua, events are printed to
STDOUT.

The idea behind this is to provide simple and easy-to-use examples
that serve as a basic introduction for lua event handler feature.

2 years agoMINOR: hlua/event_hdl: per-server event subscription
Aurelien DARRAGON [Fri, 10 Mar 2023 14:34:35 +0000 (15:34 +0100)] 
MINOR: hlua/event_hdl: per-server event subscription

Now that event_hdl api is properly implemented in hlua, we may add the
per-server event subscription in addition to the global event
subscription.

Per-server subscription allows to be notified for events related to
single server. It is useful to track a server UP/DOWN and DEL events.

It works exactly like core.event_sub() except that the subscription
will be performed within the server dedicated subscription list instead
of the global one.
The callback function will only be called for server events affecting
the server from which the subscription was performed.

Regarding the implementation, it is pretty trivial at this point, we add
more doc than code this time.

Usage examples have been added to the (lua) documentation.

2 years agoMEDIUM: hlua/event_hdl: initial support for event handlers
Aurelien DARRAGON [Mon, 20 Feb 2023 17:18:59 +0000 (18:18 +0100)] 
MEDIUM: hlua/event_hdl: initial support for event handlers

Now that the event handler API is pretty mature, we can expose it in
the lua API.

Introducing the core.event_sub(<event_types>, <cb>) lua function that
takes an array of event types <event_types> as well as a callback
function <cb> as argument.

The function returns a subscription <sub> on success.
Subscription <sub> allows you to manage the subscription from anywhere
in the script.
To this day only the sub->unsub method is implemented.

The following event types are currently supported:
  - "SERVER_ADD": when a server is added
  - "SERVER_DEL": when a server is removed from haproxy
  - "SERVER_DOWN": server states goes from up to down
  - "SERVER_UP": server states goes from down to up

As for the <cb> function: it will be called when one of the registered
event types occur. The function will be called with 3 arguments:
  cb(<event>,<data>,<sub>)

<event>: event type (string) that triggered the function.
(could be any of the types used in <event_types> when registering
the subscription)

<data>: data associated with the event (specific to each event family).

For "SERVER_" family events, server details such as server name/id/proxy
will be provided.
If the server still exists (not yet deleted), a reference to the live
server is provided to spare you from an additionnal lookup if you need
to have direct access to the server from lua.

<sub> refers to the subscription. In case you need to manage it from
within an event handler.
(It refers to the same subscription that the one returned from
core.event_sub())

Subscriptions are per-thread: the thread that will be handling the
event is the one who performed the subscription using
core.event_sub() function.

Each thread treats events sequentially, it means that if you have,
let's say SERVER_UP, then SERVER_DOWN in a short timelapse, then your
cb function will first be called with SERVER_UP, and once you're done
handling the event, your function will be called again with SERVER_DOWN.

This is to ensure event consitency when it comes to logging / triggering
logic from lua.

Your lua cb function may yield if needed, but you're pleased to process
the event as fast as possible to prevent the event queue from growing up

To prevent abuses, if the event queue for the current subscription goes
over 100 unconsumed events, the subscription will pause itself
automatically for as long as it takes for your handler to catch up.
This would lead to events being missed, so a warning will be emitted in
the logs to inform you about that. This is not something you want to let
happen too often, it may indicate that you subscribed to an event that
is occurring too frequently or/and that your callback function is too
slow to keep up the pace and you should review it.

If you want to do some parallel processing because your callback
functions are slow: you might want to create subtasks from lua using
core.register_task() from within your callback function to perform the
heavy job in a dedicated task and allow remaining events to be processed
more quickly.

Please check the lua documentation for more information.