2018-02-22 15:26:27 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright 2017 The WebRTC Project Authors. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-01-11 09:11:00 -08:00
|
|
|
#ifndef PC_JSEP_TRANSPORT_CONTROLLER_H_
|
|
|
|
|
#define PC_JSEP_TRANSPORT_CONTROLLER_H_
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "api/candidate.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "api/crypto/crypto_options.h"
|
2019-11-15 12:33:05 -08:00
|
|
|
#include "api/ice_transport_factory.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "api/peer_connection_interface.h"
|
2019-08-07 12:24:53 +02:00
|
|
|
#include "api/rtc_event_log/rtc_event_log.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "media/sctp/sctp_transport_internal.h"
|
|
|
|
|
#include "p2p/base/dtls_transport.h"
|
2019-11-15 12:33:05 -08:00
|
|
|
#include "p2p/base/dtls_transport_factory.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "p2p/base/p2p_transport_channel.h"
|
2018-02-22 15:26:27 -08:00
|
|
|
#include "pc/channel.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "pc/dtls_srtp_transport.h"
|
|
|
|
|
#include "pc/dtls_transport.h"
|
|
|
|
|
#include "pc/jsep_transport.h"
|
|
|
|
|
#include "pc/rtp_transport.h"
|
|
|
|
|
#include "pc/srtp_transport.h"
|
|
|
|
|
#include "rtc_base/async_invoker.h"
|
|
|
|
|
#include "rtc_base/constructor_magic.h"
|
|
|
|
|
#include "rtc_base/ref_counted_object.h"
|
2020-10-23 12:04:40 +02:00
|
|
|
#include "rtc_base/callback_list.h"
|
2018-07-25 15:04:28 +02:00
|
|
|
#include "rtc_base/third_party/sigslot/sigslot.h"
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
namespace rtc {
|
|
|
|
|
class Thread;
|
|
|
|
|
class PacketTransportInternal;
|
|
|
|
|
} // namespace rtc
|
|
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2018-08-31 13:06:05 -07:00
|
|
|
class JsepTransportController : public sigslot::has_slots<> {
|
2018-02-22 15:26:27 -08:00
|
|
|
public:
|
2018-04-13 16:44:34 -07:00
|
|
|
// Used when the RtpTransport/DtlsTransport of the m= section is changed
|
|
|
|
|
// because the section is rejected or BUNDLE is enabled.
|
|
|
|
|
class Observer {
|
|
|
|
|
public:
|
|
|
|
|
virtual ~Observer() {}
|
|
|
|
|
|
|
|
|
|
// Returns true if media associated with |mid| was successfully set up to be
|
|
|
|
|
// demultiplexed on |rtp_transport|. Could return false if two bundled m=
|
|
|
|
|
// sections use the same SSRC, for example.
|
Changes to enable use of DatagramTransport as a data channel transport.
PeerConnection now has a new setting in RTCConfiguration to enable use of
datagram transport for data channels. There is also a corresponding field
trial, which has both a kill-switch and a way to change the default value.
PeerConnection's interaction with MediaTransport for data channels has been
refactored to work with DataChannelTransportInterface instead.
Adds a DataChannelState and OnStateChanged() to the DataChannelSink
callbacks. This allows PeerConnection to listen to the data channel's
state directly, instead of indirectly by monitoring media transport
state. This is necessary to enable use of non-media-transport (eg.
datagram transport) data channel transports.
For now, PeerConnection watches the state through MediaTransport as well.
This will persist until MediaTransport implements the new callback.
Datagram transport use is negotiated. As such, an offer that requests to use
datagram transport for data channels may be rejected by the answerer. If the
offer includes DTLS, the data channels will be negotiated as SCTP/DTLS data
channels with an extra x-opaque parameter for datagram transport. If the
opaque parameter is rejected (by an answerer without datagram support), the
offerer may fall back to SCTP.
If DTLS is not enabled, there is no viable fallback. In this case, the data
channels are negotiated as media transport data channels. If the receiver does
not understand the x-opaque line, it will reject these data channels, and the
offerer's data channels will be closed.
Bug: webrtc:9719
Change-Id: Ic1bf3664c4bcf9d754482df59897f5f72fe68fcc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/147702
Commit-Queue: Bjorn Mellem <mellem@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28932}
2019-08-21 10:44:59 -07:00
|
|
|
//
|
|
|
|
|
// If a data channel transport must be negotiated, |data_channel_transport|
|
|
|
|
|
// and |negotiation_state| indicate negotiation status. If
|
|
|
|
|
// |data_channel_transport| is null, the data channel transport should not
|
|
|
|
|
// be used. Otherwise, the value is a pointer to the transport to be used
|
|
|
|
|
// for data channels on |mid|, if any.
|
|
|
|
|
//
|
|
|
|
|
// The observer should not send data on |data_channel_transport| until
|
|
|
|
|
// |negotiation_state| is provisional or final. It should not delete
|
|
|
|
|
// |data_channel_transport| or any fallback transport until
|
|
|
|
|
// |negotiation_state| is final.
|
2018-04-16 16:42:14 -07:00
|
|
|
virtual bool OnTransportChanged(
|
2018-04-13 16:44:34 -07:00
|
|
|
const std::string& mid,
|
2018-04-16 16:42:14 -07:00
|
|
|
RtpTransportInternal* rtp_transport,
|
2019-02-28 07:51:00 +01:00
|
|
|
rtc::scoped_refptr<DtlsTransport> dtls_transport,
|
2019-09-23 14:53:54 -07:00
|
|
|
DataChannelTransportInterface* data_channel_transport) = 0;
|
2018-04-13 16:44:34 -07:00
|
|
|
};
|
|
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
struct Config {
|
|
|
|
|
// If |redetermine_role_on_ice_restart| is true, ICE role is redetermined
|
|
|
|
|
// upon setting a local transport description that indicates an ICE
|
|
|
|
|
// restart.
|
|
|
|
|
bool redetermine_role_on_ice_restart = true;
|
|
|
|
|
rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
|
|
|
|
|
// |crypto_options| is used to determine if created DTLS transports
|
|
|
|
|
// negotiate GCM crypto suites or not.
|
2018-10-11 15:33:17 -07:00
|
|
|
webrtc::CryptoOptions crypto_options;
|
2018-02-22 15:26:27 -08:00
|
|
|
PeerConnectionInterface::BundlePolicy bundle_policy =
|
|
|
|
|
PeerConnectionInterface::kBundlePolicyBalanced;
|
|
|
|
|
PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
|
|
|
|
|
PeerConnectionInterface::kRtcpMuxPolicyRequire;
|
|
|
|
|
bool disable_encryption = false;
|
|
|
|
|
bool enable_external_auth = false;
|
|
|
|
|
// Used to inject the ICE/DTLS transports created externally.
|
2019-11-15 12:33:05 -08:00
|
|
|
webrtc::IceTransportFactory* ice_transport_factory = nullptr;
|
|
|
|
|
cricket::DtlsTransportFactory* dtls_transport_factory = nullptr;
|
2018-04-13 16:44:34 -07:00
|
|
|
Observer* transport_observer = nullptr;
|
2019-09-18 18:22:12 +02:00
|
|
|
// Must be provided and valid for the lifetime of the
|
|
|
|
|
// JsepTransportController instance.
|
|
|
|
|
std::function<void(const rtc::CopyOnWriteBuffer& packet,
|
|
|
|
|
int64_t packet_time_us)>
|
|
|
|
|
rtcp_handler;
|
2018-06-12 11:41:11 -07:00
|
|
|
bool active_reset_srtp_params = false;
|
2018-06-11 20:15:46 -07:00
|
|
|
RtcEventLog* event_log = nullptr;
|
2018-10-10 10:34:49 -07:00
|
|
|
|
2019-09-23 14:53:54 -07:00
|
|
|
// Factory for SCTP transports.
|
2020-08-28 09:15:15 +02:00
|
|
|
SctpTransportFactoryInterface* sctp_factory = nullptr;
|
2021-01-27 23:32:46 -08:00
|
|
|
std::function<void(const rtc::SSLHandshakeError)> on_dtls_handshake_error_;
|
2018-02-22 15:26:27 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// The ICE related events are signaled on the |signaling_thread|.
|
|
|
|
|
// All the transport related methods are called on the |network_thread|.
|
|
|
|
|
JsepTransportController(rtc::Thread* signaling_thread,
|
|
|
|
|
rtc::Thread* network_thread,
|
|
|
|
|
cricket::PortAllocator* port_allocator,
|
2018-08-02 13:20:15 -07:00
|
|
|
AsyncResolverFactory* async_resolver_factory,
|
2018-02-22 15:26:27 -08:00
|
|
|
Config config);
|
|
|
|
|
virtual ~JsepTransportController();
|
|
|
|
|
|
|
|
|
|
// The main method to be called; applies a description at the transport
|
|
|
|
|
// level, creating/destroying transport objects as needed and updating their
|
|
|
|
|
// properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
|
|
|
|
|
// yet? May make sense to in the future.
|
|
|
|
|
RTCError SetLocalDescription(SdpType type,
|
|
|
|
|
const cricket::SessionDescription* description);
|
|
|
|
|
|
|
|
|
|
RTCError SetRemoteDescription(SdpType type,
|
|
|
|
|
const cricket::SessionDescription* description);
|
|
|
|
|
|
|
|
|
|
// Get transports to be used for the provided |mid|. If bundling is enabled,
|
|
|
|
|
// calling GetRtpTransport for multiple MIDs may yield the same object.
|
|
|
|
|
RtpTransportInternal* GetRtpTransport(const std::string& mid) const;
|
2018-11-28 16:47:46 +01:00
|
|
|
cricket::DtlsTransportInternal* GetDtlsTransport(const std::string& mid);
|
|
|
|
|
const cricket::DtlsTransportInternal* GetRtcpDtlsTransport(
|
2018-02-22 15:26:27 -08:00
|
|
|
const std::string& mid) const;
|
2018-11-28 16:47:46 +01:00
|
|
|
// Gets the externally sharable version of the DtlsTransport.
|
2019-01-17 10:39:40 +01:00
|
|
|
rtc::scoped_refptr<webrtc::DtlsTransport> LookupDtlsTransportByMid(
|
2018-11-28 16:47:46 +01:00
|
|
|
const std::string& mid);
|
2019-09-23 14:53:54 -07:00
|
|
|
rtc::scoped_refptr<SctpTransport> GetSctpTransport(
|
|
|
|
|
const std::string& mid) const;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
Changes to enable use of DatagramTransport as a data channel transport.
PeerConnection now has a new setting in RTCConfiguration to enable use of
datagram transport for data channels. There is also a corresponding field
trial, which has both a kill-switch and a way to change the default value.
PeerConnection's interaction with MediaTransport for data channels has been
refactored to work with DataChannelTransportInterface instead.
Adds a DataChannelState and OnStateChanged() to the DataChannelSink
callbacks. This allows PeerConnection to listen to the data channel's
state directly, instead of indirectly by monitoring media transport
state. This is necessary to enable use of non-media-transport (eg.
datagram transport) data channel transports.
For now, PeerConnection watches the state through MediaTransport as well.
This will persist until MediaTransport implements the new callback.
Datagram transport use is negotiated. As such, an offer that requests to use
datagram transport for data channels may be rejected by the answerer. If the
offer includes DTLS, the data channels will be negotiated as SCTP/DTLS data
channels with an extra x-opaque parameter for datagram transport. If the
opaque parameter is rejected (by an answerer without datagram support), the
offerer may fall back to SCTP.
If DTLS is not enabled, there is no viable fallback. In this case, the data
channels are negotiated as media transport data channels. If the receiver does
not understand the x-opaque line, it will reject these data channels, and the
offerer's data channels will be closed.
Bug: webrtc:9719
Change-Id: Ic1bf3664c4bcf9d754482df59897f5f72fe68fcc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/147702
Commit-Queue: Bjorn Mellem <mellem@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28932}
2019-08-21 10:44:59 -07:00
|
|
|
DataChannelTransportInterface* GetDataChannelTransport(
|
2019-05-23 15:50:38 -07:00
|
|
|
const std::string& mid) const;
|
|
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
/*********************
|
|
|
|
|
* ICE-related methods
|
|
|
|
|
********************/
|
|
|
|
|
// This method is public to allow PeerConnection to update it from
|
|
|
|
|
// SetConfiguration.
|
|
|
|
|
void SetIceConfig(const cricket::IceConfig& config);
|
|
|
|
|
// Set the "needs-ice-restart" flag as described in JSEP. After the flag is
|
|
|
|
|
// set, offers should generate new ufrags/passwords until an ICE restart
|
|
|
|
|
// occurs.
|
|
|
|
|
void SetNeedsIceRestartFlag();
|
|
|
|
|
// Returns true if the ICE restart flag above was set, and no ICE restart has
|
|
|
|
|
// occurred yet for this transport (by applying a local description with
|
|
|
|
|
// changed ufrag/password). If the transport has been deleted as a result of
|
|
|
|
|
// bundling, returns false.
|
|
|
|
|
bool NeedsIceRestart(const std::string& mid) const;
|
|
|
|
|
// Start gathering candidates for any new transports, or transports doing an
|
|
|
|
|
// ICE restart.
|
|
|
|
|
void MaybeStartGathering();
|
|
|
|
|
RTCError AddRemoteCandidates(
|
|
|
|
|
const std::string& mid,
|
|
|
|
|
const std::vector<cricket::Candidate>& candidates);
|
|
|
|
|
RTCError RemoveRemoteCandidates(
|
|
|
|
|
const std::vector<cricket::Candidate>& candidates);
|
|
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
|
* DTLS-related methods
|
|
|
|
|
*********************/
|
|
|
|
|
// Specifies the identity to use in this session.
|
|
|
|
|
// Can only be called once.
|
|
|
|
|
bool SetLocalCertificate(
|
|
|
|
|
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
|
|
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate(
|
|
|
|
|
const std::string& mid) const;
|
2018-02-23 13:04:51 -08:00
|
|
|
// Caller owns returned certificate chain. This method mainly exists for
|
|
|
|
|
// stats reporting.
|
|
|
|
|
std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
|
2018-02-22 15:26:27 -08:00
|
|
|
const std::string& mid) const;
|
|
|
|
|
// Get negotiated role, if one has been negotiated.
|
2018-06-19 16:47:43 +02:00
|
|
|
absl::optional<rtc::SSLRole> GetDtlsRole(const std::string& mid) const;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
// TODO(deadbeef): GetStats isn't const because all the way down to
|
|
|
|
|
// OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not
|
|
|
|
|
// const. Fix this.
|
|
|
|
|
bool GetStats(const std::string& mid, cricket::TransportStats* stats);
|
|
|
|
|
|
2018-03-30 10:48:35 -07:00
|
|
|
bool initial_offerer() const { return initial_offerer_ && *initial_offerer_; }
|
2018-04-13 16:44:34 -07:00
|
|
|
|
2018-06-12 11:41:11 -07:00
|
|
|
void SetActiveResetSrtpParams(bool active_reset_srtp_params);
|
|
|
|
|
|
2020-02-19 20:41:07 +02:00
|
|
|
// For now the rollback only removes mid to transport mappings
|
2019-11-25 18:49:44 +02:00
|
|
|
// and deletes unused transports, but doesn't consider anything more complex.
|
2020-02-19 20:41:07 +02:00
|
|
|
void RollbackTransports();
|
2019-10-09 18:29:44 +03:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
// F: void(const std::string&, const std::vector<cricket::Candidate>&)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceCandidateGathered(F&& callback) {
|
|
|
|
|
signal_ice_candidates_gathered_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(cricket::IceConnectionState)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceConnectionState(F&& callback) {
|
|
|
|
|
signal_ice_connection_state_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(PeerConnectionInterface::PeerConnectionState)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeConnectionState(F&& callback) {
|
|
|
|
|
signal_connection_state_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(PeerConnectionInterface::IceConnectionState)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeStandardizedIceConnectionState(F&& callback) {
|
|
|
|
|
signal_standardized_ice_connection_state_.AddReceiver(
|
|
|
|
|
std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(cricket::IceGatheringState)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceGatheringState(F&& callback) {
|
|
|
|
|
signal_ice_gathering_state_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(const cricket::IceCandidateErrorEvent&)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceCandidateError(F&& callback) {
|
|
|
|
|
signal_ice_candidate_error_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(const std::vector<cricket::Candidate>&)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceCandidatesRemoved(F&& callback) {
|
|
|
|
|
signal_ice_candidates_removed_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// F: void(const cricket::CandidatePairChangeEvent&)
|
|
|
|
|
template <typename F>
|
|
|
|
|
void SubscribeIceCandidatePairChanged(F&& callback) {
|
|
|
|
|
signal_ice_candidate_pair_changed_.AddReceiver(std::forward<F>(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// All of these callbacks are fired on the signaling thread.
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
// If any transport failed => failed,
|
|
|
|
|
// Else if all completed => completed,
|
|
|
|
|
// Else if all connected => connected,
|
|
|
|
|
// Else => connecting
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<cricket::IceConnectionState> signal_ice_connection_state_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<PeerConnectionInterface::PeerConnectionState>
|
|
|
|
|
signal_connection_state_;
|
2020-09-30 14:33:45 -07:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<PeerConnectionInterface::IceConnectionState>
|
|
|
|
|
signal_standardized_ice_connection_state_;
|
2018-10-18 15:58:17 +02:00
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
// If all transports done gathering => complete,
|
|
|
|
|
// Else if any are gathering => gathering,
|
|
|
|
|
// Else => new
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<cricket::IceGatheringState> signal_ice_gathering_state_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
// [mid, candidates]
|
|
|
|
|
CallbackList<const std::string&, const std::vector<cricket::Candidate>&>
|
|
|
|
|
signal_ice_candidates_gathered_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<const cricket::IceCandidateErrorEvent&>
|
|
|
|
|
signal_ice_candidate_error_;
|
2019-06-01 12:23:43 +03:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<const std::vector<cricket::Candidate>&>
|
|
|
|
|
signal_ice_candidates_removed_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2021-01-18 23:32:22 -08:00
|
|
|
CallbackList<const cricket::CandidatePairChangeEvent&>
|
|
|
|
|
signal_ice_candidate_pair_changed_;
|
2019-08-06 10:54:47 -07:00
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
RTCError ApplyDescription_n(bool local,
|
|
|
|
|
SdpType type,
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::SessionDescription* description)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2018-04-10 14:41:03 -07:00
|
|
|
RTCError ValidateAndMaybeUpdateBundleGroup(
|
|
|
|
|
bool local,
|
|
|
|
|
SdpType type,
|
|
|
|
|
const cricket::SessionDescription* description);
|
2018-03-30 10:48:35 -07:00
|
|
|
RTCError ValidateContent(const cricket::ContentInfo& content_info);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-04-16 16:42:14 -07:00
|
|
|
void HandleRejectedContent(const cricket::ContentInfo& content_info,
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::SessionDescription* description)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
bool HandleBundledContent(const cricket::ContentInfo& content_info)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-04-13 16:44:34 -07:00
|
|
|
bool SetTransportForMid(const std::string& mid,
|
2018-04-16 16:42:14 -07:00
|
|
|
cricket::JsepTransport* jsep_transport);
|
|
|
|
|
void RemoveTransportForMid(const std::string& mid);
|
2018-04-10 14:41:03 -07:00
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
cricket::JsepTransportDescription CreateJsepTransportDescription(
|
2019-06-03 20:35:45 +02:00
|
|
|
const cricket::ContentInfo& content_info,
|
|
|
|
|
const cricket::TransportInfo& transport_info,
|
2018-03-30 10:48:35 -07:00
|
|
|
const std::vector<int>& encrypted_extension_ids,
|
2020-06-18 10:10:17 +02:00
|
|
|
int rtp_abs_sendtime_extn_id);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-06-19 16:47:43 +02:00
|
|
|
absl::optional<std::string> bundled_mid() const {
|
|
|
|
|
absl::optional<std::string> bundled_mid;
|
2018-04-12 10:30:48 -07:00
|
|
|
if (bundle_group_ && bundle_group_->FirstContentName()) {
|
|
|
|
|
bundled_mid = *(bundle_group_->FirstContentName());
|
2018-02-22 15:26:27 -08:00
|
|
|
}
|
|
|
|
|
return bundled_mid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsBundled(const std::string& mid) const {
|
|
|
|
|
return bundle_group_ && bundle_group_->HasContentName(mid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ShouldUpdateBundleGroup(SdpType type,
|
|
|
|
|
const cricket::SessionDescription* description);
|
|
|
|
|
|
|
|
|
|
std::vector<int> MergeEncryptedHeaderExtensionIdsForBundle(
|
|
|
|
|
const cricket::SessionDescription* description);
|
|
|
|
|
std::vector<int> GetEncryptedHeaderExtensionIds(
|
|
|
|
|
const cricket::ContentInfo& content_info);
|
|
|
|
|
|
2018-03-30 10:48:35 -07:00
|
|
|
int GetRtpAbsSendTimeHeaderExtensionId(
|
|
|
|
|
const cricket::ContentInfo& content_info);
|
|
|
|
|
|
|
|
|
|
// This method takes the BUNDLE group into account. If the JsepTransport is
|
|
|
|
|
// destroyed because of BUNDLE, it would return the transport which other
|
|
|
|
|
// transports are bundled on (In current implementation, it is the first
|
|
|
|
|
// content in the BUNDLE group).
|
2018-04-13 16:44:34 -07:00
|
|
|
const cricket::JsepTransport* GetJsepTransportForMid(
|
2018-03-30 10:48:35 -07:00
|
|
|
const std::string& mid) const;
|
2018-04-13 16:44:34 -07:00
|
|
|
cricket::JsepTransport* GetJsepTransportForMid(const std::string& mid);
|
2018-03-30 10:48:35 -07:00
|
|
|
|
|
|
|
|
// Get the JsepTransport without considering the BUNDLE group. Return nullptr
|
|
|
|
|
// if the JsepTransport is destroyed.
|
2018-04-13 16:44:34 -07:00
|
|
|
const cricket::JsepTransport* GetJsepTransportByName(
|
2018-03-30 10:48:35 -07:00
|
|
|
const std::string& transport_name) const;
|
2018-04-13 16:44:34 -07:00
|
|
|
cricket::JsepTransport* GetJsepTransportByName(
|
2018-03-30 10:48:35 -07:00
|
|
|
const std::string& transport_name);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-10-10 10:34:49 -07:00
|
|
|
// Creates jsep transport. Noop if transport is already created.
|
|
|
|
|
// Transport is created either during SetLocalDescription (|local| == true) or
|
|
|
|
|
// during SetRemoteDescription (|local| == false). Passing |local| helps to
|
|
|
|
|
// differentiate initiator (caller) from answerer (callee).
|
2019-02-27 14:26:15 -08:00
|
|
|
RTCError MaybeCreateJsepTransport(
|
|
|
|
|
bool local,
|
|
|
|
|
const cricket::ContentInfo& content_info,
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::SessionDescription& description)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2018-11-16 14:13:58 -08:00
|
|
|
|
2021-01-18 14:00:36 +01:00
|
|
|
void MaybeDestroyJsepTransport(const std::string& mid)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void DestroyAllJsepTransports_n() RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2021-01-18 14:00:36 +01:00
|
|
|
void SetIceRole_n(cricket::IceRole ice_role) RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
cricket::IceRole DetermineIceRole(
|
2018-04-13 16:44:34 -07:00
|
|
|
cricket::JsepTransport* jsep_transport,
|
2018-02-22 15:26:27 -08:00
|
|
|
const cricket::TransportInfo& transport_info,
|
|
|
|
|
SdpType type,
|
|
|
|
|
bool local);
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<cricket::DtlsTransportInternal> CreateDtlsTransport(
|
2019-07-10 15:44:56 -07:00
|
|
|
const cricket::ContentInfo& content_info,
|
2020-06-16 16:39:13 +02:00
|
|
|
cricket::IceTransportInternal* ice);
|
2019-11-15 12:33:05 -08:00
|
|
|
rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
|
|
|
|
|
const std::string& transport_name,
|
2018-02-22 15:26:27 -08:00
|
|
|
bool rtcp);
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedRtpTransport(
|
|
|
|
|
const std::string& transport_name,
|
|
|
|
|
rtc::PacketTransportInternal* rtp_packet_transport,
|
|
|
|
|
rtc::PacketTransportInternal* rtcp_packet_transport);
|
|
|
|
|
std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
|
|
|
|
|
const std::string& transport_name,
|
2018-03-30 10:48:35 -07:00
|
|
|
cricket::DtlsTransportInternal* rtp_dtls_transport,
|
|
|
|
|
cricket::DtlsTransportInternal* rtcp_dtls_transport);
|
2018-02-22 15:26:27 -08:00
|
|
|
std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
|
|
|
|
|
const std::string& transport_name,
|
|
|
|
|
cricket::DtlsTransportInternal* rtp_dtls_transport,
|
|
|
|
|
cricket::DtlsTransportInternal* rtcp_dtls_transport);
|
|
|
|
|
|
|
|
|
|
// Collect all the DtlsTransports, including RTP and RTCP, from the
|
|
|
|
|
// JsepTransports. JsepTransportController can iterate all the DtlsTransports
|
|
|
|
|
// and update the aggregate states.
|
|
|
|
|
std::vector<cricket::DtlsTransportInternal*> GetDtlsTransports();
|
|
|
|
|
|
|
|
|
|
// Handlers for signals from Transport.
|
2021-01-18 14:00:36 +01:00
|
|
|
void OnTransportWritableState_n(rtc::PacketTransportInternal* transport)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void OnTransportReceivingState_n(rtc::PacketTransportInternal* transport)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void OnTransportGatheringState_n(cricket::IceTransportInternal* transport)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
void OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::Candidate& candidate)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void OnTransportCandidateError_n(cricket::IceTransportInternal* transport,
|
|
|
|
|
const cricket::IceCandidateErrorEvent& event)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
void OnTransportCandidatesRemoved_n(cricket::IceTransportInternal* transport,
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::Candidates& candidates)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void OnTransportRoleConflict_n(cricket::IceTransportInternal* transport)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void OnTransportStateChanged_n(cricket::IceTransportInternal* transport)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2019-08-06 10:54:47 -07:00
|
|
|
void OnTransportCandidatePairChanged_n(
|
2021-01-18 14:00:36 +01:00
|
|
|
const cricket::CandidatePairChangeEvent& event)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
|
|
|
|
void UpdateAggregateStates_n() RTC_RUN_ON(network_thread_);
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2019-09-18 18:22:12 +02:00
|
|
|
void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet,
|
2021-01-18 14:00:36 +01:00
|
|
|
int64_t packet_time_us)
|
|
|
|
|
RTC_RUN_ON(network_thread_);
|
2019-09-18 18:22:12 +02:00
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
|
|
|
|
|
|
|
|
|
rtc::Thread* const signaling_thread_ = nullptr;
|
|
|
|
|
rtc::Thread* const network_thread_ = nullptr;
|
|
|
|
|
cricket::PortAllocator* const port_allocator_ = nullptr;
|
2018-08-02 13:20:15 -07:00
|
|
|
AsyncResolverFactory* const async_resolver_factory_ = nullptr;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-04-13 16:44:34 -07:00
|
|
|
std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
|
2018-03-30 10:48:35 -07:00
|
|
|
jsep_transports_by_name_;
|
2018-04-10 14:41:03 -07:00
|
|
|
// This keeps track of the mapping between media section
|
2018-04-13 16:44:34 -07:00
|
|
|
// (BaseChannel/SctpTransport) and the JsepTransport underneath.
|
|
|
|
|
std::map<std::string, cricket::JsepTransport*> mid_to_transport_;
|
2020-02-19 20:41:07 +02:00
|
|
|
// Keep track of mids that have been mapped to transports. Used for rollback.
|
|
|
|
|
std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
|
2018-10-18 15:58:17 +02:00
|
|
|
// Aggregate states for Transports.
|
2018-11-23 16:18:59 +00:00
|
|
|
// standardized_ice_connection_state_ is intended to replace
|
|
|
|
|
// ice_connection_state, see bugs.webrtc.org/9308
|
|
|
|
|
cricket::IceConnectionState ice_connection_state_ =
|
|
|
|
|
cricket::kIceConnectionConnecting;
|
|
|
|
|
PeerConnectionInterface::IceConnectionState
|
|
|
|
|
standardized_ice_connection_state_ =
|
|
|
|
|
PeerConnectionInterface::kIceConnectionNew;
|
2018-10-18 15:58:17 +02:00
|
|
|
PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
|
|
|
|
|
PeerConnectionInterface::PeerConnectionState::kNew;
|
2018-02-22 15:26:27 -08:00
|
|
|
cricket::IceGatheringState ice_gathering_state_ = cricket::kIceGatheringNew;
|
|
|
|
|
|
|
|
|
|
Config config_;
|
Add x-mt line to the offer.
We already support decoding of the x-mt line. This change adds the
a=x-mt line to the SDP offer. This is not a backward compatible change
for media transport (because of the changes in pre-shared key handling)
1) if media transport is enabled, and SDES is enabled, generate the
media transport offer.
2) if media transport generated the offer, add that offer to the x-mt
line.
3) in order to create media transport, require an x-mt line (backward incompatible).
The way it works is that
1) PeerConnection, on the offerer, asks jsep transport for the
configuration of the media transport.
2) Tentative media transport is created in JsepTransportController when
that happens.
3) SessionDescription will include configuration from this tentative
media transport.
4) When the LocalDescription is set on the offerer, the tentative media
transport is promoted to the real media transport.
Caveats:
- now we really only support MaxBundle. In the previous implementations,
two media transports were briefly created in some tests, and the second
one was destroyed shortly after instantiation.
- we, for now, enforce SDES. In the future, whether SDES is used will be
refactored out of the peer connection.
In the future (on the callee) we should ignore 'is_media_transport' setting. If
Offer contains x-mt, media transport should be used (if the factory is
present). However, we need to decide how to negotiate media transport
for data channels vs data transport for media (x-mt line at this point
doesn't differentiate the two, so we still need to use app setting).
This change also removes the negotation of pre-shared key from the
a=crypto line. Instead, media transport will have its own, 256bit key.
Such key should be transported in the x-mt line. This makes the code
much simpler, and simplifies the dependency / a=crypto lines parsing.
Also, adds a proper test for the connection re-offer (on both sides: callee and caller).
Before, it was possible that media transport could get recreated, based on the offer.
The tests we had didn't test this scenario, and the loopback media factory didn't allow for such test.
This change adds counts to that loopback media factory, and asserts that only 1 media transport is created, even
when there is a re-offer.
Bug: webrtc:9719
Change-Id: Ibd8739af90e914da40ab412454bba8e1529f5a01
Reviewed-on: https://webrtc-review.googlesource.com/c/125040
Reviewed-by: Bjorn Mellem <mellem@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Peter Slatala <psla@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26933}
2019-03-01 11:14:05 -08:00
|
|
|
|
2018-02-22 15:26:27 -08:00
|
|
|
const cricket::SessionDescription* local_desc_ = nullptr;
|
|
|
|
|
const cricket::SessionDescription* remote_desc_ = nullptr;
|
2018-06-19 16:47:43 +02:00
|
|
|
absl::optional<bool> initial_offerer_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
2018-06-19 16:47:43 +02:00
|
|
|
absl::optional<cricket::ContentGroup> bundle_group_;
|
2018-02-22 15:26:27 -08:00
|
|
|
|
|
|
|
|
cricket::IceConfig ice_config_;
|
|
|
|
|
cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING;
|
|
|
|
|
uint64_t ice_tiebreaker_ = rtc::CreateRandomId64();
|
|
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
|
|
|
|
|
rtc::AsyncInvoker invoker_;
|
|
|
|
|
|
|
|
|
|
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace webrtc
|
|
|
|
|
|
2019-01-11 09:11:00 -08:00
|
|
|
#endif // PC_JSEP_TRANSPORT_CONTROLLER_H_
|