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:
RelayServerTest()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:
SetUp()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
Allocate()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 }
Bind()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
Send1(const StunMessage * msg)78 void Send1(const StunMessage* msg) {
79 rtc::ByteBuffer buf;
80 msg->Write(&buf);
81 SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
82 }
Send2(const StunMessage * msg)83 void Send2(const StunMessage* msg) {
84 rtc::ByteBuffer buf;
85 msg->Write(&buf);
86 SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
87 }
SendRaw1(const char * data,int len)88 void SendRaw1(const char* data, int len) {
89 return Send(client1_.get(), data, len, server_int_addr);
90 }
SendRaw2(const char * data,int len)91 void SendRaw2(const char* data, int len) {
92 return Send(client2_.get(), data, len, server_ext_addr);
93 }
Send(rtc::TestClient * client,const char * data,int len,const SocketAddress & addr)94 void Send(rtc::TestClient* client, const char* data,
95 int len, const SocketAddress& addr) {
96 client->SendTo(data, len, addr);
97 }
98
Receive1Fails()99 bool Receive1Fails() {
100 return client1_.get()->CheckNoPacket();
101 }
Receive2Fails()102 bool Receive2Fails() {
103 return client2_.get()->CheckNoPacket();
104 }
105
Receive1()106 StunMessage* Receive1() {
107 return Receive(client1_.get());
108 }
Receive2()109 StunMessage* Receive2() {
110 return Receive(client2_.get());
111 }
ReceiveRaw1()112 std::string ReceiveRaw1() {
113 return ReceiveRaw(client1_.get());
114 }
ReceiveRaw2()115 std::string ReceiveRaw2() {
116 return ReceiveRaw(client2_.get());
117 }
Receive(rtc::TestClient * client)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 }
ReceiveRaw(rtc::TestClient * client)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
CreateStunMessage(int type)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 }
AddMagicCookieAttr(StunMessage * msg)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 }
AddUsernameAttr(StunMessage * msg,const std::string & val)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 }
AddLifetimeAttr(StunMessage * msg,int val)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 }
AddDestinationAttr(StunMessage * msg,const SocketAddress & addr)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.
TEST_F(RelayServerTest,TestBadRequest)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.
TEST_F(RelayServerTest,TestAllocateNoUsername)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.
TEST_F(RelayServerTest,TestBindingRequest)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.
TEST_F(RelayServerTest,TestAllocate)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.
TEST_F(RelayServerTest,TestReallocate)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.
TEST_F(RelayServerTest,TestRemoteBind)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.
TEST_F(RelayServerTest,TestRemoteBadRequest)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.
TEST_F(RelayServerTest,TestSendRequestMissingUsername)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.
TEST_F(RelayServerTest,TestSendRequestBadUsername)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.
TEST_F(RelayServerTest,TestSendRequestNoDestinationAddress)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.
TEST_F(RelayServerTest,TestSendRequestNoData)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.
TEST_F(RelayServerTest,TestSendRequestWrongType)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.
TEST_F(RelayServerTest,TestSendRaw)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
TEST_F(RelayServerTest,DISABLED_TestExpiration)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