Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 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_ICE_CONTROLLER_INTERFACE_H_ |
| 12 | #define P2P_BASE_ICE_CONTROLLER_INTERFACE_H_ |
| 13 | |
| 14 | #include <string> |
| 15 | #include <utility> |
| 16 | #include <vector> |
| 17 | |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 18 | #include "absl/types/optional.h" |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 19 | #include "p2p/base/connection.h" |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 20 | #include "p2p/base/ice_switch_reason.h" |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 21 | #include "p2p/base/ice_transport_internal.h" |
| 22 | |
| 23 | namespace cricket { |
| 24 | |
| 25 | struct IceFieldTrials; // Forward declaration to avoid circular dependency. |
| 26 | |
| 27 | struct IceControllerEvent { |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 28 | // TODO(bugs.webrtc.org/14125) replace with IceSwitchReason. |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 29 | enum Type { |
| 30 | REMOTE_CANDIDATE_GENERATION_CHANGE, |
| 31 | NETWORK_PREFERENCE_CHANGE, |
| 32 | NEW_CONNECTION_FROM_LOCAL_CANDIDATE, |
| 33 | NEW_CONNECTION_FROM_REMOTE_CANDIDATE, |
| 34 | NEW_CONNECTION_FROM_UNKNOWN_REMOTE_ADDRESS, |
| 35 | NOMINATION_ON_CONTROLLED_SIDE, |
| 36 | DATA_RECEIVED, |
| 37 | CONNECT_STATE_CHANGE, |
Jonas Oreland | b5aa0a8 | 2019-12-03 09:59:11 +0100 | [diff] [blame] | 38 | SELECTED_CONNECTION_DESTROYED, |
| 39 | // The ICE_CONTROLLER_RECHECK enum value lets an IceController request |
| 40 | // P2PTransportChannel to recheck a switch periodically without an event |
| 41 | // taking place. |
| 42 | ICE_CONTROLLER_RECHECK, |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 43 | }; |
| 44 | |
Sameer Vijaykar | 781c12e | 2022-06-02 16:01:12 +0200 | [diff] [blame^] | 45 | [[deprecated("bugs.webrtc.org/14125")]] IceControllerEvent( |
| 46 | const Type& _type) // NOLINT: runtime/explicit |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 47 | : type(_type), reason(FromType(_type)) {} |
| 48 | |
| 49 | IceControllerEvent(IceSwitchReason _reason, int _recheck_delay_ms) |
| 50 | : type(FromIceSwitchReason(_reason)), |
| 51 | reason(_reason), |
| 52 | recheck_delay_ms(_recheck_delay_ms) {} |
| 53 | |
| 54 | static Type FromIceSwitchReason(IceSwitchReason reason); |
| 55 | static IceSwitchReason FromType(Type type); |
| 56 | |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 57 | std::string ToString() const; |
| 58 | |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 59 | // TODO(bugs.webrtc.org/14125) replace usage with IceSwitchReason. |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 60 | Type type; |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 61 | IceSwitchReason reason; |
Jonas Oreland | b5aa0a8 | 2019-12-03 09:59:11 +0100 | [diff] [blame] | 62 | int recheck_delay_ms = 0; |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 63 | }; |
| 64 | |
| 65 | // Defines the interface for a module that control |
| 66 | // - which connection to ping |
| 67 | // - which connection to use |
| 68 | // - which connection to prune |
Jonas Oreland | 49864b7 | 2020-06-05 14:55:35 +0200 | [diff] [blame] | 69 | // - which connection to forget learned state on |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 70 | // |
Jonas Oreland | 49864b7 | 2020-06-05 14:55:35 +0200 | [diff] [blame] | 71 | // The P2PTransportChannel owns (creates and destroys) Connections, |
| 72 | // but P2PTransportChannel gives const pointers to the the IceController using |
Artem Titov | 2dbb4c9 | 2021-07-26 15:12:41 +0200 | [diff] [blame] | 73 | // `AddConnection`, i.e the IceController should not call any non-const methods |
Jonas Oreland | 49864b7 | 2020-06-05 14:55:35 +0200 | [diff] [blame] | 74 | // on a Connection but signal back in the interface if any mutable function |
| 75 | // shall be called. |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 76 | // |
Jonas Oreland | 49864b7 | 2020-06-05 14:55:35 +0200 | [diff] [blame] | 77 | // Current these are limited to: |
| 78 | // Connection::Ping - returned in PingResult |
| 79 | // Connection::Prune - retuned in PruneConnections |
| 80 | // Connection::ForgetLearnedState - return in SwitchResult |
| 81 | // |
| 82 | // The IceController shall keep track of all connections added |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 83 | // (and not destroyed) and give them back using the connections()-function- |
| 84 | // |
| 85 | // When a Connection gets destroyed |
| 86 | // - signals on Connection::SignalDestroyed |
| 87 | // - P2PTransportChannel calls IceController::OnConnectionDestroyed |
| 88 | class IceControllerInterface { |
| 89 | public: |
| 90 | // This represents the result of a switch call. |
| 91 | struct SwitchResult { |
| 92 | // Connection that we should (optionally) switch to. |
| 93 | absl::optional<const Connection*> connection; |
| 94 | |
Jonas Oreland | b5aa0a8 | 2019-12-03 09:59:11 +0100 | [diff] [blame] | 95 | // An optional recheck event for when a Switch() should be attempted again. |
| 96 | absl::optional<IceControllerEvent> recheck_event; |
Jonas Oreland | 49864b7 | 2020-06-05 14:55:35 +0200 | [diff] [blame] | 97 | |
| 98 | // A vector with connection to run ForgetLearnedState on. |
| 99 | std::vector<const Connection*> connections_to_forget_state_on; |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 100 | }; |
| 101 | |
Jonas Oreland | 4333600 | 2020-03-26 20:59:03 +0100 | [diff] [blame] | 102 | // This represents the result of a call to SelectConnectionToPing. |
| 103 | struct PingResult { |
| 104 | PingResult(const Connection* conn, int _recheck_delay_ms) |
Tim Na | 203b549 | 2021-02-05 10:23:53 -0800 | [diff] [blame] | 105 | : connection(conn ? absl::optional<const Connection*>(conn) |
| 106 | : absl::nullopt), |
| 107 | recheck_delay_ms(_recheck_delay_ms) {} |
Jonas Oreland | 4333600 | 2020-03-26 20:59:03 +0100 | [diff] [blame] | 108 | |
Jonas Oreland | 4333600 | 2020-03-26 20:59:03 +0100 | [diff] [blame] | 109 | // Connection that we should (optionally) ping. |
| 110 | const absl::optional<const Connection*> connection; |
| 111 | |
Jonas Oreland | fa097a2 | 2020-03-27 15:12:52 +0100 | [diff] [blame] | 112 | // The delay before P2PTransportChannel shall call SelectConnectionToPing() |
| 113 | // again. |
| 114 | // |
| 115 | // Since the IceController determines which connection to ping and |
| 116 | // only returns one connection at a time, the recheck_delay_ms does not have |
| 117 | // any obvious implication on bitrate for pings. E.g the recheck_delay_ms |
| 118 | // will be shorter if there are more connections available. |
Jonas Oreland | 4333600 | 2020-03-26 20:59:03 +0100 | [diff] [blame] | 119 | const int recheck_delay_ms = 0; |
| 120 | }; |
Jonas Oreland | 2f3c019 | 2020-03-26 12:59:44 +0100 | [diff] [blame] | 121 | |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 122 | virtual ~IceControllerInterface() = default; |
| 123 | |
| 124 | // These setters are called when the state of P2PTransportChannel is mutated. |
| 125 | virtual void SetIceConfig(const IceConfig& config) = 0; |
| 126 | virtual void SetSelectedConnection(const Connection* selected_connection) = 0; |
| 127 | virtual void AddConnection(const Connection* connection) = 0; |
| 128 | virtual void OnConnectionDestroyed(const Connection* connection) = 0; |
| 129 | |
| 130 | // These are all connections that has been added and not destroyed. |
| 131 | virtual rtc::ArrayView<const Connection*> connections() const = 0; |
| 132 | |
| 133 | // Is there a pingable connection ? |
| 134 | // This function is used to boot-strap pinging, after this returns true |
| 135 | // SelectConnectionToPing() will be called periodically. |
| 136 | virtual bool HasPingableConnection() const = 0; |
| 137 | |
| 138 | // Select a connection to Ping, or nullptr if none. |
Jonas Oreland | 2f3c019 | 2020-03-26 12:59:44 +0100 | [diff] [blame] | 139 | virtual PingResult SelectConnectionToPing(int64_t last_ping_sent_ms) = 0; |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 140 | |
Artem Titov | 2dbb4c9 | 2021-07-26 15:12:41 +0200 | [diff] [blame] | 141 | // Compute the "STUN_ATTR_USE_CANDIDATE" for `conn`. |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 142 | virtual bool GetUseCandidateAttr(const Connection* conn, |
| 143 | NominationMode mode, |
| 144 | IceMode remote_ice_mode) const = 0; |
| 145 | |
| 146 | // These methods is only added to not have to change all unit tests |
| 147 | // that simulate pinging by marking a connection pinged. |
| 148 | virtual const Connection* FindNextPingableConnection() = 0; |
| 149 | virtual void MarkConnectionPinged(const Connection* con) = 0; |
| 150 | |
Artem Titov | 2dbb4c9 | 2021-07-26 15:12:41 +0200 | [diff] [blame] | 151 | // Check if we should switch to `connection`. |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 152 | // This method is called for IceSwitchReasons that can switch directly |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 153 | // i.e without resorting. |
Sameer Vijaykar | 781c12e | 2022-06-02 16:01:12 +0200 | [diff] [blame^] | 154 | [[deprecated("bugs.webrtc.org/14125")]] virtual SwitchResult |
| 155 | ShouldSwitchConnection(IceControllerEvent reason, |
| 156 | const Connection* connection) { |
| 157 | return ShouldSwitchConnection(IceControllerEvent::FromType(reason.type), |
| 158 | connection); |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 159 | } |
Sameer Vijaykar | 781c12e | 2022-06-02 16:01:12 +0200 | [diff] [blame^] | 160 | virtual SwitchResult ShouldSwitchConnection(IceSwitchReason reason, |
| 161 | const Connection* connection) = 0; |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 162 | |
| 163 | // Sort connections and check if we should switch. |
Sameer Vijaykar | 781c12e | 2022-06-02 16:01:12 +0200 | [diff] [blame^] | 164 | [[deprecated("bugs.webrtc.org/14125")]] virtual SwitchResult |
| 165 | SortAndSwitchConnection(IceControllerEvent reason) { |
| 166 | return SortAndSwitchConnection(IceControllerEvent::FromType(reason.type)); |
Sameer Vijaykar | 3382c1c | 2022-06-02 11:29:09 +0200 | [diff] [blame] | 167 | } |
Sameer Vijaykar | 781c12e | 2022-06-02 16:01:12 +0200 | [diff] [blame^] | 168 | virtual SwitchResult SortAndSwitchConnection(IceSwitchReason reason) = 0; |
Jonas Oreland | 09c452e | 2019-11-20 09:01:02 +0100 | [diff] [blame] | 169 | |
| 170 | // Prune connections. |
| 171 | virtual std::vector<const Connection*> PruneConnections() = 0; |
| 172 | }; |
| 173 | |
| 174 | } // namespace cricket |
| 175 | |
| 176 | #endif // P2P_BASE_ICE_CONTROLLER_INTERFACE_H_ |