blob: 802401666927000ab9f45c926b39c37061da6261 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
kwiberg3ec46792016-04-27 07:22:53 -070011#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000012#include <string>
Steve Anton6c38cc72017-11-29 10:25:58 -080013#include <utility>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "p2p/base/relayserver.h"
16#include "rtc_base/gunit.h"
17#include "rtc_base/helpers.h"
18#include "rtc_base/logging.h"
19#include "rtc_base/ptr_util.h"
20#include "rtc_base/socketaddress.h"
21#include "rtc_base/ssladapter.h"
22#include "rtc_base/testclient.h"
23#include "rtc_base/thread.h"
24#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000025
26using rtc::SocketAddress;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000027
Steve Anton6c38cc72017-11-29 10:25:58 -080028namespace cricket {
29namespace {
30
31constexpr uint32_t LIFETIME = 4; // seconds
32const SocketAddress server_int_addr("127.0.0.1", 5000);
33const SocketAddress server_ext_addr("127.0.0.1", 5001);
34const SocketAddress client1_addr("127.0.0.1", 6111);
35const SocketAddress client2_addr("127.0.0.1", 7222);
36const char* bad =
37 "this is a completely nonsensical message whose only "
38 "purpose is to make the parser go 'ack'. it doesn't "
39 "look anything like a normal stun message";
40const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
41const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
42
43} // namespace
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044
45class RelayServerTest : public testing::Test {
46 public:
47 RelayServerTest()
deadbeef98e186c2017-05-16 18:00:06 -070048 : ss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -070049 thread_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050 username_(rtc::CreateRandomString(12)),
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000051 password_(rtc::CreateRandomString(12)) {}
52
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053 protected:
54 virtual void SetUp() {
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000055 server_.reset(new RelayServer(rtc::Thread::Current()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056
57 server_->AddInternalSocket(
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000058 rtc::AsyncUDPSocket::Create(ss_.get(), server_int_addr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000059 server_->AddExternalSocket(
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000060 rtc::AsyncUDPSocket::Create(ss_.get(), server_ext_addr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000061
62 client1_.reset(new rtc::TestClient(
nisse32f25052017-05-08 01:57:18 -070063 WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client1_addr))));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000064 client2_.reset(new rtc::TestClient(
nisse32f25052017-05-08 01:57:18 -070065 WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client2_addr))));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066 }
67
68 void Allocate() {
kwiberg3ec46792016-04-27 07:22:53 -070069 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070 AddUsernameAttr(req.get(), username_);
71 AddLifetimeAttr(req.get(), LIFETIME);
72 Send1(req.get());
73 delete Receive1();
74 }
75 void Bind() {
kwiberg3ec46792016-04-27 07:22:53 -070076 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000077 AddUsernameAttr(req.get(), username_);
78 Send2(req.get());
79 delete Receive1();
80 }
81
82 void Send1(const StunMessage* msg) {
jbauchf1f87202016-03-30 06:43:37 -070083 rtc::ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084 msg->Write(&buf);
85 SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
86 }
87 void Send2(const StunMessage* msg) {
jbauchf1f87202016-03-30 06:43:37 -070088 rtc::ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000089 msg->Write(&buf);
90 SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
91 }
92 void SendRaw1(const char* data, int len) {
93 return Send(client1_.get(), data, len, server_int_addr);
94 }
95 void SendRaw2(const char* data, int len) {
96 return Send(client2_.get(), data, len, server_ext_addr);
97 }
98 void Send(rtc::TestClient* client, const char* data,
99 int len, const SocketAddress& addr) {
100 client->SendTo(data, len, addr);
101 }
102
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000103 bool Receive1Fails() {
104 return client1_.get()->CheckNoPacket();
105 }
106 bool Receive2Fails() {
107 return client2_.get()->CheckNoPacket();
108 }
109
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000110 StunMessage* Receive1() {
111 return Receive(client1_.get());
112 }
113 StunMessage* Receive2() {
114 return Receive(client2_.get());
115 }
116 std::string ReceiveRaw1() {
117 return ReceiveRaw(client1_.get());
118 }
119 std::string ReceiveRaw2() {
120 return ReceiveRaw(client2_.get());
121 }
122 StunMessage* Receive(rtc::TestClient* client) {
123 StunMessage* msg = NULL;
nisse32f25052017-05-08 01:57:18 -0700124 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000125 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000126 if (packet) {
jbauchf1f87202016-03-30 06:43:37 -0700127 rtc::ByteBufferWriter buf(packet->buf, packet->size);
128 rtc::ByteBufferReader read_buf(buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000129 msg = new RelayMessage();
jbauchf1f87202016-03-30 06:43:37 -0700130 msg->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131 }
132 return msg;
133 }
134 std::string ReceiveRaw(rtc::TestClient* client) {
135 std::string raw;
nisse32f25052017-05-08 01:57:18 -0700136 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000137 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 if (packet) {
139 raw = std::string(packet->buf, packet->size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000140 }
141 return raw;
142 }
143
144 static StunMessage* CreateStunMessage(int type) {
145 StunMessage* msg = new RelayMessage();
146 msg->SetType(type);
147 msg->SetTransactionID(
148 rtc::CreateRandomString(kStunTransactionIdLength));
149 return msg;
150 }
151 static void AddMagicCookieAttr(StunMessage* msg) {
zsteinf42cc9d2017-03-27 16:17:19 -0700152 auto attr = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000153 attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
zsteinf42cc9d2017-03-27 16:17:19 -0700154 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000155 }
156 static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700157 auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000158 attr->CopyBytes(val.c_str(), val.size());
zsteinf42cc9d2017-03-27 16:17:19 -0700159 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160 }
161 static void AddLifetimeAttr(StunMessage* msg, int val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700162 auto attr = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163 attr->SetValue(val);
zsteinf42cc9d2017-03-27 16:17:19 -0700164 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165 }
166 static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
zsteinf42cc9d2017-03-27 16:17:19 -0700167 auto attr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168 attr->SetIP(addr.ipaddr());
169 attr->SetPort(addr.port());
zsteinf42cc9d2017-03-27 16:17:19 -0700170 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000171 }
172
kwiberg3ec46792016-04-27 07:22:53 -0700173 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700174 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700175 std::unique_ptr<RelayServer> server_;
176 std::unique_ptr<rtc::TestClient> client1_;
177 std::unique_ptr<rtc::TestClient> client2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000178 std::string username_;
179 std::string password_;
180};
181
182// Send a complete nonsense message and verify that it is eaten.
183TEST_F(RelayServerTest, TestBadRequest) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000185 ASSERT_TRUE(Receive1Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000186}
187
188// Send an allocate request without a username and verify it is rejected.
189TEST_F(RelayServerTest, TestAllocateNoUsername) {
kwiberg3ec46792016-04-27 07:22:53 -0700190 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
191 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000192
193 Send1(req.get());
194 res.reset(Receive1());
195
196 ASSERT_TRUE(res);
197 EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
198 EXPECT_EQ(req->transaction_id(), res->transaction_id());
199
200 const StunErrorCodeAttribute* err = res->GetErrorCode();
201 ASSERT_TRUE(err != NULL);
202 EXPECT_EQ(4, err->eclass());
203 EXPECT_EQ(32, err->number());
204 EXPECT_EQ("Missing Username", err->reason());
205}
206
207// Send a binding request and verify that it is rejected.
208TEST_F(RelayServerTest, TestBindingRequest) {
kwiberg3ec46792016-04-27 07:22:53 -0700209 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
210 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000211 AddUsernameAttr(req.get(), username_);
212
213 Send1(req.get());
214 res.reset(Receive1());
215
216 ASSERT_TRUE(res);
217 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
218 EXPECT_EQ(req->transaction_id(), res->transaction_id());
219
220 const StunErrorCodeAttribute* err = res->GetErrorCode();
221 ASSERT_TRUE(err != NULL);
222 EXPECT_EQ(6, err->eclass());
223 EXPECT_EQ(0, err->number());
224 EXPECT_EQ("Operation Not Supported", err->reason());
225}
226
227// Send an allocate request and verify that it is accepted.
228TEST_F(RelayServerTest, TestAllocate) {
kwiberg3ec46792016-04-27 07:22:53 -0700229 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
230 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231 AddUsernameAttr(req.get(), username_);
232 AddLifetimeAttr(req.get(), LIFETIME);
233
234 Send1(req.get());
235 res.reset(Receive1());
236
237 ASSERT_TRUE(res);
238 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
239 EXPECT_EQ(req->transaction_id(), res->transaction_id());
240
241 const StunAddressAttribute* mapped_addr =
242 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
243 ASSERT_TRUE(mapped_addr != NULL);
244 EXPECT_EQ(1, mapped_addr->family());
245 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
246 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
247
248 const StunUInt32Attribute* res_lifetime_attr =
249 res->GetUInt32(STUN_ATTR_LIFETIME);
250 ASSERT_TRUE(res_lifetime_attr != NULL);
251 EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
252}
253
254// Send a second allocate request and verify that it is also accepted, though
255// the lifetime should be ignored.
256TEST_F(RelayServerTest, TestReallocate) {
257 Allocate();
258
kwiberg3ec46792016-04-27 07:22:53 -0700259 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
260 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261 AddMagicCookieAttr(req.get());
262 AddUsernameAttr(req.get(), username_);
263
264 Send1(req.get());
265 res.reset(Receive1());
266
267 ASSERT_TRUE(res);
268 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
269 EXPECT_EQ(req->transaction_id(), res->transaction_id());
270
271 const StunAddressAttribute* mapped_addr =
272 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
273 ASSERT_TRUE(mapped_addr != NULL);
274 EXPECT_EQ(1, mapped_addr->family());
275 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
276 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
277
278 const StunUInt32Attribute* lifetime_attr =
279 res->GetUInt32(STUN_ATTR_LIFETIME);
280 ASSERT_TRUE(lifetime_attr != NULL);
281 EXPECT_EQ(LIFETIME, lifetime_attr->value());
282}
283
284// Send a request from another client and see that it arrives at the first
285// client in the binding.
286TEST_F(RelayServerTest, TestRemoteBind) {
287 Allocate();
288
kwiberg3ec46792016-04-27 07:22:53 -0700289 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
290 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000291 AddUsernameAttr(req.get(), username_);
292
293 Send2(req.get());
294 res.reset(Receive1());
295
296 ASSERT_TRUE(res);
297 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
298
299 const StunByteStringAttribute* recv_data =
300 res->GetByteString(STUN_ATTR_DATA);
301 ASSERT_TRUE(recv_data != NULL);
302
jbauchf1f87202016-03-30 06:43:37 -0700303 rtc::ByteBufferReader buf(recv_data->bytes(), recv_data->length());
kwiberg3ec46792016-04-27 07:22:53 -0700304 std::unique_ptr<StunMessage> res2(new StunMessage());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000305 EXPECT_TRUE(res2->Read(&buf));
306 EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
307 EXPECT_EQ(req->transaction_id(), res2->transaction_id());
308
309 const StunAddressAttribute* src_addr =
310 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
311 ASSERT_TRUE(src_addr != NULL);
312 EXPECT_EQ(1, src_addr->family());
313 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
314 EXPECT_EQ(client2_addr.port(), src_addr->port());
315
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000316 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000317}
318
319// Send a complete nonsense message to the established connection and verify
320// that it is dropped by the server.
321TEST_F(RelayServerTest, TestRemoteBadRequest) {
322 Allocate();
323 Bind();
324
325 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000326 EXPECT_TRUE(Receive1Fails());
327 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000328}
329
330// Send a send request without a username and verify it is rejected.
331TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
332 Allocate();
333 Bind();
334
kwiberg3ec46792016-04-27 07:22:53 -0700335 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000336 AddMagicCookieAttr(req.get());
337
338 Send1(req.get());
339 res.reset(Receive1());
340
341 ASSERT_TRUE(res);
342 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
343 EXPECT_EQ(req->transaction_id(), res->transaction_id());
344
345 const StunErrorCodeAttribute* err = res->GetErrorCode();
346 ASSERT_TRUE(err != NULL);
347 EXPECT_EQ(4, err->eclass());
348 EXPECT_EQ(32, err->number());
349 EXPECT_EQ("Missing Username", err->reason());
350}
351
352// Send a send request with the wrong username and verify it is rejected.
353TEST_F(RelayServerTest, TestSendRequestBadUsername) {
354 Allocate();
355 Bind();
356
kwiberg3ec46792016-04-27 07:22:53 -0700357 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000358 AddMagicCookieAttr(req.get());
359 AddUsernameAttr(req.get(), "foobarbizbaz");
360
361 Send1(req.get());
362 res.reset(Receive1());
363
364 ASSERT_TRUE(res);
365 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
366 EXPECT_EQ(req->transaction_id(), res->transaction_id());
367
368 const StunErrorCodeAttribute* err = res->GetErrorCode();
369 ASSERT_TRUE(err != NULL);
370 EXPECT_EQ(4, err->eclass());
371 EXPECT_EQ(30, err->number());
372 EXPECT_EQ("Stale Credentials", err->reason());
373}
374
375// Send a send request without a destination address and verify that it is
376// rejected.
377TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
378 Allocate();
379 Bind();
380
kwiberg3ec46792016-04-27 07:22:53 -0700381 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000382 AddMagicCookieAttr(req.get());
383 AddUsernameAttr(req.get(), username_);
384
385 Send1(req.get());
386 res.reset(Receive1());
387
388 ASSERT_TRUE(res);
389 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
390 EXPECT_EQ(req->transaction_id(), res->transaction_id());
391
392 const StunErrorCodeAttribute* err = res->GetErrorCode();
393 ASSERT_TRUE(err != NULL);
394 EXPECT_EQ(4, err->eclass());
395 EXPECT_EQ(0, err->number());
396 EXPECT_EQ("Bad Request", err->reason());
397}
398
399// Send a send request without data and verify that it is rejected.
400TEST_F(RelayServerTest, TestSendRequestNoData) {
401 Allocate();
402 Bind();
403
kwiberg3ec46792016-04-27 07:22:53 -0700404 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000405 AddMagicCookieAttr(req.get());
406 AddUsernameAttr(req.get(), username_);
407 AddDestinationAttr(req.get(), client2_addr);
408
409 Send1(req.get());
410 res.reset(Receive1());
411
412 ASSERT_TRUE(res);
413 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
414 EXPECT_EQ(req->transaction_id(), res->transaction_id());
415
416 const StunErrorCodeAttribute* err = res->GetErrorCode();
417 ASSERT_TRUE(err != NULL);
418 EXPECT_EQ(4, err->eclass());
419 EXPECT_EQ(00, err->number());
420 EXPECT_EQ("Bad Request", err->reason());
421}
422
423// Send a binding request after an allocate and verify that it is rejected.
424TEST_F(RelayServerTest, TestSendRequestWrongType) {
425 Allocate();
426 Bind();
427
kwiberg3ec46792016-04-27 07:22:53 -0700428 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
429 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000430 AddMagicCookieAttr(req.get());
431 AddUsernameAttr(req.get(), username_);
432
433 Send1(req.get());
434 res.reset(Receive1());
435
436 ASSERT_TRUE(res);
437 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
438 EXPECT_EQ(req->transaction_id(), res->transaction_id());
439
440 const StunErrorCodeAttribute* err = res->GetErrorCode();
441 ASSERT_TRUE(err != NULL);
442 EXPECT_EQ(6, err->eclass());
443 EXPECT_EQ(0, err->number());
444 EXPECT_EQ("Operation Not Supported", err->reason());
445}
446
447// Verify that we can send traffic back and forth between the clients after a
448// successful allocate and bind.
449TEST_F(RelayServerTest, TestSendRaw) {
450 Allocate();
451 Bind();
452
453 for (int i = 0; i < 10; i++) {
kwiberg3ec46792016-04-27 07:22:53 -0700454 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000455 AddMagicCookieAttr(req.get());
456 AddUsernameAttr(req.get(), username_);
457 AddDestinationAttr(req.get(), client2_addr);
458
zsteinf42cc9d2017-03-27 16:17:19 -0700459 auto send_data = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000460 send_data->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700461 req->AddAttribute(std::move(send_data));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000462
463 Send1(req.get());
464 EXPECT_EQ(msg1, ReceiveRaw2());
465 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
466 res.reset(Receive1());
467
468 ASSERT_TRUE(res);
469 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
470
471 const StunAddressAttribute* src_addr =
472 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
473 ASSERT_TRUE(src_addr != NULL);
474 EXPECT_EQ(1, src_addr->family());
475 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
476 EXPECT_EQ(client2_addr.port(), src_addr->port());
477
478 const StunByteStringAttribute* recv_data =
479 res->GetByteString(STUN_ATTR_DATA);
480 ASSERT_TRUE(recv_data != NULL);
481 EXPECT_EQ(strlen(msg2), recv_data->length());
482 EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
483 }
484}
485
486// Verify that a binding expires properly, and rejects send requests.
andrew@webrtc.org4796cb92015-01-05 23:56:19 +0000487// Flaky, see https://code.google.com/p/webrtc/issues/detail?id=4134
488TEST_F(RelayServerTest, DISABLED_TestExpiration) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000489 Allocate();
490 Bind();
491
492 // Wait twice the lifetime to make sure the server has expired the binding.
493 rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
494
kwiberg3ec46792016-04-27 07:22:53 -0700495 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000496 AddMagicCookieAttr(req.get());
497 AddUsernameAttr(req.get(), username_);
498 AddDestinationAttr(req.get(), client2_addr);
499
zsteinf42cc9d2017-03-27 16:17:19 -0700500 auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000501 data_attr->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700502 req->AddAttribute(std::move(data_attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000503
504 Send1(req.get());
505 res.reset(Receive1());
506
507 ASSERT_TRUE(res.get() != NULL);
508 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
509
510 const StunErrorCodeAttribute* err = res->GetErrorCode();
511 ASSERT_TRUE(err != NULL);
512 EXPECT_EQ(6, err->eclass());
513 EXPECT_EQ(0, err->number());
514 EXPECT_EQ("Operation Not Supported", err->reason());
515
516 // Also verify that traffic from the external client is ignored.
517 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
518 EXPECT_TRUE(ReceiveRaw1().empty());
519}
Steve Anton6c38cc72017-11-29 10:25:58 -0800520
521} // namespace cricket