1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-09 20:42:44 +03:00
Commit Graph

342 Commits

Author SHA1 Message Date
Konstantin Tsoy
b51ee87995 Add idle timer checker
Reviewed By: mjoras

Differential Revision: D60913168

fbshipit-source-id: 1b14a2e17545ba24f879e7212153eee19cfe9972
2024-08-07 18:55:45 -07:00
Konstantin Tsoy
0801517082 Expose ackTimerFactor in transport settings
Summary: to experiment with

Reviewed By: sharmafb

Differential Revision: D60845774

fbshipit-source-id: bb180bb2fd82b08b7c8af672da015276e12a29d6
2024-08-06 20:13:45 -07:00
Aman Sharma
55bf4a2d27 Move DSR-related APIs to QuicServerTransport
Reviewed By: mjoras

Differential Revision: D59768195

fbshipit-source-id: 8f0780019e5cd9bc3a3863fe30140b8da160c0bc
2024-07-31 10:48:06 -07:00
Matt Joras
e903f277da Introduce OptionalIntegral and OptionalMicros
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
2024-06-11 11:02:02 -07:00
Matt Joras
aefc9e369b Introduce quic::Optional
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
2024-06-11 11:02:02 -07:00
Joseph Beshay
149dd723ac Support for setting a dscp value for outgoing packets
Summary:
Adds a transport setting for the dscp value. The transport combines this value with the ECN flags to enable ECT0/ECT1 marking.

Previous use-cases that are setting dscp values by overriding the whole ToS field should still work, but they will override the ECN bits. This is still the default behavior. Applications willing to use ECN, should use the dscp transport setting instead of applying the tos socket option directly.

Reviewed By: mjoras

Differential Revision: D58203586

fbshipit-source-id: 7dd83ca82273fadd4ae03b015387143e02101b6c
2024-06-07 19:26:28 -07:00
Ilango Purushothaman
67587db908 Convert Ack Rx timestamps disable list to allow list
Summary:
There are still some timestamps seen on dynamic content/connections and disabling timestamps per hostname doesn't scale well.
Instead, this diff will disable timestamps by default in Liger and enable only for static content connections based on a hostname filter (`scontent`, `video`, `cdninstagram`). The actual meat of the change is in `AdvancedHTTPSessionManager::shouldEnableQuicAckRxTimestamps` - everything else is mostly a replacement of disable to enable.

This is implemented for MNS in D58099124.

Reviewed By: jbeshay

Differential Revision: D58099125

fbshipit-source-id: 06118163fcc5d2e2ce90028810d6a9af5c7958a9
2024-06-05 17:21:55 -07:00
Hani Damlaj
ba4c80afbb elide unnecessary string constructors/copies
Summary: elides some string copies in QuicError

Reviewed By: sharmafb

Differential Revision: D57633227

fbshipit-source-id: 2de48895ae221e052438112371f10e50bf47353f
2024-05-26 11:58:55 -07:00
Hani Damlaj
d1f598e0dc elide unnecessary string contructors/copies
Summary: as title mentions, elides some unnecessary string constructors/copies

Reviewed By: sharmafb

Differential Revision: D57633229

fbshipit-source-id: 1a0e6128a4941b4aa1dbaec8d3d236a393f2a35f
2024-05-26 11:58:55 -07:00
Joseph Beshay
3b8782b4b2 Wire the EcnL4STracker to the QuicTransport when L4S is validated
Summary: As title.

Reviewed By: mjoras

Differential Revision: D56449545

fbshipit-source-id: daea00bb179b7f555e9386de5e4ee490be904f4a
2024-05-24 17:16:40 -07:00
Konstantin Tsoy
c34e6eb1e0 Check that transport is still open in maybeStopWriteLooperAndArmSocketWritableEvent();
Summary: We can throw in `writeSocketDataAndCatch()` and that would result in transport closure with drain (with drain keeping the socket alive), but the congestion controller would be reset in close: https://fburl.com/code/zxwfye5u and `maybeStopWriteLooperAndArmSocketWritableEvent()` trips over it later when executed in scope exit.

Reviewed By: mjoras

Differential Revision: D57728369

