Commit Graph

18112 Commits

Author SHA1 Message Date
Amaury Denoyelle
114c9c87ce MINOR: h3: implement graceful shutdown with GOAWAY
Implement graceful shutdown as specified in RFC 9114. A GOAWAY frame is
generated with stream ID to indicate range of processed requests.

This process is done via the release app protocol operation. The MUX
is responsible to emit the generated GOAWAY frame after app release. A
CONNECTION_CLOSE will be emitted once there is no unacknowledged STREAM
frames.
2022-07-15 15:56:13 +02:00
Amaury Denoyelle
d701039773 MINOR: h3: store control stream in h3c
Store a reference to the HTTP/3 control stream in h3c context.

This will be useful to implement GOAWAY emission without having to store
the control stream ID on opening.
2022-07-15 15:56:13 +02:00
Amaury Denoyelle
a154dc0290 MINOR: mux-quic: send one last time before release
Call qc_send() on qc_release(). This is mostly useful for application
protocol with a connection closing procedure. Most notably, this will be
useful to implement HTTP/3 GOAWAY emission.
2022-07-15 15:56:13 +02:00
Amaury Denoyelle
c49d5d1a4b CLEANUP: mux-quic: move qc_release()
This change is purely cosmetic. qc_release() function is moved just
before qc_io_cb(). It's cleaner as it brings it closer where it is used.
More importantly, this will be required to be able to use it in
qc_send() function.
2022-07-15 15:56:13 +02:00
Amaury Denoyelle
240b1b108b MEDIUM: quic: send CONNECTION_CLOSE on released MUX
Send a CONNECTION_CLOSE if the MUX has been released and all STREAM data
are acknowledged. This is useful to prevent a client from trying to use
a connection which have the upper layer closed.

To implement this a new function qc_check_close_on_released_mux() has
been added. It is called on QUIC MUX release notification and each time
a qc_stream_desc has been released.

This commit is associated with the previous one :
  MINOR: mux-quic/h3: schedule CONNECTION_CLOSE on app release
Both patches are required to prevent the risk of browsers stuck on
webpage loading if MUX has been released. On CONNECTION_CLOSE reception,
the client will reopen a new QUIC connection.
2022-07-15 15:56:13 +02:00
Amaury Denoyelle
069288b4c0 MINOR: mux-quic/h3: prepare CONNECTION_CLOSE on release
When MUX is released, a CONNECTION_CLOSE frame should be emitted. This
will ensure that the client does not use anymore a half-dead connection.

App protocol layer is responsible to provide the error code via release
callback. For HTTP/3 NO_ERROR is used as specified in RFC 9114. If no
release callback is provided, generic QUIC NO_ERROR code is used. Note
that a graceful shutdown is used : quic_conn must emit CONNECTION_CLOSE
frame when possible. This will be provided in another patch.

This change should limit the risk of browsers stuck on webpage loading
if MUX has been released. On CONNECTION_CLOSE reception, the client will
reopen a new QUIC connection.
2022-07-15 15:20:33 +02:00
Amaury Denoyelle
d666d740d2 MINOR: mux-quic: support app graceful shutdown
Adjust qcc_emit_cc_app() to allow the delay of emission of a
CONNECTION_CLOSE. This will only set the error code but the quic-conn
layer is not flagged for immediate close. The quic-conn will be
responsible to shut the connection when deemed suitable.

This change will allow to implement application graceful shutdown, such
as HTTP/3 with GOAWAY emission. This will allow to emit closing frames
on MUX release. Once all work is done at the lower layer, the quic-conn
should emit a CONNECTION_CLOSE with the registered error code.
2022-07-15 15:06:59 +02:00
Amaury Denoyelle
57e6db7021 MINOR: quic: define a generic QUIC error type
Define a new structure quic_err to abstract a QUIC error type. This
allows to easily differentiate a transport and an application error
code. This simplifies error transmission from QUIC MUX and H3 layers.

