blob: 0dddbd2a434730e1a4ad02eb485dfe4bac10c16a [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>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "p2p/base/relayserver.h"
15#include "rtc_base/gunit.h"
16#include "rtc_base/helpers.h"
17#include "rtc_base/logging.h"
18#include "rtc_base/ptr_util.h"
19#include "rtc_base/socketaddress.h"
20#include "rtc_base/ssladapter.h"
21#include "rtc_base/testclient.h"
22#include "rtc_base/thread.h"
23#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000024
25using rtc::SocketAddress;
26using namespace cricket;
27
Peter Boström0c4e06b2015-10-07 12:23:21 +020028static const uint32_t LIFETIME = 4; // seconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000029static const SocketAddress server_int_addr("127.0.0.1", 5000);
30static const SocketAddress server_ext_addr("127.0.0.1", 5001);
31static const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
32static const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
33static const char* bad = "this is a completely nonsensical message whose only "
34 "purpose is to make the parser go 'ack'. it doesn't "
35 "look anything like a normal stun message";
36static const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
37static const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
38
39class RelayServerTest : public testing::Test {
40 public:
41 RelayServerTest()
deadbeef98e186c2017-05-16 18:00:06 -070042 : ss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -070043 thread_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044 username_(rtc::CreateRandomString(12)),
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000045 password_(rtc::CreateRandomString(12)) {}
46
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047 protected:
48 virtual void SetUp() {
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000049 server_.reset(new RelayServer(rtc::Thread::Current()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050
51 server_->AddInternalSocket(
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000052 rtc::AsyncUDPSocket::Create(ss_.get(), server_int_addr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053 server_->AddExternalSocket(
pbos@webrtc.org53cb7412014-12-22 07:56:42 +000054 rtc::AsyncUDPSocket::Create(ss_.get(), server_ext_addr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000055
56 client1_.reset(new rtc::TestClient(
nisse32f25052017-05-08 01:57:18 -070057 WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client1_addr))));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000058 client2_.reset(new rtc::TestClient(
nisse32f25052017-05-08 01:57:18 -070059 WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client2_addr))));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000060 }
61
62 void Allocate() {
kwiberg3ec46792016-04-27 07:22:53 -070063 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000064 AddUsernameAttr(req.get(), username_);
65 AddLifetimeAttr(req.get(), LIFETIME);
66 Send1(req.get());
67 delete Receive1();
68 }
69 void Bind() {
kwiberg3ec46792016-04-27 07:22:53 -070070 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071 AddUsernameAttr(req.get(), username_);
72 Send2(req.get());
73 delete Receive1();
74 }
75
76 void Send1(const StunMessage* msg) {
jbauchf1f87202016-03-30 06:43:37 -070077 rtc::ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000078 msg->Write(&buf);
79 SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
80 }
81 void Send2(const StunMessage* msg) {
jbauchf1f87202016-03-30 06:43:37 -070082 rtc::ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083 msg->Write(&buf);
84 SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
85 }
86 void SendRaw1(const char* data, int len) {
87 return Send(client1_.get(), data, len, server_int_addr);
88 }
89 void SendRaw2(const char* data, int len) {
90 return Send(client2_.get(), data, len, server_ext_addr);
91 }
92 void Send(rtc::TestClient* client, const char* data,
93 int len, const SocketAddress& addr) {
94 client->SendTo(data, len, addr);
95 }
96
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000097 bool Receive1Fails() {
98 return client1_.get()->CheckNoPacket();
99 }
100 bool Receive2Fails() {
101 return client2_.get()->CheckNoPacket();
102 }
103
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104 StunMessage* Receive1() {
105 return Receive(client1_.get());
106 }
107 StunMessage* Receive2() {
108 return Receive(client2_.get());
109 }
110 std::string ReceiveRaw1() {
111 return ReceiveRaw(client1_.get());
112 }
113 std::string ReceiveRaw2() {
114 return ReceiveRaw(client2_.get());
115 }
116 StunMessage* Receive(rtc::TestClient* client) {
117 StunMessage* msg = NULL;
nisse32f25052017-05-08 01:57:18 -0700118 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000119 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000120 if (packet) {
jbauchf1f87202016-03-30 06:43:37 -0700121 rtc::ByteBufferWriter buf(packet->buf, packet->size);
122 rtc::ByteBufferReader read_buf(buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000123 msg = new RelayMessage();
jbauchf1f87202016-03-30 06:43:37 -0700124 msg->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125 }
126 return msg;
127 }
128 std::string ReceiveRaw(rtc::TestClient* client) {
129 std::string raw;
nisse32f25052017-05-08 01:57:18 -0700130 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000131 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000132 if (packet) {
133 raw = std::string(packet->buf, packet->size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134 }
135 return raw;
136 }
137
138 static StunMessage* CreateStunMessage(int type) {
139 StunMessage* msg = new RelayMessage();
140 msg->SetType(type);
141 msg->SetTransactionID(
142 rtc::CreateRandomString(kStunTransactionIdLength));
143 return msg;
144 }
145 static void AddMagicCookieAttr(StunMessage* msg) {
zsteinf42cc9d2017-03-27 16:17:19 -0700146 auto attr = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000147 attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
zsteinf42cc9d2017-03-27 16:17:19 -0700148 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000149 }
150 static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700151 auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152 attr->CopyBytes(val.c_str(), val.size());
zsteinf42cc9d2017-03-27 16:17:19 -0700153 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 }
155 static void AddLifetimeAttr(StunMessage* msg, int val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700156 auto attr = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000157 attr->SetValue(val);
zsteinf42cc9d2017-03-27 16:17:19 -0700158 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159 }
160 static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
zsteinf42cc9d2017-03-27 16:17:19 -0700161 auto attr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000162 attr->SetIP(addr.ipaddr());
163 attr->SetPort(addr.port());
zsteinf42cc9d2017-03-27 16:17:19 -0700164 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165 }
166
kwiberg3ec46792016-04-27 07:22:53 -0700167 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700168 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700169 std::unique_ptr<RelayServer> server_;
170 std::unique_ptr<rtc::TestClient> client1_;
171 std::unique_ptr<rtc::TestClient> client2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000172 std::string username_;
173 std::string password_;
174};
175
176// Send a complete nonsense message and verify that it is eaten.
177TEST_F(RelayServerTest, TestBadRequest) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000178 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000179 ASSERT_TRUE(Receive1Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180}
181
182// Send an allocate request without a username and verify it is rejected.
183TEST_F(RelayServerTest, TestAllocateNoUsername) {
kwiberg3ec46792016-04-27 07:22:53 -0700184 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
185 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000186
187 Send1(req.get());
188 res.reset(Receive1());
189
190 ASSERT_TRUE(res);
191 EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
192 EXPECT_EQ(req->transaction_id(), res->transaction_id());
193
194 const StunErrorCodeAttribute* err = res->GetErrorCode();
195 ASSERT_TRUE(err != NULL);
196 EXPECT_EQ(4, err->eclass());
197 EXPECT_EQ(32, err->number());
198 EXPECT_EQ("Missing Username", err->reason());
199}
200
201// Send a binding request and verify that it is rejected.
202TEST_F(RelayServerTest, TestBindingRequest) {
kwiberg3ec46792016-04-27 07:22:53 -0700203 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
204 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000205 AddUsernameAttr(req.get(), username_);
206
207 Send1(req.get());
208 res.reset(Receive1());
209
210 ASSERT_TRUE(res);
211 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
212 EXPECT_EQ(req->transaction_id(), res->transaction_id());
213
214 const StunErrorCodeAttribute* err = res->GetErrorCode();
215 ASSERT_TRUE(err != NULL);
216 EXPECT_EQ(6, err->eclass());
217 EXPECT_EQ(0, err->number());
218 EXPECT_EQ("Operation Not Supported", err->reason());
219}
220
221// Send an allocate request and verify that it is accepted.
222TEST_F(RelayServerTest, TestAllocate) {
kwiberg3ec46792016-04-27 07:22:53 -0700223 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
224 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000225 AddUsernameAttr(req.get(), username_);
226 AddLifetimeAttr(req.get(), LIFETIME);
227
228 Send1(req.get());
229 res.reset(Receive1());
230
231 ASSERT_TRUE(res);
232 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
233 EXPECT_EQ(req->transaction_id(), res->transaction_id());
234
235 const StunAddressAttribute* mapped_addr =
236 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
237 ASSERT_TRUE(mapped_addr != NULL);
238 EXPECT_EQ(1, mapped_addr->family());
239 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
240 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
241
242 const StunUInt32Attribute* res_lifetime_attr =
243 res->GetUInt32(STUN_ATTR_LIFETIME);
244 ASSERT_TRUE(res_lifetime_attr != NULL);
245 EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
246}
247
248// Send a second allocate request and verify that it is also accepted, though
249// the lifetime should be ignored.
250TEST_F(RelayServerTest, TestReallocate) {
251 Allocate();
252
kwiberg3ec46792016-04-27 07:22:53 -0700253 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
254 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000255 AddMagicCookieAttr(req.get());
256 AddUsernameAttr(req.get(), username_);
257
258 Send1(req.get());
259 res.reset(Receive1());
260
261 ASSERT_TRUE(res);
262 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
263 EXPECT_EQ(req->transaction_id(), res->transaction_id());
264
265 const StunAddressAttribute* mapped_addr =
266 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
267 ASSERT_TRUE(mapped_addr != NULL);
268 EXPECT_EQ(1, mapped_addr->family());
269 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
270 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
271
272 const StunUInt32Attribute* lifetime_attr =
273 res->GetUInt32(STUN_ATTR_LIFETIME);
274 ASSERT_TRUE(lifetime_attr != NULL);
275 EXPECT_EQ(LIFETIME, lifetime_attr->value());
276}
277
278// Send a request from another client and see that it arrives at the first
279// client in the binding.
280TEST_F(RelayServerTest, TestRemoteBind) {
281 Allocate();
282
kwiberg3ec46792016-04-27 07:22:53 -0700283 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
284 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000285 AddUsernameAttr(req.get(), username_);
286
287 Send2(req.get());
288 res.reset(Receive1());
289
290 ASSERT_TRUE(res);
291 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
292
293 const StunByteStringAttribute* recv_data =
294 res->GetByteString(STUN_ATTR_DATA);
295 ASSERT_TRUE(recv_data != NULL);
296
jbauchf1f87202016-03-30 06:43:37 -0700297 rtc::ByteBufferReader buf(recv_data->bytes(), recv_data->length());
kwiberg3ec46792016-04-27 07:22:53 -0700298 std::unique_ptr<StunMessage> res2(new StunMessage());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000299 EXPECT_TRUE(res2->Read(&buf));
300 EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
301 EXPECT_EQ(req->transaction_id(), res2->transaction_id());
302
303 const StunAddressAttribute* src_addr =
304 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
305 ASSERT_TRUE(src_addr != NULL);
306 EXPECT_EQ(1, src_addr->family());
307 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
308 EXPECT_EQ(client2_addr.port(), src_addr->port());
309
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000310 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000311}
312
313// Send a complete nonsense message to the established connection and verify
314// that it is dropped by the server.
315TEST_F(RelayServerTest, TestRemoteBadRequest) {
316 Allocate();
317 Bind();
318
319 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000320 EXPECT_TRUE(Receive1Fails());
321 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000322}
323
324// Send a send request without a username and verify it is rejected.
325TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
326 Allocate();
327 Bind();
328
kwiberg3ec46792016-04-27 07:22:53 -0700329 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330 AddMagicCookieAttr(req.get());
331
332 Send1(req.get());
333 res.reset(Receive1());
334
335 ASSERT_TRUE(res);
336 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
337 EXPECT_EQ(req->transaction_id(), res->transaction_id());
338
339 const StunErrorCodeAttribute* err = res->GetErrorCode();
340 ASSERT_TRUE(err != NULL);
341 EXPECT_EQ(4, err->eclass());
342 EXPECT_EQ(32, err->number());
343 EXPECT_EQ("Missing Username", err->reason());
344}
345
346// Send a send request with the wrong username and verify it is rejected.
347TEST_F(RelayServerTest, TestSendRequestBadUsername) {
348 Allocate();
349 Bind();
350
kwiberg3ec46792016-04-27 07:22:53 -0700351 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000352 AddMagicCookieAttr(req.get());
353 AddUsernameAttr(req.get(), "foobarbizbaz");
354
355 Send1(req.get());
356 res.reset(Receive1());
357
358 ASSERT_TRUE(res);
359 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
360 EXPECT_EQ(req->transaction_id(), res->transaction_id());
361
362 const StunErrorCodeAttribute* err = res->GetErrorCode();
363 ASSERT_TRUE(err != NULL);
364 EXPECT_EQ(4, err->eclass());
365 EXPECT_EQ(30, err->number());
366 EXPECT_EQ("Stale Credentials", err->reason());
367}
368
369// Send a send request without a destination address and verify that it is
370// rejected.
371TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
372 Allocate();
373 Bind();
374
kwiberg3ec46792016-04-27 07:22:53 -0700375 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000376 AddMagicCookieAttr(req.get());
377 AddUsernameAttr(req.get(), username_);
378
379 Send1(req.get());
380 res.reset(Receive1());
381
382 ASSERT_TRUE(res);
383 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
384 EXPECT_EQ(req->transaction_id(), res->transaction_id());
385
386 const StunErrorCodeAttribute* err = res->GetErrorCode();
387 ASSERT_TRUE(err != NULL);
388 EXPECT_EQ(4, err->eclass());
389 EXPECT_EQ(0, err->number());
390 EXPECT_EQ("Bad Request", err->reason());
391}
392
393// Send a send request without data and verify that it is rejected.
394TEST_F(RelayServerTest, TestSendRequestNoData) {
395 Allocate();
396 Bind();
397
kwiberg3ec46792016-04-27 07:22:53 -0700398 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000399 AddMagicCookieAttr(req.get());
400 AddUsernameAttr(req.get(), username_);
401 AddDestinationAttr(req.get(), client2_addr);
402
403 Send1(req.get());
404 res.reset(Receive1());
405
406 ASSERT_TRUE(res);
407 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
408 EXPECT_EQ(req->transaction_id(), res->transaction_id());
409
410 const StunErrorCodeAttribute* err = res->GetErrorCode();
411 ASSERT_TRUE(err != NULL);
412 EXPECT_EQ(4, err->eclass());
413 EXPECT_EQ(00, err->number());
414 EXPECT_EQ("Bad Request", err->reason());
415}
416
417// Send a binding request after an allocate and verify that it is rejected.
418TEST_F(RelayServerTest, TestSendRequestWrongType) {
419 Allocate();
420 Bind();
421
kwiberg3ec46792016-04-27 07:22:53 -0700422 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
423 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000424 AddMagicCookieAttr(req.get());
425 AddUsernameAttr(req.get(), username_);
426
427 Send1(req.get());
428 res.reset(Receive1());
429
430 ASSERT_TRUE(res);
431 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
432 EXPECT_EQ(req->transaction_id(), res->transaction_id());
433
434 const StunErrorCodeAttribute* err = res->GetErrorCode();
435 ASSERT_TRUE(err != NULL);
436 EXPECT_EQ(6, err->eclass());
437 EXPECT_EQ(0, err->number());
438 EXPECT_EQ("Operation Not Supported", err->reason());
439}
440
441// Verify that we can send traffic back and forth between the clients after a
442// successful allocate and bind.
443TEST_F(RelayServerTest, TestSendRaw) {
444 Allocate();
445 Bind();
446
447 for (int i = 0; i < 10; i++) {
kwiberg3ec46792016-04-27 07:22:53 -0700448 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000449 AddMagicCookieAttr(req.get());
450 AddUsernameAttr(req.get(), username_);
451 AddDestinationAttr(req.get(), client2_addr);
452
zsteinf42cc9d2017-03-27 16:17:19 -0700453 auto send_data = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000454 send_data->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700455 req->AddAttribute(std::move(send_data));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000456
457 Send1(req.get());
458 EXPECT_EQ(msg1, ReceiveRaw2());
459 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
460 res.reset(Receive1());
461
462 ASSERT_TRUE(res);
463 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
464
465 const StunAddressAttribute* src_addr =
466 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
467 ASSERT_TRUE(src_addr != NULL);
468 EXPECT_EQ(1, src_addr->family());
469 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
470 EXPECT_EQ(client2_addr.port(), src_addr->port());
471
472 const StunByteStringAttribute* recv_data =
473 res->GetByteString(STUN_ATTR_DATA);
474 ASSERT_TRUE(recv_data != NULL);
475 EXPECT_EQ(strlen(msg2), recv_data->length());
476 EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
477 }
478}
479
480// Verify that a binding expires properly, and rejects send requests.
andrew@webrtc.org4796cb92015-01-05 23:56:19 +0000481// Flaky, see https://code.google.com/p/webrtc/issues/detail?id=4134
482TEST_F(RelayServerTest, DISABLED_TestExpiration) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000483 Allocate();
484 Bind();
485
486 // Wait twice the lifetime to make sure the server has expired the binding.
487 rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
488
kwiberg3ec46792016-04-27 07:22:53 -0700489 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000490 AddMagicCookieAttr(req.get());
491 AddUsernameAttr(req.get(), username_);
492 AddDestinationAttr(req.get(), client2_addr);
493
zsteinf42cc9d2017-03-27 16:17:19 -0700494 auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000495 data_attr->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700496 req->AddAttribute(std::move(data_attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000497
498 Send1(req.get());
499 res.reset(Receive1());
500
501 ASSERT_TRUE(res.get() != NULL);
502 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
503
504 const StunErrorCodeAttribute* err = res->GetErrorCode();
505 ASSERT_TRUE(err != NULL);
506 EXPECT_EQ(6, err->eclass());
507 EXPECT_EQ(0, err->number());
508 EXPECT_EQ("Operation Not Supported", err->reason());
509
510 // Also verify that traffic from the external client is ignored.
511 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
512 EXPECT_TRUE(ReceiveRaw1().empty());
513}