blob: d7ccd584c161f74ec2ae41bdc5d791a28ec38685 [file] [log] [blame]
deadbeef953c2ce2017-01-09 14:53:41 -08001/*
2 * Copyright (c) 2013 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
deadbeef953c2ce2017-01-09 14:53:41 -080011#include <stdio.h>
Yves Gerey3e707812018-11-28 16:47:49 +010012#include <string.h>
deadbeef953c2ce2017-01-09 14:53:41 -080013#include <memory>
14#include <string>
15#include <vector>
16
Steve Anton2c9ebef2019-01-28 17:27:58 -080017#include "absl/algorithm/container.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "media/sctp/sctp_transport.h"
19#include "p2p/base/fake_dtls_transport.h"
20#include "rtc_base/copy_on_write_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/message_queue.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/thread.h"
Yves Gerey3e707812018-11-28 16:47:49 +010025#include "test/gtest.h"
deadbeef953c2ce2017-01-09 14:53:41 -080026
27namespace {
28static const int kDefaultTimeout = 10000; // 10 seconds.
29// Use ports other than the default 5000 for testing.
30static const int kTransport1Port = 5001;
31static const int kTransport2Port = 5002;
Yves Gerey665174f2018-06-19 15:03:05 +020032} // namespace
deadbeef953c2ce2017-01-09 14:53:41 -080033
34namespace cricket {
35
36// This is essentially a buffer to hold recieved data. It stores only the last
37// received data. Calling OnDataReceived twice overwrites old data with the
38// newer one.
39// TODO(ldixon): Implement constraints, and allow new data to be added to old
40// instead of replacing it.
41class SctpFakeDataReceiver : public sigslot::has_slots<> {
42 public:
43 SctpFakeDataReceiver() : received_(false) {}
44
45 void Clear() {
46 received_ = false;
47 last_data_ = "";
48 last_params_ = ReceiveDataParams();
49 }
50
deadbeef8d517c42017-02-19 14:12:24 -080051 void OnDataReceived(const ReceiveDataParams& params,
52 const rtc::CopyOnWriteBuffer& data) {
deadbeef953c2ce2017-01-09 14:53:41 -080053 received_ = true;
54 last_data_ = std::string(data.data<char>(), data.size());
55 last_params_ = params;
56 }
57
58 bool received() const { return received_; }
59 std::string last_data() const { return last_data_; }
60 ReceiveDataParams last_params() const { return last_params_; }
61
62 private:
63 bool received_;
64 std::string last_data_;
65 ReceiveDataParams last_params_;
66};
67
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070068class SctpTransportObserver : public sigslot::has_slots<> {
deadbeef953c2ce2017-01-09 14:53:41 -080069 public:
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070070 explicit SctpTransportObserver(SctpTransport* transport) {
71 transport->SignalClosingProcedureComplete.connect(
72 this, &SctpTransportObserver::OnClosingProcedureComplete);
73 transport->SignalReadyToSendData.connect(
74 this, &SctpTransportObserver::OnReadyToSend);
deadbeef953c2ce2017-01-09 14:53:41 -080075 }
deadbeef953c2ce2017-01-09 14:53:41 -080076
77 int StreamCloseCount(int stream) {
Steve Anton2c9ebef2019-01-28 17:27:58 -080078 return absl::c_count(closed_streams_, stream);
deadbeef953c2ce2017-01-09 14:53:41 -080079 }
80
81 bool WasStreamClosed(int stream) {
Steve Anton2c9ebef2019-01-28 17:27:58 -080082 return absl::c_linear_search(closed_streams_, stream);
deadbeef953c2ce2017-01-09 14:53:41 -080083 }
84
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070085 bool ReadyToSend() { return ready_to_send_; }
86
deadbeef953c2ce2017-01-09 14:53:41 -080087 private:
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070088 void OnClosingProcedureComplete(int stream) {
89 closed_streams_.push_back(stream);
90 }
91 void OnReadyToSend() { ready_to_send_ = true; }
92
93 std::vector<int> closed_streams_;
94 bool ready_to_send_ = false;
deadbeef953c2ce2017-01-09 14:53:41 -080095};
96
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070097// Helper class used to immediately attempt to reopen a stream as soon as it's
98// been closed.
deadbeef953c2ce2017-01-09 14:53:41 -080099class SignalTransportClosedReopener : public sigslot::has_slots<> {
100 public:
101 SignalTransportClosedReopener(SctpTransport* transport, SctpTransport* peer)
102 : transport_(transport), peer_(peer) {}
103
Steve Anton2c9ebef2019-01-28 17:27:58 -0800104 int StreamCloseCount(int stream) { return absl::c_count(streams_, stream); }
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700105
106 private:
deadbeef953c2ce2017-01-09 14:53:41 -0800107 void OnStreamClosed(int stream) {
108 transport_->OpenStream(stream);
109 peer_->OpenStream(stream);
110 streams_.push_back(stream);
111 }
112
deadbeef953c2ce2017-01-09 14:53:41 -0800113 SctpTransport* transport_;
114 SctpTransport* peer_;
115 std::vector<int> streams_;
116};
117
118// SCTP Data Engine testing framework.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200119class SctpTransportTest : public ::testing::Test, public sigslot::has_slots<> {
deadbeef953c2ce2017-01-09 14:53:41 -0800120 protected:
121 // usrsctp uses the NSS random number generator on non-Android platforms,
122 // so we need to initialize SSL.
123 static void SetUpTestCase() {}
124
125 void SetupConnectedTransportsWithTwoStreams() {
jbauch46d24572017-03-10 16:20:04 -0800126 SetupConnectedTransportsWithTwoStreams(kTransport1Port, kTransport2Port);
127 }
128
129 void SetupConnectedTransportsWithTwoStreams(int port1, int port2) {
zhihuangb2cdd932017-01-19 16:54:25 -0800130 fake_dtls1_.reset(new FakeDtlsTransport("fake dtls 1", 0));
131 fake_dtls2_.reset(new FakeDtlsTransport("fake dtls 2", 0));
deadbeef953c2ce2017-01-09 14:53:41 -0800132 recv1_.reset(new SctpFakeDataReceiver());
133 recv2_.reset(new SctpFakeDataReceiver());
134 transport1_.reset(CreateTransport(fake_dtls1_.get(), recv1_.get()));
135 transport1_->set_debug_name_for_testing("transport1");
136 transport1_->SignalReadyToSendData.connect(
137 this, &SctpTransportTest::OnChan1ReadyToSend);
138 transport2_.reset(CreateTransport(fake_dtls2_.get(), recv2_.get()));
139 transport2_->set_debug_name_for_testing("transport2");
140 transport2_->SignalReadyToSendData.connect(
141 this, &SctpTransportTest::OnChan2ReadyToSend);
142 // Setup two connected transports ready to send and receive.
143 bool asymmetric = false;
144 fake_dtls1_->SetDestination(fake_dtls2_.get(), asymmetric);
145
Mirko Bonadei675513b2017-11-09 11:09:25 +0100146 RTC_LOG(LS_VERBOSE) << "Transport setup ----------------------------- ";
deadbeef953c2ce2017-01-09 14:53:41 -0800147 AddStream(1);
148 AddStream(2);
149
Mirko Bonadei675513b2017-11-09 11:09:25 +0100150 RTC_LOG(LS_VERBOSE)
151 << "Connect the transports -----------------------------";
deadbeef953c2ce2017-01-09 14:53:41 -0800152 // Both transports need to have started (with matching ports) for an
153 // association to be formed.
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200154 transport1_->Start(port1, port2, kSctpSendBufferSize);
155 transport2_->Start(port2, port1, kSctpSendBufferSize);
deadbeef953c2ce2017-01-09 14:53:41 -0800156 }
157
158 bool AddStream(int sid) {
159 bool ret = true;
160 ret = ret && transport1_->OpenStream(sid);
161 ret = ret && transport2_->OpenStream(sid);
162 return ret;
163 }
164
zhihuangb2cdd932017-01-19 16:54:25 -0800165 SctpTransport* CreateTransport(FakeDtlsTransport* fake_dtls,
deadbeef953c2ce2017-01-09 14:53:41 -0800166 SctpFakeDataReceiver* recv) {
167 SctpTransport* transport =
168 new SctpTransport(rtc::Thread::Current(), fake_dtls);
169 // When data is received, pass it to the SctpFakeDataReceiver.
170 transport->SignalDataReceived.connect(
171 recv, &SctpFakeDataReceiver::OnDataReceived);
172 return transport;
173 }
174
175 bool SendData(SctpTransport* chan,
176 int sid,
177 const std::string& msg,
178 SendDataResult* result) {
179 SendDataParams params;
180 params.sid = sid;
181
182 return chan->SendData(params, rtc::CopyOnWriteBuffer(&msg[0], msg.length()),
183 result);
184 }
185
186 bool ReceivedData(const SctpFakeDataReceiver* recv,
187 int sid,
188 const std::string& msg) {
189 return (recv->received() && recv->last_params().sid == sid &&
190 recv->last_data() == msg);
191 }
192
193 bool ProcessMessagesUntilIdle() {
194 rtc::Thread* thread = rtc::Thread::Current();
195 while (!thread->empty()) {
196 rtc::Message msg;
197 if (thread->Get(&msg, rtc::Thread::kForever)) {
198 thread->Dispatch(&msg);
199 }
200 }
201 return !thread->IsQuitting();
202 }
203
204 SctpTransport* transport1() { return transport1_.get(); }
205 SctpTransport* transport2() { return transport2_.get(); }
206 SctpFakeDataReceiver* receiver1() { return recv1_.get(); }
207 SctpFakeDataReceiver* receiver2() { return recv2_.get(); }
zhihuangb2cdd932017-01-19 16:54:25 -0800208 FakeDtlsTransport* fake_dtls1() { return fake_dtls1_.get(); }
209 FakeDtlsTransport* fake_dtls2() { return fake_dtls2_.get(); }
deadbeef953c2ce2017-01-09 14:53:41 -0800210
211 int transport1_ready_to_send_count() {
212 return transport1_ready_to_send_count_;
213 }
214 int transport2_ready_to_send_count() {
215 return transport2_ready_to_send_count_;
216 }
217
218 private:
zhihuangb2cdd932017-01-19 16:54:25 -0800219 std::unique_ptr<FakeDtlsTransport> fake_dtls1_;
220 std::unique_ptr<FakeDtlsTransport> fake_dtls2_;
deadbeef953c2ce2017-01-09 14:53:41 -0800221 std::unique_ptr<SctpFakeDataReceiver> recv1_;
222 std::unique_ptr<SctpFakeDataReceiver> recv2_;
223 std::unique_ptr<SctpTransport> transport1_;
224 std::unique_ptr<SctpTransport> transport2_;
225
226 int transport1_ready_to_send_count_ = 0;
227 int transport2_ready_to_send_count_ = 0;
228
229 void OnChan1ReadyToSend() { ++transport1_ready_to_send_count_; }
230 void OnChan2ReadyToSend() { ++transport2_ready_to_send_count_; }
231};
232
233// Test that data can be sent end-to-end when an SCTP transport starts with one
Zhi Huang644fde42018-04-02 19:16:26 -0700234// transport (which is unwritable), and then switches to another transport. A
235// common scenario due to how BUNDLE works.
236TEST_F(SctpTransportTest, SwitchDtlsTransport) {
zhihuangb2cdd932017-01-19 16:54:25 -0800237 FakeDtlsTransport black_hole("black hole", 0);
238 FakeDtlsTransport fake_dtls1("fake dtls 1", 0);
239 FakeDtlsTransport fake_dtls2("fake dtls 2", 0);
deadbeef953c2ce2017-01-09 14:53:41 -0800240 SctpFakeDataReceiver recv1;
241 SctpFakeDataReceiver recv2;
242
Zhi Huang644fde42018-04-02 19:16:26 -0700243 // Construct transport1 with the "black hole" transport.
deadbeef953c2ce2017-01-09 14:53:41 -0800244 std::unique_ptr<SctpTransport> transport1(
245 CreateTransport(&black_hole, &recv1));
246 std::unique_ptr<SctpTransport> transport2(
247 CreateTransport(&fake_dtls2, &recv2));
248
249 // Add a stream.
250 transport1->OpenStream(1);
251 transport2->OpenStream(1);
252
253 // Tell them both to start (though transport1_ is connected to black_hole).
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200254 transport1->Start(kTransport1Port, kTransport2Port, kSctpSendBufferSize);
255 transport2->Start(kTransport2Port, kTransport1Port, kSctpSendBufferSize);
deadbeef953c2ce2017-01-09 14:53:41 -0800256
Zhi Huang644fde42018-04-02 19:16:26 -0700257 // Switch transport1_ to the normal fake_dtls1_ transport.
258 transport1->SetDtlsTransport(&fake_dtls1);
deadbeef953c2ce2017-01-09 14:53:41 -0800259
Zhi Huang644fde42018-04-02 19:16:26 -0700260 // Connect the two fake DTLS transports.
deadbeef953c2ce2017-01-09 14:53:41 -0800261 bool asymmetric = false;
262 fake_dtls1.SetDestination(&fake_dtls2, asymmetric);
263
264 // Make sure we end up able to send data.
265 SendDataResult result;
266 ASSERT_TRUE(SendData(transport1.get(), 1, "foo", &result));
267 ASSERT_TRUE(SendData(transport2.get(), 1, "bar", &result));
268 EXPECT_TRUE_WAIT(ReceivedData(&recv2, 1, "foo"), kDefaultTimeout);
269 EXPECT_TRUE_WAIT(ReceivedData(&recv1, 1, "bar"), kDefaultTimeout);
Zhi Huang644fde42018-04-02 19:16:26 -0700270
271 // Setting a null DtlsTransport should work. This could happen when an SCTP
272 // data section is rejected.
273 transport1->SetDtlsTransport(nullptr);
deadbeef953c2ce2017-01-09 14:53:41 -0800274}
275
276// Calling Start twice shouldn't do anything bad, if with the same parameters.
277TEST_F(SctpTransportTest, DuplicateStartCallsIgnored) {
278 SetupConnectedTransportsWithTwoStreams();
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200279 EXPECT_TRUE(transport1()->Start(kTransport1Port, kTransport2Port,
280 kSctpSendBufferSize));
deadbeef953c2ce2017-01-09 14:53:41 -0800281
282 // Make sure we can still send/recv data.
283 SendDataResult result;
284 ASSERT_TRUE(SendData(transport1(), 1, "foo", &result));
285 ASSERT_TRUE(SendData(transport2(), 1, "bar", &result));
286 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "foo"), kDefaultTimeout);
287 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 1, "bar"), kDefaultTimeout);
288}
289
290// Calling Start a second time with a different port should fail.
291TEST_F(SctpTransportTest, CallingStartWithDifferentPortFails) {
292 SetupConnectedTransportsWithTwoStreams();
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200293 EXPECT_FALSE(transport1()->Start(kTransport1Port, 1234, kSctpSendBufferSize));
294 EXPECT_FALSE(transport1()->Start(1234, kTransport2Port, kSctpSendBufferSize));
deadbeef953c2ce2017-01-09 14:53:41 -0800295}
296
297// A value of -1 for the local/remote port should be treated as the default
298// (5000).
299TEST_F(SctpTransportTest, NegativeOnePortTreatedAsDefault) {
zhihuangb2cdd932017-01-19 16:54:25 -0800300 FakeDtlsTransport fake_dtls1("fake dtls 1", 0);
301 FakeDtlsTransport fake_dtls2("fake dtls 2", 0);
deadbeef953c2ce2017-01-09 14:53:41 -0800302 SctpFakeDataReceiver recv1;
303 SctpFakeDataReceiver recv2;
304 std::unique_ptr<SctpTransport> transport1(
305 CreateTransport(&fake_dtls1, &recv1));
306 std::unique_ptr<SctpTransport> transport2(
307 CreateTransport(&fake_dtls2, &recv2));
308
309 // Add a stream.
310 transport1->OpenStream(1);
311 transport2->OpenStream(1);
312
313 // Tell them both to start, giving one transport the default port and the
314 // other transport -1.
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200315 transport1->Start(kSctpDefaultPort, kSctpDefaultPort, kSctpSendBufferSize);
316 transport2->Start(-1, -1, kSctpSendBufferSize);
deadbeef953c2ce2017-01-09 14:53:41 -0800317
Zhi Huang644fde42018-04-02 19:16:26 -0700318 // Connect the two fake DTLS transports.
deadbeef953c2ce2017-01-09 14:53:41 -0800319 bool asymmetric = false;
320 fake_dtls1.SetDestination(&fake_dtls2, asymmetric);
321
322 // Make sure we end up able to send data.
323 SendDataResult result;
324 ASSERT_TRUE(SendData(transport1.get(), 1, "foo", &result));
325 ASSERT_TRUE(SendData(transport2.get(), 1, "bar", &result));
326 EXPECT_TRUE_WAIT(ReceivedData(&recv2, 1, "foo"), kDefaultTimeout);
327 EXPECT_TRUE_WAIT(ReceivedData(&recv1, 1, "bar"), kDefaultTimeout);
328}
329
330TEST_F(SctpTransportTest, OpenStreamWithAlreadyOpenedStreamFails) {
zhihuangb2cdd932017-01-19 16:54:25 -0800331 FakeDtlsTransport fake_dtls("fake dtls", 0);
deadbeef953c2ce2017-01-09 14:53:41 -0800332 SctpFakeDataReceiver recv;
333 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
334 EXPECT_TRUE(transport->OpenStream(1));
335 EXPECT_FALSE(transport->OpenStream(1));
336}
337
338TEST_F(SctpTransportTest, ResetStreamWithAlreadyResetStreamFails) {
zhihuangb2cdd932017-01-19 16:54:25 -0800339 FakeDtlsTransport fake_dtls("fake dtls", 0);
deadbeef953c2ce2017-01-09 14:53:41 -0800340 SctpFakeDataReceiver recv;
341 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
342 EXPECT_TRUE(transport->OpenStream(1));
343 EXPECT_TRUE(transport->ResetStream(1));
344 EXPECT_FALSE(transport->ResetStream(1));
345}
346
347// Test that SignalReadyToSendData is fired after Start has been called and the
Zhi Huang644fde42018-04-02 19:16:26 -0700348// DTLS transport is writable.
deadbeef953c2ce2017-01-09 14:53:41 -0800349TEST_F(SctpTransportTest, SignalReadyToSendDataAfterDtlsWritable) {
zhihuangb2cdd932017-01-19 16:54:25 -0800350 FakeDtlsTransport fake_dtls("fake dtls", 0);
deadbeef953c2ce2017-01-09 14:53:41 -0800351 SctpFakeDataReceiver recv;
352 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700353 SctpTransportObserver observer(transport.get());
deadbeef953c2ce2017-01-09 14:53:41 -0800354
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200355 transport->Start(kSctpDefaultPort, kSctpDefaultPort, kSctpSendBufferSize);
deadbeef953c2ce2017-01-09 14:53:41 -0800356 fake_dtls.SetWritable(true);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700357 EXPECT_TRUE_WAIT(observer.ReadyToSend(), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800358}
359
360// Test that after an SCTP socket's buffer is filled, SignalReadyToSendData
361// is fired after it begins to be drained.
362TEST_F(SctpTransportTest, SignalReadyToSendDataAfterBlocked) {
363 SetupConnectedTransportsWithTwoStreams();
364 // Wait for initial SCTP association to be formed.
365 EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
366 // Make the fake transport unwritable so that messages pile up for the SCTP
367 // socket.
368 fake_dtls1()->SetWritable(false);
369 // Send messages until we get EWOULDBLOCK.
370 static const int kMaxMessages = 1024;
371 SendDataParams params;
372 params.sid = 1;
373 rtc::CopyOnWriteBuffer buf(1024);
374 memset(buf.data<uint8_t>(), 0, 1024);
375 SendDataResult result;
376 int message_count;
377 for (message_count = 0; message_count < kMaxMessages; ++message_count) {
378 if (!transport1()->SendData(params, buf, &result) && result == SDR_BLOCK) {
379 break;
380 }
381 }
382 ASSERT_NE(kMaxMessages, message_count)
383 << "Sent max number of messages without getting SDR_BLOCK?";
384 // Make sure the ready-to-send count hasn't changed.
385 EXPECT_EQ(1, transport1_ready_to_send_count());
386 // Make the transport writable again and expect a "SignalReadyToSendData" at
387 // some point.
388 fake_dtls1()->SetWritable(true);
389 EXPECT_EQ_WAIT(2, transport1_ready_to_send_count(), kDefaultTimeout);
390}
391
392TEST_F(SctpTransportTest, SendData) {
393 SetupConnectedTransportsWithTwoStreams();
394
395 SendDataResult result;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100396 RTC_LOG(LS_VERBOSE)
deadbeef953c2ce2017-01-09 14:53:41 -0800397 << "transport1 sending: 'hello?' -----------------------------";
398 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
399 EXPECT_EQ(SDR_SUCCESS, result);
400 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100401 RTC_LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received()
402 << ", recv2.last_params.sid="
403 << receiver2()->last_params().sid
404 << ", recv2.last_params.timestamp="
405 << receiver2()->last_params().timestamp
406 << ", recv2.last_params.seq_num="
407 << receiver2()->last_params().seq_num
408 << ", recv2.last_data=" << receiver2()->last_data();
deadbeef953c2ce2017-01-09 14:53:41 -0800409
Mirko Bonadei675513b2017-11-09 11:09:25 +0100410 RTC_LOG(LS_VERBOSE)
deadbeef953c2ce2017-01-09 14:53:41 -0800411 << "transport2 sending: 'hi transport1' -----------------------------";
412 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
413 EXPECT_EQ(SDR_SUCCESS, result);
414 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
415 kDefaultTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100416 RTC_LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received()
417 << ", recv1.last_params.sid="
418 << receiver1()->last_params().sid
419 << ", recv1.last_params.timestamp="
420 << receiver1()->last_params().timestamp
421 << ", recv1.last_params.seq_num="
422 << receiver1()->last_params().seq_num
423 << ", recv1.last_data=" << receiver1()->last_data();
deadbeef953c2ce2017-01-09 14:53:41 -0800424}
425
426// Sends a lot of large messages at once and verifies SDR_BLOCK is returned.
427TEST_F(SctpTransportTest, SendDataBlocked) {
428 SetupConnectedTransportsWithTwoStreams();
429
430 SendDataResult result;
431 SendDataParams params;
432 params.sid = 1;
433
434 std::vector<char> buffer(1024 * 64, 0);
435
436 for (size_t i = 0; i < 100; ++i) {
437 transport1()->SendData(
438 params, rtc::CopyOnWriteBuffer(&buffer[0], buffer.size()), &result);
439 if (result == SDR_BLOCK)
440 break;
441 }
442
443 EXPECT_EQ(SDR_BLOCK, result);
444}
445
446// Trying to send data for a nonexistent stream should fail.
447TEST_F(SctpTransportTest, SendDataWithNonexistentStreamFails) {
448 SetupConnectedTransportsWithTwoStreams();
449 SendDataResult result;
450 EXPECT_FALSE(SendData(transport2(), 123, "some data", &result));
451 EXPECT_EQ(SDR_ERROR, result);
452}
453
jbauch46d24572017-03-10 16:20:04 -0800454TEST_F(SctpTransportTest, SendDataHighPorts) {
455 SetupConnectedTransportsWithTwoStreams(32768, 32769);
456
457 SendDataResult result;
458 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
459 EXPECT_EQ(SDR_SUCCESS, result);
460 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
461
462 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
463 EXPECT_EQ(SDR_SUCCESS, result);
464 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
465 kDefaultTimeout);
466}
467
deadbeef953c2ce2017-01-09 14:53:41 -0800468TEST_F(SctpTransportTest, ClosesRemoteStream) {
469 SetupConnectedTransportsWithTwoStreams();
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700470 SctpTransportObserver transport1_observer(transport1());
471 SctpTransportObserver transport2_observer(transport2());
deadbeef953c2ce2017-01-09 14:53:41 -0800472
473 SendDataResult result;
474 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
475 EXPECT_EQ(SDR_SUCCESS, result);
476 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
477 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
478 EXPECT_EQ(SDR_SUCCESS, result);
479 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
480 kDefaultTimeout);
481
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700482 // Close stream 1 on transport 1. Transport 2 should notify us.
deadbeef953c2ce2017-01-09 14:53:41 -0800483 transport1()->ResetStream(1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700484 EXPECT_TRUE_WAIT(transport2_observer.WasStreamClosed(1), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800485}
486
487TEST_F(SctpTransportTest, ClosesTwoRemoteStreams) {
488 SetupConnectedTransportsWithTwoStreams();
489 AddStream(3);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700490 SctpTransportObserver transport1_observer(transport1());
491 SctpTransportObserver transport2_observer(transport2());
deadbeef953c2ce2017-01-09 14:53:41 -0800492
493 SendDataResult result;
494 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
495 EXPECT_EQ(SDR_SUCCESS, result);
496 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
497 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
498 EXPECT_EQ(SDR_SUCCESS, result);
499 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
500 kDefaultTimeout);
501
502 // Close two streams on one side.
503 transport2()->ResetStream(2);
504 transport2()->ResetStream(3);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700505 EXPECT_TRUE_WAIT(transport2_observer.WasStreamClosed(2), kDefaultTimeout);
506 EXPECT_TRUE_WAIT(transport2_observer.WasStreamClosed(3), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800507}
508
509TEST_F(SctpTransportTest, ClosesStreamsOnBothSides) {
510 SetupConnectedTransportsWithTwoStreams();
511 AddStream(3);
512 AddStream(4);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700513 SctpTransportObserver transport1_observer(transport1());
514 SctpTransportObserver transport2_observer(transport2());
deadbeef953c2ce2017-01-09 14:53:41 -0800515
516 SendDataResult result;
517 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
518 EXPECT_EQ(SDR_SUCCESS, result);
519 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
520 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
521 EXPECT_EQ(SDR_SUCCESS, result);
522 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
523 kDefaultTimeout);
524
525 // Close one stream on transport1(), while closing three streams on
526 // transport2(). They will conflict (only one side can close anything at a
527 // time, apparently). Test the resolution of the conflict.
528 transport1()->ResetStream(1);
529
530 transport2()->ResetStream(2);
531 transport2()->ResetStream(3);
532 transport2()->ResetStream(4);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700533 EXPECT_TRUE_WAIT(transport2_observer.WasStreamClosed(1), kDefaultTimeout);
534 EXPECT_TRUE_WAIT(transport1_observer.WasStreamClosed(2), kDefaultTimeout);
535 EXPECT_TRUE_WAIT(transport1_observer.WasStreamClosed(3), kDefaultTimeout);
536 EXPECT_TRUE_WAIT(transport1_observer.WasStreamClosed(4), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800537}
538
539TEST_F(SctpTransportTest, RefusesHighNumberedTransports) {
540 SetupConnectedTransportsWithTwoStreams();
541 EXPECT_TRUE(AddStream(kMaxSctpSid));
542 EXPECT_FALSE(AddStream(kMaxSctpSid + 1));
543}
544
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700545TEST_F(SctpTransportTest, ReusesAStream) {
deadbeef953c2ce2017-01-09 14:53:41 -0800546 // Shut down transport 1, then open it up again for reuse.
547 SetupConnectedTransportsWithTwoStreams();
548 SendDataResult result;
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700549 SctpTransportObserver transport2_observer(transport2());
deadbeef953c2ce2017-01-09 14:53:41 -0800550
551 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
552 EXPECT_EQ(SDR_SUCCESS, result);
553 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
554
555 transport1()->ResetStream(1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700556 EXPECT_TRUE_WAIT(transport2_observer.WasStreamClosed(1), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800557 // Transport 1 is gone now.
558
559 // Create a new transport 1.
560 AddStream(1);
561 ASSERT_TRUE(SendData(transport1(), 1, "hi?", &result));
562 EXPECT_EQ(SDR_SUCCESS, result);
563 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hi?"), kDefaultTimeout);
564 transport1()->ResetStream(1);
Taylor Brandstettercdd05f02018-05-31 13:23:32 -0700565 EXPECT_EQ_WAIT(2, transport2_observer.StreamCloseCount(1), kDefaultTimeout);
deadbeef953c2ce2017-01-09 14:53:41 -0800566}
567
Harald Alvestrandfbb45bd2019-05-15 08:07:47 +0200568TEST_F(SctpTransportTest, RejectsTooLargeMessageSize) {
569 FakeDtlsTransport fake_dtls("fake dtls", 0);
570 SctpFakeDataReceiver recv;
571 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
572
573 EXPECT_FALSE(transport->Start(kSctpDefaultPort, kSctpDefaultPort,
574 kSctpSendBufferSize + 1));
575}
576
577TEST_F(SctpTransportTest, RejectsTooSmallMessageSize) {
578 FakeDtlsTransport fake_dtls("fake dtls", 0);
579 SctpFakeDataReceiver recv;
580 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
581
582 EXPECT_FALSE(transport->Start(kSctpDefaultPort, kSctpDefaultPort, 0));
583}
584
585TEST_F(SctpTransportTest, RejectsSendTooLargeMessages) {
586 SetupConnectedTransportsWithTwoStreams();
587 // Use "Start" to reduce the max message size
588 transport1()->Start(kTransport1Port, kTransport2Port, 10);
589 EXPECT_EQ(10, transport1()->max_message_size());
590 const char eleven_characters[] = "12345678901";
591 SendDataResult result;
592 EXPECT_FALSE(SendData(transport1(), 1, eleven_characters, &result));
593}
594
deadbeef953c2ce2017-01-09 14:53:41 -0800595} // namespace cricket