25093 Commits

Author SHA1 Message Date
Christopher Faulet
75e8c8ed33 BUG/MINOR: cli: Fix a possible infinite loop in _getsocks()
In _getsocks() functuoin, when we failed to set the unix socket in
non-blocking mode, a goto to "out" label led to loop infinitly. To fix the
issue, we must only let the function exit.

This patch should be backported to all stable versions.
2025-02-06 15:44:21 +01:00
Christopher Faulet
372cc696d4 BUG/MINOR: cli: Fix memory leak on error for _getsocks command
Some errors in parse function of _getsocks commands were not properly handled
and immediately returned, leading to a memory leak on cmsgbuf and tmpbuf
buffers.

To fix the issue, instead of immediately return with -1, we jump to "out"
label. Returning 1 intead of -1 in that case is valid.

This was reported by Coverity in #2841: CIDs 1587773 and 1587772.

This patch should be backported as far as 2.4.
2025-02-06 15:43:04 +01:00
Christopher Faulet
7e927243b9 BUG/MINOR: cli: Don't set SE flags from the cli applet
Since the CLI was updated to use the new applet API, it should no longer set
directly the SE flags. Instead, the corresponding applet flags must be set,
using the applet API (appet_set_*). It is true for the CLI I/O handler but also
for the commands parse function and I/O callback function.

This patch should be backported as far as 3.0.
2025-02-06 15:23:20 +01:00
Christopher Faulet
0aa69e7865 MINOR: mux-spop/mux-fcgi: Add support of the debug string for logs
Now it is possible to have debug info about FCGI and SPOP multiplexers. To do
so, the support for the MUX_SCTL_DBG_STR command was implemented for these
muxes.

The have this log message, the log-format must be set to:

  log-format "$HAPROXY_HTTP_LOG_FMT bs=<%[bs.debug_str]>"
2025-02-06 11:19:32 +01:00
Christopher Faulet
456cfa450a MINOR: mux-fcgi: Dump info about connections and streams in dedicated functions
fcgi_show_fd() function was splitted to dump the info about the FCGI
connections and the FCGI streams in dedicated functions, duplicating this
way what is performed in other muxes.

In addition, the FCGI multiplexer now implements the .show_sd callback
function called by "show sess" CLI command.
2025-02-06 11:19:32 +01:00
Christopher Faulet
bbc8c98a54 MINOR: tevt/mux-fcgi: Report termination events for the FCGI connect/stream
Termination events are now reported for the FCGI connections and the FCGI
streams. In addition, all available termination events logs are reported in
the "show-fd" callback function. The .ctl and .sctl callback functions were
also update to support, respectively, MUX_CTL_TEVTS and MUX_SCTL_TEVTS
commands.
2025-02-06 11:19:32 +01:00
Christopher Faulet
5b1c2277ae BUG/MEDIUM: mux-fcgi: Propagate flags to SE in fcgi_strm_wake_one_stream
The commit is flagged as a bug because the same fix on the H2 multiplexer was
reported as a bug. But no issue was reported.

When a stream is explicitly woken up by the FCGI conneciton, if an error
condition is detected, the corresponding error flag is set on the SE. So
SE_FL_ERROR or SE_FL_ERR_PENDING, depending if the end of stream was
reported or not.

However, there is no attempt to propagate other termination flags. We must
be sure to properly set SE_FL_EOI and SE_FL_EOS when appropriate to be able
to switch a pending error to a fatal error.

Because of this bug, the SE could remain with a pending error and no end of
stream, preventing the applicative stream to trully abort it. It means on
some abort scenario, it seems to be possible to block a stream infinitely.

This patche depends on:

  * MEDIUM: mux-fcgi: Add a function to propagate termination flags from fstrm to SE
  * BUG/MEDIUM: mux-fcgi: Properly handle read0 on partial records

This patch could be backported at least as far as 2.8 after a period of
observation. However no bug was reportedn so there is no rush.
2025-02-06 11:19:32 +01:00
Christopher Faulet
ccdca4bb77 MEDIUM: mux-fcgi: Add a function to propagate termination flags from fstrm to SE
The function fcgi_strm_propagate_term_flags() was added to check the FSTRM
state and evaluate when EOI/EOS/ERR_PENDING/ERROR flags must be set on the
SE. It is not the only place where those flags are set. But it centralizes
the synchro between the FCGI stream and the SC.

