OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 192 |
193 } // namespace | 193 } // namespace |
194 | 194 |
195 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 195 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
196 | 196 |
197 QuicConnection::QuicConnection(QuicGuid guid, | 197 QuicConnection::QuicConnection(QuicGuid guid, |
198 IPEndPoint address, | 198 IPEndPoint address, |
199 QuicConnectionHelperInterface* helper, | 199 QuicConnectionHelperInterface* helper, |
200 QuicPacketWriter* writer, | 200 QuicPacketWriter* writer, |
201 bool is_server, | 201 bool is_server, |
202 QuicVersion version) | 202 const QuicVersionVector& supported_versions) |
203 : framer_(version, | 203 : framer_(supported_versions, |
204 helper->GetClock()->ApproximateNow(), | 204 helper->GetClock()->ApproximateNow(), |
205 is_server), | 205 is_server), |
206 helper_(helper), | 206 helper_(helper), |
207 writer_(writer), | 207 writer_(writer), |
208 encryption_level_(ENCRYPTION_NONE), | 208 encryption_level_(ENCRYPTION_NONE), |
209 clock_(helper->GetClock()), | 209 clock_(helper->GetClock()), |
210 random_generator_(helper->GetRandomGenerator()), | 210 random_generator_(helper->GetRandomGenerator()), |
211 guid_(guid), | 211 guid_(guid), |
212 peer_address_(address), | 212 peer_address_(address), |
213 largest_seen_packet_with_ack_(0), | 213 largest_seen_packet_with_ack_(0), |
(...skipping 16 matching lines...) Expand all Loading... |
230 time_of_last_sent_packet_(clock_->ApproximateNow()), | 230 time_of_last_sent_packet_(clock_->ApproximateNow()), |
231 sequence_number_of_last_inorder_packet_(0), | 231 sequence_number_of_last_inorder_packet_(0), |
232 congestion_manager_(clock_, kTCP), | 232 congestion_manager_(clock_, kTCP), |
233 sent_packet_manager_(is_server, this), | 233 sent_packet_manager_(is_server, this), |
234 version_negotiation_state_(START_NEGOTIATION), | 234 version_negotiation_state_(START_NEGOTIATION), |
235 consecutive_rto_count_(0), | 235 consecutive_rto_count_(0), |
236 is_server_(is_server), | 236 is_server_(is_server), |
237 connected_(true), | 237 connected_(true), |
238 received_truncated_ack_(false), | 238 received_truncated_ack_(false), |
239 address_migrating_(false) { | 239 address_migrating_(false) { |
| 240 DLOG(INFO) << ENDPOINT << "Created connection with guid: " << guid; |
240 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 241 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
241 framer_.set_visitor(this); | 242 framer_.set_visitor(this); |
242 framer_.set_received_entropy_calculator(&received_packet_manager_); | 243 framer_.set_received_entropy_calculator(&received_packet_manager_); |
243 } | 244 } |
244 | 245 |
245 QuicConnection::~QuicConnection() { | 246 QuicConnection::~QuicConnection() { |
246 STLDeleteElements(&undecryptable_packets_); | 247 STLDeleteElements(&undecryptable_packets_); |
247 STLDeleteValues(&group_map_); | 248 STLDeleteValues(&group_map_); |
248 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 249 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
249 it != queued_packets_.end(); ++it) { | 250 it != queued_packets_.end(); ++it) { |
250 delete it->packet; | 251 delete it->packet; |
251 } | 252 } |
252 } | 253 } |
253 | 254 |
254 bool QuicConnection::SelectMutualVersion( | 255 bool QuicConnection::SelectMutualVersion( |
255 const QuicVersionVector& available_versions) { | 256 const QuicVersionVector& available_versions) { |
256 // Try to find the highest mutual version by iterating over supported | 257 // Try to find the highest mutual version by iterating over supported |
257 // versions, starting with the highest, and breaking out of the loop once we | 258 // versions, starting with the highest, and breaking out of the loop once we |
258 // find a matching version in the provided available_versions vector. | 259 // find a matching version in the provided available_versions vector. |
259 for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { | 260 const QuicVersionVector& supported_versions = framer_.supported_versions(); |
260 const QuicVersion& version = kSupportedQuicVersions[i]; | 261 for (size_t i = 0; i < supported_versions.size(); ++i) { |
| 262 const QuicVersion& version = supported_versions[i]; |
261 if (std::find(available_versions.begin(), available_versions.end(), | 263 if (std::find(available_versions.begin(), available_versions.end(), |
262 version) != available_versions.end()) { | 264 version) != available_versions.end()) { |
263 framer_.set_version(version); | 265 framer_.set_version(version); |
264 return true; | 266 return true; |
265 } | 267 } |
266 } | 268 } |
267 | 269 |
268 return false; | 270 return false; |
269 } | 271 } |
270 | 272 |
(...skipping 16 matching lines...) Expand all Loading... |
287 | 289 |
288 void QuicConnection::OnPublicResetPacket( | 290 void QuicConnection::OnPublicResetPacket( |
289 const QuicPublicResetPacket& packet) { | 291 const QuicPublicResetPacket& packet) { |
290 if (debug_visitor_) { | 292 if (debug_visitor_) { |
291 debug_visitor_->OnPublicResetPacket(packet); | 293 debug_visitor_->OnPublicResetPacket(packet); |
292 } | 294 } |
293 CloseConnection(QUIC_PUBLIC_RESET, true); | 295 CloseConnection(QUIC_PUBLIC_RESET, true); |
294 } | 296 } |
295 | 297 |
296 bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { | 298 bool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { |
| 299 DLOG(INFO) << ENDPOINT << "Received packet with mismatched version " |
| 300 << received_version; |
297 // TODO(satyamshekhar): Implement no server state in this mode. | 301 // TODO(satyamshekhar): Implement no server state in this mode. |
298 if (!is_server_) { | 302 if (!is_server_) { |
299 LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " | 303 LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " |
300 << "Closing connection."; | 304 << "Closing connection."; |
301 CloseConnection(QUIC_INTERNAL_ERROR, false); | 305 CloseConnection(QUIC_INTERNAL_ERROR, false); |
302 return false; | 306 return false; |
303 } | 307 } |
304 DCHECK_NE(version(), received_version); | 308 DCHECK_NE(version(), received_version); |
305 | 309 |
306 if (debug_visitor_) { | 310 if (debug_visitor_) { |
307 debug_visitor_->OnProtocolVersionMismatch(received_version); | 311 debug_visitor_->OnProtocolVersionMismatch(received_version); |
308 } | 312 } |
309 | 313 |
310 switch (version_negotiation_state_) { | 314 switch (version_negotiation_state_) { |
311 case START_NEGOTIATION: | 315 case START_NEGOTIATION: |
312 if (!framer_.IsSupportedVersion(received_version)) { | 316 if (!framer_.IsSupportedVersion(received_version)) { |
313 SendVersionNegotiationPacket(); | 317 SendVersionNegotiationPacket(); |
314 version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; | 318 version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; |
315 return false; | 319 return false; |
316 } | 320 } |
317 break; | 321 break; |
318 | 322 |
319 case NEGOTIATION_IN_PROGRESS: | 323 case NEGOTIATION_IN_PROGRESS: |
320 if (!framer_.IsSupportedVersion(received_version)) { | 324 if (!framer_.IsSupportedVersion(received_version)) { |
321 // Drop packets which can't be parsed due to version mismatch. | 325 SendVersionNegotiationPacket(); |
322 return false; | 326 return false; |
323 } | 327 } |
324 break; | 328 break; |
325 | 329 |
326 case NEGOTIATED_VERSION: | 330 case NEGOTIATED_VERSION: |
327 // Might be old packets that were sent by the client before the version | 331 // Might be old packets that were sent by the client before the version |
328 // was negotiated. Drop these. | 332 // was negotiated. Drop these. |
329 return false; | 333 return false; |
330 | 334 |
331 default: | 335 default: |
332 DCHECK(false); | 336 DCHECK(false); |
333 } | 337 } |
334 | 338 |
335 version_negotiation_state_ = NEGOTIATED_VERSION; | 339 version_negotiation_state_ = NEGOTIATED_VERSION; |
336 visitor_->OnSuccessfulVersionNegotiation(received_version); | 340 visitor_->OnSuccessfulVersionNegotiation(received_version); |
| 341 DLOG(INFO) << ENDPOINT << "version negotiated " << received_version; |
337 | 342 |
338 // Store the new version. | 343 // Store the new version. |
339 framer_.set_version(received_version); | 344 framer_.set_version(received_version); |
340 | 345 |
341 // TODO(satyamshekhar): Store the sequence number of this packet and close the | 346 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
342 // connection if we ever received a packet with incorrect version and whose | 347 // connection if we ever received a packet with incorrect version and whose |
343 // sequence number is greater. | 348 // sequence number is greater. |
344 return true; | 349 return true; |
345 } | 350 } |
346 | 351 |
(...skipping 24 matching lines...) Expand all Loading... |
371 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); | 376 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); |
372 return; | 377 return; |
373 } | 378 } |
374 | 379 |
375 if (!SelectMutualVersion(packet.versions)) { | 380 if (!SelectMutualVersion(packet.versions)) { |
376 SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, | 381 SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, |
377 "no common version found"); | 382 "no common version found"); |
378 return; | 383 return; |
379 } | 384 } |
380 | 385 |
| 386 DLOG(INFO) << ENDPOINT << "negotiating version " << version(); |
381 version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; | 387 version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; |
382 RetransmitUnackedPackets(ALL_PACKETS); | 388 RetransmitUnackedPackets(ALL_PACKETS); |
383 } | 389 } |
384 | 390 |
385 void QuicConnection::OnRevivedPacket() { | 391 void QuicConnection::OnRevivedPacket() { |
386 } | 392 } |
387 | 393 |
388 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { | 394 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
389 if (debug_visitor_) { | 395 if (debug_visitor_) { |
390 debug_visitor_->OnPacketHeader(header); | 396 debug_visitor_->OnPacketHeader(header); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 send_alarm_->Cancel(); | 823 send_alarm_->Cancel(); |
818 WriteIfNotBlocked(); | 824 WriteIfNotBlocked(); |
819 } else if (!delay.IsInfinite()) { | 825 } else if (!delay.IsInfinite()) { |
820 send_alarm_->Cancel(); | 826 send_alarm_->Cancel(); |
821 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); | 827 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); |
822 } | 828 } |
823 } | 829 } |
824 } | 830 } |
825 | 831 |
826 void QuicConnection::SendVersionNegotiationPacket() { | 832 void QuicConnection::SendVersionNegotiationPacket() { |
827 QuicVersionVector supported_versions; | |
828 for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { | |
829 supported_versions.push_back(kSupportedQuicVersions[i]); | |
830 } | |
831 scoped_ptr<QuicEncryptedPacket> version_packet( | 833 scoped_ptr<QuicEncryptedPacket> version_packet( |
832 packet_creator_.SerializeVersionNegotiationPacket(supported_versions)); | 834 packet_creator_.SerializeVersionNegotiationPacket( |
| 835 framer_.supported_versions())); |
833 // TODO(satyamshekhar): implement zero server state negotiation. | 836 // TODO(satyamshekhar): implement zero server state negotiation. |
834 WriteResult result = | 837 WriteResult result = |
835 writer_->WritePacket(version_packet->data(), version_packet->length(), | 838 writer_->WritePacket(version_packet->data(), version_packet->length(), |
836 self_address().address(), peer_address(), this); | 839 self_address().address(), peer_address(), this); |
| 840 if (result.status == WRITE_STATUS_BLOCKED) { |
| 841 write_blocked_ = true; |
| 842 } |
837 if (result.status == WRITE_STATUS_OK || | 843 if (result.status == WRITE_STATUS_OK || |
838 (result.status == WRITE_STATUS_BLOCKED && | 844 (result.status == WRITE_STATUS_BLOCKED && |
839 writer_->IsWriteBlockedDataBuffered())) { | 845 writer_->IsWriteBlockedDataBuffered())) { |
840 pending_version_negotiation_packet_ = false; | 846 pending_version_negotiation_packet_ = false; |
841 return; | 847 return; |
842 } | 848 } |
843 if (result.status == WRITE_STATUS_ERROR) { | 849 if (result.status == WRITE_STATUS_ERROR) { |
844 // We can't send an error as the socket is presumably borked. | 850 // We can't send an error as the socket is presumably borked. |
845 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); | 851 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); |
846 } | 852 } |
847 if (result.status == WRITE_STATUS_BLOCKED) { | |
848 write_blocked_ = true; | |
849 } | |
850 pending_version_negotiation_packet_ = true; | 853 pending_version_negotiation_packet_ = true; |
851 } | 854 } |
852 | 855 |
853 QuicConsumedData QuicConnection::SendStreamDataInner( | 856 QuicConsumedData QuicConnection::SendStreamDataInner( |
854 QuicStreamId id, | 857 QuicStreamId id, |
855 const IOVector& data, | 858 const IOVector& data, |
856 QuicStreamOffset offset, | 859 QuicStreamOffset offset, |
857 bool fin, | 860 bool fin, |
858 QuicAckNotifier* notifier) { | 861 QuicAckNotifier* notifier) { |
859 // TODO(ianswett): Further improve sending by passing the iovec down | 862 // TODO(ianswett): Further improve sending by passing the iovec down |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 QuicPacket* packet, | 1250 QuicPacket* packet, |
1248 TransmissionType transmission_type, | 1251 TransmissionType transmission_type, |
1249 HasRetransmittableData retransmittable, | 1252 HasRetransmittableData retransmittable, |
1250 IsHandshake handshake, | 1253 IsHandshake handshake, |
1251 Force forced) { | 1254 Force forced) { |
1252 if (ShouldDiscardPacket(level, sequence_number, retransmittable)) { | 1255 if (ShouldDiscardPacket(level, sequence_number, retransmittable)) { |
1253 delete packet; | 1256 delete packet; |
1254 return true; | 1257 return true; |
1255 } | 1258 } |
1256 | 1259 |
| 1260 // If we're write blocked, we know we can't write. |
| 1261 if (write_blocked_) { |
| 1262 return false; |
| 1263 } |
| 1264 |
1257 // If we are not forced and we can't write, then simply return false; | 1265 // If we are not forced and we can't write, then simply return false; |
1258 if (forced == NO_FORCE && | 1266 if (forced == NO_FORCE && |
1259 !CanWrite(transmission_type, retransmittable, handshake)) { | 1267 !CanWrite(transmission_type, retransmittable, handshake)) { |
1260 return false; | 1268 return false; |
1261 } | 1269 } |
1262 | 1270 |
1263 // Some encryption algorithms require the packet sequence numbers not be | 1271 // Some encryption algorithms require the packet sequence numbers not be |
1264 // repeated. | 1272 // repeated. |
1265 DCHECK_LE(sequence_number_of_last_inorder_packet_, sequence_number); | 1273 DCHECK_LE(sequence_number_of_last_inorder_packet_, sequence_number); |
1266 // Only increase this when packets have not been queued. Once they're queued | 1274 // Only increase this when packets have not been queued. Once they're queued |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 | 1403 |
1396 QuicPacketSequenceNumber sequence_number = pending_write_->sequence_number; | 1404 QuicPacketSequenceNumber sequence_number = pending_write_->sequence_number; |
1397 TransmissionType transmission_type = pending_write_->transmission_type; | 1405 TransmissionType transmission_type = pending_write_->transmission_type; |
1398 HasRetransmittableData retransmittable = pending_write_->retransmittable; | 1406 HasRetransmittableData retransmittable = pending_write_->retransmittable; |
1399 EncryptionLevel level = pending_write_->level; | 1407 EncryptionLevel level = pending_write_->level; |
1400 bool is_fec_packet = pending_write_->is_fec_packet; | 1408 bool is_fec_packet = pending_write_->is_fec_packet; |
1401 size_t length = pending_write_->length; | 1409 size_t length = pending_write_->length; |
1402 pending_write_.reset(); | 1410 pending_write_.reset(); |
1403 | 1411 |
1404 if (result.status == WRITE_STATUS_ERROR) { | 1412 if (result.status == WRITE_STATUS_ERROR) { |
| 1413 DLOG(INFO) << "Write failed with error code: " << result.error_code; |
1405 // We can't send an error as the socket is presumably borked. | 1414 // We can't send an error as the socket is presumably borked. |
1406 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); | 1415 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); |
1407 return false; | 1416 return false; |
1408 } | 1417 } |
1409 | 1418 |
1410 QuicTime now = clock_->Now(); | 1419 QuicTime now = clock_->Now(); |
1411 if (transmission_type == NOT_RETRANSMISSION) { | 1420 if (transmission_type == NOT_RETRANSMISSION) { |
1412 time_of_last_sent_packet_ = now; | 1421 time_of_last_sent_packet_ = now; |
1413 } | 1422 } |
1414 DVLOG(1) << ENDPOINT << "time of last sent packet: " | 1423 DVLOG(1) << ENDPOINT << "time of last sent packet: " |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 // If we changed the generator's batch state, restore original batch state. | 1884 // If we changed the generator's batch state, restore original batch state. |
1876 if (!already_in_batch_mode_) { | 1885 if (!already_in_batch_mode_) { |
1877 DVLOG(1) << "Leaving Batch Mode."; | 1886 DVLOG(1) << "Leaving Batch Mode."; |
1878 connection_->packet_generator_.FinishBatchOperations(); | 1887 connection_->packet_generator_.FinishBatchOperations(); |
1879 } | 1888 } |
1880 DCHECK_EQ(already_in_batch_mode_, | 1889 DCHECK_EQ(already_in_batch_mode_, |
1881 connection_->packet_generator_.InBatchMode()); | 1890 connection_->packet_generator_.InBatchMode()); |
1882 } | 1891 } |
1883 | 1892 |
1884 } // namespace net | 1893 } // namespace net |
OLD | NEW |