| Index: net/quic/quic_connection.cc
|
| diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
|
| index f222a1f5a49c1301636207bb0709ca7a7ae3ac63..2fa5a12de1b49ffdbd666926733e48f1e33a221f 100644
|
| --- a/net/quic/quic_connection.cc
|
| +++ b/net/quic/quic_connection.cc
|
| @@ -278,6 +278,7 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id,
|
| largest_seen_packet_with_stop_waiting_(0),
|
| max_undecryptable_packets_(0),
|
| pending_version_negotiation_packet_(false),
|
| + save_crypto_packets_as_termination_packets_(false),
|
| silent_close_enabled_(false),
|
| received_packet_manager_(&stats_),
|
| ack_queued_(false),
|
| @@ -341,6 +342,9 @@ QuicConnection::~QuicConnection() {
|
| delete writer_;
|
| }
|
| STLDeleteElements(&undecryptable_packets_);
|
| + if (termination_packets_.get() != nullptr) {
|
| + STLDeleteElements(termination_packets_.get());
|
| + }
|
| STLDeleteValues(&group_map_);
|
| ClearQueuedPackets();
|
| }
|
| @@ -1497,9 +1501,9 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
|
| ++stats_.packets_discarded;
|
| return true;
|
| }
|
| - // Connection close packets are encrypted and saved, so don't exit early.
|
| - const bool is_connection_close = IsConnectionClose(*packet);
|
| - if (writer_->IsWriteBlocked() && !is_connection_close) {
|
| + // Termination packets are encrypted and saved, so don't exit early.
|
| + const bool is_termination_packet = IsTerminationPacket(*packet);
|
| + if (writer_->IsWriteBlocked() && !is_termination_packet) {
|
| return false;
|
| }
|
|
|
| @@ -1508,12 +1512,14 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) {
|
| packet_number_of_last_sent_packet_ = packet_number;
|
|
|
| QuicEncryptedPacket* encrypted = packet->serialized_packet.packet;
|
| - // Connection close packets are eventually owned by TimeWaitListManager.
|
| + // Termination packets are eventually owned by TimeWaitListManager.
|
| // Others are deleted at the end of this call.
|
| - if (is_connection_close) {
|
| - DCHECK(connection_close_packet_.get() == nullptr);
|
| + if (is_termination_packet) {
|
| + if (termination_packets_.get() == nullptr) {
|
| + termination_packets_.reset(new std::vector<QuicEncryptedPacket*>);
|
| + }
|
| // Clone the packet so it's owned in the future.
|
| - connection_close_packet_.reset(encrypted->Clone());
|
| + termination_packets_->push_back(encrypted->Clone());
|
| // This assures we won't try to write *forced* packets when blocked.
|
| // Return true to stop processing.
|
| if (writer_->IsWriteBlocked()) {
|
| @@ -2024,6 +2030,10 @@ bool QuicConnection::HasQueuedData() const {
|
| !queued_packets_.empty() || packet_generator_.HasQueuedFrames();
|
| }
|
|
|
| +void QuicConnection::EnableSavingCryptoPackets() {
|
| + save_crypto_packets_as_termination_packets_ = true;
|
| +}
|
| +
|
| bool QuicConnection::CanWriteStreamData() {
|
| // Don't write stream data if there are negotiation or queued data packets
|
| // to send. Otherwise, continue and bundle as many frames as possible.
|
| @@ -2228,7 +2238,7 @@ HasRetransmittableData QuicConnection::IsRetransmittable(
|
| }
|
| }
|
|
|
| -bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) {
|
| +bool QuicConnection::IsTerminationPacket(const QueuedPacket& packet) {
|
| const RetransmittableFrames* retransmittable_frames =
|
| packet.serialized_packet.retransmittable_frames;
|
| if (retransmittable_frames == nullptr) {
|
| @@ -2238,6 +2248,11 @@ bool QuicConnection::IsConnectionClose(const QueuedPacket& packet) {
|
| if (frame.type == CONNECTION_CLOSE_FRAME) {
|
| return true;
|
| }
|
| + if (save_crypto_packets_as_termination_packets_ &&
|
| + frame.type == STREAM_FRAME &&
|
| + frame.stream_frame->stream_id == kCryptoStreamId) {
|
| + return true;
|
| + }
|
| }
|
| return false;
|
| }
|
|
|