]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 years agoBUG/MINOR: sink: free forward_px on deinit()
Aurelien DARRAGON [Thu, 9 Mar 2023 11:07:09 +0000 (12:07 +0100)] 
BUG/MINOR: sink: free forward_px on deinit()

When a ring section is configured, a new sink is created and forward_px
proxy may be allocated and assigned to the sink.
Such sink-related proxies are added to the sink_proxies_list and thus
don't belong to the main proxy list which is cleaned up in
haproxy deinit() function.

We don't have to manually clean up sink_proxies_list in the main deinit()
func:
sink API already provides the sink_deinit() function so we just add the
missing free_proxy(sink->forward_px) there.

This could be backported up to 2.4.
[in 2.4, commit b0281a49 ("MINOR: proxy: check if p is NULL in free_proxy()")
must be backported first]

2 years agoBUG/MINOR: stats: properly handle server stats dumping resumption
Aurelien DARRAGON [Tue, 31 Jan 2023 08:51:32 +0000 (09:51 +0100)] 
BUG/MINOR: stats: properly handle server stats dumping resumption

In stats_dump_proxy_to_buffer() function, special care was taken when
dealing with servers dump.
Indeed, stats_dump_proxy_to_buffer() can be interrupted and resumed if
buffer space is not big enough to complete dump.
Thus, a reference is taken on the server being dumped in the hope that
the server will still be valid when the function resumes.
(to prevent the server from being freed in the meantime)

While this is now true thanks to:
-  "BUG/MINOR: server/del: fix legacy srv->next pointer consistency"

We still have an issue: when resuming, saved server reference is not
dropped.
This prevents the server from being freed when we no longer use it.
Moreover, as the saved server might now be deleted
(SRV_F_DELETED flag set), the current deleted server may still be dumped
in the stats and while this is not a bug, this could be misleading for
the user.

Let's add a px_st variable to detect if the stats_dump_proxy_to_buffer()
is being resumed at the STAT_PX_ST_SV stage: perform some housekeeping
to skip deleted servers and properly drop the reference on the saved
server.

This commit depends on:
 - "MINOR: server: add SRV_F_DELETED flag"
 - "BUG/MINOR: server/del: fix legacy srv->next pointer consistency"

This should be backported up to 2.6

2 years agoBUG/MINOR: server/del: fix srv->next pointer consistency
Aurelien DARRAGON [Wed, 1 Feb 2023 16:22:32 +0000 (17:22 +0100)] 
BUG/MINOR: server/del: fix srv->next pointer consistency

We recently discovered a bug which affects dynamic server deletion:

When a server is deleted, it is removed from the "visible" server list.
But as we've seen in previous commit
("MINOR: server: add SRV_F_DELETED flag"), it can still be accessed by
someone who keeps a reference on it (waiting for the final srv_drop()).
Throughout this transient state, server ptr is still valid (may be
dereferenced) and the flag SRV_F_DELETED is set.

However, as the server is not part of server list anymore, we have
an issue: srv->next pointer won't be updated anymore as the only place
where we perform such update is in cli_parse_delete_server() by
iterating over the "visible" server list.

Because of this, we cannot guarantee that a server with the
SRV_F_DELETED flag has a valid 'next' ptr: 'next' could be pointing
to a fully removed (already freed) server.

This problem can be easily demonstrated with server dumping in
the stats:

server list dumping is performed in stats_dump_proxy_to_buffer()
The function can be interrupted and resumed later by design.
ie: output buffer is full: partial dump and finish the dump after
the flush

This is implemented by calling srv_take() on the server being dumped,
and only releasing it when we're done with it using srv_drop().
(drop can be delayed after function resume if buffer is full)

While the function design seems OK, it works with the assumption that
srv->next will still be valid after the function resumes, which is
not true. (especially if multiple servers are being removed in between
the 2 dumping attempts)

In practice, this did not cause any crash yet (at least this was not
reported so far), because server dumping is so fast that it is very
unlikely that multiple server deletions make their way between 2
dumping attempts in most setups. But still, this is a problem that we
need to address because some upcoming work might depend on this
assumption as well and for the moment it is not safe at all.

========================================================================

Here is a quick reproducer:

With this patch, we're creating a large deletion window of 3s as soon
as we reach a server named "t2" while iterating over the list.

This will give us plenty of time to perform multiple deletions before
the function is resumed.

    |  diff --git a/src/stats.c b/src/stats.c
    |  index 84a4f9b6e..15e49b4cd 100644
    |  --- a/src/stats.c
    |  +++ b/src/stats.c
    |  @@ -3189,11 +3189,24 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
    |                    * Temporarily increment its refcount to prevent its
    |                    * anticipated cleaning. Call free_server to release it.
    |                    */
    |  +                struct server *orig = ctx->obj2;
    |                   for (; ctx->obj2 != NULL;
    |                          ctx->obj2 = srv_drop(sv)) {
    |
    |                           sv = ctx->obj2;
    |  +                        printf("sv = %s\n", sv->id);
    |                           srv_take(sv);
    |  +                        if (!strcmp("t2", sv->id) && orig == px->srv) {
    |  +                                printf("deletion window: 3s\n");
    |  +                                thread_idle_now();
    |  +                                thread_harmless_now();
    |  +                                sleep(3);
    |  +                                thread_harmless_end();
    |  +
    |  +                                thread_idle_end();
    |  +
    |  +                                goto full; /* simulate full buffer */
    |  +                        }
    |
    |                           if (htx) {
    |                                   if (htx_almost_full(htx))
    |  @@ -4353,6 +4366,7 @@ static void http_stats_io_handler(struct appctx *appctx)
    |           struct channel *res = sc_ic(sc);
    |           struct htx *req_htx, *res_htx;
    |
    |  +        printf("http dump\n");
    |           /* only proxy stats are available via http */
    |           ctx->domain = STATS_DOMAIN_PROXY;
    |

Ok, we're ready, now we start haproxy with the following conf:

       global
          stats socket /tmp/ha.sock  mode 660  level admin  expose-fd listeners thread 1-1
          nbthread 2

       frontend stats
           mode http
           bind *:8081 thread 2-2
           stats enable
           stats uri /

       backend farm
               server t1 127.0.0.1:1899  disabled
               server t2 127.0.0.1:18999 disabled
               server t3 127.0.0.1:18998 disabled
               server t4 127.0.0.1:18997 disabled

And finally, we execute the following script:

       curl localhost:8081/stats&
       sleep .2
       echo "del server farm/t2" | nc -U /tmp/ha.sock
       echo "del server farm/t3" | nc -U /tmp/ha.sock

This should be enough to reveal the issue, I easily manage to
consistently crash haproxy with the following reproducer:

    http dump
    sv = t1
    http dump
    sv = t1
    sv = t2
    deletion window = 3s
    [NOTICE]   (2940566) : Server deleted.
    [NOTICE]   (2940566) : Server deleted.
    http dump
    sv = t2
    sv = �����U
    [1]    2940566 segmentation fault (core dumped)  ./haproxy -f ttt.conf

========================================================================

To fix this, we add prev_deleted mt_list in server struct.
For a given "visible" server, this list will contain the pending
"deleted" servers references that point to it using their 'next' ptr.

This way, whenever this "visible" server is going to be deleted via
cli_parse_delete_server() it will check for servers in its
'prev_deleted' list and update their 'next' pointer so that they no
longer point to it, and then it will push them in its
'next->prev_deleted' list to transfer the update responsibility to the
next 'visible' server (if next != NULL).

Then, following the same logic, the server about to be removed in
cli_parse_delete_server() will push itself as well into its
'next->prev_deleted' list (if next != NULL) so that it may still use its
'next' ptr for the time it is in transient removal state.

In srv_drop(), right before the server is finally freed, we make sure
to remove it from the 'next->prev_deleted' list so that 'next' won't
try to perform the pointers update for this server anymore.
This has to be done atomically to prevent 'next' srv from accessing a
purged server.

As a result:
  for a valid server, either deleted or not, 'next' ptr will always
  point to a non deleted (ie: visible) server.

With the proposed fix, and several removal combinations (including
unordered cli_parse_delete_server() and srv_drop() calls), I cannot
reproduce the crash anymore.

Example tricky removal sequence that is now properly handled:

sv list: t1,t2,t3,t4,t5,t6

ops:
   take(t2)
   del(t4)
   del(t3)
   del(t5)
   drop(t3)
   drop(t4)
   drop(t5)
   drop(t2)

2 years agoMINOR: server: add SRV_F_DELETED flag
Aurelien DARRAGON [Tue, 24 Jan 2023 13:40:01 +0000 (14:40 +0100)] 
MINOR: server: add SRV_F_DELETED flag

Set the SRV_F_DELETED flag when server is removed from the cli.

When removing a server from the cli (in cli_parse_delete_server()),
we update the "visible" server list so that the removed server is no
longer part of the list.

However, despite the server being removed from "visible" server list,
one could still access the server data from a valid ptr (ie: srv_take())

Deleted flag helps detecting when a server is in transient removal
state: that is, removed from the list, thus not visible but not yet
purged from memory.

2 years agoMINOR: stconn/applet: Add BUG_ON_HOT() to be sure SE_FL_EOS is never set alone
Christopher Faulet [Thu, 23 Mar 2023 16:30:29 +0000 (17:30 +0100)] 
MINOR: stconn/applet: Add BUG_ON_HOT() to be sure SE_FL_EOS is never set alone

SE_FL_EOS flag must never be set on the SE descriptor without SE_FL_EOI or
SE_FL_ERROR. When a mux or an applet report an end of stream, it must be
able to state if it is the end of input too or if it is an error.

Because all this part was recently refactored, especially the applet part,
it is a bit sensitive. Thus a BUG_ON_HOT() is used and not a BUG_ON().

2 years agoMINOR: tree-wide: Simplifiy some tests on SHUT flags by accessing SCs directly
Christopher Faulet [Tue, 4 Apr 2023 08:05:27 +0000 (10:05 +0200)] 
MINOR: tree-wide: Simplifiy some tests on SHUT flags by accessing SCs directly

At many places, we simplify the tests on SHUT flags to remove calls to
chn_prod() or chn_cons() function because the corresponding SC is available.

2 years agoMEDIUM: tree-wide: Move flags about shut from the channel to the SC
Christopher Faulet [Mon, 3 Apr 2023 16:32:50 +0000 (18:32 +0200)] 
MEDIUM: tree-wide: Move flags about shut from the channel to the SC

The purpose of this patch is only a one-to-one replacement, as far as
possible.

CF_SHUTR(_NOW) and CF_SHUTW(_NOW) flags are now carried by the
stream-connecter. CF_ prefix is replaced by SC_FL_ one. Of course, it is not
so simple because at many places, we were testing if a channel was shut for
reads and writes in same time. To do the same, shut for reads must be tested
on one side on the SC and shut for writes on the other side on the opposite
SC. A special care was taken with process_stream(). flags of SCs must be
saved to be able to detect changes, just like for the channels.

2 years agoMINOR: stconn/channel: Move CF_EOI into the SC and rename it
Christopher Faulet [Wed, 22 Mar 2023 13:53:11 +0000 (14:53 +0100)] 
MINOR: stconn/channel: Move CF_EOI into the SC and rename it

The channel flag CF_EOI is renamed to SC_FL_EOI and moved into the
stream-connector.

2 years agoMEDIUM: http_client: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:30:32 +0000 (11:30 +0200)] 
MEDIUM: http_client: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream. Here, the applet is a bit
refactored to handle SE descriptor EOS, EOI and ERROR flags

2 years agoMEDIUM: promex: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:29:54 +0000 (11:29 +0200)] 
MEDIUM: promex: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream.