For now, this function is only used at the end of fcgi_rcv_buf(). But it
will be used to fix a potential bug.
2025-02-06 11:19:32 +01:00
Christopher Faulet
7b638eb1a6 MINOR: mux-spop: Implement .show_sd callback function
The SPOP multiplexer now implements the .show_sd callback function called by
"show sess" CLI command.
2025-02-06 11:19:32 +01:00
Christopher Faulet
5aeb678762 MINOR: mux-spop: Dump info about connections and streams in dedicated functions
spop_show_fd() function was splitted to dump the info about the SPOP
connections and the SPOP streams in dedicated functions, duplicating this
way what is performed in other muxes.
2025-02-06 11:19:32 +01:00
Christopher Faulet
eb4e517489 CLEANUP: mux-spop: Remove useless comments
Just a small cleanup to remove some comments added during the development of
the mux.
2025-02-06 11:19:32 +01:00
Christopher Faulet
4f8ae5b1f6 MINOR: tevt/mux-spop: Report termination events for the SPOP connect/stream
Termination events are now reported for the SPOP connections and the SPOP
streams. In addition, all available termination events logs are reported in
the "show-fd" callback function. The .ctl and .sctl callback functions were
also update to support, respectively, MUX_CTL_TEVTS and MUX_SCTL_TEVTS
commands.
2025-02-06 11:19:32 +01:00
Christopher Faulet
514a912a4d MINOR: mux-spop: Set SPOP_CF_ERROR flag on connection error only
The SPOP_CF_ERROR flag is now set on connection error only. It was also set
on some demux failures. But it is not mandatory because the connection is
closed anyway. And it is handy to have a flag dedicated to tcp connection
error. It was the original purpose of this flag.

This patch could be backported to 3.1 to ease future backports.
2025-02-06 11:19:32 +01:00
Christopher Faulet
d16c534511 MINOR: mux-spop: Report EOI on the SE when a ACK is received for a stream
The spop stream now reports the end of input when the ACK is transferred to
the SPOE applet. To do so, the flag SPOP_SF_ACK_RCVD was added. It is set on
the SPOP stream when its ACK is received by the SPOP connection.

In addition when SPOP stream flags are propagated to the SE, the error is
now reported if end of input was not reached instead of testing the
connection error code. It is more accurate.

This patch should be backported to 3.1.
2025-02-06 11:19:32 +01:00
Christopher Faulet
f7e5718596 MINOR: flt-spoe: Report end of input immediately after applet init
The SPOE applet forwards the message that must be sent to agent during its
init stage. So just after it is created. When it is performed, the end of
input must be reported because no more data will be forwarded. However, it
was performed after receiving the ACK response. It is harmless, but there is
no reason to delay the EOI. It is now fixed.