fbshipit-source-id: 51a4719ae97fab0e90e3ae093a3f56be5a096aff
2024-05-23 11:09:34 -07:00
Joseph Beshay
71b8af4b1a Add new batch writer SinglePacketBackpressureBatchWriter to retry failed writes
Summary:
The existing batch writers do not handle failed writes to the AsyncUDPSocket. A packet that fails to be written is detected as a packet loss later when feedback is received from the peer. This negatively impacts the congestion controller because of the fake loss signal, and artificially inflates the number of retransmitted packets/bytes.

This change adds a new batch writer (SinglePacketBackpressuretBatchWriter) that retains the buffers when a write fails. For subsequent writes, the writer retries the same buffer. No new packets are scheduled until the retried buffer succeeds.

Notes:
- To make sure that retry writes are scheduled, the write callback is installed on the socket when a buffer needs to be retried.
- The retries are for an already scheduled packet. The connection state reflects the timing of the first attempt. This could still have an impact on rtt samples, etc. but it this is a milder impact compared to fake losses/retranmissions.
- Any changes outside of the batch writer only impact the new batch writer. Existing batch writers do not use the fields and are not affected by the changes in this diff.

Reviewed By: kvtsoy

Differential Revision: D57597576

fbshipit-source-id: 9476d71ce52e383c5946466f64bb5eecd4f5d549
2024-05-22 15:35:32 -07:00
Konstantin Tsoy
bc6f00a4f0 Use writable events on the socket
Summary: Use writable events on the socket (disabled by default)

Reviewed By: jbeshay

Differential Revision: D56305786

fbshipit-source-id: f04dea326587268c96915f7a39338ff21dee4aec
2024-05-21 20:06:29 -07:00
Konstantin Tsoy
8aad008940 Use full class name for WRiteCallback to avoid ambiguity
Summary: Adding another WriteCallback in the next diff

Reviewed By: jbeshay

Differential Revision: D56371737

fbshipit-source-id: 4918ca2af3e49968ca0822d7a99309a05021fd10
2024-05-21 10:40:11 -07:00
Hani Damlaj
125cd69ef4 introduce handleHandshakeWriteDataCommon
Summary: - as title, code de-dup

Reviewed By: sharmafb

Differential Revision: D55901184

fbshipit-source-id: c45cb07fc0f13360925bafce75f0a4e2d6910269
2024-05-16 20:45:24 -07:00
Hani Damlaj
9084526f80 introduce handleInitialWriteDataCommon
Summary: - as title; code de-dup

Reviewed By: sharmafb

Differential Revision: D55901183

fbshipit-source-id: 4eae4f2c87c16a413d92c5a724baa35a8f796810
2024-05-16 20:45:24 -07:00
Joseph Beshay
eb778e8f5d Validate ECN/L4S feedback
Summary:
This adds validation to verify that packets sent with an ECT(0/1) marks, are being echoed correctly by the client without any interference in the network path. If validation succeeds, the transport can use the ECN feedback in the congestion controller. If it fails, packet marking is disabled.

Ideally, the number of marks echoed by the peer in ACK_ECN frames should be equal to the number of packets sent with marks. However, that is not achievable with the current design due to the following restrictions:

- To be able to track the number of marks accurately, the sending transport needs to match incoming acks with the outstanding packets they are acking. However,  the sending transport's list of outstanding packets only tracks retransmittable packets. Therefore, acks containing marks that refer to non-retranmittable packets cannot be verified.
- If the client is using GRO, we have one header for the whole batch. So echoed marking can be inflated.

To work around these limitations, the validation logic checks that:
- At least 10 retransmittable packets were sent with marks in the AppData packet number space.
- The number of echoed marks is greater than the number of retransmittable AppData packets sent with marks.
- The number of echoed marks is less than the total number of packets sent.
- No unexpected marks show up. I.e. No ECT0 when sending ECT1 or vv.

Reviewed By: kvtsoy

Differential Revision: D55618562

fbshipit-source-id: 8bc44b4f1b64725f51f63bb86d6c4bd573338e83
2024-05-15 11:51:15 -07:00
Joseph Beshay
3eef6d0e55 Add ToS field to ReceivedUdpPacket
Summary: Adds new field `tosValue` to  ReceivedUdpPacket so it is accessible in the rest of the read path.

