Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      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
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/p2p/base/p2ptransportchannel.h"
     12 
     13 #include <algorithm>
     14 #include <set>
     15 #include "webrtc/p2p/base/common.h"
     16 #include "webrtc/p2p/base/relayport.h"  // For RELAY_PORT_TYPE.
     17 #include "webrtc/p2p/base/stunport.h"  // For STUN_PORT_TYPE.
     18 #include "webrtc/base/common.h"
     19 #include "webrtc/base/crc32.h"
     20 #include "webrtc/base/logging.h"
     21 #include "webrtc/base/stringencode.h"
     22 #include "webrtc/system_wrappers/include/field_trial.h"
     23 
     24 namespace {
     25 
     26 // messages for queuing up work for ourselves
     27 enum { MSG_SORT = 1, MSG_CHECK_AND_PING };
     28 
     29 // The minimum improvement in RTT that justifies a switch.
     30 static const double kMinImprovement = 10;
     31 
     32 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port,
     33                                          cricket::PortInterface* origin_port) {
     34   if (!origin_port)
     35     return cricket::PortInterface::ORIGIN_MESSAGE;
     36   else if (port == origin_port)
     37     return cricket::PortInterface::ORIGIN_THIS_PORT;
     38   else
     39     return cricket::PortInterface::ORIGIN_OTHER_PORT;
     40 }
     41 
     42 // Compares two connections based only on static information about them.
     43 int CompareConnectionCandidates(cricket::Connection* a,
     44                                 cricket::Connection* b) {
     45   // Compare connection priority. Lower values get sorted last.
     46   if (a->priority() > b->priority())
     47     return 1;
     48   if (a->priority() < b->priority())
     49     return -1;
     50 
     51   // If we're still tied at this point, prefer a younger generation.
     52   return (a->remote_candidate().generation() + a->port()->generation()) -
     53          (b->remote_candidate().generation() + b->port()->generation());
     54 }
     55 
     56 // Compare two connections based on their writing, receiving, and connected
     57 // states.
     58 int CompareConnectionStates(cricket::Connection* a, cricket::Connection* b) {
     59   // Sort based on write-state.  Better states have lower values.
     60   if (a->write_state() < b->write_state())
     61     return 1;
     62   if (a->write_state() > b->write_state())
     63     return -1;
     64 
     65   // We prefer a receiving connection to a non-receiving, higher-priority
     66   // connection when sorting connections and choosing which connection to
     67   // switch to.
     68   if (a->receiving() && !b->receiving())
     69     return 1;
     70   if (!a->receiving() && b->receiving())
     71     return -1;
     72 
     73   // WARNING: Some complexity here about TCP reconnecting.
     74   // When a TCP connection fails because of a TCP socket disconnecting, the
     75   // active side of the connection will attempt to reconnect for 5 seconds while
     76   // pretending to be writable (the connection is not set to the unwritable
     77   // state).  On the passive side, the connection also remains writable even
     78   // though it is disconnected, and a new connection is created when the active
     79   // side connects.  At that point, there are two TCP connections on the passive
     80   // side: 1. the old, disconnected one that is pretending to be writable, and
     81   // 2.  the new, connected one that is maybe not yet writable.  For purposes of
     82   // pruning, pinging, and selecting the best connection, we want to treat the
     83   // new connection as "better" than the old one.  We could add a method called
     84   // something like Connection::ImReallyBadEvenThoughImWritable, but that is
     85   // equivalent to the existing Connection::connected(), which we already have.
     86   // So, in code throughout this file, we'll check whether the connection is
     87   // connected() or not, and if it is not, treat it as "worse" than a connected
     88   // one, even though it's writable.  In the code below, we're doing so to make
     89   // sure we treat a new writable connection as better than an old disconnected
     90   // connection.
     91 
     92   // In the case where we reconnect TCP connections, the original best
     93   // connection is disconnected without changing to WRITE_TIMEOUT. In this case,
     94   // the new connection, when it becomes writable, should have higher priority.
     95   if (a->write_state() == cricket::Connection::STATE_WRITABLE &&
     96       b->write_state() == cricket::Connection::STATE_WRITABLE) {
     97     if (a->connected() && !b->connected()) {
     98       return 1;
     99     }
    100     if (!a->connected() && b->connected()) {
    101       return -1;
    102     }
    103   }
    104   return 0;
    105 }
    106 
    107 int CompareConnections(cricket::Connection* a, cricket::Connection* b) {
    108   int state_cmp = CompareConnectionStates(a, b);
    109   if (state_cmp != 0) {
    110     return state_cmp;
    111   }
    112   // Compare the candidate information.
    113   return CompareConnectionCandidates(a, b);
    114 }
    115 
    116 // Wraps the comparison connection into a less than operator that puts higher
    117 // priority writable connections first.
    118 class ConnectionCompare {
    119  public:
    120   bool operator()(const cricket::Connection *ca,
    121                   const cricket::Connection *cb) {
    122     cricket::Connection* a = const_cast<cricket::Connection*>(ca);
    123     cricket::Connection* b = const_cast<cricket::Connection*>(cb);
    124 
    125     // Compare first on writability and static preferences.
    126     int cmp = CompareConnections(a, b);
    127     if (cmp > 0)
    128       return true;
    129     if (cmp < 0)
    130       return false;
    131 
    132     // Otherwise, sort based on latency estimate.
    133     return a->rtt() < b->rtt();
    134 
    135     // Should we bother checking for the last connection that last received
    136     // data? It would help rendezvous on the connection that is also receiving
    137     // packets.
    138     //
    139     // TODO: Yes we should definitely do this.  The TCP protocol gains
    140     // efficiency by being used bidirectionally, as opposed to two separate
    141     // unidirectional streams.  This test should probably occur before
    142     // comparison of local prefs (assuming combined prefs are the same).  We
    143     // need to be careful though, not to bounce back and forth with both sides
    144     // trying to rendevous with the other.
    145   }
    146 };
    147 
    148 // Determines whether we should switch between two connections, based first on
    149 // connection states, static preferences, and then (if those are equal) on
    150 // latency estimates.
    151 bool ShouldSwitch(cricket::Connection* a_conn,
    152                   cricket::Connection* b_conn,
    153                   cricket::IceRole ice_role) {
    154   if (a_conn == b_conn)
    155     return false;
    156 
    157   if (!a_conn || !b_conn)  // don't think the latter should happen
    158     return true;
    159 
    160   // We prefer to switch to a writable and receiving connection over a
    161   // non-writable or non-receiving connection, even if the latter has
    162   // been nominated by the controlling side.
    163   int state_cmp = CompareConnectionStates(a_conn, b_conn);
    164   if (state_cmp != 0) {
    165     return state_cmp < 0;
    166   }
    167   if (ice_role == cricket::ICEROLE_CONTROLLED && a_conn->nominated()) {
    168     LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status";
    169     return false;
    170   }
    171 
    172   int prefs_cmp = CompareConnectionCandidates(a_conn, b_conn);
    173   if (prefs_cmp != 0) {
    174     return prefs_cmp < 0;
    175   }
    176 
    177   return b_conn->rtt() <= a_conn->rtt() + kMinImprovement;
    178 }
    179 
    180 }  // unnamed namespace
    181 
    182 namespace cricket {
    183 
    184 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
    185 // for pinging.  When the socket is writable, we will use only 1 Kbps because
    186 // we don't want to degrade the quality on a modem.  These numbers should work
    187 // well on a 28.8K modem, which is the slowest connection on which the voice
    188 // quality is reasonable at all.
    189 static const uint32_t PING_PACKET_SIZE = 60 * 8;
    190 // TODO(honghaiz): Change the word DELAY to INTERVAL whenever appropriate.
    191 // STRONG_PING_DELAY (480ms) is applied when the best connection is both
    192 // writable and receiving.
    193 static const uint32_t STRONG_PING_DELAY = 1000 * PING_PACKET_SIZE / 1000;
    194 // WEAK_PING_DELAY (48ms) is applied when the best connection is either not
    195 // writable or not receiving.
    196 const uint32_t WEAK_PING_DELAY = 1000 * PING_PACKET_SIZE / 10000;
    197 
    198 // If the current best connection is both writable and receiving, then we will
    199 // also try hard to make sure it is pinged at this rate (a little less than
    200 // 2 * STRONG_PING_DELAY).
    201 static const uint32_t MAX_CURRENT_STRONG_DELAY = 900;
    202 
    203 static const int MIN_CHECK_RECEIVING_DELAY = 50;  // ms
    204 
    205 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
    206                                          int component,
    207                                          P2PTransport* transport,
    208                                          PortAllocator* allocator)
    209     : TransportChannelImpl(transport_name, component),
    210       transport_(transport),
    211       allocator_(allocator),
    212       worker_thread_(rtc::Thread::Current()),
    213       incoming_only_(false),
    214       error_(0),
    215       best_connection_(NULL),
    216       pending_best_connection_(NULL),
    217       sort_dirty_(false),
    218       remote_ice_mode_(ICEMODE_FULL),
    219       ice_role_(ICEROLE_UNKNOWN),
    220       tiebreaker_(0),
    221       gathering_state_(kIceGatheringNew),
    222       check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5),
    223       receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50),
    224       backup_connection_ping_interval_(0) {
    225   uint32_t weak_ping_delay = ::strtoul(
    226       webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(),
    227       nullptr, 10);
    228   if (weak_ping_delay) {
    229     weak_ping_delay_ =  weak_ping_delay;
    230   }
    231 }
    232 
    233 P2PTransportChannel::~P2PTransportChannel() {
    234   ASSERT(worker_thread_ == rtc::Thread::Current());
    235 
    236   for (size_t i = 0; i < allocator_sessions_.size(); ++i)
    237     delete allocator_sessions_[i];
    238 }
    239 
    240 // Add the allocator session to our list so that we know which sessions
    241 // are still active.
    242 void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) {
    243   ASSERT(worker_thread_ == rtc::Thread::Current());
    244 
    245   session->set_generation(static_cast<uint32_t>(allocator_sessions_.size()));
    246   allocator_sessions_.push_back(session);
    247 
    248   // We now only want to apply new candidates that we receive to the ports
    249   // created by this new session because these are replacing those of the
    250   // previous sessions.
    251   ports_.clear();
    252 
    253   session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady);
    254   session->SignalCandidatesReady.connect(
    255       this, &P2PTransportChannel::OnCandidatesReady);
    256   session->SignalCandidatesAllocationDone.connect(
    257       this, &P2PTransportChannel::OnCandidatesAllocationDone);
    258   session->StartGettingPorts();
    259 }
    260 
    261 void P2PTransportChannel::AddConnection(Connection* connection) {
    262   connections_.push_back(connection);
    263   connection->set_remote_ice_mode(remote_ice_mode_);
    264   connection->set_receiving_timeout(receiving_timeout_);
    265   connection->SignalReadPacket.connect(
    266       this, &P2PTransportChannel::OnReadPacket);
    267   connection->SignalReadyToSend.connect(
    268       this, &P2PTransportChannel::OnReadyToSend);
    269   connection->SignalStateChange.connect(
    270       this, &P2PTransportChannel::OnConnectionStateChange);
    271   connection->SignalDestroyed.connect(
    272       this, &P2PTransportChannel::OnConnectionDestroyed);
    273   connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated);
    274   had_connection_ = true;
    275 }
    276 
    277 void P2PTransportChannel::SetIceRole(IceRole ice_role) {
    278   ASSERT(worker_thread_ == rtc::Thread::Current());
    279   if (ice_role_ != ice_role) {
    280     ice_role_ = ice_role;
    281     for (std::vector<PortInterface *>::iterator it = ports_.begin();
    282          it != ports_.end(); ++it) {
    283       (*it)->SetIceRole(ice_role);
    284     }
    285   }
    286 }
    287 
    288 void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) {
    289   ASSERT(worker_thread_ == rtc::Thread::Current());
    290   if (!ports_.empty()) {
    291     LOG(LS_ERROR)
    292         << "Attempt to change tiebreaker after Port has been allocated.";
    293     return;
    294   }
    295 
    296   tiebreaker_ = tiebreaker;
    297 }
    298 
    299 TransportChannelState P2PTransportChannel::GetState() const {
    300   return state_;
    301 }
    302 
    303 // A channel is considered ICE completed once there is at most one active
    304 // connection per network and at least one active connection.
    305 TransportChannelState P2PTransportChannel::ComputeState() const {
    306   if (!had_connection_) {
    307     return TransportChannelState::STATE_INIT;
    308   }
    309 
    310   std::vector<Connection*> active_connections;
    311   for (Connection* connection : connections_) {
    312     if (connection->active()) {
    313       active_connections.push_back(connection);
    314     }
    315   }
    316   if (active_connections.empty()) {
    317     return TransportChannelState::STATE_FAILED;
    318   }
    319 
    320   std::set<rtc::Network*> networks;
    321   for (Connection* connection : active_connections) {
    322     rtc::Network* network = connection->port()->Network();
    323     if (networks.find(network) == networks.end()) {
    324       networks.insert(network);
    325     } else {
    326       LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as "
    327                               << network->ToString()
    328                               << " has more than 1 connection.";
    329       return TransportChannelState::STATE_CONNECTING;
    330     }
    331   }
    332 
    333   LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel.";
    334   return TransportChannelState::STATE_COMPLETED;
    335 }
    336 
    337 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag,
    338                                             const std::string& ice_pwd) {
    339   ASSERT(worker_thread_ == rtc::Thread::Current());
    340   ice_ufrag_ = ice_ufrag;
    341   ice_pwd_ = ice_pwd;
    342   // Note: Candidate gathering will restart when MaybeStartGathering is next
    343   // called.
    344 }
    345 
    346 void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag,
    347                                                   const std::string& ice_pwd) {
    348   ASSERT(worker_thread_ == rtc::Thread::Current());
    349   IceParameters* current_ice = remote_ice();
    350   IceParameters new_ice(ice_ufrag, ice_pwd);
    351   if (!current_ice || *current_ice != new_ice) {
    352     // Keep the ICE credentials so that newer connections
    353     // are prioritized over the older ones.
    354     remote_ice_parameters_.push_back(new_ice);
    355   }
    356 
    357   // Update the pwd of remote candidate if needed.
    358   for (RemoteCandidate& candidate : remote_candidates_) {
    359     if (candidate.username() == ice_ufrag && candidate.password().empty()) {
    360       candidate.set_password(ice_pwd);
    361     }
    362   }
    363   // We need to update the credentials for any peer reflexive candidates.
    364   for (Connection* conn : connections_) {
    365     conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd);
    366   }
    367 }
    368 
    369 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
    370   remote_ice_mode_ = mode;
    371 }
    372 
    373 void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
    374   gather_continually_ = config.gather_continually;
    375   LOG(LS_INFO) << "Set gather_continually to " << gather_continually_;
    376 
    377   if (config.backup_connection_ping_interval >= 0 &&
    378       backup_connection_ping_interval_ !=
    379           config.backup_connection_ping_interval) {
    380     backup_connection_ping_interval_ = config.backup_connection_ping_interval;
    381     LOG(LS_INFO) << "Set backup connection ping interval to "
    382                  << backup_connection_ping_interval_ << " milliseconds.";
    383   }
    384 
    385   if (config.receiving_timeout_ms >= 0 &&
    386       receiving_timeout_ != config.receiving_timeout_ms) {
    387     receiving_timeout_ = config.receiving_timeout_ms;
    388     check_receiving_delay_ =
    389         std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10);
    390 
    391     for (Connection* connection : connections_) {
    392       connection->set_receiving_timeout(receiving_timeout_);
    393     }
    394     LOG(LS_INFO) << "Set ICE receiving timeout to " << receiving_timeout_
    395                  << " milliseconds";
    396   }
    397 }
    398 
    399 // Go into the state of processing candidates, and running in general
    400 void P2PTransportChannel::Connect() {
    401   ASSERT(worker_thread_ == rtc::Thread::Current());
    402   if (ice_ufrag_.empty() || ice_pwd_.empty()) {
    403     ASSERT(false);
    404     LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
    405                   << "ice_pwd_ are not set.";
    406     return;
    407   }
    408 
    409   // Start checking and pinging as the ports come in.
    410   thread()->Post(this, MSG_CHECK_AND_PING);
    411 }
    412 
    413 void P2PTransportChannel::MaybeStartGathering() {
    414   // Start gathering if we never started before, or if an ICE restart occurred.
    415   if (allocator_sessions_.empty() ||
    416       IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(),
    417                             allocator_sessions_.back()->ice_pwd(), ice_ufrag_,
    418                             ice_pwd_)) {
    419     if (gathering_state_ != kIceGatheringGathering) {
    420       gathering_state_ = kIceGatheringGathering;
    421       SignalGatheringState(this);
    422     }
    423     // Time for a new allocator
    424     AddAllocatorSession(allocator_->CreateSession(
    425         SessionId(), transport_name(), component(), ice_ufrag_, ice_pwd_));
    426   }
    427 }
    428 
    429 // A new port is available, attempt to make connections for it
    430 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
    431                                       PortInterface* port) {
    432   ASSERT(worker_thread_ == rtc::Thread::Current());
    433 
    434   // Set in-effect options on the new port
    435   for (OptionMap::const_iterator it = options_.begin();
    436        it != options_.end();
    437        ++it) {
    438     int val = port->SetOption(it->first, it->second);
    439     if (val < 0) {
    440       LOG_J(LS_WARNING, port) << "SetOption(" << it->first
    441                               << ", " << it->second
    442                               << ") failed: " << port->GetError();
    443     }
    444   }
    445 
    446   // Remember the ports and candidates, and signal that candidates are ready.
    447   // The session will handle this, and send an initiate/accept/modify message
    448   // if one is pending.
    449 
    450   port->SetIceRole(ice_role_);
    451   port->SetIceTiebreaker(tiebreaker_);
    452   ports_.push_back(port);
    453   port->SignalUnknownAddress.connect(
    454       this, &P2PTransportChannel::OnUnknownAddress);
    455   port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
    456   port->SignalRoleConflict.connect(
    457       this, &P2PTransportChannel::OnRoleConflict);
    458   port->SignalSentPacket.connect(this, &P2PTransportChannel::OnSentPacket);
    459 
    460   // Attempt to create a connection from this new port to all of the remote
    461   // candidates that we were given so far.
    462 
    463   std::vector<RemoteCandidate>::iterator iter;
    464   for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
    465        ++iter) {
    466     CreateConnection(port, *iter, iter->origin_port());
    467   }
    468 
    469   SortConnections();
    470 }
    471 
    472 // A new candidate is available, let listeners know
    473 void P2PTransportChannel::OnCandidatesReady(
    474     PortAllocatorSession* session,
    475     const std::vector<Candidate>& candidates) {
    476   ASSERT(worker_thread_ == rtc::Thread::Current());
    477   for (size_t i = 0; i < candidates.size(); ++i) {
    478     SignalCandidateGathered(this, candidates[i]);
    479   }
    480 }
    481 
    482 void P2PTransportChannel::OnCandidatesAllocationDone(
    483     PortAllocatorSession* session) {
    484   ASSERT(worker_thread_ == rtc::Thread::Current());
    485   gathering_state_ = kIceGatheringComplete;
    486   LOG(LS_INFO) << "P2PTransportChannel: " << transport_name() << ", component "
    487                << component() << " gathering complete";
    488   SignalGatheringState(this);
    489 }
    490 
    491 // Handle stun packets
    492 void P2PTransportChannel::OnUnknownAddress(
    493     PortInterface* port,
    494     const rtc::SocketAddress& address, ProtocolType proto,
    495     IceMessage* stun_msg, const std::string &remote_username,
    496     bool port_muxed) {
    497   ASSERT(worker_thread_ == rtc::Thread::Current());
    498 
    499   // Port has received a valid stun packet from an address that no Connection
    500   // is currently available for. See if we already have a candidate with the
    501   // address. If it isn't we need to create new candidate for it.
    502 
    503   // Determine if the remote candidates use shared ufrag.
    504   bool ufrag_per_port = false;
    505   std::vector<RemoteCandidate>::iterator it;
    506   if (remote_candidates_.size() > 0) {
    507     it = remote_candidates_.begin();
    508     std::string username = it->username();
    509     for (; it != remote_candidates_.end(); ++it) {
    510       if (it->username() != username) {
    511         ufrag_per_port = true;
    512         break;
    513       }
    514     }
    515   }
    516 
    517   const Candidate* candidate = NULL;
    518   std::string remote_password;
    519   for (it = remote_candidates_.begin(); it != remote_candidates_.end(); ++it) {
    520     if (it->username() == remote_username) {
    521       remote_password = it->password();
    522       if (ufrag_per_port ||
    523           (it->address() == address &&
    524            it->protocol() == ProtoToString(proto))) {
    525         candidate = &(*it);
    526         break;
    527       }
    528       // We don't want to break here because we may find a match of the address
    529       // later.
    530     }
    531   }
    532 
    533   uint32_t remote_generation = 0;
    534   // The STUN binding request may arrive after setRemoteDescription and before
    535   // adding remote candidate, so we need to set the password to the shared
    536   // password if the user name matches.
    537   if (remote_password.empty()) {
    538     const IceParameters* ice_param =
    539         FindRemoteIceFromUfrag(remote_username, &remote_generation);
    540     // Note: if not found, the remote_generation will still be 0.
    541     if (ice_param != nullptr) {
    542       remote_password = ice_param->pwd;
    543     }
    544   }
    545 
    546   Candidate remote_candidate;
    547   bool remote_candidate_is_new = (candidate == nullptr);
    548   if (!remote_candidate_is_new) {
    549     remote_candidate = *candidate;
    550     if (ufrag_per_port) {
    551       remote_candidate.set_address(address);
    552     }
    553   } else {
    554     // Create a new candidate with this address.
    555     int remote_candidate_priority;
    556 
    557     // The priority of the candidate is set to the PRIORITY attribute
    558     // from the request.
    559     const StunUInt32Attribute* priority_attr =
    560         stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
    561     if (!priority_attr) {
    562       LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
    563                       << "No STUN_ATTR_PRIORITY found in the "
    564                       << "stun request message";
    565       port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_BAD_REQUEST,
    566                                      STUN_ERROR_REASON_BAD_REQUEST);
    567       return;
    568     }
    569     remote_candidate_priority = priority_attr->value();
    570 
    571     // RFC 5245
    572     // If the source transport address of the request does not match any
    573     // existing remote candidates, it represents a new peer reflexive remote
    574     // candidate.
    575     remote_candidate = Candidate(component(), ProtoToString(proto), address, 0,
    576                                  remote_username, remote_password,
    577                                  PRFLX_PORT_TYPE, remote_generation, "");
    578 
    579     // From RFC 5245, section-7.2.1.3:
    580     // The foundation of the candidate is set to an arbitrary value, different
    581     // from the foundation for all other remote candidates.
    582     remote_candidate.set_foundation(
    583         rtc::ToString<uint32_t>(rtc::ComputeCrc32(remote_candidate.id())));
    584 
    585     remote_candidate.set_priority(remote_candidate_priority);
    586   }
    587 
    588   // RFC5245, the agent constructs a pair whose local candidate is equal to
    589   // the transport address on which the STUN request was received, and a
    590   // remote candidate equal to the source transport address where the
    591   // request came from.
    592 
    593   // There shouldn't be an existing connection with this remote address.
    594   // When ports are muxed, this channel might get multiple unknown address
    595   // signals. In that case if the connection is already exists, we should
    596   // simply ignore the signal otherwise send server error.
    597   if (port->GetConnection(remote_candidate.address())) {
    598     if (port_muxed) {
    599       LOG(LS_INFO) << "Connection already exists for peer reflexive "
    600                    << "candidate: " << remote_candidate.ToString();
    601       return;
    602     } else {
    603       ASSERT(false);
    604       port->SendBindingErrorResponse(stun_msg, address,
    605                                      STUN_ERROR_SERVER_ERROR,
    606                                      STUN_ERROR_REASON_SERVER_ERROR);
    607       return;
    608     }
    609   }
    610 
    611   Connection* connection = port->CreateConnection(
    612       remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
    613   if (!connection) {
    614     ASSERT(false);
    615     port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
    616                                    STUN_ERROR_REASON_SERVER_ERROR);
    617     return;
    618   }
    619 
    620   LOG(LS_INFO) << "Adding connection from "
    621                << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
    622                << " candidate: " << remote_candidate.ToString();
    623   AddConnection(connection);
    624   connection->HandleBindingRequest(stun_msg);
    625 
    626   // Update the list of connections since we just added another.  We do this
    627   // after sending the response since it could (in principle) delete the
    628   // connection in question.
    629   SortConnections();
    630 }
    631 
    632 void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
    633   SignalRoleConflict(this);  // STUN ping will be sent when SetRole is called
    634                              // from Transport.
    635 }
    636 
    637 const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag(
    638     const std::string& ufrag,
    639     uint32_t* generation) {
    640   const auto& params = remote_ice_parameters_;
    641   auto it = std::find_if(
    642       params.rbegin(), params.rend(),
    643       [ufrag](const IceParameters& param) { return param.ufrag == ufrag; });
    644   if (it == params.rend()) {
    645     // Not found.
    646     return nullptr;
    647   }
    648   *generation = params.rend() - it - 1;
    649   return &(*it);
    650 }
    651 
    652 void P2PTransportChannel::OnNominated(Connection* conn) {
    653   ASSERT(worker_thread_ == rtc::Thread::Current());
    654   ASSERT(ice_role_ == ICEROLE_CONTROLLED);
    655 
    656   if (conn->write_state() == Connection::STATE_WRITABLE) {
    657     if (best_connection_ != conn) {
    658       pending_best_connection_ = NULL;
    659       LOG(LS_INFO) << "Switching best connection on controlled side: "
    660                    << conn->ToString();
    661       SwitchBestConnectionTo(conn);
    662       // Now we have selected the best connection, time to prune other existing
    663       // connections and update the read/write state of the channel.
    664       RequestSort();
    665     }
    666   } else {
    667     LOG(LS_INFO) << "Not switching the best connection on controlled side yet,"
    668                  << " because it's not writable: " << conn->ToString();
    669     pending_best_connection_ = conn;
    670   }
    671 }
    672 
    673 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) {
    674   ASSERT(worker_thread_ == rtc::Thread::Current());
    675 
    676   uint32_t generation = GetRemoteCandidateGeneration(candidate);
    677   // If a remote candidate with a previous generation arrives, drop it.
    678   if (generation < remote_ice_generation()) {
    679     LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag "
    680                     << candidate.username()
    681                     << " indicates it was for a previous generation.";
    682     return;
    683   }
    684 
    685   Candidate new_remote_candidate(candidate);
    686   new_remote_candidate.set_generation(generation);
    687   // ICE candidates don't need to have username and password set, but
    688   // the code below this (specifically, ConnectionRequest::Prepare in
    689   // port.cc) uses the remote candidates's username.  So, we set it
    690   // here.
    691   if (remote_ice()) {
    692     if (candidate.username().empty()) {
    693       new_remote_candidate.set_username(remote_ice()->ufrag);
    694     }
    695     if (new_remote_candidate.username() == remote_ice()->ufrag) {
    696       if (candidate.password().empty()) {
    697         new_remote_candidate.set_password(remote_ice()->pwd);
    698       }
    699     } else {
    700       // The candidate belongs to the next generation. Its pwd will be set
    701       // when the new remote ICE credentials arrive.
    702       LOG(LS_WARNING) << "A remote candidate arrives with an unknown ufrag: "
    703                       << candidate.username();
    704     }
    705   }
    706 
    707   // Create connections to this remote candidate.
    708   CreateConnections(new_remote_candidate, NULL);
    709 
    710   // Resort the connections list, which may have new elements.
    711   SortConnections();
    712 }
    713 
    714 // Creates connections from all of the ports that we care about to the given
    715 // remote candidate.  The return value is true if we created a connection from
    716 // the origin port.
    717 bool P2PTransportChannel::CreateConnections(const Candidate& remote_candidate,
    718                                             PortInterface* origin_port) {
    719   ASSERT(worker_thread_ == rtc::Thread::Current());
    720 
    721   // If we've already seen the new remote candidate (in the current candidate
    722   // generation), then we shouldn't try creating connections for it.
    723   // We either already have a connection for it, or we previously created one
    724   // and then later pruned it. If we don't return, the channel will again
    725   // re-create any connections that were previously pruned, which will then
    726   // immediately be re-pruned, churning the network for no purpose.
    727   // This only applies to candidates received over signaling (i.e. origin_port
    728   // is NULL).
    729   if (!origin_port && IsDuplicateRemoteCandidate(remote_candidate)) {
    730     // return true to indicate success, without creating any new connections.
    731     return true;
    732   }
    733 
    734   // Add a new connection for this candidate to every port that allows such a
    735   // connection (i.e., if they have compatible protocols) and that does not
    736   // already have a connection to an equivalent candidate.  We must be careful
    737   // to make sure that the origin port is included, even if it was pruned,
    738   // since that may be the only port that can create this connection.
    739   bool created = false;
    740   std::vector<PortInterface *>::reverse_iterator it;
    741   for (it = ports_.rbegin(); it != ports_.rend(); ++it) {
    742     if (CreateConnection(*it, remote_candidate, origin_port)) {
    743       if (*it == origin_port)
    744         created = true;
    745     }
    746   }
    747 
    748   if ((origin_port != NULL) &&
    749       std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) {
    750     if (CreateConnection(origin_port, remote_candidate, origin_port))
    751       created = true;
    752   }
    753 
    754   // Remember this remote candidate so that we can add it to future ports.
    755   RememberRemoteCandidate(remote_candidate, origin_port);
    756 
    757   return created;
    758 }
    759 
    760 // Setup a connection object for the local and remote candidate combination.
    761 // And then listen to connection object for changes.
    762 bool P2PTransportChannel::CreateConnection(PortInterface* port,
    763                                            const Candidate& remote_candidate,
    764                                            PortInterface* origin_port) {
    765   if (!port->SupportsProtocol(remote_candidate.protocol())) {
    766     return false;
    767   }
    768   // Look for an existing connection with this remote address.  If one is not
    769   // found, then we can create a new connection for this address.
    770   Connection* connection = port->GetConnection(remote_candidate.address());
    771   if (connection != NULL) {
    772     connection->MaybeUpdatePeerReflexiveCandidate(remote_candidate);
    773 
    774     // It is not legal to try to change any of the parameters of an existing
    775     // connection; however, the other side can send a duplicate candidate.
    776     if (!remote_candidate.IsEquivalent(connection->remote_candidate())) {
    777       LOG(INFO) << "Attempt to change a remote candidate."
    778                 << " Existing remote candidate: "
    779                 << connection->remote_candidate().ToString()
    780                 << "New remote candidate: "
    781                 << remote_candidate.ToString();
    782       return false;
    783     }
    784   } else {
    785     PortInterface::CandidateOrigin origin = GetOrigin(port, origin_port);
    786 
    787     // Don't create connection if this is a candidate we received in a
    788     // message and we are not allowed to make outgoing connections.
    789     if (origin == cricket::PortInterface::ORIGIN_MESSAGE && incoming_only_)
    790       return false;
    791 
    792     connection = port->CreateConnection(remote_candidate, origin);
    793     if (!connection)
    794       return false;
    795 
    796     AddConnection(connection);
    797 
    798     LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", ("
    799                          << connections_.size() << " total)";
    800   }
    801 
    802   return true;
    803 }
    804 
    805 bool P2PTransportChannel::FindConnection(
    806     cricket::Connection* connection) const {
    807   std::vector<Connection*>::const_iterator citer =
    808       std::find(connections_.begin(), connections_.end(), connection);
    809   return citer != connections_.end();
    810 }
    811 
    812 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration(
    813     const Candidate& candidate) {
    814   // If the candidate has a ufrag, use it to find the generation.
    815   if (!candidate.username().empty()) {
    816     uint32_t generation = 0;
    817     if (!FindRemoteIceFromUfrag(candidate.username(), &generation)) {
    818       // If the ufrag is not found, assume the next/future generation.
    819       generation = static_cast<uint32_t>(remote_ice_parameters_.size());
    820     }
    821     return generation;
    822   }
    823   // If candidate generation is set, use that.
    824   if (candidate.generation() > 0) {
    825     return candidate.generation();
    826   }
    827   // Otherwise, assume the generation from remote ice parameters.
    828   return remote_ice_generation();
    829 }
    830 
    831 // Check if remote candidate is already cached.
    832 bool P2PTransportChannel::IsDuplicateRemoteCandidate(
    833     const Candidate& candidate) {
    834   for (size_t i = 0; i < remote_candidates_.size(); ++i) {
    835     if (remote_candidates_[i].IsEquivalent(candidate)) {
    836       return true;
    837     }
    838   }
    839   return false;
    840 }
    841 
    842 // Maintain our remote candidate list, adding this new remote one.
    843 void P2PTransportChannel::RememberRemoteCandidate(
    844     const Candidate& remote_candidate, PortInterface* origin_port) {
    845   // Remove any candidates whose generation is older than this one.  The
    846   // presence of a new generation indicates that the old ones are not useful.
    847   size_t i = 0;
    848   while (i < remote_candidates_.size()) {
    849     if (remote_candidates_[i].generation() < remote_candidate.generation()) {
    850       LOG(INFO) << "Pruning candidate from old generation: "
    851                 << remote_candidates_[i].address().ToSensitiveString();
    852       remote_candidates_.erase(remote_candidates_.begin() + i);
    853     } else {
    854       i += 1;
    855     }
    856   }
    857 
    858   // Make sure this candidate is not a duplicate.
    859   if (IsDuplicateRemoteCandidate(remote_candidate)) {
    860     LOG(INFO) << "Duplicate candidate: " << remote_candidate.ToString();
    861     return;
    862   }
    863 
    864   // Try this candidate for all future ports.
    865   remote_candidates_.push_back(RemoteCandidate(remote_candidate, origin_port));
    866 }
    867 
    868 // Set options on ourselves is simply setting options on all of our available
    869 // port objects.
    870 int P2PTransportChannel::SetOption(rtc::Socket::Option opt, int value) {
    871   ASSERT(worker_thread_ == rtc::Thread::Current());
    872   OptionMap::iterator it = options_.find(opt);
    873   if (it == options_.end()) {
    874     options_.insert(std::make_pair(opt, value));
    875   } else if (it->second == value) {
    876     return 0;
    877   } else {
    878     it->second = value;
    879   }
    880 
    881   for (size_t i = 0; i < ports_.size(); ++i) {
    882     int val = ports_[i]->SetOption(opt, value);
    883     if (val < 0) {
    884       // Because this also occurs deferred, probably no point in reporting an
    885       // error
    886       LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: "
    887                    << ports_[i]->GetError();
    888     }
    889   }
    890   return 0;
    891 }
    892 
    893 bool P2PTransportChannel::GetOption(rtc::Socket::Option opt, int* value) {
    894   ASSERT(worker_thread_ == rtc::Thread::Current());
    895 
    896   const auto& found = options_.find(opt);
    897   if (found == options_.end()) {
    898     return false;
    899   }
    900   *value = found->second;
    901   return true;
    902 }
    903 
    904 // Send data to the other side, using our best connection.
    905 int P2PTransportChannel::SendPacket(const char *data, size_t len,
    906                                     const rtc::PacketOptions& options,
    907                                     int flags) {
    908   ASSERT(worker_thread_ == rtc::Thread::Current());
    909   if (flags != 0) {
    910     error_ = EINVAL;
    911     return -1;
    912   }
    913   if (best_connection_ == NULL) {
    914     error_ = EWOULDBLOCK;
    915     return -1;
    916   }
    917 
    918   int sent = best_connection_->Send(data, len, options);
    919   if (sent <= 0) {
    920     ASSERT(sent < 0);
    921     error_ = best_connection_->GetError();
    922   }
    923   return sent;
    924 }
    925 
    926 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
    927   ASSERT(worker_thread_ == rtc::Thread::Current());
    928   // Gather connection infos.
    929   infos->clear();
    930 
    931   std::vector<Connection *>::const_iterator it;
    932   for (Connection* connection : connections_) {
    933     ConnectionInfo info;
    934     info.best_connection = (best_connection_ == connection);
    935     info.receiving = connection->receiving();
    936     info.writable =
    937         (connection->write_state() == Connection::STATE_WRITABLE);
    938     info.timeout =
    939         (connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
    940     info.new_connection = !connection->reported();
    941     connection->set_reported(true);
    942     info.rtt = connection->rtt();
    943     info.sent_total_bytes = connection->sent_total_bytes();
    944     info.sent_bytes_second = connection->sent_bytes_second();
    945     info.sent_discarded_packets = connection->sent_discarded_packets();
    946     info.sent_total_packets = connection->sent_total_packets();
    947     info.recv_total_bytes = connection->recv_total_bytes();
    948     info.recv_bytes_second = connection->recv_bytes_second();
    949     info.local_candidate = connection->local_candidate();
    950     info.remote_candidate = connection->remote_candidate();
    951     info.key = connection;
    952     infos->push_back(info);
    953   }
    954 
    955   return true;
    956 }
    957 
    958 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const {
    959   OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP);
    960   if (it == options_.end()) {
    961     return rtc::DSCP_NO_CHANGE;
    962   }
    963   return static_cast<rtc::DiffServCodePoint> (it->second);
    964 }
    965 
    966 // Monitor connection states.
    967 void P2PTransportChannel::UpdateConnectionStates() {
    968   uint32_t now = rtc::Time();
    969 
    970   // We need to copy the list of connections since some may delete themselves
    971   // when we call UpdateState.
    972   for (size_t i = 0; i < connections_.size(); ++i)
    973     connections_[i]->UpdateState(now);
    974 }
    975 
    976 // Prepare for best candidate sorting.
    977 void P2PTransportChannel::RequestSort() {
    978   if (!sort_dirty_) {
    979     worker_thread_->Post(this, MSG_SORT);
    980     sort_dirty_ = true;
    981   }
    982 }
    983 
    984 // Sort the available connections to find the best one.  We also monitor
    985 // the number of available connections and the current state.
    986 void P2PTransportChannel::SortConnections() {
    987   ASSERT(worker_thread_ == rtc::Thread::Current());
    988 
    989   // Make sure the connection states are up-to-date since this affects how they
    990   // will be sorted.
    991   UpdateConnectionStates();
    992 
    993   // Any changes after this point will require a re-sort.
    994   sort_dirty_ = false;
    995 
    996   // Find the best alternative connection by sorting.  It is important to note
    997   // that amongst equal preference, writable connections, this will choose the
    998   // one whose estimated latency is lowest.  So it is the only one that we
    999   // need to consider switching to.
   1000   ConnectionCompare cmp;
   1001   std::stable_sort(connections_.begin(), connections_.end(), cmp);
   1002   LOG(LS_VERBOSE) << "Sorting " << connections_.size()
   1003                   << " available connections:";
   1004   for (size_t i = 0; i < connections_.size(); ++i) {
   1005     LOG(LS_VERBOSE) << connections_[i]->ToString();
   1006   }
   1007 
   1008   Connection* top_connection =
   1009       (connections_.size() > 0) ? connections_[0] : nullptr;
   1010 
   1011   // If necessary, switch to the new choice.
   1012   // Note that |top_connection| doesn't have to be writable to become the best
   1013   // connection although it will have higher priority if it is writable.
   1014   if (ShouldSwitch(best_connection_, top_connection, ice_role_)) {
   1015     LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString();
   1016     SwitchBestConnectionTo(top_connection);
   1017   }
   1018 
   1019   // Controlled side can prune only if the best connection has been nominated.
   1020   // because otherwise it may delete the connection that will be selected by
   1021   // the controlling side.
   1022   if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) {
   1023     PruneConnections();
   1024   }
   1025 
   1026   // Check if all connections are timedout.
   1027   bool all_connections_timedout = true;
   1028   for (size_t i = 0; i < connections_.size(); ++i) {
   1029     if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) {
   1030       all_connections_timedout = false;
   1031       break;
   1032     }
   1033   }
   1034 
   1035   // Now update the writable state of the channel with the information we have
   1036   // so far.
   1037   if (all_connections_timedout) {
   1038     HandleAllTimedOut();
   1039   }
   1040 
   1041   // Update the state of this channel.  This method is called whenever the
   1042   // state of any connection changes, so this is a good place to do this.
   1043   UpdateState();
   1044 }
   1045 
   1046 Connection* P2PTransportChannel::best_nominated_connection() const {
   1047   return (best_connection_ && best_connection_->nominated()) ? best_connection_
   1048                                                              : nullptr;
   1049 }
   1050 
   1051 void P2PTransportChannel::PruneConnections() {
   1052   // We can prune any connection for which there is a connected, writable
   1053   // connection on the same network with better or equal priority.  We leave
   1054   // those with better priority just in case they become writable later (at
   1055   // which point, we would prune out the current best connection).  We leave
   1056   // connections on other networks because they may not be using the same
   1057   // resources and they may represent very distinct paths over which we can
   1058   // switch. If the |premier| connection is not connected, we may be
   1059   // reconnecting a TCP connection and temporarily do not prune connections in
   1060   // this network. See the big comment in CompareConnections.
   1061 
   1062   // Get a list of the networks that we are using.
   1063   std::set<rtc::Network*> networks;
   1064   for (const Connection* conn : connections_) {
   1065     networks.insert(conn->port()->Network());
   1066   }
   1067   for (rtc::Network* network : networks) {
   1068     Connection* premier = GetBestConnectionOnNetwork(network);
   1069     // Do not prune connections if the current best connection is weak on this
   1070     // network. Otherwise, it may delete connections prematurely.
   1071     if (!premier || premier->weak()) {
   1072       continue;
   1073     }
   1074 
   1075     for (Connection* conn : connections_) {
   1076       if ((conn != premier) && (conn->port()->Network() == network) &&
   1077           (CompareConnectionCandidates(premier, conn) >= 0)) {
   1078         conn->Prune();
   1079       }
   1080     }
   1081   }
   1082 }
   1083 
   1084 // Track the best connection, and let listeners know
   1085 void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) {
   1086   // Note: if conn is NULL, the previous best_connection_ has been destroyed,
   1087   // so don't use it.
   1088   Connection* old_best_connection = best_connection_;
   1089   best_connection_ = conn;
   1090   if (best_connection_) {
   1091     if (old_best_connection) {
   1092       LOG_J(LS_INFO, this) << "Previous best connection: "
   1093                            << old_best_connection->ToString();
   1094     }
   1095     LOG_J(LS_INFO, this) << "New best connection: "
   1096                          << best_connection_->ToString();
   1097     SignalRouteChange(this, best_connection_->remote_candidate());
   1098   } else {
   1099     LOG_J(LS_INFO, this) << "No best connection";
   1100   }
   1101 }
   1102 
   1103 // Warning: UpdateState should eventually be called whenever a connection
   1104 // is added, deleted, or the write state of any connection changes so that the
   1105 // transport controller will get the up-to-date channel state. However it
   1106 // should not be called too often; in the case that multiple connection states
   1107 // change, it should be called after all the connection states have changed. For
   1108 // example, we call this at the end of SortConnections.
   1109 void P2PTransportChannel::UpdateState() {
   1110   state_ = ComputeState();
   1111 
   1112   bool writable = best_connection_ && best_connection_->writable();
   1113   set_writable(writable);
   1114 
   1115   bool receiving = false;
   1116   for (const Connection* connection : connections_) {
   1117     if (connection->receiving()) {
   1118       receiving = true;
   1119       break;
   1120     }
   1121   }
   1122   set_receiving(receiving);
   1123 }
   1124 
   1125 void P2PTransportChannel::MaybeStopPortAllocatorSessions() {
   1126   if (!IsGettingPorts()) {
   1127     return;
   1128   }
   1129 
   1130   for (PortAllocatorSession* session : allocator_sessions_) {
   1131     if (!session->IsGettingPorts()) {
   1132       continue;
   1133     }
   1134     // If gathering continually, keep the last session running so that it
   1135     // will gather candidates if the networks change.
   1136     if (gather_continually_ && session == allocator_sessions_.back()) {
   1137       session->ClearGettingPorts();
   1138       break;
   1139     }
   1140     session->StopGettingPorts();
   1141   }
   1142 }
   1143 
   1144 // If all connections timed out, delete them all.
   1145 void P2PTransportChannel::HandleAllTimedOut() {
   1146   for (Connection* connection : connections_) {
   1147     connection->Destroy();
   1148   }
   1149 }
   1150 
   1151 bool P2PTransportChannel::weak() const {
   1152   return !best_connection_ || best_connection_->weak();
   1153 }
   1154 
   1155 // If we have a best connection, return it, otherwise return top one in the
   1156 // list (later we will mark it best).
   1157 Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
   1158     rtc::Network* network) const {
   1159   // If the best connection is on this network, then it wins.
   1160   if (best_connection_ && (best_connection_->port()->Network() == network))
   1161     return best_connection_;
   1162 
   1163   // Otherwise, we return the top-most in sorted order.
   1164   for (size_t i = 0; i < connections_.size(); ++i) {
   1165     if (connections_[i]->port()->Network() == network)
   1166       return connections_[i];
   1167   }
   1168 
   1169   return NULL;
   1170 }
   1171 
   1172 // Handle any queued up requests
   1173 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
   1174   switch (pmsg->message_id) {
   1175     case MSG_SORT:
   1176       OnSort();
   1177       break;
   1178     case MSG_CHECK_AND_PING:
   1179       OnCheckAndPing();
   1180       break;
   1181     default:
   1182       ASSERT(false);
   1183       break;
   1184   }
   1185 }
   1186 
   1187 // Handle queued up sort request
   1188 void P2PTransportChannel::OnSort() {
   1189   // Resort the connections based on the new statistics.
   1190   SortConnections();
   1191 }
   1192 
   1193 // Handle queued up check-and-ping request
   1194 void P2PTransportChannel::OnCheckAndPing() {
   1195   // Make sure the states of the connections are up-to-date (since this affects
   1196   // which ones are pingable).
   1197   UpdateConnectionStates();
   1198   // When the best connection is either not receiving or not writable,
   1199   // switch to weak ping delay.
   1200   int ping_delay = weak() ? weak_ping_delay_ : STRONG_PING_DELAY;
   1201   if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) {
   1202     Connection* conn = FindNextPingableConnection();
   1203     if (conn) {
   1204       PingConnection(conn);
   1205     }
   1206   }
   1207   int check_delay = std::min(ping_delay, check_receiving_delay_);
   1208   thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING);
   1209 }
   1210 
   1211 // A connection is considered a backup connection if the channel state
   1212 // is completed, the connection is not the best connection and it is active.
   1213 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const {
   1214   return state_ == STATE_COMPLETED && conn != best_connection_ &&
   1215          conn->active();
   1216 }
   1217 
   1218 // Is the connection in a state for us to even consider pinging the other side?
   1219 // We consider a connection pingable even if it's not connected because that's
   1220 // how a TCP connection is kicked into reconnecting on the active side.
   1221 bool P2PTransportChannel::IsPingable(Connection* conn, uint32_t now) {
   1222   const Candidate& remote = conn->remote_candidate();
   1223   // We should never get this far with an empty remote ufrag.
   1224   ASSERT(!remote.username().empty());
   1225   if (remote.username().empty() || remote.password().empty()) {
   1226     // If we don't have an ICE ufrag and pwd, there's no way we can ping.
   1227     return false;
   1228   }
   1229 
   1230   // An never connected connection cannot be written to at all, so pinging is
   1231   // out of the question. However, if it has become WRITABLE, it is in the
   1232   // reconnecting state so ping is needed.
   1233   if (!conn->connected() && !conn->writable()) {
   1234     return false;
   1235   }
   1236 
   1237   // If the channel is weakly connected, ping all connections.
   1238   if (weak()) {
   1239     return true;
   1240   }
   1241 
   1242   // Always ping active connections regardless whether the channel is completed
   1243   // or not, but backup connections are pinged at a slower rate.
   1244   if (IsBackupConnection(conn)) {
   1245     return (now >= conn->last_ping_response_received() +
   1246                        backup_connection_ping_interval_);
   1247   }
   1248   return conn->active();
   1249 }
   1250 
   1251 // Returns the next pingable connection to ping.  This will be the oldest
   1252 // pingable connection unless we have a connected, writable connection that is
   1253 // past the maximum acceptable ping delay. When reconnecting a TCP connection,
   1254 // the best connection is disconnected, although still WRITABLE while
   1255 // reconnecting. The newly created connection should be selected as the ping
   1256 // target to become writable instead. See the big comment in CompareConnections.
   1257 Connection* P2PTransportChannel::FindNextPingableConnection() {
   1258   uint32_t now = rtc::Time();
   1259   if (best_connection_ && best_connection_->connected() &&
   1260       best_connection_->writable() &&
   1261       (best_connection_->last_ping_sent() + MAX_CURRENT_STRONG_DELAY <= now)) {
   1262     return best_connection_;
   1263   }
   1264 
   1265   // First, find "triggered checks".  We ping first those connections
   1266   // that have received a ping but have not sent a ping since receiving
   1267   // it (last_received_ping > last_sent_ping).  But we shouldn't do
   1268   // triggered checks if the connection is already writable.
   1269   Connection* oldest_needing_triggered_check = nullptr;
   1270   Connection* oldest = nullptr;
   1271   for (Connection* conn : connections_) {
   1272     if (!IsPingable(conn, now)) {
   1273       continue;
   1274     }
   1275     bool needs_triggered_check =
   1276         (!conn->writable() &&
   1277          conn->last_ping_received() > conn->last_ping_sent());
   1278     if (needs_triggered_check &&
   1279         (!oldest_needing_triggered_check ||
   1280          (conn->last_ping_received() <
   1281           oldest_needing_triggered_check->last_ping_received()))) {
   1282       oldest_needing_triggered_check = conn;
   1283     }
   1284     if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) {
   1285       oldest = conn;
   1286     }
   1287   }
   1288 
   1289   if (oldest_needing_triggered_check) {
   1290     LOG(LS_INFO) << "Selecting connection for triggered check: " <<
   1291         oldest_needing_triggered_check->ToString();
   1292     return oldest_needing_triggered_check;
   1293   }
   1294   return oldest;
   1295 }
   1296 
   1297 // Apart from sending ping from |conn| this method also updates
   1298 // |use_candidate_attr| flag. The criteria to update this flag is
   1299 // explained below.
   1300 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND
   1301 //    a) Channel is in FULL ICE AND
   1302 //      a.1) |conn| is the best connection OR
   1303 //      a.2) there is no best connection OR
   1304 //      a.3) the best connection is unwritable OR
   1305 //      a.4) |conn| has higher priority than best_connection.
   1306 //    b) we're doing LITE ICE AND
   1307 //      b.1) |conn| is the best_connection AND
   1308 //      b.2) |conn| is writable.
   1309 void P2PTransportChannel::PingConnection(Connection* conn) {
   1310   bool use_candidate = false;
   1311   if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
   1312     use_candidate = (conn == best_connection_) || (best_connection_ == NULL) ||
   1313                     (!best_connection_->writable()) ||
   1314                     (conn->priority() > best_connection_->priority());
   1315   } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
   1316     use_candidate = best_connection_->writable();
   1317   }
   1318   conn->set_use_candidate_attr(use_candidate);
   1319   last_ping_sent_ms_ = rtc::Time();
   1320   conn->Ping(last_ping_sent_ms_);
   1321 }
   1322 
   1323 // When a connection's state changes, we need to figure out who to use as
   1324 // the best connection again.  It could have become usable, or become unusable.
   1325 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
   1326   ASSERT(worker_thread_ == rtc::Thread::Current());
   1327 
   1328   // Update the best connection if the state change is from pending best
   1329   // connection and role is controlled.
   1330   if (ice_role_ == ICEROLE_CONTROLLED) {
   1331     if (connection == pending_best_connection_ && connection->writable()) {
   1332       pending_best_connection_ = NULL;
   1333       LOG(LS_INFO) << "Switching best connection on controlled side"
   1334                    << " because it's now writable: " << connection->ToString();
   1335       SwitchBestConnectionTo(connection);
   1336     }
   1337   }
   1338 
   1339   // May stop the allocator session when at least one connection becomes
   1340   // strongly connected after starting to get ports. It is not enough to check
   1341   // that the connection becomes weakly connected because the connection may be
   1342   // changing from (writable, receiving) to (writable, not receiving).
   1343   if (!connection->weak()) {
   1344     MaybeStopPortAllocatorSessions();
   1345   }
   1346 
   1347   // We have to unroll the stack before doing this because we may be changing
   1348   // the state of connections while sorting.
   1349   RequestSort();
   1350 }
   1351 
   1352 // When a connection is removed, edit it out, and then update our best
   1353 // connection.
   1354 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
   1355   ASSERT(worker_thread_ == rtc::Thread::Current());
   1356 
   1357   // Note: the previous best_connection_ may be destroyed by now, so don't
   1358   // use it.
   1359 
   1360   // Remove this connection from the list.
   1361   std::vector<Connection*>::iterator iter =
   1362       std::find(connections_.begin(), connections_.end(), connection);
   1363   ASSERT(iter != connections_.end());
   1364   connections_.erase(iter);
   1365 
   1366   LOG_J(LS_INFO, this) << "Removed connection ("
   1367     << static_cast<int>(connections_.size()) << " remaining)";
   1368 
   1369   if (pending_best_connection_ == connection) {
   1370     pending_best_connection_ = NULL;
   1371   }
   1372 
   1373   // If this is currently the best connection, then we need to pick a new one.
   1374   // The call to SortConnections will pick a new one.  It looks at the current
   1375   // best connection in order to avoid switching between fairly similar ones.
   1376   // Since this connection is no longer an option, we can just set best to NULL
   1377   // and re-choose a best assuming that there was no best connection.
   1378   if (best_connection_ == connection) {
   1379     LOG(LS_INFO) << "Best connection destroyed.  Will choose a new one.";
   1380     SwitchBestConnectionTo(NULL);
   1381     RequestSort();
   1382   }
   1383 
   1384   UpdateState();
   1385   // SignalConnectionRemoved should be called after the channel state is
   1386   // updated because the receiver of the event may access the channel state.
   1387   SignalConnectionRemoved(this);
   1388 }
   1389 
   1390 // When a port is destroyed remove it from our list of ports to use for
   1391 // connection attempts.
   1392 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) {
   1393   ASSERT(worker_thread_ == rtc::Thread::Current());
   1394 
   1395   // Remove this port from the list (if we didn't drop it already).
   1396   std::vector<PortInterface*>::iterator iter =
   1397       std::find(ports_.begin(), ports_.end(), port);
   1398   if (iter != ports_.end())
   1399     ports_.erase(iter);
   1400 
   1401   LOG(INFO) << "Removed port from p2p socket: "
   1402             << static_cast<int>(ports_.size()) << " remaining";
   1403 }
   1404 
   1405 // We data is available, let listeners know
   1406 void P2PTransportChannel::OnReadPacket(Connection* connection,
   1407                                        const char* data,
   1408                                        size_t len,
   1409                                        const rtc::PacketTime& packet_time) {
   1410   ASSERT(worker_thread_ == rtc::Thread::Current());
   1411 
   1412   // Do not deliver, if packet doesn't belong to the correct transport channel.
   1413   if (!FindConnection(connection))
   1414     return;
   1415 
   1416   // Let the client know of an incoming packet
   1417   SignalReadPacket(this, data, len, packet_time, 0);
   1418 
   1419   // May need to switch the sending connection based on the receiving media path
   1420   // if this is the controlled side.
   1421   if (ice_role_ == ICEROLE_CONTROLLED && !best_nominated_connection() &&
   1422       connection->writable() && best_connection_ != connection) {
   1423     SwitchBestConnectionTo(connection);
   1424   }
   1425 }
   1426 
   1427 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) {
   1428   ASSERT(worker_thread_ == rtc::Thread::Current());
   1429 
   1430   SignalSentPacket(this, sent_packet);
   1431 }
   1432 
   1433 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
   1434   if (connection == best_connection_ && writable()) {
   1435     SignalReadyToSend(this);
   1436   }
   1437 }
   1438 
   1439 }  // namespace cricket
   1440