Summary:
This introduces a new frame type for acks (ACK_EXTENDED) that can carry optional fields depending on the features supported by the peer. The currently supported features set will include ECN count fields, and Receive Timstamp fields. This enables a quic connection to report both ECN counts and receive timestamps, which is not possible otherwise because they use different frame types.
Support for the extended ack as well as the set of features that can be included in it is negotiated through a new transport parameter (extended_ack_supported = 0xff0a004). Its value indicates which features are supported by the local transport. The value is an integer which is evaluated against the following bitmasks:
```
ECN_COUNTS = 0x01,
RECEIVE_TIMESTAMPS = 0x02,
```
This diff introduces the transport parameter and negotiates the supported features between the peers of the connection. The parameter is cached in the psk cache so the client can remember the server config. It is also encoded inside the 0-rtt ticket so the server can reject it if its local config has changed.
The following diffs add reading and writing the frame itself.
The ACK_EXTENDED frame itself will have the following format
```
ACK_EXTENDED Frame {
Type (i) = 0xB1
// Fields of the existing ACK (type=0x02) frame:
Largest Acknowledged (i),
ACK Delay (i),
ACK Range Count (i),
First ACK Range (i),
ACK Range (..) ...,
Extended Ack Features (i),
// Optional ECN counts (if bit 0 is set in Features)
[ECN Counts (..)],
// Optional Receive Timestamps (if bit 1 is set in Features)
[Receive Timestamps (..)]
}
// Fields from the existing ACK_ECN frame
ECN Counts {
ECT0 Count (i),
ECT1 Count (i),
ECN-CE Count (i),
}
// Fields from the existing ACK_RECEIVE_TIMESTAMPS frame
Receive Timestamps {
Timestamp Range Count (i),
Timestamp Ranges (..) ...,
}
Timestamp Range {
Gap (i),
Timestamp Delta Count (i),
Timestamp Delta (i) ...,
}
```
Reviewed By: sharmafb
Differential Revision: D68931151
fbshipit-source-id: 44c8c83d2f434abca97c4e85f0fa7502736cddc1
Summary:
Remove headers flagged by facebook-unused-include-check over fbcode.quic.
+ format and autodeps
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: uiq
Autodiff partition: fbcode.quic
Autodiff bookmark: ad.uiq.fbcode.quic
Reviewed By: hanidamlaj
Differential Revision: D69864370
fbshipit-source-id: fb8f85599e1e12429f00dc2817dfc5ecf55bc482
Summary: Separate functionality for parsing receive timestamp and ecn fields in ACKs into their own functions.
Differential Revision: D68931150
fbshipit-source-id: 8031770b118138a0002999bca52c69f96f29b617
Summary:
You can find the format of the RST_STREAM_AT frame in the [RFC](https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset-06#name-reset_stream_at-frame). In this change, I'm adding RST_STREAM_AT to the FrameType enum and am also adding the functionality to decode such frames.
Note that we ignore the case when we receive RST_STREAM_AT frames (because we haven't implemented their handler yet).
Reviewed By: hanidamlaj
Differential Revision: D64836490
fbshipit-source-id: 5bd742b14c343ce2f26dd29d3a285a6fed60676a
Summary: This will make it easier to distinguish between the `finalSize` and the `reliableSize` when we implement reliable resets
Reviewed By: hanidamlaj
Differential Revision: D64836474
fbshipit-source-id: d811d64a2538d4d1acba1ea10a7790d5905f02a4
Summary: Constructing an `fbstring` from an `IOBuf` and then converting that to `std::string` is inefficient: if the `IOBuf` is chained, that can end up copying the data twice. `to<std::string>()` does exactly one copy.
Reviewed By: mjoras
Differential Revision: D58379802
fbshipit-source-id: a1094dd63ae00fc123e0d695a800a017004562e9
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:
Read echoed ECN counts from incoming ACK_ECN frames.
Write ECN counts from AckState into outgoing ACK_ECN frames.
This also logs both the ECN counts in the read/writter packets in qlog.
Reviewed By: kvtsoy
Differential Revision: D54967248
fbshipit-source-id: 68b910865515271abfd1fa61fc43ce1cb12f30a7
Summary:
- trimAtMost() can be implemented via splitAtMost()
- trimAtMost() now releases owned IOBuf if the entire chain is consumed
Reviewed By: mjoras
Differential Revision: D46776767
fbshipit-source-id: 0ace20d07d8b9adc1a5171e39732b8278776c332
Summary:
the helper function `Decode.cpp:computeAdjustedDelay()` function takes a delay value, applies an exponent adjustment, and performs checks for overflow and validity before returning the adjusted delay.
This function is used to decode both the ack_delay, as well as the relative time-gap between RX time-stamps.
Additional logging collected via D41988681 and multiple long-running canaries indicate the "long ack delay error" that is flagged when the decoded value > 1000secs, occurs only when decoding rx timestamps.
The first rx timestamp in any ack_receive_timestamp range has a relative delay computed with the connection start time as a basis, hence on long lived connections this can exceed > 1000secs (the current threshold for the error message).
Therefore, we have moved the error statement (and the error check) to be only at the call site processing ack delays (and not rx timestamp relative delays).
Reviewed By: bschlinker, mjoras
Differential Revision: D46059268
fbshipit-source-id: 2637986d5919207b6c7d858a69b33139dad785e7
Summary: We shouldn't have config in the codec types. Instead solve the plumbing problem more explicitly, and only define the config in one place.
Reviewed By: jbeshay
Differential Revision: D45881730
fbshipit-source-id: fab6c967a38172f16e57a8978b10460fd196902e
Summary:
Padding frames by definition have no semantics. There also can be quite a large number of them, which makes their storage expensive.
Optimize for this by effectively coalescing multiple contiguous padding frames into a single frame.
(Note: this ignores all push blocking failures!)
Reviewed By: kvtsoy
Differential Revision: D44636497
fbshipit-source-id: 4c1cd88123c4fdf40ec9c553885f46669f7326da
Summary: Add the new IMMEDIATE_ACK frame from the ack frequency draft.
Reviewed By: mjoras
Differential Revision: D38523438
fbshipit-source-id: 79f4a26160ccf4333fb79897ab4ace2ed262fa01
Summary:
- Use varint reordering threshold (this is still being discussed, using varint until a decision is made)
- Track server's minAckDelay on client
- Track ack frequency frame sequence number
- Improve frame parsing error logs
- Add some unit tests
Reviewed By: hanidamlaj
Differential Revision: D38289108
fbshipit-source-id: 274e45115022ffd4e15b60dc57f77f1cce69bd82
Summary:
- Issuing NewTokenFrames to clients, allowing them to verify their address in subsequent connections by including the token.
- add NewTokenFrame struct in the union type QuicSimpleFrame.
- Issued only once when the crypto handshake is complete.
- Testing includes validating token serialization & deserialization and asserting that the NewTokenFrame is only issued once on handshake completeness.
Reviewed By: mjoras
Differential Revision: D31673160
fbshipit-source-id: 9401ab1a4b878d8b4380d55afa531ec768f5f4cd
Summary:
These are either no longer relevant, are unlikely to be done, or are spculative enough that they don't deserve code space.
Hope here is to make our search for TODOs higher signal.
Reviewed By: lnicco
Differential Revision: D29769792
fbshipit-source-id: 7cfa62cdc15e72d8b7b0cd5dbb5913ea3ca3dc5a
Summary: This diff is the encode and decode support of Datagram frame.
Reviewed By: mjoras, yangchi
Differential Revision: D20983883
fbshipit-source-id: 1a72a87e6ce3601b71fececca872a9d20bf7820e
Summary:
Checks that MaxStreamsId is in range during MaxStreamsFrame decode, otherwise throws exception.
Added tests for MaxStreamsFrame decode.
Reviewed By: mjoras
Differential Revision: D27520634
fbshipit-source-id: f903763781639d078f92080b98f15b97e04a8d60
Summary: As in title. This doesn't actually send any frames, but implements basic support for the transport parameter and responding to the frames.
Reviewed By: yangchi
Differential Revision: D26134787
fbshipit-source-id: 2c48e01084034317c8f36f89c69d172e3cb42278
Summary:
the previous sanitizing of ack delay is too local. The bad value is
later on used again in another calculation. This diff moves the sanitization
code to the frame decoding site and overwrite the value to 0us if it's too ridiculous.
(Note: this ignores all push blocking failures!)
Reviewed By: lnicco
Differential Revision: D25515650
fbshipit-source-id: d18dc39e51bbbac24a6b271e67b79a82e9dc38a6
Summary:
This introduces a new extension frame, the KnobFrame, and an implementation.
The idea with Knobs is that they are arbitrary key-values within a namespace that can be transmitted to the peer at any time. They provide an alternative to transport settings, by eschewing the standard transport setting space entirely.
The idea is simple, each knob has a "knobspace", "id", and value. The knobspace is a namespace in which the knob has semantic meaning (e.g. 0xfaceb00). The id and value are just that, arbitrary identifiers and values.
On receiving a knob it is the application's reponsibility to deal with it.
Reviewed By: mjoras
Differential Revision: D23601468
fbshipit-source-id: 63e5e4a7bdb76e11e8c952f1234f512a629ef348
Summary: We need to internally represent them as uint64_t, in addition to parsing them as var ints.
Reviewed By: yangchi
Differential Revision: D21261466
fbshipit-source-id: 4ff7b9350cbf1dc0b58cb7ce00674430afd3ba53
Summary: This makes the change for the client to use stateless retries
Reviewed By: mjoras
Differential Revision: D19657433
fbshipit-source-id: d4b34087d15e49153860a7833ed54e28c6cd6777
Summary: This can happen more often than we'd like, and there's no reason to force throwing the exception when we can instead validate the length first.
Reviewed By: udippant
Differential Revision: D20770869
fbshipit-source-id: 93e2349b02d6d2067f345b5fa9decee800c84ea6
Summary: This is without cipher dropping, but the frame is parseable and the server will send it at the correct time.
Reviewed By: yangchi, lnicco
Differential Revision: D20235013
fbshipit-source-id: 696c11ec573a530b3ed9f4185a2f6847ee08819f
Summary:
This eliminatees some tech debt by completely removing the notion of version from the core transport parameters structure and the app token for zero rtt.
Note that for the draft-27 changes we will need to temporarily re-introduce it, but to a different layer (the extension encoding itself).
Reviewed By: JunqiWang
Differential Revision: D20073578
fbshipit-source-id: 2b55af621566bf1c20e21dd17251116de1788fa0
Summary: This implements the handshake done signal and also cipher dropping.
Reviewed By: yangchi
Differential Revision: D19584922
fbshipit-source-id: a98bec8f1076393b051ff65a2d8aae7d572b42f5
Summary:
New QUIC draft no longer has this limitation for connection-id, and allows
connid of len 0 -> 20.
This diff removes the constraints. I still kept the requirement for
*server-chosen* conn-id
Reviewed By: mjoras, lnicco
Differential Revision: D19507366
fbshipit-source-id: 4c73f45617f40b29d47d2d86b7598f6c95588d0a
Summary:
All instancesi of LIKELY and UNLIKELY probably should be removed. We will
add them back in if we see pathologies in performance profiles.
Reviewed By: mjoras
Differential Revision: D19163441
fbshipit-source-id: c4c2494d18ecfd28f00af1e68ecaf1e85c1a2e10
Summary: By using something which inlines some number of elements, we can avoid doing any mallocs from `std::vector` in the common cases. This also eliminates one layer of indirection in the common case.
Reviewed By: siyengar
Differential Revision: D18903523
fbshipit-source-id: 9f72e93f58a6b42777e5afe10e7ee6a13bf94c66
Summary:
For padding frames we don't really need to know the exact number of padding frames in the packet,
but just that a padding frame exists.
This diff tries to collapse multiple sequential padding frames into 1 frame while decoding the packet.
While this wont collapse all padding frames, the common case is that padding is sequential and at the
end of the packet.
Reviewed By: JunqiWang
Differential Revision: D18901925
fbshipit-source-id: 17b4eeabdbf4df01c900a9d5078891eb64bf254a
Summary:
Don't use IOBufQueue for most operations in mvfst and use BufQueue instead. Since BufQueue did not support a splitAtMost, added it in instead.
The only place that we still use IOBufQueue is in crypto because fizz still requires it
Reviewed By: mjoras
Differential Revision: D18846960
fbshipit-source-id: 4320b7f8614f8d2c75f6de0e6b786d33650e9656
Summary:
Don't clone during decoding a stream frame.
This uses a BufQueue to manage the data instead of passing around cursors.
Reviewed By: yangchi
Differential Revision: D18827718
fbshipit-source-id: 7874d308bb5f43b983b9965b2862e733a2107039