blob: c8effd746b7f6c54109331adfd433b75c0b8cc2d [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"
Qingsi Wang7685e862018-06-11 20:15:46 -070022#include "logging/rtc_event_log/rtc_event_log.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080023#include "media/sctp/sctptransportinternal.h"
24#include "p2p/base/dtlstransport.h"
25#include "p2p/base/p2ptransportchannel.h"
26#include "p2p/base/transportfactoryinterface.h"
27#include "pc/channel.h"
28#include "pc/dtlssrtptransport.h"
Zhi Huang365381f2018-04-13 16:44:34 -070029#include "pc/jseptransport.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080030#include "pc/rtptransport.h"
31#include "pc/srtptransport.h"
32#include "rtc_base/asyncinvoker.h"
33#include "rtc_base/constructormagic.h"
34#include "rtc_base/refcountedobject.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080035#include "rtc_base/sslstreamadapter.h"
Artem Titove41c4332018-07-25 15:04:28 +020036#include "rtc_base/third_party/sigslot/sigslot.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080037
38namespace rtc {
39class Thread;
40class PacketTransportInternal;
41} // namespace rtc
42
43namespace webrtc {
44
45class JsepTransportController : public sigslot::has_slots<>,
46 public rtc::MessageHandler {
47 public:
Zhi Huang365381f2018-04-13 16:44:34 -070048 // Used when the RtpTransport/DtlsTransport of the m= section is changed
49 // because the section is rejected or BUNDLE is enabled.
50 class Observer {
51 public:
52 virtual ~Observer() {}
53
54 // Returns true if media associated with |mid| was successfully set up to be
55 // demultiplexed on |rtp_transport|. Could return false if two bundled m=
56 // sections use the same SSRC, for example.
Taylor Brandstettercbaa2542018-04-16 16:42:14 -070057 virtual bool OnTransportChanged(
Zhi Huang365381f2018-04-13 16:44:34 -070058 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 16:42:14 -070059 RtpTransportInternal* rtp_transport,
Zhi Huang365381f2018-04-13 16:44:34 -070060 cricket::DtlsTransportInternal* dtls_transport) = 0;
61 };
62
Zhi Huange818b6e2018-02-22 15:26:27 -080063 struct Config {
64 // If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
65 // upon setting a local transport description that indicates an ICE
66 // restart.
67 bool redetermine_role_on_ice_restart = true;
68 rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
69 // |crypto_options| is used to determine if created DTLS transports
70 // negotiate GCM crypto suites or not.
71 rtc::CryptoOptions crypto_options;
72 PeerConnectionInterface::BundlePolicy bundle_policy =
73 PeerConnectionInterface::kBundlePolicyBalanced;
74 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
75 PeerConnectionInterface::kRtcpMuxPolicyRequire;
76 bool disable_encryption = false;
77 bool enable_external_auth = false;
78 // Used to inject the ICE/DTLS transports created externally.
79 cricket::TransportFactoryInterface* external_transport_factory = nullptr;
Zhi Huang365381f2018-04-13 16:44:34 -070080 Observer* transport_observer = nullptr;
Zhi Huangb57e1692018-06-12 11:41:11 -070081 bool active_reset_srtp_params = false;
Qingsi Wang7685e862018-06-11 20:15:46 -070082 RtcEventLog* event_log = nullptr;
Zhi Huange818b6e2018-02-22 15:26:27 -080083 };
84
85 // The ICE related events are signaled on the |signaling_thread|.
86 // All the transport related methods are called on the |network_thread|.
87 JsepTransportController(rtc::Thread* signaling_thread,
88 rtc::Thread* network_thread,
89 cricket::PortAllocator* port_allocator,
Zach Steine20867f2018-08-02 13:20:15 -070090 AsyncResolverFactory* async_resolver_factory,
Zhi Huange818b6e2018-02-22 15:26:27 -080091 Config config);
92 virtual ~JsepTransportController();
93
94 // The main method to be called; applies a description at the transport
95 // level, creating/destroying transport objects as needed and updating their
96 // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
97 // yet? May make sense to in the future.
98 RTCError SetLocalDescription(SdpType type,
99 const cricket::SessionDescription* description);
100
101 RTCError SetRemoteDescription(SdpType type,
102 const cricket::SessionDescription* description);
103
104 // Get transports to be used for the provided |mid|. If bundling is enabled,
105 // calling GetRtpTransport for multiple MIDs may yield the same object.
106 RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
107 cricket::DtlsTransportInternal* GetDtlsTransport(
108 const std::string& mid) const;
109 cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
110 const std::string& mid) const;
111
112 /*********************
113 * ICE-related methods
114 ********************/
115 // This method is public to allow PeerConnection to update it from
116 // SetConfiguration.
117 void SetIceConfig(const cricket::IceConfig& config);
118 // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
119 // set, offers should generate new ufrags/passwords until an ICE restart
120 // occurs.
121 void SetNeedsIceRestartFlag();
122 // Returns true if the ICE restart flag above was set, and no ICE restart has
123 // occurred yet for this transport (by applying a local description with
124 // changed ufrag/password). If the transport has been deleted as a result of
125 // bundling, returns false.
126 bool NeedsIceRestart(const std::string& mid) const;
127 // Start gathering candidates for any new transports, or transports doing an
128 // ICE restart.
129 void MaybeStartGathering();
130 RTCError AddRemoteCandidates(
131 const std::string& mid,
132 const std::vector<cricket::Candidate>& candidates);
133 RTCError RemoveRemoteCandidates(
134 const std::vector<cricket::Candidate>& candidates);
135
136 /**********************
137 * DTLS-related methods
138 *********************/
139 // Specifies the identity to use in this session.
140 // Can only be called once.
141 bool SetLocalCertificate(
142 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
143 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
144 const std::string& mid) const;
Taylor Brandstetterc3928662018-02-23 13:04:51 -0800145 // Caller owns returned certificate chain. This method mainly exists for
146 // stats reporting.
147 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
Zhi Huange818b6e2018-02-22 15:26:27 -0800148 const std::string& mid) const;
149 // Get negotiated role, if one has been negotiated.
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200150 absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
Zhi Huange818b6e2018-02-22 15:26:27 -0800151
152 // TODO(deadbeef): GetStats isn't const because all the way down to
153 // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
154 // const. Fix this.
155 bool GetStats(const std::string& mid, cricket::TransportStats* stats);
Zhi Huange818b6e2018-02-22 15:26:27 -0800156
Zhi Huange830e682018-03-30 10:48:35 -0700157 bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
Zhi Huang365381f2018-04-13 16:44:34 -0700158
Zhi Huangb57e1692018-06-12 11:41:11 -0700159 void SetActiveResetSrtpParams(bool active_reset_srtp_params);
160
Zhi Huange818b6e2018-02-22 15:26:27 -0800161 // All of these signals are fired on the signaling thread.
162
163 // If any transport failed => failed,
164 // Else if all completed => completed,
165 // Else if all connected => connected,
166 // Else => connecting
167 sigslot::signal1<cricket::IceConnectionState> SignalIceConnectionState;
168
169 // If all transports done gathering => complete,
170 // Else if any are gathering => gathering,
171 // Else => new
172 sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
173
174 // (mid, candidates)
175 sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
176 SignalIceCandidatesGathered;
177
178 sigslot::signal1<const std::vector<cricket::Candidate>&>
179 SignalIceCandidatesRemoved;
180
181 sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
182
Zhi Huange818b6e2018-02-22 15:26:27 -0800183 private:
184 void OnMessage(rtc::Message* pmsg) override;
185
186 RTCError ApplyDescription_n(bool local,
187 SdpType type,
188 const cricket::SessionDescription* description);
Zhi Huangd2248f82018-04-10 14:41:03 -0700189 RTCError ValidateAndMaybeUpdateBundleGroup(
190 bool local,
191 SdpType type,
192 const cricket::SessionDescription* description);
Zhi Huange830e682018-03-30 10:48:35 -0700193 RTCError ValidateContent(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800194
Taylor Brandstettercbaa2542018-04-16 16:42:14 -0700195 void HandleRejectedContent(const cricket::ContentInfo& content_info,
Zhi Huangd2248f82018-04-10 14:41:03 -0700196 const cricket::SessionDescription* description);
Zhi Huang365381f2018-04-13 16:44:34 -0700197 bool HandleBundledContent(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800198
Zhi Huang365381f2018-04-13 16:44:34 -0700199 bool SetTransportForMid(const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 16:42:14 -0700200 cricket::JsepTransport* jsep_transport);
201 void RemoveTransportForMid(const std::string& mid);
Zhi Huangd2248f82018-04-10 14:41:03 -0700202
Zhi Huange818b6e2018-02-22 15:26:27 -0800203 cricket::JsepTransportDescription CreateJsepTransportDescription(
204 cricket::ContentInfo content_info,
205 cricket::TransportInfo transport_info,
Zhi Huange830e682018-03-30 10:48:35 -0700206 const std::vector<int>& encrypted_extension_ids,
207 int rtp_abs_sendtime_extn_id);
Zhi Huange818b6e2018-02-22 15:26:27 -0800208
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200209 absl::optional<std::string> bundled_mid() const {
210 absl::optional<std::string> bundled_mid;
Taylor Brandstetter0ab56512018-04-12 10:30:48 -0700211 if (bundle_group_ && bundle_group_->FirstContentName()) {
212 bundled_mid = *(bundle_group_->FirstContentName());
Zhi Huange818b6e2018-02-22 15:26:27 -0800213 }
214 return bundled_mid;
215 }
216
217 bool IsBundled(const std::string& mid) const {
218 return bundle_group_ && bundle_group_->HasContentName(mid);
219 }
220
221 bool ShouldUpdateBundleGroup(SdpType type,
222 const cricket::SessionDescription* description);
223
224 std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
225 const cricket::SessionDescription* description);
Zhi Huange818b6e2018-02-22 15:26:27 -0800226 std::vector<int> GetEncryptedHeaderExtensionIds(
227 const cricket::ContentInfo& content_info);
228
Zhi Huange830e682018-03-30 10:48:35 -0700229 int GetRtpAbsSendTimeHeaderExtensionId(
230 const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800231
Zhi Huange830e682018-03-30 10:48:35 -0700232 // This method takes the BUNDLE group into account. If the JsepTransport is
233 // destroyed because of BUNDLE, it would return the transport which other
234 // transports are bundled on (In current implementation, it is the first
235 // content in the BUNDLE group).
Zhi Huang365381f2018-04-13 16:44:34 -0700236 const cricket::JsepTransport* GetJsepTransportForMid(
Zhi Huange830e682018-03-30 10:48:35 -0700237 const std::string& mid) const;
Zhi Huang365381f2018-04-13 16:44:34 -0700238 cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
Zhi Huange830e682018-03-30 10:48:35 -0700239
240 // Get the JsepTransport without considering the BUNDLE group. Return nullptr
241 // if the JsepTransport is destroyed.
Zhi Huang365381f2018-04-13 16:44:34 -0700242 const cricket::JsepTransport* GetJsepTransportByName(
Zhi Huange830e682018-03-30 10:48:35 -0700243 const std::string& transport_name) const;
Zhi Huang365381f2018-04-13 16:44:34 -0700244 cricket::JsepTransport* GetJsepTransportByName(
Zhi Huange830e682018-03-30 10:48:35 -0700245 const std::string& transport_name);
246
Zhi Huangd2248f82018-04-10 14:41:03 -0700247 RTCError MaybeCreateJsepTransport(const cricket::ContentInfo& content_info);
Zhi Huange818b6e2018-02-22 15:26:27 -0800248 void MaybeDestroyJsepTransport(const std::string& mid);
249 void DestroyAllJsepTransports_n();
250
251 void SetIceRole_n(cricket::IceRole ice_role);
252
253 cricket::IceRole DetermineIceRole(
Zhi Huang365381f2018-04-13 16:44:34 -0700254 cricket::JsepTransport* jsep_transport,
Zhi Huange818b6e2018-02-22 15:26:27 -0800255 const cricket::TransportInfo& transport_info,
256 SdpType type,
257 bool local);
258
259 std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
260 const std::string& transport_name,
261 bool rtcp);
262
263 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
264 const std::string& transport_name,
265 rtc::PacketTransportInternal* rtp_packet_transport,
266 rtc::PacketTransportInternal* rtcp_packet_transport);
267 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
268 const std::string& transport_name,
Zhi Huange830e682018-03-30 10:48:35 -0700269 cricket::DtlsTransportInternal* rtp_dtls_transport,
270 cricket::DtlsTransportInternal* rtcp_dtls_transport);
Zhi Huange818b6e2018-02-22 15:26:27 -0800271 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
272 const std::string& transport_name,
273 cricket::DtlsTransportInternal* rtp_dtls_transport,
274 cricket::DtlsTransportInternal* rtcp_dtls_transport);
275
276 // Collect all the DtlsTransports, including RTP and RTCP, from the
277 // JsepTransports. JsepTransportController can iterate all the DtlsTransports
278 // and update the aggregate states.
279 std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
280
281 // Handlers for signals from Transport.
282 void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
283 void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
284 void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
285 void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
286 const cricket::Candidate& candidate);
287 void OnTransportCandidatesRemoved(const cricket::Candidates& candidates);
288 void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
289 const cricket::Candidates& candidates);
290 void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
291 void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
292
293 void UpdateAggregateStates_n();
294
295 void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
296
297 rtc::Thread* const signaling_thread_ = nullptr;
298 rtc::Thread* const network_thread_ = nullptr;
299 cricket::PortAllocator* const port_allocator_ = nullptr;
Zach Steine20867f2018-08-02 13:20:15 -0700300 AsyncResolverFactory* const async_resolver_factory_ = nullptr;
Zhi Huange818b6e2018-02-22 15:26:27 -0800301
Zhi Huang365381f2018-04-13 16:44:34 -0700302 std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
Zhi Huange830e682018-03-30 10:48:35 -0700303 jsep_transports_by_name_;
Zhi Huangd2248f82018-04-10 14:41:03 -0700304 // This keeps track of the mapping between media section
Zhi Huang365381f2018-04-13 16:44:34 -0700305 // (BaseChannel/SctpTransport) and the JsepTransport underneath.
306 std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800307
Zhi Huange830e682018-03-30 10:48:35 -0700308 // Aggregate state for Transports.
Zhi Huange818b6e2018-02-22 15:26:27 -0800309 cricket::IceConnectionState ice_connection_state_ =
310 cricket::kIceConnectionConnecting;
311 cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
312
313 Config config_;
314 const cricket::SessionDescription* local_desc_ = nullptr;
315 const cricket::SessionDescription* remote_desc_ = nullptr;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200316 absl::optional<bool> initial_offerer_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800317
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200318 absl::optional<cricket::ContentGroup> bundle_group_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800319
320 cricket::IceConfig ice_config_;
321 cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
322 uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
323 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
324 rtc::AsyncInvoker invoker_;
325
Zhi Huange818b6e2018-02-22 15:26:27 -0800326 RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
327};
328
329} // namespace webrtc
330
331#endif // PC_JSEPTRANSPORTCONTROLLER_H_