1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-04-18 17:24:03 +03:00

112 Commits

Author SHA1 Message Date
Joseph Beshay
c6d8f76e67 Refactor AckScheduler to use it in both PacketScheduler and PacketRebuilder
Summary: The logic for deciding which ACK type to write was duplicated in QuicPacketScheduler and QuicPacketRebuilder. This refactors the logic out into a separate QuicAckScheduler so it can be tested for correction and reused in both places.

Reviewed By: sharmafb

Differential Revision: D69933311

fbshipit-source-id: e4f45688a5d258dd2a57f9f7844407f3efad5f49
2025-02-24 12:32:50 -08:00
Matt Joras
6a8f9bcb6b Add fixed short header padding
Summary: This adds a knob which puts a fixed amount of padding at the start of short header packets. This is useful to test the consequences of e.g. a larger CID or the impacts of a smaller packet size.

Reviewed By: jbeshay

Differential Revision: D69603113

fbshipit-source-id: b92ba78682eed21b7d75e38c9584a93481e2eb2f
2025-02-14 09:57:41 -08:00
Alan Frindell
bdc0b34443 Refactor QuicPacketScheduleTest priority tests
Summary: There was so much boilerplate in these tests they were very hard to read and reason about.

Reviewed By: mjoras

Differential Revision: D68677041

fbshipit-source-id: 162c80021ee6db5baacd6999a2958242b906e83a
2025-01-27 11:00:59 -08:00
Paul Farcasanu
38d77ba81f paused priority support
Reviewed By: afrind

Differential Revision: D67988645

fbshipit-source-id: 465f8c56177e5b703dbc1511b73521e6c26c1f3e
2025-01-24 13:54:42 -08:00
Jolene Tan
a61b13a005 Add option to clone all CRYPTO packets at most once
Summary: Restore the buggy version of `cloneAllPacketsWithCryptoFrame`, which did allow up to two packets to be cloned in the same PTO flight but would only clone them at most once, as an optional mode of operation.

Reviewed By: mjoras

Differential Revision: D67994014

fbshipit-source-id: 16f66fd48a9a4410427ba21dea6e7f6d1eee48e6
2025-01-15 14:08:52 -08:00
Aman Sharma
d40144ab03 Modify QuicPacketScheduler for sending reliable resets
Summary:
I'm modifying the `QuicPacketScheduler` so that we only send RESET_STREAM_AT frames when we've sent out all of the data upto the reliable offset. While this is not something that's mandated by the spec, it greatly simplifies the accounting of flow control if we do it this way.

In more detail, if we allowed the egressing of the RESET_STREAM_AT frame before all of the reliable data was sent out, we'd need coordination between the StreamFrameScheduler and the RstStreamScheduler, so as to ensure that we are correctly accounting for flow control. In addition to that, we'd likely have to have a "flow control accounted for" offset in each stream state, so as to ensure that we don't "double count" flow control between the two schedulers. This adds significant complexity, so we're just sending RESET_STREAM_AT frames when we've sent out all of the data upto the reliable offset.

Reviewed By: mjoras

Differential Revision: D66709346

fbshipit-source-id: 01ca8659ae80fcdbd0e599f480fde10a11f0a56b
2024-12-04 19:09:05 -08:00
Nicholas Ormrod
37cf3495d8 namespace-concat in fbcode/quic
Summary:
Concatenate adjacent namespaces + format

This is a codemod. It was automatically generated and will be landed once it is approved and tests are passing in sandcastle.
You have been added as a reviewer by Sentinel or Butterfly.

Autodiff project: nc
Autodiff partition: fbcode.quic
Autodiff bookmark: ad.nc.fbcode.quic

Reviewed By: hanidamlaj

Differential Revision: D65365244

fbshipit-source-id: 0bbaa7684d03caf8fc8eff3439a0865940398220
2024-11-01 18:34:56 -07:00
Jolene Tan
599d410b01 Only skip cloned CRYPTO packet if same as most recent outstanding packet
Summary:
In CloningScheduler, in the loop for selecting a candidate packet for cloning under the "cloneAllPacketsWithCryptoFrame" mode of operation, skip a packet containing a CRYPTO frame only if both it and the most recent outstanding packet are clones of the same packet.

Otherwise, it would clone the CRYPTO packets no more than once.

