3 * Copyright 2004 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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"
40 using rtc::SocketAddress;
41 using namespace cricket;
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...";
54 class RelayServerTest : public testing::Test {
57 : main_(rtc::Thread::Current()), ss_(main_->socketserver()),
58 username_(rtc::CreateRandomString(12)),
59 password_(rtc::CreateRandomString(12)) {
62 virtual void SetUp() {
63 server_.reset(new RelayServer(main_));
65 server_->AddInternalSocket(
66 rtc::AsyncUDPSocket::Create(ss_, server_int_addr));
67 server_->AddExternalSocket(
68 rtc::AsyncUDPSocket::Create(ss_, server_ext_addr));
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)));
77 rtc::scoped_ptr<StunMessage> req(
78 CreateStunMessage(STUN_ALLOCATE_REQUEST));
79 AddUsernameAttr(req.get(), username_);
80 AddLifetimeAttr(req.get(), LIFETIME);
85 rtc::scoped_ptr<StunMessage> req(
86 CreateStunMessage(STUN_BINDING_REQUEST));
87 AddUsernameAttr(req.get(), username_);
92 void Send1(const StunMessage* msg) {
95 SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
97 void Send2(const StunMessage* msg) {
100 SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
102 void SendRaw1(const char* data, int len) {
103 return Send(client1_.get(), data, len, server_int_addr);
105 void SendRaw2(const char* data, int len) {
106 return Send(client2_.get(), data, len, server_ext_addr);
108 void Send(rtc::TestClient* client, const char* data,
109 int len, const SocketAddress& addr) {
110 client->SendTo(data, len, addr);
113 StunMessage* Receive1() {
114 return Receive(client1_.get());
116 StunMessage* Receive2() {
117 return Receive(client2_.get());
119 std::string ReceiveRaw1() {
120 return ReceiveRaw(client1_.get());
122 std::string ReceiveRaw2() {
123 return ReceiveRaw(client2_.get());
125 StunMessage* Receive(rtc::TestClient* client) {
126 StunMessage* msg = NULL;
127 rtc::TestClient::Packet* packet = client->NextPacket();
129 rtc::ByteBuffer buf(packet->buf, packet->size);
130 msg = new RelayMessage();
136 std::string ReceiveRaw(rtc::TestClient* client) {
138 rtc::TestClient::Packet* packet = client->NextPacket();
140 raw = std::string(packet->buf, packet->size);
146 static StunMessage* CreateStunMessage(int type) {
147 StunMessage* msg = new RelayMessage();
149 msg->SetTransactionID(
150 rtc::CreateRandomString(kStunTransactionIdLength));
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);
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);
165 static void AddLifetimeAttr(StunMessage* msg, int val) {
166 StunUInt32Attribute* attr =
167 StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
169 msg->AddAttribute(attr);
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);
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_;
188 // Send a complete nonsense message and verify that it is eaten.
189 TEST_F(RelayServerTest, TestBadRequest) {
190 rtc::scoped_ptr<StunMessage> res;
192 SendRaw1(bad, static_cast<int>(strlen(bad)));
193 res.reset(Receive1());
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;
204 res.reset(Receive1());
207 EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
208 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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_);
224 res.reset(Receive1());
227 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
228 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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);
245 res.reset(Receive1());
248 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
249 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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());
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) {
269 rtc::scoped_ptr<StunMessage> req(
270 CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
271 AddMagicCookieAttr(req.get());
272 AddUsernameAttr(req.get(), username_);
275 res.reset(Receive1());
278 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
279 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
288 const StunUInt32Attribute* lifetime_attr =
289 res->GetUInt32(STUN_ATTR_LIFETIME);
290 ASSERT_TRUE(lifetime_attr != NULL);
291 EXPECT_EQ(LIFETIME, lifetime_attr->value());
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) {
299 rtc::scoped_ptr<StunMessage> req(
300 CreateStunMessage(STUN_BINDING_REQUEST)), res;
301 AddUsernameAttr(req.get(), username_);
304 res.reset(Receive1());
307 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
309 const StunByteStringAttribute* recv_data =
310 res->GetByteString(STUN_ATTR_DATA);
311 ASSERT_TRUE(recv_data != NULL);
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());
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());
326 EXPECT_TRUE(Receive2() == NULL);
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) {
335 SendRaw1(bad, static_cast<int>(strlen(bad)));
336 EXPECT_TRUE(Receive1() == NULL);
337 EXPECT_TRUE(Receive2() == NULL);
340 // Send a send request without a username and verify it is rejected.
341 TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
345 rtc::scoped_ptr<StunMessage> req(
346 CreateStunMessage(STUN_SEND_REQUEST)), res;
347 AddMagicCookieAttr(req.get());
350 res.reset(Receive1());
353 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
354 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
363 // Send a send request with the wrong username and verify it is rejected.
364 TEST_F(RelayServerTest, TestSendRequestBadUsername) {
368 rtc::scoped_ptr<StunMessage> req(
369 CreateStunMessage(STUN_SEND_REQUEST)), res;
370 AddMagicCookieAttr(req.get());
371 AddUsernameAttr(req.get(), "foobarbizbaz");
374 res.reset(Receive1());
377 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
378 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
387 // Send a send request without a destination address and verify that it is
389 TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
393 rtc::scoped_ptr<StunMessage> req(
394 CreateStunMessage(STUN_SEND_REQUEST)), res;
395 AddMagicCookieAttr(req.get());
396 AddUsernameAttr(req.get(), username_);
399 res.reset(Receive1());
402 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
403 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
412 // Send a send request without data and verify that it is rejected.
413 TEST_F(RelayServerTest, TestSendRequestNoData) {
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);
424 res.reset(Receive1());
427 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
428 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
437 // Send a binding request after an allocate and verify that it is rejected.
438 TEST_F(RelayServerTest, TestSendRequestWrongType) {
442 rtc::scoped_ptr<StunMessage> req(
443 CreateStunMessage(STUN_BINDING_REQUEST)), res;
444 AddMagicCookieAttr(req.get());
445 AddUsernameAttr(req.get(), username_);
448 res.reset(Receive1());
451 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
452 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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) {
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);
474 StunByteStringAttribute* send_data =
475 StunAttribute::CreateByteString(STUN_ATTR_DATA);
476 send_data->CopyBytes(msg1);
477 req->AddAttribute(send_data);
480 EXPECT_EQ(msg1, ReceiveRaw2());
481 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
482 res.reset(Receive1());
485 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
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());
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()));
502 // Verify that a binding expires properly, and rejects send requests.
503 TEST_F(RelayServerTest, TestExpiration) {
507 // Wait twice the lifetime to make sure the server has expired the binding.
508 rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
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);
516 StunByteStringAttribute* data_attr =
517 StunAttribute::CreateByteString(STUN_ATTR_DATA);
518 data_attr->CopyBytes(msg1);
519 req->AddAttribute(data_attr);
522 res.reset(Receive1());
524 ASSERT_TRUE(res.get() != NULL);
525 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
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());
533 // Also verify that traffic from the external client is ignored.
534 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
535 EXPECT_TRUE(ReceiveRaw1().empty());