]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoMINOR: stream: add "last_rule_file" and "last_rule_line" samples
Willy Tarreau [Wed, 9 Mar 2022 16:33:05 +0000 (17:33 +0100)] 
MINOR: stream: add "last_rule_file" and "last_rule_line" samples

These two sample fetch methods report respectively the file name and the
line number where was located the last rule that was final. This is aimed
at being used on log-format lines to help admins figure what rule in the
configuration gave a final verdict, and help understand the condition
that led to the action.

For example, it's now possible to log the last matched rule by adding
this to the log-format:

  ... lr=%[last_rule_file]:%[last_rule_line]

A regtest is provided to test various combinations of final rules, some
even on top of each other from different rulesets.

3 years agoMINOR: rules: record the last http/tcp rule that gave a final verdict
Willy Tarreau [Wed, 9 Mar 2022 16:23:10 +0000 (17:23 +0100)] 
MINOR: rules: record the last http/tcp rule that gave a final verdict

When a tcp-{request,response} content or http-request/http-response
rule delivers a final verdict (deny, accept, redirect etc), the last
evaluated one will now be recorded in the stream. The purpose is to
permit to log the last one that performed a final action. For now
the log is not produced.

3 years agoDOC: sample fetch methods: move distcc_* to the right locations
Willy Tarreau [Thu, 10 Mar 2022 09:39:58 +0000 (10:39 +0100)] 
DOC: sample fetch methods: move distcc_* to the right locations

The distcc* sample fetch methods were surprisingly located within the
"internal state" section, while they in fact depend on L6 contents.
This can be backported to all versions where they appear.

3 years agoBUG/MAJOR: mux-pt: Always destroy the backend connection on detach
Christopher Faulet [Wed, 9 Mar 2022 14:55:58 +0000 (15:55 +0100)] 
BUG/MAJOR: mux-pt: Always destroy the backend connection on detach

In TCP, when a conn-stream is detached from a backend connection, the
connection must be always closed. It was only performed if an error or a
shutdown occurred or if there was no connection owner. But it is a problem,
because, since the 2.3, backend connections are always owned by a
session. This way it is possible to have idle connections attached to a
session instead of a server. But there is no idle connections in TCP. In
addition, when a session owns a connection it is responsible to close it
when it is released. But it only works for idle connections. And it only
works if the session is released.

Thus there is the place for bugs here. And indeed, a connection leak may
occur if a connection retry is performed because of a timeout. In this case,
the underlying connection is still alive and is waiting to be fully
established. Thus, when the conn-stream is detached from the connection, the
connection is not closed. Because the PT multiplexer is quite simple, there
is no timeout at this stage. We depend on the kenerl to be notified and
finally close the connection. With an unreachable server, orphan backend
connections may be accumulated for a while. It may be perceived as a leak.

Because there is no reason to keep such backend connections, we just close
it now. Frontend connections are still closed by the session or when an
error or a shutdown occurs.

This patch should fix the issue #1522. It must be backported as far as
2.0. Note that the 2.2 and 2.0 are not affected by this bug because there is
no owner for backend TCP connections. But it is probably a good idea to
backport the patch on these versions to avoid any future bugs.

3 years agoCLEANUP: fcgi: Use `istadv()` in `fcgi_strm_send_params`
Tim Duesterhus [Fri, 4 Mar 2022 23:52:45 +0000 (00:52 +0100)] 
CLEANUP: fcgi: Use `istadv()` in `fcgi_strm_send_params`

Found manually, while creating the previous commits to turn `struct proxy`
members into ists.

There is an existing Coccinelle rule to replace this pattern by `istadv()` in
`ist.cocci`:

    @@
    struct ist i;
    expression e;
    @@

    - i.ptr += e;
    - i.len -= e;
    + i = istadv(i, e);

But apparently it is not smart enough to match ists that are stored in another
struct. It would be useful to make the existing rule more generic, so that it
might catch similar cases in the future.

3 years agoCLEANUP: fcgi: Replace memcpy() on ist by istcat()
Tim Duesterhus [Fri, 4 Mar 2022 23:52:44 +0000 (00:52 +0100)] 
CLEANUP: fcgi: Replace memcpy() on ist by istcat()

This is a little cleaner, because the length of the resulting string does not
need to be calculated manually.

3 years agoMEDIUM: proxy: Store server_id_hdr_name as a `struct ist`
Tim Duesterhus [Fri, 4 Mar 2022 23:52:43 +0000 (00:52 +0100)] 
MEDIUM: proxy: Store server_id_hdr_name as a `struct ist`

The server_id_hdr_name is already processed as an ist in various locations lets
also just store it as such.

see 0643b0e7e ("MINOR: proxy: Make `header_unique_id` a `struct ist`") for a
very similar past commit.

3 years agoMINOR: proxy: Store orgto_hdr_name as a `struct ist`
Tim Duesterhus [Fri, 4 Mar 2022 23:52:42 +0000 (00:52 +0100)] 
MINOR: proxy: Store orgto_hdr_name as a `struct ist`

The orgto_hdr_name is already processed as an ist in `http_process_request`,
lets also just store it as such.

see 0643b0e7e ("MINOR: proxy: Make `header_unique_id` a `struct ist`") for a
very similar past commit.

3 years agoMINOR: proxy: Store fwdfor_hdr_name as a `struct ist`
Tim Duesterhus [Fri, 4 Mar 2022 23:52:41 +0000 (00:52 +0100)] 
MINOR: proxy: Store fwdfor_hdr_name as a `struct ist`

The fwdfor_hdr_name is already processed as an ist in `http_process_request`,
lets also just store it as such.

see 0643b0e7e ("MINOR: proxy: Make `header_unique_id` a `struct ist`") for a
very similar past commit.

3 years agoMINOR: proxy: Store monitor_uri as a `struct ist`
Tim Duesterhus [Fri, 4 Mar 2022 23:52:40 +0000 (00:52 +0100)] 
MINOR: proxy: Store monitor_uri as a `struct ist`

The monitor_uri is already processed as an ist in `http_wait_for_request`, lets
also just store it as such.

see 0643b0e7e ("MINOR: proxy: Make `header_unique_id` a `struct ist`") for a
very similar past commit.

3 years agoDEBUG: stream: Fix stream trace message to print response buffer state
Christopher Faulet [Tue, 8 Mar 2022 14:48:55 +0000 (15:48 +0100)] 
DEBUG: stream: Fix stream trace message to print response buffer state

Channels buffer state is displayed in the strem trace messages. However,
because of a typo, the request buffer was used instead of the response one.

This patch should be backported as far as 2.2.

3 years agoDEBUG: stream: Add the missing descriptions for stream trace events
Christopher Faulet [Tue, 8 Mar 2022 14:47:02 +0000 (15:47 +0100)] 
DEBUG: stream: Add the missing descriptions for stream trace events

The description for STRM_EV_FLT_ANA and STRM_EV_FLT_ERR was missing.

This patch should be backported as far as 2.2.

3 years agoBUG/MEDIUM: mcli: Properly handle errors and timeouts during reponse processing
Christopher Faulet [Mon, 7 Mar 2022 17:20:21 +0000 (18:20 +0100)] 
BUG/MEDIUM: mcli: Properly handle errors and timeouts during reponse processing

