diff options
author | mek@chromium.org <mek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 23:58:14 +0000 |
---|---|---|
committer | mek@chromium.org <mek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 23:58:14 +0000 |
commit | 573ebcb35b5e92124a5de20131fbedeab26ebf12 (patch) | |
tree | fc7f87d7083dff8afb67b6e5a8d5ab5ebfdf6225 | |
parent | 5733b22124b90e9ad8dd5045e9acc173d1545755 (diff) | |
download | chromium_src-573ebcb35b5e92124a5de20131fbedeab26ebf12.zip chromium_src-573ebcb35b5e92124a5de20131fbedeab26ebf12.tar.gz chromium_src-573ebcb35b5e92124a5de20131fbedeab26ebf12.tar.bz2 |
Revert 227827 "Land Recent QUIC changes."
Causing problem for Linux ASAN:
http://build.chromium.org/p/chromium.memory/buildstatus?builder=Linux%20ASAN%20Tests%20%281%29&number=19137
> Land Recent QUIC changes.
>
> Addressing comments in Jana's review of cr/52231261.
>
> Merge internal change: 53582401
>
> Add a temporary legacy quic constructor
>
> Merge internal change: 53506960
>
> QUIC: disable P-256 support on the server.
>
> The P-256 key generation is done with OpenSSL, which doesn't use the
> QuicRandom passed to DefaultConfig(). This is causing the generated
> server configs to be non-deterministic and breaking 0-RTT handshakes.
>
> Merge internal change: 53501783
>
> Fix an LOG to use the correct condition in QuicReceivedPacketManager and
> change it to a DFATAL so in the future tests will prevent re-occurrence.
>
> Merge internal change: 53483753
>
> Cleanup: Rename OnIncomingAck to OnPacketAcked, and remove unneeeded
> argument from SentPacketManager::OnIncomingAck.
>
> Merge internal change: 53483155
>
> Fix a bug in QuicConnection/QuicConnectionHelper if the helper buffered
> the write (as is the case in chrome). In this case, the sent packet was
> not accounted for properly.
>
> Merge internal change: 53462749
>
> Refactor to change WritePacket to return a WriteResult struct.
>
> Merge internal change: 53382221
>
> Fixing a bug where the version negotiation packet would get dropped on
> the floor if the socket was write blocked at the time it was sent. The
> packet is now queued.
>
> Merge internal change: 53317846
>
> Create a new QUIC_INVALID_CHANNEL_ID_SIGNATURE error to replace a usage
> of QUIC_INTERNAL_ERROR.
>
> Merge internal change: 53277933
>
> Added a todo to merge internal CL 53267501 when chromium's version of
> OpenSSL has latest AEAD code.
>
> Didn't merge internal change: 53267501
>
> R=rch@chromium.org
>
> Review URL: https://codereview.chromium.org/26385004
TBR=rtenneti@chromium.org
Review URL: https://codereview.chromium.org/26666003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227837 0039d316-1c4b-4281-b951-d872f2087c98
35 files changed, 322 insertions, 482 deletions
diff --git a/net/quic/crypto/aes_128_gcm_12_decrypter.h b/net/quic/crypto/aes_128_gcm_12_decrypter.h index aba610f..5dc12c8 100644 --- a/net/quic/crypto/aes_128_gcm_12_decrypter.h +++ b/net/quic/crypto/aes_128_gcm_12_decrypter.h @@ -60,8 +60,6 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Decrypter : public QuicDecrypter { unsigned char nonce_prefix_[4]; #if defined(USE_OPENSSL) - // TODO(rtenneti): when Chromium's version of OpenSSL has EVP_AEAD_CTX, merge - // internal CL 53267501. ScopedEVPCipherCtx ctx_; #endif }; diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter.h b/net/quic/crypto/aes_128_gcm_12_encrypter.h index abea8ac2..ca9a2b1 100644 --- a/net/quic/crypto/aes_128_gcm_12_encrypter.h +++ b/net/quic/crypto/aes_128_gcm_12_encrypter.h @@ -63,8 +63,6 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Encrypter : public QuicEncrypter { unsigned char nonce_prefix_[4]; #if defined(USE_OPENSSL) - // TODO(rtenneti): when Chromium's version of OpenSSL has EVP_AEAD_CTX, merge - // internal CL 53267501. ScopedEVPCipherCtx ctx_; #endif }; diff --git a/net/quic/crypto/crypto_handshake.cc b/net/quic/crypto/crypto_handshake.cc index f5c7f4d..395f4ae 100644 --- a/net/quic/crypto/crypto_handshake.cc +++ b/net/quic/crypto/crypto_handshake.cc @@ -752,7 +752,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( if (!channel_id_signer_->Sign(server_hostname, hkdf_input, &key, &signature)) { *error_details = "Channel ID signature failed"; - return QUIC_INVALID_CHANNEL_ID_SIGNATURE; + return QUIC_INTERNAL_ERROR; } cetv.SetStringPiece(kCIDK, key); diff --git a/net/quic/crypto/crypto_server_config.cc b/net/quic/crypto/crypto_server_config.cc index 7c7d0ff..89cea42 100644 --- a/net/quic/crypto/crypto_server_config.cc +++ b/net/quic/crypto/crypto_server_config.cc @@ -46,8 +46,7 @@ const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; QuicCryptoServerConfig::ConfigOptions::ConfigOptions() : expiry_time(QuicWallTime::Zero()), - channel_id_enabled(false), - p256(false) {} + channel_id_enabled(false) { } QuicCryptoServerConfig::QuicCryptoServerConfig( StringPiece source_address_token_secret, @@ -98,14 +97,9 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( Curve25519KeyExchange::New(curve25519_private_key)); StringPiece curve25519_public_value = curve25519->public_value(); - string p256_private_key; - StringPiece p256_public_value; - scoped_ptr<P256KeyExchange> p256; - if (options.p256) { - p256_private_key = P256KeyExchange::NewPrivateKey(); - p256.reset(P256KeyExchange::New(p256_private_key)); - p256_public_value = p256->public_value(); - } + const string p256_private_key = P256KeyExchange::NewPrivateKey(); + scoped_ptr<P256KeyExchange> p256(P256KeyExchange::New(p256_private_key)); + StringPiece p256_public_value = p256->public_value(); string encoded_public_values; // First three bytes encode the length of the public value. @@ -121,11 +115,7 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( p256_public_value.size()); msg.set_tag(kSCFG); - if (options.p256) { - msg.SetTaglist(kKEXS, kC255, kP256, 0); - } else { - msg.SetTaglist(kKEXS, kC255, 0); - } + msg.SetTaglist(kKEXS, kC255, kP256, 0); msg.SetTaglist(kAEAD, kAESG, 0); msg.SetValue(kVERS, static_cast<uint16>(0)); msg.SetStringPiece(kPUBS, encoded_public_values); @@ -168,12 +158,9 @@ QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key(); curve25519_key->set_tag(kC255); curve25519_key->set_private_key(curve25519_private_key); - - if (options.p256) { - QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); - p256_key->set_tag(kP256); - p256_key->set_private_key(p256_private_key); - } + QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); + p256_key->set_tag(kP256); + p256_key->set_private_key(p256_private_key); return config.release(); } diff --git a/net/quic/crypto/crypto_server_config.h b/net/quic/crypto/crypto_server_config.h index 4551425..4255d22 100644 --- a/net/quic/crypto/crypto_server_config.h +++ b/net/quic/crypto/crypto_server_config.h @@ -61,11 +61,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // orbit contains the kOrbitSize bytes of the orbit value for the server // config. If |orbit| is empty then a random orbit is generated. std::string orbit; - // p256 determines whether a P-256 public key will be included in the - // server config. Note that this breaks deterministic server-config - // generation since P-256 key generation doesn't use the QuicRandom given - // to DefaultConfig(). - bool p256; }; // |source_address_token_secret|: secret key material used for encrypting and diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc index 348b31a..b2cdf82 100644 --- a/net/quic/crypto/crypto_server_test.cc +++ b/net/quic/crypto/crypto_server_test.cc @@ -8,7 +8,6 @@ #include "net/quic/crypto/quic_random.h" #include "net/quic/test_tools/crypto_test_utils.h" #include "net/quic/test_tools/mock_clock.h" -#include "net/quic/test_tools/mock_random.h" #include "testing/gtest/include/gtest/gtest.h" using base::StringPiece; @@ -240,24 +239,6 @@ TEST_F(CryptoServerTest, ReplayProtection) { ASSERT_EQ(kSHLO, out_.tag()); } -TEST(CryptoServerConfigGenerationTest, Determinism) { - // Test that using a deterministic PRNG causes the server-config to be - // deterministic. - - MockRandom rand_a, rand_b; - const QuicCryptoServerConfig::ConfigOptions options; - MockClock clock; - - QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a); - QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b); - scoped_ptr<CryptoHandshakeMessage> scfg_a( - a.AddDefaultConfig(&rand_a, &clock, options)); - scoped_ptr<CryptoHandshakeMessage> scfg_b( - b.AddDefaultConfig(&rand_b, &clock, options)); - - ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString()); -} - class CryptoServerTestNoConfig : public CryptoServerTest { public: virtual void SetUp() { diff --git a/net/quic/quic_ack_notifier_manager.cc b/net/quic/quic_ack_notifier_manager.cc index 2221e30..901d9d6 100644 --- a/net/quic/quic_ack_notifier_manager.cc +++ b/net/quic/quic_ack_notifier_manager.cc @@ -22,32 +22,40 @@ AckNotifierManager::~AckNotifierManager() { STLDeleteElements(&ack_notifiers_); } -void AckNotifierManager::OnPacketAcked( - QuicPacketSequenceNumber sequence_number) { - // Inform all the registered AckNotifiers of the new ACK. - AckNotifierMap::iterator map_it = ack_notifier_map_.find(sequence_number); - if (map_it == ack_notifier_map_.end()) { - // No AckNotifier is interested in this sequence number. - return; - } +void AckNotifierManager::OnIncomingAck(const SequenceNumberSet& acked_packets) { + // Inform all the registered AckNotifiers of the new ACKs. + for (SequenceNumberSet::const_iterator seq_it = acked_packets.begin(); + seq_it != acked_packets.end(); ++seq_it) { + AckNotifierMap::iterator map_it = ack_notifier_map_.find(*seq_it); + if (map_it == ack_notifier_map_.end()) { + // No AckNotifier is interested in this sequence number. + continue; + } - // One or more AckNotifiers are registered as interested in this sequence - // number. Iterate through them and call OnAck on each. - for (AckNotifierSet::iterator set_it = map_it->second.begin(); - set_it != map_it->second.end(); ++set_it) { - QuicAckNotifier* ack_notifier = *set_it; - ack_notifier->OnAck(sequence_number); - - // If this has resulted in an empty AckNotifer, erase it. - if (ack_notifier->IsEmpty()) { - delete ack_notifier; - ack_notifiers_.erase(ack_notifier); + // One or more AckNotifiers are registered as interested in this sequence + // number. Iterate through them and call OnAck on each. + for (AckNotifierSet::iterator set_it = map_it->second.begin(); + set_it != map_it->second.end(); ++set_it) { + (*set_it)->OnAck(*seq_it); } + + // Remove the sequence number from the map as we have notified all the + // registered AckNotifiers, and we won't see it again. + ack_notifier_map_.erase(map_it); } - // Remove the sequence number from the map as we have notified all the - // registered AckNotifiers, and we won't see it again. - ack_notifier_map_.erase(map_it); + // Clear up any empty AckNotifiers + AckNotifierSet::iterator it = ack_notifiers_.begin(); + while (it != ack_notifiers_.end()) { + if ((*it)->IsEmpty()) { + // The QuicAckNotifier has seen all the ACKs it was interested in, and + // has triggered its callback. No more use for it. + delete *it; + ack_notifiers_.erase(it++); + } else { + ++it; + } + } } void AckNotifierManager::UpdateSequenceNumber( diff --git a/net/quic/quic_ack_notifier_manager.h b/net/quic/quic_ack_notifier_manager.h index 5ddf794..7fe9a46 100644 --- a/net/quic/quic_ack_notifier_manager.h +++ b/net/quic/quic_ack_notifier_manager.h @@ -37,10 +37,11 @@ class NET_EXPORT_PRIVATE AckNotifierManager { AckNotifierManager(); virtual ~AckNotifierManager(); - // Called when the connection receives a new AckFrame. If |sequence_number| - // exists in ack_notifier_map_ then the corresponding AckNotifiers will have - // their OnAck method called. - void OnPacketAcked(QuicPacketSequenceNumber sequence_number); + // Called when the connection receives a new AckFrame. For each packet + // in |acked_packets|, if the packet sequence number exists in + // ack_notifier_map_ then the corresponding AckNotifiers will have their OnAck + // method called. + void OnIncomingAck(const SequenceNumberSet& acked_packets); // If a packet has been retransmitted with a new sequence number, then this // will be called. It updates the mapping in ack_notifier_map_, and also diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index 2073919..59759f7 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -52,9 +52,8 @@ namespace { // This will likely have to be tuned. const QuicPacketSequenceNumber kMaxPacketGap = 5000; -// We want to make sure if we get a nack packet which triggers several -// retransmissions, we don't queue up too many packets. 10 is TCP's default -// initial congestion window(RFC 6928). +// We want to make sure if we get a large nack packet, we don't queue up too +// many packets at once. 10 is a common default initial congestion window. const size_t kMaxRetransmissionsPerAck = 10; // TCP retransmits after 2 nacks. We allow for a third in case of out-of-order @@ -216,7 +215,6 @@ QuicConnection::QuicConnection(QuicGuid guid, guid_(guid), peer_address_(address), largest_seen_packet_with_ack_(0), - pending_version_negotiation_packet_(false), write_blocked_(false), ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), @@ -506,15 +504,11 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { } void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) { - // Latch current least unacked sequence number. This allows us to reset the - // retransmission and FEC abandonment timers conditionally below. - QuicPacketSequenceNumber least_unacked_sent_before = - sent_packet_manager_.GetLeastUnackedSentPacket(); - largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; - received_truncated_ack_ = incoming_ack.received_info.missing_packets.size() >= - QuicFramer::GetMaxUnackedPackets(last_header_); + received_truncated_ack_ = + incoming_ack.received_info.missing_packets.size() >= + QuicFramer::GetMaxUnackedPackets(last_header_); received_packet_manager_.UpdatePacketInformationReceivedByPeer(incoming_ack); received_packet_manager_.UpdatePacketInformationSentByPeer(incoming_ack); @@ -525,42 +519,35 @@ void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) { received_packet_manager_.least_packet_awaited_by_peer() - 1); retransmitted_nacked_packet_count_ = 0; - sent_packet_manager_.OnIncomingAck(incoming_ack.received_info, - received_truncated_ack_); - - // Get the updated least unacked sequence number. - QuicPacketSequenceNumber least_unacked_sent_after = - sent_packet_manager_.GetLeastUnackedSentPacket(); - - // Used to set RTO and FEC alarms. - QuicTime::Delta retransmission_delay = - congestion_manager_.GetRetransmissionDelay( - sent_packet_manager_.GetNumUnackedPackets(), 0); - - // If there are outstanding packets, and the least unacked sequence number - // has increased after processing this latest AckFrame, then reschedule the - // retransmission timer. - if (sent_packet_manager_.HasUnackedPackets() && - least_unacked_sent_before < least_unacked_sent_after) { - DCHECK(retransmission_alarm_->IsSet()); - - retransmission_alarm_->Cancel(); - retransmission_alarm_->Set( - clock_->ApproximateNow().Add(retransmission_delay)); + SequenceNumberSet acked_packets; + sent_packet_manager_.OnIncomingAck( + incoming_ack.received_info, received_truncated_ack_, &acked_packets); + if (acked_packets.size() > 0) { + // Reset the RTO timeout for each packet when an ack is received. + if (retransmission_alarm_->IsSet()) { + retransmission_alarm_->Cancel(); + // Only reschedule the timer if there are outstanding packets. + if (sent_packet_manager_.HasUnackedPackets()) { + QuicTime::Delta retransmission_delay = + congestion_manager_.GetRetransmissionDelay( + sent_packet_manager_.GetNumUnackedPackets(), 0); + retransmission_alarm_->Set(clock_->ApproximateNow().Add( + retransmission_delay)); + } + } + if (abandon_fec_alarm_->IsSet()) { + abandon_fec_alarm_->Cancel(); + // Only reschedule the timer if there are outstanding fec packets. + if (sent_packet_manager_.HasUnackedFecPackets()) { + QuicTime::Delta retransmission_delay = + congestion_manager_.GetRetransmissionDelay( + sent_packet_manager_.GetNumUnackedPackets(), 0); + abandon_fec_alarm_->Set(clock_->ApproximateNow().Add( + retransmission_delay)); + } + } consecutive_rto_count_ = 0; - } else if (!sent_packet_manager_.HasUnackedPackets()) { - retransmission_alarm_->Cancel(); } - - // If there are outstanding FEC packets, and the least unacked sequence number - // has increased after processing this latest AckFrame, then reschedule the - // abandon FEC timer. - abandon_fec_alarm_->Cancel(); - if (sent_packet_manager_.HasUnackedFecPackets() && - least_unacked_sent_before < least_unacked_sent_after) { - abandon_fec_alarm_->Set(clock_->ApproximateNow().Add(retransmission_delay)); - } - congestion_manager_.OnIncomingAckFrame(incoming_ack, time_of_last_received_packet_); } @@ -753,6 +740,7 @@ void QuicConnection::OnPacketComplete() { MaybeSendInResponseToPacket(send_ack_immediately, last_packet_should_instigate_ack); + ClearLastFrames(); } @@ -845,25 +833,12 @@ void QuicConnection::SendVersionNegotiationPacket() { for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { supported_versions.push_back(kSupportedQuicVersions[i]); } - scoped_ptr<QuicEncryptedPacket> version_packet( - packet_creator_.SerializeVersionNegotiationPacket(supported_versions)); + QuicEncryptedPacket* encrypted = + packet_creator_.SerializeVersionNegotiationPacket(supported_versions); // TODO(satyamshekhar): implement zero server state negotiation. - WriteResult result = - helper_->WritePacketToWire(*version_packet); - if (result.status == WRITE_STATUS_OK || - (result.status == WRITE_STATUS_BLOCKED && - helper_->IsWriteBlockedDataBuffered())) { - pending_version_negotiation_packet_ = false; - return; - } - if (result.status == WRITE_STATUS_ERROR) { - // We can't send an error as the socket is presumably borked. - CloseConnection(QUIC_PACKET_WRITE_ERROR, false); - } - if (result.status == WRITE_STATUS_BLOCKED) { - write_blocked_ = true; - } - pending_version_negotiation_packet_ = true; + int error; + helper_->WritePacketToWire(*encrypted, &error); + delete encrypted; } QuicConsumedData QuicConnection::SendvStreamDataInner( @@ -1074,10 +1049,6 @@ bool QuicConnection::ProcessValidatedPacket() { bool QuicConnection::WriteQueuedPackets() { DCHECK(!write_blocked_); - if (pending_version_negotiation_packet_) { - SendVersionNegotiationPacket(); - } - QueuedPacketList::iterator packet_iterator = queued_packets_.begin(); while (!write_blocked_ && packet_iterator != queued_packets_.end()) { if (WritePacket(packet_iterator->encryption_level, @@ -1232,8 +1203,9 @@ void QuicConnection::SetupRetransmission( return; } - // Do not set the retransmission alarm if we're already handling one, since - // it will be reset when OnRetransmissionTimeout completes. + // Do not set the retransmission alarm if we're already handling the + // retransmission alarm because the retransmission alarm will be reset when + // OnRetransmissionTimeout completes. if (retransmission_alarm_->IsSet()) { return; } @@ -1366,51 +1338,27 @@ bool QuicConnection::WritePacket(EncryptionLevel level, << packet->length() << " " << encrypted->length() << " " << " forced: " << (forced == FORCE ? "yes" : "no"); - DCHECK(pending_write_.get() == NULL); - pending_write_.reset(new PendingWrite(sequence_number, transmission_type, - retransmittable, level, packet)); - - WriteResult result = WritePacketToWire(sequence_number, level, *encrypted); - if (result.status == WRITE_STATUS_BLOCKED) { - // TODO(satyashekhar): It might be more efficient (fewer system calls), if - // all connections share this variable i.e this becomes a part of - // PacketWriterInterface. - write_blocked_ = true; - // If the socket buffers the the data, then the packet should not - // be queued and sent again, which would result in an unnecessary - // duplicate packet being sent. The helper must call OnPacketSent - // when the packet is actually sent. - if (helper_->IsWriteBlockedDataBuffered()) { - return true; + int error; + QuicTime now = clock_->Now(); + if (WritePacketToWire(sequence_number, level, *encrypted, &error) == -1) { + if (helper_->IsWriteBlocked(error)) { + // TODO(satyashekhar): It might be more efficient (fewer system calls), if + // all connections share this variable i.e this becomes a part of + // PacketWriterInterface. + write_blocked_ = true; + // If the socket buffers the the data, then the packet should not + // be queued and sent again, which would result in an unnecessary + // duplicate packet being sent. + if (helper_->IsWriteBlockedDataBuffered()) { + delete packet; + return true; + } + return false; } - pending_write_.reset(); - return false; - } - - return OnPacketSent(result); -} - -bool QuicConnection::OnPacketSent(WriteResult result) { - DCHECK_NE(WRITE_STATUS_BLOCKED, result.status); - if (pending_write_.get() == NULL) { - LOG(DFATAL) << "OnPacketSent called without a pending write."; - return false; - } - - QuicPacketSequenceNumber sequence_number = pending_write_->sequence_number; - TransmissionType transmission_type = pending_write_->transmission_type; - HasRetransmittableData retransmittable = pending_write_->retransmittable; - EncryptionLevel level = pending_write_->level; - QuicPacket* packet = pending_write_->packet; - pending_write_.reset(); - - if (result.status == WRITE_STATUS_ERROR) { // We can't send an error as the socket is presumably borked. CloseConnection(QUIC_PACKET_WRITE_ERROR, false); return false; } - - QuicTime now = clock_->Now(); if (transmission_type == NOT_RETRANSMISSION) { time_of_last_sent_packet_ = now; } @@ -1436,12 +1384,12 @@ bool QuicConnection::OnPacketSent(WriteResult result) { congestion_manager_.OnPacketSent(sequence_number, now, packet->length(), transmission_type, retransmittable); - stats_.bytes_sent += result.bytes_written; + stats_.bytes_sent += encrypted->length(); ++stats_.packets_sent; if (transmission_type == NACK_RETRANSMISSION || transmission_type == RTO_RETRANSMISSION) { - stats_.bytes_retransmitted += result.bytes_written; + stats_.bytes_retransmitted += encrypted->length(); ++stats_.packets_retransmitted; } @@ -1449,16 +1397,18 @@ bool QuicConnection::OnPacketSent(WriteResult result) { return true; } -WriteResult QuicConnection::WritePacketToWire( - QuicPacketSequenceNumber sequence_number, - EncryptionLevel level, - const QuicEncryptedPacket& packet) { - WriteResult result = helper_->WritePacketToWire(packet); +int QuicConnection::WritePacketToWire(QuicPacketSequenceNumber sequence_number, + EncryptionLevel level, + const QuicEncryptedPacket& packet, + int* error) { + int bytes_written = helper_->WritePacketToWire(packet, error); if (debug_visitor_) { - // Pass the write result to the visitor. - debug_visitor_->OnPacketSent(sequence_number, level, packet, result); + // WritePacketToWire returned -1, then |error| will be populated with + // an error code, which we want to pass along to the visitor. + debug_visitor_->OnPacketSent(sequence_number, level, packet, + bytes_written == -1 ? *error : bytes_written); } - return result; + return bytes_written; } bool QuicConnection::OnSerializedPacket( @@ -1556,6 +1506,8 @@ void QuicConnection::OnRetransmissionTimeout() { return; } + // TODO(ianswett): When multiple RTO's fire, the subsequent RTO should send + // the same data packet as the first RTO according to the TCP spec. // TODO(ianswett): When an RTO fires, but the connection has not been // established as forward secure, re-send the client hello first. ++stats_.rto_count; @@ -1813,8 +1765,7 @@ void QuicConnection::Flush() { } bool QuicConnection::HasQueuedData() const { - return pending_version_negotiation_packet_ || - !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); + return !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); } void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 2eb7873..2f20351 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -104,7 +104,7 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitorInterface virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, EncryptionLevel level, const QuicEncryptedPacket& packet, - WriteResult result) = 0; + int rv) = 0; // Called when the contents of a packet have been retransmitted as // a new packet. @@ -171,10 +171,10 @@ class NET_EXPORT_PRIVATE QuicConnectionHelperInterface { // Sends the packet out to the peer, possibly simulating packet // loss if FLAGS_fake_packet_loss_percentage is set. If the write - // succeeded, the result's status is WRITE_STATUS_OK and bytes_written is - // populated. If the write failed, the result's status is WRITE_STATUS_BLOCKED - // or WRITE_STATUS_ERROR and error_code will populated. - virtual WriteResult WritePacketToWire(const QuicEncryptedPacket& packet) = 0; + // succeeded, returns the number of bytes written. If the write + // failed, returns -1 and the error code will be copied to |*error|. + virtual int WritePacketToWire(const QuicEncryptedPacket& packet, + int* error) = 0; // Returns true if the helper buffers and subsequently rewrites data // when an attempt to write results in the underlying socket becoming @@ -274,9 +274,6 @@ class NET_EXPORT_PRIVATE QuicConnection // writes to happen. Returns false if the socket has become blocked. virtual bool OnCanWrite() OVERRIDE; - // Called when a packet has been finally sent to the network. - bool OnPacketSent(WriteResult result); - // If the socket is not blocked, this allows queued writes to happen. Returns // false if the socket has become blocked. bool WriteIfNotBlocked(); @@ -458,9 +455,10 @@ class NET_EXPORT_PRIVATE QuicConnection HasRetransmittableData retransmittable, Force force); - WriteResult WritePacketToWire(QuicPacketSequenceNumber sequence_number, - EncryptionLevel level, - const QuicEncryptedPacket& packet); + int WritePacketToWire(QuicPacketSequenceNumber sequence_number, + EncryptionLevel level, + const QuicEncryptedPacket& packet, + int* error); // Make sure an ack we got from our peer is sane. bool ValidateAckFrame(const QuicAckFrame& incoming_ack); @@ -575,25 +573,6 @@ class NET_EXPORT_PRIVATE QuicConnection bool for_fec; }; - struct PendingWrite { - PendingWrite(QuicPacketSequenceNumber sequence_number, - TransmissionType transmission_type, - HasRetransmittableData retransmittable, - EncryptionLevel level, - QuicPacket* packet) - : sequence_number(sequence_number), - transmission_type(transmission_type), - retransmittable(retransmittable), - level(level), - packet(packet) { } - - QuicPacketSequenceNumber sequence_number; - TransmissionType transmission_type; - HasRetransmittableData retransmittable; - EncryptionLevel level; - QuicPacket* packet; - }; - class RetransmissionTimeComparator { public: bool operator()(const RetransmissionTime& lhs, @@ -721,18 +700,11 @@ class NET_EXPORT_PRIVATE QuicConnection // sent with the INITIAL encryption and the CHLO message was lost. std::deque<QuicEncryptedPacket*> undecryptable_packets_; - // When the version negotiation packet could not be sent because the socket - // was not writable, this is set to true. - bool pending_version_negotiation_packet_; - // When packets could not be sent because the socket was not writable, // they are added to this list. All corresponding frames are in // unacked_packets_ if they are to be retransmitted. QueuedPacketList queued_packets_; - // Contains information about the current write in progress, if any. - scoped_ptr<PendingWrite> pending_write_; - // True when the socket becomes unwritable. bool write_blocked_; diff --git a/net/quic/quic_connection_helper.cc b/net/quic/quic_connection_helper.cc index 1de5013..703151b 100644 --- a/net/quic/quic_connection_helper.cc +++ b/net/quic/quic_connection_helper.cc @@ -107,11 +107,13 @@ QuicRandom* QuicConnectionHelper::GetRandomGenerator() { return random_generator_; } -WriteResult QuicConnectionHelper::WritePacketToWire( - const QuicEncryptedPacket& packet) { +int QuicConnectionHelper::WritePacketToWire( + const QuicEncryptedPacket& packet, + int* error) { if (connection_->ShouldSimulateLostPacket()) { DLOG(INFO) << "Dropping packet due to fake packet loss."; - return WriteResult(WRITE_STATUS_OK, packet.length()); + *error = 0; + return packet.length(); } scoped_refptr<StringIOBuffer> buf( @@ -121,17 +123,16 @@ WriteResult QuicConnectionHelper::WritePacketToWire( packet.length(), base::Bind(&QuicConnectionHelper::OnWriteComplete, weak_factory_.GetWeakPtr())); - WriteStatus status = WRITE_STATUS_OK; - if (rv < 0) { + if (rv >= 0) { + *error = 0; + } else { if (rv != ERR_IO_PENDING) { UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv); - status = WRITE_STATUS_ERROR; - } else { - status = WRITE_STATUS_BLOCKED; } + *error = rv; + rv = -1; } - - return WriteResult(status, rv); + return rv; } bool QuicConnectionHelper::IsWriteBlockedDataBuffered() { diff --git a/net/quic/quic_connection_helper.h b/net/quic/quic_connection_helper.h index e530176..6667b95 100644 --- a/net/quic/quic_connection_helper.h +++ b/net/quic/quic_connection_helper.h @@ -45,8 +45,8 @@ class NET_EXPORT_PRIVATE QuicConnectionHelper virtual void SetConnection(QuicConnection* connection) OVERRIDE; virtual const QuicClock* GetClock() const OVERRIDE; virtual QuicRandom* GetRandomGenerator() OVERRIDE; - virtual WriteResult WritePacketToWire( - const QuicEncryptedPacket& packet) OVERRIDE; + virtual int WritePacketToWire(const QuicEncryptedPacket& packet, + int* error) OVERRIDE; virtual bool IsWriteBlockedDataBuffered() OVERRIDE; virtual bool IsWriteBlocked(int error) OVERRIDE; virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) OVERRIDE; diff --git a/net/quic/quic_connection_helper_test.cc b/net/quic/quic_connection_helper_test.cc index ffc6ee19..e228d12 100644 --- a/net/quic/quic_connection_helper_test.cc +++ b/net/quic/quic_connection_helper_test.cc @@ -10,7 +10,6 @@ #include "net/quic/crypto/quic_decrypter.h" #include "net/quic/crypto/quic_encrypter.h" #include "net/quic/quic_connection.h" -#include "net/quic/quic_protocol.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/quic_connection_peer.h" #include "net/quic/test_tools/quic_test_utils.h" @@ -410,9 +409,9 @@ TEST_F(QuicConnectionHelperTest, WritePacketToWire) { Initialize(); int len = GetWrite(0)->length(); - WriteResult result = helper_->WritePacketToWire(*GetWrite(0)); - EXPECT_EQ(len, result.bytes_written); - EXPECT_EQ(WRITE_STATUS_OK, result.status); + int error = 0; + EXPECT_EQ(len, helper_->WritePacketToWire(*GetWrite(0), &error)); + EXPECT_EQ(0, error); EXPECT_TRUE(AtEof()); } @@ -421,9 +420,9 @@ TEST_F(QuicConnectionHelperTest, WritePacketToWireAsync) { Initialize(); EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(Return(true)); - WriteResult result = helper_->WritePacketToWire(*GetWrite(0)); - EXPECT_EQ(-1, result.bytes_written); - EXPECT_EQ(WRITE_STATUS_BLOCKED, result.status); + int error = 0; + EXPECT_EQ(-1, helper_->WritePacketToWire(*GetWrite(0), &error)); + EXPECT_EQ(ERR_IO_PENDING, error); base::MessageLoop::current()->RunUntilIdle(); EXPECT_TRUE(AtEof()); } diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 25532e0..5195f43 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc @@ -33,15 +33,15 @@ base::Value* NetLogQuicPacketSentCallback( QuicPacketSequenceNumber sequence_number, EncryptionLevel level, size_t packet_size, - WriteResult result, + int rv, NetLog::LogLevel /* log_level */) { base::DictionaryValue* dict = new base::DictionaryValue(); dict->SetInteger("encryption_level", level); dict->SetString("packet_sequence_number", base::Uint64ToString(sequence_number)); dict->SetInteger("size", packet_size); - if (result.status != WRITE_STATUS_OK) { - dict->SetInteger("net_error", result.error_code); + if (rv < 0) { + dict->SetInteger("net_error", rv); } return dict; } @@ -255,11 +255,11 @@ void QuicConnectionLogger::OnPacketSent( QuicPacketSequenceNumber sequence_number, EncryptionLevel level, const QuicEncryptedPacket& packet, - WriteResult result) { + int rv) { net_log_.AddEvent( NetLog::TYPE_QUIC_SESSION_PACKET_SENT, base::Bind(&NetLogQuicPacketSentCallback, sequence_number, level, - packet.length(), result)); + packet.length(), rv)); } void QuicConnectionLogger:: OnPacketRetransmitted( diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index a7a8747..d498b12 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h @@ -6,7 +6,6 @@ #define NET_QUIC_QUIC_CONNECTION_LOGGER_H_ #include "net/quic/quic_connection.h" -#include "net/quic/quic_protocol.h" namespace net { @@ -29,7 +28,7 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, EncryptionLevel level, const QuicEncryptedPacket& packet, - WriteResult result) OVERRIDE; + int rv) OVERRIDE; virtual void OnPacketRetransmitted( QuicPacketSequenceNumber old_sequence_number, QuicPacketSequenceNumber new_sequence_number) OVERRIDE; diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index f861b1b..102bb33 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -243,9 +243,7 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { TestConnectionHelper(MockClock* clock, MockRandom* random_generator) : clock_(clock), random_generator_(random_generator), - last_packet_size_(0), blocked_(false), - is_write_blocked_data_buffered_(false), is_server_(true), use_tagging_decrypter_(false), packets_write_attempts_(0) { @@ -263,8 +261,8 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { return random_generator_; } - virtual WriteResult WritePacketToWire( - const QuicEncryptedPacket& packet) OVERRIDE { + virtual int WritePacketToWire(const QuicEncryptedPacket& packet, + int* error) OVERRIDE { ++packets_write_attempts_; if (packet.length() >= sizeof(final_bytes_of_last_packet_)) { @@ -295,14 +293,16 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { *visitor.version_negotiation_packet())); } if (blocked_) { - return WriteResult(WRITE_STATUS_BLOCKED, -1); + *error = ERR_IO_PENDING; + return -1; } + *error = 0; last_packet_size_ = packet.length(); - return WriteResult(WRITE_STATUS_OK, last_packet_size_); + return last_packet_size_; } virtual bool IsWriteBlockedDataBuffered() OVERRIDE { - return is_write_blocked_data_buffered_; + return false; } virtual bool IsWriteBlocked(int error) OVERRIDE { @@ -335,10 +335,6 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { void set_blocked(bool blocked) { blocked_ = blocked; } - void set_is_write_blocked_data_buffered(bool buffered) { - is_write_blocked_data_buffered_ = buffered; - } - void set_is_server(bool is_server) { is_server_ = is_server; } // final_bytes_of_last_packet_ returns the last four bytes of the previous @@ -364,7 +360,6 @@ class TestConnectionHelper : public QuicConnectionHelperInterface { scoped_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_; size_t last_packet_size_; bool blocked_; - bool is_write_blocked_data_buffered_; bool is_server_; uint32 final_bytes_of_last_packet_; bool use_tagging_decrypter_; @@ -1721,18 +1716,6 @@ TEST_P(QuicConnectionTest, ResumptionAlarmThenWriteBlocked) { EXPECT_TRUE(QuicConnectionPeer::IsWriteBlocked(&connection_)); } -TEST_P(QuicConnectionTest, WriteBlockedThenSent) { - helper_->set_blocked(true); - - helper_->set_is_write_blocked_data_buffered(true); - connection_.SendStreamData(1, "foo", 0, !kFin); - EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); - - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); - connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0)); - EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); -} - TEST_P(QuicConnectionTest, LimitPacketsPerNack) { EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); EXPECT_CALL(*send_algorithm_, OnIncomingAck(12, _, _)).Times(1); @@ -2746,49 +2729,6 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) { } } -TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) { - framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); - - QuicPacketHeader header; - header.public_header.guid = guid_; - header.public_header.reset_flag = false; - header.public_header.version_flag = true; - header.entropy_flag = false; - header.fec_flag = false; - header.packet_sequence_number = 12; - header.fec_group = 0; - - QuicFrames frames; - QuicFrame frame(&frame1_); - frames.push_back(frame); - scoped_ptr<QuicPacket> packet( - framer_.BuildUnsizedDataPacket(header, frames).packet); - scoped_ptr<QuicEncryptedPacket> encrypted( - framer_.EncryptPacket(ENCRYPTION_NONE, 12, *packet)); - - framer_.set_version(QuicVersionMax()); - connection_.set_is_server(true); - helper_->set_blocked(true); - connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); - EXPECT_EQ(0u, helper_->last_packet_size()); - EXPECT_TRUE(connection_.HasQueuedData()); - - helper_->set_blocked(false); - connection_.OnCanWrite(); - EXPECT_TRUE(helper_->version_negotiation_packet() != NULL); - - size_t num_versions = arraysize(kSupportedQuicVersions); - EXPECT_EQ(num_versions, - helper_->version_negotiation_packet()->versions.size()); - - // We expect all versions in kSupportedQuicVersions to be - // included in the packet. - for (size_t i = 0; i < num_versions; ++i) { - EXPECT_EQ(kSupportedQuicVersions[i], - helper_->version_negotiation_packet()->versions[i]); - } -} - TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) { // Start out with some unsupported version. QuicConnectionPeer::GetFramer(&connection_)->set_version_for_tests( @@ -3190,7 +3130,7 @@ class MockQuicConnectionDebugVisitor void(QuicPacketSequenceNumber, EncryptionLevel, const QuicEncryptedPacket&, - WriteResult)); + int)); MOCK_METHOD2(OnPacketRetransmitted, void(QuicPacketSequenceNumber, diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index c42d1fe..8532a22 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h @@ -377,8 +377,6 @@ enum QuicErrorCode { QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33, // A crypto message was received with an illegal parameter. QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34, - // An invalid channel id signature was supplied. - QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52, // A crypto message was received with a mandatory parameter missing. QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35, // A crypto message was received with a parameter that has no overlap @@ -407,7 +405,7 @@ enum QuicErrorCode { QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45, // No error. Used as bound while iterating. - QUIC_LAST_ERROR = 53, + QUIC_LAST_ERROR = 52, }; struct NET_EXPORT_PRIVATE QuicPacketPublicHeader { @@ -872,26 +870,6 @@ struct QuicConsumedData { bool fin_consumed; }; -enum WriteStatus { - WRITE_STATUS_OK, - WRITE_STATUS_BLOCKED, - WRITE_STATUS_ERROR, -}; - -// A struct used to return the result of write calls including either the number -// of bytes written or the error code, depending upon the status. -struct NET_EXPORT_PRIVATE WriteResult { - WriteResult(WriteStatus status, int bytes_written_or_error_code) : - status(status), bytes_written(bytes_written_or_error_code) { - } - - WriteStatus status; - union { - int bytes_written; // only valid when status is OK - int error_code; // only valid when status is ERROR - }; -}; - } // namespace net #endif // NET_QUIC_QUIC_PROTOCOL_H_ diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc index 1cd261a..81868ac 100644 --- a/net/quic/quic_received_packet_manager.cc +++ b/net/quic/quic_received_packet_manager.cc @@ -98,13 +98,11 @@ QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash( ReceivedEntropyMap::const_iterator it = packets_entropy_.upper_bound(sequence_number); // When this map is empty we should only query entropy for - // received_info_.largest_observed, since no other entropy can be correctly - // calculated, because we're not storing the entropy for any prior packets. + // |largest_received_sequence_number_|. // TODO(rtenneti): add support for LOG_IF_EVERY_N_SEC to chromium. - // LOG_IF_EVERY_N_SEC(DFATAL, it == packets_entropy_.end(), 10) - LOG_IF(DFATAL, it == packets_entropy_.end()) - << "EntropyHash may be unknown. largest_received: " - << received_info_.largest_observed + // LOG_IF_EVERY_N_SEC(WARNING, it != packets_entropy_.end(), 10) + LOG_IF(WARNING, it != packets_entropy_.end()) + << "largest_received: " << received_info_.largest_observed << " sequence_number: " << sequence_number; // TODO(satyamshekhar): Make this O(1). diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index 66eea78..a9f26b8 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc @@ -131,9 +131,15 @@ void QuicSentPacketManager::OnRetransmittedPacket( void QuicSentPacketManager::OnIncomingAck( const ReceivedPacketInfo& received_info, - bool is_truncated_ack) { - HandleAckForSentPackets(received_info, is_truncated_ack); - HandleAckForSentFecPackets(received_info); + bool is_truncated_ack, + SequenceNumberSet* acked_packets) { + HandleAckForSentPackets(received_info, is_truncated_ack, acked_packets); + HandleAckForSentFecPackets(received_info, acked_packets); + + if (acked_packets->size() > 0) { + // The AckNotifierManager should be informed of every ACKed sequence number. + ack_notifier_manager_.OnIncomingAck(*acked_packets); + } } void QuicSentPacketManager::DiscardUnackedPacket( @@ -143,7 +149,8 @@ void QuicSentPacketManager::DiscardUnackedPacket( void QuicSentPacketManager::HandleAckForSentPackets( const ReceivedPacketInfo& received_info, - bool is_truncated_ack) { + bool is_truncated_ack, + SequenceNumberSet* acked_packets) { // Go through the packets we have not received an ack for and see if this // incoming_ack shows they've been seen by the peer. UnackedPacketMap::iterator it = unacked_packets_.begin(); @@ -159,11 +166,12 @@ void QuicSentPacketManager::HandleAckForSentPackets( DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; // If data is associated with the most recent transmission of this // packet, then inform the caller. + QuicPacketSequenceNumber most_recent_transmission = + GetMostRecentTransmission(sequence_number); + if (HasRetransmittableFrames(most_recent_transmission)) { + acked_packets->insert(most_recent_transmission); + } it = MarkPacketReceivedByPeer(sequence_number); - - // The AckNotifierManager is informed of every ACKed sequence number. - ack_notifier_manager_.OnPacketAcked(sequence_number); - continue; } @@ -373,7 +381,8 @@ void QuicSentPacketManager::DiscardPacket( } void QuicSentPacketManager::HandleAckForSentFecPackets( - const ReceivedPacketInfo& received_info) { + const ReceivedPacketInfo& received_info, + SequenceNumberSet* acked_packets) { UnackedFecPacketMap::iterator it = unacked_fec_packets_.begin(); while (it != unacked_fec_packets_.end()) { QuicPacketSequenceNumber sequence_number = it->first; @@ -383,6 +392,7 @@ void QuicSentPacketManager::HandleAckForSentFecPackets( if (!IsAwaitingPacket(received_info, sequence_number)) { DVLOG(1) << ENDPOINT << "Got an ack for fec packet: " << sequence_number; + acked_packets->insert(sequence_number); unacked_fec_packets_.erase(it++); } else { // TODO(rch): treat these packets more consistently. They should diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h index cf4edc9..4987bcc 100644 --- a/net/quic/quic_sent_packet_manager.h +++ b/net/quic/quic_sent_packet_manager.h @@ -79,7 +79,8 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Processes the ReceivedPacketInfo data from the incoming ack. void OnIncomingAck(const ReceivedPacketInfo& received_info, - bool is_truncated_ack); + bool is_truncated_ack, + SequenceNumberSet* acked_packets); // Discards any information for the packet corresponding to |sequence_number|. // If this packet has been retransmitted, information on those packets @@ -186,10 +187,12 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { // Process the incoming ack looking for newly ack'd data packets. void HandleAckForSentPackets(const ReceivedPacketInfo& received_info, - bool is_truncated_ack); + bool is_truncated_ack, + SequenceNumberSet* acked_packets); // Process the incoming ack looking for newly ack'd FEC packets. - void HandleAckForSentFecPackets(const ReceivedPacketInfo& received_info); + void HandleAckForSentFecPackets(const ReceivedPacketInfo& received_info, + SequenceNumberSet* acked_packets); // Marks |sequence_number| as having been seen by the peer. Returns an // iterator to the next remaining unacked packet. diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc index 201d9a1..bfd4d4a 100644 --- a/net/quic/quic_sent_packet_manager_test.cc +++ b/net/quic/quic_sent_packet_manager_test.cc @@ -170,11 +170,14 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAck) { ReceivedPacketInfo received_info; received_info.largest_observed = 2; received_info.missing_packets.insert(1); - manager_.OnIncomingAck(received_info, false); + SequenceNumberSet acked; + manager_.OnIncomingAck(received_info, false, &acked); // No unacked packets remain. VerifyUnackedPackets(NULL, 0); VerifyRetransmittablePackets(NULL, 0); + QuicPacketSequenceNumber expected_acked[] = { 2 }; + VerifyAckedPackets(expected_acked, arraysize(expected_acked), acked); } TEST_P(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { @@ -187,7 +190,8 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { // Ack 1. ReceivedPacketInfo received_info; received_info.largest_observed = 1; - manager_.OnIncomingAck(received_info, false); + SequenceNumberSet acked; + manager_.OnIncomingAck(received_info, false, &acked); // There should no longer be a pending retransmission. EXPECT_FALSE(manager_.HasPendingRetransmissions()); @@ -195,6 +199,8 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) { // No unacked packets remain. VerifyUnackedPackets(NULL, 0); VerifyRetransmittablePackets(NULL, 0); + QuicPacketSequenceNumber expected_acked[] = { 1 }; + VerifyAckedPackets(expected_acked, arraysize(expected_acked), acked); } TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPrevious) { @@ -211,13 +217,16 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPrevious) { ReceivedPacketInfo received_info; received_info.largest_observed = 2; received_info.missing_packets.insert(2); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(2, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); // 2 remains unacked, but no packets have retransmittable data. QuicPacketSequenceNumber unacked[] = { 2 }; VerifyUnackedPackets(unacked, arraysize(unacked)); VerifyRetransmittablePackets(NULL, 0); + QuicPacketSequenceNumber expected_acked[] = { 2 }; + VerifyAckedPackets(expected_acked, arraysize(expected_acked), acked); } TEST_P(QuicSentPacketManagerTest, TruncatedAck) { @@ -237,7 +246,8 @@ TEST_P(QuicSentPacketManagerTest, TruncatedAck) { received_info.largest_observed = 2; received_info.missing_packets.insert(1); received_info.missing_packets.insert(2); - manager_.OnIncomingAck(received_info, true); + SequenceNumberSet acked; + manager_.OnIncomingAck(received_info, true, &acked); // High water mark will be raised. QuicPacketSequenceNumber unacked[] = { 2, 3, 4 }; @@ -260,8 +270,9 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { ReceivedPacketInfo received_info; received_info.largest_observed = 3; received_info.missing_packets.insert(2); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(2, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); QuicPacketSequenceNumber unacked[] = { 2 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -278,9 +289,10 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { received_info.largest_observed = 5; received_info.missing_packets.insert(2); received_info.missing_packets.insert(4); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(2, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(4, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); QuicPacketSequenceNumber unacked[] = { 2, 4 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -298,10 +310,11 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { received_info.missing_packets.insert(2); received_info.missing_packets.insert(4); received_info.missing_packets.insert(6); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(2, 3)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(4, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(6, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); QuicPacketSequenceNumber unacked[] = { 2, 4, 6 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -322,11 +335,12 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { received_info.missing_packets.insert(6); received_info.missing_packets.insert(8); received_info.missing_packets.insert(9); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(4, 3)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(6, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(8, 1)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(9, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); QuicPacketSequenceNumber unacked[] = { 2, 4, 6, 8, 9 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -350,12 +364,13 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { received_info.missing_packets.insert(9); received_info.missing_packets.insert(11); received_info.missing_packets.insert(12); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(6, 3)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(8, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(9, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(11, 1)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(12, 1)).Times(1); - manager_.OnIncomingAck(received_info, false); + manager_.OnIncomingAck(received_info, false, &acked); QuicPacketSequenceNumber unacked[] = { 2, 4, 6, 8, 9, 11, 12 }; VerifyUnackedPackets(unacked, arraysize(unacked)); @@ -378,11 +393,12 @@ TEST_P(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) { received_info.missing_packets.insert(9); received_info.missing_packets.insert(11); received_info.missing_packets.insert(12); + SequenceNumberSet acked; EXPECT_CALL(helper_, OnPacketNacked(8, 3)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(9, 3)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(11, 2)).Times(1); EXPECT_CALL(helper_, OnPacketNacked(12, 2)).Times(1); - manager_.OnIncomingAck(received_info, true); + manager_.OnIncomingAck(received_info, true, &acked); // Truncated ack raises the high water mark by clearing out 2, 4, and 6. QuicPacketSequenceNumber unacked[] = { 8, 9, 11, 12, 14, 15, 16 }; @@ -446,7 +462,8 @@ TEST_P(QuicSentPacketManagerTest, GetLeastUnackedFecPacketAndDiscard) { // Ack 2. ReceivedPacketInfo received_info; received_info.largest_observed = 2; - manager_.OnIncomingAck(received_info, false); + SequenceNumberSet acked; + manager_.OnIncomingAck(received_info, false, &acked); EXPECT_EQ(3u, manager_.GetLeastUnackedFecPacket()); diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc index a5a0eec..cfb3cb7 100644 --- a/net/quic/quic_utils.cc +++ b/net/quic/quic_utils.cc @@ -188,7 +188,6 @@ const char* QuicUtils::ErrorToString(QuicErrorCode error) { RETURN_STRING_LITERAL(QUIC_CRYPTO_DUPLICATE_TAG); RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT); RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED); - RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE); RETURN_STRING_LITERAL(QUIC_LAST_ERROR); // Intentionally have no default case, so we'll break the build // if we add errors and don't put them here. diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index fd29824..ffb433e 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h @@ -197,8 +197,8 @@ class MockHelper : public QuicConnectionHelperInterface { const QuicClock* GetClock() const; QuicRandom* GetRandomGenerator(); void AdvanceTime(QuicTime::Delta delta); - MOCK_METHOD1(WritePacketToWire, - WriteResult(const QuicEncryptedPacket& packet)); + MOCK_METHOD2(WritePacketToWire, int(const QuicEncryptedPacket& packet, + int* error)); MOCK_METHOD0(IsWriteBlockedDataBuffered, bool()); MOCK_METHOD1(IsWriteBlocked, bool(int stream_id)); virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate); diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 43684c4..7305127 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc @@ -534,13 +534,14 @@ class WrongAddressWriter : public QuicPacketWriter { self_address_ = IPEndPoint(ip, 0); } - virtual WriteResult WritePacket( - const char* buffer, size_t buf_len, - const IPAddressNumber& real_self_address, - const IPEndPoint& peer_address, - QuicBlockedWriterInterface* blocked_writer) OVERRIDE { + virtual int WritePacket(const char* buffer, size_t buf_len, + const IPAddressNumber& real_self_address, + const IPEndPoint& peer_address, + QuicBlockedWriterInterface* blocked_writer, + int* error) OVERRIDE { return QuicSocketUtils::WritePacket(fd_, buffer, buf_len, - self_address_.address(), peer_address); + self_address_.address(), peer_address, + error); } IPEndPoint self_address_; diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index b22b9dc..8550ef0 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc @@ -53,22 +53,25 @@ QuicDispatcher::~QuicDispatcher() { STLDeleteElements(&closed_session_list_); } -WriteResult QuicDispatcher::WritePacket(const char* buffer, size_t buf_len, - const IPAddressNumber& self_address, - const IPEndPoint& peer_address, - QuicBlockedWriterInterface* writer) { +int QuicDispatcher::WritePacket(const char* buffer, size_t buf_len, + const IPAddressNumber& self_address, + const IPEndPoint& peer_address, + QuicBlockedWriterInterface* writer, + int* error) { if (write_blocked_) { write_blocked_list_.insert(make_pair(writer, true)); - return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN); + *error = EAGAIN; + return -1; } - WriteResult result = QuicSocketUtils::WritePacket(fd_, buffer, buf_len, - self_address, peer_address); - if (result.status == WRITE_STATUS_BLOCKED) { + int rc = QuicSocketUtils::WritePacket(fd_, buffer, buf_len, + self_address, peer_address, + error); + if (rc == -1 && (*error == EWOULDBLOCK || *error == EAGAIN)) { write_blocked_list_.insert(make_pair(writer, true)); write_blocked_ = true; } - return result; + return rc; } void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 584965c..465601c 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h @@ -60,11 +60,11 @@ class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner { virtual ~QuicDispatcher(); // QuicPacketWriter - virtual WriteResult WritePacket( - const char* buffer, size_t buf_len, - const IPAddressNumber& self_address, - const IPEndPoint& peer_address, - QuicBlockedWriterInterface* writer) OVERRIDE; + virtual int WritePacket(const char* buffer, size_t buf_len, + const IPAddressNumber& self_address, + const IPEndPoint& peer_address, + QuicBlockedWriterInterface* writer, + int* error) OVERRIDE; virtual void ProcessPacket(const IPEndPoint& server_address, const IPEndPoint& client_address, diff --git a/net/tools/quic/quic_epoll_connection_helper.cc b/net/tools/quic/quic_epoll_connection_helper.cc index fc68b8f..9c33847 100644 --- a/net/tools/quic/quic_epoll_connection_helper.cc +++ b/net/tools/quic/quic_epoll_connection_helper.cc @@ -98,11 +98,13 @@ QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() { return random_generator_; } -WriteResult QuicEpollConnectionHelper::WritePacketToWire( - const QuicEncryptedPacket& packet) { +int QuicEpollConnectionHelper::WritePacketToWire( + const QuicEncryptedPacket& packet, + int* error) { if (connection_->ShouldSimulateLostPacket()) { DLOG(INFO) << "Dropping packet due to fake packet loss."; - return WriteResult(WRITE_STATUS_OK, packet.length()); + *error = 0; + return packet.length(); } // If we have a writer, delgate the write to it. @@ -110,12 +112,14 @@ WriteResult QuicEpollConnectionHelper::WritePacketToWire( return writer_->WritePacket(packet.data(), packet.length(), connection_->self_address().address(), connection_->peer_address(), - connection_); + connection_, + error); } else { return QuicSocketUtils::WritePacket( fd_, packet.data(), packet.length(), connection_->self_address().address(), - connection_->peer_address()); + connection_->peer_address(), + error); } } diff --git a/net/tools/quic/quic_epoll_connection_helper.h b/net/tools/quic/quic_epoll_connection_helper.h index a7e6f01..5bd526f 100644 --- a/net/tools/quic/quic_epoll_connection_helper.h +++ b/net/tools/quic/quic_epoll_connection_helper.h @@ -43,8 +43,8 @@ class QuicEpollConnectionHelper : public QuicConnectionHelperInterface { virtual void SetConnection(QuicConnection* connection) OVERRIDE; virtual const QuicClock* GetClock() const OVERRIDE; virtual QuicRandom* GetRandomGenerator() OVERRIDE; - virtual WriteResult WritePacketToWire( - const QuicEncryptedPacket& packet) OVERRIDE; + virtual int WritePacketToWire(const QuicEncryptedPacket& packet, + int* error) OVERRIDE; virtual bool IsWriteBlockedDataBuffered() OVERRIDE; virtual bool IsWriteBlocked(int error) OVERRIDE; virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) OVERRIDE; diff --git a/net/tools/quic/quic_epoll_connection_helper_test.cc b/net/tools/quic/quic_epoll_connection_helper_test.cc index 0e5cd48..154c393 100644 --- a/net/tools/quic/quic_epoll_connection_helper_test.cc +++ b/net/tools/quic/quic_epoll_connection_helper_test.cc @@ -39,14 +39,15 @@ class TestConnectionHelper : public QuicEpollConnectionHelper { : QuicEpollConnectionHelper(fd, eps) { } - virtual WriteResult WritePacketToWire( - const QuicEncryptedPacket& packet) OVERRIDE { + virtual int WritePacketToWire(const QuicEncryptedPacket& packet, + int* error) OVERRIDE { QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), true); FramerVisitorCapturingFrames visitor; framer.set_visitor(&visitor); EXPECT_TRUE(framer.ProcessPacket(packet)); header_ = *visitor.header(); - return WriteResult(WRITE_STATUS_OK, packet.length()); + *error = 0; + return packet.length(); } QuicPacketHeader* header() { return &header_; } diff --git a/net/tools/quic/quic_packet_writer.h b/net/tools/quic/quic_packet_writer.h index 2d70e09..b10e852 100644 --- a/net/tools/quic/quic_packet_writer.h +++ b/net/tools/quic/quic_packet_writer.h @@ -6,12 +6,10 @@ #define NET_TOOLS_QUIC_QUIC_PACKET_WRITER_H_ #include "net/base/ip_endpoint.h" -#include "net/quic/quic_protocol.h" namespace net { class QuicBlockedWriterInterface; -struct WriteResult; namespace tools { @@ -22,11 +20,11 @@ class QuicPacketWriter { public: virtual ~QuicPacketWriter() {} - virtual WriteResult WritePacket( - const char* buffer, size_t buf_len, - const net::IPAddressNumber& self_address, - const net::IPEndPoint& peer_address, - QuicBlockedWriterInterface* blocked_writer) = 0; + virtual int WritePacket(const char* buffer, size_t buf_len, + const net::IPAddressNumber& self_address, + const net::IPEndPoint& peer_address, + QuicBlockedWriterInterface* blocked_writer, + int* error) = 0; }; } // namespace tools diff --git a/net/tools/quic/quic_socket_utils.cc b/net/tools/quic/quic_socket_utils.cc index 87071a6..6535d57 100644 --- a/net/tools/quic/quic_socket_utils.cc +++ b/net/tools/quic/quic_socket_utils.cc @@ -12,7 +12,6 @@ #include <string> #include "base/logging.h" -#include "net/quic/quic_protocol.h" #ifndef SO_RXQ_OVFL #define SO_RXQ_OVFL 40 @@ -51,7 +50,7 @@ IPAddressNumber QuicSocketUtils::GetAddressFromMsghdr(struct msghdr *hdr) { // static bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr *hdr, - int *dropped_packets) { + int *dropped_packets) { if (hdr->msg_controllen > 0) { struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR(hdr); @@ -80,9 +79,9 @@ int QuicSocketUtils::SetGetAddressInfo(int fd, int address_family) { // static int QuicSocketUtils::ReadPacket(int fd, char* buffer, size_t buf_len, - int* dropped_packets, - IPAddressNumber* self_address, - IPEndPoint* peer_address) { + int* dropped_packets, + IPAddressNumber* self_address, + IPEndPoint* peer_address) { CHECK(peer_address != NULL); const int kSpaceForOverflowAndIp = CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(in6_pktinfo)); @@ -136,11 +135,10 @@ int QuicSocketUtils::ReadPacket(int fd, char* buffer, size_t buf_len, } // static -WriteResult QuicSocketUtils::WritePacket(int fd, - const char* buffer, - size_t buf_len, - const IPAddressNumber& self_address, - const IPEndPoint& peer_address) { +int QuicSocketUtils::WritePacket(int fd, const char* buffer, size_t buf_len, + const IPAddressNumber& self_address, + const IPEndPoint& peer_address, + int* error) { sockaddr_storage raw_address; socklen_t address_len = sizeof(raw_address); CHECK(peer_address.ToSockAddr( @@ -192,11 +190,8 @@ WriteResult QuicSocketUtils::WritePacket(int fd, } int rc = sendmsg(fd, &hdr, 0); - if (rc >= 0) { - return WriteResult(WRITE_STATUS_OK, rc); - } - return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK) ? - WRITE_STATUS_BLOCKED : WRITE_STATUS_ERROR, errno); + *error = (rc >= 0) ? 0 : errno; + return rc; } } // namespace tools diff --git a/net/tools/quic/quic_socket_utils.h b/net/tools/quic/quic_socket_utils.h index 8f0feff..bfacc6c 100644 --- a/net/tools/quic/quic_socket_utils.h +++ b/net/tools/quic/quic_socket_utils.h @@ -12,7 +12,6 @@ #include <string> #include "net/base/ip_endpoint.h" -#include "net/quic/quic_protocol.h" namespace net { namespace tools { @@ -46,13 +45,12 @@ class QuicSocketUtils { IPAddressNumber* self_address, IPEndPoint* peer_address); - // Writes buf_len to the socket. If writing is successful, sets the result's - // status to WRITE_STATUS_OK and sets bytes_written. Otherwise sets the - // result's status to WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and sets - // error_code to errno. - static WriteResult WritePacket(int fd, const char* buffer, size_t buf_len, - const IPAddressNumber& self_address, - const IPEndPoint& peer_address); + // Writes buf_len to the socket. If writing is successful returns the number + // of bytes written otherwise returns -1 and sets error to errno. + static int WritePacket(int fd, const char* buffer, size_t buf_len, + const IPAddressNumber& self_address, + const IPEndPoint& peer_address, + int* error); }; } // namespace tools diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc index 345ddb2..a2fc4f8 100644 --- a/net/tools/quic/quic_time_wait_list_manager.cc +++ b/net/tools/quic/quic_time_wait_list_manager.cc @@ -263,19 +263,22 @@ void QuicTimeWaitListManager::SendOrQueuePacket(QueuedPacket* packet) { void QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { DCHECK(!is_write_blocked_); - WriteResult result = writer_->WritePacket( - queued_packet->packet()->data(), - queued_packet->packet()->length(), - queued_packet->server_address().address(), - queued_packet->client_address(), - this); - - if (result.status == WRITE_STATUS_BLOCKED) { - is_write_blocked_ = true; - } else if (result.status == WRITE_STATUS_ERROR) { - LOG(WARNING) << "Received unknown error while sending reset packet to " - << queued_packet->client_address().ToString() << ": " - << strerror(result.error_code); + int error; + int rc = writer_->WritePacket(queued_packet->packet()->data(), + queued_packet->packet()->length(), + queued_packet->server_address().address(), + queued_packet->client_address(), + this, + &error); + + if (rc == -1) { + if (error == EAGAIN || error == EWOULDBLOCK) { + is_write_blocked_ = true; + } else { + LOG(WARNING) << "Received unknown error while sending reset packet to " + << queued_packet->client_address().ToString() << ": " + << strerror(error); + } } } diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc index 64abb61..8f59687 100644 --- a/net/tools/quic/quic_time_wait_list_manager_test.cc +++ b/net/tools/quic/quic_time_wait_list_manager_test.cc @@ -195,10 +195,11 @@ TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) { EXPECT_CALL(writer_, WritePacket(_, _, server_address_.address(), client_address_, - &time_wait_list_manager_)) + &time_wait_list_manager_, + _)) .With(Args<0, 1>(PublicResetPacketEq(guid_, kRandomSequenceNumber))) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); + .WillOnce(Return(packet->length())); ProcessPacket(guid_, *packet); } @@ -209,7 +210,7 @@ TEST_F(QuicTimeWaitListManagerTest, DropInvalidPacket) { QuicEncryptedPacket packet(buffer, arraysize(buffer)); ProcessPacket(guid_, packet); // Will get called for a valid packet since received packet count = 1 (2 ^ 0). - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0); + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)).Times(0); } TEST_F(QuicTimeWaitListManagerTest, DropPublicResetPacket) { @@ -224,7 +225,7 @@ TEST_F(QuicTimeWaitListManagerTest, DropPublicResetPacket) { QuicFramer::BuildPublicResetPacket(packet)); ProcessPacket(guid_, *public_reset_packet); // Will get called for a data packet since received packet count = 1 (2 ^ 0). - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)) .Times(0); } @@ -234,8 +235,8 @@ TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) { scoped_ptr<QuicEncryptedPacket> packet( ConstructEncryptedPacket(guid_, sequence_number)); if ((sequence_number & (sequence_number - 1)) == 0) { - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)) + .WillOnce(Return(1)); } ProcessPacket(guid_, *packet); // Send public reset with exponential back off. @@ -293,10 +294,11 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) { EXPECT_CALL(writer_, WritePacket(_, _, server_address_.address(), client_address_, - &time_wait_list_manager_)) + &time_wait_list_manager_, + _)) .With(Args<0, 1>(PublicResetPacketEq(guid, sequence_number))) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); + .WillOnce(Return(packet->length())); ProcessPacket(guid, *packet); EXPECT_FALSE(time_wait_list_manager_.is_write_blocked()); @@ -304,10 +306,11 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) { EXPECT_CALL(writer_, WritePacket(_, _, server_address_.address(), client_address_, - &time_wait_list_manager_)) + &time_wait_list_manager_, + _)) .With(Args<0, 1>(PublicResetPacketEq(guid, sequence_number))) - .WillOnce(Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))); + .WillOnce(DoAll(SetArgPointee<5>(EAGAIN), Return(-1))); ProcessPacket(guid, *packet); // 3rd packet. No public reset should be sent; ProcessPacket(guid, *packet); @@ -320,7 +323,7 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) { QuicPacketSequenceNumber other_sequence_number = 23423; scoped_ptr<QuicEncryptedPacket> other_packet( ConstructEncryptedPacket(other_guid, other_sequence_number)); - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)) .Times(0); ProcessPacket(other_guid, *other_packet); @@ -328,18 +331,19 @@ TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) { EXPECT_CALL(writer_, WritePacket(_, _, server_address_.address(), client_address_, - &time_wait_list_manager_)) + &time_wait_list_manager_, + _)) .With(Args<0, 1>(PublicResetPacketEq(guid, sequence_number))) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); + .WillOnce(Return(packet->length())); EXPECT_CALL(writer_, WritePacket(_, _, server_address_.address(), client_address_, - &time_wait_list_manager_)) + &time_wait_list_manager_, + _)) .With(Args<0, 1>(PublicResetPacketEq(other_guid, other_sequence_number))) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, - other_packet->length()))); + .WillOnce(Return(other_packet->length())); time_wait_list_manager_.OnCanWrite(); EXPECT_FALSE(time_wait_list_manager_.is_write_blocked()); } @@ -353,8 +357,7 @@ TEST_F(QuicTimeWaitListManagerTest, MakeSureFramerUsesCorrectVersion) { packet.reset(ConstructEncryptedPacket(guid_, kRandomSequenceNumber)); // Reset packet should be written, using the minimum quic version. - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(1) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)).Times(1); ProcessPacket(guid_, *packet); EXPECT_EQ(time_wait_list_manager_.version(), QuicVersionMin()); @@ -366,8 +369,7 @@ TEST_F(QuicTimeWaitListManagerTest, MakeSureFramerUsesCorrectVersion) { packet.reset(ConstructEncryptedPacket(guid_, kRandomSequenceNumber)); // Reset packet should be written, using the maximum quic version. - EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(1) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); + EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)).Times(1); ProcessPacket(guid_, *packet); EXPECT_EQ(time_wait_list_manager_.version(), QuicVersionMax()); } diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h index 2710a56..dffa255 100644 --- a/net/tools/quic/test_tools/quic_test_utils.h +++ b/net/tools/quic/test_tools/quic_test_utils.h @@ -125,12 +125,12 @@ class MockPacketWriter : public QuicPacketWriter { MockPacketWriter(); virtual ~MockPacketWriter(); - MOCK_METHOD5(WritePacket, - WriteResult(const char* buffer, - size_t buf_len, - const IPAddressNumber& self_address, - const IPEndPoint& peer_address, - QuicBlockedWriterInterface* blocked_writer)); + MOCK_METHOD6(WritePacket, int(const char* buffer, + size_t buf_len, + const IPAddressNumber& self_address, + const IPEndPoint& peer_address, + QuicBlockedWriterInterface* blocked_writer, + int* error)); }; } // namespace test |