2 years agoMEDIUM: stats: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:28:22 +0000 (11:28 +0200)] 
MEDIUM: stats: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream.

2 years agoMEDIUM: sink: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:25:55 +0000 (11:25 +0200)] 
MEDIUM: sink: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream.

2 years agoMINOR: sink: Remove the tests on the opposite SC state to process messages
Christopher Faulet [Fri, 31 Mar 2023 09:24:48 +0000 (11:24 +0200)] 
MINOR: sink: Remove the tests on the opposite SC state to process messages

The state of the opposite SC is already tested to wait the connection is
established before sending messages. So, there is no reason to test it again
before looping on the ring buffer.

2 years agoMEDIUM: peers: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:21:06 +0000 (11:21 +0200)] 
MEDIUM: peers: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream. We must just be sure to consume
request data when we are waiting the applet to be released.

2 years agoMEDIUM: log: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:17:13 +0000 (11:17 +0200)] 
MEDIUM: log: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream.

Here, the refactoring only reports errors by setting SE_FL_ERROR flag.

2 years agoMEDIUM: hlua/applet: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:13:48 +0000 (11:13 +0200)] 
MEDIUM: hlua/applet: Use the sedesc to report and detect end of processing

There are 3 kinds of applet in lua: The co-sockets, the TCP services and the
HTTP services. The three are refactored to use the SE descriptor instead of
the channel to report error and end-of-stream.

2 years agoMEDIUM: spoe: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 09:04:34 +0000 (11:04 +0200)] 
MEDIUM: spoe: Use the sedesc to report and detect end of processing

Just like for other applets, we now use the SE descriptor instead of the
channel to report error and end-of-stream. We must just be sure to consume
request data when we are waiting the applet to be released.

This patch is bit different than others because messages handling is
dispatched in several functions. But idea if the same.

2 years agoMEDIUM: dns: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 08:48:03 +0000 (10:48 +0200)] 
MEDIUM: dns: Use the sedesc to report and detect end of processing

It is now the dns turn to be refactored to use the SE descriptor instead of
the channel to report error and end-of-stream. We must just be sure to
consume request data when we are waiting the applet to be released.

2 years agoMINOR: dns: Remove the test on the opposite SC state to send requests
Christopher Faulet [Fri, 31 Mar 2023 08:42:22 +0000 (10:42 +0200)] 
MINOR: dns: Remove the test on the opposite SC state to send requests

The state of the opposite SC is already tested to wait the connection is
established before sending requests. So, there is no reason to test it again
before looping on the ring buffer.

2 years agoMEDIUM: cli: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 08:25:07 +0000 (10:25 +0200)] 
MEDIUM: cli: Use the sedesc to report and detect end of processing

It is the same kind of change than for the cache applet. Idea is to use the SE
desc instead of the channel or the SC to report end-of-input, end-of-stream and
errors.

Truncated commands are now reported on error. Other changes are the same than
for the cache applet. We now set SE_FL_EOS flag instead of calling cf_shutr()
and calls to cf_shutw are removed.

2 years agoMEDIUM: cache: Use the sedesc to report and detect end of processing
Christopher Faulet [Fri, 31 Mar 2023 08:11:39 +0000 (10:11 +0200)] 
MEDIUM: cache: Use the sedesc to report and detect end of processing

We now try, as far as possible, to rely on the SE descriptor to detect end
of processing. Idea is to no longer rely on the channel or the SC to do so.

First, we now set SE_FL_EOS instead of calling and cf_shutr() to report the
end of the stream. It happens when the response is fully sent (SE_FL_EOI is
already set in this case) or when an error is reported. In this last case,
SE_FL_ERROR is also set.

Thanks to this change, it is now possible to detect the applet must only
consume the request waiting for the upper layer releases it. So, if
SE_FL_EOS or SE_FL_ERROR are set, it means the reponse was fully
handled. And if SE_FL_SHR or SE_FL_SHW are set, it means the applet was
released by upper layer and is waiting to be freed.

2 years agoMINOR: stconn/applet: Handle EOS in the applet .wake callback function
Christopher Faulet [Tue, 21 Mar 2023 13:19:08 +0000 (14:19 +0100)] 
MINOR: stconn/applet: Handle EOS in the applet .wake callback function

Just like for end of input, the end of stream reported by the endpoint
(SE_FL_EOS flag) is now handled in sc_applet_process(). The idea is to have
applets acting as muxes by reporting events through the SE descriptor, as
far as possible.

2 years agoMINOR: applet: No longer set EOI on the SC
Christopher Faulet [Tue, 21 Mar 2023 10:52:16 +0000 (11:52 +0100)] 
MINOR: applet: No longer set EOI on the SC

Thanks to the previous patch, it is now possible for applets to not set the
CF_EOI flag on the channels. On this point, the applets get closer to the
muxes.

2 years agoMINOR: stconn/applet: Handle EOI in the applet .wake callback function
Christopher Faulet [Tue, 21 Mar 2023 10:49:21 +0000 (11:49 +0100)] 
MINOR: stconn/applet: Handle EOI in the applet .wake callback function

The end of input reported by the endpoint (SE_FL_EOI flag), is now handled
in sc_applet_process(). This function is always called after an applet was
called. So, the applets can now only report EOI on the SE descriptor and
have no reason to update the channel too.

2 years agoMINOR: stconn: Always ack EOS at the end of sc_conn_recv()
Christopher Faulet [Tue, 21 Mar 2023 10:25:21 +0000 (11:25 +0100)] 
MINOR: stconn: Always ack EOS at the end of sc_conn_recv()

EOS is now acknowledge at the end of sc_conn_recv(), even if an error was
encountered. There is no reason to not do so, especially because, if it not
performed here, it will be ack in sc_conn_process().

Note, it is still performed in sc_conn_process() because this function is
also the .wake callback function and can be directly called from the lower
layer.

2 years agoMINOR: mux-h1: Report an error to the SE descriptor on truncated message
Christopher Faulet [Wed, 29 Mar 2023 08:23:21 +0000 (10:23 +0200)] 
MINOR: mux-h1: Report an error to the SE descriptor on truncated message

On truncated message, a parsing error is still reported. But an error on the
SE descriptor is also reported. This will avoid any bugs in future. We are
know sure the SC is able to detect the error, independently on the HTTP
analyzers.

2 years agoCLEANUP: mux-h1/mux-pt: Remove useless test on SE_FL_SHR/SE_FL_SHW flags
Christopher Faulet [Wed, 29 Mar 2023 07:34:25 +0000 (09:34 +0200)] 
CLEANUP: mux-h1/mux-pt: Remove useless test on SE_FL_SHR/SE_FL_SHW flags

It is already performed by the called, sc_conn_shutr() and
sc_conn_shutw(). So there is no reason to still test these flags in the PT
and H1 muxes.

2 years agoBUG/MINOR: mux-h1: Properly report EOI/ERROR on read0 in h1_rcv_pipe()
Christopher Faulet [Thu, 23 Mar 2023 16:29:47 +0000 (17:29 +0100)] 
BUG/MINOR: mux-h1: Properly report EOI/ERROR on read0 in h1_rcv_pipe()

