c6a7b1b6fbca2fe073663489dbe0e7a36e82f9ba
[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/base/asyncsocket.h"
29 #include "talk/base/gunit.h"
30 #include "talk/base/physicalsocketserver.h"
31 #include "talk/base/virtualsocketserver.h"
32 #include "talk/p2p/base/asyncstuntcpsocket.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 talk_base::SocketAddress kClientAddr("11.11.11.11", 0);
81 static const talk_base::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 talk_base::VirtualSocketServer(NULL)),
88         ss_scope_(vss_.get()) {
89   }
90
91   virtual void SetUp() {
92     CreateSockets();
93   }
94
95   void CreateSockets() {
96     talk_base::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     talk_base::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(talk_base::AsyncPacketSocket* socket, const char* data,
112                     size_t len, const talk_base::SocketAddress& remote_addr,
113                     const talk_base::PacketTime& packet_time) {
114     recv_packets_.push_back(std::string(data, len));
115   }
116
117   void OnNewConnection(talk_base::AsyncPacketSocket* server,
118                        talk_base::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     size_t ret = send_socket_->Send(
126         reinterpret_cast<const char*>(data), len, talk_base::DSCP_NO_CHANGE);
127     vss_->ProcessMessagesUntilIdle();
128     return (ret == len);
129   }
130
131   bool CheckData(const void* data, int len) {
132     bool ret = false;
133     if (recv_packets_.size()) {
134       std::string packet =  recv_packets_.front();
135       recv_packets_.pop_front();
136       ret = (memcmp(data, packet.c_str(), len) == 0);
137     }
138     return ret;
139   }
140
141   talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
142   talk_base::SocketServerScope ss_scope_;
143   talk_base::scoped_ptr<AsyncStunTCPSocket> send_socket_;
144   talk_base::scoped_ptr<AsyncStunTCPSocket> recv_socket_;
145   talk_base::scoped_ptr<talk_base::AsyncPacketSocket> listen_socket_;
146   std::list<std::string> recv_packets_;
147 };
148
149 // Testing a stun packet sent/recv properly.
150 TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
151   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
152                    sizeof(kStunMessageWithZeroLength)));
153   EXPECT_EQ(1u, recv_packets_.size());
154   EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
155                         sizeof(kStunMessageWithZeroLength)));
156 }
157
158 // Verify sending multiple packets.
159 TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
160   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
161                    sizeof(kStunMessageWithZeroLength)));
162   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
163                    sizeof(kStunMessageWithZeroLength)));
164   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
165                    sizeof(kStunMessageWithZeroLength)));
166   EXPECT_TRUE(Send(kStunMessageWithZeroLength,
167                    sizeof(kStunMessageWithZeroLength)));
168   EXPECT_EQ(4u, recv_packets_.size());
169 }
170
171 // Verifying TURN channel data message with zero length.
172 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
173   EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
174                    sizeof(kTurnChannelDataMessageWithZeroLength)));
175   EXPECT_EQ(1u, recv_packets_.size());
176   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
177                         sizeof(kTurnChannelDataMessageWithZeroLength)));
178 }
179
180 // Verifying TURN channel data message.
181 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
182   EXPECT_TRUE(Send(kTurnChannelDataMessage,
183                    sizeof(kTurnChannelDataMessage)));
184   EXPECT_EQ(1u, recv_packets_.size());
185   EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
186                         sizeof(kTurnChannelDataMessage)));
187 }
188
189 // Verifying TURN channel messages which needs padding handled properly.
190 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
191   EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
192                    sizeof(kTurnChannelDataMessageWithOddLength)));
193   EXPECT_EQ(1u, recv_packets_.size());
194   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
195                         sizeof(kTurnChannelDataMessageWithOddLength)));
196 }
197
198 // Verifying stun message with invalid length.
199 TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
200   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
201                     sizeof(kStunMessageWithInvalidLength)));
202   EXPECT_EQ(0u, recv_packets_.size());
203
204   // Modify the message length to larger value.
205   kStunMessageWithInvalidLength[2] = 0xFF;
206   kStunMessageWithInvalidLength[3] = 0xFF;
207   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
208                     sizeof(kStunMessageWithInvalidLength)));
209
210   // Modify the message length to smaller value.
211   kStunMessageWithInvalidLength[2] = 0x00;
212   kStunMessageWithInvalidLength[3] = 0x01;
213   EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
214                     sizeof(kStunMessageWithInvalidLength)));
215 }
216
217 // Verifying TURN channel data message with invalid length.
218 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
219   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
220                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
221   // Modify the length to larger value.
222   kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
223   kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
224   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
225                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
226
227   // Modify the length to smaller value.
228   kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
229   kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
230   EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
231                    sizeof(kTurnChannelDataMessageWithInvalidLength)));
232 }
233
234 // Verifying a small buffer handled (dropped) properly. This will be
235 // a common one for both stun and turn.
236 TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
237   char data[1];
238   EXPECT_FALSE(Send(data, sizeof(data)));
239 }
240
241 // Verifying a legal large turn message.
242 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
243   // We have problem in getting the SignalWriteEvent from the virtual socket
244   // server. So increasing the send buffer to 64k.
245   // TODO(mallinath) - Remove this setting after we fix vss issue.
246   vss_->set_send_buffer_capacity(64 * 1024);
247   unsigned char packet[65539];
248   packet[0] = 0x40;
249   packet[1] = 0x00;
250   packet[2] = 0xFF;
251   packet[3] = 0xFF;
252   EXPECT_TRUE(Send(packet, sizeof(packet)));
253 }
254
255 // Verifying a legal large stun message.
256 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
257   // We have problem in getting the SignalWriteEvent from the virtual socket
258   // server. So increasing the send buffer to 64k.
259   // TODO(mallinath) - Remove this setting after we fix vss issue.
260   vss_->set_send_buffer_capacity(64 * 1024);
261   unsigned char packet[65552];
262   packet[0] = 0x00;
263   packet[1] = 0x01;
264   packet[2] = 0xFF;
265   packet[3] = 0xFC;
266   EXPECT_TRUE(Send(packet, sizeof(packet)));
267 }
268
269 // Investigate why WriteEvent is not signaled from VSS.
270 TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
271   vss_->set_send_buffer_capacity(1);
272   Send(kTurnChannelDataMessageWithOddLength,
273        sizeof(kTurnChannelDataMessageWithOddLength));
274   EXPECT_EQ(1u, recv_packets_.size());
275   EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
276                         sizeof(kTurnChannelDataMessageWithOddLength)));
277 }
278
279 }  // namespace cricket