The response analyzer of the master CLI only handles read errors. So if
there is a write error, the session remains stuck because some outgoing data
are blocked in the channel and the response analyzer waits everything to be
sent. Because the maxconn is set to 10 for the master CLI, it may be
unresponsive if this happens to many times.

Now read and write errors, timeouts and client aborts are handled.

This patch should solve the issue #1512. It must be backported as far as
2.0.

3 years agoDEBUG: cache: Update underlying buffer when loading HTX message in cache applet
Christopher Faulet [Mon, 7 Mar 2022 15:44:30 +0000 (16:44 +0100)] 
DEBUG: cache: Update underlying buffer when loading HTX message in cache applet

In the I/O handler of the cache applet, we must update the underlying buffer
when the HTX message is loaded, using htx_from_buf() function instead of
htxbuf(). It is important because the applet will update the message by
adding new HTX blocks. This way, the state of the underlying buffer remains
consistant with the state of the HTX message.

It is especially important if HAProxy is compiled with "DEBUG_STRICT=2"
mode. Without this patch, channel_add_input() call crashed if the channel
was empty at the begining of the I/O handler.

Note that it is more a build/debug issue than a bug. But this patch may
prevent future bugs. For now it is safe because htx_to_buf() function is
systematically called, updating accordingly the underlying buffer.

This patch may be backported as far as 2.0.

3 years agoBUG/MEDIUM: stream: Use the front analyzers for new listener-less streams
Christopher Faulet [Mon, 7 Mar 2022 14:31:46 +0000 (15:31 +0100)] 
BUG/MEDIUM: stream: Use the front analyzers for new listener-less streams

For now, for a stream, request analyzers are set at 2 stages. The first one
is when the stream is created. The session's listener analyzers, if any, are
set on the request channel. In addition, some HTTP analyzers are set for HTX
streams (AN_REQ_WAIT_HTTP and AN_REQ_HTTP_PROCESS_FE). The second one is
when the backend is set on the stream. At the stage, request analyzers are
updated using the backend settings.

It is an issue for client applets because there is no listener attached to
the stream. In addtion, it may have no specific/dedicated backend. Thus,
several request analyzers are missing. Among others, the HTTP analyzers for
HTTP applets. The HTTP client is the only one affected for now.

To fix the bug, when a stream is created without a listener, we use the
frontend to set the request analyzers. Note that there is no issue with the
response channel because its analyzers are set when the server connection is
established.

This patch may be backported to all stable versions. Because only the HTTP
client is affected, it must at least be backported to 2.5. It is related to
the issue #1593.

3 years agoBUG/MINOR: promex: Set conn-stream/channel EOI flags at the end of request
Christopher Faulet [Mon, 7 Mar 2022 14:56:20 +0000 (15:56 +0100)] 
BUG/MINOR: promex: Set conn-stream/channel EOI flags at the end of request

This bug is the same than for the HTTP client. See "BUG/MINOR: httpclient:
Set conn-stream/channel EOI flags at the end of request" for details.

This patch must be backported as far as 2.0. But only CF_EOI must be set
because applets are not attached to a conn-stream on older versions.

3 years agoBUG/MINOR: cache: Set conn-stream/channel EOI flags at the end of request
Christopher Faulet [Mon, 7 Mar 2022 14:53:57 +0000 (15:53 +0100)] 
BUG/MINOR: cache: Set conn-stream/channel EOI flags at the end of request

This bug is the same than for the HTTP client. See "BUG/MINOR: httpclient:
Set conn-stream/channel EOI flags at the end of request" for details.

Note that because a filter is always attached to the stream when the cache
is used, there is no issue because there is no direct forwarding in this
case. Thus the stream analyzers are able to see the HTX_FL_EOM flag on the
HTX messge.

This patch must be backported as far as 2.0. But only CF_EOI must be set
because applets are not attached to a conn-stream on older versions.

3 years agoBUG/MINOR: stats: Set conn-stream/channel EOI flags at the end of request
Christopher Faulet [Mon, 7 Mar 2022 14:52:42 +0000 (15:52 +0100)] 
BUG/MINOR: stats: Set conn-stream/channel EOI flags at the end of request

This bug is the same than for the HTTP client. See "BUG/MINOR: httpclient:
Set conn-stream/channel EOI flags at the end of request" for details.

This patch must be backported as far as 2.0. But only CF_EOI must be set
because applets are not attached to a conn-stream on older versions.

3 years agoBUG/MINOR: hlua: Set conn-stream/channel EOI flags at the end of request
Christopher Faulet [Mon, 7 Mar 2022 14:50:54 +0000 (15:50 +0100)] 
BUG/MINOR: hlua: Set conn-stream/channel EOI flags at the end of request

This bug is the same than for the HTTP client. See "BUG/MINOR: httpclient:
Set conn-stream/channel EOI flags at the end of request" for details.

This patch must be backported as far as 2.0. But only CF_EOI must be set
because applets are not attached to a conn-stream on older versions.

3 years agoBUG/MINOR: httpclient: Set conn-stream/channel EOI flags at the end of request
Christopher Faulet [Thu, 3 Mar 2022 14:38:39 +0000 (15:38 +0100)] 
BUG/MINOR: httpclient: Set conn-stream/channel EOI flags at the end of request

In HTX, HTX_FL_EOM flag is added on the message to notifiy the end of the
message was received. In addition, the producer must set CS_FL_EOI flag on
the conn-stream. If it is a mux, the stream-interface is responsible to set
CF_EOI flag on the input channel. But, for now, if the producer is an
applet, in addition to the conn-stream flag, it must also set the channel
one.

These flags are used to notify the stream that the message is finished and
no more data are expected. It is especially important when the message
itself it directly forwarded from one side to the other. Because in this
case, the stream has no way to see the HTX_FL_EOM flag on the
message. Otherwise, the stream will detect a client or a server abort,
depending on the side.

For the HTTP client, it is not really easy to diagnose this error because
there is also another bug hiding this one. All HTTP request analyzers are
not set on the input channel. This will be fixed by another patch.

This patch must be backported to 2.5. It is related to the issue #1593.

3 years agoBUILD: fix recent build breakage of freebsd caused by kFreeBSD build fix
David Carlier [Tue, 8 Mar 2022 14:49:29 +0000 (14:49 +0000)] 
BUILD: fix recent build breakage of freebsd caused by kFreeBSD build fix

Supporting kFreebsd previously led to FreeBSD (< 14) build breakage:

 In file included from src/cpuset.c:5:
 In file included from include/haproxy/cpuset.h:4:
 include/haproxy/cpuset-t.h:46:2: error: unknown type name 'cpu_set_t'; did you mean 'cpuset_t'?
         CPUSET_REPR cpuset;
         ^~~~~~~~~~~
         cpuset_t
 include/haproxy/cpuset-t.h:21:22: note: expanded from macro 'CPUSET_REPR'
 # define CPUSET_REPR cpu_set_t
                      ^

3 years agoMINOR: stats: Add dark mode support for socket rows
Marno Krahmer [Tue, 8 Mar 2022 12:45:09 +0000 (13:45 +0100)] 
MINOR: stats: Add dark mode support for socket rows

