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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 const int kMaxPacketsToSerializeAtOnce = 6; | 62 const int kMaxPacketsToSerializeAtOnce = 6; |
63 | 63 |
64 // Limit the number of packets we send per retransmission-alarm so we | 64 // Limit the number of packets we send per retransmission-alarm so we |
65 // eventually cede. 10 is arbitrary. | 65 // eventually cede. 10 is arbitrary. |
66 const int kMaxPacketsPerRetransmissionAlarm = 10; | 66 const int kMaxPacketsPerRetransmissionAlarm = 10; |
67 | 67 |
68 // Named constant for WritePacket() | 68 // Named constant for WritePacket() |
69 const bool kForce = true; | 69 const bool kForce = true; |
70 // Named constant for CanWrite(). | 70 // Named constant for CanWrite(). |
71 const bool kIsRetransmission = true; | 71 const bool kIsRetransmission = true; |
72 // Named constatn for WritePacket. | 72 // Named constant for WritePacket. |
73 const bool kHasRetransmittableData = true; | 73 const bool kHasRetransmittableData = true; |
74 | 74 |
75 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 75 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
76 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 76 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
77 return delta <= kMaxPacketGap; | 77 return delta <= kMaxPacketGap; |
78 } | 78 } |
79 | 79 |
80 } // namespace | 80 } // namespace |
81 | 81 |
82 QuicConnection::QuicConnection(QuicGuid guid, | 82 QuicConnection::QuicConnection(QuicGuid guid, |
83 IPEndPoint address, | 83 IPEndPoint address, |
84 QuicConnectionHelperInterface* helper) | 84 QuicConnectionHelperInterface* helper, |
| 85 bool is_server) |
85 : helper_(helper), | 86 : helper_(helper), |
86 framer_(kQuicVersion1, | 87 framer_(kQuicVersion1, |
87 QuicDecrypter::Create(kNULL), | 88 QuicDecrypter::Create(kNULL), |
88 QuicEncrypter::Create(kNULL)), | 89 QuicEncrypter::Create(kNULL), |
| 90 is_server), |
89 clock_(helper->GetClock()), | 91 clock_(helper->GetClock()), |
90 random_generator_(helper->GetRandomGenerator()), | 92 random_generator_(helper->GetRandomGenerator()), |
91 guid_(guid), | 93 guid_(guid), |
92 peer_address_(address), | 94 peer_address_(address), |
93 largest_seen_packet_with_ack_(0), | 95 largest_seen_packet_with_ack_(0), |
94 peer_largest_observed_packet_(0), | 96 peer_largest_observed_packet_(0), |
95 least_packet_awaited_by_peer_(1), | 97 least_packet_awaited_by_peer_(1), |
96 peer_least_packet_awaiting_ack_(0), | 98 peer_least_packet_awaiting_ack_(0), |
97 handling_retransmission_timeout_(false), | 99 handling_retransmission_timeout_(false), |
98 write_blocked_(false), | 100 write_blocked_(false), |
99 debug_visitor_(NULL), | 101 debug_visitor_(NULL), |
100 packet_creator_(guid_, &framer_, random_generator_), | 102 packet_creator_(guid_, &framer_, random_generator_, is_server), |
101 packet_generator_(this, &packet_creator_), | 103 packet_generator_(this, &packet_creator_), |
102 timeout_(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs)), | 104 timeout_(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs)), |
103 time_of_last_received_packet_(clock_->ApproximateNow()), | 105 time_of_last_received_packet_(clock_->ApproximateNow()), |
104 time_of_last_sent_packet_(clock_->ApproximateNow()), | 106 time_of_last_sent_packet_(clock_->ApproximateNow()), |
105 congestion_manager_(clock_, kTCP), | 107 congestion_manager_(clock_, kTCP), |
| 108 version_negotiation_state_(START_NEGOTIATION), |
| 109 quic_version_(kQuicVersion1), |
| 110 is_server_(is_server), |
106 connected_(true), | 111 connected_(true), |
107 received_truncated_ack_(false), | 112 received_truncated_ack_(false), |
108 send_ack_in_response_to_packet_(false) { | 113 send_ack_in_response_to_packet_(false) { |
109 helper_->SetConnection(this); | 114 helper_->SetConnection(this); |
| 115 // TODO(satyamshekhar): Have a smaller timeout till version is negotiated and |
| 116 // connection is established (CHLO fully processed). |
110 helper_->SetTimeoutAlarm(timeout_); | 117 helper_->SetTimeoutAlarm(timeout_); |
111 framer_.set_visitor(this); | 118 framer_.set_visitor(this); |
112 framer_.set_entropy_calculator(&entropy_manager_); | 119 framer_.set_entropy_calculator(&entropy_manager_); |
113 memset(&last_header_, 0, sizeof(last_header_)); | 120 memset(&last_header_, 0, sizeof(last_header_)); |
114 outgoing_ack_.sent_info.least_unacked = 0; | 121 outgoing_ack_.sent_info.least_unacked = 0; |
115 outgoing_ack_.sent_info.entropy_hash = 0; | 122 outgoing_ack_.sent_info.entropy_hash = 0; |
116 outgoing_ack_.received_info.largest_observed = 0; | 123 outgoing_ack_.received_info.largest_observed = 0; |
117 outgoing_ack_.received_info.entropy_hash = 0; | 124 outgoing_ack_.received_info.entropy_hash = 0; |
118 | 125 |
119 /* | 126 /* |
120 if (FLAGS_fake_packet_loss_percentage > 0) { | 127 if (FLAGS_fake_packet_loss_percentage > 0) { |
121 int32 seed = RandomBase::WeakSeed32(); | 128 int32 seed = RandomBase::WeakSeed32(); |
122 LOG(INFO) << "Seeding packet loss with " << seed; | 129 LOG(INFO) << "Seeding packet loss with " << seed; |
123 random_.reset(new MTRandom(seed)); | 130 random_.reset(new MTRandom(seed)); |
124 } | 131 } |
125 */ | 132 */ |
126 } | 133 } |
127 | 134 |
128 QuicConnection::~QuicConnection() { | 135 QuicConnection::~QuicConnection() { |
129 STLDeleteValues(&unacked_packets_); | 136 STLDeleteValues(&unacked_packets_); |
130 STLDeleteValues(&group_map_); | 137 STLDeleteValues(&group_map_); |
131 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 138 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
132 it != queued_packets_.end(); ++it) { | 139 it != queued_packets_.end(); ++it) { |
133 delete it->packet; | 140 delete it->packet; |
134 } | 141 } |
135 } | 142 } |
136 | 143 |
| 144 bool QuicConnection::SelectMutualVersion( |
| 145 const QuicVersionTagList& available_versions) { |
| 146 // TODO(satyamshekhar): Make this generic. |
| 147 if (std::find(available_versions.begin(), available_versions.end(), |
| 148 kQuicVersion1) == available_versions.end()) { |
| 149 return false; |
| 150 } |
| 151 |
| 152 // Right now we only support kQuicVersion1 so it's okay not to |
| 153 // update the framer and quic_version_. When start supporting more |
| 154 // versions please update both. |
| 155 return true; |
| 156 } |
| 157 |
137 void QuicConnection::OnError(QuicFramer* framer) { | 158 void QuicConnection::OnError(QuicFramer* framer) { |
138 SendConnectionClose(framer->error()); | 159 SendConnectionClose(framer->error()); |
139 } | 160 } |
140 | 161 |
141 void QuicConnection::OnPacket() { | 162 void QuicConnection::OnPacket() { |
| 163 // TODO(satyamshekhar): Validate packet before updating the time |
| 164 // since it affects the timeout of the connection. |
142 time_of_last_received_packet_ = clock_->Now(); | 165 time_of_last_received_packet_ = clock_->Now(); |
143 DVLOG(1) << "time of last received packet: " | 166 DVLOG(1) << "time of last received packet: " |
144 << time_of_last_received_packet_.ToMicroseconds(); | 167 << time_of_last_received_packet_.ToMicroseconds(); |
145 | 168 |
146 // TODO(alyssar, rch) handle migration! | 169 // TODO(alyssar, rch) handle migration! |
147 self_address_ = last_self_address_; | 170 self_address_ = last_self_address_; |
148 peer_address_ = last_peer_address_; | 171 peer_address_ = last_peer_address_; |
149 } | 172 } |
150 | 173 |
151 void QuicConnection::OnPublicResetPacket( | 174 void QuicConnection::OnPublicResetPacket( |
152 const QuicPublicResetPacket& packet) { | 175 const QuicPublicResetPacket& packet) { |
153 if (debug_visitor_) { | 176 if (debug_visitor_) { |
154 debug_visitor_->OnPublicResetPacket(packet); | 177 debug_visitor_->OnPublicResetPacket(packet); |
155 } | 178 } |
156 CloseConnection(QUIC_PUBLIC_RESET, true); | 179 CloseConnection(QUIC_PUBLIC_RESET, true); |
157 } | 180 } |
158 | 181 |
| 182 bool QuicConnection::OnProtocolVersionMismatch( |
| 183 QuicVersionTag received_version) { |
| 184 // TODO(satyamshekhar): Implement no server state in this mode. |
| 185 if (!is_server_) { |
| 186 LOG(DFATAL) << "Framer called OnProtocolVersionMismatch for server. " |
| 187 << "Closing connection."; |
| 188 CloseConnection(QUIC_INTERNAL_ERROR, false); |
| 189 } |
| 190 DCHECK_NE(quic_version_, received_version); |
| 191 |
| 192 if (debug_visitor_) { |
| 193 debug_visitor_->OnProtocolVersionMismatch(received_version); |
| 194 } |
| 195 |
| 196 switch (version_negotiation_state_) { |
| 197 case START_NEGOTIATION: |
| 198 if (!framer_.IsSupportedVersion(received_version)) { |
| 199 SendVersionNegotiationPacket(); |
| 200 version_negotiation_state_ = SENT_NEGOTIATION_PACKET; |
| 201 return false; |
| 202 } |
| 203 break; |
| 204 |
| 205 case SENT_NEGOTIATION_PACKET: |
| 206 if (!framer_.IsSupportedVersion(received_version)) { |
| 207 // Drop packets which can't be parsed due to version mismatch. |
| 208 return false; |
| 209 } |
| 210 break; |
| 211 |
| 212 case NEGOTIATED_VERSION: |
| 213 // Might be old packets that were sent by the client before the version |
| 214 // was negotiated. Drop these. |
| 215 return false; |
| 216 |
| 217 default: |
| 218 DCHECK(false); |
| 219 } |
| 220 |
| 221 // Right now we only support kQuicVersion1 so it's okay not to |
| 222 // update the framer and quic_version_. When start supporting more |
| 223 // versions please update both. |
| 224 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 225 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
| 226 // connection if we ever received a packet with incorrect version and whose |
| 227 // sequence number is greater. |
| 228 return true; |
| 229 } |
| 230 |
| 231 // Handles version negotiation for client connection. |
| 232 void QuicConnection::OnVersionNegotiationPacket( |
| 233 const QuicVersionNegotiationPacket& packet) { |
| 234 if (is_server_) { |
| 235 LOG(DFATAL) << "Framer parsed VersionNegotiationPacket for server." |
| 236 << "Closing connection."; |
| 237 CloseConnection(QUIC_INTERNAL_ERROR, false); |
| 238 } |
| 239 if (debug_visitor_) { |
| 240 debug_visitor_->OnVersionNegotiationPacket(packet); |
| 241 } |
| 242 |
| 243 if (version_negotiation_state_ == NEGOTIATED_VERSION) { |
| 244 // Possibly a duplicate version negotiation packet. |
| 245 return; |
| 246 } |
| 247 |
| 248 if (std::find(packet.versions.begin(), |
| 249 packet.versions.end(), quic_version_) != |
| 250 packet.versions.end()) { |
| 251 DLOG(WARNING) << "The server already supports our version. It should have " |
| 252 << "accepted our connection."; |
| 253 // Just drop the connection. |
| 254 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); |
| 255 return; |
| 256 } |
| 257 |
| 258 if (!SelectMutualVersion(packet.versions)) { |
| 259 SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, |
| 260 "no common version found"); |
| 261 } |
| 262 |
| 263 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 264 RetransmitAllUnackedPackets(); |
| 265 } |
| 266 |
159 void QuicConnection::OnRevivedPacket() { | 267 void QuicConnection::OnRevivedPacket() { |
160 } | 268 } |
161 | 269 |
162 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { | 270 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
163 if (debug_visitor_) { | 271 if (debug_visitor_) { |
164 debug_visitor_->OnPacketHeader(header); | 272 debug_visitor_->OnPacketHeader(header); |
165 } | 273 } |
| 274 |
| 275 // Will be decrement below if we fall through to return true; |
| 276 ++stats_.packets_dropped; |
| 277 |
166 if (header.public_header.guid != guid_) { | 278 if (header.public_header.guid != guid_) { |
167 DLOG(INFO) << "Ignoring packet from unexpected GUID: " | 279 DLOG(INFO) << "Ignoring packet from unexpected GUID: " |
168 << header.public_header.guid << " instead of " << guid_; | 280 << header.public_header.guid << " instead of " << guid_; |
169 return false; | 281 return false; |
170 } | 282 } |
171 | 283 |
172 if (!Near(header.packet_sequence_number, | 284 if (!Near(header.packet_sequence_number, |
173 last_header_.packet_sequence_number)) { | 285 last_header_.packet_sequence_number)) { |
174 DLOG(INFO) << "Packet " << header.packet_sequence_number | 286 DLOG(INFO) << "Packet " << header.packet_sequence_number |
175 << " out of bounds. Discarding"; | 287 << " out of bounds. Discarding"; |
176 // TODO(alyssar) close the connection entirely. | 288 // TODO(alyssar) close the connection entirely. |
177 return false; | 289 return false; |
178 } | 290 } |
179 | 291 |
180 // If this packet has already been seen, or that the sender | 292 // If this packet has already been seen, or that the sender |
181 // has told us will not be retransmitted, then stop processing the packet. | 293 // has told us will not be retransmitted, then stop processing the packet. |
182 if (!IsAwaitingPacket(outgoing_ack_.received_info, | 294 if (!IsAwaitingPacket(outgoing_ack_.received_info, |
183 header.packet_sequence_number)) { | 295 header.packet_sequence_number)) { |
184 return false; | 296 return false; |
185 } | 297 } |
186 | 298 |
| 299 if (version_negotiation_state_ != NEGOTIATED_VERSION) { |
| 300 if (is_server_) { |
| 301 if (!header.public_header.version_flag) { |
| 302 DLOG(WARNING) << "Got packet without version flag before version " |
| 303 << "negotiated."; |
| 304 // Packets should have the version flag till version negotiation is |
| 305 // done. |
| 306 CloseConnection(QUIC_INVALID_VERSION, false); |
| 307 return false; |
| 308 } else { |
| 309 DCHECK_EQ(1u, header.public_header.versions.size()); |
| 310 DCHECK_EQ(header.public_header.versions[0], quic_version_); |
| 311 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 312 } |
| 313 } else { |
| 314 DCHECK(!header.public_header.version_flag); |
| 315 // If the client gets a packet without the version flag from the server |
| 316 // it should stop sending version since the version negotiation is done. |
| 317 packet_creator_.StopSendingVersion(); |
| 318 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 319 } |
| 320 } |
| 321 |
| 322 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); |
| 323 |
| 324 --stats_.packets_dropped; |
187 DVLOG(1) << "Received packet header: " << header; | 325 DVLOG(1) << "Received packet header: " << header; |
188 last_header_ = header; | 326 last_header_ = header; |
189 return true; | 327 return true; |
190 } | 328 } |
191 | 329 |
192 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { | 330 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { |
193 DCHECK_NE(0u, last_header_.fec_group); | 331 DCHECK_NE(0u, last_header_.fec_group); |
194 QuicFecGroup* group = GetFecGroup(); | 332 QuicFecGroup* group = GetFecGroup(); |
195 group->Update(last_header_, payload); | 333 group->Update(last_header_, payload); |
196 } | 334 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 370 |
233 UpdatePacketInformationReceivedByPeer(incoming_ack); | 371 UpdatePacketInformationReceivedByPeer(incoming_ack); |
234 UpdatePacketInformationSentByPeer(incoming_ack); | 372 UpdatePacketInformationSentByPeer(incoming_ack); |
235 congestion_manager_.OnIncomingAckFrame(incoming_ack, | 373 congestion_manager_.OnIncomingAckFrame(incoming_ack, |
236 time_of_last_received_packet_); | 374 time_of_last_received_packet_); |
237 | 375 |
238 // Now the we have received an ack, we might be able to send queued packets. | 376 // Now the we have received an ack, we might be able to send queued packets. |
239 if (queued_packets_.empty()) { | 377 if (queued_packets_.empty()) { |
240 return; | 378 return; |
241 } | 379 } |
| 380 bool has_retransmittable_data = true; |
242 | 381 |
243 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( | 382 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
244 time_of_last_received_packet_, false); | 383 time_of_last_received_packet_, false, has_retransmittable_data); |
245 if (delay.IsZero()) { | 384 if (delay.IsZero()) { |
246 helper_->UnregisterSendAlarmIfRegistered(); | 385 helper_->UnregisterSendAlarmIfRegistered(); |
247 if (!write_blocked_) { | 386 if (!write_blocked_) { |
248 OnCanWrite(); | 387 OnCanWrite(); |
249 } | 388 } |
250 } else { | 389 } else if (!delay.IsInfinite()) { |
251 helper_->SetSendAlarm(delay); | 390 helper_->SetSendAlarm(delay); |
252 } | 391 } |
253 } | 392 } |
254 | 393 |
255 void QuicConnection::OnCongestionFeedbackFrame( | 394 void QuicConnection::OnCongestionFeedbackFrame( |
256 const QuicCongestionFeedbackFrame& feedback) { | 395 const QuicCongestionFeedbackFrame& feedback) { |
257 if (debug_visitor_) { | 396 if (debug_visitor_) { |
258 debug_visitor_->OnCongestionFeedbackFrame(feedback); | 397 debug_visitor_->OnCongestionFeedbackFrame(feedback); |
259 } | 398 } |
260 congestion_manager_.OnIncomingQuicCongestionFeedbackFrame( | 399 congestion_manager_.OnIncomingQuicCongestionFeedbackFrame( |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } | 534 } |
396 if (acked_packets.size() > 0) { | 535 if (acked_packets.size() > 0) { |
397 visitor_->OnAck(acked_packets); | 536 visitor_->OnAck(acked_packets); |
398 } | 537 } |
399 } | 538 } |
400 | 539 |
401 bool QuicConnection::DontWaitForPacketsBefore( | 540 bool QuicConnection::DontWaitForPacketsBefore( |
402 QuicPacketSequenceNumber least_unacked) { | 541 QuicPacketSequenceNumber least_unacked) { |
403 size_t missing_packets_count = | 542 size_t missing_packets_count = |
404 outgoing_ack_.received_info.missing_packets.size(); | 543 outgoing_ack_.received_info.missing_packets.size(); |
405 outgoing_ack_.received_info.missing_packets.erase( | 544 outgoing_ack_.received_info.missing_packets.erase( |
406 outgoing_ack_.received_info.missing_packets.begin(), | 545 outgoing_ack_.received_info.missing_packets.begin(), |
407 outgoing_ack_.received_info.missing_packets.lower_bound(least_unacked)); | 546 outgoing_ack_.received_info.missing_packets.lower_bound(least_unacked)); |
408 return missing_packets_count != | 547 return missing_packets_count != |
409 outgoing_ack_.received_info.missing_packets.size(); | 548 outgoing_ack_.received_info.missing_packets.size(); |
410 } | 549 } |
411 | 550 |
412 void QuicConnection::UpdatePacketInformationSentByPeer( | 551 void QuicConnection::UpdatePacketInformationSentByPeer( |
413 const QuicAckFrame& incoming_ack) { | 552 const QuicAckFrame& incoming_ack) { |
414 // ValidateAck() should fail if peer_least_packet_awaiting_ack_ shrinks. | 553 // ValidateAck() should fail if peer_least_packet_awaiting_ack_ shrinks. |
415 DCHECK_LE(peer_least_packet_awaiting_ack_, | 554 DCHECK_LE(peer_least_packet_awaiting_ack_, |
416 incoming_ack.sent_info.least_unacked); | 555 incoming_ack.sent_info.least_unacked); |
417 if (incoming_ack.sent_info.least_unacked > peer_least_packet_awaiting_ack_) { | 556 if (incoming_ack.sent_info.least_unacked > peer_least_packet_awaiting_ack_) { |
418 bool missed_packets = | 557 bool missed_packets = |
419 DontWaitForPacketsBefore(incoming_ack.sent_info.least_unacked); | 558 DontWaitForPacketsBefore(incoming_ack.sent_info.least_unacked); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 if (send_ack_in_response_to_packet_) { | 648 if (send_ack_in_response_to_packet_) { |
510 SendAck(); | 649 SendAck(); |
511 } else if (!last_stream_frames_.empty()) { | 650 } else if (!last_stream_frames_.empty()) { |
512 // TODO(alyssar) this case should really be "if the packet contained any | 651 // TODO(alyssar) this case should really be "if the packet contained any |
513 // non-ack frame", rather than "if the packet contained a stream frame" | 652 // non-ack frame", rather than "if the packet contained a stream frame" |
514 helper_->SetAckAlarm(congestion_manager_.DefaultRetransmissionTime()); | 653 helper_->SetAckAlarm(congestion_manager_.DefaultRetransmissionTime()); |
515 } | 654 } |
516 send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_; | 655 send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_; |
517 } | 656 } |
518 | 657 |
| 658 void QuicConnection::SendVersionNegotiationPacket() { |
| 659 QuicVersionTagList supported_versions; |
| 660 supported_versions.push_back(kQuicVersion1); |
| 661 QuicEncryptedPacket* encrypted = |
| 662 packet_creator_.SerializeVersionNegotiationPacket(supported_versions); |
| 663 // TODO(satyamshekhar): implement zero server state negotiation. |
| 664 int error; |
| 665 helper_->WritePacketToWire(*encrypted, &error); |
| 666 delete encrypted; |
| 667 } |
| 668 |
519 QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id, | 669 QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id, |
520 base::StringPiece data, | 670 base::StringPiece data, |
521 QuicStreamOffset offset, | 671 QuicStreamOffset offset, |
522 bool fin) { | 672 bool fin) { |
523 return packet_generator_.ConsumeData(id, data, offset, fin); | 673 return packet_generator_.ConsumeData(id, data, offset, fin); |
524 } | 674 } |
525 | 675 |
526 void QuicConnection::SendRstStream(QuicStreamId id, | 676 void QuicConnection::SendRstStream(QuicStreamId id, |
527 QuicErrorCode error) { | 677 QuicErrorCode error) { |
528 packet_generator_.AddControlFrame( | 678 packet_generator_.AddControlFrame( |
529 QuicFrame(new QuicRstStreamFrame(id, error))); | 679 QuicFrame(new QuicRstStreamFrame(id, error))); |
530 } | 680 } |
531 | 681 |
| 682 const QuicConnectionStats& QuicConnection::GetStats() { |
| 683 // Update rtt and estimated bandwidth. |
| 684 stats_.rtt = congestion_manager_.SmoothedRtt().ToMicroseconds(); |
| 685 stats_.estimated_bandwidth = |
| 686 congestion_manager_.BandwidthEstimate().ToBytesPerSecond(); |
| 687 return stats_; |
| 688 } |
| 689 |
532 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, | 690 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, |
533 const IPEndPoint& peer_address, | 691 const IPEndPoint& peer_address, |
534 const QuicEncryptedPacket& packet) { | 692 const QuicEncryptedPacket& packet) { |
535 if (debug_visitor_) { | 693 if (debug_visitor_) { |
536 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); | 694 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); |
537 } | 695 } |
538 last_packet_revived_ = false; | 696 last_packet_revived_ = false; |
539 last_size_ = packet.length(); | 697 last_size_ = packet.length(); |
540 last_self_address_ = self_address; | 698 last_self_address_ = self_address; |
541 last_peer_address_ = peer_address; | 699 last_peer_address_ = peer_address; |
| 700 |
| 701 stats_.bytes_received += packet.length(); |
| 702 ++stats_.packets_received; |
| 703 |
542 framer_.ProcessPacket(packet); | 704 framer_.ProcessPacket(packet); |
543 MaybeProcessRevivedPacket(); | 705 MaybeProcessRevivedPacket(); |
544 } | 706 } |
545 | 707 |
546 bool QuicConnection::OnCanWrite() { | 708 bool QuicConnection::OnCanWrite() { |
547 LOG(INFO) << "here!!!"; | |
548 write_blocked_ = false; | 709 write_blocked_ = false; |
549 | 710 |
550 WriteQueuedPackets(); | 711 WriteQueuedPackets(); |
551 | 712 |
552 // Sending queued packets may have caused the socket to become write blocked, | 713 // Sending queued packets may have caused the socket to become write blocked, |
553 // or the congestion manager to prohibit sending. If we've sent everything | 714 // or the congestion manager to prohibit sending. If we've sent everything |
554 // we had queued and we're still not blocked, let the visitor know it can | 715 // we had queued and we're still not blocked, let the visitor know it can |
555 // write more. | 716 // write more. |
556 // TODO(rch): shouldn't this be "if (CanWrite(false))" | 717 if (CanWrite(false, true)) { |
557 if (!write_blocked_) { | |
558 packet_generator_.StartBatchOperations(); | 718 packet_generator_.StartBatchOperations(); |
559 bool all_bytes_written = visitor_->OnCanWrite(); | 719 bool all_bytes_written = visitor_->OnCanWrite(); |
560 packet_generator_.FinishBatchOperations(); | 720 packet_generator_.FinishBatchOperations(); |
561 | 721 |
562 // After the visitor writes, it may have caused the socket to become write | 722 // After the visitor writes, it may have caused the socket to become write |
563 // blocked or the congestion manager to prohibit sending, so check again. | 723 // blocked or the congestion manager to prohibit sending, so check again. |
564 if (!write_blocked_ && !all_bytes_written && !helper_->IsSendAlarmSet()) { | 724 if (!write_blocked_ && !all_bytes_written && CanWrite(false, true)) { |
565 // We're not write blocked, but some stream didn't write out all of its | 725 // We're not write blocked, but some stream didn't write out all of its |
566 // bytes. Register for 'immediate' resumption so we'll keep writing after | 726 // bytes. Register for 'immediate' resumption so we'll keep writing after |
567 // other quic connections have had a chance to use the socket. | 727 // other quic connections have had a chance to use the socket. |
568 helper_->SetSendAlarm(QuicTime::Delta::Zero()); | 728 helper_->SetSendAlarm(QuicTime::Delta::Zero()); |
569 } | 729 } |
570 } | 730 } |
571 | 731 |
572 return !write_blocked_; | 732 return !write_blocked_; |
573 } | 733 } |
574 | 734 |
575 bool QuicConnection::WriteQueuedPackets() { | 735 bool QuicConnection::WriteQueuedPackets() { |
576 DCHECK(!write_blocked_); | 736 DCHECK(!write_blocked_); |
577 | 737 |
578 size_t num_queued_packets = queued_packets_.size() + 1; | 738 size_t num_queued_packets = queued_packets_.size() + 1; |
579 QueuedPacketList::iterator packet_iterator = queued_packets_.begin(); | 739 QueuedPacketList::iterator packet_iterator = queued_packets_.begin(); |
580 while (!write_blocked_ && !helper_->IsSendAlarmSet() && | 740 while (!write_blocked_ && packet_iterator != queued_packets_.end()) { |
581 packet_iterator != queued_packets_.end()) { | |
582 // Ensure that from one iteration of this loop to the next we | 741 // Ensure that from one iteration of this loop to the next we |
583 // succeeded in sending a packet so we don't infinitely loop. | 742 // succeeded in sending a packet so we don't infinitely loop. |
584 // TODO(rch): clean up and close the connection if we really hit this. | 743 // TODO(rch): clean up and close the connection if we really hit this. |
585 DCHECK_LT(queued_packets_.size(), num_queued_packets); | 744 DCHECK_LT(queued_packets_.size(), num_queued_packets); |
586 num_queued_packets = queued_packets_.size(); | 745 num_queued_packets = queued_packets_.size(); |
587 if (WritePacket(packet_iterator->sequence_number, | 746 if (WritePacket(packet_iterator->sequence_number, |
588 packet_iterator->packet, kHasRetransmittableData, | 747 packet_iterator->packet, |
| 748 packet_iterator->has_retransmittable_data, |
589 !kForce)) { | 749 !kForce)) { |
590 packet_iterator = queued_packets_.erase(packet_iterator); | 750 packet_iterator = queued_packets_.erase(packet_iterator); |
591 } else { | 751 } else { |
592 // Continue, because some queued packets may still be writable. | 752 // Continue, because some queued packets may still be writable. |
| 753 // This can happen if a retransmit send fail. |
593 ++packet_iterator; | 754 ++packet_iterator; |
594 } | 755 } |
595 } | 756 } |
596 | 757 |
597 return !write_blocked_; | 758 return !write_blocked_; |
598 } | 759 } |
599 | 760 |
600 void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) { | 761 void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) { |
601 DLOG(INFO) << "Recording received packet: " << header.packet_sequence_number; | 762 DLOG(INFO) << "Recording received packet: " << header.packet_sequence_number; |
602 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; | 763 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
603 DCHECK(IsAwaitingPacket(outgoing_ack_.received_info, sequence_number)); | 764 DCHECK(IsAwaitingPacket(outgoing_ack_.received_info, sequence_number)); |
604 | 765 |
605 InsertMissingPacketsBetween( | 766 InsertMissingPacketsBetween( |
606 &outgoing_ack_.received_info, | 767 &outgoing_ack_.received_info, |
607 max(outgoing_ack_.received_info.largest_observed + 1, | 768 max(outgoing_ack_.received_info.largest_observed + 1, |
608 peer_least_packet_awaiting_ack_), | 769 peer_least_packet_awaiting_ack_), |
609 header.packet_sequence_number); | 770 header.packet_sequence_number); |
610 | 771 |
611 if (outgoing_ack_.received_info.largest_observed > | 772 if (outgoing_ack_.received_info.largest_observed > |
612 header.packet_sequence_number) { | 773 header.packet_sequence_number) { |
613 // We've gotten one of the out of order packets - remove it from our | 774 // We've gotten one of the out of order packets - remove it from our |
614 // "missing packets" list. | 775 // "missing packets" list. |
615 DVLOG(1) << "Removing " << sequence_number << " from missing list"; | 776 DVLOG(1) << "Removing " << sequence_number << " from missing list"; |
616 outgoing_ack_.received_info.missing_packets.erase(sequence_number); | 777 outgoing_ack_.received_info.missing_packets.erase(sequence_number); |
617 } | 778 } |
618 outgoing_ack_.received_info.largest_observed = max( | 779 outgoing_ack_.received_info.largest_observed = max( |
619 outgoing_ack_.received_info.largest_observed, | 780 outgoing_ack_.received_info.largest_observed, |
620 header.packet_sequence_number); | 781 header.packet_sequence_number); |
| 782 // TODO(pwestin): update received_info with time_of_last_received_packet_. |
621 entropy_manager_.RecordReceivedPacketEntropyHash(sequence_number, | 783 entropy_manager_.RecordReceivedPacketEntropyHash(sequence_number, |
622 header.entropy_hash); | 784 header.entropy_hash); |
623 } | 785 } |
624 | 786 |
625 bool QuicConnection::MaybeRetransmitPacketForRTO( | 787 bool QuicConnection::MaybeRetransmitPacketForRTO( |
626 QuicPacketSequenceNumber sequence_number) { | 788 QuicPacketSequenceNumber sequence_number) { |
627 DCHECK_EQ(ContainsKey(unacked_packets_, sequence_number), | 789 DCHECK_EQ(ContainsKey(unacked_packets_, sequence_number), |
628 ContainsKey(retransmission_map_, sequence_number)); | 790 ContainsKey(retransmission_map_, sequence_number)); |
629 | 791 |
630 if (!ContainsKey(unacked_packets_, sequence_number)) { | 792 if (!ContainsKey(unacked_packets_, sequence_number)) { |
631 DVLOG(2) << "alarm fired for " << sequence_number | 793 DVLOG(2) << "alarm fired for " << sequence_number |
632 << " but it has been acked or already retransmitted with" | 794 << " but it has been acked or already retransmitted with" |
633 << " different sequence number."; | 795 << " different sequence number."; |
634 // So no extra delay is added for this packet. | 796 // So no extra delay is added for this packet. |
635 return true; | 797 return true; |
636 } | 798 } |
637 | 799 |
638 // If the packet hasn't been acked and we're getting truncated acks, ignore | 800 // If the packet hasn't been acked and we're getting truncated acks, ignore |
639 // any RTO for packets larger than the peer's largest observed packet; it may | 801 // any RTO for packets larger than the peer's largest observed packet; it may |
640 // have been received by the peer and just wasn't acked due to the ack frame | 802 // have been received by the peer and just wasn't acked due to the ack frame |
641 // running out of space. | 803 // running out of space. |
642 if (received_truncated_ack_ && | 804 if (received_truncated_ack_ && |
643 sequence_number > peer_largest_observed_packet_) { | 805 sequence_number > peer_largest_observed_packet_) { |
644 return false; | 806 return false; |
645 } else { | 807 } else { |
| 808 ++stats_.rto_count; |
646 RetransmitPacket(sequence_number); | 809 RetransmitPacket(sequence_number); |
647 return true; | 810 return true; |
648 } | 811 } |
649 } | 812 } |
650 | 813 |
| 814 void QuicConnection::RetransmitAllUnackedPackets() { |
| 815 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 816 it != unacked_packets_.end(); ++it) { |
| 817 RetransmitPacket(it->first); |
| 818 } |
| 819 } |
| 820 |
651 void QuicConnection::RetransmitPacket( | 821 void QuicConnection::RetransmitPacket( |
652 QuicPacketSequenceNumber sequence_number) { | 822 QuicPacketSequenceNumber sequence_number) { |
653 UnackedPacketMap::iterator unacked_it = | 823 UnackedPacketMap::iterator unacked_it = |
654 unacked_packets_.find(sequence_number); | 824 unacked_packets_.find(sequence_number); |
655 RetransmissionMap::iterator retransmission_it = | 825 RetransmissionMap::iterator retransmission_it = |
656 retransmission_map_.find(sequence_number); | 826 retransmission_map_.find(sequence_number); |
657 // There should always be an entry corresponding to |sequence_number| in | 827 // There should always be an entry corresponding to |sequence_number| in |
658 // both |retransmission_map_| and |unacked_packets_|. Retransmissions due to | 828 // both |retransmission_map_| and |unacked_packets_|. Retransmissions due to |
659 // RTO for sequence numbers that are already acked or retransmitted are | 829 // RTO for sequence numbers that are already acked or retransmitted are |
660 // ignored by MaybeRetransmitPacketForRTO. | 830 // ignored by MaybeRetransmitPacketForRTO. |
661 DCHECK(unacked_it != unacked_packets_.end()); | 831 DCHECK(unacked_it != unacked_packets_.end()); |
662 DCHECK(retransmission_it != retransmission_map_.end()); | 832 DCHECK(retransmission_it != retransmission_map_.end()); |
663 RetransmittableFrames* unacked = unacked_it->second; | 833 RetransmittableFrames* unacked = unacked_it->second; |
| 834 // TODO(pwestin): Need to fix potential issue with FEC and a 1 packet |
| 835 // congestion window see b/8331807 for details. |
| 836 congestion_manager_.AbandoningPacket(sequence_number); |
664 // TODO(ianswett): Never change the sequence number of the connect packet. | 837 // TODO(ianswett): Never change the sequence number of the connect packet. |
665 // Re-packetize the frames with a new sequence number for retransmission. | 838 // Re-packetize the frames with a new sequence number for retransmission. |
666 // Retransmitted data packets do not use FEC, even when it's enabled. | 839 // Retransmitted data packets do not use FEC, even when it's enabled. |
667 SerializedPacket serialized_packet = | 840 SerializedPacket serialized_packet = |
668 packet_creator_.SerializeAllFrames(unacked->frames()); | 841 packet_creator_.SerializeAllFrames(unacked->frames()); |
669 RetransmissionInfo retransmission_info(serialized_packet.sequence_number); | 842 RetransmissionInfo retransmission_info(serialized_packet.sequence_number); |
670 retransmission_info.number_retransmissions = | 843 retransmission_info.number_retransmissions = |
671 retransmission_it->second.number_retransmissions + 1; | 844 retransmission_it->second.number_retransmissions + 1; |
672 retransmission_map_.insert(make_pair(serialized_packet.sequence_number, | 845 retransmission_map_.insert(make_pair(serialized_packet.sequence_number, |
673 retransmission_info)); | 846 retransmission_info)); |
674 // Remove info with old sequence number. | 847 // Remove info with old sequence number. |
675 unacked_packets_.erase(unacked_it); | 848 unacked_packets_.erase(unacked_it); |
676 retransmission_map_.erase(retransmission_it); | 849 retransmission_map_.erase(retransmission_it); |
677 DVLOG(1) << "Retransmitting unacked packet " << sequence_number << " as " | 850 DVLOG(1) << "Retransmitting unacked packet " << sequence_number << " as " |
678 << serialized_packet.sequence_number; | 851 << serialized_packet.sequence_number; |
679 DCHECK(unacked_packets_.empty() || | 852 DCHECK(unacked_packets_.empty() || |
680 unacked_packets_.rbegin()->first < serialized_packet.sequence_number); | 853 unacked_packets_.rbegin()->first < serialized_packet.sequence_number); |
681 unacked_packets_.insert(make_pair(serialized_packet.sequence_number, | 854 unacked_packets_.insert(make_pair(serialized_packet.sequence_number, |
682 unacked)); | 855 unacked)); |
683 SendOrQueuePacket(serialized_packet.sequence_number, | 856 SendOrQueuePacket(serialized_packet.sequence_number, |
684 serialized_packet.packet, | 857 serialized_packet.packet, |
685 serialized_packet.entropy_hash, | 858 serialized_packet.entropy_hash, |
686 true); | 859 true); |
687 } | 860 } |
688 | 861 |
689 bool QuicConnection::CanWrite(bool is_retransmission) { | 862 bool QuicConnection::CanWrite(bool is_retransmission, |
| 863 bool has_retransmittable_data) { |
690 // TODO(ianswett): If the packet is a retransmit, the current send alarm may | 864 // TODO(ianswett): If the packet is a retransmit, the current send alarm may |
691 // be too long. | 865 // be too long. |
692 if (write_blocked_ || helper_->IsSendAlarmSet()) { | 866 if (write_blocked_ || helper_->IsSendAlarmSet()) { |
693 return false; | 867 return false; |
694 } | 868 } |
695 QuicTime::Delta delay = congestion_manager_.TimeUntilSend(clock_->Now(), | 869 |
696 is_retransmission); | 870 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
| 871 clock_->Now(), is_retransmission, has_retransmittable_data); |
| 872 if (delay.IsInfinite()) { |
| 873 return false; |
| 874 } |
| 875 |
697 // If the scheduler requires a delay, then we can not send this packet now. | 876 // If the scheduler requires a delay, then we can not send this packet now. |
698 if (!delay.IsZero() && !delay.IsInfinite()) { | 877 if (!delay.IsZero()) { |
699 // TODO(pwestin): we need to handle delay.IsInfinite() separately. | |
700 helper_->SetSendAlarm(delay); | 878 helper_->SetSendAlarm(delay); |
701 return false; | 879 return false; |
702 } | 880 } |
703 return true; | 881 return true; |
704 } | 882 } |
705 | 883 |
706 bool QuicConnection::IsRetransmission( | 884 bool QuicConnection::IsRetransmission( |
707 QuicPacketSequenceNumber sequence_number) { | 885 QuicPacketSequenceNumber sequence_number) { |
708 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); | 886 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); |
709 return it != retransmission_map_.end() && | 887 return it != retransmission_map_.end() && |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 DLOG(INFO) | 923 DLOG(INFO) |
746 << "Dropping packet to be sent since connection is disconnected."; | 924 << "Dropping packet to be sent since connection is disconnected."; |
747 delete packet; | 925 delete packet; |
748 // Returning true because we deleted the packet and the caller shouldn't | 926 // Returning true because we deleted the packet and the caller shouldn't |
749 // delete it again. | 927 // delete it again. |
750 return true; | 928 return true; |
751 } | 929 } |
752 | 930 |
753 bool is_retransmission = IsRetransmission(sequence_number); | 931 bool is_retransmission = IsRetransmission(sequence_number); |
754 // If we are not forced and we can't write, then simply return false; | 932 // If we are not forced and we can't write, then simply return false; |
755 if (!forced && !CanWrite(is_retransmission)) { | 933 if (!forced && !CanWrite(is_retransmission, has_retransmittable_data)) { |
756 return false; | 934 return false; |
757 } | 935 } |
758 | 936 |
759 scoped_ptr<QuicEncryptedPacket> encrypted( | 937 scoped_ptr<QuicEncryptedPacket> encrypted( |
760 framer_.EncryptPacket(sequence_number, *packet)); | 938 framer_.EncryptPacket(sequence_number, *packet)); |
761 DLOG(INFO) << "Sending packet number " << sequence_number << " : " | 939 DLOG(INFO) << "Sending packet number " << sequence_number << " : " |
762 << (packet->is_fec_packet() ? "FEC " : | 940 << (packet->is_fec_packet() ? "FEC " : |
763 (ContainsKey(retransmission_map_, sequence_number) ? | 941 (has_retransmittable_data ? "data bearing " : " ack only ")) |
764 "data bearing " : " ack only ")); | 942 << " Packet length:" << packet->length(); |
765 | 943 |
766 DCHECK(encrypted->length() <= kMaxPacketSize) | 944 DCHECK(encrypted->length() <= kMaxPacketSize) |
767 << "Packet " << sequence_number << " will not be read; too large: " | 945 << "Packet " << sequence_number << " will not be read; too large: " |
768 << packet->length() << " " << encrypted->length() << " " | 946 << packet->length() << " " << encrypted->length() << " " |
769 << outgoing_ack_; | 947 << outgoing_ack_ << " forced: " << (forced ? "yes" : "no"); |
770 | 948 |
771 int error; | 949 int error; |
772 QuicTime now = clock_->Now(); | 950 QuicTime now = clock_->Now(); |
773 int rv = helper_->WritePacketToWire(*encrypted, &error); | 951 int rv = helper_->WritePacketToWire(*encrypted, &error); |
774 if (rv == -1 && error == ERR_IO_PENDING) { | 952 if (rv == -1 && error == ERR_IO_PENDING) { |
775 // TODO(satyashekhar): It might be more efficient (fewer system calls), if | 953 // TODO(satyashekhar): It might be more efficient (fewer system calls), if |
776 // all connections share this variable i.e this becomes a part of | 954 // all connections share this variable i.e this becomes a part of |
777 // PacketWriterInterface. | 955 // PacketWriterInterface. |
778 write_blocked_ = true; | 956 write_blocked_ = true; |
779 return false; | 957 return false; |
780 } | 958 } |
781 time_of_last_sent_packet_ = now; | 959 time_of_last_sent_packet_ = now; |
782 DVLOG(1) << "time of last sent packet: " << now.ToMicroseconds(); | 960 DVLOG(1) << "time of last sent packet: " << now.ToMicroseconds(); |
783 // TODO(wtc): Is it correct to continue if the write failed. | 961 // TODO(wtc): Is it correct to continue if the write failed. |
784 | 962 |
785 // Set the retransmit alarm only when we have sent the packet to the client | 963 // Set the retransmit alarm only when we have sent the packet to the client |
786 // and not when it goes to the pending queue, otherwise we will end up adding | 964 // and not when it goes to the pending queue, otherwise we will end up adding |
787 // an entry to retransmission_timeout_ every time we attempt a write. | 965 // an entry to retransmission_timeout_ every time we attempt a write. |
788 MaybeSetupRetransmission(sequence_number); | 966 MaybeSetupRetransmission(sequence_number); |
789 | 967 |
790 congestion_manager_.SentPacket(sequence_number, now, packet->length(), | 968 congestion_manager_.SentPacket(sequence_number, now, packet->length(), |
791 is_retransmission, has_retransmittable_data); | 969 is_retransmission); |
| 970 |
| 971 stats_.bytes_sent += encrypted->length(); |
| 972 ++stats_.packets_sent; |
| 973 |
| 974 if (is_retransmission) { |
| 975 stats_.bytes_retransmitted += encrypted->length(); |
| 976 ++stats_.packets_retransmitted; |
| 977 } |
| 978 |
792 delete packet; | 979 delete packet; |
793 return true; | 980 return true; |
794 } | 981 } |
795 | 982 |
796 bool QuicConnection::OnSerializedPacket( | 983 bool QuicConnection::OnSerializedPacket( |
797 const SerializedPacket& serialized_packet) { | 984 const SerializedPacket& serialized_packet) { |
798 if (serialized_packet.retransmittable_frames != NULL) { | 985 if (serialized_packet.retransmittable_frames != NULL) { |
799 DCHECK(unacked_packets_.empty() || | 986 DCHECK(unacked_packets_.empty() || |
800 unacked_packets_.rbegin()->first < | 987 unacked_packets_.rbegin()->first < |
801 serialized_packet.sequence_number); | 988 serialized_packet.sequence_number); |
(...skipping 12 matching lines...) Expand all Loading... |
814 } | 1001 } |
815 | 1002 |
816 bool QuicConnection::SendOrQueuePacket(QuicPacketSequenceNumber sequence_number, | 1003 bool QuicConnection::SendOrQueuePacket(QuicPacketSequenceNumber sequence_number, |
817 QuicPacket* packet, | 1004 QuicPacket* packet, |
818 QuicPacketEntropyHash entropy_hash, | 1005 QuicPacketEntropyHash entropy_hash, |
819 bool has_retransmittable_data) { | 1006 bool has_retransmittable_data) { |
820 entropy_manager_.RecordSentPacketEntropyHash(sequence_number, | 1007 entropy_manager_.RecordSentPacketEntropyHash(sequence_number, |
821 entropy_hash); | 1008 entropy_hash); |
822 if (!WritePacket(sequence_number, packet, has_retransmittable_data, | 1009 if (!WritePacket(sequence_number, packet, has_retransmittable_data, |
823 !kForce)) { | 1010 !kForce)) { |
824 queued_packets_.push_back(QueuedPacket(sequence_number, packet)); | 1011 queued_packets_.push_back(QueuedPacket(sequence_number, packet, |
| 1012 has_retransmittable_data)); |
825 return false; | 1013 return false; |
826 } | 1014 } |
827 return true; | 1015 return true; |
828 } | 1016 } |
829 | 1017 |
830 bool QuicConnection::ShouldSimulateLostPacket() { | 1018 bool QuicConnection::ShouldSimulateLostPacket() { |
831 // TODO(rch): enable this | 1019 // TODO(rch): enable this |
832 return false; | 1020 return false; |
833 /* | 1021 /* |
834 return FLAGS_fake_packet_loss_percentage > 0 && | 1022 return FLAGS_fake_packet_loss_percentage > 0 && |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 revived_header.fec_flag = false; | 1112 revived_header.fec_flag = false; |
925 revived_header.fec_group = kNoFecOffset; | 1113 revived_header.fec_group = kNoFecOffset; |
926 group_map_.erase(last_header_.fec_group); | 1114 group_map_.erase(last_header_.fec_group); |
927 delete group; | 1115 delete group; |
928 | 1116 |
929 last_packet_revived_ = true; | 1117 last_packet_revived_ = true; |
930 if (debug_visitor_) { | 1118 if (debug_visitor_) { |
931 debug_visitor_->OnRevivedPacket(revived_header, | 1119 debug_visitor_->OnRevivedPacket(revived_header, |
932 StringPiece(revived_payload, len)); | 1120 StringPiece(revived_payload, len)); |
933 } | 1121 } |
| 1122 |
| 1123 ++stats_.packets_revived; |
934 framer_.ProcessRevivedPacket(&revived_header, | 1124 framer_.ProcessRevivedPacket(&revived_header, |
935 StringPiece(revived_payload, len)); | 1125 StringPiece(revived_payload, len)); |
936 } | 1126 } |
937 | 1127 |
938 QuicFecGroup* QuicConnection::GetFecGroup() { | 1128 QuicFecGroup* QuicConnection::GetFecGroup() { |
939 QuicFecGroupNumber fec_group_num = last_header_.fec_group; | 1129 QuicFecGroupNumber fec_group_num = last_header_.fec_group; |
940 if (fec_group_num == 0) { | 1130 if (fec_group_num == 0) { |
941 return NULL; | 1131 return NULL; |
942 } | 1132 } |
943 if (group_map_.count(fec_group_num) == 0) { | 1133 if (group_map_.count(fec_group_num) == 0) { |
(...skipping 25 matching lines...) Expand all Loading... |
969 serialized_packet.retransmittable_frames != NULL); | 1159 serialized_packet.retransmittable_frames != NULL); |
970 } | 1160 } |
971 | 1161 |
972 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, | 1162 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, |
973 const string& details) { | 1163 const string& details) { |
974 SendConnectionClosePacket(error, details); | 1164 SendConnectionClosePacket(error, details); |
975 CloseConnection(error, false); | 1165 CloseConnection(error, false); |
976 } | 1166 } |
977 | 1167 |
978 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { | 1168 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { |
979 // TODO(satyamshekhar): Ask the dispatcher to delete visitor and hence self | |
980 // if the visitor will always be deleted by closing the connection. | |
981 connected_ = false; | 1169 connected_ = false; |
982 visitor_->ConnectionClose(error, from_peer); | 1170 visitor_->ConnectionClose(error, from_peer); |
983 } | 1171 } |
984 | 1172 |
985 void QuicConnection::SendGoAway(QuicErrorCode error, | 1173 void QuicConnection::SendGoAway(QuicErrorCode error, |
986 QuicStreamId last_good_stream_id, | 1174 QuicStreamId last_good_stream_id, |
987 const string& reason) { | 1175 const string& reason) { |
988 DLOG(INFO) << "Going away with error " << QuicUtils::ErrorToString(error) | 1176 DLOG(INFO) << "Going away with error " << QuicUtils::ErrorToString(error) |
989 << " (" << error << ")"; | 1177 << " (" << error << ")"; |
990 packet_generator_.AddControlFrame( | 1178 packet_generator_.AddControlFrame( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 << " delta:" << delta.ToMicroseconds(); | 1215 << " delta:" << delta.ToMicroseconds(); |
1028 if (delta >= timeout_) { | 1216 if (delta >= timeout_) { |
1029 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 1217 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
1030 return true; | 1218 return true; |
1031 } | 1219 } |
1032 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 1220 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); |
1033 return false; | 1221 return false; |
1034 } | 1222 } |
1035 | 1223 |
1036 } // namespace net | 1224 } // namespace net |
OLD | NEW |