| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <iterator> | 10 #include <iterator> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using base::StringPiece; | 28 using base::StringPiece; |
| 29 using std::list; | 29 using std::list; |
| 30 using std::make_pair; | 30 using std::make_pair; |
| 31 using std::min; | 31 using std::min; |
| 32 using std::max; | 32 using std::max; |
| 33 using std::numeric_limits; | 33 using std::numeric_limits; |
| 34 using std::vector; | 34 using std::vector; |
| 35 using std::set; | 35 using std::set; |
| 36 using std::string; | 36 using std::string; |
| 37 | 37 |
| 38 int FLAGS_fake_packet_loss_percentage = 0; | 38 extern bool FLAGS_quic_allow_oversized_packets_for_test; |
| 39 | |
| 40 // If true, then QUIC connections will bundle acks with any outgoing packet when | |
| 41 // an ack is being delayed. This is an optimization to reduce ack latency and | |
| 42 // packet count of pure ack packets. | |
| 43 bool FLAGS_bundle_ack_with_outgoing_packet = false; | |
| 44 | 39 |
| 45 namespace net { | 40 namespace net { |
| 46 | 41 |
| 47 class QuicDecrypter; | 42 class QuicDecrypter; |
| 48 class QuicEncrypter; | 43 class QuicEncrypter; |
| 49 | 44 |
| 50 namespace { | 45 namespace { |
| 51 | 46 |
| 52 // The largest gap in packets we'll accept without closing the connection. | 47 // The largest gap in packets we'll accept without closing the connection. |
| 53 // This will likely have to be tuned. | 48 // This will likely have to be tuned. |
| 54 const QuicPacketSequenceNumber kMaxPacketGap = 5000; | 49 const QuicPacketSequenceNumber kMaxPacketGap = 5000; |
| 55 | 50 |
| 56 // Limit the number of FEC groups to two. If we get enough out of order packets | 51 // Limit the number of FEC groups to two. If we get enough out of order packets |
| 57 // that this becomes limiting, we can revisit. | 52 // that this becomes limiting, we can revisit. |
| 58 const size_t kMaxFecGroups = 2; | 53 const size_t kMaxFecGroups = 2; |
| 59 | 54 |
| 60 // Limit the number of undecryptable packets we buffer in | 55 // Limit the number of undecryptable packets we buffer in |
| 61 // expectation of the CHLO/SHLO arriving. | 56 // expectation of the CHLO/SHLO arriving. |
| 62 const size_t kMaxUndecryptablePackets = 10; | 57 const size_t kMaxUndecryptablePackets = 10; |
| 63 | 58 |
| 64 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 59 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
| 65 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 60 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
| 66 return delta <= kMaxPacketGap; | 61 return delta <= kMaxPacketGap; |
| 67 } | 62 } |
| 68 | 63 |
| 69 | |
| 70 // An alarm that is scheduled to send an ack if a timeout occurs. | 64 // An alarm that is scheduled to send an ack if a timeout occurs. |
| 71 class AckAlarm : public QuicAlarm::Delegate { | 65 class AckAlarm : public QuicAlarm::Delegate { |
| 72 public: | 66 public: |
| 73 explicit AckAlarm(QuicConnection* connection) | 67 explicit AckAlarm(QuicConnection* connection) |
| 74 : connection_(connection) { | 68 : connection_(connection) { |
| 75 } | 69 } |
| 76 | 70 |
| 77 virtual QuicTime OnAlarm() OVERRIDE { | 71 virtual QuicTime OnAlarm() OVERRIDE { |
| 78 connection_->SendAck(); | 72 connection_->SendAck(); |
| 79 return QuicTime::Zero(); | 73 return QuicTime::Zero(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 // Never reschedule the alarm, since CheckForTimeout does that. | 124 // Never reschedule the alarm, since CheckForTimeout does that. |
| 131 return QuicTime::Zero(); | 125 return QuicTime::Zero(); |
| 132 } | 126 } |
| 133 | 127 |
| 134 private: | 128 private: |
| 135 QuicConnection* connection_; | 129 QuicConnection* connection_; |
| 136 }; | 130 }; |
| 137 | 131 |
| 138 // Indicates if any of the frames are intended to be sent with FORCE. | 132 // Indicates if any of the frames are intended to be sent with FORCE. |
| 139 // Returns FORCE when one of the frames is a CONNECTION_CLOSE_FRAME. | 133 // Returns FORCE when one of the frames is a CONNECTION_CLOSE_FRAME. |
| 140 net::QuicConnection::Force HasForcedFrames( | 134 QuicConnection::Force HasForcedFrames( |
| 141 const RetransmittableFrames* retransmittable_frames) { | 135 const RetransmittableFrames* retransmittable_frames) { |
| 142 if (!retransmittable_frames) { | 136 if (!retransmittable_frames) { |
| 143 return net::QuicConnection::NO_FORCE; | 137 return QuicConnection::NO_FORCE; |
| 144 } | 138 } |
| 145 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { | 139 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { |
| 146 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { | 140 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { |
| 147 return net::QuicConnection::FORCE; | 141 return QuicConnection::FORCE; |
| 148 } | 142 } |
| 149 } | 143 } |
| 150 return net::QuicConnection::NO_FORCE; | 144 return QuicConnection::NO_FORCE; |
| 151 } | 145 } |
| 152 | 146 |
| 153 } // namespace | 147 } // namespace |
| 154 | 148 |
| 155 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 149 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 156 | 150 |
| 157 QuicConnection::QuicConnection(QuicGuid guid, | 151 QuicConnection::QuicConnection(QuicGuid guid, |
| 158 IPEndPoint address, | 152 IPEndPoint address, |
| 159 QuicConnectionHelperInterface* helper, | 153 QuicConnectionHelperInterface* helper, |
| 160 QuicPacketWriter* writer, | 154 QuicPacketWriter* writer, |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 (consumed_data.bytes_consumed == 0 && !consumed_data.fin_consumed)) { | 815 (consumed_data.bytes_consumed == 0 && !consumed_data.fin_consumed)) { |
| 822 // No data was consumed, nor was a fin consumed, so delete the notifier. | 816 // No data was consumed, nor was a fin consumed, so delete the notifier. |
| 823 delete notifier; | 817 delete notifier; |
| 824 } | 818 } |
| 825 | 819 |
| 826 return consumed_data; | 820 return consumed_data; |
| 827 } | 821 } |
| 828 | 822 |
| 829 void QuicConnection::SendRstStream(QuicStreamId id, | 823 void QuicConnection::SendRstStream(QuicStreamId id, |
| 830 QuicRstStreamErrorCode error) { | 824 QuicRstStreamErrorCode error) { |
| 831 DVLOG(1) << "Sending RST_STREAM: " << id << " code: " << error; | |
| 832 // Opportunistically bundle an ack with this outgoing packet. | 825 // Opportunistically bundle an ack with this outgoing packet. |
| 833 ScopedPacketBundler ack_bundler(this, true); | 826 ScopedPacketBundler ack_bundler(this, true); |
| 834 packet_generator_.AddControlFrame( | 827 packet_generator_.AddControlFrame( |
| 835 QuicFrame(new QuicRstStreamFrame(id, error))); | 828 QuicFrame(new QuicRstStreamFrame(id, error))); |
| 836 } | 829 } |
| 837 | 830 |
| 838 const QuicConnectionStats& QuicConnection::GetStats() { | 831 const QuicConnectionStats& QuicConnection::GetStats() { |
| 839 // Update rtt and estimated bandwidth. | 832 // Update rtt and estimated bandwidth. |
| 840 stats_.rtt = sent_packet_manager_.SmoothedRtt().ToMicroseconds(); | 833 stats_.rtt = sent_packet_manager_.SmoothedRtt().ToMicroseconds(); |
| 841 stats_.estimated_bandwidth = | 834 stats_.estimated_bandwidth = |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 << " : " << (packet->is_fec_packet() ? "FEC " : | 1123 << " : " << (packet->is_fec_packet() ? "FEC " : |
| 1131 (retransmittable == HAS_RETRANSMITTABLE_DATA | 1124 (retransmittable == HAS_RETRANSMITTABLE_DATA |
| 1132 ? "data bearing " : " ack only ")) | 1125 ? "data bearing " : " ack only ")) |
| 1133 << ", encryption level: " | 1126 << ", encryption level: " |
| 1134 << QuicUtils::EncryptionLevelToString(level) | 1127 << QuicUtils::EncryptionLevelToString(level) |
| 1135 << ", length:" << packet->length() << ", encrypted length:" | 1128 << ", length:" << packet->length() << ", encrypted length:" |
| 1136 << encrypted->length(); | 1129 << encrypted->length(); |
| 1137 DVLOG(2) << ENDPOINT << "packet(" << sequence_number << "): " << std::endl | 1130 DVLOG(2) << ENDPOINT << "packet(" << sequence_number << "): " << std::endl |
| 1138 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece()); | 1131 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece()); |
| 1139 | 1132 |
| 1140 DCHECK(encrypted->length() <= kMaxPacketSize) | 1133 DCHECK(encrypted->length() <= kMaxPacketSize || |
| 1134 FLAGS_quic_allow_oversized_packets_for_test) |
| 1141 << "Packet " << sequence_number << " will not be read; too large: " | 1135 << "Packet " << sequence_number << " will not be read; too large: " |
| 1142 << packet->length() << " " << encrypted->length() << " " | 1136 << packet->length() << " " << encrypted->length() << " " |
| 1143 << " forced: " << (forced == FORCE ? "yes" : "no"); | 1137 << " forced: " << (forced == FORCE ? "yes" : "no"); |
| 1144 | 1138 |
| 1145 DCHECK(pending_write_.get() == NULL); | 1139 DCHECK(pending_write_.get() == NULL); |
| 1146 pending_write_.reset(new PendingWrite(sequence_number, transmission_type, | 1140 pending_write_.reset(new PendingWrite(sequence_number, transmission_type, |
| 1147 retransmittable, level, | 1141 retransmittable, level, |
| 1148 packet->is_fec_packet(), | 1142 packet->is_fec_packet(), |
| 1149 packet->length())); | 1143 packet->length())); |
| 1150 | 1144 |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 if (timeout < overall_connection_timeout_) { | 1579 if (timeout < overall_connection_timeout_) { |
| 1586 overall_connection_timeout_ = timeout; | 1580 overall_connection_timeout_ = timeout; |
| 1587 CheckForTimeout(); | 1581 CheckForTimeout(); |
| 1588 } else { | 1582 } else { |
| 1589 overall_connection_timeout_ = timeout; | 1583 overall_connection_timeout_ = timeout; |
| 1590 } | 1584 } |
| 1591 } | 1585 } |
| 1592 | 1586 |
| 1593 bool QuicConnection::CheckForTimeout() { | 1587 bool QuicConnection::CheckForTimeout() { |
| 1594 QuicTime now = clock_->ApproximateNow(); | 1588 QuicTime now = clock_->ApproximateNow(); |
| 1595 QuicTime time_of_last_packet = std::max(time_of_last_received_packet_, | 1589 QuicTime time_of_last_packet = max(time_of_last_received_packet_, |
| 1596 time_of_last_sent_new_packet_); | 1590 time_of_last_sent_new_packet_); |
| 1597 | 1591 |
| 1598 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| | 1592 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| |
| 1599 // is accurate time. However, this should not change the behavior of | 1593 // is accurate time. However, this should not change the behavior of |
| 1600 // timeout handling. | 1594 // timeout handling. |
| 1601 QuicTime::Delta delta = now.Subtract(time_of_last_packet); | 1595 QuicTime::Delta delta = now.Subtract(time_of_last_packet); |
| 1602 DVLOG(1) << ENDPOINT << "last packet " | 1596 DVLOG(1) << ENDPOINT << "last packet " |
| 1603 << time_of_last_packet.ToDebuggingValue() | 1597 << time_of_last_packet.ToDebuggingValue() |
| 1604 << " now:" << now.ToDebuggingValue() | 1598 << " now:" << now.ToDebuggingValue() |
| 1605 << " delta:" << delta.ToMicroseconds() | 1599 << " delta:" << delta.ToMicroseconds() |
| 1606 << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); | 1600 << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 // If we changed the generator's batch state, restore original batch state. | 1653 // If we changed the generator's batch state, restore original batch state. |
| 1660 if (!already_in_batch_mode_) { | 1654 if (!already_in_batch_mode_) { |
| 1661 DVLOG(1) << "Leaving Batch Mode."; | 1655 DVLOG(1) << "Leaving Batch Mode."; |
| 1662 connection_->packet_generator_.FinishBatchOperations(); | 1656 connection_->packet_generator_.FinishBatchOperations(); |
| 1663 } | 1657 } |
| 1664 DCHECK_EQ(already_in_batch_mode_, | 1658 DCHECK_EQ(already_in_batch_mode_, |
| 1665 connection_->packet_generator_.InBatchMode()); | 1659 connection_->packet_generator_.InBatchMode()); |
| 1666 } | 1660 } |
| 1667 | 1661 |
| 1668 } // namespace net | 1662 } // namespace net |
| OLD | NEW |