blob: 0203e4805bc852d9303323ee80441c4f51716a8c [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 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
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <stdint.h>
12#include <string.h>
Steve Anton6c38cc72017-11-29 10:25:58 -080013#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070014#include <memory>
Steve Anton6c38cc72017-11-29 10:25:58 -080015#include <string>
kwiberg3ec46792016-04-27 07:22:53 -070016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "p2p/base/asyncstuntcpsocket.h"
18#include "rtc_base/asyncsocket.h"
Yves Gerey3e707812018-11-28 16:47:49 +010019#include "rtc_base/network/sent_packet.h"
20#include "rtc_base/third_party/sigslot/sigslot.h"
21#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/virtualsocketserver.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "test/gtest.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000024
25namespace cricket {
26
27static unsigned char kStunMessageWithZeroLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020028 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
29 0x21, 0x12, 0xA4, 0x42, '0', '1', '2', '3',
30 '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000031};
32
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000033static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020034 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000035};
36
37static unsigned char kTurnChannelDataMessage[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020038 0x40, 0x00, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
39 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000040};
41
42static unsigned char kStunMessageWithInvalidLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020043 0x00, 0x01, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
44 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000045};
46
47static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020048 0x80, 0x00, 0x00, 0x20, 0x21, 0x12, 0xA4, 0x42, '0', '1',
49 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050};
51
52static unsigned char kTurnChannelDataMessageWithOddLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020053 0x40, 0x00, 0x00, 0x05, 0x21, 0x12, 0xA4, 0x42, '0',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054};
55
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
57static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
58
59class AsyncStunTCPSocketTest : public testing::Test,
60 public sigslot::has_slots<> {
61 protected:
62 AsyncStunTCPSocketTest()
deadbeef98e186c2017-05-16 18:00:06 -070063 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000064
Yves Gerey665174f2018-06-19 15:03:05 +020065 virtual void SetUp() { CreateSockets(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066
67 void CreateSockets() {
Yves Gerey665174f2018-06-19 15:03:05 +020068 rtc::AsyncSocket* server =
69 vss_->CreateAsyncSocket(kServerAddr.family(), SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070 server->Bind(kServerAddr);
71 recv_socket_.reset(new AsyncStunTCPSocket(server, true));
72 recv_socket_->SignalNewConnection.connect(
73 this, &AsyncStunTCPSocketTest::OnNewConnection);
74
Yves Gerey665174f2018-06-19 15:03:05 +020075 rtc::AsyncSocket* client =
76 vss_->CreateAsyncSocket(kClientAddr.family(), SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000077 send_socket_.reset(AsyncStunTCPSocket::Create(
78 client, kClientAddr, recv_socket_->GetLocalAddress()));
deadbeefb56671e2017-05-26 18:40:05 -070079 send_socket_->SignalSentPacket.connect(
80 this, &AsyncStunTCPSocketTest::OnSentPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000081 ASSERT_TRUE(send_socket_.get() != NULL);
82 vss_->ProcessMessagesUntilIdle();
83 }
84
Yves Gerey665174f2018-06-19 15:03:05 +020085 void OnReadPacket(rtc::AsyncPacketSocket* socket,
86 const char* data,
87 size_t len,
88 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +010089 const int64_t& /* packet_time_us */) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090 recv_packets_.push_back(std::string(data, len));
91 }
92
deadbeefb56671e2017-05-26 18:40:05 -070093 void OnSentPacket(rtc::AsyncPacketSocket* socket,
94 const rtc::SentPacket& packet) {
95 ++sent_packets_;
96 }
97
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098 void OnNewConnection(rtc::AsyncPacketSocket* server,
99 rtc::AsyncPacketSocket* new_socket) {
100 listen_socket_.reset(new_socket);
Yves Gerey665174f2018-06-19 15:03:05 +0200101 new_socket->SignalReadPacket.connect(this,
102 &AsyncStunTCPSocketTest::OnReadPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103 }
104
105 bool Send(const void* data, size_t len) {
106 rtc::PacketOptions options;
Yves Gerey665174f2018-06-19 15:03:05 +0200107 size_t ret =
108 send_socket_->Send(reinterpret_cast<const char*>(data), len, options);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109 vss_->ProcessMessagesUntilIdle();
110 return (ret == len);
111 }
112
113 bool CheckData(const void* data, int len) {
114 bool ret = false;
115 if (recv_packets_.size()) {
Yves Gerey665174f2018-06-19 15:03:05 +0200116 std::string packet = recv_packets_.front();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117 recv_packets_.pop_front();
118 ret = (memcmp(data, packet.c_str(), len) == 0);
119 }
120 return ret;
121 }
122
kwiberg3ec46792016-04-27 07:22:53 -0700123 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700124 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700125 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
126 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
127 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 std::list<std::string> recv_packets_;
deadbeefb56671e2017-05-26 18:40:05 -0700129 int sent_packets_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000130};
131
132// Testing a stun packet sent/recv properly.
133TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
Yves Gerey665174f2018-06-19 15:03:05 +0200134 EXPECT_TRUE(
135 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000136 EXPECT_EQ(1u, recv_packets_.size());
137 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
138 sizeof(kStunMessageWithZeroLength)));
139}
140
141// Verify sending multiple packets.
142TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
Yves Gerey665174f2018-06-19 15:03:05 +0200143 EXPECT_TRUE(
144 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
145 EXPECT_TRUE(
146 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
147 EXPECT_TRUE(
148 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
149 EXPECT_TRUE(
150 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151 EXPECT_EQ(4u, recv_packets_.size());
152}
153
154// Verifying TURN channel data message with zero length.
155TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
156 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
157 sizeof(kTurnChannelDataMessageWithZeroLength)));
158 EXPECT_EQ(1u, recv_packets_.size());
159 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
160 sizeof(kTurnChannelDataMessageWithZeroLength)));
161}
162
163// Verifying TURN channel data message.
164TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
Yves Gerey665174f2018-06-19 15:03:05 +0200165 EXPECT_TRUE(Send(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166 EXPECT_EQ(1u, recv_packets_.size());
Yves Gerey665174f2018-06-19 15:03:05 +0200167 EXPECT_TRUE(
168 CheckData(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000169}
170
171// Verifying TURN channel messages which needs padding handled properly.
172TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
173 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
174 sizeof(kTurnChannelDataMessageWithOddLength)));
175 EXPECT_EQ(1u, recv_packets_.size());
176 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
177 sizeof(kTurnChannelDataMessageWithOddLength)));
178}
179
180// Verifying stun message with invalid length.
181TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
182 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
183 sizeof(kStunMessageWithInvalidLength)));
184 EXPECT_EQ(0u, recv_packets_.size());
185
186 // Modify the message length to larger value.
187 kStunMessageWithInvalidLength[2] = 0xFF;
188 kStunMessageWithInvalidLength[3] = 0xFF;
189 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
190 sizeof(kStunMessageWithInvalidLength)));
191
192 // Modify the message length to smaller value.
193 kStunMessageWithInvalidLength[2] = 0x00;
194 kStunMessageWithInvalidLength[3] = 0x01;
195 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
196 sizeof(kStunMessageWithInvalidLength)));
197}
198
199// Verifying TURN channel data message with invalid length.
200TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
201 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200202 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000203 // Modify the length to larger value.
204 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
205 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
206 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200207 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208
209 // Modify the length to smaller value.
210 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
211 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
212 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200213 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000214}
215
216// Verifying a small buffer handled (dropped) properly. This will be
217// a common one for both stun and turn.
218TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
219 char data[1];
220 EXPECT_FALSE(Send(data, sizeof(data)));
221}
222
223// Verifying a legal large turn message.
224TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
225 // We have problem in getting the SignalWriteEvent from the virtual socket
226 // server. So increasing the send buffer to 64k.
227 // TODO(mallinath) - Remove this setting after we fix vss issue.
228 vss_->set_send_buffer_capacity(64 * 1024);
229 unsigned char packet[65539];
230 packet[0] = 0x40;
231 packet[1] = 0x00;
232 packet[2] = 0xFF;
233 packet[3] = 0xFF;
234 EXPECT_TRUE(Send(packet, sizeof(packet)));
235}
236
237// Verifying a legal large stun message.
238TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
239 // We have problem in getting the SignalWriteEvent from the virtual socket
240 // server. So increasing the send buffer to 64k.
241 // TODO(mallinath) - Remove this setting after we fix vss issue.
242 vss_->set_send_buffer_capacity(64 * 1024);
243 unsigned char packet[65552];
244 packet[0] = 0x00;
245 packet[1] = 0x01;
246 packet[2] = 0xFF;
247 packet[3] = 0xFC;
248 EXPECT_TRUE(Send(packet, sizeof(packet)));
249}
250
251// Investigate why WriteEvent is not signaled from VSS.
252TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
253 vss_->set_send_buffer_capacity(1);
254 Send(kTurnChannelDataMessageWithOddLength,
255 sizeof(kTurnChannelDataMessageWithOddLength));
256 EXPECT_EQ(1u, recv_packets_.size());
257 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
258 sizeof(kTurnChannelDataMessageWithOddLength)));
259}
260
deadbeefb56671e2017-05-26 18:40:05 -0700261// Test that SignalSentPacket is fired when a packet is sent.
262TEST_F(AsyncStunTCPSocketTest, SignalSentPacketFiredWhenPacketSent) {
263 ASSERT_TRUE(
264 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
265 EXPECT_EQ(1, sent_packets_);
266 // Send another packet for good measure.
267 ASSERT_TRUE(
268 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
269 EXPECT_EQ(2, sent_packets_);
270}
271
272// Test that SignalSentPacket isn't fired when a packet isn't sent (for
273// example, because it's invalid).
274TEST_F(AsyncStunTCPSocketTest, SignalSentPacketNotFiredWhenPacketNotSent) {
275 // Attempt to send a packet that's too small; since it isn't sent,
276 // SignalSentPacket shouldn't fire.
277 char data[1];
278 ASSERT_FALSE(Send(data, sizeof(data)));
279 EXPECT_EQ(0, sent_packets_);
280}
281
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000282} // namespace cricket