In commit e9ed63e548 dark mode support was added to the stats page. The
initial commit does not include  dark mode color overwrites for the
.socket CSS class. This commit colors socket rows the same way as
backends that acre active but do not have a health check defined.

This fixes an issue where reading information from socket lines became
really hard in dark mode due to suboptimal coloring of the cell
background and the font in it.

3 years agoBUG/MEDIUM: quic: do not drop packet on duplicate stream/decoding error
Amaury Denoyelle [Tue, 8 Mar 2022 09:48:35 +0000 (10:48 +0100)] 
BUG/MEDIUM: quic: do not drop packet on duplicate stream/decoding error

Change the return value to success in qc_handle_bidi_strm_frm for two
specific cases :
* if STREAM frame is an already received offset
* if application decoding failed

This ensures that the packet is not dropped and properly acknowledged.
Previous to this fix, the return code was set to error which prevented
the ACK to be generated.

The impact of the bug might be noticeable in environment with packet
loss and retransmission. Due to haproxy not generating ACK for packets
containing STREAM frames with already received offset, the client will
probably retransmit them again, which will worsen the network
transmission.

3 years agoBUG/MINOR: cli: shows correct mode in "show sess"
William Lallemand [Tue, 8 Mar 2022 11:05:31 +0000 (12:05 +0100)] 
BUG/MINOR: cli: shows correct mode in "show sess"

The "show sess" cli command only handles "http" or "tcp" as a fallback
mode, replace this by a call to proxy_mode_str() to show all the modes.

Could be backported in every maintained versions.

3 years agoBUG/MINOR: add missing modes in proxy_mode_str()
William Lallemand [Tue, 8 Mar 2022 10:50:59 +0000 (11:50 +0100)] 
BUG/MINOR: add missing modes in proxy_mode_str()

Add the missing PR_MODE_SYSLOG and PR_MODE_PEERS in proxy_mode_str().

Could be backported in every maintained versions.

3 years agoMINOR: pools: add a new global option "no-memory-trimming"
Willy Tarreau [Tue, 8 Mar 2022 09:41:40 +0000 (10:41 +0100)] 
MINOR: pools: add a new global option "no-memory-trimming"

Some users with very large numbers of connections have been facing
extremely long malloc_trim() calls on reload that managed to trigger
the watchdog! That's a bit counter-productive. It's even possible
that some implementations are not perfectly reliable or that their
trimming time grows quadratically with the memory used. Instead of
constantly trying to work around these issues, let's offer an option
to disable this mechanism, since nobody had been complaining in the
past, and this was only meant to be an improvement.

This should be backported to 2.4 where trimming on reload started to
appear.

3 years agoBUG/MAJOR: quic: Wrong quic_max_available_room() returned value
Frédéric Lécaille [Fri, 4 Mar 2022 14:44:21 +0000 (15:44 +0100)] 
BUG/MAJOR: quic: Wrong quic_max_available_room() returned value

Around limits for QUIC integer encoding, this functions could return
wrong values which lead to qc_build_frms() to prepare wrong CRYPTO (less chances)
or STREAM frames (more chances). qc_do_build_pkt() could build wrong packets
with bad CRYPTO/STREAM frames which could not be decoded by the peer.
In such a case ngtcp2 closes the connection with an ENCRYPTION_ERROR error
in a transport CONNECTION_CLOSE frame.

3 years agoMINOR: quic: Add quic_max_int_by_size() function
Frédéric Lécaille [Fri, 4 Mar 2022 14:38:51 +0000 (15:38 +0100)] 
MINOR: quic: Add quic_max_int_by_size() function

This function returns the maximum integer which may be encoded with a number of
bytes passed as parameter. Useful to precisely compute the number of bytes which
may used to fulfill a buffer with lengths as QUIC enteger encoded prefixes for the
number of following bytes.

3 years agoCLEANUP: quic: Remove window redundant variable from NewReno algorithm state struct
Frédéric Lécaille [Thu, 3 Mar 2022 07:24:53 +0000 (08:24 +0100)] 
CLEANUP: quic: Remove window redundant variable from NewReno algorithm state struct

We use the window variable which is stored in the path struct.

3 years agoMINOR: quic: More precise window update calculation
Frédéric Lécaille [Thu, 3 Mar 2022 06:50:45 +0000 (07:50 +0100)] 
MINOR: quic: More precise window update calculation

When in congestion avoidance state and when acknowledging an <acked> number bytes
we must increase the congestion window by at most one datagram (<path->mtu>)
by congestion window. So thanks to this patch we apply a ratio to the current
number of acked bytes : <acked> * <path->mtu> / <cwnd>.
So, when <cwnd> bytes are acked we precisely increment <cwnd> by <path->mtu>.
Furthermore we take into an account the number of remaining acknowledged bytes
each time we increment the window by <acked> storing their values in the algorithm
struct state (->remain_acked) so that it might be take into an account at the
next ACK event.

3 years agoBUG/MINOR: quic: Confusion betwen "in_flight" and "prep_in_flight" in quic_path_prep_...
Frédéric Lécaille [Thu, 3 Mar 2022 06:16:45 +0000 (07:16 +0100)] 
BUG/MINOR: quic: Confusion betwen "in_flight" and "prep_in_flight" in quic_path_prep_data()

This function returns the remaining number of bytes which can be sent on the
network before fulfilling the congestion window. There is a counter for
the number of prepared data and another one for the really in flight number
of bytes (in_flight). These variable have been mixed up.

3 years agoCLEANUP: quic: Remove useless definitions from quic_cc_event struct
Frédéric Lécaille [Wed, 2 Mar 2022 14:33:06 +0000 (15:33 +0100)] 
CLEANUP: quic: Remove useless definitions from quic_cc_event struct

Since the persistent congestion detection is done out of the congestion
controllers, there is no need to pass them information through quic_cc_event struct.
We remove its useless members. Also remove qc_cc_loss_event() which is no more used.

3 years agoMINOR: quic: Persistent congestion detection outside of controllers
Frédéric Lécaille [Wed, 2 Mar 2022 13:52:56 +0000 (14:52 +0100)] 
MINOR: quic: Persistent congestion detection outside of controllers

We establish the persistent congestion out of any congestion controller
to improve the algorithms genericity. This path characteristic detection may
be implemented regarless of the underlying congestion control algorithm.

Send congestion (loss) event using directly quic_cc_event(), so without
qc_cc_loss_event() wrapper function around quic_cc_event().

Take the opportunity of this patch to shorten "newest_time_sent" member field
of quic_cc_event to "time_sent".

3 years agoMINOR: quic: Add a "slow start" callback to congestion controller
Frédéric Lécaille [Wed, 2 Mar 2022 10:18:33 +0000 (11:18 +0100)] 
MINOR: quic: Add a "slow start" callback to congestion controller

We want to be able to make the congestion controllers re-enter the slow
start state outside of the congestion controllers themselves. So,
we add a callback ->slow_start() to do so.
Define this callback for NewReno algorithm.

3 years agoCLEANUP: quic: Remove QUIC path manipulations out of the congestion controller
Frédéric Lécaille [Tue, 1 Mar 2022 16:06:50 +0000 (17:06 +0100)] 
CLEANUP: quic: Remove QUIC path manipulations out of the congestion controller

