• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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_JSEP_TRANSPORT_CONTROLLER_H_
12 #define PC_JSEP_TRANSPORT_CONTROLLER_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/crypto/crypto_options.h"
22 #include "api/ice_transport_factory.h"
23 #include "api/peer_connection_interface.h"
24 #include "api/rtc_event_log/rtc_event_log.h"
25 #include "media/sctp/sctp_transport_internal.h"
26 #include "p2p/base/dtls_transport.h"
27 #include "p2p/base/dtls_transport_factory.h"
28 #include "p2p/base/p2p_transport_channel.h"
29 #include "pc/channel.h"
30 #include "pc/dtls_srtp_transport.h"
31 #include "pc/dtls_transport.h"
32 #include "pc/jsep_transport.h"
33 #include "pc/rtp_transport.h"
34 #include "pc/srtp_transport.h"
35 #include "rtc_base/async_invoker.h"
36 #include "rtc_base/constructor_magic.h"
37 #include "rtc_base/ref_counted_object.h"
38 #include "rtc_base/third_party/sigslot/sigslot.h"
39 
40 namespace rtc {
41 class Thread;
42 class PacketTransportInternal;
43 }  // namespace rtc
44 
45 namespace webrtc {
46 
47 class JsepTransportController : public sigslot::has_slots<> {
48  public:
49   // Used when the RtpTransport/DtlsTransport of the m= section is changed
50   // because the section is rejected or BUNDLE is enabled.
51   class Observer {
52    public:
~Observer()53     virtual ~Observer() {}
54 
55     // Returns true if media associated with |mid| was successfully set up to be
56     // demultiplexed on |rtp_transport|. Could return false if two bundled m=
57     // sections use the same SSRC, for example.
58     //
59     // If a data channel transport must be negotiated, |data_channel_transport|
60     // and |negotiation_state| indicate negotiation status.  If
61     // |data_channel_transport| is null, the data channel transport should not
62     // be used.  Otherwise, the value is a pointer to the transport to be used
63     // for data channels on |mid|, if any.
64     //
65     // The observer should not send data on |data_channel_transport| until
66     // |negotiation_state| is provisional or final.  It should not delete
67     // |data_channel_transport| or any fallback transport until
68     // |negotiation_state| is final.
69     virtual bool OnTransportChanged(
70         const std::string& mid,
71         RtpTransportInternal* rtp_transport,
72         rtc::scoped_refptr<DtlsTransport> dtls_transport,
73         DataChannelTransportInterface* data_channel_transport) = 0;
74   };
75 
76   struct Config {
77     // If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
78     // upon setting a local transport description that indicates an ICE
79     // restart.
80     bool redetermine_role_on_ice_restart = true;
81     rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
82     // |crypto_options| is used to determine if created DTLS transports
83     // negotiate GCM crypto suites or not.
84     webrtc::CryptoOptions crypto_options;
85     PeerConnectionInterface::BundlePolicy bundle_policy =
86         PeerConnectionInterface::kBundlePolicyBalanced;
87     PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
88         PeerConnectionInterface::kRtcpMuxPolicyRequire;
89     bool disable_encryption = false;
90     bool enable_external_auth = false;
91     // Used to inject the ICE/DTLS transports created externally.
92     webrtc::IceTransportFactory* ice_transport_factory = nullptr;
93     cricket::DtlsTransportFactory* dtls_transport_factory = nullptr;
94     Observer* transport_observer = nullptr;
95     // Must be provided and valid for the lifetime of the
96     // JsepTransportController instance.
97     std::function<void(const rtc::CopyOnWriteBuffer& packet,
98                        int64_t packet_time_us)>
99         rtcp_handler;
100     bool active_reset_srtp_params = false;
101     RtcEventLog* event_log = nullptr;
102 
103     // Factory for SCTP transports.
104     cricket::SctpTransportInternalFactory* sctp_factory = nullptr;
105   };
106 
107   // The ICE related events are signaled on the |signaling_thread|.
108   // All the transport related methods are called on the |network_thread|.
109   JsepTransportController(rtc::Thread* signaling_thread,
110                           rtc::Thread* network_thread,
111                           cricket::PortAllocator* port_allocator,
112                           AsyncResolverFactory* async_resolver_factory,
113                           Config config);
114   virtual ~JsepTransportController();
115 
116   // The main method to be called; applies a description at the transport
117   // level, creating/destroying transport objects as needed and updating their
118   // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
119   // yet? May make sense to in the future.
120   RTCError SetLocalDescription(SdpType type,
121                                const cricket::SessionDescription* description);
122 
123   RTCError SetRemoteDescription(SdpType type,
124                                 const cricket::SessionDescription* description);
125 
126   // Get transports to be used for the provided |mid|. If bundling is enabled,
127   // calling GetRtpTransport for multiple MIDs may yield the same object.
128   RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
129   cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid);
130   const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
131       const std::string& mid) const;
132   // Gets the externally sharable version of the DtlsTransport.
133   rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid(
134       const std::string& mid);
135   rtc::scoped_refptr<SctpTransport> GetSctpTransport(
136       const std::string& mid) const;
137 
138   DataChannelTransportInterface* GetDataChannelTransport(
139       const std::string& mid) const;
140 
141   /*********************
142    * ICE-related methods
143    ********************/
144   // This method is public to allow PeerConnection to update it from
145   // SetConfiguration.
146   void SetIceConfig(const cricket::IceConfig& config);
147   // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
148   // set, offers should generate new ufrags/passwords until an ICE restart
149   // occurs.
150   void SetNeedsIceRestartFlag();
151   // Returns true if the ICE restart flag above was set, and no ICE restart has
152   // occurred yet for this transport (by applying a local description with
153   // changed ufrag/password). If the transport has been deleted as a result of
154   // bundling, returns false.
155   bool NeedsIceRestart(const std::string& mid) const;
156   // Start gathering candidates for any new transports, or transports doing an
157   // ICE restart.
158   void MaybeStartGathering();
159   RTCError AddRemoteCandidates(
160       const std::string& mid,
161       const std::vector<cricket::Candidate>& candidates);
162   RTCError RemoveRemoteCandidates(
163       const std::vector<cricket::Candidate>& candidates);
164 
165   /**********************
166    * DTLS-related methods
167    *********************/
168   // Specifies the identity to use in this session.
169   // Can only be called once.
170   bool SetLocalCertificate(
171       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
172   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
173       const std::string& mid) const;
174   // Caller owns returned certificate chain. This method mainly exists for
175   // stats reporting.
176   std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
177       const std::string& mid) const;
178   // Get negotiated role, if one has been negotiated.
179   absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
180 
181   // TODO(deadbeef): GetStats isn't const because all the way down to
182   // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
183   // const. Fix this.
184   bool GetStats(const std::string& mid, cricket::TransportStats* stats);
185 
initial_offerer()186   bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
187 
188   void SetActiveResetSrtpParams(bool active_reset_srtp_params);
189 
190   // For now the rollback only removes mid to transport mappings
191   // and deletes unused transports, but doesn't consider anything more complex.
192   void RollbackTransports();
193 
194   // All of these signals are fired on the signaling thread.
195 
196   // If any transport failed => failed,
197   // Else if all completed => completed,
198   // Else if all connected => connected,
199   // Else => connecting
200   sigslot::signal1<cricket::IceConnectionState> SignalIceConnectionState;
201 
202   sigslot::signal1<PeerConnectionInterface::PeerConnectionState>
203       SignalConnectionState;
204   sigslot::signal1<PeerConnectionInterface::IceConnectionState>
205       SignalStandardizedIceConnectionState;
206 
207   // If all transports done gathering => complete,
208   // Else if any are gathering => gathering,
209   // Else => new
210   sigslot::signal1<cricket::IceGatheringState> SignalIceGatheringState;
211 
212   // (mid, candidates)
213   sigslot::signal2<const std::string&, const std::vector<cricket::Candidate>&>
214       SignalIceCandidatesGathered;
215 
216   sigslot::signal1<const cricket::IceCandidateErrorEvent&>
217       SignalIceCandidateError;
218 
219   sigslot::signal1<const std::vector<cricket::Candidate>&>
220       SignalIceCandidatesRemoved;
221 
222   sigslot::signal1<const cricket::CandidatePairChangeEvent&>
223       SignalIceCandidatePairChanged;
224 
225   sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
226 
227  private:
228   RTCError ApplyDescription_n(bool local,
229                               SdpType type,
230                               const cricket::SessionDescription* description);
231   RTCError ValidateAndMaybeUpdateBundleGroup(
232       bool local,
233       SdpType type,
234       const cricket::SessionDescription* description);
235   RTCError ValidateContent(const cricket::ContentInfo& content_info);
236 
237   void HandleRejectedContent(const cricket::ContentInfo& content_info,
238                              const cricket::SessionDescription* description);
239   bool HandleBundledContent(const cricket::ContentInfo& content_info);
240 
241   bool SetTransportForMid(const std::string& mid,
242                           cricket::JsepTransport* jsep_transport);
243   void RemoveTransportForMid(const std::string& mid);
244 
245   cricket::JsepTransportDescription CreateJsepTransportDescription(
246       const cricket::ContentInfo& content_info,
247       const cricket::TransportInfo& transport_info,
248       const std::vector<int>& encrypted_extension_ids,
249       int rtp_abs_sendtime_extn_id);
250 
bundled_mid()251   absl::optional<std::string> bundled_mid() const {
252     absl::optional<std::string> bundled_mid;
253     if (bundle_group_ && bundle_group_->FirstContentName()) {
254       bundled_mid = *(bundle_group_->FirstContentName());
255     }
256     return bundled_mid;
257   }
258 
IsBundled(const std::string & mid)259   bool IsBundled(const std::string& mid) const {
260     return bundle_group_ && bundle_group_->HasContentName(mid);
261   }
262 
263   bool ShouldUpdateBundleGroup(SdpType type,
264                                const cricket::SessionDescription* description);
265 
266   std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
267       const cricket::SessionDescription* description);
268   std::vector<int> GetEncryptedHeaderExtensionIds(
269       const cricket::ContentInfo& content_info);
270 
271   int GetRtpAbsSendTimeHeaderExtensionId(
272       const cricket::ContentInfo& content_info);
273 
274   // This method takes the BUNDLE group into account. If the JsepTransport is
275   // destroyed because of BUNDLE, it would return the transport which other
276   // transports are bundled on (In current implementation, it is the first
277   // content in the BUNDLE group).
278   const cricket::JsepTransport* GetJsepTransportForMid(
279       const std::string& mid) const;
280   cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
281 
282   // Get the JsepTransport without considering the BUNDLE group. Return nullptr
283   // if the JsepTransport is destroyed.
284   const cricket::JsepTransport* GetJsepTransportByName(
285       const std::string& transport_name) const;
286   cricket::JsepTransport* GetJsepTransportByName(
287       const std::string& transport_name);
288 
289   // Creates jsep transport. Noop if transport is already created.
290   // Transport is created either during SetLocalDescription (|local| == true) or
291   // during SetRemoteDescription (|local| == false). Passing |local| helps to
292   // differentiate initiator (caller) from answerer (callee).
293   RTCError MaybeCreateJsepTransport(
294       bool local,
295       const cricket::ContentInfo& content_info,
296       const cricket::SessionDescription& description);
297 
298   void MaybeDestroyJsepTransport(const std::string& mid);
299   void DestroyAllJsepTransports_n();
300 
301   void SetIceRole_n(cricket::IceRole ice_role);
302 
303   cricket::IceRole DetermineIceRole(
304       cricket::JsepTransport* jsep_transport,
305       const cricket::TransportInfo& transport_info,
306       SdpType type,
307       bool local);
308 
309   std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
310       const cricket::ContentInfo& content_info,
311       cricket::IceTransportInternal* ice);
312   rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
313       const std::string& transport_name,
314       bool rtcp);
315 
316   std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
317       const std::string& transport_name,
318       rtc::PacketTransportInternal* rtp_packet_transport,
319       rtc::PacketTransportInternal* rtcp_packet_transport);
320   std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
321       const std::string& transport_name,
322       cricket::DtlsTransportInternal* rtp_dtls_transport,
323       cricket::DtlsTransportInternal* rtcp_dtls_transport);
324   std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
325       const std::string& transport_name,
326       cricket::DtlsTransportInternal* rtp_dtls_transport,
327       cricket::DtlsTransportInternal* rtcp_dtls_transport);
328 
329   // Collect all the DtlsTransports, including RTP and RTCP, from the
330   // JsepTransports. JsepTransportController can iterate all the DtlsTransports
331   // and update the aggregate states.
332   std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
333 
334   // Handlers for signals from Transport.
335   void OnTransportWritableState_n(rtc::PacketTransportInternal* transport);
336   void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport);
337   void OnTransportGatheringState_n(cricket::IceTransportInternal* transport);
338   void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
339                                       const cricket::Candidate& candidate);
340   void OnTransportCandidateError_n(
341       cricket::IceTransportInternal* transport,
342       const cricket::IceCandidateErrorEvent& event);
343   void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
344                                       const cricket::Candidates& candidates);
345   void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport);
346   void OnTransportStateChanged_n(cricket::IceTransportInternal* transport);
347   void OnTransportCandidatePairChanged_n(
348       const cricket::CandidatePairChangeEvent& event);
349   void UpdateAggregateStates_n();
350 
351   void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet,
352                               int64_t packet_time_us);
353 
354   void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
355 
356   rtc::Thread* const signaling_thread_ = nullptr;
357   rtc::Thread* const network_thread_ = nullptr;
358   cricket::PortAllocator* const port_allocator_ = nullptr;
359   AsyncResolverFactory* const async_resolver_factory_ = nullptr;
360 
361   std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
362       jsep_transports_by_name_;
363   // This keeps track of the mapping between media section
364   // (BaseChannel/SctpTransport) and the JsepTransport underneath.
365   std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
366   // Keep track of mids that have been mapped to transports. Used for rollback.
367   std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
368   // Aggregate states for Transports.
369   // standardized_ice_connection_state_ is intended to replace
370   // ice_connection_state, see bugs.webrtc.org/9308
371   cricket::IceConnectionState ice_connection_state_ =
372       cricket::kIceConnectionConnecting;
373   PeerConnectionInterface::IceConnectionState
374       standardized_ice_connection_state_ =
375           PeerConnectionInterface::kIceConnectionNew;
376   PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
377       PeerConnectionInterface::PeerConnectionState::kNew;
378   cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
379 
380   Config config_;
381 
382   const cricket::SessionDescription* local_desc_ = nullptr;
383   const cricket::SessionDescription* remote_desc_ = nullptr;
384   absl::optional<bool> initial_offerer_;
385 
386   absl::optional<cricket::ContentGroup> bundle_group_;
387 
388   cricket::IceConfig ice_config_;
389   cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
390   uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
391   rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
392   rtc::AsyncInvoker invoker_;
393 
394   RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
395 };
396 
397 }  // namespace webrtc
398 
399 #endif  // PC_JSEP_TRANSPORT_CONTROLLER_H_
400