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

Unified Diff: net/quic/quic_connection.cc

Issue 23597045: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged QuicPriority to RequestPriority changes Created 7 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_helper_test.cc » ('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 748821e445e844a01a78410d03208df7a06fd762..0633f90fa034ca87c60ab25754099d482b7db811 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -19,6 +19,7 @@ using std::list;
using std::make_pair;
using std::min;
using std::max;
+using std::numeric_limits;
using std::vector;
using std::set;
using std::string;
@@ -282,6 +283,7 @@ bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) {
}
version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(received_version);
// Store the new version.
framer_.set_version(received_version);
@@ -380,6 +382,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
DCHECK_EQ(1u, header.public_header.versions.size());
DCHECK_EQ(header.public_header.versions[0], version());
version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(version());
}
} else {
DCHECK(!header.public_header.version_flag);
@@ -387,6 +390,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
// it should stop sending version since the version negotiation is done.
packet_creator_.StopSendingVersion();
version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(version());
}
}
@@ -781,7 +785,7 @@ void QuicConnection::MaybeSendInResponseToPacket(
// Set the ack alarm for when any retransmittable frame is received.
if (!ack_alarm_->IsSet()) {
ack_alarm_->Set(clock_->ApproximateNow().Add(
- congestion_manager_.DefaultRetransmissionTime()));
+ congestion_manager_.DelayedAckTime()));
}
}
send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_;
@@ -817,26 +821,51 @@ void QuicConnection::SendVersionNegotiationPacket() {
delete encrypted;
}
-QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
- StringPiece data,
- QuicStreamOffset offset,
- bool fin) {
- // To make reasoning about crypto frames easier, we don't combine them with
- // any other frames in a single packet.
- const bool crypto_frame_while_batch_mode =
- id == kCryptoStreamId && packet_generator_.InBatchMode();
+QuicConsumedData QuicConnection::SendvStreamData(QuicStreamId id,
+ const struct iovec* iov,
+ int count,
+ QuicStreamOffset offset,
+ bool fin) {
+ // TODO(ianswett): Further improve sending by passing the iovec down
+ // instead of batching into multiple stream frames in a single packet.
+ const bool already_in_batch_mode = packet_generator_.InBatchMode();
+ packet_generator_.StartBatchOperations();
- if (crypto_frame_while_batch_mode) {
- // Flush pending frames to make room for a crypto frame.
- packet_generator_.FinishBatchOperations();
+ size_t bytes_written = 0;
+ bool fin_consumed = false;
+ for (int i = 0; i < count; ++i) {
+ bool send_fin = fin && (i == count - 1);
+ if (!send_fin && iov[i].iov_len == 0) {
+ LOG(DFATAL) << "Attempt to send empty stream frame";
+ }
+ QuicConsumedData data_consumed = packet_generator_.ConsumeData(
+ id,
+ StringPiece(static_cast<char*>(iov[i].iov_base), iov[i].iov_len),
+ offset + bytes_written,
+ send_fin);
+ DCHECK_LE(data_consumed.bytes_consumed, numeric_limits<uint32>::max());
+ bytes_written += data_consumed.bytes_consumed;
+ fin_consumed = data_consumed.fin_consumed;
+ // If no bytes were consumed, bail now, because the stream can not write
+ // more data.
+ if (data_consumed.bytes_consumed < iov[i].iov_len) {
+ break;
+ }
}
- QuicConsumedData consumed_data =
- packet_generator_.ConsumeData(id, data, offset, fin);
- if (crypto_frame_while_batch_mode) {
- // Restore batch mode.
- packet_generator_.StartBatchOperations();
+ // Handle the 0 byte write properly.
+ if (count == 0) {
+ DCHECK(fin);
+ QuicConsumedData data_consumed = packet_generator_.ConsumeData(
+ id, StringPiece(), offset, fin);
+ fin_consumed = data_consumed.fin_consumed;
}
- return consumed_data;
+
+ // Leave the generator in the original batch state.
+ if (!already_in_batch_mode) {
+ packet_generator_.FinishBatchOperations();
+ }
+ DCHECK_EQ(already_in_batch_mode, packet_generator_.InBatchMode());
+ return QuicConsumedData(bytes_written, fin_consumed);
}
QuicConsumedData QuicConnection::SendStreamDataAndNotifyWhenAcked(
@@ -845,6 +874,9 @@ QuicConsumedData QuicConnection::SendStreamDataAndNotifyWhenAcked(
QuicStreamOffset offset,
bool fin,
QuicAckNotifier::DelegateInterface* delegate) {
+ if (!fin && data.empty()) {
+ LOG(DFATAL) << "Attempt to send empty stream frame";
+ }
// This notifier will be deleted in ProcessAckFrame once it has seen ACKs for
// all the consumed data (or below if no data was consumed).
QuicAckNotifier* notifier = new QuicAckNotifier(delegate);
@@ -953,12 +985,12 @@ bool QuicConnection::DoWrite() {
// write more.
if (CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA,
maybe_handshake)) {
- const bool in_batch_mode = packet_generator_.InBatchMode();
- if (!in_batch_mode) {
+ const bool already_in_batch_mode = packet_generator_.InBatchMode();
+ if (!already_in_batch_mode) {
packet_generator_.StartBatchOperations();
}
bool all_bytes_written = visitor_->OnCanWrite();
- if (!in_batch_mode) {
+ if (!already_in_batch_mode) {
packet_generator_.FinishBatchOperations();
}
@@ -1305,7 +1337,11 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
// 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.
- return helper_->IsWriteBlockedDataBuffered();
+ if (helper_->IsWriteBlockedDataBuffered()) {
+ delete packet;
+ return true;
+ }
+ return false;
}
// We can't send an error as the socket is presumably borked.
CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
@@ -1323,11 +1359,13 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
// TODO(ianswett): Change the sequence number length and other packet creator
// options by a more explicit API than setting a struct value directly.
- packet_creator_.options()->send_sequence_number_length =
- CalculateSequenceNumberLength(sequence_number);
+ packet_creator_.UpdateSequenceNumberLength(
+ received_packet_manager_.least_packet_awaited_by_peer(),
+ congestion_manager_.BandwidthEstimate().ToBytesPerPeriod(
+ congestion_manager_.SmoothedRtt()));
congestion_manager_.SentPacket(sequence_number, now, packet->length(),
- retransmission);
+ retransmission, retransmittable);
stats_.bytes_sent += encrypted->length();
++stats_.packets_sent;
@@ -1355,31 +1393,6 @@ int QuicConnection::WritePacketToWire(QuicPacketSequenceNumber sequence_number,
return bytes_written;
}
-QuicSequenceNumberLength QuicConnection::CalculateSequenceNumberLength(
- QuicPacketSequenceNumber sequence_number) {
- DCHECK_LE(received_packet_manager_.least_packet_awaited_by_peer(),
- sequence_number);
- // Since the packet creator will not change sequence number length mid FEC
- // group, include the size of an FEC group to be safe.
- const QuicPacketSequenceNumber current_delta =
- packet_creator_.options()->max_packets_per_fec_group + sequence_number
- - received_packet_manager_.least_packet_awaited_by_peer();
- const uint64 congestion_window =
- congestion_manager_.BandwidthEstimate().ToBytesPerPeriod(
- congestion_manager_.SmoothedRtt()) /
- packet_creator_.options()->max_packet_length;
- const uint64 delta = max(current_delta, congestion_window);
-
- if (delta < 1 << ((PACKET_1BYTE_SEQUENCE_NUMBER * 8) - 2)) {
- return PACKET_1BYTE_SEQUENCE_NUMBER;
- } else if (delta < 1 << ((PACKET_2BYTE_SEQUENCE_NUMBER * 8) - 2)) {
- return PACKET_2BYTE_SEQUENCE_NUMBER;
- } else if (delta < 1 << ((PACKET_4BYTE_SEQUENCE_NUMBER * 8) - 2)) {
- return PACKET_4BYTE_SEQUENCE_NUMBER;
- }
- return PACKET_6BYTE_SEQUENCE_NUMBER;
-}
-
bool QuicConnection::OnSerializedPacket(
const SerializedPacket& serialized_packet) {
if (serialized_packet.retransmittable_frames != NULL) {
@@ -1716,6 +1729,14 @@ void QuicConnection::CloseFecGroupsBefore(
}
}
+void QuicConnection::Flush() {
+ if (!packet_generator_.InBatchMode()) {
+ return;
+ }
+ packet_generator_.FinishBatchOperations();
+ packet_generator_.StartBatchOperations();
+}
+
bool QuicConnection::HasQueuedData() const {
return !queued_packets_.empty() || packet_generator_.HasQueuedFrames();
}
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_helper_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698