QUIC connection path in flight bytes is a variable which should not be manipulated
by the congestion controller. This latter aim is to compute the congestion window.
So, we pass it as less as parameters as possible to do so.

3 years agoBUG/MINOR: quic: Missing recovery start timer reset
Frédéric Lécaille [Tue, 1 Mar 2022 14:09:45 +0000 (15:09 +0100)] 
BUG/MINOR: quic: Missing recovery start timer reset

The recovery start time must be reset after a persistent congestion has been
detected.

3 years agoMINOR: quic: Retry on qc_build_pkt() failures
Frédéric Lécaille [Mon, 28 Feb 2022 15:55:32 +0000 (16:55 +0100)] 
MINOR: quic: Retry on qc_build_pkt() failures

This is done going to stop_build label when qc_build_pkt() fails
because of a lack of buffer room (returns -1).

3 years agoBUILD: fix kFreeBSD build.
David Carlier [Fri, 4 Mar 2022 15:50:48 +0000 (15:50 +0000)] 
BUILD: fix kFreeBSD build.

kFreeBSD needs to be treated as a distinct target from FreeBSD
since the underlying system libc is the GNU one. Thus, relying
only on __GLIBC__ no longer suffice.

- freebsd-glibc new target, key difference is including crypt.h
  and linking to libdl like linux.
- cpu affinity available but the api is still the FreeBSD's.
- enabling auxiliary data access only for Linux.

Patch based on preliminary work done by @bigon.

closes #1555

3 years agoMEDIUM: mux-quic: implement MAX_STREAMS emission for bidir streams
Amaury Denoyelle [Mon, 7 Feb 2022 15:09:06 +0000 (16:09 +0100)] 
MEDIUM: mux-quic: implement MAX_STREAMS emission for bidir streams

Implement the locally flow-control streams limit for opened
bidirectional streams. Add a counter which is used to count the total
number of closed streams. If this number is big enough, emit a
MAX_STREAMS frame to increase the limit of remotely opened bidirectional
streams.

This is the first commit to implement QUIC flow-control. A series of
patches should follow to complete this.

This is required to be able to handle more than 100 client requests.
This should help to validate the Multiplexing interop test.

3 years agoMINOR: mux-quic: retry send opportunistically for remaining frames
Amaury Denoyelle [Fri, 4 Mar 2022 14:29:53 +0000 (15:29 +0100)] 
MINOR: mux-quic: retry send opportunistically for remaining frames

This commit should fix the possible transfer interruption caused by the
previous commit. The MUX always retry to send frames if there is
remaining data after a send call on the transport layer. This is useful
if the transport layer is not blocked on the sending path.

In the future, the transport layer should retry by itself the send
operation if no blocking condition exists. The MUX layer will always
subscribe to retry later if remaining frames are reported which indicate
a blocking on the transport layer.

3 years agoMEDIUM: mux-quic: use direct send transport API for STREAMs
Amaury Denoyelle [Wed, 9 Feb 2022 17:16:49 +0000 (18:16 +0100)] 
MEDIUM: mux-quic: use direct send transport API for STREAMs

Modify the STREAM emission in qc_send. Use the new transport function
qc_send_app_pkts to directly send the list of constructed frames. This
allows to remove the tasklet wakeup on the quic_conn and should reduce
the latency.

If not all frames are send after the transport call, subscribe the MUX
on the lower layer to be able to retry. Currently there is a bug because
the transport layer does not retry to send frames in excess after a
successful sendto. This might cause the transfer to be interrupted.

3 years agoMINOR: mux-quic: define new unions for flow-control fields
Amaury Denoyelle [Mon, 7 Feb 2022 15:03:22 +0000 (16:03 +0100)] 
MINOR: mux-quic: define new unions for flow-control fields

Define two new unions in the qcc structure named 'lfctl' and 'rfctl'.
For the moment they are empty. They will be completed to store the
initial and current level for flow-control on the local and remote side.

3 years agoMINOR: mux-quic: complete functions to detect stream type
Amaury Denoyelle [Mon, 7 Feb 2022 10:44:17 +0000 (11:44 +0100)] 
MINOR: mux-quic: complete functions to detect stream type

Improve the functions used to detect the stream characteristics :
uni/bidirectional and local/remote initiated.

Most notably, these functions are now designed to work transparently for
a MUX in the frontend or backend side. For this, we use the connection
to determine the current MUX side. This will be useful if QUIC is
implemented on the server side.

3 years agoMINOR: mux-quic: refactor transport parameters init
Amaury Denoyelle [Wed, 9 Feb 2022 09:25:29 +0000 (10:25 +0100)] 
MINOR: mux-quic: refactor transport parameters init

Since QUIC accept handling has been improved, the MUX is initialized
after the handshake completion. Thus its safe to access transport
parameters in qc_init via the quic_conn.

Remove quic_mux_transport_params_update which was called by the
transport for the MUX. This improves the architecture by removing a
direct call from the transport to the MUX.

The deleted function body is not transfered to qc_init because this part
will change heavily in the near future when implementing the
flow-control.

3 years agoMINOR: quic: Export qc_send_app_pkts()
Frédéric Lécaille [Fri, 25 Feb 2022 16:46:07 +0000 (17:46 +0100)] 
MINOR: quic: Export qc_send_app_pkts()

This is at least to make this function be callable by the mux.

3 years agoMINOR: quic: Make qc_build_frms() build ack-eliciting frames from a list
Frédéric Lécaille [Fri, 25 Feb 2022 16:44:29 +0000 (17:44 +0100)] 
MINOR: quic: Make qc_build_frms() build ack-eliciting frames from a list

We want to be able to build ack-eliciting frames to be embedded into QUIC packets
from a prebuilt list of ack-eliciting frames. This will be helpful for the mux
which would like to send STREAM frames asap after having builts its own prebuilt
list.
To do so, we only add a parameter as struct list to this function to handle
such a prebuilt list.

3 years agoMINOR: quic: Send short packet from a frame list
Frédéric Lécaille [Fri, 25 Feb 2022 16:41:39 +0000 (17:41 +0100)] 
MINOR: quic: Send short packet from a frame list

We want to be able to send ack-elicting packets from a list of ack-eliciting
frames. So, this patch adds such a paramaters to the function responsible of
building 1RTT packets. The entry point function is qc_send_app_pkts() which
is used with the underlying packet number space TX frame list as parameter.

3 years agoMINOR: quic: qc_prep_app_pkts() implementation
Frédéric Lécaille [Fri, 25 Feb 2022 16:15:21 +0000 (17:15 +0100)] 
MINOR: quic: qc_prep_app_pkts() implementation

We want to get rid of the code used during the handshake step. qc_prep_app_pkts()
aim is to build short packets which are also datagrams.
Make quic_conn_app_io_cb() call this new function to prepare short packets.

3 years agoCLEANUP: quic: complete ABORT_NOW with a TODO comment
Amaury Denoyelle [Fri, 4 Mar 2022 15:51:20 +0000 (16:51 +0100)] 
CLEANUP: quic: complete ABORT_NOW with a TODO comment

