blob: c4c026a241b27297b8e3b2bd9e83ea35e432eff4 [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
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "p2p/base/relayserver.h"
17#include "rtc_base/gunit.h"
18#include "rtc_base/helpers.h"
19#include "rtc_base/logging.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#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
Karl Wiberg918f50c2018-07-05 11:40:33 +020062 client1_.reset(new rtc::TestClient(absl::WrapUnique(
63 rtc::AsyncUDPSocket::Create(ss_.get(), client1_addr))));
64 client2_.reset(new rtc::TestClient(absl::WrapUnique(
65 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 }
Yves Gerey665174f2018-06-19 15:03:05 +020098 void Send(rtc::TestClient* client,
99 const char* data,
100 int len,
101 const SocketAddress& addr) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102 client->SendTo(data, len, addr);
103 }
104
Yves Gerey665174f2018-06-19 15:03:05 +0200105 bool Receive1Fails() { return client1_.get()->CheckNoPacket(); }
106 bool Receive2Fails() { return client2_.get()->CheckNoPacket(); }
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000107
Yves Gerey665174f2018-06-19 15:03:05 +0200108 StunMessage* Receive1() { return Receive(client1_.get()); }
109 StunMessage* Receive2() { return Receive(client2_.get()); }
110 std::string ReceiveRaw1() { return ReceiveRaw(client1_.get()); }
111 std::string ReceiveRaw2() { return ReceiveRaw(client2_.get()); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000112 StunMessage* Receive(rtc::TestClient* client) {
113 StunMessage* msg = NULL;
nisse32f25052017-05-08 01:57:18 -0700114 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000115 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000116 if (packet) {
jbauchf1f87202016-03-30 06:43:37 -0700117 rtc::ByteBufferWriter buf(packet->buf, packet->size);
118 rtc::ByteBufferReader read_buf(buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000119 msg = new RelayMessage();
jbauchf1f87202016-03-30 06:43:37 -0700120 msg->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000121 }
122 return msg;
123 }
124 std::string ReceiveRaw(rtc::TestClient* client) {
125 std::string raw;
nisse32f25052017-05-08 01:57:18 -0700126 std::unique_ptr<rtc::TestClient::Packet> packet =
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000127 client->NextPacket(rtc::TestClient::kTimeoutMs);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 if (packet) {
129 raw = std::string(packet->buf, packet->size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000130 }
131 return raw;
132 }
133
134 static StunMessage* CreateStunMessage(int type) {
135 StunMessage* msg = new RelayMessage();
136 msg->SetType(type);
Yves Gerey665174f2018-06-19 15:03:05 +0200137 msg->SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 return msg;
139 }
140 static void AddMagicCookieAttr(StunMessage* msg) {
zsteinf42cc9d2017-03-27 16:17:19 -0700141 auto attr = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000142 attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
zsteinf42cc9d2017-03-27 16:17:19 -0700143 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000144 }
145 static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700146 auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000147 attr->CopyBytes(val.c_str(), val.size());
zsteinf42cc9d2017-03-27 16:17:19 -0700148 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000149 }
150 static void AddLifetimeAttr(StunMessage* msg, int val) {
zsteinf42cc9d2017-03-27 16:17:19 -0700151 auto attr = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152 attr->SetValue(val);
zsteinf42cc9d2017-03-27 16:17:19 -0700153 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 }
155 static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
zsteinf42cc9d2017-03-27 16:17:19 -0700156 auto attr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000157 attr->SetIP(addr.ipaddr());
158 attr->SetPort(addr.port());
zsteinf42cc9d2017-03-27 16:17:19 -0700159 msg->AddAttribute(std::move(attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160 }
161
kwiberg3ec46792016-04-27 07:22:53 -0700162 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700163 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700164 std::unique_ptr<RelayServer> server_;
165 std::unique_ptr<rtc::TestClient> client1_;
166 std::unique_ptr<rtc::TestClient> client2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000167 std::string username_;
168 std::string password_;
169};
170
171// Send a complete nonsense message and verify that it is eaten.
172TEST_F(RelayServerTest, TestBadRequest) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000173 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000174 ASSERT_TRUE(Receive1Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000175}
176
177// Send an allocate request without a username and verify it is rejected.
178TEST_F(RelayServerTest, TestAllocateNoUsername) {
kwiberg3ec46792016-04-27 07:22:53 -0700179 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
180 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000181
182 Send1(req.get());
183 res.reset(Receive1());
184
185 ASSERT_TRUE(res);
186 EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
187 EXPECT_EQ(req->transaction_id(), res->transaction_id());
188
189 const StunErrorCodeAttribute* err = res->GetErrorCode();
190 ASSERT_TRUE(err != NULL);
191 EXPECT_EQ(4, err->eclass());
192 EXPECT_EQ(32, err->number());
193 EXPECT_EQ("Missing Username", err->reason());
194}
195
196// Send a binding request and verify that it is rejected.
197TEST_F(RelayServerTest, TestBindingRequest) {
kwiberg3ec46792016-04-27 07:22:53 -0700198 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
199 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000200 AddUsernameAttr(req.get(), username_);
201
202 Send1(req.get());
203 res.reset(Receive1());
204
205 ASSERT_TRUE(res);
206 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
207 EXPECT_EQ(req->transaction_id(), res->transaction_id());
208
209 const StunErrorCodeAttribute* err = res->GetErrorCode();
210 ASSERT_TRUE(err != NULL);
211 EXPECT_EQ(6, err->eclass());
212 EXPECT_EQ(0, err->number());
213 EXPECT_EQ("Operation Not Supported", err->reason());
214}
215
216// Send an allocate request and verify that it is accepted.
217TEST_F(RelayServerTest, TestAllocate) {
kwiberg3ec46792016-04-27 07:22:53 -0700218 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
219 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 AddUsernameAttr(req.get(), username_);
221 AddLifetimeAttr(req.get(), LIFETIME);
222
223 Send1(req.get());
224 res.reset(Receive1());
225
226 ASSERT_TRUE(res);
227 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
228 EXPECT_EQ(req->transaction_id(), res->transaction_id());
229
230 const StunAddressAttribute* mapped_addr =
231 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
232 ASSERT_TRUE(mapped_addr != NULL);
233 EXPECT_EQ(1, mapped_addr->family());
234 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
235 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
236
237 const StunUInt32Attribute* res_lifetime_attr =
238 res->GetUInt32(STUN_ATTR_LIFETIME);
239 ASSERT_TRUE(res_lifetime_attr != NULL);
240 EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
241}
242
243// Send a second allocate request and verify that it is also accepted, though
244// the lifetime should be ignored.
245TEST_F(RelayServerTest, TestReallocate) {
246 Allocate();
247
kwiberg3ec46792016-04-27 07:22:53 -0700248 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
249 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000250 AddMagicCookieAttr(req.get());
251 AddUsernameAttr(req.get(), username_);
252
253 Send1(req.get());
254 res.reset(Receive1());
255
256 ASSERT_TRUE(res);
257 EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
258 EXPECT_EQ(req->transaction_id(), res->transaction_id());
259
260 const StunAddressAttribute* mapped_addr =
261 res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
262 ASSERT_TRUE(mapped_addr != NULL);
263 EXPECT_EQ(1, mapped_addr->family());
264 EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
265 EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
266
Yves Gerey665174f2018-06-19 15:03:05 +0200267 const StunUInt32Attribute* lifetime_attr = res->GetUInt32(STUN_ATTR_LIFETIME);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000268 ASSERT_TRUE(lifetime_attr != NULL);
269 EXPECT_EQ(LIFETIME, lifetime_attr->value());
270}
271
272// Send a request from another client and see that it arrives at the first
273// client in the binding.
274TEST_F(RelayServerTest, TestRemoteBind) {
275 Allocate();
276
kwiberg3ec46792016-04-27 07:22:53 -0700277 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
278 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 AddUsernameAttr(req.get(), username_);
280
281 Send2(req.get());
282 res.reset(Receive1());
283
284 ASSERT_TRUE(res);
285 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
286
Yves Gerey665174f2018-06-19 15:03:05 +0200287 const StunByteStringAttribute* recv_data = res->GetByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000288 ASSERT_TRUE(recv_data != NULL);
289
jbauchf1f87202016-03-30 06:43:37 -0700290 rtc::ByteBufferReader buf(recv_data->bytes(), recv_data->length());
kwiberg3ec46792016-04-27 07:22:53 -0700291 std::unique_ptr<StunMessage> res2(new StunMessage());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000292 EXPECT_TRUE(res2->Read(&buf));
293 EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
294 EXPECT_EQ(req->transaction_id(), res2->transaction_id());
295
296 const StunAddressAttribute* src_addr =
297 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
298 ASSERT_TRUE(src_addr != NULL);
299 EXPECT_EQ(1, src_addr->family());
300 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
301 EXPECT_EQ(client2_addr.port(), src_addr->port());
302
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000303 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000304}
305
306// Send a complete nonsense message to the established connection and verify
307// that it is dropped by the server.
308TEST_F(RelayServerTest, TestRemoteBadRequest) {
309 Allocate();
310 Bind();
311
312 SendRaw1(bad, static_cast<int>(strlen(bad)));
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000313 EXPECT_TRUE(Receive1Fails());
314 EXPECT_TRUE(Receive2Fails());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000315}
316
317// Send a send request without a username and verify it is rejected.
318TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
319 Allocate();
320 Bind();
321
kwiberg3ec46792016-04-27 07:22:53 -0700322 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000323 AddMagicCookieAttr(req.get());
324
325 Send1(req.get());
326 res.reset(Receive1());
327
328 ASSERT_TRUE(res);
329 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
330 EXPECT_EQ(req->transaction_id(), res->transaction_id());
331
332 const StunErrorCodeAttribute* err = res->GetErrorCode();
333 ASSERT_TRUE(err != NULL);
334 EXPECT_EQ(4, err->eclass());
335 EXPECT_EQ(32, err->number());
336 EXPECT_EQ("Missing Username", err->reason());
337}
338
339// Send a send request with the wrong username and verify it is rejected.
340TEST_F(RelayServerTest, TestSendRequestBadUsername) {
341 Allocate();
342 Bind();
343
kwiberg3ec46792016-04-27 07:22:53 -0700344 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000345 AddMagicCookieAttr(req.get());
346 AddUsernameAttr(req.get(), "foobarbizbaz");
347
348 Send1(req.get());
349 res.reset(Receive1());
350
351 ASSERT_TRUE(res);
352 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
353 EXPECT_EQ(req->transaction_id(), res->transaction_id());
354
355 const StunErrorCodeAttribute* err = res->GetErrorCode();
356 ASSERT_TRUE(err != NULL);
357 EXPECT_EQ(4, err->eclass());
358 EXPECT_EQ(30, err->number());
359 EXPECT_EQ("Stale Credentials", err->reason());
360}
361
362// Send a send request without a destination address and verify that it is
363// rejected.
364TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
365 Allocate();
366 Bind();
367
kwiberg3ec46792016-04-27 07:22:53 -0700368 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000369 AddMagicCookieAttr(req.get());
370 AddUsernameAttr(req.get(), username_);
371
372 Send1(req.get());
373 res.reset(Receive1());
374
375 ASSERT_TRUE(res);
376 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
377 EXPECT_EQ(req->transaction_id(), res->transaction_id());
378
379 const StunErrorCodeAttribute* err = res->GetErrorCode();
380 ASSERT_TRUE(err != NULL);
381 EXPECT_EQ(4, err->eclass());
382 EXPECT_EQ(0, err->number());
383 EXPECT_EQ("Bad Request", err->reason());
384}
385
386// Send a send request without data and verify that it is rejected.
387TEST_F(RelayServerTest, TestSendRequestNoData) {
388 Allocate();
389 Bind();
390
kwiberg3ec46792016-04-27 07:22:53 -0700391 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000392 AddMagicCookieAttr(req.get());
393 AddUsernameAttr(req.get(), username_);
394 AddDestinationAttr(req.get(), client2_addr);
395
396 Send1(req.get());
397 res.reset(Receive1());
398
399 ASSERT_TRUE(res);
400 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
401 EXPECT_EQ(req->transaction_id(), res->transaction_id());
402
403 const StunErrorCodeAttribute* err = res->GetErrorCode();
404 ASSERT_TRUE(err != NULL);
405 EXPECT_EQ(4, err->eclass());
406 EXPECT_EQ(00, err->number());
407 EXPECT_EQ("Bad Request", err->reason());
408}
409
410// Send a binding request after an allocate and verify that it is rejected.
411TEST_F(RelayServerTest, TestSendRequestWrongType) {
412 Allocate();
413 Bind();
414
kwiberg3ec46792016-04-27 07:22:53 -0700415 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
416 res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000417 AddMagicCookieAttr(req.get());
418 AddUsernameAttr(req.get(), username_);
419
420 Send1(req.get());
421 res.reset(Receive1());
422
423 ASSERT_TRUE(res);
424 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
425 EXPECT_EQ(req->transaction_id(), res->transaction_id());
426
427 const StunErrorCodeAttribute* err = res->GetErrorCode();
428 ASSERT_TRUE(err != NULL);
429 EXPECT_EQ(6, err->eclass());
430 EXPECT_EQ(0, err->number());
431 EXPECT_EQ("Operation Not Supported", err->reason());
432}
433
434// Verify that we can send traffic back and forth between the clients after a
435// successful allocate and bind.
436TEST_F(RelayServerTest, TestSendRaw) {
437 Allocate();
438 Bind();
439
440 for (int i = 0; i < 10; i++) {
kwiberg3ec46792016-04-27 07:22:53 -0700441 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000442 AddMagicCookieAttr(req.get());
443 AddUsernameAttr(req.get(), username_);
444 AddDestinationAttr(req.get(), client2_addr);
445
zsteinf42cc9d2017-03-27 16:17:19 -0700446 auto send_data = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000447 send_data->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700448 req->AddAttribute(std::move(send_data));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000449
450 Send1(req.get());
451 EXPECT_EQ(msg1, ReceiveRaw2());
452 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
453 res.reset(Receive1());
454
455 ASSERT_TRUE(res);
456 EXPECT_EQ(STUN_DATA_INDICATION, res->type());
457
458 const StunAddressAttribute* src_addr =
459 res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
460 ASSERT_TRUE(src_addr != NULL);
461 EXPECT_EQ(1, src_addr->family());
462 EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
463 EXPECT_EQ(client2_addr.port(), src_addr->port());
464
465 const StunByteStringAttribute* recv_data =
466 res->GetByteString(STUN_ATTR_DATA);
467 ASSERT_TRUE(recv_data != NULL);
468 EXPECT_EQ(strlen(msg2), recv_data->length());
469 EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
470 }
471}
472
473// Verify that a binding expires properly, and rejects send requests.
andrew@webrtc.org4796cb92015-01-05 23:56:19 +0000474// Flaky, see https://code.google.com/p/webrtc/issues/detail?id=4134
475TEST_F(RelayServerTest, DISABLED_TestExpiration) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000476 Allocate();
477 Bind();
478
479 // Wait twice the lifetime to make sure the server has expired the binding.
480 rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
481
kwiberg3ec46792016-04-27 07:22:53 -0700482 std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000483 AddMagicCookieAttr(req.get());
484 AddUsernameAttr(req.get(), username_);
485 AddDestinationAttr(req.get(), client2_addr);
486
zsteinf42cc9d2017-03-27 16:17:19 -0700487 auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000488 data_attr->CopyBytes(msg1);
zsteinf42cc9d2017-03-27 16:17:19 -0700489 req->AddAttribute(std::move(data_attr));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000490
491 Send1(req.get());
492 res.reset(Receive1());
493
494 ASSERT_TRUE(res.get() != NULL);
495 EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
496
497 const StunErrorCodeAttribute* err = res->GetErrorCode();
498 ASSERT_TRUE(err != NULL);
499 EXPECT_EQ(6, err->eclass());
500 EXPECT_EQ(0, err->number());
501 EXPECT_EQ("Operation Not Supported", err->reason());
502
503 // Also verify that traffic from the external client is ignored.
504 SendRaw2(msg2, static_cast<int>(strlen(msg2)));
505 EXPECT_TRUE(ReceiveRaw1().empty());
506}
Steve Anton6c38cc72017-11-29 10:25:58 -0800507
508} // namespace cricket