Patch in 249021555 (and 248702511) Support QUIC Client connection IDs
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 209bc81..c72622c 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -210,8 +210,9 @@
chlo_multiplier_(0),
stream_factory_(nullptr),
support_server_push_(false),
- override_connection_id_(nullptr),
- expected_connection_id_length_(kQuicDefaultConnectionIdLength) {
+ override_server_connection_id_(nullptr),
+ override_client_connection_id_(nullptr),
+ expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
SetQuicRestartFlag(quic_no_server_conn_ver_negotiation2, true);
SetQuicReloadableFlag(quic_no_client_conn_ver_negotiation, true);
@@ -258,8 +259,11 @@
if (!pre_shared_key_client_.empty()) {
client->client()->SetPreSharedKey(pre_shared_key_client_);
}
- if (override_connection_id_ != nullptr) {
- client->UseConnectionId(*override_connection_id_);
+ if (override_server_connection_id_ != nullptr) {
+ client->UseConnectionId(*override_server_connection_id_);
+ }
+ if (override_client_connection_id_ != nullptr) {
+ client->UseClientConnectionId(*override_client_connection_id_);
}
client->Connect();
return client;
@@ -374,7 +378,7 @@
auto* test_server = new QuicTestServer(
crypto_test_utils::ProofSourceForTesting(), server_config_,
server_supported_versions_, &memory_cache_backend_,
- expected_connection_id_length_);
+ expected_server_connection_id_length_);
server_thread_ = QuicMakeUnique<ServerThread>(test_server, server_address_);
if (chlo_multiplier_ != 0) {
server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
@@ -537,8 +541,9 @@
bool support_server_push_;
std::string pre_shared_key_client_;
std::string pre_shared_key_server_;
- QuicConnectionId* override_connection_id_;
- uint8_t expected_connection_id_length_;
+ QuicConnectionId* override_server_connection_id_;
+ QuicConnectionId* override_client_connection_id_;
+ uint8_t expected_server_connection_id_length_;
};
// Run all end to end tests with all supported versions.
@@ -602,8 +607,8 @@
TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
QuicConnectionId connection_id = QuicUtils::CreateZeroConnectionId(
GetParam().negotiated_version.transport_version);
- override_connection_id_ = &connection_id;
- expected_connection_id_length_ = connection_id.length();
+ override_server_connection_id_ = &connection_id;
+ expected_server_connection_id_length_ = connection_id.length();
ASSERT_TRUE(Initialize());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -627,7 +632,7 @@
}
QuicConnectionId connection_id =
TestConnectionIdNineBytesLong(UINT64_C(0xBADbadBADbad));
- override_connection_id_ = &connection_id;
+ override_server_connection_id_ = &connection_id;
ASSERT_TRUE(Initialize());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
@@ -638,6 +643,43 @@
.length());
}
+TEST_P(EndToEndTest, ClientConnectionId) {
+ if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ QuicConnectionId client_connection_id =
+ TestConnectionId(UINT64_C(0xc1c2c3c4c5c6c7c8));
+ override_client_connection_id_ = &client_connection_id;
+ ASSERT_TRUE(Initialize());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_EQ(client_connection_id, client_->client()
+ ->client_session()
+ ->connection()
+ ->client_connection_id());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
+ if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ client_supported_versions_.insert(client_supported_versions_.begin(),
+ QuicVersionReservedForNegotiation());
+ QuicConnectionId client_connection_id =
+ TestConnectionId(UINT64_C(0xc1c2c3c4c5c6c7c8));
+ override_client_connection_id_ = &client_connection_id;
+ ASSERT_TRUE(Initialize());
+ ASSERT_TRUE(ServerSendsVersionNegotiation());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_EQ(client_connection_id, client_->client()
+ ->client_session()
+ ->connection()
+ ->client_connection_id());
+}
+
TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
if (!GetQuicRestartFlag(
quic_allow_variable_length_connection_id_for_negotiation)) {
@@ -653,7 +695,7 @@
QuicVersionReservedForNegotiation());
QuicConnectionId connection_id =
TestConnectionIdNineBytesLong(UINT64_C(0xBADbadBADbad));
- override_connection_id_ = &connection_id;
+ override_server_connection_id_ = &connection_id;
ASSERT_TRUE(Initialize());
ASSERT_TRUE(ServerSendsVersionNegotiation());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -675,9 +717,9 @@
// Start client_ which will use a bad connection ID length.
QuicConnectionId connection_id =
TestConnectionIdNineBytesLong(UINT64_C(0xBADbadBADbad));
- override_connection_id_ = &connection_id;
+ override_server_connection_id_ = &connection_id;
ASSERT_TRUE(Initialize());
- override_connection_id_ = nullptr;
+ override_server_connection_id_ = nullptr;
// Start client2 which will use a good connection ID length.
std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
@@ -766,8 +808,8 @@
TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
QuicConnectionId connection_id = QuicUtils::CreateZeroConnectionId(
GetParam().negotiated_version.transport_version);
- override_connection_id_ = &connection_id;
- expected_connection_id_length_ = connection_id.length();
+ override_server_connection_id_ = &connection_id;
+ expected_server_connection_id_length_ = connection_id.length();
ASSERT_TRUE(Initialize());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -2318,7 +2360,7 @@
TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
std::unique_ptr<QuicEncryptedPacket> packet(
QuicFramer::BuildVersionNegotiationPacket(
- incorrect_connection_id,
+ incorrect_connection_id, EmptyQuicConnectionId(),
client_connection->transport_version() > QUIC_VERSION_43,
server_supported_versions_));
testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 77d105c..0d6b36c 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -504,7 +504,7 @@
session_->ProcessUdpPacket(client_address, server_address, valid_packet);
// Verify that a non-decryptable packet doesn't close the connection.
- QuicFramerPeer::SetLastSerializedConnectionId(
+ QuicFramerPeer::SetLastSerializedServerConnectionId(
QuicConnectionPeer::GetFramer(connection_), connection_id);
ParsedQuicVersionVector versions = SupportedVersions(GetParam());
QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
@@ -549,7 +549,7 @@
QuicConnectionId destination_connection_id =
session_->connection()->connection_id();
QuicConnectionId source_connection_id = EmptyQuicConnectionId();
- QuicFramerPeer::SetLastSerializedConnectionId(
+ QuicFramerPeer::SetLastSerializedServerConnectionId(
QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
ParsedQuicVersionVector versions = {GetParam()};
bool version_flag = false;
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index e61bae4..169b17b 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -219,7 +219,7 @@
(perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
QuicConnection::QuicConnection(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
QuicSocketAddress initial_peer_address,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
@@ -230,7 +230,7 @@
: framer_(supported_versions,
helper->GetClock()->ApproximateNow(),
perspective,
- connection_id.length()),
+ server_connection_id.length()),
current_packet_content_(NO_FRAMES_RECEIVED),
is_current_packet_connectivity_probing_(false),
current_effective_peer_migration_type_(NO_CHANGE),
@@ -242,7 +242,7 @@
encryption_level_(ENCRYPTION_INITIAL),
clock_(helper->GetClock()),
random_generator_(helper->GetRandomGenerator()),
- connection_id_(connection_id),
+ server_connection_id_(server_connection_id),
peer_address_(initial_peer_address),
direct_peer_address_(initial_peer_address),
active_effective_peer_migration_type_(NO_CHANGE),
@@ -302,7 +302,10 @@
&arena_)),
visitor_(nullptr),
debug_visitor_(nullptr),
- packet_generator_(connection_id_, &framer_, random_generator_, this),
+ packet_generator_(server_connection_id_,
+ &framer_,
+ random_generator_,
+ this),
idle_network_timeout_(QuicTime::Delta::Infinite()),
handshake_timeout_(QuicTime::Delta::Infinite()),
time_of_first_packet_sent_after_receiving_(
@@ -373,14 +376,14 @@
if (use_uber_received_packet_manager_) {
QUIC_RELOADABLE_FLAG_COUNT(quic_use_uber_received_packet_manager);
}
- QUIC_DLOG(INFO) << ENDPOINT
- << "Created connection with connection_id: " << connection_id
+ QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
+ << server_connection_id
<< " and version: " << ParsedQuicVersionToString(version());
- QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(connection_id,
+ QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(server_connection_id,
transport_version()))
- << "QuicConnection: attempted to use connection ID " << connection_id
- << " which is invalid with version "
+ << "QuicConnection: attempted to use server connection ID "
+ << server_connection_id << " which is invalid with version "
<< QuicVersionToString(transport_version());
framer_.set_visitor(this);
@@ -444,7 +447,7 @@
sent_packet_manager_.SetFromConfig(config);
if (config.HasReceivedBytesForConnectionId() &&
can_truncate_connection_ids_) {
- packet_generator_.SetConnectionIdLength(
+ packet_generator_.SetServerConnectionIdLength(
config.ReceivedBytesForConnectionId());
}
max_undecryptable_packets_ = config.max_undecryptable_packets();
@@ -592,7 +595,7 @@
// Check that any public reset packet with a different connection ID that was
// routed to this QuicConnection has been redirected before control reaches
// here. (Check for a bug regression.)
- DCHECK_EQ(connection_id_, packet.connection_id);
+ DCHECK_EQ(server_connection_id_, packet.connection_id);
DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPublicResetPacket(packet);
@@ -683,7 +686,7 @@
// Check that any public reset packet with a different connection ID that was
// routed to this QuicConnection has been redirected before control reaches
// here. (Check for a bug regression.)
- DCHECK_EQ(connection_id_, packet.connection_id);
+ DCHECK_EQ(server_connection_id_, packet.connection_id);
if (perspective_ == Perspective::IS_SERVER) {
const std::string error_details =
"Server received version negotiation packet.";
@@ -766,10 +769,10 @@
void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
QuicConnectionId new_connection_id,
QuicStringPiece retry_token) {
- if (original_connection_id != connection_id_) {
+ if (original_connection_id != server_connection_id_) {
QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
<< original_connection_id << " not matching expected "
- << connection_id_ << " token "
+ << server_connection_id_ << " token "
<< QuicTextUtils::HexEncode(retry_token);
return;
}
@@ -780,17 +783,18 @@
}
retry_has_been_parsed_ = true;
QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
- << connection_id_ << " with " << new_connection_id
+ << server_connection_id_ << " with " << new_connection_id
<< ", received token "
<< QuicTextUtils::HexEncode(retry_token);
- connection_id_ = new_connection_id;
- packet_generator_.SetConnectionId(connection_id_);
+ server_connection_id_ = new_connection_id;
+ packet_generator_.SetServerConnectionId(server_connection_id_);
packet_generator_.SetRetryToken(retry_token);
// Reinstall initial crypters because the connection ID changed.
CrypterPair crypters;
- CryptoUtils::CreateTlsInitialCrypters(
- Perspective::IS_CLIENT, transport_version(), connection_id_, &crypters);
+ CryptoUtils::CreateTlsInitialCrypters(Perspective::IS_CLIENT,
+ transport_version(),
+ server_connection_id_, &crypters);
SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
}
@@ -817,29 +821,53 @@
QuicConnectionId server_connection_id =
GetServerConnectionIdAsRecipient(header, perspective_);
- if (server_connection_id == connection_id_ ||
- HasIncomingConnectionId(server_connection_id)) {
+ if (server_connection_id != server_connection_id_ &&
+ !HasIncomingConnectionId(server_connection_id)) {
+ if (PacketCanReplaceConnectionId(header, perspective_)) {
+ QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
+ << server_connection_id << " instead of "
+ << server_connection_id_;
+ return true;
+ }
+
+ ++stats_.packets_dropped;
+ QUIC_DLOG(INFO)
+ << ENDPOINT << "Ignoring packet from unexpected server connection ID "
+ << server_connection_id << " instead of " << server_connection_id_;
+ QUIC_BUG
+ << ENDPOINT << "Ignoring packet from unexpected server connection ID "
+ << server_connection_id << " instead of " << server_connection_id_
+ << " header " << header;
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnIncorrectConnectionId(server_connection_id);
+ }
+ // If this is a server, the dispatcher routes each packet to the
+ // QuicConnection responsible for the packet's connection ID. So if control
+ // arrives here and this is a server, the dispatcher must be malfunctioning.
+ DCHECK_NE(Perspective::IS_SERVER, perspective_);
+ return false;
+ }
+
+ if (!version().SupportsClientConnectionIds()) {
return true;
}
- if (PacketCanReplaceConnectionId(header, perspective_)) {
- QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
- << server_connection_id << " instead of " << connection_id_;
- return true;
+ QuicConnectionId client_connection_id =
+ GetClientConnectionIdAsRecipient(header, perspective_);
+
+ if (client_connection_id != client_connection_id_) {
+ ++stats_.packets_dropped;
+ QUIC_DLOG(INFO)
+ << ENDPOINT << "Ignoring packet from unexpected client connection ID "
+ << client_connection_id << " instead of " << client_connection_id_;
+ QUIC_BUG
+ << ENDPOINT << "Ignoring packet from unexpected client connection ID "
+ << client_connection_id << " instead of " << client_connection_id_
+ << " header " << header;
+ return false;
}
- ++stats_.packets_dropped;
- QUIC_DLOG(INFO) << ENDPOINT
- << "Ignoring packet from unexpected ConnectionId: "
- << server_connection_id << " instead of " << connection_id_;
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnIncorrectConnectionId(server_connection_id);
- }
- // If this is a server, the dispatcher routes each packet to the
- // QuicConnection responsible for the packet's connection ID. So if control
- // arrives here and this is a server, the dispatcher must be malfunctioning.
- DCHECK_NE(Perspective::IS_SERVER, perspective_);
- return false;
+ return true;
}
bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
@@ -851,7 +879,7 @@
// routed to this QuicConnection has been redirected before control reaches
// here.
DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
- connection_id_ ||
+ server_connection_id_ ||
HasIncomingConnectionId(
GetServerConnectionIdAsRecipient(header, perspective_)) ||
PacketCanReplaceConnectionId(header, perspective_));
@@ -1109,7 +1137,7 @@
<< " packet_number:" << last_header_.packet_number
<< " largest seen with ack:"
<< GetLargestReceivedPacketWithAck()
- << " connection_id: " << connection_id_;
+ << " server_connection_id: " << server_connection_id_;
// A new ack has a diminished largest_observed value.
// If this was an old packet, we wouldn't even have checked.
CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too low.",
@@ -2132,11 +2160,12 @@
}
if (PacketCanReplaceConnectionId(header, perspective_) &&
- connection_id_ != header.source_connection_id) {
- QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID " << connection_id_
- << " with " << header.source_connection_id;
- connection_id_ = header.source_connection_id;
- packet_generator_.SetConnectionId(connection_id_);
+ server_connection_id_ != header.source_connection_id) {
+ QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
+ << server_connection_id_ << " with "
+ << header.source_connection_id;
+ server_connection_id_ = header.source_connection_id;
+ packet_generator_.SetServerConnectionId(server_connection_id_);
}
if (!ValidateReceivedPacketNumber(header.packet_number)) {
@@ -3578,7 +3607,7 @@
QUIC_DLOG(INFO) << ENDPOINT
<< "Sending path probe packet for connection_id = "
- << connection_id_;
+ << server_connection_id_;
OwningSerializedPacketPointer probing_packet;
if (transport_version() != QUIC_VERSION_99) {
@@ -4215,5 +4244,22 @@
return received_packet_manager_.ack_frame();
}
+void QuicConnection::set_client_connection_id(
+ QuicConnectionId client_connection_id) {
+ if (!version().SupportsClientConnectionIds()) {
+ QUIC_BUG_IF(!client_connection_id.IsEmpty())
+ << ENDPOINT << "Attempted to use client connection ID "
+ << client_connection_id << " with unsupported version " << version();
+ return;
+ }
+ client_connection_id_ = client_connection_id;
+ QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
+ << client_connection_id_
+ << " for connection with server connection ID "
+ << server_connection_id_;
+ packet_generator_.SetClientConnectionId(client_connection_id_);
+ framer_.SetExpectedClientConnectionIdLength(client_connection_id_.length());
+}
+
#undef ENDPOINT // undef for jumbo builds
} // namespace quic
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 8c8ed2b..00902a9 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -341,7 +341,7 @@
// |initial_peer_address| using |writer| to write packets. |owns_writer|
// specifies whether the connection takes ownership of |writer|. |helper| must
// outlive this connection.
- QuicConnection(QuicConnectionId connection_id,
+ QuicConnection(QuicConnectionId server_connection_id,
QuicSocketAddress initial_peer_address,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
@@ -582,7 +582,11 @@
const QuicSocketAddress& effective_peer_address() const {
return effective_peer_address_;
}
- QuicConnectionId connection_id() const { return connection_id_; }
+ QuicConnectionId connection_id() const { return server_connection_id_; }
+ QuicConnectionId client_connection_id() const {
+ return client_connection_id_;
+ }
+ void set_client_connection_id(QuicConnectionId client_connection_id);
const QuicClock* clock() const { return clock_; }
QuicRandom* random_generator() const { return random_generator_; }
QuicByteCount max_packet_length() const;
@@ -1168,7 +1172,8 @@
const QuicClock* clock_;
QuicRandom* random_generator_;
- QuicConnectionId connection_id_;
+ QuicConnectionId server_connection_id_;
+ QuicConnectionId client_connection_id_;
// Address on the last successfully processed packet received from the
// direct peer.
QuicSocketAddress self_address_;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 4ecb780..5c98970 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -938,7 +938,7 @@
peer_creator_.SetEncrypter(
level, QuicMakeUnique<NullEncrypter>(peer_framer_.perspective()));
}
- QuicFramerPeer::SetLastSerializedConnectionId(
+ QuicFramerPeer::SetLastSerializedServerConnectionId(
QuicConnectionPeer::GetFramer(&connection_), connection_id_);
if (version().transport_version > QUIC_VERSION_43) {
EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
@@ -6877,7 +6877,8 @@
// Send a version negotiation packet.
std::unique_ptr<QuicEncryptedPacket> encrypted(
peer_framer_.BuildVersionNegotiationPacket(
- connection_id_, connection_.transport_version() > QUIC_VERSION_43,
+ connection_id_, EmptyQuicConnectionId(),
+ connection_.transport_version() > QUIC_VERSION_43,
AllSupportedVersions()));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 9af5f84..b57f398 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -115,17 +115,17 @@
// list manager.
class StatelessConnectionTerminator {
public:
- StatelessConnectionTerminator(QuicConnectionId connection_id,
+ StatelessConnectionTerminator(QuicConnectionId server_connection_id,
const ParsedQuicVersion version,
QuicConnectionHelperInterface* helper,
QuicTimeWaitListManager* time_wait_list_manager)
- : connection_id_(connection_id),
+ : server_connection_id_(server_connection_id),
framer_(ParsedQuicVersionVector{version},
/*unused*/ QuicTime::Zero(),
Perspective::IS_SERVER,
/*unused*/ kQuicDefaultConnectionIdLength),
collector_(helper->GetStreamSendBufferAllocator()),
- creator_(connection_id, &framer_, &collector_),
+ creator_(server_connection_id, &framer_, &collector_),
time_wait_list_manager_(time_wait_list_manager) {
framer_.set_data_producer(&collector_);
}
@@ -154,7 +154,7 @@
creator_.Flush();
DCHECK_EQ(1u, collector_.packets()->size());
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, ietf_quic,
+ server_connection_id_, ietf_quic,
QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
quic::ENCRYPTION_INITIAL, collector_.packets());
}
@@ -195,14 +195,15 @@
creator_.Flush();
}
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, ietf_quic,
+ server_connection_id_, ietf_quic,
QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, ENCRYPTION_INITIAL,
collector_.packets());
- DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id_));
+ DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
+ server_connection_id_));
}
private:
- QuicConnectionId connection_id_;
+ QuicConnectionId server_connection_id_;
QuicFramer framer_;
// Set as the visitor of |creator_| to collect any generated packets.
PacketCollector collector_;
@@ -214,7 +215,7 @@
class ChloAlpnExtractor : public ChloExtractor::Delegate {
public:
void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
const CryptoHandshakeMessage& chlo) override {
QuicStringPiece alpn_value;
if (chlo.GetStringPiece(kALPN, &alpn_value)) {
@@ -247,16 +248,17 @@
// ChloExtractor::Delegate implementation.
void OnChlo(QuicTransportVersion version,
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
const CryptoHandshakeMessage& chlo) override {
// Extract the ALPN
- ChloAlpnExtractor::OnChlo(version, connection_id, chlo);
+ ChloAlpnExtractor::OnChlo(version, server_connection_id, chlo);
if (helper_->CanAcceptClientHello(chlo, client_address_, peer_address_,
self_address_, &error_details_)) {
can_accept_ = true;
rejector_->OnChlo(
- version, connection_id,
- helper_->GenerateConnectionIdForReject(version, connection_id), chlo);
+ version, server_connection_id,
+ helper_->GenerateConnectionIdForReject(version, server_connection_id),
+ chlo);
}
}
@@ -285,7 +287,7 @@
std::unique_ptr<QuicConnectionHelperInterface> helper,
std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: config_(config),
crypto_config_(crypto_config),
compressed_certs_cache_(
@@ -301,14 +303,15 @@
framer_(GetSupportedVersions(),
/*unused*/ QuicTime::Zero(),
Perspective::IS_SERVER,
- expected_connection_id_length),
+ expected_server_connection_id_length),
last_error_(QUIC_NO_ERROR),
new_sessions_allowed_per_event_loop_(0u),
accept_new_connections_(true),
- allow_short_initial_connection_ids_(false),
+ allow_short_initial_server_connection_ids_(false),
last_version_label_(0),
- expected_connection_id_length_(expected_connection_id_length),
- should_update_expected_connection_id_length_(false),
+ expected_server_connection_id_length_(
+ expected_server_connection_id_length),
+ should_update_expected_server_connection_id_length_(false),
no_framer_(GetQuicRestartFlag(quic_no_framer_object_in_dispatcher)) {
if (!no_framer_) {
framer_.set_visitor(this);
@@ -345,12 +348,11 @@
}
QUIC_RESTART_FLAG_COUNT(quic_no_framer_object_in_dispatcher);
QuicPacketHeader header;
- uint8_t destination_connection_id_length;
std::string detailed_error;
const QuicErrorCode error = QuicFramer::ProcessPacketDispatcher(
- packet, expected_connection_id_length_, &header.form,
+ packet, expected_server_connection_id_length_, &header.form,
&header.version_flag, &last_version_label_,
- &destination_connection_id_length, &header.destination_connection_id,
+ &header.destination_connection_id, &header.source_connection_id,
&detailed_error);
if (error != QUIC_NO_ERROR) {
// Packet has framing error.
@@ -359,16 +361,18 @@
return;
}
header.version = ParseQuicVersionLabel(last_version_label_);
- if (destination_connection_id_length != expected_connection_id_length_ &&
- !should_update_expected_connection_id_length_ &&
+ if (header.destination_connection_id.length() !=
+ expected_server_connection_id_length_ &&
+ !should_update_expected_server_connection_id_length_ &&
!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
header.version.transport_version)) {
SetLastError(QUIC_INVALID_PACKET_HEADER);
QUIC_DLOG(ERROR) << "Invalid Connection Id Length";
return;
}
- if (should_update_expected_connection_id_length_) {
- expected_connection_id_length_ = destination_connection_id_length;
+ if (should_update_expected_server_connection_id_length_) {
+ expected_server_connection_id_length_ =
+ header.destination_connection_id.length();
}
// TODO(fayang): Instead of passing in QuicPacketHeader, pass format,
// version_flag, version and destination_connection_id. Combine
@@ -382,34 +386,36 @@
// the next packet does not use them incorrectly.
}
-QuicConnectionId QuicDispatcher::MaybeReplaceConnectionId(
- QuicConnectionId connection_id,
+QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
+ QuicConnectionId server_connection_id,
ParsedQuicVersion version) {
- const uint8_t expected_connection_id_length =
- no_framer_ ? expected_connection_id_length_
- : framer_.GetExpectedConnectionIdLength();
- if (connection_id.length() == expected_connection_id_length) {
- return connection_id;
+ const uint8_t expected_server_connection_id_length =
+ no_framer_ ? expected_server_connection_id_length_
+ : framer_.GetExpectedServerConnectionIdLength();
+ if (server_connection_id.length() == expected_server_connection_id_length) {
+ return server_connection_id;
}
DCHECK(QuicUtils::VariableLengthConnectionIdAllowedForVersion(
version.transport_version));
- auto it = connection_id_map_.find(connection_id);
+ auto it = connection_id_map_.find(server_connection_id);
if (it != connection_id_map_.end()) {
return it->second;
}
QuicConnectionId new_connection_id =
session_helper_->GenerateConnectionIdForReject(version.transport_version,
- connection_id);
- DCHECK_EQ(expected_connection_id_length, new_connection_id.length());
- connection_id_map_.insert(std::make_pair(connection_id, new_connection_id));
- QUIC_DLOG(INFO) << "Replacing incoming connection ID " << connection_id
+ server_connection_id);
+ DCHECK_EQ(expected_server_connection_id_length, new_connection_id.length());
+ connection_id_map_.insert(
+ std::make_pair(server_connection_id, new_connection_id));
+ QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
<< " with " << new_connection_id;
return new_connection_id;
}
bool QuicDispatcher::OnUnauthenticatedPublicHeader(
const QuicPacketHeader& header) {
- current_connection_id_ = header.destination_connection_id;
+ current_server_connection_id_ = header.destination_connection_id;
+ current_client_connection_id_ = header.source_connection_id;
// Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC.
// Given that we can't even send a reply rejecting the packet, just drop the
@@ -423,52 +429,54 @@
if (header.destination_connection_id_included != CONNECTION_ID_PRESENT) {
return false;
}
- QuicConnectionId connection_id = header.destination_connection_id;
+ QuicConnectionId server_connection_id = header.destination_connection_id;
+ QuicConnectionId client_connection_id = header.source_connection_id;
// The IETF spec requires the client to generate an initial server
// connection ID that is at least 64 bits long. After that initial
// connection ID, the dispatcher picks a new one of its expected length.
// Therefore we should never receive a connection ID that is smaller
// than 64 bits and smaller than what we expect.
- const uint8_t expected_connection_id_length =
- no_framer_ ? expected_connection_id_length_
- : framer_.GetExpectedConnectionIdLength();
- if (connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
- connection_id.length() < expected_connection_id_length &&
- !allow_short_initial_connection_ids_) {
+ const uint8_t expected_server_connection_id_length =
+ no_framer_ ? expected_server_connection_id_length_
+ : framer_.GetExpectedServerConnectionIdLength();
+ if (server_connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
+ server_connection_id.length() < expected_server_connection_id_length &&
+ !allow_short_initial_server_connection_ids_) {
DCHECK(header.version_flag);
DCHECK(QuicUtils::VariableLengthConnectionIdAllowedForVersion(
header.version.transport_version));
QUIC_DLOG(INFO) << "Packet with short destination connection ID "
- << connection_id << " expected "
- << static_cast<int>(expected_connection_id_length);
- ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, header.form,
- header.version_flag, header.version);
+ << server_connection_id << " expected "
+ << static_cast<int>(expected_server_connection_id_length);
+ ProcessUnauthenticatedHeaderFate(kFateTimeWait, server_connection_id,
+ header.form, header.version_flag,
+ header.version);
return false;
}
// Packets with connection IDs for active connections are processed
// immediately.
- auto it = session_map_.find(connection_id);
+ auto it = session_map_.find(server_connection_id);
if (it != session_map_.end()) {
- DCHECK(!buffered_packets_.HasBufferedPackets(connection_id));
+ DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
it->second->ProcessUdpPacket(current_self_address_, current_peer_address_,
*current_packet_);
return false;
}
- if (buffered_packets_.HasChloForConnection(connection_id)) {
- BufferEarlyPacket(connection_id, header.form != GOOGLE_QUIC_PACKET,
+ if (buffered_packets_.HasChloForConnection(server_connection_id)) {
+ BufferEarlyPacket(server_connection_id, header.form != GOOGLE_QUIC_PACKET,
header.version);
return false;
}
// Check if we are buffering packets for this connection ID
- if (temporarily_buffered_connections_.find(connection_id) !=
+ if (temporarily_buffered_connections_.find(server_connection_id) !=
temporarily_buffered_connections_.end()) {
// This packet was received while the a CHLO for the same connection ID was
// being processed. Buffer it.
- BufferEarlyPacket(connection_id, header.form != GOOGLE_QUIC_PACKET,
+ BufferEarlyPacket(server_connection_id, header.form != GOOGLE_QUIC_PACKET,
header.version);
return false;
}
@@ -483,7 +491,7 @@
return false;
}
- if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
+ if (time_wait_list_manager_->IsConnectionIdInTimeWait(server_connection_id)) {
// This connection ID is already in time-wait state.
time_wait_list_manager_->ProcessPacket(
current_self_address_, current_peer_address_,
@@ -513,9 +521,10 @@
// Since the version is not supported, send a version negotiation
// packet and stop processing the current packet.
time_wait_list_manager()->SendVersionNegotiationPacket(
- connection_id, header.form != GOOGLE_QUIC_PACKET,
- GetSupportedVersions(), current_self_address_,
- current_peer_address_, GetPerPacketContext());
+ server_connection_id, client_connection_id,
+ header.form != GOOGLE_QUIC_PACKET, GetSupportedVersions(),
+ current_self_address_, current_peer_address_,
+ GetPerPacketContext());
}
return false;
}
@@ -539,25 +548,25 @@
}
void QuicDispatcher::ProcessHeader(const QuicPacketHeader& header) {
- QuicConnectionId connection_id = header.destination_connection_id;
+ QuicConnectionId server_connection_id = header.destination_connection_id;
// Packet's connection ID is unknown. Apply the validity checks.
QuicPacketFate fate = ValidityChecks(header);
if (fate == kFateProcess) {
// Execute stateless rejection logic to determine the packet fate, then
// invoke ProcessUnauthenticatedHeaderFate.
- MaybeRejectStatelessly(connection_id, header.form, header.version_flag,
- header.version);
+ MaybeRejectStatelessly(server_connection_id, header.form,
+ header.version_flag, header.version);
} else {
// If the fate is already known, process it without executing stateless
// rejection logic.
- ProcessUnauthenticatedHeaderFate(fate, connection_id, header.form,
+ ProcessUnauthenticatedHeaderFate(fate, server_connection_id, header.form,
header.version_flag, header.version);
}
}
void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
QuicPacketFate fate,
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
PacketHeaderFormat form,
bool version_flag,
ParsedQuicVersion version) {
@@ -570,33 +579,36 @@
// MaybeRejectStatelessly or OnExpiredPackets might have already added the
// connection to time wait, in which case it should not be added again.
if (!GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
- !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
+ !time_wait_list_manager_->IsConnectionIdInTimeWait(
+ server_connection_id)) {
// Add this connection_id to the time-wait state, to safely reject
// future packets.
- QUIC_DLOG(INFO) << "Adding connection ID " << connection_id
+ QUIC_DLOG(INFO) << "Adding connection ID " << server_connection_id
<< " to time-wait list.";
QUIC_CODE_COUNT(quic_reject_fate_time_wait);
StatelesslyTerminateConnection(
- connection_id, form, version_flag, version, QUIC_HANDSHAKE_FAILED,
- "Reject connection",
+ server_connection_id, form, version_flag, version,
+ QUIC_HANDSHAKE_FAILED, "Reject connection",
quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
}
- DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
+ DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
+ server_connection_id));
time_wait_list_manager_->ProcessPacket(
- current_self_address_, current_peer_address_, connection_id, form,
- GetPerPacketContext());
+ current_self_address_, current_peer_address_, server_connection_id,
+ form, GetPerPacketContext());
// Any packets which were buffered while the stateless rejector logic was
// running should be discarded. Do not inform the time wait list manager,
// which should already have a made a decision about sending a reject
// based on the CHLO alone.
- buffered_packets_.DiscardPackets(connection_id);
+ buffered_packets_.DiscardPackets(server_connection_id);
break;
case kFateBuffer:
// This packet is a non-CHLO packet which has arrived before the
// corresponding CHLO, *or* this packet was received while the
// corresponding CHLO was being processed. Buffer it.
- BufferEarlyPacket(connection_id, form != GOOGLE_QUIC_PACKET, version);
+ BufferEarlyPacket(server_connection_id, form != GOOGLE_QUIC_PACKET,
+ version);
break;
case kFateDrop:
// Do nothing with the packet.
@@ -775,13 +787,13 @@
DeleteSessions();
}
-void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id,
+void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
QuicErrorCode error,
const std::string& error_details,
ConnectionCloseSource source) {
- auto it = session_map_.find(connection_id);
+ auto it = session_map_.find(server_connection_id);
if (it == session_map_.end()) {
- QUIC_BUG << "ConnectionId " << connection_id
+ QUIC_BUG << "ConnectionId " << server_connection_id
<< " does not exist in the session map. Error: "
<< QuicErrorCodeToString(error);
QUIC_BUG << QuicStackTrace();
@@ -789,7 +801,7 @@
}
QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
- << "Closing connection (" << connection_id
+ << "Closing connection (" << server_connection_id
<< ") due to error: " << QuicErrorCodeToString(error)
<< ", with details: " << error_details;
@@ -828,13 +840,13 @@
void QuicDispatcher::OnStopSendingReceived(const QuicStopSendingFrame& frame) {}
void QuicDispatcher::OnConnectionAddedToTimeWaitList(
- QuicConnectionId connection_id) {
- QUIC_DLOG(INFO) << "Connection " << connection_id
+ QuicConnectionId server_connection_id) {
+ QUIC_DLOG(INFO) << "Connection " << server_connection_id
<< " added to time wait list.";
}
void QuicDispatcher::StatelesslyTerminateConnection(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
PacketHeaderFormat format,
bool version_flag,
ParsedQuicVersion version,
@@ -844,26 +856,27 @@
if (format != IETF_QUIC_LONG_HEADER_PACKET &&
(!GetQuicReloadableFlag(quic_terminate_gquic_connection_as_ietf) ||
!version_flag)) {
- QUIC_DVLOG(1) << "Statelessly terminating " << connection_id
+ QUIC_DVLOG(1) << "Statelessly terminating " << server_connection_id
<< " based on a non-ietf-long packet, action:" << action
<< ", error_code:" << error_code
<< ", error_details:" << error_details;
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, format != GOOGLE_QUIC_PACKET, action, ENCRYPTION_INITIAL,
- nullptr);
+ server_connection_id, format != GOOGLE_QUIC_PACKET, action,
+ ENCRYPTION_INITIAL, nullptr);
return;
}
// If the version is known and supported by framer, send a connection close.
if (IsSupportedVersion(version)) {
QUIC_DVLOG(1)
- << "Statelessly terminating " << connection_id
+ << "Statelessly terminating " << server_connection_id
<< " based on an ietf-long packet, which has a supported version:"
<< version << ", error_code:" << error_code
<< ", error_details:" << error_details;
- StatelessConnectionTerminator terminator(
- connection_id, version, helper_.get(), time_wait_list_manager_.get());
+ StatelessConnectionTerminator terminator(server_connection_id, version,
+ helper_.get(),
+ time_wait_list_manager_.get());
// This also adds the connection to time wait list.
if (format == GOOGLE_QUIC_PACKET) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_terminate_gquic_connection_as_ietf, 1,
@@ -875,7 +888,7 @@
}
QUIC_DVLOG(1)
- << "Statelessly terminating " << connection_id
+ << "Statelessly terminating " << server_connection_id
<< " based on an ietf-long packet, which has an unsupported version:"
<< version << ", error_code:" << error_code
<< ", error_details:" << error_details;
@@ -883,13 +896,14 @@
// with an empty version list, which can be understood by the client.
std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
- connection_id, /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
+ server_connection_id, EmptyQuicConnectionId(),
+ /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
ParsedQuicVersionVector{UnsupportedQuicVersion()}));
if (format == GOOGLE_QUIC_PACKET) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_terminate_gquic_connection_as_ietf, 2, 2);
}
time_wait_list_manager()->AddConnectionIdToTimeWait(
- connection_id, /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
+ server_connection_id, /*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, ENCRYPTION_INITIAL,
&termination_packets);
}
@@ -913,7 +927,7 @@
DCHECK(!no_framer_);
QUIC_BUG_IF(
!time_wait_list_manager_->IsConnectionIdInTimeWait(
- current_connection_id_) &&
+ current_server_connection_id_) &&
!ShouldCreateSessionForUnknownVersion(framer_.last_version_label()))
<< "Unexpected version mismatch: "
<< QuicVersionLabelToString(framer_.last_version_label());
@@ -1090,11 +1104,11 @@
}
void QuicDispatcher::OnExpiredPackets(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
BufferedPacketList early_arrived_packets) {
QUIC_CODE_COUNT(quic_reject_buffered_packets_expired);
StatelesslyTerminateConnection(
- connection_id,
+ server_connection_id,
early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
: GOOGLE_QUIC_PACKET,
/*version_flag=*/true, early_arrived_packets.version,
@@ -1107,24 +1121,44 @@
new_sessions_allowed_per_event_loop_ = max_connections_to_create;
for (; new_sessions_allowed_per_event_loop_ > 0;
--new_sessions_allowed_per_event_loop_) {
- QuicConnectionId connection_id;
+ QuicConnectionId server_connection_id;
BufferedPacketList packet_list =
- buffered_packets_.DeliverPacketsForNextConnection(&connection_id);
+ buffered_packets_.DeliverPacketsForNextConnection(
+ &server_connection_id);
const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
if (packets.empty()) {
return;
}
- QuicConnectionId original_connection_id = connection_id;
- connection_id =
- MaybeReplaceConnectionId(connection_id, packet_list.version);
+ QuicConnectionId original_connection_id = server_connection_id;
+ server_connection_id = MaybeReplaceServerConnectionId(server_connection_id,
+ packet_list.version);
QuicSession* session =
- CreateQuicSession(connection_id, packets.front().peer_address,
+ CreateQuicSession(server_connection_id, packets.front().peer_address,
packet_list.alpn, packet_list.version);
- if (original_connection_id != connection_id) {
+ if (original_connection_id != server_connection_id) {
session->connection()->AddIncomingConnectionId(original_connection_id);
}
- QUIC_DLOG(INFO) << "Created new session for " << connection_id;
- session_map_.insert(std::make_pair(connection_id, QuicWrapUnique(session)));
+ if (packet_list.version.SupportsClientConnectionIds()) {
+ // Parse out the first packet's source connection ID and set it as the
+ // connection's client connection ID.
+ QuicPacketHeader header;
+ QuicVersionLabel version_label;
+ std::string detailed_error;
+ const QuicErrorCode error = QuicFramer::ProcessPacketDispatcher(
+ *packets.front().packet, expected_server_connection_id_length_,
+ &header.form, &header.version_flag, &version_label,
+ &header.destination_connection_id, &header.source_connection_id,
+ &detailed_error);
+ if (error == QUIC_NO_ERROR) {
+ session->connection()->set_client_connection_id(
+ header.source_connection_id);
+ } else {
+ QUIC_DLOG(ERROR) << detailed_error;
+ }
+ }
+ QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
+ session_map_.insert(
+ std::make_pair(server_connection_id, QuicWrapUnique(session)));
DeliverPacketsToSession(packets, session);
}
}
@@ -1134,21 +1168,23 @@
}
bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
bool ietf_quic) {
- QUIC_VLOG(1) << "Received packet from new connection " << connection_id;
+ QUIC_VLOG(1) << "Received packet from new connection "
+ << server_connection_id;
return true;
}
// Return true if there is any packet buffered in the store.
-bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) {
- return buffered_packets_.HasBufferedPackets(connection_id);
+bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) {
+ return buffered_packets_.HasBufferedPackets(server_connection_id);
}
-void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result,
- QuicConnectionId connection_id) {
- QUIC_DLOG(INFO) << "Fail to buffer packet on connection " << connection_id
- << " because of " << result;
+void QuicDispatcher::OnBufferPacketFailure(
+ EnqueuePacketResult result,
+ QuicConnectionId server_connection_id) {
+ QUIC_DLOG(INFO) << "Fail to buffer packet on connection "
+ << server_connection_id << " because of " << result;
}
bool QuicDispatcher::ShouldAttemptCheapStatelessRejection() {
@@ -1160,21 +1196,22 @@
alarm_factory_.get());
}
-void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id,
+void QuicDispatcher::BufferEarlyPacket(QuicConnectionId server_connection_id,
bool ietf_quic,
ParsedQuicVersion version) {
- bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id);
- if (is_new_connection &&
- !ShouldCreateOrBufferPacketForConnection(connection_id, ietf_quic)) {
+ bool is_new_connection =
+ !buffered_packets_.HasBufferedPackets(server_connection_id);
+ if (is_new_connection && !ShouldCreateOrBufferPacketForConnection(
+ server_connection_id, ietf_quic)) {
return;
}
EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- connection_id, ietf_quic, *current_packet_, current_self_address_,
+ server_connection_id, ietf_quic, *current_packet_, current_self_address_,
current_peer_address_, /*is_chlo=*/false,
/*alpn=*/"", version);
if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, connection_id);
+ OnBufferPacketFailure(rs, server_connection_id);
}
}
@@ -1184,48 +1221,56 @@
// Don't any create new connection.
QUIC_CODE_COUNT(quic_reject_stop_accepting_new_connections);
StatelesslyTerminateConnection(
- current_connection_id(), form, /*version_flag=*/true, version,
+ current_server_connection_id(), form, /*version_flag=*/true, version,
QUIC_HANDSHAKE_FAILED, "Stop accepting new connections",
quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
// Time wait list will reject the packet correspondingly.
time_wait_list_manager()->ProcessPacket(
- current_self_address(), current_peer_address(), current_connection_id(),
- form, GetPerPacketContext());
+ current_self_address(), current_peer_address(),
+ current_server_connection_id(), form, GetPerPacketContext());
return;
}
- if (!buffered_packets_.HasBufferedPackets(current_connection_id_) &&
- !ShouldCreateOrBufferPacketForConnection(current_connection_id_,
+ if (!buffered_packets_.HasBufferedPackets(current_server_connection_id_) &&
+ !ShouldCreateOrBufferPacketForConnection(current_server_connection_id_,
form != GOOGLE_QUIC_PACKET)) {
return;
}
if (FLAGS_quic_allow_chlo_buffering &&
new_sessions_allowed_per_event_loop_ <= 0) {
// Can't create new session any more. Wait till next event loop.
- QUIC_BUG_IF(buffered_packets_.HasChloForConnection(current_connection_id_));
+ QUIC_BUG_IF(
+ buffered_packets_.HasChloForConnection(current_server_connection_id_));
EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- current_connection_id_, form != GOOGLE_QUIC_PACKET, *current_packet_,
- current_self_address_, current_peer_address_,
+ current_server_connection_id_, form != GOOGLE_QUIC_PACKET,
+ *current_packet_, current_self_address_, current_peer_address_,
/*is_chlo=*/true, current_alpn_, version);
if (rs != EnqueuePacketResult::SUCCESS) {
- OnBufferPacketFailure(rs, current_connection_id_);
+ OnBufferPacketFailure(rs, current_server_connection_id_);
}
return;
}
- QuicConnectionId original_connection_id = current_connection_id_;
- current_connection_id_ =
- MaybeReplaceConnectionId(current_connection_id_, version);
+ QuicConnectionId original_connection_id = current_server_connection_id_;
+ current_server_connection_id_ =
+ MaybeReplaceServerConnectionId(current_server_connection_id_, version);
// Creates a new session and process all buffered packets for this connection.
- QuicSession* session = CreateQuicSession(
- current_connection_id_, current_peer_address_, current_alpn_, version);
- if (original_connection_id != current_connection_id_) {
+ QuicSession* session =
+ CreateQuicSession(current_server_connection_id_, current_peer_address_,
+ current_alpn_, version);
+ if (original_connection_id != current_server_connection_id_) {
session->connection()->AddIncomingConnectionId(original_connection_id);
}
- QUIC_DLOG(INFO) << "Created new session for " << current_connection_id_;
+ if (version.SupportsClientConnectionIds()) {
+ session->connection()->set_client_connection_id(
+ current_client_connection_id_);
+ }
+ QUIC_DLOG(INFO) << "Created new session for "
+ << current_server_connection_id_;
session_map_.insert(
- std::make_pair(current_connection_id_, QuicWrapUnique(session)));
+ std::make_pair(current_server_connection_id_, QuicWrapUnique(session)));
std::list<BufferedPacket> packets =
- buffered_packets_.DeliverPackets(current_connection_id_).buffered_packets;
+ buffered_packets_.DeliverPackets(current_server_connection_id_)
+ .buffered_packets;
// Process CHLO at first.
session->ProcessUdpPacket(current_self_address_, current_peer_address_,
*current_packet_);
@@ -1295,12 +1340,13 @@
bool current_version_flag_;
};
-void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
- PacketHeaderFormat form,
- bool version_flag,
- ParsedQuicVersion version) {
+void QuicDispatcher::MaybeRejectStatelessly(
+ QuicConnectionId server_connection_id,
+ PacketHeaderFormat form,
+ bool version_flag,
+ ParsedQuicVersion version) {
if (version.handshake_protocol == PROTOCOL_TLS1_3) {
- ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, form,
+ ProcessUnauthenticatedHeaderFate(kFateProcess, server_connection_id, form,
version_flag, version);
return;
// TODO(nharper): Support buffering non-ClientHello packets when using TLS.
@@ -1315,14 +1361,15 @@
if (FLAGS_quic_allow_chlo_buffering &&
!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
config_->create_session_tag_indicators(),
- &alpn_extractor, connection_id.length())) {
+ &alpn_extractor,
+ server_connection_id.length())) {
// Buffer non-CHLO packets.
- ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, form,
+ ProcessUnauthenticatedHeaderFate(kFateBuffer, server_connection_id, form,
version_flag, version);
return;
}
current_alpn_ = alpn_extractor.ConsumeAlpn();
- ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, form,
+ ProcessUnauthenticatedHeaderFate(kFateProcess, server_connection_id, form,
version_flag, version);
return;
}
@@ -1337,8 +1384,8 @@
rejector.get());
if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
config_->create_session_tag_indicators(),
- &validator, connection_id.length())) {
- ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, form,
+ &validator, server_connection_id.length())) {
+ ProcessUnauthenticatedHeaderFate(kFateBuffer, server_connection_id, form,
version_flag, version);
return;
}
@@ -1347,13 +1394,13 @@
if (!validator.can_accept()) {
// This CHLO is prohibited by policy.
QUIC_CODE_COUNT(quic_reject_cant_accept_chlo);
- StatelessConnectionTerminator terminator(connection_id, version, helper(),
- time_wait_list_manager_.get());
+ StatelessConnectionTerminator terminator(
+ server_connection_id, version, helper(), time_wait_list_manager_.get());
terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, validator.error_details(),
form != GOOGLE_QUIC_PACKET);
QuicSession::RecordConnectionCloseAtServer(
QUIC_HANDSHAKE_FAILED, ConnectionCloseSource::FROM_SELF);
- ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, form,
+ ProcessUnauthenticatedHeaderFate(kFateTimeWait, server_connection_id, form,
version_flag, version);
return;
}
@@ -1368,10 +1415,10 @@
// Insert into set of connection IDs to buffer
const bool ok =
- temporarily_buffered_connections_.insert(connection_id).second;
+ temporarily_buffered_connections_.insert(server_connection_id).second;
QUIC_BUG_IF(!ok)
<< "Processing multiple stateless rejections for connection ID "
- << connection_id;
+ << server_connection_id;
// Continue stateless rejector processing
std::unique_ptr<StatelessRejectorProcessDoneCallback> cb(
@@ -1395,7 +1442,7 @@
current_peer_address_ = current_peer_address;
current_self_address_ = current_self_address;
current_packet_ = current_packet.get();
- current_connection_id_ = rejector->connection_id();
+ current_server_connection_id_ = rejector->connection_id();
if (!no_framer_) {
framer_.set_version(first_version);
}
diff --git a/quic/core/quic_dispatcher.h b/quic/core/quic_dispatcher.h
index 6adf5f3..5e755dd 100644
--- a/quic/core/quic_dispatcher.h
+++ b/quic/core/quic_dispatcher.h
@@ -49,7 +49,7 @@
std::unique_ptr<QuicConnectionHelperInterface> helper,
std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
QuicDispatcher(const QuicDispatcher&) = delete;
QuicDispatcher& operator=(const QuicDispatcher&) = delete;
@@ -76,7 +76,7 @@
// QuicSession::Visitor interface implementation (via inheritance of
// QuicTimeWaitListManager::Visitor):
// Ensure that the closed connection is cleaned up asynchronously.
- void OnConnectionClosed(QuicConnectionId connection_id,
+ void OnConnectionClosed(QuicConnectionId server_connection_id,
QuicErrorCode error,
const std::string& error_details,
ConnectionCloseSource source) override;
@@ -99,7 +99,8 @@
// QuicTimeWaitListManager::Visitor interface implementation
// Called whenever the time wait list manager adds a new connection to the
// time-wait list.
- void OnConnectionAddedToTimeWaitList(QuicConnectionId connection_id) override;
+ void OnConnectionAddedToTimeWaitList(
+ QuicConnectionId server_connection_id) override;
using SessionMap = QuicUnorderedMap<QuicConnectionId,
std::unique_ptr<QuicSession>,
@@ -191,7 +192,7 @@
const QuicIetfStatelessResetPacket& packet) override;
// QuicBufferedPacketStore::VisitorInterface implementation.
- void OnExpiredPackets(QuicConnectionId connection_id,
+ void OnExpiredPackets(QuicConnectionId server_connection_id,
QuicBufferedPacketStore::BufferedPacketList
early_arrived_packets) override;
@@ -202,7 +203,7 @@
virtual bool HasChlosBuffered() const;
protected:
- virtual QuicSession* CreateQuicSession(QuicConnectionId connection_id,
+ virtual QuicSession* CreateQuicSession(QuicConnectionId server_connection_id,
const QuicSocketAddress& peer_address,
QuicStringPiece alpn,
const ParsedQuicVersion& version) = 0;
@@ -238,9 +239,9 @@
// will be owned by the dispatcher as time_wait_list_manager_
virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
- // Called when |connection_id| doesn't have an open connection yet, to buffer
- // |current_packet_| until it can be delivered to the connection.
- void BufferEarlyPacket(QuicConnectionId connection_id,
+ // Called when |server_connection_id| doesn't have an open connection yet,
+ // to buffer |current_packet_| until it can be delivered to the connection.
+ void BufferEarlyPacket(QuicConnectionId server_connection_id,
bool ietf_quic,
ParsedQuicVersion version);
@@ -269,8 +270,8 @@
const ParsedQuicVersionVector& GetSupportedVersions();
- QuicConnectionId current_connection_id() const {
- return current_connection_id_;
+ QuicConnectionId current_server_connection_id() const {
+ return current_server_connection_id_;
}
const QuicSocketAddress& current_self_address() const {
return current_self_address_;
@@ -319,15 +320,15 @@
// for CHLO. Returns true if a new connection should be created or its packets
// should be buffered, false otherwise.
virtual bool ShouldCreateOrBufferPacketForConnection(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
bool ietf_quic);
- bool HasBufferedPackets(QuicConnectionId connection_id);
+ bool HasBufferedPackets(QuicConnectionId server_connection_id);
// Called when BufferEarlyPacket() fail to buffer the packet.
virtual void OnBufferPacketFailure(
QuicBufferedPacketStore::EnqueuePacketResult result,
- QuicConnectionId connection_id);
+ QuicConnectionId server_connection_id);
// Removes the session from the session map and write blocked list, and adds
// the ConnectionId to the time-wait list. If |session_closed_statelessly| is
@@ -344,7 +345,7 @@
// connection to time wait list or 2) directly add connection to time wait
// list with |action|.
void StatelesslyTerminateConnection(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
PacketHeaderFormat format,
bool version_flag,
ParsedQuicVersion version,
@@ -363,21 +364,22 @@
// If true, our framer will change its expected connection ID length
// to the received destination connection ID length of all IETF long headers.
void SetShouldUpdateExpectedConnectionIdLength(
- bool should_update_expected_connection_id_length) {
+ bool should_update_expected_server_connection_id_length) {
if (!no_framer_) {
framer_.SetShouldUpdateExpectedConnectionIdLength(
- should_update_expected_connection_id_length);
+ should_update_expected_server_connection_id_length);
return;
}
- should_update_expected_connection_id_length_ =
- should_update_expected_connection_id_length;
+ should_update_expected_server_connection_id_length_ =
+ should_update_expected_server_connection_id_length;
}
// If true, the dispatcher will allow incoming initial packets that have
- // connection IDs shorter than 64 bits.
- void SetAllowShortInitialConnectionIds(
- bool allow_short_initial_connection_ids) {
- allow_short_initial_connection_ids_ = allow_short_initial_connection_ids;
+ // destination connection IDs shorter than 64 bits.
+ void SetAllowShortInitialServerConnectionIds(
+ bool allow_short_initial_server_connection_ids) {
+ allow_short_initial_server_connection_ids_ =
+ allow_short_initial_server_connection_ids;
}
private:
@@ -395,7 +397,7 @@
// possible and if the current packet contains a CHLO message. Determines a
// fate which describes what subsequent processing should be performed on the
// packets, like ValidityChecks, and invokes ProcessUnauthenticatedHeaderFate.
- void MaybeRejectStatelessly(QuicConnectionId connection_id,
+ void MaybeRejectStatelessly(QuicConnectionId server_connection_id,
PacketHeaderFormat form,
bool version_flag,
ParsedQuicVersion version);
@@ -408,7 +410,7 @@
// Perform the appropriate actions on the current packet based on |fate| -
// either process, buffer, or drop it.
void ProcessUnauthenticatedHeaderFate(QuicPacketFate fate,
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
PacketHeaderFormat form,
bool version_flag,
ParsedQuicVersion version);
@@ -440,8 +442,9 @@
// If the connection ID length is different from what the dispatcher expects,
// replace the connection ID with a random one of the right length,
// and save it to make sure the mapping is persistent.
- QuicConnectionId MaybeReplaceConnectionId(QuicConnectionId connection_id,
- ParsedQuicVersion version);
+ QuicConnectionId MaybeReplaceServerConnectionId(
+ QuicConnectionId server_connection_id,
+ ParsedQuicVersion version);
// Returns true if |version| is a supported protocol version.
bool IsSupportedVersion(const ParsedQuicVersion version);
@@ -505,7 +508,8 @@
const QuicReceivedPacket* current_packet_;
// If |current_packet_| is a CHLO packet, the extracted alpn.
std::string current_alpn_;
- QuicConnectionId current_connection_id_;
+ QuicConnectionId current_server_connection_id_;
+ QuicConnectionId current_client_connection_id_;
// Used to get the supported versions based on flag. Does not own.
QuicVersionManager* version_manager_;
@@ -524,8 +528,9 @@
bool accept_new_connections_;
// If false, the dispatcher follows the IETF spec and rejects packets with
- // invalid connection IDs lengths below 64 bits. If true they are allowed.
- bool allow_short_initial_connection_ids_;
+ // invalid destination connection IDs lengths below 64 bits.
+ // If true they are allowed.
+ bool allow_short_initial_server_connection_ids_;
// The last QUIC version label received. Used when no_framer_ is true.
// TODO(fayang): remove this member variable, instead, add an argument to
@@ -537,14 +542,15 @@
// encode its length. This variable contains the length we expect to read.
// This is also used to signal an error when a long header packet with
// different destination connection ID length is received when
- // should_update_expected_connection_id_length_ is false and packet's version
- // does not allow variable length connection ID. Used when no_framer_ is true.
- uint8_t expected_connection_id_length_;
+ // should_update_expected_server_connection_id_length_ is false and packet's
+ // version does not allow variable length connection ID. Used when no_framer_
+ // is true.
+ uint8_t expected_server_connection_id_length_;
- // If true, change expected_connection_id_length_ to be the received
+ // If true, change expected_server_connection_id_length_ to be the received
// destination connection ID length of all IETF long headers. Used when
// no_framer_ is true.
- bool should_update_expected_connection_id_length_;
+ bool should_update_expected_server_connection_id_length_;
// Latched value of quic_no_framer_object_in_dispatcher.
const bool no_framer_;
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index 46c5bc2..668541b 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -156,7 +156,7 @@
using QuicDispatcher::current_client_address;
using QuicDispatcher::current_peer_address;
using QuicDispatcher::current_self_address;
- using QuicDispatcher::SetAllowShortInitialConnectionIds;
+ using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
using QuicDispatcher::writer;
};
@@ -493,7 +493,7 @@
EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, _, _, _, _))
+ SendVersionNegotiationPacket(_, _, _, _, _, _, _))
.Times(1);
QuicTransportVersion version =
static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
@@ -512,7 +512,7 @@
EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, _, _, _, _))
+ SendVersionNegotiationPacket(_, _, _, _, _, _, _))
.Times(0);
QuicTransportVersion version =
static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
@@ -538,7 +538,7 @@
EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- SendVersionNegotiationPacket(_, _, _, _, _, _))
+ SendVersionNegotiationPacket(_, _, _, _, _, _, _))
.Times(1);
QuicTransportVersion version =
static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
@@ -686,7 +686,7 @@
QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
// Disable validation of invalid short connection IDs.
- dispatcher_->SetAllowShortInitialConnectionIds(true);
+ dispatcher_->SetAllowShortInitialServerConnectionIds(true);
// Note that StrayPacketTruncatedConnectionId covers the case where the
// validation is still enabled.
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 27af834..c35c076 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -459,10 +459,11 @@
QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
QuicTime creation_time,
Perspective perspective,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: visitor_(nullptr),
error_(QUIC_NO_ERROR),
- last_serialized_connection_id_(EmptyQuicConnectionId()),
+ last_serialized_server_connection_id_(EmptyQuicConnectionId()),
+ last_serialized_client_connection_id_(EmptyQuicConnectionId()),
last_version_label_(0),
version_(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
supported_versions_(supported_versions),
@@ -478,8 +479,10 @@
data_producer_(nullptr),
infer_packet_header_type_from_version_(perspective ==
Perspective::IS_CLIENT),
- expected_connection_id_length_(expected_connection_id_length),
- should_update_expected_connection_id_length_(false),
+ expected_server_connection_id_length_(
+ expected_server_connection_id_length),
+ expected_client_connection_id_length_(0),
+ should_update_expected_server_connection_id_length_(false),
supports_multiple_packet_number_spaces_(false),
last_written_packet_number_length_(0) {
DCHECK(!supported_versions.empty());
@@ -1387,14 +1390,17 @@
// static
std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
bool ietf_quic,
const ParsedQuicVersionVector& versions) {
if (ietf_quic) {
- return BuildIetfVersionNegotiationPacket(connection_id, versions);
+ return BuildIetfVersionNegotiationPacket(server_connection_id,
+ client_connection_id, versions);
}
+ DCHECK(client_connection_id.IsEmpty());
DCHECK(!versions.empty());
- size_t len = kPublicFlagsSize + connection_id.length() +
+ size_t len = kPublicFlagsSize + server_connection_id.length() +
versions.size() * kQuicVersionSize;
std::unique_ptr<char[]> buffer(new char[len]);
// Endianness is not a concern here, version negotiation packet does not have
@@ -1409,7 +1415,7 @@
return nullptr;
}
- if (!writer.WriteConnectionId(connection_id)) {
+ if (!writer.WriteConnectionId(server_connection_id)) {
return nullptr;
}
@@ -1427,13 +1433,14 @@
// static
std::unique_ptr<QuicEncryptedPacket>
QuicFramer::BuildIetfVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
const ParsedQuicVersionVector& versions) {
QUIC_DVLOG(1) << "Building IETF version negotiation packet: "
<< ParsedQuicVersionVectorToString(versions);
DCHECK(!versions.empty());
size_t len = kPacketHeaderTypeSize + kConnectionIdLengthSize +
- connection_id.length() +
+ client_connection_id.length() + server_connection_id.length() +
(versions.size() + 1) * kQuicVersionSize;
std::unique_ptr<char[]> buffer(new char[len]);
QuicDataWriter writer(len, buffer.get());
@@ -1452,7 +1459,7 @@
return nullptr;
}
- if (!AppendIetfConnectionIds(true, EmptyQuicConnectionId(), connection_id,
+ if (!AppendIetfConnectionIds(true, client_connection_id, server_connection_id,
&writer)) {
return nullptr;
}
@@ -2064,14 +2071,14 @@
public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
}
- QuicConnectionId connection_id =
+ QuicConnectionId server_connection_id =
GetServerConnectionIdAsSender(header, perspective_);
- QuicConnectionIdIncluded connection_id_included =
+ QuicConnectionIdIncluded server_connection_id_included =
GetServerConnectionIdIncludedAsSender(header, perspective_);
DCHECK_EQ(CONNECTION_ID_ABSENT,
GetClientConnectionIdIncludedAsSender(header, perspective_));
- switch (connection_id_included) {
+ switch (server_connection_id_included) {
case CONNECTION_ID_ABSENT:
if (!writer->WriteUInt8(public_flags |
PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
@@ -2080,9 +2087,9 @@
break;
case CONNECTION_ID_PRESENT:
QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(
- connection_id, transport_version()))
+ server_connection_id, transport_version()))
<< "AppendPacketHeader: attempted to use connection ID "
- << connection_id << " which is invalid with version "
+ << server_connection_id << " which is invalid with version "
<< QuicVersionToString(transport_version());
public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
@@ -2090,12 +2097,12 @@
public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
}
if (!writer->WriteUInt8(public_flags) ||
- !writer->WriteConnectionId(connection_id)) {
+ !writer->WriteConnectionId(server_connection_id)) {
return false;
}
break;
}
- last_serialized_connection_id_ = connection_id;
+ last_serialized_server_connection_id_ = server_connection_id;
if (header.version_flag) {
DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
@@ -2194,7 +2201,10 @@
return false;
}
- last_serialized_connection_id_ = server_connection_id;
+ last_serialized_server_connection_id_ = server_connection_id;
+ if (version_.SupportsClientConnectionIds()) {
+ last_serialized_client_connection_id_ = GetClientConnectionIdAsSender(header, perspective_);
+ }
if (QuicVersionHasLongHeaderLengths(transport_version()) &&
header.version_flag) {
@@ -2336,7 +2346,7 @@
break;
case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
*header_connection_id_included = CONNECTION_ID_ABSENT;
- *header_connection_id = last_serialized_connection_id_;
+ *header_connection_id = last_serialized_server_connection_id_;
break;
}
@@ -2521,11 +2531,15 @@
// connection ID, and those received by server must include 8-byte
// destination connection ID.
header->destination_connection_id_included =
- perspective_ == Perspective::IS_CLIENT ? CONNECTION_ID_ABSENT
- : CONNECTION_ID_PRESENT;
+ (perspective_ == Perspective::IS_SERVER ||
+ version_.SupportsClientConnectionIds())
+ ? CONNECTION_ID_PRESENT
+ : CONNECTION_ID_ABSENT;
header->source_connection_id_included =
- perspective_ == Perspective::IS_CLIENT ? CONNECTION_ID_PRESENT
- : CONNECTION_ID_ABSENT;
+ (perspective_ == Perspective::IS_CLIENT ||
+ version_.SupportsClientConnectionIds())
+ ? CONNECTION_ID_PRESENT
+ : CONNECTION_ID_ABSENT;
// Read version tag.
QuicVersionLabel version_label;
if (!ProcessVersionLabel(reader, &version_label)) {
@@ -2580,8 +2594,10 @@
// Connection ID length depends on the perspective. Client does not expect
// destination connection ID, and server expects destination connection ID.
header->destination_connection_id_included =
- perspective_ == Perspective::IS_CLIENT ? CONNECTION_ID_ABSENT
- : CONNECTION_ID_PRESENT;
+ (perspective_ == Perspective::IS_SERVER ||
+ version_.SupportsClientConnectionIds())
+ ? CONNECTION_ID_PRESENT
+ : CONNECTION_ID_ABSENT;
header->source_connection_id_included = CONNECTION_ID_ABSENT;
if (infer_packet_header_type_from_version_ &&
transport_version() > QUIC_VERSION_44 && !(type & FLAGS_FIXED_BIT)) {
@@ -2614,11 +2630,21 @@
bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
QuicDataReader* reader,
ParsedQuicVersion version,
- bool should_update_expected_connection_id_length,
- uint8_t* expected_connection_id_length,
+ Perspective perspective,
+ bool should_update_expected_server_connection_id_length,
+ uint8_t* expected_server_connection_id_length,
uint8_t* destination_connection_id_length,
uint8_t* source_connection_id_length,
std::string* detailed_error) {
+ QUIC_LOG(ERROR) << "ds33 should_update_expected_server_connection_id_length "
+ << (should_update_expected_server_connection_id_length ? "Y"
+ : "N")
+ << " expected_server_connection_id_length "
+ << (int)*expected_server_connection_id_length
+ << " destination_connection_id_length "
+ << (int)*destination_connection_id_length
+ << " source_connection_id_length "
+ << (int)*source_connection_id_length;
uint8_t connection_id_lengths_byte;
if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
*detailed_error = "Unable to read ConnectionId length.";
@@ -2629,18 +2655,21 @@
if (dcil != 0) {
dcil += kConnectionIdLengthAdjustment;
}
- if (should_update_expected_connection_id_length &&
- *expected_connection_id_length != dcil) {
- QUIC_DVLOG(1) << "Updating expected_connection_id_length: "
- << static_cast<int>(*expected_connection_id_length) << " -> "
- << static_cast<int>(dcil);
- *expected_connection_id_length = dcil;
- }
uint8_t scil = connection_id_lengths_byte & kSourceConnectionIdLengthMask;
if (scil != 0) {
scil += kConnectionIdLengthAdjustment;
}
- if (!should_update_expected_connection_id_length &&
+ if (should_update_expected_server_connection_id_length) {
+ uint8_t server_connection_id_length =
+ perspective == Perspective::IS_SERVER ? dcil : scil;
+ if (*expected_server_connection_id_length != server_connection_id_length) {
+ QUIC_DVLOG(1) << "Updating expected_server_connection_id_length: "
+ << static_cast<int>(*expected_server_connection_id_length)
+ << " -> " << static_cast<int>(server_connection_id_length);
+ *expected_server_connection_id_length = server_connection_id_length;
+ }
+ }
+ if (!should_update_expected_server_connection_id_length &&
(dcil != *destination_connection_id_length ||
scil != *source_connection_id_length) &&
!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
@@ -2665,18 +2694,35 @@
uint8_t destination_connection_id_length =
header->destination_connection_id_included == CONNECTION_ID_PRESENT
- ? expected_connection_id_length_
+ ? (perspective_ == Perspective::IS_SERVER
+ ? expected_server_connection_id_length_
+ : expected_client_connection_id_length_)
: 0;
uint8_t source_connection_id_length =
header->source_connection_id_included == CONNECTION_ID_PRESENT
- ? expected_connection_id_length_
+ ? (perspective_ == Perspective::IS_CLIENT
+ ? expected_server_connection_id_length_
+ : expected_client_connection_id_length_)
: 0;
+ QUIC_LOG(ERROR) << ENDPOINT
+ << "ds33 should_update_expected_server_connection_id_length_ "
+ << (should_update_expected_server_connection_id_length_ ? "Y"
+ : "N")
+ << " expected_server_connection_id_length_ "
+ << (int)expected_server_connection_id_length_
+ << " expected_client_connection_id_length_ "
+ << (int)expected_client_connection_id_length_
+ << " destination_connection_id_length "
+ << (int)destination_connection_id_length
+ << " source_connection_id_length "
+ << (int)source_connection_id_length << " header " << *header;
if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
if (!ProcessAndValidateIetfConnectionIdLength(
- reader, header->version,
- should_update_expected_connection_id_length_,
- &expected_connection_id_length_, &destination_connection_id_length,
- &source_connection_id_length, &detailed_error_)) {
+ reader, header->version, perspective_,
+ should_update_expected_server_connection_id_length_,
+ &expected_server_connection_id_length_,
+ &destination_connection_id_length, &source_connection_id_length,
+ &detailed_error_)) {
return false;
}
}
@@ -2709,13 +2755,17 @@
header->destination_connection_id = header->source_connection_id;
} else if (header->destination_connection_id_included ==
CONNECTION_ID_ABSENT) {
- header->destination_connection_id = last_serialized_connection_id_;
+ header->destination_connection_id = last_serialized_server_connection_id_;
}
} else {
QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 5, 5);
if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
DCHECK_EQ(EmptyQuicConnectionId(), header->source_connection_id);
- header->source_connection_id = last_serialized_connection_id_;
+ if (perspective_ == Perspective::IS_CLIENT) {
+ header->source_connection_id = last_serialized_server_connection_id_;
+ } else {
+ header->source_connection_id = last_serialized_client_connection_id_;
+ }
}
}
@@ -6042,28 +6092,30 @@
// static
QuicErrorCode QuicFramer::ProcessPacketDispatcher(
const QuicEncryptedPacket& packet,
- uint8_t expected_connection_id_length,
+ uint8_t expected_server_connection_id_length,
PacketHeaderFormat* format,
bool* version_flag,
QuicVersionLabel* version_label,
- uint8_t* destination_connection_id_length,
QuicConnectionId* destination_connection_id,
+ QuicConnectionId* source_connection_id,
std::string* detailed_error) {
QuicDataReader reader(packet.data(), packet.length());
+ *source_connection_id = EmptyQuicConnectionId();
uint8_t first_byte;
if (!reader.ReadBytes(&first_byte, 1)) {
*detailed_error = "Unable to read first byte.";
return QUIC_INVALID_PACKET_HEADER;
}
+ uint8_t destination_connection_id_length = 0, source_connection_id_length = 0;
if (!QuicUtils::IsIetfPacketHeader(first_byte)) {
*format = GOOGLE_QUIC_PACKET;
*version_flag = (first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
- *destination_connection_id_length =
+ destination_connection_id_length =
first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
- if (*destination_connection_id_length == 0 ||
+ if (destination_connection_id_length == 0 ||
!reader.ReadConnectionId(destination_connection_id,
- *destination_connection_id_length)) {
+ destination_connection_id_length)) {
*detailed_error = "Unable to read ConnectionId.";
return QUIC_INVALID_PACKET_HEADER;
}
@@ -6083,27 +6135,33 @@
*detailed_error = "Unable to read protocol version.";
return QUIC_INVALID_PACKET_HEADER;
}
- // Set should_update_expected_connection_id_length to true to bypass
+ // Set should_update_expected_server_connection_id_length to true to bypass
// connection ID lengths validation.
- uint8_t unused_source_connection_id_length = 0;
- uint8_t unused_expected_connection_id_length = 0;
+ uint8_t unused_expected_server_connection_id_length = 0;
if (!ProcessAndValidateIetfConnectionIdLength(
&reader, ParseQuicVersionLabel(*version_label),
- /*should_update_expected_connection_id_length=*/true,
- &unused_expected_connection_id_length,
- destination_connection_id_length,
- &unused_source_connection_id_length, detailed_error)) {
+ Perspective::IS_SERVER,
+ /*should_update_expected_server_connection_id_length=*/true,
+ &unused_expected_server_connection_id_length,
+ &destination_connection_id_length, &source_connection_id_length,
+ detailed_error)) {
return QUIC_INVALID_PACKET_HEADER;
}
} else {
- // For short header packets, expected_connection_id_length is used to
+ // For short header packets, expected_server_connection_id_length is used to
// determine the destination_connection_id_length.
- *destination_connection_id_length = expected_connection_id_length;
+ destination_connection_id_length = expected_server_connection_id_length;
}
// Read destination connection ID.
if (!reader.ReadConnectionId(destination_connection_id,
- *destination_connection_id_length)) {
- *detailed_error = "Unable to read Destination ConnectionId.";
+ destination_connection_id_length)) {
+ *detailed_error = "Unable to read destination connection ID.";
+ return QUIC_INVALID_PACKET_HEADER;
+ }
+ // Read source connection ID.
+ if (!reader.ReadConnectionId(source_connection_id,
+ source_connection_id_length)) {
+ *detailed_error = "Unable to read source connection ID.";
return QUIC_INVALID_PACKET_HEADER;
}
return QUIC_NO_ERROR;
@@ -6234,13 +6292,14 @@
*detailed_error = "Packet is not a version negotiation packet";
return false;
}
- uint8_t expected_connection_id_length = 0,
+ uint8_t expected_server_connection_id_length = 0,
destination_connection_id_length = 0, source_connection_id_length = 0;
if (!ProcessAndValidateIetfConnectionIdLength(
- &reader, UnsupportedQuicVersion(),
- /*should_update_expected_connection_id_length=*/true,
- &expected_connection_id_length, &destination_connection_id_length,
- &source_connection_id_length, detailed_error)) {
+ &reader, UnsupportedQuicVersion(), Perspective::IS_CLIENT,
+ /*should_update_expected_server_connection_id_length=*/true,
+ &expected_server_connection_id_length,
+ &destination_connection_id_length, &source_connection_id_length,
+ detailed_error)) {
return false;
}
if (destination_connection_id_length != 0) {
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index ab0e8d7..931dd4a 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -226,7 +226,7 @@
QuicFramer(const ParsedQuicVersionVector& supported_versions,
QuicTime creation_time,
Perspective perspective,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
QuicFramer(const QuicFramer&) = delete;
QuicFramer& operator=(const QuicFramer&) = delete;
@@ -374,18 +374,18 @@
QuicVariableLengthIntegerLength length_length);
// Lightweight parsing of |packet| and populates |format|, |version_flag|,
- // |version_label|, |destination_connection_id_length|,
- // |destination_connection_id| and |detailed_error|. Please note,
- // |expected_connection_id_length| is only used to determine IETF short header
- // packet's destination connection ID length.
+ // |version_label|, |destination_connection_id|, |source_connection_id| and
+ // |detailed_error|. Please note, |expected_server_connection_id_length| is
+ // only used to determine IETF short header packet's destination connection ID
+ // length.
static QuicErrorCode ProcessPacketDispatcher(
const QuicEncryptedPacket& packet,
- uint8_t expected_connection_id_length,
+ uint8_t expected_server_connection_id_length,
PacketHeaderFormat* format,
bool* version_flag,
QuicVersionLabel* version_label,
- uint8_t* destination_connection_id_length,
QuicConnectionId* destination_connection_id,
+ QuicConnectionId* source_connection_id,
std::string* detailed_error);
// Serializes a packet containing |frames| into |buffer|.
@@ -435,13 +435,15 @@
// Returns a new version negotiation packet.
static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
bool ietf_quic,
const ParsedQuicVersionVector& versions);
// Returns a new IETF version negotiation packet.
static std::unique_ptr<QuicEncryptedPacket> BuildIetfVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
const ParsedQuicVersionVector& versions);
// If header.version_flag is set, the version in the
@@ -576,14 +578,23 @@
// If true, QuicFramer will change its expected connection ID length
// to the received destination connection ID length of all IETF long headers.
void SetShouldUpdateExpectedConnectionIdLength(
- bool should_update_expected_connection_id_length) {
- should_update_expected_connection_id_length_ =
- should_update_expected_connection_id_length;
+ bool should_update_expected_server_connection_id_length) {
+ should_update_expected_server_connection_id_length_ =
+ should_update_expected_server_connection_id_length;
}
- // The connection ID length the framer expects on incoming IETF short headers.
- uint8_t GetExpectedConnectionIdLength() {
- return expected_connection_id_length_;
+ // The connection ID length the framer expects on incoming IETF short headers
+ // on the server.
+ uint8_t GetExpectedServerConnectionIdLength() {
+ return expected_server_connection_id_length_;
+ }
+
+ // Change the expected destination connection ID length for short headers on
+ // the client.
+ void SetExpectedClientConnectionIdLength(
+ uint8_t expected_client_connection_id_length) {
+ expected_client_connection_id_length_ =
+ expected_client_connection_id_length;
}
void EnableMultiplePacketNumberSpacesSupport();
@@ -715,8 +726,9 @@
static bool ProcessAndValidateIetfConnectionIdLength(
QuicDataReader* reader,
ParsedQuicVersion version,
- bool should_update_expected_connection_id_length,
- uint8_t* expected_connection_id_length,
+ Perspective perspective,
+ bool should_update_expected_server_connection_id_length,
+ uint8_t* expected_server_connection_id_length,
uint8_t* destination_connection_id_length,
uint8_t* source_connection_id_length,
std::string* detailed_error);
@@ -958,8 +970,10 @@
// Largest successfully decrypted packet number per packet number space. Only
// used when supports_multiple_packet_number_spaces_ is true.
QuicPacketNumber largest_decrypted_packet_numbers_[NUM_PACKET_NUMBER_SPACES];
- // Updated by WritePacketHeader.
- QuicConnectionId last_serialized_connection_id_;
+ // Last server connection ID seen on the wire.
+ QuicConnectionId last_serialized_server_connection_id_;
+ // Last client connection ID seen on the wire.
+ QuicConnectionId last_serialized_client_connection_id_;
// The last QUIC version label received.
// TODO(fayang): Remove this when deprecating
// quic_no_framer_object_in_dispatcher.
@@ -1014,18 +1028,18 @@
bool infer_packet_header_type_from_version_;
// IETF short headers contain a destination connection ID but do not
- // encode its length. This variable contains the length we expect to read.
- // This is also used to validate the long header connection ID lengths in
- // older versions of QUIC.
- // TODO(fayang): Remove this when deprecating
- // quic_no_framer_object_in_dispatcher.
- uint8_t expected_connection_id_length_;
+ // encode its length. These variables contains the length we expect to read.
+ // This is also used to validate the long header destination connection ID
+ // lengths in older versions of QUIC.
+ uint8_t expected_server_connection_id_length_;
+ uint8_t expected_client_connection_id_length_;
- // When this is true, QuicFramer will change expected_connection_id_length_
- // to the received destination connection ID length of all IETF long headers.
+ // When this is true, QuicFramer will change
+ // expected_server_connection_id_length_ to the received destination
+ // connection ID length of all IETF long headers.
// TODO(fayang): Remove this when deprecating
// quic_no_framer_object_in_dispatcher.
- bool should_update_expected_connection_id_length_;
+ bool should_update_expected_server_connection_id_length_;
// Indicates whether this framer supports multiple packet number spaces.
bool supports_multiple_packet_number_spaces_;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index bf87ace..5f46e8e 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -916,18 +916,17 @@
PacketHeaderFormat format;
bool version_flag;
- uint8_t destination_connection_id_length;
- QuicConnectionId destination_connection_id;
+ QuicConnectionId destination_connection_id, source_connection_id;
QuicVersionLabel version_label;
std::string detailed_error;
- EXPECT_EQ(QUIC_NO_ERROR, QuicFramer::ProcessPacketDispatcher(
- *encrypted, kQuicDefaultConnectionIdLength,
- &format, &version_flag, &version_label,
- &destination_connection_id_length,
- &destination_connection_id, &detailed_error));
+ EXPECT_EQ(QUIC_NO_ERROR,
+ QuicFramer::ProcessPacketDispatcher(
+ *encrypted, kQuicDefaultConnectionIdLength, &format,
+ &version_flag, &version_label, &destination_connection_id,
+ &source_connection_id, &detailed_error));
EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
EXPECT_FALSE(version_flag);
- EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id_length);
+ EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
}
@@ -994,25 +993,24 @@
PacketHeaderFormat format;
bool version_flag;
- uint8_t destination_connection_id_length;
- QuicConnectionId destination_connection_id;
+ QuicConnectionId destination_connection_id, source_connection_id;
QuicVersionLabel version_label;
std::string detailed_error;
- EXPECT_EQ(QUIC_NO_ERROR, QuicFramer::ProcessPacketDispatcher(
- *encrypted, kQuicDefaultConnectionIdLength,
- &format, &version_flag, &version_label,
- &destination_connection_id_length,
- &destination_connection_id, &detailed_error));
+ EXPECT_EQ(QUIC_NO_ERROR,
+ QuicFramer::ProcessPacketDispatcher(
+ *encrypted, kQuicDefaultConnectionIdLength, &format,
+ &version_flag, &version_label, &destination_connection_id,
+ &source_connection_id, &detailed_error));
EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
EXPECT_TRUE(version_flag);
- EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id_length);
+ EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
}
TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
- QuicFramerPeer::SetLastSerializedConnectionId(&framer_,
- FramerTestConnectionId());
+ QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+ FramerTestConnectionId());
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
// clang-format off
@@ -6626,7 +6624,8 @@
QuicConnectionId connection_id = FramerTestConnectionId();
std::unique_ptr<QuicEncryptedPacket> data(
framer_.BuildVersionNegotiationPacket(
- connection_id, framer_.transport_version() > QUIC_VERSION_43,
+ connection_id, EmptyQuicConnectionId(),
+ framer_.transport_version() > QUIC_VERSION_43,
SupportedVersions(GetParam())));
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p), p_size);
@@ -13182,8 +13181,8 @@
QuicConnectionId connection_id(connection_id_bytes,
sizeof(connection_id_bytes));
QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
- QuicFramerPeer::SetExpectedConnectionIDLength(&framer_,
- connection_id.length());
+ QuicFramerPeer::SetExpectedServerConnectionIDLength(&framer_,
+ connection_id.length());
// clang-format off
PacketFragments packet = {
@@ -13320,8 +13319,7 @@
PacketHeaderFormat format;
bool version_flag;
- uint8_t destination_connection_id_length;
- QuicConnectionId destination_connection_id;
+ QuicConnectionId destination_connection_id, source_connection_id;
QuicVersionLabel version_label;
std::string detailed_error;
EXPECT_EQ(QUIC_NO_ERROR,
@@ -13329,21 +13327,21 @@
QuicEncryptedPacket(AsChars(long_header_packet),
QUIC_ARRAYSIZE(long_header_packet)),
kQuicDefaultConnectionIdLength, &format, &version_flag,
- &version_label, &destination_connection_id_length,
- &destination_connection_id, &detailed_error));
+ &version_label, &destination_connection_id,
+ &source_connection_id, &detailed_error));
EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
EXPECT_TRUE(version_flag);
- EXPECT_EQ(9, destination_connection_id_length);
+ EXPECT_EQ(9, destination_connection_id.length());
EXPECT_EQ(FramerTestConnectionIdNineBytes(), destination_connection_id);
- EXPECT_EQ(QUIC_NO_ERROR,
- QuicFramer::ProcessPacketDispatcher(
- short_header_encrypted, 9, &format, &version_flag,
- &version_label, &destination_connection_id_length,
- &destination_connection_id, &detailed_error));
+ EXPECT_EQ(
+ QUIC_NO_ERROR,
+ QuicFramer::ProcessPacketDispatcher(
+ short_header_encrypted, 9, &format, &version_flag, &version_label,
+ &destination_connection_id, &source_connection_id, &detailed_error));
EXPECT_EQ(IETF_QUIC_SHORT_HEADER_PACKET, format);
EXPECT_FALSE(version_flag);
- EXPECT_EQ(9, destination_connection_id_length);
+ EXPECT_EQ(9, destination_connection_id.length());
EXPECT_EQ(FramerTestConnectionIdNineBytes(), destination_connection_id);
}
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index c013ce8..47af951 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -53,15 +53,15 @@
#define ENDPOINT \
(framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QuicFramer* framer,
DelegateInterface* delegate)
- : QuicPacketCreator(connection_id,
+ : QuicPacketCreator(server_connection_id,
framer,
QuicRandom::GetInstance(),
delegate) {}
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QuicFramer* framer,
QuicRandom* random,
DelegateInterface* delegate)
@@ -72,9 +72,10 @@
send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
have_diversification_nonce_(false),
max_packet_length_(0),
- connection_id_included_(CONNECTION_ID_PRESENT),
+ server_connection_id_included_(CONNECTION_ID_PRESENT),
packet_size_(0),
- connection_id_(connection_id),
+ server_connection_id_(server_connection_id),
+ client_connection_id_(EmptyQuicConnectionId()),
packet_(QuicPacketNumber(),
PACKET_1BYTE_PACKET_NUMBER,
nullptr,
@@ -626,8 +627,9 @@
const ParsedQuicVersionVector& supported_versions) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
std::unique_ptr<QuicEncryptedPacket> encrypted =
- QuicFramer::BuildVersionNegotiationPacket(connection_id_, ietf_quic,
- supported_versions);
+ QuicFramer::BuildVersionNegotiationPacket(server_connection_id_,
+ client_connection_id_,
+ ietf_quic, supported_versions);
DCHECK(encrypted);
DCHECK_GE(max_packet_length_, encrypted->length());
return encrypted;
@@ -737,24 +739,24 @@
QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
- return connection_id_;
+ return server_connection_id_;
}
QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 1, 5);
if (framer_->perspective() == Perspective::IS_SERVER) {
- return EmptyQuicConnectionId();
+ return client_connection_id_;
}
- return connection_id_;
+ return server_connection_id_;
}
QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
- return connection_id_;
+ return server_connection_id_;
}
QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 6, 6);
if (framer_->perspective() == Perspective::IS_CLIENT) {
- return EmptyQuicConnectionId();
+ return client_connection_id_;
}
- return connection_id_;
+ return server_connection_id_;
}
QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
@@ -763,30 +765,33 @@
GetQuicRestartFlag(quic_do_not_override_connection_id)) {
// Packets sent by client always include destination connection ID, and
// those sent by the server do not include destination connection ID.
- return framer_->perspective() == Perspective::IS_CLIENT
+ return (framer_->perspective() == Perspective::IS_CLIENT ||
+ framer_->version().SupportsClientConnectionIds())
? CONNECTION_ID_PRESENT
: CONNECTION_ID_ABSENT;
}
- return connection_id_included_;
+ return server_connection_id_included_;
}
QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
const {
// Long header packets sent by server include source connection ID.
- if (HasIetfLongHeader() && framer_->perspective() == Perspective::IS_SERVER) {
+ if (HasIetfLongHeader() &&
+ (framer_->perspective() == Perspective::IS_SERVER ||
+ framer_->version().SupportsClientConnectionIds())) {
return CONNECTION_ID_PRESENT;
}
if (GetQuicRestartFlag(quic_do_not_override_connection_id) &&
framer_->perspective() == Perspective::IS_SERVER) {
QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 2, 5);
- return connection_id_included_;
+ return server_connection_id_included_;
}
return CONNECTION_ID_ABSENT;
}
QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
const {
- DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
+ DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
transport_version()));
return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
? static_cast<QuicConnectionIdLength>(
@@ -795,7 +800,7 @@
}
QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
- DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
+ DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
transport_version()));
return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
? static_cast<QuicConnectionIdLength>(
@@ -1019,17 +1024,25 @@
return packet_.encryption_level == ENCRYPTION_INITIAL;
}
-void QuicPacketCreator::SetConnectionIdIncluded(
- QuicConnectionIdIncluded connection_id_included) {
- DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
- connection_id_included == CONNECTION_ID_ABSENT);
+void QuicPacketCreator::SetServerConnectionIdIncluded(
+ QuicConnectionIdIncluded server_connection_id_included) {
+ DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
+ server_connection_id_included == CONNECTION_ID_ABSENT);
DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
- connection_id_included != CONNECTION_ID_ABSENT);
- connection_id_included_ = connection_id_included;
+ server_connection_id_included != CONNECTION_ID_ABSENT);
+ server_connection_id_included_ = server_connection_id_included;
}
-void QuicPacketCreator::SetConnectionId(QuicConnectionId connection_id) {
- connection_id_ = connection_id;
+void QuicPacketCreator::SetServerConnectionId(
+ QuicConnectionId server_connection_id) {
+ server_connection_id_ = server_connection_id;
+}
+
+void QuicPacketCreator::SetClientConnectionId(
+ QuicConnectionId client_connection_id) {
+ DCHECK(client_connection_id.IsEmpty() ||
+ framer_->version().SupportsClientConnectionIds());
+ client_connection_id_ = client_connection_id;
}
void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
index 6e1f7a2..b666f71 100644
--- a/quic/core/quic_packet_creator.h
+++ b/quic/core/quic_packet_creator.h
@@ -56,10 +56,10 @@
virtual void OnFrameAddedToPacket(const QuicFrame& frame) {}
};
- QuicPacketCreator(QuicConnectionId connection_id,
+ QuicPacketCreator(QuicConnectionId server_connection_id,
QuicFramer* framer,
DelegateInterface* delegate);
- QuicPacketCreator(QuicConnectionId connection_id,
+ QuicPacketCreator(QuicConnectionId server_connection_id,
QuicFramer* framer,
QuicRandom* random,
DelegateInterface* delegate);
@@ -222,11 +222,15 @@
// Returns length of source connection ID to send over the wire.
QuicConnectionIdLength GetSourceConnectionIdLength() const;
- // Sets whether the connection ID should be sent over the wire.
- void SetConnectionIdIncluded(QuicConnectionIdIncluded connection_id_included);
+ // Sets whether the server connection ID should be sent over the wire.
+ void SetServerConnectionIdIncluded(
+ QuicConnectionIdIncluded server_connection_id_included);
- // Update the connection ID used in outgoing packets.
- void SetConnectionId(QuicConnectionId connection_id);
+ // Update the server connection ID used in outgoing packets.
+ void SetServerConnectionId(QuicConnectionId server_connection_id);
+
+ // Update the client connection ID used in outgoing packets.
+ void SetClientConnectionId(QuicConnectionId client_connection_id);
// Sets the encryption level that will be applied to new packets.
void set_encryption_level(EncryptionLevel level) {
@@ -393,8 +397,8 @@
// Maximum length including headers and encryption (UDP payload length.)
QuicByteCount max_packet_length_;
size_t max_plaintext_size_;
- // Whether the connection_id is sent over the wire.
- QuicConnectionIdIncluded connection_id_included_;
+ // Whether the server_connection_id is sent over the wire.
+ QuicConnectionIdIncluded server_connection_id_included_;
// Frames to be added to the next SerializedPacket
QuicFrames queued_frames_;
@@ -403,7 +407,8 @@
// TODO(ianswett): Move packet_size_ into SerializedPacket once
// QuicEncryptedPacket has been flattened into SerializedPacket.
size_t packet_size_;
- QuicConnectionId connection_id_;
+ QuicConnectionId server_connection_id_;
+ QuicConnectionId client_connection_id_;
// Packet used to invoke OnSerializedPacket.
SerializedPacket packet_;
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc
index d811f9d..766f8ca 100644
--- a/quic/core/quic_packet_generator.cc
+++ b/quic/core/quic_packet_generator.cc
@@ -17,12 +17,12 @@
namespace quic {
-QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
+QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId server_connection_id,
QuicFramer* framer,
QuicRandom* random_generator,
DelegateInterface* delegate)
: delegate_(delegate),
- packet_creator_(connection_id, framer, random_generator, delegate),
+ packet_creator_(server_connection_id, framer, random_generator, delegate),
next_transmission_type_(NOT_RETRANSMISSION),
flusher_attached_(false),
should_send_ack_(false),
@@ -438,11 +438,11 @@
max_packets_in_flight);
}
-void QuicPacketGenerator::SetConnectionIdLength(uint32_t length) {
+void QuicPacketGenerator::SetServerConnectionIdLength(uint32_t length) {
if (length == 0) {
- packet_creator_.SetConnectionIdIncluded(CONNECTION_ID_ABSENT);
+ packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
} else {
- packet_creator_.SetConnectionIdIncluded(CONNECTION_ID_PRESENT);
+ packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
}
}
@@ -569,8 +569,14 @@
return packet_creator_.GetGuaranteedLargestMessagePayload();
}
-void QuicPacketGenerator::SetConnectionId(QuicConnectionId connection_id) {
- packet_creator_.SetConnectionId(connection_id);
+void QuicPacketGenerator::SetServerConnectionId(
+ QuicConnectionId server_connection_id) {
+ packet_creator_.SetServerConnectionId(server_connection_id);
+}
+
+void QuicPacketGenerator::SetClientConnectionId(
+ QuicConnectionId client_connection_id) {
+ packet_creator_.SetClientConnectionId(client_connection_id);
}
} // namespace quic
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h
index 417fda6..ec25550 100644
--- a/quic/core/quic_packet_generator.h
+++ b/quic/core/quic_packet_generator.h
@@ -76,7 +76,7 @@
QuicStopWaitingFrame* stop_waiting) = 0;
};
- QuicPacketGenerator(QuicConnectionId connection_id,
+ QuicPacketGenerator(QuicConnectionId server_connection_id,
QuicFramer* framer,
QuicRandom* random_generator,
DelegateInterface* delegate);
@@ -185,8 +185,8 @@
void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
QuicPacketCount max_packets_in_flight);
- // Set the minimum number of bytes for the connection id length;
- void SetConnectionIdLength(uint32_t length);
+ // Set the minimum number of bytes for the server connection id length;
+ void SetServerConnectionIdLength(uint32_t length);
// Sets the encrypter to use for the encryption level.
void SetEncrypter(EncryptionLevel level,
@@ -235,8 +235,11 @@
QuicPacketLength GetCurrentLargestMessagePayload() const;
QuicPacketLength GetGuaranteedLargestMessagePayload() const;
- // Update the connection ID used in outgoing packets.
- void SetConnectionId(QuicConnectionId connection_id);
+ // Update the server connection ID used in outgoing packets.
+ void SetServerConnectionId(QuicConnectionId server_connection_id);
+
+ // Update the client connection ID used in outgoing packets.
+ void SetClientConnectionId(QuicConnectionId client_connection_id);
void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) {
packet_creator_.set_debug_delegate(debug_delegate);
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 676d6e7..e1899ff 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -1139,12 +1139,12 @@
TEST_F(QuicPacketGeneratorTest, TestConnectionIdLength) {
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
- generator_.SetConnectionIdLength(0);
+ generator_.SetServerConnectionIdLength(0);
EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
creator_->GetDestinationConnectionIdLength());
for (size_t i = 1; i < 10; i++) {
- generator_.SetConnectionIdLength(i);
+ generator_.SetServerConnectionIdLength(i);
if (framer_.transport_version() > QUIC_VERSION_43) {
EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
creator_->GetDestinationConnectionIdLength());
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
index 57bda54..738cc6e 100644
--- a/quic/core/quic_packets.cc
+++ b/quic/core/quic_packets.cc
@@ -27,6 +27,16 @@
return header.source_connection_id;
}
+QuicConnectionId GetClientConnectionIdAsRecipient(
+ const QuicPacketHeader& header,
+ Perspective perspective) {
+ DCHECK(GetQuicRestartFlag(quic_do_not_override_connection_id));
+ if (perspective == Perspective::IS_CLIENT) {
+ return header.destination_connection_id;
+ }
+ return header.source_connection_id;
+}
+
QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
Perspective perspective) {
if (perspective == Perspective::IS_CLIENT ||
@@ -48,6 +58,16 @@
return header.source_connection_id_included;
}
+QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+ Perspective perspective) {
+ if (perspective == Perspective::IS_CLIENT ||
+ !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+ return header.source_connection_id;
+ }
+ QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 3, 5);
+ return header.destination_connection_id;
+}
+
QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
const QuicPacketHeader& header,
Perspective perspective) {
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h
index d3c2600..b1964e7 100644
--- a/quic/core/quic_packets.h
+++ b/quic/core/quic_packets.h
@@ -41,6 +41,12 @@
// Returns the destination connection ID of |header| when |perspective| is
// client, and the source connection ID when |perspective| is server.
QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsRecipient(const QuicPacketHeader& header,
+ Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
GetServerConnectionIdAsSender(const QuicPacketHeader& header,
Perspective perspective);
@@ -51,6 +57,12 @@
GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
Perspective perspective);
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+ Perspective perspective);
+
// Returns the destination connection ID included of |header| when |perspective|
// is server, and the source connection ID included when |perspective| is
// client.
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index d8f40c9..dc7153a 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -52,7 +52,7 @@
virtual ~Visitor() {}
// Called when the connection is closed after the streams have been closed.
- virtual void OnConnectionClosed(QuicConnectionId connection_id,
+ virtual void OnConnectionClosed(QuicConnectionId server_connection_id,
QuicErrorCode error,
const std::string& error_details,
ConnectionCloseSource source) = 0;
diff --git a/quic/core/quic_time_wait_list_manager.cc b/quic/core/quic_time_wait_list_manager.cc
index fa62fc5..d646f41 100644
--- a/quic/core/quic_time_wait_list_manager.cc
+++ b/quic/core/quic_time_wait_list_manager.cc
@@ -200,7 +200,8 @@
}
void QuicTimeWaitListManager::SendVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& self_address,
@@ -209,7 +210,8 @@
SendOrQueuePacket(QuicMakeUnique<QueuedPacket>(
self_address, peer_address,
QuicFramer::BuildVersionNegotiationPacket(
- connection_id, ietf_quic, supported_versions)),
+ server_connection_id, client_connection_id,
+ ietf_quic, supported_versions)),
packet_context.get());
}
diff --git a/quic/core/quic_time_wait_list_manager.h b/quic/core/quic_time_wait_list_manager.h
index dee5d11..26e894d 100644
--- a/quic/core/quic_time_wait_list_manager.h
+++ b/quic/core/quic_time_wait_list_manager.h
@@ -121,7 +121,8 @@
// Sends a version negotiation packet for |connection_id| announcing support
// for |supported_versions| to |peer_address| from |self_address|.
virtual void SendVersionNegotiationPacket(
- QuicConnectionId connection_id,
+ QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& self_address,
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc
index a391390..c1dadba 100644
--- a/quic/core/quic_time_wait_list_manager_test.cc
+++ b/quic/core/quic_time_wait_list_manager_test.cc
@@ -251,15 +251,16 @@
TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(connection_id_, false,
+ QuicFramer::BuildVersionNegotiationPacket(connection_id_,
+ EmptyQuicConnectionId(), false,
AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
peer_address_, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, false, AllSupportedVersions(), self_address_,
- peer_address_, QuicMakeUnique<QuicPerPacketContext>());
+ connection_id_, EmptyQuicConnectionId(), false, AllSupportedVersions(),
+ self_address_, peer_address_, QuicMakeUnique<QuicPerPacketContext>());
EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
}
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index a1f4d8e..ed493a5 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -55,6 +55,16 @@
return transport_version > QUIC_VERSION_46;
}
+bool ParsedQuicVersion::SupportsClientConnectionIds() const {
+ if (!GetQuicRestartFlag(quic_do_not_override_connection_id)) {
+ // Do not enable this feature in a production version until this flag has
+ // been deprecated.
+ return false;
+ }
+ return transport_version >= QUIC_VERSION_99 ||
+ transport_version == QUIC_VERSION_UNSUPPORTED;
+}
+
std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
os << ParsedQuicVersionToString(version);
return os;
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 7853134..1f6a431 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -162,6 +162,9 @@
// Returns whether this version supports IETF RETRY packets.
bool SupportsRetry() const;
+
+ // Returns whether this version supports client connection ID.
+ bool SupportsClientConnectionIds() const;
};
QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
diff --git a/quic/quartc/quartc_dispatcher.cc b/quic/quartc/quartc_dispatcher.cc
index fd4f289..091d56b 100644
--- a/quic/quartc/quartc_dispatcher.cc
+++ b/quic/quartc/quartc_dispatcher.cc
@@ -39,7 +39,7 @@
// Allow incoming packets to set our expected connection ID length.
SetShouldUpdateExpectedConnectionIdLength(true);
// Allow incoming packets with connection ID lengths shorter than allowed.
- SetAllowShortInitialConnectionIds(true);
+ SetAllowShortInitialServerConnectionIds(true);
// QuicDispatcher takes ownership of the writer.
QuicDispatcher::InitializeWithWriter(packet_writer.release());
// NB: This must happen *after* InitializeWithWriter. It can call us back
diff --git a/quic/quartc/quartc_dispatcher.h b/quic/quartc/quartc_dispatcher.h
index 26b52ac..239b6ef 100644
--- a/quic/quartc/quartc_dispatcher.h
+++ b/quic/quartc/quartc_dispatcher.h
@@ -41,7 +41,7 @@
Delegate* delegate);
~QuartcDispatcher() override;
- QuartcSession* CreateQuicSession(QuicConnectionId connection_id,
+ QuartcSession* CreateQuicSession(QuicConnectionId server_connection_id,
const QuicSocketAddress& client_address,
QuicStringPiece alpn,
const ParsedQuicVersion& version) override;
diff --git a/quic/test_tools/mock_quic_time_wait_list_manager.h b/quic/test_tools/mock_quic_time_wait_list_manager.h
index d13d5ac..8a39442 100644
--- a/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ b/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -45,8 +45,9 @@
PacketHeaderFormat header_format,
std::unique_ptr<QuicPerPacketContext> packet_context));
- MOCK_METHOD6(SendVersionNegotiationPacket,
- void(QuicConnectionId connection_id,
+ MOCK_METHOD7(SendVersionNegotiationPacket,
+ void(QuicConnectionId server_connection_id,
+ QuicConnectionId client_connection_id,
bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
diff --git a/quic/test_tools/quic_framer_peer.cc b/quic/test_tools/quic_framer_peer.cc
index 23486ea..6eedd60 100644
--- a/quic/test_tools/quic_framer_peer.cc
+++ b/quic/test_tools/quic_framer_peer.cc
@@ -22,10 +22,10 @@
}
// static
-void QuicFramerPeer::SetLastSerializedConnectionId(
+void QuicFramerPeer::SetLastSerializedServerConnectionId(
QuicFramer* framer,
- QuicConnectionId connection_id) {
- framer->last_serialized_connection_id_ = connection_id;
+ QuicConnectionId server_connection_id) {
+ framer->last_serialized_server_connection_id_ = server_connection_id;
}
// static
@@ -337,11 +337,11 @@
}
// static
-void QuicFramerPeer::SetExpectedConnectionIDLength(
+void QuicFramerPeer::SetExpectedServerConnectionIDLength(
QuicFramer* framer,
- uint8_t expected_connection_id_length) {
- *const_cast<uint8_t*>(&framer->expected_connection_id_length_) =
- expected_connection_id_length;
+ uint8_t expected_server_connection_id_length) {
+ *const_cast<uint8_t*>(&framer->expected_server_connection_id_length_) =
+ expected_server_connection_id_length;
}
// static
diff --git a/quic/test_tools/quic_framer_peer.h b/quic/test_tools/quic_framer_peer.h
index 4a5efa6..0b17c19 100644
--- a/quic/test_tools/quic_framer_peer.h
+++ b/quic/test_tools/quic_framer_peer.h
@@ -22,8 +22,9 @@
QuicPacketNumberLength packet_number_length,
QuicPacketNumber last_packet_number,
uint64_t packet_number);
- static void SetLastSerializedConnectionId(QuicFramer* framer,
- QuicConnectionId connection_id);
+ static void SetLastSerializedServerConnectionId(
+ QuicFramer* framer,
+ QuicConnectionId server_connection_id);
static void SetLargestPacketNumber(QuicFramer* framer,
QuicPacketNumber packet_number);
static void SetPerspective(QuicFramer* framer, Perspective perspective);
@@ -159,9 +160,9 @@
QuicPacketNumberLength packet_number_length);
static void SetFirstSendingPacketNumber(QuicFramer* framer,
uint64_t packet_number);
- static void SetExpectedConnectionIDLength(
+ static void SetExpectedServerConnectionIDLength(
QuicFramer* framer,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
static QuicPacketNumber GetLargestDecryptedPacketNumber(
QuicFramer* framer,
PacketNumberSpace packet_number_space);
diff --git a/quic/test_tools/quic_test_client.cc b/quic/test_tools/quic_test_client.cc
index 497dd8a..a290e7d 100644
--- a/quic/test_tools/quic_test_client.cc
+++ b/quic/test_tools/quic_test_client.cc
@@ -209,8 +209,10 @@
this),
QuicWrapUnique(
new RecordingProofVerifier(std::move(proof_verifier)))),
- override_connection_id_(EmptyQuicConnectionId()),
- connection_id_overridden_(false) {}
+ override_server_connection_id_(EmptyQuicConnectionId()),
+ server_connection_id_overridden_(false),
+ override_client_connection_id_(EmptyQuicConnectionId()),
+ client_connection_id_overridden_(false) {}
MockableQuicClient::~MockableQuicClient() {
if (connected()) {
@@ -231,13 +233,26 @@
}
QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
- return connection_id_overridden_ ? override_connection_id_
- : QuicClient::GenerateNewConnectionId();
+ return server_connection_id_overridden_
+ ? override_server_connection_id_
+ : QuicClient::GenerateNewConnectionId();
}
-void MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) {
- connection_id_overridden_ = true;
- override_connection_id_ = connection_id;
+void MockableQuicClient::UseConnectionId(
+ QuicConnectionId server_connection_id) {
+ server_connection_id_overridden_ = true;
+ override_server_connection_id_ = server_connection_id;
+}
+
+QuicConnectionId MockableQuicClient::GetClientConnectionId() {
+ return client_connection_id_overridden_ ? override_client_connection_id_
+ : QuicClient::GetClientConnectionId();
+}
+
+void MockableQuicClient::UseClientConnectionId(
+ QuicConnectionId client_connection_id) {
+ client_connection_id_overridden_ = true;
+ override_client_connection_id_ = client_connection_id;
}
void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
@@ -759,9 +774,15 @@
client_->UseWriter(writer);
}
-void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
+void QuicTestClient::UseConnectionId(QuicConnectionId server_connection_id) {
DCHECK(!connected());
- client_->UseConnectionId(connection_id);
+ client_->UseConnectionId(server_connection_id);
+}
+
+void QuicTestClient::UseClientConnectionId(
+ QuicConnectionId client_connection_id) {
+ DCHECK(!connected());
+ client_->UseClientConnectionId(client_connection_id);
}
bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
diff --git a/quic/test_tools/quic_test_client.h b/quic/test_tools/quic_test_client.h
index 353c29e..5f1b6fa 100644
--- a/quic/test_tools/quic_test_client.h
+++ b/quic/test_tools/quic_test_client.h
@@ -55,7 +55,9 @@
~MockableQuicClient() override;
QuicConnectionId GenerateNewConnectionId() override;
- void UseConnectionId(QuicConnectionId connection_id);
+ void UseConnectionId(QuicConnectionId server_connection_id);
+ QuicConnectionId GetClientConnectionId() override;
+ void UseClientConnectionId(QuicConnectionId client_connection_id);
void UseWriter(QuicPacketWriterWrapper* writer);
void set_peer_address(const QuicSocketAddress& address);
@@ -69,9 +71,12 @@
const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const;
private:
- // ConnectionId to use, if connection_id_overridden_
- QuicConnectionId override_connection_id_;
- bool connection_id_overridden_;
+ // Server connection ID to use, if server_connection_id_overridden_
+ QuicConnectionId override_server_connection_id_;
+ bool server_connection_id_overridden_;
+ // Client connection ID to use, if client_connection_id_overridden_
+ QuicConnectionId override_client_connection_id_;
+ bool client_connection_id_overridden_;
CachedNetworkParameters cached_network_paramaters_;
};
@@ -219,9 +224,12 @@
// Configures client_ to take ownership of and use the writer.
// Must be called before initial connect.
void UseWriter(QuicPacketWriterWrapper* writer);
- // If the given ConnectionId is nonzero, configures client_ to use a specific
- // ConnectionId instead of a random one.
- void UseConnectionId(QuicConnectionId connection_id);
+ // Configures client_ to use a specific server connection ID instead of a
+ // random one.
+ void UseConnectionId(QuicConnectionId server_connection_id);
+ // Configures client_ to use a specific client connection ID instead of an
+ // empty one.
+ void UseClientConnectionId(QuicConnectionId client_connection_id);
// Returns nullptr if the maximum number of streams have already been created.
QuicSpdyClientStream* GetOrCreateStream();
diff --git a/quic/test_tools/quic_test_server.cc b/quic/test_tools/quic_test_server.cc
index bda2148..68c500e 100644
--- a/quic/test_tools/quic_test_server.cc
+++ b/quic/test_tools/quic_test_server.cc
@@ -77,7 +77,7 @@
std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: QuicSimpleDispatcher(config,
crypto_config,
version_manager,
@@ -85,7 +85,7 @@
std::move(session_helper),
std::move(alarm_factory),
quic_simple_server_backend,
- expected_connection_id_length),
+ expected_server_connection_id_length),
session_factory_(nullptr),
stream_factory_(nullptr),
crypto_stream_factory_(nullptr) {}
@@ -170,13 +170,13 @@
const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: QuicServer(std::move(proof_source),
config,
QuicCryptoServerConfig::ConfigOptions(),
supported_versions,
quic_simple_server_backend,
- expected_connection_id_length) {}
+ expected_server_connection_id_length) {}
QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
return new QuicTestDispatcher(
@@ -186,7 +186,7 @@
std::unique_ptr<QuicCryptoServerStream::Helper>(
new QuicSimpleCryptoServerStreamHelper(QuicRandom::GetInstance())),
QuicMakeUnique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
- expected_connection_id_length());
+ expected_server_connection_id_length());
}
void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
diff --git a/quic/test_tools/quic_test_server.h b/quic/test_tools/quic_test_server.h
index 52fb7c5..3661b7a 100644
--- a/quic/test_tools/quic_test_server.h
+++ b/quic/test_tools/quic_test_server.h
@@ -69,7 +69,7 @@
const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
// Create a custom dispatcher which creates custom sessions.
QuicDispatcher* CreateQuicDispatcher() override;
diff --git a/quic/tools/quic_client_base.cc b/quic/tools/quic_client_base.cc
index 57cbd9a..fd4776f 100644
--- a/quic/tools/quic_client_base.cc
+++ b/quic/tools/quic_client_base.cc
@@ -135,6 +135,7 @@
can_reconnect_with_different_version
? ParsedQuicVersionVector{mutual_version}
: supported_versions()));
+ session()->connection()->set_client_connection_id(GetClientConnectionId());
if (initial_max_packet_length_ != 0) {
session()->connection()->SetMaxPacketLength(initial_max_packet_length_);
}
@@ -333,6 +334,10 @@
return QuicUtils::CreateRandomConnectionId();
}
+QuicConnectionId QuicClientBase::GetClientConnectionId() {
+ return EmptyQuicConnectionId();
+}
+
bool QuicClientBase::CanReconnectWithDifferentVersion(
ParsedQuicVersion* version) const {
if (session_ == nullptr || session_->connection() == nullptr ||
diff --git a/quic/tools/quic_client_base.h b/quic/tools/quic_client_base.h
index 0cc4d71..134404b 100644
--- a/quic/tools/quic_client_base.h
+++ b/quic/tools/quic_client_base.h
@@ -268,6 +268,9 @@
// connection ID).
virtual QuicConnectionId GenerateNewConnectionId();
+ // Returns the client connection ID to use.
+ virtual QuicConnectionId GetClientConnectionId();
+
QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
// Subclasses may need to explicitly clear the session on destruction
diff --git a/quic/tools/quic_server.cc b/quic/tools/quic_server.cc
index 4ac1dac..3696b7c 100644
--- a/quic/tools/quic_server.cc
+++ b/quic/tools/quic_server.cc
@@ -64,7 +64,7 @@
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
const ParsedQuicVersionVector& supported_versions,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: port_(0),
fd_(-1),
packets_dropped_(0),
@@ -80,7 +80,8 @@
version_manager_(supported_versions),
packet_reader_(new QuicPacketReader()),
quic_simple_server_backend_(quic_simple_server_backend),
- expected_connection_id_length_(expected_connection_id_length) {
+ expected_server_connection_id_length_(
+ expected_server_connection_id_length) {
DCHECK(quic_simple_server_backend_);
Initialize();
}
@@ -159,7 +160,7 @@
new QuicSimpleCryptoServerStreamHelper(QuicRandom::GetInstance())),
std::unique_ptr<QuicEpollAlarmFactory>(
new QuicEpollAlarmFactory(&epoll_server_)),
- quic_simple_server_backend_, expected_connection_id_length_);
+ quic_simple_server_backend_, expected_server_connection_id_length_);
}
void QuicServer::HandleEventsForever() {
diff --git a/quic/tools/quic_server.h b/quic/tools/quic_server.h
index 6fb1646..1f9c225 100644
--- a/quic/tools/quic_server.h
+++ b/quic/tools/quic_server.h
@@ -43,7 +43,7 @@
const QuicCryptoServerConfig::ConfigOptions& server_config_options,
const ParsedQuicVersionVector& supported_versions,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
QuicServer(const QuicServer&) = delete;
QuicServer& operator=(const QuicServer&) = delete;
@@ -103,8 +103,8 @@
void set_silent_close(bool value) { silent_close_ = value; }
- uint8_t expected_connection_id_length() {
- return expected_connection_id_length_;
+ uint8_t expected_server_connection_id_length() {
+ return expected_server_connection_id_length_;
}
private:
@@ -155,7 +155,7 @@
QuicSimpleServerBackend* quic_simple_server_backend_; // unowned.
// Connection ID length expected to be read on incoming IETF short headers.
- uint8_t expected_connection_id_length_;
+ uint8_t expected_server_connection_id_length_;
};
} // namespace quic
diff --git a/quic/tools/quic_simple_dispatcher.cc b/quic/tools/quic_simple_dispatcher.cc
index 4706b60..0f4d447 100644
--- a/quic/tools/quic_simple_dispatcher.cc
+++ b/quic/tools/quic_simple_dispatcher.cc
@@ -16,14 +16,14 @@
std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length)
+ uint8_t expected_server_connection_id_length)
: QuicDispatcher(config,
crypto_config,
version_manager,
std::move(helper),
std::move(session_helper),
std::move(alarm_factory),
- expected_connection_id_length),
+ expected_server_connection_id_length),
quic_simple_server_backend_(quic_simple_server_backend) {}
QuicSimpleDispatcher::~QuicSimpleDispatcher() = default;
diff --git a/quic/tools/quic_simple_dispatcher.h b/quic/tools/quic_simple_dispatcher.h
index 46d976c..8a6cf85 100644
--- a/quic/tools/quic_simple_dispatcher.h
+++ b/quic/tools/quic_simple_dispatcher.h
@@ -21,7 +21,7 @@
std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
QuicSimpleServerBackend* quic_simple_server_backend,
- uint8_t expected_connection_id_length);
+ uint8_t expected_server_connection_id_length);
~QuicSimpleDispatcher() override;