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 "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"
40 using talk_base::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 {
56 static void SetUpTestCase() {
57 talk_base::InitializeSSL();
60 static void TearDownTestCase() {
61 talk_base::CleanupSSL();
65 : main_(talk_base::Thread::Current()), ss_(main_->socketserver()),
66 username_(talk_base::CreateRandomString(12)),
67 password_(talk_base::CreateRandomString(12)) {
70 virtual void SetUp() {
71 server_.reset(new RelayServer(main_));
73 server_->AddInternalSocket(
74 talk_base::AsyncUDPSocket::Create(ss_, server_int_addr));
75 server_->AddExternalSocket(
76 talk_base::AsyncUDPSocket::Create(ss_, server_ext_addr));
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)));
85 talk_base::scoped_ptr<StunMessage> req(
86 CreateStunMessage(STUN_ALLOCATE_REQUEST));
87 AddUsernameAttr(req.get(), username_);
88 AddLifetimeAttr(req.get(), LIFETIME);
93 talk_base::scoped_ptr<StunMessage> req(
94 CreateStunMessage(STUN_BINDING_REQUEST));
95 AddUsernameAttr(req.get(), username_);
100 void Send1(const StunMessage* msg) {
101 talk_base::ByteBuffer buf;
103 SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
105 void Send2(const StunMessage* msg) {
106 talk_base::ByteBuffer buf;
108 SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
110 void SendRaw1(const char* data, int len) {
111 return Send(client1_.get(), data, len, server_int_addr);
113 void SendRaw2(const char* data, int len) {
114 return Send(client2_.get(), data, len, server_ext_addr);
116 void Send(talk_base::TestClient* client, const char* data,
117 int len, const SocketAddress& addr) {
118 client->SendTo(data, len, addr);
121 StunMessage* Receive1() {
122 return Receive(client1_.get());
124 StunMessage* Receive2() {
125 return Receive(client2_.get());
127 std::string ReceiveRaw1() {
128 return ReceiveRaw(client1_.get());
130 std::string ReceiveRaw2() {
131 return ReceiveRaw(client2_.get());
133 StunMessage* Receive(talk_base::TestClient* client) {
134 StunMessage* msg = NULL;
135 talk_base::TestClient::Packet* packet = client->NextPacket();
137 talk_base::ByteBuffer buf(packet->buf, packet->size);
138 msg = new RelayMessage();
144 std::string ReceiveRaw(talk_base::TestClient* client) {
146 talk_base::TestClient::Packet* packet = client->NextPacket();
148 raw = std::string(packet->buf, packet->size);
154 static StunMessage* CreateStunMessage(int type) {
155 StunMessage* msg = new RelayMessage();
157 msg->SetTransactionID(
158 talk_base::CreateRandomString(kStunTransactionIdLength));
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);
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);
173 static void AddLifetimeAttr(StunMessage* msg, int val) {
174 StunUInt32Attribute* attr =
175 StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
177 msg->AddAttribute(attr);
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);
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_;
196 // Send a complete nonsense message and verify that it is eaten.
197 TEST_F(RelayServerTest, TestBadRequest) {
198 talk_base::scoped_ptr<StunMessage> res;
200 SendRaw1(bad, static_cast<int>(std::strlen(bad)));
201 res.reset(Receive1());
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;
212 res.reset(Receive1());
215 EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
216 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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_);
232 res.reset(Receive1());
235 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
236 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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);
253 res.reset(Receive1());
256 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
257 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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());
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) {
277 talk_base::scoped_ptr<StunMessage> req(
278 CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
279 AddMagicCookieAttr(req.get());
280 AddUsernameAttr(req.get(), username_);
283 res.reset(Receive1());
286 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
287 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
296 const StunUInt32Attribute* lifetime_attr =
297 res->GetUInt32(STUN_ATTR_LIFETIME);
298 ASSERT_TRUE(lifetime_attr != NULL);
299 EXPECT_EQ(LIFETIME, lifetime_attr->value());
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) {
307 talk_base::scoped_ptr<StunMessage> req(
308 CreateStunMessage(STUN_BINDING_REQUEST)), res;
309 AddUsernameAttr(req.get(), username_);
312 res.reset(Receive1());
315 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
317 const StunByteStringAttribute* recv_data =
318 res->GetByteString(STUN_ATTR_DATA);
319 ASSERT_TRUE(recv_data != NULL);
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());
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());
334 EXPECT_TRUE(Receive2() == NULL);
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) {
343 SendRaw1(bad, static_cast<int>(std::strlen(bad)));
344 EXPECT_TRUE(Receive1() == NULL);
345 EXPECT_TRUE(Receive2() == NULL);
348 // Send a send request without a username and verify it is rejected.
349 TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
353 talk_base::scoped_ptr<StunMessage> req(
354 CreateStunMessage(STUN_SEND_REQUEST)), res;
355 AddMagicCookieAttr(req.get());
358 res.reset(Receive1());
361 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
362 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
371 // Send a send request with the wrong username and verify it is rejected.
372 TEST_F(RelayServerTest, TestSendRequestBadUsername) {
376 talk_base::scoped_ptr<StunMessage> req(
377 CreateStunMessage(STUN_SEND_REQUEST)), res;
378 AddMagicCookieAttr(req.get());
379 AddUsernameAttr(req.get(), "foobarbizbaz");
382 res.reset(Receive1());
385 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
386 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
395 // Send a send request without a destination address and verify that it is
397 TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
401 talk_base::scoped_ptr<StunMessage> req(
402 CreateStunMessage(STUN_SEND_REQUEST)), res;
403 AddMagicCookieAttr(req.get());
404 AddUsernameAttr(req.get(), username_);
407 res.reset(Receive1());
410 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
411 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
420 // Send a send request without data and verify that it is rejected.
421 TEST_F(RelayServerTest, TestSendRequestNoData) {
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);
432 res.reset(Receive1());
435 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
436 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
445 // Send a binding request after an allocate and verify that it is rejected.
446 TEST_F(RelayServerTest, TestSendRequestWrongType) {
450 talk_base::scoped_ptr<StunMessage> req(
451 CreateStunMessage(STUN_BINDING_REQUEST)), res;
452 AddMagicCookieAttr(req.get());
453 AddUsernameAttr(req.get(), username_);
456 res.reset(Receive1());
459 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
460 EXPECT_EQ(req->transaction_id(), res->transaction_id());
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());
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) {
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);
482 StunByteStringAttribute* send_data =
483 StunAttribute::CreateByteString(STUN_ATTR_DATA);
484 send_data->CopyBytes(msg1);
485 req->AddAttribute(send_data);
488 EXPECT_EQ(msg1, ReceiveRaw2());
489 SendRaw2(msg2, static_cast<int>(std::strlen(msg2)));
490 res.reset(Receive1());
493 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
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());
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()));
510 // Verify that a binding expires properly, and rejects send requests.
511 TEST_F(RelayServerTest, TestExpiration) {
515 // Wait twice the lifetime to make sure the server has expired the binding.
516 talk_base::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
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);
524 StunByteStringAttribute* data_attr =
525 StunAttribute::CreateByteString(STUN_ATTR_DATA);
526 data_attr->CopyBytes(msg1);
527 req->AddAttribute(data_attr);
530 res.reset(Receive1());
532 ASSERT_TRUE(res.get() != NULL);
533 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
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());
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());