Reviewed By: mjoras

Differential Revision: D64411438

fbshipit-source-id: eac9e3dbb4c6d2536b1259af08f3c9647ef06ad8
2024-10-15 18:04:35 -07:00
Jolene Tan
c2715ab822 Clone and schedule all packets containing CRYPTO frames
Summary:
A packet in the CloningScheduler can be in three states:

1. Not cloned yet
2. Cloned, not processed yet
3. Cloned and processed

Currently, CloningScheduler will clone a packet in state 1, moving it to state 2, and continue cloning the packet while it is in state 2 without proceeding to subsequent packets.

This change makes it so that a packet in state 2 that has a CRYPTO frame will be skipped over, so that the next packet (which will be in state 1) has a chance to also be cloned.

Extra: Fix `DoNotCloneProcessedClonedPacket` to have the first packet be the already-processed one. If the second packet is the only one already processed, then of course the first one would be scheduled, letting the test speciously pass.

Reviewed By: mjoras

Differential Revision: D62770483

fbshipit-source-id: 5b00958ab4a787615338debacbe9bd2a0f6f74a4
2024-09-23 13:09:46 -07:00
Aman Sharma
8e650ed585 Rename PacketEvent -> ClonedPacketIdentifier [take 2]
Summary: This is my second attempt at D61871891. This time, I ran `xplat/cross_plat_devx/somerge_maps/compute_merge_maps.py`, which generated quic/somerge_defs.bzl

Reviewed By: kvtsoy

Differential Revision: D61975459

fbshipit-source-id: bec62acb2b400f4a102574e8c882927f41b9330e
2024-08-30 12:18:20 -07:00
Marshall Mann-Wood
457ae5b1ac Revert D61871891: Rename PacketEvent -> ClonedPacketIdentifier
Differential Revision:
D61871891

Original commit changeset: f9c626d900c8

Original Phabricator Diff: D61871891

fbshipit-source-id: afe88d4b7a2ca62b16e122d9f087df3caf3e0f41
2024-08-28 16:13:54 -07:00
Aman Sharma
6f13f404b0 Rename PacketEvent -> ClonedPacketIdentifier
Summary: `PacketEvent` is a very inaccurate and misleading name. We're basically using this as an identifier for cloned packets, so `ClonedPacketIdentifier` is a much better.

Reviewed By: kvtsoy

Differential Revision: D61871891

fbshipit-source-id: f9c626d900c8b7ab7e231c9bad4c1629384ebb77
2024-08-28 14:26:30 -07:00
Aman Sharma
bc386475e5 Integrate RangeChain into write path of QUIC stack
Summary: See title

Reviewed By: mjoras

Differential Revision: D58216871

fbshipit-source-id: 9afc08946a676ec967c998416a6470d4884af550
2024-08-15 05:46:08 -07:00
Aman Sharma
a84708be4b Less direct Buf access in BufAccessor
Summary:
**Context**
The `BufAccessor` is used to access a contiguous section of memory. Right now, it works with a `Buf` under the hood.

**Overall plan**
The plan is to change the `BufAccessor` to use a `uint8_t*` instead. Since we're using section of contiguous memory, there's no need to use a chained buffer abstraction here. This'll move us closer to deprecating the usage `folly::IOBuf`.

**What this diff is doing**
Most use cases of the `BufAccessor` look like the following:
```
auto buf = bufAccessor.obtain();
// Do something with buf, like calling trimEnd
bufAccessor.release(buf)
```
I'm adding APIs to the `BufAccessor` so that there's no need to `obtain()` and `release()` the `Buf`. We'd instead just call an API on the `BufAccessor`, which would call that same API on the underlying `folly::IOBuf`. Later on, we'll change the `BufAccessor` to use a `uint8_t*` under the hood.

I'm currently leaving in the `obtain()`, `release()`, and `buf()` APIs because Fizz and the AsyncUDPSocket expect `folly::IOBuf` as inputs in many of their APIs. Once those callsites are migrated off `folly::IOBuf`, we can remove these APIs.

Reviewed By: mjoras

Differential Revision: D60973166

fbshipit-source-id: 52aa3541d0c4878c7ee8525d70ac280508b61e24
2024-08-09 14:35:39 -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
Matt Joras
6ce29d58ff remove isHandshake
Summary: This is effectively an unused field encoding duplicated information, but it was widespread.