In h1_rcv_pipe(), only the end of stream was reported when a read0 was
detected. However, it is also important to report the end of input or an
error, depending on the message state. This patch does not fix any real
issue for now, but some others, specific to the 2.8, rely on it.

No backport needed.

2 years agoMINOR: mux-pt: Report end-of-input with the end-of-stream after a read
Christopher Faulet [Mon, 20 Mar 2023 07:25:38 +0000 (08:25 +0100)] 
MINOR: mux-pt: Report end-of-input with the end-of-stream after a read

In the PT multiplexer, the end of stream is also the end of input. Thus
we must report EOI to the stream-endpoint descriptor when the EOS is
reported. For now, it is a bit useless but it will be important to
disginguish an shutdown to an error to an abort.

To be sure to not report an EOI on an error, the errors are now handled
first.

2 years agoMINOR: stconn/channel: Move CF_EXPECT_MORE into the SC and rename it
Christopher Faulet [Fri, 17 Mar 2023 14:45:58 +0000 (15:45 +0100)] 
MINOR: stconn/channel: Move CF_EXPECT_MORE into the SC and rename it

The channel flag CF_EXPECT_MORE is renamed to SC_FL_SND_EXP_MORE and moved
into the stream-connector.

2 years agoMINOR: stconn/channel: Move CF_NEVER_WAIT into the SC and rename it
Christopher Faulet [Fri, 17 Mar 2023 14:38:18 +0000 (15:38 +0100)] 
MINOR: stconn/channel: Move CF_NEVER_WAIT into the SC and rename it

The channel flag CF_NEVER_WAIT is renamed to SC_FL_SND_NEVERWAIT and moved
into the stream-connector.

2 years agoMINOR: stconn/channel: Move CF_SEND_DONTWAIT into the SC and rename it
Christopher Faulet [Thu, 16 Mar 2023 14:53:28 +0000 (15:53 +0100)] 
MINOR: stconn/channel: Move CF_SEND_DONTWAIT into the SC and rename it

The channel flag CF_SEND_DONTWAIT is renamed to SC_FL_SND_ASAP and moved
into the stream-connector.

2 years agoMINOR: stconn/channel: Move CF_READ_DONTWAIT into the SC and rename it
Christopher Faulet [Thu, 16 Mar 2023 13:40:03 +0000 (14:40 +0100)] 
MINOR: stconn/channel: Move CF_READ_DONTWAIT into the SC and rename it

The channel flag CF_READ_DONTWAIT is renamed to SC_FL_RCV_ONCE and moved
into the stream-connector.

2 years agoMINOR: stconn: Remove unecessary test on SE_FL_EOS before receiving data
Christopher Faulet [Tue, 21 Mar 2023 09:50:16 +0000 (10:50 +0100)] 
MINOR: stconn: Remove unecessary test on SE_FL_EOS before receiving data

In sc_conn_recv(), if the EOS is reported by the endpoint, it will always be
acknowledged by the SC and a read0 will be performed on the input
channel. Thus there is no reason to still test at the begining of the
function because there is already a test on CF_SHUTR.

2 years agoBUG/MEDIUM: dns: Properly handle error when a response consumed
Christopher Faulet [Thu, 30 Mar 2023 13:49:30 +0000 (15:49 +0200)] 
BUG/MEDIUM: dns: Properly handle error when a response consumed

When a response is consumed, result for co_getblk() is never checked. It
seems ok because amount of output data is always checked first. But There is
an issue when we try to get the first 2 bytes to read the message length. If
there is only one byte followed by a shutdown, the applet ignore the
shutdown and loop till the timeout to get more data.

So to avoid any issue and improve shutdown detection, the co_getblk() return
value is always tested. In addition, if there is not enough data, the applet
explicitly ask for more data by calling applet_need_more_data().

This patch relies on the previous one:

   * BUG/MEDIUM: channel: Improve reports for shut in co_getblk()

Both should be backported as far as 2.4. On 2.5 and 2.4,
applet_need_more_data() must be replaced by si_rx_endp_more().

2 years agoBUG/MEDIUM: channel: Improve reports for shut in co_getblk()
Christopher Faulet [Thu, 30 Mar 2023 13:48:27 +0000 (15:48 +0200)] 
BUG/MEDIUM: channel: Improve reports for shut in co_getblk()

When co_getblk() is called with a length and an offset to 0, shutdown is
never reported. It may be an issue when the function is called to retrieve
all available output data, while there is no output data at all. And it
seems pretty annoying to handle this case in the caller.

Thus, now, in co_getblk(), -1 is returned when the channel is empty and a
shutdown was received.

There is no real reason to backport this patch alone. However, another fix
will rely on it.

2 years agoCLEANUP: stconn: Remove remaining debug messages
Christopher Faulet [Fri, 31 Mar 2023 08:23:27 +0000 (10:23 +0200)] 
CLEANUP: stconn: Remove remaining debug messages

It is now possible to enable traces for applets. Thus we can remove annoying
debug messages (DPRINTF) to track calls to applets.

2 years agoMEDIUM: applet/trace: Register a new trace source with its events
Christopher Faulet [Wed, 29 Mar 2023 15:42:28 +0000 (17:42 +0200)] 
MEDIUM: applet/trace: Register a new trace source with its events

Traces are now supported for applets. The first argument is always the
appctx. This will help to debug applets.

2 years agoMINOR: applet: Uninline appctx_free()
Christopher Faulet [Wed, 29 Mar 2023 15:37:48 +0000 (17:37 +0200)] 
MINOR: applet: Uninline appctx_free()

This functin is uninlined and move in src/applet.c. It is mandatory to add
traces for applets.

2 years agoBUG/MINOR: stream: Fix test on channels flags to set clientfin/serverfin touts
Christopher Faulet [Tue, 4 Apr 2023 08:16:57 +0000 (10:16 +0200)] 
BUG/MINOR: stream: Fix test on channels flags to set clientfin/serverfin touts

There is a bug in a way the channels flags are checked to set clientfin or
serverfin timeout. Indeed, to set the clientfin timeout, the request channel
must be shut for reads (CF_SHUTR) or the response channel must be shut for
writes (CF_SHUTW). As the opposite, the serverfin timeout must be set when
the request channel is shut for writes (CF_SHUTW) or the response channel is
shut for reads (CF_SHUTR).

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

2 years agoBUG/MEDIUM: stconn: Add a missing return statement in sc_app_shutr()
Christopher Faulet [Tue, 4 Apr 2023 08:06:57 +0000 (10:06 +0200)] 
BUG/MEDIUM: stconn: Add a missing return statement in sc_app_shutr()

