Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
Previously, if `quiche::h3::with_transport()` failed to initialize the
HTTP/3 connection for any reason, it would return an error and rely on
the caller to tidy up the QUIC connection. This is inconsistent with how
other parts of quiche's HTTP/3 layer deal with low level issues.
This change ensures the QUIC connection is closed before returning the
reason to the caller.
|
|
There is not requirement for HTTP/3 header names and values to be valid
UTF-8, so don't require it.
|
|
Previously, quiche would always prefer sending pending DATAGRAM frames
over STREAM frames. Depending on the size of DATAGRAMs in relation to
QUIC packet sizes the available space in packets for STREAM frames
can end up being small. Similarly, sometimes STREAM frames may only get
sent when the congestion window was smaller than the next DATAGRAM.
This commit introduces a preference toggle into the quiche sending
logic. This gives equal opportunity to send full-sized DATAGRAM or
STREAM frames between calls to `send()`. In cases where there is no
pending data of one type, quiche will just fallback to the other.
|
|
|
|
|
|
cwnd_inc is used for storing cwnd increments during congestion
avoidance. When cwnd_inc >= MSS we increase cwnd by 1 MSS.
Currently we clear cwnd_inc when cwnd is updated but this will
lead to slightly slower growth because the residual part is gone.
|
|
`HANDSHAKE_DONE` can only be sent by a server, so don't try to send a packet from the client if the frame hasn't been sent yet.
|
|
Now it uses sendto() and recvfrom(), the socket need to be
connectionless.
Fixes #952.
|
|
RFC3465 ABC_L constant (2) is to prevent an ACK from
growing cwnd too fast for TCP ACK. However in QUIC
recovery we process each ack'ed packet one by one in
on_packet_acked(), there is no case where 2 or more
packets are acked in on_packet_acked() hook.
Also current logic limits growing cwnd more than 2 MSS
for ACK packet containing more than 2 ACK packets,
cwnd can grow too conservative in case that an ACK range
contains many packets. For example the receiver may
ack multiple packets in a single ACK frame when it processed
multiple packets at once.
This PR partially reverts #737.
|
|
|
|
|
|
|
|
|
|
Currently quiche does not hold any information about the network path of
a QUIC connection (such as the address of the peer), and the application
is responsible for maintaining such information.
This means that in case of a network migration, the application is
responsible for detecting the change and switching over to new path,
however there is currently no way for an application to actually
validate a new path, as required by the QUIC spec.
Adding an ad-hoc API to only expose path validation to applications
would likely be very cumbersome, due to the synchronization needed
between an application and quiche on the state of the current path, and
any other path being probed.
Instead, this change makes quiche be aware of the network path being
used.
The application needs to communicate the destination address of a
connection upon creationg (via `accept()` or `connect()`), as well as
the source address of received packets (via `recv()` and the new
`RecvInfo` structure).
In turn quiche will provide the application with the destination address
of generated packets (via `send()` and the new `SendInfo` structure).
Currently only the destination address of a connection is tracked, which
would allow quiche to handle responding to migrations transparently from
the application (but this will be added as a separate change).
Additional fields can later be added to `RecvInfo` and `SendInfo`, such
as the address of the local endpoint in order to be able to initiate
migrations, rather than just respond to them.
|
|
|
|
Currently, when writing stream data, `RangeBuf` objects are allocated
with a fixed capacity, and if the buffer is not immediately filled, the
next stream write will re-use it.
This was originally implemented to try to reduce memory fragmentation of
stream data, and, in order to be able to maintain the `Send` and `Sync`
traits implementation, the `RangeBuf` data buffer was wrapped in an
`RWlock`, in order to implement thread-safe interior mutability.
However due to the fact that the locking falls within 2 hot code paths
(stream data writing, and STREAM frame creation) it heavuily affects
throughput.
In retrospect, the benefit of reduced memory fragmentation does not seem
to justify the performance penalty, so this undoes the consistent
allocation change to remove the need for the lock.
This partially reverts commit 0976433e68ea1926aa9cf581e1a5846aba6da672.
|
|
Instead of using a static value of what the frame overhead _could_ be,
use the actual header length value that is available.
|
|
Motivation:
We should expose functions to access the source and destination ids via the c API as well
Modifications:
Expose functions in the C API
Result:
Be able to access the ids of a connection
|
|
This check is currently done in `Connection::send()` as well, but when
coalescing multiple packets, if one causes the connection to move to
draining (e.g. because a CONNECTION_CLOSE was sent), we should stop
trying to write additional coalesced packets.
|
|
For Initial packets we need to make the UDP datagram at least 1200
bytes following the transport spec. However when the last packet
in the datagram is Short and the datagram is not fully filled, we try
to do null padding at the end which causes a decryption failure on
the server because Short packet doesn't have an explicit length.
To avoid this issue, when Short packet is added in the same
datagram with Initial packet, add a PADDING frame to Short packet
to fill up the datagram size. If Short packet is not added,
we still add zero padding at the end of packet.
|
|
Update based on https://github.com/NTAP/rfc8312bis/pull/35
- remove w_last_max
- update the logic of fast convergence
- fix the bug where fast convergence is not applied
|
|
- Update based on https://github.com/NTAP/rfc8312bis/pull/24
- Fix congestion avoidance test
|
|
- Update based on https://github.com/NTAP/rfc8312bis/pull/3
- Fix congestion avoidance test (but still has a TODO)
|
|
Seems we missed the header file...
|
|
|
|
Motivation:
We should validate that the version is valid that was used to create the Config object and if not fail.
Modifications:
- Add validation for the version
- Add some tests
Result:
Version is validated during config creation
|
|
|
|
|
|
|
|
|
|
Motivation:
Quiche added support for session resumption and 0-RTT lately but the API was not exposed via the C api.
This was done in https://github.com/cloudflare/quiche/pull/911 and https://github.com/cloudflare/quiche/pull/914.
Modifications:
Add C API to also be able to make use of the functionality via C.
Result:
Be able to use session resumption and 0-RTT via the C api
|
|
When we queue 0-rtt packets in undecryptable_pkts, there is
a case that actual packet length is smaller than the size in
the payload (packet length field) which may cause a runtime panic.
Such packet is undecryptable in any way, so check it early
and return error.
|
|
|
|
Add EARLY_DATA and SESSION_FILE for testing 0-rtt connection
resumption on http3_test.
|
|
This adds support for clients to generate 0-RTT packets. Currently only
STREAM and DATAGRAM frames are allowed, though this is somewhat stricter
than what is allowed in theory.
This requies exporting the peer's transport parameters as part of the
TLS session, so that they can be restored on resumption.
This also changes how epoch/packet type is picked when creating a new
packet. Packet types offer more granularity (e.g. Short vs. ZeroRTT), so
it's better to pick the type first and then derive the epoch, rather
than the other way around.
Closes #683.
|
|
Commit 877bace8 added support for buffering undecryptable 0-RTT packets
and processing them when 0-RTT read keys become available.
One notable change was the fact that packets could be processed as part
of the `Connection::send()` method, which does call the `do_handshake()`
method for advancing the handshake state, but it doesn't try to parse
and configure the peer's transport parameters, unlike the
`Connection::recv()` method which tries to parse transport params when
receiving CRYPTO frames
This could cause a server to be unable to reply to buffered 0-RTT data
due to missing flow control credits.
This change moves the parsing and configuration of peer transport params
directly into the `do_handshake()` method, so that those actions are
always executed when the handshake is advanced.
|
|
In 60f66cac, run_quiche_client_tests was changed to do "case $1", like
check_testcase, but the testcase was not passed to the function.
Also remove unused variable.
|
|
|
|
|
|
Currently, incoming packets that can't be decrypted because the
corresponding read keys are not available yet are simply dropped. On the
server side this can happen with 0-RTT packets, for example if an early
handshake callback configured in BoringSSL delays installation of read
keys.
This change implements buffering a limited number of 0-RTT packets
received before the corresponding read keys are installed, for a short
period, so that they can be correctly processed at a later time. The
buffer is limited to 10 packets (no particular reason for this number,
though it is also what Chrome uses), and it should be drained as soon as
keys become available.
It can also happen that the server ends up rejecting 0-RTT anyway, in
which case the buffer is cleared as soon as the handshake is completed.
In theory this could happen at an earlier time during the handshake, but
BoringSSL does not (yet?) expose a signal for this.
This could, in theory, also be used to support the case where 0-RTT
packets are received before an Initial one. However it is up to the
application to decide whether a connection should be accept()ed even if
no valid Initial packet has been received yet, as well as dropping the
connection object after a certain amount of time in case the handshake
doesn't complete, as the idle timer is not armed if no Initial packet is
received.
|
|
|
|
This makes it possible to support session resumption on a client and is
a pre-requisite for supporting sending 0-RTT data.
|
|
When a pre-v1 client connects to a v1-enabled server, we need to
re-enable the legacy TLS extension codepoint on the server-side due to
the downgrade.
|
|
Previously, if `send_goaway()` was called on a client connection, it
would return without emitting a frame. This was justified by the lack
of server push support in quiche. However, it also prevented client
GOAWAY when the endpoints didn't use push, which is unfortunate.
This change simply always populates the emitted GOAWAY frame with an
ID of 0, which is valid and consistent with our server push support
status.
|
|
`send_body()` attempts to constrain writes to within stream capacity
limits. Previously, it would prevent writing a 0-length DATA frame if
the stream capacity would not allow it to send the frame overhead and at
least 1 byte of payload.
Assuming it is desirable to send 0-length DATA with fin=true when the
stream has capacity for only the frame overhead, the current behavior
adds at least an RTT for flow control to add 1 byte that won't actually
be used.
Assuming it is undesirable to send 0-length DATA with fin=false,
send_body would allow that if there was stream capacity.
This change reworks send_body to be more consistent when handling
0-length DATA frames. It returns Error::Done in any condition where
0-length with fin=false occurs, and Ok(0) when 0-length with fin=true
occurs.
|
|
Follow-up to 77064a32, which caused multiple probe packets of the same
type to be coalesced together.
|
|
|
|
|
|
|