Summary: This diff adds the reliable_stream_reset transport parameter to mvfst.
Reviewed By: hanidamlaj
Differential Revision: D65383676
fbshipit-source-id: cb2f6a1a90004ea489447b67ed3cfc12ca90b804
Summary:
Missed modifying a test after final changes to D58572572 but Sandcastle didn't catch it?
{F1694722170}
Differential Revision: D58636574
fbshipit-source-id: c0b868718ddd6eac21764926bee5bb6e097411dd
Summary:
Ack Rx timestamps are currently disabled on 0-rtt connections, which is enabled on mvfst for all non-video connections.
This is because the timestamp config is negotiated with transport settings during handshake which doesn't happen on a new 0-rtt connection (resumption).
Solution:
Store the peer's rx timestamp config in PSKCache on the client. On 0-rtt resumption of the connection, this peer config is restored and used to send Rx timestamps (if enabled).
Note that if the server had changed its timestamp config during this period (through configerator) then the server needs to reject this 0-rtt connection and start anew. Server code changes to support this will be in a followup diff. With this client diff though, server will drop the Rx timestamps if its own config is suddenly disabled (this is a waste of network resource).
Reviewed By: jbeshay
Differential Revision: D58572572
fbshipit-source-id: d95720c177ac4bc8dcbe40362f19b279b3f8e708
Summary: We have a lot of optionals that are either integral values or std::chrono::microseconds. These end up wasting memory, where we can instead store sentinel values to encode whether the value is there or not. This reduces the effective range of the type by one value, but that is an acceptable tradeoff.
Reviewed By: kvtsoy
Differential Revision: D57684368
fbshipit-source-id: b406b86011f9b8169b6e5e925265f4829928cc63
Summary:
The idea here is to make it so we can swap out the type we are using for optionality. In the near term we are going to try swapping towards one that more aggressively tries to save size.
For now there is no functional change and this is just a big aliasing diff.
Reviewed By: sharmafb
Differential Revision: D57633896
fbshipit-source-id: 6eae5953d47395b390016e59cf9d639f3b6c8cfe
Summary:
This is the major transition that updates mvfst code to use the new interfaces. The new Folly implementations of the interfaces maintain all the existing behavior of folly types so this should not introduce any functional change. The core changes are:
- Update the BatchWriters to use the new interfaces.
- Update the FunctionLooper to use the new interfaces.
- Change QuicServerTransport to take the folly types and wrap them in the new types for use in the QuicTransportBase.
The rest of the diff is for updating all the existing uses of the QuicTrasnport to initialize the necessary types and pass them to the QUIC transport instead of directly passing folly types.
Reviewed By: mjoras
Differential Revision: D51413481
fbshipit-source-id: 5ed607e12b9a52b96148ad9b4f8f43899655d936
Summary:
- Remove setCustomTransportParameter, which (based on the quic v19 rfc), verifies whether a parameter is within the private range [0xff00, 0xffff]
> Values with the first byte in the range 0x00 to 0xfe (in hexadecimal) are assigned via the Specification Required policy [RFC8126].
- Consolidating adding MaxStreamGroups transport parameter into all other transport parameters extension.
More specifically, `QuicClientTransport::maybeEnableStreamGroups()` logic is now moved into `QuicClientTransport::setSupportedExtensionTransportParameters()`
Reviewed By: mjoras
Differential Revision: D50461610
fbshipit-source-id: 802b546c8364586cdcf36a230b156ca140c57ce4
Summary:
This diff:
- Adds `QuicAsyncUDPSocketWrapperImpl` and changes existing instantiatons of `QuicAsyncUDPSocketWrapper` to instead instantiate `QuicAsyncUDPSocketWrapperImpl`. In follow up diffs, pure virtual functions will be added to `QuicAsyncUDPSocketWrapper` and implemented in `QuicAsyncUDPSocketWrapperImpl`. See D48717388 for more information.
--
This diff is part of a larger stack focused on the following:
- **Cleaning up client and server UDP packet receive paths while improving testability.** We currently have multiple receive paths for client and server. Capabilities vary significantly and there are few tests. For instance:
- The server receive path supports socket RX timestamps, abet incorrectly in that it does not store timestamp per packet. In comparison, the client receive path does not currently support socket RX timestamps, although the code in `QuicClientTransport::recvmsg` and `QuicClientTransport::recvmmsg` makes reference to socket RX timestamps, making it confusing to understand the capabilities available when tracing through the code. This complicates the tests in `QuicTypedTransportTests`, as we have to disable test logic that depends on socket RX timestamps for client tests.
- The client currently has three receive paths, and none of them are well tested.
- **Modularize and abstract components in the receive path.** This will make it easier to mock/fake the UDP socket and network layers.
- `QuicClientTransport` and `QuicServerTransport` currently contain UDP socket handling logic that operates over lower layer primitives such `cmsg` and `io_vec` (see `QuicClientTransport::recvmmsg` and `...::recvmsg` as examples).
- Because this UDP socket handling logic is inside of the mvfst transport implementations, it is difficult to test this logic in isolation and mock/fake the underlying socket and network layers. For instance, injecting a user space network emulator that operates at the socket layer would require faking `folly::AsyncUDPSocket`, which is non-trivial given that `AsyncUDPSocket` does not abstract away intricacies arising from the aforementioned lower layer primitives.
- By shifting this logic into an intermediate layer between the transport and the underlying UDP socket, it will be easier to mock out the UDP socket layer when testing functionality at higher layers, and inject fake components when we want to emulate the network between a mvfst client and server. It will also be easier for us to have unit tests focused on testing interactions between the UDP socket implementation and this intermediate layer.
- **Improving receive path timestamping.** We only record a single timestamp per `NetworkData` at the moment, but (1) it is possible for a `NetworkData` to have multiple packets, each with their own timestamps, and (2) we should be able to record both userspace and socket timestamps.
Reviewed By: jbeshay, mjoras
Differential Revision: D48717592
fbshipit-source-id: e21368f5c1f3b37608fc1c88617e96b93a02f6e0
Summary:
This diff changes `QuicAsyncUDPSocketWrapper` so that it is an abstraction layer that inherits from `QuicAsyncUDPSocketType`, instead of simply being a container with aliases.
- Key changes in `QuicAsyncUDPSocketWrapper.h`, the rest of the updates switch us from using `QuicAsyncUDPSocketType` to `QuicAsyncUDPSocketWrapper`.
- It's difficult to mock the UDP socket today given that we expose the entire `folly::AsyncUDPSocket` type to the higher layers of the QUIC stack. This complicates testing and emulation because any mock / fake has to implement low level primitives like `recvmmsg`, and because the `folly::AsyncUDPSocket` interface can change over time.
- Pure virtual functions will be defined in `QuicAsyncUDPSocketWrapper` in a follow up diff to start creating an interface between the higher layers of the mvfst QUIC stack and the UDP socket, and this interface will abstract away lower layer details such as `cmsgs` and `io_vec`, and instead focus on populating higher layer structures such as `NetworkData` and `ReceivedPacket` (D48714615). This will make it easier for us to mock or fake the UDP socket.
This diff relies on changes to `folly::MockAsyncUDPSocket` introduced in D48717389.
--
This diff is part of a larger stack focused on the following:
- **Cleaning up client and server UDP packet receive paths while improving testability.** We currently have multiple receive paths for client and server. Capabilities vary significantly and there are few tests. For instance:
- The server receive path supports socket RX timestamps, abet incorrectly in that it does not store timestamp per packet. In comparison, the client receive path does not currently support socket RX timestamps, although the code in `QuicClientTransport::recvmsg` and `QuicClientTransport::recvmmsg` makes reference to socket RX timestamps, making it confusing to understand the capabilities available when tracing through the code. This complicates the tests in `QuicTypedTransportTests`, as we have to disable test logic that depends on socket RX timestamps for client tests.
- The client currently has three receive paths, and none of them are well tested.
- **Modularize and abstract components in the receive path.** This will make it easier to mock/fake the UDP socket and network layers.
- `QuicClientTransport` and `QuicServerTransport` currently contain UDP socket handling logic that operates over lower layer primitives such `cmsg` and `io_vec` (see `QuicClientTransport::recvmmsg` and `...::recvmsg` as examples).
- Because this UDP socket handling logic is inside of the mvfst transport implementations, it is difficult to test this logic in isolation and mock/fake the underlying socket and network layers. For instance, injecting a user space network emulator that operates at the socket layer would require faking `folly::AsyncUDPSocket`, which is non-trivial given that `AsyncUDPSocket` does not abstract away intricacies arising from the aforementioned lower layer primitives.
- By shifting this logic into an intermediate layer between the transport and the underlying UDP socket, it will be easier to mock out the UDP socket layer when testing functionality at higher layers, and inject fake components when we want to emulate the network between a mvfst client and server. It will also be easier for us to have unit tests focused on testing interactions between the UDP socket implementation and this intermediate layer.
- **Improving receive path timestamping.** We only record a single timestamp per `NetworkData` at the moment, but (1) it is possible for a `NetworkData` to have multiple packets, each with their own timestamps, and (2) we should be able to record both userspace and socket timestamps.
Reviewed By: jbeshay, hanidamlaj
Differential Revision: D48717388
fbshipit-source-id: 4f34182a69ab1e619e454da19e357a6a2ee2b9ab
Summary: Update flow control settings names to reflect that these are indeed flow control
Reviewed By: jbeshay
Differential Revision: D48137685
fbshipit-source-id: a48372e21cdd529480e25785a9bd5de456427ef3
Summary:
This removes the older method of deciding whether knob frames should be sent using the QuicVersion. With this change, the client can only send knobs when the server has signaled support using the `knob_frames_supported` transport parameter.
To make sure that knobs can be sent in 0-rtt connections, the transport parameter is now included in the client's cache of server transport parameters.
Reviewed By: mjoras
Differential Revision: D43014893
fbshipit-source-id: 204dd43b4551cd1c943153a3716e882fc80e6136
Summary:
This diff changes `QuicConnectionStateBase` so that it stores a `std::weak_ptr<SocketObserverContainer>` instead of a `std::shared_ptr<SocketObserverContainer>`.
- `QuicConnectionStateBase` needs a pointer to the `SocketObserverContainer` so that loss / ACK / other processing logic can access the observer container and send the observers notifications. There may not be a `SocketObserverContainer` if the `QuicTransportBase` implementation does not support it.
- A `SocketObserverContainer` must not outlive the instance of the `QuicTransportBase` implementation that it is associated with. This is because observers are notified that the object being observed has been destroyed when the container is destroyed, and thus if the container outlives the lifetime of the transport, then the observers will think the transport is still alive when it is in fact dead.
- By storing a weak pointer to the `SocketObserverContainer` in the `QuicConnectionStateBase`, we provide access to the observer container without extending its lifetime. In parallel, because it is a managed pointer, we avoid the possibility of dereferencing a stale pointer (e.g., a pointer pointing to an object that has since been destroyed).
Reviewed By: mjoras
Differential Revision: D42856161
fbshipit-source-id: f35558a21fea91ba794adcf9b573dd48a626ea1f
Summary: Decide if knob frames are supported based upon a transport parameter instead of relying on the QUIC version. This is a cleaner approach, at the cost of an additional transport parameter.
Reviewed By: mjoras
Differential Revision: D42465442
fbshipit-source-id: bfd1d177bdbe198e5eb47e63113410b5738dcede
Summary: This is a cosmetic change to make the naming consistent for all the advertised* variables in the transport settings.
Reviewed By: sharmafb
Differential Revision: D42465443
fbshipit-source-id: d570cbb1a2ca017105ac335b8efc404cb73f3c57
Summary: Use TransportParameterId enum as the source of truth for all the parameter ids. This basically moved the stream groups enabled parameter to the enum.
Reviewed By: kvtsoy
Differential Revision: D42465425
fbshipit-source-id: 94f9968326ac61f92587ef380a7288dd8ab38eef
Summary:
Pass max stream group parameter on handshake
The parameter conveys max number of stream groups a peer wishes to support. Note that the number/param is exchanged during handshake and currently there is now way to bump it later in connection. We can add something like MAX_STREAM_GROUP frame later.
Reviewed By: mjoras
Differential Revision: D36415454
fbshipit-source-id: 9d1c8fca7efa4adfb67fdeef859c47a3f50a67ef
Summary:
This diff is part of larger change to switch to using `folly::ObserverContainer` (introduced in D27062840).
This diff:
- Changes `LegacyObserver` to inherit from the new `Observer` class by adding a compatibility layer. This compatibility layer enables existing observers to continue to be supported.
- Changes generation of observer events so that they are routed through `ObserverContainer::invokeInterfaceMethod`
- Temporarily removes some of the reentrancy protection that previously existed, as it was not being applied consistently — some events had reentrancy protection, some did not. This will be reintroduced in the next diff.
- Improves some unit tests for observers during the transition process.
Differential Revision: D35268271
fbshipit-source-id: 5731c8a9aa8da8a2da1dd23d093e5f2e1a692653
Summary:
make getDatagramSizeLimit return the maximum datagram payload size that the
peer can accept.
This is currently the most conservative length, considering the maximum length
of a QUIC short header packet and a datagram frame header
Reviewed By: mjoras
Differential Revision: D28784866
fbshipit-source-id: cce8944a77f6f7b2d3535758c3c29ad88382710f
Summary:
as title. This also moves a FizzCryptoTestFactory from FizzCryptoFactoryTest to TestUtils so that it can be used in other test code
This change has an unfortunate side-effect that cryptoFactory_ in both client and server will be moved from stack to heap.
Reviewed By: mjoras
Differential Revision: D27264488
fbshipit-source-id: febc307fb02cb136d58fe70bee648d35431acff0
Summary:
(1) Receiving a valid retry packet is a HappyEyeballs signal. We should
use that to update the happy eyeballs state.
(2) HappyEyeballs state should also be preserved when we undo client connection
state for retry.
Reviewed By: mjoras
Differential Revision: D25728713
fbshipit-source-id: 4ff06879f5a05e6fb4faeb1e9f330e251d3dbcb6
Summary: This is a temporary hack until we properly implement 0-rtt transport parameter updating. Now after 0-rtt we will use the packet size from the peer as the max packet size, if the can ignore setting is set.
Reviewed By: xttjsn
Differential Revision: D23690019
fbshipit-source-id: b4dbf5702e81e52ccd437e0fa68f4d156c7123be
Summary: This was in the right spirit, but doesn't work because we don't actually update the transport parameters if 0-rtt was accepted, so this ends up being the packet size in perpetuity.
Reviewed By: lnicco, xttjsn
Differential Revision: D23689185
fbshipit-source-id: c45eca1e388534f07eeafbb2c075e133bac071f8
Summary:
This is a bug, for 0rtt, even if the can ignore flag is set, we shouldn't trust the old max packet size. If it has changed then the peer will fail to decrypt anything.
There are open questions here around the PMTU we use for the handshake/0rtt, but let's just punt on those for now.
Reviewed By: udippant, xttjsn
Differential Revision: D23641082
fbshipit-source-id: aba93713091805e9498ab2c14b24bccf18192c02
Summary: This adds the Mocks for ClientHandshake and ClientHandshakeFactory. I added a simple test for `updateTransportParamsFromCachedEarlyParams`.
Reviewed By: mjoras
Differential Revision: D23308946
fbshipit-source-id: 6c22412efc6708ad13cd64ade3e9bccc7c80305d