mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-11-24 04:01:07 +03:00
Write ACK_EXTENDED frame when supported by peer
Summary:
Write the new ACK_EXTENDED frame. When any of the ACK_EXTENDED features are enabled locally and supported by the peer, this frame type will take precedence over ACK_ECN and ACK_RECEIVETIMESTAMPS. See first diff in the stack for the features.
Frame 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: D68931148
fbshipit-source-id: 0fb4bac23e121f82a11602daabc1ec7084db43dd
This commit is contained in:
committed by
Facebook GitHub Bot
parent
31fbb343d1
commit
aac108ddc7
@@ -569,15 +569,36 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
PacketBuilderInterface& builder,
|
||||
FrameType frameType,
|
||||
const AckReceiveTimestampsConfig& recvTimestampsConfig,
|
||||
uint64_t maxRecvTimestampsToSend) {
|
||||
uint64_t maxRecvTimestampsToSend,
|
||||
ExtendedAckFeatureMaskType extendedAckFeatures) {
|
||||
if (ackFrameMetaData.ackState.acks.empty()) {
|
||||
return none;
|
||||
}
|
||||
uint64_t beginningSpace = builder.remainingSpaceInPkt();
|
||||
uint64_t spaceLeft = beginningSpace;
|
||||
|
||||
bool ecnEnabled = (frameType == FrameType::ACK_ECN) ||
|
||||
(extendedAckFeatures &
|
||||
static_cast<ExtendedAckFeatureMaskType>(
|
||||
ExtendedAckFeatureMask::ECN_COUNTS));
|
||||
|
||||
bool receiveTimestampsEnabled =
|
||||
(frameType == FrameType::ACK_RECEIVE_TIMESTAMPS) ||
|
||||
(extendedAckFeatures &
|
||||
static_cast<ExtendedAckFeatureMaskType>(
|
||||
ExtendedAckFeatureMask::RECEIVE_TIMESTAMPS));
|
||||
|
||||
// Reserve space for ACK_EXTENDED header
|
||||
if (frameType == FrameType::ACK_EXTENDED) {
|
||||
auto extendedAckRequiredSpace = QuicInteger(extendedAckFeatures).getSize();
|
||||
if (spaceLeft < extendedAckRequiredSpace) {
|
||||
return none;
|
||||
}
|
||||
spaceLeft -= extendedAckRequiredSpace;
|
||||
}
|
||||
|
||||
// Reserve space for ECN counts if enabled
|
||||
if (frameType == FrameType::ACK_ECN) {
|
||||
if (ecnEnabled) {
|
||||
auto ecnRequiredSpace = computeEcnRequiredSpace(ackFrameMetaData);
|
||||
if (spaceLeft < ecnRequiredSpace) {
|
||||
return none;
|
||||
@@ -586,7 +607,7 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
}
|
||||
|
||||
// Reserve space for receive timestamps if enabled
|
||||
if (frameType == FrameType::ACK_RECEIVE_TIMESTAMPS) {
|
||||
if (receiveTimestampsEnabled) {
|
||||
auto receiveTimestampsMinimumSpace =
|
||||
computeReceiveTimestampsMinimumSpace(ackFrameMetaData);
|
||||
if (spaceLeft < receiveTimestampsMinimumSpace) {
|
||||
@@ -597,7 +618,7 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
|
||||
// Start writing fields to the builder
|
||||
|
||||
// 1. Write the base ack fields (ACK packet type)
|
||||
// 1. Write the base ack fields
|
||||
auto maybeAckFrame =
|
||||
maybeWriteAckBaseFields(ackFrameMetaData, builder, frameType, spaceLeft);
|
||||
if (!maybeAckFrame.has_value()) {
|
||||
@@ -605,14 +626,20 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
}
|
||||
auto& ackFrame = maybeAckFrame.value();
|
||||
|
||||
// 2. Write ECN fields if enabled
|
||||
if (frameType == FrameType::ACK_ECN) {
|
||||
// 2. Write extended ack header if enabled
|
||||
if (frameType == FrameType::ACK_EXTENDED) {
|
||||
QuicInteger quicExtendedAckFeatures(extendedAckFeatures);
|
||||
builder.write(quicExtendedAckFeatures);
|
||||
}
|
||||
|
||||
// 3. Write ECN fields if enabled
|
||||
if (ecnEnabled) {
|
||||
writeECNFieldsToAck(ackFrameMetaData, ackFrame, builder);
|
||||
}
|
||||
|
||||
// 3. Write receive timestamp fields if enabled
|
||||
// 4. Write receive timestamp fields if enabled
|
||||
AckReceiveTimesStampsWritten receiveTimestampsWritten;
|
||||
if (frameType == FrameType::ACK_RECEIVE_TIMESTAMPS) {
|
||||
if (receiveTimestampsEnabled) {
|
||||
receiveTimestampsWritten = writeReceiveTimestampFieldsToAck(
|
||||
ackFrameMetaData,
|
||||
ackFrame,
|
||||
@@ -626,7 +653,8 @@ Optional<WriteAckFrameResult> writeAckFrame(
|
||||
ackFrame,
|
||||
ackFrame.ackBlocks.size(),
|
||||
receiveTimestampsWritten.TimestampRangesWritten,
|
||||
receiveTimestampsWritten.TimestampWritten);
|
||||
receiveTimestampsWritten.TimestampWritten,
|
||||
extendedAckFeatures);
|
||||
|
||||
builder.appendFrame(std::move(ackFrame));
|
||||
return ackFrameWriteResult;
|
||||
|
||||
Reference in New Issue
Block a user