Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / relayserver_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2004 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 <string>
29
30 #include "webrtc/p2p/base/relayserver.h"
31 #include "webrtc/base/gunit.h"
32 #include "webrtc/base/helpers.h"
33 #include "webrtc/base/logging.h"
34 #include "webrtc/base/physicalsocketserver.h"
35 #include "webrtc/base/socketaddress.h"
36 #include "webrtc/base/ssladapter.h"
37 #include "webrtc/base/testclient.h"
38 #include "webrtc/base/thread.h"
39
40 using rtc::SocketAddress;
41 using namespace cricket;
42
43 static const uint32 LIFETIME = 4;  // seconds
44 static const SocketAddress server_int_addr("127.0.0.1", 5000);
45 static const SocketAddress server_ext_addr("127.0.0.1", 5001);
46 static const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
47 static const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
48 static const char* bad = "this is a completely nonsensical message whose only "
49                          "purpose is to make the parser go 'ack'.  it doesn't "
50                          "look anything like a normal stun message";
51 static const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
52 static const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
53
54 class RelayServerTest : public testing::Test {
55  public:
56   RelayServerTest()
57       : main_(rtc::Thread::Current()), ss_(main_->socketserver()),
58         username_(rtc::CreateRandomString(12)),
59         password_(rtc::CreateRandomString(12)) {
60   }
61  protected:
62   virtual void SetUp() {
63     server_.reset(new RelayServer(main_));
64
65     server_->AddInternalSocket(
66         rtc::AsyncUDPSocket::Create(ss_, server_int_addr));
67     server_->AddExternalSocket(
68         rtc::AsyncUDPSocket::Create(ss_, server_ext_addr));
69
70     client1_.reset(new rtc::TestClient(
71         rtc::AsyncUDPSocket::Create(ss_, client1_addr)));
72     client2_.reset(new rtc::TestClient(
73         rtc::AsyncUDPSocket::Create(ss_, client2_addr)));
74   }
75
76   void Allocate() {
77     rtc::scoped_ptr<StunMessage> req(
78         CreateStunMessage(STUN_ALLOCATE_REQUEST));
79     AddUsernameAttr(req.get(), username_);
80     AddLifetimeAttr(req.get(), LIFETIME);
81     Send1(req.get());
82     delete Receive1();
83   }
84   void Bind() {
85     rtc::scoped_ptr<StunMessage> req(
86         CreateStunMessage(STUN_BINDING_REQUEST));
87     AddUsernameAttr(req.get(), username_);
88     Send2(req.get());
89     delete Receive1();
90   }
91
92   void Send1(const StunMessage* msg) {
93     rtc::ByteBuffer buf;
94     msg->Write(&buf);
95     SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
96   }
97   void Send2(const StunMessage* msg) {
98     rtc::ByteBuffer buf;
99     msg->Write(&buf);
100     SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
101   }
102   void SendRaw1(const char* data, int len) {
103     return Send(client1_.get(), data, len, server_int_addr);
104   }
105   void SendRaw2(const char* data, int len) {
106     return Send(client2_.get(), data, len, server_ext_addr);
107   }
108   void Send(rtc::TestClient* client, const char* data,
109             int len, const SocketAddress& addr) {
110     client->SendTo(data, len, addr);
111   }
112
113   StunMessage* Receive1() {
114     return Receive(client1_.get());
115   }
116   StunMessage* Receive2() {
117     return Receive(client2_.get());
118   }
119   std::string ReceiveRaw1() {
120     return ReceiveRaw(client1_.get());
121   }
122   std::string ReceiveRaw2() {
123     return ReceiveRaw(client2_.get());
124   }
125   StunMessage* Receive(rtc::TestClient* client) {
126     StunMessage* msg = NULL;
127     rtc::TestClient::Packet* packet = client->NextPacket();
128     if (packet) {
129       rtc::ByteBuffer buf(packet->buf, packet->size);
130       msg = new RelayMessage();
131       msg->Read(&buf);
132       delete packet;
133     }
134     return msg;
135   }
136   std::string ReceiveRaw(rtc::TestClient* client) {
137     std::string raw;
138     rtc::TestClient::Packet* packet = client->NextPacket();
139     if (packet) {
140       raw = std::string(packet->buf, packet->size);
141       delete packet;
142     }
143     return raw;
144   }
145
146   static StunMessage* CreateStunMessage(int type) {
147     StunMessage* msg = new RelayMessage();
148     msg->SetType(type);
149     msg->SetTransactionID(
150         rtc::CreateRandomString(kStunTransactionIdLength));
151     return msg;
152   }
153   static void AddMagicCookieAttr(StunMessage* msg) {
154     StunByteStringAttribute* attr =
155         StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
156     attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
157     msg->AddAttribute(attr);
158   }
159   static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
160     StunByteStringAttribute* attr =
161         StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
162     attr->CopyBytes(val.c_str(), val.size());
163     msg->AddAttribute(attr);
164   }
165   static void AddLifetimeAttr(StunMessage* msg, int val) {
166     StunUInt32Attribute* attr =
167         StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
168     attr->SetValue(val);
169     msg->AddAttribute(attr);
170   }
171   static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
172     StunAddressAttribute* attr =
173         StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
174     attr->SetIP(addr.ipaddr());
175     attr->SetPort(addr.port());
176     msg->AddAttribute(attr);
177   }
178
179   rtc::Thread* main_;
180   rtc::SocketServer* ss_;
181   rtc::scoped_ptr<RelayServer> server_;
182   rtc::scoped_ptr<rtc::TestClient> client1_;
183   rtc::scoped_ptr<rtc::TestClient> client2_;
184   std::string username_;
185   std::string password_;
186 };
187
188 // Send a complete nonsense message and verify that it is eaten.
189 TEST_F(RelayServerTest, TestBadRequest) {
190   rtc::scoped_ptr<StunMessage> res;
191
192   SendRaw1(bad, static_cast<int>(strlen(bad)));
193   res.reset(Receive1());
194
195   ASSERT_TRUE(!res);
196 }
197
198 // Send an allocate request without a username and verify it is rejected.
199 TEST_F(RelayServerTest, TestAllocateNoUsername) {
200   rtc::scoped_ptr<StunMessage> req(
201       CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
202
203   Send1(req.get());
204   res.reset(Receive1());
205
206   ASSERT_TRUE(res);
207   EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
208   EXPECT_EQ(req->transaction_id(), res->transaction_id());
209
210   const StunErrorCodeAttribute* err = res->GetErrorCode();
211   ASSERT_TRUE(err != NULL);
212   EXPECT_EQ(4, err->eclass());
213   EXPECT_EQ(32, err->number());
214   EXPECT_EQ("Missing Username", err->reason());
215 }
216
217 // Send a binding request and verify that it is rejected.
218 TEST_F(RelayServerTest, TestBindingRequest) {
219   rtc::scoped_ptr<StunMessage> req(
220       CreateStunMessage(STUN_BINDING_REQUEST)), res;
221   AddUsernameAttr(req.get(), username_);
222
223   Send1(req.get());
224   res.reset(Receive1());
225
226   ASSERT_TRUE(res);
227   EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
228   EXPECT_EQ(req->transaction_id(), res->transaction_id());
229
230   const StunErrorCodeAttribute* err = res->GetErrorCode();
231   ASSERT_TRUE(err != NULL);
232   EXPECT_EQ(6, err->eclass());
233   EXPECT_EQ(0, err->number());
234   EXPECT_EQ("Operation Not Supported", err->reason());
235 }
236
237 // Send an allocate request and verify that it is accepted.
238 TEST_F(RelayServerTest, TestAllocate) {
239   rtc::scoped_ptr<StunMessage> req(
240       CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
241   AddUsernameAttr(req.get(), username_);
242   AddLifetimeAttr(req.get(), LIFETIME);
243
244   Send1(req.get());
245   res.reset(Receive1());
246
247   ASSERT_TRUE(res);
248   EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
249   EXPECT_EQ(req->transaction_id(), res->transaction_id());
250
251   const StunAddressAttribute* mapped_addr =
252       res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
253   ASSERT_TRUE(mapped_addr != NULL);
254   EXPECT_EQ(1, mapped_addr->family());
255   EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
256   EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
257
258   const StunUInt32Attribute* res_lifetime_attr =
259       res->GetUInt32(STUN_ATTR_LIFETIME);
260   ASSERT_TRUE(res_lifetime_attr != NULL);
261   EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
262 }
263
264 // Send a second allocate request and verify that it is also accepted, though
265 // the lifetime should be ignored.
266 TEST_F(RelayServerTest, TestReallocate) {
267   Allocate();
268
269   rtc::scoped_ptr<StunMessage> req(
270       CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
271   AddMagicCookieAttr(req.get());
272   AddUsernameAttr(req.get(), username_);
273
274   Send1(req.get());
275   res.reset(Receive1());
276
277   ASSERT_TRUE(res);
278   EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
279   EXPECT_EQ(req->transaction_id(), res->transaction_id());
280
281   const StunAddressAttribute* mapped_addr =
282       res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
283   ASSERT_TRUE(mapped_addr != NULL);
284   EXPECT_EQ(1, mapped_addr->family());
285   EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
286   EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
287
288   const StunUInt32Attribute* lifetime_attr =
289       res->GetUInt32(STUN_ATTR_LIFETIME);
290   ASSERT_TRUE(lifetime_attr != NULL);
291   EXPECT_EQ(LIFETIME, lifetime_attr->value());
292 }
293
294 // Send a request from another client and see that it arrives at the first
295 // client in the binding.
296 TEST_F(RelayServerTest, TestRemoteBind) {
297   Allocate();
298
299   rtc::scoped_ptr<StunMessage> req(
300       CreateStunMessage(STUN_BINDING_REQUEST)), res;
301   AddUsernameAttr(req.get(), username_);
302
303   Send2(req.get());
304   res.reset(Receive1());
305
306   ASSERT_TRUE(res);
307   EXPECT_EQ(STUN_DATA_INDICATION, res->type());
308
309   const StunByteStringAttribute* recv_data =
310       res->GetByteString(STUN_ATTR_DATA);
311   ASSERT_TRUE(recv_data != NULL);
312
313   rtc::ByteBuffer buf(recv_data->bytes(), recv_data->length());
314   rtc::scoped_ptr<StunMessage> res2(new StunMessage());
315   EXPECT_TRUE(res2->Read(&buf));
316   EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
317   EXPECT_EQ(req->transaction_id(), res2->transaction_id());
318
319   const StunAddressAttribute* src_addr =
320       res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
321   ASSERT_TRUE(src_addr != NULL);
322   EXPECT_EQ(1, src_addr->family());
323   EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
324   EXPECT_EQ(client2_addr.port(), src_addr->port());
325
326   EXPECT_TRUE(Receive2() == NULL);
327 }
328
329 // Send a complete nonsense message to the established connection and verify
330 // that it is dropped by the server.
331 TEST_F(RelayServerTest, TestRemoteBadRequest) {
332   Allocate();
333   Bind();
334
335   SendRaw1(bad, static_cast<int>(strlen(bad)));
336   EXPECT_TRUE(Receive1() == NULL);
337   EXPECT_TRUE(Receive2() == NULL);
338 }
339
340 // Send a send request without a username and verify it is rejected.
341 TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
342   Allocate();
343   Bind();
344
345   rtc::scoped_ptr<StunMessage> req(
346       CreateStunMessage(STUN_SEND_REQUEST)), res;
347   AddMagicCookieAttr(req.get());
348
349   Send1(req.get());
350   res.reset(Receive1());
351
352   ASSERT_TRUE(res);
353   EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
354   EXPECT_EQ(req->transaction_id(), res->transaction_id());
355
356   const StunErrorCodeAttribute* err = res->GetErrorCode();
357   ASSERT_TRUE(err != NULL);
358   EXPECT_EQ(4, err->eclass());
359   EXPECT_EQ(32, err->number());
360   EXPECT_EQ("Missing Username", err->reason());
361 }
362
363 // Send a send request with the wrong username and verify it is rejected.
364 TEST_F(RelayServerTest, TestSendRequestBadUsername) {
365   Allocate();
366   Bind();
367
368   rtc::scoped_ptr<StunMessage> req(
369       CreateStunMessage(STUN_SEND_REQUEST)), res;
370   AddMagicCookieAttr(req.get());
371   AddUsernameAttr(req.get(), "foobarbizbaz");
372
373   Send1(req.get());
374   res.reset(Receive1());
375
376   ASSERT_TRUE(res);
377   EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
378   EXPECT_EQ(req->transaction_id(), res->transaction_id());
379
380   const StunErrorCodeAttribute* err = res->GetErrorCode();
381   ASSERT_TRUE(err != NULL);
382   EXPECT_EQ(4, err->eclass());
383   EXPECT_EQ(30, err->number());
384   EXPECT_EQ("Stale Credentials", err->reason());
385 }
386
387 // Send a send request without a destination address and verify that it is
388 // rejected.
389 TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
390   Allocate();
391   Bind();
392
393   rtc::scoped_ptr<StunMessage> req(
394       CreateStunMessage(STUN_SEND_REQUEST)), res;
395   AddMagicCookieAttr(req.get());
396   AddUsernameAttr(req.get(), username_);
397
398   Send1(req.get());
399   res.reset(Receive1());
400
401   ASSERT_TRUE(res);
402   EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
403   EXPECT_EQ(req->transaction_id(), res->transaction_id());
404
405   const StunErrorCodeAttribute* err = res->GetErrorCode();
406   ASSERT_TRUE(err != NULL);
407   EXPECT_EQ(4, err->eclass());
408   EXPECT_EQ(0, err->number());
409   EXPECT_EQ("Bad Request", err->reason());
410 }
411
412 // Send a send request without data and verify that it is rejected.
413 TEST_F(RelayServerTest, TestSendRequestNoData) {
414   Allocate();
415   Bind();
416
417   rtc::scoped_ptr<StunMessage> req(
418       CreateStunMessage(STUN_SEND_REQUEST)), res;
419   AddMagicCookieAttr(req.get());
420   AddUsernameAttr(req.get(), username_);
421   AddDestinationAttr(req.get(), client2_addr);
422
423   Send1(req.get());
424   res.reset(Receive1());
425
426   ASSERT_TRUE(res);
427   EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
428   EXPECT_EQ(req->transaction_id(), res->transaction_id());
429
430   const StunErrorCodeAttribute* err = res->GetErrorCode();
431   ASSERT_TRUE(err != NULL);
432   EXPECT_EQ(4, err->eclass());
433   EXPECT_EQ(00, err->number());
434   EXPECT_EQ("Bad Request", err->reason());
435 }
436
437 // Send a binding request after an allocate and verify that it is rejected.
438 TEST_F(RelayServerTest, TestSendRequestWrongType) {
439   Allocate();
440   Bind();
441
442   rtc::scoped_ptr<StunMessage> req(
443       CreateStunMessage(STUN_BINDING_REQUEST)), res;
444   AddMagicCookieAttr(req.get());
445   AddUsernameAttr(req.get(), username_);
446
447   Send1(req.get());
448   res.reset(Receive1());
449
450   ASSERT_TRUE(res);
451   EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
452   EXPECT_EQ(req->transaction_id(), res->transaction_id());
453
454   const StunErrorCodeAttribute* err = res->GetErrorCode();
455   ASSERT_TRUE(err != NULL);
456   EXPECT_EQ(6, err->eclass());
457   EXPECT_EQ(0, err->number());
458   EXPECT_EQ("Operation Not Supported", err->reason());
459 }
460
461 // Verify that we can send traffic back and forth between the clients after a
462 // successful allocate and bind.
463 TEST_F(RelayServerTest, TestSendRaw) {
464   Allocate();
465   Bind();
466
467   for (int i = 0; i < 10; i++) {
468     rtc::scoped_ptr<StunMessage> req(
469         CreateStunMessage(STUN_SEND_REQUEST)), res;
470     AddMagicCookieAttr(req.get());
471     AddUsernameAttr(req.get(), username_);
472     AddDestinationAttr(req.get(), client2_addr);
473
474     StunByteStringAttribute* send_data =
475         StunAttribute::CreateByteString(STUN_ATTR_DATA);
476     send_data->CopyBytes(msg1);
477     req->AddAttribute(send_data);
478
479     Send1(req.get());
480     EXPECT_EQ(msg1, ReceiveRaw2());
481     SendRaw2(msg2, static_cast<int>(strlen(msg2)));
482     res.reset(Receive1());
483
484     ASSERT_TRUE(res);
485     EXPECT_EQ(STUN_DATA_INDICATION, res->type());
486
487     const StunAddressAttribute* src_addr =
488         res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
489     ASSERT_TRUE(src_addr != NULL);
490     EXPECT_EQ(1, src_addr->family());
491     EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
492     EXPECT_EQ(client2_addr.port(), src_addr->port());
493
494     const StunByteStringAttribute* recv_data =
495         res->GetByteString(STUN_ATTR_DATA);
496     ASSERT_TRUE(recv_data != NULL);
497     EXPECT_EQ(strlen(msg2), recv_data->length());
498     EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
499   }
500 }
501
502 // Verify that a binding expires properly, and rejects send requests.
503 TEST_F(RelayServerTest, TestExpiration) {
504   Allocate();
505   Bind();
506
507   // Wait twice the lifetime to make sure the server has expired the binding.
508   rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
509
510   rtc::scoped_ptr<StunMessage> req(
511       CreateStunMessage(STUN_SEND_REQUEST)), res;
512   AddMagicCookieAttr(req.get());
513   AddUsernameAttr(req.get(), username_);
514   AddDestinationAttr(req.get(), client2_addr);
515
516   StunByteStringAttribute* data_attr =
517       StunAttribute::CreateByteString(STUN_ATTR_DATA);
518   data_attr->CopyBytes(msg1);
519   req->AddAttribute(data_attr);
520
521   Send1(req.get());
522   res.reset(Receive1());
523
524   ASSERT_TRUE(res.get() != NULL);
525   EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
526
527   const StunErrorCodeAttribute* err = res->GetErrorCode();
528   ASSERT_TRUE(err != NULL);
529   EXPECT_EQ(6, err->eclass());
530   EXPECT_EQ(0, err->number());
531   EXPECT_EQ("Operation Not Supported", err->reason());
532
533   // Also verify that traffic from the external client is ignored.
534   SendRaw2(msg2, static_cast<int>(strlen(msg2)));
535   EXPECT_TRUE(ReceiveRaw1().empty());
536 }