Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / asyncstuntcpsocket_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2013, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "talk/p2p/base/asyncstuntcpsocket.h"
29 #include "webrtc/base/asyncsocket.h"
30 #include "webrtc/base/gunit.h"
31 #include "webrtc/base/physicalsocketserver.h"
32 #include "webrtc/base/virtualsocketserver.h"
33
34 namespace cricket {
35
36 static unsigned char kStunMessageWithZeroLength[] = {
37   0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
38   0x21, 0x12, 0xA4, 0x42,
39   '0', '1', '2', '3',
40   '4', '5', '6', '7',
41   '8', '9', 'a', 'b',
42 };
43
44
45 static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
46   0x40, 0x00, 0x00, 0x00,  // length of 0 (last 2 bytes)
47 };
48
49 static unsigned char kTurnChannelDataMessage[] = {
50   0x40, 0x00, 0x00, 0x10,
51   0x21, 0x12, 0xA4, 0x42,
52   '0', '1', '2', '3',
53   '4', '5', '6', '7',
54   '8', '9', 'a', 'b',
55 };
56
57 static unsigned char kStunMessageWithInvalidLength[] = {
58   0x00, 0x01, 0x00, 0x10,
59   0x21, 0x12, 0xA4, 0x42,
60   '0', '1', '2', '3',
61   '4', '5', '6', '7',
62   '8', '9', 'a', 'b',
63 };
64
65 static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
66   0x80, 0x00, 0x00, 0x20,
67   0x21, 0x12, 0xA4, 0x42,
68   '0', '1', '2', '3',
69   '4', '5', '6', '7',
70   '8', '9', 'a', 'b',
71 };
72
73 static unsigned char kTurnChannelDataMessageWithOddLength[] = {
74   0x40, 0x00, 0x00, 0x05,
75   0x21, 0x12, 0xA4, 0x42,
76   '0',
77 };
78
79
80 static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
81 static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
82
83 class AsyncStunTCPSocketTest : public testing::Test,
84                                public sigslot::has_slots<> {
85  protected:
86   AsyncStunTCPSocketTest()
87       : vss_(new rtc::VirtualSocketServer(NULL)),
88         ss_scope_(vss_.get()) {
89   }
90
91   virtual void SetUp() {
92     CreateSockets();
93   }
94
95   void CreateSockets() {
96     rtc::AsyncSocket* server = vss_->CreateAsyncSocket(
97         kServerAddr.family(), SOCK_STREAM);
98     server->Bind(kServerAddr);
99     recv_socket_.reset(new AsyncStunTCPSocket(server, true));
100     recv_socket_->SignalNewConnection.connect(
101         this, &AsyncStunTCPSocketTest::OnNewConnection);
102
103     rtc::AsyncSocket* client = vss_->CreateAsyncSocket(
104         kClientAddr.family(), SOCK_STREAM);
105     send_socket_.reset(AsyncStunTCPSocket::Create(
106         client, kClientAddr, recv_socket_->GetLocalAddress()));
107     ASSERT_TRUE(send_socket_.get() != NULL);
108     vss_->ProcessMessagesUntilIdle();
109   }
110
111   void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
112                     size_t len, const rtc::SocketAddress& remote_addr,
113                     const rtc::PacketTime& packet_time) {
114     recv_packets_.push_back(std::string(data, len));
115   }
116
117   void OnNewConnection(rtc::AsyncPacketSocket* server,
118                        rtc::AsyncPacketSocket* new_socket) {
119     listen_socket_.reset(new_socket);
120     new_socket->SignalReadPacket.connect(
121         this, &AsyncStunTCPSocketTest::OnReadPacket);
122   }
123
124   bool Send(const void* data, size_t len) {
125     rtc::PacketOptions options;
126     size_t ret = send_socket_->Send(
127         reinterpret_cast<const char*>(data), len, options);
128     vss_->ProcessMessagesUntilIdle();
129     return (ret == len);
130   }
131
132   bool CheckData(const void* data, int len) {
133     bool ret = false;
134     if (recv_packets_.size()) {
135       std::string packet =  recv_packets_.front();
136       recv_packets_.pop_front();
137       ret = (memcmp(data, packet.c_str(), len) == 0);
138     }
139     return ret;
140   }
141
142   rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
143   rtc::SocketServerScope ss_scope_;
144   rtc::scoped_ptr<AsyncStunTCPSocket> send_socket_;
145   rtc::scoped_ptr<AsyncStunTCPSocket> recv_socket_;
146   rtc::scoped_ptr<rtc::AsyncPacketSocket> listen_socket_;
147   std::list<std::string> recv_packets_;
148 };
149
150 // Testing a stun packet sent/recv properly.
151 TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
152   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
153                    sizeof(kStunMessageWithZeroLength)));
154   EXPECT_EQ(1u, recv_packets_.size());
155   EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
156                         sizeof(kStunMessageWithZeroLength)));
157 }
158
159 // Verify sending multiple packets.
160 TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
161   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
162                    sizeof(kStunMessageWithZeroLength)));
163   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
164                    sizeof(kStunMessageWithZeroLength)));
165   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
166                    sizeof(kStunMessageWithZeroLength)));
167   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
168                    sizeof(kStunMessageWithZeroLength)));
169   EXPECT_EQ(4u, recv_packets_.size());
170 }
171
172 // Verifying TURN channel data message with zero length.
173 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
174   EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
175                    sizeof(kTurnChannelDataMessageWithZeroLength)));
176   EXPECT_EQ(1u, recv_packets_.size());
177   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
178                         sizeof(kTurnChannelDataMessageWithZeroLength)));
179 }
180
181 // Verifying TURN channel data message.
182 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
183   EXPECT_TRUE(Send(kTurnChannelDataMessage,
184                    sizeof(kTurnChannelDataMessage)));
185   EXPECT_EQ(1u, recv_packets_.size());
186   EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
187                         sizeof(kTurnChannelDataMessage)));
188 }
189
190 // Verifying TURN channel messages which needs padding handled properly.
191 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
192   EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
193                    sizeof(kTurnChannelDataMessageWithOddLength)));
194   EXPECT_EQ(1u, recv_packets_.size());
195   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
196                         sizeof(kTurnChannelDataMessageWithOddLength)));
197 }
198
199 // Verifying stun message with invalid length.
200 TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
201   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
202                     sizeof(kStunMessageWithInvalidLength)));
203   EXPECT_EQ(0u, recv_packets_.size());
204
205   // Modify the message length to larger value.
206   kStunMessageWithInvalidLength[2] = 0xFF;
207   kStunMessageWithInvalidLength[3] = 0xFF;
208   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
209                     sizeof(kStunMessageWithInvalidLength)));
210
211   // Modify the message length to smaller value.
212   kStunMessageWithInvalidLength[2] = 0x00;
213   kStunMessageWithInvalidLength[3] = 0x01;
214   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
215                     sizeof(kStunMessageWithInvalidLength)));
216 }
217
218 // Verifying TURN channel data message with invalid length.
219 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
220   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
221                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
222   // Modify the length to larger value.
223   kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
224   kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
225   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
226                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
227
228   // Modify the length to smaller value.
229   kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
230   kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
231   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
232                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
233 }
234
235 // Verifying a small buffer handled (dropped) properly. This will be
236 // a common one for both stun and turn.
237 TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
238   char data[1];
239   EXPECT_FALSE(Send(data, sizeof(data)));
240 }
241
242 // Verifying a legal large turn message.
243 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
244   // We have problem in getting the SignalWriteEvent from the virtual socket
245   // server. So increasing the send buffer to 64k.
246   // TODO(mallinath) - Remove this setting after we fix vss issue.
247   vss_->set_send_buffer_capacity(64 * 1024);
248   unsigned char packet[65539];
249   packet[0] = 0x40;
250   packet[1] = 0x00;
251   packet[2] = 0xFF;
252   packet[3] = 0xFF;
253   EXPECT_TRUE(Send(packet, sizeof(packet)));
254 }
255
256 // Verifying a legal large stun message.
257 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
258   // We have problem in getting the SignalWriteEvent from the virtual socket
259   // server. So increasing the send buffer to 64k.
260   // TODO(mallinath) - Remove this setting after we fix vss issue.
261   vss_->set_send_buffer_capacity(64 * 1024);
262   unsigned char packet[65552];
263   packet[0] = 0x00;
264   packet[1] = 0x01;
265   packet[2] = 0xFF;
266   packet[3] = 0xFC;
267   EXPECT_TRUE(Send(packet, sizeof(packet)));
268 }
269
270 // Investigate why WriteEvent is not signaled from VSS.
271 TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
272   vss_->set_send_buffer_capacity(1);
273   Send(kTurnChannelDataMessageWithOddLength,
274        sizeof(kTurnChannelDataMessageWithOddLength));
275   EXPECT_EQ(1u, recv_packets_.size());
276   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
277                         sizeof(kTurnChannelDataMessageWithOddLength)));
278 }
279
280 }  // namespace cricket