This new type is defined in quic_frame module. It is used to replace
<err_code> field in <quic_conn>. QUIC_FL_CONN_APP_ALERT flag is removed
as it is now useless.

Utility functions are defined to be able to quickly instantiate
transport, tls and application errors.
2022-07-15 14:57:49 +02:00
Amaury Denoyelle
41cd879383 CLEANUP: quic: clean up include on quic_frame-t.h
quic_frame-t.h and xprt_quic-t.h include themselves mutually. This may
cause some troubles later.

In fact, xprt_quic does not need to include quic_frame so remove this.
And as quic_frame is a generic source file which is included in multiple
places, it is useful to also remove the xprt_quic include in it. Use
forward declaration for this.
2022-07-15 14:54:24 +02:00
Amaury Denoyelle
72d86509f1 BUG/MINOR: quic: fix closing state on NO_ERROR code sent
Reception is disabled as soon as a CONNECTION_CLOSE emission is
required. An early return is done on qc_lstnr_pkt_rcv() to implement
this.

This condition is not functional if the error code sent is NO_ERROR
(0x00). To fix this, check the quic-conn flags instead of the
error code.

Currently this bug has no impact has NO_ERROR emission is not used.

This can be backported up to 2.6.
2022-07-13 15:33:15 +02:00
Willy Tarreau
672972604f BUG/MEDIUM: debug: fix possible hang when multiple threads dump at once
A bug in the thread dumper was introduced by commit 00c27b50c ("MEDIUM:
debug: make the thread dumper not rely on a thread mask anymore"). If
two or more threads try to trigger a thread dump exactly at the same
time, the second one may loop indefinitely trying to set the value to 1
while the other ones will wait for it to finish dumping before leaving.
This is a consequence of a logic change using thread numbers instead of
a thread mask, as threads do not need to see all other ones there anymore.

No backport is needed, this is only for 2.7.
2022-07-13 09:03:02 +02:00
Amaury Denoyelle
a5b5075211 MEDIUM: mux-quic: implement STOP_SENDING handling
Implement support for STOP_SENDING frame parsing. The stream is resetted
as specified by RFC 9000. This will automatically interrupt all future
send operation in qc_send(). A RESET_STREAM will be sent with the code
extracted from the original STOP_SENDING frame.
2022-07-11 16:45:04 +02:00
Amaury Denoyelle
843a1196b3 MEDIUM: mux-quic: implement RESET_STREAM emission
Implement functions to be able to reset a stream via RESET_STREAM.

If needed, a qcs instance is flagged with QC_SF_TO_RESET to schedule a
stream reset. This will interrupt all future send operations.

On stream emission, if a stream is flagged with QC_SF_TO_RESET, a
RESET_STREAM frame is generated and emitted to the transport layer. If
this operation succeeds, the stream is locally closed. If upper layer is
instantiated, error flag is set on it.
2022-07-11 16:45:04 +02:00
Amaury Denoyelle
20d1f84ce4 MINOR: mux-quic: use stream states to mark as detached
Adjust condition to detach a qcs instance : if the stream is not locally
close it is not directly free. This should improve stream closing by
ensuring that either FIN or a RESET_STREAM is sent before destroying it.
2022-07-11 16:41:10 +02:00
Amaury Denoyelle
38e6006da1 MINOR: mux-quic: define basic stream states
Implement a basic state machine to represent stream lifecycle. By
default a stream is idle. It is marked as open when sending or receiving
the first data on a stream.

Bidirectional streams has two states to represent the closing on both
receive and send channels. This distinction does not exists for
unidirectional streams which passed automatically from open to close
state.

This patch is mostly internal and has a limited visible impact. Some
behaviors are slightly updated :
* closed streams are garbage collected at the start of io handler
* send operation is interrupted if a stream is close locally

Outside of this, there is no functional change. However, some additional
BUG_ON guards are implemented to ensure that we do not conduct invalid
operation on a stream. This should strengthen the code safety. Also,
stream states are displayed on trace which should help debugging.
2022-07-11 16:37:21 +02:00
Amaury Denoyelle
b68559a9aa MINOR: mux-quic: support stream opening via MAX_STREAM_DATA
MAX_STREAM_DATA can be used as the first frame of a stream. In this
case, the stream should be opened, if it respects flow-control limit. To
implement this, simply replace plain lookup in stream tree by
qcc_get_qcs() at the start of the parsing function. This automatically
takes care of opening the stream if not already done.

As specified by RFC 9000, if MAX_STREAM_DATA is receive for a
receive-only stream, a STREAM_STATE_ERROR connection error is emitted.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
57161b7d0c MINOR: mux-quic: do not ack STREAM frames on unrecoverable error
Improve return path for qcc_recv() on STREAM parsing. It returns 0 on
success. On error, a non-zero value is returned which indicates to the
caller that the packet containing the frame should not be acknowledged.

When qcc_recv() generates a CONNECTION_CLOSE or RESET_STREAM, either
directly or via qcc_get_qcs(), an error is returned which ensure that no
acknowledgement is generated. This required an adjustment on
qcc_get_qcs() API which now returns a success/error code. The stream
instance is returned via a new out argument.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
5fbb8691d4 MINOR: mux-quic: filter send/receive-only streams on frame parsing
Extend the function qcc_get_qcs() to be able to filter send/receive-only
unidirectional streams. A connection error STREAM_STATE_ERROR is emitted
if this new filter does not match.

This will be useful when various frames handlers are converted with
qcc_get_qcs(). Depending on the frame type, it will be easy to filter on
the forbidden stream types as specified in RFC 9000.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
4561f84ad4 MINOR: mux-quic: implement qcs_alert()
Implement a simple function to notify a possible subscriber or wake up
the upper layer if a special condition happens on a stream. For the
moment, this is only used to replace identical code in
qc_wake_some_streams().
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
392e94e985 MINOR: mux-quic: add traces on frame parsing functions
Add traces for parsing functions for MAX_DATA and MAX_STREAM_DATA.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
c1a6dfd477 MINOR: mux-quic: rename stream purge function
Rename qc_release_detached_streams() to qc_purge_streams(). The aim is
to have a more generic name. It's expected to complete this function to
add other criteria to purge dead streams.

Also the function documentation has been corrected. It does not return a
number of streams. Instead it is a boolean value, to true if at least
one stream was released.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
b143723411 REORG: mux-quic: rename stream initialization function
Rename both qcc_open_stream_local/remote() functions to
qcc_init_stream_local/remote(). This change is purely cosmetic. It will
reduces the ambiguity with the soon to be implemented OPEN states for
QCS instances.
2022-07-11 16:24:03 +02:00
Amaury Denoyelle
e53b489826 BUG/MEDIUM: mux-quic: fix server chunked encoding response
QUIC MUX was not able to correctly deal with server response using
chunked transfer-encoding. All data will be transfered correctly to the
client but the FIN bit is missing. The transfer will never stop as the
client will wait indefinitely for the FIN bit.

This bug happened because the HTX message representing a chunked encoded
payload contains a final empty block with the EOM flag. However,
emission is skipped by QUIC MUX if there is no data to transfer. To fix
this, the condition was completed to ensure that there is no need to
send the FIN signal. If this is false, data emission will proceed even
if there is no data : this will generate an empty QUIC STREAM frame with
FIN set which will mark the end of the transfer.

To ensure that a FIN STREAM frame is sent only one time,
QC_SF_FIN_STREAM is resetted on send confirmation from the transport in
qcc_streams_sent_done().

This bug was reproduced when dealing with chunked transfer-encoding
response for the HTTP server.

This must be backported up to 2.6.
2022-07-11 16:21:52 +02:00
Willy Tarreau
a88e8bf428 BUILD: http: silence an uninitialized warning affecting gcc-5
When building with gcc-5, one can see this warning:

  src/http_fetch.c: In function 'smp_fetch_meth':
  src/http_fetch.c:356:6: warning: 'htx' may be used uninitialized in this function [-Wmaybe-uninitialized]
     sl = http_get_stline(htx);
        ^

It's wrong since the only way to reach this code is to have met the
same condition a few lines before and initialized the htx variable.
The reason in fact is that the same test happens on different variables
of distinct types, so the compiler possibly doesn't know that the
condition is the same. Newer gcc versions do not have this problem.
Let's just move the assignment earlier and have the exact same test,
as it's sufficient to shut this up. This may have to be backported
to 2.6 since the code is the same there.
2022-07-10 14:13:48 +02:00
Willy Tarreau
481edaceb8 BUILD: debug: silence warning on gcc-5
In 2.6, 8a0fd3a36 ("BUILD: debug: work around gcc-12 excessive
-Warray-bounds warnings") disabled some warnings that were reported
around the the BUG() statement. But the -Wnull-dereference warning
isn't known from gcc-5, it only arrived in gcc-6, hence makes gcc-5
complain loudly that it doesn't know this directive. Let's just
condition this one to gcc-6.
2022-07-10 14:13:48 +02:00
Willy Tarreau
0d023774bf MEDIUM: epoll: don't synchronously delete migrated FDs
Between 1.8 and 1.9 commit d9e7e36c6 ("BUG/MEDIUM: epoll/threads: use one
epoll_fd per thread") split the epoll poller to use one poller per thread
(and this was backported to 1.8). This patch added a call to epoll_ctl(DEL)
on return from the I/O handler as a safe way to deal with a detected thread
migration when that code was still quite fragile. One aspect of this choice
was that by then we wanted to maintain support for the rare old bogus epoll
implementations that failed to remove events on close(), so risking to lose
the event was not an option.

Later in 2.5, commit 200bd50b7 ("MEDIUM: fd: rely more on fd_update_events()
to detect changes") changed the code to perform most of the operations
inside fd_update_events(), but it maintained that oddity, to the point that
strictly all pollers except epoll now just add an update to be dealt with at
the next round.

This approach is much more efficient, because under load and server-side
connection reuse, it's perfectly possible for a thread to see the same FD
several times in a poll loop, the first time to relinquish it after a
migration, then the other thread makes a request, gets its response, and
still during the same loop for the first one, grabbing an idle connection
to send a request and wait for a response will program a new update on
this FD. By using a synchronous epoll_ctl(DEL), we effectively lose the
opportunity to aggregate certain changes in the same update.

Some tests performed locally with 8 threads and one server show that on
average, by using an update instead of a synchronous call, we reduce the
number of epoll_ctl() calls by 25-30% (under low loads it will probably
not change anything).

So this patch implements the same method for all pollers and replaces the
synchronous epoll_ctl() with an update.
2022-07-10 14:13:48 +02:00
Christopher Faulet
372b38f935 BUG/MEDIUM: mux-h1: Handle connection error after a synchronous send
Since commit d1480cc8 ("BUG/MEDIUM: stream-int: do not rely on the
connection error once established"), connection errors are not handled
anymore by the stream-connector once established. But it is a problem for
the H1 mux when an error occurred during a synchronous send in
h1_snd_buf(). Because in this case, the connction error is just missed. It
leads to a session leak until a timeout is reached (client or server).

To fix the bug, the connection flags are now checked in h1_snd_buf(). If
there is an error, it is reported to the stconn level by setting SF_FL_ERROR
flags. But only if there is no pending data in the input buffer.

This patch should solve the issue #1774. It must be backported as far as
2.2.
2022-07-08 16:37:31 +02:00
Christopher Faulet
52fc0cbaad BUG/MEDIUM: http-ana: Don't wait to have an empty buf to switch in TUNNEL state
When we want to establish a tunnel on a side, we wait to have flush all data
from the buffer. At this stage the other side is at least in DONE state. But
there is no real reason to wait. We are already in DONE state on its
side. So all the HTTP message was already forwarded or planned to be
forwarded. Depending on the scheduling if the mux already started to
transfer tunneled data, these data may block the switch in TUNNEL state and
thus block these data infinitly.

This bug exists since the early days of HTX. May it was mandatory but today
it seems useless. But I honestly don't remember why this prerequisite was
added. So be careful during the backports.

This patch should be backported with caution. At least as far as 2.4. For
2.2 and 2.0, it seems to be mandatory too. But a review must be performed.
2022-07-08 16:37:31 +02:00
Christopher Faulet
5966e40641 BUG/MINOR: mux-h1: Be sure to commit htx changes in the demux buffer
When a buffer area is casted to an htx message, depending on the method
used, the underlying buffer may be updated or not. The htxbuf() function
does not change the buffer state. We assume the buffer was already prepared
to store an htx message. htx_from_buf() on its side, updates the
buffer. With the first function, we only need to commit changes to the
underlying buffer if the htx message is changed.  With last one, we must
always commit the changes. The idea is to be sure to keep non-empty HTX
messages while an empty message must be lead to an empty buffer after
commit.

All that said because in h1_process_demux(), the changes is not always
committed as expected. When the demux is blocked, we just leave the
function. So it is possible to have an empty htx message stored in a buffer
that appears non-empty. It is not critical, but the buffer cannot be
released in this state. And we should always release an empty buffer.

This patch must be backported as far as 2.4.
2022-07-08 16:37:31 +02:00
William Lallemand
a46a99e98c MEDIUM: mworker/systemd: send STATUS over sd_notify
The sd_notify API is not able to change the "Active:" line in "systemcl
status". However a message can still be displayed on a "Status: " line,
even if the service is still green and "active (running)".

When startup succeed the Status will be set to "Ready.", upon a reload
it will be set to "Reloading Configuration." If the configuration
succeed "Ready." again. However if the reload failed, it will be set to
"Reload failed!".

Keep in mind that the "Active:" line won't change upon a reload failure,
and will still be green.
2022-07-07 14:48:46 +02:00
Christopher Faulet
887a2b5bc4 REGTEESTS: filters: Fix CONNECT request in random-forwarding script
An invalid CONNECT request was used and make the script failed because of a
recent fix.
2022-07-07 09:52:56 +02:00
Christopher Faulet
12f6dbb863 BUG/MEDIUM: http-fetch: Don't fetch the method if there is no stream
The "method" sample fetch does not perform any check on the stream existence
before using it. However, for errors triggered at the mux level, there is no
stream. When the log message is formatted, this sample fetch must fail. It
must also fail when it is called from a health-check.

This patch must be backported as far as 2.4.
2022-07-07 09:35:58 +02:00
Christopher Faulet
d1d983fb12 MINOR: http-htx: Use new HTTP functions for the scheme based normalization
Use http_get_host_port() and http_is_default_port() functions to perform the
scheme based normalization.
2022-07-07 09:35:58 +02:00
Christopher Faulet
3f5fbe9407 BUG/MEDIUM: h1: Improve authority validation for CONNCET request
From time to time, users complain to get 400-Bad-request responses for
totally valid CONNECT requests. After analysis, it is due to the H1 parser
performs an exact match between the authority and the host header value. For
non-CONNECT requests, it is valid. But for CONNECT requests the authority
must contain a port while it is often omitted from the host header value
(for default ports).

So, to be sure to not reject valid CONNECT requests, a basic authority
validation is now performed during the message parsing. In addition, the
host header value is normalized. It means the default port is removed if
possible.

This patch should solve the issue #1761. It must be backported to 2.6 and
probably as far as 2.4.
2022-07-07 09:35:58 +02:00
Christopher Faulet
ca7218aaf0 MINOR: http: Add function to detect default port
http_is_default_port() can be used to test if a port is a default HTTP/HTTPS
port. A scheme may be specified. In this case, it is used to detect defaults
ports, 80 for "http://" and 443 for "https://". Otherwise, with no scheme, both
are considered as default ports.
2022-07-06 17:54:03 +02:00
Christopher Faulet
658f971621 MINOR: http: Add function to get port part of a host
http_get_host_port() function can be used to get the port part of a host. It
will be used to get the port of an uri authority or a host header
value. This function only look for a port starting from the end of the
host. It is the caller responsibility to call it with a valid host value. An
indirect string is returned.
2022-07-06 17:54:03 +02:00
Christopher Faulet
0eab050b04 BUG/MINOR: http-htx: Fix scheme based normalization for URIs wih userinfo
The scheme based normalization is not properly handled the URI's userinfo,
if any. First, the authority parser is not called with "no_userinfo"
parameter set. Then it is skipped from the URI normalization.

This patch must be backported as far as 2.4.
2022-07-06 17:54:02 +02:00
William Lallemand
1d93217a05 BUG/MINOR: peers: fix possible NULL dereferences at config parsing
Patch 49f6f4b ("BUG/MEDIUM: peers: fix segfault using multiple bind on
peers sections") introduced possible NULL dereferences when parsing the
peers configuration.

Fix the issue by checking the return value of bind_conf_uniq_alloc().

This patch should be backported as far as 2.0.
2022-07-06 14:40:11 +02:00
Willy Tarreau
ad92fdf196 CLEANUP: thread: also remove a thread's bit from stopping_threads on stop
As much as possible we should take care of not leaving bits from stopped
threads in shared thread masks. It can avoid issues like the previous
fix and will also make debugging less confusing.
2022-07-06 10:19:46 +02:00
Willy Tarreau
f34a3fa33d BUG/MEDIUM: thread: mask stopping_threads with threads_enabled when checking it
When soft-stopping, there's a comparison between stopping_threads and
threads_enabled to make sure all threads are stopped, but this is not
correct and is racy since the threads_enabled bit is removed when a
thread is stopped but not its stopping_threads bit. The consequence is
that depending on timing, when stopping, if the first stopping thread
is fast enough to remove its bit from threads_enabled, the other threads
will see that stopping_threads doesn't match threads_enabled anymore and
will wait forever. As such the mask must be applied to stopping_threads
during the test. This issue was introduced in recent commit ef422ced9
("MEDIUM: thread: make stopping_threads per-group and add stopping_tgroups"),
no backport is needed.
2022-07-06 10:19:46 +02:00
Christopher Faulet
4c3d3d2a68 BUG/MINOR: http-act: Properly generate 103 responses when several rules are used
When several "early-hint" rules are used, we try, as far as possible, to
merge links into the same 103-early-hints response. However, it only works
if there is no ACLs. If a "early-hint" rule is not executed an invalid
response is generated. the EOH block or the start-line may be missing,
depending on the rule order.

To fix the bug, we use the transaction status code. It is unused at this
stage. Thus, it is set to 103 when a 103-early-hints response is in
progress. And it is reset when the response is forwarded. In addition, the
response is forwarded if the next rule is an "early-hint" rule with an
ACL. This way, the response is always valid.

This patch must be backported as far as 2.2.
2022-07-06 09:37:43 +02:00
Christopher Faulet
4c8e58def6 BUG/MINOR: http-check: Preserve headers if not redefined by an implicit rule
When an explicit "http-check send" rule is used, if it is the first one, it
is merge with the implicit rule created by "option httpchk" statement. The
opposite is also true. Idea is to have only one send rule with the merged
info. It means info defined in the second rule override those defined in the
first one. However, if an element is not defined in the second rule, it must
be ignored, keeping this way info from the first rule. It works as expected
for the method, the uri and the request version. But it is not true for the
header list.

For instance, with the following statements, a x-forwarded-proto header is
added to healthcheck requests:

  option httpchk
  http-check send meth GET hdr x-forwarded-proto https

while by inverting the statements, no extra headers are added:

  http-check send meth GET hdr x-forwarded-proto https
  option httpchk

Now the old header list is overriden if the new one is not empty.

This patch should fix the issue #1772. It must be backported as far as 2.2.
2022-07-06 09:35:13 +02:00
Christopher Faulet
f0196f4f71 CLEANUP: bwlim: Set pointers to NULL when memory is released
Calls to free() are replaced by ha_free(). And otherwise, the pointers are
explicitly set to NULL after a release. There is no issue here but it could
help debugging sessions.
2022-07-06 09:34:54 +02:00
Willy Tarreau
d2494e0489 BUG/MEDIUM: peers/config: properly set the thread mask
The peers didn't have their bind_conf thread mask nor group set, because
they're still not part of the global proxy list. Till 2.6 it seems it does
not have any visible impact, since most listener-oriented operations pass
through thread_mask() which detects null masks and turns them to
all_threads_mask. But starting with 2.7 it becomes a problem as won't
permit these null masks anymore.

This patch duplicates (yes, sorry) the loop that applies to the frontend's
bind_conf, though it is simplified (no sharding, etc).

As the code is right now, it simply seems impossible to trigger the second
(and largest) part of the check when leaving thread_resolve_group_mask()
on success, so it looks like it might be removed.

No backport is needed, unless a report in 2.6 or earlier mentions an issue
with a null thread_mask.
2022-07-05 19:10:26 +02:00
Willy Tarreau
8d158132bd BUG/MINOR: peers/config: always fill the bind_conf's argument
Some generic frontend errors mention the bind_conf by its name as
"bind '%s'", but if this is used on peers "bind" lines it shows
"(null)" because the argument is set to NULL in the call to
bind_conf_uniq_alloc() instead of passing the argument. Fortunately
that's trivial to fix.

This may be backported to older versions.
2022-07-05 19:06:47 +02:00
Amaury Denoyelle
bf91e3922b MINOR: mux-quic: emit FINAL_SIZE_ERROR on invalid STREAM size
Add a check on stream size when the stream is in state Size Known. In
this case, a STREAM frame cannot change the stream size. If this is not
respected, a CONNECTION_CLOSE with FINAL_SIZE_ERROR will be emitted as
specified in the RFC 9000.
2022-07-05 16:44:01 +02:00
Amaury Denoyelle
3f39b40fe0 MINOR: mux-quic: rename qcs flag FIN_RECV to SIZE_KNOWN
Rename QC_SF_FIN_RECV to the more generic name QC_SF_SIZE_KNOWN. This
better align with the QUIC RFC 9000 which uses the "Size Known" state
definition. This change is purely cosmetic.
2022-07-05 16:18:27 +02:00
Amaury Denoyelle
a509ffb505 MEDIUM: mux-quic: refactor streams opening
Review the whole API used to access/instantiate qcs.

A public function qcc_open_stream_local() is available to the
application protocol layer. It allows to easily opening a local stream.
The ID is automatically attributed to the next one available.

For remote streams, qcc_open_stream_remote() has been implemented. It
will automatically take care of allocating streams in a linear way
according to the ID. This function is called via qcc_get_qcs() which can
be used for each qcc_recv*() operations. For the moment, it is only used
for STREAM frames via qcc_recv(), but soon it will be implemented for
other frames types which can also be used to open a new stream.

qcs_new() and qcs_free() has been restricted to the MUX QUIC only as
they are now reserved for internal usage.

This change is a pure refactoring and should not have any noticeable
impact. It clarifies the developer intent and help to ensure that a
stream is not automatically opened when not desired.
2022-07-05 16:18:27 +02:00
Amaury Denoyelle
3abeb57909 MINOR: mux-quic: implement accessor for sedesc
Implement a function <qcs_sc> to easily access to the stconn associated
with a QCS. This takes care of qcs.sd which may be NULL, for example for
unidirectional streams.

It is expected that in the future when implementing
STOP_SENDING/RESET_STREAM, stconn must be notify about the event. This
accessor will allow to easily test if the stconn is instantiated or not.
2022-07-05 11:22:15 +02:00
Amaury Denoyelle
321fa7733c REORG: mux-quic: reorganize flow-control fields
<qcc.cl_bidi_r> is used to implement STREAM ID flow control enforcement.
Move it with all fields related to this operation and separated from MAX
STREAM DATA calcul.
2022-07-05 11:20:02 +02:00