1 /*
2  *  Copyright 2018 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_H_
12 #define PC_JSEP_TRANSPORT_H_
13 
14 #include <map>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/candidate.h"
21 #include "api/ice_transport_interface.h"
22 #include "api/jsep.h"
23 #include "api/transport/data_channel_transport_interface.h"
24 #include "media/sctp/sctp_transport_internal.h"
25 #include "p2p/base/dtls_transport.h"
26 #include "p2p/base/p2p_constants.h"
27 #include "p2p/base/transport_info.h"
28 #include "pc/composite_rtp_transport.h"
29 #include "pc/dtls_srtp_transport.h"
30 #include "pc/dtls_transport.h"
31 #include "pc/rtcp_mux_filter.h"
32 #include "pc/rtp_transport.h"
33 #include "pc/sctp_transport.h"
34 #include "pc/session_description.h"
35 #include "pc/srtp_filter.h"
36 #include "pc/srtp_transport.h"
37 #include "pc/transport_stats.h"
38 #include "rtc_base/constructor_magic.h"
39 #include "rtc_base/rtc_certificate.h"
40 #include "rtc_base/ssl_stream_adapter.h"
41 #include "rtc_base/third_party/sigslot/sigslot.h"
42 #include "rtc_base/thread_checker.h"
43 
44 namespace cricket {
45 
46 class DtlsTransportInternal;
47 
48 struct JsepTransportDescription {
49  public:
50   JsepTransportDescription();
51   JsepTransportDescription(
52       bool rtcp_mux_enabled,
53       const std::vector<CryptoParams>& cryptos,
54       const std::vector<int>& encrypted_header_extension_ids,
55       int rtp_abs_sendtime_extn_id,
56       const TransportDescription& transport_description);
57   JsepTransportDescription(const JsepTransportDescription& from);
58   ~JsepTransportDescription();
59 
60   JsepTransportDescription& operator=(const JsepTransportDescription& from);
61 
62   bool rtcp_mux_enabled = true;
63   std::vector<CryptoParams> cryptos;
64   std::vector<int> encrypted_header_extension_ids;
65   int rtp_abs_sendtime_extn_id = -1;
66   // TODO(zhihuang): Add the ICE and DTLS related variables and methods from
67   // TransportDescription and remove this extra layer of abstraction.
68   TransportDescription transport_desc;
69 };
70 
71 // Helper class used by JsepTransportController that processes
72 // TransportDescriptions. A TransportDescription represents the
73 // transport-specific properties of an SDP m= section, processed according to
74 // JSEP. Each transport consists of DTLS and ICE transport channels for RTP
75 // (and possibly RTCP, if rtcp-mux isn't used).
76 //
77 // On Threading: JsepTransport performs work solely on the network thread, and
78 // so its methods should only be called on the network thread.
79 class JsepTransport : public sigslot::has_slots<> {
80  public:
81   // |mid| is just used for log statements in order to identify the Transport.
82   // Note that |local_certificate| is allowed to be null since a remote
83   // description may be set before a local certificate is generated.
84   JsepTransport(
85       const std::string& mid,
86       const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
87       rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
88       rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport,
89       std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
90       std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
91       std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
92       std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport,
93       std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
94       std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
95       std::unique_ptr<SctpTransportInternal> sctp_transport);
96 
97   ~JsepTransport() override;
98 
99   // Returns the MID of this transport. This is only used for logging.
mid()100   const std::string& mid() const { return mid_; }
101 
102   // Must be called before applying local session description.
103   // Needed in order to verify the local fingerprint.
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & local_certificate)104   void SetLocalCertificate(
105       const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate) {
106     RTC_DCHECK_RUN_ON(network_thread_);
107     local_certificate_ = local_certificate;
108   }
109 
110   // Return the local certificate provided by SetLocalCertificate.
GetLocalCertificate()111   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
112     RTC_DCHECK_RUN_ON(network_thread_);
113     return local_certificate_;
114   }
115 
116   webrtc::RTCError SetLocalJsepTransportDescription(
117       const JsepTransportDescription& jsep_description,
118       webrtc::SdpType type) RTC_LOCKS_EXCLUDED(accessor_lock_);
119 
120   // Set the remote TransportDescription to be used by DTLS and ICE channels
121   // that are part of this Transport.
122   webrtc::RTCError SetRemoteJsepTransportDescription(
123       const JsepTransportDescription& jsep_description,
124       webrtc::SdpType type) RTC_LOCKS_EXCLUDED(accessor_lock_);
125   webrtc::RTCError AddRemoteCandidates(const Candidates& candidates)
126       RTC_LOCKS_EXCLUDED(accessor_lock_);
127 
128   // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
129   // set, offers should generate new ufrags/passwords until an ICE restart
130   // occurs.
131   //
132   // This and the below method can be called safely from any thread as long as
133   // SetXTransportDescription is not in progress.
134   void SetNeedsIceRestartFlag() RTC_LOCKS_EXCLUDED(accessor_lock_);
135   // Returns true if the ICE restart flag above was set, and no ICE restart has
136   // occurred yet for this transport (by applying a local description with
137   // changed ufrag/password).
needs_ice_restart()138   bool needs_ice_restart() const RTC_LOCKS_EXCLUDED(accessor_lock_) {
139     rtc::CritScope scope(&accessor_lock_);
140     return needs_ice_restart_;
141   }
142 
143   // Returns role if negotiated, or empty absl::optional if it hasn't been
144   // negotiated yet.
145   absl::optional<rtc::SSLRole> GetDtlsRole() const
146       RTC_LOCKS_EXCLUDED(accessor_lock_);
147 
148   // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
149   bool GetStats(TransportStats* stats) RTC_LOCKS_EXCLUDED(accessor_lock_);
150 
local_description()151   const JsepTransportDescription* local_description() const {
152     RTC_DCHECK_RUN_ON(network_thread_);
153     return local_description_.get();
154   }
155 
remote_description()156   const JsepTransportDescription* remote_description() const {
157     RTC_DCHECK_RUN_ON(network_thread_);
158     return remote_description_.get();
159   }
160 
rtp_transport()161   webrtc::RtpTransportInternal* rtp_transport() const
162       RTC_LOCKS_EXCLUDED(accessor_lock_) {
163     rtc::CritScope scope(&accessor_lock_);
164     if (composite_rtp_transport_) {
165       return composite_rtp_transport_.get();
166     } else if (datagram_rtp_transport_) {
167       return datagram_rtp_transport_.get();
168     } else {
169       return default_rtp_transport();
170     }
171   }
172 
rtp_dtls_transport()173   const DtlsTransportInternal* rtp_dtls_transport() const
174       RTC_LOCKS_EXCLUDED(accessor_lock_) {
175     rtc::CritScope scope(&accessor_lock_);
176     if (rtp_dtls_transport_) {
177       return rtp_dtls_transport_->internal();
178     } else {
179       return nullptr;
180     }
181   }
182 
rtp_dtls_transport()183   DtlsTransportInternal* rtp_dtls_transport()
184       RTC_LOCKS_EXCLUDED(accessor_lock_) {
185     rtc::CritScope scope(&accessor_lock_);
186     return rtp_dtls_transport_locked();
187   }
188 
rtcp_dtls_transport()189   const DtlsTransportInternal* rtcp_dtls_transport() const
190       RTC_LOCKS_EXCLUDED(accessor_lock_) {
191     rtc::CritScope scope(&accessor_lock_);
192     if (rtcp_dtls_transport_) {
193       return rtcp_dtls_transport_->internal();
194     } else {
195       return nullptr;
196     }
197   }
198 
rtcp_dtls_transport()199   DtlsTransportInternal* rtcp_dtls_transport()
200       RTC_LOCKS_EXCLUDED(accessor_lock_) {
201     rtc::CritScope scope(&accessor_lock_);
202     if (rtcp_dtls_transport_) {
203       return rtcp_dtls_transport_->internal();
204     } else {
205       return nullptr;
206     }
207   }
208 
RtpDtlsTransport()209   rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport()
210       RTC_LOCKS_EXCLUDED(accessor_lock_) {
211     rtc::CritScope scope(&accessor_lock_);
212     return rtp_dtls_transport_;
213   }
214 
SctpTransport()215   rtc::scoped_refptr<webrtc::SctpTransport> SctpTransport() const
216       RTC_LOCKS_EXCLUDED(accessor_lock_) {
217     rtc::CritScope scope(&accessor_lock_);
218     return sctp_transport_;
219   }
220 
221   // TODO(bugs.webrtc.org/9719): Delete method, update callers to use
222   // SctpTransport() instead.
data_channel_transport()223   webrtc::DataChannelTransportInterface* data_channel_transport() const
224       RTC_LOCKS_EXCLUDED(accessor_lock_) {
225     rtc::CritScope scope(&accessor_lock_);
226     if (sctp_data_channel_transport_) {
227       return sctp_data_channel_transport_.get();
228     }
229     return nullptr;
230   }
231 
232   // This is signaled when RTCP-mux becomes active and
233   // |rtcp_dtls_transport_| is destroyed. The JsepTransportController will
234   // handle the signal and update the aggregate transport states.
235   sigslot::signal<> SignalRtcpMuxActive;
236 
237   // TODO(deadbeef): The methods below are only public for testing. Should make
238   // them utility functions or objects so they can be tested independently from
239   // this class.
240 
241   // Returns an error if the certificate's identity does not match the
242   // fingerprint, or either is NULL.
243   webrtc::RTCError VerifyCertificateFingerprint(
244       const rtc::RTCCertificate* certificate,
245       const rtc::SSLFingerprint* fingerprint) const;
246 
247   void SetActiveResetSrtpParams(bool active_reset_srtp_params);
248 
249  private:
rtp_dtls_transport_locked()250   DtlsTransportInternal* rtp_dtls_transport_locked()
251       RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_) {
252     if (rtp_dtls_transport_) {
253       return rtp_dtls_transport_->internal();
254     } else {
255       return nullptr;
256     }
257   }
258 
259   bool SetRtcpMux(bool enable, webrtc::SdpType type, ContentSource source);
260 
261   void ActivateRtcpMux();
262 
263   bool SetSdes(const std::vector<CryptoParams>& cryptos,
264                const std::vector<int>& encrypted_extension_ids,
265                webrtc::SdpType type,
266                ContentSource source)
267       RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_);
268 
269   // Negotiates and sets the DTLS parameters based on the current local and
270   // remote transport description, such as the DTLS role to use, and whether
271   // DTLS should be activated.
272   //
273   // Called when an answer TransportDescription is applied.
274   webrtc::RTCError NegotiateAndSetDtlsParameters(
275       webrtc::SdpType local_description_type);
276 
277   // Negotiates the DTLS role based off the offer and answer as specified by
278   // RFC 4145, section-4.1. Returns an RTCError if role cannot be determined
279   // from the local description and remote description.
280   webrtc::RTCError NegotiateDtlsRole(
281       webrtc::SdpType local_description_type,
282       ConnectionRole local_connection_role,
283       ConnectionRole remote_connection_role,
284       absl::optional<rtc::SSLRole>* negotiated_dtls_role)
285       RTC_LOCKS_EXCLUDED(accessor_lock_);
286 
287   // Pushes down the ICE parameters from the remote description.
288   void SetRemoteIceParameters(const IceParameters& ice_parameters,
289                               IceTransportInternal* ice);
290 
291   // Pushes down the DTLS parameters obtained via negotiation.
292   static webrtc::RTCError SetNegotiatedDtlsParameters(
293       DtlsTransportInternal* dtls_transport,
294       absl::optional<rtc::SSLRole> dtls_role,
295       rtc::SSLFingerprint* remote_fingerprint);
296 
297   bool GetTransportStats(DtlsTransportInternal* dtls_transport,
298                          TransportStats* stats)
299       RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_);
300 
301   // Returns the default (non-datagram) rtp transport, if any.
default_rtp_transport()302   webrtc::RtpTransportInternal* default_rtp_transport() const
303       RTC_EXCLUSIVE_LOCKS_REQUIRED(accessor_lock_) {
304     if (dtls_srtp_transport_) {
305       return dtls_srtp_transport_.get();
306     } else if (sdes_transport_) {
307       return sdes_transport_.get();
308     } else if (unencrypted_rtp_transport_) {
309       return unencrypted_rtp_transport_.get();
310     } else {
311       return nullptr;
312     }
313   }
314 
315   // Owning thread, for safety checks
316   const rtc::Thread* const network_thread_;
317   // Critical scope for fields accessed off-thread
318   // TODO(https://bugs.webrtc.org/10300): Stop doing this.
319   rtc::RecursiveCriticalSection accessor_lock_;
320   const std::string mid_;
321   // needs-ice-restart bit as described in JSEP.
322   bool needs_ice_restart_ RTC_GUARDED_BY(accessor_lock_) = false;
323   rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_
324       RTC_GUARDED_BY(network_thread_);
325   std::unique_ptr<JsepTransportDescription> local_description_
326       RTC_GUARDED_BY(network_thread_);
327   std::unique_ptr<JsepTransportDescription> remote_description_
328       RTC_GUARDED_BY(network_thread_);
329 
330   // Ice transport which may be used by any of upper-layer transports (below).
331   // Owned by JsepTransport and guaranteed to outlive the transports below.
332   const rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_;
333   const rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport_;
334 
335   // To avoid downcasting and make it type safe, keep three unique pointers for
336   // different SRTP mode and only one of these is non-nullptr.
337   std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport_
338       RTC_GUARDED_BY(accessor_lock_);
339   std::unique_ptr<webrtc::SrtpTransport> sdes_transport_
340       RTC_GUARDED_BY(accessor_lock_);
341   std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_
342       RTC_GUARDED_BY(accessor_lock_);
343 
344   // If multiple RTP transports are in use, |composite_rtp_transport_| will be
345   // passed to callers.  This is only valid for offer-only, receive-only
346   // scenarios, as it is not possible for the composite to correctly choose
347   // which transport to use for sending.
348   std::unique_ptr<webrtc::CompositeRtpTransport> composite_rtp_transport_
349       RTC_GUARDED_BY(accessor_lock_);
350 
351   rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_
352       RTC_GUARDED_BY(accessor_lock_);
353   rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_
354       RTC_GUARDED_BY(accessor_lock_);
355   rtc::scoped_refptr<webrtc::DtlsTransport> datagram_dtls_transport_
356       RTC_GUARDED_BY(accessor_lock_);
357 
358   std::unique_ptr<webrtc::DataChannelTransportInterface>
359       sctp_data_channel_transport_ RTC_GUARDED_BY(accessor_lock_);
360   rtc::scoped_refptr<webrtc::SctpTransport> sctp_transport_
361       RTC_GUARDED_BY(accessor_lock_);
362 
363   SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_);
364   RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_);
365 
366   // Cache the encrypted header extension IDs for SDES negoitation.
367   absl::optional<std::vector<int>> send_extension_ids_
368       RTC_GUARDED_BY(network_thread_);
369   absl::optional<std::vector<int>> recv_extension_ids_
370       RTC_GUARDED_BY(network_thread_);
371 
372   std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport_
373       RTC_GUARDED_BY(accessor_lock_);
374 
375   RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
376 };
377 
378 }  // namespace cricket
379 
380 #endif  // PC_JSEP_TRANSPORT_H_
381