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:
The current `close` observer event marks when `closeImpl` is called. However, the actual close of the socket may be delayed for some time while the socket drains. I've changed the existing event to `closeStarted` and added a new event `closing` that marks the close of the underlying `AsyncUDPSocket`.
Adding the `closeStarted` event required two other changes which are difficult to separate from this diff:
- When a transport is destroyed, `QuicTransportBase` was calling `closeImpl` and also closing the UDP socket. However, because the `folly::ObserverContainer` used to store observers is maintained in classes that derive from `QuicTransportBase`, the observers are gone by the time the UDP socket is closed in the base class destructor. Thus, the UDP socket should be closed by the derived classes in their respective destructors. This requirement is inline with the existing code: `closeImpl` is called by all derived classes in their destructors. Made this change and added `DCHECK` statements in the `QuicTransportBase` destructor to ensure that derived classes cleanup after themselves.
- Writing tests with draining enabled and disabled required being able to set the transport settings. However, all of the existing `QuicTypedTransportTest` test cases were designed to operate after the connection was accepted (for the server impls) or established (for client impls), and transport settings cannot be updated at this state. Resolving this required adding new test classes in which the accept/connect operation is delayed until requested by the test.
Reviewed By: mjoras
Differential Revision: D39249604
fbshipit-source-id: 0ebf8b719c4d3b01d4f9509cf2b9a4fc72c2e737
Summary: - adding an API to the QuicSocket to enable users to synchronously query the socket for the maximum amount of data that should be written.
Reviewed By: mjoras
Differential Revision: D37390086
fbshipit-source-id: 5dd64e28b7f841ba3e28a4bc2a79c1b1e5a95047
Summary: PacketProcessors process the packets that we send and their corresponding ack and loss events. We store a vector of packet processors inside `QuicConnectionStateBase` and we call `onPacketSent` and `onPacketAck` whenever their corresponding functions in `CongestionController` class are called. The plan is to make `CongestionController` class extend `PacketProcessor`.
Reviewed By: bschlinker
Differential Revision: D36404668
fbshipit-source-id: 52d63a6a74bfa2031131d31047da25a5e2be12aa
Summary: Implement group streams receiver api in transport
Reviewed By: mjoras
Differential Revision: D36419901
fbshipit-source-id: 98bfefa1a4205fde8764f2e4300f51156667e024
Summary: Implement group streams api in transport
Reviewed By: mjoras
Differential Revision: D36417214
fbshipit-source-id: dee93807fe061f2abd9c779da9a2cd1df1865c3e
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:
This diff is part of larger change to switch to using `folly::ObserverContainer` (introduced in D27062840).
This diff:
- Adds methods to `QuicSocket` to support adding and removing `ObserverContainer` observers. By default, `QuicSocket` implementations will not support observers as `QuicSocket::getSocketObserverContainer` returns `nullptr`, and this will cause `QuicSocket::addObserver` and `QuicSocket::removeObserver` to fail gracefully.
- Adds support in `QuicClientTransport` and `QuicServerTransport` for `ObserverContainer` observers by overriding `getSocketObserverContainer`. Each implementation creates an `ObserverContainer` on construction that is destroyed on destruction.
- Adds the `close` event to the new observer interface and adds corresponding support in `QuicTransportBase`. This allows both the old and new observers to receive the close event. The next diff will do a hard cutover of the rest of the events.
Differential Revision: D35000960
fbshipit-source-id: e75807c97f4385532bf36244591a259aa0a2f4cc
Summary:
This diff is part of larger change to switch to using `folly::ObserverContainer` (introduced in D27062840).
This diff:
- Renames `quic::Observer` to `quic::LegacyObserver`.
- Switches to using `quic::SocketObserverInterface` instead of `quic::Observer` when referencing structures used for the observer interface. For instance, `quic::Observer::WriteEvent` changes to `quic::SocketObserverInterface::WriteEvent`.
Differential Revision: D35000152
fbshipit-source-id: f387231fd58e8e763c3d7ed0a9c6fcec3b2324e2
Summary: Report all bytes written in observer packets written events.
Reviewed By: jbeshay
Differential Revision: D33086404
fbshipit-source-id: 1456cf23a420abd025f047f190cb2b8a9868826e
Summary:
This implements a basic keepalive timer at the transport layer.
The basic idea is to leverage the same conditions as the idle timer. The keepalive timer will fire ~15% before the idle timer and trigger a PING frame. This has the effect of keeping the connection open if the PING is acknowledged.
Reviewed By: jbeshay
Differential Revision: D34256174
fbshipit-source-id: a8cee579f5b09bdfa23bcdc7cf4c70de299de3bd
Summary:
Add a helper function to set default error code for close() and
closeNow()
Reviewed By: mjoras
Differential Revision: D34191863
fbshipit-source-id: 8f818f471307ea64ed046ec5e93852566247faa3
Summary: Add new connection end cb option to client/server transport
Reviewed By: mjoras
Differential Revision: D34190871
fbshipit-source-id: 375cf95bc8dbe4ab759140cfb4b33b732869953f
Summary: In order to provide more information about datagrams when we receive them, I'm adding a wrapper around the BufQueue that we currently hold so we can include receiveTimePoint and any other metadata we might want to expose for the Datagram API.
Reviewed By: mjoras
Differential Revision: D33994358
fbshipit-source-id: 805f182cd350908320639bc07eb6f3b7349bbc05
Summary:
Adds a transport callback for ping received.
Uses the callback in the HTTP3 session to reset the timeout
Also now invokes the ping callbacks synchronously to avoid issues during connection shutdown
Reviewed By: mjoras
Differential Revision: D33753068
fbshipit-source-id: 99ac14d0e4b9539f3a20c5c55bb5241351bf1c57
Summary:
Adds a transport callback for ping received.
Uses the callback in the HTTP3 session to reset the timeout
Reviewed By: mjoras
Differential Revision: D33101180
fbshipit-source-id: d6fcecd22cbd5c311674dd9421c0c54eb04728a0
Summary:
Providers observers with insight into ACKs received. Works for both client and server transport.
Attempts to prevent wasted memory by removing any allocated memory for ACK events if no packets in flight. In tandem, reduces allocs by _not_ removing allocated memory when packets are in flight (as this means more ACK events will occur soon...).
Reviewed By: jbeshay
Differential Revision: D31221280
fbshipit-source-id: 64b73aa74c757ebbfc27bb9c2a047d08dc7a77ca
Summary:
Currently the `packetsWritten` observer event is only triggered when ACK-eliciting packets are written to the network. This change makes it so that the event is triggered even when non ACK-eliciting packets are written. In addition, this change increases the information provided in the observer event to reduce the processing that must be performed by observers.
More specifically, this diff makes the following changes:
- It creates two new structs — `WriteEvent` and `PacketsWrittenEvent` — and makes `PacketsWrittenEvent` and `AppLimitedEvent` inherit from `WriteEvent`, which contains the base set of fields that appear in both derived events. The base set of fields includes `writeCount` and the reference to the list of `OutstandingPackets`.
- A `PacketsWrittenEvent` is generated after each write loop during which packets are written.
- The `PacketsWrittenEvent` records the total number of packets written (the sum of ACK-eliciting and non ACK-eliciting packets written) and the total number of ACK-eliciting packets written during the last loop. By exposing this information, observers can determine whether there is value in inspecting the list of `OutstandingPackets` before doing so.
- In the future, I'll extend this event to also report the number of stream bytes written.
- It adopts a new builder pattern for observer events to make it easier to create instances of these structures:
- We use this approach instead of aggregate initialization (specifically designated initializers via aggregate initialization), because designated initializers (C++20 feature, although supported by some compilers long before) is not yet supported on all platforms for which we need this code to compile.
- I intend to change the other observer events to use this pattern as the number of arguments in some of their constructors makes them increasingly difficult to deal with.
Reviewed By: mjoras
Differential Revision: D31216724
fbshipit-source-id: 42ceb922d46ab0e0dc356f8726c2d0467a219587
Summary: Provide observers with visibility into stream events triggered by local and peer (e.g., new stream opened locally or by peer).
Reviewed By: mjoras
Differential Revision: D31886978
fbshipit-source-id: 7556fef0f336bd0f190b4474f1a7b0120aae6ef1
Summary:
The StreamManager monitors can now have a reference to a new observer interface QuicStreamPrioritiesObserver. If the reference is set, the observer is notified whenever streams are created, removed, or change priorities
QuicTransportBase implements this observer interface. It uses the event notifications to control a connection's background mode based upon the new background mode parameters: priority level threshold, and target utilization factor. When these parameters are set, and all active streams have a priority lower than the threshold, the connection's congestion controller is set to use only the defined utilization factor of the available bandwidth.
Reviewed By: bschlinker
Differential Revision: D31562505
fbshipit-source-id: 9c74fa834301f745d97e851741b911795f756023
Summary:
This diff introduces split callbacks to QUIC.
Old: callback:
* `ConnectionCallback`
Two new callbacks:
* `ConnectionSetupCallback`
* `ConnectionStreamsCallback`
For now the idea is that both old and new callbacks will live side by side and mvfst will decide which callbacks scheme to use via the `useSplitConnectionCallbacks` flag supplied on both QUIC client and server creation.
Reviewed By: mjoras
Differential Revision: D30407129
fbshipit-source-id: 7b726c2652ebe00b47f44bf291cffb9d9f6c884b
Summary:
This is another diff preparing mvfst for the new split callbacks.
This change introduces a callback dispatcher. Right now, it simply calls the existing monolithic callback everywhere. In future diffs, this dispatcher will be using the `useSplitCallbacks` flag to decide which callback object to call.
Reviewed By: mjoras
Differential Revision: D30404458
fbshipit-source-id: 5bb919185b845acc3e8ce7c596c0769b541ff69d
Summary:
For the split QUIC callbacks, onConnectionError() will be present in both connection setup and normal connection callbacks.
This diff has no functional changes rather just separates the code that will change (in diffs higher up the stack) into a few functions for easiness.
Reviewed By: mjoras, lnicco
Differential Revision: D30400469
fbshipit-source-id: df259f201b74c51704e4284cbf94ad485f80a1ab
Summary:
This change just adds a (currently no-op) flag that will be used in diffs up the stack.
The idea here is that I'll add split QUIC connection callback interfaces that will live side by side with existing single monolithic callback for now. We will experiment with split callbacks on small scale to see that there is no regressions and then will phase out the old callback gradually.
This flag is to control which callback(s) to use.
Reviewed By: mjoras
Differential Revision: D30399667
fbshipit-source-id: 8fc4e4a005e93cf6d48a987f49edee33b90dbbf1
Summary:
For each `QuicServerTransport` created by `QuicServerWorker`, we are able to set the `cmsg`s to be sent whenever there's a write.
With this we can set things like TOS/SO_MARK per connection
Reviewed By: bschlinker
Differential Revision: D29313608
fbshipit-source-id: d60c97f65681086ae1079b6b95beade95158ec59
Summary:
Add a new QuicSocket API that sets the maximum pacing rate in Bytes per second to be used if pacing is enabled. This setting is passed down to the Pacer which enforces it.
The change also includes:
- Refactoring the setPacingRate function of the Pacer to make it more consistent with the other refreshPacingRate function.
- A new flag for testing the MAX_PACING_RATE using tperf.
Reviewed By: mjoras
Differential Revision: D29276789
fbshipit-source-id: 818d86707084b2697f7417b4a47e62cbbce65c73
Summary: DeliveryCallback is a ByteEventCallback, so callers shouldn't need to change.
Reviewed By: bschlinker, mjoras
Differential Revision: D28562237
fbshipit-source-id: d7d41bbc3cbc708f7ecda5086fcba46b6a7847b0
Summary:
Previously we were using a single flag appDataSentEvents to enable 3 callbacks
(startWritingFromAppLimited, packetsWritten and appRateLimited). This commit
creates separate flags to enable each of these callbacks, we have use-cases
where Observers might want only packetsWritten events and not the others.
Also, this commit refactors the logic to deliver these 3 callbacks to all
observers into a separate method so they can be unit tested easily.
Reviewed By: bschlinker
Differential Revision: D27925011
fbshipit-source-id: 7f7436dfc3d50c3abcb8ec121b221d20e30b0c4b
Summary:
This assigns a DSRPacketizationRequestSender to a QUIC stream, and let
it own it.
Reviewed By: mjoras
Differential Revision: D27668523
fbshipit-source-id: 4beba6ddf247801368c3e1c24a0a4956490d45cd
Summary:
Instead of writing real data into the transport, we want to support a
use case where only its metadata is written to the transport. Sending of the
real data is delegated to another entity in such setup.
Reviewed By: mjoras
Differential Revision: D26131772
fbshipit-source-id: 4fcfa3a1626203f63c61898e6de089a3079d043d
Summary:
Before the change, there's no good way to recreate Cubic CC instance with custom CC factory, because Cubic is created by default.
On client side this requires calling setCongestionControl() or setTransportSettings() after calling setCongestionControllerFactory(), which is normally the case.
Reviewed By: yangchi
Differential Revision: D26401996
fbshipit-source-id: dfda39be835c67b9db42f726b3ac64c7b3d37c2f
Summary: Allows CongestionControllerFactor to access Pacer and update it's state if needed
Reviewed By: yangchi
Differential Revision: D26382984
fbshipit-source-id: fd73fbb6f0989c52a1a2061670fb9e6b188049d6
Summary: Adding QuiConnectionStats to client transport. Moving getConnectionsStats() logic from server worker into transport base class.
Reviewed By: lnicco
Differential Revision: D26316635
fbshipit-source-id: a384eee5d1bc7b23d908e0b03fafcc4ee962b0b9