1269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/*
2269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *
4269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org */
10269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
11269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <string>
12269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
13269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/relayserver.h"
14269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/gunit.h"
15269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/helpers.h"
16269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/logging.h"
17269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h"
18269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/socketaddress.h"
19269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/ssladapter.h"
20269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/testclient.h"
21269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/thread.h"
2253cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org#include "webrtc/base/virtualsocketserver.h"
23269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
24269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::SocketAddress;
25269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing namespace cricket;
26269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
270c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmstatic const uint32_t LIFETIME = 4;  // seconds
28269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress server_int_addr("127.0.0.1", 5000);
29269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress server_ext_addr("127.0.0.1", 5001);
30269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
31269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
32269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const char* bad = "this is a completely nonsensical message whose only "
33269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                         "purpose is to make the parser go 'ack'.  it doesn't "
34269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                         "look anything like a normal stun message";
35269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
36269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
37269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
38269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass RelayServerTest : public testing::Test {
39269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
40269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  RelayServerTest()
4153cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org      : pss_(new rtc::PhysicalSocketServer),
4253cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        ss_(new rtc::VirtualSocketServer(pss_.get())),
4353cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        ss_scope_(ss_.get()),
44269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        username_(rtc::CreateRandomString(12)),
4553cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        password_(rtc::CreateRandomString(12)) {}
4653cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org
47269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org protected:
48269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual void SetUp() {
4953cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org    server_.reset(new RelayServer(rtc::Thread::Current()));
50269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
51269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    server_->AddInternalSocket(
5253cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        rtc::AsyncUDPSocket::Create(ss_.get(), server_int_addr));
53269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    server_->AddExternalSocket(
5453cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        rtc::AsyncUDPSocket::Create(ss_.get(), server_ext_addr));
55269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
56269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    client1_.reset(new rtc::TestClient(
5753cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        rtc::AsyncUDPSocket::Create(ss_.get(), client1_addr)));
58269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    client2_.reset(new rtc::TestClient(
5953cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org        rtc::AsyncUDPSocket::Create(ss_.get(), client2_addr)));
60269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
61269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
62269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Allocate() {
63269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::scoped_ptr<StunMessage> req(
64269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        CreateStunMessage(STUN_ALLOCATE_REQUEST));
65269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddUsernameAttr(req.get(), username_);
66269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddLifetimeAttr(req.get(), LIFETIME);
67269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Send1(req.get());
68269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    delete Receive1();
69269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
70269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Bind() {
71269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::scoped_ptr<StunMessage> req(
72269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        CreateStunMessage(STUN_BINDING_REQUEST));
73269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddUsernameAttr(req.get(), username_);
74269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Send2(req.get());
75269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    delete Receive1();
76269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
77269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
78269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Send1(const StunMessage* msg) {
79269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::ByteBuffer buf;
80269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->Write(&buf);
81269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
82269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
83269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Send2(const StunMessage* msg) {
84269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::ByteBuffer buf;
85269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->Write(&buf);
86269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
87269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
88269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void SendRaw1(const char* data, int len) {
89269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return Send(client1_.get(), data, len, server_int_addr);
90269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
91269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void SendRaw2(const char* data, int len) {
92269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return Send(client2_.get(), data, len, server_ext_addr);
93269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
94269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Send(rtc::TestClient* client, const char* data,
95269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            int len, const SocketAddress& addr) {
96269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    client->SendTo(data, len, addr);
97269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
98269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
99ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  bool Receive1Fails() {
100ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org    return client1_.get()->CheckNoPacket();
101ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  }
102ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  bool Receive2Fails() {
103ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org    return client2_.get()->CheckNoPacket();
104ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  }
105ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org
106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StunMessage* Receive1() {
107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return Receive(client1_.get());
108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StunMessage* Receive2() {
110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return Receive(client2_.get());
111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string ReceiveRaw1() {
113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return ReceiveRaw(client1_.get());
114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string ReceiveRaw2() {
116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return ReceiveRaw(client2_.get());
117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StunMessage* Receive(rtc::TestClient* client) {
119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunMessage* msg = NULL;
120ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org    rtc::TestClient::Packet* packet =
121ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org        client->NextPacket(rtc::TestClient::kTimeoutMs);
122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (packet) {
123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rtc::ByteBuffer buf(packet->buf, packet->size);
124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg = new RelayMessage();
125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->Read(&buf);
126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      delete packet;
127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return msg;
129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string ReceiveRaw(rtc::TestClient* client) {
131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    std::string raw;
132ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org    rtc::TestClient::Packet* packet =
133ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org        client->NextPacket(rtc::TestClient::kTimeoutMs);
134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (packet) {
135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      raw = std::string(packet->buf, packet->size);
136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      delete packet;
137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return raw;
139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static StunMessage* CreateStunMessage(int type) {
142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunMessage* msg = new RelayMessage();
143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->SetType(type);
144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->SetTransactionID(
145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        rtc::CreateRandomString(kStunTransactionIdLength));
146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return msg;
147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static void AddMagicCookieAttr(StunMessage* msg) {
149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunByteStringAttribute* attr =
150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->AddAttribute(attr);
153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunByteStringAttribute* attr =
156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    attr->CopyBytes(val.c_str(), val.size());
158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->AddAttribute(attr);
159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static void AddLifetimeAttr(StunMessage* msg, int val) {
161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunUInt32Attribute* attr =
162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    attr->SetValue(val);
164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->AddAttribute(attr);
165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunAddressAttribute* attr =
168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    attr->SetIP(addr.ipaddr());
170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    attr->SetPort(addr.port());
171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->AddAttribute(attr);
172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
17453cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
17553cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org  rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
17653cb74107f9ae07b0e2d04dd41d29248f55cec56pbos@webrtc.org  rtc::SocketServerScope ss_scope_;
177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<RelayServer> server_;
178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::TestClient> client1_;
179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::TestClient> client2_;
180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username_;
181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string password_;
182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a complete nonsense message and verify that it is eaten.
185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestBadRequest) {
186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SendRaw1(bad, static_cast<int>(strlen(bad)));
187ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  ASSERT_TRUE(Receive1Fails());
188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send an allocate request without a username and verify it is rejected.
191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestAllocateNoUsername) {
192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
201269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
202269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
203269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
204269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(4, err->eclass());
205269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(32, err->number());
206269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Missing Username", err->reason());
207269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
208269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
209269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a binding request and verify that it is rejected.
210269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestBindingRequest) {
211269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
212269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_BINDING_REQUEST)), res;
213269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
214269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
215269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
216269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
217269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
218269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
219269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
223269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
224269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(6, err->eclass());
225269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, err->number());
226269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Operation Not Supported", err->reason());
227269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
228269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
229269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send an allocate request and verify that it is accepted.
230269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestAllocate) {
231269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
232269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
233269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
234269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddLifetimeAttr(req.get(), LIFETIME);
235269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
236269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
237269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
238269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
239269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
240269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
241269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
242269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
243269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunAddressAttribute* mapped_addr =
244269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
245269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(mapped_addr != NULL);
246269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1, mapped_addr->family());
247269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
248269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
249269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
250269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt32Attribute* res_lifetime_attr =
251269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetUInt32(STUN_ATTR_LIFETIME);
252269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res_lifetime_attr != NULL);
253269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
254269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
255269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
256269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a second allocate request and verify that it is also accepted, though
257269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// the lifetime should be ignored.
258269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestReallocate) {
259269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
260269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
261269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
262269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
263269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
264269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
265269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
266269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
267269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
268269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
269269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
270269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
271269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
272269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
273269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunAddressAttribute* mapped_addr =
274269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
275269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(mapped_addr != NULL);
276269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1, mapped_addr->family());
277269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
278269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
279269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
280269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt32Attribute* lifetime_attr =
281269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetUInt32(STUN_ATTR_LIFETIME);
282269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(lifetime_attr != NULL);
283269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(LIFETIME, lifetime_attr->value());
284269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
285269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
286269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a request from another client and see that it arrives at the first
287269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// client in the binding.
288269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestRemoteBind) {
289269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
290269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
291269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
292269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_BINDING_REQUEST)), res;
293269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
294269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
295269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send2(req.get());
296269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
297269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
298269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
299269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_DATA_INDICATION, res->type());
300269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
301269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunByteStringAttribute* recv_data =
302269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetByteString(STUN_ATTR_DATA);
303269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(recv_data != NULL);
304269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
305269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::ByteBuffer buf(recv_data->bytes(), recv_data->length());
306269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> res2(new StunMessage());
307269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(res2->Read(&buf));
308269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
309269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res2->transaction_id());
310269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
311269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunAddressAttribute* src_addr =
312269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
313269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(src_addr != NULL);
314269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1, src_addr->family());
315269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
316269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(client2_addr.port(), src_addr->port());
317269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
318ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  EXPECT_TRUE(Receive2Fails());
319269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
320269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
321269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a complete nonsense message to the established connection and verify
322269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// that it is dropped by the server.
323269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestRemoteBadRequest) {
324269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
325269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
326269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
327269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SendRaw1(bad, static_cast<int>(strlen(bad)));
328ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  EXPECT_TRUE(Receive1Fails());
329ec499beaf53409bbdc67dcda48cfc29ade2afa32jlmiller@webrtc.org  EXPECT_TRUE(Receive2Fails());
330269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
331269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
332269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a send request without a username and verify it is rejected.
333269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRequestMissingUsername) {
334269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
335269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
336269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
337269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
338269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_SEND_REQUEST)), res;
339269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
340269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
341269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
342269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
343269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
344269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
345269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
346269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
347269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
348269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
349269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
350269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(4, err->eclass());
351269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(32, err->number());
352269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Missing Username", err->reason());
353269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
354269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
355269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a send request with the wrong username and verify it is rejected.
356269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRequestBadUsername) {
357269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
358269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
359269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
360269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
361269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_SEND_REQUEST)), res;
362269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
363269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), "foobarbizbaz");
364269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
365269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
366269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
367269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
368269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
369269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
370269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
371269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
372269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
373269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
374269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(4, err->eclass());
375269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(30, err->number());
376269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Stale Credentials", err->reason());
377269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
378269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
379269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a send request without a destination address and verify that it is
380269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// rejected.
381269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
382269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
383269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
384269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
385269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
386269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_SEND_REQUEST)), res;
387269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
388269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
389269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
390269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
391269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
392269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
393269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
394269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
395269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
396269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
397269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
398269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
399269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(4, err->eclass());
400269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, err->number());
401269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Bad Request", err->reason());
402269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
403269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
404269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a send request without data and verify that it is rejected.
405269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRequestNoData) {
406269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
407269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
408269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
409269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
410269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_SEND_REQUEST)), res;
411269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
412269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
413269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddDestinationAttr(req.get(), client2_addr);
414269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
415269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
416269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
417269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
418269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
419269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
420269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
421269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
422269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
423269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
424269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(4, err->eclass());
425269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(00, err->number());
426269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Bad Request", err->reason());
427269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
428269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
429269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Send a binding request after an allocate and verify that it is rejected.
430269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRequestWrongType) {
431269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
432269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
433269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
434269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
435269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_BINDING_REQUEST)), res;
436269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
437269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
438269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
439269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
440269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
441269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
442269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res);
443269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
444269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(req->transaction_id(), res->transaction_id());
445269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
446269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
447269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
448269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(6, err->eclass());
449269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, err->number());
450269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Operation Not Supported", err->reason());
451269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
452269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
453269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Verify that we can send traffic back and forth between the clients after a
454269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// successful allocate and bind.
455269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(RelayServerTest, TestSendRaw) {
456269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
457269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
458269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
459269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  for (int i = 0; i < 10; i++) {
460269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::scoped_ptr<StunMessage> req(
461269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        CreateStunMessage(STUN_SEND_REQUEST)), res;
462269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddMagicCookieAttr(req.get());
463269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddUsernameAttr(req.get(), username_);
464269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddDestinationAttr(req.get(), client2_addr);
465269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
466269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    StunByteStringAttribute* send_data =
467269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        StunAttribute::CreateByteString(STUN_ATTR_DATA);
468269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    send_data->CopyBytes(msg1);
469269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    req->AddAttribute(send_data);
470269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
471269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Send1(req.get());
472269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(msg1, ReceiveRaw2());
473269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    SendRaw2(msg2, static_cast<int>(strlen(msg2)));
474269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    res.reset(Receive1());
475269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
476269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(res);
477269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(STUN_DATA_INDICATION, res->type());
478269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
479269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const StunAddressAttribute* src_addr =
480269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
481269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(src_addr != NULL);
482269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(1, src_addr->family());
483269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
484269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(client2_addr.port(), src_addr->port());
485269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
486269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const StunByteStringAttribute* recv_data =
487269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        res->GetByteString(STUN_ATTR_DATA);
488269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(recv_data != NULL);
489269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(strlen(msg2), recv_data->length());
490269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
491269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
492269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
493269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
494269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Verify that a binding expires properly, and rejects send requests.
4954796cb93dc80f7921a1724e5da87a1bbb0fc3717andrew@webrtc.org// Flaky, see https://code.google.com/p/webrtc/issues/detail?id=4134
4964796cb93dc80f7921a1724e5da87a1bbb0fc3717andrew@webrtc.orgTEST_F(RelayServerTest, DISABLED_TestExpiration) {
497269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Allocate();
498269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Bind();
499269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
500269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Wait twice the lifetime to make sure the server has expired the binding.
501269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
502269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
503269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> req(
504269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_SEND_REQUEST)), res;
505269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddMagicCookieAttr(req.get());
506269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddUsernameAttr(req.get(), username_);
507269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AddDestinationAttr(req.get(), client2_addr);
508269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
509269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StunByteStringAttribute* data_attr =
510269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      StunAttribute::CreateByteString(STUN_ATTR_DATA);
511269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  data_attr->CopyBytes(msg1);
512269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  req->AddAttribute(data_attr);
513269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
514269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Send1(req.get());
515269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  res.reset(Receive1());
516269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
517269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(res.get() != NULL);
518269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
519269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
520269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* err = res->GetErrorCode();
521269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(err != NULL);
522269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(6, err->eclass());
523269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, err->number());
524269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("Operation Not Supported", err->reason());
525269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
526269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Also verify that traffic from the external client is ignored.
527269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SendRaw2(msg2, static_cast<int>(strlen(msg2)));
528269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(ReceiveRaw1().empty());
529269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
530