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
24using rtc::SocketAddress;
25using namespace cricket;
26
27static const uint32_t LIFETIME = 4;  // seconds
28static const SocketAddress server_int_addr("127.0.0.1", 5000);
29static const SocketAddress server_ext_addr("127.0.0.1", 5001);
30static const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
31static const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
32static 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";
35static const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
36static const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
37
38class 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.
185TEST_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.
191TEST_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.
210TEST_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.
230TEST_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.
258TEST_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.
288TEST_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.
323TEST_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.
333TEST_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.
356TEST_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.
381TEST_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.
405TEST_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.
430TEST_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.
455TEST_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
496TEST_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