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

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
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 // Send the response message. 623 // Send the response message.
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_DEAD);
634 CheckTimeout(); 634 if (dead()) {
635 Destroy();
636 }
635 } 637 }
636 638
637 std::string Port::ToString() const { 639 std::string Port::ToString() const {
638 std::stringstream ss; 640 std::stringstream ss;
639 ss << "Port[" << content_name_ << ":" << component_ 641 ss << "Port[" << content_name_ << ":" << component_
640 << ":" << generation_ << ":" << type_ 642 << ":" << generation_ << ":" << type_
641 << ":" << network_->ToString() << "]"; 643 << ":" << network_->ToString() << "]";
642 return ss.str(); 644 return ss.str();
643 } 645 }
644 646
645 void Port::EnablePortPackets() { 647 void Port::EnablePortPackets() {
646 enable_port_packets_ = true; 648 enable_port_packets_ = true;
647 } 649 }
648 650
649 void Port::OnConnectionDestroyed(Connection* conn) { 651 void Port::OnConnectionDestroyed(Connection* conn) {
650 AddressMap::iterator iter = 652 AddressMap::iterator iter =
651 connections_.find(conn->remote_candidate().address()); 653 connections_.find(conn->remote_candidate().address());
652 ASSERT(iter != connections_.end()); 654 ASSERT(iter != connections_.end());
653 connections_.erase(iter); 655 connections_.erase(iter);
654 656
655 // On the controlled side, ports time out, but only after all connections 657 // 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, 658 // Note: If a new connection is added after this message is posted, but it
657 // but it fails and is removed before kPortTimeoutDelay, then this message 659 // fails and is removed before kPortTimeoutDelay, then this message will
658 // will still cause the Port to be destroyed. 660 // still cause the Port to be destroyed.
659 if (ice_role_ == ICEROLE_CONTROLLED) 661 if (dead()) {
660 thread_->PostDelayed(timeout_delay_, this, MSG_CHECKTIMEOUT); 662 thread_->PostDelayed(timeout_delay_, this, MSG_DEAD);
663 }
661 } 664 }
662 665
663 void Port::Destroy() { 666 void Port::Destroy() {
664 ASSERT(connections_.empty()); 667 ASSERT(connections_.empty());
665 LOG_J(LS_INFO, this) << "Port deleted"; 668 LOG_J(LS_INFO, this) << "Port deleted";
666 SignalDestroyed(this); 669 SignalDestroyed(this);
667 delete this; 670 delete this;
668 } 671 }
669 672
670 void Port::CheckTimeout() {
671 ASSERT(ice_role_ == ICEROLE_CONTROLLED);
672 // If this port has no connections, then there's no reason to keep it around.
673 // When the connections time out (both read and write), they will delete
674 // themselves, so if we have any connections, they are either readable or
675 // writable (or still connecting).
676 if (connections_.empty())
677 Destroy();
678 }
679
680 const std::string Port::username_fragment() const { 673 const std::string Port::username_fragment() const {
681 return ice_username_fragment_; 674 return ice_username_fragment_;
682 } 675 }
683 676
684 // A ConnectionRequest is a simple STUN ping used to determine writability. 677 // A ConnectionRequest is a simple STUN ping used to determine writability.
685 class ConnectionRequest : public StunRequest { 678 class ConnectionRequest : public StunRequest {
686 public: 679 public:
687 explicit ConnectionRequest(Connection* connection) 680 explicit ConnectionRequest(Connection* connection)
688 : StunRequest(new IceMessage()), 681 : StunRequest(new IceMessage()),
689 connection_(connection) { 682 connection_(connection) {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { 905 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
913 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " 906 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. "
914 << "Resetting state to STATE_WRITE_INIT."; 907 << "Resetting state to STATE_WRITE_INIT.";
915 set_write_state(STATE_WRITE_INIT); 908 set_write_state(STATE_WRITE_INIT);
916 } 909 }
917 } else if (!msg) { 910 } else if (!msg) {
918 // The packet was STUN, but failed a check and was handled internally. 911 // The packet was STUN, but failed a check and was handled internally.
919 } else { 912 } else {
920 // The packet is STUN and passed the Port checks. 913 // The packet is STUN and passed the Port checks.
921 // Perform our own checks to ensure this packet is valid. 914 // Perform our own checks to ensure this packet is valid.
922 // If this is a STUN request, then update the readable bit and respond. 915 // 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. 916 // 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. 917 // Log at LS_INFO if we receive a ping on an unwritable connection.
925 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); 918 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE);
926 switch (msg->type()) { 919 switch (msg->type()) {
927 case STUN_BINDING_REQUEST: 920 case STUN_BINDING_REQUEST:
928 LOG_JV(sev, this) << "Received STUN ping" 921 LOG_JV(sev, this) << "Received STUN ping"
929 << ", id=" << rtc::hex_encode(msg->transaction_id()); 922 << ", id=" << rtc::hex_encode(msg->transaction_id());
930 923
931 if (remote_ufrag == remote_candidate_.username()) { 924 if (remote_ufrag == remote_candidate_.username()) {
932 // Check for role conflicts. 925 // Check for role conflicts.
933 if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) { 926 if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
934 // Received conflicting role from the peer. 927 // Received conflicting role from the peer.
935 LOG(LS_INFO) << "Received conflicting role from the peer."; 928 LOG(LS_INFO) << "Received conflicting role from the peer.";
936 return; 929 return;
937 } 930 }
938 931
939 // Incoming, validated stun request from remote peer. 932 // Incoming, validated stun request from remote peer.
940 // This call will also set the connection readable. 933 // This call will also set the connection receiving.
941 port_->SendBindingResponse(msg.get(), addr); 934 port_->SendBindingResponse(msg.get(), addr);
942 935
943 // If timed out sending writability checks, start up again 936 // If timed out sending writability checks, start up again
944 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) 937 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
945 set_write_state(STATE_WRITE_INIT); 938 set_write_state(STATE_WRITE_INIT);
946 939
947 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { 940 if (port_->GetIceRole() == ICEROLE_CONTROLLED) {
948 const StunByteStringAttribute* use_candidate_attr = 941 const StunByteStringAttribute* use_candidate_attr =
949 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); 942 msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
950 if (use_candidate_attr) { 943 if (use_candidate_attr) {
(...skipping 19 matching lines...) Expand all
970 // id's match. 963 // id's match.
971 case STUN_BINDING_RESPONSE: 964 case STUN_BINDING_RESPONSE:
972 case STUN_BINDING_ERROR_RESPONSE: 965 case STUN_BINDING_ERROR_RESPONSE:
973 if (msg->ValidateMessageIntegrity( 966 if (msg->ValidateMessageIntegrity(
974 data, size, remote_candidate().password())) { 967 data, size, remote_candidate().password())) {
975 requests_.CheckResponse(msg.get()); 968 requests_.CheckResponse(msg.get());
976 } 969 }
977 // Otherwise silently discard the response message. 970 // Otherwise silently discard the response message.
978 break; 971 break;
979 972
980 // Remote end point sent an STUN indication instead of regular 973 // Remote end point sent an STUN indication instead of regular binding
981 // binding request. In this case |last_ping_received_| will be updated. 974 // 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 975 // response will be sent.
983 // sent in this scenario.
984 case STUN_BINDING_INDICATION: 976 case STUN_BINDING_INDICATION:
985 ReceivedPing(); 977 ReceivedPing();
986 break; 978 break;
987 979
988 default: 980 default:
989 ASSERT(false); 981 ASSERT(false);
990 break; 982 break;
991 } 983 }
992 } 984 }
993 } 985 }
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 remote_candidate_.address() == new_candidate.address() && 1270 remote_candidate_.address() == new_candidate.address() &&
1279 remote_candidate_.username() == new_candidate.username() && 1271 remote_candidate_.username() == new_candidate.username() &&
1280 remote_candidate_.password() == new_candidate.password() && 1272 remote_candidate_.password() == new_candidate.password() &&
1281 remote_candidate_.generation() == new_candidate.generation()) { 1273 remote_candidate_.generation() == new_candidate.generation()) {
1282 remote_candidate_ = new_candidate; 1274 remote_candidate_ = new_candidate;
1283 } 1275 }
1284 } 1276 }
1285 1277
1286 void Connection::OnMessage(rtc::Message *pmsg) { 1278 void Connection::OnMessage(rtc::Message *pmsg) {
1287 ASSERT(pmsg->message_id == MSG_DELETE); 1279 ASSERT(pmsg->message_id == MSG_DELETE);
1288 LOG_J(LS_INFO, this) << "Connection deleted due to read or write timeout"; 1280 LOG_J(LS_INFO, this) << "Connection deleted";
1289 SignalDestroyed(this); 1281 SignalDestroyed(this);
1290 delete this; 1282 delete this;
1291 } 1283 }
1292 1284
1293 uint32 Connection::last_received() { 1285 uint32 Connection::last_received() {
1294 return std::max(last_data_received_, 1286 return std::max(last_data_received_,
1295 std::max(last_ping_received_, last_ping_response_received_)); 1287 std::max(last_ping_received_, last_ping_response_received_));
1296 } 1288 }
1297 1289
1298 size_t Connection::recv_bytes_second() { 1290 size_t Connection::recv_bytes_second() {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 ASSERT(sent < 0); 1394 ASSERT(sent < 0);
1403 error_ = port_->GetError(); 1395 error_ = port_->GetError();
1404 sent_packets_discarded_++; 1396 sent_packets_discarded_++;
1405 } else { 1397 } else {
1406 send_rate_tracker_.AddSamples(sent); 1398 send_rate_tracker_.AddSamples(sent);
1407 } 1399 }
1408 return sent; 1400 return sent;
1409 } 1401 }
1410 1402
1411 } // namespace cricket 1403 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698