blob: 7cb5275edc5ea36d5a03b15d75536c2976ea13da [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg3ec46792016-04-27 07:22:53 -070011#include <memory>
12
tfarina5237aaf2015-11-10 23:44:30 -080013#include "webrtc/base/arraysize.h"
jbauchf1f87202016-03-30 06:43:37 -070014#include "webrtc/base/buffer.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000015#include "webrtc/base/crc32.h"
16#include "webrtc/base/gunit.h"
17#include "webrtc/base/helpers.h"
18#include "webrtc/base/logging.h"
19#include "webrtc/base/natserver.h"
20#include "webrtc/base/natsocketfactory.h"
21#include "webrtc/base/physicalsocketserver.h"
zsteinf42cc9d2017-03-27 16:17:19 -070022#include "webrtc/base/ptr_util.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023#include "webrtc/base/socketaddress.h"
24#include "webrtc/base/ssladapter.h"
25#include "webrtc/base/stringutils.h"
26#include "webrtc/base/thread.h"
27#include "webrtc/base/virtualsocketserver.h"
zsteinf42cc9d2017-03-27 16:17:19 -070028#include "webrtc/p2p/base/basicpacketsocketfactory.h"
29#include "webrtc/p2p/base/jseptransport.h"
30#include "webrtc/p2p/base/relayport.h"
31#include "webrtc/p2p/base/stunport.h"
32#include "webrtc/p2p/base/tcpport.h"
33#include "webrtc/p2p/base/testrelayserver.h"
34#include "webrtc/p2p/base/teststunserver.h"
35#include "webrtc/p2p/base/testturnserver.h"
36#include "webrtc/p2p/base/turnport.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000037
38using rtc::AsyncPacketSocket;
jbauchf1f87202016-03-30 06:43:37 -070039using rtc::Buffer;
40using rtc::ByteBufferReader;
41using rtc::ByteBufferWriter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042using rtc::NATType;
43using rtc::NAT_OPEN_CONE;
44using rtc::NAT_ADDR_RESTRICTED;
45using rtc::NAT_PORT_RESTRICTED;
46using rtc::NAT_SYMMETRIC;
47using rtc::PacketSocketFactory;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000048using rtc::Socket;
49using rtc::SocketAddress;
50using namespace cricket;
51
Honghai Zhang161a5862016-10-20 11:47:02 -070052static const int kDefaultTimeout = 3000;
53static const int kShortTimeout = 1000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054static const SocketAddress kLocalAddr1("192.168.1.2", 0);
55static const SocketAddress kLocalAddr2("192.168.1.3", 0);
deadbeefc5d0d952015-07-16 10:22:21 -070056static const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
57static const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000058static const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
59static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
60static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
61static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
62static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
63static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
64static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
65static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
Honghai Zhang80f1db92016-01-27 11:54:45 -080066static const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
68static const RelayCredentials kRelayCredentials("test", "test");
69
70// TODO: Update these when RFC5245 is completely supported.
71// Magic value of 30 is from RFC3484, for IPv4 addresses.
Peter Boström0c4e06b2015-10-07 12:23:21 +020072static const uint32_t kDefaultPrflxPriority =
73 ICE_TYPE_PREFERENCE_PRFLX << 24 | 30 << 8 |
74 (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000075
76static const int kTiebreaker1 = 11111;
77static const int kTiebreaker2 = 22222;
78
Guo-wei Shiehbe508a12015-04-06 12:48:47 -070079static const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
80
zhihuang6d0d4bf2016-05-24 10:13:32 -070081static const int kGturnUserNameLength = 16;
82
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083static Candidate GetCandidate(Port* port) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -070084 assert(port->Candidates().size() >= 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085 return port->Candidates()[0];
86}
87
88static SocketAddress GetAddress(Port* port) {
89 return GetCandidate(port).address();
90}
91
92static IceMessage* CopyStunMessage(const IceMessage* src) {
93 IceMessage* dst = new IceMessage();
jbauchf1f87202016-03-30 06:43:37 -070094 ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000095 src->Write(&buf);
jbauchf1f87202016-03-30 06:43:37 -070096 ByteBufferReader read_buf(buf);
97 dst->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098 return dst;
99}
100
jbauchf1f87202016-03-30 06:43:37 -0700101static bool WriteStunMessage(const StunMessage* msg, ByteBufferWriter* buf) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102 buf->Resize(0); // clear out any existing buffer contents
103 return msg->Write(buf);
104}
105
106// Stub port class for testing STUN generation and processing.
107class TestPort : public Port {
108 public:
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000109 TestPort(rtc::Thread* thread,
110 const std::string& type,
111 rtc::PacketSocketFactory* factory,
112 rtc::Network* network,
113 const rtc::IPAddress& ip,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200114 uint16_t min_port,
115 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000116 const std::string& username_fragment,
117 const std::string& password)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200118 : Port(thread,
119 type,
120 factory,
121 network,
122 ip,
123 min_port,
124 max_port,
125 username_fragment,
126 password) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000127 ~TestPort() {}
128
129 // Expose GetStunMessage so that we can test it.
130 using cricket::Port::GetStunMessage;
131
132 // The last StunMessage that was sent on this Port.
133 // TODO: Make these const; requires changes to SendXXXXResponse.
jbauchf1f87202016-03-30 06:43:37 -0700134 Buffer* last_stun_buf() { return last_stun_buf_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000135 IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
136 int last_stun_error_code() {
137 int code = 0;
138 if (last_stun_msg_) {
139 const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
140 if (error_attr) {
141 code = error_attr->code();
142 }
143 }
144 return code;
145 }
146
147 virtual void PrepareAddress() {
148 rtc::SocketAddress addr(ip(), min_port());
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700149 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
zhihuang26d99c22017-02-13 12:47:27 -0800150 ICE_TYPE_PREFERENCE_HOST, 0, "", true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151 }
152
Honghai Zhangf9945b22015-12-15 12:20:13 -0800153 virtual bool SupportsProtocol(const std::string& protocol) const {
154 return true;
155 }
156
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -0700157 virtual ProtocolType GetProtocol() const { return PROTO_UDP; }
158
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159 // Exposed for testing candidate building.
160 void AddCandidateAddress(const rtc::SocketAddress& addr) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700161 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
zhihuang26d99c22017-02-13 12:47:27 -0800162 type_preference_, 0, "", false);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163 }
164 void AddCandidateAddress(const rtc::SocketAddress& addr,
165 const rtc::SocketAddress& base_address,
166 const std::string& type,
167 int type_preference,
168 bool final) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700169 AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
zhihuang26d99c22017-02-13 12:47:27 -0800170 type_preference, 0, "", final);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000171 }
172
173 virtual Connection* CreateConnection(const Candidate& remote_candidate,
174 CandidateOrigin origin) {
175 Connection* conn = new ProxyConnection(this, 0, remote_candidate);
honghaiz36f50e82016-06-01 15:57:03 -0700176 AddOrReplaceConnection(conn);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000177 // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
178 // in STUN binding requests.
179 conn->set_use_candidate_attr(true);
180 return conn;
181 }
182 virtual int SendTo(
183 const void* data, size_t size, const rtc::SocketAddress& addr,
184 const rtc::PacketOptions& options, bool payload) {
185 if (!payload) {
186 IceMessage* msg = new IceMessage;
jbauchf1f87202016-03-30 06:43:37 -0700187 Buffer* buf = new Buffer(static_cast<const char*>(data), size);
188 ByteBufferReader read_buf(*buf);
189 if (!msg->Read(&read_buf)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190 delete msg;
191 delete buf;
192 return -1;
193 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194 last_stun_buf_.reset(buf);
195 last_stun_msg_.reset(msg);
196 }
197 return static_cast<int>(size);
198 }
199 virtual int SetOption(rtc::Socket::Option opt, int value) {
200 return 0;
201 }
202 virtual int GetOption(rtc::Socket::Option opt, int* value) {
203 return -1;
204 }
205 virtual int GetError() {
206 return 0;
207 }
208 void Reset() {
209 last_stun_buf_.reset();
210 last_stun_msg_.reset();
211 }
212 void set_type_preference(int type_preference) {
213 type_preference_ = type_preference;
214 }
215
216 private:
Stefan Holmer55674ff2016-01-14 15:49:16 +0100217 void OnSentPacket(rtc::AsyncPacketSocket* socket,
218 const rtc::SentPacket& sent_packet) {
219 PortInterface::SignalSentPacket(sent_packet);
220 }
kwiberg3ec46792016-04-27 07:22:53 -0700221 std::unique_ptr<Buffer> last_stun_buf_;
222 std::unique_ptr<IceMessage> last_stun_msg_;
pbos7640ffa2015-11-30 09:16:59 -0800223 int type_preference_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000224};
225
hbosbf8d3e52017-02-28 06:34:47 -0800226static void SendPingAndReceiveResponse(
227 Connection* lconn, TestPort* lport, Connection* rconn, TestPort* rport,
228 rtc::ScopedFakeClock* clock, int64_t ms) {
229 lconn->Ping(rtc::TimeMillis());
230 ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
231 ASSERT_TRUE(lport->last_stun_buf());
232 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
233 lport->last_stun_buf()->size(),
234 rtc::PacketTime());
235 clock->AdvanceTime(rtc::TimeDelta::FromMilliseconds(ms));
236 ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
237 ASSERT_TRUE(rport->last_stun_buf());
238 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
239 rport->last_stun_buf()->size(),
240 rtc::PacketTime());
241}
242
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000243class TestChannel : public sigslot::has_slots<> {
244 public:
245 // Takes ownership of |p1| (but not |p2|).
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700246 TestChannel(Port* p1)
247 : ice_mode_(ICEMODE_FULL),
248 port_(p1),
249 complete_count_(0),
250 conn_(NULL),
251 remote_request_(),
252 nominated_(false) {
253 port_->SignalPortComplete.connect(this, &TestChannel::OnPortComplete);
254 port_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
255 port_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000256 }
257
258 int complete_count() { return complete_count_; }
259 Connection* conn() { return conn_; }
260 const SocketAddress& remote_address() { return remote_address_; }
261 const std::string remote_fragment() { return remote_frag_; }
262
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700263 void Start() { port_->PrepareAddress(); }
264 void CreateConnection(const Candidate& remote_candidate) {
265 conn_ = port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 IceMode remote_ice_mode =
267 (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
268 conn_->set_remote_ice_mode(remote_ice_mode);
269 conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
270 conn_->SignalStateChange.connect(
271 this, &TestChannel::OnConnectionStateChange);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700272 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700273 conn_->SignalReadyToSend.connect(this,
274 &TestChannel::OnConnectionReadyToSend);
275 connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000276 }
277 void OnConnectionStateChange(Connection* conn) {
278 if (conn->write_state() == Connection::STATE_WRITABLE) {
279 conn->set_use_candidate_attr(true);
280 nominated_ = true;
281 }
282 }
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700283 void AcceptConnection(const Candidate& remote_candidate) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000284 ASSERT_TRUE(remote_request_.get() != NULL);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700285 Candidate c = remote_candidate;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000286 c.set_address(remote_address_);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700287 conn_ = port_->CreateConnection(c, Port::ORIGIN_MESSAGE);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700288 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700289 port_->SendBindingResponse(remote_request_.get(), remote_address_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000290 remote_request_.reset();
291 }
292 void Ping() {
293 Ping(0);
294 }
honghaiz34b11eb2016-03-16 08:55:44 -0700295 void Ping(int64_t now) { conn_->Ping(now); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000296 void Stop() {
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700297 if (conn_) {
298 conn_->Destroy();
299 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000300 }
301
302 void OnPortComplete(Port* port) {
303 complete_count_++;
304 }
305 void SetIceMode(IceMode ice_mode) {
306 ice_mode_ = ice_mode;
307 }
308
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700309 int SendData(const char* data, size_t len) {
310 rtc::PacketOptions options;
311 return conn_->Send(data, len, options);
312 }
313
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000314 void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
315 ProtocolType proto,
316 IceMessage* msg, const std::string& rf,
317 bool /*port_muxed*/) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700318 ASSERT_EQ(port_.get(), port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000319 if (!remote_address_.IsNil()) {
320 ASSERT_EQ(remote_address_, addr);
321 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000322 const cricket::StunUInt32Attribute* priority_attr =
323 msg->GetUInt32(STUN_ATTR_PRIORITY);
324 const cricket::StunByteStringAttribute* mi_attr =
325 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
326 const cricket::StunUInt32Attribute* fingerprint_attr =
327 msg->GetUInt32(STUN_ATTR_FINGERPRINT);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700328 EXPECT_TRUE(priority_attr != NULL);
329 EXPECT_TRUE(mi_attr != NULL);
330 EXPECT_TRUE(fingerprint_attr != NULL);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000331 remote_address_ = addr;
332 remote_request_.reset(CopyStunMessage(msg));
333 remote_frag_ = rf;
334 }
335
336 void OnDestroyed(Connection* conn) {
337 ASSERT_EQ(conn_, conn);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700338 LOG(INFO) << "OnDestroy connection " << conn << " deleted";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000339 conn_ = NULL;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700340 // When the connection is destroyed, also clear these fields so future
341 // connections are possible.
342 remote_request_.reset();
343 remote_address_.Clear();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000344 }
345
346 void OnSrcPortDestroyed(PortInterface* port) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700347 Port* destroyed_src = port_.release();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000348 ASSERT_EQ(destroyed_src, port);
349 }
350
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700351 Port* port() { return port_.get(); }
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700352
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000353 bool nominated() const { return nominated_; }
354
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700355 void set_connection_ready_to_send(bool ready) {
356 connection_ready_to_send_ = ready;
357 }
358 bool connection_ready_to_send() const {
359 return connection_ready_to_send_;
360 }
361
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000362 private:
skvladc309e0e2016-07-28 17:15:20 -0700363 // ReadyToSend will only issue after a Connection recovers from ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700364 void OnConnectionReadyToSend(Connection* conn) {
365 ASSERT_EQ(conn, conn_);
366 connection_ready_to_send_ = true;
367 }
368
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000369 IceMode ice_mode_;
kwiberg3ec46792016-04-27 07:22:53 -0700370 std::unique_ptr<Port> port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000371
372 int complete_count_;
373 Connection* conn_;
374 SocketAddress remote_address_;
kwiberg3ec46792016-04-27 07:22:53 -0700375 std::unique_ptr<StunMessage> remote_request_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000376 std::string remote_frag_;
377 bool nominated_;
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700378 bool connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000379};
380
381class PortTest : public testing::Test, public sigslot::has_slots<> {
382 public:
383 PortTest()
384 : main_(rtc::Thread::Current()),
385 pss_(new rtc::PhysicalSocketServer),
386 ss_(new rtc::VirtualSocketServer(pss_.get())),
387 ss_scope_(ss_.get()),
388 network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
389 socket_factory_(rtc::Thread::Current()),
deadbeefc5d0d952015-07-16 10:22:21 -0700390 nat_factory1_(ss_.get(), kNatAddr1, SocketAddress()),
391 nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000392 nat_socket_factory1_(&nat_factory1_),
393 nat_socket_factory2_(&nat_factory2_),
394 stun_server_(TestStunServer::Create(main_, kStunAddr)),
395 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700396 relay_server_(main_,
397 kRelayUdpIntAddr,
398 kRelayUdpExtAddr,
399 kRelayTcpIntAddr,
400 kRelayTcpExtAddr,
401 kRelaySslTcpIntAddr,
402 kRelaySslTcpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000403 username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
404 password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000405 role_conflict_(false),
Honghai Zhanga74363c2016-07-28 18:06:15 -0700406 ports_destroyed_(0) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000407 network_.AddIP(rtc::IPAddress(INADDR_ANY));
408 }
409
410 protected:
411 void TestLocalToLocal() {
412 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700413 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000414 Port* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700415 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000416 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
417 }
418 void TestLocalToStun(NATType ntype) {
419 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700420 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000421 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
422 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700423 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000424 TestConnectivity("udp", port1, StunName(ntype), port2,
425 ntype == NAT_OPEN_CONE, true,
426 ntype != NAT_SYMMETRIC, true);
427 }
428 void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
429 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700430 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000431 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700432 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000433 TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
434 rtype == RELAY_GTURN, true, true, true);
435 }
436 void TestStunToLocal(NATType ntype) {
437 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
438 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700439 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000440 Port* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700441 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000442 TestConnectivity(StunName(ntype), port1, "udp", port2,
443 true, ntype != NAT_SYMMETRIC, true, true);
444 }
445 void TestStunToStun(NATType ntype1, NATType ntype2) {
446 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
447 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700448 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000449 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
450 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700451 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000452 TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
453 ntype2 == NAT_OPEN_CONE,
454 ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
455 ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
456 }
457 void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
458 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
459 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700460 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000461 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700462 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000463 TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
464 rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
465 }
466 void TestTcpToTcp() {
467 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700468 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000469 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700470 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000471 TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
472 }
473 void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
474 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700475 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000476 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700477 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000478 TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
479 rtype == RELAY_GTURN, false, true, true);
480 }
481 void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
482 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700483 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000484 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700485 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000486 TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
487 rtype == RELAY_GTURN, false, true, true);
488 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000489 // helpers for above functions
490 UDPPort* CreateUdpPort(const SocketAddress& addr) {
491 return CreateUdpPort(addr, &socket_factory_);
492 }
493 UDPPort* CreateUdpPort(const SocketAddress& addr,
494 PacketSocketFactory* socket_factory) {
Guo-wei Shieh9af97f82015-11-10 14:47:39 -0800495 return UDPPort::Create(main_, socket_factory, &network_, addr.ipaddr(), 0,
496 0, username_, password_, std::string(), true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000497 }
498 TCPPort* CreateTcpPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700499 return CreateTcpPort(addr, &socket_factory_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000500 }
501 TCPPort* CreateTcpPort(const SocketAddress& addr,
502 PacketSocketFactory* socket_factory) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700503 return TCPPort::Create(main_, socket_factory, &network_,
504 addr.ipaddr(), 0, 0, username_, password_,
505 true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000506 }
507 StunPort* CreateStunPort(const SocketAddress& addr,
508 rtc::PacketSocketFactory* factory) {
509 ServerAddresses stun_servers;
510 stun_servers.insert(kStunAddr);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700511 return StunPort::Create(main_, factory, &network_,
512 addr.ipaddr(), 0, 0,
513 username_, password_, stun_servers,
514 std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000515 }
516 Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
517 ProtocolType int_proto, ProtocolType ext_proto) {
518 if (rtype == RELAY_TURN) {
519 return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
520 } else {
521 return CreateGturnPort(addr, int_proto, ext_proto);
522 }
523 }
524 TurnPort* CreateTurnPort(const SocketAddress& addr,
525 PacketSocketFactory* socket_factory,
526 ProtocolType int_proto, ProtocolType ext_proto) {
Honghai Zhang80f1db92016-01-27 11:54:45 -0800527 SocketAddress server_addr =
528 int_proto == PROTO_TCP ? kTurnTcpIntAddr : kTurnUdpIntAddr;
529 return CreateTurnPort(addr, socket_factory, int_proto, ext_proto,
530 server_addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000531 }
532 TurnPort* CreateTurnPort(const SocketAddress& addr,
533 PacketSocketFactory* socket_factory,
534 ProtocolType int_proto, ProtocolType ext_proto,
535 const rtc::SocketAddress& server_addr) {
Honghai Zhang80f1db92016-01-27 11:54:45 -0800536 return TurnPort::Create(main_, socket_factory, &network_, addr.ipaddr(), 0,
537 0, username_, password_,
538 ProtocolAddress(server_addr, int_proto),
539 kRelayCredentials, 0, std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000540 }
541 RelayPort* CreateGturnPort(const SocketAddress& addr,
542 ProtocolType int_proto, ProtocolType ext_proto) {
543 RelayPort* port = CreateGturnPort(addr);
544 SocketAddress addrs[] =
545 { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
546 port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
547 return port;
548 }
549 RelayPort* CreateGturnPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700550 // TODO(pthatcher): Remove GTURN.
zhihuang6d0d4bf2016-05-24 10:13:32 -0700551 // Generate a username with length of 16 for Gturn only.
552 std::string username = rtc::CreateRandomString(kGturnUserNameLength);
553 return RelayPort::Create(main_, &socket_factory_, &network_, addr.ipaddr(),
554 0, 0, username, password_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000555 // TODO: Add an external address for ext_proto, so that the
556 // other side can connect to this port using a non-UDP protocol.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000557 }
558 rtc::NATServer* CreateNatServer(const SocketAddress& addr,
559 rtc::NATType type) {
deadbeefc5d0d952015-07-16 10:22:21 -0700560 return new rtc::NATServer(type, ss_.get(), addr, addr, ss_.get(), addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000561 }
562 static const char* StunName(NATType type) {
563 switch (type) {
hnsl277b2502016-12-13 05:17:23 -0800564 case NAT_OPEN_CONE:
565 return "stun(open cone)";
566 case NAT_ADDR_RESTRICTED:
567 return "stun(addr restricted)";
568 case NAT_PORT_RESTRICTED:
569 return "stun(port restricted)";
570 case NAT_SYMMETRIC:
571 return "stun(symmetric)";
572 default:
573 return "stun(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000574 }
575 }
576 static const char* RelayName(RelayType type, ProtocolType proto) {
577 if (type == RELAY_TURN) {
578 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800579 case PROTO_UDP:
580 return "turn(udp)";
581 case PROTO_TCP:
582 return "turn(tcp)";
583 case PROTO_SSLTCP:
584 return "turn(ssltcp)";
585 case PROTO_TLS:
586 return "turn(tls)";
587 default:
588 return "turn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000589 }
590 } else {
591 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800592 case PROTO_UDP:
593 return "gturn(udp)";
594 case PROTO_TCP:
595 return "gturn(tcp)";
596 case PROTO_SSLTCP:
597 return "gturn(ssltcp)";
598 case PROTO_TLS:
599 return "gturn(tls)";
600 default:
601 return "gturn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000602 }
603 }
604 }
605
honghaiza0c44ea2016-03-23 16:07:48 -0700606 void SetNetworkType(rtc::AdapterType adapter_type) {
607 network_.set_type(adapter_type);
608 }
609
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000610 void TestCrossFamilyPorts(int type);
611
Peter Thatcherb8b01432015-07-07 16:45:53 -0700612 void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2);
613
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000614 // This does all the work and then deletes |port1| and |port2|.
615 void TestConnectivity(const char* name1, Port* port1,
616 const char* name2, Port* port2,
617 bool accept, bool same_addr1,
618 bool same_addr2, bool possible);
619
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700620 // This connects the provided channels which have already started. |ch1|
621 // should have its Connection created (either through CreateConnection() or
622 // TCP reconnecting mechanism before entering this function.
623 void ConnectStartedChannels(TestChannel* ch1, TestChannel* ch2) {
624 ASSERT_TRUE(ch1->conn());
Honghai Zhang161a5862016-10-20 11:47:02 -0700625 EXPECT_TRUE_WAIT(ch1->conn()->connected(),
626 kDefaultTimeout); // for TCP connect
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700627 ch1->Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700628 WAIT(!ch2->remote_address().IsNil(), kShortTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700629
630 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700631 ch2->AcceptConnection(GetCandidate(ch1->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700632 ch2->Ping();
633 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -0700634 kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700635 }
636
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000637 // This connects and disconnects the provided channels in the same sequence as
638 // TestConnectivity with all options set to |true|. It does not delete either
639 // channel.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700640 void StartConnectAndStopChannels(TestChannel* ch1, TestChannel* ch2) {
641 // Acquire addresses.
642 ch1->Start();
643 ch2->Start();
644
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700645 ch1->CreateConnection(GetCandidate(ch2->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700646 ConnectStartedChannels(ch1, ch2);
647
648 // Destroy the connections.
649 ch1->Stop();
650 ch2->Stop();
651 }
652
653 // This disconnects both end's Connection and make sure ch2 ready for new
654 // connection.
655 void DisconnectTcpTestChannels(TestChannel* ch1, TestChannel* ch2) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700656 TCPConnection* tcp_conn1 = static_cast<TCPConnection*>(ch1->conn());
657 TCPConnection* tcp_conn2 = static_cast<TCPConnection*>(ch2->conn());
658 ASSERT_TRUE(
659 ss_->CloseTcpConnections(tcp_conn1->socket()->GetLocalAddress(),
660 tcp_conn2->socket()->GetLocalAddress()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700661
662 // Wait for both OnClose are delivered.
Honghai Zhang161a5862016-10-20 11:47:02 -0700663 EXPECT_TRUE_WAIT(!ch1->conn()->connected(), kDefaultTimeout);
664 EXPECT_TRUE_WAIT(!ch2->conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700665
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700666 // Ensure redundant SignalClose events on TcpConnection won't break tcp
667 // reconnection. Chromium will fire SignalClose for all outstanding IPC
668 // packets during reconnection.
669 tcp_conn1->socket()->SignalClose(tcp_conn1->socket(), 0);
670 tcp_conn2->socket()->SignalClose(tcp_conn2->socket(), 0);
671
672 // Speed up destroying ch2's connection such that the test is ready to
673 // accept a new connection from ch1 before ch1's connection destroys itself.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700674 ch2->conn()->Destroy();
Honghai Zhang161a5862016-10-20 11:47:02 -0700675 EXPECT_TRUE_WAIT(ch2->conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700676 }
677
678 void TestTcpReconnect(bool ping_after_disconnected,
679 bool send_after_disconnected) {
680 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700681 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700682 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700683 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700684
685 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
686 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
687
688 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700689 TestChannel ch1(port1);
690 TestChannel ch2(port2);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700691 EXPECT_EQ(0, ch1.complete_count());
692 EXPECT_EQ(0, ch2.complete_count());
693
694 ch1.Start();
695 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700696 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
697 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700698
699 // Initial connecting the channel, create connection on channel1.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700700 ch1.CreateConnection(GetCandidate(port2));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700701 ConnectStartedChannels(&ch1, &ch2);
702
703 // Shorten the timeout period.
Honghai Zhang161a5862016-10-20 11:47:02 -0700704 const int kTcpReconnectTimeout = kDefaultTimeout;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700705 static_cast<TCPConnection*>(ch1.conn())
706 ->set_reconnection_timeout(kTcpReconnectTimeout);
707 static_cast<TCPConnection*>(ch2.conn())
708 ->set_reconnection_timeout(kTcpReconnectTimeout);
709
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700710 EXPECT_FALSE(ch1.connection_ready_to_send());
711 EXPECT_FALSE(ch2.connection_ready_to_send());
712
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700713 // Once connected, disconnect them.
714 DisconnectTcpTestChannels(&ch1, &ch2);
715
716 if (send_after_disconnected || ping_after_disconnected) {
717 if (send_after_disconnected) {
718 // First SendData after disconnect should fail but will trigger
719 // reconnect.
720 EXPECT_EQ(-1, ch1.SendData(data, static_cast<int>(strlen(data))));
721 }
722
723 if (ping_after_disconnected) {
724 // Ping should trigger reconnect.
725 ch1.Ping();
726 }
727
728 // Wait for channel's outgoing TCPConnection connected.
Honghai Zhang161a5862016-10-20 11:47:02 -0700729 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700730
731 // Verify that we could still connect channels.
732 ConnectStartedChannels(&ch1, &ch2);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700733 EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(),
734 kTcpReconnectTimeout);
735 // Channel2 is the passive one so a new connection is created during
skvladc309e0e2016-07-28 17:15:20 -0700736 // reconnect. This new connection should never have issued ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700737 // hence the connection_ready_to_send() should be false.
738 EXPECT_FALSE(ch2.connection_ready_to_send());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700739 } else {
740 EXPECT_EQ(ch1.conn()->write_state(), Connection::STATE_WRITABLE);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700741 // Since the reconnection never happens, the connections should have been
742 // destroyed after the timeout.
Honghai Zhang161a5862016-10-20 11:47:02 -0700743 EXPECT_TRUE_WAIT(!ch1.conn(), kTcpReconnectTimeout + kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700744 EXPECT_TRUE(!ch2.conn());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700745 }
746
747 // Tear down and ensure that goes smoothly.
748 ch1.Stop();
749 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700750 EXPECT_TRUE_WAIT(ch1.conn() == NULL, kDefaultTimeout);
751 EXPECT_TRUE_WAIT(ch2.conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700752 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000753
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000754 IceMessage* CreateStunMessage(int type) {
755 IceMessage* msg = new IceMessage();
756 msg->SetType(type);
757 msg->SetTransactionID("TESTTESTTEST");
758 return msg;
759 }
760 IceMessage* CreateStunMessageWithUsername(int type,
761 const std::string& username) {
762 IceMessage* msg = CreateStunMessage(type);
763 msg->AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -0700764 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USERNAME, username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000765 return msg;
766 }
767 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
768 const std::string& username,
769 const std::string& password) {
770 TestPort* port = new TestPort(main_, "test", &socket_factory_, &network_,
771 addr.ipaddr(), 0, 0, username, password);
772 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
773 return port;
774 }
775 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
776 const std::string& username,
777 const std::string& password,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000778 cricket::IceRole role,
779 int tiebreaker) {
780 TestPort* port = CreateTestPort(addr, username, password);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000781 port->SetIceRole(role);
782 port->SetIceTiebreaker(tiebreaker);
783 return port;
784 }
785
786 void OnRoleConflict(PortInterface* port) {
787 role_conflict_ = true;
788 }
789 bool role_conflict() const { return role_conflict_; }
790
791 void ConnectToSignalDestroyed(PortInterface* port) {
792 port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
793 }
794
Honghai Zhanga74363c2016-07-28 18:06:15 -0700795 void OnDestroyed(PortInterface* port) { ++ports_destroyed_; }
796 int ports_destroyed() const { return ports_destroyed_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000797
798 rtc::BasicPacketSocketFactory* nat_socket_factory1() {
799 return &nat_socket_factory1_;
800 }
801
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700802 rtc::VirtualSocketServer* vss() { return ss_.get(); }
803
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000804 private:
805 rtc::Thread* main_;
kwiberg3ec46792016-04-27 07:22:53 -0700806 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
807 std::unique_ptr<rtc::VirtualSocketServer> ss_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000808 rtc::SocketServerScope ss_scope_;
809 rtc::Network network_;
810 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700811 std::unique_ptr<rtc::NATServer> nat_server1_;
812 std::unique_ptr<rtc::NATServer> nat_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000813 rtc::NATSocketFactory nat_factory1_;
814 rtc::NATSocketFactory nat_factory2_;
815 rtc::BasicPacketSocketFactory nat_socket_factory1_;
816 rtc::BasicPacketSocketFactory nat_socket_factory2_;
kwiberg3ec46792016-04-27 07:22:53 -0700817 std::unique_ptr<TestStunServer> stun_server_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000818 TestTurnServer turn_server_;
819 TestRelayServer relay_server_;
820 std::string username_;
821 std::string password_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000822 bool role_conflict_;
Honghai Zhanga74363c2016-07-28 18:06:15 -0700823 int ports_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000824};
825
826void PortTest::TestConnectivity(const char* name1, Port* port1,
827 const char* name2, Port* port2,
828 bool accept, bool same_addr1,
829 bool same_addr2, bool possible) {
Honghai Zhang161a5862016-10-20 11:47:02 -0700830 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000831 LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
832 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
833 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
834
835 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700836 TestChannel ch1(port1);
837 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000838 EXPECT_EQ(0, ch1.complete_count());
839 EXPECT_EQ(0, ch2.complete_count());
840
841 // Acquire addresses.
842 ch1.Start();
843 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700844 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
845 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000846
847 // Send a ping from src to dst. This may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700848 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000849 ASSERT_TRUE(ch1.conn() != NULL);
Honghai Zhang161a5862016-10-20 11:47:02 -0700850 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout,
851 clock); // for TCP connect
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000852 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700853 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000854
855 if (accept) {
856 // We are able to send a ping from src to dst. This is the case when
857 // sending to UDP ports and cone NATs.
858 EXPECT_TRUE(ch1.remote_address().IsNil());
859 EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
860
861 // Ensure the ping came from the same address used for src.
862 // This is the case unless the source NAT was symmetric.
863 if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
864 EXPECT_TRUE(same_addr2);
865
866 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700867 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000868 ASSERT_TRUE(ch2.conn() != NULL);
869 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700870 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
871 ch2.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000872 } else {
873 // We can't send a ping from src to dst, so flip it around. This will happen
874 // when the destination NAT is addr/port restricted or symmetric.
875 EXPECT_TRUE(ch1.remote_address().IsNil());
876 EXPECT_TRUE(ch2.remote_address().IsNil());
877
878 // Send a ping from dst to src. Again, this may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700879 ch2.CreateConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000880 ASSERT_TRUE(ch2.conn() != NULL);
881 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700882 SIMULATED_WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE,
883 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000884
885 if (same_addr1 && same_addr2) {
886 // The new ping got back to the source.
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700887 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000888 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
889
890 // First connection may not be writable if the first ping did not get
891 // through. So we will have to do another.
892 if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
893 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700894 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
895 ch1.conn()->write_state(), kDefaultTimeout,
896 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000897 }
898 } else if (!same_addr1 && possible) {
899 // The new ping went to the candidate address, but that address was bad.
900 // This will happen when the source NAT is symmetric.
901 EXPECT_TRUE(ch1.remote_address().IsNil());
902 EXPECT_TRUE(ch2.remote_address().IsNil());
903
904 // However, since we have now sent a ping to the source IP, we should be
905 // able to get a ping from it. This gives us the real source address.
906 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700907 EXPECT_TRUE_SIMULATED_WAIT(!ch2.remote_address().IsNil(), kDefaultTimeout,
908 clock);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700909 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000910 EXPECT_TRUE(ch1.remote_address().IsNil());
911
912 // Pick up the actual address and establish the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700913 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000914 ASSERT_TRUE(ch2.conn() != NULL);
915 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700916 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
917 ch2.conn()->write_state(), kDefaultTimeout,
918 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000919 } else if (!same_addr2 && possible) {
920 // The new ping came in, but from an unexpected address. This will happen
921 // when the destination NAT is symmetric.
922 EXPECT_FALSE(ch1.remote_address().IsNil());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700923 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000924
925 // Update our address and complete the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700926 ch1.AcceptConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000927 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700928 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
929 ch1.conn()->write_state(), kDefaultTimeout,
930 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000931 } else { // (!possible)
932 // There should be s no way for the pings to reach each other. Check it.
933 EXPECT_TRUE(ch1.remote_address().IsNil());
934 EXPECT_TRUE(ch2.remote_address().IsNil());
935 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700936 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000937 EXPECT_TRUE(ch1.remote_address().IsNil());
938 EXPECT_TRUE(ch2.remote_address().IsNil());
939 }
940 }
941
942 // Everything should be good, unless we know the situation is impossible.
943 ASSERT_TRUE(ch1.conn() != NULL);
944 ASSERT_TRUE(ch2.conn() != NULL);
945 if (possible) {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700946 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000947 EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700948 EXPECT_TRUE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000949 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
950 } else {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700951 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000952 EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700953 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000954 EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
955 }
956
957 // Tear down and ensure that goes smoothly.
958 ch1.Stop();
959 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700960 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn() == NULL, kDefaultTimeout, clock);
961 EXPECT_TRUE_SIMULATED_WAIT(ch2.conn() == NULL, kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000962}
963
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000964class FakePacketSocketFactory : public rtc::PacketSocketFactory {
965 public:
966 FakePacketSocketFactory()
967 : next_udp_socket_(NULL),
968 next_server_tcp_socket_(NULL),
969 next_client_tcp_socket_(NULL) {
970 }
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000971 ~FakePacketSocketFactory() override { }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000972
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000973 AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200974 uint16_t min_port,
975 uint16_t max_port) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000976 EXPECT_TRUE(next_udp_socket_ != NULL);
977 AsyncPacketSocket* result = next_udp_socket_;
978 next_udp_socket_ = NULL;
979 return result;
980 }
981
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000982 AsyncPacketSocket* CreateServerTcpSocket(const SocketAddress& local_address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200983 uint16_t min_port,
984 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000985 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000986 EXPECT_TRUE(next_server_tcp_socket_ != NULL);
987 AsyncPacketSocket* result = next_server_tcp_socket_;
988 next_server_tcp_socket_ = NULL;
989 return result;
990 }
991
992 // TODO: |proxy_info| and |user_agent| should be set
993 // per-factory and not when socket is created.
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000994 AsyncPacketSocket* CreateClientTcpSocket(const SocketAddress& local_address,
995 const SocketAddress& remote_address,
996 const rtc::ProxyInfo& proxy_info,
997 const std::string& user_agent,
998 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000999 EXPECT_TRUE(next_client_tcp_socket_ != NULL);
1000 AsyncPacketSocket* result = next_client_tcp_socket_;
1001 next_client_tcp_socket_ = NULL;
1002 return result;
1003 }
1004
1005 void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
1006 next_udp_socket_ = next_udp_socket;
1007 }
1008 void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
1009 next_server_tcp_socket_ = next_server_tcp_socket;
1010 }
1011 void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
1012 next_client_tcp_socket_ = next_client_tcp_socket;
1013 }
nisseef8b61e2016-04-29 06:09:15 -07001014 rtc::AsyncResolverInterface* CreateAsyncResolver() override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001015 return NULL;
1016 }
1017
1018 private:
1019 AsyncPacketSocket* next_udp_socket_;
1020 AsyncPacketSocket* next_server_tcp_socket_;
1021 AsyncPacketSocket* next_client_tcp_socket_;
1022};
1023
1024class FakeAsyncPacketSocket : public AsyncPacketSocket {
1025 public:
1026 // Returns current local address. Address may be set to NULL if the
1027 // socket is not bound yet (GetState() returns STATE_BINDING).
1028 virtual SocketAddress GetLocalAddress() const {
1029 return SocketAddress();
1030 }
1031
1032 // Returns remote address. Returns zeroes if this is not a client TCP socket.
1033 virtual SocketAddress GetRemoteAddress() const {
1034 return SocketAddress();
1035 }
1036
1037 // Send a packet.
1038 virtual int Send(const void *pv, size_t cb,
1039 const rtc::PacketOptions& options) {
1040 return static_cast<int>(cb);
1041 }
1042 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
1043 const rtc::PacketOptions& options) {
1044 return static_cast<int>(cb);
1045 }
1046 virtual int Close() {
1047 return 0;
1048 }
1049
1050 virtual State GetState() const { return state_; }
1051 virtual int GetOption(Socket::Option opt, int* value) { return 0; }
1052 virtual int SetOption(Socket::Option opt, int value) { return 0; }
1053 virtual int GetError() const { return 0; }
1054 virtual void SetError(int error) { }
1055
1056 void set_state(State state) { state_ = state; }
1057
1058 private:
1059 State state_;
1060};
1061
1062// Local -> XXXX
1063TEST_F(PortTest, TestLocalToLocal) {
1064 TestLocalToLocal();
1065}
1066
1067TEST_F(PortTest, TestLocalToConeNat) {
1068 TestLocalToStun(NAT_OPEN_CONE);
1069}
1070
1071TEST_F(PortTest, TestLocalToARNat) {
1072 TestLocalToStun(NAT_ADDR_RESTRICTED);
1073}
1074
1075TEST_F(PortTest, TestLocalToPRNat) {
1076 TestLocalToStun(NAT_PORT_RESTRICTED);
1077}
1078
1079TEST_F(PortTest, TestLocalToSymNat) {
1080 TestLocalToStun(NAT_SYMMETRIC);
1081}
1082
1083// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
1084TEST_F(PortTest, DISABLED_TestLocalToTurn) {
1085 TestLocalToRelay(RELAY_TURN, PROTO_UDP);
1086}
1087
1088TEST_F(PortTest, TestLocalToGturn) {
1089 TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
1090}
1091
1092TEST_F(PortTest, TestLocalToTcpGturn) {
1093 TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
1094}
1095
1096TEST_F(PortTest, TestLocalToSslTcpGturn) {
1097 TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
1098}
1099
1100// Cone NAT -> XXXX
1101TEST_F(PortTest, TestConeNatToLocal) {
1102 TestStunToLocal(NAT_OPEN_CONE);
1103}
1104
1105TEST_F(PortTest, TestConeNatToConeNat) {
1106 TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
1107}
1108
1109TEST_F(PortTest, TestConeNatToARNat) {
1110 TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
1111}
1112
1113TEST_F(PortTest, TestConeNatToPRNat) {
1114 TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
1115}
1116
1117TEST_F(PortTest, TestConeNatToSymNat) {
1118 TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
1119}
1120
1121TEST_F(PortTest, TestConeNatToTurn) {
1122 TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
1123}
1124
1125TEST_F(PortTest, TestConeNatToGturn) {
1126 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
1127}
1128
1129TEST_F(PortTest, TestConeNatToTcpGturn) {
1130 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
1131}
1132
1133// Address-restricted NAT -> XXXX
1134TEST_F(PortTest, TestARNatToLocal) {
1135 TestStunToLocal(NAT_ADDR_RESTRICTED);
1136}
1137
1138TEST_F(PortTest, TestARNatToConeNat) {
1139 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
1140}
1141
1142TEST_F(PortTest, TestARNatToARNat) {
1143 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
1144}
1145
1146TEST_F(PortTest, TestARNatToPRNat) {
1147 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
1148}
1149
1150TEST_F(PortTest, TestARNatToSymNat) {
1151 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
1152}
1153
1154TEST_F(PortTest, TestARNatToTurn) {
1155 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
1156}
1157
1158TEST_F(PortTest, TestARNatToGturn) {
1159 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1160}
1161
1162TEST_F(PortTest, TestARNATNatToTcpGturn) {
1163 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1164}
1165
1166// Port-restricted NAT -> XXXX
1167TEST_F(PortTest, TestPRNatToLocal) {
1168 TestStunToLocal(NAT_PORT_RESTRICTED);
1169}
1170
1171TEST_F(PortTest, TestPRNatToConeNat) {
1172 TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
1173}
1174
1175TEST_F(PortTest, TestPRNatToARNat) {
1176 TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
1177}
1178
1179TEST_F(PortTest, TestPRNatToPRNat) {
1180 TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
1181}
1182
1183TEST_F(PortTest, TestPRNatToSymNat) {
1184 // Will "fail"
1185 TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1186}
1187
1188TEST_F(PortTest, TestPRNatToTurn) {
1189 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
1190}
1191
1192TEST_F(PortTest, TestPRNatToGturn) {
1193 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1194}
1195
1196TEST_F(PortTest, TestPRNatToTcpGturn) {
1197 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1198}
1199
1200// Symmetric NAT -> XXXX
1201TEST_F(PortTest, TestSymNatToLocal) {
1202 TestStunToLocal(NAT_SYMMETRIC);
1203}
1204
1205TEST_F(PortTest, TestSymNatToConeNat) {
1206 TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1207}
1208
1209TEST_F(PortTest, TestSymNatToARNat) {
1210 TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1211}
1212
1213TEST_F(PortTest, TestSymNatToPRNat) {
1214 // Will "fail"
1215 TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1216}
1217
1218TEST_F(PortTest, TestSymNatToSymNat) {
1219 // Will "fail"
1220 TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1221}
1222
1223TEST_F(PortTest, TestSymNatToTurn) {
1224 TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1225}
1226
1227TEST_F(PortTest, TestSymNatToGturn) {
1228 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1229}
1230
1231TEST_F(PortTest, TestSymNatToTcpGturn) {
1232 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1233}
1234
1235// Outbound TCP -> XXXX
1236TEST_F(PortTest, TestTcpToTcp) {
1237 TestTcpToTcp();
1238}
1239
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07001240TEST_F(PortTest, TestTcpReconnectOnSendPacket) {
1241 TestTcpReconnect(false /* ping */, true /* send */);
1242}
1243
1244TEST_F(PortTest, TestTcpReconnectOnPing) {
1245 TestTcpReconnect(true /* ping */, false /* send */);
1246}
1247
1248TEST_F(PortTest, TestTcpReconnectTimeout) {
1249 TestTcpReconnect(false /* ping */, false /* send */);
1250}
1251
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001252// Test when TcpConnection never connects, the OnClose() will be called to
1253// destroy the connection.
1254TEST_F(PortTest, TestTcpNeverConnect) {
1255 Port* port1 = CreateTcpPort(kLocalAddr1);
1256 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1257 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
1258
1259 // Set up a channel and ensure the port will be deleted.
1260 TestChannel ch1(port1);
1261 EXPECT_EQ(0, ch1.complete_count());
1262
1263 ch1.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001264 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001265
kwiberg3ec46792016-04-27 07:22:53 -07001266 std::unique_ptr<rtc::AsyncSocket> server(
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001267 vss()->CreateAsyncSocket(kLocalAddr2.family(), SOCK_STREAM));
1268 // Bind but not listen.
1269 EXPECT_EQ(0, server->Bind(kLocalAddr2));
1270
1271 Candidate c = GetCandidate(port1);
1272 c.set_address(server->GetLocalAddress());
1273
1274 ch1.CreateConnection(c);
1275 EXPECT_TRUE(ch1.conn());
Honghai Zhang161a5862016-10-20 11:47:02 -07001276 EXPECT_TRUE_WAIT(!ch1.conn(), kDefaultTimeout); // for TCP connect
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001277}
1278
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001279/* TODO: Enable these once testrelayserver can accept external TCP.
1280TEST_F(PortTest, TestTcpToTcpRelay) {
1281 TestTcpToRelay(PROTO_TCP);
1282}
1283
1284TEST_F(PortTest, TestTcpToSslTcpRelay) {
1285 TestTcpToRelay(PROTO_SSLTCP);
1286}
1287*/
1288
1289// Outbound SSLTCP -> XXXX
1290/* TODO: Enable these once testrelayserver can accept external SSL.
1291TEST_F(PortTest, TestSslTcpToTcpRelay) {
1292 TestSslTcpToRelay(PROTO_TCP);
1293}
1294
1295TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1296 TestSslTcpToRelay(PROTO_SSLTCP);
1297}
1298*/
1299
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001300// Test that a connection will be dead and deleted if
1301// i) it has never received anything for MIN_CONNECTION_LIFETIME milliseconds
1302// since it was created, or
1303// ii) it has not received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT
1304// milliseconds since last receiving.
1305TEST_F(PortTest, TestConnectionDead) {
1306 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1307 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1308 TestChannel ch1(port1);
1309 TestChannel ch2(port2);
1310 // Acquire address.
1311 ch1.Start();
1312 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001313 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1314 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001315
honghaiz37389b42016-01-04 21:57:33 -08001316 // Test case that the connection has never received anything.
nisse1bffc1d2016-05-02 08:18:55 -07001317 int64_t before_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001318 ch1.CreateConnection(GetCandidate(port2));
nisse1bffc1d2016-05-02 08:18:55 -07001319 int64_t after_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001320 Connection* conn = ch1.conn();
nissec8ee8822017-01-18 07:20:55 -08001321 ASSERT_NE(conn, nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001322 // It is not dead if it is after MIN_CONNECTION_LIFETIME but not pruned.
1323 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
1324 rtc::Thread::Current()->ProcessMessages(0);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001325 EXPECT_TRUE(ch1.conn() != nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001326 // It is not dead if it is before MIN_CONNECTION_LIFETIME and pruned.
1327 conn->UpdateState(before_created + MIN_CONNECTION_LIFETIME - 1);
1328 conn->Prune();
1329 rtc::Thread::Current()->ProcessMessages(0);
1330 EXPECT_TRUE(ch1.conn() != nullptr);
1331 // It will be dead after MIN_CONNECTION_LIFETIME and pruned.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001332 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001333 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001334
honghaiz37389b42016-01-04 21:57:33 -08001335 // Test case that the connection has received something.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001336 // Create a connection again and receive a ping.
1337 ch1.CreateConnection(GetCandidate(port2));
1338 conn = ch1.conn();
nissec8ee8822017-01-18 07:20:55 -08001339 ASSERT_NE(conn, nullptr);
nisse1bffc1d2016-05-02 08:18:55 -07001340 int64_t before_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001341 conn->ReceivedPing();
nisse1bffc1d2016-05-02 08:18:55 -07001342 int64_t after_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001343 // The connection will be dead after DEAD_CONNECTION_RECEIVE_TIMEOUT
1344 conn->UpdateState(
1345 before_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT - 1);
1346 rtc::Thread::Current()->ProcessMessages(100);
1347 EXPECT_TRUE(ch1.conn() != nullptr);
1348 conn->UpdateState(after_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001349 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001350}
1351
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001352// This test case verifies standard ICE features in STUN messages. Currently it
1353// verifies Message Integrity attribute in STUN messages and username in STUN
1354// binding request will have colon (":") between remote and local username.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001355TEST_F(PortTest, TestLocalToLocalStandard) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001356 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1357 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1358 port1->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001359 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1360 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1361 port2->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001362 // Same parameters as TestLocalToLocal above.
1363 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1364}
1365
1366// This test is trying to validate a successful and failure scenario in a
1367// loopback test when protocol is RFC5245. For success IceTiebreaker, username
1368// should remain equal to the request generated by the port and role of port
1369// must be in controlling.
Honghai Zhang161a5862016-10-20 11:47:02 -07001370TEST_F(PortTest, TestLoopbackCall) {
kwiberg3ec46792016-04-27 07:22:53 -07001371 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001372 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001373 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1374 lport->SetIceTiebreaker(kTiebreaker1);
1375 lport->PrepareAddress();
1376 ASSERT_FALSE(lport->Candidates().empty());
1377 Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1378 Port::ORIGIN_MESSAGE);
1379 conn->Ping(0);
1380
Honghai Zhang161a5862016-10-20 11:47:02 -07001381 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001382 IceMessage* msg = lport->last_stun_msg();
1383 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
jbauchf1f87202016-03-30 06:43:37 -07001384 conn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1385 lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001386 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001387 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001388 msg = lport->last_stun_msg();
1389 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1390
1391 // If the tiebreaker value is different from port, we expect a error
1392 // response.
1393 lport->Reset();
1394 lport->AddCandidateAddress(kLocalAddr2);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001395 // Creating a different connection as |conn| is receiving.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001396 Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1397 Port::ORIGIN_MESSAGE);
1398 conn1->Ping(0);
1399
Honghai Zhang161a5862016-10-20 11:47:02 -07001400 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001401 msg = lport->last_stun_msg();
1402 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
kwiberg3ec46792016-04-27 07:22:53 -07001403 std::unique_ptr<IceMessage> modified_req(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001404 CreateStunMessage(STUN_BINDING_REQUEST));
1405 const StunByteStringAttribute* username_attr = msg->GetByteString(
1406 STUN_ATTR_USERNAME);
zsteinf42cc9d2017-03-27 16:17:19 -07001407 modified_req->AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001408 STUN_ATTR_USERNAME, username_attr->GetString()));
1409 // To make sure we receive error response, adding tiebreaker less than
1410 // what's present in request.
zsteinf42cc9d2017-03-27 16:17:19 -07001411 modified_req->AddAttribute(rtc::MakeUnique<StunUInt64Attribute>(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001412 STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1413 modified_req->AddMessageIntegrity("lpass");
1414 modified_req->AddFingerprint();
1415
1416 lport->Reset();
kwiberg3ec46792016-04-27 07:22:53 -07001417 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001418 WriteStunMessage(modified_req.get(), buf.get());
1419 conn1->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001420 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001421 msg = lport->last_stun_msg();
1422 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1423}
1424
1425// This test verifies role conflict signal is received when there is
1426// conflict in the role. In this case both ports are in controlling and
1427// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1428// value of tiebreaker, when it receives ping request from |rport| it will
1429// send role conflict signal.
1430TEST_F(PortTest, TestIceRoleConflict) {
kwiberg3ec46792016-04-27 07:22:53 -07001431 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001432 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001433 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1434 lport->SetIceTiebreaker(kTiebreaker1);
kwiberg3ec46792016-04-27 07:22:53 -07001435 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001436 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001437 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1438 rport->SetIceTiebreaker(kTiebreaker2);
1439
1440 lport->PrepareAddress();
1441 rport->PrepareAddress();
1442 ASSERT_FALSE(lport->Candidates().empty());
1443 ASSERT_FALSE(rport->Candidates().empty());
1444 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1445 Port::ORIGIN_MESSAGE);
1446 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1447 Port::ORIGIN_MESSAGE);
1448 rconn->Ping(0);
1449
Honghai Zhang161a5862016-10-20 11:47:02 -07001450 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001451 IceMessage* msg = rport->last_stun_msg();
1452 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1453 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07001454 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1455 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001456 rtc::PacketTime());
1457
Honghai Zhang161a5862016-10-20 11:47:02 -07001458 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001459 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1460 EXPECT_TRUE(role_conflict());
1461}
1462
1463TEST_F(PortTest, TestTcpNoDelay) {
1464 TCPPort* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001465 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001466 int option_value = -1;
1467 int success = port1->GetOption(rtc::Socket::OPT_NODELAY,
1468 &option_value);
1469 ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1470 ASSERT_EQ(1, option_value);
1471 delete port1;
1472}
1473
1474TEST_F(PortTest, TestDelayedBindingUdp) {
1475 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1476 FakePacketSocketFactory socket_factory;
1477
1478 socket_factory.set_next_udp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001479 std::unique_ptr<UDPPort> port(CreateUdpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001480
1481 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1482 port->PrepareAddress();
1483
1484 EXPECT_EQ(0U, port->Candidates().size());
1485 socket->SignalAddressReady(socket, kLocalAddr2);
1486
1487 EXPECT_EQ(1U, port->Candidates().size());
1488}
1489
1490TEST_F(PortTest, TestDelayedBindingTcp) {
1491 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1492 FakePacketSocketFactory socket_factory;
1493
1494 socket_factory.set_next_server_tcp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001495 std::unique_ptr<TCPPort> port(CreateTcpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001496
1497 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1498 port->PrepareAddress();
1499
1500 EXPECT_EQ(0U, port->Candidates().size());
1501 socket->SignalAddressReady(socket, kLocalAddr2);
1502
1503 EXPECT_EQ(1U, port->Candidates().size());
1504}
1505
1506void PortTest::TestCrossFamilyPorts(int type) {
1507 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001508 std::unique_ptr<Port> ports[4];
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001509 SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1510 SocketAddress("192.168.1.4", 0),
1511 SocketAddress("2001:db8::1", 0),
1512 SocketAddress("2001:db8::2", 0)};
1513 for (int i = 0; i < 4; i++) {
1514 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1515 if (type == SOCK_DGRAM) {
1516 factory.set_next_udp_socket(socket);
1517 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1518 } else if (type == SOCK_STREAM) {
1519 factory.set_next_server_tcp_socket(socket);
1520 ports[i].reset(CreateTcpPort(addresses[i], &factory));
1521 }
1522 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1523 socket->SignalAddressReady(socket, addresses[i]);
1524 ports[i]->PrepareAddress();
1525 }
1526
1527 // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1528 if (type == SOCK_STREAM) {
1529 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1530 factory.set_next_client_tcp_socket(clientsocket);
1531 }
1532 Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1533 Port::ORIGIN_MESSAGE);
1534 EXPECT_TRUE(NULL == c);
1535 EXPECT_EQ(0U, ports[0]->connections().size());
1536 c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1537 Port::ORIGIN_MESSAGE);
1538 EXPECT_FALSE(NULL == c);
1539 EXPECT_EQ(1U, ports[0]->connections().size());
1540
1541 // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1542 if (type == SOCK_STREAM) {
1543 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1544 factory.set_next_client_tcp_socket(clientsocket);
1545 }
1546 c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1547 Port::ORIGIN_MESSAGE);
1548 EXPECT_TRUE(NULL == c);
1549 EXPECT_EQ(0U, ports[2]->connections().size());
1550 c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1551 Port::ORIGIN_MESSAGE);
1552 EXPECT_FALSE(NULL == c);
1553 EXPECT_EQ(1U, ports[2]->connections().size());
1554}
1555
1556TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1557 TestCrossFamilyPorts(SOCK_STREAM);
1558}
1559
1560TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1561 TestCrossFamilyPorts(SOCK_DGRAM);
1562}
1563
Peter Thatcherb8b01432015-07-07 16:45:53 -07001564void PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) {
1565 Connection* c = p1->CreateConnection(GetCandidate(p2),
1566 Port::ORIGIN_MESSAGE);
1567 if (can_connect) {
1568 EXPECT_FALSE(NULL == c);
1569 EXPECT_EQ(1U, p1->connections().size());
1570 } else {
1571 EXPECT_TRUE(NULL == c);
1572 EXPECT_EQ(0U, p1->connections().size());
1573 }
1574}
1575
1576TEST_F(PortTest, TestUdpV6CrossTypePorts) {
1577 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001578 std::unique_ptr<Port> ports[4];
Peter Thatcherb8b01432015-07-07 16:45:53 -07001579 SocketAddress addresses[4] = {SocketAddress("2001:db8::1", 0),
1580 SocketAddress("fe80::1", 0),
1581 SocketAddress("fe80::2", 0),
1582 SocketAddress("::1", 0)};
1583 for (int i = 0; i < 4; i++) {
1584 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1585 factory.set_next_udp_socket(socket);
1586 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1587 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1588 socket->SignalAddressReady(socket, addresses[i]);
1589 ports[i]->PrepareAddress();
1590 }
1591
1592 Port* standard = ports[0].get();
1593 Port* link_local1 = ports[1].get();
1594 Port* link_local2 = ports[2].get();
1595 Port* localhost = ports[3].get();
1596
1597 ExpectPortsCanConnect(false, link_local1, standard);
1598 ExpectPortsCanConnect(false, standard, link_local1);
1599 ExpectPortsCanConnect(false, link_local1, localhost);
1600 ExpectPortsCanConnect(false, localhost, link_local1);
1601
1602 ExpectPortsCanConnect(true, link_local1, link_local2);
1603 ExpectPortsCanConnect(true, localhost, standard);
1604 ExpectPortsCanConnect(true, standard, localhost);
1605}
1606
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001607// This test verifies DSCP value set through SetOption interface can be
1608// get through DefaultDscpValue.
1609TEST_F(PortTest, TestDefaultDscpValue) {
1610 int dscp;
kwiberg3ec46792016-04-27 07:22:53 -07001611 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001612 EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP,
1613 rtc::DSCP_CS6));
1614 EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
kwiberg3ec46792016-04-27 07:22:53 -07001615 std::unique_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001616 EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP,
1617 rtc::DSCP_AF31));
1618 EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1619 EXPECT_EQ(rtc::DSCP_AF31, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001620 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001621 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
1622 EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP,
1623 rtc::DSCP_AF41));
1624 EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1625 EXPECT_EQ(rtc::DSCP_AF41, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001626 std::unique_ptr<TurnPort> turnport1(
1627 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001628 // Socket is created in PrepareAddress.
1629 turnport1->PrepareAddress();
1630 EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP,
1631 rtc::DSCP_CS7));
1632 EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1633 EXPECT_EQ(rtc::DSCP_CS7, dscp);
1634 // This will verify correct value returned without the socket.
kwiberg3ec46792016-04-27 07:22:53 -07001635 std::unique_ptr<TurnPort> turnport2(
1636 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001637 EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP,
1638 rtc::DSCP_CS6));
1639 EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1640 EXPECT_EQ(rtc::DSCP_CS6, dscp);
1641}
1642
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001643// Test sending STUN messages.
1644TEST_F(PortTest, TestSendStunMessage) {
kwiberg3ec46792016-04-27 07:22:53 -07001645 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001646 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001647 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001648 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001649 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1650 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001651 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1652 rport->SetIceTiebreaker(kTiebreaker2);
1653
1654 // Send a fake ping from lport to rport.
1655 lport->PrepareAddress();
1656 rport->PrepareAddress();
1657 ASSERT_FALSE(rport->Candidates().empty());
1658 Connection* lconn = lport->CreateConnection(
1659 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1660 Connection* rconn = rport->CreateConnection(
1661 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1662 lconn->Ping(0);
1663
1664 // Check that it's a proper BINDING-REQUEST.
Honghai Zhang161a5862016-10-20 11:47:02 -07001665 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001666 IceMessage* msg = lport->last_stun_msg();
1667 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1668 EXPECT_FALSE(msg->IsLegacy());
1669 const StunByteStringAttribute* username_attr =
1670 msg->GetByteString(STUN_ATTR_USERNAME);
1671 ASSERT_TRUE(username_attr != NULL);
1672 const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1673 ASSERT_TRUE(priority_attr != NULL);
1674 EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1675 EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1676 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1677 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001678 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001679 "rpass"));
1680 const StunUInt64Attribute* ice_controlling_attr =
1681 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1682 ASSERT_TRUE(ice_controlling_attr != NULL);
1683 EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
1684 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1685 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1686 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1687 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001688 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001689
1690 // Request should not include ping count.
1691 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1692
1693 // Save a copy of the BINDING-REQUEST for use below.
kwiberg3ec46792016-04-27 07:22:53 -07001694 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001695
zhihuang5ecf16c2016-06-01 17:09:15 -07001696 // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE.
1697 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1698 lport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001699 msg = rport->last_stun_msg();
1700 ASSERT_TRUE(msg != NULL);
1701 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
zhihuang5ecf16c2016-06-01 17:09:15 -07001702 // Received a BINDING-RESPONSE.
1703 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1704 rport->last_stun_buf()->size(), rtc::PacketTime());
1705 // Verify the STUN Stats.
1706 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total);
1707 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_before_first_response);
1708 EXPECT_EQ(1U, lconn->stats().recv_ping_responses);
1709 EXPECT_EQ(1U, rconn->stats().recv_ping_requests);
1710 EXPECT_EQ(1U, rconn->stats().sent_ping_responses);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001711
1712 EXPECT_FALSE(msg->IsLegacy());
1713 const StunAddressAttribute* addr_attr = msg->GetAddress(
1714 STUN_ATTR_XOR_MAPPED_ADDRESS);
1715 ASSERT_TRUE(addr_attr != NULL);
1716 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1717 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1718 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001719 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001720 "rpass"));
1721 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1722 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001723 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001724 // No USERNAME or PRIORITY in ICE responses.
1725 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1726 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1727 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1728 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1729 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1730 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1731
1732 // Response should not include ping count.
1733 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1734
1735 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1736 // but we can do it here.
1737 rport->SendBindingErrorResponse(request.get(),
1738 lport->Candidates()[0].address(),
1739 STUN_ERROR_SERVER_ERROR,
1740 STUN_ERROR_REASON_SERVER_ERROR);
1741 msg = rport->last_stun_msg();
1742 ASSERT_TRUE(msg != NULL);
1743 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1744 EXPECT_FALSE(msg->IsLegacy());
1745 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1746 ASSERT_TRUE(error_attr != NULL);
1747 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1748 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1749 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1750 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001751 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001752 "rpass"));
1753 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1754 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001755 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001756 // No USERNAME with ICE.
1757 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1758 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1759
1760 // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1761 // and (incremented) RETRANSMIT_COUNT attributes.
1762 rport->Reset();
1763 rport->set_send_retransmit_count_attribute(true);
1764 rconn->Ping(0);
1765 rconn->Ping(0);
1766 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001767 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001768 msg = rport->last_stun_msg();
1769 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1770 const StunUInt64Attribute* ice_controlled_attr =
1771 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1772 ASSERT_TRUE(ice_controlled_attr != NULL);
1773 EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
1774 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1775
1776 // Request should include ping count.
1777 const StunUInt32Attribute* retransmit_attr =
1778 msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1779 ASSERT_TRUE(retransmit_attr != NULL);
1780 EXPECT_EQ(2U, retransmit_attr->value());
1781
1782 // Respond with a BINDING-RESPONSE.
1783 request.reset(CopyStunMessage(msg));
zhihuang5ecf16c2016-06-01 17:09:15 -07001784 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1785 rport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001786 msg = lport->last_stun_msg();
zhihuang5ecf16c2016-06-01 17:09:15 -07001787 // Receive the BINDING-RESPONSE.
1788 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1789 lport->last_stun_buf()->size(), rtc::PacketTime());
1790
1791 // Verify the Stun ping stats.
1792 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total);
1793 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
1794 EXPECT_EQ(1U, rconn->stats().recv_ping_responses);
1795 EXPECT_EQ(1U, lconn->stats().sent_ping_responses);
1796 EXPECT_EQ(1U, lconn->stats().recv_ping_requests);
1797 // Ping after receiver the first response
1798 rconn->Ping(0);
1799 rconn->Ping(0);
1800 EXPECT_EQ(5U, rconn->stats().sent_ping_requests_total);
1801 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001802
1803 // Response should include same ping count.
1804 retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1805 ASSERT_TRUE(retransmit_attr != NULL);
1806 EXPECT_EQ(2U, retransmit_attr->value());
1807}
1808
hbos92eaec62017-02-27 01:38:08 -08001809TEST_F(PortTest, TestNomination) {
1810 std::unique_ptr<TestPort> lport(
1811 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1812 std::unique_ptr<TestPort> rport(
1813 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1814 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1815 lport->SetIceTiebreaker(kTiebreaker1);
1816 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1817 rport->SetIceTiebreaker(kTiebreaker2);
1818
1819 lport->PrepareAddress();
1820 rport->PrepareAddress();
1821 ASSERT_FALSE(lport->Candidates().empty());
1822 ASSERT_FALSE(rport->Candidates().empty());
1823 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1824 Port::ORIGIN_MESSAGE);
1825 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1826 Port::ORIGIN_MESSAGE);
1827
1828 // |lconn| is controlling, |rconn| is controlled.
1829 uint32_t nomination = 1234;
1830 lconn->set_nomination(nomination);
1831
1832 EXPECT_FALSE(lconn->nominated());
1833 EXPECT_FALSE(rconn->nominated());
1834 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1835 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1836
1837 // Send ping (including the nomination value) from |lconn| to |rconn|. This
1838 // should set the remote nomination of |rconn|.
1839 lconn->Ping(0);
1840 ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
1841 ASSERT_TRUE(lport->last_stun_buf());
1842 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1843 lport->last_stun_buf()->size(),
1844 rtc::PacketTime());
1845 EXPECT_EQ(nomination, rconn->remote_nomination());
1846 EXPECT_FALSE(lconn->nominated());
1847 EXPECT_TRUE(rconn->nominated());
1848 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1849 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1850
1851 // This should result in an acknowledgment sent back from |rconn| to |lconn|,
1852 // updating the acknowledged nomination of |lconn|.
1853 ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
1854 ASSERT_TRUE(rport->last_stun_buf());
1855 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1856 rport->last_stun_buf()->size(),
1857 rtc::PacketTime());
1858 EXPECT_EQ(nomination, lconn->acked_nomination());
1859 EXPECT_TRUE(lconn->nominated());
1860 EXPECT_TRUE(rconn->nominated());
1861 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1862 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1863}
1864
hbosbf8d3e52017-02-28 06:34:47 -08001865TEST_F(PortTest, TestRoundTripTime) {
1866 rtc::ScopedFakeClock clock;
1867
1868 std::unique_ptr<TestPort> lport(
1869 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1870 std::unique_ptr<TestPort> rport(
1871 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1872 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1873 lport->SetIceTiebreaker(kTiebreaker1);
1874 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1875 rport->SetIceTiebreaker(kTiebreaker2);
1876
1877 lport->PrepareAddress();
1878 rport->PrepareAddress();
1879 ASSERT_FALSE(lport->Candidates().empty());
1880 ASSERT_FALSE(rport->Candidates().empty());
1881 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1882 Port::ORIGIN_MESSAGE);
1883 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1884 Port::ORIGIN_MESSAGE);
1885
1886 EXPECT_EQ(0u, lconn->stats().total_round_trip_time_ms);
1887 EXPECT_FALSE(lconn->stats().current_round_trip_time_ms);
1888
1889 SendPingAndReceiveResponse(
1890 lconn, lport.get(), rconn, rport.get(), &clock, 10);
1891 EXPECT_EQ(10u, lconn->stats().total_round_trip_time_ms);
1892 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1893 EXPECT_EQ(10u, *lconn->stats().current_round_trip_time_ms);
1894
1895 SendPingAndReceiveResponse(
1896 lconn, lport.get(), rconn, rport.get(), &clock, 20);
1897 EXPECT_EQ(30u, lconn->stats().total_round_trip_time_ms);
1898 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1899 EXPECT_EQ(20u, *lconn->stats().current_round_trip_time_ms);
1900
1901 SendPingAndReceiveResponse(
1902 lconn, lport.get(), rconn, rport.get(), &clock, 30);
1903 EXPECT_EQ(60u, lconn->stats().total_round_trip_time_ms);
1904 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1905 EXPECT_EQ(30u, *lconn->stats().current_round_trip_time_ms);
1906}
1907
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001908TEST_F(PortTest, TestUseCandidateAttribute) {
kwiberg3ec46792016-04-27 07:22:53 -07001909 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001910 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001911 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001912 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001913 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1914 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001915 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1916 rport->SetIceTiebreaker(kTiebreaker2);
1917
1918 // Send a fake ping from lport to rport.
1919 lport->PrepareAddress();
1920 rport->PrepareAddress();
1921 ASSERT_FALSE(rport->Candidates().empty());
1922 Connection* lconn = lport->CreateConnection(
1923 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1924 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001925 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001926 IceMessage* msg = lport->last_stun_msg();
1927 const StunUInt64Attribute* ice_controlling_attr =
1928 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1929 ASSERT_TRUE(ice_controlling_attr != NULL);
1930 const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1931 STUN_ATTR_USE_CANDIDATE);
1932 ASSERT_TRUE(use_candidate_attr != NULL);
1933}
1934
Honghai Zhang351d77b2016-05-20 15:08:29 -07001935// Tests that when the network type changes, the network cost of the port will
1936// change, the network cost of the local candidates will change. Also tests that
1937// the remote network costs are updated with the stun binding requests.
1938TEST_F(PortTest, TestNetworkCostChange) {
1939 std::unique_ptr<TestPort> lport(
1940 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1941 std::unique_ptr<TestPort> rport(
1942 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1943 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1944 lport->SetIceTiebreaker(kTiebreaker1);
1945 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1946 rport->SetIceTiebreaker(kTiebreaker2);
1947 lport->PrepareAddress();
1948 rport->PrepareAddress();
1949
1950 // Default local port cost is rtc::kNetworkCostUnknown.
1951 EXPECT_EQ(rtc::kNetworkCostUnknown, lport->network_cost());
1952 ASSERT_TRUE(!lport->Candidates().empty());
1953 for (const cricket::Candidate& candidate : lport->Candidates()) {
1954 EXPECT_EQ(rtc::kNetworkCostUnknown, candidate.network_cost());
1955 }
1956
1957 // Change the network type to wifi.
1958 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
1959 EXPECT_EQ(rtc::kNetworkCostLow, lport->network_cost());
1960 for (const cricket::Candidate& candidate : lport->Candidates()) {
1961 EXPECT_EQ(rtc::kNetworkCostLow, candidate.network_cost());
1962 }
1963
1964 // Add a connection and then change the network type.
1965 Connection* lconn =
1966 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1967 // Change the network type to cellular.
1968 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
1969 EXPECT_EQ(rtc::kNetworkCostHigh, lport->network_cost());
1970 for (const cricket::Candidate& candidate : lport->Candidates()) {
1971 EXPECT_EQ(rtc::kNetworkCostHigh, candidate.network_cost());
1972 }
1973
1974 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
1975 Connection* rconn =
1976 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1977 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
1978 lconn->Ping(0);
1979 // The rconn's remote candidate cost is rtc::kNetworkCostLow, but the ping
1980 // contains an attribute of network cost of rtc::kNetworkCostHigh. Once the
1981 // message is handled in rconn, The rconn's remote candidate will have cost
1982 // rtc::kNetworkCostHigh;
1983 EXPECT_EQ(rtc::kNetworkCostLow, rconn->remote_candidate().network_cost());
Honghai Zhang161a5862016-10-20 11:47:02 -07001984 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001985 IceMessage* msg = lport->last_stun_msg();
1986 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1987 // Pass the binding request to rport.
1988 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1989 lport->last_stun_buf()->size(), rtc::PacketTime());
1990 // Wait until rport sends the response and then check the remote network cost.
Honghai Zhang161a5862016-10-20 11:47:02 -07001991 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001992 EXPECT_EQ(rtc::kNetworkCostHigh, rconn->remote_candidate().network_cost());
1993}
1994
honghaiza0c44ea2016-03-23 16:07:48 -07001995TEST_F(PortTest, TestNetworkInfoAttribute) {
kwiberg3ec46792016-04-27 07:22:53 -07001996 std::unique_ptr<TestPort> lport(
honghaiza0c44ea2016-03-23 16:07:48 -07001997 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001998 std::unique_ptr<TestPort> rport(
honghaiza0c44ea2016-03-23 16:07:48 -07001999 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2000 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2001 lport->SetIceTiebreaker(kTiebreaker1);
2002 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2003 rport->SetIceTiebreaker(kTiebreaker2);
2004
2005 uint16_t lnetwork_id = 9;
2006 lport->Network()->set_id(lnetwork_id);
2007 // Send a fake ping from lport to rport.
2008 lport->PrepareAddress();
2009 rport->PrepareAddress();
2010 Connection* lconn =
2011 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2012 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07002013 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07002014 IceMessage* msg = lport->last_stun_msg();
2015 const StunUInt32Attribute* network_info_attr =
2016 msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
2017 ASSERT_TRUE(network_info_attr != NULL);
2018 uint32_t network_info = network_info_attr->value();
2019 EXPECT_EQ(lnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07002020 // Default network has unknown type and cost kNetworkCostUnknown.
2021 EXPECT_EQ(rtc::kNetworkCostUnknown, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07002022
Honghai Zhang351d77b2016-05-20 15:08:29 -07002023 // Set the network type to be cellular so its cost will be kNetworkCostHigh.
honghaiza0c44ea2016-03-23 16:07:48 -07002024 // Send a fake ping from rport to lport.
Honghai Zhang351d77b2016-05-20 15:08:29 -07002025 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
honghaiza0c44ea2016-03-23 16:07:48 -07002026 uint16_t rnetwork_id = 8;
2027 rport->Network()->set_id(rnetwork_id);
2028 Connection* rconn =
2029 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2030 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07002031 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07002032 msg = rport->last_stun_msg();
2033 network_info_attr = msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
2034 ASSERT_TRUE(network_info_attr != NULL);
2035 network_info = network_info_attr->value();
2036 EXPECT_EQ(rnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07002037 EXPECT_EQ(rtc::kNetworkCostHigh, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07002038}
2039
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002040// Test handling STUN messages.
2041TEST_F(PortTest, TestHandleStunMessage) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002042 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002043 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002044
kwiberg3ec46792016-04-27 07:22:53 -07002045 std::unique_ptr<IceMessage> in_msg, out_msg;
2046 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002047 rtc::SocketAddress addr(kLocalAddr1);
2048 std::string username;
2049
2050 // BINDING-REQUEST from local to remote with valid ICE username,
2051 // MESSAGE-INTEGRITY, and FINGERPRINT.
2052 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2053 "rfrag:lfrag"));
2054 in_msg->AddMessageIntegrity("rpass");
2055 in_msg->AddFingerprint();
2056 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002057 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2058 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002059 EXPECT_TRUE(out_msg.get() != NULL);
2060 EXPECT_EQ("lfrag", username);
2061
2062 // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
2063 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002064 in_msg->AddAttribute(rtc::MakeUnique<StunXorAddressAttribute>(
2065 STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002066 in_msg->AddMessageIntegrity("rpass");
2067 in_msg->AddFingerprint();
2068 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002069 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2070 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002071 EXPECT_TRUE(out_msg.get() != NULL);
2072 EXPECT_EQ("", username);
2073
2074 // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
2075 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002076 in_msg->AddAttribute(rtc::MakeUnique<StunErrorCodeAttribute>(
2077 STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2078 STUN_ERROR_REASON_SERVER_ERROR));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002079 in_msg->AddFingerprint();
2080 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002081 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2082 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002083 EXPECT_TRUE(out_msg.get() != NULL);
2084 EXPECT_EQ("", username);
2085 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
2086 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
2087 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
2088 out_msg->GetErrorCode()->reason());
2089}
2090
guoweisd12140a2015-09-10 13:32:11 -07002091// Tests handling of ICE binding requests with missing or incorrect usernames.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002092TEST_F(PortTest, TestHandleStunMessageBadUsername) {
kwiberg3ec46792016-04-27 07:22:53 -07002093 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002094
kwiberg3ec46792016-04-27 07:22:53 -07002095 std::unique_ptr<IceMessage> in_msg, out_msg;
2096 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002097 rtc::SocketAddress addr(kLocalAddr1);
2098 std::string username;
2099
2100 // BINDING-REQUEST with no username.
2101 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
2102 in_msg->AddMessageIntegrity("rpass");
2103 in_msg->AddFingerprint();
2104 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002105 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2106 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002107 EXPECT_TRUE(out_msg.get() == NULL);
2108 EXPECT_EQ("", username);
2109 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2110
2111 // BINDING-REQUEST with empty username.
2112 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
2113 in_msg->AddMessageIntegrity("rpass");
2114 in_msg->AddFingerprint();
2115 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002116 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2117 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002118 EXPECT_TRUE(out_msg.get() == NULL);
2119 EXPECT_EQ("", username);
2120 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2121
2122 // BINDING-REQUEST with too-short username.
2123 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
2124 in_msg->AddMessageIntegrity("rpass");
2125 in_msg->AddFingerprint();
2126 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002127 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2128 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002129 EXPECT_TRUE(out_msg.get() == NULL);
2130 EXPECT_EQ("", username);
2131 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2132
2133 // BINDING-REQUEST with reversed username.
2134 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2135 "lfrag:rfrag"));
2136 in_msg->AddMessageIntegrity("rpass");
2137 in_msg->AddFingerprint();
2138 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002139 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2140 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002141 EXPECT_TRUE(out_msg.get() == NULL);
2142 EXPECT_EQ("", username);
2143 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2144
2145 // BINDING-REQUEST with garbage username.
2146 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2147 "abcd:efgh"));
2148 in_msg->AddMessageIntegrity("rpass");
2149 in_msg->AddFingerprint();
2150 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002151 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2152 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002153 EXPECT_TRUE(out_msg.get() == NULL);
2154 EXPECT_EQ("", username);
2155 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2156}
2157
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002158// Test handling STUN messages with missing or malformed M-I.
2159TEST_F(PortTest, TestHandleStunMessageBadMessageIntegrity) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002160 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002161 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002162
kwiberg3ec46792016-04-27 07:22:53 -07002163 std::unique_ptr<IceMessage> in_msg, out_msg;
2164 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002165 rtc::SocketAddress addr(kLocalAddr1);
2166 std::string username;
2167
2168 // BINDING-REQUEST from local to remote with valid ICE username and
2169 // FINGERPRINT, but no MESSAGE-INTEGRITY.
2170 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2171 "rfrag:lfrag"));
2172 in_msg->AddFingerprint();
2173 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002174 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2175 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002176 EXPECT_TRUE(out_msg.get() == NULL);
2177 EXPECT_EQ("", username);
2178 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2179
2180 // BINDING-REQUEST from local to remote with valid ICE username and
2181 // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
2182 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2183 "rfrag:lfrag"));
2184 in_msg->AddMessageIntegrity("invalid");
2185 in_msg->AddFingerprint();
2186 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002187 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2188 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002189 EXPECT_TRUE(out_msg.get() == NULL);
2190 EXPECT_EQ("", username);
2191 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2192
2193 // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
2194 // by the Connection, not the Port, since they require the remote username.
2195 // Change this test to pass in data via Connection::OnReadPacket instead.
2196}
2197
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002198// Test handling STUN messages with missing or malformed FINGERPRINT.
2199TEST_F(PortTest, TestHandleStunMessageBadFingerprint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002200 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002201 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002202
kwiberg3ec46792016-04-27 07:22:53 -07002203 std::unique_ptr<IceMessage> in_msg, out_msg;
2204 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002205 rtc::SocketAddress addr(kLocalAddr1);
2206 std::string username;
2207
2208 // BINDING-REQUEST from local to remote with valid ICE username and
2209 // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
2210 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2211 "rfrag:lfrag"));
2212 in_msg->AddMessageIntegrity("rpass");
2213 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002214 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2215 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002216 EXPECT_EQ(0, port->last_stun_error_code());
2217
2218 // Now, add a fingerprint, but munge the message so it's not valid.
2219 in_msg->AddFingerprint();
2220 in_msg->SetTransactionID("TESTTESTBADD");
2221 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002222 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2223 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002224 EXPECT_EQ(0, port->last_stun_error_code());
2225
2226 // Valid BINDING-RESPONSE, except no FINGERPRINT.
2227 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002228 in_msg->AddAttribute(rtc::MakeUnique<StunXorAddressAttribute>(
2229 STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002230 in_msg->AddMessageIntegrity("rpass");
2231 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002232 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2233 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002234 EXPECT_EQ(0, port->last_stun_error_code());
2235
2236 // Now, add a fingerprint, but munge the message so it's not valid.
2237 in_msg->AddFingerprint();
2238 in_msg->SetTransactionID("TESTTESTBADD");
2239 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002240 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2241 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002242 EXPECT_EQ(0, port->last_stun_error_code());
2243
2244 // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
2245 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002246 in_msg->AddAttribute(rtc::MakeUnique<StunErrorCodeAttribute>(
2247 STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2248 STUN_ERROR_REASON_SERVER_ERROR));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002249 in_msg->AddMessageIntegrity("rpass");
2250 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002251 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2252 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002253 EXPECT_EQ(0, port->last_stun_error_code());
2254
2255 // Now, add a fingerprint, but munge the message so it's not valid.
2256 in_msg->AddFingerprint();
2257 in_msg->SetTransactionID("TESTTESTBADD");
2258 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002259 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2260 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002261 EXPECT_EQ(0, port->last_stun_error_code());
2262}
2263
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002264// Test handling of STUN binding indication messages . STUN binding
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002265// indications are allowed only to the connection which is in read mode.
2266TEST_F(PortTest, TestHandleStunBindingIndication) {
kwiberg3ec46792016-04-27 07:22:53 -07002267 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002268 CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002269 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2270 lport->SetIceTiebreaker(kTiebreaker1);
2271
2272 // Verifying encoding and decoding STUN indication message.
kwiberg3ec46792016-04-27 07:22:53 -07002273 std::unique_ptr<IceMessage> in_msg, out_msg;
2274 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002275 rtc::SocketAddress addr(kLocalAddr1);
2276 std::string username;
2277
2278 in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
2279 in_msg->AddFingerprint();
2280 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002281 EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2282 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002283 EXPECT_TRUE(out_msg.get() != NULL);
2284 EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2285 EXPECT_EQ("", username);
2286
2287 // Verify connection can handle STUN indication and updates
2288 // last_ping_received.
kwiberg3ec46792016-04-27 07:22:53 -07002289 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002290 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002291 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2292 rport->SetIceTiebreaker(kTiebreaker2);
2293
2294 lport->PrepareAddress();
2295 rport->PrepareAddress();
2296 ASSERT_FALSE(lport->Candidates().empty());
2297 ASSERT_FALSE(rport->Candidates().empty());
2298
2299 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
2300 Port::ORIGIN_MESSAGE);
2301 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
2302 Port::ORIGIN_MESSAGE);
2303 rconn->Ping(0);
2304
Honghai Zhang161a5862016-10-20 11:47:02 -07002305 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002306 IceMessage* msg = rport->last_stun_msg();
2307 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2308 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07002309 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
2310 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002311 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07002312 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002313 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
honghaiz34b11eb2016-03-16 08:55:44 -07002314 int64_t last_ping_received1 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002315
2316 // Adding a delay of 100ms.
2317 rtc::Thread::Current()->ProcessMessages(100);
2318 // Pinging lconn using stun indication message.
2319 lconn->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
honghaiz34b11eb2016-03-16 08:55:44 -07002320 int64_t last_ping_received2 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002321 EXPECT_GT(last_ping_received2, last_ping_received1);
2322}
2323
2324TEST_F(PortTest, TestComputeCandidatePriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002325 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr1, "name", "pass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002326 port->set_type_preference(90);
2327 port->set_component(177);
2328 port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2329 port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2330 port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2331 port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2332 port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2333 port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2334 port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2335 port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2336 port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2337 // These should all be:
2338 // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
Peter Boström0c4e06b2015-10-07 12:23:21 +02002339 uint32_t expected_priority_v4 = 1509957199U;
2340 uint32_t expected_priority_v6 = 1509959759U;
2341 uint32_t expected_priority_ula = 1509962319U;
2342 uint32_t expected_priority_v4mapped = expected_priority_v4;
2343 uint32_t expected_priority_v4compat = 1509949775U;
2344 uint32_t expected_priority_6to4 = 1509954639U;
2345 uint32_t expected_priority_teredo = 1509952079U;
2346 uint32_t expected_priority_sitelocal = 1509949775U;
2347 uint32_t expected_priority_6bone = 1509949775U;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002348 ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2349 ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2350 ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2351 ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2352 ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2353 ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2354 ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2355 ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2356 ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2357}
2358
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002359// In the case of shared socket, one port may be shared by local and stun.
2360// Test that candidates with different types will have different foundation.
2361TEST_F(PortTest, TestFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002362 std::unique_ptr<TestPort> testport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002363 CreateTestPort(kLocalAddr1, "name", "pass"));
2364 testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2365 LOCAL_PORT_TYPE,
2366 cricket::ICE_TYPE_PREFERENCE_HOST, false);
2367 testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2368 STUN_PORT_TYPE,
2369 cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2370 EXPECT_NE(testport->Candidates()[0].foundation(),
2371 testport->Candidates()[1].foundation());
2372}
2373
2374// This test verifies the foundation of different types of ICE candidates.
2375TEST_F(PortTest, TestCandidateFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002376 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002377 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002378 std::unique_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002379 udpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002380 std::unique_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002381 udpport2->PrepareAddress();
2382 EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2383 udpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002384 std::unique_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002385 tcpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002386 std::unique_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002387 tcpport2->PrepareAddress();
2388 EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2389 tcpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002390 std::unique_ptr<Port> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002391 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2392 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002393 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002394 EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2395 stunport->Candidates()[0].foundation());
2396 EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2397 stunport->Candidates()[0].foundation());
2398 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2399 stunport->Candidates()[0].foundation());
2400 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2401 stunport->Candidates()[0].foundation());
2402 // Verify GTURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002403 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002404 relayport->AddServerAddress(
2405 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2406 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002407 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002408 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2409 relayport->Candidates()[0].foundation());
2410 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2411 relayport->Candidates()[0].foundation());
2412 // Verifying TURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002413 std::unique_ptr<Port> turnport1(
2414 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002415 turnport1->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002416 ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002417 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2418 turnport1->Candidates()[0].foundation());
2419 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2420 turnport1->Candidates()[0].foundation());
2421 EXPECT_NE(stunport->Candidates()[0].foundation(),
2422 turnport1->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002423 std::unique_ptr<Port> turnport2(
2424 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002425 turnport2->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002426 ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002427 EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2428 turnport2->Candidates()[0].foundation());
2429
2430 // Running a second turn server, to get different base IP address.
2431 SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2432 SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2433 TestTurnServer turn_server2(
2434 rtc::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
kwiberg3ec46792016-04-27 07:22:53 -07002435 std::unique_ptr<Port> turnport3(
2436 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
2437 kTurnUdpIntAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002438 turnport3->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002439 ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002440 EXPECT_NE(turnport3->Candidates()[0].foundation(),
2441 turnport2->Candidates()[0].foundation());
Honghai Zhang80f1db92016-01-27 11:54:45 -08002442
2443 // Start a TCP turn server, and check that two turn candidates have
2444 // different foundations if their relay protocols are different.
2445 TestTurnServer turn_server3(rtc::Thread::Current(), kTurnTcpIntAddr,
2446 kTurnUdpExtAddr, PROTO_TCP);
kwiberg3ec46792016-04-27 07:22:53 -07002447 std::unique_ptr<Port> turnport4(
Honghai Zhang80f1db92016-01-27 11:54:45 -08002448 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_TCP, PROTO_UDP));
2449 turnport4->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002450 ASSERT_EQ_WAIT(1U, turnport4->Candidates().size(), kDefaultTimeout);
Honghai Zhang80f1db92016-01-27 11:54:45 -08002451 EXPECT_NE(turnport2->Candidates()[0].foundation(),
2452 turnport4->Candidates()[0].foundation());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002453}
2454
2455// This test verifies the related addresses of different types of
2456// ICE candiates.
2457TEST_F(PortTest, TestCandidateRelatedAddress) {
kwiberg3ec46792016-04-27 07:22:53 -07002458 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002459 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002460 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002461 udpport->PrepareAddress();
2462 // For UDPPort, related address will be empty.
2463 EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2464 // Testing related address for stun candidates.
2465 // For stun candidate related address must be equal to the base
2466 // socket address.
kwiberg3ec46792016-04-27 07:22:53 -07002467 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002468 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2469 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002470 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002471 // Check STUN candidate address.
2472 EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2473 kNatAddr1.ipaddr());
2474 // Check STUN candidate related address.
2475 EXPECT_EQ(stunport->Candidates()[0].related_address(),
2476 stunport->GetLocalAddress());
2477 // Verifying the related address for the GTURN candidates.
2478 // NOTE: In case of GTURN related address will be equal to the mapped
2479 // address, but address(mapped) will not be XOR.
kwiberg3ec46792016-04-27 07:22:53 -07002480 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002481 relayport->AddServerAddress(
2482 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2483 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002484 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002485 // For Gturn related address is set to "0.0.0.0:0"
2486 EXPECT_EQ(rtc::SocketAddress(),
2487 relayport->Candidates()[0].related_address());
2488 // Verifying the related address for TURN candidate.
2489 // For TURN related address must be equal to the mapped address.
kwiberg3ec46792016-04-27 07:22:53 -07002490 std::unique_ptr<Port> turnport(
2491 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002492 turnport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002493 ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002494 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
2495 turnport->Candidates()[0].address().ipaddr());
2496 EXPECT_EQ(kNatAddr1.ipaddr(),
2497 turnport->Candidates()[0].related_address().ipaddr());
2498}
2499
2500// Test priority value overflow handling when preference is set to 3.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002501TEST_F(PortTest, TestCandidatePriority) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002502 cricket::Candidate cand1;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002503 cand1.set_priority(3);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002504 cricket::Candidate cand2;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002505 cand2.set_priority(1);
2506 EXPECT_TRUE(cand1.priority() > cand2.priority());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002507}
2508
2509// Test the Connection priority is calculated correctly.
2510TEST_F(PortTest, TestConnectionPriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002511 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002512 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2513 lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
kwiberg3ec46792016-04-27 07:22:53 -07002514 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002515 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
hnsl277b2502016-12-13 05:17:23 -08002516 rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002517 lport->set_component(123);
2518 lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2519 rport->set_component(23);
2520 rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2521
2522 EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2523 EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2524
2525 // RFC 5245
2526 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
2527 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2528 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2529 Connection* lconn = lport->CreateConnection(
2530 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2531#if defined(WEBRTC_WIN)
2532 EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2533#else
2534 EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2535#endif
2536
2537 lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2538 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2539 Connection* rconn = rport->CreateConnection(
2540 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2541#if defined(WEBRTC_WIN)
2542 EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2543#else
2544 EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2545#endif
2546}
2547
2548TEST_F(PortTest, TestWritableState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002549 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002550 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002551 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002552 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002553 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002554
2555 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002556 TestChannel ch1(port1);
2557 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002558
2559 // Acquire addresses.
2560 ch1.Start();
2561 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07002562 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
2563 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002564
2565 // Send a ping from src to dst.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002566 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002567 ASSERT_TRUE(ch1.conn() != NULL);
2568 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
Honghai Zhang161a5862016-10-20 11:47:02 -07002569 // for TCP connect
2570 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002571 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002572 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002573
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002574 // Data should be sendable before the connection is accepted.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002575 char data[] = "abcd";
tfarina5237aaf2015-11-10 23:44:30 -08002576 int data_size = arraysize(data);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002577 rtc::PacketOptions options;
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002578 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002579
2580 // Accept the connection to return the binding response, transition to
2581 // writable, and allow data to be sent.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002582 ch2.AcceptConnection(GetCandidate(port1));
Honghai Zhang161a5862016-10-20 11:47:02 -07002583 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2584 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002585 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2586
2587 // Ask the connection to update state as if enough time has passed to lose
2588 // full writability and 5 pings went unresponded to. We'll accomplish the
2589 // latter by sending pings but not pumping messages.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002590 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002591 ch1.Ping(i);
2592 }
honghaiz34b11eb2016-03-16 08:55:44 -07002593 int unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002594 ch1.conn()->UpdateState(unreliable_timeout_delay);
2595 EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2596
2597 // Data should be able to be sent in this state.
2598 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2599
2600 // And now allow the other side to process the pings and send binding
2601 // responses.
Honghai Zhang161a5862016-10-20 11:47:02 -07002602 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2603 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002604
2605 // Wait long enough for a full timeout (past however long we've already
2606 // waited).
Peter Boström0c4e06b2015-10-07 12:23:21 +02002607 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002608 ch1.Ping(unreliable_timeout_delay + i);
2609 }
2610 ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2611 500u);
2612 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2613
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002614 // Even if the connection has timed out, the Connection shouldn't block
2615 // the sending of data.
2616 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002617
2618 ch1.Stop();
2619 ch2.Stop();
2620}
2621
2622TEST_F(PortTest, TestTimeoutForNeverWritable) {
2623 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002624 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002625 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002626 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002627
2628 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002629 TestChannel ch1(port1);
2630 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002631
2632 // Acquire addresses.
2633 ch1.Start();
2634 ch2.Start();
2635
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002636 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002637 ASSERT_TRUE(ch1.conn() != NULL);
2638 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2639
2640 // Attempt to go directly to write timeout.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002641 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002642 ch1.Ping(i);
2643 }
2644 ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2645 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2646}
2647
2648// This test verifies the connection setup between ICEMODE_FULL
2649// and ICEMODE_LITE.
2650// In this test |ch1| behaves like FULL mode client and we have created
2651// port which responds to the ping message just like LITE client.
2652TEST_F(PortTest, TestIceLiteConnectivity) {
2653 TestPort* ice_full_port = CreateTestPort(
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002654 kLocalAddr1, "lfrag", "lpass",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002655 cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2656
kwiberg3ec46792016-04-27 07:22:53 -07002657 std::unique_ptr<TestPort> ice_lite_port(
2658 CreateTestPort(kLocalAddr2, "rfrag", "rpass", cricket::ICEROLE_CONTROLLED,
2659 kTiebreaker2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002660 // Setup TestChannel. This behaves like FULL mode client.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002661 TestChannel ch1(ice_full_port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002662 ch1.SetIceMode(ICEMODE_FULL);
2663
2664 // Start gathering candidates.
2665 ch1.Start();
2666 ice_lite_port->PrepareAddress();
2667
Honghai Zhang161a5862016-10-20 11:47:02 -07002668 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002669 ASSERT_FALSE(ice_lite_port->Candidates().empty());
2670
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002671 ch1.CreateConnection(GetCandidate(ice_lite_port.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002672 ASSERT_TRUE(ch1.conn() != NULL);
2673 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2674
2675 // Send ping from full mode client.
2676 // This ping must not have USE_CANDIDATE_ATTR.
2677 ch1.Ping();
2678
2679 // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2680 // from port.
Honghai Zhang161a5862016-10-20 11:47:02 -07002681 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002682 IceMessage* msg = ice_full_port->last_stun_msg();
2683 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2684
2685 // Respond with a BINDING-RESPONSE from litemode client.
2686 // NOTE: Ideally we should't create connection at this stage from lite
2687 // port, as it should be done only after receiving ping with USE_CANDIDATE.
2688 // But we need a connection to send a response message.
2689 ice_lite_port->CreateConnection(
2690 ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
kwiberg3ec46792016-04-27 07:22:53 -07002691 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002692 ice_lite_port->SendBindingResponse(
2693 request.get(), ice_full_port->Candidates()[0].address());
2694
2695 // Feeding the respone message from litemode to the full mode connection.
jbauchf1f87202016-03-30 06:43:37 -07002696 ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->data<char>(),
2697 ice_lite_port->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002698 rtc::PacketTime());
2699 // Verifying full mode connection becomes writable from the response.
2700 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002701 kDefaultTimeout);
2702 EXPECT_TRUE_WAIT(ch1.nominated(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002703
2704 // Clear existing stun messsages. Otherwise we will process old stun
2705 // message right after we send ping.
2706 ice_full_port->Reset();
2707 // Send ping. This must have USE_CANDIDATE_ATTR.
2708 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002709 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002710 msg = ice_full_port->last_stun_msg();
2711 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2712 ch1.Stop();
2713}
2714
Honghai Zhanga74363c2016-07-28 18:06:15 -07002715// This test case verifies that both the controlling port and the controlled
2716// port will time out after connectivity is lost, if they are not marked as
2717// "keep alive until pruned."
2718TEST_F(PortTest, TestPortTimeoutIfNotKeptAlive) {
2719 rtc::ScopedFakeClock clock;
2720 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002721 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2722 ConnectToSignalDestroyed(port1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002723 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002724 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2725 port1->SetIceTiebreaker(kTiebreaker1);
2726
2727 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002728 ConnectToSignalDestroyed(port2);
2729 port2->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002730 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2731 port2->SetIceTiebreaker(kTiebreaker2);
2732
2733 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002734 TestChannel ch1(port1);
2735 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002736
2737 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002738 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002739 // After the connection is destroyed, the port will be destroyed because
2740 // none of them is marked as "keep alive until pruned.
2741 EXPECT_EQ_SIMULATED_WAIT(2, ports_destroyed(), 110, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002742}
2743
Honghai Zhanga74363c2016-07-28 18:06:15 -07002744// Test that if after all connection are destroyed, new connections are created
2745// and destroyed again, ports won't be destroyed until a timeout period passes
2746// after the last set of connections are all destroyed.
2747TEST_F(PortTest, TestPortTimeoutAfterNewConnectionCreatedAndDestroyed) {
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002748 rtc::ScopedFakeClock clock;
Honghai Zhanga74363c2016-07-28 18:06:15 -07002749 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002750 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002751 ConnectToSignalDestroyed(port1);
2752 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002753 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2754 port1->SetIceTiebreaker(kTiebreaker1);
2755
2756 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2757 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002758 port2->set_timeout_delay(timeout_delay); // milliseconds
2759
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002760 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2761 port2->SetIceTiebreaker(kTiebreaker2);
2762
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002763 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002764 TestChannel ch1(port1);
2765 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002766
2767 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002768 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002769 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2770 EXPECT_EQ(0, ports_destroyed());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002771
Honghai Zhanga74363c2016-07-28 18:06:15 -07002772 // Start the second set of connection and destroy them.
2773 ch1.CreateConnection(GetCandidate(ch2.port()));
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002774 ch2.CreateConnection(GetCandidate(ch1.port()));
Honghai Zhanga74363c2016-07-28 18:06:15 -07002775 ch1.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002776 ch2.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002777
Honghai Zhanga74363c2016-07-28 18:06:15 -07002778 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2779 EXPECT_EQ(0, ports_destroyed());
2780
2781 // The ports on both sides should be destroyed after timeout.
2782 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 30, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002783}
honghaizd0b31432015-09-30 12:42:17 -07002784
Honghai Zhanga74363c2016-07-28 18:06:15 -07002785// This test case verifies that neither the controlling port nor the controlled
2786// port will time out after connectivity is lost if they are marked as "keep
2787// alive until pruned". They will time out after they are pruned.
2788TEST_F(PortTest, TestPortNotTimeoutUntilPruned) {
2789 rtc::ScopedFakeClock clock;
2790 int timeout_delay = 100;
honghaizd0b31432015-09-30 12:42:17 -07002791 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002792 ConnectToSignalDestroyed(port1);
2793 port1->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002794 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2795 port1->SetIceTiebreaker(kTiebreaker1);
2796
2797 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2798 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002799 port2->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002800 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2801 port2->SetIceTiebreaker(kTiebreaker2);
honghaizd0b31432015-09-30 12:42:17 -07002802 // The connection must not be destroyed before a connection is attempted.
Honghai Zhanga74363c2016-07-28 18:06:15 -07002803 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002804
2805 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2806 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2807
Honghai Zhanga74363c2016-07-28 18:06:15 -07002808 // Set up channels and keep the port alive.
honghaizd0b31432015-09-30 12:42:17 -07002809 TestChannel ch1(port1);
2810 TestChannel ch2(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002811 // Simulate a connection that succeeds, and then is destroyed. But ports
2812 // are kept alive. Ports won't be destroyed.
honghaizd0b31432015-09-30 12:42:17 -07002813 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002814 port1->KeepAliveUntilPruned();
2815 port2->KeepAliveUntilPruned();
2816 SIMULATED_WAIT(ports_destroyed() > 0, 150, clock);
2817 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002818
Honghai Zhanga74363c2016-07-28 18:06:15 -07002819 // If they are pruned now, they will be destroyed right away.
2820 port1->Prune();
2821 port2->Prune();
2822 // The ports on both sides should be destroyed after timeout.
2823 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 1, clock);
honghaizd0b31432015-09-30 12:42:17 -07002824}
Honghai Zhangf9945b22015-12-15 12:20:13 -08002825
2826TEST_F(PortTest, TestSupportsProtocol) {
kwiberg3ec46792016-04-27 07:22:53 -07002827 std::unique_ptr<Port> udp_port(CreateUdpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002828 EXPECT_TRUE(udp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2829 EXPECT_FALSE(udp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2830
kwiberg3ec46792016-04-27 07:22:53 -07002831 std::unique_ptr<Port> stun_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002832 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2833 EXPECT_TRUE(stun_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2834 EXPECT_FALSE(stun_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2835
kwiberg3ec46792016-04-27 07:22:53 -07002836 std::unique_ptr<Port> tcp_port(CreateTcpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002837 EXPECT_TRUE(tcp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2838 EXPECT_TRUE(tcp_port->SupportsProtocol(SSLTCP_PROTOCOL_NAME));
2839 EXPECT_FALSE(tcp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2840
kwiberg3ec46792016-04-27 07:22:53 -07002841 std::unique_ptr<Port> turn_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002842 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2843 EXPECT_TRUE(turn_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2844 EXPECT_FALSE(turn_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2845}
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002846
2847// Test that SetIceParameters updates the component, ufrag and password
2848// on both the port itself and its candidates.
2849TEST_F(PortTest, TestSetIceParameters) {
2850 std::unique_ptr<TestPort> port(
2851 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2852 port->PrepareAddress();
2853 EXPECT_EQ(1UL, port->Candidates().size());
2854 port->SetIceParameters(1, "ufrag2", "password2");
2855 EXPECT_EQ(1, port->component());
2856 EXPECT_EQ("ufrag2", port->username_fragment());
2857 EXPECT_EQ("password2", port->password());
2858 const Candidate& candidate = port->Candidates()[0];
2859 EXPECT_EQ(1, candidate.component());
2860 EXPECT_EQ("ufrag2", candidate.username());
2861 EXPECT_EQ("password2", candidate.password());
2862}
honghaiz36f50e82016-06-01 15:57:03 -07002863
2864TEST_F(PortTest, TestAddConnectionWithSameAddress) {
2865 std::unique_ptr<TestPort> port(
2866 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2867 port->PrepareAddress();
2868 EXPECT_EQ(1u, port->Candidates().size());
2869 rtc::SocketAddress address("1.1.1.1", 5000);
2870 cricket::Candidate candidate(1, "udp", address, 0, "", "", "relay", 0, "");
2871 cricket::Connection* conn1 =
2872 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2873 cricket::Connection* conn_in_use = port->GetConnection(address);
2874 EXPECT_EQ(conn1, conn_in_use);
2875 EXPECT_EQ(0u, conn_in_use->remote_candidate().generation());
2876
2877 // Creating with a candidate with the same address again will get us a
2878 // different connection with the new candidate.
2879 candidate.set_generation(2);
2880 cricket::Connection* conn2 =
2881 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2882 EXPECT_NE(conn1, conn2);
2883 conn_in_use = port->GetConnection(address);
2884 EXPECT_EQ(conn2, conn_in_use);
2885 EXPECT_EQ(2u, conn_in_use->remote_candidate().generation());
2886
2887 // Make sure the new connection was not deleted.
2888 rtc::Thread::Current()->ProcessMessages(300);
2889 EXPECT_TRUE(port->GetConnection(address) != nullptr);
2890}