diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-26 14:51:56 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-26 14:51:56 +0000 |
commit | 48878097c79f472be47c9c518bd07041762af6c1 (patch) | |
tree | b3b8f0adb99d2bf9356917c4ca9fed4daa2f3a9a /net/tools | |
parent | 581ec2af841f60e4a36fdee26013c2ada2933c70 (diff) | |
download | chromium_src-48878097c79f472be47c9c518bd07041762af6c1.zip chromium_src-48878097c79f472be47c9c518bd07041762af6c1.tar.gz chromium_src-48878097c79f472be47c9c518bd07041762af6c1.tar.bz2 |
Land Recent QUIC changes.
Implemented RTO calculation for TCP sender.
Merge internal change: 49182038
Introduce a different proof-demand type for ECDSA certs.
In cl/48309237, wtc enabled ECDSA certificates for QUIC. However,
Windows XP can't cope with them so we mustn't return ECDSA certs to
those clients.
The value of ECDSA over RSA in QUIC is much less than in TLS because the
server doesn't need to sign every connection. However, they are likely
to be ~192 bytes smaller, which might be useful.
This change disables ECDSA certificates for the <X509> tag and
introduces a new <X59E> tag by which the client can advertise that it
supports ECDSA certificates.
Merge internal change: 49170028
Added whitespace.
Merge internal change: 49130502
QUIC: check that encryption sequence numbers always increase.
Since sequence number reuse is causes the end of the world, check that
it never happens.
This makes me feel more warm and fuzzy.
Merge internal change: 49113162
QUIC: Send larger client hellos when hoping for certificates.
With cl/49050453, larger client hellos can get larger rejection messages.
This change causes the client to send larger client hellos when it's
likely that we'll be getting certificates. In the event that the
certificates fit in the larger space, but not the smaller one, this
saves a round trip.
Merge internal change: 49109243
QUIC: allow larger ClientHellos to get larger certificate chains.
At the moment we hope that the certificate chain compression gets the
certs down to under 400 bytes and then we feel ok about sending them in
a reply to an unverified source address.
But since we're switching to 2K certs that's basically hopeless: the
leaf certificate will have two, uncompressable blobs in it: the public
key and the signature and, for 2K, they are 256 bytes each.
This change allows a client to send a client hello with more padding and
get a larger reply to an unverified source address. What we don't want
is to become a DDoS amplifier so we make the attacker work in order to
get more from us.
Merge internal change: 49050453
QUIC: Update the common certificate set with GIAG2.
This doesn't break the protocol, but it does mean that clients with the
old certificate set won't be able to elide any certificates. But since
Chrome isn't working with QUIC HTTPS yet anyway, that's not a problem.
Merge internal change: 49050091
Modify QuicStreamSequencer::OnStreamFrame to not call ProcessRawData
with zero length data. Fixes http://crbug.com/257041
Merge internal change: 48912969
BUG=257041
Change ReliableQuicStream::OnStreamFrame to simply delegate fin
handling to the QuicStreamSequencer.
Merge internal change: 48900554
Spliting QuicPacketEntropyManager into QuicReceivedEntropyManager and
QuicSentEntropyManager, in preparation for a larger refactor to create
a ReceivedPacketManager.
Merge internal change: 48860732
Add a test to recreate the invalid ack created when an Ack is sent
immediately in response to a received ack, but the incoming ack's
corresponding headers, and hence packet entropy, has not been
processed.
Merge internal change: 48848920
Aggregate ACK and Feedback frames properly.
Existing code tried to pack acks with feedback info, and regulate
transmission of control packets. There was a bug where it sometimes
didn't pack together an ack with a feedback frame (specifically when
we were blocked from sending non-retransmittable data). There was a
second bug wherein a control frame might be prematurely serialized,
when it could *not* be sent immediately. Specifically when the control
frame was the first frame in a packet, and non-retransmittable data
could be sent, the control frame could be errantly added.
We now consistently aggregate ack frames with feedback frames in a
single packet whenever the coalescing won't delay the sending of the
just-in-time calculated frames. We now also avoid adding a control
frame into a packet unless we are sure it can be sent immediately (so
that we don't block or delay future ack and feedback transmission).
The CL includes updates to tests so that they fail with the old code,
but pass with the new code, as well as a bunch of additions to
comments. This CL is based on the Chromium CL 17341005 (which is not
landing until its merge time comes around), and resolves chromium bug
256116.
FIXED=9502307
Merge internal change: 48841932
BUG=256116
Add logging to the QUIC write path.
merge chromium CL: 17518002
Merge internal change: 48811324
Most of the changes were already in chromium except for comment change.
Fix broken test (opt mode) in cl/48802264.
Merge internal change: 48806857
Demote LOG(ERROR) to DLOG(INFO) when a client sends a packet with
unsupported version. This should not be considered an ERROR
server-side, as a client is free to send us whatever they like. We
deal with it by sending a version negotiation packet and all is well.
Updated tests, and added some comments.
Merge internal change: 48802264
Added time_wait_list_manager helper method to QuicDispatcher.
Merge internal change: 48787571
QUIC: encode the cluster in the first four bytes of the orbit value.
In order to try and measure, in Chrome, when we might have saved a round-trip
with a cluster-wide strike-register we need to know when we hit another server
in the same cluster. We could do that by IP address somewhat, but it's a little
complex and there's the /8 vs /5 between core and ....
This change causes the first four bytes of the orbit to include a hash of the
cluster (or ... rack name) so that we can easily track this in Chrome.
Merge internal change: 48784059
Fix a bug in ReliableQuicStream::OnDecompressorAvailable where a
decompression failure would result in an infinite loop.
Merge internal change: 48696905
patch from issue 20054002
Enabling ChannelId for QUIC, and passing the ChannelId header to
google backends if we're using it. Not flag protected as we're not
doing secure-quic in prod yet.
Merge internal change: 48645878
* Removed QuicTag kQuicVersion1
* Replaced this with enum QuicVersion, which currently has
QUIC_VERSION_6 and QUIC_VERSION_7
* End to end tests are run with both versions
* Framer tests are run with both versions
* QuicConnection now takes a QuicVersion parameter
* TimeWaitListManager now stores QuicVersion in the GUID map and sets
the framer version appropriately using this before sending reset
Merge internal change: 48634592
R=rch@chromium.org
Review URL: https://chromiumcodereview.appspot.com/20227003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213914 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/tools')
-rw-r--r-- | net/tools/quic/end_to_end_test.cc | 55 | ||||
-rw-r--r-- | net/tools/quic/quic_client.cc | 14 | ||||
-rw-r--r-- | net/tools/quic/quic_client.h | 16 | ||||
-rw-r--r-- | net/tools/quic/quic_client_bin.cc | 4 | ||||
-rw-r--r-- | net/tools/quic/quic_dispatcher.cc | 9 | ||||
-rw-r--r-- | net/tools/quic/quic_dispatcher.h | 4 | ||||
-rw-r--r-- | net/tools/quic/quic_epoll_connection_helper_test.cc | 10 | ||||
-rw-r--r-- | net/tools/quic/quic_server_session.h | 2 | ||||
-rw-r--r-- | net/tools/quic/quic_time_wait_list_manager.cc | 29 | ||||
-rw-r--r-- | net/tools/quic/quic_time_wait_list_manager.h | 24 | ||||
-rw-r--r-- | net/tools/quic/test_tools/quic_test_client.cc | 15 | ||||
-rw-r--r-- | net/tools/quic/test_tools/quic_test_client.h | 10 | ||||
-rw-r--r-- | net/tools/quic/test_tools/quic_test_utils.cc | 7 | ||||
-rw-r--r-- | net/tools/quic/test_tools/quic_test_utils.h | 2 |
14 files changed, 138 insertions, 63 deletions
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 23e9b56..310c393 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc @@ -107,7 +107,12 @@ class ServerThread : public base::SimpleThread { DISALLOW_COPY_AND_ASSIGN(ServerThread); }; -class EndToEndTest : public ::testing::Test { +class EndToEndTest : public ::testing::TestWithParam<QuicVersion> { + public: + static void SetUpTestCase() { + QuicInMemoryCache::GetInstance()->ResetForTests(); + } + protected: EndToEndTest() : server_hostname_("example.com"), @@ -123,16 +128,14 @@ class EndToEndTest : public ::testing::Test { "HTTP/1.1", "200", "OK", kFooResponseBody); AddToCache("GET", "https://www.google.com/bar", "HTTP/1.1", "200", "OK", kBarResponseBody); - } - - static void SetUpTestCase() { - QuicInMemoryCache::GetInstance()->ResetForTests(); + version_ = GetParam(); } virtual QuicTestClient* CreateQuicClient() { QuicTestClient* client = new QuicTestClient(server_address_, server_hostname_, - client_config_); + client_config_, + version_); client->Connect(); return client; } @@ -205,9 +208,15 @@ class EndToEndTest : public ::testing::Test { bool server_started_; QuicConfig client_config_; QuicConfig server_config_; + QuicVersion version_; }; -TEST_F(EndToEndTest, SimpleRequestResponse) { +// Run all end to end tests with QUIC version 6. +INSTANTIATE_TEST_CASE_P(EndToEndTests, + EndToEndTest, + ::testing::Values(QUIC_VERSION_6)); + +TEST_P(EndToEndTest, SimpleRequestResponse) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -222,7 +231,7 @@ TEST_F(EndToEndTest, SimpleRequestResponse) { // TODO(rch): figure out how to detect missing v6 supprt (like on the linux // try bots) and selectively disable this test. -TEST_F(EndToEndTest, DISABLED_SimpleRequestResponsev6) { +TEST_P(EndToEndTest, DISABLED_SimpleRequestResponsev6) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -238,7 +247,7 @@ TEST_F(EndToEndTest, DISABLED_SimpleRequestResponsev6) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, SeparateFinPacket) { +TEST_P(EndToEndTest, SeparateFinPacket) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -268,7 +277,7 @@ TEST_F(EndToEndTest, SeparateFinPacket) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleRequestResponse) { +TEST_P(EndToEndTest, MultipleRequestResponse) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -283,7 +292,7 @@ TEST_F(EndToEndTest, MultipleRequestResponse) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleClients) { +TEST_P(EndToEndTest, MultipleClients) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -312,7 +321,7 @@ TEST_F(EndToEndTest, MultipleClients) { EXPECT_EQ(200u, client2->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, RequestOverMultiplePackets) { +TEST_P(EndToEndTest, RequestOverMultiplePackets) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -344,7 +353,7 @@ TEST_F(EndToEndTest, RequestOverMultiplePackets) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, MultipleFramesRandomOrder) { +TEST_P(EndToEndTest, MultipleFramesRandomOrder) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -377,7 +386,7 @@ TEST_F(EndToEndTest, MultipleFramesRandomOrder) { EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, PostMissingBytes) { +TEST_P(EndToEndTest, PostMissingBytes) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -399,7 +408,7 @@ TEST_F(EndToEndTest, PostMissingBytes) { EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); } -TEST_F(EndToEndTest, LargePost) { +TEST_P(EndToEndTest, LargePost) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -420,7 +429,7 @@ TEST_F(EndToEndTest, LargePost) { } // TODO(ianswett): Enable once b/9295090 is fixed. -TEST_F(EndToEndTest, DISABLED_LargePostFEC) { +TEST_P(EndToEndTest, DISABLED_LargePostFEC) { // FLAGS_fake_packet_loss_percentage = 30; ASSERT_TRUE(Initialize()); client_->options()->max_packets_per_fec_group = 6; @@ -445,7 +454,7 @@ TEST_F(EndToEndTest, DISABLED_LargePostFEC) { EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request)); } -/*TEST_F(EndToEndTest, PacketTooLarge) { +/*TEST_P(EndToEndTest, PacketTooLarge) { FLAGS_quic_allow_oversized_packets_for_test = true; ASSERT_TRUE(Initialize()); @@ -462,7 +471,7 @@ TEST_F(EndToEndTest, DISABLED_LargePostFEC) { EXPECT_EQ(QUIC_PACKET_TOO_LARGE, client_->connection_error()); }*/ -TEST_F(EndToEndTest, InvalidStream) { +TEST_P(EndToEndTest, InvalidStream) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -487,7 +496,7 @@ TEST_F(EndToEndTest, InvalidStream) { } // TODO(rch): this test seems to cause net_unittests timeouts :| -TEST_F(EndToEndTest, DISABLED_MultipleTermination) { +TEST_P(EndToEndTest, DISABLED_MultipleTermination) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -535,7 +544,7 @@ TEST_F(EndToEndTest, DISABLED_MultipleTermination) { #endif } -TEST_F(EndToEndTest, Timeout) { +TEST_P(EndToEndTest, Timeout) { client_config_.set_idle_connection_state_lifetime( QuicTime::Delta::FromMicroseconds(500), QuicTime::Delta::FromMicroseconds(500)); @@ -547,7 +556,7 @@ TEST_F(EndToEndTest, Timeout) { } } -TEST_F(EndToEndTest, LimitMaxOpenStreams) { +TEST_P(EndToEndTest, LimitMaxOpenStreams) { // Server limits the number of max streams to 2. server_config_.set_max_streams_per_connection(2, 2); // Client tries to negotiate for 10. @@ -559,7 +568,7 @@ TEST_F(EndToEndTest, LimitMaxOpenStreams) { EXPECT_EQ(2u, client_negotiated_config->max_streams_per_connection()); } -TEST_F(EndToEndTest, ResetConnection) { +TEST_P(EndToEndTest, ResetConnection) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; @@ -597,7 +606,7 @@ class WrongAddressWriter : public QuicPacketWriter { int fd_; }; -TEST_F(EndToEndTest, ConnectionMigration) { +TEST_P(EndToEndTest, ConnectionMigration) { // TODO(rtenneti): Delete this when NSS is supported. if (!Aes128Gcm12Encrypter::IsSupported()) { LOG(INFO) << "AES GCM not supported. Test skipped."; diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc index b7e8d78..0d3baa9 100644 --- a/net/tools/quic/quic_client.cc +++ b/net/tools/quic/quic_client.cc @@ -31,20 +31,23 @@ namespace tools { const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; QuicClient::QuicClient(IPEndPoint server_address, - const string& server_hostname) + const string& server_hostname, + const QuicVersion version) : server_address_(server_address), server_hostname_(server_hostname), local_port_(0), fd_(-1), initialized_(false), packets_dropped_(0), - overflow_supported_(false) { + overflow_supported_(false), + version_(version) { config_.SetDefaults(); } QuicClient::QuicClient(IPEndPoint server_address, const string& server_hostname, - const QuicConfig& config) + const QuicConfig& config, + const QuicVersion version) : server_address_(server_address), server_hostname_(server_hostname), config_(config), @@ -52,7 +55,8 @@ QuicClient::QuicClient(IPEndPoint server_address, fd_(-1), initialized_(false), packets_dropped_(0), - overflow_supported_(false) { + overflow_supported_(false), + version_(version) { } QuicClient::~QuicClient() { @@ -152,7 +156,7 @@ bool QuicClient::StartConnect() { config_, new QuicConnection(guid, server_address_, new QuicEpollConnectionHelper(fd_, &epoll_server_), - false), + false, version_), &crypto_config_)); return session_->CryptoConnect(); } diff --git a/net/tools/quic/quic_client.h b/net/tools/quic/quic_client.h index 77b2eec..2b9b9e7 100644 --- a/net/tools/quic/quic_client.h +++ b/net/tools/quic/quic_client.h @@ -34,10 +34,12 @@ class QuicClientPeer; class QuicClient : public EpollCallbackInterface { public: - QuicClient(IPEndPoint server_address, const std::string& server_hostname); + QuicClient(IPEndPoint server_address, const std::string& server_hostname, + const QuicVersion version); QuicClient(IPEndPoint server_address, const std::string& server_hostname, - const QuicConfig& config); + const QuicConfig& config, + const QuicVersion version); virtual ~QuicClient(); @@ -130,6 +132,13 @@ class QuicClient : public EpollCallbackInterface { crypto_config_.SetProofVerifier(verifier); } + // SetChannelIDSigner sets a ChannelIDSigner that will be called when the + // server supports channel IDs to sign a message proving possession of the + // given ChannelID. This object takes ownership of |signer|. + void SetChannelIDSigner(ChannelIDSigner* signer) { + crypto_config_.SetChannelIDSigner(signer); + } + private: friend class net::tools::test::QuicClientPeer; @@ -177,6 +186,9 @@ class QuicClient : public EpollCallbackInterface { // because the socket would otherwise overflow. bool overflow_supported_; + // Which QUIC version does this client talk? + QuicVersion version_; + DISALLOW_COPY_AND_ASSIGN(QuicClient); }; diff --git a/net/tools/quic/quic_client_bin.cc b/net/tools/quic/quic_client_bin.cc index 13fbfc0..e13bea5 100644 --- a/net/tools/quic/quic_client_bin.cc +++ b/net/tools/quic/quic_client_bin.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "net/base/ip_endpoint.h" +#include "net/quic/quic_protocol.h" #include "net/tools/quic/quic_client.h" int32 FLAGS_port = 6121; @@ -42,8 +43,9 @@ int main(int argc, char *argv[]) { net::IPAddressNumber addr; CHECK(net::ParseIPLiteralToNumber(FLAGS_address, &addr)); + // TODO(rjshade): Set version on command line. net::tools::QuicClient client( - net::IPEndPoint(addr, FLAGS_port), FLAGS_hostname); + net::IPEndPoint(addr, FLAGS_port), FLAGS_hostname, net::QuicVersionMax()); client.Initialize(); diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index bfff5e6..d702b1d 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc @@ -94,7 +94,8 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, if (session == NULL) { DLOG(INFO) << "Failed to create session for " << guid; // Add this guid fo the time-wait state, to safely nack future packets. - time_wait_list_manager_->AddGuidToTimeWait(guid); + // We don't know the version here, so assume latest. + time_wait_list_manager_->AddGuidToTimeWait(guid, QuicVersionMax()); time_wait_list_manager_->ProcessPacket(server_address, client_address, guid, @@ -114,7 +115,8 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { QuicSession* session = it->second; write_blocked_list_.RemoveBlockedObject(session->connection()); - time_wait_list_manager_->AddGuidToTimeWait(it->first); + time_wait_list_manager_->AddGuidToTimeWait(it->first, + session->connection()->version()); session_map_.erase(it); } @@ -188,7 +190,8 @@ QuicSession* QuicDispatcher::CreateQuicSession( QuicConnectionHelperInterface* helper = new QuicEpollConnectionHelper(this, epoll_server); QuicServerSession* session = new QuicServerSession( - config_, new QuicConnection(guid, client_address, helper, true), this); + config_, new QuicConnection(guid, client_address, helper, true, + QuicVersionMax()), this); session->InitializeSession(crypto_config_); return session; } diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 521475b38..bbf8d9b 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h @@ -104,6 +104,10 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner { const QuicConfig& config_; const QuicCryptoServerConfig& crypto_config_; + QuicTimeWaitListManager* time_wait_list_manager() { + return time_wait_list_manager_.get(); + } + private: friend class net::tools::test::QuicDispatcherPeer; diff --git a/net/tools/quic/quic_epoll_connection_helper_test.cc b/net/tools/quic/quic_epoll_connection_helper_test.cc index 519e2e8..f765242 100644 --- a/net/tools/quic/quic_epoll_connection_helper_test.cc +++ b/net/tools/quic/quic_epoll_connection_helper_test.cc @@ -39,7 +39,7 @@ class TestConnectionHelper : public QuicEpollConnectionHelper { virtual int WritePacketToWire(const QuicEncryptedPacket& packet, int* error) OVERRIDE { - QuicFramer framer(kQuicVersion1, QuicTime::Zero(), true); + QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), true); FramerVisitorCapturingFrames visitor; framer.set_visitor(&visitor); EXPECT_TRUE(framer.ProcessPacket(packet)); @@ -59,7 +59,7 @@ class TestConnection : public QuicConnection { TestConnection(QuicGuid guid, IPEndPoint address, TestConnectionHelper* helper) - : QuicConnection(guid, address, helper, false) { + : QuicConnection(guid, address, helper, false, QuicVersionMax()) { } void SendAck() { @@ -77,7 +77,7 @@ class QuicEpollConnectionHelperTest : public ::testing::Test { protected: QuicEpollConnectionHelperTest() : guid_(42), - framer_(kQuicVersion1, QuicTime::Zero(), false), + framer_(QuicVersionMax(), QuicTime::Zero(), false), send_algorithm_(new testing::StrictMock<MockSendAlgorithm>), helper_(new TestConnectionHelper(0, &epoll_server_)), connection_(guid_, IPEndPoint(), helper_), @@ -120,6 +120,8 @@ class QuicEpollConnectionHelperTest : public ::testing::Test { TEST_F(QuicEpollConnectionHelperTest, DISABLED_TestRetransmission) { //FLAGS_fake_packet_loss_percentage = 100; + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + Return(QuicTime::Delta::Zero())); const int64 kDefaultRetransmissionTimeMs = 500; const char buffer[] = "foo"; @@ -178,6 +180,8 @@ TEST_F(QuicEpollConnectionHelperTest, TimeoutAfterSend) { TEST_F(QuicEpollConnectionHelperTest, SendSchedulerDelayThenSend) { // Test that if we send a packet with a delay, it ends up queued. + EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( + Return(QuicTime::Delta::Zero())); QuicPacket* packet = ConstructDataPacket(1, 0); EXPECT_CALL( *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillOnce( diff --git a/net/tools/quic/quic_server_session.h b/net/tools/quic/quic_server_session.h index ba3ebd6..604b9fc 100644 --- a/net/tools/quic/quic_server_session.h +++ b/net/tools/quic/quic_server_session.h @@ -48,6 +48,8 @@ class QuicServerSession : public QuicSession { virtual void InitializeSession(const QuicCryptoServerConfig& crypto_config); + const QuicCryptoServerStream* crypto_stream() { return crypto_stream_.get(); } + protected: // QuicSession methods: virtual ReliableQuicStream* CreateIncomingReliableStream( diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc index 3bc2d41..7d5862a 100644 --- a/net/tools/quic/quic_time_wait_list_manager.cc +++ b/net/tools/quic/quic_time_wait_list_manager.cc @@ -18,6 +18,8 @@ #include "net/quic/quic_protocol.h" #include "net/quic/quic_utils.h" +using std::make_pair; + namespace net { namespace tools { @@ -91,7 +93,7 @@ class QuicTimeWaitListManager::QueuedPacket { QuicTimeWaitListManager::QuicTimeWaitListManager( QuicPacketWriter* writer, EpollServer* epoll_server) - : framer_(kQuicVersion1, + : framer_(QUIC_VERSION_6, QuicTime::Zero(), // unused true), epoll_server_(epoll_server), @@ -110,10 +112,12 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() { STLDeleteElements(&pending_packets_queue_); } -void QuicTimeWaitListManager::AddGuidToTimeWait(QuicGuid guid) { +void QuicTimeWaitListManager::AddGuidToTimeWait(QuicGuid guid, + QuicVersion version) { DCHECK(!IsGuidInTimeWait(guid)); // Initialize the guid with 0 packets received. - guid_map_.insert(std::make_pair(guid, 0)); + GuidData data(0, version); + guid_map_.insert(make_pair(guid, data)); time_ordered_guid_list_.push_back(new GuidAddTime(guid, clock_.ApproximateNow())); } @@ -130,11 +134,20 @@ void QuicTimeWaitListManager::ProcessPacket( DCHECK(IsGuidInTimeWait(guid)); server_address_ = server_address; client_address_ = client_address; - // TODO(satyamshekhar): Also store the version of protocol for and - // update the protocol version of the framer before processing. + + // Set the framer to the appropriate version for this GUID, before processing. + QuicVersion version = GetQuicVersionFromGuid(guid); + framer_.set_version(version); + framer_.ProcessPacket(packet); } +QuicVersion QuicTimeWaitListManager::GetQuicVersionFromGuid(QuicGuid guid) { + GuidMapIterator it = guid_map_.find(guid); + DCHECK(it != guid_map_.end()); + return (it->second).version; +} + bool QuicTimeWaitListManager::OnCanWrite() { is_write_blocked_ = false; while (!is_write_blocked_ && !pending_packets_queue_.empty()) { @@ -154,7 +167,7 @@ void QuicTimeWaitListManager::OnError(QuicFramer* framer) { } bool QuicTimeWaitListManager::OnProtocolVersionMismatch( - QuicTag received_version) { + QuicVersion received_version) { // Drop such packets whose version don't match. return false; } @@ -192,8 +205,8 @@ bool QuicTimeWaitListManager::OnPacketHeader(const QuicPacketHeader& header) { GuidMapIterator it = guid_map_.find(header.public_header.guid); DCHECK(it != guid_map_.end()); // Increment the received packet count. - ++(it->second); - if (ShouldSendPublicReset(it->second)) { + ++((it->second).num_packets); + if (ShouldSendPublicReset((it->second).num_packets)) { // We don't need the packet anymore. Just tell the client what sequence // number we rejected. SendPublicReset(server_address_, diff --git a/net/tools/quic/quic_time_wait_list_manager.h b/net/tools/quic/quic_time_wait_list_manager.h index 2b07334..815b9d9 100644 --- a/net/tools/quic/quic_time_wait_list_manager.h +++ b/net/tools/quic/quic_time_wait_list_manager.h @@ -44,8 +44,9 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // any packet bearing this guid should not be processed while the guid remains // in this list. Public reset packets are sent to the clients by the time wait // list manager that send packets to guids in this state. DCHECKs that guid is - // not already on the list. - void AddGuidToTimeWait(QuicGuid guid); + // not already on the list. Pass in the version as well so that if a public + // reset packet needs to be sent the framer version can be set first. + void AddGuidToTimeWait(QuicGuid guid, QuicVersion version); // Returns true if the guid is in time wait state, false otherwise. Packets // received for this guid should not lead to creation of new QuicSessions. @@ -71,7 +72,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // FramerVisitorInterface virtual void OnError(QuicFramer* framer) OVERRIDE; - virtual bool OnProtocolVersionMismatch(QuicTag received_version) OVERRIDE; + virtual bool OnProtocolVersionMismatch(QuicVersion received_version) OVERRIDE; virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; virtual void OnPacket() OVERRIDE {} virtual void OnPublicResetPacket( @@ -94,6 +95,8 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE; virtual void OnFecData(const QuicFecData& fec) OVERRIDE {} + QuicVersion version() const { return framer_.version(); } + protected: // Exposed for tests. bool is_write_blocked() const { return is_write_blocked_; } @@ -105,6 +108,11 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // Exposed for tests. const QuicTime::Delta time_wait_period() const { return kTimeWaitPeriod_; } + // Given a GUID that exists in the time wait list, returns the QuicVersion + // associated with it. Used internally to set the framer version before + // writing the public reset packet. + QuicVersion GetQuicVersionFromGuid(QuicGuid guid); + private: // Stores the guid and the time it was added to time wait state. struct GuidAddTime; @@ -132,8 +140,14 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface, // A map from a recently closed guid to the number of packets received after // the termination of the connection bound to the guid. - base::hash_map<QuicGuid, int> guid_map_; - typedef base::hash_map<QuicGuid, int>::iterator GuidMapIterator; + struct GuidData { + GuidData(int num_packets_, QuicVersion version_) + : num_packets(num_packets_), version(version_) {} + int num_packets; + QuicVersion version; + }; + base::hash_map<QuicGuid, GuidData> guid_map_; + typedef base::hash_map<QuicGuid, GuidData>::iterator GuidMapIterator; // Maintains a list of GuidAddTime elements which it owns, in the // order they should be deleted. diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc index 9825425..eb26078 100644 --- a/net/tools/quic/test_tools/quic_test_client.cc +++ b/net/tools/quic/test_tools/quic_test_client.cc @@ -88,15 +88,17 @@ BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers, return headers; } -QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname) - : client_(address, hostname) { +QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, + const QuicVersion version) + : client_(address, hostname, version) { Initialize(address, hostname); } QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, - bool secure) - : client_(address, hostname) { + bool secure, + const QuicVersion version) + : client_(address, hostname, version) { Initialize(address, hostname); secure_ = secure; // TODO(alyssar, agl) uncomment here and below when default certs are allowed. @@ -105,8 +107,9 @@ QuicTestClient::QuicTestClient(IPEndPoint address, QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname, - const QuicConfig& config) - : client_(address, hostname, config) { + const QuicConfig& config, + const QuicVersion version) + : client_(address, hostname, config, version) { Initialize(address, hostname); } diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h index d277100..051c011 100644 --- a/net/tools/quic/test_tools/quic_test_client.h +++ b/net/tools/quic/test_tools/quic_test_client.h @@ -26,13 +26,16 @@ class HTTPMessage; // A toy QUIC client used for testing. class QuicTestClient : public ReliableQuicStream::Visitor { public: - QuicTestClient(IPEndPoint server_address, const string& server_hostname); + QuicTestClient(IPEndPoint server_address, const string& server_hostname, + const QuicVersion version); QuicTestClient(IPEndPoint server_address, const string& server_hostname, - bool secure); + bool secure, + const QuicVersion version); QuicTestClient(IPEndPoint server_address, const string& server_hostname, - const QuicConfig& config); + const QuicConfig& config, + const QuicVersion version); virtual ~QuicTestClient(); @@ -114,6 +117,7 @@ class QuicTestClient : public ReliableQuicStream::Visitor { // If true, the client will always reconnect if necessary before creating a // stream. bool auto_reconnect_; + // proof_verifier_ points to a RecordingProofVerifier that is owned by // client_. ProofVerifier* proof_verifier_; diff --git a/net/tools/quic/test_tools/quic_test_utils.cc b/net/tools/quic/test_tools/quic_test_utils.cc index 05c3a57..95f1fb2 100644 --- a/net/tools/quic/test_tools/quic_test_utils.cc +++ b/net/tools/quic/test_tools/quic_test_utils.cc @@ -20,7 +20,8 @@ MockConnection::MockConnection(QuicGuid guid, EpollServer* eps, bool is_server) : QuicConnection(guid, address, - new QuicEpollConnectionHelper(fd, eps), is_server), + new QuicEpollConnectionHelper(fd, eps), is_server, + QuicVersionMax()), has_mock_helper_(false) { } @@ -28,7 +29,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, bool is_server) : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(), - is_server), + is_server, QuicVersionMax()), has_mock_helper_(true) { } @@ -36,7 +37,7 @@ MockConnection::MockConnection(QuicGuid guid, IPEndPoint address, QuicConnectionHelperInterface* helper, bool is_server) - : QuicConnection(guid, address, helper, is_server), + : QuicConnection(guid, address, helper, is_server, QuicVersionMax()), has_mock_helper_(false) { } diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h index 68f4de4..31ea1815 100644 --- a/net/tools/quic/test_tools/quic_test_utils.h +++ b/net/tools/quic/test_tools/quic_test_utils.h @@ -63,7 +63,7 @@ class MockConnection : public QuicConnection { return QuicConnection::ProcessUdpPacket(self_address, peer_address, packet); } - virtual bool OnProtocolVersionMismatch(QuicTag version) { return false; } + virtual bool OnProtocolVersionMismatch(QuicVersion version) { return false; } private: const bool has_mock_helper_; |