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