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 
18 #include "p2p/base/connection.h"
19 #include "p2p/base/ice_transport_internal.h"
20 
21 namespace cricket {
22 
23 struct IceFieldTrials;  // Forward declaration to avoid circular dependency.
24 
25 struct IceControllerEvent {
26   enum Type {
27     REMOTE_CANDIDATE_GENERATION_CHANGE,
28     NETWORK_PREFERENCE_CHANGE,
29     NEW_CONNECTION_FROM_LOCAL_CANDIDATE,
30     NEW_CONNECTION_FROM_REMOTE_CANDIDATE,
31     NEW_CONNECTION_FROM_UNKNOWN_REMOTE_ADDRESS,
32     NOMINATION_ON_CONTROLLED_SIDE,
33     DATA_RECEIVED,
34     CONNECT_STATE_CHANGE,
35     SELECTED_CONNECTION_DESTROYED,
36     // The ICE_CONTROLLER_RECHECK enum value lets an IceController request
37     // P2PTransportChannel to recheck a switch periodically without an event
38     // taking place.
39     ICE_CONTROLLER_RECHECK,
40   };
41 
IceControllerEventIceControllerEvent42   IceControllerEvent(const Type& _type)  // NOLINT: runtime/explicit
43       : type(_type) {}
44   std::string ToString() const;
45 
46   Type type;
47   int recheck_delay_ms = 0;
48 };
49 
50 // Defines the interface for a module that control
51 // - which connection to ping
52 // - which connection to use
53 // - which connection to prune
54 // - which connection to forget learned state on
55 //
56 // The P2PTransportChannel owns (creates and destroys) Connections,
57 // but P2PTransportChannel gives const pointers to the the IceController using
58 // |AddConnection|, i.e the IceController should not call any non-const methods
59 // on a Connection but signal back in the interface if any mutable function
60 // shall be called.
61 //
62 // Current these are limited to:
63 // Connection::Ping               - returned in PingResult
64 // Connection::Prune              - retuned in PruneConnections
65 // Connection::ForgetLearnedState - return in SwitchResult
66 //
67 // The IceController shall keep track of all connections added
68 // (and not destroyed) and give them back using the connections()-function-
69 //
70 // When a Connection gets destroyed
71 // - signals on Connection::SignalDestroyed
72 // - P2PTransportChannel calls IceController::OnConnectionDestroyed
73 class IceControllerInterface {
74  public:
75   // This represents the result of a switch call.
76   struct SwitchResult {
77     // Connection that we should (optionally) switch to.
78     absl::optional<const Connection*> connection;
79 
80     // An optional recheck event for when a Switch() should be attempted again.
81     absl::optional<IceControllerEvent> recheck_event;
82 
83     // A vector with connection to run ForgetLearnedState on.
84     std::vector<const Connection*> connections_to_forget_state_on;
85   };
86 
87   // This represents the result of a call to SelectConnectionToPing.
88   struct PingResult {
PingResultPingResult89     PingResult(const Connection* conn, int _recheck_delay_ms)
90         : connection(conn), recheck_delay_ms(_recheck_delay_ms) {}
91 
92     // Connection that we should (optionally) ping.
93     const absl::optional<const Connection*> connection;
94 
95     // The delay before P2PTransportChannel shall call SelectConnectionToPing()
96     // again.
97     //
98     // Since the IceController determines which connection to ping and
99     // only returns one connection at a time, the recheck_delay_ms does not have
100     // any obvious implication on bitrate for pings. E.g the recheck_delay_ms
101     // will be shorter if there are more connections available.
102     const int recheck_delay_ms = 0;
103   };
104 
105   virtual ~IceControllerInterface() = default;
106 
107   // These setters are called when the state of P2PTransportChannel is mutated.
108   virtual void SetIceConfig(const IceConfig& config) = 0;
109   virtual void SetSelectedConnection(const Connection* selected_connection) = 0;
110   virtual void AddConnection(const Connection* connection) = 0;
111   virtual void OnConnectionDestroyed(const Connection* connection) = 0;
112 
113   // These are all connections that has been added and not destroyed.
114   virtual rtc::ArrayView<const Connection*> connections() const = 0;
115 
116   // Is there a pingable connection ?
117   // This function is used to boot-strap pinging, after this returns true
118   // SelectConnectionToPing() will be called periodically.
119   virtual bool HasPingableConnection() const = 0;
120 
121   // Select a connection to Ping, or nullptr if none.
122   virtual PingResult SelectConnectionToPing(int64_t last_ping_sent_ms) = 0;
123 
124   // Compute the "STUN_ATTR_USE_CANDIDATE" for |conn|.
125   virtual bool GetUseCandidateAttr(const Connection* conn,
126                                    NominationMode mode,
127                                    IceMode remote_ice_mode) const = 0;
128 
129   // These methods is only added to not have to change all unit tests
130   // that simulate pinging by marking a connection pinged.
131   virtual const Connection* FindNextPingableConnection() = 0;
132   virtual void MarkConnectionPinged(const Connection* con) = 0;
133 
134   // Check if we should switch to |connection|.
135   // This method is called for IceControllerEvent's that can switch directly
136   // i.e without resorting.
137   virtual SwitchResult ShouldSwitchConnection(IceControllerEvent reason,
138                                               const Connection* connection) = 0;
139 
140   // Sort connections and check if we should switch.
141   virtual SwitchResult SortAndSwitchConnection(IceControllerEvent reason) = 0;
142 
143   // Prune connections.
144   virtual std::vector<const Connection*> PruneConnections() = 0;
145 };
146 
147 }  // namespace cricket
148 
149 #endif  // P2P_BASE_ICE_CONTROLLER_INTERFACE_H_
150