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