In the commut b08c5259e ("MINOR: stconn: Always report READ/WRITE event on
shutr/shutw"), a return statement was erroneously removed from
sc_app_shutr(). As a consequence, CF_SHUTR flags was never set. Fortunately,
it is the default .shutr callback function. Thus when a connection or an
applet is attached to the SC, another callback is used to performe a
shutdown for reads.

It is a 28-dev specific issue. No backport needed.

2 years agoBUG/MINOR: tcpcheck: Be able to expect an empty response
Christopher Faulet [Mon, 20 Mar 2023 15:49:51 +0000 (16:49 +0100)] 
BUG/MINOR: tcpcheck: Be able to expect an empty response

It is not possible to successfully match an empty response. However using
regex, it should be possible to reject response with any content. For
instance:

   tcp-check expect !rstring ".+"

It may seem a be strange to do that, but it is possible, it is a valid
config. So it must work. Thanks to this patch, it is now really supported.

This patch may be backported as far as 2.2. But only if someone ask for it.

2 years agoBUG/MINOR: quic: Possible wrong PTO computing
Frédéric Lécaille [Tue, 4 Apr 2023 13:47:16 +0000 (15:47 +0200)] 
BUG/MINOR: quic: Possible wrong PTO computing

As timestamps based on now_ms values are used to compute the probing timeout,
they may wrap. So, use ticks API to compared them.

Must be backported to 2.7 and 2.6.

2 years agoBUILD: quic: 32bits compilation issue in cli_io_handler_dump_quic()
Frédéric Lécaille [Tue, 4 Apr 2023 13:09:53 +0000 (15:09 +0200)] 
BUILD: quic: 32bits compilation issue in cli_io_handler_dump_quic()

Replaced a %zu printf format by %llu for an uint64_t.

Must be backported to 2.7.

2 years agoBUG/MINOR: quic: Wrong idle timer expiration (during 20s)
Frédéric Lécaille [Tue, 4 Apr 2023 12:31:49 +0000 (14:31 +0200)] 
BUG/MINOR: quic: Wrong idle timer expiration (during 20s)

This this commit, this is ->idle_expire of quic_conn struct which must
be taken into an account to display the idel timer task expiration value:

     MEDIUM: quic: Ack delay implementation

Furthermore, this value was always zero until now_ms has wrapped (20 s after
the start time) due to this commit:
     MEDIUM: clock: force internal time to wrap early after boot

Do not rely on the value of now_ms compared to ->idle_expire to display the
difference but use ticks_remain() to compute it.

Must be backported to 2.7 where "show quic" has already been backported.

2 years agoBUG/MINOR: quic: Unexpected connection closures upon idle timer task execution
Frédéric Lécaille [Tue, 4 Apr 2023 08:46:54 +0000 (10:46 +0200)] 
BUG/MINOR: quic: Unexpected connection closures upon idle timer task execution

This bug arrived with this commit:

      MEDIUM: quic: Ack delay implementation

It is possible that the idle timer task was already in the run queue when its
->expire field was updated calling qc_idle_timer_do_rearm(). To prevent this
task from running in this condition, one must check its ->expire field value
with this condition to run the task if its timer has really expired:

!tick_is_expired(t->expire, now_ms)

Furthermore, as this task may be directly woken up with a call to task_wakeup()
all, for instance by qc_kill_conn() to kill the connection, one must check this
task has really been woken up when it was in the wait queue and not by a direct
call to task_wakeup() thanks to this test:

(state & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER

Again, when this condition is not fulfilled, the task must be run.

Must be backported where the commit mentionned above was backported.

2 years agoMINOR: quic: Add trace to debug idle timer task issues
Frédéric Lécaille [Mon, 3 Apr 2023 15:42:05 +0000 (17:42 +0200)] 
MINOR: quic: Add trace to debug idle timer task issues

Add TRACE_PROTO() call where this is relevant to debug issues about
qc_idle_timer_task() issues.

Must be backported to 2.6 and 2.7.

2 years agoDOC: config: strict-sni allows to start without certificate
William Lallemand [Tue, 4 Apr 2023 14:28:58 +0000 (16:28 +0200)] 
DOC: config: strict-sni allows to start without certificate

The strict-sni keyword allows to start without certificate on a bind
line.

Must be backported as far as 2.2.

2 years agoMINOR: http-act: emit a warning when a header field name contains forbidden chars
Willy Tarreau [Tue, 4 Apr 2023 03:25:16 +0000 (05:25 +0200)] 
MINOR: http-act: emit a warning when a header field name contains forbidden chars

As found in issue #2089, it's easy to mistakenly paste a colon in a
header name, or other chars (e.g. spaces) when quotes are in use, and
this causes all sort of trouble in field because such chars are rejected
by the peer.

Better try to detect these upfront. That's what we're doing here during
the parsing of the add-header/set-header/early-hint actions, where a
warning is emitted if a non-token character is found in a header name.
A special case is made for the colon at the beginning so that it remains
possible to place any future pseudo-headers that may appear. E.g:

  [WARNING]  (14388) : config : parsing [badchar.cfg:23] : header name 'X-Content-Type-Options:' contains forbidden character ':'.

This should be backported to 2.7, and ideally it should be turned to an
error in future versions.

2 years agoBUG/MINOR: quic: Remove useless BUG_ON() in newreno and cubic algo implementation
Frédéric Lécaille [Mon, 3 Apr 2023 11:01:58 +0000 (13:01 +0200)] 
BUG/MINOR: quic: Remove useless BUG_ON() in newreno and cubic algo implementation

As now_ms may be zero, these BUG_ON() could be triggered when its value has wrapped.
These call to BUG_ON() may be removed because the values they was supposed to
check are safely used by the ticks API.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: ssl: Undefined reference when building with OPENSSL_NO_DEPRECATED
Remi Tricot-Le Breton [Mon, 3 Apr 2023 09:17:26 +0000 (11:17 +0200)] 
BUG/MINOR: ssl: Undefined reference when building with OPENSSL_NO_DEPRECATED

If OPENSSL_NO_DEPRECATED is set, we get a 'error: ‘RSA_PKCS1_PADDING’
undeclared' when building jwt.c. The symbol is not deprecated, we are
just missing an include.

This was raised in GitHub issue #2098.
It does not need to be backported.

2 years agoBUG/MAJOR: quic: Congestion algorithms states shared between the connection
Frédéric Lécaille [Sun, 2 Apr 2023 10:43:22 +0000 (12:43 +0200)] 
BUG/MAJOR: quic: Congestion algorithms states shared between the connection

This very old bug is there since the first implementation of newreno congestion
algorithm implementation. This was a very bad idea to put a state variable
into quic_cc_algo struct which only defines the congestion control algorithm used
by a QUIC listener, typically its type and its callbacks.
This bug could lead to crashes since BUG_ON() calls have been added to each algorithm
implementation. This was revealed by interop test, but not very often as there was
not very often several connections run at the time during these tests.

Hopefully this was also reported by Tristan in GH #2095.

Move the congestion algorithm state to the correct structures which are private
to a connection (see cubic and nr structs).

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add missing traces in cubic algorithm implementation
Frédéric Lécaille [Sun, 2 Apr 2023 08:49:35 +0000 (10:49 +0200)] 
MINOR: quic: Add missing traces in cubic algorithm implementation

May be useful to debug.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: quic: Cubic congestion control window may wrap
Frédéric Lécaille [Sun, 2 Apr 2023 08:07:48 +0000 (10:07 +0200)] 
BUG/MINOR: quic: Cubic congestion control window may wrap

Add a check to prevent the cubic congestion control from wrapping (very low risk)
in slow start callback.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: quic: Remaining useless statements in cubic slow start callback
Frédéric Lécaille [Fri, 31 Mar 2023 18:18:44 +0000 (20:18 +0200)] 
BUG/MINOR: quic: Remaining useless statements in cubic slow start callback

When entering a recovery period, the algo state is set by quic_enter_recovery().
And that's it!. These two lines should have been removed with this commit:

     BUG/MINOR: quic: Wrong use of now_ms timestamps (cubic algo)

Take the opportunity of this patch to add a missing TRACE_LEAVE() call in
quic_cc_cubic_ca_cb().

Must be backported to 2.7 and 2.6.

2 years agoCI: exclude doc/{design-thoughts,internals} from spell check
Ilya Shipitsin [Sat, 1 Apr 2023 10:27:31 +0000 (12:27 +0200)] 
CI: exclude doc/{design-thoughts,internals} from spell check

as those directories do contain many documents written in French,
codespell is catching a lot of false positives scanning them.

2 years agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Sat, 1 Apr 2023 10:26:42 +0000 (12:26 +0200)] 
CLEANUP: assorted typo fixes in the code and comments

This is 35th iteration of typo fixes

2 years agoCI: run smoke tests on config syntax to check memory related issues
Ilya Shipitsin [Sat, 1 Apr 2023 11:29:46 +0000 (13:29 +0200)] 
CI: run smoke tests on config syntax to check memory related issues

config syntax check seems add a value on testing code path not
covered by VTest, also checks are very fast

2 years agoMINOR: quic: Add a fake congestion control algorithm named "nocc"
Frédéric Lécaille [Fri, 31 Mar 2023 13:21:55 +0000 (15:21 +0200)] 
MINOR: quic: Add a fake congestion control algorithm named "nocc"

This algorithm does nothing except initializing the congestion control window
to a fixed value. Very smart!

Modify the QUIC congestion control configuration parser to support this new
algorithm. The congestion control algorithm must be set as follows:

     quic-cc-algo nocc-<cc window size(KB))

For instance if "nocc-15" is provided as quic-cc-algo keyword value, this
will set a fixed window of 15KB.

2 years agoMINOR: cli: support filtering on FD types in "show fd"
Willy Tarreau [Fri, 31 Mar 2023 14:33:53 +0000 (16:33 +0200)] 
MINOR: cli: support filtering on FD types in "show fd"

Depending on what we're debugging, some FDs can represent pollution in
the "show fd" output. Here we add a set of filters allowing to pick (or
exclude) any combination of listener, frontend conn, backend conn, pipes,
etc. "show fd l" will only list listening connections for example.

2 years agoBUG/MINOR: quic: Wrong rtt variance computing
Frédéric Lécaille [Thu, 30 Mar 2023 13:31:06 +0000 (15:31 +0200)] 
BUG/MINOR: quic: Wrong rtt variance computing

In ->srtt quic_loss struct this is 8*srtt which is stored so that not to have to multiply/devide
it to compute the RTT variance (at least). This is where there was a bug in quic_loss_srtt_update():
each time ->srtt must be used, it must be devided by 8 or right shifted by 3.
This bug had a very bad impact for network with non negligeable packet loss.

Must be backported to 2.6 and 2.7.

2 years agoMEDIUM: quic: Ack delay implementation
Frédéric Lécaille [Fri, 24 Mar 2023 17:13:37 +0000 (18:13 +0100)] 
MEDIUM: quic: Ack delay implementation

Reuse the idle timeout task to delay the acknowledgments. The time of the
idle timer expiration is for now on stored in ->idle_expire. The one to
trigger the acknowledgements is stored in ->ack_expire.
Add QUIC_FL_CONN_ACK_TIMER_FIRED new connection flag to mark a connection
as having its acknowledgement timer been triggered.
Modify qc_may_build_pkt() to prevent the sending of "ack only" packets and
allows the connection to send packet when the ack timer has fired.
It is possible that acks are sent before the ack timer has triggered. In
this case it is cancelled only if ACK frames are really sent.
The idle timer expiration must be set again when the ack timer has been
triggered or when it is cancelled.

Must be backported to 2.7.

2 years agoMINOR: quic: Traces adjustments at proto level.
Frédéric Lécaille [Fri, 24 Mar 2023 14:14:45 +0000 (15:14 +0100)] 
MINOR: quic: Traces adjustments at proto level.

