Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Unified Diff: net/quic/quic_connection.cc

Issue 515303003: Landing Recent QUIC Changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bug fix for 409191 Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_logger.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_connection.cc
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index ab1e0fe8de4158f8b83c41e962a17843d4154a26..4adf6246d7ef9c061c2953ea6ed5c9e31e5829d7 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -154,35 +154,14 @@ class PingAlarm : public QuicAlarm::Delegate {
DISALLOW_COPY_AND_ASSIGN(PingAlarm);
};
-QuicConnection::PacketType GetPacketType(
- const RetransmittableFrames* retransmittable_frames) {
- if (!retransmittable_frames) {
- return QuicConnection::NORMAL;
- }
- for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) {
- if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) {
- return QuicConnection::CONNECTION_CLOSE;
- }
- }
- return QuicConnection::NORMAL;
-}
-
} // namespace
QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet,
EncryptionLevel level,
TransmissionType transmission_type)
- : sequence_number(packet.sequence_number),
- packet(packet.packet),
+ : serialized_packet(packet),
encryption_level(level),
- transmission_type(transmission_type),
- retransmittable((transmission_type != NOT_RETRANSMISSION ||
- packet.retransmittable_frames != NULL) ?
- HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA),
- handshake(packet.retransmittable_frames == NULL ?
- NOT_HANDSHAKE : packet.retransmittable_frames->HasCryptoHandshake()),
- type(GetPacketType(packet.retransmittable_frames)),
- length(packet.packet->length()) {
+ transmission_type(transmission_type) {
}
#define ENDPOINT (is_server_ ? "Server: " : " Client: ")
@@ -262,7 +241,7 @@ QuicConnection::~QuicConnection() {
STLDeleteValues(&group_map_);
for (QueuedPacketList::iterator it = queued_packets_.begin();
it != queued_packets_.end(); ++it) {
- delete it->packet;
+ delete it->serialized_packet.packet;
}
}
@@ -300,13 +279,15 @@ void QuicConnection::OnError(QuicFramer* framer) {
void QuicConnection::OnPacket() {
DCHECK(last_stream_frames_.empty() &&
+ last_ack_frames_.empty() &&
+ last_congestion_frames_.empty() &&
+ last_stop_waiting_frames_.empty() &&
+ last_rst_frames_.empty() &&
last_goaway_frames_.empty() &&
last_window_update_frames_.empty() &&
last_blocked_frames_.empty() &&
- last_rst_frames_.empty() &&
- last_ack_frames_.empty() &&
- last_congestion_frames_.empty() &&
- last_stop_waiting_frames_.empty());
+ last_ping_frames_.empty() &&
+ last_close_frames_.empty());
}
void QuicConnection::OnPublicResetPacket(
@@ -363,6 +344,9 @@ bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) {
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(received_version);
+ if (debug_visitor_.get() != NULL) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(received_version);
+ }
DVLOG(1) << ENDPOINT << "version negotiated " << received_version;
// Store the new version.
@@ -489,6 +473,9 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
DCHECK_EQ(header.public_header.versions[0], version());
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(version());
+ if (debug_visitor_.get() != NULL) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
+ }
}
} else {
DCHECK(!header.public_header.version_flag);
@@ -497,6 +484,9 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
packet_generator_.StopSendingVersion();
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(version());
+ if (debug_visitor_.get() != NULL) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
+ }
}
}
@@ -617,6 +607,7 @@ bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
if (debug_visitor_.get() != NULL) {
debug_visitor_->OnPingFrame(frame);
}
+ last_ping_frames_.push_back(frame);
return true;
}
@@ -778,17 +769,17 @@ void QuicConnection::OnPacketComplete() {
DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got")
<< " packet " << last_header_.packet_sequence_number
- << " with " << last_ack_frames_.size() << " acks, "
+ << " with " << last_stream_frames_.size()<< " stream frames "
+ << last_ack_frames_.size() << " acks, "
<< last_congestion_frames_.size() << " congestions, "
<< last_stop_waiting_frames_.size() << " stop_waiting, "
+ << last_rst_frames_.size() << " rsts, "
<< last_goaway_frames_.size() << " goaways, "
<< last_window_update_frames_.size() << " window updates, "
<< last_blocked_frames_.size() << " blocked, "
- << last_rst_frames_.size() << " rsts, "
+ << last_ping_frames_.size() << " pings, "
<< last_close_frames_.size() << " closes, "
- << last_stream_frames_.size()
- << " stream frames for "
- << last_header_.public_header.connection_id;
+ << "for " << last_header_.public_header.connection_id;
// Call MaybeQueueAck() before recording the received packet, since we want
// to trigger an ack if the newly received packet was previously missing.
@@ -881,13 +872,15 @@ void QuicConnection::MaybeQueueAck() {
void QuicConnection::ClearLastFrames() {
last_stream_frames_.clear();
+ last_ack_frames_.clear();
+ last_congestion_frames_.clear();
+ last_stop_waiting_frames_.clear();
+ last_rst_frames_.clear();
last_goaway_frames_.clear();
last_window_update_frames_.clear();
last_blocked_frames_.clear();
- last_rst_frames_.clear();
- last_ack_frames_.clear();
- last_stop_waiting_frames_.clear();
- last_congestion_frames_.clear();
+ last_ping_frames_.clear();
+ last_close_frames_.clear();
}
QuicAckFrame* QuicConnection::CreateAckFrame() {
@@ -913,7 +906,8 @@ bool QuicConnection::ShouldLastPacketInstigateAck() const {
!last_goaway_frames_.empty() ||
!last_rst_frames_.empty() ||
!last_window_update_frames_.empty() ||
- !last_blocked_frames_.empty()) {
+ !last_blocked_frames_.empty() ||
+ !last_ping_frames_.empty()) {
return true;
}
@@ -1212,16 +1206,10 @@ void QuicConnection::WriteQueuedPackets() {
}
QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
- while (!writer_->IsWriteBlocked() &&
- packet_iterator != queued_packets_.end()) {
- if (WritePacket(*packet_iterator)) {
- delete packet_iterator->packet;
- packet_iterator = queued_packets_.erase(packet_iterator);
- } else {
- // Continue, because some queued packets may still be writable.
- // This can happen if a retransmit send fails.
- ++packet_iterator;
- }
+ while (packet_iterator != queued_packets_.end() &&
+ WritePacket(*packet_iterator)) {
+ delete packet_iterator->serialized_packet.packet;
+ packet_iterator = queued_packets_.erase(packet_iterator);
}
}
@@ -1231,8 +1219,7 @@ void QuicConnection::WritePendingRetransmissions() {
while (sent_packet_manager_.HasPendingRetransmissions()) {
const QuicSentPacketManager::PendingRetransmission pending =
sent_packet_manager_.NextPendingRetransmission();
- if (GetPacketType(&pending.retransmittable_frames) == NORMAL &&
- !CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+ if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
break;
}
@@ -1316,22 +1303,17 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
return true;
}
-bool QuicConnection::WritePacket(QueuedPacket packet) {
- QuicPacketSequenceNumber sequence_number = packet.sequence_number;
+bool QuicConnection::WritePacket(const QueuedPacket& packet) {
+ QuicPacketSequenceNumber sequence_number =
+ packet.serialized_packet.sequence_number;
if (ShouldDiscardPacket(packet.encryption_level,
sequence_number,
- packet.retransmittable)) {
+ IsRetransmittable(packet))) {
++stats_.packets_discarded;
return true;
}
-
- // If the packet is CONNECTION_CLOSE, we need to try to send it immediately
- // and encrypt it to hand it off to TimeWaitListManager.
- // If the packet is QUEUED, we don't re-consult the congestion control.
- // This ensures packets are sent in sequence number order.
- // TODO(ianswett): The congestion control should have been consulted before
- // serializing the packet, so this could be turned into a LOG_IF(DFATAL).
- if (packet.type == NORMAL && !CanWrite(packet.retransmittable)) {
+ // Connection close packets are encypted and saved, so don't exit early.
+ if (writer_->IsWriteBlocked() && !IsConnectionClose(packet)) {
return false;
}
@@ -1341,7 +1323,9 @@ bool QuicConnection::WritePacket(QueuedPacket packet) {
sequence_number_of_last_sent_packet_ = sequence_number;
QuicEncryptedPacket* encrypted = framer_.EncryptPacket(
- packet.encryption_level, sequence_number, *packet.packet);
+ packet.encryption_level,
+ sequence_number,
+ *packet.serialized_packet.packet);
if (encrypted == NULL) {
LOG(DFATAL) << ENDPOINT << "Failed to encrypt packet number "
<< sequence_number;
@@ -1353,7 +1337,7 @@ bool QuicConnection::WritePacket(QueuedPacket packet) {
// Connection close packets are eventually owned by TimeWaitListManager.
// Others are deleted at the end of this call.
scoped_ptr<QuicEncryptedPacket> encrypted_deleter;
- if (packet.type == CONNECTION_CLOSE) {
+ if (IsConnectionClose(packet)) {
DCHECK(connection_close_packet_.get() == NULL);
connection_close_packet_.reset(encrypted);
// This assures we won't try to write *forced* packets when blocked.
@@ -1370,16 +1354,19 @@ bool QuicConnection::WritePacket(QueuedPacket packet) {
DCHECK_LE(encrypted->length(), kMaxPacketSize);
}
DCHECK_LE(encrypted->length(), packet_generator_.max_packet_length());
- DVLOG(1) << ENDPOINT << "Sending packet " << sequence_number
- << " : " << (packet.packet->is_fec_packet() ? "FEC " :
- (packet.retransmittable == HAS_RETRANSMITTABLE_DATA
- ? "data bearing " : " ack only "))
+ DVLOG(1) << ENDPOINT << "Sending packet " << sequence_number << " : "
+ << (packet.serialized_packet.packet->is_fec_packet() ? "FEC " :
+ (IsRetransmittable(packet) == HAS_RETRANSMITTABLE_DATA
+ ? "data bearing " : " ack only "))
<< ", encryption level: "
<< QuicUtils::EncryptionLevelToString(packet.encryption_level)
- << ", length:" << packet.packet->length() << ", encrypted length:"
+ << ", length:"
+ << packet.serialized_packet.packet->length()
+ << ", encrypted length:"
<< encrypted->length();
DVLOG(2) << ENDPOINT << "packet(" << sequence_number << "): " << std::endl
- << QuicUtils::StringToHexASCIIDump(packet.packet->AsStringPiece());
+ << QuicUtils::StringToHexASCIIDump(
+ packet.serialized_packet.packet->AsStringPiece());
WriteResult result = writer_->WritePacket(encrypted->data(),
encrypted->length(),
@@ -1422,12 +1409,12 @@ bool QuicConnection::WritePacket(QueuedPacket packet) {
sent_packet_manager_.least_packet_awaited_by_peer(),
sent_packet_manager_.GetCongestionWindow());
- bool reset_retransmission_alarm =
- sent_packet_manager_.OnPacketSent(sequence_number,
- now,
- encrypted->length(),
- packet.transmission_type,
- packet.retransmittable);
+ bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent(
+ sequence_number,
+ now,
+ encrypted->length(),
+ packet.transmission_type,
+ IsRetransmittable(packet));
if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) {
retransmission_alarm_->Update(sent_packet_manager_.GetRetransmissionTime(),
@@ -1523,6 +1510,7 @@ void QuicConnection::OnHandshakeComplete() {
bool QuicConnection::SendOrQueuePacket(EncryptionLevel level,
const SerializedPacket& packet,
TransmissionType transmission_type) {
+ // The caller of this function is responsible for checking CanWrite().
if (packet.packet == NULL) {
LOG(DFATAL) << "NULL packet passed in to SendOrQueuePacket";
return true;
@@ -1531,14 +1519,12 @@ bool QuicConnection::SendOrQueuePacket(EncryptionLevel level,
sent_entropy_manager_.RecordPacketEntropyHash(packet.sequence_number,
packet.entropy_hash);
QueuedPacket queued_packet(packet, level, transmission_type);
- // If there are already queued packets, put this at the end,
- // unless it's ConnectionClose, in which case it is written immediately.
- if ((queued_packet.type == CONNECTION_CLOSE || queued_packets_.empty()) &&
- WritePacket(queued_packet)) {
+ LOG_IF(DFATAL, !queued_packets_.empty() && !writer_->IsWriteBlocked())
+ << "Packets should only be left queued if we're write blocked.";
+ if (WritePacket(queued_packet)) {
delete packet.packet;
return true;
}
- queued_packet.type = QUEUED;
queued_packets_.push_back(queued_packet);
return false;
}
@@ -1991,4 +1977,31 @@ QuicConnection::ScopedPacketBundler::~ScopedPacketBundler() {
connection_->packet_generator_.InBatchMode());
}
+HasRetransmittableData QuicConnection::IsRetransmittable(
+ QueuedPacket packet) {
+ // TODO(cyr): Understand why the first check here is necessary. Without it,
+ // DiscardRetransmit test fails.
+ if (packet.transmission_type != NOT_RETRANSMISSION ||
+ packet.serialized_packet.retransmittable_frames != NULL) {
+ return HAS_RETRANSMITTABLE_DATA;
+ } else {
+ return NO_RETRANSMITTABLE_DATA;
+ }
+}
+
+bool QuicConnection::IsConnectionClose(
+ QueuedPacket packet) {
+ RetransmittableFrames* retransmittable_frames =
+ packet.serialized_packet.retransmittable_frames;
+ if (!retransmittable_frames) {
+ return false;
+ }
+ for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) {
+ if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace net
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_logger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698