| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 peer_address_(address), | 77 peer_address_(address), |
| 78 largest_seen_packet_with_ack_(0), | 78 largest_seen_packet_with_ack_(0), |
| 79 peer_largest_observed_packet_(0), | 79 peer_largest_observed_packet_(0), |
| 80 least_packet_awaited_by_peer_(1), | 80 least_packet_awaited_by_peer_(1), |
| 81 peer_least_packet_awaiting_ack_(0), | 81 peer_least_packet_awaiting_ack_(0), |
| 82 handling_retransmission_timeout_(false), | 82 handling_retransmission_timeout_(false), |
| 83 write_blocked_(false), | 83 write_blocked_(false), |
| 84 debug_visitor_(NULL), | 84 debug_visitor_(NULL), |
| 85 packet_creator_(guid_, &framer_, random_generator_, is_server), | 85 packet_creator_(guid_, &framer_, random_generator_, is_server), |
| 86 packet_generator_(this, &packet_creator_), | 86 packet_generator_(this, &packet_creator_), |
| 87 timeout_(QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 87 idle_network_timeout_( |
| 88 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
| 89 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
| 90 creation_time_(clock_->ApproximateNow()), |
| 88 time_of_last_received_packet_(clock_->ApproximateNow()), | 91 time_of_last_received_packet_(clock_->ApproximateNow()), |
| 89 time_of_last_sent_packet_(clock_->ApproximateNow()), | 92 time_of_last_sent_packet_(clock_->ApproximateNow()), |
| 90 time_largest_observed_(QuicTime::Zero()), | 93 time_largest_observed_(QuicTime::Zero()), |
| 91 congestion_manager_(clock_, kTCP), | 94 congestion_manager_(clock_, kTCP), |
| 92 version_negotiation_state_(START_NEGOTIATION), | 95 version_negotiation_state_(START_NEGOTIATION), |
| 93 quic_version_(kQuicVersion1), | 96 quic_version_(kQuicVersion1), |
| 94 max_packets_per_retransmission_alarm_(kMaxPacketsPerRetransmissionAlarm), | 97 max_packets_per_retransmission_alarm_(kMaxPacketsPerRetransmissionAlarm), |
| 95 is_server_(is_server), | 98 is_server_(is_server), |
| 96 connected_(true), | 99 connected_(true), |
| 97 received_truncated_ack_(false), | 100 received_truncated_ack_(false), |
| 98 send_ack_in_response_to_packet_(false), | 101 send_ack_in_response_to_packet_(false), |
| 99 address_migrating_(false) { | 102 address_migrating_(false) { |
| 100 helper_->SetConnection(this); | 103 helper_->SetConnection(this); |
| 101 helper_->SetTimeoutAlarm(timeout_); | 104 helper_->SetTimeoutAlarm(idle_network_timeout_); |
| 102 framer_.set_visitor(this); | 105 framer_.set_visitor(this); |
| 103 framer_.set_entropy_calculator(&entropy_manager_); | 106 framer_.set_entropy_calculator(&entropy_manager_); |
| 104 outgoing_ack_.sent_info.least_unacked = 0; | 107 outgoing_ack_.sent_info.least_unacked = 0; |
| 105 outgoing_ack_.sent_info.entropy_hash = 0; | 108 outgoing_ack_.sent_info.entropy_hash = 0; |
| 106 outgoing_ack_.received_info.largest_observed = 0; | 109 outgoing_ack_.received_info.largest_observed = 0; |
| 107 outgoing_ack_.received_info.entropy_hash = 0; | 110 outgoing_ack_.received_info.entropy_hash = 0; |
| 108 | 111 |
| 109 /* | 112 /* |
| 110 if (FLAGS_fake_packet_loss_percentage > 0) { | 113 if (FLAGS_fake_packet_loss_percentage > 0) { |
| 111 int32 seed = RandomBase::WeakSeed32(); | 114 int32 seed = RandomBase::WeakSeed32(); |
| 112 LOG(INFO) << ENDPOINT << "Seeding packet loss with " << seed; | 115 LOG(INFO) << ENDPOINT << "Seeding packet loss with " << seed; |
| 113 random_.reset(new MTRandom(seed)); | 116 random_.reset(new MTRandom(seed)); |
| 114 } | 117 } |
| 115 */ | 118 */ |
| 116 } | 119 } |
| 117 | 120 |
| 118 QuicConnection::~QuicConnection() { | 121 QuicConnection::~QuicConnection() { |
| 119 STLDeleteValues(&unacked_packets_); | 122 STLDeleteValues(&unacked_packets_); |
| 120 STLDeleteValues(&group_map_); | 123 STLDeleteValues(&group_map_); |
| 121 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 124 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
| 122 it != queued_packets_.end(); ++it) { | 125 it != queued_packets_.end(); ++it) { |
| 123 delete it->packet; | 126 delete it->packet; |
| 124 } | 127 } |
| 128 LOG(ERROR) << "Quic connection " << write_blocked_; |
| 125 } | 129 } |
| 126 | 130 |
| 127 bool QuicConnection::SelectMutualVersion( | 131 bool QuicConnection::SelectMutualVersion( |
| 128 const QuicTagVector& available_versions) { | 132 const QuicTagVector& available_versions) { |
| 129 // TODO(satyamshekhar): Make this generic. | 133 // TODO(satyamshekhar): Make this generic. |
| 130 if (std::find(available_versions.begin(), available_versions.end(), | 134 if (std::find(available_versions.begin(), available_versions.end(), |
| 131 kQuicVersion1) == available_versions.end()) { | 135 kQuicVersion1) == available_versions.end()) { |
| 132 return false; | 136 return false; |
| 133 } | 137 } |
| 134 | 138 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 | 310 |
| 307 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); | 311 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); |
| 308 | 312 |
| 309 --stats_.packets_dropped; | 313 --stats_.packets_dropped; |
| 310 DVLOG(1) << ENDPOINT << "Received packet header: " << header; | 314 DVLOG(1) << ENDPOINT << "Received packet header: " << header; |
| 311 last_header_ = header; | 315 last_header_ = header; |
| 312 return true; | 316 return true; |
| 313 } | 317 } |
| 314 | 318 |
| 315 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { | 319 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { |
| 320 DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group); |
| 316 DCHECK_NE(0u, last_header_.fec_group); | 321 DCHECK_NE(0u, last_header_.fec_group); |
| 317 QuicFecGroup* group = GetFecGroup(); | 322 QuicFecGroup* group = GetFecGroup(); |
| 318 if (group != NULL) { | 323 if (group != NULL) { |
| 319 group->Update(last_header_, payload); | 324 group->Update(last_header_, payload); |
| 320 } | 325 } |
| 321 } | 326 } |
| 322 | 327 |
| 323 bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) { | 328 bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) { |
| 324 DCHECK(connected_); | 329 DCHECK(connected_); |
| 325 if (debug_visitor_) { | 330 if (debug_visitor_) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 342 } | 347 } |
| 343 largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; | 348 largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; |
| 344 | 349 |
| 345 if (!ValidateAckFrame(incoming_ack)) { | 350 if (!ValidateAckFrame(incoming_ack)) { |
| 346 SendConnectionClose(QUIC_INVALID_ACK_DATA); | 351 SendConnectionClose(QUIC_INVALID_ACK_DATA); |
| 347 return false; | 352 return false; |
| 348 } | 353 } |
| 349 | 354 |
| 350 received_truncated_ack_ = | 355 received_truncated_ack_ = |
| 351 incoming_ack.received_info.missing_packets.size() >= | 356 incoming_ack.received_info.missing_packets.size() >= |
| 352 QuicFramer::GetMaxUnackedPackets(last_header_.public_header.version_flag); | 357 QuicFramer::GetMaxUnackedPackets(last_header_); |
| 353 | 358 |
| 354 UpdatePacketInformationReceivedByPeer(incoming_ack); | 359 UpdatePacketInformationReceivedByPeer(incoming_ack); |
| 355 UpdatePacketInformationSentByPeer(incoming_ack); | 360 UpdatePacketInformationSentByPeer(incoming_ack); |
| 356 congestion_manager_.OnIncomingAckFrame(incoming_ack, | 361 congestion_manager_.OnIncomingAckFrame(incoming_ack, |
| 357 time_of_last_received_packet_); | 362 time_of_last_received_packet_); |
| 358 | 363 |
| 359 // Now the we have received an ack, we might be able to send queued packets. | 364 // Now the we have received an ack, we might be able to send queued packets. |
| 360 if (!queued_packets_.empty()) { | 365 if (!queued_packets_.empty()) { |
| 361 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( | 366 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
| 362 time_of_last_received_packet_, NOT_RETRANSMISSION, | 367 time_of_last_received_packet_, NOT_RETRANSMISSION, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" | 404 DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" |
| 400 << incoming_ack.received_info.largest_observed << " vs " | 405 << incoming_ack.received_info.largest_observed << " vs " |
| 401 << peer_largest_observed_packet_; | 406 << peer_largest_observed_packet_; |
| 402 // We got an error for data we have not sent. Error out. | 407 // We got an error for data we have not sent. Error out. |
| 403 return false; | 408 return false; |
| 404 } | 409 } |
| 405 | 410 |
| 406 // We can't have too many unacked packets, or our ack frames go over | 411 // We can't have too many unacked packets, or our ack frames go over |
| 407 // kMaxPacketSize. | 412 // kMaxPacketSize. |
| 408 DCHECK_LE(incoming_ack.received_info.missing_packets.size(), | 413 DCHECK_LE(incoming_ack.received_info.missing_packets.size(), |
| 409 QuicFramer::GetMaxUnackedPackets( | 414 QuicFramer::GetMaxUnackedPackets(last_header_)); |
| 410 last_header_.public_header.version_flag)); | |
| 411 | 415 |
| 412 if (incoming_ack.sent_info.least_unacked < peer_least_packet_awaiting_ack_) { | 416 if (incoming_ack.sent_info.least_unacked < peer_least_packet_awaiting_ack_) { |
| 413 DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: " | 417 DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: " |
| 414 << incoming_ack.sent_info.least_unacked | 418 << incoming_ack.sent_info.least_unacked |
| 415 << " vs " << peer_least_packet_awaiting_ack_; | 419 << " vs " << peer_least_packet_awaiting_ack_; |
| 416 // We never process old ack frames, so this number should only increase. | 420 // We never process old ack frames, so this number should only increase. |
| 417 return false; | 421 return false; |
| 418 } | 422 } |
| 419 | 423 |
| 420 if (incoming_ack.sent_info.least_unacked > | 424 if (incoming_ack.sent_info.least_unacked > |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 peer_least_packet_awaiting_ack_); | 562 peer_least_packet_awaiting_ack_); |
| 559 } | 563 } |
| 560 DCHECK(outgoing_ack_.received_info.missing_packets.empty() || | 564 DCHECK(outgoing_ack_.received_info.missing_packets.empty() || |
| 561 *outgoing_ack_.received_info.missing_packets.begin() >= | 565 *outgoing_ack_.received_info.missing_packets.begin() >= |
| 562 peer_least_packet_awaiting_ack_); | 566 peer_least_packet_awaiting_ack_); |
| 563 // Possibly close any FecGroups which are now irrelevant | 567 // Possibly close any FecGroups which are now irrelevant |
| 564 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); | 568 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); |
| 565 } | 569 } |
| 566 | 570 |
| 567 void QuicConnection::OnFecData(const QuicFecData& fec) { | 571 void QuicConnection::OnFecData(const QuicFecData& fec) { |
| 572 DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group); |
| 568 DCHECK_NE(0u, last_header_.fec_group); | 573 DCHECK_NE(0u, last_header_.fec_group); |
| 569 QuicFecGroup* group = GetFecGroup(); | 574 QuicFecGroup* group = GetFecGroup(); |
| 570 if (group != NULL) { | 575 if (group != NULL) { |
| 571 group->UpdateFec(last_header_.packet_sequence_number, | 576 group->UpdateFec(last_header_.packet_sequence_number, |
| 572 last_header_.fec_entropy_flag, fec); | 577 last_header_.entropy_flag, fec); |
| 573 } | 578 } |
| 574 } | 579 } |
| 575 | 580 |
| 576 bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) { | 581 bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) { |
| 577 DCHECK(connected_); | 582 DCHECK(connected_); |
| 578 if (debug_visitor_) { | 583 if (debug_visitor_) { |
| 579 debug_visitor_->OnRstStreamFrame(frame); | 584 debug_visitor_->OnRstStreamFrame(frame); |
| 580 } | 585 } |
| 581 DLOG(INFO) << ENDPOINT << "Stream reset with error " | 586 DLOG(INFO) << ENDPOINT << "Stream reset with error " |
| 582 << QuicUtils::StreamErrorToString(frame.error_code); | 587 << QuicUtils::StreamErrorToString(frame.error_code); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 // Continue, because some queued packets may still be writable. | 800 // Continue, because some queued packets may still be writable. |
| 796 // This can happen if a retransmit send fail. | 801 // This can happen if a retransmit send fail. |
| 797 ++packet_iterator; | 802 ++packet_iterator; |
| 798 } | 803 } |
| 799 } | 804 } |
| 800 | 805 |
| 801 return !write_blocked_; | 806 return !write_blocked_; |
| 802 } | 807 } |
| 803 | 808 |
| 804 void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) { | 809 void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) { |
| 805 DLOG(INFO) << ENDPOINT << "Recording received packet: " | |
| 806 << header.packet_sequence_number; | |
| 807 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; | 810 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
| 808 DCHECK(IsAwaitingPacket(outgoing_ack_.received_info, sequence_number)); | 811 DCHECK(IsAwaitingPacket(outgoing_ack_.received_info, sequence_number)); |
| 809 | 812 |
| 810 InsertMissingPacketsBetween( | 813 InsertMissingPacketsBetween( |
| 811 &outgoing_ack_.received_info, | 814 &outgoing_ack_.received_info, |
| 812 max(outgoing_ack_.received_info.largest_observed + 1, | 815 max(outgoing_ack_.received_info.largest_observed + 1, |
| 813 peer_least_packet_awaiting_ack_), | 816 peer_least_packet_awaiting_ack_), |
| 814 header.packet_sequence_number); | 817 header.packet_sequence_number); |
| 815 | 818 |
| 816 if (outgoing_ack_.received_info.largest_observed > | 819 if (outgoing_ack_.received_info.largest_observed > |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 if (group == NULL || !group->CanRevive()) { | 1255 if (group == NULL || !group->CanRevive()) { |
| 1253 return; | 1256 return; |
| 1254 } | 1257 } |
| 1255 QuicPacketHeader revived_header; | 1258 QuicPacketHeader revived_header; |
| 1256 char revived_payload[kMaxPacketSize]; | 1259 char revived_payload[kMaxPacketSize]; |
| 1257 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); | 1260 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); |
| 1258 revived_header.public_header.guid = guid_; | 1261 revived_header.public_header.guid = guid_; |
| 1259 revived_header.public_header.version_flag = false; | 1262 revived_header.public_header.version_flag = false; |
| 1260 revived_header.public_header.reset_flag = false; | 1263 revived_header.public_header.reset_flag = false; |
| 1261 revived_header.fec_flag = false; | 1264 revived_header.fec_flag = false; |
| 1262 revived_header.fec_group = kNoFecOffset; | 1265 revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; |
| 1266 revived_header.fec_group = 0; |
| 1263 group_map_.erase(last_header_.fec_group); | 1267 group_map_.erase(last_header_.fec_group); |
| 1264 delete group; | 1268 delete group; |
| 1265 | 1269 |
| 1266 last_packet_revived_ = true; | 1270 last_packet_revived_ = true; |
| 1267 if (debug_visitor_) { | 1271 if (debug_visitor_) { |
| 1268 debug_visitor_->OnRevivedPacket(revived_header, | 1272 debug_visitor_->OnRevivedPacket(revived_header, |
| 1269 StringPiece(revived_payload, len)); | 1273 StringPiece(revived_payload, len)); |
| 1270 } | 1274 } |
| 1271 | 1275 |
| 1272 ++stats_.packets_revived; | 1276 ++stats_.packets_revived; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 DCHECK(!fec_group->CanRevive()); | 1366 DCHECK(!fec_group->CanRevive()); |
| 1363 FecGroupMap::iterator next = it; | 1367 FecGroupMap::iterator next = it; |
| 1364 ++next; | 1368 ++next; |
| 1365 group_map_.erase(it); | 1369 group_map_.erase(it); |
| 1366 delete fec_group; | 1370 delete fec_group; |
| 1367 it = next; | 1371 it = next; |
| 1368 } | 1372 } |
| 1369 } | 1373 } |
| 1370 | 1374 |
| 1371 bool QuicConnection::HasQueuedData() const { | 1375 bool QuicConnection::HasQueuedData() const { |
| 1372 return !queued_packets_.empty() || packet_generator_.HasQueuedData(); | 1376 return !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); |
| 1373 } | 1377 } |
| 1374 | 1378 |
| 1375 void QuicConnection::SetConnectionTimeout(QuicTime::Delta timeout) { | 1379 void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { |
| 1376 timeout_ = timeout; | 1380 // if (timeout < idle_network_timeout_) { |
| 1377 CheckForTimeout(); | 1381 idle_network_timeout_ = timeout; |
| 1382 CheckForTimeout(); |
| 1383 // } else { |
| 1384 // idle_network_timeout_ = timeout; |
| 1385 // } |
| 1386 } |
| 1387 |
| 1388 void QuicConnection::SetOverallConnectionTimeout(QuicTime::Delta timeout) { |
| 1389 // if (timeout < overall_connection_timeout_) { |
| 1390 overall_connection_timeout_ = timeout; |
| 1391 CheckForTimeout(); |
| 1392 // } else { |
| 1393 // overall_connection_timeout_ = timeout; |
| 1394 // } |
| 1378 } | 1395 } |
| 1379 | 1396 |
| 1380 bool QuicConnection::CheckForTimeout() { | 1397 bool QuicConnection::CheckForTimeout() { |
| 1381 QuicTime now = clock_->ApproximateNow(); | 1398 QuicTime now = clock_->ApproximateNow(); |
| 1382 QuicTime time_of_last_packet = std::max(time_of_last_received_packet_, | 1399 QuicTime time_of_last_packet = std::max(time_of_last_received_packet_, |
| 1383 time_of_last_sent_packet_); | 1400 time_of_last_sent_packet_); |
| 1384 | 1401 |
| 1385 QuicTime::Delta delta = now.Subtract(time_of_last_packet); | 1402 QuicTime::Delta delta = now.Subtract(time_of_last_packet); |
| 1386 DVLOG(1) << ENDPOINT << "last packet " | 1403 DVLOG(1) << ENDPOINT << "last packet " |
| 1387 << time_of_last_packet.ToDebuggingValue() | 1404 << time_of_last_packet.ToDebuggingValue() |
| 1388 << " now:" << now.ToDebuggingValue() | 1405 << " now:" << now.ToDebuggingValue() |
| 1389 << " delta:" << delta.ToMicroseconds(); | 1406 << " delta:" << delta.ToMicroseconds() |
| 1390 if (delta >= timeout_) { | 1407 << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); |
| 1408 if (delta >= idle_network_timeout_) { |
| 1409 DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; |
| 1391 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 1410 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
| 1392 return true; | 1411 return true; |
| 1393 } | 1412 } |
| 1394 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 1413 |
| 1414 // Next timeout delta. |
| 1415 QuicTime::Delta timeout = idle_network_timeout_.Subtract(delta); |
| 1416 |
| 1417 if (!overall_connection_timeout_.IsInfinite()) { |
| 1418 QuicTime::Delta connected_time = now.Subtract(creation_time_); |
| 1419 DVLOG(1) << ENDPOINT << "connection time: " |
| 1420 << connected_time.ToMilliseconds() << " overall timeout: " |
| 1421 << overall_connection_timeout_.ToMilliseconds(); |
| 1422 if (connected_time >= overall_connection_timeout_) { |
| 1423 DVLOG(1) << ENDPOINT << |
| 1424 "Connection timedout due to overall connection timeout."; |
| 1425 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
| 1426 return true; |
| 1427 } |
| 1428 |
| 1429 // Take the min timeout. |
| 1430 QuicTime::Delta connection_timeout = |
| 1431 overall_connection_timeout_.Subtract(connected_time); |
| 1432 if (connection_timeout < timeout) { |
| 1433 timeout = connection_timeout; |
| 1434 } |
| 1435 } |
| 1436 |
| 1437 helper_->SetTimeoutAlarm(timeout); |
| 1395 return false; | 1438 return false; |
| 1396 } | 1439 } |
| 1397 | 1440 |
| 1398 } // namespace net | 1441 } // namespace net |
| OLD | NEW |