Reviewed By: kvtsoy

Differential Revision: D57289922

fbshipit-source-id: ca1499e2576e5ae28e3880b865a29c2b8d9a3d1b
2024-06-11 11:02:02 -07:00
Alan Frindell
ee90db8520 Aggregate QUIC stats callbacks
Summary: This reduces the number of stats callbacks when processing multiple packets in rapid succession.

Reviewed By: mjoras

Differential Revision: D56315022

fbshipit-source-id: 750024301f28b21e3125c144ead6f115706736a4
2024-04-21 16:38:06 -07:00
Aman Sharma
9cdb1cd251 Remove unused fields in OutstandingPacketMetadata [2/n]
Summary: Neither QUIC not TransportMonitor is using the `packetsInflight` field of the `OutstandingPacketMetadata`

Reviewed By: hanidamlaj

Differential Revision: D55926288

fbshipit-source-id: 32efd66add1e6374a8d3446ff635fe582b36e644
2024-04-12 16:29:04 -07:00
Aman Sharma
5fc474a2f9 Remove unused fields in OutstandingPacketMetadata [1/n]
Summary: Neither QUIC not TransportMonitor is using the `totalBodyBytesSent` field of the `OutstandingPacketMetadata`

Reviewed By: hanidamlaj

Differential Revision: D55897240

fbshipit-source-id: 521f8a016f838dd1fe0593daa7a4e45c4fd222cf
2024-04-12 14:19:16 -07:00
Aman Sharma
303c405e10 Create IOBuf on the stack using folly::IOBuf::wrapBufferAsValue for body
Summary: This is similar to the previous commit. We use a stack-based IOBuf instead of allocating one on the heap. This saves CPU because allocations/deallocations on the stack are a lot cheaper.

Reviewed By: hanidamlaj

Differential Revision: D53101722

fbshipit-source-id: dd59a7eca6498db19472a62f954db3e2f2f27a42
2024-01-29 15:19:12 -08:00
Aman Sharma
b2db063139 Create IOBuf on the stack using folly::IOBuf::wrapBufferAsValue for headers
Summary: Creating an IOBuf on the heap when we use `folly::IOBuf::wrapBuffer` is expensive.

Reviewed By: hanidamlaj

Differential Revision: D52506216

fbshipit-source-id: eed2b77beae0419b542b0461303785cc175e3518
2024-01-26 14:01:08 -08:00
Hani Damlaj
4eefa3bebd remove QuicVersion::QUIC_DRAFT
Summary: - as title, deprecate QuicVersion::QUIC_DRAFT

Reviewed By: jbeshay

Differential Revision: D50466992

fbshipit-source-id: 2b2776d142142bc07fd27053a68dd635959a7f31
2023-11-09 19:30:07 -08:00
Matt Joras
6ecdb35ade Minimum packets per stream before next() moves forward
Summary:
The idea here is to allow a way to do incremental stream priorities while switching between streams as aggressively.

Achieving this is somewhat tricky. The easiest place to track this is to make it so the iterator in QuicPriorityQueue no-op next() until a counter reaches an increment.

This is especially impacftul for DSR, where round robining per packet is almost pathologically bad both for CPU impact but also spurious losses and low bandwidth estimates.

Thoughts?

(Note: this ignores all push blocking failures!)

Reviewed By: kvtsoy

Differential Revision: D46268308

fbshipit-source-id: cd5b924141365f61f8a3363bc9cb38a62e5c94cf
2023-06-01 14:11:31 -07:00
Matt Joras
35a2d34843 Use a single queue for scheduling DSR and non-DSR streams.
Summary:
The write loop functions for DSR or non-DSR are segmented today. As such, so are the schedulers. Mirroring this, we also currently store the DSR and non-DSR streams in separate write queues. This makes it impossible to effectively balance between the two without potential priority inversions or starvation.

Combining them into a single queue eliminates this possibility, but is not entirely straightforward.

The main difficulty comes from the schedulers. The `StreamFrameScheduler` for non-DSR data essentially loops over the control stream queue and the normal write queue looking for the next stream to write to a given packet. When the queues are segmented things are nice and easy. When they are combined, we have to deal with the potential that the non-DSR scheduler will hit a stream with only DSR data. Simply bailing isn't quite correct, since it will just cause an empty write loop. To fix that we need check, after we are finished writing a packet, if the next scheduled stream only has DSR data. If it does, we need to ensure `hasPendingData()` returns false.

