blob: ebe105b510d60b7b2c2206769341b979f42e4db7 [file] [log] [blame]
Zhi Huange818b6e2018-02-22 15:26:27 -08001/*
2 * Copyright 2017 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 PC_JSEPTRANSPORTCONTROLLER_H_
12#define PC_JSEPTRANSPORTCONTROLLER_H_
13
14#include <map>
15#include <memory>
16#include <string>
17#include <utility>
18#include <vector>
19
20#include "api/candidate.h"
21#include "api/peerconnectioninterface.h"
22#include "media/sctp/sctptransportinternal.h"
23#include "p2p/base/dtlstransport.h"
24#include "p2p/base/p2ptransportchannel.h"
25#include "p2p/base/transportfactoryinterface.h"
26#include "pc/channel.h"
27#include "pc/dtlssrtptransport.h"
Zhi Huang365381f2018-04-13 16:44:34 -070028#include "pc/jseptransport.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080029#include "pc/rtptransport.h"
30#include "pc/srtptransport.h"
31#include "rtc_base/asyncinvoker.h"
32#include "rtc_base/constructormagic.h"
33#include "rtc_base/refcountedobject.h"
34#include "rtc_base/sigslot.h"
35#include "rtc_base/sslstreamadapter.h"
36
37namespace rtc {
38class Thread;
39class PacketTransportInternal;
40} // namespace rtc
41
42namespace webrtc {
43
44class JsepTransportController : public sigslot::has_slots<>,
45 public rtc::MessageHandler {
46 public:
Zhi Huang365381f2018-04-13 16:44:34 -070047 // Used when the RtpTransport/DtlsTransport of the m= section is changed
48 // because the section is rejected or BUNDLE is enabled.
49 class Observer {
50 public:
51 virtual ~Observer() {}
52
53 // Returns true if media associated with |mid| was successfully set up to be
54 // demultiplexed on |rtp_transport|. Could return false if two bundled m=
55 // sections use the same SSRC, for example.
Taylor Brandstettercbaa2542018-04-16 16:42:14 -070056 virtual bool OnTransportChanged(
Zhi Huang365381f2018-04-13 16:44:34 -070057 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 16:42:14 -070058 RtpTransportInternal* rtp_transport,
Zhi Huang365381f2018-04-13 16:44:34 -070059 cricket::DtlsTransportInternal* dtls_transport) = 0;
60 };
61
Zhi Huange818b6e2018-02-22 15:26:27 -080062 struct Config {
63 // If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
64 // upon setting a local transport description that indicates an ICE
65 // restart.
66 bool redetermine_role_on_ice_restart = true;
67 rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
68 // |crypto_options| is used to determine if created DTLS transports
69 // negotiate GCM crypto suites or not.
70 rtc::CryptoOptions crypto_options;
71 PeerConnectionInterface::BundlePolicy bundle_policy =
72 PeerConnectionInterface::kBundlePolicyBalanced;
73 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
74 PeerConnectionInterface::kRtcpMuxPolicyRequire;
75 bool disable_encryption = false;
76 bool enable_external_auth = false;
77 // Used to inject the ICE/DTLS transports created externally.
78 cricket::TransportFactoryInterface* external_transport_factory = nullptr;
Zhi Huang365381f2018-04-13 16:44:34 -070079 Observer* transport_observer = nullptr;
Zhi Huange818b6e2018-02-22 15:26:27 -080080 };
81
82 // The ICE related events are signaled on the |signaling_thread|.
83 // All the transport related methods are called on the |network_thread|.
84 JsepTransportController(rtc::Thread* signaling_thread,
85 rtc::Thread* network_thread,
86 cricket::PortAllocator* port_allocator,
87 Config config);
88 virtual ~JsepTransportController();
89
90 // The main method to be called; applies a description at the transport
91 // level, creating/destroying transport objects as needed and updating their
92 // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
93 // yet? May make sense to in the future.
94 RTCError SetLocalDescription(SdpType type,
95 const cricket::SessionDescription* description);
96
97 RTCError SetRemoteDescription(SdpType type,
98 const cricket::SessionDescription* description);
99
100 // Get transports to be used for the provided |mid|. If bundling is enabled,
101 // calling GetRtpTransport for multiple MIDs may yield the same object.
102 RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
103 cricket::DtlsTransportInternal* GetDtlsTransport(
104 const std::string& mid) const;
105 cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
106 const std::string& mid) const;
107
108 /*********************
109 * ICE-related methods
110 ********************/
111 // This method is public to allow PeerConnection to update it from
112 // SetConfiguration.
113 void SetIceConfig(const cricket::IceConfig& config);
114 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
115 // set, offers should generate new ufrags/passwords until an ICE restart
116 // occurs.
117 void SetNeedsIceRestartFlag();
118 // Returns true if the ICE restart flag above was set, and no ICE restart has
119 // occurred yet for this transport (by applying a local description with
120 // changed ufrag/password). If the transport has been deleted as a result of
121 // bundling, returns false.
122 bool NeedsIceRestart(const std::string& mid) const;
123 // Start gathering candidates for any new transports, or transports doing an
124 // ICE restart.
125 void MaybeStartGathering();
126 RTCError AddRemoteCandidates(
127 const std::string& mid,
128 const std::vector<cricket::Candidate>& candidates);
129 RTCError RemoveRemoteCandidates(
130 const std::vector<cricket::Candidate>& candidates);
131
132 /**********************
133 * DTLS-related methods
134 *********************/
135 // Specifies the identity to use in this session.
136 // Can only be called once.
137 bool SetLocalCertificate(
138 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
139 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
140 const std::string& mid) const;
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800141 // Caller owns returned certificate chain. This method mainly exists for
142 // stats reporting.
143 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
Zhi Huange818b6e2018-02-22 15:26:27 -0800144 const std::string& mid) const;
145 // Get negotiated role, if one has been negotiated.
146 rtc::Optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
147
148 // TODO(deadbeef): GetStats isn't const because all the way down to
149 // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
150 // const. Fix this.
151 bool GetStats(const std::string& mid, cricket::TransportStats* stats);
152 void SetMetricsObserver(webrtc::MetricsObserverInterface* metrics_observer);
153
Zhi Huange830e682018-03-30 10:48:35 -0700154 bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
Zhi Huang365381f2018-04-13 16:44:34 -0700155
Zhi Huange818b6e2018-02-22 15:26:27 -0800156 // All of these signals are fired on the signaling thread.
157
158 // If any transport failed => failed,
159 // Else if all completed => completed,
160 // Else if all connected => connected,
161 // Else => connecting
162 sigslot::signal1<cricket::IceConnectionState> SignalIceConnectionState;
163
164 // If all transports done gathering => complete,
165 // Else if any are gathering => gathering,
166 // Else => new
167 sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
168
169 // (mid, candidates)
170 sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
171 SignalIceCandidatesGathered;
172
173 sigslot::signal1<const std::vector<cricket::Candidate>&>
174 SignalIceCandidatesRemoved;
175
176 sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
177
Zhi Huange818b6e2018-02-22 15:26:27 -0800178 private:
179 void OnMessage(rtc::Message* pmsg) override;
180
181 RTCError ApplyDescription_n(bool local,
182 SdpType type,
183 const cricket::SessionDescription* description);
Zhi Huangd2248f82018-04-10 14:41:03 -0700184 RTCError ValidateAndMaybeUpdateBundleGroup(
185 bool local,
186 SdpType type,
187 const cricket::SessionDescription* description);
Zhi Huange830e682018-03-30 10:48:35 -0700188 RTCError ValidateContent(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800189
Taylor Brandstettercbaa2542018-04-16 16:42:14 -0700190 void HandleRejectedContent(const cricket::ContentInfo& content_info,
Zhi Huangd2248f82018-04-10 14:41:03 -0700191 const cricket::SessionDescription* description);
Zhi Huang365381f2018-04-13 16:44:34 -0700192 bool HandleBundledContent(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800193
Zhi Huang365381f2018-04-13 16:44:34 -0700194 bool SetTransportForMid(const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 16:42:14 -0700195 cricket::JsepTransport* jsep_transport);
196 void RemoveTransportForMid(const std::string& mid);
Zhi Huangd2248f82018-04-10 14:41:03 -0700197
Zhi Huange818b6e2018-02-22 15:26:27 -0800198 cricket::JsepTransportDescription CreateJsepTransportDescription(
199 cricket::ContentInfo content_info,
200 cricket::TransportInfo transport_info,
Zhi Huange830e682018-03-30 10:48:35 -0700201 const std::vector<int>& encrypted_extension_ids,
202 int rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800203
204 rtc::Optional<std::string> bundled_mid() const {
205 rtc::Optional<std::string> bundled_mid;
Taylor Brandstetter0ab56512018-04-12 10:30:48 -0700206 if (bundle_group_ && bundle_group_->FirstContentName()) {
207 bundled_mid = *(bundle_group_->FirstContentName());
Zhi Huange818b6e2018-02-22 15:26:27 -0800208 }
209 return bundled_mid;
210 }
211
212 bool IsBundled(const std::string& mid) const {
213 return bundle_group_ && bundle_group_->HasContentName(mid);
214 }
215
216 bool ShouldUpdateBundleGroup(SdpType type,
217 const cricket::SessionDescription* description);
218
219 std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
220 const cricket::SessionDescription* description);
Zhi Huange818b6e2018-02-22 15:26:27 -0800221 std::vector<int> GetEncryptedHeaderExtensionIds(
222 const cricket::ContentInfo& content_info);
223
Zhi Huange830e682018-03-30 10:48:35 -0700224 int GetRtpAbsSendTimeHeaderExtensionId(
225 const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800226
Zhi Huange830e682018-03-30 10:48:35 -0700227 // This method takes the BUNDLE group into account. If the JsepTransport is
228 // destroyed because of BUNDLE, it would return the transport which other
229 // transports are bundled on (In current implementation, it is the first
230 // content in the BUNDLE group).
Zhi Huang365381f2018-04-13 16:44:34 -0700231 const cricket::JsepTransport* GetJsepTransportForMid(
Zhi Huange830e682018-03-30 10:48:35 -0700232 const std::string& mid) const;
Zhi Huang365381f2018-04-13 16:44:34 -0700233 cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
Zhi Huange830e682018-03-30 10:48:35 -0700234
235 // Get the JsepTransport without considering the BUNDLE group. Return nullptr
236 // if the JsepTransport is destroyed.
Zhi Huang365381f2018-04-13 16:44:34 -0700237 const cricket::JsepTransport* GetJsepTransportByName(
Zhi Huange830e682018-03-30 10:48:35 -0700238 const std::string& transport_name) const;
Zhi Huang365381f2018-04-13 16:44:34 -0700239 cricket::JsepTransport* GetJsepTransportByName(
Zhi Huange830e682018-03-30 10:48:35 -0700240 const std::string& transport_name);
241
Zhi Huangd2248f82018-04-10 14:41:03 -0700242 RTCError MaybeCreateJsepTransport(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800243 void MaybeDestroyJsepTransport(const std::string& mid);
244 void DestroyAllJsepTransports_n();
245
246 void SetIceRole_n(cricket::IceRole ice_role);
247
248 cricket::IceRole DetermineIceRole(
Zhi Huang365381f2018-04-13 16:44:34 -0700249 cricket::JsepTransport* jsep_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -0800250 const cricket::TransportInfo& transport_info,
251 SdpType type,
252 bool local);
253
254 std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
255 const std::string& transport_name,
256 bool rtcp);
257
258 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
259 const std::string& transport_name,
260 rtc::PacketTransportInternal* rtp_packet_transport,
261 rtc::PacketTransportInternal* rtcp_packet_transport);
262 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
263 const std::string& transport_name,
Zhi Huange830e682018-03-30 10:48:35 -0700264 cricket::DtlsTransportInternal* rtp_dtls_transport,
265 cricket::DtlsTransportInternal* rtcp_dtls_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800266 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
267 const std::string& transport_name,
268 cricket::DtlsTransportInternal* rtp_dtls_transport,
269 cricket::DtlsTransportInternal* rtcp_dtls_transport);
270
271 // Collect all the DtlsTransports, including RTP and RTCP, from the
272 // JsepTransports. JsepTransportController can iterate all the DtlsTransports
273 // and update the aggregate states.
274 std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
275
276 // Handlers for signals from Transport.
277 void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
278 void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
279 void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
280 void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
281 const cricket::Candidate& candidate);
282 void OnTransportCandidatesRemoved(const cricket::Candidates& candidates);
283 void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
284 const cricket::Candidates& candidates);
285 void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
286 void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
287
288 void UpdateAggregateStates_n();
289
290 void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
291
292 rtc::Thread* const signaling_thread_ = nullptr;
293 rtc::Thread* const network_thread_ = nullptr;
294 cricket::PortAllocator* const port_allocator_ = nullptr;
295
Zhi Huang365381f2018-04-13 16:44:34 -0700296 std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
Zhi Huange830e682018-03-30 10:48:35 -0700297 jsep_transports_by_name_;
Zhi Huangd2248f82018-04-10 14:41:03 -0700298 // This keeps track of the mapping between media section
Zhi Huang365381f2018-04-13 16:44:34 -0700299 // (BaseChannel/SctpTransport) and the JsepTransport underneath.
300 std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800301
Zhi Huange830e682018-03-30 10:48:35 -0700302 // Aggregate state for Transports.
Zhi Huange818b6e2018-02-22 15:26:27 -0800303 cricket::IceConnectionState ice_connection_state_ =
304 cricket::kIceConnectionConnecting;
305 cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
306
307 Config config_;
308 const cricket::SessionDescription* local_desc_ = nullptr;
309 const cricket::SessionDescription* remote_desc_ = nullptr;
310 rtc::Optional<bool> initial_offerer_;
311
312 rtc::Optional<cricket::ContentGroup> bundle_group_;
313
314 cricket::IceConfig ice_config_;
315 cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
316 uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
317 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
318 rtc::AsyncInvoker invoker_;
319
320 webrtc::MetricsObserverInterface* metrics_observer_ = nullptr;
321
322 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
323};
324
325} // namespace webrtc
326
327#endif // PC_JSEPTRANSPORTCONTROLLER_H_