Dump variables displayed by TRACE_ENTER() or TRACE_LEAVE() by calls to TRACE_PROTO().
No more variables are displayed by the two former macros. For now on, these information
are accessible from proto level.
Add new calls to TRACE_PROTO() at important locations in relation whith QUIC transport
protocol.
When relevant, try to prefix such traces with TX or RX keyword to identify the
concerned subpart (transmission or reception) of the protocol.

Must be backported to 2.7.

2 years agoMINOR: quic: Adjustments for generic control congestion traces
Frédéric Lécaille [Fri, 24 Mar 2023 13:16:28 +0000 (14:16 +0100)] 
MINOR: quic: Adjustments for generic control congestion traces

Display the elapsed time since packets were sent in place of the timestamp which
do not bring easy to read information.

Must be backported to 2.7.

2 years agoMINOR: quic: Implement cubic state trace callback
Frédéric Lécaille [Fri, 24 Mar 2023 13:09:55 +0000 (14:09 +0100)] 
MINOR: quic: Implement cubic state trace callback

This callback was left as not implemented. It should at least display
the algorithm state, the control congestion window the slow start threshold
and the time of the current recovery period. Should be helpful to debug.

Must be backported to 2.7.

2 years agoBUG/MINOR: quic: Missing max_idle_timeout initialization for the connection
Frédéric Lécaille [Wed, 22 Mar 2023 10:29:45 +0000 (11:29 +0100)] 
BUG/MINOR: quic: Missing max_idle_timeout initialization for the connection

This bug was revealed by handshakeloss interop tests (often with quiceh) where one
could see haproxy an Initial packet without TLS ClientHello message (only a padded
PING frame). In this case, as the ->max_idle_timeout was not initialized, the
connection was closed about three seconds later, and haproxy opened a new one with
a new source connection ID upon receipt of the next client Initial packet. As the
interop runner count the number of source connection ID used by the server to check
there were exactly 50 such IDs used by the server, it considered the test as failed.

So, the ->max_idle_timeout of the connection must be at least initialized
to the local "max_idle_timeout" transport parameter value to avoid such
a situation (closing connections too soon) until it is "negotiated" with the
client when receiving its TLS ClientHello message.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: quic: Wrong use of now_ms timestamps (newreno algo)
Frédéric Lécaille [Wed, 22 Mar 2023 08:13:14 +0000 (09:13 +0100)] 
BUG/MINOR: quic: Wrong use of now_ms timestamps (newreno algo)

This patch is similar to the one for cubic algorithm:
    "BUG/MINOR: quic: Wrong use of timestamps with now_ms variable (cubic algo)"

As now_ms may wrap, one must use the ticks API to protect the cubic congestion
control algorithm implementation from side effects due to this.

Furthermore, to make the newreno congestion control algorithm more readable and easy
to maintain, add quic_cc_cubic_rp_cb() new callback for the "in recovery period"
state (QUIC_CC_ST_RP).

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add recovery related information to "show quic"
Frédéric Lécaille [Tue, 21 Mar 2023 12:42:43 +0000 (13:42 +0100)] 
MINOR: quic: Add recovery related information to "show quic"

Add ->srtt, ->rtt_var, ->rtt_min and ->pto_count values from ->path->loss
struct to "show quic". Same thing for ->cwnd from ->path struct.

Also take the opportunity of this patch to dump the packet number
space information directly from ->pktns[] array in place of ->els[]
array. Indeed, ->els[QUIC_TLS_ENC_LEVEL_EARLY_DATA] and ->els[QUIC_TLS_ENC_LEVEL_APP]
have the same packet number space.

Must be backported to 2.7 where "show quic" implementation has alredy been
backported.

2 years agoBUG/MINOR: quic: Wrong use of now_ms timestamps (cubic algo)
Frédéric Lécaille [Tue, 21 Mar 2023 10:54:02 +0000 (11:54 +0100)] 
BUG/MINOR: quic: Wrong use of now_ms timestamps (cubic algo)

As now_ms may wrap, one must use the ticks API to protect the cubic congestion
control algorithm implementation from side effects due to this.

Furthermore to make the cubic congestion control algorithm more readable and easy
to maintain, adding a new state ("in recovery period" QUIC_CC_ST_RP new enum) helps
in reaching this goal. Implement quic_cc_cubic_rp_cb() which is the callback for
this new state.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: ssl: ssl-(min|max)-ver parameter not duplicated for bundles in crt-list
Remi Tricot-Le Breton [Tue, 14 Mar 2023 16:22:24 +0000 (17:22 +0100)] 
BUG/MINOR: ssl: ssl-(min|max)-ver parameter not duplicated for bundles in crt-list

If a bundle is used in a crt-list, the ssl-min-ver and ssl-max-ver
options were not taken into account in entries other than the first one
because the corresponding fields in the ssl_bind_conf structure were not
copied in crtlist_dup_ssl_conf.

This should fix GitHub issue #2069.
This patch should be backported up to 2.4.

2 years agoBUG/MINOR: ssl: Fix potential leak in cli_parse_update_ocsp_response
Remi Tricot-Le Breton [Tue, 21 Mar 2023 09:28:34 +0000 (10:28 +0100)] 
BUG/MINOR: ssl: Fix potential leak in cli_parse_update_ocsp_response

In some extremely unlikely case (or even impossible for now), we might
exit cli_parse_update_ocsp_response without raising an error but with a
filled 'err' buffer. It was not properly free'd.

It does not need to be backported.

2 years agoBUG/MINOR: ssl: Remove dead code in cli_parse_update_ocsp_response
Remi Tricot-Le Breton [Tue, 21 Mar 2023 09:26:20 +0000 (10:26 +0100)] 
BUG/MINOR: ssl: Remove dead code in cli_parse_update_ocsp_response

This patch removes dead code from the cli_parse_update_ocsp_response
function. The 'end' label in only used in case of error so the check of
the 'errcode' variable and the errcode variable itself become useless.

This patch does not need to be backported.
It fixes GitHub issue #2077.

2 years agoBUG/MINOR: backend: make be_usable_srv() consistent when stopping
Aurelien DARRAGON [Thu, 30 Mar 2023 16:03:21 +0000 (18:03 +0200)] 
BUG/MINOR: backend: make be_usable_srv() consistent when stopping

When a proxy enters the STOPPED state, it will no longer accept new
connections.

However, it doesn't mean that it's completely inactive yet: it will
still be able to handle already pending / keep-alive connections,
thus finishing ongoing work before effectively stopping.

be_usable_srv(), which is used by nbsrv converter and sample fetch,
will return 0 if the proxy is either stopped or disabled.

nbsrv behaves this way since it was originally implemented in b7e7c4720
("MINOR: Add nbsrv sample converter").

(Since then, multiple refactors were performed around this area, but
the current implementation still follows the same logic)

It was found that if nbsrv is used in a proxy section to perform routing
logic, unexpected decisions are being made when nbsrv is used on a proxy
with STOPPED state, since in-flight requests will suffer from nbsrv
returning 0 instead of the current number of usable servers which may
still process existing connections.
For instance, this can happen during process soft-stop, or even when
stopping the proxy from the cli / lua.

To fix this: we now make sure be_usable_srv() always returns the
current number of usable servers, unless the proxy is explicitly
disabled (from the config, not at runtime)

This could be backported up to 2.6.
For older versions, the need for a backport should be evaluated first.

--
Note for 2.4: proxy flags did not exist, it was implemented with fd10ab5e
("MINOR: proxy: Introduce proxy flags to replace disabled bitfield")

For 2.2: STOPPED and DISABLED states were not separated, so we have no
easy way to apply the fix anyway.

2 years agoBUG/MEDIUM: proxy/sktable: prevent watchdog trigger on soft-stop
Aurelien DARRAGON [Wed, 29 Mar 2023 14:18:50 +0000 (16:18 +0200)] 
BUG/MEDIUM: proxy/sktable: prevent watchdog trigger on soft-stop

During soft-stop, manage_proxy() (p->task) will try to purge
trashable (expired and not referenced) sticktable entries,
effectively releasing the process memory to leave some space
for new processes.

This is done by calling stktable_trash_oldest(), immediately
followed by a pool_gc() to give the memory back to the OS.

