blob: 794175a6e28dd7925b70ea81b2f35fbad7241273 [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"
28#include "pc/jseptransport2.h"
29#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:
47 struct Config {
48 // If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
49 // upon setting a local transport description that indicates an ICE
50 // restart.
51 bool redetermine_role_on_ice_restart = true;
52 rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
53 // |crypto_options| is used to determine if created DTLS transports
54 // negotiate GCM crypto suites or not.
55 rtc::CryptoOptions crypto_options;
56 PeerConnectionInterface::BundlePolicy bundle_policy =
57 PeerConnectionInterface::kBundlePolicyBalanced;
58 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
59 PeerConnectionInterface::kRtcpMuxPolicyRequire;
60 bool disable_encryption = false;
61 bool enable_external_auth = false;
62 // Used to inject the ICE/DTLS transports created externally.
63 cricket::TransportFactoryInterface* external_transport_factory = nullptr;
64 };
65
66 // The ICE related events are signaled on the |signaling_thread|.
67 // All the transport related methods are called on the |network_thread|.
68 JsepTransportController(rtc::Thread* signaling_thread,
69 rtc::Thread* network_thread,
70 cricket::PortAllocator* port_allocator,
71 Config config);
72 virtual ~JsepTransportController();
73
74 // The main method to be called; applies a description at the transport
75 // level, creating/destroying transport objects as needed and updating their
76 // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
77 // yet? May make sense to in the future.
78 RTCError SetLocalDescription(SdpType type,
79 const cricket::SessionDescription* description);
80
81 RTCError SetRemoteDescription(SdpType type,
82 const cricket::SessionDescription* description);
83
84 // Get transports to be used for the provided |mid|. If bundling is enabled,
85 // calling GetRtpTransport for multiple MIDs may yield the same object.
86 RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
87 cricket::DtlsTransportInternal* GetDtlsTransport(
88 const std::string& mid) const;
89 cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
90 const std::string& mid) const;
91
92 /*********************
93 * ICE-related methods
94 ********************/
95 // This method is public to allow PeerConnection to update it from
96 // SetConfiguration.
97 void SetIceConfig(const cricket::IceConfig& config);
98 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
99 // set, offers should generate new ufrags/passwords until an ICE restart
100 // occurs.
101 void SetNeedsIceRestartFlag();
102 // Returns true if the ICE restart flag above was set, and no ICE restart has
103 // occurred yet for this transport (by applying a local description with
104 // changed ufrag/password). If the transport has been deleted as a result of
105 // bundling, returns false.
106 bool NeedsIceRestart(const std::string& mid) const;
107 // Start gathering candidates for any new transports, or transports doing an
108 // ICE restart.
109 void MaybeStartGathering();
110 RTCError AddRemoteCandidates(
111 const std::string& mid,
112 const std::vector<cricket::Candidate>& candidates);
113 RTCError RemoveRemoteCandidates(
114 const std::vector<cricket::Candidate>& candidates);
115
116 /**********************
117 * DTLS-related methods
118 *********************/
119 // Specifies the identity to use in this session.
120 // Can only be called once.
121 bool SetLocalCertificate(
122 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
123 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
124 const std::string& mid) const;
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800125 // Caller owns returned certificate chain. This method mainly exists for
126 // stats reporting.
127 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
Zhi Huange818b6e2018-02-22 15:26:27 -0800128 const std::string& mid) const;
129 // Get negotiated role, if one has been negotiated.
130 rtc::Optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
131
132 // TODO(deadbeef): GetStats isn't const because all the way down to
133 // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
134 // const. Fix this.
135 bool GetStats(const std::string& mid, cricket::TransportStats* stats);
136 void SetMetricsObserver(webrtc::MetricsObserverInterface* metrics_observer);
137
Zhi Huange830e682018-03-30 10:48:35 -0700138 bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
Zhi Huange818b6e2018-02-22 15:26:27 -0800139 // All of these signals are fired on the signaling thread.
140
141 // If any transport failed => failed,
142 // Else if all completed => completed,
143 // Else if all connected => connected,
144 // Else => connecting
145 sigslot::signal1<cricket::IceConnectionState> SignalIceConnectionState;
146
147 // If all transports done gathering => complete,
148 // Else if any are gathering => gathering,
149 // Else => new
150 sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
151
152 // (mid, candidates)
153 sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
154 SignalIceCandidatesGathered;
155
156 sigslot::signal1<const std::vector<cricket::Candidate>&>
157 SignalIceCandidatesRemoved;
158
159 sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
160
161 // This will be fired when BUNDLE is enabled, the PeerConnection will handle
162 // the signal and set the RtpTransport for the BaseChannel.
163 // The first argument is the MID and the second is the new RtpTransport.
164 // Before firing this signal, the previous RtpTransport must no longer be
165 // referenced.
166 sigslot::signal2<const std::string&, RtpTransportInternal*>
167 SignalRtpTransportChanged;
168
169 // SCTP version of the signal above. PeerConnection will set a new
170 // DtlsTransport for the SctpTransport.
171 sigslot::signal2<const std::string&, cricket::DtlsTransportInternal*>
172 SignalDtlsTransportChanged;
173
174 private:
175 void OnMessage(rtc::Message* pmsg) override;
176
177 RTCError ApplyDescription_n(bool local,
178 SdpType type,
179 const cricket::SessionDescription* description);
Zhi Huangd2248f82018-04-10 14:41:03 -0700180 RTCError ValidateAndMaybeUpdateBundleGroup(
181 bool local,
182 SdpType type,
183 const cricket::SessionDescription* description);
Zhi Huange830e682018-03-30 10:48:35 -0700184 RTCError ValidateContent(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800185
Zhi Huangd2248f82018-04-10 14:41:03 -0700186 void HandleRejectedContent(const cricket::ContentInfo& content_info,
187 const cricket::SessionDescription* description);
Zhi Huange818b6e2018-02-22 15:26:27 -0800188 void HandleBundledContent(const cricket::ContentInfo& content_info);
189
Zhi Huangd2248f82018-04-10 14:41:03 -0700190 void SetTransportForMid(const std::string& mid,
191 cricket::JsepTransport2* jsep_transport,
192 cricket::MediaProtocolType protocol_type);
193 void RemoveTransportForMid(const std::string& mid,
194 cricket::MediaProtocolType protocol_type);
195
Zhi Huange818b6e2018-02-22 15:26:27 -0800196 cricket::JsepTransportDescription CreateJsepTransportDescription(
197 cricket::ContentInfo content_info,
198 cricket::TransportInfo transport_info,
Zhi Huange830e682018-03-30 10:48:35 -0700199 const std::vector<int>& encrypted_extension_ids,
200 int rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800201
202 rtc::Optional<std::string> bundled_mid() const {
203 rtc::Optional<std::string> bundled_mid;
204 if (bundle_group_) {
205 bundled_mid = std::move(*(bundle_group_->FirstContentName()));
206 }
207 return bundled_mid;
208 }
209
210 bool IsBundled(const std::string& mid) const {
211 return bundle_group_ && bundle_group_->HasContentName(mid);
212 }
213
214 bool ShouldUpdateBundleGroup(SdpType type,
215 const cricket::SessionDescription* description);
216
217 std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
218 const cricket::SessionDescription* description);
Zhi Huange818b6e2018-02-22 15:26:27 -0800219 std::vector<int> GetEncryptedHeaderExtensionIds(
220 const cricket::ContentInfo& content_info);
221
Zhi Huange830e682018-03-30 10:48:35 -0700222 int GetRtpAbsSendTimeHeaderExtensionId(
223 const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800224
Zhi Huange830e682018-03-30 10:48:35 -0700225 // This method takes the BUNDLE group into account. If the JsepTransport is
226 // destroyed because of BUNDLE, it would return the transport which other
227 // transports are bundled on (In current implementation, it is the first
228 // content in the BUNDLE group).
229 const cricket::JsepTransport2* GetJsepTransportForMid(
230 const std::string& mid) const;
231 cricket::JsepTransport2* GetJsepTransportForMid(const std::string& mid);
232
233 // Get the JsepTransport without considering the BUNDLE group. Return nullptr
234 // if the JsepTransport is destroyed.
235 const cricket::JsepTransport2* GetJsepTransportByName(
236 const std::string& transport_name) const;
237 cricket::JsepTransport2* GetJsepTransportByName(
238 const std::string& transport_name);
239
Zhi Huangd2248f82018-04-10 14:41:03 -0700240 RTCError MaybeCreateJsepTransport(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800241 void MaybeDestroyJsepTransport(const std::string& mid);
242 void DestroyAllJsepTransports_n();
243
244 void SetIceRole_n(cricket::IceRole ice_role);
245
246 cricket::IceRole DetermineIceRole(
247 cricket::JsepTransport2* jsep_transport,
248 const cricket::TransportInfo& transport_info,
249 SdpType type,
250 bool local);
251
252 std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
253 const std::string& transport_name,
254 bool rtcp);
255
256 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
257 const std::string& transport_name,
258 rtc::PacketTransportInternal* rtp_packet_transport,
259 rtc::PacketTransportInternal* rtcp_packet_transport);
260 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
261 const std::string& transport_name,
Zhi Huange830e682018-03-30 10:48:35 -0700262 cricket::DtlsTransportInternal* rtp_dtls_transport,
263 cricket::DtlsTransportInternal* rtcp_dtls_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800264 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
265 const std::string& transport_name,
266 cricket::DtlsTransportInternal* rtp_dtls_transport,
267 cricket::DtlsTransportInternal* rtcp_dtls_transport);
268
269 // Collect all the DtlsTransports, including RTP and RTCP, from the
270 // JsepTransports. JsepTransportController can iterate all the DtlsTransports
271 // and update the aggregate states.
272 std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
273
274 // Handlers for signals from Transport.
275 void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
276 void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
277 void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
278 void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
279 const cricket::Candidate& candidate);
280 void OnTransportCandidatesRemoved(const cricket::Candidates& candidates);
281 void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
282 const cricket::Candidates& candidates);
283 void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
284 void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
285
286 void UpdateAggregateStates_n();
287
288 void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
289
290 rtc::Thread* const signaling_thread_ = nullptr;
291 rtc::Thread* const network_thread_ = nullptr;
292 cricket::PortAllocator* const port_allocator_ = nullptr;
293
294 std::map<std::string, std::unique_ptr<cricket::JsepTransport2>>
Zhi Huange830e682018-03-30 10:48:35 -0700295 jsep_transports_by_name_;
Zhi Huangd2248f82018-04-10 14:41:03 -0700296 // This keeps track of the mapping between media section
297 // (BaseChannel/SctpTransport) and the JsepTransport2 underneath.
298 std::map<std::string, cricket::JsepTransport2*> mid_to_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800299
Zhi Huange830e682018-03-30 10:48:35 -0700300 // Aggregate state for Transports.
Zhi Huange818b6e2018-02-22 15:26:27 -0800301 cricket::IceConnectionState ice_connection_state_ =
302 cricket::kIceConnectionConnecting;
303 cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
304
305 Config config_;
306 const cricket::SessionDescription* local_desc_ = nullptr;
307 const cricket::SessionDescription* remote_desc_ = nullptr;
308 rtc::Optional<bool> initial_offerer_;
309
310 rtc::Optional<cricket::ContentGroup> bundle_group_;
311
312 cricket::IceConfig ice_config_;
313 cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
314 uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
315 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
316 rtc::AsyncInvoker invoker_;
317
318 webrtc::MetricsObserverInterface* metrics_observer_ = nullptr;
319
320 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
321};
322
323} // namespace webrtc
324
325#endif // PC_JSEPTRANSPORTCONTROLLER_H_