1 /*
2  *  Copyright 2016 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_TRANSPORT_INTERNAL_H_
12 #define P2P_BASE_ICE_TRANSPORT_INTERNAL_H_
13 
14 #include <stdint.h>
15 
16 #include <string>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/candidate.h"
21 #include "api/transport/enums.h"
22 #include "p2p/base/connection.h"
23 #include "p2p/base/packet_transport_internal.h"
24 #include "p2p/base/port.h"
25 #include "p2p/base/transport_description.h"
26 #include "rtc_base/network_constants.h"
27 #include "rtc_base/system/rtc_export.h"
28 #include "rtc_base/third_party/sigslot/sigslot.h"
29 #include "rtc_base/time_utils.h"
30 
31 namespace cricket {
32 
33 struct IceTransportStats {
34   CandidateStatsList candidate_stats_list;
35   ConnectionInfos connection_infos;
36   // Number of times the selected candidate pair has changed
37   // Initially 0 and 1 once the first candidate pair has been selected.
38   // The counter is increase also when "unselecting" a connection.
39   uint32_t selected_candidate_pair_changes = 0;
40 };
41 
42 typedef std::vector<Candidate> Candidates;
43 
44 enum IceConnectionState {
45   kIceConnectionConnecting = 0,
46   kIceConnectionFailed,
47   kIceConnectionConnected,  // Writable, but still checking one or more
48                             // connections
49   kIceConnectionCompleted,
50 };
51 
52 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
53 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
54 // style.
55 enum IceGatheringState {
56   kIceGatheringNew = 0,
57   kIceGatheringGathering,
58   kIceGatheringComplete,
59 };
60 
61 enum ContinualGatheringPolicy {
62   // All port allocator sessions will stop after a writable connection is found.
63   GATHER_ONCE = 0,
64   // The most recent port allocator session will keep on running.
65   GATHER_CONTINUALLY,
66 };
67 
68 // ICE Nomination mode.
69 enum class NominationMode {
70   REGULAR,         // Nominate once per ICE restart (Not implemented yet).
71   AGGRESSIVE,      // Nominate every connection except that it will behave as if
72                    // REGULAR when the remote is an ICE-LITE endpoint.
73   SEMI_AGGRESSIVE  // Our current implementation of the nomination algorithm.
74                    // The details are described in P2PTransportChannel.
75 };
76 
77 // Information about ICE configuration.
78 // TODO(deadbeef): Use absl::optional to represent unset values, instead of
79 // -1.
80 struct IceConfig {
81   // The ICE connection receiving timeout value in milliseconds.
82   absl::optional<int> receiving_timeout;
83   // Time interval in milliseconds to ping a backup connection when the ICE
84   // channel is strongly connected.
85   absl::optional<int> backup_connection_ping_interval;
86 
87   ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
88 
gather_continuallyIceConfig89   bool gather_continually() const {
90     return continual_gathering_policy == GATHER_CONTINUALLY;
91   }
92 
93   // Whether we should prioritize Relay/Relay candidate when nothing
94   // is writable yet.
95   bool prioritize_most_likely_candidate_pairs = false;
96 
97   // Writable connections are pinged at a slower rate once stablized.
98   absl::optional<int> stable_writable_connection_ping_interval;
99 
100   // If set to true, this means the ICE transport should presume TURN-to-TURN
101   // candidate pairs will succeed, even before a binding response is received.
102   bool presume_writable_when_fully_relayed = false;
103 
104   // If true, after the ICE transport type (as the candidate filter used by the
105   // port allocator) is changed such that new types of ICE candidates are
106   // allowed by the new filter, e.g. from CF_RELAY to CF_ALL, candidates that
107   // have been gathered by the ICE transport but filtered out and not signaled
108   // to the upper layers, will be surfaced.
109   bool surface_ice_candidates_on_ice_transport_type_changed = false;
110 
111   // Interval to check on all networks and to perform ICE regathering on any
112   // active network having no connection on it.
113   absl::optional<int> regather_on_failed_networks_interval;
114 
115   // The time period in which we will not switch the selected connection
116   // when a new connection becomes receiving but the selected connection is not
117   // in case that the selected connection may become receiving soon.
118   absl::optional<int> receiving_switching_delay;
119 
120   // TODO(honghaiz): Change the default to regular nomination.
121   // Default nomination mode if the remote does not support renomination.
122   NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
123 
124   // The interval in milliseconds at which ICE checks (STUN pings) will be sent
125   // for a candidate pair when it is both writable and receiving (strong
126   // connectivity). This parameter overrides the default value given by
127   // |STRONG_PING_INTERVAL| in p2ptransport.h if set.
128   absl::optional<int> ice_check_interval_strong_connectivity;
129   // The interval in milliseconds at which ICE checks (STUN pings) will be sent
130   // for a candidate pair when it is either not writable or not receiving (weak
131   // connectivity). This parameter overrides the default value given by
132   // |WEAK_PING_INTERVAL| in p2ptransport.h if set.
133   absl::optional<int> ice_check_interval_weak_connectivity;
134   // ICE checks (STUN pings) will not be sent at higher rate (lower interval)
135   // than this, no matter what other settings there are.
136   // Measure in milliseconds.
137   //
138   // Note that this parameter overrides both the above check intervals for
139   // candidate pairs with strong or weak connectivity, if either of the above
140   // interval is shorter than the min interval.
141   absl::optional<int> ice_check_min_interval;
142   // The min time period for which a candidate pair must wait for response to
143   // connectivity checks before it becomes unwritable. This parameter
144   // overrides the default value given by |CONNECTION_WRITE_CONNECT_TIMEOUT|
145   // in port.h if set, when determining the writability of a candidate pair.
146   absl::optional<int> ice_unwritable_timeout;
147 
148   // The min number of connectivity checks that a candidate pair must sent
149   // without receiving response before it becomes unwritable. This parameter
150   // overrides the default value given by |CONNECTION_WRITE_CONNECT_FAILURES| in
151   // port.h if set, when determining the writability of a candidate pair.
152   absl::optional<int> ice_unwritable_min_checks;
153 
154   // The min time period for which a candidate pair must wait for response to
155   // connectivity checks it becomes inactive. This parameter overrides the
156   // default value given by |CONNECTION_WRITE_TIMEOUT| in port.h if set, when
157   // determining the writability of a candidate pair.
158   absl::optional<int> ice_inactive_timeout;
159 
160   // The interval in milliseconds at which STUN candidates will resend STUN
161   // binding requests to keep NAT bindings open.
162   absl::optional<int> stun_keepalive_interval;
163 
164   absl::optional<rtc::AdapterType> network_preference;
165 
166   IceConfig();
167   IceConfig(int receiving_timeout_ms,
168             int backup_connection_ping_interval,
169             ContinualGatheringPolicy gathering_policy,
170             bool prioritize_most_likely_candidate_pairs,
171             int stable_writable_connection_ping_interval_ms,
172             bool presume_writable_when_fully_relayed,
173             int regather_on_failed_networks_interval_ms,
174             int receiving_switching_delay_ms);
175   ~IceConfig();
176 
177   // Helper getters for parameters with implementation-specific default value.
178   // By convention, parameters with default value are represented by
179   // absl::optional and setting a parameter to null restores its default value.
180   int receiving_timeout_or_default() const;
181   int backup_connection_ping_interval_or_default() const;
182   int stable_writable_connection_ping_interval_or_default() const;
183   int regather_on_failed_networks_interval_or_default() const;
184   int receiving_switching_delay_or_default() const;
185   int ice_check_interval_strong_connectivity_or_default() const;
186   int ice_check_interval_weak_connectivity_or_default() const;
187   int ice_check_min_interval_or_default() const;
188   int ice_unwritable_timeout_or_default() const;
189   int ice_unwritable_min_checks_or_default() const;
190   int ice_inactive_timeout_or_default() const;
191   int stun_keepalive_interval_or_default() const;
192 };
193 
194 // TODO(zhihuang): Replace this with
195 // PeerConnectionInterface::IceConnectionState.
196 enum class IceTransportState {
197   STATE_INIT,
198   STATE_CONNECTING,  // Will enter this state once a connection is created
199   STATE_COMPLETED,
200   STATE_FAILED
201 };
202 
203 // TODO(zhihuang): Remove this once it's no longer used in
204 // remoting/protocol/libjingle_transport_factory.cc
205 enum IceProtocolType {
206   ICEPROTO_RFC5245  // Standard RFC 5245 version of ICE.
207 };
208 
209 // IceTransportInternal is an internal abstract class that does ICE.
210 // Once the public interface is supported,
211 // (https://www.w3.org/TR/webrtc/#rtcicetransport)
212 // the IceTransportInterface will be split from this class.
213 class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal {
214  public:
215   IceTransportInternal();
216   ~IceTransportInternal() override;
217 
218   // TODO(bugs.webrtc.org/9308): Remove GetState once all uses have been
219   // migrated to GetIceTransportState.
220   virtual IceTransportState GetState() const = 0;
221   virtual webrtc::IceTransportState GetIceTransportState() const = 0;
222 
223   virtual int component() const = 0;
224 
225   virtual IceRole GetIceRole() const = 0;
226 
227   virtual void SetIceRole(IceRole role) = 0;
228 
229   virtual void SetIceTiebreaker(uint64_t tiebreaker) = 0;
230 
231   // TODO(zhihuang): Remove this once it's no longer called in
232   // remoting/protocol/libjingle_transport_factory.cc
SetIceProtocolType(IceProtocolType type)233   virtual void SetIceProtocolType(IceProtocolType type) {}
234 
235   virtual void SetIceCredentials(const std::string& ice_ufrag,
236                                  const std::string& ice_pwd);
237 
238   virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
239                                        const std::string& ice_pwd);
240 
241   // The ufrag and pwd in |ice_params| must be set
242   // before candidate gathering can start.
243   virtual void SetIceParameters(const IceParameters& ice_params) = 0;
244 
245   virtual void SetRemoteIceParameters(const IceParameters& ice_params) = 0;
246 
247   virtual void SetRemoteIceMode(IceMode mode) = 0;
248 
249   virtual void SetIceConfig(const IceConfig& config) = 0;
250 
251   // Start gathering candidates if not already started, or if an ICE restart
252   // occurred.
253   virtual void MaybeStartGathering() = 0;
254 
255   virtual void AddRemoteCandidate(const Candidate& candidate) = 0;
256 
257   virtual void RemoveRemoteCandidate(const Candidate& candidate) = 0;
258 
259   virtual void RemoveAllRemoteCandidates() = 0;
260 
261   virtual IceGatheringState gathering_state() const = 0;
262 
263   // Returns the current stats for this connection.
264   virtual bool GetStats(IceTransportStats* ice_transport_stats) = 0;
265 
266   // Returns RTT estimate over the currently active connection, or an empty
267   // absl::optional if there is none.
268   virtual absl::optional<int> GetRttEstimate() = 0;
269 
270   // TODO(qingsi): Remove this method once Chrome does not depend on it anymore.
271   virtual const Connection* selected_connection() const = 0;
272 
273   // Returns the selected candidate pair, or an empty absl::optional if there is
274   // none.
275   virtual absl::optional<const CandidatePair> GetSelectedCandidatePair()
276       const = 0;
277 
278   sigslot::signal1<IceTransportInternal*> SignalGatheringState;
279 
280   // Handles sending and receiving of candidates.
281   sigslot::signal2<IceTransportInternal*, const Candidate&>
282       SignalCandidateGathered;
283 
284   sigslot::signal2<IceTransportInternal*, const IceCandidateErrorEvent&>
285       SignalCandidateError;
286 
287   sigslot::signal2<IceTransportInternal*, const Candidates&>
288       SignalCandidatesRemoved;
289 
290   // Deprecated by PacketTransportInternal::SignalNetworkRouteChanged.
291   // This signal occurs when there is a change in the way that packets are
292   // being routed, i.e. to a different remote location. The candidate
293   // indicates where and how we are currently sending media.
294   // TODO(zhihuang): Update the Chrome remoting to use the new
295   // SignalNetworkRouteChanged.
296   sigslot::signal2<IceTransportInternal*, const Candidate&> SignalRouteChange;
297 
298   sigslot::signal1<const cricket::CandidatePairChangeEvent&>
299       SignalCandidatePairChanged;
300 
301   // Invoked when there is conflict in the ICE role between local and remote
302   // agents.
303   sigslot::signal1<IceTransportInternal*> SignalRoleConflict;
304 
305   // Emitted whenever the transport state changed.
306   // TODO(bugs.webrtc.org/9308): Remove once all uses have migrated to the new
307   // IceTransportState.
308   sigslot::signal1<IceTransportInternal*> SignalStateChanged;
309 
310   // Emitted whenever the new standards-compliant transport state changed.
311   sigslot::signal1<IceTransportInternal*> SignalIceTransportStateChanged;
312 
313   // Invoked when the transport is being destroyed.
314   sigslot::signal1<IceTransportInternal*> SignalDestroyed;
315 };
316 
317 }  // namespace cricket
318 
319 #endif  // P2P_BASE_ICE_TRANSPORT_INTERNAL_H_
320