Reviewed By: kvtsoy

Differential Revision: D54912161

fbshipit-source-id: ea4714fa2374d38e915fc850387e1094d1fb8adf
2024-05-15 11:51:15 -07:00
Joseph Beshay
7f2cb16408 Refactor QuicClient and Server transports to process ReceivedUdpPackets with attached metadata
Summary: ReceivedUdpPacket has attached metadata (currently timings and later in the stack, tos values). Rather than passing the metadata separately in the read path for the client and the server, this propagates the ReceivedUdpPacket further up so this metadata is easier to use in the rest of the stack.

Reviewed By: mjoras

Differential Revision: D54912162

fbshipit-source-id: c980d5b276704f5bba780ac16a380bbb4e5bedad
2024-05-09 11:05:32 -07:00
Joseph Beshay
993fe05231 Support for sending packets with DSCP, ECT(0) and ECT(1) marking
Summary:
Adds new transport settings for enabling quic sockets to read or write the tos/tclass field in the IP headers.

The new transport settings are: readEcnOnIngress, enableEcnOnEgress, useL4sEcn. All are defaulted to false.

readEcnOnIngress=true --> enabled reading the ToS field from incoming packets.

enableEcnOnEgress=false --> does not set marking
enableEcnOnEgress=true, useL4sEcn=false --> sets marking to ECT0
enableEcnOnEgress=true, useL4sEcn=true --> sets marking to ECT1

The next changes handle these packets in the rest of the stack.

Reviewed By: mjoras, kvtsoy

Differential Revision: D54877773

fbshipit-source-id: af6aefc714e2678f488d027583cf666200748782
2024-05-09 11:05:32 -07:00
Vadim Meleshuk
16501032fa Add open_streams metric
Summary: I want to have visibility in to the current count of streams. There are already callback methods onNew/onClosed, unfortunately, the latter is not called when connections are closed, so I had to fix that to prevent the metric from uncontrolled growth. I am still not positive it's correct and was thinking of hooking into QuicStreamState destructor instead.

Reviewed By: kvtsoy

Differential Revision: D56195487

fbshipit-source-id: 901bce9473327a8f7ef1bc0f70af10899784d681
2024-04-24 19:39:14 -07:00
Konstantin Tsoy
b6d0633e84 Excess writes timer to continue writes
Summary:
We currently do not make use of socket writeable events in mvfst (will be working on that soon), so we may end up in a situation where mvfst has pending data to write, but needs evb loop wake up to do so.

This change introduces a (immediate) timeout to wake up the loop right after it exits to write out the data we have left.

Alternative would be to make the packets per loop limit higher, but this _may_ be nicer given we do yield the loop for other things before waking it up again.

Reviewed By: jbeshay, mjoras

Differential Revision: D56224059

fbshipit-source-id: 2fc0f5000096def459c5d0cb98f6421d36ebbda4
2024-04-16 22:34:27 -07:00
Andres Suarez
71fac54812 Apply clang-format 18
Summary: Previously this code conformed from clang-format 12.

Reviewed By: igorsugak

Differential Revision: D56065247

fbshipit-source-id: f5a985dd8f8b84f2f9e1818b3719b43c5a1b05b3
2024-04-14 11:28:32 -07:00
Konstantin Tsoy
22c661ad6d Allow for contiguous write path in quic client
Summary: Need to create buf accessor for it to work

Reviewed By: jbeshay, sharmafb

Differential Revision: D55264376

fbshipit-source-id: b58de662468f388ac78f369031626567a56988d9
2024-03-25 21:38:02 -07:00
Yedidya Feldblum
f8ccdde463 migrate from FOLLY_MAYBE_UNUSED to [[maybe_unused]]
Reviewed By: ot, Orvid, xinchenguo

Differential Revision: D54089810

fbshipit-source-id: c88eb520404590c9759e0e29966d1399c26a2244
2024-02-28 13:28:26 -08:00
Hani Damlaj
e9c9feea7f remove QuicStreamManager::swapStreams()
Summary: - `swapStreams` is likely mis-implemented and causing an unnecessary copy of the "dst" vector

