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