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