Index: net/quic/core/quic_packet_generator.cc |
diff --git a/net/quic/core/quic_packet_generator.cc b/net/quic/core/quic_packet_generator.cc |
index 025b54d573df1725c73e93cd6b354c0e592e3247..dc68d253096c31b16e6fd5627768b4b677260f6d 100644 |
--- a/net/quic/core/quic_packet_generator.cc |
+++ b/net/quic/core/quic_packet_generator.cc |
@@ -6,6 +6,7 @@ |
#include <cstdint> |
+#include "net/quic/core/crypto/quic_random.h" |
#include "net/quic/core/quic_utils.h" |
#include "net/quic/platform/api/quic_bug_tracker.h" |
#include "net/quic/platform/api/quic_logging.h" |
@@ -14,13 +15,15 @@ namespace net { |
QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, |
QuicFramer* framer, |
+ QuicRandom* random_generator, |
QuicBufferAllocator* buffer_allocator, |
DelegateInterface* delegate) |
: delegate_(delegate), |
packet_creator_(connection_id, framer, buffer_allocator, delegate), |
batch_mode_(false), |
should_send_ack_(false), |
- should_send_stop_waiting_(false) {} |
+ should_send_stop_waiting_(false), |
+ random_generator_(random_generator) {} |
QuicPacketGenerator::~QuicPacketGenerator() { |
DeleteFrames(&queued_control_frames_); |
@@ -51,9 +54,10 @@ QuicConsumedData QuicPacketGenerator::ConsumeData( |
QuicStreamId id, |
QuicIOVector iov, |
QuicStreamOffset offset, |
- bool fin, |
+ StreamSendingState state, |
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
bool has_handshake = (id == kCryptoStreamId); |
+ bool fin = state != NO_FIN; |
QUIC_BUG_IF(has_handshake && fin) |
<< "Handshake packets should never send a fin"; |
// To make reasoning about crypto frames easier, we don't combine them with |
@@ -93,6 +97,9 @@ QuicConsumedData QuicPacketGenerator::ConsumeData( |
} |
total_bytes_consumed += bytes_consumed; |
fin_consumed = fin && total_bytes_consumed == iov.total_length; |
+ if (fin_consumed && state == FIN_AND_PADDING) { |
+ AddRandomPadding(); |
+ } |
DCHECK(total_bytes_consumed == iov.total_length || |
(bytes_consumed > 0 && packet_creator_.HasPendingFrames())); |
@@ -174,9 +181,10 @@ void QuicPacketGenerator::GenerateMtuDiscoveryPacket( |
} |
bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { |
- DCHECK(HasPendingFrames()); |
+ DCHECK(HasPendingFrames() || packet_creator_.pending_padding_bytes() > 0); |
HasRetransmittableData retransmittable = |
- (should_send_ack_ || should_send_stop_waiting_) |
+ (should_send_ack_ || should_send_stop_waiting_ || |
+ packet_creator_.pending_padding_bytes() > 0) |
? NO_RETRANSMITTABLE_DATA |
: HAS_RETRANSMITTABLE_DATA; |
if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
@@ -222,6 +230,7 @@ void QuicPacketGenerator::StartBatchOperations() { |
void QuicPacketGenerator::FinishBatchOperations() { |
batch_mode_ = false; |
SendQueuedFrames(/*flush=*/false); |
+ SendRemainingPendingPadding(); |
} |
void QuicPacketGenerator::FlushAllQueuedFrames() { |
@@ -327,4 +336,16 @@ void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, |
packet_creator_.SetEncrypter(level, encrypter); |
} |
+void QuicPacketGenerator::AddRandomPadding() { |
+ packet_creator_.AddPendingPadding( |
+ random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1); |
+} |
+ |
+void QuicPacketGenerator::SendRemainingPendingPadding() { |
+ while (packet_creator_.pending_padding_bytes() > 0 && !HasQueuedFrames() && |
+ CanSendWithNextPendingFrameAddition()) { |
+ packet_creator_.Flush(); |
+ } |
+} |
+ |
} // namespace net |