Add a TODO comment to not forget to properly implement error returned by
qcs_push_frame.

3 years agoCI: coverity: simplify debugging options
Willy Tarreau [Fri, 4 Mar 2022 09:12:40 +0000 (10:12 +0100)] 
CI: coverity: simplify debugging options

We used to rely on a call to "sed" to modify the DEBUG option in the
makefile when running under Coverity because it splits words around
spaces and does not allow to pass multi-word build options. As reported
by Tim in issue #1592, this broke with commit 8de7f2822 ("BUILD: makefile:
enable both DEBUG_STRICT and DEBUG_MEMORY_POOLS by default") when the
default DEBUG options changed.

Let's change this to pass all DEBUG options one at a time instead and
get rid of this sed.

3 years agoCLEANUP: tree-wide: remove a few rare non-ASCII chars
Willy Tarreau [Wed, 2 Mar 2022 21:33:39 +0000 (22:33 +0100)] 
CLEANUP: tree-wide: remove a few rare non-ASCII chars

As reported by Tim in issue #1428, our sources are clean, there are
just a few files with a few rare non-ASCII chars for the paragraph
symbol, a few typos, or in Fred's name. Given that Fred already uses
the non-accentuated form at other places like on the public list,
let's uniformize all this and make sure the code displays equally
everywhere.

3 years agoBUG/MEDIUM: pools: fix ha_free() on area in the process of being freed
Willy Tarreau [Thu, 3 Mar 2022 17:31:54 +0000 (18:31 +0100)] 
BUG/MEDIUM: pools: fix ha_free() on area in the process of being freed

Commit e81248c0c ("BUG/MINOR: pool: always align pool_heads to 64 bytes")
added a free of the allocated pool in pool_destroy() using ha_free(), but
it added a subtle bug by which once the pool is released, setting its
address to NULL inside the structure itself cannot work because the area
has just been freed.

This will need to be backported wherever the patch above is backported.

3 years agoBUG/MINOR: quic: fix segfault on CC if mux uninitialized
Amaury Denoyelle [Thu, 3 Mar 2022 17:04:24 +0000 (18:04 +0100)] 
BUG/MINOR: quic: fix segfault on CC if mux uninitialized

A segfault happens when receiving a CONNECTION_CLOSE during handshake.
This is because the mux is not initialized at this stage but the
transport layer dereferences it.

Fix this by ensuring that the MUX is initialized before. Thanks to Willy
for his help on this one. Welcome in the QUIC-men team !

3 years agoDEV: udp: add an optional argument to set the prng seed
Willy Tarreau [Thu, 3 Mar 2022 17:01:26 +0000 (18:01 +0100)] 
DEV: udp: add an optional argument to set the prng seed

This will help reproduce certain sequences that were observed.

3 years agoDEV: udp: implement pseudo-random reordering/loss
Willy Tarreau [Thu, 3 Mar 2022 16:36:53 +0000 (17:36 +0100)] 
DEV: udp: implement pseudo-random reordering/loss

By passing a 3rd argument it's now possible to set a randomness level
according to which received packets will be replaced by one of the 20
previous ones. This happens in both directions and the buffer is common
so that it's possible to receive responses on requests and conversely,
which adds to the perturbation. E.g:

    ./dev/udp/udp-perturb 127.0.0.4:9443 127.0.0.4:8443 10

This will add 10% randomness on forwarded packets between these two
ports.

3 years agoDEV: udp: add a tiny UDP proxy for testing
Willy Tarreau [Thu, 3 Mar 2022 15:53:46 +0000 (16:53 +0100)] 
DEV: udp: add a tiny UDP proxy for testing

QUIC really needs more traffic perturbation for the tests. Let's have
a tiny UDP proxy for this, mostly derived from the 'connect' test suite.
For now it only supports a single "connection" at once, but the code is
here to support more. A new "connection" will simply replace the previous
one. It doesn't yet cause traffic perturbations, this is still to be added.
Some of the setsockopt() are possibly unneeded. The error handling is
almost inexistent, and polling for sends is not implemented at all (will
cause losses). No stats are collected.

3 years agoBUG/MINOR: pool: always align pool_heads to 64 bytes
Willy Tarreau [Wed, 2 Mar 2022 16:59:04 +0000 (17:59 +0100)] 
BUG/MINOR: pool: always align pool_heads to 64 bytes

This is the pool equivalent of commit 97ea9c49f ("BUG/MEDIUM: fd: always
align fdtab[] to 64 bytes"). After a careful code review, it happens that
the pool heads are the other structures allocated with malloc/calloc that
claim to be aligned to a size larger than what the allocator can offer.
While no issue was reported on them, no memset() is performed and no type
is large, this is a problem waiting to happen, so better fix it. In
addition, it's relatively easy to do by storing the allocation address
inside the pool_head itself and use it at free() time. Finally, threads
might benefit from the fact that the caches will really be aligned and
that there will be no false sharing.

This should be backported to all versions where it applies easily.

3 years agoBUG/MEDIUM: httpclient/lua: infinite appctx loop with POST
William Lallemand [Wed, 2 Mar 2022 15:18:26 +0000 (16:18 +0100)] 
BUG/MEDIUM: httpclient/lua: infinite appctx loop with POST

When POSTing a request with a payload, and reusing the same httpclient
lua instance, one could encounter a spinning of the httpclient appctx.

Indeed the sent counter is not reset between 2 POSTs and the condition
for sending the EOM flag is never met.

Must fixed issue #1593.

To be backported in 2.5.

3 years agoDEBUG: reduce the footprint of BUG_ON() calls
Willy Tarreau [Wed, 2 Mar 2022 14:52:03 +0000 (15:52 +0100)] 
DEBUG: reduce the footprint of BUG_ON() calls

Many inline functions involve some BUG_ON() calls and because of the
partial complexity of the functions, they're not inlined anymore (e.g.
co_data()). The reason is that the expression instantiates the message,
its size, sometimes a counter, then the atomic OR to taint the process,
and the back trace. That can be a lot for an inline function and most
of it is always the same.

This commit modifies this by delegating the common parts to a dedicated
function "complain()" that takes care of updating the counter if needed,
writing the message and measuring its length, and tainting the process.
This way the caller only has to check a condition, pass a pointer to the
preset message, and the info about the type (bug or warn) for the tainting,
then decide whether to dump or crash. Note that this part could also be
moved to the function but resulted in complain() always being at the top
of the stack, which didn't seem like an improvement.

Thanks to these changes, the BUG_ON() calls do not result in uninlining
functions anymore and the overall code size was reduced by 60 to 120 kB
depending on the build options.

3 years agoBUILD: tcpcheck: do not declare tcp_check_keywords_register() inline
Willy Tarreau [Wed, 2 Mar 2022 13:54:44 +0000 (14:54 +0100)] 
BUILD: tcpcheck: do not declare tcp_check_keywords_register() inline

This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.

3 years agoBUILD: trace: do not declare trace_registre_source() inline
Willy Tarreau [Wed, 2 Mar 2022 13:53:00 +0000 (14:53 +0100)] 
BUILD: trace: do not declare trace_registre_source() inline

This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.