The same needs to be done in reverse for the DSR stream scheduler.

The last major compication is that we need another loop which wraps the two individual write loop functions, and calls both functions until the packet limit is exhausted or there's no more data to write. This is to handle the case where there are, for example, two active streams with the same incremental priority, and one is DSR and the other is not. In this case each write loop we want to write `packetLimit` packets, flip flopping between DSR and non DSR packets.

This kind of round robining is pathologically bad for DSR, and a future diff will experiment with changing the round robin behavior such that we write a minimum number of packets per stream before moving on to the next stream.

This change also contains some other refactors, such as eliminating `updateLossStreams` from the stream manager.

(Note: this ignores all push blocking failures!)

Reviewed By: kvtsoy

Differential Revision: D46249067

fbshipit-source-id: 56a37c02fef51908c1336266ed40ac6d99bd14d4
2023-06-01 14:11:31 -07:00
Matt Joras
b89882a772 Add TransportSetting and knob for default priority.
Summary: Allows the default stream priority (which also means scheduling policy) to be set via TransportSettings.

Reviewed By: jbeshay, hanidamlaj

Differential Revision: D45881729

fbshipit-source-id: fcb72022cd6eac2f1dafc55173d5a46a72a95dbc
2023-05-18 13:51:53 -07:00
Matt Joras
89cb636283 Remove default priority param.
Summary: As in title. I don't think there's a good reason to have this, better to have the caller be explicit.

Reviewed By: afrind, hanidamlaj

Differential Revision: D45875589

fbshipit-source-id: 3958ca10db542923b46ed8511c996ab3b292e9ab
2023-05-16 12:22:41 -07:00
Paul Farcasanu
e56d4bd7f6 refactor setStreamPriority to accept Priority struct
Summary:
## Context
Context: see summary for D43854603.

## In this diff
In this diff, make way for easily adding new elements to Priority struct.

Reviewed By: afrind

Differential Revision: D43882907

fbshipit-source-id: f74f6ec41162a970dcd666bfa5192676f968d740
2023-03-28 16:00:38 -07:00
Konstantin Tsoy
377260f704 Remove d6d code
Summary: we're not using it

Reviewed By: mjoras

Differential Revision: D43482344

fbshipit-source-id: 05ac6792848e32e7c1bcf53a2df172852b5def62
2023-02-23 20:11:24 -08:00
Brandon Schlinker
87d00ece35 Fix dependency loop and improve namings
Summary:
Fixing dependency loop introduced by D37799050 (96abc8160d)

Running `autodeps` yields the following patch:

```
 --- a/xplat/quic/state/TARGETS
+++ b/xplat/quic/state/TARGETS
@@ -43,8 +43,8 @@
     exported_deps = [
         "//folly:random",
         "//quic:constants",
+        "//quic/codec:codec",
         "//quic/codec:types",
-        "//quic/common:circular_deque",
         "//quic/common:interval_set",
     ],
 )
```

If this patch is applied, there is a circular dependency loop between `//quic/codec:codec` and `//quic/state:ack_states` by way of `//quic/codec:types`; this loop was introduced by D37799050 (96abc8160d).

Fixed by separating out headers files and targets. In parallel, renamed structures used for writing ACK frames (which were the reason this loop occurred) to make their role clear.

Differential Revision: D42281359

fbshipit-source-id: 8514c99f3fe72ff1d942d7f303e4a209838c7623
2023-01-05 15:20:44 -08:00
Matt Joras
1275798146 Make the AckState for Initial/Handshake a unique_ptr
Summary:
We don't need to carry these states after the handshake is confirmed, so make them pointers instead. This will facilitate adding a structure to the AckState for tracking duplicate packets.

(Note: this ignores all push blocking failures!)

Reviewed By: hanidamlaj

Differential Revision: D41626895

fbshipit-source-id: d8ac960b3672b9bb9adaaececa53a1203ec801e0
2022-12-20 11:08:43 -08:00
Matt Joras
bdcffae366 Fix edgecase around writing FIN in a non-DSR stream frame.
Summary:
We previously made the decision to disallow the writing of a FIN on a DSR stream from a non-DSR stream frame as there's not really much value in allowing it.

