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

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: Rebase 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
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 QueueUndecryptablePacket(packet); 1077 QueueUndecryptablePacket(packet);
1054 } 1078 }
1055 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " 1079 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
1056 << last_header_.packet_sequence_number; 1080 << last_header_.packet_sequence_number;
1057 return; 1081 return;
1058 } 1082 }
1059 1083
1060 MaybeProcessUndecryptablePackets(); 1084 MaybeProcessUndecryptablePackets();
1061 MaybeProcessRevivedPacket(); 1085 MaybeProcessRevivedPacket();
1062 MaybeSendInResponseToPacket(); 1086 MaybeSendInResponseToPacket();
1087 SetPingAlarm();
1063 } 1088 }
1064 1089
1065 void QuicConnection::OnCanWrite() { 1090 void QuicConnection::OnCanWrite() {
1066 DCHECK(!writer_->IsWriteBlocked()); 1091 DCHECK(!writer_->IsWriteBlocked());
1067 1092
1068 WriteQueuedPackets(); 1093 WriteQueuedPackets();
1069 WritePendingRetransmissions(); 1094 WritePendingRetransmissions();
1070 1095
1071 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? 1096 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ?
1072 IS_HANDSHAKE : NOT_HANDSHAKE; 1097 IS_HANDSHAKE : NOT_HANDSHAKE;
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 DVLOG(1) << "Write failed with error code: " << result.error_code; 1427 DVLOG(1) << "Write failed with error code: " << result.error_code;
1403 // We can't send an error as the socket is presumably borked. 1428 // We can't send an error as the socket is presumably borked.
1404 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); 1429 CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
1405 return false; 1430 return false;
1406 } 1431 }
1407 1432
1408 QuicTime now = clock_->Now(); 1433 QuicTime now = clock_->Now();
1409 if (transmission_type == NOT_RETRANSMISSION) { 1434 if (transmission_type == NOT_RETRANSMISSION) {
1410 time_of_last_sent_new_packet_ = now; 1435 time_of_last_sent_new_packet_ = now;
1411 } 1436 }
1437 SetPingAlarm();
1412 DVLOG(1) << ENDPOINT << "time of last sent packet: " 1438 DVLOG(1) << ENDPOINT << "time of last sent packet: "
1413 << now.ToDebuggingValue(); 1439 << now.ToDebuggingValue();
1414 1440
1415 // TODO(ianswett): Change the sequence number length and other packet creator 1441 // TODO(ianswett): Change the sequence number length and other packet creator
1416 // options by a more explicit API than setting a struct value directly. 1442 // options by a more explicit API than setting a struct value directly.
1417 packet_creator_.UpdateSequenceNumberLength( 1443 packet_creator_.UpdateSequenceNumberLength(
1418 received_packet_manager_.least_packet_awaited_by_peer(), 1444 received_packet_manager_.least_packet_awaited_by_peer(),
1419 sent_packet_manager_.GetCongestionWindow()); 1445 sent_packet_manager_.GetCongestionWindow());
1420 1446
1421 bool reset_retransmission_alarm = 1447 bool reset_retransmission_alarm =
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 queued_packets_.push_back(queued_packet); 1503 queued_packets_.push_back(queued_packet);
1478 return false; 1504 return false;
1479 } 1505 }
1480 1506
1481 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { 1507 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) {
1482 stop_waiting->least_unacked = GetLeastUnacked(); 1508 stop_waiting->least_unacked = GetLeastUnacked();
1483 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash( 1509 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash(
1484 stop_waiting->least_unacked - 1); 1510 stop_waiting->least_unacked - 1);
1485 } 1511 }
1486 1512
1513 void QuicConnection::SendPing() {
1514 if (retransmission_alarm_->IsSet()) {
1515 return;
1516 }
1517 if (version() <= QUIC_VERSION_17) {
1518 // TODO(rch): remove this when we remove version 17.
1519 // This is a horrible hideous hack which we should not support.
1520 IOVector data;
1521 char c_data[] = "C";
1522 data.Append(c_data, 1);
1523 QuicConsumedData consumed_data =
1524 packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, NULL);
1525 if (consumed_data.bytes_consumed == 0) {
1526 DLOG(ERROR) << "Unable to send ping!?";
1527 }
1528 } else {
1529 // TODO(rch): enable this when we merge version 18.
1530 // packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame));
1531 }
1532 }
1533
1487 void QuicConnection::SendAck() { 1534 void QuicConnection::SendAck() {
1488 ack_alarm_->Cancel(); 1535 ack_alarm_->Cancel();
1489 stop_waiting_count_ = 0; 1536 stop_waiting_count_ = 0;
1490 // TODO(rch): delay this until the CreateFeedbackFrame 1537 // TODO(rch): delay this until the CreateFeedbackFrame
1491 // method is invoked. This requires changes SetShouldSendAck 1538 // method is invoked. This requires changes SetShouldSendAck
1492 // to be a no-arg method, and re-jiggering its implementation. 1539 // to be a no-arg method, and re-jiggering its implementation.
1493 bool send_feedback = false; 1540 bool send_feedback = false;
1494 if (received_packet_manager_.GenerateCongestionFeedback( 1541 if (received_packet_manager_.GenerateCongestionFeedback(
1495 &outgoing_congestion_feedback_)) { 1542 &outgoing_congestion_feedback_)) {
1496 DVLOG(1) << ENDPOINT << "Sending feedback: " 1543 DVLOG(1) << ENDPOINT << "Sending feedback: "
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 if (connection_timeout < timeout) { 1848 if (connection_timeout < timeout) {
1802 timeout = connection_timeout; 1849 timeout = connection_timeout;
1803 } 1850 }
1804 } 1851 }
1805 1852
1806 timeout_alarm_->Cancel(); 1853 timeout_alarm_->Cancel();
1807 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout)); 1854 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout));
1808 return false; 1855 return false;
1809 } 1856 }
1810 1857
1858 void QuicConnection::SetPingAlarm() {
1859 if (is_server_) {
1860 // Only clients send pings.
1861 return;
1862 }
1863 ping_alarm_->Cancel();
1864 if (!visitor_->HasOpenDataStreams()) {
1865 // Don't send a ping unless there are open streams.
1866 return;
1867 }
1868 QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
1869 ping_alarm_->Set(clock_->ApproximateNow().Add(ping_timeout));
1870 }
1871
1811 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( 1872 QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
1812 QuicConnection* connection, 1873 QuicConnection* connection,
1813 AckBundling send_ack) 1874 AckBundling send_ack)
1814 : connection_(connection), 1875 : connection_(connection),
1815 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) { 1876 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) {
1816 // Move generator into batch mode. If caller wants us to include an ack, 1877 // Move generator into batch mode. If caller wants us to include an ack,
1817 // check the delayed-ack timer to see if there's ack info to be sent. 1878 // check the delayed-ack timer to see if there's ack info to be sent.
1818 if (!already_in_batch_mode_) { 1879 if (!already_in_batch_mode_) {
1819 DVLOG(1) << "Entering Batch Mode."; 1880 DVLOG(1) << "Entering Batch Mode.";
1820 connection_->packet_generator_.StartBatchOperations(); 1881 connection_->packet_generator_.StartBatchOperations();
(...skipping 12 matching lines...) Expand all
1833 // If we changed the generator's batch state, restore original batch state. 1894 // If we changed the generator's batch state, restore original batch state.
1834 if (!already_in_batch_mode_) { 1895 if (!already_in_batch_mode_) {
1835 DVLOG(1) << "Leaving Batch Mode."; 1896 DVLOG(1) << "Leaving Batch Mode.";
1836 connection_->packet_generator_.FinishBatchOperations(); 1897 connection_->packet_generator_.FinishBatchOperations();
1837 } 1898 }
1838 DCHECK_EQ(already_in_batch_mode_, 1899 DCHECK_EQ(already_in_batch_mode_,
1839 connection_->packet_generator_.InBatchMode()); 1900 connection_->packet_generator_.InBatchMode());
1840 } 1901 }
1841 1902
1842 } // namespace net 1903 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698