blob: f680646e16edafa8db508b1129760b873ac9112c [file] [log] [blame]
deadbeef49f34fd2016-12-06 16:22:06 -08001/*
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#ifndef WEBRTC_P2P_BASE_JSEPTRANSPORT_H_
12#define WEBRTC_P2P_BASE_JSEPTRANSPORT_H_
13
14#include <map>
15#include <memory>
16#include <string>
17#include <vector>
18
kwiberg84f6a3f2017-09-05 08:43:13 -070019#include "webrtc/api/optional.h"
deadbeef49f34fd2016-12-06 16:22:06 -080020#include "webrtc/p2p/base/candidate.h"
21#include "webrtc/p2p/base/p2pconstants.h"
22#include "webrtc/p2p/base/sessiondescription.h"
23#include "webrtc/p2p/base/transportinfo.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020024#include "webrtc/rtc_base/constructormagic.h"
25#include "webrtc/rtc_base/messagequeue.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020026#include "webrtc/rtc_base/rtccertificate.h"
27#include "webrtc/rtc_base/sigslot.h"
28#include "webrtc/rtc_base/sslstreamadapter.h"
deadbeef49f34fd2016-12-06 16:22:06 -080029
30namespace cricket {
31
zhihuangb2cdd932017-01-19 16:54:25 -080032class DtlsTransportInternal;
hbos06495bc2017-01-02 08:08:18 -080033enum class IceCandidatePairState;
deadbeef49f34fd2016-12-06 16:22:06 -080034
35typedef std::vector<Candidate> Candidates;
36
37// TODO(deadbeef): Move all of these enums, POD types and utility methods to
38// another header file.
39
40// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
41// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
42// style.
43enum IceConnectionState {
44 kIceConnectionConnecting = 0,
45 kIceConnectionFailed,
46 kIceConnectionConnected, // Writable, but still checking one or more
47 // connections
48 kIceConnectionCompleted,
49};
50
51enum DtlsTransportState {
52 // Haven't started negotiating.
53 DTLS_TRANSPORT_NEW = 0,
54 // Have started negotiating.
55 DTLS_TRANSPORT_CONNECTING,
56 // Negotiated, and has a secure connection.
57 DTLS_TRANSPORT_CONNECTED,
58 // Transport is closed.
59 DTLS_TRANSPORT_CLOSED,
60 // Failed due to some error in the handshake process.
61 DTLS_TRANSPORT_FAILED,
62};
63
64// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
65// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
66// style.
67enum IceGatheringState {
68 kIceGatheringNew = 0,
69 kIceGatheringGathering,
70 kIceGatheringComplete,
71};
72
73enum ContinualGatheringPolicy {
74 // All port allocator sessions will stop after a writable connection is found.
75 GATHER_ONCE = 0,
76 // The most recent port allocator session will keep on running.
77 GATHER_CONTINUALLY,
78 // The most recent port allocator session will keep on running, and it will
79 // try to recover connectivity if the channel becomes disconnected.
80 GATHER_CONTINUALLY_AND_RECOVER,
81};
82
83// Stats that we can return about the connections for a transport channel.
84// TODO(hta): Rename to ConnectionStats
85struct ConnectionInfo {
hbos06495bc2017-01-02 08:08:18 -080086 ConnectionInfo();
deadbeef49f34fd2016-12-06 16:22:06 -080087
88 bool best_connection; // Is this the best connection we have?
89 bool writable; // Has this connection received a STUN response?
90 bool receiving; // Has this connection received anything?
91 bool timeout; // Has this connection timed out?
92 bool new_connection; // Is this a newly created connection?
93 size_t rtt; // The STUN RTT for this connection.
94 size_t sent_total_bytes; // Total bytes sent on this connection.
95 size_t sent_bytes_second; // Bps over the last measurement interval.
96 size_t sent_discarded_packets; // Number of outgoing packets discarded due to
97 // socket errors.
98 size_t sent_total_packets; // Number of total outgoing packets attempted for
99 // sending.
100 size_t sent_ping_requests_total; // Number of STUN ping request sent.
101 size_t sent_ping_requests_before_first_response; // Number of STUN ping
102 // sent before receiving the first response.
103 size_t sent_ping_responses; // Number of STUN ping response sent.
104
105 size_t recv_total_bytes; // Total bytes received on this connection.
106 size_t recv_bytes_second; // Bps over the last measurement interval.
107 size_t recv_ping_requests; // Number of STUN ping request received.
108 size_t recv_ping_responses; // Number of STUN ping response received.
109 Candidate local_candidate; // The local candidate for this connection.
110 Candidate remote_candidate; // The remote candidate for this connection.
111 void* key; // A static value that identifies this conn.
hbos06495bc2017-01-02 08:08:18 -0800112 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
113 IceCandidatePairState state;
114 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
115 uint64_t priority;
hbos92eaec62017-02-27 01:38:08 -0800116 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-nominated
117 bool nominated;
hbosbf8d3e52017-02-28 06:34:47 -0800118 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
119 uint64_t total_round_trip_time_ms;
120 // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
121 rtc::Optional<uint32_t> current_round_trip_time_ms;
deadbeef49f34fd2016-12-06 16:22:06 -0800122};
123
124// Information about all the connections of a channel.
125typedef std::vector<ConnectionInfo> ConnectionInfos;
126
127// Information about a specific channel
128struct TransportChannelStats {
129 int component = 0;
130 ConnectionInfos connection_infos;
131 int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
132 int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
hbos7064d592017-01-16 07:38:02 -0800133 DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
deadbeef49f34fd2016-12-06 16:22:06 -0800134};
135
136// Information about all the channels of a transport.
137// TODO(hta): Consider if a simple vector is as good as a map.
138typedef std::vector<TransportChannelStats> TransportChannelStatsList;
139
140// Information about the stats of a transport.
141struct TransportStats {
142 std::string transport_name;
143 TransportChannelStatsList channel_stats;
144};
145
146// ICE Nomination mode.
147enum class NominationMode {
148 REGULAR, // Nominate once per ICE restart (Not implemented yet).
149 AGGRESSIVE, // Nominate every connection except that it will behave as if
150 // REGULAR when the remote is an ICE-LITE endpoint.
151 SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm.
152 // The details are described in P2PTransportChannel.
153};
154
155// Information about ICE configuration.
156// TODO(deadbeef): Use rtc::Optional to represent unset values, instead of
157// -1.
158struct IceConfig {
159 // The ICE connection receiving timeout value in milliseconds.
160 int receiving_timeout = -1;
161 // Time interval in milliseconds to ping a backup connection when the ICE
162 // channel is strongly connected.
163 int backup_connection_ping_interval = -1;
164
165 ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
166
167 bool gather_continually() const {
168 return continual_gathering_policy == GATHER_CONTINUALLY ||
169 continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER;
170 }
171
172 // Whether we should prioritize Relay/Relay candidate when nothing
173 // is writable yet.
174 bool prioritize_most_likely_candidate_pairs = false;
175
176 // Writable connections are pinged at a slower rate once stablized.
177 int stable_writable_connection_ping_interval = -1;
178
179 // If set to true, this means the ICE transport should presume TURN-to-TURN
180 // candidate pairs will succeed, even before a binding response is received.
181 bool presume_writable_when_fully_relayed = false;
182
183 // Interval to check on all networks and to perform ICE regathering on any
184 // active network having no connection on it.
185 rtc::Optional<int> regather_on_failed_networks_interval;
186
Steve Anton300bf8e2017-07-14 10:13:10 -0700187 // Interval to perform ICE regathering on all networks
188 // The delay in milliseconds is sampled from the uniform distribution [a, b]
189 rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
190
deadbeef49f34fd2016-12-06 16:22:06 -0800191 // The time period in which we will not switch the selected connection
192 // when a new connection becomes receiving but the selected connection is not
193 // in case that the selected connection may become receiving soon.
194 rtc::Optional<int> receiving_switching_delay;
195
196 // TODO(honghaiz): Change the default to regular nomination.
197 // Default nomination mode if the remote does not support renomination.
198 NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
199
skvlad51072462017-02-02 11:50:14 -0800200 // ICE checks (STUN pings) will not be sent at higher rate (lower interval)
201 // than this, no matter what other settings there are.
202 // Measure in milliseconds.
203 rtc::Optional<int> ice_check_min_interval;
204
deadbeef49f34fd2016-12-06 16:22:06 -0800205 IceConfig() {}
206 IceConfig(int receiving_timeout_ms,
207 int backup_connection_ping_interval,
208 ContinualGatheringPolicy gathering_policy,
209 bool prioritize_most_likely_candidate_pairs,
210 int stable_writable_connection_ping_interval_ms,
211 bool presume_writable_when_fully_relayed,
212 int regather_on_failed_networks_interval_ms,
213 int receiving_switching_delay_ms)
214 : receiving_timeout(receiving_timeout_ms),
215 backup_connection_ping_interval(backup_connection_ping_interval),
216 continual_gathering_policy(gathering_policy),
217 prioritize_most_likely_candidate_pairs(
218 prioritize_most_likely_candidate_pairs),
219 stable_writable_connection_ping_interval(
220 stable_writable_connection_ping_interval_ms),
221 presume_writable_when_fully_relayed(
222 presume_writable_when_fully_relayed),
223 regather_on_failed_networks_interval(
224 regather_on_failed_networks_interval_ms),
225 receiving_switching_delay(receiving_switching_delay_ms) {}
226};
227
228bool BadTransportDescription(const std::string& desc, std::string* err_desc);
229
230bool IceCredentialsChanged(const std::string& old_ufrag,
231 const std::string& old_pwd,
232 const std::string& new_ufrag,
233 const std::string& new_pwd);
234
235// If a candidate is not acceptable, returns false and sets error.
236bool VerifyCandidate(const Candidate& candidate, std::string* error);
237bool VerifyCandidates(const Candidates& candidates, std::string* error);
238
239// Helper class used by TransportController that processes
240// TransportDescriptions. A TransportDescription represents the
241// transport-specific properties of an SDP m= section, processed according to
242// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
243// (and possibly RTCP, if rtcp-mux isn't used).
244//
245// On Threading: Transport performs work solely on the network thread, and so
246// its methods should only be called on the network thread.
247//
248// TODO(deadbeef): Move this into /pc/ and out of /p2p/base/, since it's
249// PeerConnection-specific.
250class JsepTransport : public sigslot::has_slots<> {
251 public:
252 // |mid| is just used for log statements in order to identify the Transport.
253 // Note that |certificate| is allowed to be null since a remote description
254 // may be set before a local certificate is generated.
255 JsepTransport(const std::string& mid,
256 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
257
258 // Returns the MID of this transport.
259 const std::string& mid() const { return mid_; }
260
261 // Add or remove channel that is affected when a local/remote transport
262 // description is set on this transport. Need to add all channels before
263 // setting a transport description.
zhihuangb2cdd932017-01-19 16:54:25 -0800264 bool AddChannel(DtlsTransportInternal* dtls, int component);
deadbeef49f34fd2016-12-06 16:22:06 -0800265 bool RemoveChannel(int component);
266 bool HasChannels() const;
267
268 bool ready_for_remote_candidates() const {
269 return local_description_set_ && remote_description_set_;
270 }
271
272 // Must be called before applying local session description.
273 // Needed in order to verify the local fingerprint.
274 void SetLocalCertificate(
275 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
276
277 // Get a copy of the local certificate provided by SetLocalCertificate.
278 bool GetLocalCertificate(
279 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const;
280
281 // Set the local TransportDescription to be used by DTLS and ICE channels
282 // that are part of this Transport.
283 bool SetLocalTransportDescription(const TransportDescription& description,
284 ContentAction action,
285 std::string* error_desc);
286
287 // Set the remote TransportDescription to be used by DTLS and ICE channels
288 // that are part of this Transport.
289 bool SetRemoteTransportDescription(const TransportDescription& description,
290 ContentAction action,
291 std::string* error_desc);
292
deadbeefd1a38b52016-12-10 13:15:33 -0800293 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
294 // set, offers should generate new ufrags/passwords until an ICE restart
295 // occurs.
296 //
297 // This and the below method can be called safely from any thread as long as
298 // SetXTransportDescription is not in progress.
299 void SetNeedsIceRestartFlag();
300 // Returns true if the ICE restart flag above was set, and no ICE restart has
301 // occurred yet for this transport (by applying a local description with
302 // changed ufrag/password).
303 bool NeedsIceRestart() const;
304
deadbeefd8cfa1a2017-03-27 10:33:26 -0700305 // Returns role if negotiated, or empty Optional if it hasn't been negotiated
306 // yet.
307 rtc::Optional<rtc::SSLRole> GetSslRole() const;
deadbeef49f34fd2016-12-06 16:22:06 -0800308
309 // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
310 bool GetStats(TransportStats* stats);
311
312 // The current local transport description, possibly used
313 // by the transport controller.
314 const TransportDescription* local_description() const {
315 return local_description_.get();
316 }
317
318 // The current remote transport description, possibly used
319 // by the transport controller.
320 const TransportDescription* remote_description() const {
321 return remote_description_.get();
322 }
323
324 // TODO(deadbeef): The methods below are only public for testing. Should make
325 // them utility functions or objects so they can be tested independently from
326 // this class.
327
328 // Returns false if the certificate's identity does not match the fingerprint,
329 // or either is NULL.
330 bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate,
331 const rtc::SSLFingerprint* fingerprint,
332 std::string* error_desc) const;
333
deadbeef49f34fd2016-12-06 16:22:06 -0800334 private:
deadbeef49f34fd2016-12-06 16:22:06 -0800335 // Negotiates the transport parameters based on the current local and remote
336 // transport description, such as the ICE role to use, and whether DTLS
337 // should be activated.
338 //
339 // Called when an answer TransportDescription is applied.
deadbeefd8cfa1a2017-03-27 10:33:26 -0700340 bool NegotiateTransportDescription(ContentAction local_description_type,
deadbeef49f34fd2016-12-06 16:22:06 -0800341 std::string* error_desc);
342
deadbeefd8cfa1a2017-03-27 10:33:26 -0700343 // Negotiates the SSL role based off the offer and answer as specified by
344 // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined
345 // from the local description and remote description.
346 bool NegotiateRole(ContentAction local_description_type,
347 std::string* error_desc);
348
deadbeef49f34fd2016-12-06 16:22:06 -0800349 // Pushes down the transport parameters from the local description, such
350 // as the ICE ufrag and pwd.
zhihuangb2cdd932017-01-19 16:54:25 -0800351 bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
deadbeef49f34fd2016-12-06 16:22:06 -0800352 std::string* error_desc);
353
354 // Pushes down the transport parameters from the remote description to the
355 // transport channel.
zhihuangb2cdd932017-01-19 16:54:25 -0800356 bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
deadbeef49f34fd2016-12-06 16:22:06 -0800357 std::string* error_desc);
358
359 // Pushes down the transport parameters obtained via negotiation.
zhihuangb2cdd932017-01-19 16:54:25 -0800360 bool ApplyNegotiatedTransportDescription(
361 DtlsTransportInternal* dtls_transport,
362 std::string* error_desc);
deadbeef49f34fd2016-12-06 16:22:06 -0800363
364 const std::string mid_;
deadbeefd1a38b52016-12-10 13:15:33 -0800365 // needs-ice-restart bit as described in JSEP.
366 bool needs_ice_restart_ = false;
deadbeef49f34fd2016-12-06 16:22:06 -0800367 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
deadbeefd8cfa1a2017-03-27 10:33:26 -0700368 rtc::Optional<rtc::SSLRole> ssl_role_;
deadbeef49f34fd2016-12-06 16:22:06 -0800369 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_;
370 std::unique_ptr<TransportDescription> local_description_;
371 std::unique_ptr<TransportDescription> remote_description_;
372 bool local_description_set_ = false;
373 bool remote_description_set_ = false;
374
375 // Candidate component => DTLS channel
zhihuangb2cdd932017-01-19 16:54:25 -0800376 std::map<int, DtlsTransportInternal*> channels_;
deadbeef49f34fd2016-12-06 16:22:06 -0800377
378 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
379};
380
381} // namespace cricket
382
383#endif // WEBRTC_P2P_BASE_JSEPTRANSPORT_H_