The code that was previously allowing this to work has a bad bug. If the DSR bytes for a stream were written completely before the non-DSR bytes had been written, the scheduling code would set `canSetFin = true`, which would cause a FIN to be written at the `bufMetaStartingOffset`. This would race with the FIN sent by the backend and, if not cause a connection error, cause an HTTP truncated body of length 0.

We can avoid this by finishing the job of not allowing DSR streams to be FIN'd by non-DSR stream frames.

Reviewed By: hanidamlaj

Differential Revision: D41479274

fbshipit-source-id: 66b321db72fdb4a16378e33048e3fb97133ced92
2022-11-23 10:40:15 -08:00
Sharad Jaiswal (Eng)
96abc8160d Codec changes to support ACK_RECEIVE_TIMESTAMPS
Summary: Create a new ACK_RECEIVE_TIMESTAMPS frame, as outlined in https://www.ietf.org/archive/id/draft-smith-quic-receive-ts-00.html#name-ack_receive_timestamps-fram

Reviewed By: mjoras

Differential Revision: D37799050

fbshipit-source-id: 0157c7fa7c4e489bb310f7c9cd6c0c1877e4967f
2022-11-16 13:02:27 -08:00
Matt Joras
03e314a3a4 Separately track streams by DSR and non DSR data lost.
Summary: We need to do this to maintain consistency with the schedulers. Prior to this fix when we ran out of connection flow control and had lost DSR data the non-DSR stream scheduler would do an empty write _and_ the DSR stream scheduler would do an empty write. To fully resolve the issue we need to track the streams separately (note that the same stream can be in both sets).

Reviewed By: jbeshay

Differential Revision: D40003361

fbshipit-source-id: fd3e567bc8a2bc8b71d4c4543894053fa6e24dc4
2022-10-03 17:02:52 -07:00
Joseph Beshay
9b3a6c0249 If an initial packet is written, its padding should be allowed to bypass the cwnd
Summary:
When 0-rtt is used and an initial packet is lost, the retransmission of this packet may end up shorter than allowed because the padding frames are subject to the cwnd.

This change makes the padding of initial packets not subject to the cwnd.

Reviewed By: mjoras

Differential Revision: D39594390

fbshipit-source-id: 2d714c921f243f8a59577a6edaaeaa1c7e2be815
2022-09-19 17:39:32 -07:00
Joseph Beshay
abee1d8387 Add IMMEDIATE_ACK frame
Summary: Add the new IMMEDIATE_ACK frame from the ack frequency draft.

Reviewed By: mjoras

Differential Revision: D38523438

fbshipit-source-id: 79f4a26160ccf4333fb79897ab4ace2ed262fa01
2022-08-24 11:11:33 -07:00
Konstantin Tsoy
d31df23ca5 Do not add ack frames to packet when it was rebuilt in cloning scheduler
Summary:
We may end up writing acks after a length-less stream frame and it
will be considered garbage data by the peer. The acks will be written later as
usual, outside of cloning scheduler.

Reviewed By: mjoras

Differential Revision: D35561912

fbshipit-source-id: 9334523b984870fa525c856a504ae7d2ae4f34c3
2022-04-12 09:38:19 -07:00
Konstantin Tsoy
42d13f54ae Do not emit empty PTO packets
Summary: Do not emit empty PTO packets

Reviewed By: mjoras

Differential Revision: D34944343

fbshipit-source-id: a49d82cc3d137ed7f113a8e5adab54c84e0e72d0
2022-03-17 08:48:28 -07:00
Richard Barnes
e27b107c6a use gmock 1.10 instead of 1.8
Summary: See D34622171 for details

Differential Revision: D34688142

fbshipit-source-id: ec0c3fdd92723629e0c484388b9ae24436780cf9
2022-03-07 20:03:35 -08:00
Gilson Takaasi Gil
7f2f302f96 Revert D34351084: Migrate from googletest 1.8 to googletest 1.10
Differential Revision:
D34351084 (715dec85be)

Original commit changeset: 939b3985ab63

Original Phabricator Diff: D34351084 (715dec85be)

