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