Reviewed By: mjoras

Differential Revision: D53139321

fbshipit-source-id: adbf1417ee46f10ca4b32389eae7ddaca873c790
2024-01-31 15:13:07 -08:00
Hani Damlaj
d8952820d9 QuicTransportBase
Summary: - refactor some code for conciseness

Reviewed By: mjoras, sharmafb

Differential Revision: D48408121

fbshipit-source-id: 5f774328e1b28f8cbf130c1dc45b3ead0201a874
2024-01-31 15:13:07 -08:00
Hani Damlaj
6573a9f979 maybeSetGenericAppError
Summary: - move `maybeSetGenericAppError` to anonymous namespace

Reviewed By: mjoras, sharmafb

Differential Revision: D48408122

fbshipit-source-id: 1e4f77d2aa6d2440217dfed5b83b5643f8e090c6
2024-01-31 15:13:07 -08:00
Joseph Beshay
cf6f6b98ec Fix active connection counter in QuicStats, and make it work for the client too
Summary:
The current open connection counting is broken. To fix it this change:
- moves the counter to be for both the server and client transport
- calls onNewConnection() when the transport is ready.
- calls onConnectionClose() when the transport is closed after it was ready.

Reviewed By: lnicco, frankfeir

Differential Revision: D52638628

fbshipit-source-id: bcff7a8c671f8eede53c22e698e1b95332c56959
2024-01-12 08:59:15 -08:00
Joseph Beshay
e606de45db Add stream read/write errors to the StreamTransportInfo struct
Summary: As title.

Reviewed By: sharmafb

Differential Revision: D52678304

fbshipit-source-id: 3df2d588c40d40059141c72d0945d31b319b61f8
2024-01-11 19:35:07 -08:00
Joseph Beshay
96b65104dc Move QuicEventBase and QuicTimer callback operations back to the Callbacks themselves.
Summary:
This moves all the loop and timer callback operations back to the callbacks instead of relying the QuicEventBase to perform them. I.e. it's now Callback::cancelCallback() instead of QuicEventBase::cancelCallback(&callback).

To simplify the design, the lifetime of LoopCallbackWrapper and TimerCallbackWrapper has been changed. Previously these wrappers lasted for one iteration of the loop or the timer callback. In the new design the wrapper is created the first time the callback is scheduled and is only destroyed when the callback is destroyed. This significantly simplifies the lifetime management of the wrapper and the code overall.

While transitioning LibevQuicEventBase to this new design, this change also consolidates the QuicTimer functionality in the LibevQuicEventBase itself.

Reviewed By: hanidamlaj, mjoras

Differential Revision: D52217879

fbshipit-source-id: da7b95d592650ddc112813fdc3b9f5010d32e7fb
2024-01-03 12:38:20 -08:00
Matt Joras
3ba2147b67 Always cancel drain timeout in QuicTransportBase destructor
Summary: This is basically as a safeguard, to ensure that the drain timeout doesn't try to keep running after the destruction of the transport.

Reviewed By: jbeshay

Differential Revision: D52267494

fbshipit-source-id: d9ba99e499de7d01281b56bec40298f4e52e6fca
2023-12-18 20:29:12 -08:00
Matt Joras
cc927374d7 Optional writable bytes backpressure
Summary: Add backpressure based on CCA's writable bytes (cwnd), which can be useful for the app to use as backpressure. This also takes into account stream bytes currently buffered.

Differential Revision: D52098629

fbshipit-source-id: c672e73bab01eb301a67c9b8a95225780000cbd6
2023-12-15 21:58:10 -08:00
Joseph Beshay
ead139adef Move all mvfst use-cases to the new Eventbase, Timer, and Socket interfaces
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
2023-12-14 00:24:12 -08:00
Matt Joras
f7a59e8465 onStreamPreReaped
Summary: Move the callback to before the stream is destroyed.

Reviewed By: jbeshay

Differential Revision: D52127833

