OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2004 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 // A Transport manages a set of named channels of the same type. | |
12 // | |
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 | |
25 #ifndef WEBRTC_P2P_BASE_JSEPTRANSPORT_H_ | |
26 #define WEBRTC_P2P_BASE_JSEPTRANSPORT_H_ | |
27 | |
28 #include <map> | |
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 TransportChannelImpl; | |
47 class TransportChannelImpl; | |
48 | |
49 typedef std::vector<Candidate> Candidates; | |
50 | |
51 // TODO(deadbeef): Move all of these enums, POD types and utility methods to | |
52 // another header file. | |
53 | |
54 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState | |
55 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming | |
56 // style. | |
57 enum IceConnectionState { | |
58 kIceConnectionConnecting = 0, | |
59 kIceConnectionFailed, | |
60 kIceConnectionConnected, // Writable, but still checking one or more | |
61 // connections | |
62 kIceConnectionCompleted, | |
63 }; | |
64 | |
65 enum DtlsTransportState { | |
66 // Haven't started negotiating. | |
67 DTLS_TRANSPORT_NEW = 0, | |
68 // Have started negotiating. | |
69 DTLS_TRANSPORT_CONNECTING, | |
70 // Negotiated, and has a secure connection. | |
71 DTLS_TRANSPORT_CONNECTED, | |
72 // Transport is closed. | |
73 DTLS_TRANSPORT_CLOSED, | |
74 // Failed due to some error in the handshake process. | |
75 DTLS_TRANSPORT_FAILED, | |
76 }; | |
77 | |
78 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState | |
79 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming | |
80 // style. | |
81 enum IceGatheringState { | |
82 kIceGatheringNew = 0, | |
83 kIceGatheringGathering, | |
84 kIceGatheringComplete, | |
85 }; | |
86 | |
87 enum ContinualGatheringPolicy { | |
88 // All port allocator sessions will stop after a writable connection is found. | |
89 GATHER_ONCE = 0, | |
90 // The most recent port allocator session will keep on running. | |
91 GATHER_CONTINUALLY, | |
92 // The most recent port allocator session will keep on running, and it will | |
93 // try to recover connectivity if the channel becomes disconnected. | |
94 GATHER_CONTINUALLY_AND_RECOVER, | |
95 }; | |
96 | |
97 // Stats that we can return about the connections for a transport channel. | |
98 // TODO(hta): Rename to ConnectionStats | |
99 struct ConnectionInfo { | |
100 ConnectionInfo() | |
101 : best_connection(false), | |
102 writable(false), | |
103 receiving(false), | |
104 timeout(false), | |
105 new_connection(false), | |
106 rtt(0), | |
107 sent_total_bytes(0), | |
108 sent_bytes_second(0), | |
109 sent_discarded_packets(0), | |
110 sent_total_packets(0), | |
111 sent_ping_requests_total(0), | |
112 sent_ping_requests_before_first_response(0), | |
113 sent_ping_responses(0), | |
114 recv_total_bytes(0), | |
115 recv_bytes_second(0), | |
116 recv_ping_requests(0), | |
117 recv_ping_responses(0), | |
118 key(NULL) {} | |
119 | |
120 bool best_connection; // Is this the best connection we have? | |
121 bool writable; // Has this connection received a STUN response? | |
122 bool receiving; // Has this connection received anything? | |
123 bool timeout; // Has this connection timed out? | |
124 bool new_connection; // Is this a newly created connection? | |
125 size_t rtt; // The STUN RTT for this connection. | |
126 size_t sent_total_bytes; // Total bytes sent on this connection. | |
127 size_t sent_bytes_second; // Bps over the last measurement interval. | |
128 size_t sent_discarded_packets; // Number of outgoing packets discarded due to | |
129 // socket errors. | |
130 size_t sent_total_packets; // Number of total outgoing packets attempted for | |
131 // sending. | |
132 size_t sent_ping_requests_total; // Number of STUN ping request sent. | |
133 size_t sent_ping_requests_before_first_response; // Number of STUN ping | |
134 // sent before receiving the first response. | |
135 size_t sent_ping_responses; // Number of STUN ping response sent. | |
136 | |
137 size_t recv_total_bytes; // Total bytes received on this connection. | |
138 size_t recv_bytes_second; // Bps over the last measurement interval. | |
139 size_t recv_ping_requests; // Number of STUN ping request received. | |
140 size_t recv_ping_responses; // Number of STUN ping response received. | |
141 Candidate local_candidate; // The local candidate for this connection. | |
142 Candidate remote_candidate; // The remote candidate for this connection. | |
143 void* key; // A static value that identifies this conn. | |
144 }; | |
145 | |
146 // Information about all the connections of a channel. | |
147 typedef std::vector<ConnectionInfo> ConnectionInfos; | |
148 | |
149 // Information about a specific channel | |
150 struct TransportChannelStats { | |
151 int component = 0; | |
152 ConnectionInfos connection_infos; | |
153 int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE; | |
154 int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL; | |
155 }; | |
156 | |
157 // Information about all the channels of a transport. | |
158 // TODO(hta): Consider if a simple vector is as good as a map. | |
159 typedef std::vector<TransportChannelStats> TransportChannelStatsList; | |
160 | |
161 // Information about the stats of a transport. | |
162 struct TransportStats { | |
163 std::string transport_name; | |
164 TransportChannelStatsList channel_stats; | |
165 }; | |
166 | |
167 // ICE Nomination mode. | |
168 enum class NominationMode { | |
169 REGULAR, // Nominate once per ICE restart (Not implemented yet). | |
170 AGGRESSIVE, // Nominate every connection except that it will behave as if | |
171 // REGULAR when the remote is an ICE-LITE endpoint. | |
172 SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm. | |
173 // The details are described in P2PTransportChannel. | |
174 }; | |
175 | |
176 // Information about ICE configuration. | |
177 // TODO(deadbeef): Use rtc::Optional to represent unset values, instead of | |
178 // -1. | |
179 struct IceConfig { | |
180 // The ICE connection receiving timeout value in milliseconds. | |
181 int receiving_timeout = -1; | |
182 // Time interval in milliseconds to ping a backup connection when the ICE | |
183 // channel is strongly connected. | |
184 int backup_connection_ping_interval = -1; | |
185 | |
186 ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE; | |
187 | |
188 bool gather_continually() const { | |
189 return continual_gathering_policy == GATHER_CONTINUALLY || | |
190 continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER; | |
191 } | |
192 | |
193 // Whether we should prioritize Relay/Relay candidate when nothing | |
194 // is writable yet. | |
195 bool prioritize_most_likely_candidate_pairs = false; | |
196 | |
197 // Writable connections are pinged at a slower rate once stablized. | |
198 int stable_writable_connection_ping_interval = -1; | |
199 | |
200 // If set to true, this means the ICE transport should presume TURN-to-TURN | |
201 // candidate pairs will succeed, even before a binding response is received. | |
202 bool presume_writable_when_fully_relayed = false; | |
203 | |
204 // Interval to check on all networks and to perform ICE regathering on any | |
205 // active network having no connection on it. | |
206 rtc::Optional<int> regather_on_failed_networks_interval; | |
207 | |
208 // The time period in which we will not switch the selected connection | |
209 // when a new connection becomes receiving but the selected connection is not | |
210 // in case that the selected connection may become receiving soon. | |
211 rtc::Optional<int> receiving_switching_delay; | |
212 | |
213 // TODO(honghaiz): Change the default to regular nomination. | |
214 // Default nomination mode if the remote does not support renomination. | |
215 NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE; | |
216 | |
217 IceConfig() {} | |
218 IceConfig(int receiving_timeout_ms, | |
219 int backup_connection_ping_interval, | |
220 ContinualGatheringPolicy gathering_policy, | |
221 bool prioritize_most_likely_candidate_pairs, | |
222 int stable_writable_connection_ping_interval_ms, | |
223 bool presume_writable_when_fully_relayed, | |
224 int regather_on_failed_networks_interval_ms, | |
225 int receiving_switching_delay_ms) | |
226 : receiving_timeout(receiving_timeout_ms), | |
227 backup_connection_ping_interval(backup_connection_ping_interval), | |
228 continual_gathering_policy(gathering_policy), | |
229 prioritize_most_likely_candidate_pairs( | |
230 prioritize_most_likely_candidate_pairs), | |
231 stable_writable_connection_ping_interval( | |
232 stable_writable_connection_ping_interval_ms), | |
233 presume_writable_when_fully_relayed( | |
234 presume_writable_when_fully_relayed), | |
235 regather_on_failed_networks_interval( | |
236 regather_on_failed_networks_interval_ms), | |
237 receiving_switching_delay(receiving_switching_delay_ms) {} | |
238 }; | |
239 | |
240 bool BadTransportDescription(const std::string& desc, std::string* err_desc); | |
241 | |
242 bool IceCredentialsChanged(const std::string& old_ufrag, | |
243 const std::string& old_pwd, | |
244 const std::string& new_ufrag, | |
245 const std::string& new_pwd); | |
246 | |
247 // If a candidate is not acceptable, returns false and sets error. | |
248 bool VerifyCandidate(const Candidate& candidate, std::string* error); | |
249 bool VerifyCandidates(const Candidates& candidates, std::string* error); | |
250 | |
251 // Helper class used by TransportController that processes | |
252 // TransportDescriptions. A TransportDescription represents the | |
253 // transport-specific properties of an SDP m= section, processed according to | |
254 // JSEP. Each transport consists of DTLS and ICE transport channels for RTP | |
255 // (and possibly RTCP, if rtcp-mux isn't used). | |
256 // TODO(deadbeef): Move this into /pc/ and out of /p2p/base/, since it's | |
257 // PeerConnection-specific. | |
258 class JsepTransport : public sigslot::has_slots<> { | |
259 public: | |
260 // |mid| is just used for log statements in order to identify the Transport. | |
261 // Note that |certificate| is allowed to be null since a remote description | |
262 // may be set before a local certificate is generated. | |
263 JsepTransport(const std::string& mid, | |
264 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); | |
265 | |
266 // Returns the MID of this transport. | |
267 const std::string& mid() const { return mid_; } | |
268 | |
269 // Add or remove channel that is affected when a local/remote transport | |
270 // description is set on this transport. Need to add all channels before | |
271 // setting a transport description. | |
272 bool AddChannel(TransportChannelImpl* dtls, int component); | |
273 bool RemoveChannel(int component); | |
274 bool HasChannels() const; | |
275 | |
276 bool ready_for_remote_candidates() const { | |
277 return local_description_set_ && remote_description_set_; | |
278 } | |
279 | |
280 // Must be called before applying local session description. | |
281 // Needed in order to verify the local fingerprint. | |
282 void SetLocalCertificate( | |
283 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); | |
284 | |
285 // Get a copy of the local certificate provided by SetLocalCertificate. | |
286 bool GetLocalCertificate( | |
287 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const; | |
288 | |
289 // Set the local TransportDescription to be used by DTLS and ICE channels | |
290 // that are part of this Transport. | |
291 bool SetLocalTransportDescription(const TransportDescription& description, | |
292 ContentAction action, | |
293 std::string* error_desc); | |
294 | |
295 // Set the remote TransportDescription to be used by DTLS and ICE channels | |
296 // that are part of this Transport. | |
297 bool SetRemoteTransportDescription(const TransportDescription& description, | |
298 ContentAction action, | |
299 std::string* error_desc); | |
300 | |
301 void GetSslRole(rtc::SSLRole* ssl_role) const; | |
302 | |
303 // TODO(deadbeef): Make this const. See comment in transportcontroller.h. | |
304 bool GetStats(TransportStats* stats); | |
305 | |
306 // The current local transport description, possibly used | |
307 // by the transport controller. | |
308 const TransportDescription* local_description() const { | |
309 return local_description_.get(); | |
310 } | |
311 | |
312 // The current remote transport description, possibly used | |
313 // by the transport controller. | |
314 const TransportDescription* remote_description() const { | |
315 return remote_description_.get(); | |
316 } | |
317 | |
318 // TODO(deadbeef): The methods below are only public for testing. Should make | |
319 // them utility functions or objects so they can be tested independently from | |
320 // this class. | |
321 | |
322 // Returns false if the certificate's identity does not match the fingerprint, | |
323 // or either is NULL. | |
324 bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate, | |
325 const rtc::SSLFingerprint* fingerprint, | |
326 std::string* error_desc) const; | |
327 | |
328 // Negotiates the SSL role based off the offer and answer as specified by | |
329 // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined | |
330 // from the local description and remote description. | |
331 bool NegotiateRole(ContentAction local_role, | |
332 rtc::SSLRole* ssl_role, | |
333 std::string* error_desc) const; | |
334 | |
335 private: | |
336 TransportChannelImpl* GetChannel(int component); | |
337 | |
338 // Negotiates the transport parameters based on the current local and remote | |
339 // transport description, such as the ICE role to use, and whether DTLS | |
340 // should be activated. | |
341 // | |
342 // Called when an answer TransportDescription is applied. | |
343 bool NegotiateTransportDescription(ContentAction local_role, | |
344 std::string* error_desc); | |
345 | |
346 // Pushes down the transport parameters from the local description, such | |
347 // as the ICE ufrag and pwd. | |
348 bool ApplyLocalTransportDescription(TransportChannelImpl* channel, | |
349 std::string* error_desc); | |
350 | |
351 // Pushes down the transport parameters from the remote description to the | |
352 // transport channel. | |
353 bool ApplyRemoteTransportDescription(TransportChannelImpl* channel, | |
354 std::string* error_desc); | |
355 | |
356 // Pushes down the transport parameters obtained via negotiation. | |
357 bool ApplyNegotiatedTransportDescription(TransportChannelImpl* channel, | |
358 std::string* error_desc); | |
359 | |
360 const std::string mid_; | |
361 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | |
362 rtc::SSLRole secure_role_ = rtc::SSL_CLIENT; | |
363 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_; | |
364 std::unique_ptr<TransportDescription> local_description_; | |
365 std::unique_ptr<TransportDescription> remote_description_; | |
366 bool local_description_set_ = false; | |
367 bool remote_description_set_ = false; | |
368 | |
369 // Candidate component => DTLS channel | |
370 std::map<int, TransportChannelImpl*> channels_; | |
371 | |
372 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport); | |
373 }; | |
374 | |
375 } // namespace cricket | |
376 | |
377 #endif // WEBRTC_P2P_BASE_JSEPTRANSPORT_H_ | |
OLD | NEW |