Chromium Code Reviews| 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 }; | |
| 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(); | |
| 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)); | |
|
ramant (doing other things)
2014/04/18 21:20:01
nit: space between // and packet_generator_....
Sh
Ryan Hamilton
2014/04/19 13:55:59
Done.
| |
| 1515 } | |
| 1516 SetPingAlarm(); | |
| 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 |