1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2019 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef P2P_BASE_BASIC_ICE_CONTROLLER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define P2P_BASE_BASIC_ICE_CONTROLLER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <algorithm> 15*d9f75844SAndroid Build Coastguard Worker #include <map> 16*d9f75844SAndroid Build Coastguard Worker #include <set> 17*d9f75844SAndroid Build Coastguard Worker #include <utility> 18*d9f75844SAndroid Build Coastguard Worker #include <vector> 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/ice_controller_factory_interface.h" 21*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/ice_controller_interface.h" 22*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/p2p_transport_channel.h" 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker namespace cricket { 25*d9f75844SAndroid Build Coastguard Worker 26*d9f75844SAndroid Build Coastguard Worker class BasicIceController : public IceControllerInterface { 27*d9f75844SAndroid Build Coastguard Worker public: 28*d9f75844SAndroid Build Coastguard Worker explicit BasicIceController(const IceControllerFactoryArgs& args); 29*d9f75844SAndroid Build Coastguard Worker virtual ~BasicIceController(); 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker void SetIceConfig(const IceConfig& config) override; 32*d9f75844SAndroid Build Coastguard Worker void SetSelectedConnection(const Connection* selected_connection) override; 33*d9f75844SAndroid Build Coastguard Worker void AddConnection(const Connection* connection) override; 34*d9f75844SAndroid Build Coastguard Worker void OnConnectionDestroyed(const Connection* connection) override; connections()35*d9f75844SAndroid Build Coastguard Worker rtc::ArrayView<const Connection*> connections() const override { 36*d9f75844SAndroid Build Coastguard Worker return rtc::ArrayView<const Connection*>( 37*d9f75844SAndroid Build Coastguard Worker const_cast<const Connection**>(connections_.data()), 38*d9f75844SAndroid Build Coastguard Worker connections_.size()); 39*d9f75844SAndroid Build Coastguard Worker } 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker bool HasPingableConnection() const override; 42*d9f75844SAndroid Build Coastguard Worker 43*d9f75844SAndroid Build Coastguard Worker PingResult SelectConnectionToPing(int64_t last_ping_sent_ms) override; 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard Worker bool GetUseCandidateAttr(const Connection* conn, 46*d9f75844SAndroid Build Coastguard Worker NominationMode mode, 47*d9f75844SAndroid Build Coastguard Worker IceMode remote_ice_mode) const override; 48*d9f75844SAndroid Build Coastguard Worker 49*d9f75844SAndroid Build Coastguard Worker SwitchResult ShouldSwitchConnection(IceSwitchReason reason, 50*d9f75844SAndroid Build Coastguard Worker const Connection* connection) override; 51*d9f75844SAndroid Build Coastguard Worker SwitchResult SortAndSwitchConnection(IceSwitchReason reason) override; 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Worker std::vector<const Connection*> PruneConnections() override; 54*d9f75844SAndroid Build Coastguard Worker 55*d9f75844SAndroid Build Coastguard Worker // These methods are only for tests. 56*d9f75844SAndroid Build Coastguard Worker const Connection* FindNextPingableConnection() override; 57*d9f75844SAndroid Build Coastguard Worker void MarkConnectionPinged(const Connection* conn) override; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker private: 60*d9f75844SAndroid Build Coastguard Worker // A transport channel is weak if the current best connection is either 61*d9f75844SAndroid Build Coastguard Worker // not receiving or not writable, or if there is no best connection at all. weak()62*d9f75844SAndroid Build Coastguard Worker bool weak() const { 63*d9f75844SAndroid Build Coastguard Worker return !selected_connection_ || selected_connection_->weak(); 64*d9f75844SAndroid Build Coastguard Worker } 65*d9f75844SAndroid Build Coastguard Worker weak_ping_interval()66*d9f75844SAndroid Build Coastguard Worker int weak_ping_interval() const { 67*d9f75844SAndroid Build Coastguard Worker return std::max(config_.ice_check_interval_weak_connectivity_or_default(), 68*d9f75844SAndroid Build Coastguard Worker config_.ice_check_min_interval_or_default()); 69*d9f75844SAndroid Build Coastguard Worker } 70*d9f75844SAndroid Build Coastguard Worker strong_ping_interval()71*d9f75844SAndroid Build Coastguard Worker int strong_ping_interval() const { 72*d9f75844SAndroid Build Coastguard Worker return std::max(config_.ice_check_interval_strong_connectivity_or_default(), 73*d9f75844SAndroid Build Coastguard Worker config_.ice_check_min_interval_or_default()); 74*d9f75844SAndroid Build Coastguard Worker } 75*d9f75844SAndroid Build Coastguard Worker check_receiving_interval()76*d9f75844SAndroid Build Coastguard Worker int check_receiving_interval() const { 77*d9f75844SAndroid Build Coastguard Worker return std::max(MIN_CHECK_RECEIVING_INTERVAL, 78*d9f75844SAndroid Build Coastguard Worker config_.receiving_timeout_or_default() / 10); 79*d9f75844SAndroid Build Coastguard Worker } 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker const Connection* FindOldestConnectionNeedingTriggeredCheck(int64_t now); 82*d9f75844SAndroid Build Coastguard Worker // Between `conn1` and `conn2`, this function returns the one which should 83*d9f75844SAndroid Build Coastguard Worker // be pinged first. 84*d9f75844SAndroid Build Coastguard Worker const Connection* MorePingable(const Connection* conn1, 85*d9f75844SAndroid Build Coastguard Worker const Connection* conn2); 86*d9f75844SAndroid Build Coastguard Worker // Select the connection which is Relay/Relay. If both of them are, 87*d9f75844SAndroid Build Coastguard Worker // UDP relay protocol takes precedence. 88*d9f75844SAndroid Build Coastguard Worker const Connection* MostLikelyToWork(const Connection* conn1, 89*d9f75844SAndroid Build Coastguard Worker const Connection* conn2); 90*d9f75844SAndroid Build Coastguard Worker // Compare the last_ping_sent time and return the one least recently pinged. 91*d9f75844SAndroid Build Coastguard Worker const Connection* LeastRecentlyPinged(const Connection* conn1, 92*d9f75844SAndroid Build Coastguard Worker const Connection* conn2); 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker bool IsPingable(const Connection* conn, int64_t now) const; 95*d9f75844SAndroid Build Coastguard Worker bool IsBackupConnection(const Connection* conn) const; 96*d9f75844SAndroid Build Coastguard Worker // Whether a writable connection is past its ping interval and needs to be 97*d9f75844SAndroid Build Coastguard Worker // pinged again. 98*d9f75844SAndroid Build Coastguard Worker bool WritableConnectionPastPingInterval(const Connection* conn, 99*d9f75844SAndroid Build Coastguard Worker int64_t now) const; 100*d9f75844SAndroid Build Coastguard Worker int CalculateActiveWritablePingInterval(const Connection* conn, 101*d9f75844SAndroid Build Coastguard Worker int64_t now) const; 102*d9f75844SAndroid Build Coastguard Worker 103*d9f75844SAndroid Build Coastguard Worker std::map<const rtc::Network*, const Connection*> GetBestConnectionByNetwork() 104*d9f75844SAndroid Build Coastguard Worker const; 105*d9f75844SAndroid Build Coastguard Worker std::vector<const Connection*> GetBestWritableConnectionPerNetwork() const; 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker bool ReadyToSend(const Connection* connection) const; 108*d9f75844SAndroid Build Coastguard Worker bool PresumedWritable(const Connection* conn) const; 109*d9f75844SAndroid Build Coastguard Worker 110*d9f75844SAndroid Build Coastguard Worker int CompareCandidatePairNetworks( 111*d9f75844SAndroid Build Coastguard Worker const Connection* a, 112*d9f75844SAndroid Build Coastguard Worker const Connection* b, 113*d9f75844SAndroid Build Coastguard Worker absl::optional<rtc::AdapterType> network_preference) const; 114*d9f75844SAndroid Build Coastguard Worker 115*d9f75844SAndroid Build Coastguard Worker // The methods below return a positive value if `a` is preferable to `b`, 116*d9f75844SAndroid Build Coastguard Worker // a negative value if `b` is preferable, and 0 if they're equally preferable. 117*d9f75844SAndroid Build Coastguard Worker // If `receiving_unchanged_threshold` is set, then when `b` is receiving and 118*d9f75844SAndroid Build Coastguard Worker // `a` is not, returns a negative value only if `b` has been in receiving 119*d9f75844SAndroid Build Coastguard Worker // state and `a` has been in not receiving state since 120*d9f75844SAndroid Build Coastguard Worker // `receiving_unchanged_threshold` and sets 121*d9f75844SAndroid Build Coastguard Worker // `missed_receiving_unchanged_threshold` to true otherwise. 122*d9f75844SAndroid Build Coastguard Worker int CompareConnectionStates( 123*d9f75844SAndroid Build Coastguard Worker const Connection* a, 124*d9f75844SAndroid Build Coastguard Worker const Connection* b, 125*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> receiving_unchanged_threshold, 126*d9f75844SAndroid Build Coastguard Worker bool* missed_receiving_unchanged_threshold) const; 127*d9f75844SAndroid Build Coastguard Worker int CompareConnectionCandidates(const Connection* a, 128*d9f75844SAndroid Build Coastguard Worker const Connection* b) const; 129*d9f75844SAndroid Build Coastguard Worker // Compares two connections based on the connection states 130*d9f75844SAndroid Build Coastguard Worker // (writable/receiving/connected), nomination states, last data received time, 131*d9f75844SAndroid Build Coastguard Worker // and static preferences. Does not include latency. Used by both sorting 132*d9f75844SAndroid Build Coastguard Worker // and ShouldSwitchSelectedConnection(). 133*d9f75844SAndroid Build Coastguard Worker // Returns a positive value if `a` is better than `b`. 134*d9f75844SAndroid Build Coastguard Worker int CompareConnections(const Connection* a, 135*d9f75844SAndroid Build Coastguard Worker const Connection* b, 136*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> receiving_unchanged_threshold, 137*d9f75844SAndroid Build Coastguard Worker bool* missed_receiving_unchanged_threshold) const; 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker SwitchResult HandleInitialSelectDampening(IceSwitchReason reason, 140*d9f75844SAndroid Build Coastguard Worker const Connection* new_connection); 141*d9f75844SAndroid Build Coastguard Worker 142*d9f75844SAndroid Build Coastguard Worker std::function<IceTransportState()> ice_transport_state_func_; 143*d9f75844SAndroid Build Coastguard Worker std::function<IceRole()> ice_role_func_; 144*d9f75844SAndroid Build Coastguard Worker std::function<bool(const Connection*)> is_connection_pruned_func_; 145*d9f75844SAndroid Build Coastguard Worker 146*d9f75844SAndroid Build Coastguard Worker IceConfig config_; 147*d9f75844SAndroid Build Coastguard Worker const IceFieldTrials* field_trials_; 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker // `connections_` is a sorted list with the first one always be the 150*d9f75844SAndroid Build Coastguard Worker // `selected_connection_` when it's not nullptr. The combination of 151*d9f75844SAndroid Build Coastguard Worker // `pinged_connections_` and `unpinged_connections_` has the same 152*d9f75844SAndroid Build Coastguard Worker // connections as `connections_`. These 2 sets maintain whether a 153*d9f75844SAndroid Build Coastguard Worker // connection should be pinged next or not. 154*d9f75844SAndroid Build Coastguard Worker const Connection* selected_connection_ = nullptr; 155*d9f75844SAndroid Build Coastguard Worker std::vector<const Connection*> connections_; 156*d9f75844SAndroid Build Coastguard Worker std::set<const Connection*> pinged_connections_; 157*d9f75844SAndroid Build Coastguard Worker std::set<const Connection*> unpinged_connections_; 158*d9f75844SAndroid Build Coastguard Worker 159*d9f75844SAndroid Build Coastguard Worker // Timestamp for when we got the first selectable connection. 160*d9f75844SAndroid Build Coastguard Worker int64_t initial_select_timestamp_ms_ = 0; 161*d9f75844SAndroid Build Coastguard Worker }; 162*d9f75844SAndroid Build Coastguard Worker 163*d9f75844SAndroid Build Coastguard Worker } // namespace cricket 164*d9f75844SAndroid Build Coastguard Worker 165*d9f75844SAndroid Build Coastguard Worker #endif // P2P_BASE_BASIC_ICE_CONTROLLER_H_ 166