3 years agoBUILD: http_rules: do not declare http_*_keywords_registre() inline
Willy Tarreau [Wed, 2 Mar 2022 13:50:38 +0000 (14:50 +0100)] 
BUILD: http_rules: do not declare http_*_keywords_registre() inline

The 3 functions http_{req,res,after_res}_keywords_register() are
referenced in initcalls by their pointer, it makes no sense to declare
them inline. At best it causes function duplication, at worst it doesn't
build on older compilers.

3 years agoBUILD: connection: do not declare register_mux_proto() inline
Willy Tarreau [Wed, 2 Mar 2022 13:46:45 +0000 (14:46 +0100)] 
BUILD: connection: do not declare register_mux_proto() inline

This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.

3 years agoBUILD: conn_stream: avoid null-deref warnings on gcc 6
Willy Tarreau [Wed, 2 Mar 2022 13:38:11 +0000 (14:38 +0100)] 
BUILD: conn_stream: avoid null-deref warnings on gcc 6

gcc 6 continues its saga with excessive reports of null-deref warnings.
This time it was in the IS_HTX_CS() macro. Let's use __cs_conn() after
cs_conn() was checked.

3 years agoMINOR: quic: Assemble QUIC TLS flags at the same level
Frédéric Lécaille [Fri, 25 Feb 2022 16:17:59 +0000 (17:17 +0100)] 
MINOR: quic: Assemble QUIC TLS flags at the same level

Do not distinguish the direction (TX/RX) when settings TLS secrets flags.
There is not such a distinction in the RFC 9001.
Assemble them at the same level: at the upper context level.

3 years agoCLEANUP: quic: Indentation fix in qc_prep_pkts()
Frédéric Lécaille [Wed, 23 Feb 2022 08:38:01 +0000 (09:38 +0100)] 
CLEANUP: quic: Indentation fix in qc_prep_pkts()

Non-invasive modification.

3 years agoCLEANUP: quic: Useless tests in qc_try_rm_hp()
Frédéric Lécaille [Mon, 21 Feb 2022 18:22:09 +0000 (19:22 +0100)] 
CLEANUP: quic: Useless tests in qc_try_rm_hp()

There is no need to test <qel>. Furthermore the packet type has already checked
by the caller.

3 years agoMINOR: quic: Drop the packets of discarded packet number spaces
Frédéric Lécaille [Tue, 22 Feb 2022 10:39:14 +0000 (11:39 +0100)] 
MINOR: quic: Drop the packets of discarded packet number spaces

This is required since this previous commit:
   "MINOR: quic: Post handshake I/O callback switching"
If not, such packets remain endlessly in the RX buffer and cannot be parsed
by the new I/O callback used after the handshake has been confirmed.

3 years agoMINOR: quic: Post handshake I/O callback switching
Frédéric Lécaille [Fri, 18 Feb 2022 16:13:45 +0000 (17:13 +0100)] 
MINOR: quic: Post handshake I/O callback switching

Implement a simple task quic_conn_app_io_cb() to be used after the handshakes
have completed.

3 years agoMINOR: quic: Ensure PTO timer is not set in the past
Frédéric Lécaille [Wed, 16 Feb 2022 13:46:17 +0000 (14:46 +0100)] 
MINOR: quic: Ensure PTO timer is not set in the past

Wakeup asap the timer task when setting its timer in the past.
Take also the opportunity of this patch to make simplify quic_pto_pktns():
calling tick_first() is useless here to compare <lpto> with <tmp_pto>.

3 years agoBUILD: ssl: another build warning on LIBRESSL_VERSION_NUMBER
Julien Thomas [Mon, 28 Feb 2022 21:13:31 +0000 (22:13 +0100)] 
BUILD: ssl: another build warning on LIBRESSL_VERSION_NUMBER

We had several warnings when building haproxy 2.5.4 with
old openssl 1.0.1e. This version of openssl is the latest
available in EOL centos 6.

  include/haproxy/openssl-compat.h:157:51: \
  warning: "LIBRESSL_VERSION_NUMBER" is not defined

This patch fixed the build. It changes the #if condition,
as done in other similar parts of openssl-compat.h.

3 years agoCLEANUP: stream: Remove useless tests on conn-stream in stream_dump()
Christopher Faulet [Tue, 1 Mar 2022 14:16:57 +0000 (15:16 +0100)] 
CLEANUP: stream: Remove useless tests on conn-stream in stream_dump()

Since the recent refactoring on the conn-streams, a stream has always a
defined frontend and backend conn-streams. Thus, in stream_dump(), there is
no reason to still test if these conn-streams are defined.

In addition, still in stream_dump(), get the stream-interfaces using the
conn-streams and not the opposite.

This patch should fix issue #1589 and #1590.

3 years agoREGTESTS: fix the race conditions in secure_memcmp.vtc
Christopher Faulet [Tue, 1 Mar 2022 10:03:00 +0000 (11:03 +0100)] 
REGTESTS: fix the race conditions in secure_memcmp.vtc

In the same way than for normalize_uri.vtc, a "Connection: close" header is
added to all responses to avoid any connection reuse. This should avoid any
"HTTP header incomplete" errors.

3 years agoMEDIUM: quic: rearchitecture Rx path for bidirectional STREAM frames
Amaury Denoyelle [Mon, 28 Feb 2022 10:37:48 +0000 (11:37 +0100)] 
MEDIUM: quic: rearchitecture Rx path for bidirectional STREAM frames

Reorganize the Rx path for STREAM frames on bidirectional streams. A new
function qcc_recv is implemented on the MUX. It will handle the STREAM
frames copy and offset calculation from transport to MUX.

Another function named qcc_decode_qcs from the MUX can be called by
transport each time new STREAM data has been copied.

The architecture is now cleaner with the MUX layer in charge of parsing
the STREAM frames offsets. This is required to be able to implement the
flow-control on the MUX layer.

Note that as a convenience, a STREAM frame is not partially copied to
the MUX buffer. This simplify the implementation for the moment but it
may change in the future to optimize the STREAM frames handling.

For the moment, only bidirectional streams benefit from this change. In
the future, it may be extended to unidirectional streams to unify the
STREAM frames processing.

3 years agoBUG/MINOR: quic: support FIN on Rx-buffered STREAM frames
Amaury Denoyelle [Mon, 28 Feb 2022 10:38:36 +0000 (11:38 +0100)] 
BUG/MINOR: quic: support FIN on Rx-buffered STREAM frames

FIN flag on a STREAM frame was not detected if the frame was previously
buffered on qcs.rx.frms before being handled.

To fix this, copy the fin field from the quic_stream instance to
quic_rx_strm_frm. This is required to properly notify the FIN flag on
qc_treat_rx_strm_frms for the MUX layer.

Without this fix, the request channel might be left opened after the
last STREAM frame reception if there is out-of-order frames on the Rx
path.

3 years agoMINOR: mux-quic: define flag for last received frame
Amaury Denoyelle [Mon, 28 Feb 2022 10:36:57 +0000 (11:36 +0100)] 
MINOR: mux-quic: define flag for last received frame

This flag is set when the STREAM frame with FIN set has been received on
a qcs instance. For now, this is only used as a BUG_ON guard to prevent
against multiple frames with FIN set. It will also be useful when
reorganize the RX path and move some of its code in the mux.

