blob: 41b3be27653d6f6d820ec533ee0dcd60e46d88a5 [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
kwiberg3ec46792016-04-27 07:22:53 -070011#include <memory>
12
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013#include "webrtc/p2p/base/asyncstuntcpsocket.h"
14#include "webrtc/base/asyncsocket.h"
15#include "webrtc/base/gunit.h"
16#include "webrtc/base/physicalsocketserver.h"
17#include "webrtc/base/virtualsocketserver.h"
18
19namespace cricket {
20
21static unsigned char kStunMessageWithZeroLength[] = {
22 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
23 0x21, 0x12, 0xA4, 0x42,
24 '0', '1', '2', '3',
25 '4', '5', '6', '7',
26 '8', '9', 'a', 'b',
27};
28
29
30static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
31 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
32};
33
34static unsigned char kTurnChannelDataMessage[] = {
35 0x40, 0x00, 0x00, 0x10,
36 0x21, 0x12, 0xA4, 0x42,
37 '0', '1', '2', '3',
38 '4', '5', '6', '7',
39 '8', '9', 'a', 'b',
40};
41
42static unsigned char kStunMessageWithInvalidLength[] = {
43 0x00, 0x01, 0x00, 0x10,
44 0x21, 0x12, 0xA4, 0x42,
45 '0', '1', '2', '3',
46 '4', '5', '6', '7',
47 '8', '9', 'a', 'b',
48};
49
50static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
51 0x80, 0x00, 0x00, 0x20,
52 0x21, 0x12, 0xA4, 0x42,
53 '0', '1', '2', '3',
54 '4', '5', '6', '7',
55 '8', '9', 'a', 'b',
56};
57
58static unsigned char kTurnChannelDataMessageWithOddLength[] = {
59 0x40, 0x00, 0x00, 0x05,
60 0x21, 0x12, 0xA4, 0x42,
61 '0',
62};
63
64
65static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
66static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
67
68class AsyncStunTCPSocketTest : public testing::Test,
69 public sigslot::has_slots<> {
70 protected:
71 AsyncStunTCPSocketTest()
72 : vss_(new rtc::VirtualSocketServer(NULL)),
nisse7eaa4ea2017-05-08 05:25:41 -070073 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()));
91 ASSERT_TRUE(send_socket_.get() != NULL);
92 vss_->ProcessMessagesUntilIdle();
93 }
94
95 void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
96 size_t len, const rtc::SocketAddress& remote_addr,
97 const rtc::PacketTime& packet_time) {
98 recv_packets_.push_back(std::string(data, len));
99 }
100
101 void OnNewConnection(rtc::AsyncPacketSocket* server,
102 rtc::AsyncPacketSocket* new_socket) {
103 listen_socket_.reset(new_socket);
104 new_socket->SignalReadPacket.connect(
105 this, &AsyncStunTCPSocketTest::OnReadPacket);
106 }
107
108 bool Send(const void* data, size_t len) {
109 rtc::PacketOptions options;
110 size_t ret = send_socket_->Send(
111 reinterpret_cast<const char*>(data), len, options);
112 vss_->ProcessMessagesUntilIdle();
113 return (ret == len);
114 }
115
116 bool CheckData(const void* data, int len) {
117 bool ret = false;
118 if (recv_packets_.size()) {
119 std::string packet = recv_packets_.front();
120 recv_packets_.pop_front();
121 ret = (memcmp(data, packet.c_str(), len) == 0);
122 }
123 return ret;
124 }
125
kwiberg3ec46792016-04-27 07:22:53 -0700126 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700127 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700128 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
129 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
130 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131 std::list<std::string> recv_packets_;
132};
133
134// Testing a stun packet sent/recv properly.
135TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
136 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
137 sizeof(kStunMessageWithZeroLength)));
138 EXPECT_EQ(1u, recv_packets_.size());
139 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
140 sizeof(kStunMessageWithZeroLength)));
141}
142
143// Verify sending multiple packets.
144TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
145 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
146 sizeof(kStunMessageWithZeroLength)));
147 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
148 sizeof(kStunMessageWithZeroLength)));
149 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
150 sizeof(kStunMessageWithZeroLength)));
151 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
152 sizeof(kStunMessageWithZeroLength)));
153 EXPECT_EQ(4u, recv_packets_.size());
154}
155
156// Verifying TURN channel data message with zero length.
157TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
158 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
159 sizeof(kTurnChannelDataMessageWithZeroLength)));
160 EXPECT_EQ(1u, recv_packets_.size());
161 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
162 sizeof(kTurnChannelDataMessageWithZeroLength)));
163}
164
165// Verifying TURN channel data message.
166TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
167 EXPECT_TRUE(Send(kTurnChannelDataMessage,
168 sizeof(kTurnChannelDataMessage)));
169 EXPECT_EQ(1u, recv_packets_.size());
170 EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
171 sizeof(kTurnChannelDataMessage)));
172}
173
174// Verifying TURN channel messages which needs padding handled properly.
175TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
176 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
177 sizeof(kTurnChannelDataMessageWithOddLength)));
178 EXPECT_EQ(1u, recv_packets_.size());
179 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
180 sizeof(kTurnChannelDataMessageWithOddLength)));
181}
182
183// Verifying stun message with invalid length.
184TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
185 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
186 sizeof(kStunMessageWithInvalidLength)));
187 EXPECT_EQ(0u, recv_packets_.size());
188
189 // Modify the message length to larger value.
190 kStunMessageWithInvalidLength[2] = 0xFF;
191 kStunMessageWithInvalidLength[3] = 0xFF;
192 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
193 sizeof(kStunMessageWithInvalidLength)));
194
195 // Modify the message length to smaller value.
196 kStunMessageWithInvalidLength[2] = 0x00;
197 kStunMessageWithInvalidLength[3] = 0x01;
198 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
199 sizeof(kStunMessageWithInvalidLength)));
200}
201
202// Verifying TURN channel data message with invalid length.
203TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
204 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
205 sizeof(kTurnChannelDataMessageWithInvalidLength)));
206 // Modify the length to larger value.
207 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
208 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
209 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
210 sizeof(kTurnChannelDataMessageWithInvalidLength)));
211
212 // Modify the length to smaller value.
213 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
214 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
215 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
216 sizeof(kTurnChannelDataMessageWithInvalidLength)));
217}
218
219// Verifying a small buffer handled (dropped) properly. This will be
220// a common one for both stun and turn.
221TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
222 char data[1];
223 EXPECT_FALSE(Send(data, sizeof(data)));
224}
225
226// Verifying a legal large turn message.
227TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
228 // We have problem in getting the SignalWriteEvent from the virtual socket
229 // server. So increasing the send buffer to 64k.
230 // TODO(mallinath) - Remove this setting after we fix vss issue.
231 vss_->set_send_buffer_capacity(64 * 1024);
232 unsigned char packet[65539];
233 packet[0] = 0x40;
234 packet[1] = 0x00;
235 packet[2] = 0xFF;
236 packet[3] = 0xFF;
237 EXPECT_TRUE(Send(packet, sizeof(packet)));
238}
239
240// Verifying a legal large stun message.
241TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
242 // We have problem in getting the SignalWriteEvent from the virtual socket
243 // server. So increasing the send buffer to 64k.
244 // TODO(mallinath) - Remove this setting after we fix vss issue.
245 vss_->set_send_buffer_capacity(64 * 1024);
246 unsigned char packet[65552];
247 packet[0] = 0x00;
248 packet[1] = 0x01;
249 packet[2] = 0xFF;
250 packet[3] = 0xFC;
251 EXPECT_TRUE(Send(packet, sizeof(packet)));
252}
253
254// Investigate why WriteEvent is not signaled from VSS.
255TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
256 vss_->set_send_buffer_capacity(1);
257 Send(kTurnChannelDataMessageWithOddLength,
258 sizeof(kTurnChannelDataMessageWithOddLength));
259 EXPECT_EQ(1u, recv_packets_.size());
260 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
261 sizeof(kTurnChannelDataMessageWithOddLength)));
262}
263
264} // namespace cricket