blob: 03e8820c30981535c5e8c4708526b6d4200871a1 [file] [log] [blame]
zstein56162b92017-04-24 16:54:35 -07001/*
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "pc/rtp_transport.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <cstdint>
14#include <set>
zstein56162b92017-04-24 16:54:35 -070015#include <string>
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010016#include <utility>
zstein56162b92017-04-24 16:54:35 -070017
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "api/rtp_headers.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/rtp_parameters.h"
20#include "p2p/base/fake_packet_transport.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "pc/test/rtp_transport_test_util.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/buffer.h"
23#include "rtc_base/third_party/sigslot/sigslot.h"
24#include "test/gtest.h"
zstein56162b92017-04-24 16:54:35 -070025
26namespace webrtc {
27
zstein56162b92017-04-24 16:54:35 -070028constexpr bool kMuxDisabled = false;
29constexpr bool kMuxEnabled = true;
Zhi Huang942bc2e2017-11-13 13:26:07 -080030constexpr uint16_t kLocalNetId = 1;
31constexpr uint16_t kRemoteNetId = 2;
32constexpr int kLastPacketId = 100;
33constexpr int kTransportOverheadPerPacket = 28; // Ipv4(20) + UDP(8).
zstein56162b92017-04-24 16:54:35 -070034
zstein56162b92017-04-24 16:54:35 -070035class SignalObserver : public sigslot::has_slots<> {
36 public:
37 explicit SignalObserver(RtpTransport* transport) {
Zhi Huange830e682018-03-30 10:48:35 -070038 transport_ = transport;
zstein56162b92017-04-24 16:54:35 -070039 transport->SignalReadyToSend.connect(this, &SignalObserver::OnReadyToSend);
Zhi Huang942bc2e2017-11-13 13:26:07 -080040 transport->SignalNetworkRouteChanged.connect(
41 this, &SignalObserver::OnNetworkRouteChanged);
Zhi Huange830e682018-03-30 10:48:35 -070042 if (transport->rtp_packet_transport()) {
43 transport->rtp_packet_transport()->SignalSentPacket.connect(
44 this, &SignalObserver::OnSentPacket);
45 }
46
47 if (transport->rtcp_packet_transport()) {
48 transport->rtcp_packet_transport()->SignalSentPacket.connect(
49 this, &SignalObserver::OnSentPacket);
50 }
zstein56162b92017-04-24 16:54:35 -070051 }
Zhi Huang942bc2e2017-11-13 13:26:07 -080052
zstein3dcf0e92017-06-01 13:22:42 -070053 bool ready() const { return ready_; }
zstein56162b92017-04-24 16:54:35 -070054 void OnReadyToSend(bool ready) { ready_ = ready; }
zstein3dcf0e92017-06-01 13:22:42 -070055
Danil Chapovalov66cadcc2018-06-19 16:47:43 +020056 absl::optional<rtc::NetworkRoute> network_route() { return network_route_; }
57 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Mirko Bonadei05cf6be2019-01-31 21:38:12 +010058 network_route_ = network_route;
Zhi Huang942bc2e2017-11-13 13:26:07 -080059 }
60
Zhi Huange830e682018-03-30 10:48:35 -070061 void OnSentPacket(rtc::PacketTransportInternal* packet_transport,
62 const rtc::SentPacket& sent_packet) {
63 if (packet_transport == transport_->rtp_packet_transport()) {
64 rtp_transport_sent_count_++;
65 } else {
66 ASSERT_EQ(transport_->rtcp_packet_transport(), packet_transport);
67 rtcp_transport_sent_count_++;
68 }
69 }
70
71 int rtp_transport_sent_count() { return rtp_transport_sent_count_; }
72
73 int rtcp_transport_sent_count() { return rtcp_transport_sent_count_; }
74
zstein3dcf0e92017-06-01 13:22:42 -070075 private:
Zhi Huange830e682018-03-30 10:48:35 -070076 int rtp_transport_sent_count_ = 0;
77 int rtcp_transport_sent_count_ = 0;
78 RtpTransport* transport_ = nullptr;
zstein56162b92017-04-24 16:54:35 -070079 bool ready_ = false;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +020080 absl::optional<rtc::NetworkRoute> network_route_;
zstein56162b92017-04-24 16:54:35 -070081};
82
zstein3dcf0e92017-06-01 13:22:42 -070083TEST(RtpTransportTest, SettingRtcpAndRtpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -070084 RtpTransport transport(kMuxDisabled);
85 SignalObserver observer(&transport);
86 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
87 fake_rtcp.SetWritable(true);
88 rtc::FakePacketTransport fake_rtp("fake_rtp");
89 fake_rtp.SetWritable(true);
90
91 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 13:22:42 -070092 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -070093 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -070094 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -070095}
96
zstein3dcf0e92017-06-01 13:22:42 -070097TEST(RtpTransportTest, SettingRtpAndRtcpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -070098 RtpTransport transport(kMuxDisabled);
99 SignalObserver observer(&transport);
100 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
101 fake_rtcp.SetWritable(true);
102 rtc::FakePacketTransport fake_rtp("fake_rtp");
103 fake_rtp.SetWritable(true);
104
105 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700106 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700107 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 13:22:42 -0700108 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700109}
110
zstein3dcf0e92017-06-01 13:22:42 -0700111TEST(RtpTransportTest, SettingRtpWithRtcpMuxEnabledSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700112 RtpTransport transport(kMuxEnabled);
113 SignalObserver observer(&transport);
114 rtc::FakePacketTransport fake_rtp("fake_rtp");
115 fake_rtp.SetWritable(true);
116
117 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700118 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700119}
120
zstein3dcf0e92017-06-01 13:22:42 -0700121TEST(RtpTransportTest, DisablingRtcpMuxSignalsNotReady) {
zstein56162b92017-04-24 16:54:35 -0700122 RtpTransport transport(kMuxEnabled);
123 SignalObserver observer(&transport);
124 rtc::FakePacketTransport fake_rtp("fake_rtp");
125 fake_rtp.SetWritable(true);
126
127 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700128 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700129
130 transport.SetRtcpMuxEnabled(false);
zstein3dcf0e92017-06-01 13:22:42 -0700131 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700132}
133
zstein3dcf0e92017-06-01 13:22:42 -0700134TEST(RtpTransportTest, EnablingRtcpMuxSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700135 RtpTransport transport(kMuxDisabled);
136 SignalObserver observer(&transport);
137 rtc::FakePacketTransport fake_rtp("fake_rtp");
138 fake_rtp.SetWritable(true);
139
140 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700141 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700142
143 transport.SetRtcpMuxEnabled(true);
zstein3dcf0e92017-06-01 13:22:42 -0700144 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700145}
146
Zhi Huang942bc2e2017-11-13 13:26:07 -0800147// Tests the SignalNetworkRoute is fired when setting a packet transport.
148TEST(RtpTransportTest, SetRtpTransportWithNetworkRouteChanged) {
149 RtpTransport transport(kMuxDisabled);
150 SignalObserver observer(&transport);
151 rtc::FakePacketTransport fake_rtp("fake_rtp");
152
153 EXPECT_FALSE(observer.network_route());
154
155 rtc::NetworkRoute network_route;
156 // Set a non-null RTP transport with a new network route.
157 network_route.connected = true;
158 network_route.local_network_id = kLocalNetId;
159 network_route.remote_network_id = kRemoteNetId;
160 network_route.last_sent_packet_id = kLastPacketId;
161 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200162 fake_rtp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 13:26:07 -0800163 transport.SetRtpPacketTransport(&fake_rtp);
164 ASSERT_TRUE(observer.network_route());
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100165 EXPECT_TRUE(observer.network_route()->connected);
166 EXPECT_EQ(kLocalNetId, observer.network_route()->local_network_id);
167 EXPECT_EQ(kRemoteNetId, observer.network_route()->remote_network_id);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800168 EXPECT_EQ(kTransportOverheadPerPacket,
169 observer.network_route()->packet_overhead);
170 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
171
172 // Set a null RTP transport.
173 transport.SetRtpPacketTransport(nullptr);
174 EXPECT_FALSE(observer.network_route());
175}
176
177TEST(RtpTransportTest, SetRtcpTransportWithNetworkRouteChanged) {
178 RtpTransport transport(kMuxDisabled);
179 SignalObserver observer(&transport);
180 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
181
182 EXPECT_FALSE(observer.network_route());
183
184 rtc::NetworkRoute network_route;
185 // Set a non-null RTCP transport with a new network route.
186 network_route.connected = true;
187 network_route.local_network_id = kLocalNetId;
188 network_route.remote_network_id = kRemoteNetId;
189 network_route.last_sent_packet_id = kLastPacketId;
190 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200191 fake_rtcp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 13:26:07 -0800192 transport.SetRtcpPacketTransport(&fake_rtcp);
193 ASSERT_TRUE(observer.network_route());
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100194 EXPECT_TRUE(observer.network_route()->connected);
195 EXPECT_EQ(kLocalNetId, observer.network_route()->local_network_id);
196 EXPECT_EQ(kRemoteNetId, observer.network_route()->remote_network_id);
Zhi Huang942bc2e2017-11-13 13:26:07 -0800197 EXPECT_EQ(kTransportOverheadPerPacket,
198 observer.network_route()->packet_overhead);
199 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
200
201 // Set a null RTCP transport.
202 transport.SetRtcpPacketTransport(nullptr);
203 EXPECT_FALSE(observer.network_route());
204}
205
Zhi Huange830e682018-03-30 10:48:35 -0700206// Test that RTCP packets are sent over correct transport based on the RTCP-mux
207// status.
208TEST(RtpTransportTest, RtcpPacketSentOverCorrectTransport) {
209 // If the RTCP-mux is not enabled, RTCP packets are expected to be sent over
210 // the RtcpPacketTransport.
211 RtpTransport transport(kMuxDisabled);
212 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
213 rtc::FakePacketTransport fake_rtp("fake_rtp");
214 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
215 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
216 SignalObserver observer(&transport);
217
218 fake_rtp.SetDestination(&fake_rtp, true);
219 fake_rtcp.SetDestination(&fake_rtcp, true);
220
221 rtc::CopyOnWriteBuffer packet;
222 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
223 EXPECT_EQ(1, observer.rtcp_transport_sent_count());
224
225 // The RTCP packets are expected to be sent over RtpPacketTransport if
226 // RTCP-mux is enabled.
227 transport.SetRtcpMuxEnabled(true);
228 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
229 EXPECT_EQ(1, observer.rtp_transport_sent_count());
230}
231
zstein3dcf0e92017-06-01 13:22:42 -0700232TEST(RtpTransportTest, ChangingReadyToSendStateOnlySignalsWhenChanged) {
zstein56162b92017-04-24 16:54:35 -0700233 RtpTransport transport(kMuxEnabled);
Zhi Huang365381f2018-04-13 16:44:34 -0700234 TransportObserver observer(&transport);
zstein56162b92017-04-24 16:54:35 -0700235 rtc::FakePacketTransport fake_rtp("fake_rtp");
236 fake_rtp.SetWritable(true);
237
238 // State changes, so we should signal.
239 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700240 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700241
242 // State does not change, so we should not signal.
243 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700244 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700245
246 // State does not change, so we should not signal.
247 transport.SetRtcpMuxEnabled(true);
Zhi Huang365381f2018-04-13 16:44:34 -0700248 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700249
250 // State changes, so we should signal.
251 transport.SetRtcpMuxEnabled(false);
Zhi Huang365381f2018-04-13 16:44:34 -0700252 EXPECT_EQ(observer.ready_to_send_signal_count(), 2);
zstein3dcf0e92017-06-01 13:22:42 -0700253}
254
zstein3dcf0e92017-06-01 13:22:42 -0700255// Test that SignalPacketReceived fires with rtcp=true when a RTCP packet is
256// received.
257TEST(RtpTransportTest, SignalDemuxedRtcp) {
258 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 13:22:42 -0700259 rtc::FakePacketTransport fake_rtp("fake_rtp");
260 fake_rtp.SetDestination(&fake_rtp, true);
261 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700262 TransportObserver observer(&transport);
zstein3dcf0e92017-06-01 13:22:42 -0700263
264 // An rtcp packet.
Piotr (Peter) Slatala042bb002019-01-30 14:57:12 -0800265 const unsigned char data[] = {0x80, 73, 0, 0};
zstein3dcf0e92017-06-01 13:22:42 -0700266 const int len = 4;
267 const rtc::PacketOptions options;
268 const int flags = 0;
Piotr (Peter) Slatala042bb002019-01-30 14:57:12 -0800269 fake_rtp.SendPacket(reinterpret_cast<const char*>(data), len, options, flags);
zstein3dcf0e92017-06-01 13:22:42 -0700270 EXPECT_EQ(0, observer.rtp_count());
271 EXPECT_EQ(1, observer.rtcp_count());
272}
273
274static const unsigned char kRtpData[] = {0x80, 0x11, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0};
276static const int kRtpLen = 12;
277
278// Test that SignalPacketReceived fires with rtcp=false when a RTP packet with a
279// handled payload type is received.
280TEST(RtpTransportTest, SignalHandledRtpPayloadType) {
281 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 13:22:42 -0700282 rtc::FakePacketTransport fake_rtp("fake_rtp");
283 fake_rtp.SetDestination(&fake_rtp, true);
284 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700285 TransportObserver observer(&transport);
286 RtpDemuxerCriteria demuxer_criteria;
287 // Add a handled payload type.
288 demuxer_criteria.payload_types = {0x11};
289 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
zstein3dcf0e92017-06-01 13:22:42 -0700290
291 // An rtp packet.
292 const rtc::PacketOptions options;
293 const int flags = 0;
294 rtc::Buffer rtp_data(kRtpData, kRtpLen);
295 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
296 EXPECT_EQ(1, observer.rtp_count());
297 EXPECT_EQ(0, observer.rtcp_count());
Zhi Huang365381f2018-04-13 16:44:34 -0700298 // Remove the sink before destroying the transport.
299 transport.UnregisterRtpDemuxerSink(&observer);
300}
301
302// Test that SignalPacketReceived does not fire when a RTP packet with an
303// unhandled payload type is received.
304TEST(RtpTransportTest, DontSignalUnhandledRtpPayloadType) {
305 RtpTransport transport(kMuxDisabled);
306 rtc::FakePacketTransport fake_rtp("fake_rtp");
307 fake_rtp.SetDestination(&fake_rtp, true);
308 transport.SetRtpPacketTransport(&fake_rtp);
309 TransportObserver observer(&transport);
310 RtpDemuxerCriteria demuxer_criteria;
311 // Add an unhandled payload type.
312 demuxer_criteria.payload_types = {0x12};
313 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
314
315 const rtc::PacketOptions options;
316 const int flags = 0;
317 rtc::Buffer rtp_data(kRtpData, kRtpLen);
318 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
319 EXPECT_EQ(0, observer.rtp_count());
320 EXPECT_EQ(0, observer.rtcp_count());
321 // Remove the sink before destroying the transport.
322 transport.UnregisterRtpDemuxerSink(&observer);
zstein3dcf0e92017-06-01 13:22:42 -0700323}
324
zstein56162b92017-04-24 16:54:35 -0700325} // namespace webrtc