1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
16*d9f75844SAndroid Build Coastguard Worker #include <limits>
17*d9f75844SAndroid Build Coastguard Worker #include <list>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker #include <string>
20*d9f75844SAndroid Build Coastguard Worker #include <utility>
21*d9f75844SAndroid Build Coastguard Worker #include <vector>
22*d9f75844SAndroid Build Coastguard Worker
23*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
24*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/candidate.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/packet_socket_factory.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/transport/stun.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
29*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/basic_packet_socket_factory.h"
30*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/p2p_constants.h"
31*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
32*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_interface.h"
33*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/stun_port.h"
34*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/stun_server.h"
35*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/tcp_port.h"
36*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_stun_server.h"
37*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/test_turn_server.h"
38*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/transport_description.h"
39*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/turn_port.h"
40*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/turn_server.h"
41*d9f75844SAndroid Build Coastguard Worker #include "p2p/client/relay_port_factory_interface.h"
42*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/arraysize.h"
43*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_packet_socket.h"
44*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/buffer.h"
45*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/byte_buffer.h"
46*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
47*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/dscp.h"
48*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_clock.h"
49*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
50*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
51*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
52*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/nat_server.h"
53*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/nat_socket_factory.h"
54*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/nat_types.h"
55*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/net_helper.h"
56*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/network.h"
57*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/network/sent_packet.h"
58*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/network_constants.h"
59*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/proxy_info.h"
60*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket.h"
61*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_adapters.h"
62*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_address.h"
63*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/sigslot/sigslot.h"
64*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
65*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
66*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
67*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
68*d9f75844SAndroid Build Coastguard Worker #include "test/scoped_key_value_config.h"
69*d9f75844SAndroid Build Coastguard Worker
70*d9f75844SAndroid Build Coastguard Worker using rtc::AsyncListenSocket;
71*d9f75844SAndroid Build Coastguard Worker using rtc::AsyncPacketSocket;
72*d9f75844SAndroid Build Coastguard Worker using rtc::ByteBufferReader;
73*d9f75844SAndroid Build Coastguard Worker using rtc::ByteBufferWriter;
74*d9f75844SAndroid Build Coastguard Worker using rtc::NAT_ADDR_RESTRICTED;
75*d9f75844SAndroid Build Coastguard Worker using rtc::NAT_OPEN_CONE;
76*d9f75844SAndroid Build Coastguard Worker using rtc::NAT_PORT_RESTRICTED;
77*d9f75844SAndroid Build Coastguard Worker using rtc::NAT_SYMMETRIC;
78*d9f75844SAndroid Build Coastguard Worker using rtc::NATType;
79*d9f75844SAndroid Build Coastguard Worker using rtc::PacketSocketFactory;
80*d9f75844SAndroid Build Coastguard Worker using rtc::Socket;
81*d9f75844SAndroid Build Coastguard Worker using rtc::SocketAddress;
82*d9f75844SAndroid Build Coastguard Worker
83*d9f75844SAndroid Build Coastguard Worker namespace cricket {
84*d9f75844SAndroid Build Coastguard Worker namespace {
85*d9f75844SAndroid Build Coastguard Worker
86*d9f75844SAndroid Build Coastguard Worker constexpr int kDefaultTimeout = 3000;
87*d9f75844SAndroid Build Coastguard Worker constexpr int kShortTimeout = 1000;
88*d9f75844SAndroid Build Coastguard Worker constexpr int kMaxExpectedSimulatedRtt = 200;
89*d9f75844SAndroid Build Coastguard Worker const SocketAddress kLocalAddr1("192.168.1.2", 0);
90*d9f75844SAndroid Build Coastguard Worker const SocketAddress kLocalAddr2("192.168.1.3", 0);
91*d9f75844SAndroid Build Coastguard Worker const SocketAddress kLinkLocalIPv6Addr("fe80::aabb:ccff:fedd:eeff", 0);
92*d9f75844SAndroid Build Coastguard Worker const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
93*d9f75844SAndroid Build Coastguard Worker const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
94*d9f75844SAndroid Build Coastguard Worker const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
95*d9f75844SAndroid Build Coastguard Worker const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
96*d9f75844SAndroid Build Coastguard Worker const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
97*d9f75844SAndroid Build Coastguard Worker const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
98*d9f75844SAndroid Build Coastguard Worker const RelayCredentials kRelayCredentials("test", "test");
99*d9f75844SAndroid Build Coastguard Worker
100*d9f75844SAndroid Build Coastguard Worker // TODO(?): Update these when RFC5245 is completely supported.
101*d9f75844SAndroid Build Coastguard Worker // Magic value of 30 is from RFC3484, for IPv4 addresses.
102*d9f75844SAndroid Build Coastguard Worker const uint32_t kDefaultPrflxPriority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
103*d9f75844SAndroid Build Coastguard Worker 30 << 8 |
104*d9f75844SAndroid Build Coastguard Worker (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
105*d9f75844SAndroid Build Coastguard Worker
106*d9f75844SAndroid Build Coastguard Worker constexpr int kTiebreaker1 = 11111;
107*d9f75844SAndroid Build Coastguard Worker constexpr int kTiebreaker2 = 22222;
108*d9f75844SAndroid Build Coastguard Worker constexpr int kTiebreakerDefault = 44444;
109*d9f75844SAndroid Build Coastguard Worker
110*d9f75844SAndroid Build Coastguard Worker const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
111*d9f75844SAndroid Build Coastguard Worker
GetCandidate(Port * port)112*d9f75844SAndroid Build Coastguard Worker Candidate GetCandidate(Port* port) {
113*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GE(port->Candidates().size(), 1);
114*d9f75844SAndroid Build Coastguard Worker return port->Candidates()[0];
115*d9f75844SAndroid Build Coastguard Worker }
116*d9f75844SAndroid Build Coastguard Worker
GetAddress(Port * port)117*d9f75844SAndroid Build Coastguard Worker SocketAddress GetAddress(Port* port) {
118*d9f75844SAndroid Build Coastguard Worker return GetCandidate(port).address();
119*d9f75844SAndroid Build Coastguard Worker }
120*d9f75844SAndroid Build Coastguard Worker
CopyStunMessage(const IceMessage & src)121*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> CopyStunMessage(const IceMessage& src) {
122*d9f75844SAndroid Build Coastguard Worker auto dst = std::make_unique<IceMessage>();
123*d9f75844SAndroid Build Coastguard Worker ByteBufferWriter buf;
124*d9f75844SAndroid Build Coastguard Worker src.Write(&buf);
125*d9f75844SAndroid Build Coastguard Worker ByteBufferReader read_buf(buf);
126*d9f75844SAndroid Build Coastguard Worker dst->Read(&read_buf);
127*d9f75844SAndroid Build Coastguard Worker return dst;
128*d9f75844SAndroid Build Coastguard Worker }
129*d9f75844SAndroid Build Coastguard Worker
WriteStunMessage(const StunMessage & msg,ByteBufferWriter * buf)130*d9f75844SAndroid Build Coastguard Worker bool WriteStunMessage(const StunMessage& msg, ByteBufferWriter* buf) {
131*d9f75844SAndroid Build Coastguard Worker buf->Resize(0); // clear out any existing buffer contents
132*d9f75844SAndroid Build Coastguard Worker return msg.Write(buf);
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker
135*d9f75844SAndroid Build Coastguard Worker } // namespace
136*d9f75844SAndroid Build Coastguard Worker
137*d9f75844SAndroid Build Coastguard Worker // Stub port class for testing STUN generation and processing.
138*d9f75844SAndroid Build Coastguard Worker class TestPort : public Port {
139*d9f75844SAndroid Build Coastguard Worker public:
TestPort(rtc::Thread * thread,absl::string_view type,rtc::PacketSocketFactory * factory,const rtc::Network * network,uint16_t min_port,uint16_t max_port,absl::string_view username_fragment,absl::string_view password)140*d9f75844SAndroid Build Coastguard Worker TestPort(rtc::Thread* thread,
141*d9f75844SAndroid Build Coastguard Worker absl::string_view type,
142*d9f75844SAndroid Build Coastguard Worker rtc::PacketSocketFactory* factory,
143*d9f75844SAndroid Build Coastguard Worker const rtc::Network* network,
144*d9f75844SAndroid Build Coastguard Worker uint16_t min_port,
145*d9f75844SAndroid Build Coastguard Worker uint16_t max_port,
146*d9f75844SAndroid Build Coastguard Worker absl::string_view username_fragment,
147*d9f75844SAndroid Build Coastguard Worker absl::string_view password)
148*d9f75844SAndroid Build Coastguard Worker : Port(thread,
149*d9f75844SAndroid Build Coastguard Worker type,
150*d9f75844SAndroid Build Coastguard Worker factory,
151*d9f75844SAndroid Build Coastguard Worker network,
152*d9f75844SAndroid Build Coastguard Worker min_port,
153*d9f75844SAndroid Build Coastguard Worker max_port,
154*d9f75844SAndroid Build Coastguard Worker username_fragment,
155*d9f75844SAndroid Build Coastguard Worker password) {}
~TestPort()156*d9f75844SAndroid Build Coastguard Worker ~TestPort() {}
157*d9f75844SAndroid Build Coastguard Worker
158*d9f75844SAndroid Build Coastguard Worker // Expose GetStunMessage so that we can test it.
159*d9f75844SAndroid Build Coastguard Worker using cricket::Port::GetStunMessage;
160*d9f75844SAndroid Build Coastguard Worker
161*d9f75844SAndroid Build Coastguard Worker // The last StunMessage that was sent on this Port.
162*d9f75844SAndroid Build Coastguard Worker // TODO(?): Make these const; requires changes to SendXXXXResponse.
last_stun_buf()163*d9f75844SAndroid Build Coastguard Worker rtc::BufferT<uint8_t>* last_stun_buf() { return last_stun_buf_.get(); }
last_stun_msg()164*d9f75844SAndroid Build Coastguard Worker IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
last_stun_error_code()165*d9f75844SAndroid Build Coastguard Worker int last_stun_error_code() {
166*d9f75844SAndroid Build Coastguard Worker int code = 0;
167*d9f75844SAndroid Build Coastguard Worker if (last_stun_msg_) {
168*d9f75844SAndroid Build Coastguard Worker const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
169*d9f75844SAndroid Build Coastguard Worker if (error_attr) {
170*d9f75844SAndroid Build Coastguard Worker code = error_attr->code();
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker }
173*d9f75844SAndroid Build Coastguard Worker return code;
174*d9f75844SAndroid Build Coastguard Worker }
175*d9f75844SAndroid Build Coastguard Worker
PrepareAddress()176*d9f75844SAndroid Build Coastguard Worker virtual void PrepareAddress() {
177*d9f75844SAndroid Build Coastguard Worker // Act as if the socket was bound to the best IP on the network, to the
178*d9f75844SAndroid Build Coastguard Worker // first port in the allowed range.
179*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(Network()->GetBestIP(), min_port());
180*d9f75844SAndroid Build Coastguard Worker AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
181*d9f75844SAndroid Build Coastguard Worker ICE_TYPE_PREFERENCE_HOST, 0, "", true);
182*d9f75844SAndroid Build Coastguard Worker }
183*d9f75844SAndroid Build Coastguard Worker
SupportsProtocol(absl::string_view protocol) const184*d9f75844SAndroid Build Coastguard Worker virtual bool SupportsProtocol(absl::string_view protocol) const {
185*d9f75844SAndroid Build Coastguard Worker return true;
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker
GetProtocol() const188*d9f75844SAndroid Build Coastguard Worker virtual ProtocolType GetProtocol() const { return PROTO_UDP; }
189*d9f75844SAndroid Build Coastguard Worker
190*d9f75844SAndroid Build Coastguard Worker // Exposed for testing candidate building.
AddCandidateAddress(const rtc::SocketAddress & addr)191*d9f75844SAndroid Build Coastguard Worker void AddCandidateAddress(const rtc::SocketAddress& addr) {
192*d9f75844SAndroid Build Coastguard Worker AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
193*d9f75844SAndroid Build Coastguard Worker type_preference_, 0, "", false);
194*d9f75844SAndroid Build Coastguard Worker }
AddCandidateAddress(const rtc::SocketAddress & addr,const rtc::SocketAddress & base_address,absl::string_view type,int type_preference,bool final)195*d9f75844SAndroid Build Coastguard Worker void AddCandidateAddress(const rtc::SocketAddress& addr,
196*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress& base_address,
197*d9f75844SAndroid Build Coastguard Worker absl::string_view type,
198*d9f75844SAndroid Build Coastguard Worker int type_preference,
199*d9f75844SAndroid Build Coastguard Worker bool final) {
200*d9f75844SAndroid Build Coastguard Worker AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
201*d9f75844SAndroid Build Coastguard Worker type_preference, 0, "", final);
202*d9f75844SAndroid Build Coastguard Worker }
203*d9f75844SAndroid Build Coastguard Worker
CreateConnection(const Candidate & remote_candidate,CandidateOrigin origin)204*d9f75844SAndroid Build Coastguard Worker virtual Connection* CreateConnection(const Candidate& remote_candidate,
205*d9f75844SAndroid Build Coastguard Worker CandidateOrigin origin) {
206*d9f75844SAndroid Build Coastguard Worker Connection* conn = new ProxyConnection(NewWeakPtr(), 0, remote_candidate);
207*d9f75844SAndroid Build Coastguard Worker AddOrReplaceConnection(conn);
208*d9f75844SAndroid Build Coastguard Worker // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
209*d9f75844SAndroid Build Coastguard Worker // in STUN binding requests.
210*d9f75844SAndroid Build Coastguard Worker conn->set_use_candidate_attr(true);
211*d9f75844SAndroid Build Coastguard Worker return conn;
212*d9f75844SAndroid Build Coastguard Worker }
SendTo(const void * data,size_t size,const rtc::SocketAddress & addr,const rtc::PacketOptions & options,bool payload)213*d9f75844SAndroid Build Coastguard Worker virtual int SendTo(const void* data,
214*d9f75844SAndroid Build Coastguard Worker size_t size,
215*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress& addr,
216*d9f75844SAndroid Build Coastguard Worker const rtc::PacketOptions& options,
217*d9f75844SAndroid Build Coastguard Worker bool payload) {
218*d9f75844SAndroid Build Coastguard Worker if (!payload) {
219*d9f75844SAndroid Build Coastguard Worker auto msg = std::make_unique<IceMessage>();
220*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<rtc::BufferT<uint8_t>>(
221*d9f75844SAndroid Build Coastguard Worker static_cast<const char*>(data), size);
222*d9f75844SAndroid Build Coastguard Worker ByteBufferReader read_buf(*buf);
223*d9f75844SAndroid Build Coastguard Worker if (!msg->Read(&read_buf)) {
224*d9f75844SAndroid Build Coastguard Worker return -1;
225*d9f75844SAndroid Build Coastguard Worker }
226*d9f75844SAndroid Build Coastguard Worker last_stun_buf_ = std::move(buf);
227*d9f75844SAndroid Build Coastguard Worker last_stun_msg_ = std::move(msg);
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker return static_cast<int>(size);
230*d9f75844SAndroid Build Coastguard Worker }
SetOption(rtc::Socket::Option opt,int value)231*d9f75844SAndroid Build Coastguard Worker virtual int SetOption(rtc::Socket::Option opt, int value) { return 0; }
GetOption(rtc::Socket::Option opt,int * value)232*d9f75844SAndroid Build Coastguard Worker virtual int GetOption(rtc::Socket::Option opt, int* value) { return -1; }
GetError()233*d9f75844SAndroid Build Coastguard Worker virtual int GetError() { return 0; }
Reset()234*d9f75844SAndroid Build Coastguard Worker void Reset() {
235*d9f75844SAndroid Build Coastguard Worker last_stun_buf_.reset();
236*d9f75844SAndroid Build Coastguard Worker last_stun_msg_.reset();
237*d9f75844SAndroid Build Coastguard Worker }
set_type_preference(int type_preference)238*d9f75844SAndroid Build Coastguard Worker void set_type_preference(int type_preference) {
239*d9f75844SAndroid Build Coastguard Worker type_preference_ = type_preference;
240*d9f75844SAndroid Build Coastguard Worker }
241*d9f75844SAndroid Build Coastguard Worker
242*d9f75844SAndroid Build Coastguard Worker private:
OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & sent_packet)243*d9f75844SAndroid Build Coastguard Worker void OnSentPacket(rtc::AsyncPacketSocket* socket,
244*d9f75844SAndroid Build Coastguard Worker const rtc::SentPacket& sent_packet) {
245*d9f75844SAndroid Build Coastguard Worker PortInterface::SignalSentPacket(sent_packet);
246*d9f75844SAndroid Build Coastguard Worker }
247*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::BufferT<uint8_t>> last_stun_buf_;
248*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> last_stun_msg_;
249*d9f75844SAndroid Build Coastguard Worker int type_preference_ = 0;
250*d9f75844SAndroid Build Coastguard Worker };
251*d9f75844SAndroid Build Coastguard Worker
SendPingAndReceiveResponse(Connection * lconn,TestPort * lport,Connection * rconn,TestPort * rport,rtc::ScopedFakeClock * clock,int64_t ms)252*d9f75844SAndroid Build Coastguard Worker static void SendPingAndReceiveResponse(Connection* lconn,
253*d9f75844SAndroid Build Coastguard Worker TestPort* lport,
254*d9f75844SAndroid Build Coastguard Worker Connection* rconn,
255*d9f75844SAndroid Build Coastguard Worker TestPort* rport,
256*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock* clock,
257*d9f75844SAndroid Build Coastguard Worker int64_t ms) {
258*d9f75844SAndroid Build Coastguard Worker lconn->Ping(rtc::TimeMillis());
259*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
260*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lport->last_stun_buf());
261*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
262*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
263*d9f75844SAndroid Build Coastguard Worker clock->AdvanceTime(webrtc::TimeDelta::Millis(ms));
264*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
265*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(rport->last_stun_buf());
266*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
267*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
268*d9f75844SAndroid Build Coastguard Worker }
269*d9f75844SAndroid Build Coastguard Worker
270*d9f75844SAndroid Build Coastguard Worker class TestChannel : public sigslot::has_slots<> {
271*d9f75844SAndroid Build Coastguard Worker public:
272*d9f75844SAndroid Build Coastguard Worker // Takes ownership of `p1` (but not `p2`).
TestChannel(std::unique_ptr<Port> p1)273*d9f75844SAndroid Build Coastguard Worker explicit TestChannel(std::unique_ptr<Port> p1) : port_(std::move(p1)) {
274*d9f75844SAndroid Build Coastguard Worker port_->SignalPortComplete.connect(this, &TestChannel::OnPortComplete);
275*d9f75844SAndroid Build Coastguard Worker port_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
276*d9f75844SAndroid Build Coastguard Worker port_->SubscribePortDestroyed(
277*d9f75844SAndroid Build Coastguard Worker [this](PortInterface* port) { OnSrcPortDestroyed(port); });
278*d9f75844SAndroid Build Coastguard Worker }
279*d9f75844SAndroid Build Coastguard Worker
~TestChannel()280*d9f75844SAndroid Build Coastguard Worker ~TestChannel() { Stop(); }
281*d9f75844SAndroid Build Coastguard Worker
complete_count()282*d9f75844SAndroid Build Coastguard Worker int complete_count() { return complete_count_; }
conn()283*d9f75844SAndroid Build Coastguard Worker Connection* conn() { return conn_; }
remote_address()284*d9f75844SAndroid Build Coastguard Worker const SocketAddress& remote_address() { return remote_address_; }
remote_fragment()285*d9f75844SAndroid Build Coastguard Worker const std::string remote_fragment() { return remote_frag_; }
286*d9f75844SAndroid Build Coastguard Worker
Start()287*d9f75844SAndroid Build Coastguard Worker void Start() { port_->PrepareAddress(); }
CreateConnection(const Candidate & remote_candidate)288*d9f75844SAndroid Build Coastguard Worker void CreateConnection(const Candidate& remote_candidate) {
289*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!conn_);
290*d9f75844SAndroid Build Coastguard Worker conn_ = port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
291*d9f75844SAndroid Build Coastguard Worker IceMode remote_ice_mode =
292*d9f75844SAndroid Build Coastguard Worker (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
293*d9f75844SAndroid Build Coastguard Worker conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
294*d9f75844SAndroid Build Coastguard Worker conn_->SignalStateChange.connect(this,
295*d9f75844SAndroid Build Coastguard Worker &TestChannel::OnConnectionStateChange);
296*d9f75844SAndroid Build Coastguard Worker conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
297*d9f75844SAndroid Build Coastguard Worker conn_->SignalReadyToSend.connect(this,
298*d9f75844SAndroid Build Coastguard Worker &TestChannel::OnConnectionReadyToSend);
299*d9f75844SAndroid Build Coastguard Worker connection_ready_to_send_ = false;
300*d9f75844SAndroid Build Coastguard Worker }
301*d9f75844SAndroid Build Coastguard Worker
OnConnectionStateChange(Connection * conn)302*d9f75844SAndroid Build Coastguard Worker void OnConnectionStateChange(Connection* conn) {
303*d9f75844SAndroid Build Coastguard Worker if (conn->write_state() == Connection::STATE_WRITABLE) {
304*d9f75844SAndroid Build Coastguard Worker conn->set_use_candidate_attr(true);
305*d9f75844SAndroid Build Coastguard Worker nominated_ = true;
306*d9f75844SAndroid Build Coastguard Worker }
307*d9f75844SAndroid Build Coastguard Worker }
AcceptConnection(const Candidate & remote_candidate)308*d9f75844SAndroid Build Coastguard Worker void AcceptConnection(const Candidate& remote_candidate) {
309*d9f75844SAndroid Build Coastguard Worker if (conn_) {
310*d9f75844SAndroid Build Coastguard Worker conn_->SignalDestroyed.disconnect(this);
311*d9f75844SAndroid Build Coastguard Worker conn_ = nullptr;
312*d9f75844SAndroid Build Coastguard Worker }
313*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(remote_request_.get() != NULL);
314*d9f75844SAndroid Build Coastguard Worker Candidate c = remote_candidate;
315*d9f75844SAndroid Build Coastguard Worker c.set_address(remote_address_);
316*d9f75844SAndroid Build Coastguard Worker conn_ = port_->CreateConnection(c, Port::ORIGIN_MESSAGE);
317*d9f75844SAndroid Build Coastguard Worker conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
318*d9f75844SAndroid Build Coastguard Worker conn_->SendStunBindingResponse(remote_request_.get());
319*d9f75844SAndroid Build Coastguard Worker remote_request_.reset();
320*d9f75844SAndroid Build Coastguard Worker }
Ping()321*d9f75844SAndroid Build Coastguard Worker void Ping() { Ping(0); }
Ping(int64_t now)322*d9f75844SAndroid Build Coastguard Worker void Ping(int64_t now) { conn_->Ping(now); }
Stop()323*d9f75844SAndroid Build Coastguard Worker void Stop() {
324*d9f75844SAndroid Build Coastguard Worker if (conn_) {
325*d9f75844SAndroid Build Coastguard Worker port_->DestroyConnection(conn_);
326*d9f75844SAndroid Build Coastguard Worker conn_ = nullptr;
327*d9f75844SAndroid Build Coastguard Worker }
328*d9f75844SAndroid Build Coastguard Worker }
329*d9f75844SAndroid Build Coastguard Worker
OnPortComplete(Port * port)330*d9f75844SAndroid Build Coastguard Worker void OnPortComplete(Port* port) { complete_count_++; }
SetIceMode(IceMode ice_mode)331*d9f75844SAndroid Build Coastguard Worker void SetIceMode(IceMode ice_mode) { ice_mode_ = ice_mode; }
332*d9f75844SAndroid Build Coastguard Worker
SendData(const char * data,size_t len)333*d9f75844SAndroid Build Coastguard Worker int SendData(const char* data, size_t len) {
334*d9f75844SAndroid Build Coastguard Worker rtc::PacketOptions options;
335*d9f75844SAndroid Build Coastguard Worker return conn_->Send(data, len, options);
336*d9f75844SAndroid Build Coastguard Worker }
337*d9f75844SAndroid Build Coastguard Worker
OnUnknownAddress(PortInterface * port,const SocketAddress & addr,ProtocolType proto,IceMessage * msg,const std::string & rf,bool)338*d9f75844SAndroid Build Coastguard Worker void OnUnknownAddress(PortInterface* port,
339*d9f75844SAndroid Build Coastguard Worker const SocketAddress& addr,
340*d9f75844SAndroid Build Coastguard Worker ProtocolType proto,
341*d9f75844SAndroid Build Coastguard Worker IceMessage* msg,
342*d9f75844SAndroid Build Coastguard Worker const std::string& rf,
343*d9f75844SAndroid Build Coastguard Worker bool /*port_muxed*/) {
344*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(port_.get(), port);
345*d9f75844SAndroid Build Coastguard Worker if (!remote_address_.IsNil()) {
346*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(remote_address_, addr);
347*d9f75844SAndroid Build Coastguard Worker }
348*d9f75844SAndroid Build Coastguard Worker const cricket::StunUInt32Attribute* priority_attr =
349*d9f75844SAndroid Build Coastguard Worker msg->GetUInt32(STUN_ATTR_PRIORITY);
350*d9f75844SAndroid Build Coastguard Worker const cricket::StunByteStringAttribute* mi_attr =
351*d9f75844SAndroid Build Coastguard Worker msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
352*d9f75844SAndroid Build Coastguard Worker const cricket::StunUInt32Attribute* fingerprint_attr =
353*d9f75844SAndroid Build Coastguard Worker msg->GetUInt32(STUN_ATTR_FINGERPRINT);
354*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(priority_attr != NULL);
355*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(mi_attr != NULL);
356*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(fingerprint_attr != NULL);
357*d9f75844SAndroid Build Coastguard Worker remote_address_ = addr;
358*d9f75844SAndroid Build Coastguard Worker remote_request_ = CopyStunMessage(*msg);
359*d9f75844SAndroid Build Coastguard Worker remote_frag_ = rf;
360*d9f75844SAndroid Build Coastguard Worker }
361*d9f75844SAndroid Build Coastguard Worker
OnDestroyed(Connection * conn)362*d9f75844SAndroid Build Coastguard Worker void OnDestroyed(Connection* conn) {
363*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(conn_, conn);
364*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "OnDestroy connection " << conn << " deleted";
365*d9f75844SAndroid Build Coastguard Worker conn_ = nullptr;
366*d9f75844SAndroid Build Coastguard Worker // When the connection is destroyed, also clear these fields so future
367*d9f75844SAndroid Build Coastguard Worker // connections are possible.
368*d9f75844SAndroid Build Coastguard Worker remote_request_.reset();
369*d9f75844SAndroid Build Coastguard Worker remote_address_.Clear();
370*d9f75844SAndroid Build Coastguard Worker }
371*d9f75844SAndroid Build Coastguard Worker
OnSrcPortDestroyed(PortInterface * port)372*d9f75844SAndroid Build Coastguard Worker void OnSrcPortDestroyed(PortInterface* port) {
373*d9f75844SAndroid Build Coastguard Worker Port* destroyed_src = port_.release();
374*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(destroyed_src, port);
375*d9f75844SAndroid Build Coastguard Worker }
376*d9f75844SAndroid Build Coastguard Worker
port()377*d9f75844SAndroid Build Coastguard Worker Port* port() { return port_.get(); }
378*d9f75844SAndroid Build Coastguard Worker
nominated() const379*d9f75844SAndroid Build Coastguard Worker bool nominated() const { return nominated_; }
380*d9f75844SAndroid Build Coastguard Worker
set_connection_ready_to_send(bool ready)381*d9f75844SAndroid Build Coastguard Worker void set_connection_ready_to_send(bool ready) {
382*d9f75844SAndroid Build Coastguard Worker connection_ready_to_send_ = ready;
383*d9f75844SAndroid Build Coastguard Worker }
connection_ready_to_send() const384*d9f75844SAndroid Build Coastguard Worker bool connection_ready_to_send() const { return connection_ready_to_send_; }
385*d9f75844SAndroid Build Coastguard Worker
386*d9f75844SAndroid Build Coastguard Worker private:
387*d9f75844SAndroid Build Coastguard Worker // ReadyToSend will only issue after a Connection recovers from ENOTCONN
OnConnectionReadyToSend(Connection * conn)388*d9f75844SAndroid Build Coastguard Worker void OnConnectionReadyToSend(Connection* conn) {
389*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(conn, conn_);
390*d9f75844SAndroid Build Coastguard Worker connection_ready_to_send_ = true;
391*d9f75844SAndroid Build Coastguard Worker }
392*d9f75844SAndroid Build Coastguard Worker
393*d9f75844SAndroid Build Coastguard Worker IceMode ice_mode_ = ICEMODE_FULL;
394*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> port_;
395*d9f75844SAndroid Build Coastguard Worker
396*d9f75844SAndroid Build Coastguard Worker int complete_count_ = 0;
397*d9f75844SAndroid Build Coastguard Worker Connection* conn_ = nullptr;
398*d9f75844SAndroid Build Coastguard Worker SocketAddress remote_address_;
399*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<StunMessage> remote_request_;
400*d9f75844SAndroid Build Coastguard Worker std::string remote_frag_;
401*d9f75844SAndroid Build Coastguard Worker bool nominated_ = false;
402*d9f75844SAndroid Build Coastguard Worker bool connection_ready_to_send_ = false;
403*d9f75844SAndroid Build Coastguard Worker };
404*d9f75844SAndroid Build Coastguard Worker
405*d9f75844SAndroid Build Coastguard Worker class PortTest : public ::testing::Test, public sigslot::has_slots<> {
406*d9f75844SAndroid Build Coastguard Worker public:
PortTest()407*d9f75844SAndroid Build Coastguard Worker PortTest()
408*d9f75844SAndroid Build Coastguard Worker : ss_(new rtc::VirtualSocketServer()),
409*d9f75844SAndroid Build Coastguard Worker main_(ss_.get()),
410*d9f75844SAndroid Build Coastguard Worker socket_factory_(ss_.get()),
411*d9f75844SAndroid Build Coastguard Worker nat_factory1_(ss_.get(), kNatAddr1, SocketAddress()),
412*d9f75844SAndroid Build Coastguard Worker nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
413*d9f75844SAndroid Build Coastguard Worker nat_socket_factory1_(&nat_factory1_),
414*d9f75844SAndroid Build Coastguard Worker nat_socket_factory2_(&nat_factory2_),
415*d9f75844SAndroid Build Coastguard Worker stun_server_(TestStunServer::Create(ss_.get(), kStunAddr)),
416*d9f75844SAndroid Build Coastguard Worker turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
417*d9f75844SAndroid Build Coastguard Worker username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
418*d9f75844SAndroid Build Coastguard Worker password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
419*d9f75844SAndroid Build Coastguard Worker role_conflict_(false),
420*d9f75844SAndroid Build Coastguard Worker ports_destroyed_(0) {}
421*d9f75844SAndroid Build Coastguard Worker
~PortTest()422*d9f75844SAndroid Build Coastguard Worker ~PortTest() {
423*d9f75844SAndroid Build Coastguard Worker // Workaround for tests that trigger async destruction of objects that we
424*d9f75844SAndroid Build Coastguard Worker // need to give an opportunity here to run, before proceeding with other
425*d9f75844SAndroid Build Coastguard Worker // teardown.
426*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(0);
427*d9f75844SAndroid Build Coastguard Worker }
428*d9f75844SAndroid Build Coastguard Worker
429*d9f75844SAndroid Build Coastguard Worker protected:
password()430*d9f75844SAndroid Build Coastguard Worker std::string password() { return password_; }
431*d9f75844SAndroid Build Coastguard Worker
TestLocalToLocal()432*d9f75844SAndroid Build Coastguard Worker void TestLocalToLocal() {
433*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
434*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
435*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
436*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
437*d9f75844SAndroid Build Coastguard Worker TestConnectivity("udp", std::move(port1), "udp", std::move(port2), true,
438*d9f75844SAndroid Build Coastguard Worker true, true, true);
439*d9f75844SAndroid Build Coastguard Worker }
TestLocalToStun(NATType ntype)440*d9f75844SAndroid Build Coastguard Worker void TestLocalToStun(NATType ntype) {
441*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
442*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
443*d9f75844SAndroid Build Coastguard Worker nat_server2_ = CreateNatServer(kNatAddr2, ntype);
444*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
445*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
446*d9f75844SAndroid Build Coastguard Worker TestConnectivity("udp", std::move(port1), StunName(ntype), std::move(port2),
447*d9f75844SAndroid Build Coastguard Worker ntype == NAT_OPEN_CONE, true, ntype != NAT_SYMMETRIC,
448*d9f75844SAndroid Build Coastguard Worker true);
449*d9f75844SAndroid Build Coastguard Worker }
TestLocalToRelay(ProtocolType proto)450*d9f75844SAndroid Build Coastguard Worker void TestLocalToRelay(ProtocolType proto) {
451*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
452*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
453*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
454*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
455*d9f75844SAndroid Build Coastguard Worker TestConnectivity("udp", std::move(port1), RelayName(proto),
456*d9f75844SAndroid Build Coastguard Worker std::move(port2), false, true, true, true);
457*d9f75844SAndroid Build Coastguard Worker }
TestStunToLocal(NATType ntype)458*d9f75844SAndroid Build Coastguard Worker void TestStunToLocal(NATType ntype) {
459*d9f75844SAndroid Build Coastguard Worker nat_server1_ = CreateNatServer(kNatAddr1, ntype);
460*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
461*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
462*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
463*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
464*d9f75844SAndroid Build Coastguard Worker TestConnectivity(StunName(ntype), std::move(port1), "udp", std::move(port2),
465*d9f75844SAndroid Build Coastguard Worker true, ntype != NAT_SYMMETRIC, true, true);
466*d9f75844SAndroid Build Coastguard Worker }
TestStunToStun(NATType ntype1,NATType ntype2)467*d9f75844SAndroid Build Coastguard Worker void TestStunToStun(NATType ntype1, NATType ntype2) {
468*d9f75844SAndroid Build Coastguard Worker nat_server1_ = CreateNatServer(kNatAddr1, ntype1);
469*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
470*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
471*d9f75844SAndroid Build Coastguard Worker nat_server2_ = CreateNatServer(kNatAddr2, ntype2);
472*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
473*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
474*d9f75844SAndroid Build Coastguard Worker TestConnectivity(StunName(ntype1), std::move(port1), StunName(ntype2),
475*d9f75844SAndroid Build Coastguard Worker std::move(port2), ntype2 == NAT_OPEN_CONE,
476*d9f75844SAndroid Build Coastguard Worker ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
477*d9f75844SAndroid Build Coastguard Worker ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
478*d9f75844SAndroid Build Coastguard Worker }
TestStunToRelay(NATType ntype,ProtocolType proto)479*d9f75844SAndroid Build Coastguard Worker void TestStunToRelay(NATType ntype, ProtocolType proto) {
480*d9f75844SAndroid Build Coastguard Worker nat_server1_ = CreateNatServer(kNatAddr1, ntype);
481*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
482*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
483*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
484*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
485*d9f75844SAndroid Build Coastguard Worker TestConnectivity(StunName(ntype), std::move(port1), RelayName(proto),
486*d9f75844SAndroid Build Coastguard Worker std::move(port2), false, ntype != NAT_SYMMETRIC, true,
487*d9f75844SAndroid Build Coastguard Worker true);
488*d9f75844SAndroid Build Coastguard Worker }
TestTcpToTcp()489*d9f75844SAndroid Build Coastguard Worker void TestTcpToTcp() {
490*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
491*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
492*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTcpPort(kLocalAddr2);
493*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
494*d9f75844SAndroid Build Coastguard Worker TestConnectivity("tcp", std::move(port1), "tcp", std::move(port2), true,
495*d9f75844SAndroid Build Coastguard Worker false, true, true);
496*d9f75844SAndroid Build Coastguard Worker }
TestTcpToRelay(ProtocolType proto)497*d9f75844SAndroid Build Coastguard Worker void TestTcpToRelay(ProtocolType proto) {
498*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
499*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
500*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_TCP);
501*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
502*d9f75844SAndroid Build Coastguard Worker TestConnectivity("tcp", std::move(port1), RelayName(proto),
503*d9f75844SAndroid Build Coastguard Worker std::move(port2), false, false, true, true);
504*d9f75844SAndroid Build Coastguard Worker }
TestSslTcpToRelay(ProtocolType proto)505*d9f75844SAndroid Build Coastguard Worker void TestSslTcpToRelay(ProtocolType proto) {
506*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
507*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
508*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_SSLTCP);
509*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
510*d9f75844SAndroid Build Coastguard Worker TestConnectivity("ssltcp", std::move(port1), RelayName(proto),
511*d9f75844SAndroid Build Coastguard Worker std::move(port2), false, false, true, true);
512*d9f75844SAndroid Build Coastguard Worker }
513*d9f75844SAndroid Build Coastguard Worker
MakeNetwork(const SocketAddress & addr)514*d9f75844SAndroid Build Coastguard Worker rtc::Network* MakeNetwork(const SocketAddress& addr) {
515*d9f75844SAndroid Build Coastguard Worker networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
516*d9f75844SAndroid Build Coastguard Worker networks_.back().AddIP(addr.ipaddr());
517*d9f75844SAndroid Build Coastguard Worker return &networks_.back();
518*d9f75844SAndroid Build Coastguard Worker }
519*d9f75844SAndroid Build Coastguard Worker
MakeNetworkMultipleAddrs(const SocketAddress & global_addr,const SocketAddress & link_local_addr,const webrtc::FieldTrialsView * field_trials)520*d9f75844SAndroid Build Coastguard Worker rtc::Network* MakeNetworkMultipleAddrs(
521*d9f75844SAndroid Build Coastguard Worker const SocketAddress& global_addr,
522*d9f75844SAndroid Build Coastguard Worker const SocketAddress& link_local_addr,
523*d9f75844SAndroid Build Coastguard Worker const webrtc::FieldTrialsView* field_trials) {
524*d9f75844SAndroid Build Coastguard Worker networks_.emplace_back("unittest", "unittest", global_addr.ipaddr(), 32,
525*d9f75844SAndroid Build Coastguard Worker rtc::ADAPTER_TYPE_UNKNOWN, field_trials);
526*d9f75844SAndroid Build Coastguard Worker networks_.back().AddIP(link_local_addr.ipaddr());
527*d9f75844SAndroid Build Coastguard Worker networks_.back().AddIP(global_addr.ipaddr());
528*d9f75844SAndroid Build Coastguard Worker networks_.back().AddIP(link_local_addr.ipaddr());
529*d9f75844SAndroid Build Coastguard Worker return &networks_.back();
530*d9f75844SAndroid Build Coastguard Worker }
531*d9f75844SAndroid Build Coastguard Worker
532*d9f75844SAndroid Build Coastguard Worker // helpers for above functions
CreateUdpPort(const SocketAddress & addr)533*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<UDPPort> CreateUdpPort(const SocketAddress& addr) {
534*d9f75844SAndroid Build Coastguard Worker return CreateUdpPort(addr, &socket_factory_);
535*d9f75844SAndroid Build Coastguard Worker }
CreateUdpPort(const SocketAddress & addr,PacketSocketFactory * socket_factory)536*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<UDPPort> CreateUdpPort(const SocketAddress& addr,
537*d9f75844SAndroid Build Coastguard Worker PacketSocketFactory* socket_factory) {
538*d9f75844SAndroid Build Coastguard Worker auto port = UDPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
539*d9f75844SAndroid Build Coastguard Worker username_, password_, true, absl::nullopt,
540*d9f75844SAndroid Build Coastguard Worker &field_trials_);
541*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
542*d9f75844SAndroid Build Coastguard Worker return port;
543*d9f75844SAndroid Build Coastguard Worker }
544*d9f75844SAndroid Build Coastguard Worker
CreateUdpPortMultipleAddrs(const SocketAddress & global_addr,const SocketAddress & link_local_addr,PacketSocketFactory * socket_factory,const webrtc::test::ScopedKeyValueConfig & field_trials)545*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<UDPPort> CreateUdpPortMultipleAddrs(
546*d9f75844SAndroid Build Coastguard Worker const SocketAddress& global_addr,
547*d9f75844SAndroid Build Coastguard Worker const SocketAddress& link_local_addr,
548*d9f75844SAndroid Build Coastguard Worker PacketSocketFactory* socket_factory,
549*d9f75844SAndroid Build Coastguard Worker const webrtc::test::ScopedKeyValueConfig& field_trials) {
550*d9f75844SAndroid Build Coastguard Worker auto port = UDPPort::Create(
551*d9f75844SAndroid Build Coastguard Worker &main_, socket_factory,
552*d9f75844SAndroid Build Coastguard Worker MakeNetworkMultipleAddrs(global_addr, link_local_addr, &field_trials),
553*d9f75844SAndroid Build Coastguard Worker 0, 0, username_, password_, true, absl::nullopt, &field_trials);
554*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
555*d9f75844SAndroid Build Coastguard Worker return port;
556*d9f75844SAndroid Build Coastguard Worker }
CreateTcpPort(const SocketAddress & addr)557*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TCPPort> CreateTcpPort(const SocketAddress& addr) {
558*d9f75844SAndroid Build Coastguard Worker return CreateTcpPort(addr, &socket_factory_);
559*d9f75844SAndroid Build Coastguard Worker }
CreateTcpPort(const SocketAddress & addr,PacketSocketFactory * socket_factory)560*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TCPPort> CreateTcpPort(const SocketAddress& addr,
561*d9f75844SAndroid Build Coastguard Worker PacketSocketFactory* socket_factory) {
562*d9f75844SAndroid Build Coastguard Worker auto port = TCPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
563*d9f75844SAndroid Build Coastguard Worker username_, password_, true, &field_trials_);
564*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
565*d9f75844SAndroid Build Coastguard Worker return port;
566*d9f75844SAndroid Build Coastguard Worker }
CreateStunPort(const SocketAddress & addr,rtc::PacketSocketFactory * factory)567*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<StunPort> CreateStunPort(const SocketAddress& addr,
568*d9f75844SAndroid Build Coastguard Worker rtc::PacketSocketFactory* factory) {
569*d9f75844SAndroid Build Coastguard Worker ServerAddresses stun_servers;
570*d9f75844SAndroid Build Coastguard Worker stun_servers.insert(kStunAddr);
571*d9f75844SAndroid Build Coastguard Worker auto port = StunPort::Create(&main_, factory, MakeNetwork(addr), 0, 0,
572*d9f75844SAndroid Build Coastguard Worker username_, password_, stun_servers,
573*d9f75844SAndroid Build Coastguard Worker absl::nullopt, &field_trials_);
574*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
575*d9f75844SAndroid Build Coastguard Worker return port;
576*d9f75844SAndroid Build Coastguard Worker }
CreateRelayPort(const SocketAddress & addr,ProtocolType int_proto,ProtocolType ext_proto)577*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> CreateRelayPort(const SocketAddress& addr,
578*d9f75844SAndroid Build Coastguard Worker ProtocolType int_proto,
579*d9f75844SAndroid Build Coastguard Worker ProtocolType ext_proto) {
580*d9f75844SAndroid Build Coastguard Worker return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
581*d9f75844SAndroid Build Coastguard Worker }
CreateTurnPort(const SocketAddress & addr,PacketSocketFactory * socket_factory,ProtocolType int_proto,ProtocolType ext_proto)582*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TurnPort> CreateTurnPort(const SocketAddress& addr,
583*d9f75844SAndroid Build Coastguard Worker PacketSocketFactory* socket_factory,
584*d9f75844SAndroid Build Coastguard Worker ProtocolType int_proto,
585*d9f75844SAndroid Build Coastguard Worker ProtocolType ext_proto) {
586*d9f75844SAndroid Build Coastguard Worker SocketAddress server_addr =
587*d9f75844SAndroid Build Coastguard Worker int_proto == PROTO_TCP ? kTurnTcpIntAddr : kTurnUdpIntAddr;
588*d9f75844SAndroid Build Coastguard Worker return CreateTurnPort(addr, socket_factory, int_proto, ext_proto,
589*d9f75844SAndroid Build Coastguard Worker server_addr);
590*d9f75844SAndroid Build Coastguard Worker }
CreateTurnPort(const SocketAddress & addr,PacketSocketFactory * socket_factory,ProtocolType int_proto,ProtocolType ext_proto,const rtc::SocketAddress & server_addr)591*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TurnPort> CreateTurnPort(
592*d9f75844SAndroid Build Coastguard Worker const SocketAddress& addr,
593*d9f75844SAndroid Build Coastguard Worker PacketSocketFactory* socket_factory,
594*d9f75844SAndroid Build Coastguard Worker ProtocolType int_proto,
595*d9f75844SAndroid Build Coastguard Worker ProtocolType ext_proto,
596*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress& server_addr) {
597*d9f75844SAndroid Build Coastguard Worker RelayServerConfig config;
598*d9f75844SAndroid Build Coastguard Worker config.credentials = kRelayCredentials;
599*d9f75844SAndroid Build Coastguard Worker ProtocolAddress server_address(server_addr, int_proto);
600*d9f75844SAndroid Build Coastguard Worker CreateRelayPortArgs args;
601*d9f75844SAndroid Build Coastguard Worker args.network_thread = &main_;
602*d9f75844SAndroid Build Coastguard Worker args.socket_factory = socket_factory;
603*d9f75844SAndroid Build Coastguard Worker args.network = MakeNetwork(addr);
604*d9f75844SAndroid Build Coastguard Worker args.username = username_;
605*d9f75844SAndroid Build Coastguard Worker args.password = password_;
606*d9f75844SAndroid Build Coastguard Worker args.server_address = &server_address;
607*d9f75844SAndroid Build Coastguard Worker args.config = &config;
608*d9f75844SAndroid Build Coastguard Worker args.field_trials = &field_trials_;
609*d9f75844SAndroid Build Coastguard Worker
610*d9f75844SAndroid Build Coastguard Worker auto port = TurnPort::Create(args, 0, 0);
611*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
612*d9f75844SAndroid Build Coastguard Worker return port;
613*d9f75844SAndroid Build Coastguard Worker }
614*d9f75844SAndroid Build Coastguard Worker
CreateNatServer(const SocketAddress & addr,rtc::NATType type)615*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::NATServer> CreateNatServer(const SocketAddress& addr,
616*d9f75844SAndroid Build Coastguard Worker rtc::NATType type) {
617*d9f75844SAndroid Build Coastguard Worker return std::make_unique<rtc::NATServer>(type, ss_.get(), addr, addr,
618*d9f75844SAndroid Build Coastguard Worker ss_.get(), addr);
619*d9f75844SAndroid Build Coastguard Worker }
StunName(NATType type)620*d9f75844SAndroid Build Coastguard Worker static const char* StunName(NATType type) {
621*d9f75844SAndroid Build Coastguard Worker switch (type) {
622*d9f75844SAndroid Build Coastguard Worker case NAT_OPEN_CONE:
623*d9f75844SAndroid Build Coastguard Worker return "stun(open cone)";
624*d9f75844SAndroid Build Coastguard Worker case NAT_ADDR_RESTRICTED:
625*d9f75844SAndroid Build Coastguard Worker return "stun(addr restricted)";
626*d9f75844SAndroid Build Coastguard Worker case NAT_PORT_RESTRICTED:
627*d9f75844SAndroid Build Coastguard Worker return "stun(port restricted)";
628*d9f75844SAndroid Build Coastguard Worker case NAT_SYMMETRIC:
629*d9f75844SAndroid Build Coastguard Worker return "stun(symmetric)";
630*d9f75844SAndroid Build Coastguard Worker default:
631*d9f75844SAndroid Build Coastguard Worker return "stun(?)";
632*d9f75844SAndroid Build Coastguard Worker }
633*d9f75844SAndroid Build Coastguard Worker }
RelayName(ProtocolType proto)634*d9f75844SAndroid Build Coastguard Worker static const char* RelayName(ProtocolType proto) {
635*d9f75844SAndroid Build Coastguard Worker switch (proto) {
636*d9f75844SAndroid Build Coastguard Worker case PROTO_UDP:
637*d9f75844SAndroid Build Coastguard Worker return "turn(udp)";
638*d9f75844SAndroid Build Coastguard Worker case PROTO_TCP:
639*d9f75844SAndroid Build Coastguard Worker return "turn(tcp)";
640*d9f75844SAndroid Build Coastguard Worker case PROTO_SSLTCP:
641*d9f75844SAndroid Build Coastguard Worker return "turn(ssltcp)";
642*d9f75844SAndroid Build Coastguard Worker case PROTO_TLS:
643*d9f75844SAndroid Build Coastguard Worker return "turn(tls)";
644*d9f75844SAndroid Build Coastguard Worker default:
645*d9f75844SAndroid Build Coastguard Worker return "turn(?)";
646*d9f75844SAndroid Build Coastguard Worker }
647*d9f75844SAndroid Build Coastguard Worker }
648*d9f75844SAndroid Build Coastguard Worker
649*d9f75844SAndroid Build Coastguard Worker void TestCrossFamilyPorts(int type);
650*d9f75844SAndroid Build Coastguard Worker
651*d9f75844SAndroid Build Coastguard Worker void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2);
652*d9f75844SAndroid Build Coastguard Worker
653*d9f75844SAndroid Build Coastguard Worker // This does all the work and then deletes `port1` and `port2`.
654*d9f75844SAndroid Build Coastguard Worker void TestConnectivity(absl::string_view name1,
655*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> port1,
656*d9f75844SAndroid Build Coastguard Worker absl::string_view name2,
657*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> port2,
658*d9f75844SAndroid Build Coastguard Worker bool accept,
659*d9f75844SAndroid Build Coastguard Worker bool same_addr1,
660*d9f75844SAndroid Build Coastguard Worker bool same_addr2,
661*d9f75844SAndroid Build Coastguard Worker bool possible);
662*d9f75844SAndroid Build Coastguard Worker
663*d9f75844SAndroid Build Coastguard Worker // This connects the provided channels which have already started. `ch1`
664*d9f75844SAndroid Build Coastguard Worker // should have its Connection created (either through CreateConnection() or
665*d9f75844SAndroid Build Coastguard Worker // TCP reconnecting mechanism before entering this function.
ConnectStartedChannels(TestChannel * ch1,TestChannel * ch2)666*d9f75844SAndroid Build Coastguard Worker void ConnectStartedChannels(TestChannel* ch1, TestChannel* ch2) {
667*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1->conn());
668*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1->conn()->connected(),
669*d9f75844SAndroid Build Coastguard Worker kDefaultTimeout); // for TCP connect
670*d9f75844SAndroid Build Coastguard Worker ch1->Ping();
671*d9f75844SAndroid Build Coastguard Worker WAIT(!ch2->remote_address().IsNil(), kShortTimeout);
672*d9f75844SAndroid Build Coastguard Worker
673*d9f75844SAndroid Build Coastguard Worker // Send a ping from dst to src.
674*d9f75844SAndroid Build Coastguard Worker ch2->AcceptConnection(GetCandidate(ch1->port()));
675*d9f75844SAndroid Build Coastguard Worker ch2->Ping();
676*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
677*d9f75844SAndroid Build Coastguard Worker kDefaultTimeout);
678*d9f75844SAndroid Build Coastguard Worker }
679*d9f75844SAndroid Build Coastguard Worker
680*d9f75844SAndroid Build Coastguard Worker // This connects and disconnects the provided channels in the same sequence as
681*d9f75844SAndroid Build Coastguard Worker // TestConnectivity with all options set to `true`. It does not delete either
682*d9f75844SAndroid Build Coastguard Worker // channel.
StartConnectAndStopChannels(TestChannel * ch1,TestChannel * ch2)683*d9f75844SAndroid Build Coastguard Worker void StartConnectAndStopChannels(TestChannel* ch1, TestChannel* ch2) {
684*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
685*d9f75844SAndroid Build Coastguard Worker ch1->Start();
686*d9f75844SAndroid Build Coastguard Worker ch2->Start();
687*d9f75844SAndroid Build Coastguard Worker
688*d9f75844SAndroid Build Coastguard Worker ch1->CreateConnection(GetCandidate(ch2->port()));
689*d9f75844SAndroid Build Coastguard Worker ConnectStartedChannels(ch1, ch2);
690*d9f75844SAndroid Build Coastguard Worker
691*d9f75844SAndroid Build Coastguard Worker // Destroy the connections.
692*d9f75844SAndroid Build Coastguard Worker ch1->Stop();
693*d9f75844SAndroid Build Coastguard Worker ch2->Stop();
694*d9f75844SAndroid Build Coastguard Worker }
695*d9f75844SAndroid Build Coastguard Worker
696*d9f75844SAndroid Build Coastguard Worker // This disconnects both end's Connection and make sure ch2 ready for new
697*d9f75844SAndroid Build Coastguard Worker // connection.
DisconnectTcpTestChannels(TestChannel * ch1,TestChannel * ch2)698*d9f75844SAndroid Build Coastguard Worker void DisconnectTcpTestChannels(TestChannel* ch1, TestChannel* ch2) {
699*d9f75844SAndroid Build Coastguard Worker TCPConnection* tcp_conn1 = static_cast<TCPConnection*>(ch1->conn());
700*d9f75844SAndroid Build Coastguard Worker TCPConnection* tcp_conn2 = static_cast<TCPConnection*>(ch2->conn());
701*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(
702*d9f75844SAndroid Build Coastguard Worker ss_->CloseTcpConnections(tcp_conn1->socket()->GetLocalAddress(),
703*d9f75844SAndroid Build Coastguard Worker tcp_conn2->socket()->GetLocalAddress()));
704*d9f75844SAndroid Build Coastguard Worker
705*d9f75844SAndroid Build Coastguard Worker // Wait for both OnClose are delivered.
706*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(!ch1->conn()->connected(), kDefaultTimeout);
707*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(!ch2->conn()->connected(), kDefaultTimeout);
708*d9f75844SAndroid Build Coastguard Worker
709*d9f75844SAndroid Build Coastguard Worker // Ensure redundant SignalClose events on TcpConnection won't break tcp
710*d9f75844SAndroid Build Coastguard Worker // reconnection. Chromium will fire SignalClose for all outstanding IPC
711*d9f75844SAndroid Build Coastguard Worker // packets during reconnection.
712*d9f75844SAndroid Build Coastguard Worker tcp_conn1->socket()->NotifyClosedForTest(0);
713*d9f75844SAndroid Build Coastguard Worker tcp_conn2->socket()->NotifyClosedForTest(0);
714*d9f75844SAndroid Build Coastguard Worker
715*d9f75844SAndroid Build Coastguard Worker // Speed up destroying ch2's connection such that the test is ready to
716*d9f75844SAndroid Build Coastguard Worker // accept a new connection from ch1 before ch1's connection destroys itself.
717*d9f75844SAndroid Build Coastguard Worker ch2->Stop();
718*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch2->conn() == NULL, kDefaultTimeout);
719*d9f75844SAndroid Build Coastguard Worker }
720*d9f75844SAndroid Build Coastguard Worker
TestTcpReconnect(bool ping_after_disconnected,bool send_after_disconnected)721*d9f75844SAndroid Build Coastguard Worker void TestTcpReconnect(bool ping_after_disconnected,
722*d9f75844SAndroid Build Coastguard Worker bool send_after_disconnected) {
723*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
724*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
725*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTcpPort(kLocalAddr2);
726*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
727*d9f75844SAndroid Build Coastguard Worker
728*d9f75844SAndroid Build Coastguard Worker port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
729*d9f75844SAndroid Build Coastguard Worker port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
730*d9f75844SAndroid Build Coastguard Worker
731*d9f75844SAndroid Build Coastguard Worker // Set up channels and ensure both ports will be deleted.
732*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
733*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
734*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ch1.complete_count());
735*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ch2.complete_count());
736*d9f75844SAndroid Build Coastguard Worker
737*d9f75844SAndroid Build Coastguard Worker ch1.Start();
738*d9f75844SAndroid Build Coastguard Worker ch2.Start();
739*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
740*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
741*d9f75844SAndroid Build Coastguard Worker
742*d9f75844SAndroid Build Coastguard Worker // Initial connecting the channel, create connection on channel1.
743*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
744*d9f75844SAndroid Build Coastguard Worker ConnectStartedChannels(&ch1, &ch2);
745*d9f75844SAndroid Build Coastguard Worker
746*d9f75844SAndroid Build Coastguard Worker // Shorten the timeout period.
747*d9f75844SAndroid Build Coastguard Worker const int kTcpReconnectTimeout = kDefaultTimeout;
748*d9f75844SAndroid Build Coastguard Worker static_cast<TCPConnection*>(ch1.conn())
749*d9f75844SAndroid Build Coastguard Worker ->set_reconnection_timeout(kTcpReconnectTimeout);
750*d9f75844SAndroid Build Coastguard Worker static_cast<TCPConnection*>(ch2.conn())
751*d9f75844SAndroid Build Coastguard Worker ->set_reconnection_timeout(kTcpReconnectTimeout);
752*d9f75844SAndroid Build Coastguard Worker
753*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch1.connection_ready_to_send());
754*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch2.connection_ready_to_send());
755*d9f75844SAndroid Build Coastguard Worker
756*d9f75844SAndroid Build Coastguard Worker // Once connected, disconnect them.
757*d9f75844SAndroid Build Coastguard Worker DisconnectTcpTestChannels(&ch1, &ch2);
758*d9f75844SAndroid Build Coastguard Worker
759*d9f75844SAndroid Build Coastguard Worker if (send_after_disconnected || ping_after_disconnected) {
760*d9f75844SAndroid Build Coastguard Worker if (send_after_disconnected) {
761*d9f75844SAndroid Build Coastguard Worker // First SendData after disconnect should fail but will trigger
762*d9f75844SAndroid Build Coastguard Worker // reconnect.
763*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, ch1.SendData(data, static_cast<int>(strlen(data))));
764*d9f75844SAndroid Build Coastguard Worker }
765*d9f75844SAndroid Build Coastguard Worker
766*d9f75844SAndroid Build Coastguard Worker if (ping_after_disconnected) {
767*d9f75844SAndroid Build Coastguard Worker // Ping should trigger reconnect.
768*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
769*d9f75844SAndroid Build Coastguard Worker }
770*d9f75844SAndroid Build Coastguard Worker
771*d9f75844SAndroid Build Coastguard Worker // Wait for channel's outgoing TCPConnection connected.
772*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn()->connected(), kDefaultTimeout);
773*d9f75844SAndroid Build Coastguard Worker
774*d9f75844SAndroid Build Coastguard Worker // Verify that we could still connect channels.
775*d9f75844SAndroid Build Coastguard Worker ConnectStartedChannels(&ch1, &ch2);
776*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(), kTcpReconnectTimeout);
777*d9f75844SAndroid Build Coastguard Worker // Channel2 is the passive one so a new connection is created during
778*d9f75844SAndroid Build Coastguard Worker // reconnect. This new connection should never have issued ENOTCONN
779*d9f75844SAndroid Build Coastguard Worker // hence the connection_ready_to_send() should be false.
780*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch2.connection_ready_to_send());
781*d9f75844SAndroid Build Coastguard Worker } else {
782*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(ch1.conn()->write_state(), Connection::STATE_WRITABLE);
783*d9f75844SAndroid Build Coastguard Worker // Since the reconnection never happens, the connections should have been
784*d9f75844SAndroid Build Coastguard Worker // destroyed after the timeout.
785*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(!ch1.conn(), kTcpReconnectTimeout + kDefaultTimeout);
786*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(!ch2.conn());
787*d9f75844SAndroid Build Coastguard Worker }
788*d9f75844SAndroid Build Coastguard Worker
789*d9f75844SAndroid Build Coastguard Worker // Tear down and ensure that goes smoothly.
790*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
791*d9f75844SAndroid Build Coastguard Worker ch2.Stop();
792*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn() == NULL, kDefaultTimeout);
793*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch2.conn() == NULL, kDefaultTimeout);
794*d9f75844SAndroid Build Coastguard Worker }
795*d9f75844SAndroid Build Coastguard Worker
CreateStunMessage(StunMessageType type)796*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> CreateStunMessage(StunMessageType type) {
797*d9f75844SAndroid Build Coastguard Worker auto msg = std::make_unique<IceMessage>(type, "TESTTESTTEST");
798*d9f75844SAndroid Build Coastguard Worker return msg;
799*d9f75844SAndroid Build Coastguard Worker }
CreateStunMessageWithUsername(StunMessageType type,absl::string_view username)800*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> CreateStunMessageWithUsername(
801*d9f75844SAndroid Build Coastguard Worker StunMessageType type,
802*d9f75844SAndroid Build Coastguard Worker absl::string_view username) {
803*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> msg = CreateStunMessage(type);
804*d9f75844SAndroid Build Coastguard Worker msg->AddAttribute(std::make_unique<StunByteStringAttribute>(
805*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_USERNAME, std::string(username)));
806*d9f75844SAndroid Build Coastguard Worker return msg;
807*d9f75844SAndroid Build Coastguard Worker }
CreateTestPort(const rtc::SocketAddress & addr,absl::string_view username,absl::string_view password)808*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> CreateTestPort(const rtc::SocketAddress& addr,
809*d9f75844SAndroid Build Coastguard Worker absl::string_view username,
810*d9f75844SAndroid Build Coastguard Worker absl::string_view password) {
811*d9f75844SAndroid Build Coastguard Worker auto port =
812*d9f75844SAndroid Build Coastguard Worker std::make_unique<TestPort>(&main_, "test", &socket_factory_,
813*d9f75844SAndroid Build Coastguard Worker MakeNetwork(addr), 0, 0, username, password);
814*d9f75844SAndroid Build Coastguard Worker port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
815*d9f75844SAndroid Build Coastguard Worker return port;
816*d9f75844SAndroid Build Coastguard Worker }
CreateTestPort(const rtc::SocketAddress & addr,absl::string_view username,absl::string_view password,cricket::IceRole role,int tiebreaker)817*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> CreateTestPort(const rtc::SocketAddress& addr,
818*d9f75844SAndroid Build Coastguard Worker absl::string_view username,
819*d9f75844SAndroid Build Coastguard Worker absl::string_view password,
820*d9f75844SAndroid Build Coastguard Worker cricket::IceRole role,
821*d9f75844SAndroid Build Coastguard Worker int tiebreaker) {
822*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(addr, username, password);
823*d9f75844SAndroid Build Coastguard Worker port->SetIceRole(role);
824*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(tiebreaker);
825*d9f75844SAndroid Build Coastguard Worker return port;
826*d9f75844SAndroid Build Coastguard Worker }
827*d9f75844SAndroid Build Coastguard Worker // Overload to create a test port given an rtc::Network directly.
CreateTestPort(const rtc::Network * network,absl::string_view username,absl::string_view password)828*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> CreateTestPort(const rtc::Network* network,
829*d9f75844SAndroid Build Coastguard Worker absl::string_view username,
830*d9f75844SAndroid Build Coastguard Worker absl::string_view password) {
831*d9f75844SAndroid Build Coastguard Worker auto port = std::make_unique<TestPort>(&main_, "test", &socket_factory_,
832*d9f75844SAndroid Build Coastguard Worker network, 0, 0, username, password);
833*d9f75844SAndroid Build Coastguard Worker port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
834*d9f75844SAndroid Build Coastguard Worker return port;
835*d9f75844SAndroid Build Coastguard Worker }
836*d9f75844SAndroid Build Coastguard Worker
OnRoleConflict(PortInterface * port)837*d9f75844SAndroid Build Coastguard Worker void OnRoleConflict(PortInterface* port) { role_conflict_ = true; }
role_conflict() const838*d9f75844SAndroid Build Coastguard Worker bool role_conflict() const { return role_conflict_; }
839*d9f75844SAndroid Build Coastguard Worker
ConnectToSignalDestroyed(PortInterface * port)840*d9f75844SAndroid Build Coastguard Worker void ConnectToSignalDestroyed(PortInterface* port) {
841*d9f75844SAndroid Build Coastguard Worker port->SubscribePortDestroyed(
842*d9f75844SAndroid Build Coastguard Worker [this](PortInterface* port) { OnDestroyed(port); });
843*d9f75844SAndroid Build Coastguard Worker }
844*d9f75844SAndroid Build Coastguard Worker
OnDestroyed(PortInterface * port)845*d9f75844SAndroid Build Coastguard Worker void OnDestroyed(PortInterface* port) { ++ports_destroyed_; }
ports_destroyed() const846*d9f75844SAndroid Build Coastguard Worker int ports_destroyed() const { return ports_destroyed_; }
847*d9f75844SAndroid Build Coastguard Worker
nat_socket_factory1()848*d9f75844SAndroid Build Coastguard Worker rtc::BasicPacketSocketFactory* nat_socket_factory1() {
849*d9f75844SAndroid Build Coastguard Worker return &nat_socket_factory1_;
850*d9f75844SAndroid Build Coastguard Worker }
851*d9f75844SAndroid Build Coastguard Worker
vss()852*d9f75844SAndroid Build Coastguard Worker rtc::VirtualSocketServer* vss() { return ss_.get(); }
853*d9f75844SAndroid Build Coastguard Worker
854*d9f75844SAndroid Build Coastguard Worker private:
855*d9f75844SAndroid Build Coastguard Worker // When a "create port" helper method is called with an IP, we create a
856*d9f75844SAndroid Build Coastguard Worker // Network with that IP and add it to this list. Using a list instead of a
857*d9f75844SAndroid Build Coastguard Worker // vector so that when it grows, pointers aren't invalidated.
858*d9f75844SAndroid Build Coastguard Worker std::list<rtc::Network> networks_;
859*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::VirtualSocketServer> ss_;
860*d9f75844SAndroid Build Coastguard Worker rtc::AutoSocketServerThread main_;
861*d9f75844SAndroid Build Coastguard Worker rtc::BasicPacketSocketFactory socket_factory_;
862*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::NATServer> nat_server1_;
863*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::NATServer> nat_server2_;
864*d9f75844SAndroid Build Coastguard Worker rtc::NATSocketFactory nat_factory1_;
865*d9f75844SAndroid Build Coastguard Worker rtc::NATSocketFactory nat_factory2_;
866*d9f75844SAndroid Build Coastguard Worker rtc::BasicPacketSocketFactory nat_socket_factory1_;
867*d9f75844SAndroid Build Coastguard Worker rtc::BasicPacketSocketFactory nat_socket_factory2_;
868*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestStunServer> stun_server_;
869*d9f75844SAndroid Build Coastguard Worker TestTurnServer turn_server_;
870*d9f75844SAndroid Build Coastguard Worker std::string username_;
871*d9f75844SAndroid Build Coastguard Worker std::string password_;
872*d9f75844SAndroid Build Coastguard Worker bool role_conflict_;
873*d9f75844SAndroid Build Coastguard Worker int ports_destroyed_;
874*d9f75844SAndroid Build Coastguard Worker webrtc::test::ScopedKeyValueConfig field_trials_;
875*d9f75844SAndroid Build Coastguard Worker };
876*d9f75844SAndroid Build Coastguard Worker
TestConnectivity(absl::string_view name1,std::unique_ptr<Port> port1,absl::string_view name2,std::unique_ptr<Port> port2,bool accept,bool same_addr1,bool same_addr2,bool possible)877*d9f75844SAndroid Build Coastguard Worker void PortTest::TestConnectivity(absl::string_view name1,
878*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> port1,
879*d9f75844SAndroid Build Coastguard Worker absl::string_view name2,
880*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> port2,
881*d9f75844SAndroid Build Coastguard Worker bool accept,
882*d9f75844SAndroid Build Coastguard Worker bool same_addr1,
883*d9f75844SAndroid Build Coastguard Worker bool same_addr2,
884*d9f75844SAndroid Build Coastguard Worker bool possible) {
885*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
886*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
887*d9f75844SAndroid Build Coastguard Worker port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
888*d9f75844SAndroid Build Coastguard Worker port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
889*d9f75844SAndroid Build Coastguard Worker
890*d9f75844SAndroid Build Coastguard Worker // Set up channels and ensure both ports will be deleted.
891*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
892*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
893*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ch1.complete_count());
894*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ch2.complete_count());
895*d9f75844SAndroid Build Coastguard Worker
896*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
897*d9f75844SAndroid Build Coastguard Worker ch1.Start();
898*d9f75844SAndroid Build Coastguard Worker ch2.Start();
899*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
900*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
901*d9f75844SAndroid Build Coastguard Worker
902*d9f75844SAndroid Build Coastguard Worker // Send a ping from src to dst. This may or may not make it.
903*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
904*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
905*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout,
906*d9f75844SAndroid Build Coastguard Worker clock); // for TCP connect
907*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
908*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
909*d9f75844SAndroid Build Coastguard Worker
910*d9f75844SAndroid Build Coastguard Worker if (accept) {
911*d9f75844SAndroid Build Coastguard Worker // We are able to send a ping from src to dst. This is the case when
912*d9f75844SAndroid Build Coastguard Worker // sending to UDP ports and cone NATs.
913*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
914*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(ch2.remote_fragment(), ch1.port()->username_fragment());
915*d9f75844SAndroid Build Coastguard Worker
916*d9f75844SAndroid Build Coastguard Worker // Ensure the ping came from the same address used for src.
917*d9f75844SAndroid Build Coastguard Worker // This is the case unless the source NAT was symmetric.
918*d9f75844SAndroid Build Coastguard Worker if (same_addr1)
919*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(ch2.remote_address(), GetAddress(ch1.port()));
920*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(same_addr2);
921*d9f75844SAndroid Build Coastguard Worker
922*d9f75844SAndroid Build Coastguard Worker // Send a ping from dst to src.
923*d9f75844SAndroid Build Coastguard Worker ch2.AcceptConnection(GetCandidate(ch1.port()));
924*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch2.conn() != NULL);
925*d9f75844SAndroid Build Coastguard Worker ch2.Ping();
926*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
927*d9f75844SAndroid Build Coastguard Worker ch2.conn()->write_state(), kDefaultTimeout, clock);
928*d9f75844SAndroid Build Coastguard Worker } else {
929*d9f75844SAndroid Build Coastguard Worker // We can't send a ping from src to dst, so flip it around. This will happen
930*d9f75844SAndroid Build Coastguard Worker // when the destination NAT is addr/port restricted or symmetric.
931*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
932*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch2.remote_address().IsNil());
933*d9f75844SAndroid Build Coastguard Worker
934*d9f75844SAndroid Build Coastguard Worker // Send a ping from dst to src. Again, this may or may not make it.
935*d9f75844SAndroid Build Coastguard Worker ch2.CreateConnection(GetCandidate(ch1.port()));
936*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch2.conn() != NULL);
937*d9f75844SAndroid Build Coastguard Worker ch2.Ping();
938*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE,
939*d9f75844SAndroid Build Coastguard Worker kShortTimeout, clock);
940*d9f75844SAndroid Build Coastguard Worker
941*d9f75844SAndroid Build Coastguard Worker if (same_addr1 && same_addr2) {
942*d9f75844SAndroid Build Coastguard Worker // The new ping got back to the source.
943*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn()->receiving());
944*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
945*d9f75844SAndroid Build Coastguard Worker
946*d9f75844SAndroid Build Coastguard Worker // First connection may not be writable if the first ping did not get
947*d9f75844SAndroid Build Coastguard Worker // through. So we will have to do another.
948*d9f75844SAndroid Build Coastguard Worker if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
949*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
950*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
951*d9f75844SAndroid Build Coastguard Worker ch1.conn()->write_state(), kDefaultTimeout,
952*d9f75844SAndroid Build Coastguard Worker clock);
953*d9f75844SAndroid Build Coastguard Worker }
954*d9f75844SAndroid Build Coastguard Worker } else if (!same_addr1 && possible) {
955*d9f75844SAndroid Build Coastguard Worker // The new ping went to the candidate address, but that address was bad.
956*d9f75844SAndroid Build Coastguard Worker // This will happen when the source NAT is symmetric.
957*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
958*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch2.remote_address().IsNil());
959*d9f75844SAndroid Build Coastguard Worker
960*d9f75844SAndroid Build Coastguard Worker // However, since we have now sent a ping to the source IP, we should be
961*d9f75844SAndroid Build Coastguard Worker // able to get a ping from it. This gives us the real source address.
962*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
963*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(!ch2.remote_address().IsNil(), kDefaultTimeout,
964*d9f75844SAndroid Build Coastguard Worker clock);
965*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch2.conn()->receiving());
966*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
967*d9f75844SAndroid Build Coastguard Worker
968*d9f75844SAndroid Build Coastguard Worker // Pick up the actual address and establish the connection.
969*d9f75844SAndroid Build Coastguard Worker ch2.AcceptConnection(GetCandidate(ch1.port()));
970*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch2.conn() != NULL);
971*d9f75844SAndroid Build Coastguard Worker ch2.Ping();
972*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
973*d9f75844SAndroid Build Coastguard Worker ch2.conn()->write_state(), kDefaultTimeout,
974*d9f75844SAndroid Build Coastguard Worker clock);
975*d9f75844SAndroid Build Coastguard Worker } else if (!same_addr2 && possible) {
976*d9f75844SAndroid Build Coastguard Worker // The new ping came in, but from an unexpected address. This will happen
977*d9f75844SAndroid Build Coastguard Worker // when the destination NAT is symmetric.
978*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch1.remote_address().IsNil());
979*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch1.conn()->receiving());
980*d9f75844SAndroid Build Coastguard Worker
981*d9f75844SAndroid Build Coastguard Worker // Update our address and complete the connection.
982*d9f75844SAndroid Build Coastguard Worker ch1.AcceptConnection(GetCandidate(ch2.port()));
983*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
984*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
985*d9f75844SAndroid Build Coastguard Worker ch1.conn()->write_state(), kDefaultTimeout,
986*d9f75844SAndroid Build Coastguard Worker clock);
987*d9f75844SAndroid Build Coastguard Worker } else { // (!possible)
988*d9f75844SAndroid Build Coastguard Worker // There should be s no way for the pings to reach each other. Check it.
989*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
990*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch2.remote_address().IsNil());
991*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
992*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
993*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.remote_address().IsNil());
994*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch2.remote_address().IsNil());
995*d9f75844SAndroid Build Coastguard Worker }
996*d9f75844SAndroid Build Coastguard Worker }
997*d9f75844SAndroid Build Coastguard Worker
998*d9f75844SAndroid Build Coastguard Worker // Everything should be good, unless we know the situation is impossible.
999*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
1000*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch2.conn() != NULL);
1001*d9f75844SAndroid Build Coastguard Worker if (possible) {
1002*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn()->receiving());
1003*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
1004*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch2.conn()->receiving());
1005*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
1006*d9f75844SAndroid Build Coastguard Worker } else {
1007*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch1.conn()->receiving());
1008*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
1009*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(ch2.conn()->receiving());
1010*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
1011*d9f75844SAndroid Build Coastguard Worker }
1012*d9f75844SAndroid Build Coastguard Worker
1013*d9f75844SAndroid Build Coastguard Worker // Tear down and ensure that goes smoothly.
1014*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
1015*d9f75844SAndroid Build Coastguard Worker ch2.Stop();
1016*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ch1.conn() == NULL, kDefaultTimeout, clock);
1017*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ch2.conn() == NULL, kDefaultTimeout, clock);
1018*d9f75844SAndroid Build Coastguard Worker }
1019*d9f75844SAndroid Build Coastguard Worker
1020*d9f75844SAndroid Build Coastguard Worker class FakePacketSocketFactory : public rtc::PacketSocketFactory {
1021*d9f75844SAndroid Build Coastguard Worker public:
FakePacketSocketFactory()1022*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory()
1023*d9f75844SAndroid Build Coastguard Worker : next_udp_socket_(NULL), next_server_tcp_socket_(NULL) {}
~FakePacketSocketFactory()1024*d9f75844SAndroid Build Coastguard Worker ~FakePacketSocketFactory() override {}
1025*d9f75844SAndroid Build Coastguard Worker
CreateUdpSocket(const SocketAddress & address,uint16_t min_port,uint16_t max_port)1026*d9f75844SAndroid Build Coastguard Worker AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
1027*d9f75844SAndroid Build Coastguard Worker uint16_t min_port,
1028*d9f75844SAndroid Build Coastguard Worker uint16_t max_port) override {
1029*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(next_udp_socket_ != NULL);
1030*d9f75844SAndroid Build Coastguard Worker AsyncPacketSocket* result = next_udp_socket_;
1031*d9f75844SAndroid Build Coastguard Worker next_udp_socket_ = NULL;
1032*d9f75844SAndroid Build Coastguard Worker return result;
1033*d9f75844SAndroid Build Coastguard Worker }
1034*d9f75844SAndroid Build Coastguard Worker
CreateServerTcpSocket(const SocketAddress & local_address,uint16_t min_port,uint16_t max_port,int opts)1035*d9f75844SAndroid Build Coastguard Worker AsyncListenSocket* CreateServerTcpSocket(const SocketAddress& local_address,
1036*d9f75844SAndroid Build Coastguard Worker uint16_t min_port,
1037*d9f75844SAndroid Build Coastguard Worker uint16_t max_port,
1038*d9f75844SAndroid Build Coastguard Worker int opts) override {
1039*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(next_server_tcp_socket_ != NULL);
1040*d9f75844SAndroid Build Coastguard Worker AsyncListenSocket* result = next_server_tcp_socket_;
1041*d9f75844SAndroid Build Coastguard Worker next_server_tcp_socket_ = NULL;
1042*d9f75844SAndroid Build Coastguard Worker return result;
1043*d9f75844SAndroid Build Coastguard Worker }
1044*d9f75844SAndroid Build Coastguard Worker
CreateClientTcpSocket(const SocketAddress & local_address,const SocketAddress & remote_address,const rtc::ProxyInfo & proxy_info,const std::string & user_agent,const rtc::PacketSocketTcpOptions & opts)1045*d9f75844SAndroid Build Coastguard Worker AsyncPacketSocket* CreateClientTcpSocket(
1046*d9f75844SAndroid Build Coastguard Worker const SocketAddress& local_address,
1047*d9f75844SAndroid Build Coastguard Worker const SocketAddress& remote_address,
1048*d9f75844SAndroid Build Coastguard Worker const rtc::ProxyInfo& proxy_info,
1049*d9f75844SAndroid Build Coastguard Worker const std::string& user_agent,
1050*d9f75844SAndroid Build Coastguard Worker const rtc::PacketSocketTcpOptions& opts) override {
1051*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(next_client_tcp_socket_.has_value());
1052*d9f75844SAndroid Build Coastguard Worker AsyncPacketSocket* result = *next_client_tcp_socket_;
1053*d9f75844SAndroid Build Coastguard Worker next_client_tcp_socket_ = nullptr;
1054*d9f75844SAndroid Build Coastguard Worker return result;
1055*d9f75844SAndroid Build Coastguard Worker }
1056*d9f75844SAndroid Build Coastguard Worker
set_next_udp_socket(AsyncPacketSocket * next_udp_socket)1057*d9f75844SAndroid Build Coastguard Worker void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
1058*d9f75844SAndroid Build Coastguard Worker next_udp_socket_ = next_udp_socket;
1059*d9f75844SAndroid Build Coastguard Worker }
set_next_server_tcp_socket(AsyncListenSocket * next_server_tcp_socket)1060*d9f75844SAndroid Build Coastguard Worker void set_next_server_tcp_socket(AsyncListenSocket* next_server_tcp_socket) {
1061*d9f75844SAndroid Build Coastguard Worker next_server_tcp_socket_ = next_server_tcp_socket;
1062*d9f75844SAndroid Build Coastguard Worker }
set_next_client_tcp_socket(AsyncPacketSocket * next_client_tcp_socket)1063*d9f75844SAndroid Build Coastguard Worker void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
1064*d9f75844SAndroid Build Coastguard Worker next_client_tcp_socket_ = next_client_tcp_socket;
1065*d9f75844SAndroid Build Coastguard Worker }
CreateAsyncDnsResolver()1066*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAsyncDnsResolver()
1067*d9f75844SAndroid Build Coastguard Worker override {
1068*d9f75844SAndroid Build Coastguard Worker return nullptr;
1069*d9f75844SAndroid Build Coastguard Worker }
1070*d9f75844SAndroid Build Coastguard Worker
1071*d9f75844SAndroid Build Coastguard Worker private:
1072*d9f75844SAndroid Build Coastguard Worker AsyncPacketSocket* next_udp_socket_;
1073*d9f75844SAndroid Build Coastguard Worker AsyncListenSocket* next_server_tcp_socket_;
1074*d9f75844SAndroid Build Coastguard Worker absl::optional<AsyncPacketSocket*> next_client_tcp_socket_;
1075*d9f75844SAndroid Build Coastguard Worker };
1076*d9f75844SAndroid Build Coastguard Worker
1077*d9f75844SAndroid Build Coastguard Worker class FakeAsyncPacketSocket : public AsyncPacketSocket {
1078*d9f75844SAndroid Build Coastguard Worker public:
1079*d9f75844SAndroid Build Coastguard Worker // Returns current local address. Address may be set to NULL if the
1080*d9f75844SAndroid Build Coastguard Worker // socket is not bound yet (GetState() returns STATE_BINDING).
GetLocalAddress() const1081*d9f75844SAndroid Build Coastguard Worker virtual SocketAddress GetLocalAddress() const { return local_address_; }
1082*d9f75844SAndroid Build Coastguard Worker
1083*d9f75844SAndroid Build Coastguard Worker // Returns remote address. Returns zeroes if this is not a client TCP socket.
GetRemoteAddress() const1084*d9f75844SAndroid Build Coastguard Worker virtual SocketAddress GetRemoteAddress() const { return remote_address_; }
1085*d9f75844SAndroid Build Coastguard Worker
1086*d9f75844SAndroid Build Coastguard Worker // Send a packet.
Send(const void * pv,size_t cb,const rtc::PacketOptions & options)1087*d9f75844SAndroid Build Coastguard Worker virtual int Send(const void* pv,
1088*d9f75844SAndroid Build Coastguard Worker size_t cb,
1089*d9f75844SAndroid Build Coastguard Worker const rtc::PacketOptions& options) {
1090*d9f75844SAndroid Build Coastguard Worker if (error_ == 0) {
1091*d9f75844SAndroid Build Coastguard Worker return static_cast<int>(cb);
1092*d9f75844SAndroid Build Coastguard Worker } else {
1093*d9f75844SAndroid Build Coastguard Worker return -1;
1094*d9f75844SAndroid Build Coastguard Worker }
1095*d9f75844SAndroid Build Coastguard Worker }
SendTo(const void * pv,size_t cb,const SocketAddress & addr,const rtc::PacketOptions & options)1096*d9f75844SAndroid Build Coastguard Worker virtual int SendTo(const void* pv,
1097*d9f75844SAndroid Build Coastguard Worker size_t cb,
1098*d9f75844SAndroid Build Coastguard Worker const SocketAddress& addr,
1099*d9f75844SAndroid Build Coastguard Worker const rtc::PacketOptions& options) {
1100*d9f75844SAndroid Build Coastguard Worker if (error_ == 0) {
1101*d9f75844SAndroid Build Coastguard Worker return static_cast<int>(cb);
1102*d9f75844SAndroid Build Coastguard Worker } else {
1103*d9f75844SAndroid Build Coastguard Worker return -1;
1104*d9f75844SAndroid Build Coastguard Worker }
1105*d9f75844SAndroid Build Coastguard Worker }
Close()1106*d9f75844SAndroid Build Coastguard Worker virtual int Close() { return 0; }
1107*d9f75844SAndroid Build Coastguard Worker
GetState() const1108*d9f75844SAndroid Build Coastguard Worker virtual State GetState() const { return state_; }
GetOption(Socket::Option opt,int * value)1109*d9f75844SAndroid Build Coastguard Worker virtual int GetOption(Socket::Option opt, int* value) { return 0; }
SetOption(Socket::Option opt,int value)1110*d9f75844SAndroid Build Coastguard Worker virtual int SetOption(Socket::Option opt, int value) { return 0; }
GetError() const1111*d9f75844SAndroid Build Coastguard Worker virtual int GetError() const { return 0; }
SetError(int error)1112*d9f75844SAndroid Build Coastguard Worker virtual void SetError(int error) { error_ = error; }
1113*d9f75844SAndroid Build Coastguard Worker
set_state(State state)1114*d9f75844SAndroid Build Coastguard Worker void set_state(State state) { state_ = state; }
1115*d9f75844SAndroid Build Coastguard Worker
1116*d9f75844SAndroid Build Coastguard Worker SocketAddress local_address_;
1117*d9f75844SAndroid Build Coastguard Worker SocketAddress remote_address_;
1118*d9f75844SAndroid Build Coastguard Worker
1119*d9f75844SAndroid Build Coastguard Worker private:
1120*d9f75844SAndroid Build Coastguard Worker int error_ = 0;
1121*d9f75844SAndroid Build Coastguard Worker State state_;
1122*d9f75844SAndroid Build Coastguard Worker };
1123*d9f75844SAndroid Build Coastguard Worker
1124*d9f75844SAndroid Build Coastguard Worker class FakeAsyncListenSocket : public AsyncListenSocket {
1125*d9f75844SAndroid Build Coastguard Worker public:
1126*d9f75844SAndroid Build Coastguard Worker // Returns current local address. Address may be set to NULL if the
1127*d9f75844SAndroid Build Coastguard Worker // socket is not bound yet (GetState() returns STATE_BINDING).
GetLocalAddress() const1128*d9f75844SAndroid Build Coastguard Worker virtual SocketAddress GetLocalAddress() const { return local_address_; }
Bind(const SocketAddress & address)1129*d9f75844SAndroid Build Coastguard Worker void Bind(const SocketAddress& address) {
1130*d9f75844SAndroid Build Coastguard Worker local_address_ = address;
1131*d9f75844SAndroid Build Coastguard Worker state_ = State::kBound;
1132*d9f75844SAndroid Build Coastguard Worker }
GetOption(Socket::Option opt,int * value)1133*d9f75844SAndroid Build Coastguard Worker virtual int GetOption(Socket::Option opt, int* value) { return 0; }
SetOption(Socket::Option opt,int value)1134*d9f75844SAndroid Build Coastguard Worker virtual int SetOption(Socket::Option opt, int value) { return 0; }
GetState() const1135*d9f75844SAndroid Build Coastguard Worker virtual State GetState() const { return state_; }
1136*d9f75844SAndroid Build Coastguard Worker
1137*d9f75844SAndroid Build Coastguard Worker private:
1138*d9f75844SAndroid Build Coastguard Worker SocketAddress local_address_;
1139*d9f75844SAndroid Build Coastguard Worker State state_ = State::kClosed;
1140*d9f75844SAndroid Build Coastguard Worker };
1141*d9f75844SAndroid Build Coastguard Worker
1142*d9f75844SAndroid Build Coastguard Worker // Local -> XXXX
TEST_F(PortTest,TestLocalToLocal)1143*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToLocal) {
1144*d9f75844SAndroid Build Coastguard Worker TestLocalToLocal();
1145*d9f75844SAndroid Build Coastguard Worker }
1146*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestLocalToConeNat)1147*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToConeNat) {
1148*d9f75844SAndroid Build Coastguard Worker TestLocalToStun(NAT_OPEN_CONE);
1149*d9f75844SAndroid Build Coastguard Worker }
1150*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestLocalToARNat)1151*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToARNat) {
1152*d9f75844SAndroid Build Coastguard Worker TestLocalToStun(NAT_ADDR_RESTRICTED);
1153*d9f75844SAndroid Build Coastguard Worker }
1154*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestLocalToPRNat)1155*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToPRNat) {
1156*d9f75844SAndroid Build Coastguard Worker TestLocalToStun(NAT_PORT_RESTRICTED);
1157*d9f75844SAndroid Build Coastguard Worker }
1158*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestLocalToSymNat)1159*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToSymNat) {
1160*d9f75844SAndroid Build Coastguard Worker TestLocalToStun(NAT_SYMMETRIC);
1161*d9f75844SAndroid Build Coastguard Worker }
1162*d9f75844SAndroid Build Coastguard Worker
1163*d9f75844SAndroid Build Coastguard Worker // Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
TEST_F(PortTest,DISABLED_TestLocalToTurn)1164*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, DISABLED_TestLocalToTurn) {
1165*d9f75844SAndroid Build Coastguard Worker TestLocalToRelay(PROTO_UDP);
1166*d9f75844SAndroid Build Coastguard Worker }
1167*d9f75844SAndroid Build Coastguard Worker
1168*d9f75844SAndroid Build Coastguard Worker // Cone NAT -> XXXX
TEST_F(PortTest,TestConeNatToLocal)1169*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToLocal) {
1170*d9f75844SAndroid Build Coastguard Worker TestStunToLocal(NAT_OPEN_CONE);
1171*d9f75844SAndroid Build Coastguard Worker }
1172*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConeNatToConeNat)1173*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToConeNat) {
1174*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
1175*d9f75844SAndroid Build Coastguard Worker }
1176*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConeNatToARNat)1177*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToARNat) {
1178*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
1179*d9f75844SAndroid Build Coastguard Worker }
1180*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConeNatToPRNat)1181*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToPRNat) {
1182*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
1183*d9f75844SAndroid Build Coastguard Worker }
1184*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConeNatToSymNat)1185*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToSymNat) {
1186*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
1187*d9f75844SAndroid Build Coastguard Worker }
1188*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConeNatToTurn)1189*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConeNatToTurn) {
1190*d9f75844SAndroid Build Coastguard Worker TestStunToRelay(NAT_OPEN_CONE, PROTO_UDP);
1191*d9f75844SAndroid Build Coastguard Worker }
1192*d9f75844SAndroid Build Coastguard Worker
1193*d9f75844SAndroid Build Coastguard Worker // Address-restricted NAT -> XXXX
TEST_F(PortTest,TestARNatToLocal)1194*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToLocal) {
1195*d9f75844SAndroid Build Coastguard Worker TestStunToLocal(NAT_ADDR_RESTRICTED);
1196*d9f75844SAndroid Build Coastguard Worker }
1197*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestARNatToConeNat)1198*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToConeNat) {
1199*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
1200*d9f75844SAndroid Build Coastguard Worker }
1201*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestARNatToARNat)1202*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToARNat) {
1203*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
1204*d9f75844SAndroid Build Coastguard Worker }
1205*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestARNatToPRNat)1206*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToPRNat) {
1207*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
1208*d9f75844SAndroid Build Coastguard Worker }
1209*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestARNatToSymNat)1210*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToSymNat) {
1211*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
1212*d9f75844SAndroid Build Coastguard Worker }
1213*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestARNatToTurn)1214*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestARNatToTurn) {
1215*d9f75844SAndroid Build Coastguard Worker TestStunToRelay(NAT_ADDR_RESTRICTED, PROTO_UDP);
1216*d9f75844SAndroid Build Coastguard Worker }
1217*d9f75844SAndroid Build Coastguard Worker
1218*d9f75844SAndroid Build Coastguard Worker // Port-restricted NAT -> XXXX
TEST_F(PortTest,TestPRNatToLocal)1219*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToLocal) {
1220*d9f75844SAndroid Build Coastguard Worker TestStunToLocal(NAT_PORT_RESTRICTED);
1221*d9f75844SAndroid Build Coastguard Worker }
1222*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestPRNatToConeNat)1223*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToConeNat) {
1224*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
1225*d9f75844SAndroid Build Coastguard Worker }
1226*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestPRNatToARNat)1227*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToARNat) {
1228*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
1229*d9f75844SAndroid Build Coastguard Worker }
1230*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestPRNatToPRNat)1231*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToPRNat) {
1232*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
1233*d9f75844SAndroid Build Coastguard Worker }
1234*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestPRNatToSymNat)1235*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToSymNat) {
1236*d9f75844SAndroid Build Coastguard Worker // Will "fail"
1237*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1238*d9f75844SAndroid Build Coastguard Worker }
1239*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestPRNatToTurn)1240*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPRNatToTurn) {
1241*d9f75844SAndroid Build Coastguard Worker TestStunToRelay(NAT_PORT_RESTRICTED, PROTO_UDP);
1242*d9f75844SAndroid Build Coastguard Worker }
1243*d9f75844SAndroid Build Coastguard Worker
1244*d9f75844SAndroid Build Coastguard Worker // Symmetric NAT -> XXXX
TEST_F(PortTest,TestSymNatToLocal)1245*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToLocal) {
1246*d9f75844SAndroid Build Coastguard Worker TestStunToLocal(NAT_SYMMETRIC);
1247*d9f75844SAndroid Build Coastguard Worker }
1248*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSymNatToConeNat)1249*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToConeNat) {
1250*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1251*d9f75844SAndroid Build Coastguard Worker }
1252*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSymNatToARNat)1253*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToARNat) {
1254*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1255*d9f75844SAndroid Build Coastguard Worker }
1256*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSymNatToPRNat)1257*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToPRNat) {
1258*d9f75844SAndroid Build Coastguard Worker // Will "fail"
1259*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1260*d9f75844SAndroid Build Coastguard Worker }
1261*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSymNatToSymNat)1262*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToSymNat) {
1263*d9f75844SAndroid Build Coastguard Worker // Will "fail"
1264*d9f75844SAndroid Build Coastguard Worker TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1265*d9f75844SAndroid Build Coastguard Worker }
1266*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSymNatToTurn)1267*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSymNatToTurn) {
1268*d9f75844SAndroid Build Coastguard Worker TestStunToRelay(NAT_SYMMETRIC, PROTO_UDP);
1269*d9f75844SAndroid Build Coastguard Worker }
1270*d9f75844SAndroid Build Coastguard Worker
1271*d9f75844SAndroid Build Coastguard Worker // Outbound TCP -> XXXX
TEST_F(PortTest,TestTcpToTcp)1272*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpToTcp) {
1273*d9f75844SAndroid Build Coastguard Worker TestTcpToTcp();
1274*d9f75844SAndroid Build Coastguard Worker }
1275*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestTcpReconnectOnSendPacket)1276*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpReconnectOnSendPacket) {
1277*d9f75844SAndroid Build Coastguard Worker TestTcpReconnect(false /* ping */, true /* send */);
1278*d9f75844SAndroid Build Coastguard Worker }
1279*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestTcpReconnectOnPing)1280*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpReconnectOnPing) {
1281*d9f75844SAndroid Build Coastguard Worker TestTcpReconnect(true /* ping */, false /* send */);
1282*d9f75844SAndroid Build Coastguard Worker }
1283*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestTcpReconnectTimeout)1284*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpReconnectTimeout) {
1285*d9f75844SAndroid Build Coastguard Worker TestTcpReconnect(false /* ping */, false /* send */);
1286*d9f75844SAndroid Build Coastguard Worker }
1287*d9f75844SAndroid Build Coastguard Worker
1288*d9f75844SAndroid Build Coastguard Worker // Test when TcpConnection never connects, the OnClose() will be called to
1289*d9f75844SAndroid Build Coastguard Worker // destroy the connection.
TEST_F(PortTest,TestTcpNeverConnect)1290*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpNeverConnect) {
1291*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
1292*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1293*d9f75844SAndroid Build Coastguard Worker port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
1294*d9f75844SAndroid Build Coastguard Worker
1295*d9f75844SAndroid Build Coastguard Worker // Set up a channel and ensure the port will be deleted.
1296*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
1297*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ch1.complete_count());
1298*d9f75844SAndroid Build Coastguard Worker
1299*d9f75844SAndroid Build Coastguard Worker ch1.Start();
1300*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1301*d9f75844SAndroid Build Coastguard Worker
1302*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::Socket> server(
1303*d9f75844SAndroid Build Coastguard Worker vss()->CreateSocket(kLocalAddr2.family(), SOCK_STREAM));
1304*d9f75844SAndroid Build Coastguard Worker // Bind but not listen.
1305*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, server->Bind(kLocalAddr2));
1306*d9f75844SAndroid Build Coastguard Worker
1307*d9f75844SAndroid Build Coastguard Worker Candidate c = GetCandidate(ch1.port());
1308*d9f75844SAndroid Build Coastguard Worker c.set_address(server->GetLocalAddress());
1309*d9f75844SAndroid Build Coastguard Worker
1310*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(c);
1311*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn());
1312*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(!ch1.conn(), kDefaultTimeout); // for TCP connect
1313*d9f75844SAndroid Build Coastguard Worker }
1314*d9f75844SAndroid Build Coastguard Worker
1315*d9f75844SAndroid Build Coastguard Worker /* TODO(?): Enable these once testrelayserver can accept external TCP.
1316*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpToTcpRelay) {
1317*d9f75844SAndroid Build Coastguard Worker TestTcpToRelay(PROTO_TCP);
1318*d9f75844SAndroid Build Coastguard Worker }
1319*d9f75844SAndroid Build Coastguard Worker
1320*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpToSslTcpRelay) {
1321*d9f75844SAndroid Build Coastguard Worker TestTcpToRelay(PROTO_SSLTCP);
1322*d9f75844SAndroid Build Coastguard Worker }
1323*d9f75844SAndroid Build Coastguard Worker */
1324*d9f75844SAndroid Build Coastguard Worker
1325*d9f75844SAndroid Build Coastguard Worker // Outbound SSLTCP -> XXXX
1326*d9f75844SAndroid Build Coastguard Worker /* TODO(?): Enable these once testrelayserver can accept external SSL.
1327*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSslTcpToTcpRelay) {
1328*d9f75844SAndroid Build Coastguard Worker TestSslTcpToRelay(PROTO_TCP);
1329*d9f75844SAndroid Build Coastguard Worker }
1330*d9f75844SAndroid Build Coastguard Worker
1331*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1332*d9f75844SAndroid Build Coastguard Worker TestSslTcpToRelay(PROTO_SSLTCP);
1333*d9f75844SAndroid Build Coastguard Worker }
1334*d9f75844SAndroid Build Coastguard Worker */
1335*d9f75844SAndroid Build Coastguard Worker
1336*d9f75844SAndroid Build Coastguard Worker // Test that a connection will be dead and deleted if
1337*d9f75844SAndroid Build Coastguard Worker // i) it has never received anything for MIN_CONNECTION_LIFETIME milliseconds
1338*d9f75844SAndroid Build Coastguard Worker // since it was created, or
1339*d9f75844SAndroid Build Coastguard Worker // ii) it has not received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT
1340*d9f75844SAndroid Build Coastguard Worker // milliseconds since last receiving.
TEST_F(PortTest,TestConnectionDead)1341*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConnectionDead) {
1342*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(CreateUdpPort(kLocalAddr1));
1343*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(CreateUdpPort(kLocalAddr2));
1344*d9f75844SAndroid Build Coastguard Worker // Acquire address.
1345*d9f75844SAndroid Build Coastguard Worker ch1.Start();
1346*d9f75844SAndroid Build Coastguard Worker ch2.Start();
1347*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1348*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
1349*d9f75844SAndroid Build Coastguard Worker
1350*d9f75844SAndroid Build Coastguard Worker // Test case that the connection has never received anything.
1351*d9f75844SAndroid Build Coastguard Worker int64_t before_created = rtc::TimeMillis();
1352*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
1353*d9f75844SAndroid Build Coastguard Worker int64_t after_created = rtc::TimeMillis();
1354*d9f75844SAndroid Build Coastguard Worker Connection* conn = ch1.conn();
1355*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(conn, nullptr);
1356*d9f75844SAndroid Build Coastguard Worker // It is not dead if it is after MIN_CONNECTION_LIFETIME but not pruned.
1357*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
1358*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(0);
1359*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn() != nullptr);
1360*d9f75844SAndroid Build Coastguard Worker // It is not dead if it is before MIN_CONNECTION_LIFETIME and pruned.
1361*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(before_created + MIN_CONNECTION_LIFETIME - 1);
1362*d9f75844SAndroid Build Coastguard Worker conn->Prune();
1363*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(0);
1364*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn() != nullptr);
1365*d9f75844SAndroid Build Coastguard Worker // It will be dead after MIN_CONNECTION_LIFETIME and pruned.
1366*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
1367*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
1368*d9f75844SAndroid Build Coastguard Worker
1369*d9f75844SAndroid Build Coastguard Worker // Test case that the connection has received something.
1370*d9f75844SAndroid Build Coastguard Worker // Create a connection again and receive a ping.
1371*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
1372*d9f75844SAndroid Build Coastguard Worker conn = ch1.conn();
1373*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(conn, nullptr);
1374*d9f75844SAndroid Build Coastguard Worker int64_t before_last_receiving = rtc::TimeMillis();
1375*d9f75844SAndroid Build Coastguard Worker conn->ReceivedPing();
1376*d9f75844SAndroid Build Coastguard Worker int64_t after_last_receiving = rtc::TimeMillis();
1377*d9f75844SAndroid Build Coastguard Worker // The connection will be dead after DEAD_CONNECTION_RECEIVE_TIMEOUT
1378*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(before_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT -
1379*d9f75844SAndroid Build Coastguard Worker 1);
1380*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(100);
1381*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn() != nullptr);
1382*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(after_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT + 1);
1383*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
1384*d9f75844SAndroid Build Coastguard Worker }
1385*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConnectionDeadWithDeadConnectionTimeout)1386*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConnectionDeadWithDeadConnectionTimeout) {
1387*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(CreateUdpPort(kLocalAddr1));
1388*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(CreateUdpPort(kLocalAddr2));
1389*d9f75844SAndroid Build Coastguard Worker // Acquire address.
1390*d9f75844SAndroid Build Coastguard Worker ch1.Start();
1391*d9f75844SAndroid Build Coastguard Worker ch2.Start();
1392*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1393*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
1394*d9f75844SAndroid Build Coastguard Worker
1395*d9f75844SAndroid Build Coastguard Worker // Note: set field trials manually since they are parsed by
1396*d9f75844SAndroid Build Coastguard Worker // P2PTransportChannel but P2PTransportChannel is not used in this test.
1397*d9f75844SAndroid Build Coastguard Worker IceFieldTrials field_trials;
1398*d9f75844SAndroid Build Coastguard Worker field_trials.dead_connection_timeout_ms = 90000;
1399*d9f75844SAndroid Build Coastguard Worker
1400*d9f75844SAndroid Build Coastguard Worker // Create a connection again and receive a ping.
1401*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
1402*d9f75844SAndroid Build Coastguard Worker auto conn = ch1.conn();
1403*d9f75844SAndroid Build Coastguard Worker conn->SetIceFieldTrials(&field_trials);
1404*d9f75844SAndroid Build Coastguard Worker
1405*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(conn, nullptr);
1406*d9f75844SAndroid Build Coastguard Worker int64_t before_last_receiving = rtc::TimeMillis();
1407*d9f75844SAndroid Build Coastguard Worker conn->ReceivedPing();
1408*d9f75844SAndroid Build Coastguard Worker int64_t after_last_receiving = rtc::TimeMillis();
1409*d9f75844SAndroid Build Coastguard Worker // The connection will be dead after 90s
1410*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(before_last_receiving + 90000 - 1);
1411*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(100);
1412*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn() != nullptr);
1413*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(after_last_receiving + 90000 + 1);
1414*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
1415*d9f75844SAndroid Build Coastguard Worker }
1416*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestConnectionDeadOutstandingPing)1417*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConnectionDeadOutstandingPing) {
1418*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
1419*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1420*d9f75844SAndroid Build Coastguard Worker port1->SetIceTiebreaker(kTiebreaker1);
1421*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
1422*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1423*d9f75844SAndroid Build Coastguard Worker port2->SetIceTiebreaker(kTiebreaker2);
1424*d9f75844SAndroid Build Coastguard Worker
1425*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
1426*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
1427*d9f75844SAndroid Build Coastguard Worker // Acquire address.
1428*d9f75844SAndroid Build Coastguard Worker ch1.Start();
1429*d9f75844SAndroid Build Coastguard Worker ch2.Start();
1430*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1431*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
1432*d9f75844SAndroid Build Coastguard Worker
1433*d9f75844SAndroid Build Coastguard Worker // Note: set field trials manually since they are parsed by
1434*d9f75844SAndroid Build Coastguard Worker // P2PTransportChannel but P2PTransportChannel is not used in this test.
1435*d9f75844SAndroid Build Coastguard Worker IceFieldTrials field_trials;
1436*d9f75844SAndroid Build Coastguard Worker field_trials.dead_connection_timeout_ms = 360000;
1437*d9f75844SAndroid Build Coastguard Worker
1438*d9f75844SAndroid Build Coastguard Worker // Create a connection again and receive a ping and then send
1439*d9f75844SAndroid Build Coastguard Worker // a ping and keep it outstanding.
1440*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
1441*d9f75844SAndroid Build Coastguard Worker auto conn = ch1.conn();
1442*d9f75844SAndroid Build Coastguard Worker conn->SetIceFieldTrials(&field_trials);
1443*d9f75844SAndroid Build Coastguard Worker
1444*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(conn, nullptr);
1445*d9f75844SAndroid Build Coastguard Worker conn->ReceivedPing();
1446*d9f75844SAndroid Build Coastguard Worker int64_t send_ping_timestamp = rtc::TimeMillis();
1447*d9f75844SAndroid Build Coastguard Worker conn->Ping(send_ping_timestamp);
1448*d9f75844SAndroid Build Coastguard Worker
1449*d9f75844SAndroid Build Coastguard Worker // The connection will be dead 30s after the ping was sent.
1450*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(send_ping_timestamp + DEAD_CONNECTION_RECEIVE_TIMEOUT - 1);
1451*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(100);
1452*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(ch1.conn() != nullptr);
1453*d9f75844SAndroid Build Coastguard Worker conn->UpdateState(send_ping_timestamp + DEAD_CONNECTION_RECEIVE_TIMEOUT + 1);
1454*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
1455*d9f75844SAndroid Build Coastguard Worker }
1456*d9f75844SAndroid Build Coastguard Worker
1457*d9f75844SAndroid Build Coastguard Worker // This test case verifies standard ICE features in STUN messages. Currently it
1458*d9f75844SAndroid Build Coastguard Worker // verifies Message Integrity attribute in STUN messages and username in STUN
1459*d9f75844SAndroid Build Coastguard Worker // binding request will have colon (":") between remote and local username.
TEST_F(PortTest,TestLocalToLocalStandard)1460*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLocalToLocalStandard) {
1461*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
1462*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1463*d9f75844SAndroid Build Coastguard Worker port1->SetIceTiebreaker(kTiebreaker1);
1464*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
1465*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1466*d9f75844SAndroid Build Coastguard Worker port2->SetIceTiebreaker(kTiebreaker2);
1467*d9f75844SAndroid Build Coastguard Worker // Same parameters as TestLocalToLocal above.
1468*d9f75844SAndroid Build Coastguard Worker TestConnectivity("udp", std::move(port1), "udp", std::move(port2), true, true,
1469*d9f75844SAndroid Build Coastguard Worker true, true);
1470*d9f75844SAndroid Build Coastguard Worker }
1471*d9f75844SAndroid Build Coastguard Worker
1472*d9f75844SAndroid Build Coastguard Worker // This test is trying to validate a successful and failure scenario in a
1473*d9f75844SAndroid Build Coastguard Worker // loopback test when protocol is RFC5245. For success IceTiebreaker, username
1474*d9f75844SAndroid Build Coastguard Worker // should remain equal to the request generated by the port and role of port
1475*d9f75844SAndroid Build Coastguard Worker // must be in controlling.
TEST_F(PortTest,TestLoopbackCall)1476*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestLoopbackCall) {
1477*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
1478*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1479*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
1480*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
1481*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
1482*d9f75844SAndroid Build Coastguard Worker Connection* conn =
1483*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1484*d9f75844SAndroid Build Coastguard Worker conn->Ping(0);
1485*d9f75844SAndroid Build Coastguard Worker
1486*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1487*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = lport->last_stun_msg();
1488*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1489*d9f75844SAndroid Build Coastguard Worker conn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1490*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
1491*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1492*d9f75844SAndroid Build Coastguard Worker msg = lport->last_stun_msg();
1493*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1494*d9f75844SAndroid Build Coastguard Worker
1495*d9f75844SAndroid Build Coastguard Worker // If the tiebreaker value is different from port, we expect a error
1496*d9f75844SAndroid Build Coastguard Worker // response.
1497*d9f75844SAndroid Build Coastguard Worker lport->Reset();
1498*d9f75844SAndroid Build Coastguard Worker lport->AddCandidateAddress(kLocalAddr2);
1499*d9f75844SAndroid Build Coastguard Worker // Creating a different connection as `conn` is receiving.
1500*d9f75844SAndroid Build Coastguard Worker Connection* conn1 =
1501*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(lport->Candidates()[1], Port::ORIGIN_MESSAGE);
1502*d9f75844SAndroid Build Coastguard Worker conn1->Ping(0);
1503*d9f75844SAndroid Build Coastguard Worker
1504*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1505*d9f75844SAndroid Build Coastguard Worker msg = lport->last_stun_msg();
1506*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1507*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> modified_req(
1508*d9f75844SAndroid Build Coastguard Worker CreateStunMessage(STUN_BINDING_REQUEST));
1509*d9f75844SAndroid Build Coastguard Worker const StunByteStringAttribute* username_attr =
1510*d9f75844SAndroid Build Coastguard Worker msg->GetByteString(STUN_ATTR_USERNAME);
1511*d9f75844SAndroid Build Coastguard Worker modified_req->AddAttribute(std::make_unique<StunByteStringAttribute>(
1512*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_USERNAME, username_attr->string_view()));
1513*d9f75844SAndroid Build Coastguard Worker // To make sure we receive error response, adding tiebreaker less than
1514*d9f75844SAndroid Build Coastguard Worker // what's present in request.
1515*d9f75844SAndroid Build Coastguard Worker modified_req->AddAttribute(std::make_unique<StunUInt64Attribute>(
1516*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1517*d9f75844SAndroid Build Coastguard Worker modified_req->AddMessageIntegrity("lpass");
1518*d9f75844SAndroid Build Coastguard Worker modified_req->AddFingerprint();
1519*d9f75844SAndroid Build Coastguard Worker
1520*d9f75844SAndroid Build Coastguard Worker lport->Reset();
1521*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
1522*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*modified_req, buf.get());
1523*d9f75844SAndroid Build Coastguard Worker conn1->OnReadPacket(buf->Data(), buf->Length(), /* packet_time_us */ -1);
1524*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1525*d9f75844SAndroid Build Coastguard Worker msg = lport->last_stun_msg();
1526*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1527*d9f75844SAndroid Build Coastguard Worker }
1528*d9f75844SAndroid Build Coastguard Worker
1529*d9f75844SAndroid Build Coastguard Worker // This test verifies role conflict signal is received when there is
1530*d9f75844SAndroid Build Coastguard Worker // conflict in the role. In this case both ports are in controlling and
1531*d9f75844SAndroid Build Coastguard Worker // `rport` has higher tiebreaker value than `lport`. Since `lport` has lower
1532*d9f75844SAndroid Build Coastguard Worker // value of tiebreaker, when it receives ping request from `rport` it will
1533*d9f75844SAndroid Build Coastguard Worker // send role conflict signal.
TEST_F(PortTest,TestIceRoleConflict)1534*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestIceRoleConflict) {
1535*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
1536*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1537*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
1538*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
1539*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1540*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
1541*d9f75844SAndroid Build Coastguard Worker
1542*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
1543*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
1544*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
1545*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
1546*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
1547*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1548*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
1549*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1550*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1551*d9f75844SAndroid Build Coastguard Worker
1552*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
1553*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = rport->last_stun_msg();
1554*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1555*d9f75844SAndroid Build Coastguard Worker // Send rport binding request to lport.
1556*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1557*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
1558*d9f75844SAndroid Build Coastguard Worker
1559*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1560*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1561*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(role_conflict());
1562*d9f75844SAndroid Build Coastguard Worker }
1563*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestTcpNoDelay)1564*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTcpNoDelay) {
1565*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
1566*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateTcpPort(kLocalAddr1);
1567*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1568*d9f75844SAndroid Build Coastguard Worker int option_value = -1;
1569*d9f75844SAndroid Build Coastguard Worker int success = port1->GetOption(rtc::Socket::OPT_NODELAY, &option_value);
1570*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1571*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, option_value);
1572*d9f75844SAndroid Build Coastguard Worker
1573*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTcpPort(kLocalAddr2);
1574*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1575*d9f75844SAndroid Build Coastguard Worker
1576*d9f75844SAndroid Build Coastguard Worker // Set up a connection, and verify that option is set on connected sockets at
1577*d9f75844SAndroid Build Coastguard Worker // both ends.
1578*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
1579*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
1580*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
1581*d9f75844SAndroid Build Coastguard Worker ch1.Start();
1582*d9f75844SAndroid Build Coastguard Worker ch2.Start();
1583*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
1584*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
1585*d9f75844SAndroid Build Coastguard Worker // Connect and send a ping from src to dst.
1586*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
1587*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
1588*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout,
1589*d9f75844SAndroid Build Coastguard Worker clock); // for TCP connect
1590*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
1591*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
1592*d9f75844SAndroid Build Coastguard Worker
1593*d9f75844SAndroid Build Coastguard Worker // Accept the connection.
1594*d9f75844SAndroid Build Coastguard Worker ch2.AcceptConnection(GetCandidate(ch1.port()));
1595*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch2.conn() != NULL);
1596*d9f75844SAndroid Build Coastguard Worker
1597*d9f75844SAndroid Build Coastguard Worker option_value = -1;
1598*d9f75844SAndroid Build Coastguard Worker success = static_cast<TCPConnection*>(ch1.conn())
1599*d9f75844SAndroid Build Coastguard Worker ->socket()
1600*d9f75844SAndroid Build Coastguard Worker ->GetOption(rtc::Socket::OPT_NODELAY, &option_value);
1601*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(0, success);
1602*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, option_value);
1603*d9f75844SAndroid Build Coastguard Worker
1604*d9f75844SAndroid Build Coastguard Worker option_value = -1;
1605*d9f75844SAndroid Build Coastguard Worker success = static_cast<TCPConnection*>(ch2.conn())
1606*d9f75844SAndroid Build Coastguard Worker ->socket()
1607*d9f75844SAndroid Build Coastguard Worker ->GetOption(rtc::Socket::OPT_NODELAY, &option_value);
1608*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(0, success);
1609*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, option_value);
1610*d9f75844SAndroid Build Coastguard Worker }
1611*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestDelayedBindingUdp)1612*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestDelayedBindingUdp) {
1613*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
1614*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory socket_factory;
1615*d9f75844SAndroid Build Coastguard Worker
1616*d9f75844SAndroid Build Coastguard Worker socket_factory.set_next_udp_socket(socket);
1617*d9f75844SAndroid Build Coastguard Worker auto port = CreateUdpPort(kLocalAddr1, &socket_factory);
1618*d9f75844SAndroid Build Coastguard Worker
1619*d9f75844SAndroid Build Coastguard Worker socket->set_state(AsyncPacketSocket::STATE_BINDING);
1620*d9f75844SAndroid Build Coastguard Worker port->PrepareAddress();
1621*d9f75844SAndroid Build Coastguard Worker
1622*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, port->Candidates().size());
1623*d9f75844SAndroid Build Coastguard Worker socket->SignalAddressReady(socket, kLocalAddr2);
1624*d9f75844SAndroid Build Coastguard Worker
1625*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, port->Candidates().size());
1626*d9f75844SAndroid Build Coastguard Worker }
1627*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestDisableInterfaceOfTcpPort)1628*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestDisableInterfaceOfTcpPort) {
1629*d9f75844SAndroid Build Coastguard Worker FakeAsyncListenSocket* lsocket = new FakeAsyncListenSocket();
1630*d9f75844SAndroid Build Coastguard Worker FakeAsyncListenSocket* rsocket = new FakeAsyncListenSocket();
1631*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory socket_factory;
1632*d9f75844SAndroid Build Coastguard Worker
1633*d9f75844SAndroid Build Coastguard Worker socket_factory.set_next_server_tcp_socket(lsocket);
1634*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTcpPort(kLocalAddr1, &socket_factory);
1635*d9f75844SAndroid Build Coastguard Worker
1636*d9f75844SAndroid Build Coastguard Worker socket_factory.set_next_server_tcp_socket(rsocket);
1637*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTcpPort(kLocalAddr2, &socket_factory);
1638*d9f75844SAndroid Build Coastguard Worker
1639*d9f75844SAndroid Build Coastguard Worker lsocket->Bind(kLocalAddr1);
1640*d9f75844SAndroid Build Coastguard Worker rsocket->Bind(kLocalAddr2);
1641*d9f75844SAndroid Build Coastguard Worker
1642*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1643*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
1644*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1645*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
1646*d9f75844SAndroid Build Coastguard Worker
1647*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
1648*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
1649*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
1650*d9f75844SAndroid Build Coastguard Worker
1651*d9f75844SAndroid Build Coastguard Worker // A client socket.
1652*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
1653*d9f75844SAndroid Build Coastguard Worker socket->local_address_ = kLocalAddr1;
1654*d9f75844SAndroid Build Coastguard Worker socket->remote_address_ = kLocalAddr2;
1655*d9f75844SAndroid Build Coastguard Worker socket_factory.set_next_client_tcp_socket(socket);
1656*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
1657*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1658*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(lconn, nullptr);
1659*d9f75844SAndroid Build Coastguard Worker socket->SignalConnect(socket);
1660*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
1661*d9f75844SAndroid Build Coastguard Worker
1662*d9f75844SAndroid Build Coastguard Worker // Now disconnect the client socket...
1663*d9f75844SAndroid Build Coastguard Worker socket->NotifyClosedForTest(1);
1664*d9f75844SAndroid Build Coastguard Worker
1665*d9f75844SAndroid Build Coastguard Worker // And prevent new sockets from being created.
1666*d9f75844SAndroid Build Coastguard Worker socket_factory.set_next_client_tcp_socket(nullptr);
1667*d9f75844SAndroid Build Coastguard Worker
1668*d9f75844SAndroid Build Coastguard Worker // Test that Ping() does not cause SEGV.
1669*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
1670*d9f75844SAndroid Build Coastguard Worker }
1671*d9f75844SAndroid Build Coastguard Worker
TestCrossFamilyPorts(int type)1672*d9f75844SAndroid Build Coastguard Worker void PortTest::TestCrossFamilyPorts(int type) {
1673*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory factory;
1674*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> ports[4];
1675*d9f75844SAndroid Build Coastguard Worker SocketAddress addresses[4] = {
1676*d9f75844SAndroid Build Coastguard Worker SocketAddress("192.168.1.3", 0), SocketAddress("192.168.1.4", 0),
1677*d9f75844SAndroid Build Coastguard Worker SocketAddress("2001:db8::1", 0), SocketAddress("2001:db8::2", 0)};
1678*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) {
1679*d9f75844SAndroid Build Coastguard Worker if (type == SOCK_DGRAM) {
1680*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
1681*d9f75844SAndroid Build Coastguard Worker factory.set_next_udp_socket(socket);
1682*d9f75844SAndroid Build Coastguard Worker ports[i] = CreateUdpPort(addresses[i], &factory);
1683*d9f75844SAndroid Build Coastguard Worker socket->set_state(AsyncPacketSocket::STATE_BINDING);
1684*d9f75844SAndroid Build Coastguard Worker socket->SignalAddressReady(socket, addresses[i]);
1685*d9f75844SAndroid Build Coastguard Worker } else if (type == SOCK_STREAM) {
1686*d9f75844SAndroid Build Coastguard Worker FakeAsyncListenSocket* socket = new FakeAsyncListenSocket();
1687*d9f75844SAndroid Build Coastguard Worker factory.set_next_server_tcp_socket(socket);
1688*d9f75844SAndroid Build Coastguard Worker ports[i] = CreateTcpPort(addresses[i], &factory);
1689*d9f75844SAndroid Build Coastguard Worker socket->Bind(addresses[i]);
1690*d9f75844SAndroid Build Coastguard Worker }
1691*d9f75844SAndroid Build Coastguard Worker ports[i]->PrepareAddress();
1692*d9f75844SAndroid Build Coastguard Worker }
1693*d9f75844SAndroid Build Coastguard Worker
1694*d9f75844SAndroid Build Coastguard Worker // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1695*d9f75844SAndroid Build Coastguard Worker if (type == SOCK_STREAM) {
1696*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1697*d9f75844SAndroid Build Coastguard Worker factory.set_next_client_tcp_socket(clientsocket);
1698*d9f75844SAndroid Build Coastguard Worker }
1699*d9f75844SAndroid Build Coastguard Worker Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1700*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
1701*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(NULL == c);
1702*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, ports[0]->connections().size());
1703*d9f75844SAndroid Build Coastguard Worker c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1704*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
1705*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(NULL == c);
1706*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, ports[0]->connections().size());
1707*d9f75844SAndroid Build Coastguard Worker
1708*d9f75844SAndroid Build Coastguard Worker // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1709*d9f75844SAndroid Build Coastguard Worker if (type == SOCK_STREAM) {
1710*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1711*d9f75844SAndroid Build Coastguard Worker factory.set_next_client_tcp_socket(clientsocket);
1712*d9f75844SAndroid Build Coastguard Worker }
1713*d9f75844SAndroid Build Coastguard Worker c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1714*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
1715*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(NULL == c);
1716*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, ports[2]->connections().size());
1717*d9f75844SAndroid Build Coastguard Worker c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1718*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
1719*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(NULL == c);
1720*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, ports[2]->connections().size());
1721*d9f75844SAndroid Build Coastguard Worker }
1722*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSkipCrossFamilyTcp)1723*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1724*d9f75844SAndroid Build Coastguard Worker TestCrossFamilyPorts(SOCK_STREAM);
1725*d9f75844SAndroid Build Coastguard Worker }
1726*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSkipCrossFamilyUdp)1727*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1728*d9f75844SAndroid Build Coastguard Worker TestCrossFamilyPorts(SOCK_DGRAM);
1729*d9f75844SAndroid Build Coastguard Worker }
1730*d9f75844SAndroid Build Coastguard Worker
ExpectPortsCanConnect(bool can_connect,Port * p1,Port * p2)1731*d9f75844SAndroid Build Coastguard Worker void PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) {
1732*d9f75844SAndroid Build Coastguard Worker Connection* c = p1->CreateConnection(GetCandidate(p2), Port::ORIGIN_MESSAGE);
1733*d9f75844SAndroid Build Coastguard Worker if (can_connect) {
1734*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(NULL == c);
1735*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, p1->connections().size());
1736*d9f75844SAndroid Build Coastguard Worker } else {
1737*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(NULL == c);
1738*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, p1->connections().size());
1739*d9f75844SAndroid Build Coastguard Worker }
1740*d9f75844SAndroid Build Coastguard Worker }
1741*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestUdpSingleAddressV6CrossTypePorts)1742*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestUdpSingleAddressV6CrossTypePorts) {
1743*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory factory;
1744*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> ports[4];
1745*d9f75844SAndroid Build Coastguard Worker SocketAddress addresses[4] = {
1746*d9f75844SAndroid Build Coastguard Worker SocketAddress("2001:db8::1", 0), SocketAddress("fe80::1", 0),
1747*d9f75844SAndroid Build Coastguard Worker SocketAddress("fe80::2", 0), SocketAddress("::1", 0)};
1748*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) {
1749*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
1750*d9f75844SAndroid Build Coastguard Worker factory.set_next_udp_socket(socket);
1751*d9f75844SAndroid Build Coastguard Worker ports[i] = CreateUdpPort(addresses[i], &factory);
1752*d9f75844SAndroid Build Coastguard Worker socket->set_state(AsyncPacketSocket::STATE_BINDING);
1753*d9f75844SAndroid Build Coastguard Worker socket->SignalAddressReady(socket, addresses[i]);
1754*d9f75844SAndroid Build Coastguard Worker ports[i]->PrepareAddress();
1755*d9f75844SAndroid Build Coastguard Worker }
1756*d9f75844SAndroid Build Coastguard Worker
1757*d9f75844SAndroid Build Coastguard Worker Port* standard = ports[0].get();
1758*d9f75844SAndroid Build Coastguard Worker Port* link_local1 = ports[1].get();
1759*d9f75844SAndroid Build Coastguard Worker Port* link_local2 = ports[2].get();
1760*d9f75844SAndroid Build Coastguard Worker Port* localhost = ports[3].get();
1761*d9f75844SAndroid Build Coastguard Worker
1762*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, link_local1, standard);
1763*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, standard, link_local1);
1764*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, link_local1, localhost);
1765*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, localhost, link_local1);
1766*d9f75844SAndroid Build Coastguard Worker
1767*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, link_local1, link_local2);
1768*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, localhost, standard);
1769*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, standard, localhost);
1770*d9f75844SAndroid Build Coastguard Worker }
1771*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestUdpMultipleAddressesV6CrossTypePorts)1772*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestUdpMultipleAddressesV6CrossTypePorts) {
1773*d9f75844SAndroid Build Coastguard Worker webrtc::test::ScopedKeyValueConfig field_trials(
1774*d9f75844SAndroid Build Coastguard Worker "WebRTC-IPv6NetworkResolutionFixes/"
1775*d9f75844SAndroid Build Coastguard Worker "Enabled,PreferGlobalIPv6Address:true/");
1776*d9f75844SAndroid Build Coastguard Worker FakePacketSocketFactory factory;
1777*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Port> ports[5];
1778*d9f75844SAndroid Build Coastguard Worker SocketAddress addresses[5] = {
1779*d9f75844SAndroid Build Coastguard Worker SocketAddress("2001:db8::1", 0), SocketAddress("2001:db8::2", 0),
1780*d9f75844SAndroid Build Coastguard Worker SocketAddress("fe80::1", 0), SocketAddress("fe80::2", 0),
1781*d9f75844SAndroid Build Coastguard Worker SocketAddress("::1", 0)};
1782*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 5; i++) {
1783*d9f75844SAndroid Build Coastguard Worker FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
1784*d9f75844SAndroid Build Coastguard Worker factory.set_next_udp_socket(socket);
1785*d9f75844SAndroid Build Coastguard Worker ports[i] = CreateUdpPortMultipleAddrs(addresses[i], kLinkLocalIPv6Addr,
1786*d9f75844SAndroid Build Coastguard Worker &factory, field_trials);
1787*d9f75844SAndroid Build Coastguard Worker ports[i]->SetIceTiebreaker(kTiebreakerDefault);
1788*d9f75844SAndroid Build Coastguard Worker socket->set_state(AsyncPacketSocket::STATE_BINDING);
1789*d9f75844SAndroid Build Coastguard Worker socket->SignalAddressReady(socket, addresses[i]);
1790*d9f75844SAndroid Build Coastguard Worker ports[i]->PrepareAddress();
1791*d9f75844SAndroid Build Coastguard Worker }
1792*d9f75844SAndroid Build Coastguard Worker
1793*d9f75844SAndroid Build Coastguard Worker Port* standard1 = ports[0].get();
1794*d9f75844SAndroid Build Coastguard Worker Port* standard2 = ports[1].get();
1795*d9f75844SAndroid Build Coastguard Worker Port* link_local1 = ports[2].get();
1796*d9f75844SAndroid Build Coastguard Worker Port* link_local2 = ports[3].get();
1797*d9f75844SAndroid Build Coastguard Worker Port* localhost = ports[4].get();
1798*d9f75844SAndroid Build Coastguard Worker
1799*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, link_local1, standard1);
1800*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, standard1, link_local1);
1801*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, link_local1, localhost);
1802*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(false, localhost, link_local1);
1803*d9f75844SAndroid Build Coastguard Worker
1804*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, link_local1, link_local2);
1805*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, localhost, standard1);
1806*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, standard1, localhost);
1807*d9f75844SAndroid Build Coastguard Worker ExpectPortsCanConnect(true, standard2, standard1);
1808*d9f75844SAndroid Build Coastguard Worker }
1809*d9f75844SAndroid Build Coastguard Worker
1810*d9f75844SAndroid Build Coastguard Worker // This test verifies DSCP value set through SetOption interface can be
1811*d9f75844SAndroid Build Coastguard Worker // get through DefaultDscpValue.
TEST_F(PortTest,TestDefaultDscpValue)1812*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestDefaultDscpValue) {
1813*d9f75844SAndroid Build Coastguard Worker int dscp;
1814*d9f75844SAndroid Build Coastguard Worker auto udpport = CreateUdpPort(kLocalAddr1);
1815*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6));
1816*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1817*d9f75844SAndroid Build Coastguard Worker auto tcpport = CreateTcpPort(kLocalAddr1);
1818*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF31));
1819*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1820*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::DSCP_AF31, dscp);
1821*d9f75844SAndroid Build Coastguard Worker auto stunport = CreateStunPort(kLocalAddr1, nat_socket_factory1());
1822*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41));
1823*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1824*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::DSCP_AF41, dscp);
1825*d9f75844SAndroid Build Coastguard Worker auto turnport1 =
1826*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
1827*d9f75844SAndroid Build Coastguard Worker // Socket is created in PrepareAddress.
1828*d9f75844SAndroid Build Coastguard Worker turnport1->PrepareAddress();
1829*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS7));
1830*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1831*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::DSCP_CS7, dscp);
1832*d9f75844SAndroid Build Coastguard Worker // This will verify correct value returned without the socket.
1833*d9f75844SAndroid Build Coastguard Worker auto turnport2 =
1834*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
1835*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6));
1836*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1837*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::DSCP_CS6, dscp);
1838*d9f75844SAndroid Build Coastguard Worker }
1839*d9f75844SAndroid Build Coastguard Worker
1840*d9f75844SAndroid Build Coastguard Worker // Test sending STUN messages.
TEST_F(PortTest,TestSendStunMessage)1841*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSendStunMessage) {
1842*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
1843*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
1844*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1845*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
1846*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1847*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
1848*d9f75844SAndroid Build Coastguard Worker
1849*d9f75844SAndroid Build Coastguard Worker // Send a fake ping from lport to rport.
1850*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
1851*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
1852*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
1853*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
1854*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1855*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
1856*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1857*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
1858*d9f75844SAndroid Build Coastguard Worker
1859*d9f75844SAndroid Build Coastguard Worker // Check that it's a proper BINDING-REQUEST.
1860*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
1861*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = lport->last_stun_msg();
1862*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1863*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(msg->IsLegacy());
1864*d9f75844SAndroid Build Coastguard Worker const StunByteStringAttribute* username_attr =
1865*d9f75844SAndroid Build Coastguard Worker msg->GetByteString(STUN_ATTR_USERNAME);
1866*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(username_attr != NULL);
1867*d9f75844SAndroid Build Coastguard Worker const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1868*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(priority_attr != NULL);
1869*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1870*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("rfrag:lfrag", username_attr->string_view());
1871*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1872*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(StunMessage::IntegrityStatus::kIntegrityOk,
1873*d9f75844SAndroid Build Coastguard Worker msg->ValidateMessageIntegrity("rpass"));
1874*d9f75844SAndroid Build Coastguard Worker const StunUInt64Attribute* ice_controlling_attr =
1875*d9f75844SAndroid Build Coastguard Worker msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1876*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ice_controlling_attr != NULL);
1877*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
1878*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1879*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1880*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1881*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(StunMessage::ValidateFingerprint(
1882*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
1883*d9f75844SAndroid Build Coastguard Worker
1884*d9f75844SAndroid Build Coastguard Worker // Request should not include ping count.
1885*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1886*d9f75844SAndroid Build Coastguard Worker
1887*d9f75844SAndroid Build Coastguard Worker // Save a copy of the BINDING-REQUEST for use below.
1888*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> request = CopyStunMessage(*msg);
1889*d9f75844SAndroid Build Coastguard Worker
1890*d9f75844SAndroid Build Coastguard Worker // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE.
1891*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1892*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
1893*d9f75844SAndroid Build Coastguard Worker msg = rport->last_stun_msg();
1894*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(msg != NULL);
1895*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1896*d9f75844SAndroid Build Coastguard Worker // Received a BINDING-RESPONSE.
1897*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1898*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
1899*d9f75844SAndroid Build Coastguard Worker // Verify the STUN Stats.
1900*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total);
1901*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, lconn->stats().sent_ping_requests_before_first_response);
1902*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, lconn->stats().recv_ping_responses);
1903*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, rconn->stats().recv_ping_requests);
1904*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, rconn->stats().sent_ping_responses);
1905*d9f75844SAndroid Build Coastguard Worker
1906*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(msg->IsLegacy());
1907*d9f75844SAndroid Build Coastguard Worker const StunAddressAttribute* addr_attr =
1908*d9f75844SAndroid Build Coastguard Worker msg->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
1909*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(addr_attr != NULL);
1910*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1911*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1912*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(StunMessage::IntegrityStatus::kIntegrityOk,
1913*d9f75844SAndroid Build Coastguard Worker msg->ValidateMessageIntegrity("rpass"));
1914*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1915*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(StunMessage::ValidateFingerprint(
1916*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
1917*d9f75844SAndroid Build Coastguard Worker // No USERNAME or PRIORITY in ICE responses.
1918*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1919*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1920*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1921*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1922*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1923*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1924*d9f75844SAndroid Build Coastguard Worker
1925*d9f75844SAndroid Build Coastguard Worker // Response should not include ping count.
1926*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1927*d9f75844SAndroid Build Coastguard Worker
1928*d9f75844SAndroid Build Coastguard Worker // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1929*d9f75844SAndroid Build Coastguard Worker // but we can do it here.
1930*d9f75844SAndroid Build Coastguard Worker rport->SendBindingErrorResponse(
1931*d9f75844SAndroid Build Coastguard Worker request.get(), lport->Candidates()[0].address(), STUN_ERROR_SERVER_ERROR,
1932*d9f75844SAndroid Build Coastguard Worker STUN_ERROR_REASON_SERVER_ERROR);
1933*d9f75844SAndroid Build Coastguard Worker msg = rport->last_stun_msg();
1934*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(msg != NULL);
1935*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1936*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(msg->IsLegacy());
1937*d9f75844SAndroid Build Coastguard Worker const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1938*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(error_attr != NULL);
1939*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1940*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1941*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1942*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(StunMessage::IntegrityStatus::kIntegrityOk,
1943*d9f75844SAndroid Build Coastguard Worker msg->ValidateMessageIntegrity("rpass"));
1944*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1945*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(StunMessage::ValidateFingerprint(
1946*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
1947*d9f75844SAndroid Build Coastguard Worker // No USERNAME with ICE.
1948*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1949*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1950*d9f75844SAndroid Build Coastguard Worker
1951*d9f75844SAndroid Build Coastguard Worker // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1952*d9f75844SAndroid Build Coastguard Worker // and (incremented) RETRANSMIT_COUNT attributes.
1953*d9f75844SAndroid Build Coastguard Worker rport->Reset();
1954*d9f75844SAndroid Build Coastguard Worker rport->set_send_retransmit_count_attribute(true);
1955*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1956*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1957*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1958*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
1959*d9f75844SAndroid Build Coastguard Worker msg = rport->last_stun_msg();
1960*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1961*d9f75844SAndroid Build Coastguard Worker const StunUInt64Attribute* ice_controlled_attr =
1962*d9f75844SAndroid Build Coastguard Worker msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1963*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ice_controlled_attr != NULL);
1964*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
1965*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1966*d9f75844SAndroid Build Coastguard Worker
1967*d9f75844SAndroid Build Coastguard Worker // Request should include ping count.
1968*d9f75844SAndroid Build Coastguard Worker const StunUInt32Attribute* retransmit_attr =
1969*d9f75844SAndroid Build Coastguard Worker msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1970*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(retransmit_attr != NULL);
1971*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2U, retransmit_attr->value());
1972*d9f75844SAndroid Build Coastguard Worker
1973*d9f75844SAndroid Build Coastguard Worker // Respond with a BINDING-RESPONSE.
1974*d9f75844SAndroid Build Coastguard Worker request = CopyStunMessage(*msg);
1975*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1976*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
1977*d9f75844SAndroid Build Coastguard Worker msg = lport->last_stun_msg();
1978*d9f75844SAndroid Build Coastguard Worker // Receive the BINDING-RESPONSE.
1979*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1980*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
1981*d9f75844SAndroid Build Coastguard Worker
1982*d9f75844SAndroid Build Coastguard Worker // Verify the Stun ping stats.
1983*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total);
1984*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
1985*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, rconn->stats().recv_ping_responses);
1986*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, lconn->stats().sent_ping_responses);
1987*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, lconn->stats().recv_ping_requests);
1988*d9f75844SAndroid Build Coastguard Worker // Ping after receiver the first response
1989*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1990*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
1991*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(5U, rconn->stats().sent_ping_requests_total);
1992*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
1993*d9f75844SAndroid Build Coastguard Worker
1994*d9f75844SAndroid Build Coastguard Worker // Response should include same ping count.
1995*d9f75844SAndroid Build Coastguard Worker retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1996*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(retransmit_attr != NULL);
1997*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2U, retransmit_attr->value());
1998*d9f75844SAndroid Build Coastguard Worker }
1999*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestNomination)2000*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestNomination) {
2001*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
2002*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2003*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2004*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
2005*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2006*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2007*d9f75844SAndroid Build Coastguard Worker
2008*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2009*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2010*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
2011*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2012*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2013*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2014*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2015*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2016*d9f75844SAndroid Build Coastguard Worker
2017*d9f75844SAndroid Build Coastguard Worker // `lconn` is controlling, `rconn` is controlled.
2018*d9f75844SAndroid Build Coastguard Worker uint32_t nomination = 1234;
2019*d9f75844SAndroid Build Coastguard Worker lconn->set_nomination(nomination);
2020*d9f75844SAndroid Build Coastguard Worker
2021*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->nominated());
2022*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(rconn->nominated());
2023*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
2024*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
2025*d9f75844SAndroid Build Coastguard Worker
2026*d9f75844SAndroid Build Coastguard Worker // Send ping (including the nomination value) from `lconn` to `rconn`. This
2027*d9f75844SAndroid Build Coastguard Worker // should set the remote nomination of `rconn`.
2028*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
2029*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
2030*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lport->last_stun_buf());
2031*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
2032*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
2033*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nomination, rconn->remote_nomination());
2034*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->nominated());
2035*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(rconn->nominated());
2036*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
2037*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
2038*d9f75844SAndroid Build Coastguard Worker
2039*d9f75844SAndroid Build Coastguard Worker // This should result in an acknowledgment sent back from `rconn` to `lconn`,
2040*d9f75844SAndroid Build Coastguard Worker // updating the acknowledged nomination of `lconn`.
2041*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
2042*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(rport->last_stun_buf());
2043*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
2044*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
2045*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nomination, lconn->acked_nomination());
2046*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->nominated());
2047*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(rconn->nominated());
2048*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
2049*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
2050*d9f75844SAndroid Build Coastguard Worker }
2051*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestRoundTripTime)2052*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestRoundTripTime) {
2053*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
2054*d9f75844SAndroid Build Coastguard Worker
2055*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
2056*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2057*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2058*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
2059*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2060*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2061*d9f75844SAndroid Build Coastguard Worker
2062*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2063*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2064*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
2065*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2066*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2067*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2068*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2069*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2070*d9f75844SAndroid Build Coastguard Worker
2071*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, lconn->stats().total_round_trip_time_ms);
2072*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->stats().current_round_trip_time_ms);
2073*d9f75844SAndroid Build Coastguard Worker
2074*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, lport.get(), rconn, rport.get(), &clock,
2075*d9f75844SAndroid Build Coastguard Worker 10);
2076*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(10u, lconn->stats().total_round_trip_time_ms);
2077*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
2078*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(10u, *lconn->stats().current_round_trip_time_ms);
2079*d9f75844SAndroid Build Coastguard Worker
2080*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, lport.get(), rconn, rport.get(), &clock,
2081*d9f75844SAndroid Build Coastguard Worker 20);
2082*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30u, lconn->stats().total_round_trip_time_ms);
2083*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
2084*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(20u, *lconn->stats().current_round_trip_time_ms);
2085*d9f75844SAndroid Build Coastguard Worker
2086*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, lport.get(), rconn, rport.get(), &clock,
2087*d9f75844SAndroid Build Coastguard Worker 30);
2088*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(60u, lconn->stats().total_round_trip_time_ms);
2089*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
2090*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(30u, *lconn->stats().current_round_trip_time_ms);
2091*d9f75844SAndroid Build Coastguard Worker }
2092*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestUseCandidateAttribute)2093*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestUseCandidateAttribute) {
2094*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
2095*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2096*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2097*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
2098*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2099*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2100*d9f75844SAndroid Build Coastguard Worker
2101*d9f75844SAndroid Build Coastguard Worker // Send a fake ping from lport to rport.
2102*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2103*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2104*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2105*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2106*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2107*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
2108*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
2109*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = lport->last_stun_msg();
2110*d9f75844SAndroid Build Coastguard Worker const StunUInt64Attribute* ice_controlling_attr =
2111*d9f75844SAndroid Build Coastguard Worker msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
2112*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ice_controlling_attr != NULL);
2113*d9f75844SAndroid Build Coastguard Worker const StunByteStringAttribute* use_candidate_attr =
2114*d9f75844SAndroid Build Coastguard Worker msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
2115*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(use_candidate_attr != NULL);
2116*d9f75844SAndroid Build Coastguard Worker }
2117*d9f75844SAndroid Build Coastguard Worker
2118*d9f75844SAndroid Build Coastguard Worker // Tests that when the network type changes, the network cost of the port will
2119*d9f75844SAndroid Build Coastguard Worker // change, the network cost of the local candidates will change. Also tests that
2120*d9f75844SAndroid Build Coastguard Worker // the remote network costs are updated with the stun binding requests.
TEST_F(PortTest,TestNetworkCostChange)2121*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestNetworkCostChange) {
2122*d9f75844SAndroid Build Coastguard Worker rtc::Network* test_network = MakeNetwork(kLocalAddr1);
2123*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(test_network, "lfrag", "lpass");
2124*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(test_network, "rfrag", "rpass");
2125*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2126*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
2127*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2128*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2129*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2130*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2131*d9f75844SAndroid Build Coastguard Worker
2132*d9f75844SAndroid Build Coastguard Worker // Default local port cost is rtc::kNetworkCostUnknown.
2133*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostUnknown, lport->network_cost());
2134*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(!lport->Candidates().empty());
2135*d9f75844SAndroid Build Coastguard Worker for (const cricket::Candidate& candidate : lport->Candidates()) {
2136*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostUnknown, candidate.network_cost());
2137*d9f75844SAndroid Build Coastguard Worker }
2138*d9f75844SAndroid Build Coastguard Worker
2139*d9f75844SAndroid Build Coastguard Worker // Change the network type to wifi.
2140*d9f75844SAndroid Build Coastguard Worker test_network->set_type(rtc::ADAPTER_TYPE_WIFI);
2141*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostLow, lport->network_cost());
2142*d9f75844SAndroid Build Coastguard Worker for (const cricket::Candidate& candidate : lport->Candidates()) {
2143*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostLow, candidate.network_cost());
2144*d9f75844SAndroid Build Coastguard Worker }
2145*d9f75844SAndroid Build Coastguard Worker
2146*d9f75844SAndroid Build Coastguard Worker // Add a connection and then change the network type.
2147*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2148*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2149*d9f75844SAndroid Build Coastguard Worker // Change the network type to cellular.
2150*d9f75844SAndroid Build Coastguard Worker test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
2151*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostHigh, lport->network_cost());
2152*d9f75844SAndroid Build Coastguard Worker for (const cricket::Candidate& candidate : lport->Candidates()) {
2153*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostHigh, candidate.network_cost());
2154*d9f75844SAndroid Build Coastguard Worker }
2155*d9f75844SAndroid Build Coastguard Worker
2156*d9f75844SAndroid Build Coastguard Worker test_network->set_type(rtc::ADAPTER_TYPE_WIFI);
2157*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2158*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2159*d9f75844SAndroid Build Coastguard Worker test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
2160*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
2161*d9f75844SAndroid Build Coastguard Worker // The rconn's remote candidate cost is rtc::kNetworkCostLow, but the ping
2162*d9f75844SAndroid Build Coastguard Worker // contains an attribute of network cost of rtc::kNetworkCostHigh. Once the
2163*d9f75844SAndroid Build Coastguard Worker // message is handled in rconn, The rconn's remote candidate will have cost
2164*d9f75844SAndroid Build Coastguard Worker // rtc::kNetworkCostHigh;
2165*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostLow, rconn->remote_candidate().network_cost());
2166*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
2167*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = lport->last_stun_msg();
2168*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2169*d9f75844SAndroid Build Coastguard Worker // Pass the binding request to rport.
2170*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
2171*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
2172*d9f75844SAndroid Build Coastguard Worker // Wait until rport sends the response and then check the remote network cost.
2173*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
2174*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostHigh, rconn->remote_candidate().network_cost());
2175*d9f75844SAndroid Build Coastguard Worker }
2176*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestNetworkInfoAttribute)2177*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestNetworkInfoAttribute) {
2178*d9f75844SAndroid Build Coastguard Worker rtc::Network* test_network = MakeNetwork(kLocalAddr1);
2179*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(test_network, "lfrag", "lpass");
2180*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(test_network, "rfrag", "rpass");
2181*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2182*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreaker1);
2183*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2184*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2185*d9f75844SAndroid Build Coastguard Worker
2186*d9f75844SAndroid Build Coastguard Worker uint16_t lnetwork_id = 9;
2187*d9f75844SAndroid Build Coastguard Worker test_network->set_id(lnetwork_id);
2188*d9f75844SAndroid Build Coastguard Worker // Send a fake ping from lport to rport.
2189*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2190*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2191*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2192*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2193*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
2194*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
2195*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = lport->last_stun_msg();
2196*d9f75844SAndroid Build Coastguard Worker const StunUInt32Attribute* network_info_attr =
2197*d9f75844SAndroid Build Coastguard Worker msg->GetUInt32(STUN_ATTR_GOOG_NETWORK_INFO);
2198*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(network_info_attr != NULL);
2199*d9f75844SAndroid Build Coastguard Worker uint32_t network_info = network_info_attr->value();
2200*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lnetwork_id, network_info >> 16);
2201*d9f75844SAndroid Build Coastguard Worker // Default network has unknown type and cost kNetworkCostUnknown.
2202*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostUnknown, network_info & 0xFFFF);
2203*d9f75844SAndroid Build Coastguard Worker
2204*d9f75844SAndroid Build Coastguard Worker // Set the network type to be cellular so its cost will be kNetworkCostHigh.
2205*d9f75844SAndroid Build Coastguard Worker // Send a fake ping from rport to lport.
2206*d9f75844SAndroid Build Coastguard Worker test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
2207*d9f75844SAndroid Build Coastguard Worker uint16_t rnetwork_id = 8;
2208*d9f75844SAndroid Build Coastguard Worker test_network->set_id(rnetwork_id);
2209*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2210*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2211*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
2212*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
2213*d9f75844SAndroid Build Coastguard Worker msg = rport->last_stun_msg();
2214*d9f75844SAndroid Build Coastguard Worker network_info_attr = msg->GetUInt32(STUN_ATTR_GOOG_NETWORK_INFO);
2215*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(network_info_attr != NULL);
2216*d9f75844SAndroid Build Coastguard Worker network_info = network_info_attr->value();
2217*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rnetwork_id, network_info >> 16);
2218*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rtc::kNetworkCostHigh, network_info & 0xFFFF);
2219*d9f75844SAndroid Build Coastguard Worker }
2220*d9f75844SAndroid Build Coastguard Worker
2221*d9f75844SAndroid Build Coastguard Worker // Test handling STUN messages.
TEST_F(PortTest,TestHandleStunMessage)2222*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestHandleStunMessage) {
2223*d9f75844SAndroid Build Coastguard Worker // Our port will act as the "remote" port.
2224*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2225*d9f75844SAndroid Build Coastguard Worker
2226*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2227*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
2228*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2229*d9f75844SAndroid Build Coastguard Worker std::string username;
2230*d9f75844SAndroid Build Coastguard Worker
2231*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST from local to remote with valid ICE username,
2232*d9f75844SAndroid Build Coastguard Worker // MESSAGE-INTEGRITY, and FINGERPRINT.
2233*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfrag:lfrag");
2234*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2235*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2236*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2237*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2238*d9f75844SAndroid Build Coastguard Worker &username));
2239*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() != NULL);
2240*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("lfrag", username);
2241*d9f75844SAndroid Build Coastguard Worker
2242*d9f75844SAndroid Build Coastguard Worker // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
2243*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_RESPONSE);
2244*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(std::make_unique<StunXorAddressAttribute>(
2245*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
2246*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2247*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2248*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2249*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2250*d9f75844SAndroid Build Coastguard Worker &username));
2251*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() != NULL);
2252*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2253*d9f75844SAndroid Build Coastguard Worker
2254*d9f75844SAndroid Build Coastguard Worker // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
2255*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_ERROR_RESPONSE);
2256*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(std::make_unique<StunErrorCodeAttribute>(
2257*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2258*d9f75844SAndroid Build Coastguard Worker STUN_ERROR_REASON_SERVER_ERROR));
2259*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2260*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2261*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2262*d9f75844SAndroid Build Coastguard Worker &username));
2263*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() != NULL);
2264*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2265*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
2266*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
2267*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
2268*d9f75844SAndroid Build Coastguard Worker out_msg->GetErrorCode()->reason());
2269*d9f75844SAndroid Build Coastguard Worker }
2270*d9f75844SAndroid Build Coastguard Worker
2271*d9f75844SAndroid Build Coastguard Worker // Tests handling of ICE binding requests with missing or incorrect usernames.
TEST_F(PortTest,TestHandleStunMessageBadUsername)2272*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestHandleStunMessageBadUsername) {
2273*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2274*d9f75844SAndroid Build Coastguard Worker
2275*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2276*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
2277*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2278*d9f75844SAndroid Build Coastguard Worker std::string username;
2279*d9f75844SAndroid Build Coastguard Worker
2280*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST with no username.
2281*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_REQUEST);
2282*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2283*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2284*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2285*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2286*d9f75844SAndroid Build Coastguard Worker &username));
2287*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2288*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2289*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2290*d9f75844SAndroid Build Coastguard Worker
2291*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST with empty username.
2292*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "");
2293*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2294*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2295*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2296*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2297*d9f75844SAndroid Build Coastguard Worker &username));
2298*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2299*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2300*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2301*d9f75844SAndroid Build Coastguard Worker
2302*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST with too-short username.
2303*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra");
2304*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2305*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2306*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2307*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2308*d9f75844SAndroid Build Coastguard Worker &username));
2309*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2310*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2311*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2312*d9f75844SAndroid Build Coastguard Worker
2313*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST with reversed username.
2314*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "lfrag:rfrag");
2315*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2316*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2317*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2318*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2319*d9f75844SAndroid Build Coastguard Worker &username));
2320*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2321*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2322*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2323*d9f75844SAndroid Build Coastguard Worker
2324*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST with garbage username.
2325*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "abcd:efgh");
2326*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2327*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2328*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2329*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2330*d9f75844SAndroid Build Coastguard Worker &username));
2331*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2332*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2333*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2334*d9f75844SAndroid Build Coastguard Worker }
2335*d9f75844SAndroid Build Coastguard Worker
2336*d9f75844SAndroid Build Coastguard Worker // Test handling STUN messages with missing or malformed M-I.
TEST_F(PortTest,TestHandleStunMessageBadMessageIntegrity)2337*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestHandleStunMessageBadMessageIntegrity) {
2338*d9f75844SAndroid Build Coastguard Worker // Our port will act as the "remote" port.
2339*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2340*d9f75844SAndroid Build Coastguard Worker
2341*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2342*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
2343*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2344*d9f75844SAndroid Build Coastguard Worker std::string username;
2345*d9f75844SAndroid Build Coastguard Worker
2346*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST from local to remote with valid ICE username and
2347*d9f75844SAndroid Build Coastguard Worker // FINGERPRINT, but no MESSAGE-INTEGRITY.
2348*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfrag:lfrag");
2349*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2350*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2351*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2352*d9f75844SAndroid Build Coastguard Worker &username));
2353*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2354*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2355*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2356*d9f75844SAndroid Build Coastguard Worker
2357*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST from local to remote with valid ICE username and
2358*d9f75844SAndroid Build Coastguard Worker // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
2359*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfrag:lfrag");
2360*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("invalid");
2361*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2362*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2363*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2364*d9f75844SAndroid Build Coastguard Worker &username));
2365*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() == NULL);
2366*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2367*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2368*d9f75844SAndroid Build Coastguard Worker
2369*d9f75844SAndroid Build Coastguard Worker // TODO(?): BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
2370*d9f75844SAndroid Build Coastguard Worker // by the Connection, not the Port, since they require the remote username.
2371*d9f75844SAndroid Build Coastguard Worker // Change this test to pass in data via Connection::OnReadPacket instead.
2372*d9f75844SAndroid Build Coastguard Worker }
2373*d9f75844SAndroid Build Coastguard Worker
2374*d9f75844SAndroid Build Coastguard Worker // Test handling STUN messages with missing or malformed FINGERPRINT.
TEST_F(PortTest,TestHandleStunMessageBadFingerprint)2375*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestHandleStunMessageBadFingerprint) {
2376*d9f75844SAndroid Build Coastguard Worker // Our port will act as the "remote" port.
2377*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2378*d9f75844SAndroid Build Coastguard Worker
2379*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2380*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
2381*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2382*d9f75844SAndroid Build Coastguard Worker std::string username;
2383*d9f75844SAndroid Build Coastguard Worker
2384*d9f75844SAndroid Build Coastguard Worker // BINDING-REQUEST from local to remote with valid ICE username and
2385*d9f75844SAndroid Build Coastguard Worker // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
2386*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfrag:lfrag");
2387*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2388*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2389*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2390*d9f75844SAndroid Build Coastguard Worker &username));
2391*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2392*d9f75844SAndroid Build Coastguard Worker
2393*d9f75844SAndroid Build Coastguard Worker // Now, add a fingerprint, but munge the message so it's not valid.
2394*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2395*d9f75844SAndroid Build Coastguard Worker in_msg->SetTransactionIdForTesting("TESTTESTBADD");
2396*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2397*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2398*d9f75844SAndroid Build Coastguard Worker &username));
2399*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2400*d9f75844SAndroid Build Coastguard Worker
2401*d9f75844SAndroid Build Coastguard Worker // Valid BINDING-RESPONSE, except no FINGERPRINT.
2402*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_RESPONSE);
2403*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(std::make_unique<StunXorAddressAttribute>(
2404*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
2405*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2406*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2407*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2408*d9f75844SAndroid Build Coastguard Worker &username));
2409*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2410*d9f75844SAndroid Build Coastguard Worker
2411*d9f75844SAndroid Build Coastguard Worker // Now, add a fingerprint, but munge the message so it's not valid.
2412*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2413*d9f75844SAndroid Build Coastguard Worker in_msg->SetTransactionIdForTesting("TESTTESTBADD");
2414*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2415*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2416*d9f75844SAndroid Build Coastguard Worker &username));
2417*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2418*d9f75844SAndroid Build Coastguard Worker
2419*d9f75844SAndroid Build Coastguard Worker // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
2420*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_ERROR_RESPONSE);
2421*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(std::make_unique<StunErrorCodeAttribute>(
2422*d9f75844SAndroid Build Coastguard Worker STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2423*d9f75844SAndroid Build Coastguard Worker STUN_ERROR_REASON_SERVER_ERROR));
2424*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2425*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2426*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2427*d9f75844SAndroid Build Coastguard Worker &username));
2428*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2429*d9f75844SAndroid Build Coastguard Worker
2430*d9f75844SAndroid Build Coastguard Worker // Now, add a fingerprint, but munge the message so it's not valid.
2431*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2432*d9f75844SAndroid Build Coastguard Worker in_msg->SetTransactionIdForTesting("TESTTESTBADD");
2433*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2434*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2435*d9f75844SAndroid Build Coastguard Worker &username));
2436*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, port->last_stun_error_code());
2437*d9f75844SAndroid Build Coastguard Worker }
2438*d9f75844SAndroid Build Coastguard Worker
2439*d9f75844SAndroid Build Coastguard Worker // Test handling a STUN message with unknown attributes in the
2440*d9f75844SAndroid Build Coastguard Worker // "comprehension-required" range. Should respond with an error with the
2441*d9f75844SAndroid Build Coastguard Worker // unknown attributes' IDs.
TEST_F(PortTest,TestHandleStunRequestWithUnknownComprehensionRequiredAttribute)2442*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest,
2443*d9f75844SAndroid Build Coastguard Worker TestHandleStunRequestWithUnknownComprehensionRequiredAttribute) {
2444*d9f75844SAndroid Build Coastguard Worker // Our port will act as the "remote" port.
2445*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2446*d9f75844SAndroid Build Coastguard Worker
2447*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2448*d9f75844SAndroid Build Coastguard Worker auto buf = std::make_unique<ByteBufferWriter>();
2449*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2450*d9f75844SAndroid Build Coastguard Worker std::string username;
2451*d9f75844SAndroid Build Coastguard Worker
2452*d9f75844SAndroid Build Coastguard Worker // Build ordinary message with valid ufrag/pass.
2453*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfrag:lfrag");
2454*d9f75844SAndroid Build Coastguard Worker in_msg->AddMessageIntegrity("rpass");
2455*d9f75844SAndroid Build Coastguard Worker // Add a couple attributes with ID in comprehension-required range.
2456*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(StunAttribute::CreateUInt32(0x7777));
2457*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(StunAttribute::CreateUInt32(0x4567));
2458*d9f75844SAndroid Build Coastguard Worker // ... And one outside the range.
2459*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(StunAttribute::CreateUInt32(0xdead));
2460*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2461*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2462*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2463*d9f75844SAndroid Build Coastguard Worker &username));
2464*d9f75844SAndroid Build Coastguard Worker IceMessage* error_response = port->last_stun_msg();
2465*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(nullptr, error_response);
2466*d9f75844SAndroid Build Coastguard Worker
2467*d9f75844SAndroid Build Coastguard Worker // Verify that the "unknown attribute" error response has the right error
2468*d9f75844SAndroid Build Coastguard Worker // code, and includes an attribute that lists out the unrecognized attribute
2469*d9f75844SAndroid Build Coastguard Worker // types.
2470*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_ERROR_UNKNOWN_ATTRIBUTE, error_response->GetErrorCodeValue());
2471*d9f75844SAndroid Build Coastguard Worker const StunUInt16ListAttribute* unknown_attributes =
2472*d9f75844SAndroid Build Coastguard Worker error_response->GetUnknownAttributes();
2473*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(nullptr, unknown_attributes);
2474*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(2u, unknown_attributes->Size());
2475*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x7777, unknown_attributes->GetType(0));
2476*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x4567, unknown_attributes->GetType(1));
2477*d9f75844SAndroid Build Coastguard Worker }
2478*d9f75844SAndroid Build Coastguard Worker
2479*d9f75844SAndroid Build Coastguard Worker // Similar to the above, but with a response instead of a request. In this
2480*d9f75844SAndroid Build Coastguard Worker // case the response should just be ignored and transaction treated is failed.
TEST_F(PortTest,TestHandleStunResponseWithUnknownComprehensionRequiredAttribute)2481*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest,
2482*d9f75844SAndroid Build Coastguard Worker TestHandleStunResponseWithUnknownComprehensionRequiredAttribute) {
2483*d9f75844SAndroid Build Coastguard Worker // Generic setup.
2484*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass",
2485*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreakerDefault);
2486*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
2487*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreakerDefault);
2488*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2489*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2490*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
2491*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2492*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2493*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2494*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2495*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2496*d9f75844SAndroid Build Coastguard Worker
2497*d9f75844SAndroid Build Coastguard Worker // Send request.
2498*d9f75844SAndroid Build Coastguard Worker lconn->Ping(0);
2499*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
2500*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
2501*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(), /* packet_time_us */ -1);
2502*d9f75844SAndroid Build Coastguard Worker
2503*d9f75844SAndroid Build Coastguard Worker // Intercept request and add comprehension required attribute.
2504*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
2505*d9f75844SAndroid Build Coastguard Worker auto modified_response = rport->last_stun_msg()->Clone();
2506*d9f75844SAndroid Build Coastguard Worker modified_response->AddAttribute(StunAttribute::CreateUInt32(0x7777));
2507*d9f75844SAndroid Build Coastguard Worker modified_response->RemoveAttribute(STUN_ATTR_FINGERPRINT);
2508*d9f75844SAndroid Build Coastguard Worker modified_response->AddFingerprint();
2509*d9f75844SAndroid Build Coastguard Worker ByteBufferWriter buf;
2510*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*modified_response, &buf);
2511*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(buf.Data(), buf.Length(), /* packet_time_us */ -1);
2512*d9f75844SAndroid Build Coastguard Worker // Response should have been ignored, leaving us unwritable still.
2513*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
2514*d9f75844SAndroid Build Coastguard Worker }
2515*d9f75844SAndroid Build Coastguard Worker
2516*d9f75844SAndroid Build Coastguard Worker // Similar to the above, but with an indication. As with a response, it should
2517*d9f75844SAndroid Build Coastguard Worker // just be ignored.
TEST_F(PortTest,TestHandleStunIndicationWithUnknownComprehensionRequiredAttribute)2518*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest,
2519*d9f75844SAndroid Build Coastguard Worker TestHandleStunIndicationWithUnknownComprehensionRequiredAttribute) {
2520*d9f75844SAndroid Build Coastguard Worker // Generic set up.
2521*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr2, "lfrag", "lpass",
2522*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreakerDefault);
2523*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
2524*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreakerDefault);
2525*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2526*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2527*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
2528*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2529*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2530*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2531*d9f75844SAndroid Build Coastguard Worker
2532*d9f75844SAndroid Build Coastguard Worker // Generate indication with comprehension required attribute and verify it
2533*d9f75844SAndroid Build Coastguard Worker // doesn't update last_ping_received.
2534*d9f75844SAndroid Build Coastguard Worker auto in_msg = CreateStunMessage(STUN_BINDING_INDICATION);
2535*d9f75844SAndroid Build Coastguard Worker in_msg->AddAttribute(StunAttribute::CreateUInt32(0x7777));
2536*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2537*d9f75844SAndroid Build Coastguard Worker ByteBufferWriter buf;
2538*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, &buf);
2539*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(buf.Data(), buf.Length(), /* packet_time_us */ -1);
2540*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, lconn->last_ping_received());
2541*d9f75844SAndroid Build Coastguard Worker }
2542*d9f75844SAndroid Build Coastguard Worker
2543*d9f75844SAndroid Build Coastguard Worker // Test handling of STUN binding indication messages . STUN binding
2544*d9f75844SAndroid Build Coastguard Worker // indications are allowed only to the connection which is in read mode.
TEST_F(PortTest,TestHandleStunBindingIndication)2545*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestHandleStunBindingIndication) {
2546*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr2, "lfrag", "lpass",
2547*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2548*d9f75844SAndroid Build Coastguard Worker
2549*d9f75844SAndroid Build Coastguard Worker // Verifying encoding and decoding STUN indication message.
2550*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> in_msg, out_msg;
2551*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
2552*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress addr(kLocalAddr1);
2553*d9f75844SAndroid Build Coastguard Worker std::string username;
2554*d9f75844SAndroid Build Coastguard Worker
2555*d9f75844SAndroid Build Coastguard Worker in_msg = CreateStunMessage(STUN_BINDING_INDICATION);
2556*d9f75844SAndroid Build Coastguard Worker in_msg->AddFingerprint();
2557*d9f75844SAndroid Build Coastguard Worker WriteStunMessage(*in_msg, buf.get());
2558*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2559*d9f75844SAndroid Build Coastguard Worker &username));
2560*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(out_msg.get() != NULL);
2561*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2562*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("", username);
2563*d9f75844SAndroid Build Coastguard Worker
2564*d9f75844SAndroid Build Coastguard Worker // Verify connection can handle STUN indication and updates
2565*d9f75844SAndroid Build Coastguard Worker // last_ping_received.
2566*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2567*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2568*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreaker2);
2569*d9f75844SAndroid Build Coastguard Worker
2570*d9f75844SAndroid Build Coastguard Worker lport->PrepareAddress();
2571*d9f75844SAndroid Build Coastguard Worker rport->PrepareAddress();
2572*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(lport->Candidates().empty());
2573*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(rport->Candidates().empty());
2574*d9f75844SAndroid Build Coastguard Worker
2575*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2576*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2577*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2578*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2579*d9f75844SAndroid Build Coastguard Worker rconn->Ping(0);
2580*d9f75844SAndroid Build Coastguard Worker
2581*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
2582*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = rport->last_stun_msg();
2583*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2584*d9f75844SAndroid Build Coastguard Worker // Send rport binding request to lport.
2585*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
2586*d9f75844SAndroid Build Coastguard Worker rport->last_stun_buf()->size(), /* packet_time_us */ -1);
2587*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
2588*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
2589*d9f75844SAndroid Build Coastguard Worker int64_t last_ping_received1 = lconn->last_ping_received();
2590*d9f75844SAndroid Build Coastguard Worker
2591*d9f75844SAndroid Build Coastguard Worker // Adding a delay of 100ms.
2592*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(100);
2593*d9f75844SAndroid Build Coastguard Worker // Pinging lconn using stun indication message.
2594*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(buf->Data(), buf->Length(), /* packet_time_us */ -1);
2595*d9f75844SAndroid Build Coastguard Worker int64_t last_ping_received2 = lconn->last_ping_received();
2596*d9f75844SAndroid Build Coastguard Worker EXPECT_GT(last_ping_received2, last_ping_received1);
2597*d9f75844SAndroid Build Coastguard Worker }
2598*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestComputeCandidatePriority)2599*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestComputeCandidatePriority) {
2600*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr1, "name", "pass");
2601*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
2602*d9f75844SAndroid Build Coastguard Worker port->set_type_preference(90);
2603*d9f75844SAndroid Build Coastguard Worker port->set_component(177);
2604*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2605*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2606*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2607*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2608*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2609*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2610*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2611*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2612*d9f75844SAndroid Build Coastguard Worker port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2613*d9f75844SAndroid Build Coastguard Worker // These should all be:
2614*d9f75844SAndroid Build Coastguard Worker // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
2615*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_v4 = 1509957199U;
2616*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_v6 = 1509959759U;
2617*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_ula = 1509962319U;
2618*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_v4mapped = expected_priority_v4;
2619*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_v4compat = 1509949775U;
2620*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_6to4 = 1509954639U;
2621*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_teredo = 1509952079U;
2622*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_sitelocal = 1509949775U;
2623*d9f75844SAndroid Build Coastguard Worker uint32_t expected_priority_6bone = 1509949775U;
2624*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2625*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2626*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2627*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2628*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2629*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2630*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2631*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2632*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2633*d9f75844SAndroid Build Coastguard Worker }
2634*d9f75844SAndroid Build Coastguard Worker
2635*d9f75844SAndroid Build Coastguard Worker // In the case of shared socket, one port may be shared by local and stun.
2636*d9f75844SAndroid Build Coastguard Worker // Test that candidates with different types will have different foundation.
TEST_F(PortTest,TestFoundation)2637*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestFoundation) {
2638*d9f75844SAndroid Build Coastguard Worker auto testport = CreateTestPort(kLocalAddr1, "name", "pass");
2639*d9f75844SAndroid Build Coastguard Worker testport->SetIceTiebreaker(kTiebreakerDefault);
2640*d9f75844SAndroid Build Coastguard Worker testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1, LOCAL_PORT_TYPE,
2641*d9f75844SAndroid Build Coastguard Worker cricket::ICE_TYPE_PREFERENCE_HOST, false);
2642*d9f75844SAndroid Build Coastguard Worker testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1, STUN_PORT_TYPE,
2643*d9f75844SAndroid Build Coastguard Worker cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2644*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(testport->Candidates()[0].foundation(),
2645*d9f75844SAndroid Build Coastguard Worker testport->Candidates()[1].foundation());
2646*d9f75844SAndroid Build Coastguard Worker }
2647*d9f75844SAndroid Build Coastguard Worker
2648*d9f75844SAndroid Build Coastguard Worker // This test verifies the foundation of different types of ICE candidates.
TEST_F(PortTest,TestCandidateFoundation)2649*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestCandidateFoundation) {
2650*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::NATServer> nat_server(
2651*d9f75844SAndroid Build Coastguard Worker CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2652*d9f75844SAndroid Build Coastguard Worker auto udpport1 = CreateUdpPort(kLocalAddr1);
2653*d9f75844SAndroid Build Coastguard Worker udpport1->PrepareAddress();
2654*d9f75844SAndroid Build Coastguard Worker auto udpport2 = CreateUdpPort(kLocalAddr1);
2655*d9f75844SAndroid Build Coastguard Worker udpport2->PrepareAddress();
2656*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2657*d9f75844SAndroid Build Coastguard Worker udpport2->Candidates()[0].foundation());
2658*d9f75844SAndroid Build Coastguard Worker auto tcpport1 = CreateTcpPort(kLocalAddr1);
2659*d9f75844SAndroid Build Coastguard Worker tcpport1->PrepareAddress();
2660*d9f75844SAndroid Build Coastguard Worker auto tcpport2 = CreateTcpPort(kLocalAddr1);
2661*d9f75844SAndroid Build Coastguard Worker tcpport2->PrepareAddress();
2662*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2663*d9f75844SAndroid Build Coastguard Worker tcpport2->Candidates()[0].foundation());
2664*d9f75844SAndroid Build Coastguard Worker auto stunport = CreateStunPort(kLocalAddr1, nat_socket_factory1());
2665*d9f75844SAndroid Build Coastguard Worker stunport->PrepareAddress();
2666*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
2667*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2668*d9f75844SAndroid Build Coastguard Worker stunport->Candidates()[0].foundation());
2669*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2670*d9f75844SAndroid Build Coastguard Worker stunport->Candidates()[0].foundation());
2671*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(udpport1->Candidates()[0].foundation(),
2672*d9f75844SAndroid Build Coastguard Worker stunport->Candidates()[0].foundation());
2673*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(udpport2->Candidates()[0].foundation(),
2674*d9f75844SAndroid Build Coastguard Worker stunport->Candidates()[0].foundation());
2675*d9f75844SAndroid Build Coastguard Worker // Verifying TURN candidate foundation.
2676*d9f75844SAndroid Build Coastguard Worker auto turnport1 =
2677*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
2678*d9f75844SAndroid Build Coastguard Worker turnport1->PrepareAddress();
2679*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kDefaultTimeout);
2680*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(udpport1->Candidates()[0].foundation(),
2681*d9f75844SAndroid Build Coastguard Worker turnport1->Candidates()[0].foundation());
2682*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(udpport2->Candidates()[0].foundation(),
2683*d9f75844SAndroid Build Coastguard Worker turnport1->Candidates()[0].foundation());
2684*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(stunport->Candidates()[0].foundation(),
2685*d9f75844SAndroid Build Coastguard Worker turnport1->Candidates()[0].foundation());
2686*d9f75844SAndroid Build Coastguard Worker auto turnport2 =
2687*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
2688*d9f75844SAndroid Build Coastguard Worker turnport2->PrepareAddress();
2689*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kDefaultTimeout);
2690*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2691*d9f75844SAndroid Build Coastguard Worker turnport2->Candidates()[0].foundation());
2692*d9f75844SAndroid Build Coastguard Worker
2693*d9f75844SAndroid Build Coastguard Worker // Running a second turn server, to get different base IP address.
2694*d9f75844SAndroid Build Coastguard Worker SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2695*d9f75844SAndroid Build Coastguard Worker SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2696*d9f75844SAndroid Build Coastguard Worker TestTurnServer turn_server2(rtc::Thread::Current(), vss(), kTurnUdpIntAddr2,
2697*d9f75844SAndroid Build Coastguard Worker kTurnUdpExtAddr2);
2698*d9f75844SAndroid Build Coastguard Worker auto turnport3 = CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP,
2699*d9f75844SAndroid Build Coastguard Worker PROTO_UDP, kTurnUdpIntAddr2);
2700*d9f75844SAndroid Build Coastguard Worker turnport3->PrepareAddress();
2701*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kDefaultTimeout);
2702*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(turnport3->Candidates()[0].foundation(),
2703*d9f75844SAndroid Build Coastguard Worker turnport2->Candidates()[0].foundation());
2704*d9f75844SAndroid Build Coastguard Worker
2705*d9f75844SAndroid Build Coastguard Worker // Start a TCP turn server, and check that two turn candidates have
2706*d9f75844SAndroid Build Coastguard Worker // different foundations if their relay protocols are different.
2707*d9f75844SAndroid Build Coastguard Worker TestTurnServer turn_server3(rtc::Thread::Current(), vss(), kTurnTcpIntAddr,
2708*d9f75844SAndroid Build Coastguard Worker kTurnUdpExtAddr, PROTO_TCP);
2709*d9f75844SAndroid Build Coastguard Worker auto turnport4 =
2710*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_TCP, PROTO_UDP);
2711*d9f75844SAndroid Build Coastguard Worker turnport4->PrepareAddress();
2712*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, turnport4->Candidates().size(), kDefaultTimeout);
2713*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(turnport2->Candidates()[0].foundation(),
2714*d9f75844SAndroid Build Coastguard Worker turnport4->Candidates()[0].foundation());
2715*d9f75844SAndroid Build Coastguard Worker }
2716*d9f75844SAndroid Build Coastguard Worker
2717*d9f75844SAndroid Build Coastguard Worker // This test verifies the related addresses of different types of
2718*d9f75844SAndroid Build Coastguard Worker // ICE candidates.
TEST_F(PortTest,TestCandidateRelatedAddress)2719*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestCandidateRelatedAddress) {
2720*d9f75844SAndroid Build Coastguard Worker auto nat_server = CreateNatServer(kNatAddr1, NAT_OPEN_CONE);
2721*d9f75844SAndroid Build Coastguard Worker auto udpport = CreateUdpPort(kLocalAddr1);
2722*d9f75844SAndroid Build Coastguard Worker udpport->PrepareAddress();
2723*d9f75844SAndroid Build Coastguard Worker // For UDPPort, related address will be empty.
2724*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2725*d9f75844SAndroid Build Coastguard Worker // Testing related address for stun candidates.
2726*d9f75844SAndroid Build Coastguard Worker // For stun candidate related address must be equal to the base
2727*d9f75844SAndroid Build Coastguard Worker // socket address.
2728*d9f75844SAndroid Build Coastguard Worker auto stunport = CreateStunPort(kLocalAddr1, nat_socket_factory1());
2729*d9f75844SAndroid Build Coastguard Worker stunport->PrepareAddress();
2730*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
2731*d9f75844SAndroid Build Coastguard Worker // Check STUN candidate address.
2732*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(), kNatAddr1.ipaddr());
2733*d9f75844SAndroid Build Coastguard Worker // Check STUN candidate related address.
2734*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stunport->Candidates()[0].related_address(),
2735*d9f75844SAndroid Build Coastguard Worker stunport->GetLocalAddress());
2736*d9f75844SAndroid Build Coastguard Worker // Verifying the related address for TURN candidate.
2737*d9f75844SAndroid Build Coastguard Worker // For TURN related address must be equal to the mapped address.
2738*d9f75844SAndroid Build Coastguard Worker auto turnport =
2739*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
2740*d9f75844SAndroid Build Coastguard Worker turnport->PrepareAddress();
2741*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kDefaultTimeout);
2742*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
2743*d9f75844SAndroid Build Coastguard Worker turnport->Candidates()[0].address().ipaddr());
2744*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kNatAddr1.ipaddr(),
2745*d9f75844SAndroid Build Coastguard Worker turnport->Candidates()[0].related_address().ipaddr());
2746*d9f75844SAndroid Build Coastguard Worker }
2747*d9f75844SAndroid Build Coastguard Worker
2748*d9f75844SAndroid Build Coastguard Worker // Test priority value overflow handling when preference is set to 3.
TEST_F(PortTest,TestCandidatePriority)2749*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestCandidatePriority) {
2750*d9f75844SAndroid Build Coastguard Worker cricket::Candidate cand1;
2751*d9f75844SAndroid Build Coastguard Worker cand1.set_priority(3);
2752*d9f75844SAndroid Build Coastguard Worker cricket::Candidate cand2;
2753*d9f75844SAndroid Build Coastguard Worker cand2.set_priority(1);
2754*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(cand1.priority() > cand2.priority());
2755*d9f75844SAndroid Build Coastguard Worker }
2756*d9f75844SAndroid Build Coastguard Worker
2757*d9f75844SAndroid Build Coastguard Worker // Test the Connection priority is calculated correctly.
TEST_F(PortTest,TestConnectionPriority)2758*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestConnectionPriority) {
2759*d9f75844SAndroid Build Coastguard Worker auto lport = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
2760*d9f75844SAndroid Build Coastguard Worker lport->SetIceTiebreaker(kTiebreakerDefault);
2761*d9f75844SAndroid Build Coastguard Worker lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
2762*d9f75844SAndroid Build Coastguard Worker
2763*d9f75844SAndroid Build Coastguard Worker auto rport = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
2764*d9f75844SAndroid Build Coastguard Worker rport->SetIceTiebreaker(kTiebreakerDefault);
2765*d9f75844SAndroid Build Coastguard Worker rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY_UDP);
2766*d9f75844SAndroid Build Coastguard Worker lport->set_component(123);
2767*d9f75844SAndroid Build Coastguard Worker lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2768*d9f75844SAndroid Build Coastguard Worker rport->set_component(23);
2769*d9f75844SAndroid Build Coastguard Worker rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2770*d9f75844SAndroid Build Coastguard Worker
2771*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2772*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2773*d9f75844SAndroid Build Coastguard Worker
2774*d9f75844SAndroid Build Coastguard Worker // RFC 5245
2775*d9f75844SAndroid Build Coastguard Worker // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
2776*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2777*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2778*d9f75844SAndroid Build Coastguard Worker Connection* lconn =
2779*d9f75844SAndroid Build Coastguard Worker lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2780*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
2781*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2782*d9f75844SAndroid Build Coastguard Worker #else
2783*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2784*d9f75844SAndroid Build Coastguard Worker #endif
2785*d9f75844SAndroid Build Coastguard Worker
2786*d9f75844SAndroid Build Coastguard Worker lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2787*d9f75844SAndroid Build Coastguard Worker rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2788*d9f75844SAndroid Build Coastguard Worker Connection* rconn =
2789*d9f75844SAndroid Build Coastguard Worker rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2790*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
2791*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2792*d9f75844SAndroid Build Coastguard Worker #else
2793*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2794*d9f75844SAndroid Build Coastguard Worker #endif
2795*d9f75844SAndroid Build Coastguard Worker }
2796*d9f75844SAndroid Build Coastguard Worker
2797*d9f75844SAndroid Build Coastguard Worker // Note that UpdateState takes into account the estimated RTT, and the
2798*d9f75844SAndroid Build Coastguard Worker // correctness of using `kMaxExpectedSimulatedRtt` as an upper bound of RTT in
2799*d9f75844SAndroid Build Coastguard Worker // the following tests depends on the link rate and the delay distriubtion
2800*d9f75844SAndroid Build Coastguard Worker // configured in VirtualSocketServer::AddPacketToNetwork. The tests below use
2801*d9f75844SAndroid Build Coastguard Worker // the default setup where the RTT is deterministically one, which generates an
2802*d9f75844SAndroid Build Coastguard Worker // estimate given by `MINIMUM_RTT` = 100.
TEST_F(PortTest,TestWritableState)2803*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestWritableState) {
2804*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
2805*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
2806*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2807*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
2808*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2809*d9f75844SAndroid Build Coastguard Worker
2810*d9f75844SAndroid Build Coastguard Worker // Set up channels.
2811*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
2812*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
2813*d9f75844SAndroid Build Coastguard Worker
2814*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
2815*d9f75844SAndroid Build Coastguard Worker ch1.Start();
2816*d9f75844SAndroid Build Coastguard Worker ch2.Start();
2817*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
2818*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
2819*d9f75844SAndroid Build Coastguard Worker
2820*d9f75844SAndroid Build Coastguard Worker // Send a ping from src to dst.
2821*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
2822*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
2823*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2824*d9f75844SAndroid Build Coastguard Worker // for TCP connect
2825*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout, clock);
2826*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
2827*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
2828*d9f75844SAndroid Build Coastguard Worker
2829*d9f75844SAndroid Build Coastguard Worker // Data should be sendable before the connection is accepted.
2830*d9f75844SAndroid Build Coastguard Worker char data[] = "abcd";
2831*d9f75844SAndroid Build Coastguard Worker int data_size = arraysize(data);
2832*d9f75844SAndroid Build Coastguard Worker rtc::PacketOptions options;
2833*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2834*d9f75844SAndroid Build Coastguard Worker
2835*d9f75844SAndroid Build Coastguard Worker // Accept the connection to return the binding response, transition to
2836*d9f75844SAndroid Build Coastguard Worker // writable, and allow data to be sent.
2837*d9f75844SAndroid Build Coastguard Worker ch2.AcceptConnection(GetCandidate(ch1.port()));
2838*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2839*d9f75844SAndroid Build Coastguard Worker ch1.conn()->write_state(), kDefaultTimeout, clock);
2840*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2841*d9f75844SAndroid Build Coastguard Worker
2842*d9f75844SAndroid Build Coastguard Worker // Ask the connection to update state as if enough time has passed to lose
2843*d9f75844SAndroid Build Coastguard Worker // full writability and 5 pings went unresponded to. We'll accomplish the
2844*d9f75844SAndroid Build Coastguard Worker // latter by sending pings but not pumping messages.
2845*d9f75844SAndroid Build Coastguard Worker for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2846*d9f75844SAndroid Build Coastguard Worker ch1.Ping(i);
2847*d9f75844SAndroid Build Coastguard Worker }
2848*d9f75844SAndroid Build Coastguard Worker int unreliable_timeout_delay =
2849*d9f75844SAndroid Build Coastguard Worker CONNECTION_WRITE_CONNECT_TIMEOUT + kMaxExpectedSimulatedRtt;
2850*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(unreliable_timeout_delay);
2851*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2852*d9f75844SAndroid Build Coastguard Worker
2853*d9f75844SAndroid Build Coastguard Worker // Data should be able to be sent in this state.
2854*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2855*d9f75844SAndroid Build Coastguard Worker
2856*d9f75844SAndroid Build Coastguard Worker // And now allow the other side to process the pings and send binding
2857*d9f75844SAndroid Build Coastguard Worker // responses.
2858*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2859*d9f75844SAndroid Build Coastguard Worker ch1.conn()->write_state(), kDefaultTimeout, clock);
2860*d9f75844SAndroid Build Coastguard Worker // Wait long enough for a full timeout (past however long we've already
2861*d9f75844SAndroid Build Coastguard Worker // waited).
2862*d9f75844SAndroid Build Coastguard Worker for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2863*d9f75844SAndroid Build Coastguard Worker ch1.Ping(unreliable_timeout_delay + i);
2864*d9f75844SAndroid Build Coastguard Worker }
2865*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2866*d9f75844SAndroid Build Coastguard Worker kMaxExpectedSimulatedRtt);
2867*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2868*d9f75844SAndroid Build Coastguard Worker
2869*d9f75844SAndroid Build Coastguard Worker // Even if the connection has timed out, the Connection shouldn't block
2870*d9f75844SAndroid Build Coastguard Worker // the sending of data.
2871*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2872*d9f75844SAndroid Build Coastguard Worker
2873*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
2874*d9f75844SAndroid Build Coastguard Worker ch2.Stop();
2875*d9f75844SAndroid Build Coastguard Worker }
2876*d9f75844SAndroid Build Coastguard Worker
2877*d9f75844SAndroid Build Coastguard Worker // Test writability states using the configured threshold value to replace
2878*d9f75844SAndroid Build Coastguard Worker // the default value given by `CONNECTION_WRITE_CONNECT_TIMEOUT` and
2879*d9f75844SAndroid Build Coastguard Worker // `CONNECTION_WRITE_CONNECT_FAILURES`.
TEST_F(PortTest,TestWritableStateWithConfiguredThreshold)2880*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestWritableStateWithConfiguredThreshold) {
2881*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
2882*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
2883*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2884*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
2885*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2886*d9f75844SAndroid Build Coastguard Worker
2887*d9f75844SAndroid Build Coastguard Worker // Set up channels.
2888*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
2889*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
2890*d9f75844SAndroid Build Coastguard Worker
2891*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
2892*d9f75844SAndroid Build Coastguard Worker ch1.Start();
2893*d9f75844SAndroid Build Coastguard Worker ch2.Start();
2894*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
2895*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
2896*d9f75844SAndroid Build Coastguard Worker
2897*d9f75844SAndroid Build Coastguard Worker // Send a ping from src to dst.
2898*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
2899*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
2900*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
2901*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
2902*d9f75844SAndroid Build Coastguard Worker
2903*d9f75844SAndroid Build Coastguard Worker // Accept the connection to return the binding response, transition to
2904*d9f75844SAndroid Build Coastguard Worker // writable, and allow data to be sent.
2905*d9f75844SAndroid Build Coastguard Worker ch2.AcceptConnection(GetCandidate(ch1.port()));
2906*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2907*d9f75844SAndroid Build Coastguard Worker ch1.conn()->write_state(), kDefaultTimeout, clock);
2908*d9f75844SAndroid Build Coastguard Worker
2909*d9f75844SAndroid Build Coastguard Worker ch1.conn()->set_unwritable_timeout(1000);
2910*d9f75844SAndroid Build Coastguard Worker ch1.conn()->set_unwritable_min_checks(3);
2911*d9f75844SAndroid Build Coastguard Worker // Send two checks.
2912*d9f75844SAndroid Build Coastguard Worker ch1.Ping(1);
2913*d9f75844SAndroid Build Coastguard Worker ch1.Ping(2);
2914*d9f75844SAndroid Build Coastguard Worker // We have not reached the timeout nor have we sent the minimum number of
2915*d9f75844SAndroid Build Coastguard Worker // checks to change the state to Unreliable.
2916*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(999);
2917*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
2918*d9f75844SAndroid Build Coastguard Worker // We have not sent the minimum number of checks without responses.
2919*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(1000 + kMaxExpectedSimulatedRtt);
2920*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
2921*d9f75844SAndroid Build Coastguard Worker // Last ping after which the candidate pair should become Unreliable after
2922*d9f75844SAndroid Build Coastguard Worker // timeout.
2923*d9f75844SAndroid Build Coastguard Worker ch1.Ping(3);
2924*d9f75844SAndroid Build Coastguard Worker // We have not reached the timeout.
2925*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(999);
2926*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
2927*d9f75844SAndroid Build Coastguard Worker // We should be in the state Unreliable now.
2928*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(1000 + kMaxExpectedSimulatedRtt);
2929*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2930*d9f75844SAndroid Build Coastguard Worker
2931*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
2932*d9f75844SAndroid Build Coastguard Worker ch2.Stop();
2933*d9f75844SAndroid Build Coastguard Worker }
2934*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestTimeoutForNeverWritable)2935*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestTimeoutForNeverWritable) {
2936*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
2937*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2938*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
2939*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2940*d9f75844SAndroid Build Coastguard Worker
2941*d9f75844SAndroid Build Coastguard Worker // Set up channels.
2942*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
2943*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
2944*d9f75844SAndroid Build Coastguard Worker
2945*d9f75844SAndroid Build Coastguard Worker // Acquire addresses.
2946*d9f75844SAndroid Build Coastguard Worker ch1.Start();
2947*d9f75844SAndroid Build Coastguard Worker ch2.Start();
2948*d9f75844SAndroid Build Coastguard Worker
2949*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
2950*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
2951*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2952*d9f75844SAndroid Build Coastguard Worker
2953*d9f75844SAndroid Build Coastguard Worker // Attempt to go directly to write timeout.
2954*d9f75844SAndroid Build Coastguard Worker for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2955*d9f75844SAndroid Build Coastguard Worker ch1.Ping(i);
2956*d9f75844SAndroid Build Coastguard Worker }
2957*d9f75844SAndroid Build Coastguard Worker ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + kMaxExpectedSimulatedRtt);
2958*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2959*d9f75844SAndroid Build Coastguard Worker }
2960*d9f75844SAndroid Build Coastguard Worker
2961*d9f75844SAndroid Build Coastguard Worker // This test verifies the connection setup between ICEMODE_FULL
2962*d9f75844SAndroid Build Coastguard Worker // and ICEMODE_LITE.
2963*d9f75844SAndroid Build Coastguard Worker // In this test `ch1` behaves like FULL mode client and we have created
2964*d9f75844SAndroid Build Coastguard Worker // port which responds to the ping message just like LITE client.
TEST_F(PortTest,TestIceLiteConnectivity)2965*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestIceLiteConnectivity) {
2966*d9f75844SAndroid Build Coastguard Worker auto ice_full_port =
2967*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
2968*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2969*d9f75844SAndroid Build Coastguard Worker auto* ice_full_port_ptr = ice_full_port.get();
2970*d9f75844SAndroid Build Coastguard Worker
2971*d9f75844SAndroid Build Coastguard Worker auto ice_lite_port = CreateTestPort(
2972*d9f75844SAndroid Build Coastguard Worker kLocalAddr2, "rfrag", "rpass", cricket::ICEROLE_CONTROLLED, kTiebreaker2);
2973*d9f75844SAndroid Build Coastguard Worker // Setup TestChannel. This behaves like FULL mode client.
2974*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(ice_full_port));
2975*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_FULL);
2976*d9f75844SAndroid Build Coastguard Worker
2977*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
2978*d9f75844SAndroid Build Coastguard Worker ch1.Start();
2979*d9f75844SAndroid Build Coastguard Worker ice_lite_port->PrepareAddress();
2980*d9f75844SAndroid Build Coastguard Worker
2981*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
2982*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(ice_lite_port->Candidates().empty());
2983*d9f75844SAndroid Build Coastguard Worker
2984*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ice_lite_port.get()));
2985*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
2986*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2987*d9f75844SAndroid Build Coastguard Worker
2988*d9f75844SAndroid Build Coastguard Worker // Send ping from full mode client.
2989*d9f75844SAndroid Build Coastguard Worker // This ping must not have USE_CANDIDATE_ATTR.
2990*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
2991*d9f75844SAndroid Build Coastguard Worker
2992*d9f75844SAndroid Build Coastguard Worker // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2993*d9f75844SAndroid Build Coastguard Worker // from port.
2994*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(ice_full_port_ptr->last_stun_msg() != NULL, kDefaultTimeout);
2995*d9f75844SAndroid Build Coastguard Worker IceMessage* msg = ice_full_port_ptr->last_stun_msg();
2996*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2997*d9f75844SAndroid Build Coastguard Worker
2998*d9f75844SAndroid Build Coastguard Worker // Respond with a BINDING-RESPONSE from litemode client.
2999*d9f75844SAndroid Build Coastguard Worker // NOTE: Ideally we should't create connection at this stage from lite
3000*d9f75844SAndroid Build Coastguard Worker // port, as it should be done only after receiving ping with USE_CANDIDATE.
3001*d9f75844SAndroid Build Coastguard Worker // But we need a connection to send a response message.
3002*d9f75844SAndroid Build Coastguard Worker auto* con = ice_lite_port->CreateConnection(
3003*d9f75844SAndroid Build Coastguard Worker ice_full_port_ptr->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
3004*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<IceMessage> request = CopyStunMessage(*msg);
3005*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(request.get());
3006*d9f75844SAndroid Build Coastguard Worker
3007*d9f75844SAndroid Build Coastguard Worker // Feeding the respone message from litemode to the full mode connection.
3008*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->data<char>(),
3009*d9f75844SAndroid Build Coastguard Worker ice_lite_port->last_stun_buf()->size(),
3010*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3011*d9f75844SAndroid Build Coastguard Worker // Verifying full mode connection becomes writable from the response.
3012*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
3013*d9f75844SAndroid Build Coastguard Worker kDefaultTimeout);
3014*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(ch1.nominated(), kDefaultTimeout);
3015*d9f75844SAndroid Build Coastguard Worker
3016*d9f75844SAndroid Build Coastguard Worker // Clear existing stun messsages. Otherwise we will process old stun
3017*d9f75844SAndroid Build Coastguard Worker // message right after we send ping.
3018*d9f75844SAndroid Build Coastguard Worker ice_full_port_ptr->Reset();
3019*d9f75844SAndroid Build Coastguard Worker // Send ping. This must have USE_CANDIDATE_ATTR.
3020*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3021*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(ice_full_port_ptr->last_stun_msg() != NULL, kDefaultTimeout);
3022*d9f75844SAndroid Build Coastguard Worker msg = ice_full_port_ptr->last_stun_msg();
3023*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
3024*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3025*d9f75844SAndroid Build Coastguard Worker }
3026*d9f75844SAndroid Build Coastguard Worker
3027*d9f75844SAndroid Build Coastguard Worker namespace {
3028*d9f75844SAndroid Build Coastguard Worker
3029*d9f75844SAndroid Build Coastguard Worker // Utility function for testing goog ping.
GetSupportedGoogPingVersion(const StunMessage * msg)3030*d9f75844SAndroid Build Coastguard Worker absl::optional<int> GetSupportedGoogPingVersion(const StunMessage* msg) {
3031*d9f75844SAndroid Build Coastguard Worker auto goog_misc = msg->GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
3032*d9f75844SAndroid Build Coastguard Worker if (goog_misc == nullptr) {
3033*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
3034*d9f75844SAndroid Build Coastguard Worker }
3035*d9f75844SAndroid Build Coastguard Worker
3036*d9f75844SAndroid Build Coastguard Worker if (msg->type() == STUN_BINDING_REQUEST) {
3037*d9f75844SAndroid Build Coastguard Worker if (goog_misc->Size() <
3038*d9f75844SAndroid Build Coastguard Worker static_cast<int>(cricket::IceGoogMiscInfoBindingRequestAttributeIndex::
3039*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION)) {
3040*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
3041*d9f75844SAndroid Build Coastguard Worker }
3042*d9f75844SAndroid Build Coastguard Worker
3043*d9f75844SAndroid Build Coastguard Worker return goog_misc->GetType(
3044*d9f75844SAndroid Build Coastguard Worker static_cast<int>(cricket::IceGoogMiscInfoBindingRequestAttributeIndex::
3045*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION));
3046*d9f75844SAndroid Build Coastguard Worker }
3047*d9f75844SAndroid Build Coastguard Worker
3048*d9f75844SAndroid Build Coastguard Worker if (msg->type() == STUN_BINDING_RESPONSE) {
3049*d9f75844SAndroid Build Coastguard Worker if (goog_misc->Size() <
3050*d9f75844SAndroid Build Coastguard Worker static_cast<int>(cricket::IceGoogMiscInfoBindingResponseAttributeIndex::
3051*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION)) {
3052*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
3053*d9f75844SAndroid Build Coastguard Worker }
3054*d9f75844SAndroid Build Coastguard Worker
3055*d9f75844SAndroid Build Coastguard Worker return goog_misc->GetType(
3056*d9f75844SAndroid Build Coastguard Worker static_cast<int>(cricket::IceGoogMiscInfoBindingResponseAttributeIndex::
3057*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION));
3058*d9f75844SAndroid Build Coastguard Worker }
3059*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
3060*d9f75844SAndroid Build Coastguard Worker }
3061*d9f75844SAndroid Build Coastguard Worker
3062*d9f75844SAndroid Build Coastguard Worker } // namespace
3063*d9f75844SAndroid Build Coastguard Worker
3064*d9f75844SAndroid Build Coastguard Worker class GoogPingTest
3065*d9f75844SAndroid Build Coastguard Worker : public PortTest,
3066*d9f75844SAndroid Build Coastguard Worker public ::testing::WithParamInterface<std::pair<bool, bool>> {};
3067*d9f75844SAndroid Build Coastguard Worker
3068*d9f75844SAndroid Build Coastguard Worker // This test verifies the announce/enable on/off behavior
TEST_P(GoogPingTest,TestGoogPingAnnounceEnable)3069*d9f75844SAndroid Build Coastguard Worker TEST_P(GoogPingTest, TestGoogPingAnnounceEnable) {
3070*d9f75844SAndroid Build Coastguard Worker IceFieldTrials trials;
3071*d9f75844SAndroid Build Coastguard Worker trials.announce_goog_ping = GetParam().first;
3072*d9f75844SAndroid Build Coastguard Worker trials.enable_goog_ping = GetParam().second;
3073*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Testing combination: "
3074*d9f75844SAndroid Build Coastguard Worker " announce: "
3075*d9f75844SAndroid Build Coastguard Worker << trials.announce_goog_ping
3076*d9f75844SAndroid Build Coastguard Worker << " enable:" << trials.enable_goog_ping;
3077*d9f75844SAndroid Build Coastguard Worker
3078*d9f75844SAndroid Build Coastguard Worker auto port1_unique =
3079*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
3080*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
3081*d9f75844SAndroid Build Coastguard Worker auto* port1 = port1_unique.get();
3082*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
3083*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreaker2);
3084*d9f75844SAndroid Build Coastguard Worker
3085*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1_unique));
3086*d9f75844SAndroid Build Coastguard Worker // Block usage of STUN_ATTR_USE_CANDIDATE so that
3087*d9f75844SAndroid Build Coastguard Worker // ch1.conn() will sent GOOG_PING_REQUEST directly.
3088*d9f75844SAndroid Build Coastguard Worker // This only makes test a bit shorter...
3089*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_LITE);
3090*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
3091*d9f75844SAndroid Build Coastguard Worker ch1.Start();
3092*d9f75844SAndroid Build Coastguard Worker port2->PrepareAddress();
3093*d9f75844SAndroid Build Coastguard Worker
3094*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
3095*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(port2->Candidates().empty());
3096*d9f75844SAndroid Build Coastguard Worker
3097*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(port2.get()));
3098*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
3099*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
3100*d9f75844SAndroid Build Coastguard Worker ch1.conn()->SetIceFieldTrials(&trials);
3101*d9f75844SAndroid Build Coastguard Worker
3102*d9f75844SAndroid Build Coastguard Worker // Send ping.
3103*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3104*d9f75844SAndroid Build Coastguard Worker
3105*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3106*d9f75844SAndroid Build Coastguard Worker const IceMessage* request1 = port1->last_stun_msg();
3107*d9f75844SAndroid Build Coastguard Worker
3108*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(trials.enable_goog_ping,
3109*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(request1) &&
3110*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(request1) >= kGoogPingVersion);
3111*d9f75844SAndroid Build Coastguard Worker
3112*d9f75844SAndroid Build Coastguard Worker auto* con = port2->CreateConnection(port1->Candidates()[0],
3113*d9f75844SAndroid Build Coastguard Worker cricket::Port::ORIGIN_MESSAGE);
3114*d9f75844SAndroid Build Coastguard Worker con->SetIceFieldTrials(&trials);
3115*d9f75844SAndroid Build Coastguard Worker
3116*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(request1);
3117*d9f75844SAndroid Build Coastguard Worker
3118*d9f75844SAndroid Build Coastguard Worker // Then check the response matches the settings.
3119*d9f75844SAndroid Build Coastguard Worker const auto* response = port2->last_stun_msg();
3120*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(response->type(), STUN_BINDING_RESPONSE);
3121*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(trials.enable_goog_ping && trials.announce_goog_ping,
3122*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(response) &&
3123*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(response) >= kGoogPingVersion);
3124*d9f75844SAndroid Build Coastguard Worker
3125*d9f75844SAndroid Build Coastguard Worker // Feeding the respone message back.
3126*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(port2->last_stun_buf()->data<char>(),
3127*d9f75844SAndroid Build Coastguard Worker port2->last_stun_buf()->size(),
3128*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3129*d9f75844SAndroid Build Coastguard Worker
3130*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3131*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3132*d9f75844SAndroid Build Coastguard Worker
3133*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3134*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3135*d9f75844SAndroid Build Coastguard Worker const IceMessage* request2 = port1->last_stun_msg();
3136*d9f75844SAndroid Build Coastguard Worker
3137*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING if both of these are TRUE
3138*d9f75844SAndroid Build Coastguard Worker if (trials.announce_goog_ping && trials.enable_goog_ping) {
3139*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(request2->type(), GOOG_PING_REQUEST);
3140*d9f75844SAndroid Build Coastguard Worker con->SendGoogPingResponse(request2);
3141*d9f75844SAndroid Build Coastguard Worker } else {
3142*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(request2->type(), STUN_BINDING_REQUEST);
3143*d9f75844SAndroid Build Coastguard Worker // If we sent a BINDING with enable, and we got a reply that
3144*d9f75844SAndroid Build Coastguard Worker // didn't contain announce, the next ping should not contain
3145*d9f75844SAndroid Build Coastguard Worker // the enable again.
3146*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(GetSupportedGoogPingVersion(request2).has_value());
3147*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(request2);
3148*d9f75844SAndroid Build Coastguard Worker }
3149*d9f75844SAndroid Build Coastguard Worker
3150*d9f75844SAndroid Build Coastguard Worker const auto* response2 = port2->last_stun_msg();
3151*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(response2 != nullptr);
3152*d9f75844SAndroid Build Coastguard Worker
3153*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING_RESPONSE if both of these are TRUE
3154*d9f75844SAndroid Build Coastguard Worker if (trials.announce_goog_ping && trials.enable_goog_ping) {
3155*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response2->type(), GOOG_PING_RESPONSE);
3156*d9f75844SAndroid Build Coastguard Worker } else {
3157*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response2->type(), STUN_BINDING_RESPONSE);
3158*d9f75844SAndroid Build Coastguard Worker }
3159*d9f75844SAndroid Build Coastguard Worker
3160*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3161*d9f75844SAndroid Build Coastguard Worker }
3162*d9f75844SAndroid Build Coastguard Worker
3163*d9f75844SAndroid Build Coastguard Worker // This test if a someone send a STUN_BINDING with unsupported version
3164*d9f75844SAndroid Build Coastguard Worker // (kGoogPingVersion == 0)
TEST_F(PortTest,TestGoogPingUnsupportedVersionInStunBinding)3165*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestGoogPingUnsupportedVersionInStunBinding) {
3166*d9f75844SAndroid Build Coastguard Worker IceFieldTrials trials;
3167*d9f75844SAndroid Build Coastguard Worker trials.announce_goog_ping = true;
3168*d9f75844SAndroid Build Coastguard Worker trials.enable_goog_ping = true;
3169*d9f75844SAndroid Build Coastguard Worker
3170*d9f75844SAndroid Build Coastguard Worker auto port1_unique =
3171*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
3172*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
3173*d9f75844SAndroid Build Coastguard Worker auto* port1 = port1_unique.get();
3174*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
3175*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreaker2);
3176*d9f75844SAndroid Build Coastguard Worker
3177*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1_unique));
3178*d9f75844SAndroid Build Coastguard Worker // Block usage of STUN_ATTR_USE_CANDIDATE so that
3179*d9f75844SAndroid Build Coastguard Worker // ch1.conn() will sent GOOG_PING_REQUEST directly.
3180*d9f75844SAndroid Build Coastguard Worker // This only makes test a bit shorter...
3181*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_LITE);
3182*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
3183*d9f75844SAndroid Build Coastguard Worker ch1.Start();
3184*d9f75844SAndroid Build Coastguard Worker port2->PrepareAddress();
3185*d9f75844SAndroid Build Coastguard Worker
3186*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
3187*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(port2->Candidates().empty());
3188*d9f75844SAndroid Build Coastguard Worker
3189*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(port2.get()));
3190*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
3191*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
3192*d9f75844SAndroid Build Coastguard Worker ch1.conn()->SetIceFieldTrials(&trials);
3193*d9f75844SAndroid Build Coastguard Worker
3194*d9f75844SAndroid Build Coastguard Worker // Send ping.
3195*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3196*d9f75844SAndroid Build Coastguard Worker
3197*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3198*d9f75844SAndroid Build Coastguard Worker const IceMessage* request1 = port1->last_stun_msg();
3199*d9f75844SAndroid Build Coastguard Worker
3200*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(GetSupportedGoogPingVersion(request1) &&
3201*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(request1) >= kGoogPingVersion);
3202*d9f75844SAndroid Build Coastguard Worker
3203*d9f75844SAndroid Build Coastguard Worker // Modify the STUN message request1 to send GetSupportedGoogPingVersion == 0
3204*d9f75844SAndroid Build Coastguard Worker auto modified_request1 = request1->Clone();
3205*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(modified_request1->RemoveAttribute(STUN_ATTR_GOOG_MISC_INFO) !=
3206*d9f75844SAndroid Build Coastguard Worker nullptr);
3207*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(modified_request1->RemoveAttribute(STUN_ATTR_MESSAGE_INTEGRITY) !=
3208*d9f75844SAndroid Build Coastguard Worker nullptr);
3209*d9f75844SAndroid Build Coastguard Worker {
3210*d9f75844SAndroid Build Coastguard Worker auto list =
3211*d9f75844SAndroid Build Coastguard Worker StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
3212*d9f75844SAndroid Build Coastguard Worker list->AddTypeAtIndex(
3213*d9f75844SAndroid Build Coastguard Worker static_cast<uint16_t>(
3214*d9f75844SAndroid Build Coastguard Worker cricket::IceGoogMiscInfoBindingRequestAttributeIndex::
3215*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION),
3216*d9f75844SAndroid Build Coastguard Worker /* version */ 0);
3217*d9f75844SAndroid Build Coastguard Worker modified_request1->AddAttribute(std::move(list));
3218*d9f75844SAndroid Build Coastguard Worker modified_request1->AddMessageIntegrity("rpass");
3219*d9f75844SAndroid Build Coastguard Worker }
3220*d9f75844SAndroid Build Coastguard Worker auto* con = port2->CreateConnection(port1->Candidates()[0],
3221*d9f75844SAndroid Build Coastguard Worker cricket::Port::ORIGIN_MESSAGE);
3222*d9f75844SAndroid Build Coastguard Worker con->SetIceFieldTrials(&trials);
3223*d9f75844SAndroid Build Coastguard Worker
3224*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(modified_request1.get());
3225*d9f75844SAndroid Build Coastguard Worker
3226*d9f75844SAndroid Build Coastguard Worker // Then check the response matches the settings.
3227*d9f75844SAndroid Build Coastguard Worker const auto* response = port2->last_stun_msg();
3228*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(response->type(), STUN_BINDING_RESPONSE);
3229*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(GetSupportedGoogPingVersion(response));
3230*d9f75844SAndroid Build Coastguard Worker
3231*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3232*d9f75844SAndroid Build Coastguard Worker }
3233*d9f75844SAndroid Build Coastguard Worker
3234*d9f75844SAndroid Build Coastguard Worker // This test if a someone send a STUN_BINDING_RESPONSE with unsupported version
3235*d9f75844SAndroid Build Coastguard Worker // (kGoogPingVersion == 0)
TEST_F(PortTest,TestGoogPingUnsupportedVersionInStunBindingResponse)3236*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestGoogPingUnsupportedVersionInStunBindingResponse) {
3237*d9f75844SAndroid Build Coastguard Worker IceFieldTrials trials;
3238*d9f75844SAndroid Build Coastguard Worker trials.announce_goog_ping = true;
3239*d9f75844SAndroid Build Coastguard Worker trials.enable_goog_ping = true;
3240*d9f75844SAndroid Build Coastguard Worker
3241*d9f75844SAndroid Build Coastguard Worker auto port1_unique =
3242*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
3243*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
3244*d9f75844SAndroid Build Coastguard Worker auto* port1 = port1_unique.get();
3245*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
3246*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreaker2);
3247*d9f75844SAndroid Build Coastguard Worker
3248*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1_unique));
3249*d9f75844SAndroid Build Coastguard Worker // Block usage of STUN_ATTR_USE_CANDIDATE so that
3250*d9f75844SAndroid Build Coastguard Worker // ch1.conn() will sent GOOG_PING_REQUEST directly.
3251*d9f75844SAndroid Build Coastguard Worker // This only makes test a bit shorter...
3252*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_LITE);
3253*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
3254*d9f75844SAndroid Build Coastguard Worker ch1.Start();
3255*d9f75844SAndroid Build Coastguard Worker port2->PrepareAddress();
3256*d9f75844SAndroid Build Coastguard Worker
3257*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
3258*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(port2->Candidates().empty());
3259*d9f75844SAndroid Build Coastguard Worker
3260*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(port2.get()));
3261*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
3262*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
3263*d9f75844SAndroid Build Coastguard Worker ch1.conn()->SetIceFieldTrials(&trials);
3264*d9f75844SAndroid Build Coastguard Worker
3265*d9f75844SAndroid Build Coastguard Worker // Send ping.
3266*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3267*d9f75844SAndroid Build Coastguard Worker
3268*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3269*d9f75844SAndroid Build Coastguard Worker const IceMessage* request1 = port1->last_stun_msg();
3270*d9f75844SAndroid Build Coastguard Worker
3271*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(GetSupportedGoogPingVersion(request1) &&
3272*d9f75844SAndroid Build Coastguard Worker GetSupportedGoogPingVersion(request1) >= kGoogPingVersion);
3273*d9f75844SAndroid Build Coastguard Worker
3274*d9f75844SAndroid Build Coastguard Worker auto* con = port2->CreateConnection(port1->Candidates()[0],
3275*d9f75844SAndroid Build Coastguard Worker cricket::Port::ORIGIN_MESSAGE);
3276*d9f75844SAndroid Build Coastguard Worker con->SetIceFieldTrials(&trials);
3277*d9f75844SAndroid Build Coastguard Worker
3278*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(request1);
3279*d9f75844SAndroid Build Coastguard Worker
3280*d9f75844SAndroid Build Coastguard Worker // Then check the response matches the settings.
3281*d9f75844SAndroid Build Coastguard Worker const auto* response = port2->last_stun_msg();
3282*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(response->type(), STUN_BINDING_RESPONSE);
3283*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(GetSupportedGoogPingVersion(response));
3284*d9f75844SAndroid Build Coastguard Worker
3285*d9f75844SAndroid Build Coastguard Worker // Modify the STUN message response to contain GetSupportedGoogPingVersion ==
3286*d9f75844SAndroid Build Coastguard Worker // 0
3287*d9f75844SAndroid Build Coastguard Worker auto modified_response = response->Clone();
3288*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(modified_response->RemoveAttribute(STUN_ATTR_GOOG_MISC_INFO) !=
3289*d9f75844SAndroid Build Coastguard Worker nullptr);
3290*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(modified_response->RemoveAttribute(STUN_ATTR_MESSAGE_INTEGRITY) !=
3291*d9f75844SAndroid Build Coastguard Worker nullptr);
3292*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(modified_response->RemoveAttribute(STUN_ATTR_FINGERPRINT) !=
3293*d9f75844SAndroid Build Coastguard Worker nullptr);
3294*d9f75844SAndroid Build Coastguard Worker {
3295*d9f75844SAndroid Build Coastguard Worker auto list =
3296*d9f75844SAndroid Build Coastguard Worker StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
3297*d9f75844SAndroid Build Coastguard Worker list->AddTypeAtIndex(
3298*d9f75844SAndroid Build Coastguard Worker static_cast<uint16_t>(
3299*d9f75844SAndroid Build Coastguard Worker cricket::IceGoogMiscInfoBindingResponseAttributeIndex::
3300*d9f75844SAndroid Build Coastguard Worker SUPPORT_GOOG_PING_VERSION),
3301*d9f75844SAndroid Build Coastguard Worker /* version */ 0);
3302*d9f75844SAndroid Build Coastguard Worker modified_response->AddAttribute(std::move(list));
3303*d9f75844SAndroid Build Coastguard Worker modified_response->AddMessageIntegrity("rpass");
3304*d9f75844SAndroid Build Coastguard Worker modified_response->AddFingerprint();
3305*d9f75844SAndroid Build Coastguard Worker }
3306*d9f75844SAndroid Build Coastguard Worker
3307*d9f75844SAndroid Build Coastguard Worker rtc::ByteBufferWriter buf;
3308*d9f75844SAndroid Build Coastguard Worker modified_response->Write(&buf);
3309*d9f75844SAndroid Build Coastguard Worker
3310*d9f75844SAndroid Build Coastguard Worker // Feeding the modified respone message back.
3311*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(buf.Data(), buf.Length(), /* packet_time_us */ -1);
3312*d9f75844SAndroid Build Coastguard Worker
3313*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3314*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3315*d9f75844SAndroid Build Coastguard Worker
3316*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3317*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3318*d9f75844SAndroid Build Coastguard Worker
3319*d9f75844SAndroid Build Coastguard Worker // This should now be a STUN_BINDING...without a kGoogPingVersion
3320*d9f75844SAndroid Build Coastguard Worker const IceMessage* request2 = port1->last_stun_msg();
3321*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(request2->type(), STUN_BINDING_REQUEST);
3322*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(GetSupportedGoogPingVersion(request2));
3323*d9f75844SAndroid Build Coastguard Worker
3324*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3325*d9f75844SAndroid Build Coastguard Worker }
3326*d9f75844SAndroid Build Coastguard Worker
3327*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(GoogPingTest,
3328*d9f75844SAndroid Build Coastguard Worker GoogPingTest,
3329*d9f75844SAndroid Build Coastguard Worker // test all combinations of <announce, enable> pairs.
3330*d9f75844SAndroid Build Coastguard Worker ::testing::Values(std::make_pair(false, false),
3331*d9f75844SAndroid Build Coastguard Worker std::make_pair(true, false),
3332*d9f75844SAndroid Build Coastguard Worker std::make_pair(false, true),
3333*d9f75844SAndroid Build Coastguard Worker std::make_pair(true, true)));
3334*d9f75844SAndroid Build Coastguard Worker
3335*d9f75844SAndroid Build Coastguard Worker // This test checks that a change in attributes falls back to STUN_BINDING
TEST_F(PortTest,TestChangeInAttributeMakesGoogPingFallsbackToStunBinding)3336*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestChangeInAttributeMakesGoogPingFallsbackToStunBinding) {
3337*d9f75844SAndroid Build Coastguard Worker IceFieldTrials trials;
3338*d9f75844SAndroid Build Coastguard Worker trials.announce_goog_ping = true;
3339*d9f75844SAndroid Build Coastguard Worker trials.enable_goog_ping = true;
3340*d9f75844SAndroid Build Coastguard Worker
3341*d9f75844SAndroid Build Coastguard Worker auto port1_unique =
3342*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
3343*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
3344*d9f75844SAndroid Build Coastguard Worker auto* port1 = port1_unique.get();
3345*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
3346*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreaker2);
3347*d9f75844SAndroid Build Coastguard Worker
3348*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1_unique));
3349*d9f75844SAndroid Build Coastguard Worker // Block usage of STUN_ATTR_USE_CANDIDATE so that
3350*d9f75844SAndroid Build Coastguard Worker // ch1.conn() will sent GOOG_PING_REQUEST directly.
3351*d9f75844SAndroid Build Coastguard Worker // This only makes test a bit shorter...
3352*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_LITE);
3353*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
3354*d9f75844SAndroid Build Coastguard Worker ch1.Start();
3355*d9f75844SAndroid Build Coastguard Worker port2->PrepareAddress();
3356*d9f75844SAndroid Build Coastguard Worker
3357*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
3358*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(port2->Candidates().empty());
3359*d9f75844SAndroid Build Coastguard Worker
3360*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(port2.get()));
3361*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != nullptr);
3362*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
3363*d9f75844SAndroid Build Coastguard Worker ch1.conn()->SetIceFieldTrials(&trials);
3364*d9f75844SAndroid Build Coastguard Worker
3365*d9f75844SAndroid Build Coastguard Worker // Send ping.
3366*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3367*d9f75844SAndroid Build Coastguard Worker
3368*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3369*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg = port1->last_stun_msg();
3370*d9f75844SAndroid Build Coastguard Worker auto* con = port2->CreateConnection(port1->Candidates()[0],
3371*d9f75844SAndroid Build Coastguard Worker cricket::Port::ORIGIN_MESSAGE);
3372*d9f75844SAndroid Build Coastguard Worker con->SetIceFieldTrials(&trials);
3373*d9f75844SAndroid Build Coastguard Worker
3374*d9f75844SAndroid Build Coastguard Worker // Feed the message into the connection.
3375*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(msg);
3376*d9f75844SAndroid Build Coastguard Worker
3377*d9f75844SAndroid Build Coastguard Worker // The check reply wrt to settings.
3378*d9f75844SAndroid Build Coastguard Worker const auto* response = port2->last_stun_msg();
3379*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response->type(), STUN_BINDING_RESPONSE);
3380*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(GetSupportedGoogPingVersion(response) >= kGoogPingVersion);
3381*d9f75844SAndroid Build Coastguard Worker
3382*d9f75844SAndroid Build Coastguard Worker // Feeding the respone message back.
3383*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(port2->last_stun_buf()->data<char>(),
3384*d9f75844SAndroid Build Coastguard Worker port2->last_stun_buf()->size(),
3385*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3386*d9f75844SAndroid Build Coastguard Worker
3387*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3388*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3389*d9f75844SAndroid Build Coastguard Worker
3390*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3391*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3392*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg2 = port1->last_stun_msg();
3393*d9f75844SAndroid Build Coastguard Worker
3394*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING if both of these are TRUE
3395*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(msg2->type(), GOOG_PING_REQUEST);
3396*d9f75844SAndroid Build Coastguard Worker con->SendGoogPingResponse(msg2);
3397*d9f75844SAndroid Build Coastguard Worker
3398*d9f75844SAndroid Build Coastguard Worker const auto* response2 = port2->last_stun_msg();
3399*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(response2 != nullptr);
3400*d9f75844SAndroid Build Coastguard Worker
3401*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING_RESPONSE.
3402*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response2->type(), GOOG_PING_RESPONSE);
3403*d9f75844SAndroid Build Coastguard Worker
3404*d9f75844SAndroid Build Coastguard Worker // And now the third ping.
3405*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3406*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3407*d9f75844SAndroid Build Coastguard Worker
3408*d9f75844SAndroid Build Coastguard Worker // Modify the message to be sent.
3409*d9f75844SAndroid Build Coastguard Worker ch1.conn()->set_use_candidate_attr(!ch1.conn()->use_candidate_attr());
3410*d9f75844SAndroid Build Coastguard Worker
3411*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3412*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3413*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg3 = port1->last_stun_msg();
3414*d9f75844SAndroid Build Coastguard Worker
3415*d9f75844SAndroid Build Coastguard Worker // It should be a STUN_BINDING_REQUEST
3416*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(msg3->type(), STUN_BINDING_REQUEST);
3417*d9f75844SAndroid Build Coastguard Worker
3418*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3419*d9f75844SAndroid Build Coastguard Worker }
3420*d9f75844SAndroid Build Coastguard Worker
3421*d9f75844SAndroid Build Coastguard Worker // This test that an error response fall back to STUN_BINDING.
TEST_F(PortTest,TestErrorResponseMakesGoogPingFallBackToStunBinding)3422*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestErrorResponseMakesGoogPingFallBackToStunBinding) {
3423*d9f75844SAndroid Build Coastguard Worker IceFieldTrials trials;
3424*d9f75844SAndroid Build Coastguard Worker trials.announce_goog_ping = true;
3425*d9f75844SAndroid Build Coastguard Worker trials.enable_goog_ping = true;
3426*d9f75844SAndroid Build Coastguard Worker
3427*d9f75844SAndroid Build Coastguard Worker auto port1_unique =
3428*d9f75844SAndroid Build Coastguard Worker CreateTestPort(kLocalAddr1, "lfrag", "lpass",
3429*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLING, kTiebreaker1);
3430*d9f75844SAndroid Build Coastguard Worker auto* port1 = port1_unique.get();
3431*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateTestPort(kLocalAddr2, "rfrag", "rpass",
3432*d9f75844SAndroid Build Coastguard Worker cricket::ICEROLE_CONTROLLED, kTiebreaker2);
3433*d9f75844SAndroid Build Coastguard Worker
3434*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1_unique));
3435*d9f75844SAndroid Build Coastguard Worker // Block usage of STUN_ATTR_USE_CANDIDATE so that
3436*d9f75844SAndroid Build Coastguard Worker // ch1.conn() will sent GOOG_PING_REQUEST directly.
3437*d9f75844SAndroid Build Coastguard Worker // This only makes test a bit shorter...
3438*d9f75844SAndroid Build Coastguard Worker ch1.SetIceMode(ICEMODE_LITE);
3439*d9f75844SAndroid Build Coastguard Worker // Start gathering candidates.
3440*d9f75844SAndroid Build Coastguard Worker ch1.Start();
3441*d9f75844SAndroid Build Coastguard Worker port2->PrepareAddress();
3442*d9f75844SAndroid Build Coastguard Worker
3443*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
3444*d9f75844SAndroid Build Coastguard Worker ASSERT_FALSE(port2->Candidates().empty());
3445*d9f75844SAndroid Build Coastguard Worker
3446*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(port2.get()));
3447*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(ch1.conn() != NULL);
3448*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
3449*d9f75844SAndroid Build Coastguard Worker ch1.conn()->SetIceFieldTrials(&trials);
3450*d9f75844SAndroid Build Coastguard Worker
3451*d9f75844SAndroid Build Coastguard Worker // Send ping.
3452*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3453*d9f75844SAndroid Build Coastguard Worker
3454*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3455*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg = port1->last_stun_msg();
3456*d9f75844SAndroid Build Coastguard Worker auto* con = port2->CreateConnection(port1->Candidates()[0],
3457*d9f75844SAndroid Build Coastguard Worker cricket::Port::ORIGIN_MESSAGE);
3458*d9f75844SAndroid Build Coastguard Worker con->SetIceFieldTrials(&trials);
3459*d9f75844SAndroid Build Coastguard Worker
3460*d9f75844SAndroid Build Coastguard Worker // Feed the message into the connection.
3461*d9f75844SAndroid Build Coastguard Worker con->SendStunBindingResponse(msg);
3462*d9f75844SAndroid Build Coastguard Worker
3463*d9f75844SAndroid Build Coastguard Worker // The check reply wrt to settings.
3464*d9f75844SAndroid Build Coastguard Worker const auto* response = port2->last_stun_msg();
3465*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response->type(), STUN_BINDING_RESPONSE);
3466*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(GetSupportedGoogPingVersion(response) >= kGoogPingVersion);
3467*d9f75844SAndroid Build Coastguard Worker
3468*d9f75844SAndroid Build Coastguard Worker // Feeding the respone message back.
3469*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(port2->last_stun_buf()->data<char>(),
3470*d9f75844SAndroid Build Coastguard Worker port2->last_stun_buf()->size(),
3471*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3472*d9f75844SAndroid Build Coastguard Worker
3473*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3474*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3475*d9f75844SAndroid Build Coastguard Worker
3476*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3477*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3478*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg2 = port1->last_stun_msg();
3479*d9f75844SAndroid Build Coastguard Worker
3480*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING.
3481*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(msg2->type(), GOOG_PING_REQUEST);
3482*d9f75844SAndroid Build Coastguard Worker con->SendGoogPingResponse(msg2);
3483*d9f75844SAndroid Build Coastguard Worker
3484*d9f75844SAndroid Build Coastguard Worker const auto* response2 = port2->last_stun_msg();
3485*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(response2 != nullptr);
3486*d9f75844SAndroid Build Coastguard Worker
3487*d9f75844SAndroid Build Coastguard Worker // It should be a GOOG_PING_RESPONSE.
3488*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(response2->type(), GOOG_PING_RESPONSE);
3489*d9f75844SAndroid Build Coastguard Worker
3490*d9f75844SAndroid Build Coastguard Worker // But rather than the RESPONSE...feedback an error.
3491*d9f75844SAndroid Build Coastguard Worker StunMessage error_response(GOOG_PING_ERROR_RESPONSE);
3492*d9f75844SAndroid Build Coastguard Worker error_response.SetTransactionIdForTesting(response2->transaction_id());
3493*d9f75844SAndroid Build Coastguard Worker error_response.AddMessageIntegrity32("rpass");
3494*d9f75844SAndroid Build Coastguard Worker rtc::ByteBufferWriter buf;
3495*d9f75844SAndroid Build Coastguard Worker error_response.Write(&buf);
3496*d9f75844SAndroid Build Coastguard Worker
3497*d9f75844SAndroid Build Coastguard Worker ch1.conn()->OnReadPacket(buf.Data(), buf.Length(),
3498*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3499*d9f75844SAndroid Build Coastguard Worker
3500*d9f75844SAndroid Build Coastguard Worker // And now the third ping...this should be a binding.
3501*d9f75844SAndroid Build Coastguard Worker port1->Reset();
3502*d9f75844SAndroid Build Coastguard Worker port2->Reset();
3503*d9f75844SAndroid Build Coastguard Worker
3504*d9f75844SAndroid Build Coastguard Worker ch1.Ping();
3505*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(port1->last_stun_msg() != NULL, kDefaultTimeout);
3506*d9f75844SAndroid Build Coastguard Worker const IceMessage* msg3 = port1->last_stun_msg();
3507*d9f75844SAndroid Build Coastguard Worker
3508*d9f75844SAndroid Build Coastguard Worker // It should be a STUN_BINDING_REQUEST
3509*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(msg3->type(), STUN_BINDING_REQUEST);
3510*d9f75844SAndroid Build Coastguard Worker
3511*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3512*d9f75844SAndroid Build Coastguard Worker }
3513*d9f75844SAndroid Build Coastguard Worker
3514*d9f75844SAndroid Build Coastguard Worker // This test case verifies that both the controlling port and the controlled
3515*d9f75844SAndroid Build Coastguard Worker // port will time out after connectivity is lost, if they are not marked as
3516*d9f75844SAndroid Build Coastguard Worker // "keep alive until pruned."
TEST_F(PortTest,TestPortTimeoutIfNotKeptAlive)3517*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPortTimeoutIfNotKeptAlive) {
3518*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
3519*d9f75844SAndroid Build Coastguard Worker int timeout_delay = 100;
3520*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
3521*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port1.get());
3522*d9f75844SAndroid Build Coastguard Worker port1->set_timeout_delay(timeout_delay); // milliseconds
3523*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
3524*d9f75844SAndroid Build Coastguard Worker port1->SetIceTiebreaker(kTiebreaker1);
3525*d9f75844SAndroid Build Coastguard Worker
3526*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
3527*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port2.get());
3528*d9f75844SAndroid Build Coastguard Worker port2->set_timeout_delay(timeout_delay); // milliseconds
3529*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
3530*d9f75844SAndroid Build Coastguard Worker port2->SetIceTiebreaker(kTiebreaker2);
3531*d9f75844SAndroid Build Coastguard Worker
3532*d9f75844SAndroid Build Coastguard Worker // Set up channels and ensure both ports will be deleted.
3533*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
3534*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
3535*d9f75844SAndroid Build Coastguard Worker
3536*d9f75844SAndroid Build Coastguard Worker // Simulate a connection that succeeds, and then is destroyed.
3537*d9f75844SAndroid Build Coastguard Worker StartConnectAndStopChannels(&ch1, &ch2);
3538*d9f75844SAndroid Build Coastguard Worker // After the connection is destroyed, the port will be destroyed because
3539*d9f75844SAndroid Build Coastguard Worker // none of them is marked as "keep alive until pruned.
3540*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_SIMULATED_WAIT(2, ports_destroyed(), 110, clock);
3541*d9f75844SAndroid Build Coastguard Worker }
3542*d9f75844SAndroid Build Coastguard Worker
3543*d9f75844SAndroid Build Coastguard Worker // Test that if after all connection are destroyed, new connections are created
3544*d9f75844SAndroid Build Coastguard Worker // and destroyed again, ports won't be destroyed until a timeout period passes
3545*d9f75844SAndroid Build Coastguard Worker // after the last set of connections are all destroyed.
TEST_F(PortTest,TestPortTimeoutAfterNewConnectionCreatedAndDestroyed)3546*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPortTimeoutAfterNewConnectionCreatedAndDestroyed) {
3547*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
3548*d9f75844SAndroid Build Coastguard Worker int timeout_delay = 100;
3549*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
3550*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port1.get());
3551*d9f75844SAndroid Build Coastguard Worker port1->set_timeout_delay(timeout_delay); // milliseconds
3552*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
3553*d9f75844SAndroid Build Coastguard Worker port1->SetIceTiebreaker(kTiebreaker1);
3554*d9f75844SAndroid Build Coastguard Worker
3555*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
3556*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port2.get());
3557*d9f75844SAndroid Build Coastguard Worker port2->set_timeout_delay(timeout_delay); // milliseconds
3558*d9f75844SAndroid Build Coastguard Worker
3559*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
3560*d9f75844SAndroid Build Coastguard Worker port2->SetIceTiebreaker(kTiebreaker2);
3561*d9f75844SAndroid Build Coastguard Worker
3562*d9f75844SAndroid Build Coastguard Worker // Set up channels and ensure both ports will be deleted.
3563*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
3564*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
3565*d9f75844SAndroid Build Coastguard Worker
3566*d9f75844SAndroid Build Coastguard Worker // Simulate a connection that succeeds, and then is destroyed.
3567*d9f75844SAndroid Build Coastguard Worker StartConnectAndStopChannels(&ch1, &ch2);
3568*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
3569*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ports_destroyed());
3570*d9f75844SAndroid Build Coastguard Worker
3571*d9f75844SAndroid Build Coastguard Worker // Start the second set of connection and destroy them.
3572*d9f75844SAndroid Build Coastguard Worker ch1.CreateConnection(GetCandidate(ch2.port()));
3573*d9f75844SAndroid Build Coastguard Worker ch2.CreateConnection(GetCandidate(ch1.port()));
3574*d9f75844SAndroid Build Coastguard Worker ch1.Stop();
3575*d9f75844SAndroid Build Coastguard Worker ch2.Stop();
3576*d9f75844SAndroid Build Coastguard Worker
3577*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
3578*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ports_destroyed());
3579*d9f75844SAndroid Build Coastguard Worker
3580*d9f75844SAndroid Build Coastguard Worker // The ports on both sides should be destroyed after timeout.
3581*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 30, clock);
3582*d9f75844SAndroid Build Coastguard Worker }
3583*d9f75844SAndroid Build Coastguard Worker
3584*d9f75844SAndroid Build Coastguard Worker // This test case verifies that neither the controlling port nor the controlled
3585*d9f75844SAndroid Build Coastguard Worker // port will time out after connectivity is lost if they are marked as "keep
3586*d9f75844SAndroid Build Coastguard Worker // alive until pruned". They will time out after they are pruned.
TEST_F(PortTest,TestPortNotTimeoutUntilPruned)3587*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestPortNotTimeoutUntilPruned) {
3588*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock;
3589*d9f75844SAndroid Build Coastguard Worker int timeout_delay = 100;
3590*d9f75844SAndroid Build Coastguard Worker auto port1 = CreateUdpPort(kLocalAddr1);
3591*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port1.get());
3592*d9f75844SAndroid Build Coastguard Worker port1->set_timeout_delay(timeout_delay); // milliseconds
3593*d9f75844SAndroid Build Coastguard Worker port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
3594*d9f75844SAndroid Build Coastguard Worker port1->SetIceTiebreaker(kTiebreaker1);
3595*d9f75844SAndroid Build Coastguard Worker
3596*d9f75844SAndroid Build Coastguard Worker auto port2 = CreateUdpPort(kLocalAddr2);
3597*d9f75844SAndroid Build Coastguard Worker ConnectToSignalDestroyed(port2.get());
3598*d9f75844SAndroid Build Coastguard Worker port2->set_timeout_delay(timeout_delay); // milliseconds
3599*d9f75844SAndroid Build Coastguard Worker port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
3600*d9f75844SAndroid Build Coastguard Worker port2->SetIceTiebreaker(kTiebreaker2);
3601*d9f75844SAndroid Build Coastguard Worker // The connection must not be destroyed before a connection is attempted.
3602*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ports_destroyed());
3603*d9f75844SAndroid Build Coastguard Worker
3604*d9f75844SAndroid Build Coastguard Worker port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
3605*d9f75844SAndroid Build Coastguard Worker port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
3606*d9f75844SAndroid Build Coastguard Worker
3607*d9f75844SAndroid Build Coastguard Worker // Set up channels and keep the port alive.
3608*d9f75844SAndroid Build Coastguard Worker TestChannel ch1(std::move(port1));
3609*d9f75844SAndroid Build Coastguard Worker TestChannel ch2(std::move(port2));
3610*d9f75844SAndroid Build Coastguard Worker // Simulate a connection that succeeds, and then is destroyed. But ports
3611*d9f75844SAndroid Build Coastguard Worker // are kept alive. Ports won't be destroyed.
3612*d9f75844SAndroid Build Coastguard Worker StartConnectAndStopChannels(&ch1, &ch2);
3613*d9f75844SAndroid Build Coastguard Worker ch1.port()->KeepAliveUntilPruned();
3614*d9f75844SAndroid Build Coastguard Worker ch2.port()->KeepAliveUntilPruned();
3615*d9f75844SAndroid Build Coastguard Worker SIMULATED_WAIT(ports_destroyed() > 0, 150, clock);
3616*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, ports_destroyed());
3617*d9f75844SAndroid Build Coastguard Worker
3618*d9f75844SAndroid Build Coastguard Worker // If they are pruned now, they will be destroyed right away.
3619*d9f75844SAndroid Build Coastguard Worker ch1.port()->Prune();
3620*d9f75844SAndroid Build Coastguard Worker ch2.port()->Prune();
3621*d9f75844SAndroid Build Coastguard Worker // The ports on both sides should be destroyed after timeout.
3622*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 1, clock);
3623*d9f75844SAndroid Build Coastguard Worker }
3624*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestSupportsProtocol)3625*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSupportsProtocol) {
3626*d9f75844SAndroid Build Coastguard Worker auto udp_port = CreateUdpPort(kLocalAddr1);
3627*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(udp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
3628*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(udp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
3629*d9f75844SAndroid Build Coastguard Worker
3630*d9f75844SAndroid Build Coastguard Worker auto stun_port = CreateStunPort(kLocalAddr1, nat_socket_factory1());
3631*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(stun_port->SupportsProtocol(UDP_PROTOCOL_NAME));
3632*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(stun_port->SupportsProtocol(TCP_PROTOCOL_NAME));
3633*d9f75844SAndroid Build Coastguard Worker
3634*d9f75844SAndroid Build Coastguard Worker auto tcp_port = CreateTcpPort(kLocalAddr1);
3635*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(tcp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
3636*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(tcp_port->SupportsProtocol(SSLTCP_PROTOCOL_NAME));
3637*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(tcp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
3638*d9f75844SAndroid Build Coastguard Worker
3639*d9f75844SAndroid Build Coastguard Worker auto turn_port =
3640*d9f75844SAndroid Build Coastguard Worker CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
3641*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(turn_port->SupportsProtocol(UDP_PROTOCOL_NAME));
3642*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(turn_port->SupportsProtocol(TCP_PROTOCOL_NAME));
3643*d9f75844SAndroid Build Coastguard Worker }
3644*d9f75844SAndroid Build Coastguard Worker
3645*d9f75844SAndroid Build Coastguard Worker // Test that SetIceParameters updates the component, ufrag and password
3646*d9f75844SAndroid Build Coastguard Worker // on both the port itself and its candidates.
TEST_F(PortTest,TestSetIceParameters)3647*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestSetIceParameters) {
3648*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr1, "ufrag1", "password1");
3649*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
3650*d9f75844SAndroid Build Coastguard Worker port->PrepareAddress();
3651*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1UL, port->Candidates().size());
3652*d9f75844SAndroid Build Coastguard Worker port->SetIceParameters(1, "ufrag2", "password2");
3653*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, port->component());
3654*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("ufrag2", port->username_fragment());
3655*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("password2", port->password());
3656*d9f75844SAndroid Build Coastguard Worker const Candidate& candidate = port->Candidates()[0];
3657*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, candidate.component());
3658*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("ufrag2", candidate.username());
3659*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ("password2", candidate.password());
3660*d9f75844SAndroid Build Coastguard Worker }
3661*d9f75844SAndroid Build Coastguard Worker
TEST_F(PortTest,TestAddConnectionWithSameAddress)3662*d9f75844SAndroid Build Coastguard Worker TEST_F(PortTest, TestAddConnectionWithSameAddress) {
3663*d9f75844SAndroid Build Coastguard Worker auto port = CreateTestPort(kLocalAddr1, "ufrag1", "password1");
3664*d9f75844SAndroid Build Coastguard Worker port->SetIceTiebreaker(kTiebreakerDefault);
3665*d9f75844SAndroid Build Coastguard Worker port->PrepareAddress();
3666*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, port->Candidates().size());
3667*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress address("1.1.1.1", 5000);
3668*d9f75844SAndroid Build Coastguard Worker cricket::Candidate candidate(1, "udp", address, 0, "", "", "relay", 0, "");
3669*d9f75844SAndroid Build Coastguard Worker cricket::Connection* conn1 =
3670*d9f75844SAndroid Build Coastguard Worker port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
3671*d9f75844SAndroid Build Coastguard Worker cricket::Connection* conn_in_use = port->GetConnection(address);
3672*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(conn1, conn_in_use);
3673*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, conn_in_use->remote_candidate().generation());
3674*d9f75844SAndroid Build Coastguard Worker
3675*d9f75844SAndroid Build Coastguard Worker // Creating with a candidate with the same address again will get us a
3676*d9f75844SAndroid Build Coastguard Worker // different connection with the new candidate.
3677*d9f75844SAndroid Build Coastguard Worker candidate.set_generation(2);
3678*d9f75844SAndroid Build Coastguard Worker cricket::Connection* conn2 =
3679*d9f75844SAndroid Build Coastguard Worker port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
3680*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(conn1, conn2);
3681*d9f75844SAndroid Build Coastguard Worker conn_in_use = port->GetConnection(address);
3682*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(conn2, conn_in_use);
3683*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, conn_in_use->remote_candidate().generation());
3684*d9f75844SAndroid Build Coastguard Worker
3685*d9f75844SAndroid Build Coastguard Worker // Make sure the new connection was not deleted.
3686*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current()->ProcessMessages(300);
3687*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(port->GetConnection(address) != nullptr);
3688*d9f75844SAndroid Build Coastguard Worker }
3689*d9f75844SAndroid Build Coastguard Worker
3690*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:11463) : Move Connection tests into separate unit test
3691*d9f75844SAndroid Build Coastguard Worker // splitting out shared test code as needed.
3692*d9f75844SAndroid Build Coastguard Worker
3693*d9f75844SAndroid Build Coastguard Worker class ConnectionTest : public PortTest {
3694*d9f75844SAndroid Build Coastguard Worker public:
ConnectionTest()3695*d9f75844SAndroid Build Coastguard Worker ConnectionTest() {
3696*d9f75844SAndroid Build Coastguard Worker lport_ = CreateTestPort(kLocalAddr1, "lfrag", "lpass");
3697*d9f75844SAndroid Build Coastguard Worker rport_ = CreateTestPort(kLocalAddr2, "rfrag", "rpass");
3698*d9f75844SAndroid Build Coastguard Worker lport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
3699*d9f75844SAndroid Build Coastguard Worker lport_->SetIceTiebreaker(kTiebreaker1);
3700*d9f75844SAndroid Build Coastguard Worker rport_->SetIceRole(cricket::ICEROLE_CONTROLLED);
3701*d9f75844SAndroid Build Coastguard Worker rport_->SetIceTiebreaker(kTiebreaker2);
3702*d9f75844SAndroid Build Coastguard Worker
3703*d9f75844SAndroid Build Coastguard Worker lport_->PrepareAddress();
3704*d9f75844SAndroid Build Coastguard Worker rport_->PrepareAddress();
3705*d9f75844SAndroid Build Coastguard Worker }
3706*d9f75844SAndroid Build Coastguard Worker
3707*d9f75844SAndroid Build Coastguard Worker rtc::ScopedFakeClock clock_;
3708*d9f75844SAndroid Build Coastguard Worker int num_state_changes_ = 0;
3709*d9f75844SAndroid Build Coastguard Worker
CreateConnection(IceRole role)3710*d9f75844SAndroid Build Coastguard Worker Connection* CreateConnection(IceRole role) {
3711*d9f75844SAndroid Build Coastguard Worker Connection* conn;
3712*d9f75844SAndroid Build Coastguard Worker if (role == cricket::ICEROLE_CONTROLLING) {
3713*d9f75844SAndroid Build Coastguard Worker conn = lport_->CreateConnection(rport_->Candidates()[0],
3714*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
3715*d9f75844SAndroid Build Coastguard Worker } else {
3716*d9f75844SAndroid Build Coastguard Worker conn = rport_->CreateConnection(lport_->Candidates()[0],
3717*d9f75844SAndroid Build Coastguard Worker Port::ORIGIN_MESSAGE);
3718*d9f75844SAndroid Build Coastguard Worker }
3719*d9f75844SAndroid Build Coastguard Worker conn->SignalStateChange.connect(this,
3720*d9f75844SAndroid Build Coastguard Worker &ConnectionTest::OnConnectionStateChange);
3721*d9f75844SAndroid Build Coastguard Worker return conn;
3722*d9f75844SAndroid Build Coastguard Worker }
3723*d9f75844SAndroid Build Coastguard Worker
SendPingAndCaptureReply(Connection * lconn,Connection * rconn,int64_t ms,rtc::BufferT<uint8_t> * reply)3724*d9f75844SAndroid Build Coastguard Worker void SendPingAndCaptureReply(Connection* lconn,
3725*d9f75844SAndroid Build Coastguard Worker Connection* rconn,
3726*d9f75844SAndroid Build Coastguard Worker int64_t ms,
3727*d9f75844SAndroid Build Coastguard Worker rtc::BufferT<uint8_t>* reply) {
3728*d9f75844SAndroid Build Coastguard Worker TestPort* lport =
3729*d9f75844SAndroid Build Coastguard Worker lconn->PortForTest() == lport_.get() ? lport_.get() : rport_.get();
3730*d9f75844SAndroid Build Coastguard Worker TestPort* rport =
3731*d9f75844SAndroid Build Coastguard Worker rconn->PortForTest() == rport_.get() ? rport_.get() : lport_.get();
3732*d9f75844SAndroid Build Coastguard Worker lconn->Ping(rtc::TimeMillis());
3733*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
3734*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(lport->last_stun_buf());
3735*d9f75844SAndroid Build Coastguard Worker rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
3736*d9f75844SAndroid Build Coastguard Worker lport->last_stun_buf()->size(),
3737*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3738*d9f75844SAndroid Build Coastguard Worker clock_.AdvanceTime(webrtc::TimeDelta::Millis(ms));
3739*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
3740*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(rport->last_stun_buf());
3741*d9f75844SAndroid Build Coastguard Worker *reply = std::move(*rport->last_stun_buf());
3742*d9f75844SAndroid Build Coastguard Worker }
3743*d9f75844SAndroid Build Coastguard Worker
SendPingAndReceiveResponse(Connection * lconn,Connection * rconn,int64_t ms)3744*d9f75844SAndroid Build Coastguard Worker void SendPingAndReceiveResponse(Connection* lconn,
3745*d9f75844SAndroid Build Coastguard Worker Connection* rconn,
3746*d9f75844SAndroid Build Coastguard Worker int64_t ms) {
3747*d9f75844SAndroid Build Coastguard Worker rtc::BufferT<uint8_t> reply;
3748*d9f75844SAndroid Build Coastguard Worker SendPingAndCaptureReply(lconn, rconn, ms, &reply);
3749*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(reply.data<char>(), reply.size(),
3750*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3751*d9f75844SAndroid Build Coastguard Worker }
3752*d9f75844SAndroid Build Coastguard Worker
OnConnectionStateChange(Connection * connection)3753*d9f75844SAndroid Build Coastguard Worker void OnConnectionStateChange(Connection* connection) { num_state_changes_++; }
3754*d9f75844SAndroid Build Coastguard Worker
3755*d9f75844SAndroid Build Coastguard Worker private:
3756*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> lport_;
3757*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestPort> rport_;
3758*d9f75844SAndroid Build Coastguard Worker };
3759*d9f75844SAndroid Build Coastguard Worker
TEST_F(ConnectionTest,ConnectionForgetLearnedState)3760*d9f75844SAndroid Build Coastguard Worker TEST_F(ConnectionTest, ConnectionForgetLearnedState) {
3761*d9f75844SAndroid Build Coastguard Worker Connection* lconn = CreateConnection(ICEROLE_CONTROLLING);
3762*d9f75844SAndroid Build Coastguard Worker Connection* rconn = CreateConnection(ICEROLE_CONTROLLED);
3763*d9f75844SAndroid Build Coastguard Worker
3764*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
3765*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->receiving());
3766*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(std::isnan(lconn->GetRttEstimate().GetAverage()));
3767*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->GetRttEstimate().GetVariance(),
3768*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<double>::infinity());
3769*d9f75844SAndroid Build Coastguard Worker
3770*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, rconn, 10);
3771*d9f75844SAndroid Build Coastguard Worker
3772*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->writable());
3773*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->receiving());
3774*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->GetRttEstimate().GetAverage(), 10);
3775*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->GetRttEstimate().GetVariance(),
3776*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<double>::infinity());
3777*d9f75844SAndroid Build Coastguard Worker
3778*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, rconn, 11);
3779*d9f75844SAndroid Build Coastguard Worker
3780*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->writable());
3781*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->receiving());
3782*d9f75844SAndroid Build Coastguard Worker EXPECT_NEAR(lconn->GetRttEstimate().GetAverage(), 10, 0.5);
3783*d9f75844SAndroid Build Coastguard Worker EXPECT_LT(lconn->GetRttEstimate().GetVariance(),
3784*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<double>::infinity());
3785*d9f75844SAndroid Build Coastguard Worker
3786*d9f75844SAndroid Build Coastguard Worker lconn->ForgetLearnedState();
3787*d9f75844SAndroid Build Coastguard Worker
3788*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
3789*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->receiving());
3790*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(std::isnan(lconn->GetRttEstimate().GetAverage()));
3791*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(lconn->GetRttEstimate().GetVariance(),
3792*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<double>::infinity());
3793*d9f75844SAndroid Build Coastguard Worker }
3794*d9f75844SAndroid Build Coastguard Worker
TEST_F(ConnectionTest,ConnectionForgetLearnedStateDiscardsPendingPings)3795*d9f75844SAndroid Build Coastguard Worker TEST_F(ConnectionTest, ConnectionForgetLearnedStateDiscardsPendingPings) {
3796*d9f75844SAndroid Build Coastguard Worker Connection* lconn = CreateConnection(ICEROLE_CONTROLLING);
3797*d9f75844SAndroid Build Coastguard Worker Connection* rconn = CreateConnection(ICEROLE_CONTROLLED);
3798*d9f75844SAndroid Build Coastguard Worker
3799*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, rconn, 10);
3800*d9f75844SAndroid Build Coastguard Worker
3801*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->writable());
3802*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->receiving());
3803*d9f75844SAndroid Build Coastguard Worker
3804*d9f75844SAndroid Build Coastguard Worker rtc::BufferT<uint8_t> reply;
3805*d9f75844SAndroid Build Coastguard Worker SendPingAndCaptureReply(lconn, rconn, 10, &reply);
3806*d9f75844SAndroid Build Coastguard Worker
3807*d9f75844SAndroid Build Coastguard Worker lconn->ForgetLearnedState();
3808*d9f75844SAndroid Build Coastguard Worker
3809*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
3810*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->receiving());
3811*d9f75844SAndroid Build Coastguard Worker
3812*d9f75844SAndroid Build Coastguard Worker lconn->OnReadPacket(reply.data<char>(), reply.size(),
3813*d9f75844SAndroid Build Coastguard Worker /* packet_time_us */ -1);
3814*d9f75844SAndroid Build Coastguard Worker
3815*d9f75844SAndroid Build Coastguard Worker // That reply was discarded due to the ForgetLearnedState() while it was
3816*d9f75844SAndroid Build Coastguard Worker // outstanding.
3817*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
3818*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->receiving());
3819*d9f75844SAndroid Build Coastguard Worker
3820*d9f75844SAndroid Build Coastguard Worker // But sending a new ping and getting a reply works.
3821*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, rconn, 11);
3822*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->writable());
3823*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->receiving());
3824*d9f75844SAndroid Build Coastguard Worker }
3825*d9f75844SAndroid Build Coastguard Worker
TEST_F(ConnectionTest,ConnectionForgetLearnedStateDoesNotTriggerStateChange)3826*d9f75844SAndroid Build Coastguard Worker TEST_F(ConnectionTest, ConnectionForgetLearnedStateDoesNotTriggerStateChange) {
3827*d9f75844SAndroid Build Coastguard Worker Connection* lconn = CreateConnection(ICEROLE_CONTROLLING);
3828*d9f75844SAndroid Build Coastguard Worker Connection* rconn = CreateConnection(ICEROLE_CONTROLLED);
3829*d9f75844SAndroid Build Coastguard Worker
3830*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(num_state_changes_, 0);
3831*d9f75844SAndroid Build Coastguard Worker SendPingAndReceiveResponse(lconn, rconn, 10);
3832*d9f75844SAndroid Build Coastguard Worker
3833*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->writable());
3834*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(lconn->receiving());
3835*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(num_state_changes_, 2);
3836*d9f75844SAndroid Build Coastguard Worker
3837*d9f75844SAndroid Build Coastguard Worker lconn->ForgetLearnedState();
3838*d9f75844SAndroid Build Coastguard Worker
3839*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->writable());
3840*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(lconn->receiving());
3841*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(num_state_changes_, 2);
3842*d9f75844SAndroid Build Coastguard Worker }
3843*d9f75844SAndroid Build Coastguard Worker
3844*d9f75844SAndroid Build Coastguard Worker } // namespace cricket
3845