Index: net/quic/quic_packet_generator.cc |
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc |
index 12ebcfb0e5a750a01027638bc0bade9faa167749..37bb3fe7fcbe70012f848dd6e61dd49a51ad397b 100644 |
--- a/net/quic/quic_packet_generator.cc |
+++ b/net/quic/quic_packet_generator.cc |
@@ -40,7 +40,7 @@ QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, |
DelegateInterface* delegate) |
: delegate_(delegate), |
debug_delegate_(nullptr), |
- packet_creator_(connection_id, framer, random_generator), |
+ packet_creator_(connection_id, framer, random_generator, this), |
batch_mode_(false), |
fec_timeout_(QuicTime::Delta::Zero()), |
rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout), |
@@ -139,7 +139,7 @@ QuicConsumedData QuicPacketGenerator::ConsumeData( |
bool fin_consumed = false; |
if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { |
- SerializeAndSendPacket(); |
+ packet_creator_.Flush(); |
} |
if (fec_protection == MUST_FEC_PROTECT) { |
@@ -151,23 +151,22 @@ QuicConsumedData QuicPacketGenerator::ConsumeData( |
return QuicConsumedData(0, false); |
} |
- int frames_created = 0; |
while (delegate_->ShouldGeneratePacket( |
HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { |
QuicFrame frame; |
- UniqueStreamBuffer buffer; |
- size_t bytes_consumed = packet_creator_.CreateStreamFrame( |
- id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin, |
- &frame, &buffer); |
- ++frames_created; |
- |
- if (!AddFrame(frame, buffer.Pass(), has_handshake)) { |
- LOG(DFATAL) << "Failed to add stream frame."; |
- // Inability to add a STREAM frame creates an unrecoverable hole in a |
- // the stream, so it's best to close the connection. |
- delegate_->CloseConnection(QUIC_INTERNAL_ERROR, false); |
- return QuicConsumedData(0, false); |
+ if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, |
+ offset + total_bytes_consumed, fin, |
+ has_handshake, &frame)) { |
+ // Current packet is full and flushed. |
+ continue; |
} |
+ |
+ // A stream frame is created and added. |
+ size_t bytes_consumed = frame.stream_frame->data.length(); |
+ if (debug_delegate_ != nullptr) { |
+ debug_delegate_->OnFrameAddedToPacket(frame); |
+ } |
+ |
if (listener != nullptr) { |
ack_listeners_.push_back(AckListenerWrapper(listener, bytes_consumed)); |
} |
@@ -175,13 +174,13 @@ QuicConsumedData QuicPacketGenerator::ConsumeData( |
total_bytes_consumed += bytes_consumed; |
fin_consumed = fin && total_bytes_consumed == iov.total_length; |
DCHECK(total_bytes_consumed == iov.total_length || |
- packet_creator_.BytesFree() == 0u); |
+ (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
- if (!InBatchMode() || !packet_creator_.HasRoomForStreamFrame(id, offset)) { |
+ if (!InBatchMode()) { |
// TODO(rtenneti): remove MaybeSendFecPacketAndCloseGroup() from inside |
// SerializeAndSendPacket() and make it an explicit call here (and |
// elsewhere where we call SerializeAndSendPacket?). |
- SerializeAndSendPacket(); |
+ packet_creator_.Flush(); |
} |
if (total_bytes_consumed == iov.total_length) { |
@@ -228,7 +227,7 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket( |
if (listener != nullptr) { |
ack_listeners_.push_back(AckListenerWrapper(listener, 0)); |
} |
- SerializeAndSendPacket(); |
+ packet_creator_.Flush(); |
// The only reason AddFrame can fail is that the packet is too full to fit in |
// a ping. This is not possible for any sane MTU. |
DCHECK(success); |
@@ -253,13 +252,10 @@ void QuicPacketGenerator::SendQueuedFrames(bool flush, bool is_fec_timeout) { |
// Only add pending frames if we are SURE we can then send the whole packet. |
while (HasPendingFrames() && |
(flush || CanSendWithNextPendingFrameAddition())) { |
- if (!AddNextPendingFrame()) { |
- // Packet was full, so serialize and send it. |
- SerializeAndSendPacket(); |
- } |
+ AddNextPendingFrame(); |
} |
- if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) { |
- SerializeAndSendPacket(); |
+ if (flush || !InBatchMode()) { |
+ packet_creator_.Flush(); |
} |
MaybeSendFecPacketAndCloseGroup(flush, is_fec_timeout); |
} |
@@ -424,40 +420,6 @@ bool QuicPacketGenerator::AddFrame(const QuicFrame& frame, |
return success; |
} |
-void QuicPacketGenerator::SerializeAndSendPacket() { |
- // The optimized encryption algorithm implementations run faster when |
- // operating on aligned memory. |
- // |
- // TODO(rtenneti): Change the default 64 alignas value (used the default |
- // value from CACHELINE_SIZE). |
- ALIGNAS(64) char buffer[kMaxPacketSize]; |
- SerializedPacket serialized_packet = |
- packet_creator_.SerializePacket(buffer, kMaxPacketSize); |
- if (serialized_packet.packet == nullptr) { |
- LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_ |
- << " should_fec_protect_:" << should_fec_protect_; |
- delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); |
- return; |
- } |
- |
- // There may be AckListeners interested in this packet. |
- serialized_packet.listeners.swap(ack_listeners_); |
- ack_listeners_.clear(); |
- |
- delegate_->OnSerializedPacket(serialized_packet); |
- MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false); |
- |
- // Maximum packet size may be only enacted while no packet is currently being |
- // constructed, so here we have a good opportunity to actually change it. |
- if (packet_creator_.CanSetMaxPacketLength()) { |
- packet_creator_.SetMaxPacketLength(max_packet_length_); |
- } |
- |
- // The packet has now been serialized, so the frames are no longer queued. |
- ack_queued_ = false; |
- stop_waiting_queued_ = false; |
-} |
- |
void QuicPacketGenerator::StopSendingVersion() { |
packet_creator_.StopSendingVersion(); |
} |
@@ -532,4 +494,31 @@ void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, |
packet_creator_.SetEncrypter(level, encrypter); |
} |
+void QuicPacketGenerator::OnSerializedPacket( |
+ SerializedPacket* serialized_packet) { |
+ if (serialized_packet->packet == nullptr) { |
+ LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy_ |
+ << " should_fec_protect_:" << should_fec_protect_; |
+ delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); |
+ return; |
+ } |
+ |
+ // There may be AckListeners interested in this packet. |
+ serialized_packet->listeners.swap(ack_listeners_); |
+ ack_listeners_.clear(); |
+ |
+ delegate_->OnSerializedPacket(*serialized_packet); |
+ MaybeSendFecPacketAndCloseGroup(/*force=*/false, /*is_fec_timeout=*/false); |
+ |
+ // Maximum packet size may be only enacted while no packet is currently being |
+ // constructed, so here we have a good opportunity to actually change it. |
+ if (packet_creator_.CanSetMaxPacketLength()) { |
+ packet_creator_.SetMaxPacketLength(max_packet_length_); |
+ } |
+ |
+ // The packet has now been serialized, so the frames are no longer queued. |
+ ack_queued_ = false; |
+ stop_waiting_queued_ = false; |
+} |
+ |
} // namespace net |