3 years agoMINOR: quic: handle partially received buffered stream frame
Amaury Denoyelle [Fri, 25 Feb 2022 16:36:31 +0000 (17:36 +0100)] 
MINOR: quic: handle partially received buffered stream frame

Adjust the function to handle buffered STREAM frames. If the offset of
the frame was already fully received, discard the frame. If only
partially received, compute the difference and copy only the newly
offset.

Before this change, a buffered frame representing a fully or partially
received offset caused the loop to be interrupted. The frame was
preserved, thus preventing frames with greater offset to be handled.

This may fix some occurences of stalled transfer on the request channel
if there is out-of-order STREAM frames on the Rx path.

3 years agoMINOR: quic: simplify copy of STREAM frames to RX buffer
Amaury Denoyelle [Mon, 28 Feb 2022 09:00:54 +0000 (10:00 +0100)] 
MINOR: quic: simplify copy of STREAM frames to RX buffer

qc_strm_cpy can be simplified by simply using b_putblk which already
handle wrapping of the destination buffer. The function is kept to
update the frame length and offset fields.

3 years agoCLEANUP: adjust indentation in bidir STREAM handling function
Amaury Denoyelle [Fri, 25 Feb 2022 16:29:10 +0000 (17:29 +0100)] 
CLEANUP: adjust indentation in bidir STREAM handling function

Fix indentation in qc_handle_bidi_strm_frm in if condition.

3 years agoMINOR: queue: Replace if() + abort() with BUG_ON()
Tim Duesterhus [Mon, 28 Feb 2022 18:16:31 +0000 (19:16 +0100)] 
MINOR: queue: Replace if() + abort() with BUG_ON()

see 5cd4bbd7a ("BUG/MAJOR: threads/queue: Fix thread-safety issues on the queues management")

3 years agoDOC: install: describe how to choose options used in the DEBUG variable
Willy Tarreau [Tue, 1 Mar 2022 07:31:50 +0000 (08:31 +0100)] 
DOC: install: describe how to choose options used in the DEBUG variable

This enumerates a few of the options that are expected to have an effect
on the process' self-checks at the expense of more or less performance,
and how to choose sets of options for different deployments.

3 years agoDOC: install: describe the DEP variable
Willy Tarreau [Tue, 1 Mar 2022 06:45:18 +0000 (07:45 +0100)] 
DOC: install: describe the DEP variable

The variable was quickly mentioned in the makefile but not in the INSTALL
file. Let's describe its use cases and limitations.

3 years agoDOC: install: it's DEBUG_CFLAGS, not DEBUG, which is set to -g
Willy Tarreau [Tue, 1 Mar 2022 06:40:24 +0000 (07:40 +0100)] 
DOC: install: it's DEBUG_CFLAGS, not DEBUG, which is set to -g

The INSTALL doc stated that the DEBUG variable is set to -g by default
but that's not true, it's DEBUG_CFLAGS.

3 years agoMINOR: connection: Transform safety check in PROXYv2 parsing into BUG_ON()
Tim Duesterhus [Fri, 25 Feb 2022 20:44:27 +0000 (21:44 +0100)] 
MINOR: connection: Transform safety check in PROXYv2 parsing into BUG_ON()

With BUG_ON() being enabled by default it is more useful to use a BUG_ON()
instead of an effectively never-taken if, as any incorrect assumptions will
become much more visible.

see 488ee7fb6 ("BUG/MAJOR: proxy_protocol: Properly validate TLV lengths")

3 years agoCLEANUP: connection: Indicate unreachability to the compiler in conn_recv_proxy
Tim Duesterhus [Fri, 25 Feb 2022 20:44:26 +0000 (21:44 +0100)] 
CLEANUP: connection: Indicate unreachability to the compiler in conn_recv_proxy

Transform the unreachability comment into a call to `my_unreachable()` to allow
the compiler from benefitting from it.

see d1b15b6e9 ("MINOR: proxy_protocol: Ingest PP2_TYPE_UNIQUE_ID on incoming connections")
see 615f81eb5 ("MINOR: connection: Use a `struct ist` to store proxy_authority")

3 years agoBUILD: debug: fix build warning on older compilers around DEBUG_STRICT_ACTION
Willy Tarreau [Mon, 28 Feb 2022 16:57:19 +0000 (17:57 +0100)] 
BUILD: debug: fix build warning on older compilers around DEBUG_STRICT_ACTION

