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 12 matching lines...) Expand all Loading... |
23 using std::set; | 23 using std::set; |
24 using std::string; | 24 using std::string; |
25 | 25 |
26 namespace net { | 26 namespace net { |
27 namespace { | 27 namespace { |
28 | 28 |
29 // The largest gap in packets we'll accept without closing the connection. | 29 // The largest gap in packets we'll accept without closing the connection. |
30 // This will likely have to be tuned. | 30 // This will likely have to be tuned. |
31 const QuicPacketSequenceNumber kMaxPacketGap = 5000; | 31 const QuicPacketSequenceNumber kMaxPacketGap = 5000; |
32 | 32 |
33 // The maximum number of nacks which can be transmitted in a single ack packet | |
34 // without exceeding kMaxPacketSize. | |
35 // TODO(satyamshekhar): Get rid of magic numbers and move this to protocol.h | |
36 // 16 - Min ack frame size. | |
37 // 16 - Crypto hash for integrity. Not a static value. Use | |
38 // QuicEncrypter::GetMaxPlaintextSize. | |
39 size_t GetMaxUnackedPackets(bool include_version) { | |
40 return (kMaxPacketSize - GetPacketHeaderSize(include_version) - 16 - 16) / | |
41 kSequenceNumberSize; | |
42 } | |
43 | |
44 // We want to make sure if we get a large nack packet, we don't queue up too | 33 // We want to make sure if we get a large nack packet, we don't queue up too |
45 // many packets at once. 10 is arbitrary. | 34 // many packets at once. 10 is arbitrary. |
46 const int kMaxRetransmissionsPerAck = 10; | 35 const int kMaxRetransmissionsPerAck = 10; |
47 | 36 |
48 // TCP retransmits after 2 nacks. We allow for a third in case of out-of-order | 37 // TCP retransmits after 2 nacks. We allow for a third in case of out-of-order |
49 // delivery. | 38 // delivery. |
50 // TODO(ianswett): Change to match TCP's rule of retransmitting once an ack | 39 // TODO(ianswett): Change to match TCP's rule of retransmitting once an ack |
51 // at least 3 sequence numbers larger arrives. | 40 // at least 3 sequence numbers larger arrives. |
52 const size_t kNumberOfNacksBeforeRetransmission = 3; | 41 const size_t kNumberOfNacksBeforeRetransmission = 3; |
53 | 42 |
54 // The maxiumum number of packets we'd like to queue. We may end up queueing | 43 // The maxiumum number of packets we'd like to queue. We may end up queueing |
55 // more in the case of many control frames. | 44 // more in the case of many control frames. |
56 // 6 is arbitrary. | 45 // 6 is arbitrary. |
57 const int kMaxPacketsToSerializeAtOnce = 6; | 46 const int kMaxPacketsToSerializeAtOnce = 6; |
58 | 47 |
59 // Limit the number of packets we send per retransmission-alarm so we | 48 // Limit the number of packets we send per retransmission-alarm so we |
60 // eventually cede. 10 is arbitrary. | 49 // eventually cede. 10 is arbitrary. |
61 const int kMaxPacketsPerRetransmissionAlarm = 10; | 50 const size_t kMaxPacketsPerRetransmissionAlarm = 10; |
| 51 |
| 52 // Limit the number of FEC groups to two. If we get enough out of order packets |
| 53 // that this becomes limiting, we can revisit. |
| 54 const size_t kMaxFecGroups = 2; |
62 | 55 |
63 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 56 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
64 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 57 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
65 return delta <= kMaxPacketGap; | 58 return delta <= kMaxPacketGap; |
66 } | 59 } |
67 | 60 |
68 } // namespace | 61 } // namespace |
69 | 62 |
70 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 63 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
71 | 64 |
(...skipping 12 matching lines...) Expand all Loading... |
84 peer_address_(address), | 77 peer_address_(address), |
85 largest_seen_packet_with_ack_(0), | 78 largest_seen_packet_with_ack_(0), |
86 peer_largest_observed_packet_(0), | 79 peer_largest_observed_packet_(0), |
87 least_packet_awaited_by_peer_(1), | 80 least_packet_awaited_by_peer_(1), |
88 peer_least_packet_awaiting_ack_(0), | 81 peer_least_packet_awaiting_ack_(0), |
89 handling_retransmission_timeout_(false), | 82 handling_retransmission_timeout_(false), |
90 write_blocked_(false), | 83 write_blocked_(false), |
91 debug_visitor_(NULL), | 84 debug_visitor_(NULL), |
92 packet_creator_(guid_, &framer_, random_generator_, is_server), | 85 packet_creator_(guid_, &framer_, random_generator_, is_server), |
93 packet_generator_(this, &packet_creator_), | 86 packet_generator_(this, &packet_creator_), |
94 timeout_(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs)), | 87 timeout_(QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
95 time_of_last_received_packet_(clock_->ApproximateNow()), | 88 time_of_last_received_packet_(clock_->ApproximateNow()), |
96 time_of_last_sent_packet_(clock_->ApproximateNow()), | 89 time_of_last_sent_packet_(clock_->ApproximateNow()), |
97 time_largest_observed_(QuicTime::Zero()), | 90 time_largest_observed_(QuicTime::Zero()), |
98 congestion_manager_(clock_, kTCP), | 91 congestion_manager_(clock_, kTCP), |
99 version_negotiation_state_(START_NEGOTIATION), | 92 version_negotiation_state_(START_NEGOTIATION), |
100 quic_version_(kQuicVersion1), | 93 quic_version_(kQuicVersion1), |
| 94 max_packets_per_retransmission_alarm_(kMaxPacketsPerRetransmissionAlarm), |
101 is_server_(is_server), | 95 is_server_(is_server), |
102 connected_(true), | 96 connected_(true), |
103 received_truncated_ack_(false), | 97 received_truncated_ack_(false), |
104 send_ack_in_response_to_packet_(false) { | 98 send_ack_in_response_to_packet_(false), |
| 99 address_migrating_(false) { |
105 helper_->SetConnection(this); | 100 helper_->SetConnection(this); |
106 // TODO(satyamshekhar): Have a smaller timeout till version is negotiated and | |
107 // connection is established (CHLO fully processed). | |
108 helper_->SetTimeoutAlarm(timeout_); | 101 helper_->SetTimeoutAlarm(timeout_); |
109 framer_.set_visitor(this); | 102 framer_.set_visitor(this); |
110 framer_.set_entropy_calculator(&entropy_manager_); | 103 framer_.set_entropy_calculator(&entropy_manager_); |
111 outgoing_ack_.sent_info.least_unacked = 0; | 104 outgoing_ack_.sent_info.least_unacked = 0; |
112 outgoing_ack_.sent_info.entropy_hash = 0; | 105 outgoing_ack_.sent_info.entropy_hash = 0; |
113 outgoing_ack_.received_info.largest_observed = 0; | 106 outgoing_ack_.received_info.largest_observed = 0; |
114 outgoing_ack_.received_info.entropy_hash = 0; | 107 outgoing_ack_.received_info.entropy_hash = 0; |
115 | 108 |
116 /* | 109 /* |
117 if (FLAGS_fake_packet_loss_percentage > 0) { | 110 if (FLAGS_fake_packet_loss_percentage > 0) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 146 } |
154 SendConnectionClose(framer->error()); | 147 SendConnectionClose(framer->error()); |
155 } | 148 } |
156 | 149 |
157 void QuicConnection::OnPacket() { | 150 void QuicConnection::OnPacket() { |
158 // TODO(satyamshekhar): Validate packet before updating the time | 151 // TODO(satyamshekhar): Validate packet before updating the time |
159 // since it affects the timeout of the connection. | 152 // since it affects the timeout of the connection. |
160 time_of_last_received_packet_ = clock_->Now(); | 153 time_of_last_received_packet_ = clock_->Now(); |
161 DVLOG(1) << "time of last received packet: " | 154 DVLOG(1) << "time of last received packet: " |
162 << time_of_last_received_packet_.ToDebuggingValue(); | 155 << time_of_last_received_packet_.ToDebuggingValue(); |
163 | |
164 // TODO(alyssar, rch) handle migration! | |
165 self_address_ = last_self_address_; | |
166 peer_address_ = last_peer_address_; | |
167 } | 156 } |
168 | 157 |
169 void QuicConnection::OnPublicResetPacket( | 158 void QuicConnection::OnPublicResetPacket( |
170 const QuicPublicResetPacket& packet) { | 159 const QuicPublicResetPacket& packet) { |
171 if (debug_visitor_) { | 160 if (debug_visitor_) { |
172 debug_visitor_->OnPublicResetPacket(packet); | 161 debug_visitor_->OnPublicResetPacket(packet); |
173 } | 162 } |
174 CloseConnection(QUIC_PUBLIC_RESET, true); | 163 CloseConnection(QUIC_PUBLIC_RESET, true); |
175 } | 164 } |
176 | 165 |
177 bool QuicConnection::OnProtocolVersionMismatch(QuicTag received_version) { | 166 bool QuicConnection::OnProtocolVersionMismatch(QuicTag received_version) { |
| 167 if (address_migrating_) { |
| 168 SendConnectionCloseWithDetails( |
| 169 QUIC_ERROR_MIGRATING_ADDRESS, |
| 170 "Address migration is not yet a supported feature"); |
| 171 } |
| 172 |
178 // TODO(satyamshekhar): Implement no server state in this mode. | 173 // TODO(satyamshekhar): Implement no server state in this mode. |
179 if (!is_server_) { | 174 if (!is_server_) { |
180 LOG(DFATAL) << "Framer called OnProtocolVersionMismatch for server. " | 175 LOG(DFATAL) << "Framer called OnProtocolVersionMismatch for server. " |
181 << "Closing connection."; | 176 << "Closing connection."; |
182 CloseConnection(QUIC_INTERNAL_ERROR, false); | 177 CloseConnection(QUIC_INTERNAL_ERROR, false); |
183 return false; | 178 return false; |
184 } | 179 } |
185 DCHECK_NE(quic_version_, received_version); | 180 DCHECK_NE(quic_version_, received_version); |
186 | 181 |
187 if (debug_visitor_) { | 182 if (debug_visitor_) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 version_negotiation_state_ = NEGOTIATED_VERSION; | 214 version_negotiation_state_ = NEGOTIATED_VERSION; |
220 // TODO(satyamshekhar): Store the sequence number of this packet and close the | 215 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
221 // connection if we ever received a packet with incorrect version and whose | 216 // connection if we ever received a packet with incorrect version and whose |
222 // sequence number is greater. | 217 // sequence number is greater. |
223 return true; | 218 return true; |
224 } | 219 } |
225 | 220 |
226 // Handles version negotiation for client connection. | 221 // Handles version negotiation for client connection. |
227 void QuicConnection::OnVersionNegotiationPacket( | 222 void QuicConnection::OnVersionNegotiationPacket( |
228 const QuicVersionNegotiationPacket& packet) { | 223 const QuicVersionNegotiationPacket& packet) { |
| 224 if (address_migrating_) { |
| 225 SendConnectionCloseWithDetails( |
| 226 QUIC_ERROR_MIGRATING_ADDRESS, |
| 227 "Address migration is not yet a supported feature"); |
| 228 } |
229 if (is_server_) { | 229 if (is_server_) { |
230 LOG(DFATAL) << "Framer parsed VersionNegotiationPacket for server." | 230 LOG(DFATAL) << "Framer parsed VersionNegotiationPacket for server." |
231 << "Closing connection."; | 231 << "Closing connection."; |
232 CloseConnection(QUIC_INTERNAL_ERROR, false); | 232 CloseConnection(QUIC_INTERNAL_ERROR, false); |
233 return; | 233 return; |
234 } | 234 } |
235 if (debug_visitor_) { | 235 if (debug_visitor_) { |
236 debug_visitor_->OnVersionNegotiationPacket(packet); | 236 debug_visitor_->OnVersionNegotiationPacket(packet); |
237 } | 237 } |
238 | 238 |
(...skipping 22 matching lines...) Expand all Loading... |
261 } | 261 } |
262 | 262 |
263 void QuicConnection::OnRevivedPacket() { | 263 void QuicConnection::OnRevivedPacket() { |
264 } | 264 } |
265 | 265 |
266 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { | 266 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
267 if (debug_visitor_) { | 267 if (debug_visitor_) { |
268 debug_visitor_->OnPacketHeader(header); | 268 debug_visitor_->OnPacketHeader(header); |
269 } | 269 } |
270 | 270 |
| 271 if (address_migrating_) { |
| 272 SendConnectionCloseWithDetails( |
| 273 QUIC_ERROR_MIGRATING_ADDRESS, |
| 274 "Address migration is not yet a supported feature"); |
| 275 return false; |
| 276 } |
| 277 |
271 // Will be decrement below if we fall through to return true; | 278 // Will be decrement below if we fall through to return true; |
272 ++stats_.packets_dropped; | 279 ++stats_.packets_dropped; |
273 | 280 |
274 if (header.public_header.guid != guid_) { | 281 if (header.public_header.guid != guid_) { |
275 DLOG(INFO) << ENDPOINT << "Ignoring packet from unexpected GUID: " | 282 DLOG(INFO) << ENDPOINT << "Ignoring packet from unexpected GUID: " |
276 << header.public_header.guid << " instead of " << guid_; | 283 << header.public_header.guid << " instead of " << guid_; |
277 return false; | 284 return false; |
278 } | 285 } |
279 | 286 |
280 if (!Near(header.packet_sequence_number, | 287 if (!Near(header.packet_sequence_number, |
281 last_header_.packet_sequence_number)) { | 288 last_header_.packet_sequence_number)) { |
282 DLOG(INFO) << ENDPOINT << "Packet " << header.packet_sequence_number | 289 DLOG(INFO) << ENDPOINT << "Packet " << header.packet_sequence_number |
283 << " out of bounds. Discarding"; | 290 << " out of bounds. Discarding"; |
284 // TODO(alyssar) close the connection entirely. | 291 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, |
| 292 "Packet sequence number out of bounds"); |
285 return false; | 293 return false; |
286 } | 294 } |
287 | 295 |
288 // If this packet has already been seen, or that the sender | 296 // If this packet has already been seen, or that the sender |
289 // has told us will not be retransmitted, then stop processing the packet. | 297 // has told us will not be retransmitted, then stop processing the packet. |
290 if (!IsAwaitingPacket(outgoing_ack_.received_info, | 298 if (!IsAwaitingPacket(outgoing_ack_.received_info, |
291 header.packet_sequence_number)) { | 299 header.packet_sequence_number)) { |
292 return false; | 300 return false; |
293 } | 301 } |
294 | 302 |
(...skipping 24 matching lines...) Expand all Loading... |
319 | 327 |
320 --stats_.packets_dropped; | 328 --stats_.packets_dropped; |
321 DVLOG(1) << "Received packet header: " << header; | 329 DVLOG(1) << "Received packet header: " << header; |
322 last_header_ = header; | 330 last_header_ = header; |
323 return true; | 331 return true; |
324 } | 332 } |
325 | 333 |
326 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { | 334 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { |
327 DCHECK_NE(0u, last_header_.fec_group); | 335 DCHECK_NE(0u, last_header_.fec_group); |
328 QuicFecGroup* group = GetFecGroup(); | 336 QuicFecGroup* group = GetFecGroup(); |
329 group->Update(last_header_, payload); | 337 if (group != NULL) { |
| 338 group->Update(last_header_, payload); |
| 339 } |
330 } | 340 } |
331 | 341 |
332 bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) { | 342 bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) { |
333 DCHECK(connected_); | 343 DCHECK(connected_); |
334 if (debug_visitor_) { | 344 if (debug_visitor_) { |
335 debug_visitor_->OnStreamFrame(frame); | 345 debug_visitor_->OnStreamFrame(frame); |
336 } | 346 } |
337 last_stream_frames_.push_back(frame); | 347 last_stream_frames_.push_back(frame); |
338 return true; | 348 return true; |
339 } | 349 } |
340 | 350 |
341 bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { | 351 bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { |
342 DCHECK(connected_); | 352 DCHECK(connected_); |
343 if (debug_visitor_) { | 353 if (debug_visitor_) { |
344 debug_visitor_->OnAckFrame(incoming_ack); | 354 debug_visitor_->OnAckFrame(incoming_ack); |
345 } | 355 } |
346 DVLOG(1) << "OnAckFrame: " << incoming_ack; | 356 DVLOG(1) << "OnAckFrame: " << incoming_ack; |
347 | 357 |
348 if (last_header_.packet_sequence_number <= largest_seen_packet_with_ack_) { | 358 if (last_header_.packet_sequence_number <= largest_seen_packet_with_ack_) { |
349 DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring"; | 359 DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring"; |
350 return true; | 360 return true; |
351 } | 361 } |
352 largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; | 362 largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; |
353 | 363 |
354 if (!ValidateAckFrame(incoming_ack)) { | 364 if (!ValidateAckFrame(incoming_ack)) { |
355 SendConnectionClose(QUIC_INVALID_ACK_DATA); | 365 SendConnectionClose(QUIC_INVALID_ACK_DATA); |
356 return false; | 366 return false; |
357 } | 367 } |
358 | 368 |
359 // TODO(satyamshekhar): Not true if missing_packets.size() was actually | |
360 // kMaxUnackedPackets. This can result in a dead connection if all the | |
361 // missing packets get lost during retransmission. Now the new packets(or the | |
362 // older packets) will not be retransmitted due to RTO | |
363 // since received_truncated_ack_ is true and their sequence_number is > | |
364 // peer_largest_observed_packet. Fix either by resetting it in | |
365 // MaybeRetransmitPacketForRTO or keeping an explicit flag for ack truncation. | |
366 received_truncated_ack_ = | 369 received_truncated_ack_ = |
367 incoming_ack.received_info.missing_packets.size() >= | 370 incoming_ack.received_info.missing_packets.size() >= |
368 GetMaxUnackedPackets(last_header_.public_header.version_flag); | 371 QuicFramer::GetMaxUnackedPackets(last_header_.public_header.version_flag); |
369 | 372 |
370 UpdatePacketInformationReceivedByPeer(incoming_ack); | 373 UpdatePacketInformationReceivedByPeer(incoming_ack); |
371 UpdatePacketInformationSentByPeer(incoming_ack); | 374 UpdatePacketInformationSentByPeer(incoming_ack); |
372 congestion_manager_.OnIncomingAckFrame(incoming_ack, | 375 congestion_manager_.OnIncomingAckFrame(incoming_ack, |
373 time_of_last_received_packet_); | 376 time_of_last_received_packet_); |
374 | 377 |
375 // Now the we have received an ack, we might be able to send queued packets. | 378 // Now the we have received an ack, we might be able to send queued packets. |
376 if (!queued_packets_.empty()) { | 379 if (!queued_packets_.empty()) { |
377 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( | 380 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
378 time_of_last_received_packet_, NOT_RETRANSMISSION, | 381 time_of_last_received_packet_, NOT_RETRANSMISSION, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" | 418 DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" |
416 << incoming_ack.received_info.largest_observed << " vs " | 419 << incoming_ack.received_info.largest_observed << " vs " |
417 << peer_largest_observed_packet_; | 420 << peer_largest_observed_packet_; |
418 // We got an error for data we have not sent. Error out. | 421 // We got an error for data we have not sent. Error out. |
419 return false; | 422 return false; |
420 } | 423 } |
421 | 424 |
422 // We can't have too many unacked packets, or our ack frames go over | 425 // We can't have too many unacked packets, or our ack frames go over |
423 // kMaxPacketSize. | 426 // kMaxPacketSize. |
424 DCHECK_LE(incoming_ack.received_info.missing_packets.size(), | 427 DCHECK_LE(incoming_ack.received_info.missing_packets.size(), |
425 GetMaxUnackedPackets(last_header_.public_header.version_flag)); | 428 QuicFramer::GetMaxUnackedPackets( |
| 429 last_header_.public_header.version_flag)); |
426 | 430 |
427 if (incoming_ack.sent_info.least_unacked < peer_least_packet_awaiting_ack_) { | 431 if (incoming_ack.sent_info.least_unacked < peer_least_packet_awaiting_ack_) { |
428 DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: " | 432 DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: " |
429 << incoming_ack.sent_info.least_unacked | 433 << incoming_ack.sent_info.least_unacked |
430 << " vs " << peer_least_packet_awaiting_ack_; | 434 << " vs " << peer_least_packet_awaiting_ack_; |
431 // We never process old ack frames, so this number should only increase. | 435 // We never process old ack frames, so this number should only increase. |
432 return false; | 436 return false; |
433 } | 437 } |
434 | 438 |
435 if (incoming_ack.sent_info.least_unacked > | 439 if (incoming_ack.sent_info.least_unacked > |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 DCHECK(outgoing_ack_.received_info.missing_packets.empty() || | 578 DCHECK(outgoing_ack_.received_info.missing_packets.empty() || |
575 *outgoing_ack_.received_info.missing_packets.begin() >= | 579 *outgoing_ack_.received_info.missing_packets.begin() >= |
576 peer_least_packet_awaiting_ack_); | 580 peer_least_packet_awaiting_ack_); |
577 // Possibly close any FecGroups which are now irrelevant | 581 // Possibly close any FecGroups which are now irrelevant |
578 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); | 582 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); |
579 } | 583 } |
580 | 584 |
581 void QuicConnection::OnFecData(const QuicFecData& fec) { | 585 void QuicConnection::OnFecData(const QuicFecData& fec) { |
582 DCHECK_NE(0u, last_header_.fec_group); | 586 DCHECK_NE(0u, last_header_.fec_group); |
583 QuicFecGroup* group = GetFecGroup(); | 587 QuicFecGroup* group = GetFecGroup(); |
584 group->UpdateFec(last_header_.packet_sequence_number, | 588 if (group != NULL) { |
585 last_header_.fec_entropy_flag, fec); | 589 group->UpdateFec(last_header_.packet_sequence_number, |
| 590 last_header_.fec_entropy_flag, fec); |
| 591 } |
586 } | 592 } |
587 | 593 |
588 bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) { | 594 bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) { |
589 DCHECK(connected_); | 595 DCHECK(connected_); |
590 if (debug_visitor_) { | 596 if (debug_visitor_) { |
591 debug_visitor_->OnRstStreamFrame(frame); | 597 debug_visitor_->OnRstStreamFrame(frame); |
592 } | 598 } |
593 DLOG(INFO) << "Stream reset with error " | 599 DLOG(INFO) << "Stream reset with error " |
594 << QuicUtils::StreamErrorToString(frame.error_code); | 600 << QuicUtils::StreamErrorToString(frame.error_code); |
595 visitor_->OnRstStream(frame); | 601 visitor_->OnRstStream(frame); |
(...skipping 15 matching lines...) Expand all Loading... |
611 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { | 617 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { |
612 DCHECK(connected_); | 618 DCHECK(connected_); |
613 DLOG(INFO) << ENDPOINT << "Go away received with error " | 619 DLOG(INFO) << ENDPOINT << "Go away received with error " |
614 << QuicUtils::ErrorToString(frame.error_code) | 620 << QuicUtils::ErrorToString(frame.error_code) |
615 << " and reason:" << frame.reason_phrase; | 621 << " and reason:" << frame.reason_phrase; |
616 visitor_->OnGoAway(frame); | 622 visitor_->OnGoAway(frame); |
617 return connected_; | 623 return connected_; |
618 } | 624 } |
619 | 625 |
620 void QuicConnection::OnPacketComplete() { | 626 void QuicConnection::OnPacketComplete() { |
621 // TODO(satyamshekhar): Don't do anything if this packet closed the | 627 // Don't do anything if this packet closed the connection. |
622 // connection. | 628 if (!connected_) { |
| 629 last_stream_frames_.clear(); |
| 630 return; |
| 631 } |
| 632 |
623 if (!last_packet_revived_) { | 633 if (!last_packet_revived_) { |
624 DLOG(INFO) << ENDPOINT << "Got packet " | 634 DLOG(INFO) << ENDPOINT << "Got packet " |
625 << last_header_.packet_sequence_number | 635 << last_header_.packet_sequence_number |
626 << " with " << last_stream_frames_.size() | 636 << " with " << last_stream_frames_.size() |
627 << " stream frames for " << last_header_.public_header.guid; | 637 << " stream frames for " << last_header_.public_header.guid; |
628 congestion_manager_.RecordIncomingPacket( | 638 congestion_manager_.RecordIncomingPacket( |
629 last_size_, last_header_.packet_sequence_number, | 639 last_size_, last_header_.packet_sequence_number, |
630 time_of_last_received_packet_, last_packet_revived_); | 640 time_of_last_received_packet_, last_packet_revived_); |
631 } else { | 641 } else { |
632 DLOG(INFO) << ENDPOINT << "Got revived packet with " | 642 DLOG(INFO) << ENDPOINT << "Got revived packet with " |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 const IPEndPoint& peer_address, | 720 const IPEndPoint& peer_address, |
711 const QuicEncryptedPacket& packet) { | 721 const QuicEncryptedPacket& packet) { |
712 if (!connected_) { | 722 if (!connected_) { |
713 return; | 723 return; |
714 } | 724 } |
715 if (debug_visitor_) { | 725 if (debug_visitor_) { |
716 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); | 726 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); |
717 } | 727 } |
718 last_packet_revived_ = false; | 728 last_packet_revived_ = false; |
719 last_size_ = packet.length(); | 729 last_size_ = packet.length(); |
720 last_self_address_ = self_address; | 730 |
721 last_peer_address_ = peer_address; | 731 address_migrating_ = false; |
| 732 |
| 733 if (peer_address_.address().empty()) { |
| 734 peer_address_ = peer_address; |
| 735 } |
| 736 if (self_address_.address().empty()) { |
| 737 self_address_ = self_address; |
| 738 } |
| 739 |
| 740 if (!(peer_address == peer_address_) && (self_address == self_address_)) { |
| 741 address_migrating_ = true; |
| 742 } |
722 | 743 |
723 stats_.bytes_received += packet.length(); | 744 stats_.bytes_received += packet.length(); |
724 ++stats_.packets_received; | 745 ++stats_.packets_received; |
725 | 746 |
726 if (!framer_.ProcessPacket(packet)) { | 747 if (!framer_.ProcessPacket(packet)) { |
727 return; | 748 return; |
728 } | 749 } |
729 MaybeProcessRevivedPacket(); | 750 MaybeProcessRevivedPacket(); |
730 } | 751 } |
731 | 752 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 ContainsKey(retransmission_map_, sequence_number)); | 840 ContainsKey(retransmission_map_, sequence_number)); |
820 | 841 |
821 if (!ContainsKey(unacked_packets_, sequence_number)) { | 842 if (!ContainsKey(unacked_packets_, sequence_number)) { |
822 DVLOG(2) << "alarm fired for " << sequence_number | 843 DVLOG(2) << "alarm fired for " << sequence_number |
823 << " but it has been acked or already retransmitted with" | 844 << " but it has been acked or already retransmitted with" |
824 << " different sequence number."; | 845 << " different sequence number."; |
825 // So no extra delay is added for this packet. | 846 // So no extra delay is added for this packet. |
826 return true; | 847 return true; |
827 } | 848 } |
828 | 849 |
| 850 RetransmissionMap::iterator retransmission_it = |
| 851 retransmission_map_.find(sequence_number); |
829 // If the packet hasn't been acked and we're getting truncated acks, ignore | 852 // If the packet hasn't been acked and we're getting truncated acks, ignore |
830 // any RTO for packets larger than the peer's largest observed packet; it may | 853 // any RTO for packets larger than the peer's largest observed packet; it may |
831 // have been received by the peer and just wasn't acked due to the ack frame | 854 // have been received by the peer and just wasn't acked due to the ack frame |
832 // running out of space. | 855 // running out of space. |
833 if (received_truncated_ack_ && | 856 if (received_truncated_ack_ && |
834 sequence_number > peer_largest_observed_packet_) { | 857 sequence_number > peer_largest_observed_packet_ && |
| 858 // We allow retransmission of already retransmitted packets so that we |
| 859 // retransmit packets that were retransmissions of the packet with |
| 860 // sequence number < the largest observed field of the truncated ack. |
| 861 retransmission_it->second.number_retransmissions == 0) { |
835 return false; | 862 return false; |
836 } else { | 863 } else { |
837 ++stats_.rto_count; | 864 ++stats_.rto_count; |
838 RetransmitPacket(sequence_number); | 865 RetransmitPacket(sequence_number); |
839 return true; | 866 return true; |
840 } | 867 } |
841 } | 868 } |
842 | 869 |
843 void QuicConnection::RetransmitAllUnackedPackets() { | 870 void QuicConnection::RetransmitAllUnackedPackets() { |
844 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); | 871 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 // TODO(ianswett): If the packet is a retransmit, the current send alarm may | 921 // TODO(ianswett): If the packet is a retransmit, the current send alarm may |
895 // be too long. | 922 // be too long. |
896 if (write_blocked_ || helper_->IsSendAlarmSet()) { | 923 if (write_blocked_ || helper_->IsSendAlarmSet()) { |
897 return false; | 924 return false; |
898 } | 925 } |
899 | 926 |
900 QuicTime now = clock_->Now(); | 927 QuicTime now = clock_->Now(); |
901 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( | 928 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
902 now, retransmission, retransmittable); | 929 now, retransmission, retransmittable); |
903 if (delay.IsInfinite()) { | 930 if (delay.IsInfinite()) { |
904 // TODO(pwestin): should be false but trigger other bugs see b/8350327. | 931 return false; |
905 return true; | |
906 } | 932 } |
907 | 933 |
908 // If the scheduler requires a delay, then we can not send this packet now. | 934 // If the scheduler requires a delay, then we can not send this packet now. |
909 if (!delay.IsZero()) { | 935 if (!delay.IsZero()) { |
910 helper_->SetSendAlarm(now.Add(delay)); | 936 helper_->SetSendAlarm(now.Add(delay)); |
911 return false; | 937 return false; |
912 } | 938 } |
913 return true; | 939 return true; |
914 } | 940 } |
915 | 941 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 ? "data bearing " : " ack only ")) | 1002 ? "data bearing " : " ack only ")) |
977 << " Packet length:" << packet->length(); | 1003 << " Packet length:" << packet->length(); |
978 | 1004 |
979 DCHECK(encrypted->length() <= kMaxPacketSize) | 1005 DCHECK(encrypted->length() <= kMaxPacketSize) |
980 << "Packet " << sequence_number << " will not be read; too large: " | 1006 << "Packet " << sequence_number << " will not be read; too large: " |
981 << packet->length() << " " << encrypted->length() << " " | 1007 << packet->length() << " " << encrypted->length() << " " |
982 << outgoing_ack_ << " forced: " << (forced == FORCE ? "yes" : "no"); | 1008 << outgoing_ack_ << " forced: " << (forced == FORCE ? "yes" : "no"); |
983 | 1009 |
984 int error; | 1010 int error; |
985 QuicTime now = clock_->Now(); | 1011 QuicTime now = clock_->Now(); |
986 int rv = helper_->WritePacketToWire(*encrypted, &error); | 1012 if (helper_->WritePacketToWire(*encrypted, &error) == -1) { |
987 if (rv == -1 && helper_->IsWriteBlocked(error)) { | 1013 if (helper_->IsWriteBlocked(error)) { |
988 // TODO(satyashekhar): It might be more efficient (fewer system calls), if | 1014 // TODO(satyashekhar): It might be more efficient (fewer system calls), if |
989 // all connections share this variable i.e this becomes a part of | 1015 // all connections share this variable i.e this becomes a part of |
990 // PacketWriterInterface. | 1016 // PacketWriterInterface. |
991 write_blocked_ = true; | 1017 write_blocked_ = true; |
992 // If the socket buffers the the data, then the packet should not | 1018 // If the socket buffers the the data, then the packet should not |
993 // be queued and sent again, which would result in an unnecessary duplicate | 1019 // be queued and sent again, which would result in an unnecessary |
994 // packet being sent. | 1020 // duplicate packet being sent. |
995 return helper_->IsWriteBlockedDataBuffered(); | 1021 return helper_->IsWriteBlockedDataBuffered(); |
| 1022 } |
| 1023 // We can't send an error as the socket is presumably borked. |
| 1024 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); |
| 1025 return false; |
996 } | 1026 } |
997 time_of_last_sent_packet_ = now; | 1027 time_of_last_sent_packet_ = now; |
998 DVLOG(1) << "time of last sent packet: " << now.ToDebuggingValue(); | 1028 DVLOG(1) << "time of last sent packet: " << now.ToDebuggingValue(); |
999 // TODO(wtc): Is it correct to continue if the write failed. | |
1000 | 1029 |
1001 // Set the retransmit alarm only when we have sent the packet to the client | 1030 // Set the retransmit alarm only when we have sent the packet to the client |
1002 // and not when it goes to the pending queue, otherwise we will end up adding | 1031 // and not when it goes to the pending queue, otherwise we will end up adding |
1003 // an entry to retransmission_timeout_ every time we attempt a write. | 1032 // an entry to retransmission_timeout_ every time we attempt a write. |
1004 MaybeSetupRetransmission(sequence_number); | 1033 MaybeSetupRetransmission(sequence_number); |
1005 | 1034 |
1006 congestion_manager_.SentPacket(sequence_number, now, packet->length(), | 1035 congestion_manager_.SentPacket(sequence_number, now, packet->length(), |
1007 retransmission); | 1036 retransmission); |
1008 | 1037 |
1009 stats_.bytes_sent += encrypted->length(); | 1038 stats_.bytes_sent += encrypted->length(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 QuicTime QuicConnection::OnRetransmissionTimeout() { | 1135 QuicTime QuicConnection::OnRetransmissionTimeout() { |
1107 // This guards against registering the alarm later than we should. | 1136 // This guards against registering the alarm later than we should. |
1108 // | 1137 // |
1109 // If we have packet A and B in the list and we call | 1138 // If we have packet A and B in the list and we call |
1110 // MaybeRetransmitPacketForRTO on A, that may trigger a call to | 1139 // MaybeRetransmitPacketForRTO on A, that may trigger a call to |
1111 // SetRetransmissionAlarm if A is retransmitted as C. In that case we | 1140 // SetRetransmissionAlarm if A is retransmitted as C. In that case we |
1112 // don't want to register the alarm under SetRetransmissionAlarm; we | 1141 // don't want to register the alarm under SetRetransmissionAlarm; we |
1113 // want to set it to the RTO of B when we return from this function. | 1142 // want to set it to the RTO of B when we return from this function. |
1114 handling_retransmission_timeout_ = true; | 1143 handling_retransmission_timeout_ = true; |
1115 | 1144 |
1116 for (int i = 0; i < kMaxPacketsPerRetransmissionAlarm && | 1145 for (size_t i = 0; i < max_packets_per_retransmission_alarm_ && |
1117 !retransmission_timeouts_.empty(); ++i) { | 1146 !retransmission_timeouts_.empty(); ++i) { |
1118 RetransmissionInfo retransmission_info = retransmission_timeouts_.top(); | 1147 RetransmissionInfo retransmission_info = retransmission_timeouts_.top(); |
1119 DCHECK(retransmission_info.scheduled_time.IsInitialized()); | 1148 DCHECK(retransmission_info.scheduled_time.IsInitialized()); |
1120 if (retransmission_info.scheduled_time > clock_->ApproximateNow()) { | 1149 if (retransmission_info.scheduled_time > clock_->ApproximateNow()) { |
1121 break; | 1150 break; |
1122 } | 1151 } |
1123 retransmission_timeouts_.pop(); | 1152 retransmission_timeouts_.pop(); |
1124 if (!MaybeRetransmitPacketForRTO(retransmission_info.sequence_number)) { | 1153 if (!MaybeRetransmitPacketForRTO(retransmission_info.sequence_number)) { |
1125 DLOG(INFO) << ENDPOINT << "MaybeRetransmitPacketForRTO failed: " | 1154 DLOG(INFO) << ENDPOINT << "MaybeRetransmitPacketForRTO failed: " |
1126 << "adding an extra delay for " | 1155 << "adding an extra delay for " |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 framer_.ProcessRevivedPacket(&revived_header, | 1228 framer_.ProcessRevivedPacket(&revived_header, |
1200 StringPiece(revived_payload, len)); | 1229 StringPiece(revived_payload, len)); |
1201 } | 1230 } |
1202 | 1231 |
1203 QuicFecGroup* QuicConnection::GetFecGroup() { | 1232 QuicFecGroup* QuicConnection::GetFecGroup() { |
1204 QuicFecGroupNumber fec_group_num = last_header_.fec_group; | 1233 QuicFecGroupNumber fec_group_num = last_header_.fec_group; |
1205 if (fec_group_num == 0) { | 1234 if (fec_group_num == 0) { |
1206 return NULL; | 1235 return NULL; |
1207 } | 1236 } |
1208 if (group_map_.count(fec_group_num) == 0) { | 1237 if (group_map_.count(fec_group_num) == 0) { |
1209 // TODO(rch): limit the number of active FEC groups. | 1238 if (group_map_.size() >= kMaxFecGroups) { // Too many groups |
| 1239 if (fec_group_num < group_map_.begin()->first) { |
| 1240 // The group being requested is a group we've seen before and deleted. |
| 1241 // Don't recreate it. |
| 1242 return NULL; |
| 1243 } |
| 1244 // Clear the lowest group number. |
| 1245 delete group_map_.begin()->second; |
| 1246 group_map_.erase(group_map_.begin()); |
| 1247 } |
1210 group_map_[fec_group_num] = new QuicFecGroup(); | 1248 group_map_[fec_group_num] = new QuicFecGroup(); |
1211 } | 1249 } |
1212 return group_map_[fec_group_num]; | 1250 return group_map_[fec_group_num]; |
1213 } | 1251 } |
1214 | 1252 |
1215 void QuicConnection::SendConnectionClose(QuicErrorCode error) { | 1253 void QuicConnection::SendConnectionClose(QuicErrorCode error) { |
1216 SendConnectionCloseWithDetails(error, string()); | 1254 SendConnectionCloseWithDetails(error, string()); |
1217 } | 1255 } |
1218 | 1256 |
1219 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, | 1257 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 << " delta:" << delta.ToMicroseconds(); | 1343 << " delta:" << delta.ToMicroseconds(); |
1306 if (delta >= timeout_) { | 1344 if (delta >= timeout_) { |
1307 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 1345 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
1308 return true; | 1346 return true; |
1309 } | 1347 } |
1310 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 1348 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); |
1311 return false; | 1349 return false; |
1312 } | 1350 } |
1313 | 1351 |
1314 } // namespace net | 1352 } // namespace net |
OLD | NEW |