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> |
11 #include <limits> | 11 #include <limits> |
12 #include <memory> | 12 #include <memory> |
13 #include <set> | 13 #include <set> |
14 #include <utility> | 14 #include <utility> |
15 | 15 |
16 #include "base/debug/stack_trace.h" | 16 #include "base/debug/stack_trace.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
20 #include "net/quic/crypto/quic_decrypter.h" | 20 #include "net/quic/crypto/quic_decrypter.h" |
21 #include "net/quic/crypto/quic_encrypter.h" | 21 #include "net/quic/crypto/quic_encrypter.h" |
22 #include "net/quic/iovector.h" | 22 #include "net/quic/iovector.h" |
23 #include "net/quic/quic_bandwidth.h" | 23 #include "net/quic/quic_bandwidth.h" |
24 #include "net/quic/quic_config.h" | 24 #include "net/quic/quic_config.h" |
25 #include "net/quic/quic_flags.h" | 25 #include "net/quic/quic_flags.h" |
26 #include "net/quic/quic_flow_controller.h" | |
27 #include "net/quic/quic_utils.h" | 26 #include "net/quic/quic_utils.h" |
28 | 27 |
29 using base::hash_map; | 28 using base::hash_map; |
30 using base::hash_set; | 29 using base::hash_set; |
31 using base::StringPiece; | 30 using base::StringPiece; |
32 using std::list; | 31 using std::list; |
33 using std::make_pair; | 32 using std::make_pair; |
34 using std::min; | 33 using std::min; |
35 using std::max; | 34 using std::max; |
36 using std::numeric_limits; | 35 using std::numeric_limits; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 length(packet.packet->length()) { | 185 length(packet.packet->length()) { |
187 } | 186 } |
188 | 187 |
189 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 188 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
190 | 189 |
191 QuicConnection::QuicConnection(QuicConnectionId connection_id, | 190 QuicConnection::QuicConnection(QuicConnectionId connection_id, |
192 IPEndPoint address, | 191 IPEndPoint address, |
193 QuicConnectionHelperInterface* helper, | 192 QuicConnectionHelperInterface* helper, |
194 QuicPacketWriter* writer, | 193 QuicPacketWriter* writer, |
195 bool is_server, | 194 bool is_server, |
196 const QuicVersionVector& supported_versions, | 195 const QuicVersionVector& supported_versions) |
197 uint32 max_flow_control_receive_window_bytes) | |
198 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), | 196 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), |
199 is_server), | 197 is_server), |
200 helper_(helper), | 198 helper_(helper), |
201 writer_(writer), | 199 writer_(writer), |
202 encryption_level_(ENCRYPTION_NONE), | 200 encryption_level_(ENCRYPTION_NONE), |
203 clock_(helper->GetClock()), | 201 clock_(helper->GetClock()), |
204 random_generator_(helper->GetRandomGenerator()), | 202 random_generator_(helper->GetRandomGenerator()), |
205 connection_id_(connection_id), | 203 connection_id_(connection_id), |
206 peer_address_(address), | 204 peer_address_(address), |
207 migrating_peer_port_(0), | 205 migrating_peer_port_(0), |
(...skipping 23 matching lines...) Expand all Loading... |
231 sequence_number_of_last_sent_packet_(0), | 229 sequence_number_of_last_sent_packet_(0), |
232 sent_packet_manager_( | 230 sent_packet_manager_( |
233 is_server, clock_, &stats_, kTCP, | 231 is_server, clock_, &stats_, kTCP, |
234 FLAGS_quic_use_time_loss_detection ? kTime : kNack), | 232 FLAGS_quic_use_time_loss_detection ? kTime : kNack), |
235 version_negotiation_state_(START_NEGOTIATION), | 233 version_negotiation_state_(START_NEGOTIATION), |
236 is_server_(is_server), | 234 is_server_(is_server), |
237 connected_(true), | 235 connected_(true), |
238 peer_ip_changed_(false), | 236 peer_ip_changed_(false), |
239 peer_port_changed_(false), | 237 peer_port_changed_(false), |
240 self_ip_changed_(false), | 238 self_ip_changed_(false), |
241 self_port_changed_(false), | 239 self_port_changed_(false) { |
242 max_flow_control_receive_window_bytes_( | |
243 max_flow_control_receive_window_bytes) { | |
244 if (max_flow_control_receive_window_bytes_ < kDefaultFlowControlSendWindow) { | |
245 DLOG(ERROR) << "Initial receive window (" | |
246 << max_flow_control_receive_window_bytes_ | |
247 << ") cannot be set lower than default (" | |
248 << kDefaultFlowControlSendWindow << ")."; | |
249 max_flow_control_receive_window_bytes_ = kDefaultFlowControlSendWindow; | |
250 } | |
251 | |
252 flow_controller_.reset(new QuicFlowController( | |
253 supported_versions.front(), 0, is_server_, | |
254 kDefaultFlowControlSendWindow, max_flow_control_receive_window_bytes_, | |
255 max_flow_control_receive_window_bytes_)); | |
256 | |
257 if (!is_server_) { | 240 if (!is_server_) { |
258 // Pacing will be enabled if the client negotiates it. | 241 // Pacing will be enabled if the client negotiates it. |
259 sent_packet_manager_.MaybeEnablePacing(); | 242 sent_packet_manager_.MaybeEnablePacing(); |
260 } | 243 } |
261 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " | 244 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
262 << connection_id; | 245 << connection_id; |
263 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 246 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
264 framer_.set_visitor(this); | 247 framer_.set_visitor(this); |
265 framer_.set_received_entropy_calculator(&received_packet_manager_); | 248 framer_.set_received_entropy_calculator(&received_packet_manager_); |
266 stats_.connection_creation_time = clock_->ApproximateNow(); | 249 stats_.connection_creation_time = clock_->ApproximateNow(); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 DCHECK(false); | 351 DCHECK(false); |
369 } | 352 } |
370 | 353 |
371 version_negotiation_state_ = NEGOTIATED_VERSION; | 354 version_negotiation_state_ = NEGOTIATED_VERSION; |
372 visitor_->OnSuccessfulVersionNegotiation(received_version); | 355 visitor_->OnSuccessfulVersionNegotiation(received_version); |
373 DVLOG(1) << ENDPOINT << "version negotiated " << received_version; | 356 DVLOG(1) << ENDPOINT << "version negotiated " << received_version; |
374 | 357 |
375 // Store the new version. | 358 // Store the new version. |
376 framer_.set_version(received_version); | 359 framer_.set_version(received_version); |
377 | 360 |
378 if (received_version < QUIC_VERSION_19) { | |
379 flow_controller_->Disable(); | |
380 } | |
381 | |
382 // TODO(satyamshekhar): Store the sequence number of this packet and close the | 361 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
383 // connection if we ever received a packet with incorrect version and whose | 362 // connection if we ever received a packet with incorrect version and whose |
384 // sequence number is greater. | 363 // sequence number is greater. |
385 return true; | 364 return true; |
386 } | 365 } |
387 | 366 |
388 // Handles version negotiation for client connection. | 367 // Handles version negotiation for client connection. |
389 void QuicConnection::OnVersionNegotiationPacket( | 368 void QuicConnection::OnVersionNegotiationPacket( |
390 const QuicVersionNegotiationPacket& packet) { | 369 const QuicVersionNegotiationPacket& packet) { |
391 if (is_server_) { | 370 if (is_server_) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 << " without version flag before version negotiated."; | 466 << " without version flag before version negotiated."; |
488 // Packets should have the version flag till version negotiation is | 467 // Packets should have the version flag till version negotiation is |
489 // done. | 468 // done. |
490 CloseConnection(QUIC_INVALID_VERSION, false); | 469 CloseConnection(QUIC_INVALID_VERSION, false); |
491 return false; | 470 return false; |
492 } else { | 471 } else { |
493 DCHECK_EQ(1u, header.public_header.versions.size()); | 472 DCHECK_EQ(1u, header.public_header.versions.size()); |
494 DCHECK_EQ(header.public_header.versions[0], version()); | 473 DCHECK_EQ(header.public_header.versions[0], version()); |
495 version_negotiation_state_ = NEGOTIATED_VERSION; | 474 version_negotiation_state_ = NEGOTIATED_VERSION; |
496 visitor_->OnSuccessfulVersionNegotiation(version()); | 475 visitor_->OnSuccessfulVersionNegotiation(version()); |
497 if (version() < QUIC_VERSION_19) { | |
498 flow_controller_->Disable(); | |
499 } | |
500 } | 476 } |
501 } else { | 477 } else { |
502 DCHECK(!header.public_header.version_flag); | 478 DCHECK(!header.public_header.version_flag); |
503 // If the client gets a packet without the version flag from the server | 479 // If the client gets a packet without the version flag from the server |
504 // it should stop sending version since the version negotiation is done. | 480 // it should stop sending version since the version negotiation is done. |
505 packet_creator_.StopSendingVersion(); | 481 packet_creator_.StopSendingVersion(); |
506 version_negotiation_state_ = NEGOTIATED_VERSION; | 482 version_negotiation_state_ = NEGOTIATED_VERSION; |
507 visitor_->OnSuccessfulVersionNegotiation(version()); | 483 visitor_->OnSuccessfulVersionNegotiation(version()); |
508 if (version() < QUIC_VERSION_19) { | |
509 flow_controller_->Disable(); | |
510 } | |
511 } | 484 } |
512 } | 485 } |
513 | 486 |
514 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); | 487 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); |
515 | 488 |
516 --stats_.packets_dropped; | 489 --stats_.packets_dropped; |
517 DVLOG(1) << ENDPOINT << "Received packet header: " << header; | 490 DVLOG(1) << ENDPOINT << "Received packet header: " << header; |
518 last_header_ = header; | 491 last_header_ = header; |
519 DCHECK(connected_); | 492 DCHECK(connected_); |
520 return true; | 493 return true; |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 } | 1150 } |
1178 | 1151 |
1179 { // Limit the scope of the bundler. | 1152 { // Limit the scope of the bundler. |
1180 // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. | 1153 // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. |
1181 ScopedPacketBundler bundler(this, NO_ACK); | 1154 ScopedPacketBundler bundler(this, NO_ACK); |
1182 visitor_->OnCanWrite(); | 1155 visitor_->OnCanWrite(); |
1183 } | 1156 } |
1184 | 1157 |
1185 // After the visitor writes, it may have caused the socket to become write | 1158 // After the visitor writes, it may have caused the socket to become write |
1186 // blocked or the congestion manager to prohibit sending, so check again. | 1159 // blocked or the congestion manager to prohibit sending, so check again. |
1187 if (visitor_->HasPendingWrites() && !resume_writes_alarm_->IsSet() && | 1160 if (visitor_->WillingAndAbleToWrite() && |
| 1161 !resume_writes_alarm_->IsSet() && |
1188 CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) { | 1162 CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) { |
1189 // We're not write blocked, but some stream didn't write out all of its | 1163 // We're not write blocked, but some stream didn't write out all of its |
1190 // bytes. Register for 'immediate' resumption so we'll keep writing after | 1164 // bytes. Register for 'immediate' resumption so we'll keep writing after |
1191 // other connections and events have had a chance to use the thread. | 1165 // other connections and events have had a chance to use the thread. |
1192 resume_writes_alarm_->Set(clock_->ApproximateNow()); | 1166 resume_writes_alarm_->Set(clock_->ApproximateNow()); |
1193 } | 1167 } |
1194 } | 1168 } |
1195 | 1169 |
1196 void QuicConnection::WriteIfNotBlocked() { | 1170 void QuicConnection::WriteIfNotBlocked() { |
1197 if (!writer_->IsWriteBlocked()) { | 1171 if (!writer_->IsWriteBlocked()) { |
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 // If we changed the generator's batch state, restore original batch state. | 1963 // If we changed the generator's batch state, restore original batch state. |
1990 if (!already_in_batch_mode_) { | 1964 if (!already_in_batch_mode_) { |
1991 DVLOG(1) << "Leaving Batch Mode."; | 1965 DVLOG(1) << "Leaving Batch Mode."; |
1992 connection_->packet_generator_.FinishBatchOperations(); | 1966 connection_->packet_generator_.FinishBatchOperations(); |
1993 } | 1967 } |
1994 DCHECK_EQ(already_in_batch_mode_, | 1968 DCHECK_EQ(already_in_batch_mode_, |
1995 connection_->packet_generator_.InBatchMode()); | 1969 connection_->packet_generator_.InBatchMode()); |
1996 } | 1970 } |
1997 | 1971 |
1998 } // namespace net | 1972 } // namespace net |
OLD | NEW |