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