1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-09 20:42:44 +03:00
Files
mvfst/quic/state/SimpleFrameFunctions.cpp
Shawn Shihang Wei 52a79997d8 Revert D15267963: [quic] Clone RetireConnectionIdFrame
Differential Revision:
D15267963

Original commit changeset: a2e9059900c0

fbshipit-source-id: c9fb0a514788dd32d5f1956dbea4dcefe34468c8
2019-09-30 18:49:59 -07:00

210 lines
7.1 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#include "SimpleFrameFunctions.h"
#include <boost/variant/get.hpp>
#include <quic/state/QuicStateFunctions.h>
#include <quic/state/QuicStreamFunctions.h>
namespace quic {
void sendSimpleFrame(QuicConnectionStateBase& conn, QuicSimpleFrame frame) {
conn.pendingEvents.frames.emplace_back(std::move(frame));
}
void updateSimpleFrameOnAck(
QuicConnectionStateBase& /*conn*/,
const QuicSimpleFrame& /*frame*/) {
// TODO implement.
}
folly::Optional<QuicSimpleFrame> updateSimpleFrameOnPacketClone(
QuicConnectionStateBase& conn,
const QuicSimpleFrame& frame) {
return folly::variant_match(
frame,
[&](const StopSendingFrame& frame) -> folly::Optional<QuicSimpleFrame> {
if (!conn.streamManager->streamExists(frame.streamId)) {
return folly::none;
}
return QuicSimpleFrame(frame);
},
[&](const MinStreamDataFrame& frame) -> folly::Optional<QuicSimpleFrame> {
if (!conn.streamManager->streamExists(frame.streamId)) {
return folly::none;
}
return QuicSimpleFrame(frame);
},
[&](const ExpiredStreamDataFrame& frame)
-> folly::Optional<QuicSimpleFrame> {
if (!conn.streamManager->streamExists(frame.streamId)) {
return folly::none;
}
return QuicSimpleFrame(frame);
},
[&](const PathChallengeFrame& frame) -> folly::Optional<QuicSimpleFrame> {
// Path validation timer expired, path validation failed;
// or a different path validation was scheduled
if (!conn.outstandingPathValidation ||
frame != *conn.outstandingPathValidation) {
return folly::none;
}
return QuicSimpleFrame(frame);
},
[&](const PathResponseFrame&) -> folly::Optional<QuicSimpleFrame> {
// Do not clone PATH_RESPONSE to avoid buffering
return folly::none;
},
[&](const NewConnectionIdFrame& frame)
-> folly::Optional<QuicSimpleFrame> {
return QuicSimpleFrame(frame);
},
[&](const MaxStreamsFrame& frame) -> folly::Optional<QuicSimpleFrame> {
return QuicSimpleFrame(frame);
},
[&](const RetireConnectionIdFrame&) -> folly::Optional<QuicSimpleFrame> {
// TODO junqiw
return folly::none;
});
}
void updateSimpleFrameOnPacketSent(
QuicConnectionStateBase& conn,
const QuicSimpleFrame& simpleFrame) {
folly::variant_match(
simpleFrame,
[&](const PathChallengeFrame&) {
conn.outstandingPathValidation =
std::move(conn.pendingEvents.pathChallenge);
conn.pendingEvents.schedulePathValidationTimeout = true;
},
[&](const QuicSimpleFrame& frame) {
auto& frames = conn.pendingEvents.frames;
auto itr =
find_if(frames.begin(), frames.end(), [&](QuicSimpleFrame& f) {
return folly::variant_match(frame, [&](auto& vFrame) {
auto fptr = boost::get<decltype(vFrame)>(&f);
return fptr != nullptr && *fptr == vFrame;
});
});
CHECK(itr != frames.end());
frames.erase(itr);
});
}
void updateSimpleFrameOnPacketLoss(
QuicConnectionStateBase& conn,
const QuicSimpleFrame& frameIn) {
folly::variant_match(
frameIn,
[&](const StopSendingFrame& frame) {
if (conn.streamManager->streamExists(frame.streamId)) {
conn.pendingEvents.frames.push_back(frame);
}
},
[&](const MinStreamDataFrame& frame) {
auto stream = conn.streamManager->getStream(frame.streamId);
if (stream && stream->conn.partialReliabilityEnabled) {
advanceCurrentReceiveOffset(stream, frame.minimumStreamOffset);
}
},
[&](const ExpiredStreamDataFrame& frame) {
auto stream = conn.streamManager->getStream(frame.streamId);
if (stream && stream->conn.partialReliabilityEnabled) {
advanceMinimumRetransmittableOffset(
stream, frame.minimumStreamOffset);
}
},
[&](const PathChallengeFrame& frame) {
if (conn.outstandingPathValidation &&
frame == *conn.outstandingPathValidation) {
conn.pendingEvents.pathChallenge = frame;
}
},
[&](const PathResponseFrame&) {
// Do not retransmit PATH_RESPONSE to avoid buffering
},
[&](const NewConnectionIdFrame& frame) {
conn.pendingEvents.frames.push_back(frame);
},
[&](const MaxStreamsFrame& frame) {
conn.pendingEvents.frames.push_back(frame);
},
[&](const RetireConnectionIdFrame&) {
// TODO junqiw
});
}
bool updateSimpleFrameOnPacketReceived(
QuicConnectionStateBase& conn,
const QuicSimpleFrame& frameIn,
PacketNum packetNum,
bool fromChangedPeerAddress) {
return folly::variant_match(
frameIn,
[&](const StopSendingFrame& frame) {
auto stream = conn.streamManager->getStream(frame.streamId);
if (stream) {
invokeStreamSendStateMachine(conn, *stream, frame);
}
return true;
},
[&](const MinStreamDataFrame& frame) {
auto stream = conn.streamManager->getStream(frame.streamId);
if (stream && stream->conn.partialReliabilityEnabled) {
onRecvMinStreamDataFrame(stream, frame, packetNum);
}
return true;
},
[&](const ExpiredStreamDataFrame& frame) {
auto stream = conn.streamManager->getStream(frame.streamId);
if (stream && stream->conn.partialReliabilityEnabled) {
onRecvExpiredStreamDataFrame(stream, frame);
}
return true;
},
[&](const PathChallengeFrame& frame) {
conn.pendingEvents.frames.emplace_back(
PathResponseFrame(frame.pathData));
return false;
},
[&](const PathResponseFrame& frame) {
// Ignore the response if outstandingPathValidation is none or
// the path data doesn't match what's in outstandingPathValidation
if (fromChangedPeerAddress || !conn.outstandingPathValidation ||
frame.pathData != conn.outstandingPathValidation->pathData) {
return false;
}
// TODO update source token,
conn.outstandingPathValidation = folly::none;
conn.pendingEvents.schedulePathValidationTimeout = false;
conn.writableBytesLimit = folly::none;
return false;
},
[&](const NewConnectionIdFrame&) {
// TODO junqiw
return false;
},
[&](const MaxStreamsFrame& maxStreamsFrame) {
if (maxStreamsFrame.isForBidirectionalStream()) {
conn.streamManager->setMaxLocalBidirectionalStreams(
maxStreamsFrame.maxStreams);
} else {
conn.streamManager->setMaxLocalUnidirectionalStreams(
maxStreamsFrame.maxStreams);
}
return true;
},
[&](const RetireConnectionIdFrame&) {
// TODO junqiw
return false;
});
}
} // namespace quic