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