OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 // A Transport manages a set of named channels of the same type. | 11 // Most of the contents of this header have moved to jseptransport.h. |
12 // | 12 // TODO(deadbeef): Delete this file when downstream dependents are updated. |
13 // Subclasses choose the appropriate class to instantiate for each channel; | |
14 // however, this base class keeps track of the channels by name, watches their | |
15 // state changes (in order to update the manager's state), and forwards | |
16 // requests to begin connecting or to reset to each of the channels. | |
17 // | |
18 // On Threading: Transport performs work solely on the network thread, and so | |
19 // its methods should only be called on the network thread. | |
20 // | |
21 // Note: Subclasses must call DestroyChannels() in their own destructors. | |
22 // It is not possible to do so here because the subclass destructor will | |
23 // already have run. | |
24 | 13 |
25 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_ | 14 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_ |
26 #define WEBRTC_P2P_BASE_TRANSPORT_H_ | 15 #define WEBRTC_P2P_BASE_TRANSPORT_H_ |
27 | 16 |
28 #include <map> | 17 #include "webrtc/p2p/base/transport.h" |
29 #include <memory> | |
30 #include <string> | |
31 #include <vector> | |
32 | |
33 #include "webrtc/base/constructormagic.h" | |
34 #include "webrtc/base/optional.h" | |
35 #include "webrtc/p2p/base/candidate.h" | |
36 #include "webrtc/p2p/base/p2pconstants.h" | |
37 #include "webrtc/p2p/base/sessiondescription.h" | |
38 #include "webrtc/p2p/base/transportinfo.h" | |
39 #include "webrtc/base/messagequeue.h" | |
40 #include "webrtc/base/rtccertificate.h" | |
41 #include "webrtc/base/sigslot.h" | |
42 #include "webrtc/base/sslstreamadapter.h" | |
43 | |
44 namespace cricket { | |
45 | |
46 class PortAllocator; | |
47 class TransportChannel; | |
48 class TransportChannelImpl; | |
49 | |
50 typedef std::vector<Candidate> Candidates; | |
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 IceConnectionState { | |
56 kIceConnectionConnecting = 0, | |
57 kIceConnectionFailed, | |
58 kIceConnectionConnected, // Writable, but still checking one or more | |
59 // connections | |
60 kIceConnectionCompleted, | |
61 }; | |
62 | |
63 enum DtlsTransportState { | |
64 // Haven't started negotiating. | |
65 DTLS_TRANSPORT_NEW = 0, | |
66 // Have started negotiating. | |
67 DTLS_TRANSPORT_CONNECTING, | |
68 // Negotiated, and has a secure connection. | |
69 DTLS_TRANSPORT_CONNECTED, | |
70 // Transport is closed. | |
71 DTLS_TRANSPORT_CLOSED, | |
72 // Failed due to some error in the handshake process. | |
73 DTLS_TRANSPORT_FAILED, | |
74 }; | |
75 | |
76 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState | |
77 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming | |
78 // style. | |
79 enum IceGatheringState { | |
80 kIceGatheringNew = 0, | |
81 kIceGatheringGathering, | |
82 kIceGatheringComplete, | |
83 }; | |
84 | |
85 enum ContinualGatheringPolicy { | |
86 // All port allocator sessions will stop after a writable connection is found. | |
87 GATHER_ONCE = 0, | |
88 // The most recent port allocator session will keep on running. | |
89 GATHER_CONTINUALLY, | |
90 // The most recent port allocator session will keep on running, and it will | |
91 // try to recover connectivity if the channel becomes disconnected. | |
92 GATHER_CONTINUALLY_AND_RECOVER, | |
93 }; | |
94 | |
95 // Stats that we can return about the connections for a transport channel. | |
96 // TODO(hta): Rename to ConnectionStats | |
97 struct ConnectionInfo { | |
98 ConnectionInfo() | |
99 : best_connection(false), | |
100 writable(false), | |
101 receiving(false), | |
102 timeout(false), | |
103 new_connection(false), | |
104 rtt(0), | |
105 sent_total_bytes(0), | |
106 sent_bytes_second(0), | |
107 sent_discarded_packets(0), | |
108 sent_total_packets(0), | |
109 sent_ping_requests_total(0), | |
110 sent_ping_requests_before_first_response(0), | |
111 sent_ping_responses(0), | |
112 recv_total_bytes(0), | |
113 recv_bytes_second(0), | |
114 recv_ping_requests(0), | |
115 recv_ping_responses(0), | |
116 key(NULL) {} | |
117 | |
118 bool best_connection; // Is this the best connection we have? | |
119 bool writable; // Has this connection received a STUN response? | |
120 bool receiving; // Has this connection received anything? | |
121 bool timeout; // Has this connection timed out? | |
122 bool new_connection; // Is this a newly created connection? | |
123 size_t rtt; // The STUN RTT for this connection. | |
124 size_t sent_total_bytes; // Total bytes sent on this connection. | |
125 size_t sent_bytes_second; // Bps over the last measurement interval. | |
126 size_t sent_discarded_packets; // Number of outgoing packets discarded due to | |
127 // socket errors. | |
128 size_t sent_total_packets; // Number of total outgoing packets attempted for | |
129 // sending. | |
130 size_t sent_ping_requests_total; // Number of STUN ping request sent. | |
131 size_t sent_ping_requests_before_first_response; // Number of STUN ping | |
132 // sent before receiving the first response. | |
133 size_t sent_ping_responses; // Number of STUN ping response sent. | |
134 | |
135 size_t recv_total_bytes; // Total bytes received on this connection. | |
136 size_t recv_bytes_second; // Bps over the last measurement interval. | |
137 size_t recv_ping_requests; // Number of STUN ping request received. | |
138 size_t recv_ping_responses; // Number of STUN ping response received. | |
139 Candidate local_candidate; // The local candidate for this connection. | |
140 Candidate remote_candidate; // The remote candidate for this connection. | |
141 void* key; // A static value that identifies this conn. | |
142 }; | |
143 | |
144 // Information about all the connections of a channel. | |
145 typedef std::vector<ConnectionInfo> ConnectionInfos; | |
146 | |
147 // Information about a specific channel | |
148 struct TransportChannelStats { | |
149 int component = 0; | |
150 ConnectionInfos connection_infos; | |
151 int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE; | |
152 int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL; | |
153 }; | |
154 | |
155 // Information about all the channels of a transport. | |
156 // TODO(hta): Consider if a simple vector is as good as a map. | |
157 typedef std::vector<TransportChannelStats> TransportChannelStatsList; | |
158 | |
159 // Information about the stats of a transport. | |
160 struct TransportStats { | |
161 std::string transport_name; | |
162 TransportChannelStatsList channel_stats; | |
163 }; | |
164 | |
165 // ICE Nomination mode. | |
166 enum class NominationMode { | |
167 REGULAR, // Nominate once per ICE restart (Not implemented yet). | |
168 AGGRESSIVE, // Nominate every connection except that it will behave as if | |
169 // REGULAR when the remote is an ICE-LITE endpoint. | |
170 SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm. | |
171 // The details are described in P2PTransportChannel. | |
172 }; | |
173 | |
174 // Information about ICE configuration. | |
175 // TODO(deadbeef): Use rtc::Optional to represent unset values, instead of | |
176 // -1. | |
177 struct IceConfig { | |
178 // The ICE connection receiving timeout value in milliseconds. | |
179 int receiving_timeout = -1; | |
180 // Time interval in milliseconds to ping a backup connection when the ICE | |
181 // channel is strongly connected. | |
182 int backup_connection_ping_interval = -1; | |
183 | |
184 ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE; | |
185 | |
186 bool gather_continually() const { | |
187 return continual_gathering_policy == GATHER_CONTINUALLY || | |
188 continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER; | |
189 } | |
190 | |
191 // Whether we should prioritize Relay/Relay candidate when nothing | |
192 // is writable yet. | |
193 bool prioritize_most_likely_candidate_pairs = false; | |
194 | |
195 // Writable connections are pinged at a slower rate once stablized. | |
196 int stable_writable_connection_ping_interval = -1; | |
197 | |
198 // If set to true, this means the ICE transport should presume TURN-to-TURN | |
199 // candidate pairs will succeed, even before a binding response is received. | |
200 bool presume_writable_when_fully_relayed = false; | |
201 | |
202 // Interval to check on all networks and to perform ICE regathering on any | |
203 // active network having no connection on it. | |
204 rtc::Optional<int> regather_on_failed_networks_interval; | |
205 | |
206 // The time period in which we will not switch the selected connection | |
207 // when a new connection becomes receiving but the selected connection is not | |
208 // in case that the selected connection may become receiving soon. | |
209 rtc::Optional<int> receiving_switching_delay; | |
210 | |
211 // TODO(honghaiz): Change the default to regular nomination. | |
212 // Default nomination mode if the remote does not support renomination. | |
213 NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE; | |
214 | |
215 IceConfig() {} | |
216 IceConfig(int receiving_timeout_ms, | |
217 int backup_connection_ping_interval, | |
218 ContinualGatheringPolicy gathering_policy, | |
219 bool prioritize_most_likely_candidate_pairs, | |
220 int stable_writable_connection_ping_interval_ms, | |
221 bool presume_writable_when_fully_relayed, | |
222 int regather_on_failed_networks_interval_ms, | |
223 int receiving_switching_delay_ms) | |
224 : receiving_timeout(receiving_timeout_ms), | |
225 backup_connection_ping_interval(backup_connection_ping_interval), | |
226 continual_gathering_policy(gathering_policy), | |
227 prioritize_most_likely_candidate_pairs( | |
228 prioritize_most_likely_candidate_pairs), | |
229 stable_writable_connection_ping_interval( | |
230 stable_writable_connection_ping_interval_ms), | |
231 presume_writable_when_fully_relayed( | |
232 presume_writable_when_fully_relayed), | |
233 regather_on_failed_networks_interval( | |
234 regather_on_failed_networks_interval_ms), | |
235 receiving_switching_delay(receiving_switching_delay_ms) {} | |
236 }; | |
237 | |
238 bool BadTransportDescription(const std::string& desc, std::string* err_desc); | |
239 | |
240 bool IceCredentialsChanged(const std::string& old_ufrag, | |
241 const std::string& old_pwd, | |
242 const std::string& new_ufrag, | |
243 const std::string& new_pwd); | |
244 | |
245 class Transport : public sigslot::has_slots<> { | |
246 public: | |
247 Transport(const std::string& name, PortAllocator* allocator); | |
248 virtual ~Transport(); | |
249 | |
250 // Returns the name of this transport. | |
251 const std::string& name() const { return name_; } | |
252 | |
253 // Returns the port allocator object for this transport. | |
254 PortAllocator* port_allocator() { return allocator_; } | |
255 | |
256 bool ready_for_remote_candidates() const { | |
257 return local_description_set_ && remote_description_set_; | |
258 } | |
259 | |
260 void SetIceRole(IceRole role); | |
261 IceRole ice_role() const { return ice_role_; } | |
262 | |
263 void SetIceTiebreaker(uint64_t IceTiebreaker) { tiebreaker_ = IceTiebreaker; } | |
264 uint64_t IceTiebreaker() { return tiebreaker_; } | |
265 | |
266 void SetIceConfig(const IceConfig& config); | |
267 | |
268 // Must be called before applying local session description. | |
269 virtual void SetLocalCertificate( | |
270 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {} | |
271 | |
272 // Get a copy of the local certificate provided by SetLocalCertificate. | |
273 virtual bool GetLocalCertificate( | |
274 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
275 return false; | |
276 } | |
277 | |
278 // Get a copy of the remote certificate in use by the specified channel. | |
279 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(); | |
280 | |
281 // Create, destroy, and lookup the channels of this type by their components. | |
282 TransportChannelImpl* CreateChannel(int component); | |
283 | |
284 TransportChannelImpl* GetChannel(int component); | |
285 | |
286 bool HasChannel(int component) { | |
287 return (NULL != GetChannel(component)); | |
288 } | |
289 bool HasChannels(); | |
290 | |
291 void DestroyChannel(int component); | |
292 | |
293 // Set the local TransportDescription to be used by TransportChannels. | |
294 bool SetLocalTransportDescription(const TransportDescription& description, | |
295 ContentAction action, | |
296 std::string* error_desc); | |
297 | |
298 // Set the remote TransportDescription to be used by TransportChannels. | |
299 bool SetRemoteTransportDescription(const TransportDescription& description, | |
300 ContentAction action, | |
301 std::string* error_desc); | |
302 | |
303 // Tells channels to start gathering candidates if necessary. | |
304 // Should be called after ConnectChannels() has been called at least once, | |
305 // which will happen in SetLocalTransportDescription. | |
306 void MaybeStartGathering(); | |
307 | |
308 // Resets all of the channels back to their initial state. They are no | |
309 // longer connecting. | |
310 void ResetChannels(); | |
311 | |
312 // Destroys every channel created so far. | |
313 void DestroyAllChannels(); | |
314 | |
315 bool GetStats(TransportStats* stats); | |
316 | |
317 // Called when one or more candidates are ready from the remote peer. | |
318 bool AddRemoteCandidates(const std::vector<Candidate>& candidates, | |
319 std::string* error); | |
320 bool RemoveRemoteCandidates(const std::vector<Candidate>& candidates, | |
321 std::string* error); | |
322 | |
323 virtual bool GetSslRole(rtc::SSLRole* ssl_role) const { return false; } | |
324 | |
325 // Must be called before channel is starting to connect. | |
326 virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) { | |
327 return false; | |
328 } | |
329 | |
330 // The current local transport description, for use by derived classes | |
331 // when performing transport description negotiation, and possibly used | |
332 // by the transport controller. | |
333 const TransportDescription* local_description() const { | |
334 return local_description_.get(); | |
335 } | |
336 | |
337 // The current remote transport description, for use by derived classes | |
338 // when performing transport description negotiation, and possibly used | |
339 // by the transport controller. | |
340 const TransportDescription* remote_description() const { | |
341 return remote_description_.get(); | |
342 } | |
343 | |
344 protected: | |
345 // These are called by Create/DestroyChannel above in order to create or | |
346 // destroy the appropriate type of channel. | |
347 virtual TransportChannelImpl* CreateTransportChannel(int component) = 0; | |
348 virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0; | |
349 | |
350 // Pushes down the transport parameters from the local description, such | |
351 // as the ICE ufrag and pwd. | |
352 // Derived classes can override, but must call the base as well. | |
353 virtual bool ApplyLocalTransportDescription(TransportChannelImpl* channel, | |
354 std::string* error_desc); | |
355 | |
356 // Pushes down remote ice credentials from the remote description to the | |
357 // transport channel. | |
358 virtual bool ApplyRemoteTransportDescription(TransportChannelImpl* ch, | |
359 std::string* error_desc); | |
360 | |
361 // Negotiates the transport parameters based on the current local and remote | |
362 // transport description, such as the ICE role to use, and whether DTLS | |
363 // should be activated. | |
364 // Derived classes can negotiate their specific parameters here, but must call | |
365 // the base as well. | |
366 virtual bool NegotiateTransportDescription(ContentAction local_role, | |
367 std::string* error_desc); | |
368 | |
369 // Pushes down the transport parameters obtained via negotiation. | |
370 // Derived classes can set their specific parameters here, but must call the | |
371 // base as well. | |
372 virtual bool ApplyNegotiatedTransportDescription( | |
373 TransportChannelImpl* channel, | |
374 std::string* error_desc); | |
375 | |
376 // Returns false if the certificate's identity does not match the fingerprint, | |
377 // or either is NULL. | |
378 virtual bool VerifyCertificateFingerprint( | |
379 const rtc::RTCCertificate* certificate, | |
380 const rtc::SSLFingerprint* fingerprint, | |
381 std::string* error_desc) const; | |
382 | |
383 // Negotiates the SSL role based off the offer and answer as specified by | |
384 // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined | |
385 // from the local description and remote description. | |
386 virtual bool NegotiateRole(ContentAction local_role, | |
387 rtc::SSLRole* ssl_role, | |
388 std::string* error_desc) const; | |
389 | |
390 private: | |
391 // If a candidate is not acceptable, returns false and sets error. | |
392 // Call this before calling OnRemoteCandidates. | |
393 bool VerifyCandidate(const Candidate& candidate, std::string* error); | |
394 bool VerifyCandidates(const Candidates& candidates, std::string* error); | |
395 | |
396 // Candidate component => TransportChannelImpl* | |
397 typedef std::map<int, TransportChannelImpl*> ChannelMap; | |
398 | |
399 // Helper function that invokes the given function on every channel. | |
400 typedef void (TransportChannelImpl::* TransportChannelFunc)(); | |
401 void CallChannels(TransportChannelFunc func); | |
402 | |
403 const std::string name_; | |
404 PortAllocator* const allocator_; | |
405 bool channels_destroyed_ = false; | |
406 IceRole ice_role_ = ICEROLE_UNKNOWN; | |
407 uint64_t tiebreaker_ = 0; | |
408 IceMode remote_ice_mode_ = ICEMODE_FULL; | |
409 IceConfig ice_config_; | |
410 std::unique_ptr<TransportDescription> local_description_; | |
411 std::unique_ptr<TransportDescription> remote_description_; | |
412 bool local_description_set_ = false; | |
413 bool remote_description_set_ = false; | |
414 | |
415 ChannelMap channels_; | |
416 | |
417 RTC_DISALLOW_COPY_AND_ASSIGN(Transport); | |
418 }; | |
419 | |
420 | |
421 } // namespace cricket | |
422 | 18 |
423 #endif // WEBRTC_P2P_BASE_TRANSPORT_H_ | 19 #endif // WEBRTC_P2P_BASE_TRANSPORT_H_ |
OLD | NEW |