The new macro was introduced with commit 86bcc5308 ("DEBUG: implement 4
levels of choices between warn and crash.") but some older compilers can
complain that we test the value when the macro is not defined despite
having already been checked in a previous #if directive. Let's just
repeat the test for the definition.

3 years agoDEBUG: stream-int: Fix BUG_ON used to test appctx in si_applet_ops callbacks
Christopher Faulet [Mon, 28 Feb 2022 16:27:09 +0000 (17:27 +0100)] 
DEBUG: stream-int: Fix BUG_ON used to test appctx in si_applet_ops callbacks

693b23bb1 ("MEDIUM: tree-wide: Use unsafe conn-stream API when it is
relevant") introduced a regression in DEBUG_STRICT mode because some BUG_ON
conditions were inverted. It should ok now.

In addition, ALREADY_CHECKED macro was removed from appctx_wakeup() function
because it is useless now.

3 years agoREGTESTS: fix the race conditions in normalize_uri.vtc
Christopher Faulet [Mon, 28 Feb 2022 16:04:37 +0000 (17:04 +0100)] 
REGTESTS: fix the race conditions in normalize_uri.vtc

There is no connection reuse to avoid race conditions in HTTP reg-tests. But
time to time, normalize_uri.vtc still report "HTTP header incomplete"
error. It seems to be because HTTP keep-alive is still used at the session
level. Thus when the same server section is used to handle multiple requests
for the same client, via a "-repeat" statement, a new request for this client
may be handled by HAProxy before the server is restarted.

To avoid any trouble, HTTP keep-alive is disabled on the server side by
adding "Connection: close" header in responses. It seems to be ok now. We
let the CI decide.

3 years agoBUG/MEDIUM: htx: Fix a possible null derefs in htx_xfer_blks()
Christopher Faulet [Mon, 28 Feb 2022 14:29:56 +0000 (15:29 +0100)] 
BUG/MEDIUM: htx: Fix a possible null derefs in htx_xfer_blks()

In htx_xfer_blks() function, when headers or trailers are partially
transferred, we rollback the copy by removing copied blocks. Internally, all
blocks between <dstref> and <dstblk> are removed. But if the transfer was
stopped because we failed to reserve a block, the variable <dstblk> is
NULL. Thus, we must not try to remove it. It is unexpected to call
htx_remove_blk() in this case.

htx_remove_blk() was updated to test <blk> variable inside the existing
BUG_ON(). The block must be defined.

For now, this bug may only be encountered when H2 trailers are copied. On H2
headers, the destination buffer is empty. Thus a swap is performed.

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

3 years agoBUG/MEDIUM: mux-fcgi: Don't rely on SI src/dst addresses for FCGI health-checks
Christopher Faulet [Mon, 28 Feb 2022 10:49:02 +0000 (11:49 +0100)] 
BUG/MEDIUM: mux-fcgi: Don't rely on SI src/dst addresses for FCGI health-checks

When an HTTP health-check is performed in FCGI, we must not rely on the SI
source and destination addresses to set default parameters
(REMOTE_ADDR/REMOTE_PORT and SERVER_NAME/SERVER_PORT) because the backend
conn-stream is not attached to a stream but to a healt-check. Thus, there is
no stream-interface. In addition, there is no client connection because it
is an "internal" session.

Thus, for now, in this case, there is only the server connection that can be
used. So src/dst addresses are retrieved from the server connection when the
CS application is a health-check.

This patch should solve issue #1572. It must be backported to 2.5. Note than
the CS api has changed. Thus, on HAProxy 2.5, we should test the session's
origin instead:

    const struct sockaddr_storage *src = (cs_check(fstrm->cs) ? ...);
    const struct sockaddr_storage *dst = (cs_check(fstrm->cs) ? ...);

3 years agoREORG: stream-int: Uninline si_sync_recv() and make si_cs_recv() private
Christopher Faulet [Mon, 28 Feb 2022 08:21:58 +0000 (09:21 +0100)] 
REORG: stream-int: Uninline si_sync_recv() and make si_cs_recv() private

This way si_*_recv() and si_*_sned() API are defined the same
way. si_sync_snd/si_sync_recv are both exported and defined in the C
file. And si_cs_send/si_cs_recv are private and only used by
stream-interface internals.

3 years agoCLEANUP: stream-int: Make si_cs_send() function static
Christopher Faulet [Mon, 28 Feb 2022 08:14:46 +0000 (09:14 +0100)] 
CLEANUP: stream-int: Make si_cs_send() function static

This function was not exported and is only used in stream_interface.c. So
make it static.

3 years agoMEDIUM: tree-wide: Use unsafe conn-stream API when it is relevant
Christopher Faulet [Mon, 28 Feb 2022 08:09:05 +0000 (09:09 +0100)] 
MEDIUM: tree-wide: Use unsafe conn-stream API when it is relevant

The unsafe conn-stream API (__cs_*) is now used when we are sure the good
endpoint or application is attached to the conn-stream. This avoids compiler
warnings about possible null derefs. It also simplify the code and clear up
any ambiguity about manipulated entities.

3 years agoMINOR: conn-stream: Improve API to have safe/unsafe accessors
Christopher Faulet [Mon, 28 Feb 2022 07:45:41 +0000 (08:45 +0100)] 
MINOR: conn-stream: Improve API to have safe/unsafe accessors

Depending on the context, we know the endpoint or the application attached
to the conn_stream is defined and we know its type. However, having
accessors testing the endpoint or the application may lead the compiler to
report possible null derefs here and there. The alternative is to add
useless tests or use ALREAD_CHECKED/DISGUISE macros. It is tedious and
inelegant.

So now, similarily to the ob API, the safe API, testing
endpoint/application, relies on an unsafe one (same name prefixed with
'__'). This way, any caller may use the unsafe API when it is relevant.

In addition, there is no reason to test the conn-stream itself. It is the
caller responsibility to be sure there is a conn-stream to get its endpoint
or its application. And most of type, we are sure to have a conn-stream.

3 years agoDEBUG: channel: add consistency checks using BUG_ON_HOT() in some key functions
Willy Tarreau [Mon, 28 Feb 2022 15:55:51 +0000 (16:55 +0100)] 
DEBUG: channel: add consistency checks using BUG_ON_HOT() in some key functions

A few functions such as c_adv(), c_rew(), co_set_data() or co_skip() got a
BUG_ON_HOT() to make sure they're not used to push more data than available
in the buffer. Note that with HTX the margin can be high and will less easily
trigger, but the goal is to detect a misuse early enough.

co_data() should never be called with a wrong c->output. At least it never
happens in regtests, but we're adding a CHECK_IF_HOT() there to avoid crashing
but report it if it ever happened when the hot path checks are enabled.

3 years agoMINOR: channel: don't use co_set_data() to decrement output
Willy Tarreau [Mon, 28 Feb 2022 15:51:23 +0000 (16:51 +0100)] 
MINOR: channel: don't use co_set_data() to decrement output

The use of co_set_data() should be strictly limited to setting the amount
of existing data to be transmitted. It ought not be used to decrement the
output after the data have left the buffer, because doing so involves
performing incorrect calculations using co_data() that still comprises
data that are not in the buffer anymore. Let's use c_rew() for this, which
is made exactly for this purpose, i.e. decrement c->output by as much as
requested. This is cleaner, faster, and will permit stricter checks.

3 years agoDEBUG: buf: add BUG_ON_HOT() to most buffer management functions
Willy Tarreau [Mon, 28 Feb 2022 15:11:33 +0000 (16:11 +0100)] 
DEBUG: buf: add BUG_ON_HOT() to most buffer management functions

A number of tests are now performed in low-level buffer management
functions to verify that we're not appending data to a full buffer
for example, or that the buffer passed in argument is consistent in
that its data don't outweigh its size. The few functions that already
involve memcpy() or memmove() instead got a BUG_ON() that will always
be enabled, since the overhead remains minimalist.

3 years agoDEBUG: buf: replace some sensitive BUG_ON() with BUG_ON_HOT()
Willy Tarreau [Mon, 28 Feb 2022 15:10:00 +0000 (16:10 +0100)] 
DEBUG: buf: replace some sensitive BUG_ON() with BUG_ON_HOT()

The buffer ring management functions br_* were all stuffed with BUG_ON()
statements that never triggered and that are on some fast paths (e.g. in
mux_h2). Let's turn them to BUG_ON_HOT() instead.

3 years agoDEBUG: add two new macros to enable debugging in hot paths
Willy Tarreau [Mon, 28 Feb 2022 14:25:58 +0000 (15:25 +0100)] 
DEBUG: add two new macros to enable debugging in hot paths

Two new BUG_ON variants, BUG_ON_HOT() and CHECK_IF_HOT() are introduced
to debug hot paths (such as low-level API functions). These ones must
not be enabled by default as they would significantly affect performance
but they may be enabled by setting DEBUG_STRICT to a value above 1. In
this case, DEBUG_STRICT_ACTION is mostly respected with a small change,
which is that the no_crash variant of BUG_ON() isn't turned to a regular
warning but to a one-time warning so as not to spam with warnings in a
hot path. It is for this reason that there is no WARN_ON_HOT().

3 years agoDEBUG: implement 4 levels of choices between warn and crash.
Willy Tarreau [Mon, 28 Feb 2022 13:59:25 +0000 (14:59 +0100)] 
DEBUG: implement 4 levels of choices between warn and crash.

We used to have DEBUG_STRICT_NOCRASH to disable crashes on BUG_ON().
Now we have other levels (WARN_ON(), CHECK_IF()) so we need something
finer-grained.

This patch introduces DEBUG_STRICT_ACTION which takes an integer value.
0 disables crashes and is the equivalent of DEBUG_STRICT_NOCRASH. 1 is
the default and only enables crashes on BUG_ON(). 2 also enables crashes
on WARN_ON(), and 3 also enables warnings on CHECK_IF(), and is suited
to developers and CI.