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

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: more cleanup 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 virtual QuicTime OnAlarm() OVERRIDE { 122 virtual QuicTime OnAlarm() OVERRIDE {
123 connection_->CheckForTimeout(); 123 connection_->CheckForTimeout();
124 // Never reschedule the alarm, since CheckForTimeout does that. 124 // Never reschedule the alarm, since CheckForTimeout does that.
125 return QuicTime::Zero(); 125 return QuicTime::Zero();
126 } 126 }
127 127
128 private: 128 private:
129 QuicConnection* connection_; 129 QuicConnection* connection_;
130 }; 130 };
131 131
132 class PingAlarm : public QuicAlarm::Delegate {
133 public:
134 explicit PingAlarm(QuicConnection* connection)
135 : connection_(connection) {
136 }
137
138 virtual QuicTime OnAlarm() override {
139 connection_->SendPing();
140 return QuicTime::Zero();
141 }
142
143 private:
144 QuicConnection* connection_;
145 };
jar (doing other things) 2014/04/18 21:57:13 nit: NO_DEFAULT_COPY_AND_ASSIGN
Ryan Hamilton 2014/04/19 13:55:59 Done.
146
132 QuicConnection::PacketType GetPacketType( 147 QuicConnection::PacketType GetPacketType(
133 const RetransmittableFrames* retransmittable_frames) { 148 const RetransmittableFrames* retransmittable_frames) {
134 if (!retransmittable_frames) { 149 if (!retransmittable_frames) {
135 return QuicConnection::NORMAL; 150 return QuicConnection::NORMAL;
136 } 151 }
137 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { 152 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) {
138 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { 153 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) {
139 return QuicConnection::CONNECTION_CLOSE; 154 return QuicConnection::CONNECTION_CLOSE;
140 } 155 }
141 } 156 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 received_packet_manager_( 199 received_packet_manager_(
185 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP, 200 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP,
186 &stats_), 201 &stats_),
187 ack_queued_(false), 202 ack_queued_(false),
188 stop_waiting_count_(0), 203 stop_waiting_count_(0),
189 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), 204 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))),
190 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), 205 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))),
191 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), 206 send_alarm_(helper->CreateAlarm(new SendAlarm(this))),
192 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), 207 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))),
193 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), 208 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))),
209 ping_alarm_(helper->CreateAlarm(new PingAlarm(this))),
194 debug_visitor_(NULL), 210 debug_visitor_(NULL),
195 packet_creator_(connection_id_, &framer_, random_generator_, is_server), 211 packet_creator_(connection_id_, &framer_, random_generator_, is_server),
196 packet_generator_(this, NULL, &packet_creator_), 212 packet_generator_(this, NULL, &packet_creator_),
197 idle_network_timeout_( 213 idle_network_timeout_(
198 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), 214 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)),
199 overall_connection_timeout_(QuicTime::Delta::Infinite()), 215 overall_connection_timeout_(QuicTime::Delta::Infinite()),
200 creation_time_(clock_->ApproximateNow()), 216 creation_time_(clock_->ApproximateNow()),
201 time_of_last_received_packet_(clock_->ApproximateNow()), 217 time_of_last_received_packet_(clock_->ApproximateNow()),
202 time_of_last_sent_new_packet_(clock_->ApproximateNow()), 218 time_of_last_sent_new_packet_(clock_->ApproximateNow()),
203 sequence_number_of_last_sent_packet_(0), 219 sequence_number_of_last_sent_packet_(0),
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 QueueUndecryptablePacket(packet); 1067 QueueUndecryptablePacket(packet);
1052 } 1068 }
1053 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " 1069 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
1054 << last_header_.packet_sequence_number; 1070 << last_header_.packet_sequence_number;
1055 return; 1071 return;
1056 } 1072 }
1057 1073
1058 MaybeProcessUndecryptablePackets(); 1074 MaybeProcessUndecryptablePackets();
1059 MaybeProcessRevivedPacket(); 1075 MaybeProcessRevivedPacket();
1060 MaybeSendInResponseToPacket(); 1076 MaybeSendInResponseToPacket();
1077 SetPingAlarm();
1061 } 1078 }
1062 1079
1063 void QuicConnection::OnCanWrite() { 1080 void QuicConnection::OnCanWrite() {
1064 DCHECK(!writer_->IsWriteBlocked()); 1081 DCHECK(!writer_->IsWriteBlocked());
1065 1082
1066 WriteQueuedPackets(); 1083 WriteQueuedPackets();
1067 WritePendingRetransmissions(); 1084 WritePendingRetransmissions();
1068 1085
1069 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? 1086 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ?
1070 IS_HANDSHAKE : NOT_HANDSHAKE; 1087 IS_HANDSHAKE : NOT_HANDSHAKE;
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 if (result.status == WRITE_STATUS_ERROR) { 1416 if (result.status == WRITE_STATUS_ERROR) {
1400 DVLOG(1) << "Write failed with error code: " << result.error_code; 1417 DVLOG(1) << "Write failed with error code: " << result.error_code;
1401 // We can't send an error as the socket is presumably borked. 1418 // We can't send an error as the socket is presumably borked.
1402 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); 1419 CloseConnection(QUIC_PACKET_WRITE_ERROR, false);
1403 return false; 1420 return false;
1404 } 1421 }
1405 1422
1406 QuicTime now = clock_->Now(); 1423 QuicTime now = clock_->Now();
1407 if (transmission_type == NOT_RETRANSMISSION) { 1424 if (transmission_type == NOT_RETRANSMISSION) {
1408 time_of_last_sent_new_packet_ = now; 1425 time_of_last_sent_new_packet_ = now;
1426 SetPingAlarm();
jar (doing other things) 2014/04/18 21:57:13 Why don't we always set this? Why do we care if it
Ryan Hamilton 2014/04/19 13:55:59 Done. I was keeping it in sync with the timeout al
1409 } 1427 }
1410 DVLOG(1) << ENDPOINT << "time of last sent packet: " 1428 DVLOG(1) << ENDPOINT << "time of last sent packet: "
1411 << now.ToDebuggingValue(); 1429 << now.ToDebuggingValue();
1412 1430
1413 // TODO(ianswett): Change the sequence number length and other packet creator 1431 // TODO(ianswett): Change the sequence number length and other packet creator
1414 // options by a more explicit API than setting a struct value directly. 1432 // options by a more explicit API than setting a struct value directly.
1415 packet_creator_.UpdateSequenceNumberLength( 1433 packet_creator_.UpdateSequenceNumberLength(
1416 received_packet_manager_.least_packet_awaited_by_peer(), 1434 received_packet_manager_.least_packet_awaited_by_peer(),
1417 sent_packet_manager_.GetCongestionWindow()); 1435 sent_packet_manager_.GetCongestionWindow());
1418 1436
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 queued_packets_.push_back(queued_packet); 1493 queued_packets_.push_back(queued_packet);
1476 return false; 1494 return false;
1477 } 1495 }
1478 1496
1479 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { 1497 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) {
1480 stop_waiting->least_unacked = GetLeastUnacked(); 1498 stop_waiting->least_unacked = GetLeastUnacked();
1481 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash( 1499 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash(
1482 stop_waiting->least_unacked - 1); 1500 stop_waiting->least_unacked - 1);
1483 } 1501 }
1484 1502
1503 void QuicConnection::SendPing() {
1504 if (version() <= QUIC_VERSION_17) {
1505 IOVector data;
1506 char c_data[] = "C";
1507 data.Append(c_data, 1);
1508 QuicConsumedData consumed_data =
1509 packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, NULL);
1510 if (consumed_data.bytes_consumed == 0) {
1511 DLOG(ERROR) << "Unable to send ping!?";
1512 }
1513 } else {
1514 //packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame));
1515 }
1516 SetPingAlarm();
jar (doing other things) 2014/04/18 21:57:13 Do we don't need to set it again? Shouldn't it sho
Ryan Hamilton 2014/04/19 13:55:59 Interesting! Yes, good point, the send of the PING
1517 }
1518
1485 void QuicConnection::SendAck() { 1519 void QuicConnection::SendAck() {
1486 ack_alarm_->Cancel(); 1520 ack_alarm_->Cancel();
1487 stop_waiting_count_ = 0; 1521 stop_waiting_count_ = 0;
1488 // TODO(rch): delay this until the CreateFeedbackFrame 1522 // TODO(rch): delay this until the CreateFeedbackFrame
1489 // method is invoked. This requires changes SetShouldSendAck 1523 // method is invoked. This requires changes SetShouldSendAck
1490 // to be a no-arg method, and re-jiggering its implementation. 1524 // to be a no-arg method, and re-jiggering its implementation.
1491 bool send_feedback = false; 1525 bool send_feedback = false;
1492 if (received_packet_manager_.GenerateCongestionFeedback( 1526 if (received_packet_manager_.GenerateCongestionFeedback(
1493 &outgoing_congestion_feedback_)) { 1527 &outgoing_congestion_feedback_)) {
1494 DVLOG(1) << ENDPOINT << "Sending feedback: " 1528 DVLOG(1) << ENDPOINT << "Sending feedback: "
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 if (connection_timeout < timeout) { 1829 if (connection_timeout < timeout) {
1796 timeout = connection_timeout; 1830 timeout = connection_timeout;
1797 } 1831 }
1798 } 1832 }
1799 1833
1800 timeout_alarm_->Cancel(); 1834 timeout_alarm_->Cancel();
1801 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout)); 1835 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout));
1802 return false; 1836 return false;
1803 } 1837 }
1804 1838
1839 void QuicConnection::SetPingAlarm() {
1840 if (is_server_) {
1841 // Only clients send pings.
1842 return;
1843 }
1844 ping_alarm_->Cancel();
1845 if (!visitor_->HasOpenStreams()) {
1846 // Don't send a ping unless there are open streams.
1847 return;
1848 }
1849 QuicTime time_of_last_packet = max(time_of_last_received_packet_,
1850 time_of_last_sent_new_packet_);
1851 QuicTime::Delta ping_timeout = idle_network_timeout_.Multiply(0.5);
1852 ping_alarm_->Set(time_of_last_packet.Add(ping_timeout));
1853 }
1854
1805 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( 1855 QuicConnection::ScopedPacketBundler::ScopedPacketBundler(
1806 QuicConnection* connection, 1856 QuicConnection* connection,
1807 AckBundling send_ack) 1857 AckBundling send_ack)
1808 : connection_(connection), 1858 : connection_(connection),
1809 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) { 1859 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) {
1810 // Move generator into batch mode. If caller wants us to include an ack, 1860 // 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. 1861 // check the delayed-ack timer to see if there's ack info to be sent.
1812 if (!already_in_batch_mode_) { 1862 if (!already_in_batch_mode_) {
1813 DVLOG(1) << "Entering Batch Mode."; 1863 DVLOG(1) << "Entering Batch Mode.";
1814 connection_->packet_generator_.StartBatchOperations(); 1864 connection_->packet_generator_.StartBatchOperations();
(...skipping 12 matching lines...) Expand all
1827 // If we changed the generator's batch state, restore original batch state. 1877 // If we changed the generator's batch state, restore original batch state.
1828 if (!already_in_batch_mode_) { 1878 if (!already_in_batch_mode_) {
1829 DVLOG(1) << "Leaving Batch Mode."; 1879 DVLOG(1) << "Leaving Batch Mode.";
1830 connection_->packet_generator_.FinishBatchOperations(); 1880 connection_->packet_generator_.FinishBatchOperations();
1831 } 1881 }
1832 DCHECK_EQ(already_in_batch_mode_, 1882 DCHECK_EQ(already_in_batch_mode_,
1833 connection_->packet_generator_.InBatchMode()); 1883 connection_->packet_generator_.InBatchMode());
1834 } 1884 }
1835 1885
1836 } // namespace net 1886 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698