1 /*
2 * Copyright (c) 2019 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 #include "test/peer_scenario/scenario_connection.h"
11
12 #include "absl/memory/memory.h"
13 #include "media/base/rtp_utils.h"
14 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
15 #include "p2p/client/basic_port_allocator.h"
16 #include "pc/channel.h"
17 #include "pc/jsep_transport_controller.h"
18 #include "pc/rtp_transport_internal.h"
19 #include "pc/session_description.h"
20 #include "rtc_base/task_queue_for_test.h"
21
22 namespace webrtc {
23 class ScenarioIceConnectionImpl : public ScenarioIceConnection,
24 public sigslot::has_slots<>,
25 private JsepTransportController::Observer,
26 private RtpPacketSinkInterface {
27 public:
28 ScenarioIceConnectionImpl(test::NetworkEmulationManagerImpl* net,
29 IceConnectionObserver* observer);
30 ~ScenarioIceConnectionImpl() override;
31
32 void SendRtpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
33 void SendRtcpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
34
35 void SetRemoteSdp(SdpType type, const std::string& remote_sdp) override;
36 void SetLocalSdp(SdpType type, const std::string& local_sdp) override;
37
endpoint()38 EmulatedEndpoint* endpoint() override { return endpoint_; }
transport_description() const39 const cricket::TransportDescription& transport_description() const override {
40 return transport_description_;
41 }
42
43 private:
44 JsepTransportController::Config CreateJsepConfig();
45 bool OnTransportChanged(
46 const std::string& mid,
47 RtpTransportInternal* rtp_transport,
48 rtc::scoped_refptr<DtlsTransport> dtls_transport,
49 DataChannelTransportInterface* data_channel_transport) override;
50
51 void OnRtpPacket(const RtpPacketReceived& packet) override;
52 void OnCandidates(const std::string& mid,
53 const std::vector<cricket::Candidate>& candidates);
54
55 IceConnectionObserver* const observer_;
56 EmulatedEndpoint* const endpoint_;
57 EmulatedNetworkManagerInterface* const manager_;
58 rtc::Thread* const signaling_thread_;
59 rtc::Thread* const network_thread_;
60 rtc::scoped_refptr<rtc::RTCCertificate> const certificate_
61 RTC_GUARDED_BY(network_thread_);
62 cricket::TransportDescription const transport_description_
63 RTC_GUARDED_BY(signaling_thread_);
64 std::unique_ptr<cricket::BasicPortAllocator> port_allocator_
65 RTC_GUARDED_BY(network_thread_);
66 std::unique_ptr<JsepTransportController> jsep_controller_;
67 RtpTransportInternal* rtp_transport_ RTC_GUARDED_BY(network_thread_) =
68 nullptr;
69 std::unique_ptr<SessionDescriptionInterface> remote_description_
70 RTC_GUARDED_BY(signaling_thread_);
71 std::unique_ptr<SessionDescriptionInterface> local_description_
72 RTC_GUARDED_BY(signaling_thread_);
73 };
74
Create(webrtc::test::NetworkEmulationManagerImpl * net,IceConnectionObserver * observer)75 std::unique_ptr<ScenarioIceConnection> ScenarioIceConnection::Create(
76 webrtc::test::NetworkEmulationManagerImpl* net,
77 IceConnectionObserver* observer) {
78 return std::make_unique<ScenarioIceConnectionImpl>(net, observer);
79 }
80
ScenarioIceConnectionImpl(test::NetworkEmulationManagerImpl * net,IceConnectionObserver * observer)81 ScenarioIceConnectionImpl::ScenarioIceConnectionImpl(
82 test::NetworkEmulationManagerImpl* net,
83 IceConnectionObserver* observer)
84 : observer_(observer),
85 endpoint_(net->CreateEndpoint(EmulatedEndpointConfig())),
86 manager_(net->CreateEmulatedNetworkManagerInterface({endpoint_})),
87 signaling_thread_(rtc::Thread::Current()),
88 network_thread_(manager_->network_thread()),
89 certificate_(rtc::RTCCertificate::Create(
90 rtc::SSLIdentity::Create("", ::rtc::KT_DEFAULT))),
91 transport_description_(
92 /*transport_options*/ {},
93 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
94 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH),
95 cricket::IceMode::ICEMODE_FULL,
96 cricket::ConnectionRole::CONNECTIONROLE_PASSIVE,
97 rtc::SSLFingerprint::CreateFromCertificate(*certificate_.get())
98 .get()),
99 port_allocator_(
100 new cricket::BasicPortAllocator(manager_->network_manager(),
101 manager_->packet_socket_factory())),
102 jsep_controller_(
103 new JsepTransportController(network_thread_,
104 port_allocator_.get(),
105 /*async_resolver_factory*/ nullptr,
106 CreateJsepConfig())) {
__anon96c85c110102null107 SendTask(network_thread_, [this] {
108 RTC_DCHECK_RUN_ON(network_thread_);
109 uint32_t flags = cricket::PORTALLOCATOR_DISABLE_TCP;
110 port_allocator_->set_flags(port_allocator_->flags() | flags);
111 port_allocator_->Initialize();
112 RTC_CHECK(port_allocator_->SetConfiguration(/*stun_servers*/ {},
113 /*turn_servers*/ {}, 0,
114 webrtc::NO_PRUNE));
115 jsep_controller_->SetLocalCertificate(certificate_);
116 });
117 }
118
~ScenarioIceConnectionImpl()119 ScenarioIceConnectionImpl::~ScenarioIceConnectionImpl() {
120 SendTask(network_thread_, [this] {
121 RTC_DCHECK_RUN_ON(network_thread_);
122 jsep_controller_.reset();
123 port_allocator_.reset();
124 rtp_transport_ = nullptr;
125 });
126 }
127
CreateJsepConfig()128 JsepTransportController::Config ScenarioIceConnectionImpl::CreateJsepConfig() {
129 JsepTransportController::Config config;
130 config.transport_observer = this;
131 config.bundle_policy =
132 PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle;
133 config.rtcp_handler = [this](const rtc::CopyOnWriteBuffer& packet,
134 int64_t packet_time_us) {
135 RTC_DCHECK_RUN_ON(network_thread_);
136 observer_->OnPacketReceived(packet);
137 };
138 config.field_trials = &field_trials;
139 return config;
140 }
141
SendRtpPacket(rtc::ArrayView<const uint8_t> packet_view)142 void ScenarioIceConnectionImpl::SendRtpPacket(
143 rtc::ArrayView<const uint8_t> packet_view) {
144 rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
145 ::cricket::kMaxRtpPacketLen);
146 network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
147 RTC_DCHECK_RUN_ON(network_thread_);
148 if (rtp_transport_ != nullptr)
149 rtp_transport_->SendRtpPacket(&packet, rtc::PacketOptions(),
150 cricket::PF_SRTP_BYPASS);
151 });
152 }
153
SendRtcpPacket(rtc::ArrayView<const uint8_t> packet_view)154 void ScenarioIceConnectionImpl::SendRtcpPacket(
155 rtc::ArrayView<const uint8_t> packet_view) {
156 rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
157 ::cricket::kMaxRtpPacketLen);
158 network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
159 RTC_DCHECK_RUN_ON(network_thread_);
160 if (rtp_transport_ != nullptr)
161 rtp_transport_->SendRtcpPacket(&packet, rtc::PacketOptions(),
162 cricket::PF_SRTP_BYPASS);
163 });
164 }
SetRemoteSdp(SdpType type,const std::string & remote_sdp)165 void ScenarioIceConnectionImpl::SetRemoteSdp(SdpType type,
166 const std::string& remote_sdp) {
167 RTC_DCHECK_RUN_ON(signaling_thread_);
168 remote_description_ = webrtc::CreateSessionDescription(type, remote_sdp);
169 jsep_controller_->SubscribeIceCandidateGathered(
170 [this](const std::string& transport,
171 const std::vector<cricket::Candidate>& candidate) {
172 ScenarioIceConnectionImpl::OnCandidates(transport, candidate);
173 });
174
175 auto res = jsep_controller_->SetRemoteDescription(
176 remote_description_->GetType(), remote_description_->description());
177 RTC_CHECK(res.ok()) << res.message();
178 RtpDemuxerCriteria criteria;
179 for (const auto& content : remote_description_->description()->contents()) {
180 if (content.media_description()->as_audio()) {
181 for (const auto& codec :
182 content.media_description()->as_audio()->codecs()) {
183 criteria.payload_types().insert(codec.id);
184 }
185 }
186 if (content.media_description()->as_video()) {
187 for (const auto& codec :
188 content.media_description()->as_video()->codecs()) {
189 criteria.payload_types().insert(codec.id);
190 }
191 }
192 }
193
194 network_thread_->PostTask([this, criteria]() {
195 RTC_DCHECK_RUN_ON(network_thread_);
196 RTC_DCHECK(rtp_transport_);
197 rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
198 });
199 }
200
SetLocalSdp(SdpType type,const std::string & local_sdp)201 void ScenarioIceConnectionImpl::SetLocalSdp(SdpType type,
202 const std::string& local_sdp) {
203 RTC_DCHECK_RUN_ON(signaling_thread_);
204 local_description_ = webrtc::CreateSessionDescription(type, local_sdp);
205 auto res = jsep_controller_->SetLocalDescription(
206 local_description_->GetType(), local_description_->description());
207 RTC_CHECK(res.ok()) << res.message();
208 jsep_controller_->MaybeStartGathering();
209 }
210
OnTransportChanged(const std::string & mid,RtpTransportInternal * rtp_transport,rtc::scoped_refptr<DtlsTransport> dtls_transport,DataChannelTransportInterface * data_channel_transport)211 bool ScenarioIceConnectionImpl::OnTransportChanged(
212 const std::string& mid,
213 RtpTransportInternal* rtp_transport,
214 rtc::scoped_refptr<DtlsTransport> dtls_transport,
215 DataChannelTransportInterface* data_channel_transport) {
216 RTC_DCHECK_RUN_ON(network_thread_);
217 if (rtp_transport == nullptr) {
218 rtp_transport_->UnregisterRtpDemuxerSink(this);
219 } else {
220 RTC_DCHECK(rtp_transport_ == nullptr || rtp_transport_ == rtp_transport);
221 if (rtp_transport_ != rtp_transport) {
222 rtp_transport_ = rtp_transport;
223 }
224 RtpDemuxerCriteria criteria(mid);
225 rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
226 }
227 return true;
228 }
229
OnRtpPacket(const RtpPacketReceived & packet)230 void ScenarioIceConnectionImpl::OnRtpPacket(const RtpPacketReceived& packet) {
231 RTC_DCHECK_RUN_ON(network_thread_);
232 observer_->OnPacketReceived(packet.Buffer());
233 }
234
OnCandidates(const std::string & mid,const std::vector<cricket::Candidate> & candidates)235 void ScenarioIceConnectionImpl::OnCandidates(
236 const std::string& mid,
237 const std::vector<cricket::Candidate>& candidates) {
238 RTC_DCHECK_RUN_ON(signaling_thread_);
239 observer_->OnIceCandidates(mid, candidates);
240 }
241
242 } // namespace webrtc
243