fbshipit-source-id: 1a9dbcf9ad92dbdb4e15409a418307dc6852b091
2023-12-13 11:19:53 -08:00
Matt Joras
9285422f2a Add onStreamPreReaped.
Summary: This is potentially useful to an application to know when the underlying stream state has been freed by the transport.

Reviewed By: jbeshay

Differential Revision: D52048888

fbshipit-source-id: e7b2d33c3702ce8aa348459a37094198d16af60f
2023-12-13 10:08:47 -08:00
Brandon Schlinker
83ad2ad99d Cleanup and modularize receive path, improve timestamp support [20/x]
Summary:
This diff renames `ReceivedPacket` to `ReceivedUdpPacket` to clarify that it maps to a UDP packet and not a QUIC packet. A single UDP packet can contain multiple QUIC packets due to coalescing.

--

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: silver23arrow

Differential Revision: D48788809

fbshipit-source-id: 3793c30212d545e226f3e5337289bc2601dfa553
2023-11-28 07:47:57 -08:00
Brandon Schlinker
04facac67d Cleanup and modularize receive path, improve timestamp support [15/x]
Summary:
This diff drops `NetworkDataSingle` in favor of `ReceivedPacket`. The latter contains a `ReceivedPacket::Timings` field that has the same `receiveTimePoint` currently in `NetworkDataSingle`, while also providing other useful signals.

--

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: silver23arrow

Differential Revision: D48739219

fbshipit-source-id: fc2cdb7b425d68c729dd3bec00b6c6ff3c4bf8ec
2023-11-05 19:58:46 -08:00
Brandon Schlinker
05b98a99db Cleanup and modularize receive path, improve timestamp support [11/x]
Summary:
This diff:
1. Introduces a new `ReceivedPacket::Timings` structure, which will be expanded upon in subsequent diffs.
2. Adds a `ReceivedPacket::Timings` field to each `ReceivedPacket`
3. Uses the accessors added in the previous diff (D48724715) to populate the `ReceivedPacket::Timings` structure in each `ReceivedPacket` held by a `NetworkData` object. This is done by propagating the `NetworkData::receiveTimePoint` field to all `ReceivedPacket` held in a `NetworkData.` This propagation occurs each time a `ReceivedPacket` is added. The value is propagated again if the `NetworkData::receiveTimePoint` field is updated by looping over all previously added `ReceivedPacket`.

--

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

Differential Revision: D48725209

fbshipit-source-id: 580e7d7d1f3587f9947774b5ed19e9985df404c9
2023-11-05 19:58:46 -08:00
Brandon Schlinker
cb10ddf0ce Cleanup and modularize receive path, improve timestamp support [10/x]
Summary:
This diff makes the fields in `NetworkData` private so that they can only be manipulated via accessors.
- This will be used in a subsequent diff to make it possible to populate a new `ReceivedPacket::Timings` structure in each `ReceivedPacket` held by a `NetworkData` object with the timing information currently held in `NetworkData.`
- These accessors are temporary and being used to split up the stack, so relying on existing tests to provide coverage instead of adding new tests here.

--

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

Differential Revision: D48724715

fbshipit-source-id: 0230ea3feea525fa15b908161f444f4f6d9d4b39
2023-11-05 19:58:46 -08:00
Timm Böttger
5fca38ef00 Use MaybeManagedPtr for QuickSocket for optional lifetime management
Summary:
`connSetupCallback_` and `connCallback_` in `QuicTransportBase.h` are raw pointers, which delegates the responsibility to keep these callbacks alive to the caller.

There are use cases where it would be convenient to be able to tie the lifetime of the callback to the Quic transport, e.g,. as long as the Quic transport is alive, it keeps the callbacks alive as well.

This diff uses MaybeManagedPtr to achieve this lifetime tie if desired. A MaybeManagedPtr intialized with a shared pointer manages lifetime of the contained object, whereas a MaybeManagedPtr initialized with a raw pointer does not manage lifetime of the contained object. This way caller can decide to pass in a shared ptr or raw pointer and achieve the desired behavior.

Note that we cannot simply use a shared_ptr for that. Using a shared_ptr would potentially mean that callbacks passed are destroyed when the transport is destroyed. Callbacks would not be destroyed if they were managed by a shared_ptr already, but this is something we cannot assume for every case. This would thus be a change in semantics to the current implementation, where the callbacks can outlive the transport.

