1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-08 09:42:06 +03:00

Add mvfst specific encryption level (#26)

Summary:
This ensure a lot of code do not depend on fizz anymore.
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/26

Reviewed By: mjoras, JunqiWang

Differential Revision: D16030663

Pulled By: yangchi

fbshipit-source-id: a3cc34905a6afb657da194e2166434425e7e163c
This commit is contained in:
Amaury Séchet
2019-06-27 14:05:48 -07:00
committed by Facebook Github Bot
parent 002a2ebf8e
commit f4e90017a3
24 changed files with 110 additions and 73 deletions

View File

@@ -395,4 +395,15 @@ inline std::ostream& operator<<(std::ostream& os, const QuicVersion& v) {
*/
std::vector<QuicVersion> filterSupportedVersions(
const std::vector<QuicVersion>&);
/**
* Represent the different encryption levels used by QUIC.
*/
enum class EncryptionLevel : uint8_t {
Initial,
Handshake,
EarlyData,
AppData,
};
} // namespace quic

View File

@@ -55,7 +55,7 @@ folly::Optional<PacketNum> largestAckToSend(const AckState& ackState) {
FrameScheduler::Builder::Builder(
const QuicConnectionStateBase& conn,
fizz::EncryptionLevel encryptionLevel,
EncryptionLevel encryptionLevel,
PacketNumberSpace packetNumberSpace,
const std::string& name)
: conn_(conn),

View File

@@ -316,7 +316,7 @@ class FrameScheduler : public QuicPacketScheduler {
struct Builder {
Builder(
const QuicConnectionStateBase& conn,
fizz::EncryptionLevel encryptionLevel,
EncryptionLevel encryptionLevel,
PacketNumberSpace packetNumberSpace,
const std::string& name);
@@ -333,7 +333,7 @@ class FrameScheduler : public QuicPacketScheduler {
private:
const QuicConnectionStateBase& conn_;
fizz::EncryptionLevel encryptionLevel_;
EncryptionLevel encryptionLevel_;
PacketNumberSpace packetNumberSpace_;
std::string name_;

View File

@@ -491,7 +491,7 @@ uint64_t writeQuicDataToSocket(
if (connection.pendingEvents.numProbePackets) {
auto probeScheduler = std::move(FrameScheduler::Builder(
connection,
fizz::EncryptionLevel::AppTraffic,
EncryptionLevel::AppData,
PacketNumberSpace::AppData,
"ProbeScheduler")
.streamFrames()
@@ -515,7 +515,7 @@ uint64_t writeQuicDataToSocket(
}
FrameScheduler scheduler = std::move(FrameScheduler::Builder(
connection,
fizz::EncryptionLevel::AppTraffic,
EncryptionLevel::AppData,
PacketNumberSpace::AppData,
"FrameScheduler")
.streamFrames()
@@ -607,7 +607,7 @@ uint64_t writeQuicDataExceptCryptoStreamToSocket(
if (connection.pendingEvents.numProbePackets) {
auto probeScheduler = std::move(FrameScheduler::Builder(
connection,
fizz::EncryptionLevel::AppTraffic,
EncryptionLevel::AppData,
PacketNumberSpace::AppData,
"ProbeWithoutCrypto")
.streamFrames()
@@ -630,7 +630,7 @@ uint64_t writeQuicDataExceptCryptoStreamToSocket(
}
FrameScheduler scheduler = std::move(FrameScheduler::Builder(
connection,
fizz::EncryptionLevel::AppTraffic,
EncryptionLevel::AppData,
PacketNumberSpace::AppData,
"FrameSchedulerWithoutCrypto")
.streamFrames()

View File

@@ -127,8 +127,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoPaddingInitialPacket) {
std::move(longHeader1),
conn.ackStates.initialAckState.largestAckedByPeer);
CryptoStreamScheduler scheduler(
conn,
*getCryptoStream(*conn.cryptoState, fizz::EncryptionLevel::Plaintext));
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Initial));
writeDataToQuicStream(
conn.cryptoState->initialStream, folly::IOBuf::copyBuffer("chlo"));
scheduler.writeCryptoData(builder1);
@@ -165,8 +164,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoServerInitialNotPadded) {
std::move(longHeader1),
conn.ackStates.initialAckState.largestAckedByPeer);
CryptoStreamScheduler scheduler(
conn,
*getCryptoStream(*conn.cryptoState, fizz::EncryptionLevel::Plaintext));
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Initial));
writeDataToQuicStream(
conn.cryptoState->initialStream, folly::IOBuf::copyBuffer("shlo"));
scheduler.writeCryptoData(builder1);
@@ -187,8 +185,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoPaddingRetransmissionClientInitial) {
std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer);
CryptoStreamScheduler scheduler(
conn,
*getCryptoStream(*conn.cryptoState, fizz::EncryptionLevel::Plaintext));
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Initial));
conn.cryptoState->initialStream.lossBuffer.push_back(
StreamBuffer{folly::IOBuf::copyBuffer("chlo"), 0, false});
scheduler.writeCryptoData(builder);
@@ -210,8 +207,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoSchedulerOnlySingleLossFits) {
conn.ackStates.handshakeAckState.largestAckedByPeer);
PacketBuilderWrapper builderWrapper(builder, 13);
CryptoStreamScheduler scheduler(
conn,
*getCryptoStream(*conn.cryptoState, fizz::EncryptionLevel::Handshake));
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Handshake));
conn.cryptoState->handshakeStream.lossBuffer.push_back(
StreamBuffer{folly::IOBuf::copyBuffer("shlo"), 0, false});
conn.cryptoState->handshakeStream.lossBuffer.push_back(StreamBuffer{
@@ -236,8 +232,7 @@ TEST_F(QuicPacketSchedulerTest, CryptoWritePartialLossBuffer) {
std::move(longHeader),
conn.ackStates.initialAckState.largestAckedByPeer);
CryptoStreamScheduler scheduler(
conn,
*getCryptoStream(*conn.cryptoState, fizz::EncryptionLevel::Plaintext));
conn, *getCryptoStream(*conn.cryptoState, EncryptionLevel::Initial));
conn.cryptoState->initialStream.lossBuffer.push_back(StreamBuffer{
folly::IOBuf::copyBuffer("return the special duration value max"),
0,

View File

@@ -35,7 +35,7 @@ uint64_t writeProbingDataToSocketForTest(
QuicVersion version) {
FrameScheduler scheduler = std::move(FrameScheduler::Builder(
conn,
fizz::EncryptionLevel::AppTraffic,
EncryptionLevel::AppData,
PacketNumberSpace::AppData,
"test")
.streamFrames()

View File

@@ -698,11 +698,10 @@ void QuicClientTransport::writeData() {
? conn_->congestionController->getPacingRate(Clock::now())
: conn_->transportSettings.writeConnectionDataPacketsLimit);
CryptoStreamScheduler initialScheduler(
*conn_,
*getCryptoStream(*conn_->cryptoState, fizz::EncryptionLevel::Plaintext));
*conn_, *getCryptoStream(*conn_->cryptoState, EncryptionLevel::Initial));
CryptoStreamScheduler handshakeScheduler(
*conn_,
*getCryptoStream(*conn_->cryptoState, fizz::EncryptionLevel::Handshake));
*getCryptoStream(*conn_->cryptoState, EncryptionLevel::Handshake));
if (initialScheduler.hasData() ||
(conn_->ackStates.initialAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.initialAckState))) {

View File

@@ -42,7 +42,7 @@ void ClientHandshake::connect(
void ClientHandshake::doHandshake(
std::unique_ptr<folly::IOBuf> data,
fizz::EncryptionLevel encryptionLevel) {
EncryptionLevel encryptionLevel) {
if (!data) {
return;
}
@@ -59,14 +59,14 @@ void ClientHandshake::doHandshake(
// First add it to the right read buffer.
switch (encryptionLevel) {
case fizz::EncryptionLevel::Plaintext:
case EncryptionLevel::Initial:
initialReadBuf_.append(std::move(data));
break;
case fizz::EncryptionLevel::Handshake:
case EncryptionLevel::Handshake:
handshakeReadBuf_.append(std::move(data));
break;
case fizz::EncryptionLevel::EarlyData:
case fizz::EncryptionLevel::AppTraffic:
case EncryptionLevel::EarlyData:
case EncryptionLevel::AppData:
appDataReadBuf_.append(std::move(data));
break;
}
@@ -256,11 +256,12 @@ void ClientHandshake::ActionMoveVisitor::operator()(
fizz::WriteToSocket& write) {
for (auto& content : write.contents) {
auto& cryptoState = client_.cryptoState_;
if (content.encryptionLevel == fizz::EncryptionLevel::AppTraffic) {
auto encryptionLevel = getEncryptionLevelFromFizz(content.encryptionLevel);
if (encryptionLevel == EncryptionLevel::AppData) {
// Don't write 1-rtt handshake data on the client.
continue;
}
auto cryptoStream = getCryptoStream(cryptoState, content.encryptionLevel);
auto cryptoStream = getCryptoStream(cryptoState, encryptionLevel);
writeDataToQuicStream(*cryptoStream, std::move(content.data));
}
}

View File

@@ -59,7 +59,7 @@ class ClientHandshake : public Handshake {
*/
virtual void doHandshake(
std::unique_ptr<folly::IOBuf> data,
fizz::EncryptionLevel encryptionLevel);
EncryptionLevel encryptionLevel);
/**
* An edge triggered API to get the oneRttWriteCipher. Once you receive the

View File

@@ -26,6 +26,7 @@
#include <quic/client/handshake/ClientHandshake.h>
#include <quic/client/handshake/test/MockQuicPskCache.h>
#include <quic/common/test/TestUtils.h>
#include <quic/handshake/FizzBridge.h>
#include <quic/state/QuicStreamFunctions.h>
#include <quic/state/StateData.h>
@@ -119,8 +120,9 @@ class ClientHandshakeTest : public Test, public boost::static_visitor<> {
evb.loop();
for (auto& write : serverOutput) {
for (auto& content : write.contents) {
handshake->doHandshake(
std::move(content.data), content.encryptionLevel);
auto encryptionLevel =
getEncryptionLevelFromFizz(content.encryptionLevel);
handshake->doHandshake(std::move(content.data), encryptionLevel);
}
}
processHandshake();

View File

@@ -1010,8 +1010,7 @@ class FakeOneRttHandshakeLayer : public ClientHandshake {
createServerTransportParameters();
}
void doHandshake(std::unique_ptr<folly::IOBuf>, fizz::EncryptionLevel)
override {
void doHandshake(std::unique_ptr<folly::IOBuf>, EncryptionLevel) override {
EXPECT_EQ(writeBuf.get(), nullptr);
if (getPhase() == Phase::Initial) {
writeDataToQuicStream(

View File

@@ -5,6 +5,7 @@
add_library(
mvfst_handshake STATIC
FizzBridge.cpp
HandshakeLayer.cpp
QuicFizzFactory.cpp
TransportParameters.cpp

View File

@@ -0,0 +1,29 @@
/*
* 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 <quic/handshake/FizzBridge.h>
namespace quic {
EncryptionLevel getEncryptionLevelFromFizz(
const fizz::EncryptionLevel encryptionLevel) {
switch (encryptionLevel) {
case fizz::EncryptionLevel::Plaintext:
return EncryptionLevel::Initial;
case fizz::EncryptionLevel::Handshake:
return EncryptionLevel::Handshake;
case fizz::EncryptionLevel::EarlyData:
return EncryptionLevel::EarlyData;
case fizz::EncryptionLevel::AppTraffic:
return EncryptionLevel::AppData;
}
folly::assume_unreachable();
}
} // namespace quic

View File

@@ -9,6 +9,8 @@
#pragma once
#include <fizz/crypto/aead/Aead.h>
#include <fizz/protocol/Types.h>
#include <quic/QuicConstants.h>
#include <quic/handshake/Aead.h>
#include <memory>
@@ -63,4 +65,7 @@ class FizzAead final : public Aead {
: fizzAead(std::move(fizzAeadIn)) {}
};
EncryptionLevel getEncryptionLevelFromFizz(
const fizz::EncryptionLevel encryptionLevel);
} // namespace quic

View File

@@ -117,17 +117,17 @@ std::unique_ptr<PacketNumberCipher> makePacketNumberCipher(
return pnCipher;
}
fizz::EncryptionLevel protectionTypeToEncryptionLevel(ProtectionType type) {
EncryptionLevel protectionTypeToEncryptionLevel(ProtectionType type) {
switch (type) {
case ProtectionType::Initial:
return fizz::EncryptionLevel::Plaintext;
return EncryptionLevel::Initial;
case ProtectionType::Handshake:
return fizz::EncryptionLevel::Handshake;
return EncryptionLevel::Handshake;
case ProtectionType::ZeroRtt:
return fizz::EncryptionLevel::EarlyData;
return EncryptionLevel::EarlyData;
case ProtectionType::KeyPhaseZero:
case ProtectionType::KeyPhaseOne:
return fizz::EncryptionLevel::AppTraffic;
return EncryptionLevel::AppData;
}
folly::assume_unreachable();
}

View File

@@ -10,8 +10,6 @@
#include <fizz/protocol/Exporter.h>
#include <fizz/protocol/Factory.h>
#include <fizz/protocol/Types.h>
#include <fizz/record/Types.h>
#include <folly/Expected.h>
#include <quic/QuicConstants.h>
@@ -91,7 +89,7 @@ std::unique_ptr<PacketNumberCipher> makePacketNumberCipher(
fizz::CipherSuite cipher);
/**
* Converts the protection type of QUIC to the encryption type of fizz.
* Converts the protection type of QUIC to an encryption level.
*/
fizz::EncryptionLevel protectionTypeToEncryptionLevel(ProtectionType type);
EncryptionLevel protectionTypeToEncryptionLevel(ProtectionType type);
} // namespace quic

View File

@@ -189,11 +189,10 @@ void QuicServerTransport::writeData() {
? conn_->congestionController->getPacingRate(Clock::now())
: conn_->transportSettings.writeConnectionDataPacketsLimit);
CryptoStreamScheduler initialScheduler(
*conn_,
*getCryptoStream(*conn_->cryptoState, fizz::EncryptionLevel::Plaintext));
*conn_, *getCryptoStream(*conn_->cryptoState, EncryptionLevel::Initial));
CryptoStreamScheduler handshakeScheduler(
*conn_,
*getCryptoStream(*conn_->cryptoState, fizz::EncryptionLevel::Handshake));
*getCryptoStream(*conn_->cryptoState, EncryptionLevel::Handshake));
if (initialScheduler.hasData() ||
(conn_->ackStates.initialAckState.needsToSendAckImmediately &&
hasAcksToSchedule(conn_->ackStates.initialAckState))) {

View File

@@ -11,7 +11,6 @@
#include <quic/QuicConstants.h>
#include <quic/handshake/TransportParameters.h>
#include <fizz/record/Types.h>
#include <fizz/server/State.h>
#include <folly/IPAddress.h>
#include <folly/Optional.h>

View File

@@ -51,21 +51,21 @@ void ServerHandshake::initialize(
void ServerHandshake::doHandshake(
std::unique_ptr<folly::IOBuf> data,
fizz::EncryptionLevel encryptionLevel) {
EncryptionLevel encryptionLevel) {
SCOPE_EXIT {
inHandshakeStack_ = false;
};
inHandshakeStack_ = true;
waitForData_ = false;
switch (encryptionLevel) {
case fizz::EncryptionLevel::Plaintext:
case EncryptionLevel::Initial:
initialReadBuf_.append(std::move(data));
break;
case fizz::EncryptionLevel::Handshake:
case EncryptionLevel::Handshake:
handshakeReadBuf_.append(std::move(data));
break;
case fizz::EncryptionLevel::EarlyData:
case fizz::EncryptionLevel::AppTraffic:
case EncryptionLevel::EarlyData:
case EncryptionLevel::AppData:
appDataReadBuf_.append(std::move(data));
break;
}
@@ -213,12 +213,13 @@ void ServerHandshake::onWriteData(fizz::WriteToSocket& write) {
return;
}
for (auto& content : write.contents) {
CHECK(content.encryptionLevel != fizz::EncryptionLevel::EarlyData)
auto encryptionLevel = getEncryptionLevelFromFizz(content.encryptionLevel);
CHECK(encryptionLevel != EncryptionLevel::EarlyData)
<< "Server cannot write early data";
if (content.contentType != fizz::ContentType::handshake) {
continue;
}
auto cryptoStream = getCryptoStream(cryptoState_, content.encryptionLevel);
auto cryptoStream = getCryptoStream(cryptoState_, encryptionLevel);
writeDataToQuicStream(*cryptoStream, std::move(content.data));
}
handshakeEventAvailable_ = true;

View File

@@ -94,7 +94,7 @@ class ServerHandshake : public Handshake {
*/
virtual void doHandshake(
std::unique_ptr<folly::IOBuf> data,
fizz::EncryptionLevel encryptionLevel);
EncryptionLevel encryptionLevel);
/**
* Writes a session ticket on the connection.

View File

@@ -26,6 +26,7 @@
#include <quic/QuicConstants.h>
#include <quic/client/handshake/ClientTransportParametersExtension.h>
#include <quic/common/test/TestUtils.h>
#include <quic/handshake/FizzBridge.h>
#include <quic/handshake/HandshakeLayer.h>
#include <quic/server/handshake/AppToken.h>
#include <quic/server/handshake/ServerHandshake.h>
@@ -163,8 +164,9 @@ class ServerHandshakeTest : public Test {
try {
for (auto& clientWrite : clientWrites) {
for (auto& content : clientWrite.contents) {
handshake->doHandshake(
std::move(content.data), content.encryptionLevel);
auto encryptionLevel =
getEncryptionLevelFromFizz(content.encryptionLevel);
handshake->doHandshake(std::move(content.data), encryptionLevel);
}
}
setHandshakeState();

View File

@@ -47,8 +47,7 @@ class FakeServerHandshake : public ServerHandshake {
MOCK_METHOD1(writeNewSessionTicket, void(const AppToken&));
void doHandshake(std::unique_ptr<IOBuf> data, fizz::EncryptionLevel)
override {
void doHandshake(std::unique_ptr<IOBuf> data, EncryptionLevel) override {
IOBufEqualTo eq;
auto chlo = folly::IOBuf::copyBuffer("CHLO");
auto clientFinished = IOBuf::copyBuffer("FINISHED");
@@ -57,8 +56,7 @@ class FakeServerHandshake : public ServerHandshake {
// Do NOT invoke onCryptoEventAvailable callback
// Fall through and let the ServerStateMachine to process the event
writeDataToQuicStream(
*getCryptoStream(
*conn_.cryptoState, fizz::EncryptionLevel::Plaintext),
*getCryptoStream(*conn_.cryptoState, EncryptionLevel::Initial),
IOBuf::copyBuffer("SHLO"));
if (allowZeroRttKeys_) {
validateAndUpdateSourceToken(conn_, sourceAddrs_);
@@ -70,8 +68,7 @@ class FakeServerHandshake : public ServerHandshake {
// Asynchronously schedule the callback
executor_->add([&] {
writeDataToQuicStream(
*getCryptoStream(
*conn_.cryptoState, fizz::EncryptionLevel::Plaintext),
*getCryptoStream(*conn_.cryptoState, EncryptionLevel::Initial),
IOBuf::copyBuffer("SHLO"));
if (allowZeroRttKeys_) {
validateAndUpdateSourceToken(conn_, sourceAddrs_);
@@ -382,7 +379,7 @@ class QuicServerTransportTest : public Test {
auto headerCipher = test::createNoOpHeaderCipher();
uint64_t offset =
getCryptoStream(
*server->getConn().cryptoState, fizz::EncryptionLevel::Handshake)
*server->getConn().cryptoState, EncryptionLevel::Handshake)
->currentReadOffset;
auto handshakeCipher = test::createNoOpAead();
auto finishedPacket = packetToBufCleartext(
@@ -468,10 +465,9 @@ class QuicServerTransportTest : public Test {
EXPECT_NE(server->getConn().oneRttWriteHeaderCipher, nullptr);
EXPECT_NE(server->getConn().readCodec->getOneRttHeaderCipher(), nullptr);
EXPECT_TRUE(
getCryptoStream(
*server->getConn().cryptoState, fizz::EncryptionLevel::Plaintext)
->readBuffer.empty());
EXPECT_TRUE(getCryptoStream(
*server->getConn().cryptoState, EncryptionLevel::Initial)
->readBuffer.empty());
EXPECT_NE(server->getConn().initialWriteCipher, nullptr);
EXPECT_FALSE(server->getConn().localConnectionError.hasValue());
verifyTransportParameters(kDefaultIdleTimeout);

View File

@@ -396,17 +396,17 @@ void cancelHandshakeCryptoStreamRetransmissions(QuicCryptoState& cryptoState) {
QuicCryptoStream* getCryptoStream(
QuicCryptoState& cryptoState,
fizz::EncryptionLevel encryptionLevel) {
EncryptionLevel encryptionLevel) {
switch (encryptionLevel) {
case fizz::EncryptionLevel::Plaintext:
case EncryptionLevel::Initial:
return &cryptoState.initialStream;
case fizz::EncryptionLevel::Handshake:
case EncryptionLevel::Handshake:
return &cryptoState.handshakeStream;
case fizz::EncryptionLevel::EarlyData:
case EncryptionLevel::EarlyData:
// TODO: remove this when we implement EOED for
// draft-17.
return &cryptoState.handshakeStream;
case fizz::EncryptionLevel::AppTraffic:
case EncryptionLevel::AppData:
return &cryptoState.oneRttStream;
}
folly::assume_unreachable();

View File

@@ -129,7 +129,7 @@ void cancelHandshakeCryptoStreamRetransmissions(QuicCryptoState& cryptoStream);
*/
QuicCryptoStream* getCryptoStream(
QuicCryptoState& cryptoState,
fizz::EncryptionLevel encryptionLevel);
EncryptionLevel encryptionLevel);
void processCryptoStreamAck(
QuicCryptoStream& cryptoStream,