Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: webrtc/p2p/base/port.cc

Issue 1376983002: Do not time out a port if its role switched from controlled to controlling. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/p2p/base/port_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 << retransmit_attr->value(); 559 << retransmit_attr->value();
560 } 560 }
561 } 561 }
562 562
563 response.AddAttribute( 563 response.AddAttribute(
564 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr)); 564 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr));
565 response.AddMessageIntegrity(password_); 565 response.AddMessageIntegrity(password_);
566 response.AddFingerprint(); 566 response.AddFingerprint();
567 567
568 // The fact that we received a successful request means that this connection 568 // The fact that we received a successful request means that this connection
569 // (if one exists) should now be readable. 569 // (if one exists) should now be receiving.
570 Connection* conn = GetConnection(addr); 570 Connection* conn = GetConnection(addr);
571 571
572 // Send the response message. 572 // Send the response message.
573 rtc::ByteBuffer buf; 573 rtc::ByteBuffer buf;
574 response.Write(&buf); 574 response.Write(&buf);
575 rtc::PacketOptions options(DefaultDscpValue()); 575 rtc::PacketOptions options(DefaultDscpValue());
576 auto err = SendTo(buf.Data(), buf.Length(), addr, options, false); 576 auto err = SendTo(buf.Data(), buf.Length(), addr, options, false);
577 if (err < 0) { 577 if (err < 0) {
578 LOG_J(LS_ERROR, this) 578 LOG_J(LS_ERROR, this)
579 << "Failed to send STUN ping response" 579 << "Failed to send STUN ping response"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 rtc::ByteBuffer buf; 624 rtc::ByteBuffer buf;
625 response.Write(&buf); 625 response.Write(&buf);
626 rtc::PacketOptions options(DefaultDscpValue()); 626 rtc::PacketOptions options(DefaultDscpValue());
627 SendTo(buf.Data(), buf.Length(), addr, options, false); 627 SendTo(buf.Data(), buf.Length(), addr, options, false);
628 LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason 628 LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason
629 << " to " << addr.ToSensitiveString(); 629 << " to " << addr.ToSensitiveString();
630 } 630 }
631 631
632 void Port::OnMessage(rtc::Message *pmsg) { 632 void Port::OnMessage(rtc::Message *pmsg) {
633 ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT); 633 ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT);
634 CheckTimeout(); 634 CheckTimeout();
pthatcher1 2015/09/29 22:54:18 Can you remove CheckTimeout and just put the logic
honghaiz3 2015/09/30 15:59:39 Done.
635 } 635 }
636 636
637 std::string Port::ToString() const { 637 std::string Port::ToString() const {
638 std::stringstream ss; 638 std::stringstream ss;
639 ss << "Port[" << content_name_ << ":" << component_ 639 ss << "Port[" << content_name_ << ":" << component_
640 << ":" << generation_ << ":" << type_ 640 << ":" << generation_ << ":" << type_
641 << ":" << network_->ToString() << "]"; 641 << ":" << network_->ToString() << "]";
642 return ss.str(); 642 return ss.str();
643 } 643 }
644 644
645 void Port::EnablePortPackets() { 645 void Port::EnablePortPackets() {
646 enable_port_packets_ = true; 646 enable_port_packets_ = true;
647 } 647 }
648 648
649 void Port::OnConnectionDestroyed(Connection* conn) { 649 void Port::OnConnectionDestroyed(Connection* conn) {
650 AddressMap::iterator iter = 650 AddressMap::iterator iter =
651 connections_.find(conn->remote_candidate().address()); 651 connections_.find(conn->remote_candidate().address());
652 ASSERT(iter != connections_.end()); 652 ASSERT(iter != connections_.end());
653 connections_.erase(iter); 653 connections_.erase(iter);
654 654
655 // On the controlled side, ports time out, but only after all connections 655 // On the controlled side, ports time out after all connections fail.
656 // fail. Note: If a new connection is added after this message is posted, 656 // Note: This message is only processed by the controlled side. Plus, if a
657 // but it fails and is removed before kPortTimeoutDelay, then this message 657 // new connection is added after this message is posted, but it fails and is
658 // will still cause the Port to be destroyed. 658 // removed before kPortTimeoutDelay, then this message will still cause the
659 if (ice_role_ == ICEROLE_CONTROLLED) 659 // Port to be destroyed.
660 if (connections_.empty()) {
pthatcher1 2015/09/29 22:54:18 I think we should make the conditions the same ins
honghaiz3 2015/09/30 15:59:39 Done. Except that using a single line for the dead
660 thread_->PostDelayed(timeout_delay_, this, MSG_CHECKTIMEOUT); 661 thread_->PostDelayed(timeout_delay_, this, MSG_CHECKTIMEOUT);
662 }
661 } 663 }
662 664
663 void Port::Destroy() { 665 void Port::Destroy() {
664 ASSERT(connections_.empty()); 666 ASSERT(connections_.empty());
665 LOG_J(LS_INFO, this) << "Port deleted"; 667 LOG_J(LS_INFO, this) << "Port deleted";
666 SignalDestroyed(this); 668 SignalDestroyed(this);
667 delete this; 669 delete this;
668 } 670 }
669 671
670 void Port::CheckTimeout() { 672 void Port::CheckTimeout() {
671 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 673 // On the controlled side, if this port has no connection, then there's no
672 // If this port has no connections, then there's no reason to keep it around. 674 // reason to keep it around.
673 // When the connections time out (both read and write), they will delete 675 if (ice_role_ == ICEROLE_CONTROLLED && connections_.empty())
674 // themselves, so if we have any connections, they are either readable or
675 // writable (or still connecting).
676 if (connections_.empty())
677 Destroy(); 676 Destroy();
678 } 677 }
679 678
680 const std::string Port::username_fragment() const { 679 const std::string Port::username_fragment() const {
681 return ice_username_fragment_; 680 return ice_username_fragment_;
682 } 681 }
683 682
684 // A ConnectionRequest is a simple STUN ping used to determine writability. 683 // A ConnectionRequest is a simple STUN ping used to determine writability.
685 class ConnectionRequest : public StunRequest { 684 class ConnectionRequest : public StunRequest {
686 public: 685 public:
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { 911 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
913 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " 912 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. "
914 << "Resetting state to STATE_WRITE_INIT."; 913 << "Resetting state to STATE_WRITE_INIT.";
915 set_write_state(STATE_WRITE_INIT); 914 set_write_state(STATE_WRITE_INIT);
916 } 915 }
917 } else if (!msg) { 916 } else if (!msg) {
918 // The packet was STUN, but failed a check and was handled internally. 917 // The packet was STUN, but failed a check and was handled internally.
919 } else { 918 } else {
920 // The packet is STUN and passed the Port checks. 919 // The packet is STUN and passed the Port checks.
921 // Perform our own checks to ensure this packet is valid. 920 // Perform our own checks to ensure this packet is valid.
922 // If this is a STUN request, then update the readable bit and respond. 921 // If this is a STUN request, then update the receiving bit and respond.
923 // If this is a STUN response, then update the writable bit. 922 // If this is a STUN response, then update the writable bit.
924 // Log at LS_INFO if we receive a ping on an unwritable connection. 923 // Log at LS_INFO if we receive a ping on an unwritable connection.
925 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); 924 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE);
926 switch (msg->type()) { 925 switch (msg->type()) {
927 case STUN_BINDING_REQUEST: 926 case STUN_BINDING_REQUEST:
928 LOG_JV(sev, this) << "Received STUN ping" 927 LOG_JV(sev, this) << "Received STUN ping"
929 << ", id=" << rtc::hex_encode(msg->transaction_id()); 928 << ", id=" << rtc::hex_encode(msg->transaction_id());
930 929
931 if (remote_ufrag == remote_candidate_.username()) { 930 if (remote_ufrag == remote_candidate_.username()) {
932 // Check for role conflicts. 931 // Check for role conflicts.
933 if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) { 932 if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
934 // Received conflicting role from the peer. 933 // Received conflicting role from the peer.
935 LOG(LS_INFO) << "Received conflicting role from the peer."; 934 LOG(LS_INFO) << "Received conflicting role from the peer.";
936 return; 935 return;
937 } 936 }
938 937
939 // Incoming, validated stun request from remote peer. 938 // Incoming, validated stun request from remote peer.
940 // This call will also set the connection readable. 939 // This call will also set the connection receiving.
941 port_->SendBindingResponse(msg.get(), addr); 940 port_->SendBindingResponse(msg.get(), addr);
942 941
943 // If timed out sending writability checks, start up again 942 // If timed out sending writability checks, start up again
944 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) 943 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
945 set_write_state(STATE_WRITE_INIT); 944 set_write_state(STATE_WRITE_INIT);
946 945
947 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { 946 if (port_->GetIceRole() == ICEROLE_CONTROLLED) {
948 const StunByteStringAttribute* use_candidate_attr = 947 const StunByteStringAttribute* use_candidate_attr =
949 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); 948 msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
950 if (use_candidate_attr) { 949 if (use_candidate_attr) {
(...skipping 19 matching lines...) Expand all
970 // id's match. 969 // id's match.
971 case STUN_BINDING_RESPONSE: 970 case STUN_BINDING_RESPONSE:
972 case STUN_BINDING_ERROR_RESPONSE: 971 case STUN_BINDING_ERROR_RESPONSE:
973 if (msg->ValidateMessageIntegrity( 972 if (msg->ValidateMessageIntegrity(
974 data, size, remote_candidate().password())) { 973 data, size, remote_candidate().password())) {
975 requests_.CheckResponse(msg.get()); 974 requests_.CheckResponse(msg.get());
976 } 975 }
977 // Otherwise silently discard the response message. 976 // Otherwise silently discard the response message.
978 break; 977 break;
979 978
980 // Remote end point sent an STUN indication instead of regular 979 // Remote end point sent an STUN indication instead of regular binding
981 // binding request. In this case |last_ping_received_| will be updated. 980 // request. In this case |last_ping_received_| will be updated but no
982 // Otherwise we can mark connection to read timeout. No response will be 981 // response will be sent.
983 // sent in this scenario.
984 case STUN_BINDING_INDICATION: 982 case STUN_BINDING_INDICATION:
985 ReceivedPing(); 983 ReceivedPing();
986 break; 984 break;
987 985
988 default: 986 default:
989 ASSERT(false); 987 ASSERT(false);
990 break; 988 break;
991 } 989 }
992 } 990 }
993 } 991 }
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 remote_candidate_.address() == new_candidate.address() && 1276 remote_candidate_.address() == new_candidate.address() &&
1279 remote_candidate_.username() == new_candidate.username() && 1277 remote_candidate_.username() == new_candidate.username() &&
1280 remote_candidate_.password() == new_candidate.password() && 1278 remote_candidate_.password() == new_candidate.password() &&
1281 remote_candidate_.generation() == new_candidate.generation()) { 1279 remote_candidate_.generation() == new_candidate.generation()) {
1282 remote_candidate_ = new_candidate; 1280 remote_candidate_ = new_candidate;
1283 } 1281 }
1284 } 1282 }
1285 1283
1286 void Connection::OnMessage(rtc::Message *pmsg) { 1284 void Connection::OnMessage(rtc::Message *pmsg) {
1287 ASSERT(pmsg->message_id == MSG_DELETE); 1285 ASSERT(pmsg->message_id == MSG_DELETE);
1288 LOG_J(LS_INFO, this) << "Connection deleted due to read or write timeout"; 1286 LOG_J(LS_INFO, this) << "Connection deleted";
1289 SignalDestroyed(this); 1287 SignalDestroyed(this);
1290 delete this; 1288 delete this;
1291 } 1289 }
1292 1290
1293 uint32 Connection::last_received() { 1291 uint32 Connection::last_received() {
1294 return std::max(last_data_received_, 1292 return std::max(last_data_received_,
1295 std::max(last_ping_received_, last_ping_response_received_)); 1293 std::max(last_ping_received_, last_ping_response_received_));
1296 } 1294 }
1297 1295
1298 size_t Connection::recv_bytes_second() { 1296 size_t Connection::recv_bytes_second() {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 ASSERT(sent < 0); 1400 ASSERT(sent < 0);
1403 error_ = port_->GetError(); 1401 error_ = port_->GetError();
1404 sent_packets_discarded_++; 1402 sent_packets_discarded_++;
1405 } else { 1403 } else {
1406 send_rate_tracker_.AddSamples(sent); 1404 send_rate_tracker_.AddSamples(sent);
1407 } 1405 }
1408 return sent; 1406 return sent;
1409 } 1407 }
1410 1408
1411 } // namespace cricket 1409 } // namespace cricket
OLDNEW
« no previous file with comments | « no previous file | webrtc/p2p/base/port_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698