This patch must be backported to 3.1.
2025-02-06 11:19:32 +01:00
Christopher Faulet
38aac2c7bc BUG/MEDIUM: flt-spoe: Properly handle end of stream from the SPOE applet
The previous fix ("BUG/MEDIUM: applet: Don't pretend to have more data to
handle EOI/EOS/ERROR") revealed an issue with the way the SPOE applet was
reporting the end of stream, leading to never shut the applet down.

In fact, there is two bug in one. The first one is about the applet
shutdown. Since the fix above, the applet is no longer closed. Before, it
was closed because it was reported in error. But now, it is just delayed
because the applet and the SPOP stream are declared to support half close
connections. So the applet is only closed when the SPOP connection is
closed. To fix this bug, both side are now stating that half close
connections are not supported.

The second bug is about the way the end of stream is reported. It is
reported when the ACK response is received. But it is too early, because the
parent stream must process the response first. So now, we take care to have
processed the ACK from the parent applet before reporting an end of stream.

This patch must be backported with the commit above to 3.1.
2025-02-06 11:19:32 +01:00
Christopher Faulet
7214dcd52d BUG/MEDIUM: applet: Don't pretend to have more data to handle EOI/EOS/ERROR
The way appctx EOI/EOS/ERROR flags were reported for applets using the new
API were to state the applet had more data to deliver. But it was not
correct and for APPCTX_FL_EOS, this led to report an error on the SE because
it is not expected. More data to deliver and an end of stream is an
impossible situation.

This was added as a fix by commit b8ca114031 ("BUG/MEDIUM: applet: State
appctx have more data if its EOI/EOS/ERROR flag is set"), mainly to make the
SPOE applet work.

When an applet set one of these flags, it really means it has no more data
to deliver. So we must not try to trigger a new receive to handle these
flags. Instead we must handle them directly in task_process_applet()
function and only if the corresponding SE flags were not already set.

This patch must be backported to 3.1.
2025-02-06 11:19:32 +01:00
Christopher Faulet
db504fbdbe BUG/MEDIUM: flt-spoe: Set/test applet flags instead of SE flags from I/O handler
The SPOE applet is using the new applet API. Thus end of input, end of
stream and errors must be reported using the applet flags, not the SE
flags. This was not the case. So let's fix it.

It seems this bug is harmless for now.

This patch must be backported to 3.1.
2025-02-06 11:19:32 +01:00
Christopher Faulet
54a09dfe0f BUG/MINOR: tevt/mux-h2: Set truncated receive/eos events at SE level on error
When receive or EOS termination events are reported at the SE level, a
truncation was erroneously reported when no error was detected. Of course, it
must be the opposite.

No backport needed.
2025-02-06 11:19:32 +01:00
Frederic Lecaille
85cb1cc7f4 BUILD: ssl: remove a boringssl definition defined by recent boringssl libs
This is the case for AWS-LC which derives from boringssl, where
X509_OBJECT_get0_X509_CRL() is already defined. There is definitively
no more need to define this function to build haproxy against TLS libs derived
from boringssl.
2025-02-06 10:48:25 +01:00
Christopher Faulet
fad68cb16d BUG/MINOR: http-check: Don't pretend a C-L heeader is set before adding it
When a GET/HEAD/OPTIONS/DELETE healthcheck request was formatted, we claimed
there was a "content-length" header set even when there was no payload,
leading to actually send a "content-length: 0" header to the server. It was
unexpected and could be rejected by servers.

When a healthcheck request is sent we must take care to state there is a
"content-length" header when it is explicitly added.

This patch should fix the issue #2851. It must be backported as far as 2.9.
2025-02-03 18:46:41 +01:00
Aurelien DARRAGON
0846638f7f MEDIUM: stream: interrupt costly rulesets after too many evaluations
It is not rare to see configurations with a large number of "tcp-request
content" or "http-request" rules for instance. A large number of rules
combined with cpu-demanding actions (e.g.: actions that work on content)
may create thread contention as all the rules from a given ruleset are
evaluated under the same polling loop if the evaluation is not interrupted

Thus, in this patch we add extra logic around "tcp-request content",
"tcp-response content", "http-request" and "http-response" rulesets, so
that when a certain number of rules are evaluated under the single polling
loop, we force the evaluating function to yield. As such, the rule which
was about to be evaluated is saved, and the function starts evaluating
rules from the save pointer when it returns (in the next polling loop).

We use task_wakeup(task, TASK_WOKEN_MSG) to explicitly wake the task so
that no time is wasted and the processing is resumed ASAP. TASK_WOKEN_MSG
is mandatory here because process_stream() expects TASK_WOKEN_MSG for
explicit analyzers re-evaluation.

rules_bcount stream's attribute was added to count how manu rules were
evaluated since last interruption (yield). Also, SF_RULE_FYIELD flag
was added to know that the s->current_rule was assigned due to forced
yield and not regular yield.

By default haproxy will enforce a yield every 50 rules, this behavior
can be configured using the "tune.max-rules-at-once" global keyword.

There is a limitation though: for now, if the ACT_OPT_FINAL flag is set
on act_opts, we consider it is not safe to yield (as it is already the
case for automatic yield). In this case instead of yielding an taking
the risk of not being called back, we skip the yield and hope it will
not create contention. This is something we should ideally try to
improve in order to yield in all conditions.
2025-02-03 17:09:48 +01:00
Christopher Faulet
04bbfa4354 BUG/MINOR: tcp-rules: Don't forward close during tcp-response content rules eval
When the tcp-response content ruleset evaluation is delayed because of an
ACL condition, the close forwarding on the client side is not explicitly
blocked. So it is possible to close the client side before the end of the
response evaluation.

To fix the issue, this is now done in all cases where some data are
missing. Concretely, channel_dont_close() is called in "missing_data" goto
label.

Note it is only a theorical bug (or pending bug). It is not possible to
trigger it for now because an ACL cannot wait for more data when a close was
received. But the code remains a bit weak. It is safer this way. It is
especially mandatory for the "force yield" option that should be added soon.

This patch could be backported to all stable versions.
2025-02-03 15:31:59 +01:00
Christopher Faulet
431c5533b7 DEBUG: mux-h1: Remove some debug counters
Several debug counters were added to debug a strange issue about early
aborts. Most of them are now useless, especially because it is now possible
to rely on the termination events logs. So, it is better to remove them.

Note that these counters are still there in 3.1.
2025-02-03 08:48:31 +01:00
Christopher Faulet
1c6512f8fc DEBUG: http-ana: Remove debug counters from HTTP analyzers
Several debug counters were added in HTTP analyzers to help debugging a
strange issue about early aborts. But these counters are a bit overkill
now. Especially because it is now possible to rely on the termination event
log. So just remove them.

Note that these counters are still there in 3.1.
2025-02-03 08:28:45 +01:00
Christopher Faulet
274c9d21a6 BUG/MINOR: tevt/http-ana: Remove badly placed event reports
When specific events for the stream location were added, some reports about
message interception were not removed. These reports are now removed.

No need to backport.
2025-02-03 08:20:41 +01:00
Christopher Faulet
5f927f603a BUG/MEDIUM: mux-fcgi: Properly handle read0 on partial records
A Read0 event could be ignored by the FCGI multiplexer if it is blocked on a
partial record. Instead of handling the event, it remained blocked, waiting
for the end of the record.

To fix the issue, the same solution than the H2 multiplexer is used. Two
flags are introduced. The first one, FCGI_CF_END_REACHED, is used to
acknowledge a read0. This flag is set when a read0 was received AND the FCGI
multiplexer must handle it. The second one, FCGI_CF_DEM_SHORT_READ, is set
when the demux is interrupted on a partial record. A short read and a read0
lead to set the FCGI_CF_END_REACHED flag.

With these changes, the FCGI mux should be able to properly handle read0 on
partial records.

This patch should be backported to all stable versions after a period of
observation.
2025-02-03 07:49:50 +01:00
William Lallemand
0a28b1ea0c MEDIUM: htx: prevent <mark> to copy incomplete headers in htx_xfer_blks()
Prevent a partial copy of trailers or headers when using the <mark>
parameter.

When using htx_xfer_blks(), transfering partial headers or trailers are
prevented when restricted by the <count> parameter. However using the
<mark> parameter will still allow to do it.

This patch changes the behavior by checking the <mark> type only after
checking the headers/trailers type, so we can still rollback on partial
transfer.

No impact on the current code, which does not try to do that yet.
2025-01-31 15:51:51 +01:00
Amaury Denoyelle
4ad2accfee BUILD: quic: remove GCC undefined error in qc_release_lost_pkts()
Every once in a while, GCC reports issues with qc_release_lost_pkts()
function. It seems that its static analysis is foiled by the code
structuring. The latest warning reports the following issue :

  CC      src/quic_loss.o
src/quic_loss.c: In function ‘qc_release_lost_pkts’:
src/quic_loss.c:313:58: error: potential null pointer dereference [-Werror=null-dereference]
  313 |                         unsigned int period = newest_lost->time_sent_ms - oldest_lost->time_sent_ms;
      |                                               ~~~~~~~~~~~^~~~~~~~~~~~~~

To fix definitely this, change slightly the code. <oldest_lost> and
<newest_lost> are now initialized on the first list entry outside of the
loop. This is enough to guarantee to GCC that they cannot be NULL for
the remainder of the function.
2025-01-31 15:34:30 +01:00
William Lallemand
c17e029232 DOC: htx: clarify <mark> parameter for htx_xfer_blks()
Clarify the fact that the first <mark> block is transferred before
stopping when using htx_xfer_blks()
2025-01-31 15:23:47 +01:00
William Lallemand
c6390cdf9c BUG/MEDIUM: htx: wrong count computation in htx_xfer_blks()
When transfering blocks from an src to another dst htx representation,
htx_xfer_blks() decreases the size of each block removed from the <count>
value passed in parameter, so it can't transfer more than <count>. The
size must also contains the metadata, represented by a simple
sizeof(struct htk_blk).

However, the code was doing a sizeof(dstblk) instead of a
sizeof(*dstblk) which as the consequence of removing only a size_t from
count. Fortunately htx_blk size is 64bits, so that does not provoke any
problem in 64bits. But on 32bits architecture, the count value is not
decreased correctly and the function could try to transfer more blocks
than allowed by the count parameter.

Must be backported in every stable release.
2025-01-31 15:02:58 +01:00
Christopher Faulet
956cb5d554 MINOR: tevt/dev: Parse tuple of termination events
term_events tool is now able to parse tuple of termination events, as returned
by "term_events" sample fetch function.
2025-01-31 10:46:08 +01:00
Christopher Faulet
71320fc9c1 MINOR: tevt/connection: Add support for POLL_HUP/POLL_ERR events
Connection errors can be detected via connect/recv/send syscall, but also
because it was reported by the poller. So dedicated events, at the FD level,
are introduced to make the difference.

term_events tool was updated accordingly.
2025-01-31 10:41:50 +01:00
Christopher Faulet
c7457427ab MINOR: tevt/dev: Add term_events tool
This development tool can be used to convert a string representing a
termination event logs to its human redable representation. Several string
may be converting at a time. To do so, several arguments can be specified on
the commeand line or they can be provided on STDIN, using "-" argument.

Here is an exemple:

  > term_events f2x2f4x4 m2m4m1 e2e1 s2s1S1 E1 M1 F1
  ### f2x2f4x4 : fd:shutr > xprt:shutr > fd:snd_err > xprt:snd_err
  ### m2m4m1   : muxc:shutr > muxc:snd_err > muxc:shutw
  ### e2e1     : se:eos > se:shutw
  ### s2s1S1   : strm:eos > strm:shutw > STRM:shutw
  ### E1       : SE:shutw
  ### M1       : MUXC:shutw
  ### F1       : FD:shutw

The make target "dev/term_events/term_events" must be used to compile it.
2025-01-31 10:41:50 +01:00
Christopher Faulet
990854ee0d REORG: tevt/connection: Move enums at the end of the header file
Enums used to report events were placed in the connection header for
conveniance. But it is not specifically related to connection. So, they are
moved at the end of the file to have a better isolation.
2025-01-31 10:41:50 +01:00
Christopher Faulet
487d6b09f1 MINOR: tevt: Improve function to convert a termination events log to string
The function is now responsible to handle empty log because no event was
reported. In that case, an empty string is returned. It is also responsible to
handle case where termination events log is not supported for an given entity
(for instance the quic mux for now). In that case, a dash ("-") is returned.
2025-01-31 10:41:50 +01:00
Christopher Faulet
b161155498 MINOR: tevt: Add a sample to get termination events for all locations
"term_events" is a sample fetche function that can be used to get
termination events for all locations in one call. The format equivalent to:

  {fc_term_events,fc_mux_term_events,fs.term_events,txn.term_events,bs.term_events,bc_mux_term_events,bc_term_events}

If no event was reported for a location, the field is empty. If the feature
is not supported yet, a dash ('-') is printed.
2025-01-31 10:41:50 +01:00
Christopher Faulet
eb2f1a4ba4 MINOR: tevt/applet: Add limited support for termination event logs for applets
There is no termination events log for applet but events for the SE location
are filled when the endpoint is an applet. Most of them relies on the new
applet API. Only few events are reported for legacy applets.
2025-01-31 10:41:50 +01:00
Christopher Faulet
cbd898c42b MINOR: tevt: Don't duplicate termination event during reporting
It is hard to never detect the same event several time without painful
tests. In other words, the same termination event can be reported several
time and this must be handled. To do so, "tevt_report_event" macro is
updated to ignore an event if the last reported one is of the same type, for
the same location. Of course, if the same event is reported several times at
different moment, it will not be detected.
2025-01-31 10:41:50 +01:00
Christopher Faulet
2dc02f75b1 MEDIUM: tevt/stconn/stream: Add dedicated termination events for stream location
If it is the last patch to introduce dedicated termination events for each
location. In this one, events for the stream location are introcued. The old
enum is also removed because it is now unused.

Here, more accurate evets are added. The "intercepted" event was splitted.
2025-01-31 10:41:50 +01:00
Christopher Faulet
9697704932 MINOR: tevt/stconn: Be more accurate to report shutw events
In se_shutdown() a SE termination event is reported while the shutw stream
event is reported in sc_app_shut_conn().
2025-01-31 10:41:50 +01:00
Christopher Faulet
a58e650ad1 MEDIUM: tevt/muxes: Add dedicated termination events for muxc/se locations
Termination events dedicated to mux connection and stream-endpoint
descriptors are added in this patch. Specific events to these locations are
thus added. Changes for the H1 and H2 multiplexers are reviewed to be more
accurate.
2025-01-31 10:41:50 +01:00
Christopher Faulet
f2778ccc7d MINOR: tevt/connection: Add dedicated termination events for lower locations
To be able to add more accurate termination events for each location, the
enum will be splitted by location. Indeed, there are at most 16 possbile
events. It will be pretty confusing to use same termination events for the
different locations. So the best is to split them.

In this patch, the termination events for the fd, hs and xprt locations are
introduced. For now some holes are added to keep similar events aligned
across enums. But this may change in future.
2025-01-31 10:41:50 +01:00
Christopher Faulet
9cbc3229ec MINOR: tevt/mux-pt: Add support for termination event logs
A termination event logs is added to the mux-pt context and appropriate
events are reported for the muxc location. There is no SE events for this
mux.
2025-01-31 10:41:50 +01:00
Christopher Faulet
a4c281a190 MINOR: tevt/muxes: Add CTL and SCTL command to get the termination event logs
MUX_CTL_TEVTS command is added to get the termination event logs of a mux
connection and MUX_SCTL_TEVTS command to get the termination event logs of a
mux stream.
2025-01-31 10:41:50 +01:00
Christopher Faulet
95029305d3 MINOR: tevt/mux-h1/mux-h2: Add termination events log when dumping mux info
The termiantion events logs of the multiplexer connection and stream are now
dumped when corresponding mux info are dumped. The termination event logs of
the underlying connection is also dumped in the debug string.
2025-01-31 10:41:50 +01:00
Christopher Faulet
170d46989c MINOR: tevt/conn: Report intercepted event for L4 rules
When a L4 rules interrupts the processing, a termination event is reported
for the connection, with the "fd" location.
2025-01-31 10:41:50 +01:00
Christopher Faulet
00a07c8b54 MINOR: tevt/stream/stconn: Report termination events for stream and sc
In this patch, events for the stream location are reported. These events are
first reported on the corresponding stream-connector. So front events on scf
and back event on scb. Then all events are both merged in the stream. But
only 4 events are saved on the stream.

Several internal events are for now grouped with the type
"tevt_type_intercepted". More events will be added to have a better
resolution. But at least the place to report these events are identified.

For now, when a event is reported on a SC, it is also reported on the stream
and vice versa.
2025-01-31 10:41:50 +01:00
Christopher Faulet
147b6d3d4d MINOR: tevt/mux-h2: Report termination events for the H2C
shutdown for reads (read0), receive errors, shutdown for writes and timeouts
are reported, but only for the H2 connection for now.

As for the H1 multiplexer, more events must be added to report protocol
errors, goaways and rst-streams. And of course, all events for the H2
streams must be reported too.
2025-01-31 10:41:50 +01:00
Christopher Faulet
5f03261166 MINOR: tevt/mux-h1: Report termination events for the H1C and H1S
shutdown for reads (read0), receive errors, shutdown for writes and timeouts
are reported. It is not too hard to know where to report events generated by
HAProxy (timeouts and shutw). For detected events (shutr and receive error),
it is not so simple. These events must not be reported when they are
detected but when the mux can handle them. For instance, some unprocessed
input data may block a read0. So, the experience will tell us if these
events are reported at the rigth time and on the right conditions.

For now, no internal errors (parsing errors, protocol errors, intenral
errors...) are reported because these event types have not yet been added.
2025-01-31 10:41:50 +01:00