Reviewed By: mjoras

Differential Revision: D49502381

fbshipit-source-id: 771a9328b99dc4f94f8e9679f9caf98af9180428
2023-11-03 09:37:21 -07:00
Dan Melnic
e4f9973008 Try to fix a compile error
Summary: Try to fix a compile error

Reviewed By: avasylev

Differential Revision: D50066567

fbshipit-source-id: 4a774219f9badfd8c470809bec2ef44b84031828
2023-10-09 18:54:29 -07:00
Andrii Vasylevskyi
c0e008c266 Folly SocketOptionMap with strings - separate cmsgs
Summary: Splitting cmgs from socket options.

Reviewed By: mjoras

Differential Revision: D49557451

fbshipit-source-id: fa3005170d049557d1c845fd14b0ada73b58b377
2023-10-01 11:33:09 -07:00
Brandon Schlinker
a1445434b0 Cleanup and modularize receive path, improve timestamp support [5/x]
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
2023-09-21 07:57:58 -07:00
Brandon Schlinker
086822ca76 Cleanup and modularize receive path, improve timestamp support [2/x]
Summary:
This diff:
- Changes `NetworkDataSingle` to have `ReceivedPacket` instead of `Buf`, in line with earlier change to `NetworkData` in D48714615

--

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: mjoras

Differential Revision: D48714796

fbshipit-source-id: d96c2abc81e7c27a01bcd0dd552f274a0c1ede26
2023-09-21 07:57:58 -07:00
Brandon Schlinker
a2c43bcf4c Cleanup and modularize receive path, improve timestamp support [1/x]
Summary:
This diff:
- Changes `NetworkData` to have `vector<ReceivedPacket>` instead of `vector<IOBuf>` to make it easier to associate metadata with individual UDP packets.

--

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: mjoras

Differential Revision: D48714615

fbshipit-source-id: b21a88f14156ed6398308223f50b2334328586ee
2023-09-21 07:57:58 -07:00
Ilango Purushothaman
189d63ad2c Disable Ack Receive Timestamps based on hostname
Summary:
Added the capability to disable Ack receive timestamps based on hostname.
We want to disable timestamps on dynamic content (graph.facebook.com, i.instagram.com etc) to reduce network and resource overhead (thereby saving uplink BW). The hostnames can be specified via a MC. Timestamps should still be enabled for hostnames serving static content (like video, fbcdn...)

We have observed upto 40% more duplicate timestamps being sent on ACKs and ACK packet size has increased by more than 30% on average for such cases. This is a first step in reducing ACK wastage.

(Note: this ignores all push blocking failures!)

Reviewed By: jbeshay

Differential Revision: D48812624

fbshipit-source-id: aa72ec2dcc41ebe9d982364d8d45739e062daddb
2023-09-12 07:47:19 -07:00
Ashkan Nikravesh
4862982004 throttling-detector: create an interface to provide throttling signals to CCAs
Summary: An interface which will be extended by throttling detectors and will provide throttling signal to CCAs. This interface can be set through `QuicSocket` and can be accessed via `QuicConnectionStateBase`.

Reviewed By: silver23arrow, jbeshay

Differential Revision: D47027498

fbshipit-source-id: 6a2b9ee51ca54395e10500dd7c9787968cc281d4
2023-08-30 17:01:06 -07:00
Joseph Beshay
32e07e022c Ensure the pacing rtt factor is not applied for bbr2
Summary: As title.

Reviewed By: mjoras

Differential Revision: D48608150

fbshipit-source-id: 52bc0d6aa3938bfb7f217874ce70a609b2ca31fc
2023-08-24 17:05:28 -07:00
Joseph Beshay
6e3cddc5a4 Ignore incoming knob frames if we haven't advertised knob support
Summary: Only accept knob frames if support has been advertised.

Reviewed By: hanidamlaj

Differential Revision: D48329363

fbshipit-source-id: 3f06574415d95a2129e5d776b7a4f4808791ed45
2023-08-16 10:24:01 -07:00