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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |