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

Side by Side Diff: net/quic/quic_connection.cc

Issue 243533003: Sent QUIC "PING" frames when a stream is open and the connection (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix comments Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 : connection_(connection) { 68 : connection_(connection) {
69 } 69 }
70 70
71 virtual QuicTime OnAlarm() OVERRIDE { 71 virtual QuicTime OnAlarm() OVERRIDE {
72 connection_->SendAck(); 72 connection_->SendAck();
73 return QuicTime::Zero(); 73 return QuicTime::Zero();
74 } 74 }
75 75
76 private: 76 private:
77 QuicConnection* connection_; 77 QuicConnection* connection_;
78
79 DISALLOW_COPY_AND_ASSIGN(AckAlarm);
78 }; 80 };
79 81
80 // This alarm will be scheduled any time a data-bearing packet is sent out. 82 // This alarm will be scheduled any time a data-bearing packet is sent out.
81 // When the alarm goes off, the connection checks to see if the oldest packets 83 // When the alarm goes off, the connection checks to see if the oldest packets
82 // have been acked, and retransmit them if they have not. 84 // have been acked, and retransmit them if they have not.
83 class RetransmissionAlarm : public QuicAlarm::Delegate { 85 class RetransmissionAlarm : public QuicAlarm::Delegate {
84 public: 86 public:
85 explicit RetransmissionAlarm(QuicConnection* connection) 87 explicit RetransmissionAlarm(QuicConnection* connection)
86 : connection_(connection) { 88 : connection_(connection) {
87 } 89 }
88 90
89 virtual QuicTime OnAlarm() OVERRIDE { 91 virtual QuicTime OnAlarm() OVERRIDE {
90 connection_->OnRetransmissionTimeout(); 92 connection_->OnRetransmissionTimeout();
91 return QuicTime::Zero(); 93 return QuicTime::Zero();
92 } 94 }
93 95
94 private: 96 private:
95 QuicConnection* connection_; 97 QuicConnection* connection_;
98
99 DISALLOW_COPY_AND_ASSIGN(RetransmissionAlarm);
96 }; 100 };
97 101
98 // An alarm that is scheduled when the sent scheduler requires a 102 // An alarm that is scheduled when the sent scheduler requires a
99 // a delay before sending packets and fires when the packet may be sent. 103 // a delay before sending packets and fires when the packet may be sent.
100 class SendAlarm : public QuicAlarm::Delegate { 104 class SendAlarm : public QuicAlarm::Delegate {
101 public: 105 public:
102 explicit SendAlarm(QuicConnection* connection) 106 explicit SendAlarm(QuicConnection* connection)
103 : connection_(connection) { 107 : connection_(connection) {
104 } 108 }
105 109
106 virtual QuicTime OnAlarm() OVERRIDE { 110 virtual QuicTime OnAlarm() OVERRIDE {
107 connection_->WriteIfNotBlocked(); 111 connection_->WriteIfNotBlocked();
108 // Never reschedule the alarm, since CanWrite does that. 112 // Never reschedule the alarm, since CanWrite does that.
109 return QuicTime::Zero(); 113 return QuicTime::Zero();
110 } 114 }
111 115
112 private: 116 private:
113 QuicConnection* connection_; 117 QuicConnection* connection_;
118
119 DISALLOW_COPY_AND_ASSIGN(SendAlarm);
114 }; 120 };
115 121
116 class TimeoutAlarm : public QuicAlarm::Delegate { 122 class TimeoutAlarm : public QuicAlarm::Delegate {
117 public: 123 public:
118 explicit TimeoutAlarm(QuicConnection* connection) 124 explicit TimeoutAlarm(QuicConnection* connection)
119 : connection_(connection) { 125 : connection_(connection) {
120 } 126 }
121 127
122 virtual QuicTime OnAlarm() OVERRIDE { 128 virtual QuicTime OnAlarm() OVERRIDE {
123 connection_->CheckForTimeout(); 129 connection_->CheckForTimeout();
124 // Never reschedule the alarm, since CheckForTimeout does that. 130 // Never reschedule the alarm, since CheckForTimeout does that.
125 return QuicTime::Zero(); 131 return QuicTime::Zero();
126 } 132 }
127 133
128 private: 134 private:
129 QuicConnection* connection_; 135 QuicConnection* connection_;
136
137 DISALLOW_COPY_AND_ASSIGN(TimeoutAlarm);
138 };
139
140 class PingAlarm : public QuicAlarm::Delegate {
141 public:
142 explicit PingAlarm(QuicConnection* connection)
143 : connection_(connection) {
144 }
145
146 virtual QuicTime OnAlarm() override {
147 connection_->SendPing();
148 return QuicTime::Zero();
149 }
150
151 private:
152 QuicConnection* connection_;
130 }; 153 };
131 154
132 QuicConnection::PacketType GetPacketType( 155 QuicConnection::PacketType GetPacketType(
133 const RetransmittableFrames* retransmittable_frames) { 156 const RetransmittableFrames* retransmittable_frames) {
134 if (!retransmittable_frames) { 157 if (!retransmittable_frames) {
135 return QuicConnection::NORMAL; 158 return QuicConnection::NORMAL;
136 } 159 }
137 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { 160 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) {
138 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { 161 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) {
139 return QuicConnection::CONNECTION_CLOSE; 162 return QuicConnection::CONNECTION_CLOSE;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 received_packet_manager_( 207 received_packet_manager_(
185 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP, 208 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP,
186 &stats_), 209 &stats_),
187 ack_queued_(false), 210 ack_queued_(false),
188 stop_waiting_count_(0), 211 stop_waiting_count_(0),
189 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), 212 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))),
190 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), 213 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))),
191 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), 214 send_alarm_(helper->CreateAlarm(new SendAlarm(this))),
192 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), 215 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))),
193 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), 216 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))),
217 ping_alarm_(helper->CreateAlarm(new PingAlarm(this))),
194 debug_visitor_(NULL), 218 debug_visitor_(NULL),
195 packet_creator_(connection_id_, &framer_, random_generator_, is_server), 219 packet_creator_(connection_id_, &framer_, random_generator_, is_server),
196 packet_generator_(this, NULL, &packet_creator_), 220 packet_generator_(this, NULL, &packet_creator_),
197 idle_network_timeout_( 221 idle_network_timeout_(
198 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), 222 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)),
199 overall_connection_timeout_(QuicTime::Delta::Infinite()), 223 overall_connection_timeout_(QuicTime::Delta::Infinite()),
200 creation_time_(clock_->ApproximateNow()), 224 creation_time_(clock_->ApproximateNow()),
201 time_of_last_received_packet_(clock_->ApproximateNow()), 225 time_of_last_received_packet_(clock_->ApproximateNow()),
202 time_of_last_sent_new_packet_(clock_->ApproximateNow()), 226 time_of_last_sent_new_packet_(clock_->ApproximateNow()),
203 sequence_number_of_last_sent_packet_(0), 227 sequence_number_of_last_sent_packet_(0),
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 QueueUndecryptablePacket(packet); 1075 QueueUndecryptablePacket(packet);
1052 } 1076 }
1053 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " 1077 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
1054 << last_header_.packet_sequence_number; 1078 << last_header_.packet_sequence_number;
1055 return; 1079 return;
1056 } 1080 }
1057 1081
1058 MaybeProcessUndecryptablePackets(); 1082 MaybeProcessUndecryptablePackets();
1059 MaybeProcessRevivedPacket(); 1083 MaybeProcessRevivedPacket();
1060 MaybeSendInResponseToPacket(); 1084 MaybeSendInResponseToPacket();
1085 SetPingAlarm();
1061 } 1086 }
1062 1087
1063 void QuicConnection::OnCanWrite() { 1088 void QuicConnection::OnCanWrite() {
1064 DCHECK(!writer_->IsWriteBlocked()); 1089 DCHECK(!writer_->IsWriteBlocked());
1065 1090
1066 WriteQueuedPackets(); 1091 WriteQueuedPackets();
1067 WritePendingRetransmissions(); 1092 WritePendingRetransmissions();
1068 1093
1069 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? 1094 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ?
1070 IS_HANDSHAKE : NOT_HANDSHAKE; 1095 IS_HANDSHAKE : NOT_HANDSHAKE;
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 DVLOG(1) << "Write failed with error code: " << result.error_code; 1425 DVLOG(1) << "Write failed with error code: " << result.error_code;
1401 // We can't send an error as the socket is presumably borked. 1426 // We can't send an error as the socket is presumably borked.
1402 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); 1427 CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
1403 return false; 1428 return false;
1404 } 1429 }
1405 1430
1406 QuicTime now = clock_->Now(); 1431 QuicTime now = clock_->Now();
1407 if (transmission_type == NOT_RETRANSMISSION) { 1432 if (transmission_type == NOT_RETRANSMISSION) {
1408 time_of_last_sent_new_packet_ = now; 1433 time_of_last_sent_new_packet_ = now;
1409 } 1434 }
1435 SetPingAlarm();
1410 DVLOG(1) << ENDPOINT << "time of last sent packet: " 1436 DVLOG(1) << ENDPOINT << "time of last sent packet: "
1411 << now.ToDebuggingValue(); 1437 << now.ToDebuggingValue();
1412 1438
1413 // TODO(ianswett): Change the sequence number length and other packet creator 1439 // TODO(ianswett): Change the sequence number length and other packet creator
1414 // options by a more explicit API than setting a struct value directly. 1440 // options by a more explicit API than setting a struct value directly.
1415 packet_creator_.UpdateSequenceNumberLength( 1441 packet_creator_.UpdateSequenceNumberLength(
1416 received_packet_manager_.least_packet_awaited_by_peer(), 1442 received_packet_manager_.least_packet_awaited_by_peer(),
1417 sent_packet_manager_.GetCongestionWindow()); 1443 sent_packet_manager_.GetCongestionWindow());
1418 1444
1419 bool reset_retransmission_alarm = 1445 bool reset_retransmission_alarm =
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 queued_packets_.push_back(queued_packet); 1501 queued_packets_.push_back(queued_packet);
1476 return false; 1502 return false;
1477 } 1503 }
1478 1504
1479 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { 1505 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) {
1480 stop_waiting->least_unacked = GetLeastUnacked(); 1506 stop_waiting->least_unacked = GetLeastUnacked();
1481 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash( 1507 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash(
1482 stop_waiting->least_unacked - 1); 1508 stop_waiting->least_unacked - 1);
1483 } 1509 }
1484 1510
1511 void QuicConnection::SendPing() {
jar (doing other things) 2014/04/19 16:54:15 Per offline discussion... Please add an early retu
Ryan Hamilton 2014/04/19 19:18:48 Done.
1512 if (version() <= QUIC_VERSION_17) {
1513 // TODO(rch): remove this when we remove version 17.
1514 // This is a horrible hideous hack which we should not support.
1515 IOVector data;
1516 char c_data[] = "C";
1517 data.Append(c_data, 1);
1518 QuicConsumedData consumed_data =
1519 packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, NULL);
1520 if (consumed_data.bytes_consumed == 0) {
1521 DLOG(ERROR) << "Unable to send ping!?";
1522 }
1523 } else {
1524 // TODO(rch): enable this when we merge version 18.
1525 // packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame));
1526 }
1527 }
1528
1485 void QuicConnection::SendAck() { 1529 void QuicConnection::SendAck() {
1486 ack_alarm_->Cancel(); 1530 ack_alarm_->Cancel();
1487 stop_waiting_count_ = 0; 1531 stop_waiting_count_ = 0;
1488 // TODO(rch): delay this until the CreateFeedbackFrame 1532 // TODO(rch): delay this until the CreateFeedbackFrame
1489 // method is invoked. This requires changes SetShouldSendAck 1533 // method is invoked. This requires changes SetShouldSendAck
1490 // to be a no-arg method, and re-jiggering its implementation. 1534 // to be a no-arg method, and re-jiggering its implementation.
1491 bool send_feedback = false; 1535 bool send_feedback = false;
1492 if (received_packet_manager_.GenerateCongestionFeedback( 1536 if (received_packet_manager_.GenerateCongestionFeedback(
1493 &outgoing_congestion_feedback_)) { 1537 &outgoing_congestion_feedback_)) {
1494 DVLOG(1) << ENDPOINT << "Sending feedback: " 1538 DVLOG(1) << ENDPOINT << "Sending feedback: "
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 if (connection_timeout < timeout) { 1839 if (connection_timeout < timeout) {
1796 timeout = connection_timeout; 1840 timeout = connection_timeout;
1797 } 1841 }
1798 } 1842 }
1799 1843
1800 timeout_alarm_->Cancel(); 1844 timeout_alarm_->Cancel();
1801 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout)); 1845 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout));
1802 return false; 1846 return false;
1803 } 1847 }
1804 1848
1849 void QuicConnection::SetPingAlarm() {
1850 if (is_server_) {
1851 // Only clients send pings.
1852 return;
1853 }
1854 ping_alarm_->Cancel();
1855 if (!visitor_->HasOpenStreams()) {
1856 // Don't send a ping unless there are open streams.
1857 return;
1858 }
1859 QuicTime::Delta ping_timeout = idle_network_timeout_.Multiply(0.5);
jar (doing other things) 2014/04/19 16:35:43 This trick (50% of idle timeout) is perchance OK f
Ryan Hamilton 2014/04/19 19:18:48 Done. Added a new constant for this.
1860 ping_alarm_->Set(clock_->ApproximateNow().Add(ping_timeout));
1861 }
1862
1805 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( 1863 QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
1806 QuicConnection* connection, 1864 QuicConnection* connection,
1807 AckBundling send_ack) 1865 AckBundling send_ack)
1808 : connection_(connection), 1866 : connection_(connection),
1809 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) { 1867 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) {
1810 // Move generator into batch mode. If caller wants us to include an ack, 1868 // Move generator into batch mode. If caller wants us to include an ack,
1811 // check the delayed-ack timer to see if there's ack info to be sent. 1869 // check the delayed-ack timer to see if there's ack info to be sent.
1812 if (!already_in_batch_mode_) { 1870 if (!already_in_batch_mode_) {
1813 DVLOG(1) << "Entering Batch Mode."; 1871 DVLOG(1) << "Entering Batch Mode.";
1814 connection_->packet_generator_.StartBatchOperations(); 1872 connection_->packet_generator_.StartBatchOperations();
(...skipping 12 matching lines...) Expand all
1827 // If we changed the generator's batch state, restore original batch state. 1885 // If we changed the generator's batch state, restore original batch state.
1828 if (!already_in_batch_mode_) { 1886 if (!already_in_batch_mode_) {
1829 DVLOG(1) << "Leaving Batch Mode."; 1887 DVLOG(1) << "Leaving Batch Mode.";
1830 connection_->packet_generator_.FinishBatchOperations(); 1888 connection_->packet_generator_.FinishBatchOperations();
1831 } 1889 }
1832 DCHECK_EQ(already_in_batch_mode_, 1890 DCHECK_EQ(already_in_batch_mode_,
1833 connection_->packet_generator_.InBatchMode()); 1891 connection_->packet_generator_.InBatchMode());
1834 } 1892 }
1835 1893
1836 } // namespace net 1894 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698