blob: c0f7fc0994cb303192e2c7f739b7cc5738000ae4 [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
Steve Anton6c38cc72017-11-29 10:25:58 -080011#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
Steve Anton6c38cc72017-11-29 10:25:58 -080013#include <string>
kwiberg3ec46792016-04-27 07:22:53 -070014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "p2p/base/asyncstuntcpsocket.h"
16#include "rtc_base/asyncsocket.h"
17#include "rtc_base/gunit.h"
18#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000019
20namespace cricket {
21
22static unsigned char kStunMessageWithZeroLength[] = {
23 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
24 0x21, 0x12, 0xA4, 0x42,
25 '0', '1', '2', '3',
26 '4', '5', '6', '7',
27 '8', '9', 'a', 'b',
28};
29
30
31static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
32 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
33};
34
35static unsigned char kTurnChannelDataMessage[] = {
36 0x40, 0x00, 0x00, 0x10,
37 0x21, 0x12, 0xA4, 0x42,
38 '0', '1', '2', '3',
39 '4', '5', '6', '7',
40 '8', '9', 'a', 'b',
41};
42
43static unsigned char kStunMessageWithInvalidLength[] = {
44 0x00, 0x01, 0x00, 0x10,
45 0x21, 0x12, 0xA4, 0x42,
46 '0', '1', '2', '3',
47 '4', '5', '6', '7',
48 '8', '9', 'a', 'b',
49};
50
51static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
52 0x80, 0x00, 0x00, 0x20,
53 0x21, 0x12, 0xA4, 0x42,
54 '0', '1', '2', '3',
55 '4', '5', '6', '7',
56 '8', '9', 'a', 'b',
57};
58
59static unsigned char kTurnChannelDataMessageWithOddLength[] = {
60 0x40, 0x00, 0x00, 0x05,
61 0x21, 0x12, 0xA4, 0x42,
62 '0',
63};
64
65
66static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
67static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
68
69class AsyncStunTCPSocketTest : public testing::Test,
70 public sigslot::has_slots<> {
71 protected:
72 AsyncStunTCPSocketTest()
deadbeef98e186c2017-05-16 18:00:06 -070073 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000074
75 virtual void SetUp() {
76 CreateSockets();
77 }
78
79 void CreateSockets() {
80 rtc::AsyncSocket* server = vss_->CreateAsyncSocket(
81 kServerAddr.family(), SOCK_STREAM);
82 server->Bind(kServerAddr);
83 recv_socket_.reset(new AsyncStunTCPSocket(server, true));
84 recv_socket_->SignalNewConnection.connect(
85 this, &AsyncStunTCPSocketTest::OnNewConnection);
86
87 rtc::AsyncSocket* client = vss_->CreateAsyncSocket(
88 kClientAddr.family(), SOCK_STREAM);
89 send_socket_.reset(AsyncStunTCPSocket::Create(
90 client, kClientAddr, recv_socket_->GetLocalAddress()));
deadbeefb56671e2017-05-26 18:40:05 -070091 send_socket_->SignalSentPacket.connect(
92 this, &AsyncStunTCPSocketTest::OnSentPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000093 ASSERT_TRUE(send_socket_.get() != NULL);
94 vss_->ProcessMessagesUntilIdle();
95 }
96
97 void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
98 size_t len, const rtc::SocketAddress& remote_addr,
99 const rtc::PacketTime& packet_time) {
100 recv_packets_.push_back(std::string(data, len));
101 }
102
deadbeefb56671e2017-05-26 18:40:05 -0700103 void OnSentPacket(rtc::AsyncPacketSocket* socket,
104 const rtc::SentPacket& packet) {
105 ++sent_packets_;
106 }
107
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000108 void OnNewConnection(rtc::AsyncPacketSocket* server,
109 rtc::AsyncPacketSocket* new_socket) {
110 listen_socket_.reset(new_socket);
111 new_socket->SignalReadPacket.connect(
112 this, &AsyncStunTCPSocketTest::OnReadPacket);
113 }
114
115 bool Send(const void* data, size_t len) {
116 rtc::PacketOptions options;
117 size_t ret = send_socket_->Send(
118 reinterpret_cast<const char*>(data), len, options);
119 vss_->ProcessMessagesUntilIdle();
120 return (ret == len);
121 }
122
123 bool CheckData(const void* data, int len) {
124 bool ret = false;
125 if (recv_packets_.size()) {
126 std::string packet = recv_packets_.front();
127 recv_packets_.pop_front();
128 ret = (memcmp(data, packet.c_str(), len) == 0);
129 }
130 return ret;
131 }
132
kwiberg3ec46792016-04-27 07:22:53 -0700133 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700134 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700135 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
136 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
137 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 std::list<std::string> recv_packets_;
deadbeefb56671e2017-05-26 18:40:05 -0700139 int sent_packets_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000140};
141
142// Testing a stun packet sent/recv properly.
143TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
144 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
145 sizeof(kStunMessageWithZeroLength)));
146 EXPECT_EQ(1u, recv_packets_.size());
147 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
148 sizeof(kStunMessageWithZeroLength)));
149}
150
151// Verify sending multiple packets.
152TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
153 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
154 sizeof(kStunMessageWithZeroLength)));
155 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
156 sizeof(kStunMessageWithZeroLength)));
157 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
158 sizeof(kStunMessageWithZeroLength)));
159 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
160 sizeof(kStunMessageWithZeroLength)));
161 EXPECT_EQ(4u, recv_packets_.size());
162}
163
164// Verifying TURN channel data message with zero length.
165TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
166 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
167 sizeof(kTurnChannelDataMessageWithZeroLength)));
168 EXPECT_EQ(1u, recv_packets_.size());
169 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
170 sizeof(kTurnChannelDataMessageWithZeroLength)));
171}
172
173// Verifying TURN channel data message.
174TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
175 EXPECT_TRUE(Send(kTurnChannelDataMessage,
176 sizeof(kTurnChannelDataMessage)));
177 EXPECT_EQ(1u, recv_packets_.size());
178 EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
179 sizeof(kTurnChannelDataMessage)));
180}
181
182// Verifying TURN channel messages which needs padding handled properly.
183TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
184 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
185 sizeof(kTurnChannelDataMessageWithOddLength)));
186 EXPECT_EQ(1u, recv_packets_.size());
187 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
188 sizeof(kTurnChannelDataMessageWithOddLength)));
189}
190
191// Verifying stun message with invalid length.
192TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
193 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
194 sizeof(kStunMessageWithInvalidLength)));
195 EXPECT_EQ(0u, recv_packets_.size());
196
197 // Modify the message length to larger value.
198 kStunMessageWithInvalidLength[2] = 0xFF;
199 kStunMessageWithInvalidLength[3] = 0xFF;
200 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
201 sizeof(kStunMessageWithInvalidLength)));
202
203 // Modify the message length to smaller value.
204 kStunMessageWithInvalidLength[2] = 0x00;
205 kStunMessageWithInvalidLength[3] = 0x01;
206 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
207 sizeof(kStunMessageWithInvalidLength)));
208}
209
210// Verifying TURN channel data message with invalid length.
211TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
212 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
213 sizeof(kTurnChannelDataMessageWithInvalidLength)));
214 // Modify the length to larger value.
215 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
216 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
217 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
218 sizeof(kTurnChannelDataMessageWithInvalidLength)));
219
220 // Modify the length to smaller value.
221 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
222 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
223 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
224 sizeof(kTurnChannelDataMessageWithInvalidLength)));
225}
226
227// Verifying a small buffer handled (dropped) properly. This will be
228// a common one for both stun and turn.
229TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
230 char data[1];
231 EXPECT_FALSE(Send(data, sizeof(data)));
232}
233
234// Verifying a legal large turn message.
235TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
236 // We have problem in getting the SignalWriteEvent from the virtual socket
237 // server. So increasing the send buffer to 64k.
238 // TODO(mallinath) - Remove this setting after we fix vss issue.
239 vss_->set_send_buffer_capacity(64 * 1024);
240 unsigned char packet[65539];
241 packet[0] = 0x40;
242 packet[1] = 0x00;
243 packet[2] = 0xFF;
244 packet[3] = 0xFF;
245 EXPECT_TRUE(Send(packet, sizeof(packet)));
246}
247
248// Verifying a legal large stun message.
249TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
250 // We have problem in getting the SignalWriteEvent from the virtual socket
251 // server. So increasing the send buffer to 64k.
252 // TODO(mallinath) - Remove this setting after we fix vss issue.
253 vss_->set_send_buffer_capacity(64 * 1024);
254 unsigned char packet[65552];
255 packet[0] = 0x00;
256 packet[1] = 0x01;
257 packet[2] = 0xFF;
258 packet[3] = 0xFC;
259 EXPECT_TRUE(Send(packet, sizeof(packet)));
260}
261
262// Investigate why WriteEvent is not signaled from VSS.
263TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
264 vss_->set_send_buffer_capacity(1);
265 Send(kTurnChannelDataMessageWithOddLength,
266 sizeof(kTurnChannelDataMessageWithOddLength));
267 EXPECT_EQ(1u, recv_packets_.size());
268 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
269 sizeof(kTurnChannelDataMessageWithOddLength)));
270}
271
deadbeefb56671e2017-05-26 18:40:05 -0700272// Test that SignalSentPacket is fired when a packet is sent.
273TEST_F(AsyncStunTCPSocketTest, SignalSentPacketFiredWhenPacketSent) {
274 ASSERT_TRUE(
275 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
276 EXPECT_EQ(1, sent_packets_);
277 // Send another packet for good measure.
278 ASSERT_TRUE(
279 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
280 EXPECT_EQ(2, sent_packets_);
281}
282
283// Test that SignalSentPacket isn't fired when a packet isn't sent (for
284// example, because it's invalid).
285TEST_F(AsyncStunTCPSocketTest, SignalSentPacketNotFiredWhenPacketNotSent) {
286 // Attempt to send a packet that's too small; since it isn't sent,
287 // SignalSentPacket shouldn't fire.
288 char data[1];
289 ASSERT_FALSE(Send(data, sizeof(data)));
290 EXPECT_EQ(0, sent_packets_);
291}
292
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000293} // namespace cricket