As already mentioned in dfe7925 ("BUG/MEDIUM: stick-table:
limit the time spent purging old entries"), calling
stktable_trash_oldest() with a huge batch can result in the function
spending too much time searching and purging entries, and ultimately
triggering the watchdog.

Lately, an internal issue was reported in which we could see
that the watchdog is being triggered in stktable_trash_oldest()
on soft-stop (thus initiated by manage_proxy())

According to the report, the crash seems to only occur since 5938021
("BUG/MEDIUM: stick-table: do not leave entries in end of window during purge")

This could be the result of stktable_trash_oldest() now working
as expected, and thus spending a large amount of time purging
entries when called with a large enough <to_batch>.

Instead of adding new checks in stktable_trash_oldest(), here we
chose to address the issue directly in manage_proxy().

Since the stktable_trash_oldest() function is called with
<to_batch> == <p->table->current>, it's pretty obvious that it could
cause some issues during soft-stop if a large table, assuming it is
full prior to the soft-stop, suddenly sees most of its entries
becoming trashable because of the soft-stop.

Moreover, we should note that the call to stktable_trash_oldest() is
immediately followed by a call to pool_gc():

We know for sure that pool_gc(), as it involves malloc_trim() on
glibc, is rather expensive, and the more memory to reclaim,
the longer the call.

We need to ensure that both stktable_trash_oldest() + consequent
pool_gc() call both theoretically fit in a single task execution window
to avoid contention, and thus prevent the watchdog from being triggered.

To do this, we now allocate a "budget" for each purging attempt.
budget is maxed out to 32K, it means that each sticktable cleanup
attempt will trash at most 32K entries.

32K value is quite arbitrary here, and might need to be adjusted or
even deducted from other parameters if this fails to properly address
the issue without introducing new side-effects.
The goal is to find a good balance between the max duration of each
cleanup batch and the frequency of (expensive) pool_gc() calls.

If most of the budget is actually spent trashing entries, then the task
will immediately be rescheduled to continue the purge.
This way, the purge is effectively batched over multiple task runs.

This may be slowly backported to all stable versions.
[Please note that this commit depends on 6e1fe25 ("MINOR: proxy/pool:
prevent unnecessary calls to pool_gc()")]

2 years agoREGTESTS : Add test support for case insentitive for url_param
Martin DOLEZ [Thu, 30 Mar 2023 13:03:36 +0000 (09:03 -0400)] 
REGTESTS : Add test support for case insentitive for url_param

Test using case insensitive is supported in /reg-tests/http-rules/h1or2_to_h1c.vtc

2 years agoMINOR: http_fetch: Add case-insensitive argument for url_param/urlp_val
Martin DOLEZ [Tue, 28 Mar 2023 13:06:05 +0000 (09:06 -0400)] 
MINOR: http_fetch: Add case-insensitive argument for url_param/urlp_val

This commit adds a new optional argument to smp_fetch_url_param
and smp_fetch_url_param_val that makes the parameter key comparison
case-insensitive.
Now users can retrieve URL parameters regardless of their case,
allowing to match parameters in case insensitive application.
Doc was updated.

2 years agoMINOR: http_fetch: add case insensitive support for smp_fetch_url_param
Martin DOLEZ [Tue, 28 Mar 2023 13:06:05 +0000 (09:06 -0400)] 
MINOR: http_fetch: add case insensitive support for smp_fetch_url_param

This commit adds a new argument to smp_fetch_url_param
that makes the parameter key comparison case-insensitive.
Several levels of callers were modified to pass this info.

2 years agoMINOR: http_fetch: Add support for empty delim in url_param
Martin DOLEZ [Tue, 28 Mar 2023 13:49:53 +0000 (09:49 -0400)] 
MINOR: http_fetch: Add support for empty delim in url_param

In prevision of adding a third parameter to the url_param
sample-fetch function we need to make the second parameter optional.
User can now pass a empty 2nd argument to keep the default delimiter.

2 years agoDOC/MINOR: reformat configuration.txt's "quoting and escaping" table
Marcos de Oliveira [Fri, 17 Mar 2023 14:03:13 +0000 (11:03 -0300)] 
DOC/MINOR: reformat configuration.txt's "quoting and escaping" table

The table in section 2.2 ("Quoting and escaping") was formated in a way
which is not recognized by haproxy-dconv, breaking it, and cutting off
the entire section.
This commit fix that by formatting the table in way which allows the
converter to produce the correct HTML.

Fixes cbonte/haproxy-dconv#35

2 years agoCLEANUP: proxy: remove stop_time related dead code
Aurelien DARRAGON [Tue, 28 Mar 2023 13:45:53 +0000 (15:45 +0200)] 
CLEANUP: proxy: remove stop_time related dead code

Since eb77824 ("MEDIUM: proxy: remove the deprecated "grace" keyword"),
stop_time is never set, so the related code in manage_proxy() is not
relevant anymore.

Removing code that refers to p->stop_time, since it was probably
overlooked.

2 years agoMINOR: proxy/pool: prevent unnecessary calls to pool_gc()
Aurelien DARRAGON [Tue, 28 Mar 2023 13:14:48 +0000 (15:14 +0200)] 
MINOR: proxy/pool: prevent unnecessary calls to pool_gc()

Under certain soft-stopping conditions (ie: sticktable attached to proxy
and in-progress connections to the proxy that prevent haproxy from
exiting), manage_proxy() (p->task) will wake up every second to perform
a cleanup attempt on the proxy sticktable (to purge unused entries).

However, as reported by TimWolla in GH #2091, it was found that a
systematic call to pool_gc() could cause some CPU waste, mainly
because malloc_trim() (which is rather expensive) is being called
for each pool_gc() invocation.

As a result, such soft-stopping process could be spending a significant
amount of time in the malloc_trim->madvise() syscall for nothing.

Example "strace -c -f -p `pidof haproxy`" output (taken from
Tim's report):

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 46.77    1.840549        3941       467         1 epoll_wait
 43.82    1.724708          13    128509           sched_yield
  8.82    0.346968          11     29696           madvise
  0.58    0.023011          24       951           clock_gettime
  0.01    0.000257          10        25         7 recvfrom
  0.00    0.000033          11         3           sendto
  0.00    0.000021          21         1           rt_sigreturn
  0.00    0.000021          21         1           timer_settime
------ ----------- ----------- --------- --------- ----------------
100.00    3.935568          24    159653         8 total

To prevent this, we now only call pool_gc() when some memory is
really expected to be reclaimed as a direct result of the previous
stick table cleanup.
This is pretty straightforward since stktable_trash_oldest() returns
the number of trashed sticky sessions.

This may be backported to every stable versions.

2 years agoBUG/MINOR: quic: Missing padding in very short probe packets
Frédéric Lécaille [Tue, 28 Mar 2023 13:39:11 +0000 (15:39 +0200)] 
BUG/MINOR: quic: Missing padding in very short probe packets

This bug arrived with this commit:
   MINOR: quic: Send PING frames when probing Initial packet number space

This may happen when haproxy needs to probe the peer with very short packets
(only one PING frame). In this case, the packet must be padded. There was clearly
a case which was removed by the mentionned commit above. That said, there was
an extra byte which was added to the PADDING frame before the mentionned commit
above. This is no more the case with this patch.

Thank you to @tatsuhiro-t (ngtcp2 manager) for having reported this issue which
was revealed by the keyupdate test (on client side).

Must be backported to 2.7 and 2.6.

2 years agoBUG/MEDIUM: mux-h2: Be able to detect connection error during handshake
Christopher Faulet [Tue, 28 Mar 2023 10:16:53 +0000 (12:16 +0200)] 
BUG/MEDIUM: mux-h2: Be able to detect connection error during handshake

When a backend H2 connection is waiting the connection is fully established,
nothing is sent. However, it remains useful to detect connection error at
this stage. It is especially important to release H2 connection on connect
error. Be able to set H2_CF_ERR_PENDiNG or H2_CF_ERROR flags when the
underlying connection is not fully established will exclude the H2C to be
inserted in a idle list in h2_detach().

Without this fix, an H2C in PREFACE state and relying on a connection in
error can be inserted in the safe list. Of course, it will be purged if not
reused. But in the mean time, it can be reused. When this happens, the
connection remains in error and nothing happens. At the end a connection
error is returned to the client. On low traffic, we can imagine a scenario
where this dead connection is the only idle connection. If it is always
reused before being purged, no connection to the server is possible.

In addition, h2c_is_dead() is updated to declare as dead any H2 connection
with a pending error if its state is PREFACE or SETTINGS1 (thus if no
SETTINGS frame was received yet).

This patch should fix the issue #2092. It must be backported as far as 2.6.

2 years agoBUG/MINOR: stats: Don't replace sc_shutr() by SE_FL_EOS flag yet
Christopher Faulet [Tue, 28 Mar 2023 10:02:03 +0000 (12:02 +0200)] 
BUG/MINOR: stats: Don't replace sc_shutr() by SE_FL_EOS flag yet

In commit c2c043ed4 ("BUG/MEDIUM: stats: Consume the request except when
parsing the POST payload"), a change about applet was pushed too early. The
applet must still call cf_shutr() when the response is fully sent. It is
planned to rely on SE_FL_EOS flag, just like connections. But it is not
possible for now.

However, at first glance, this bug has no visible effect.

It is 2.8-specific. No backport needed.

2 years ago[RELEASE] Released version 2.8-dev6 v2.8-dev6
Willy Tarreau [Tue, 28 Mar 2023 11:58:56 +0000 (13:58 +0200)] 
[RELEASE] Released version 2.8-dev6

Released version 2.8-dev6 with the following main changes :
    - BUG/MEDIUM: mux-pt: Set EOS on error on sending path if read0 was received
    - MINOR: ssl: Change the ocsp update log-format
    - MINOR: ssl: Use ocsp update task for "update ssl ocsp-response" command
    - BUG/MINOR: ssl: Fix double free in ocsp update deinit
    - MINOR: ssl: Accept certpath as param in "show ssl ocsp-response" CLI command
    - MINOR: ssl: Add certificate path to 'show ssl ocsp-response' output
    - BUG/MEDIUM: proxy: properly stop backends on soft-stop
    - BUG/MEDIUM: resolvers: Properly stop server resolutions on soft-stop
    - DEBUG: cli/show_fd: Display connection error code
    - DEBUG: ssl-sock/show_fd: Display SSL error code
    - BUG/MEDIUM: mux-h1: Don't block SE_FL_ERROR if EOS is not reported on H1C
    - BUG/MINOR: tcp_sample: fix a bug in fc_dst_port and fc_dst_is_local sample fetches
    - BUG/MINOR: quic: Missing STREAM frame length updates
    - BUG/MEDIUM: connection: Preserve flags when a conn is removed from an idle list
    - BUG/MINOR: mux-h2: make sure the h2c task exists before refreshing it
    - MINOR: buffer: add br_count() to return the number of allocated bufs
    - MINOR: buffer: add br_single() to check if a buffer ring has more than one buf
    - BUG/MEDIUM: mux-h2: only restart sending when mux buffer is decongested
    - BUG/MINOR: mux-h2: set CO_SFL_STREAMER when sending lots of data
    - BUG/MINOR: quic: Missing STREAM frame data pointer updates
    - MINOR: stick-table: add sc-add-gpc() to http-after-response
    - MINOR: doc: missing entries for sc-add-gpc()
    - BUG/MAJOR: qpack: fix possible read out of bounds in static table
    - OPTIM: mux-h1: limit first read size to avoid wrapping
    - MINOR: mux-h2: set CO_SFL_MSG_MORE when sending multiple buffers
    - MINOR: ssl-sock: pass the CO_SFL_MSG_MORE info down the stack
    - MINOR: quic: Stop stressing the acknowledgments process (RX ACK frames)
    - BUG/MINOR: quic: Dysfunctional 01RTT packet number space probing
    - BUG/MEDIUM: stream: do not try to free a failed stream-conn
    - BUG/MEDIUM: mux-h2: do not try to free an unallocated h2s->sd
    - BUG/MEDIUM: mux-h2: erase h2c->wait_event.tasklet on error path
    - BUG/MEDIUM: stconn: don't set the type before allocation succeeds
    - BUG/MINOR: stconn: fix sedesc memory leak on stream allocation failure
    - MINOR: dynbuf: set POOL_F_NO_FAIL on buffer allocation
    - MINOR: pools: preset the allocation failure rate to 1% with -dMfail
    - BUG/MEDIUM: mux-h1: properly destroy a partially allocated h1s
    - BUG/MEDIUM: applet: only set appctx->sedesc on successful allocation
    - BUG/MINOR: quic: wake up MUX on probing only for 01RTT
    - BUG/MINOR: quic: ignore congestion window on probing for MUX wakeup
    - BUILD: thread: implement thread_harmless_end_sig() for threadless builds
    - BUILD: thread: silence a build warning when threads are disabled
    - MINOR: debug: support dumping the libs addresses when running in verbose mode
    - BUG/MINOR: illegal use of the malloc_trim() function if jemalloc is used
    - BUG/MINOR: trace: fix hardcoded level for TRACE_PRINTF
    - BUG/MEDIUM: mux-quic: release data from conn flow-control on qcs reset
    - MINOR: mux-quic: complete traces for qcs emission
    - MINOR: mux-quic: adjust trace level for MAX_DATA/MAX_STREAM_DATA recv
    - MINOR: mux-quic: add flow-control info to minimal trace level
    - MINOR: pools: make sure 'no-memory-trimming' is always used
    - MINOR: pools: intercept malloc_trim() instead of trying to plug holes
    - MEDIUM: pools: move the compat code from trim_all_pools() to malloc_trim()
    - MINOR: pools: export trim_all_pools()
    - MINOR: pattern: use trim_all_pools() instead of a conditional malloc_trim()
    - MINOR: tools: relax dlopen() on malloc/free checks
    - MEDIUM: tools: further relax dlopen() checks too consider grouped symbols
    - BUG/MINOR: pools: restore detection of built-in allocator
    - MINOR: pools: report a replaced memory allocator instead of just malloc_trim()
    - BUG/MINOR: h3: properly handle incomplete remote uni stream type
    - BUG/MINOR: mux-quic: prevent CC status to be erased by shutdown
    - MINOR: mux-quic: interrupt qcc_recv*() operations if CC scheduled
    - MINOR: mux-quic: ensure CONNECTION_CLOSE is scheduled once per conn
    - MINOR: mux-quic: close on qcs allocation failure
    - MINOR: mux-quic: close on frame alloc failure
    - BUG/MINOR: syslog: Request for more data if message was not fully received
    - BUG/MEDIUM: stats: Consume the request except when parsing the POST payload
    - DOC: config: set-var() dconv rendering issues
    - BUG/MEDIUM: mux-h1: Wakeup H1C on shutw if there is no I/O subscription
    - BUG/MINOR: applet/new: fix sedesc freeing logic
    - BUG/MINOR: quic: Missing STREAM frame type updated
    - BUILD: da: extends CFLAGS to support API v3 from 3.1.7 and onwards.
    - BUG/MINOR: ssl: Stop leaking `err` in ssl_sock_load_ocsp()

2 years agoBUG/MINOR: ssl: Stop leaking `err` in ssl_sock_load_ocsp()
Tim Duesterhus [Sun, 19 Mar 2023 15:07:47 +0000 (16:07 +0100)] 
BUG/MINOR: ssl: Stop leaking `err` in ssl_sock_load_ocsp()

Previously performing a config check of `.github/h2spec.config` would report a
20 byte leak as reported in GitHub Issue #2082.

The leak was introduced in a6c0a59e9af65180c3ff591b91855bea8d19b352, which is
dev only. No backport needed.

2 years agoBUILD: da: extends CFLAGS to support API v3 from 3.1.7 and onwards.
David Carlier [Tue, 28 Mar 2023 05:24:49 +0000 (06:24 +0100)] 
BUILD: da: extends CFLAGS to support API v3 from 3.1.7 and onwards.

Minor build update to still both support the v2 and v3 api from
the 3.1.7 release which supports a cache but would need a shift
in the HAProxy build not necessary at the moment.
In the second half of the year and for the next major HAProxy release
branch, v2 could be dropped altogether thus the next HAProxy 2.9
major release will contain more changes towards the v3 support
and reminder for the v2 EOL.

To be backported.

2 years agoBUG/MINOR: quic: Missing STREAM frame type updated
Frédéric Lécaille [Mon, 20 Mar 2023 13:32:59 +0000 (14:32 +0100)] 
BUG/MINOR: quic: Missing STREAM frame type updated

This patch follows this commit which was not sufficient:
  BUG/MINOR: quic: Missing STREAM frame data pointer updates

Indeed, after updating the ->offset field, the bit which informs the
frame builder of its presence must be systematically set.

This bug was revealed by the following BUG_ON() from
quic_build_stream_frame() :
  bug condition "!!(frm->type & 0x04) != !!stream->offset.key" matched at src/quic_frame.c:515

This should fix the last crash occured on github issue #2074.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: applet/new: fix sedesc freeing logic
Aurelien DARRAGON [Fri, 24 Mar 2023 09:01:19 +0000 (10:01 +0100)] 
BUG/MINOR: applet/new: fix sedesc freeing logic

Since 465a6c8 ("BUG/MEDIUM: applet: only set appctx->sedesc on
successful allocation"), sedesc is attached to the appctx after the
task is successfully allocated.

If the task fails to allocate: current sedesc cleanup is performed
on appctx->sedesc which still points to NULL so sedesc won't be
freed.
This is fine when sedesc is provided as argument (!=NULL), but leads
to memory leaks if sedesc is allocated locally.

It was shown in GH #2086 that if sedesc != NULL when passed as
argument, it shouldn't be freed on error paths. This is what 465a6c8
was trying to address.

In an attempt to fix both issues at once, we do as Christopher
suggested: that is moving sedesc allocation attempt at the
end of the function, so that we don't have to free it in case
of error, thus removing the ambiguity.
(We won't risk freeing a sedesc that does not belong to us)

If we fail to allocate sedesc, then the task that was previously
created locally is simply destroyed.

This needs to be backported to 2.6 with 465a6c8 ("BUG/MEDIUM: applet:
only set appctx->sedesc on successful allocation")
[Copy pasting the original backport note from Willy:
In 2.6 the function is slightly
different and called appctx_new(), though the issue is exactly the
same.]

2 years agoBUG/MEDIUM: mux-h1: Wakeup H1C on shutw if there is no I/O subscription
Christopher Faulet [Fri, 24 Mar 2023 08:26:16 +0000 (09:26 +0100)] 
BUG/MEDIUM: mux-h1: Wakeup H1C on shutw if there is no I/O subscription

This old bug was revealed because of the commit 407210a34 ("BUG/MEDIUM:
stconn: Don't rearm the read expiration date if EOI was reached"). But it is
still possible to hit it if there is no server timeout. At first glance, the
2.8 is not affected. But the fix remains valid.

When a shutdown for writes if performed the H1 connection must be notified
to be released. If it is subscribed for any I/O events, it is not an
issue. But, if there is no subscription, no I/O event is reported to the H1
connection and it remains alive. If the message was already fully received,
nothing more happens.

On my side, I was able to trigger the bug by freezing the session. Some
users reported a spinning loop on process_stream(). Not sure how to trigger
the loop. To freeze the session, the client timeout must be reached while
the server response was already fully received. On old version (< 2.6), it
only happens if there is no server timeout.

To fix the issue, we must wake up the H1 connection on shutdown for writes
if there is no I/O subscription.

This patch must be backported as far as 2.0. It should fix the issue #2090
and #2088.

2 years agoDOC: config: set-var() dconv rendering issues
Aurelien DARRAGON [Thu, 23 Mar 2023 10:54:44 +0000 (11:54 +0100)] 
DOC: config: set-var() dconv rendering issues

Since <cond> optional argument support was added to set-var() and friends
in 2.6 with 164726c ("DOC: vars: Add documentation about the set-var
conditions"), dconv is having a hard time rendering related keywords.

Everywhere `[,<cond> ...]` was inserted, html formatting is now broken.

Removing the space between <cond> and '...' allows dconv to properly parse
the token thus restores proper formatting without changing the meaning.

This was discovered when discussing about var() sample fetch doc issues
in GH #2087

This patch should be backported up to 2.6

2 years agoBUG/MEDIUM: stats: Consume the request except when parsing the POST payload
Christopher Faulet [Wed, 22 Mar 2023 08:30:40 +0000 (09:30 +0100)] 
BUG/MEDIUM: stats: Consume the request except when parsing the POST payload

The stats applet is designed to consume the request at the end, when it
finishes to send the response. And during the response forwarding, because
the request is not consumed, the applet states it will not consume
data. This avoid to wake the applet up in loop. When it finishes to send the
response, the request is consumed.

For POST requests, there is no issue because the response is small
enough. It is sent in one time and must be processed by HTTP analyzers. Thus
the forwarding is not performed by the applet itself. The applet is always
able to consume the request, regardless the payload length.

But for other requests, it may be an issue. If the response is too big to be
sent in one time and if the requests is not fully received when the response
headers are sent, the applet may be blocked infinitely, not consuming the
request. Indeed, in the case the applet will be switched in infinite forward
mode, the request will not be consumed immediately. At the end, the request
buffer is flushed. But if some data must still be received, the applet is not
woken up because it is still in a "not-consuming" mode.

So, to fix the issue, we must take care to re-enable data consuming when the
end of the response is reached.

This patch must be backported as far as 2.6.

2 years agoBUG/MINOR: syslog: Request for more data if message was not fully received
Christopher Faulet [Thu, 16 Mar 2023 13:27:29 +0000 (14:27 +0100)] 
BUG/MINOR: syslog: Request for more data if message was not fully received

In the syslog applet, when a message was not fully received, we must request
for more data by calling appctx_need_more_data() and not by setting
CF_READ_DONTWAIT flag on the request channel. Indeed, this flag is only used
to only try a read at once.

This patch could be backported as far as 2.4. On 2.5 and 2.4,
applet_need_more_data() must be replaced by si_cant_get().

2 years agoMINOR: mux-quic: close on frame alloc failure
Amaury Denoyelle [Thu, 9 Mar 2023 09:16:38 +0000 (10:16 +0100)] 
MINOR: mux-quic: close on frame alloc failure

Replace all BUG_ON() on frame allocation failure by a CONNECTION_CLOSE
sending with INTERNAL_ERROR code. This can happen for the following
cases :
* sending of MAX_STREAM_DATA
* sending of MAX_DATA
* sending of MAX_STREAMS_BIDI

In other cases (STREAM, STOP_SENDING, RESET_STREAM), an allocation
failure will only result in the current operation to be interrupted and
retried later. However, it may be desirable in the future to replace
this with a simpler CONNECTION_CLOSE emission to recover better under a
memory pressure issue.

This should be backported up to 2.7.

2 years agoMINOR: mux-quic: close on qcs allocation failure
Amaury Denoyelle [Thu, 9 Mar 2023 09:16:09 +0000 (10:16 +0100)] 
MINOR: mux-quic: close on qcs allocation failure

Emit a CONNECTION_CLOSE with INTERNAL_ERROR code each time qcs
allocation fails. This can happen in two cases :
* when creating a local stream through application layer
* when instantiating a remote stream through qcc_get_qcs()

In both cases, error paths are already in place to interrupt the current
operation and a CONNECTION_CLOSE will be emitted soon after.

This should be backported up to 2.7.

2 years agoMINOR: mux-quic: ensure CONNECTION_CLOSE is scheduled once per conn
Amaury Denoyelle [Thu, 9 Mar 2023 09:14:28 +0000 (10:14 +0100)] 
MINOR: mux-quic: ensure CONNECTION_CLOSE is scheduled once per conn

Add BUG_ON() statements to ensure qcc_emit_cc()/qcc_emit_cc_app() is not
called more than one time for each connection. This should improve code
resilience of MUX-QUIC and H3 and it will ensure that a scheduled
CONNECTION_CLOSE is not overwritten by another one with a different
error code.

This commit relies on the previous one to ensure all QUIC operations are
not conducted as soon as a CONNECTION_CLOSE has been prepared :
  commit d7fbf458f8a4c5b09cbf0da0208fbad70caaca33
  MINOR: mux-quic: interrupt most operations if CONNECTION_CLOSE scheduled

This should be backported up to 2.7.

2 years agoMINOR: mux-quic: interrupt qcc_recv*() operations if CC scheduled
Amaury Denoyelle [Thu, 9 Mar 2023 14:49:48 +0000 (15:49 +0100)] 
MINOR: mux-quic: interrupt qcc_recv*() operations if CC scheduled

Ensure that external MUX operations are interrupted if a
CONNECTION_CLOSE is scheduled. This was already the cases for some
functions. This is extended to the qcc_recv*() family for
MAX_STREAM_DATA, RESET_STREAM and STOP_SENDING.

Also, qcc_release_remote_stream() is skipped in qcs_destroy() if a
CONNECTION_CLOSE is already scheduled.

All of this will ensure we only proceed to minimal treatment as soon as
a CONNECTION_CLOSE is prepared. Indeed, all sending and receiving is
stopped as soon as a CONNECTION_CLOSE is emitted so only internal
cleanup code should be necessary at this stage.

This should prevent a registered CONNECTION_CLOSE error status to be
overwritten by an error in a follow-up treatment.

This should be backported up to 2.7.

2 years agoBUG/MINOR: mux-quic: prevent CC status to be erased by shutdown
Amaury Denoyelle [Mon, 20 Mar 2023 16:34:22 +0000 (17:34 +0100)] 
BUG/MINOR: mux-quic: prevent CC status to be erased by shutdown

HTTP/3 graceful shutdown operation is used to emit a GOAWAY followed by
a CONNECTION_CLOSE with H3_NO_ERROR status. It is used for every
connection on release which means that if a CONNECTION_CLOSE was already
registered for a previous error, its status code is overwritten.

To fix this, skip shutdown operation if a CONNECTION_CLOSE is already
registered at the MUX level. This ensures that the correct error status
is reported to the peer.

This should be backported up to 2.6. Note that qc_shutdown() does not
exists on 2.6 so modification will have to be made directly in
qc_release() as followed :

diff --git a/src/mux_quic.c b/src/mux_quic.c
index 49df0dc418..3463222956 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -1766,19 +1766,21 @@ static void qc_release(struct qcc *qcc)

        TRACE_ENTER(QMUX_EV_QCC_END, conn);

-       if (qcc->app_ops && qcc->app_ops->shutdown) {
-               /* Application protocol with dedicated connection closing
-                * procedure.
-                */
-               qcc->app_ops->shutdown(qcc->ctx);
+       if (!(qcc->flags & QC_CF_CC_EMIT)) {
+               if (qcc->app_ops && qcc->app_ops->shutdown) {
+                       /* Application protocol with dedicated connection closing
+                        * procedure.
+                        */
+                       qcc->app_ops->shutdown(qcc->ctx);

-               /* useful if application protocol should emit some closing
-                * frames. For example HTTP/3 GOAWAY frame.
-                */
-               qc_send(qcc);
-       }
-       else {
-               qcc_emit_cc_app(qcc, QC_ERR_NO_ERROR, 0);
+                       /* useful if application protocol should emit some closing
+                        * frames. For example HTTP/3 GOAWAY frame.
+                        */
+                       qc_send(qcc);
+               }
+               else {
+                       qcc_emit_cc_app(qcc, QC_ERR_NO_ERROR, 0);
+               }
        }

        if (qcc->task) {

2 years agoBUG/MINOR: h3: properly handle incomplete remote uni stream type
Amaury Denoyelle [Thu, 9 Mar 2023 10:12:32 +0000 (11:12 +0100)] 
BUG/MINOR: h3: properly handle incomplete remote uni stream type

A H3 unidirectional stream is always opened with its stream type first
encoded as a QUIC variable integer. If the STREAM frame contains some
data but not enough to decode this varint, haproxy would crash due to an
ABORT_NOW() statement.

To fix this, ensure we support an incomplete stream type. In this case,
h3_init_uni_stream() returns 0 and the buffer content is not cleared.
Stream decoding will resume when new data are received for this stream
which should be enough to decode the stream type varint.

This bug has never occured on production because standard H3 stream types
are small enough to be encoded on a single byte.

This should be backported up to 2.6.

2 years agoMINOR: pools: report a replaced memory allocator instead of just malloc_trim()
Willy Tarreau [Wed, 22 Mar 2023 17:01:41 +0000 (18:01 +0100)] 
MINOR: pools: report a replaced memory allocator instead of just malloc_trim()

Instead of reporting the inaccurate "malloc_trim() support" on -vv, let's
report the case where the memory allocator was actively replaced from the
one used at build time, as this is the corner case we want to be cautious
about. We also put a tainted bit when this happens so that it's possible
to detect it at run time (e.g. the user might have inherited it from an
environment variable during a reload operation).

The now unused is_trim_enabled() function was finally dropped.