mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-12-04 15:42:40 +03:00
Make processUdpPacketData return an expected.
Summary: Continuing the theme, remove throws and translate them to expected returns. Reviewed By: hanidamlaj Differential Revision: D72254169 fbshipit-source-id: 7de13d733802eef70660cf014f642883586b0850
This commit is contained in:
committed by
Facebook GitHub Bot
parent
456c49aa7a
commit
d9a85c0e66
@@ -145,7 +145,10 @@ QuicClientTransportLite::processUdpPacket(
|
|||||||
for (uint16_t processedPackets = 0;
|
for (uint16_t processedPackets = 0;
|
||||||
!udpData.empty() && processedPackets < kMaxNumCoalescedPackets;
|
!udpData.empty() && processedPackets < kMaxNumCoalescedPackets;
|
||||||
processedPackets++) {
|
processedPackets++) {
|
||||||
processUdpPacketData(peer, udpPacket);
|
auto res = processUdpPacketData(peer, udpPacket);
|
||||||
|
if (res.hasError()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VLOG_IF(4, !udpData.empty())
|
VLOG_IF(4, !udpData.empty())
|
||||||
<< "Leaving " << udpData.chainLength()
|
<< "Leaving " << udpData.chainLength()
|
||||||
@@ -161,7 +164,11 @@ QuicClientTransportLite::processUdpPacket(
|
|||||||
// buffer.
|
// buffer.
|
||||||
pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
|
pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
|
||||||
|
|
||||||
processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
|
auto res =
|
||||||
|
processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
|
||||||
|
if (res.hasError()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
clientConn_->pendingOneRttData.clear();
|
clientConn_->pendingOneRttData.clear();
|
||||||
}
|
}
|
||||||
@@ -172,19 +179,24 @@ QuicClientTransportLite::processUdpPacket(
|
|||||||
// buffer.
|
// buffer.
|
||||||
pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
|
pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
|
||||||
|
|
||||||
processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
|
auto res =
|
||||||
|
processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
|
||||||
|
if (res.hasError()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
clientConn_->pendingHandshakeData.clear();
|
clientConn_->pendingHandshakeData.clear();
|
||||||
}
|
}
|
||||||
return folly::unit;
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuicClientTransportLite::processUdpPacketData(
|
folly::Expected<folly::Unit, QuicError>
|
||||||
|
QuicClientTransportLite::processUdpPacketData(
|
||||||
const folly::SocketAddress& peer,
|
const folly::SocketAddress& peer,
|
||||||
ReceivedUdpPacket& udpPacket) {
|
ReceivedUdpPacket& udpPacket) {
|
||||||
auto packetSize = udpPacket.buf.chainLength();
|
auto packetSize = udpPacket.buf.chainLength();
|
||||||
if (packetSize == 0) {
|
if (packetSize == 0) {
|
||||||
return;
|
return folly::unit;
|
||||||
}
|
}
|
||||||
auto parsedPacket = conn_->readCodec->parsePacket(
|
auto parsedPacket = conn_->readCodec->parsePacket(
|
||||||
udpPacket.buf, conn_->ackStates, conn_->clientConnectionId->size());
|
udpPacket.buf, conn_->ackStates, conn_->clientConnectionId->size());
|
||||||
@@ -196,9 +208,12 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
conn_->peerConnectionError = QuicError(
|
conn_->peerConnectionError = QuicError(
|
||||||
QuicErrorCode(LocalErrorCode::CONNECTION_RESET),
|
QuicErrorCode(LocalErrorCode::CONNECTION_RESET),
|
||||||
toString(LocalErrorCode::CONNECTION_RESET).str());
|
toString(LocalErrorCode::CONNECTION_RESET).str());
|
||||||
throw QuicInternalException("Peer reset", LocalErrorCode::NO_ERROR);
|
return folly::makeUnexpected(
|
||||||
|
QuicError(LocalErrorCode::NO_ERROR, "Stateless Reset Received"));
|
||||||
}
|
}
|
||||||
VLOG(4) << "Drop StatelessReset for bad connId or token " << *this;
|
VLOG(4) << "Drop StatelessReset for bad connId or token " << *this;
|
||||||
|
// Don't treat this as a fatal error, just ignore the packet.
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetryPacket* retryPacket = parsedPacket.retryPacket();
|
RetryPacket* retryPacket = parsedPacket.retryPacket();
|
||||||
@@ -217,7 +232,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
if (shouldRejectRetryPacket) {
|
if (shouldRejectRetryPacket) {
|
||||||
VLOG(4) << "Server incorrectly issued a retry packet; dropping retry "
|
VLOG(4) << "Server incorrectly issued a retry packet; dropping retry "
|
||||||
<< *this;
|
<< *this;
|
||||||
return;
|
// Not a fatal error, just ignore the packet.
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConnectionId* originalDstConnId =
|
const ConnectionId* originalDstConnId =
|
||||||
@@ -227,7 +243,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
*originalDstConnId, *retryPacket)) {
|
*originalDstConnId, *retryPacket)) {
|
||||||
VLOG(4) << "The integrity tag in the retry packet was invalid. "
|
VLOG(4) << "The integrity tag in the retry packet was invalid. "
|
||||||
<< "Dropping bad retry packet. " << *this;
|
<< "Dropping bad retry packet. " << *this;
|
||||||
return;
|
// Not a fatal error, just ignore the packet.
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (happyEyeballsEnabled_) {
|
if (happyEyeballsEnabled_) {
|
||||||
@@ -253,7 +270,7 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
// upon receiving a subsequent initial from the server.
|
// upon receiving a subsequent initial from the server.
|
||||||
|
|
||||||
startCryptoHandshake();
|
startCryptoHandshake();
|
||||||
return;
|
return folly::unit; // Retry processed successfully
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cipherUnavailable = parsedPacket.cipherUnavailable();
|
auto cipherUnavailable = parsedPacket.cipherUnavailable();
|
||||||
@@ -278,15 +295,15 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
conn_->qLogger->addPacketBuffered(
|
conn_->qLogger->addPacketBuffered(
|
||||||
cipherUnavailable->protectionType, packetSize);
|
cipherUnavailable->protectionType, packetSize);
|
||||||
}
|
}
|
||||||
return;
|
// Packet buffered, not an error
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto codecError = parsedPacket.codecError();
|
auto codecError = parsedPacket.codecError();
|
||||||
if (codecError) {
|
if (codecError) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
codecError->error.message,
|
*codecError->error.code.asTransportErrorCode(),
|
||||||
*codecError->error.code.asTransportErrorCode());
|
std::move(codecError->error.message)));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegularQuicPacket* regularOptional = parsedPacket.regularPacket();
|
RegularQuicPacket* regularOptional = parsedPacket.regularPacket();
|
||||||
@@ -297,7 +314,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
if (conn_->qLogger) {
|
if (conn_->qLogger) {
|
||||||
conn_->qLogger->addPacketDrop(packetSize, kParse);
|
conn_->qLogger->addPacketDrop(packetSize, kParse);
|
||||||
}
|
}
|
||||||
return;
|
// If this was a protocol violation, we would return a codec error instead.
|
||||||
|
// Ignore this case as something that caused a non-codec parse error.
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regularOptional->frames.empty()) {
|
if (regularOptional->frames.empty()) {
|
||||||
@@ -314,8 +333,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
packetSize,
|
packetSize,
|
||||||
PacketDropReason(PacketDropReason::PROTOCOL_VIOLATION)._to_string());
|
PacketDropReason(PacketDropReason::PROTOCOL_VIOLATION)._to_string());
|
||||||
}
|
}
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Packet has no frames", TransportErrorCode::PROTOCOL_VIOLATION);
|
TransportErrorCode::PROTOCOL_VIOLATION, "Packet has no frames"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (happyEyeballsEnabled_) {
|
if (happyEyeballsEnabled_) {
|
||||||
@@ -349,8 +368,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
auto isPing = quicFrame.asPingFrame();
|
auto isPing = quicFrame.asPingFrame();
|
||||||
// TODO: add path challenge and response
|
// TODO: add path challenge and response
|
||||||
if (!isPadding && !isAck && !isClose && !isCrypto && !isPing) {
|
if (!isPadding && !isAck && !isClose && !isCrypto && !isPing) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(
|
||||||
"Invalid frame", TransportErrorCode::PROTOCOL_VIOLATION);
|
QuicError(TransportErrorCode::PROTOCOL_VIOLATION, "Invalid frame"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,8 +397,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
connidMatched = false;
|
connidMatched = false;
|
||||||
}
|
}
|
||||||
if (!connidMatched) {
|
if (!connidMatched) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Invalid connection id", TransportErrorCode::PROTOCOL_VIOLATION);
|
TransportErrorCode::PROTOCOL_VIOLATION, "Invalid connection id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the packet to the AckState associated with the packet number space.
|
// Add the packet to the AckState associated with the packet number space.
|
||||||
@@ -474,16 +493,16 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
|
|
||||||
if (ackFrame.frameType == FrameType::ACK_EXTENDED &&
|
if (ackFrame.frameType == FrameType::ACK_EXTENDED &&
|
||||||
!conn_->transportSettings.advertisedExtendedAckFeatures) {
|
!conn_->transportSettings.advertisedExtendedAckFeatures) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Received unexpected ACK_EXTENDED frame",
|
TransportErrorCode::PROTOCOL_VIOLATION,
|
||||||
TransportErrorCode::PROTOCOL_VIOLATION);
|
"Received unexpected ACK_EXTENDED frame"));
|
||||||
} else if (
|
} else if (
|
||||||
ackFrame.frameType == FrameType::ACK_RECEIVE_TIMESTAMPS &&
|
ackFrame.frameType == FrameType::ACK_RECEIVE_TIMESTAMPS &&
|
||||||
!conn_->transportSettings
|
!conn_->transportSettings
|
||||||
.maybeAckReceiveTimestampsConfigSentToPeer) {
|
.maybeAckReceiveTimestampsConfigSentToPeer) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Received unexpected ACK_RECEIVE_TIMESTAMPS frame",
|
TransportErrorCode::PROTOCOL_VIOLATION,
|
||||||
TransportErrorCode::PROTOCOL_VIOLATION);
|
"Received unexpected ACK_RECEIVE_TIMESTAMPS frame"));
|
||||||
}
|
}
|
||||||
|
|
||||||
conn_->lastProcessedAckEvents.emplace_back(processAckFrame(
|
conn_->lastProcessedAckEvents.emplace_back(processAckFrame(
|
||||||
@@ -502,9 +521,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
<< *this;
|
<< *this;
|
||||||
if (frame.reliableSize.hasValue()) {
|
if (frame.reliableSize.hasValue()) {
|
||||||
// We're not yet supporting the handling of RESET_STREAM_AT frames
|
// We're not yet supporting the handling of RESET_STREAM_AT frames
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Reliable resets not supported",
|
TransportErrorCode::PROTOCOL_VIOLATION,
|
||||||
TransportErrorCode::PROTOCOL_VIOLATION);
|
"Reliable resets not supported"));
|
||||||
}
|
}
|
||||||
pktHasRetransmittableData = true;
|
pktHasRetransmittableData = true;
|
||||||
auto streamId = frame.streamId;
|
auto streamId = frame.streamId;
|
||||||
@@ -572,9 +591,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
<< " offset=" << streamWindowUpdate.maximumData << " "
|
<< " offset=" << streamWindowUpdate.maximumData << " "
|
||||||
<< *this;
|
<< *this;
|
||||||
if (isReceivingStream(conn_->nodeType, streamWindowUpdate.streamId)) {
|
if (isReceivingStream(conn_->nodeType, streamWindowUpdate.streamId)) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Received MaxStreamDataFrame for receiving stream.",
|
TransportErrorCode::STREAM_STATE_ERROR,
|
||||||
TransportErrorCode::STREAM_STATE_ERROR);
|
"Received MaxStreamDataFrame for receiving stream."));
|
||||||
}
|
}
|
||||||
pktHasRetransmittableData = true;
|
pktHasRetransmittableData = true;
|
||||||
auto stream =
|
auto stream =
|
||||||
@@ -625,7 +644,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
}
|
}
|
||||||
conn_->peerConnectionError =
|
conn_->peerConnectionError =
|
||||||
QuicError(QuicErrorCode(connFrame.errorCode), std::move(errMsg));
|
QuicError(QuicErrorCode(connFrame.errorCode), std::move(errMsg));
|
||||||
return;
|
// We don't return an error here, as receiving a close triggers the
|
||||||
|
// peer connection error path instead of the local error path.
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
case QuicFrame::Type::PingFrame:
|
case QuicFrame::Type::PingFrame:
|
||||||
// Ping isn't retransmittable. But we would like to ack them early.
|
// Ping isn't retransmittable. But we would like to ack them early.
|
||||||
@@ -660,9 +681,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
if (!conn_->transportSettings.minAckDelay.has_value()) {
|
if (!conn_->transportSettings.minAckDelay.has_value()) {
|
||||||
// We do not accept IMMEDIATE_ACK frames. This is a protocol
|
// We do not accept IMMEDIATE_ACK frames. This is a protocol
|
||||||
// violation.
|
// violation.
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Received IMMEDIATE_ACK frame without announcing min_ack_delay",
|
TransportErrorCode::PROTOCOL_VIOLATION,
|
||||||
TransportErrorCode::PROTOCOL_VIOLATION);
|
"Received IMMEDIATE_ACK frame without announcing min_ack_delay"));
|
||||||
}
|
}
|
||||||
// Send an ACK from any packet number space.
|
// Send an ACK from any packet number space.
|
||||||
if (conn_->ackStates.initialAckState) {
|
if (conn_->ackStates.initialAckState) {
|
||||||
@@ -713,9 +734,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
QUIC_STATS(conn_->statsCallback, onZeroRttRejected);
|
QUIC_STATS(conn_->statsCallback, onZeroRttRejected);
|
||||||
handshakeLayer->removePsk(hostname_);
|
handshakeLayer->removePsk(hostname_);
|
||||||
if (!handshakeLayer->getCanResendZeroRtt().value_or(false)) {
|
if (!handshakeLayer->getCanResendZeroRtt().value_or(false)) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Zero-rtt attempted but the early parameters do not match the handshake parameters",
|
TransportErrorCode::TRANSPORT_PARAMETER_ERROR,
|
||||||
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
"Zero-rtt attempted but the early parameters do not match the handshake parameters"));
|
||||||
}
|
}
|
||||||
} else if (clientConn_->zeroRttRejected.has_value()) {
|
} else if (clientConn_->zeroRttRejected.has_value()) {
|
||||||
if (conn_->qLogger) {
|
if (conn_->qLogger) {
|
||||||
@@ -731,9 +752,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
if (oneRttKeyDerivationTriggered) {
|
if (oneRttKeyDerivationTriggered) {
|
||||||
const auto& serverParams = handshakeLayer->getServerTransportParams();
|
const auto& serverParams = handshakeLayer->getServerTransportParams();
|
||||||
if (!serverParams) {
|
if (!serverParams) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"No server transport params",
|
TransportErrorCode::TRANSPORT_PARAMETER_ERROR,
|
||||||
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
"No server transport params"));
|
||||||
}
|
}
|
||||||
if ((clientConn_->zeroRttRejected.has_value() &&
|
if ((clientConn_->zeroRttRejected.has_value() &&
|
||||||
*clientConn_->zeroRttRejected) ||
|
*clientConn_->zeroRttRejected) ||
|
||||||
@@ -800,9 +821,9 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
originalPeerInitialStreamOffsetUni >
|
originalPeerInitialStreamOffsetUni >
|
||||||
conn_->flowControlState
|
conn_->flowControlState
|
||||||
.peerAdvertisedInitialMaxStreamOffsetUni) {
|
.peerAdvertisedInitialMaxStreamOffsetUni) {
|
||||||
throw QuicTransportException(
|
return folly::makeUnexpected(QuicError(
|
||||||
"Rejection of zero rtt parameters unsupported",
|
TransportErrorCode::TRANSPORT_PARAMETER_ERROR,
|
||||||
TransportErrorCode::TRANSPORT_PARAMETER_ERROR);
|
"Rejection of zero rtt parameters unsupported"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -861,6 +882,8 @@ void QuicClientTransportLite::processUdpPacketData(
|
|||||||
conn_->readCodec->setInitialHeaderCipher(nullptr);
|
conn_->readCodec->setInitialHeaderCipher(nullptr);
|
||||||
implicitAckCryptoStream(*conn_, EncryptionLevel::Initial);
|
implicitAckCryptoStream(*conn_, EncryptionLevel::Initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return folly::unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::Expected<folly::Unit, QuicError> QuicClientTransportLite::onReadData(
|
folly::Expected<folly::Unit, QuicError> QuicClientTransportLite::onReadData(
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ class QuicClientTransportLite
|
|||||||
* Bytes transformed into a QUIC packet will be
|
* Bytes transformed into a QUIC packet will be
|
||||||
* removed from this buffer.
|
* removed from this buffer.
|
||||||
*/
|
*/
|
||||||
void processUdpPacketData(
|
folly::Expected<folly::Unit, QuicError> processUdpPacketData(
|
||||||
const folly::SocketAddress& peer,
|
const folly::SocketAddress& peer,
|
||||||
ReceivedUdpPacket& udpPacket);
|
ReceivedUdpPacket& udpPacket);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user