fbshipit-source-id: 2fd17e0ccd9d1f1d643f4a372d84cb95f5add1f8
2022-03-03 04:41:46 -08:00
Dimitri Bouche
715dec85be Migrate from googletest 1.8 to googletest 1.10 (#67)
Summary:
X-link: https://github.com/facebookincubator/hsthrift/pull/67

Updating `googletest` from `1.8.0` to `1.10.0`

Reviewed By: mzlee, igorsugak, luciang, meyering, r-barnes

Differential Revision: D34351084

fbshipit-source-id: 939b3985ab63a06b6d511ec8711c2d5863bdfea8
2022-03-03 03:46:03 -08:00
Hani Damlaj
00e67c1bf9 mvfst License Header Update
Reviewed By: lnicco

Differential Revision: D33587012

fbshipit-source-id: 972eb440f0156c9c04aa6e8787561b18295c1a97
2022-01-18 13:56:12 -08:00
Hani Damlaj
2660a288b3 Update Company Name
Summary: - as title

Reviewed By: lnicco

Differential Revision: D33513410

fbshipit-source-id: 282b6f512cf83b9abb7990402661135b658f7bd1
2022-01-13 12:07:48 -08:00
Kyle Mirzakhanian
29ed688b58 Add padding to QUIC short header packets
Summary:
Adds paddingModulo to QuicPacketBuilder, which pads up short header packets so that the length remaining of a packet is a multiple of paddingModulo

ie a message of length 25 and max packet size of 40 with a paddingModulo of 8 will get 7 padding frames to a total length of 32. (and a message of length 26 will get 6 padding frames to also go up to a total length of 32)

Reviewed By: mjoras

Differential Revision: D32858254

fbshipit-source-id: 99ada01108429db9f9bba1e342daf99e80385179
2022-01-07 15:02:05 -08:00
Luca Niccolini
95ff9198dd Fix Datagram Write in case there is no space in the QUIC packet
Summary: When there is not enough space in the QUIC packet to write a datagram frame, we should not dequeue the datagram

Reviewed By: mjoras

Differential Revision: D33109603

fbshipit-source-id: 937a5a0ffe55c7f88e39faf224e7ad06ca599708
2021-12-16 11:45:07 -08:00
Matt Joras
ca4705af0b If there's lost data, we have data to write, take 2.
Summary:
This is a bug that could prevent us from writing data if we ran out of connection flow control while we had lost data.

The last attempt missed a mistake in the scheduling of sequential priority streams.

Reviewed By: kvtsoy

Differential Revision: D33030784

fbshipit-source-id: e1b82234346a604875a9ffe9ab7bc5fb398450ed
2021-12-14 09:18:01 -08:00
Brandon Schlinker
82fd138b5e Make OutstandingPacketMetadata::DetailsPerStream non-optional
Summary: As titled. Reduces confusion, as we always expect this to be populated.

Differential Revision: D31887097

fbshipit-source-id: 153b05bae8abd559fe49d2c07c64d2ad0d92a809
2021-12-11 22:40:44 -08:00
Matt Joras
5b9a9705a0 Back out "If there's lost data, we have data to write."
Summary: This is causing empty write loops for some reason.

Reviewed By: jbeshay, lnicco

Differential Revision: D32990291

fbshipit-source-id: 2a183d591de54c7fe0ca54aea828a697a4cd9af0
2021-12-09 14:35:24 -08:00
Matt Joras
d6a876f201 If there's lost data, we have data to write.
Summary: This is an edge case we weren't handling properly. This can lead to situations where we run out of conn flow control, the peer hasn't received all data, and then we never write the data to trigger a flow control update.

Reviewed By: afrind

Differential Revision: D32887140

fbshipit-source-id: df5dfad8e0775ef43e5ca6ab98b8ca6b5987ce31
2021-12-07 18:19:58 -08:00
Luca Niccolini
324d819795 add stats for quic datagram
Summary: Add stats for quic datagrams

Reviewed By: afrind

Differential Revision: D32600300

fbshipit-source-id: 79ebcec5bd090dad16f81237b6b2c0fe4c0f2af6
2021-12-01 00:13:03 -08:00
Luca Niccolini
4a75224cc9 Don't drop datagrams if the frame has no room for them
Reviewed By: afrind, mjoras

Differential Revision: D32608442

fbshipit-source-id: fbd5de333571a2855d8243e7987b5e98ded527fb
2021-12-01 00:13:03 -08:00