blob: 88ed7f462320132a37a8dbeff392e085e983af77 [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
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013#include "webrtc/p2p/base/basicpacketsocketfactory.h"
deadbeef49f34fd2016-12-06 16:22:06 -080014#include "webrtc/p2p/base/jseptransport.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000015#include "webrtc/p2p/base/relayport.h"
16#include "webrtc/p2p/base/stunport.h"
17#include "webrtc/p2p/base/tcpport.h"
18#include "webrtc/p2p/base/testrelayserver.h"
19#include "webrtc/p2p/base/teststunserver.h"
20#include "webrtc/p2p/base/testturnserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021#include "webrtc/p2p/base/turnport.h"
tfarina5237aaf2015-11-10 23:44:30 -080022#include "webrtc/base/arraysize.h"
jbauchf1f87202016-03-30 06:43:37 -070023#include "webrtc/base/buffer.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000024#include "webrtc/base/crc32.h"
25#include "webrtc/base/gunit.h"
26#include "webrtc/base/helpers.h"
27#include "webrtc/base/logging.h"
28#include "webrtc/base/natserver.h"
29#include "webrtc/base/natsocketfactory.h"
30#include "webrtc/base/physicalsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000031#include "webrtc/base/socketaddress.h"
32#include "webrtc/base/ssladapter.h"
33#include "webrtc/base/stringutils.h"
34#include "webrtc/base/thread.h"
35#include "webrtc/base/virtualsocketserver.h"
36
37using rtc::AsyncPacketSocket;
jbauchf1f87202016-03-30 06:43:37 -070038using rtc::Buffer;
39using rtc::ByteBufferReader;
40using rtc::ByteBufferWriter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000041using rtc::NATType;
42using rtc::NAT_OPEN_CONE;
43using rtc::NAT_ADDR_RESTRICTED;
44using rtc::NAT_PORT_RESTRICTED;
45using rtc::NAT_SYMMETRIC;
46using rtc::PacketSocketFactory;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047using rtc::Socket;
48using rtc::SocketAddress;
49using namespace cricket;
50
Honghai Zhang161a5862016-10-20 11:47:02 -070051static const int kDefaultTimeout = 3000;
52static const int kShortTimeout = 1000;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053static const SocketAddress kLocalAddr1("192.168.1.2", 0);
54static const SocketAddress kLocalAddr2("192.168.1.3", 0);
deadbeefc5d0d952015-07-16 10:22:21 -070055static const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
56static const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000057static const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
58static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
59static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
60static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
61static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
62static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
63static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
64static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
Honghai Zhang80f1db92016-01-27 11:54:45 -080065static const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000066static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
67static const RelayCredentials kRelayCredentials("test", "test");
68
69// TODO: Update these when RFC5245 is completely supported.
70// Magic value of 30 is from RFC3484, for IPv4 addresses.
Peter Boström0c4e06b2015-10-07 12:23:21 +020071static const uint32_t kDefaultPrflxPriority =
72 ICE_TYPE_PREFERENCE_PRFLX << 24 | 30 << 8 |
73 (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000074
75static const int kTiebreaker1 = 11111;
76static const int kTiebreaker2 = 22222;
77
Guo-wei Shiehbe508a12015-04-06 12:48:47 -070078static const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
79
zhihuang6d0d4bf2016-05-24 10:13:32 -070080static const int kGturnUserNameLength = 16;
81
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000082static Candidate GetCandidate(Port* port) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -070083 assert(port->Candidates().size() >= 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084 return port->Candidates()[0];
85}
86
87static SocketAddress GetAddress(Port* port) {
88 return GetCandidate(port).address();
89}
90
91static IceMessage* CopyStunMessage(const IceMessage* src) {
92 IceMessage* dst = new IceMessage();
jbauchf1f87202016-03-30 06:43:37 -070093 ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000094 src->Write(&buf);
jbauchf1f87202016-03-30 06:43:37 -070095 ByteBufferReader read_buf(buf);
96 dst->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097 return dst;
98}
99
jbauchf1f87202016-03-30 06:43:37 -0700100static bool WriteStunMessage(const StunMessage* msg, ByteBufferWriter* buf) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000101 buf->Resize(0); // clear out any existing buffer contents
102 return msg->Write(buf);
103}
104
105// Stub port class for testing STUN generation and processing.
106class TestPort : public Port {
107 public:
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000108 TestPort(rtc::Thread* thread,
109 const std::string& type,
110 rtc::PacketSocketFactory* factory,
111 rtc::Network* network,
112 const rtc::IPAddress& ip,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200113 uint16_t min_port,
114 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000115 const std::string& username_fragment,
116 const std::string& password)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200117 : Port(thread,
118 type,
119 factory,
120 network,
121 ip,
122 min_port,
123 max_port,
124 username_fragment,
125 password) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000126 ~TestPort() {}
127
128 // Expose GetStunMessage so that we can test it.
129 using cricket::Port::GetStunMessage;
130
131 // The last StunMessage that was sent on this Port.
132 // TODO: Make these const; requires changes to SendXXXXResponse.
jbauchf1f87202016-03-30 06:43:37 -0700133 Buffer* last_stun_buf() { return last_stun_buf_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134 IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
135 int last_stun_error_code() {
136 int code = 0;
137 if (last_stun_msg_) {
138 const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
139 if (error_attr) {
140 code = error_attr->code();
141 }
142 }
143 return code;
144 }
145
146 virtual void PrepareAddress() {
147 rtc::SocketAddress addr(ip(), min_port());
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700148 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000149 ICE_TYPE_PREFERENCE_HOST, 0, true);
150 }
151
Honghai Zhangf9945b22015-12-15 12:20:13 -0800152 virtual bool SupportsProtocol(const std::string& protocol) const {
153 return true;
154 }
155
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -0700156 virtual ProtocolType GetProtocol() const { return PROTO_UDP; }
157
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000158 // Exposed for testing candidate building.
159 void AddCandidateAddress(const rtc::SocketAddress& addr) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700160 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000161 type_preference_, 0, false);
162 }
163 void AddCandidateAddress(const rtc::SocketAddress& addr,
164 const rtc::SocketAddress& base_address,
165 const std::string& type,
166 int type_preference,
167 bool final) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700168 AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000169 type_preference, 0, final);
170 }
171
172 virtual Connection* CreateConnection(const Candidate& remote_candidate,
173 CandidateOrigin origin) {
174 Connection* conn = new ProxyConnection(this, 0, remote_candidate);
honghaiz36f50e82016-06-01 15:57:03 -0700175 AddOrReplaceConnection(conn);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176 // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
177 // in STUN binding requests.
178 conn->set_use_candidate_attr(true);
179 return conn;
180 }
181 virtual int SendTo(
182 const void* data, size_t size, const rtc::SocketAddress& addr,
183 const rtc::PacketOptions& options, bool payload) {
184 if (!payload) {
185 IceMessage* msg = new IceMessage;
jbauchf1f87202016-03-30 06:43:37 -0700186 Buffer* buf = new Buffer(static_cast<const char*>(data), size);
187 ByteBufferReader read_buf(*buf);
188 if (!msg->Read(&read_buf)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000189 delete msg;
190 delete buf;
191 return -1;
192 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 last_stun_buf_.reset(buf);
194 last_stun_msg_.reset(msg);
195 }
196 return static_cast<int>(size);
197 }
198 virtual int SetOption(rtc::Socket::Option opt, int value) {
199 return 0;
200 }
201 virtual int GetOption(rtc::Socket::Option opt, int* value) {
202 return -1;
203 }
204 virtual int GetError() {
205 return 0;
206 }
207 void Reset() {
208 last_stun_buf_.reset();
209 last_stun_msg_.reset();
210 }
211 void set_type_preference(int type_preference) {
212 type_preference_ = type_preference;
213 }
214
215 private:
Stefan Holmer55674ff2016-01-14 15:49:16 +0100216 void OnSentPacket(rtc::AsyncPacketSocket* socket,
217 const rtc::SentPacket& sent_packet) {
218 PortInterface::SignalSentPacket(sent_packet);
219 }
kwiberg3ec46792016-04-27 07:22:53 -0700220 std::unique_ptr<Buffer> last_stun_buf_;
221 std::unique_ptr<IceMessage> last_stun_msg_;
pbos7640ffa2015-11-30 09:16:59 -0800222 int type_preference_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000223};
224
225class TestChannel : public sigslot::has_slots<> {
226 public:
227 // Takes ownership of |p1| (but not |p2|).
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700228 TestChannel(Port* p1)
229 : ice_mode_(ICEMODE_FULL),
230 port_(p1),
231 complete_count_(0),
232 conn_(NULL),
233 remote_request_(),
234 nominated_(false) {
235 port_->SignalPortComplete.connect(this, &TestChannel::OnPortComplete);
236 port_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
237 port_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000238 }
239
240 int complete_count() { return complete_count_; }
241 Connection* conn() { return conn_; }
242 const SocketAddress& remote_address() { return remote_address_; }
243 const std::string remote_fragment() { return remote_frag_; }
244
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700245 void Start() { port_->PrepareAddress(); }
246 void CreateConnection(const Candidate& remote_candidate) {
247 conn_ = port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000248 IceMode remote_ice_mode =
249 (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
250 conn_->set_remote_ice_mode(remote_ice_mode);
251 conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
252 conn_->SignalStateChange.connect(
253 this, &TestChannel::OnConnectionStateChange);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700254 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700255 conn_->SignalReadyToSend.connect(this,
256 &TestChannel::OnConnectionReadyToSend);
257 connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000258 }
259 void OnConnectionStateChange(Connection* conn) {
260 if (conn->write_state() == Connection::STATE_WRITABLE) {
261 conn->set_use_candidate_attr(true);
262 nominated_ = true;
263 }
264 }
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700265 void AcceptConnection(const Candidate& remote_candidate) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 ASSERT_TRUE(remote_request_.get() != NULL);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700267 Candidate c = remote_candidate;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000268 c.set_address(remote_address_);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700269 conn_ = port_->CreateConnection(c, Port::ORIGIN_MESSAGE);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700270 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700271 port_->SendBindingResponse(remote_request_.get(), remote_address_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000272 remote_request_.reset();
273 }
274 void Ping() {
275 Ping(0);
276 }
honghaiz34b11eb2016-03-16 08:55:44 -0700277 void Ping(int64_t now) { conn_->Ping(now); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000278 void Stop() {
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700279 if (conn_) {
280 conn_->Destroy();
281 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000282 }
283
284 void OnPortComplete(Port* port) {
285 complete_count_++;
286 }
287 void SetIceMode(IceMode ice_mode) {
288 ice_mode_ = ice_mode;
289 }
290
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700291 int SendData(const char* data, size_t len) {
292 rtc::PacketOptions options;
293 return conn_->Send(data, len, options);
294 }
295
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000296 void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
297 ProtocolType proto,
298 IceMessage* msg, const std::string& rf,
299 bool /*port_muxed*/) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700300 ASSERT_EQ(port_.get(), port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 if (!remote_address_.IsNil()) {
302 ASSERT_EQ(remote_address_, addr);
303 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000304 const cricket::StunUInt32Attribute* priority_attr =
305 msg->GetUInt32(STUN_ATTR_PRIORITY);
306 const cricket::StunByteStringAttribute* mi_attr =
307 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
308 const cricket::StunUInt32Attribute* fingerprint_attr =
309 msg->GetUInt32(STUN_ATTR_FINGERPRINT);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700310 EXPECT_TRUE(priority_attr != NULL);
311 EXPECT_TRUE(mi_attr != NULL);
312 EXPECT_TRUE(fingerprint_attr != NULL);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000313 remote_address_ = addr;
314 remote_request_.reset(CopyStunMessage(msg));
315 remote_frag_ = rf;
316 }
317
318 void OnDestroyed(Connection* conn) {
319 ASSERT_EQ(conn_, conn);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700320 LOG(INFO) << "OnDestroy connection " << conn << " deleted";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000321 conn_ = NULL;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700322 // When the connection is destroyed, also clear these fields so future
323 // connections are possible.
324 remote_request_.reset();
325 remote_address_.Clear();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000326 }
327
328 void OnSrcPortDestroyed(PortInterface* port) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700329 Port* destroyed_src = port_.release();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330 ASSERT_EQ(destroyed_src, port);
331 }
332
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700333 Port* port() { return port_.get(); }
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700334
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000335 bool nominated() const { return nominated_; }
336
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700337 void set_connection_ready_to_send(bool ready) {
338 connection_ready_to_send_ = ready;
339 }
340 bool connection_ready_to_send() const {
341 return connection_ready_to_send_;
342 }
343
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000344 private:
skvladc309e0e2016-07-28 17:15:20 -0700345 // ReadyToSend will only issue after a Connection recovers from ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700346 void OnConnectionReadyToSend(Connection* conn) {
347 ASSERT_EQ(conn, conn_);
348 connection_ready_to_send_ = true;
349 }
350
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000351 IceMode ice_mode_;
kwiberg3ec46792016-04-27 07:22:53 -0700352 std::unique_ptr<Port> port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000353
354 int complete_count_;
355 Connection* conn_;
356 SocketAddress remote_address_;
kwiberg3ec46792016-04-27 07:22:53 -0700357 std::unique_ptr<StunMessage> remote_request_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000358 std::string remote_frag_;
359 bool nominated_;
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700360 bool connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000361};
362
363class PortTest : public testing::Test, public sigslot::has_slots<> {
364 public:
365 PortTest()
366 : main_(rtc::Thread::Current()),
367 pss_(new rtc::PhysicalSocketServer),
368 ss_(new rtc::VirtualSocketServer(pss_.get())),
369 ss_scope_(ss_.get()),
370 network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
371 socket_factory_(rtc::Thread::Current()),
deadbeefc5d0d952015-07-16 10:22:21 -0700372 nat_factory1_(ss_.get(), kNatAddr1, SocketAddress()),
373 nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000374 nat_socket_factory1_(&nat_factory1_),
375 nat_socket_factory2_(&nat_factory2_),
376 stun_server_(TestStunServer::Create(main_, kStunAddr)),
377 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700378 relay_server_(main_,
379 kRelayUdpIntAddr,
380 kRelayUdpExtAddr,
381 kRelayTcpIntAddr,
382 kRelayTcpExtAddr,
383 kRelaySslTcpIntAddr,
384 kRelaySslTcpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000385 username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
386 password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000387 role_conflict_(false),
Honghai Zhanga74363c2016-07-28 18:06:15 -0700388 ports_destroyed_(0) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000389 network_.AddIP(rtc::IPAddress(INADDR_ANY));
390 }
391
392 protected:
393 void TestLocalToLocal() {
394 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700395 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000396 Port* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700397 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000398 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
399 }
400 void TestLocalToStun(NATType ntype) {
401 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700402 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000403 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
404 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700405 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000406 TestConnectivity("udp", port1, StunName(ntype), port2,
407 ntype == NAT_OPEN_CONE, true,
408 ntype != NAT_SYMMETRIC, true);
409 }
410 void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
411 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700412 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000413 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700414 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000415 TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
416 rtype == RELAY_GTURN, true, true, true);
417 }
418 void TestStunToLocal(NATType ntype) {
419 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
420 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700421 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000422 Port* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700423 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000424 TestConnectivity(StunName(ntype), port1, "udp", port2,
425 true, ntype != NAT_SYMMETRIC, true, true);
426 }
427 void TestStunToStun(NATType ntype1, NATType ntype2) {
428 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
429 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700430 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000431 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
432 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700433 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000434 TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
435 ntype2 == NAT_OPEN_CONE,
436 ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
437 ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
438 }
439 void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
440 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
441 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700442 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000443 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700444 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000445 TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
446 rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
447 }
448 void TestTcpToTcp() {
449 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700450 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000451 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700452 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000453 TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
454 }
455 void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
456 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700457 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000458 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700459 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000460 TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
461 rtype == RELAY_GTURN, false, true, true);
462 }
463 void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
464 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700465 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000466 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700467 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000468 TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
469 rtype == RELAY_GTURN, false, true, true);
470 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000471 // helpers for above functions
472 UDPPort* CreateUdpPort(const SocketAddress& addr) {
473 return CreateUdpPort(addr, &socket_factory_);
474 }
475 UDPPort* CreateUdpPort(const SocketAddress& addr,
476 PacketSocketFactory* socket_factory) {
Guo-wei Shieh9af97f82015-11-10 14:47:39 -0800477 return UDPPort::Create(main_, socket_factory, &network_, addr.ipaddr(), 0,
478 0, username_, password_, std::string(), true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000479 }
480 TCPPort* CreateTcpPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700481 return CreateTcpPort(addr, &socket_factory_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000482 }
483 TCPPort* CreateTcpPort(const SocketAddress& addr,
484 PacketSocketFactory* socket_factory) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700485 return TCPPort::Create(main_, socket_factory, &network_,
486 addr.ipaddr(), 0, 0, username_, password_,
487 true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000488 }
489 StunPort* CreateStunPort(const SocketAddress& addr,
490 rtc::PacketSocketFactory* factory) {
491 ServerAddresses stun_servers;
492 stun_servers.insert(kStunAddr);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700493 return StunPort::Create(main_, factory, &network_,
494 addr.ipaddr(), 0, 0,
495 username_, password_, stun_servers,
496 std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000497 }
498 Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
499 ProtocolType int_proto, ProtocolType ext_proto) {
500 if (rtype == RELAY_TURN) {
501 return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
502 } else {
503 return CreateGturnPort(addr, int_proto, ext_proto);
504 }
505 }
506 TurnPort* CreateTurnPort(const SocketAddress& addr,
507 PacketSocketFactory* socket_factory,
508 ProtocolType int_proto, ProtocolType ext_proto) {
Honghai Zhang80f1db92016-01-27 11:54:45 -0800509 SocketAddress server_addr =
510 int_proto == PROTO_TCP ? kTurnTcpIntAddr : kTurnUdpIntAddr;
511 return CreateTurnPort(addr, socket_factory, int_proto, ext_proto,
512 server_addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000513 }
514 TurnPort* CreateTurnPort(const SocketAddress& addr,
515 PacketSocketFactory* socket_factory,
516 ProtocolType int_proto, ProtocolType ext_proto,
517 const rtc::SocketAddress& server_addr) {
Honghai Zhang80f1db92016-01-27 11:54:45 -0800518 return TurnPort::Create(main_, socket_factory, &network_, addr.ipaddr(), 0,
519 0, username_, password_,
520 ProtocolAddress(server_addr, int_proto),
521 kRelayCredentials, 0, std::string());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000522 }
523 RelayPort* CreateGturnPort(const SocketAddress& addr,
524 ProtocolType int_proto, ProtocolType ext_proto) {
525 RelayPort* port = CreateGturnPort(addr);
526 SocketAddress addrs[] =
527 { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
528 port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
529 return port;
530 }
531 RelayPort* CreateGturnPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700532 // TODO(pthatcher): Remove GTURN.
zhihuang6d0d4bf2016-05-24 10:13:32 -0700533 // Generate a username with length of 16 for Gturn only.
534 std::string username = rtc::CreateRandomString(kGturnUserNameLength);
535 return RelayPort::Create(main_, &socket_factory_, &network_, addr.ipaddr(),
536 0, 0, username, password_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000537 // TODO: Add an external address for ext_proto, so that the
538 // other side can connect to this port using a non-UDP protocol.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000539 }
540 rtc::NATServer* CreateNatServer(const SocketAddress& addr,
541 rtc::NATType type) {
deadbeefc5d0d952015-07-16 10:22:21 -0700542 return new rtc::NATServer(type, ss_.get(), addr, addr, ss_.get(), addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000543 }
544 static const char* StunName(NATType type) {
545 switch (type) {
hnsl277b2502016-12-13 05:17:23 -0800546 case NAT_OPEN_CONE:
547 return "stun(open cone)";
548 case NAT_ADDR_RESTRICTED:
549 return "stun(addr restricted)";
550 case NAT_PORT_RESTRICTED:
551 return "stun(port restricted)";
552 case NAT_SYMMETRIC:
553 return "stun(symmetric)";
554 default:
555 return "stun(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000556 }
557 }
558 static const char* RelayName(RelayType type, ProtocolType proto) {
559 if (type == RELAY_TURN) {
560 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800561 case PROTO_UDP:
562 return "turn(udp)";
563 case PROTO_TCP:
564 return "turn(tcp)";
565 case PROTO_SSLTCP:
566 return "turn(ssltcp)";
567 case PROTO_TLS:
568 return "turn(tls)";
569 default:
570 return "turn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000571 }
572 } else {
573 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800574 case PROTO_UDP:
575 return "gturn(udp)";
576 case PROTO_TCP:
577 return "gturn(tcp)";
578 case PROTO_SSLTCP:
579 return "gturn(ssltcp)";
580 case PROTO_TLS:
581 return "gturn(tls)";
582 default:
583 return "gturn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000584 }
585 }
586 }
587
honghaiza0c44ea2016-03-23 16:07:48 -0700588 void SetNetworkType(rtc::AdapterType adapter_type) {
589 network_.set_type(adapter_type);
590 }
591
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000592 void TestCrossFamilyPorts(int type);
593
Peter Thatcherb8b01432015-07-07 16:45:53 -0700594 void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2);
595
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000596 // This does all the work and then deletes |port1| and |port2|.
597 void TestConnectivity(const char* name1, Port* port1,
598 const char* name2, Port* port2,
599 bool accept, bool same_addr1,
600 bool same_addr2, bool possible);
601
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700602 // This connects the provided channels which have already started. |ch1|
603 // should have its Connection created (either through CreateConnection() or
604 // TCP reconnecting mechanism before entering this function.
605 void ConnectStartedChannels(TestChannel* ch1, TestChannel* ch2) {
606 ASSERT_TRUE(ch1->conn());
Honghai Zhang161a5862016-10-20 11:47:02 -0700607 EXPECT_TRUE_WAIT(ch1->conn()->connected(),
608 kDefaultTimeout); // for TCP connect
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700609 ch1->Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700610 WAIT(!ch2->remote_address().IsNil(), kShortTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700611
612 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700613 ch2->AcceptConnection(GetCandidate(ch1->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700614 ch2->Ping();
615 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -0700616 kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700617 }
618
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000619 // This connects and disconnects the provided channels in the same sequence as
620 // TestConnectivity with all options set to |true|. It does not delete either
621 // channel.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700622 void StartConnectAndStopChannels(TestChannel* ch1, TestChannel* ch2) {
623 // Acquire addresses.
624 ch1->Start();
625 ch2->Start();
626
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700627 ch1->CreateConnection(GetCandidate(ch2->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700628 ConnectStartedChannels(ch1, ch2);
629
630 // Destroy the connections.
631 ch1->Stop();
632 ch2->Stop();
633 }
634
635 // This disconnects both end's Connection and make sure ch2 ready for new
636 // connection.
637 void DisconnectTcpTestChannels(TestChannel* ch1, TestChannel* ch2) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700638 TCPConnection* tcp_conn1 = static_cast<TCPConnection*>(ch1->conn());
639 TCPConnection* tcp_conn2 = static_cast<TCPConnection*>(ch2->conn());
640 ASSERT_TRUE(
641 ss_->CloseTcpConnections(tcp_conn1->socket()->GetLocalAddress(),
642 tcp_conn2->socket()->GetLocalAddress()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700643
644 // Wait for both OnClose are delivered.
Honghai Zhang161a5862016-10-20 11:47:02 -0700645 EXPECT_TRUE_WAIT(!ch1->conn()->connected(), kDefaultTimeout);
646 EXPECT_TRUE_WAIT(!ch2->conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700647
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700648 // Ensure redundant SignalClose events on TcpConnection won't break tcp
649 // reconnection. Chromium will fire SignalClose for all outstanding IPC
650 // packets during reconnection.
651 tcp_conn1->socket()->SignalClose(tcp_conn1->socket(), 0);
652 tcp_conn2->socket()->SignalClose(tcp_conn2->socket(), 0);
653
654 // Speed up destroying ch2's connection such that the test is ready to
655 // accept a new connection from ch1 before ch1's connection destroys itself.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700656 ch2->conn()->Destroy();
Honghai Zhang161a5862016-10-20 11:47:02 -0700657 EXPECT_TRUE_WAIT(ch2->conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700658 }
659
660 void TestTcpReconnect(bool ping_after_disconnected,
661 bool send_after_disconnected) {
662 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700663 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700664 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700665 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700666
667 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
668 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
669
670 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700671 TestChannel ch1(port1);
672 TestChannel ch2(port2);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700673 EXPECT_EQ(0, ch1.complete_count());
674 EXPECT_EQ(0, ch2.complete_count());
675
676 ch1.Start();
677 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700678 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
679 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700680
681 // Initial connecting the channel, create connection on channel1.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700682 ch1.CreateConnection(GetCandidate(port2));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700683 ConnectStartedChannels(&ch1, &ch2);
684
685 // Shorten the timeout period.
Honghai Zhang161a5862016-10-20 11:47:02 -0700686 const int kTcpReconnectTimeout = kDefaultTimeout;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700687 static_cast<TCPConnection*>(ch1.conn())
688 ->set_reconnection_timeout(kTcpReconnectTimeout);
689 static_cast<TCPConnection*>(ch2.conn())
690 ->set_reconnection_timeout(kTcpReconnectTimeout);
691
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700692 EXPECT_FALSE(ch1.connection_ready_to_send());
693 EXPECT_FALSE(ch2.connection_ready_to_send());
694
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700695 // Once connected, disconnect them.
696 DisconnectTcpTestChannels(&ch1, &ch2);
697
698 if (send_after_disconnected || ping_after_disconnected) {
699 if (send_after_disconnected) {
700 // First SendData after disconnect should fail but will trigger
701 // reconnect.
702 EXPECT_EQ(-1, ch1.SendData(data, static_cast<int>(strlen(data))));
703 }
704
705 if (ping_after_disconnected) {
706 // Ping should trigger reconnect.
707 ch1.Ping();
708 }
709
710 // Wait for channel's outgoing TCPConnection connected.
Honghai Zhang161a5862016-10-20 11:47:02 -0700711 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700712
713 // Verify that we could still connect channels.
714 ConnectStartedChannels(&ch1, &ch2);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700715 EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(),
716 kTcpReconnectTimeout);
717 // Channel2 is the passive one so a new connection is created during
skvladc309e0e2016-07-28 17:15:20 -0700718 // reconnect. This new connection should never have issued ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700719 // hence the connection_ready_to_send() should be false.
720 EXPECT_FALSE(ch2.connection_ready_to_send());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700721 } else {
722 EXPECT_EQ(ch1.conn()->write_state(), Connection::STATE_WRITABLE);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700723 // Since the reconnection never happens, the connections should have been
724 // destroyed after the timeout.
Honghai Zhang161a5862016-10-20 11:47:02 -0700725 EXPECT_TRUE_WAIT(!ch1.conn(), kTcpReconnectTimeout + kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700726 EXPECT_TRUE(!ch2.conn());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700727 }
728
729 // Tear down and ensure that goes smoothly.
730 ch1.Stop();
731 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700732 EXPECT_TRUE_WAIT(ch1.conn() == NULL, kDefaultTimeout);
733 EXPECT_TRUE_WAIT(ch2.conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700734 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000735
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000736 IceMessage* CreateStunMessage(int type) {
737 IceMessage* msg = new IceMessage();
738 msg->SetType(type);
739 msg->SetTransactionID("TESTTESTTEST");
740 return msg;
741 }
742 IceMessage* CreateStunMessageWithUsername(int type,
743 const std::string& username) {
744 IceMessage* msg = CreateStunMessage(type);
745 msg->AddAttribute(
746 new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
747 return msg;
748 }
749 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
750 const std::string& username,
751 const std::string& password) {
752 TestPort* port = new TestPort(main_, "test", &socket_factory_, &network_,
753 addr.ipaddr(), 0, 0, username, password);
754 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
755 return port;
756 }
757 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
758 const std::string& username,
759 const std::string& password,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000760 cricket::IceRole role,
761 int tiebreaker) {
762 TestPort* port = CreateTestPort(addr, username, password);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000763 port->SetIceRole(role);
764 port->SetIceTiebreaker(tiebreaker);
765 return port;
766 }
767
768 void OnRoleConflict(PortInterface* port) {
769 role_conflict_ = true;
770 }
771 bool role_conflict() const { return role_conflict_; }
772
773 void ConnectToSignalDestroyed(PortInterface* port) {
774 port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
775 }
776
Honghai Zhanga74363c2016-07-28 18:06:15 -0700777 void OnDestroyed(PortInterface* port) { ++ports_destroyed_; }
778 int ports_destroyed() const { return ports_destroyed_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000779
780 rtc::BasicPacketSocketFactory* nat_socket_factory1() {
781 return &nat_socket_factory1_;
782 }
783
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700784 rtc::VirtualSocketServer* vss() { return ss_.get(); }
785
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000786 private:
787 rtc::Thread* main_;
kwiberg3ec46792016-04-27 07:22:53 -0700788 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
789 std::unique_ptr<rtc::VirtualSocketServer> ss_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000790 rtc::SocketServerScope ss_scope_;
791 rtc::Network network_;
792 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700793 std::unique_ptr<rtc::NATServer> nat_server1_;
794 std::unique_ptr<rtc::NATServer> nat_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000795 rtc::NATSocketFactory nat_factory1_;
796 rtc::NATSocketFactory nat_factory2_;
797 rtc::BasicPacketSocketFactory nat_socket_factory1_;
798 rtc::BasicPacketSocketFactory nat_socket_factory2_;
kwiberg3ec46792016-04-27 07:22:53 -0700799 std::unique_ptr<TestStunServer> stun_server_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000800 TestTurnServer turn_server_;
801 TestRelayServer relay_server_;
802 std::string username_;
803 std::string password_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000804 bool role_conflict_;
Honghai Zhanga74363c2016-07-28 18:06:15 -0700805 int ports_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000806};
807
808void PortTest::TestConnectivity(const char* name1, Port* port1,
809 const char* name2, Port* port2,
810 bool accept, bool same_addr1,
811 bool same_addr2, bool possible) {
Honghai Zhang161a5862016-10-20 11:47:02 -0700812 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000813 LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
814 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
815 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
816
817 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700818 TestChannel ch1(port1);
819 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000820 EXPECT_EQ(0, ch1.complete_count());
821 EXPECT_EQ(0, ch2.complete_count());
822
823 // Acquire addresses.
824 ch1.Start();
825 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700826 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
827 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000828
829 // Send a ping from src to dst. This may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700830 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000831 ASSERT_TRUE(ch1.conn() != NULL);
Honghai Zhang161a5862016-10-20 11:47:02 -0700832 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout,
833 clock); // for TCP connect
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000834 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700835 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000836
837 if (accept) {
838 // We are able to send a ping from src to dst. This is the case when
839 // sending to UDP ports and cone NATs.
840 EXPECT_TRUE(ch1.remote_address().IsNil());
841 EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
842
843 // Ensure the ping came from the same address used for src.
844 // This is the case unless the source NAT was symmetric.
845 if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
846 EXPECT_TRUE(same_addr2);
847
848 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700849 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000850 ASSERT_TRUE(ch2.conn() != NULL);
851 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700852 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
853 ch2.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000854 } else {
855 // We can't send a ping from src to dst, so flip it around. This will happen
856 // when the destination NAT is addr/port restricted or symmetric.
857 EXPECT_TRUE(ch1.remote_address().IsNil());
858 EXPECT_TRUE(ch2.remote_address().IsNil());
859
860 // Send a ping from dst to src. Again, this may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700861 ch2.CreateConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000862 ASSERT_TRUE(ch2.conn() != NULL);
863 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700864 SIMULATED_WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE,
865 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000866
867 if (same_addr1 && same_addr2) {
868 // The new ping got back to the source.
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700869 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000870 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
871
872 // First connection may not be writable if the first ping did not get
873 // through. So we will have to do another.
874 if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
875 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700876 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
877 ch1.conn()->write_state(), kDefaultTimeout,
878 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000879 }
880 } else if (!same_addr1 && possible) {
881 // The new ping went to the candidate address, but that address was bad.
882 // This will happen when the source NAT is symmetric.
883 EXPECT_TRUE(ch1.remote_address().IsNil());
884 EXPECT_TRUE(ch2.remote_address().IsNil());
885
886 // However, since we have now sent a ping to the source IP, we should be
887 // able to get a ping from it. This gives us the real source address.
888 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700889 EXPECT_TRUE_SIMULATED_WAIT(!ch2.remote_address().IsNil(), kDefaultTimeout,
890 clock);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700891 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000892 EXPECT_TRUE(ch1.remote_address().IsNil());
893
894 // Pick up the actual address and establish the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700895 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000896 ASSERT_TRUE(ch2.conn() != NULL);
897 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700898 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
899 ch2.conn()->write_state(), kDefaultTimeout,
900 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000901 } else if (!same_addr2 && possible) {
902 // The new ping came in, but from an unexpected address. This will happen
903 // when the destination NAT is symmetric.
904 EXPECT_FALSE(ch1.remote_address().IsNil());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700905 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000906
907 // Update our address and complete the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700908 ch1.AcceptConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000909 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700910 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
911 ch1.conn()->write_state(), kDefaultTimeout,
912 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000913 } else { // (!possible)
914 // There should be s no way for the pings to reach each other. Check it.
915 EXPECT_TRUE(ch1.remote_address().IsNil());
916 EXPECT_TRUE(ch2.remote_address().IsNil());
917 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700918 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000919 EXPECT_TRUE(ch1.remote_address().IsNil());
920 EXPECT_TRUE(ch2.remote_address().IsNil());
921 }
922 }
923
924 // Everything should be good, unless we know the situation is impossible.
925 ASSERT_TRUE(ch1.conn() != NULL);
926 ASSERT_TRUE(ch2.conn() != NULL);
927 if (possible) {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700928 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000929 EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700930 EXPECT_TRUE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000931 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
932 } else {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700933 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000934 EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700935 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000936 EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
937 }
938
939 // Tear down and ensure that goes smoothly.
940 ch1.Stop();
941 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700942 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn() == NULL, kDefaultTimeout, clock);
943 EXPECT_TRUE_SIMULATED_WAIT(ch2.conn() == NULL, kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000944}
945
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000946class FakePacketSocketFactory : public rtc::PacketSocketFactory {
947 public:
948 FakePacketSocketFactory()
949 : next_udp_socket_(NULL),
950 next_server_tcp_socket_(NULL),
951 next_client_tcp_socket_(NULL) {
952 }
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000953 ~FakePacketSocketFactory() override { }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000954
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000955 AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200956 uint16_t min_port,
957 uint16_t max_port) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000958 EXPECT_TRUE(next_udp_socket_ != NULL);
959 AsyncPacketSocket* result = next_udp_socket_;
960 next_udp_socket_ = NULL;
961 return result;
962 }
963
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000964 AsyncPacketSocket* CreateServerTcpSocket(const SocketAddress& local_address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200965 uint16_t min_port,
966 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000967 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000968 EXPECT_TRUE(next_server_tcp_socket_ != NULL);
969 AsyncPacketSocket* result = next_server_tcp_socket_;
970 next_server_tcp_socket_ = NULL;
971 return result;
972 }
973
974 // TODO: |proxy_info| and |user_agent| should be set
975 // per-factory and not when socket is created.
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000976 AsyncPacketSocket* CreateClientTcpSocket(const SocketAddress& local_address,
977 const SocketAddress& remote_address,
978 const rtc::ProxyInfo& proxy_info,
979 const std::string& user_agent,
980 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000981 EXPECT_TRUE(next_client_tcp_socket_ != NULL);
982 AsyncPacketSocket* result = next_client_tcp_socket_;
983 next_client_tcp_socket_ = NULL;
984 return result;
985 }
986
987 void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
988 next_udp_socket_ = next_udp_socket;
989 }
990 void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
991 next_server_tcp_socket_ = next_server_tcp_socket;
992 }
993 void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
994 next_client_tcp_socket_ = next_client_tcp_socket;
995 }
nisseef8b61e2016-04-29 06:09:15 -0700996 rtc::AsyncResolverInterface* CreateAsyncResolver() override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000997 return NULL;
998 }
999
1000 private:
1001 AsyncPacketSocket* next_udp_socket_;
1002 AsyncPacketSocket* next_server_tcp_socket_;
1003 AsyncPacketSocket* next_client_tcp_socket_;
1004};
1005
1006class FakeAsyncPacketSocket : public AsyncPacketSocket {
1007 public:
1008 // Returns current local address. Address may be set to NULL if the
1009 // socket is not bound yet (GetState() returns STATE_BINDING).
1010 virtual SocketAddress GetLocalAddress() const {
1011 return SocketAddress();
1012 }
1013
1014 // Returns remote address. Returns zeroes if this is not a client TCP socket.
1015 virtual SocketAddress GetRemoteAddress() const {
1016 return SocketAddress();
1017 }
1018
1019 // Send a packet.
1020 virtual int Send(const void *pv, size_t cb,
1021 const rtc::PacketOptions& options) {
1022 return static_cast<int>(cb);
1023 }
1024 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
1025 const rtc::PacketOptions& options) {
1026 return static_cast<int>(cb);
1027 }
1028 virtual int Close() {
1029 return 0;
1030 }
1031
1032 virtual State GetState() const { return state_; }
1033 virtual int GetOption(Socket::Option opt, int* value) { return 0; }
1034 virtual int SetOption(Socket::Option opt, int value) { return 0; }
1035 virtual int GetError() const { return 0; }
1036 virtual void SetError(int error) { }
1037
1038 void set_state(State state) { state_ = state; }
1039
1040 private:
1041 State state_;
1042};
1043
1044// Local -> XXXX
1045TEST_F(PortTest, TestLocalToLocal) {
1046 TestLocalToLocal();
1047}
1048
1049TEST_F(PortTest, TestLocalToConeNat) {
1050 TestLocalToStun(NAT_OPEN_CONE);
1051}
1052
1053TEST_F(PortTest, TestLocalToARNat) {
1054 TestLocalToStun(NAT_ADDR_RESTRICTED);
1055}
1056
1057TEST_F(PortTest, TestLocalToPRNat) {
1058 TestLocalToStun(NAT_PORT_RESTRICTED);
1059}
1060
1061TEST_F(PortTest, TestLocalToSymNat) {
1062 TestLocalToStun(NAT_SYMMETRIC);
1063}
1064
1065// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
1066TEST_F(PortTest, DISABLED_TestLocalToTurn) {
1067 TestLocalToRelay(RELAY_TURN, PROTO_UDP);
1068}
1069
1070TEST_F(PortTest, TestLocalToGturn) {
1071 TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
1072}
1073
1074TEST_F(PortTest, TestLocalToTcpGturn) {
1075 TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
1076}
1077
1078TEST_F(PortTest, TestLocalToSslTcpGturn) {
1079 TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
1080}
1081
1082// Cone NAT -> XXXX
1083TEST_F(PortTest, TestConeNatToLocal) {
1084 TestStunToLocal(NAT_OPEN_CONE);
1085}
1086
1087TEST_F(PortTest, TestConeNatToConeNat) {
1088 TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
1089}
1090
1091TEST_F(PortTest, TestConeNatToARNat) {
1092 TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
1093}
1094
1095TEST_F(PortTest, TestConeNatToPRNat) {
1096 TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
1097}
1098
1099TEST_F(PortTest, TestConeNatToSymNat) {
1100 TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
1101}
1102
1103TEST_F(PortTest, TestConeNatToTurn) {
1104 TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
1105}
1106
1107TEST_F(PortTest, TestConeNatToGturn) {
1108 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
1109}
1110
1111TEST_F(PortTest, TestConeNatToTcpGturn) {
1112 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
1113}
1114
1115// Address-restricted NAT -> XXXX
1116TEST_F(PortTest, TestARNatToLocal) {
1117 TestStunToLocal(NAT_ADDR_RESTRICTED);
1118}
1119
1120TEST_F(PortTest, TestARNatToConeNat) {
1121 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
1122}
1123
1124TEST_F(PortTest, TestARNatToARNat) {
1125 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
1126}
1127
1128TEST_F(PortTest, TestARNatToPRNat) {
1129 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
1130}
1131
1132TEST_F(PortTest, TestARNatToSymNat) {
1133 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
1134}
1135
1136TEST_F(PortTest, TestARNatToTurn) {
1137 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
1138}
1139
1140TEST_F(PortTest, TestARNatToGturn) {
1141 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1142}
1143
1144TEST_F(PortTest, TestARNATNatToTcpGturn) {
1145 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1146}
1147
1148// Port-restricted NAT -> XXXX
1149TEST_F(PortTest, TestPRNatToLocal) {
1150 TestStunToLocal(NAT_PORT_RESTRICTED);
1151}
1152
1153TEST_F(PortTest, TestPRNatToConeNat) {
1154 TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
1155}
1156
1157TEST_F(PortTest, TestPRNatToARNat) {
1158 TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
1159}
1160
1161TEST_F(PortTest, TestPRNatToPRNat) {
1162 TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
1163}
1164
1165TEST_F(PortTest, TestPRNatToSymNat) {
1166 // Will "fail"
1167 TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1168}
1169
1170TEST_F(PortTest, TestPRNatToTurn) {
1171 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
1172}
1173
1174TEST_F(PortTest, TestPRNatToGturn) {
1175 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1176}
1177
1178TEST_F(PortTest, TestPRNatToTcpGturn) {
1179 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1180}
1181
1182// Symmetric NAT -> XXXX
1183TEST_F(PortTest, TestSymNatToLocal) {
1184 TestStunToLocal(NAT_SYMMETRIC);
1185}
1186
1187TEST_F(PortTest, TestSymNatToConeNat) {
1188 TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1189}
1190
1191TEST_F(PortTest, TestSymNatToARNat) {
1192 TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1193}
1194
1195TEST_F(PortTest, TestSymNatToPRNat) {
1196 // Will "fail"
1197 TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1198}
1199
1200TEST_F(PortTest, TestSymNatToSymNat) {
1201 // Will "fail"
1202 TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1203}
1204
1205TEST_F(PortTest, TestSymNatToTurn) {
1206 TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1207}
1208
1209TEST_F(PortTest, TestSymNatToGturn) {
1210 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1211}
1212
1213TEST_F(PortTest, TestSymNatToTcpGturn) {
1214 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1215}
1216
1217// Outbound TCP -> XXXX
1218TEST_F(PortTest, TestTcpToTcp) {
1219 TestTcpToTcp();
1220}
1221
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07001222TEST_F(PortTest, TestTcpReconnectOnSendPacket) {
1223 TestTcpReconnect(false /* ping */, true /* send */);
1224}
1225
1226TEST_F(PortTest, TestTcpReconnectOnPing) {
1227 TestTcpReconnect(true /* ping */, false /* send */);
1228}
1229
1230TEST_F(PortTest, TestTcpReconnectTimeout) {
1231 TestTcpReconnect(false /* ping */, false /* send */);
1232}
1233
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001234// Test when TcpConnection never connects, the OnClose() will be called to
1235// destroy the connection.
1236TEST_F(PortTest, TestTcpNeverConnect) {
1237 Port* port1 = CreateTcpPort(kLocalAddr1);
1238 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1239 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
1240
1241 // Set up a channel and ensure the port will be deleted.
1242 TestChannel ch1(port1);
1243 EXPECT_EQ(0, ch1.complete_count());
1244
1245 ch1.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001246 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001247
kwiberg3ec46792016-04-27 07:22:53 -07001248 std::unique_ptr<rtc::AsyncSocket> server(
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001249 vss()->CreateAsyncSocket(kLocalAddr2.family(), SOCK_STREAM));
1250 // Bind but not listen.
1251 EXPECT_EQ(0, server->Bind(kLocalAddr2));
1252
1253 Candidate c = GetCandidate(port1);
1254 c.set_address(server->GetLocalAddress());
1255
1256 ch1.CreateConnection(c);
1257 EXPECT_TRUE(ch1.conn());
Honghai Zhang161a5862016-10-20 11:47:02 -07001258 EXPECT_TRUE_WAIT(!ch1.conn(), kDefaultTimeout); // for TCP connect
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001259}
1260
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001261/* TODO: Enable these once testrelayserver can accept external TCP.
1262TEST_F(PortTest, TestTcpToTcpRelay) {
1263 TestTcpToRelay(PROTO_TCP);
1264}
1265
1266TEST_F(PortTest, TestTcpToSslTcpRelay) {
1267 TestTcpToRelay(PROTO_SSLTCP);
1268}
1269*/
1270
1271// Outbound SSLTCP -> XXXX
1272/* TODO: Enable these once testrelayserver can accept external SSL.
1273TEST_F(PortTest, TestSslTcpToTcpRelay) {
1274 TestSslTcpToRelay(PROTO_TCP);
1275}
1276
1277TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1278 TestSslTcpToRelay(PROTO_SSLTCP);
1279}
1280*/
1281
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001282// Test that a connection will be dead and deleted if
1283// i) it has never received anything for MIN_CONNECTION_LIFETIME milliseconds
1284// since it was created, or
1285// ii) it has not received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT
1286// milliseconds since last receiving.
1287TEST_F(PortTest, TestConnectionDead) {
1288 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1289 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1290 TestChannel ch1(port1);
1291 TestChannel ch2(port2);
1292 // Acquire address.
1293 ch1.Start();
1294 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001295 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1296 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001297
honghaiz37389b42016-01-04 21:57:33 -08001298 // Test case that the connection has never received anything.
nisse1bffc1d2016-05-02 08:18:55 -07001299 int64_t before_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001300 ch1.CreateConnection(GetCandidate(port2));
nisse1bffc1d2016-05-02 08:18:55 -07001301 int64_t after_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001302 Connection* conn = ch1.conn();
1303 ASSERT(conn != nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001304 // It is not dead if it is after MIN_CONNECTION_LIFETIME but not pruned.
1305 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
1306 rtc::Thread::Current()->ProcessMessages(0);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001307 EXPECT_TRUE(ch1.conn() != nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001308 // It is not dead if it is before MIN_CONNECTION_LIFETIME and pruned.
1309 conn->UpdateState(before_created + MIN_CONNECTION_LIFETIME - 1);
1310 conn->Prune();
1311 rtc::Thread::Current()->ProcessMessages(0);
1312 EXPECT_TRUE(ch1.conn() != nullptr);
1313 // It will be dead after MIN_CONNECTION_LIFETIME and pruned.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001314 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001315 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001316
honghaiz37389b42016-01-04 21:57:33 -08001317 // Test case that the connection has received something.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001318 // Create a connection again and receive a ping.
1319 ch1.CreateConnection(GetCandidate(port2));
1320 conn = ch1.conn();
1321 ASSERT(conn != nullptr);
nisse1bffc1d2016-05-02 08:18:55 -07001322 int64_t before_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001323 conn->ReceivedPing();
nisse1bffc1d2016-05-02 08:18:55 -07001324 int64_t after_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001325 // The connection will be dead after DEAD_CONNECTION_RECEIVE_TIMEOUT
1326 conn->UpdateState(
1327 before_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT - 1);
1328 rtc::Thread::Current()->ProcessMessages(100);
1329 EXPECT_TRUE(ch1.conn() != nullptr);
1330 conn->UpdateState(after_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001331 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001332}
1333
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001334// This test case verifies standard ICE features in STUN messages. Currently it
1335// verifies Message Integrity attribute in STUN messages and username in STUN
1336// binding request will have colon (":") between remote and local username.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001337TEST_F(PortTest, TestLocalToLocalStandard) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001338 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1339 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1340 port1->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001341 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1342 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1343 port2->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001344 // Same parameters as TestLocalToLocal above.
1345 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1346}
1347
1348// This test is trying to validate a successful and failure scenario in a
1349// loopback test when protocol is RFC5245. For success IceTiebreaker, username
1350// should remain equal to the request generated by the port and role of port
1351// must be in controlling.
Honghai Zhang161a5862016-10-20 11:47:02 -07001352TEST_F(PortTest, TestLoopbackCall) {
kwiberg3ec46792016-04-27 07:22:53 -07001353 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001354 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001355 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1356 lport->SetIceTiebreaker(kTiebreaker1);
1357 lport->PrepareAddress();
1358 ASSERT_FALSE(lport->Candidates().empty());
1359 Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1360 Port::ORIGIN_MESSAGE);
1361 conn->Ping(0);
1362
Honghai Zhang161a5862016-10-20 11:47:02 -07001363 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001364 IceMessage* msg = lport->last_stun_msg();
1365 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
jbauchf1f87202016-03-30 06:43:37 -07001366 conn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1367 lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001368 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001369 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001370 msg = lport->last_stun_msg();
1371 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1372
1373 // If the tiebreaker value is different from port, we expect a error
1374 // response.
1375 lport->Reset();
1376 lport->AddCandidateAddress(kLocalAddr2);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001377 // Creating a different connection as |conn| is receiving.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001378 Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1379 Port::ORIGIN_MESSAGE);
1380 conn1->Ping(0);
1381
Honghai Zhang161a5862016-10-20 11:47:02 -07001382 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001383 msg = lport->last_stun_msg();
1384 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
kwiberg3ec46792016-04-27 07:22:53 -07001385 std::unique_ptr<IceMessage> modified_req(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001386 CreateStunMessage(STUN_BINDING_REQUEST));
1387 const StunByteStringAttribute* username_attr = msg->GetByteString(
1388 STUN_ATTR_USERNAME);
1389 modified_req->AddAttribute(new StunByteStringAttribute(
1390 STUN_ATTR_USERNAME, username_attr->GetString()));
1391 // To make sure we receive error response, adding tiebreaker less than
1392 // what's present in request.
1393 modified_req->AddAttribute(new StunUInt64Attribute(
1394 STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1395 modified_req->AddMessageIntegrity("lpass");
1396 modified_req->AddFingerprint();
1397
1398 lport->Reset();
kwiberg3ec46792016-04-27 07:22:53 -07001399 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001400 WriteStunMessage(modified_req.get(), buf.get());
1401 conn1->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001402 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001403 msg = lport->last_stun_msg();
1404 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1405}
1406
1407// This test verifies role conflict signal is received when there is
1408// conflict in the role. In this case both ports are in controlling and
1409// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1410// value of tiebreaker, when it receives ping request from |rport| it will
1411// send role conflict signal.
1412TEST_F(PortTest, TestIceRoleConflict) {
kwiberg3ec46792016-04-27 07:22:53 -07001413 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001414 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001415 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1416 lport->SetIceTiebreaker(kTiebreaker1);
kwiberg3ec46792016-04-27 07:22:53 -07001417 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001418 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001419 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1420 rport->SetIceTiebreaker(kTiebreaker2);
1421
1422 lport->PrepareAddress();
1423 rport->PrepareAddress();
1424 ASSERT_FALSE(lport->Candidates().empty());
1425 ASSERT_FALSE(rport->Candidates().empty());
1426 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1427 Port::ORIGIN_MESSAGE);
1428 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1429 Port::ORIGIN_MESSAGE);
1430 rconn->Ping(0);
1431
Honghai Zhang161a5862016-10-20 11:47:02 -07001432 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001433 IceMessage* msg = rport->last_stun_msg();
1434 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1435 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07001436 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1437 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001438 rtc::PacketTime());
1439
Honghai Zhang161a5862016-10-20 11:47:02 -07001440 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001441 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1442 EXPECT_TRUE(role_conflict());
1443}
1444
1445TEST_F(PortTest, TestTcpNoDelay) {
1446 TCPPort* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001447 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001448 int option_value = -1;
1449 int success = port1->GetOption(rtc::Socket::OPT_NODELAY,
1450 &option_value);
1451 ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1452 ASSERT_EQ(1, option_value);
1453 delete port1;
1454}
1455
1456TEST_F(PortTest, TestDelayedBindingUdp) {
1457 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1458 FakePacketSocketFactory socket_factory;
1459
1460 socket_factory.set_next_udp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001461 std::unique_ptr<UDPPort> port(CreateUdpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001462
1463 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1464 port->PrepareAddress();
1465
1466 EXPECT_EQ(0U, port->Candidates().size());
1467 socket->SignalAddressReady(socket, kLocalAddr2);
1468
1469 EXPECT_EQ(1U, port->Candidates().size());
1470}
1471
1472TEST_F(PortTest, TestDelayedBindingTcp) {
1473 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1474 FakePacketSocketFactory socket_factory;
1475
1476 socket_factory.set_next_server_tcp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001477 std::unique_ptr<TCPPort> port(CreateTcpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001478
1479 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1480 port->PrepareAddress();
1481
1482 EXPECT_EQ(0U, port->Candidates().size());
1483 socket->SignalAddressReady(socket, kLocalAddr2);
1484
1485 EXPECT_EQ(1U, port->Candidates().size());
1486}
1487
1488void PortTest::TestCrossFamilyPorts(int type) {
1489 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001490 std::unique_ptr<Port> ports[4];
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001491 SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1492 SocketAddress("192.168.1.4", 0),
1493 SocketAddress("2001:db8::1", 0),
1494 SocketAddress("2001:db8::2", 0)};
1495 for (int i = 0; i < 4; i++) {
1496 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1497 if (type == SOCK_DGRAM) {
1498 factory.set_next_udp_socket(socket);
1499 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1500 } else if (type == SOCK_STREAM) {
1501 factory.set_next_server_tcp_socket(socket);
1502 ports[i].reset(CreateTcpPort(addresses[i], &factory));
1503 }
1504 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1505 socket->SignalAddressReady(socket, addresses[i]);
1506 ports[i]->PrepareAddress();
1507 }
1508
1509 // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1510 if (type == SOCK_STREAM) {
1511 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1512 factory.set_next_client_tcp_socket(clientsocket);
1513 }
1514 Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1515 Port::ORIGIN_MESSAGE);
1516 EXPECT_TRUE(NULL == c);
1517 EXPECT_EQ(0U, ports[0]->connections().size());
1518 c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1519 Port::ORIGIN_MESSAGE);
1520 EXPECT_FALSE(NULL == c);
1521 EXPECT_EQ(1U, ports[0]->connections().size());
1522
1523 // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1524 if (type == SOCK_STREAM) {
1525 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1526 factory.set_next_client_tcp_socket(clientsocket);
1527 }
1528 c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1529 Port::ORIGIN_MESSAGE);
1530 EXPECT_TRUE(NULL == c);
1531 EXPECT_EQ(0U, ports[2]->connections().size());
1532 c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1533 Port::ORIGIN_MESSAGE);
1534 EXPECT_FALSE(NULL == c);
1535 EXPECT_EQ(1U, ports[2]->connections().size());
1536}
1537
1538TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1539 TestCrossFamilyPorts(SOCK_STREAM);
1540}
1541
1542TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1543 TestCrossFamilyPorts(SOCK_DGRAM);
1544}
1545
Peter Thatcherb8b01432015-07-07 16:45:53 -07001546void PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) {
1547 Connection* c = p1->CreateConnection(GetCandidate(p2),
1548 Port::ORIGIN_MESSAGE);
1549 if (can_connect) {
1550 EXPECT_FALSE(NULL == c);
1551 EXPECT_EQ(1U, p1->connections().size());
1552 } else {
1553 EXPECT_TRUE(NULL == c);
1554 EXPECT_EQ(0U, p1->connections().size());
1555 }
1556}
1557
1558TEST_F(PortTest, TestUdpV6CrossTypePorts) {
1559 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001560 std::unique_ptr<Port> ports[4];
Peter Thatcherb8b01432015-07-07 16:45:53 -07001561 SocketAddress addresses[4] = {SocketAddress("2001:db8::1", 0),
1562 SocketAddress("fe80::1", 0),
1563 SocketAddress("fe80::2", 0),
1564 SocketAddress("::1", 0)};
1565 for (int i = 0; i < 4; i++) {
1566 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1567 factory.set_next_udp_socket(socket);
1568 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1569 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1570 socket->SignalAddressReady(socket, addresses[i]);
1571 ports[i]->PrepareAddress();
1572 }
1573
1574 Port* standard = ports[0].get();
1575 Port* link_local1 = ports[1].get();
1576 Port* link_local2 = ports[2].get();
1577 Port* localhost = ports[3].get();
1578
1579 ExpectPortsCanConnect(false, link_local1, standard);
1580 ExpectPortsCanConnect(false, standard, link_local1);
1581 ExpectPortsCanConnect(false, link_local1, localhost);
1582 ExpectPortsCanConnect(false, localhost, link_local1);
1583
1584 ExpectPortsCanConnect(true, link_local1, link_local2);
1585 ExpectPortsCanConnect(true, localhost, standard);
1586 ExpectPortsCanConnect(true, standard, localhost);
1587}
1588
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001589// This test verifies DSCP value set through SetOption interface can be
1590// get through DefaultDscpValue.
1591TEST_F(PortTest, TestDefaultDscpValue) {
1592 int dscp;
kwiberg3ec46792016-04-27 07:22:53 -07001593 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001594 EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP,
1595 rtc::DSCP_CS6));
1596 EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
kwiberg3ec46792016-04-27 07:22:53 -07001597 std::unique_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001598 EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP,
1599 rtc::DSCP_AF31));
1600 EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1601 EXPECT_EQ(rtc::DSCP_AF31, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001602 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001603 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
1604 EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP,
1605 rtc::DSCP_AF41));
1606 EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1607 EXPECT_EQ(rtc::DSCP_AF41, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001608 std::unique_ptr<TurnPort> turnport1(
1609 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001610 // Socket is created in PrepareAddress.
1611 turnport1->PrepareAddress();
1612 EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP,
1613 rtc::DSCP_CS7));
1614 EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1615 EXPECT_EQ(rtc::DSCP_CS7, dscp);
1616 // This will verify correct value returned without the socket.
kwiberg3ec46792016-04-27 07:22:53 -07001617 std::unique_ptr<TurnPort> turnport2(
1618 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001619 EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP,
1620 rtc::DSCP_CS6));
1621 EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1622 EXPECT_EQ(rtc::DSCP_CS6, dscp);
1623}
1624
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001625// Test sending STUN messages.
1626TEST_F(PortTest, TestSendStunMessage) {
kwiberg3ec46792016-04-27 07:22:53 -07001627 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001628 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001629 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001630 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001631 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1632 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001633 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1634 rport->SetIceTiebreaker(kTiebreaker2);
1635
1636 // Send a fake ping from lport to rport.
1637 lport->PrepareAddress();
1638 rport->PrepareAddress();
1639 ASSERT_FALSE(rport->Candidates().empty());
1640 Connection* lconn = lport->CreateConnection(
1641 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1642 Connection* rconn = rport->CreateConnection(
1643 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1644 lconn->Ping(0);
1645
1646 // Check that it's a proper BINDING-REQUEST.
Honghai Zhang161a5862016-10-20 11:47:02 -07001647 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001648 IceMessage* msg = lport->last_stun_msg();
1649 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1650 EXPECT_FALSE(msg->IsLegacy());
1651 const StunByteStringAttribute* username_attr =
1652 msg->GetByteString(STUN_ATTR_USERNAME);
1653 ASSERT_TRUE(username_attr != NULL);
1654 const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1655 ASSERT_TRUE(priority_attr != NULL);
1656 EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1657 EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1658 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1659 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001660 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001661 "rpass"));
1662 const StunUInt64Attribute* ice_controlling_attr =
1663 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1664 ASSERT_TRUE(ice_controlling_attr != NULL);
1665 EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
1666 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1667 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1668 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1669 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001670 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001671
1672 // Request should not include ping count.
1673 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1674
1675 // Save a copy of the BINDING-REQUEST for use below.
kwiberg3ec46792016-04-27 07:22:53 -07001676 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001677
zhihuang5ecf16c2016-06-01 17:09:15 -07001678 // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE.
1679 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1680 lport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001681 msg = rport->last_stun_msg();
1682 ASSERT_TRUE(msg != NULL);
1683 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
zhihuang5ecf16c2016-06-01 17:09:15 -07001684 // Received a BINDING-RESPONSE.
1685 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1686 rport->last_stun_buf()->size(), rtc::PacketTime());
1687 // Verify the STUN Stats.
1688 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total);
1689 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_before_first_response);
1690 EXPECT_EQ(1U, lconn->stats().recv_ping_responses);
1691 EXPECT_EQ(1U, rconn->stats().recv_ping_requests);
1692 EXPECT_EQ(1U, rconn->stats().sent_ping_responses);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001693
1694 EXPECT_FALSE(msg->IsLegacy());
1695 const StunAddressAttribute* addr_attr = msg->GetAddress(
1696 STUN_ATTR_XOR_MAPPED_ADDRESS);
1697 ASSERT_TRUE(addr_attr != NULL);
1698 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1699 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1700 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001701 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001702 "rpass"));
1703 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1704 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001705 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001706 // No USERNAME or PRIORITY in ICE responses.
1707 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1708 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1709 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1710 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1711 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1712 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1713
1714 // Response should not include ping count.
1715 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1716
1717 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1718 // but we can do it here.
1719 rport->SendBindingErrorResponse(request.get(),
1720 lport->Candidates()[0].address(),
1721 STUN_ERROR_SERVER_ERROR,
1722 STUN_ERROR_REASON_SERVER_ERROR);
1723 msg = rport->last_stun_msg();
1724 ASSERT_TRUE(msg != NULL);
1725 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1726 EXPECT_FALSE(msg->IsLegacy());
1727 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1728 ASSERT_TRUE(error_attr != NULL);
1729 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1730 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1731 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1732 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001733 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001734 "rpass"));
1735 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1736 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001737 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001738 // No USERNAME with ICE.
1739 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1740 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1741
1742 // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1743 // and (incremented) RETRANSMIT_COUNT attributes.
1744 rport->Reset();
1745 rport->set_send_retransmit_count_attribute(true);
1746 rconn->Ping(0);
1747 rconn->Ping(0);
1748 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001749 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001750 msg = rport->last_stun_msg();
1751 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1752 const StunUInt64Attribute* ice_controlled_attr =
1753 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1754 ASSERT_TRUE(ice_controlled_attr != NULL);
1755 EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
1756 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1757
1758 // Request should include ping count.
1759 const StunUInt32Attribute* retransmit_attr =
1760 msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1761 ASSERT_TRUE(retransmit_attr != NULL);
1762 EXPECT_EQ(2U, retransmit_attr->value());
1763
1764 // Respond with a BINDING-RESPONSE.
1765 request.reset(CopyStunMessage(msg));
zhihuang5ecf16c2016-06-01 17:09:15 -07001766 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1767 rport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001768 msg = lport->last_stun_msg();
zhihuang5ecf16c2016-06-01 17:09:15 -07001769 // Receive the BINDING-RESPONSE.
1770 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1771 lport->last_stun_buf()->size(), rtc::PacketTime());
1772
1773 // Verify the Stun ping stats.
1774 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total);
1775 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
1776 EXPECT_EQ(1U, rconn->stats().recv_ping_responses);
1777 EXPECT_EQ(1U, lconn->stats().sent_ping_responses);
1778 EXPECT_EQ(1U, lconn->stats().recv_ping_requests);
1779 // Ping after receiver the first response
1780 rconn->Ping(0);
1781 rconn->Ping(0);
1782 EXPECT_EQ(5U, rconn->stats().sent_ping_requests_total);
1783 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001784
1785 // Response should include same ping count.
1786 retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1787 ASSERT_TRUE(retransmit_attr != NULL);
1788 EXPECT_EQ(2U, retransmit_attr->value());
1789}
1790
1791TEST_F(PortTest, TestUseCandidateAttribute) {
kwiberg3ec46792016-04-27 07:22:53 -07001792 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001793 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001794 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001795 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001796 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1797 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001798 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1799 rport->SetIceTiebreaker(kTiebreaker2);
1800
1801 // Send a fake ping from lport to rport.
1802 lport->PrepareAddress();
1803 rport->PrepareAddress();
1804 ASSERT_FALSE(rport->Candidates().empty());
1805 Connection* lconn = lport->CreateConnection(
1806 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1807 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001808 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001809 IceMessage* msg = lport->last_stun_msg();
1810 const StunUInt64Attribute* ice_controlling_attr =
1811 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1812 ASSERT_TRUE(ice_controlling_attr != NULL);
1813 const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1814 STUN_ATTR_USE_CANDIDATE);
1815 ASSERT_TRUE(use_candidate_attr != NULL);
1816}
1817
Honghai Zhang351d77b2016-05-20 15:08:29 -07001818// Tests that when the network type changes, the network cost of the port will
1819// change, the network cost of the local candidates will change. Also tests that
1820// the remote network costs are updated with the stun binding requests.
1821TEST_F(PortTest, TestNetworkCostChange) {
1822 std::unique_ptr<TestPort> lport(
1823 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1824 std::unique_ptr<TestPort> rport(
1825 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1826 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1827 lport->SetIceTiebreaker(kTiebreaker1);
1828 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1829 rport->SetIceTiebreaker(kTiebreaker2);
1830 lport->PrepareAddress();
1831 rport->PrepareAddress();
1832
1833 // Default local port cost is rtc::kNetworkCostUnknown.
1834 EXPECT_EQ(rtc::kNetworkCostUnknown, lport->network_cost());
1835 ASSERT_TRUE(!lport->Candidates().empty());
1836 for (const cricket::Candidate& candidate : lport->Candidates()) {
1837 EXPECT_EQ(rtc::kNetworkCostUnknown, candidate.network_cost());
1838 }
1839
1840 // Change the network type to wifi.
1841 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
1842 EXPECT_EQ(rtc::kNetworkCostLow, lport->network_cost());
1843 for (const cricket::Candidate& candidate : lport->Candidates()) {
1844 EXPECT_EQ(rtc::kNetworkCostLow, candidate.network_cost());
1845 }
1846
1847 // Add a connection and then change the network type.
1848 Connection* lconn =
1849 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1850 // Change the network type to cellular.
1851 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
1852 EXPECT_EQ(rtc::kNetworkCostHigh, lport->network_cost());
1853 for (const cricket::Candidate& candidate : lport->Candidates()) {
1854 EXPECT_EQ(rtc::kNetworkCostHigh, candidate.network_cost());
1855 }
1856
1857 SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
1858 Connection* rconn =
1859 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1860 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
1861 lconn->Ping(0);
1862 // The rconn's remote candidate cost is rtc::kNetworkCostLow, but the ping
1863 // contains an attribute of network cost of rtc::kNetworkCostHigh. Once the
1864 // message is handled in rconn, The rconn's remote candidate will have cost
1865 // rtc::kNetworkCostHigh;
1866 EXPECT_EQ(rtc::kNetworkCostLow, rconn->remote_candidate().network_cost());
Honghai Zhang161a5862016-10-20 11:47:02 -07001867 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001868 IceMessage* msg = lport->last_stun_msg();
1869 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1870 // Pass the binding request to rport.
1871 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1872 lport->last_stun_buf()->size(), rtc::PacketTime());
1873 // Wait until rport sends the response and then check the remote network cost.
Honghai Zhang161a5862016-10-20 11:47:02 -07001874 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001875 EXPECT_EQ(rtc::kNetworkCostHigh, rconn->remote_candidate().network_cost());
1876}
1877
honghaiza0c44ea2016-03-23 16:07:48 -07001878TEST_F(PortTest, TestNetworkInfoAttribute) {
kwiberg3ec46792016-04-27 07:22:53 -07001879 std::unique_ptr<TestPort> lport(
honghaiza0c44ea2016-03-23 16:07:48 -07001880 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001881 std::unique_ptr<TestPort> rport(
honghaiza0c44ea2016-03-23 16:07:48 -07001882 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1883 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1884 lport->SetIceTiebreaker(kTiebreaker1);
1885 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1886 rport->SetIceTiebreaker(kTiebreaker2);
1887
1888 uint16_t lnetwork_id = 9;
1889 lport->Network()->set_id(lnetwork_id);
1890 // Send a fake ping from lport to rport.
1891 lport->PrepareAddress();
1892 rport->PrepareAddress();
1893 Connection* lconn =
1894 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1895 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001896 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07001897 IceMessage* msg = lport->last_stun_msg();
1898 const StunUInt32Attribute* network_info_attr =
1899 msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
1900 ASSERT_TRUE(network_info_attr != NULL);
1901 uint32_t network_info = network_info_attr->value();
1902 EXPECT_EQ(lnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001903 // Default network has unknown type and cost kNetworkCostUnknown.
1904 EXPECT_EQ(rtc::kNetworkCostUnknown, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07001905
Honghai Zhang351d77b2016-05-20 15:08:29 -07001906 // Set the network type to be cellular so its cost will be kNetworkCostHigh.
honghaiza0c44ea2016-03-23 16:07:48 -07001907 // Send a fake ping from rport to lport.
Honghai Zhang351d77b2016-05-20 15:08:29 -07001908 SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
honghaiza0c44ea2016-03-23 16:07:48 -07001909 uint16_t rnetwork_id = 8;
1910 rport->Network()->set_id(rnetwork_id);
1911 Connection* rconn =
1912 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1913 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001914 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07001915 msg = rport->last_stun_msg();
1916 network_info_attr = msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
1917 ASSERT_TRUE(network_info_attr != NULL);
1918 network_info = network_info_attr->value();
1919 EXPECT_EQ(rnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001920 EXPECT_EQ(rtc::kNetworkCostHigh, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07001921}
1922
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001923// Test handling STUN messages.
1924TEST_F(PortTest, TestHandleStunMessage) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001925 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07001926 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001927
kwiberg3ec46792016-04-27 07:22:53 -07001928 std::unique_ptr<IceMessage> in_msg, out_msg;
1929 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001930 rtc::SocketAddress addr(kLocalAddr1);
1931 std::string username;
1932
1933 // BINDING-REQUEST from local to remote with valid ICE username,
1934 // MESSAGE-INTEGRITY, and FINGERPRINT.
1935 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1936 "rfrag:lfrag"));
1937 in_msg->AddMessageIntegrity("rpass");
1938 in_msg->AddFingerprint();
1939 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07001940 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
1941 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001942 EXPECT_TRUE(out_msg.get() != NULL);
1943 EXPECT_EQ("lfrag", username);
1944
1945 // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
1946 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1947 in_msg->AddAttribute(
1948 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1949 in_msg->AddMessageIntegrity("rpass");
1950 in_msg->AddFingerprint();
1951 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07001952 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
1953 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001954 EXPECT_TRUE(out_msg.get() != NULL);
1955 EXPECT_EQ("", username);
1956
1957 // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
1958 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1959 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1960 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1961 in_msg->AddFingerprint();
1962 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07001963 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
1964 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001965 EXPECT_TRUE(out_msg.get() != NULL);
1966 EXPECT_EQ("", username);
1967 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1968 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
1969 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1970 out_msg->GetErrorCode()->reason());
1971}
1972
guoweisd12140a2015-09-10 13:32:11 -07001973// Tests handling of ICE binding requests with missing or incorrect usernames.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001974TEST_F(PortTest, TestHandleStunMessageBadUsername) {
kwiberg3ec46792016-04-27 07:22:53 -07001975 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001976
kwiberg3ec46792016-04-27 07:22:53 -07001977 std::unique_ptr<IceMessage> in_msg, out_msg;
1978 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001979 rtc::SocketAddress addr(kLocalAddr1);
1980 std::string username;
1981
1982 // BINDING-REQUEST with no username.
1983 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1984 in_msg->AddMessageIntegrity("rpass");
1985 in_msg->AddFingerprint();
1986 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07001987 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
1988 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001989 EXPECT_TRUE(out_msg.get() == NULL);
1990 EXPECT_EQ("", username);
1991 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1992
1993 // BINDING-REQUEST with empty username.
1994 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1995 in_msg->AddMessageIntegrity("rpass");
1996 in_msg->AddFingerprint();
1997 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07001998 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
1999 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002000 EXPECT_TRUE(out_msg.get() == NULL);
2001 EXPECT_EQ("", username);
2002 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2003
2004 // BINDING-REQUEST with too-short username.
2005 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
2006 in_msg->AddMessageIntegrity("rpass");
2007 in_msg->AddFingerprint();
2008 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002009 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2010 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002011 EXPECT_TRUE(out_msg.get() == NULL);
2012 EXPECT_EQ("", username);
2013 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2014
2015 // BINDING-REQUEST with reversed username.
2016 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2017 "lfrag:rfrag"));
2018 in_msg->AddMessageIntegrity("rpass");
2019 in_msg->AddFingerprint();
2020 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002021 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2022 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002023 EXPECT_TRUE(out_msg.get() == NULL);
2024 EXPECT_EQ("", username);
2025 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2026
2027 // BINDING-REQUEST with garbage username.
2028 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2029 "abcd:efgh"));
2030 in_msg->AddMessageIntegrity("rpass");
2031 in_msg->AddFingerprint();
2032 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002033 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2034 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002035 EXPECT_TRUE(out_msg.get() == NULL);
2036 EXPECT_EQ("", username);
2037 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2038}
2039
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002040// Test handling STUN messages with missing or malformed M-I.
2041TEST_F(PortTest, TestHandleStunMessageBadMessageIntegrity) {
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 and
2051 // FINGERPRINT, but no MESSAGE-INTEGRITY.
2052 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2053 "rfrag:lfrag"));
2054 in_msg->AddFingerprint();
2055 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002056 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2057 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002058 EXPECT_TRUE(out_msg.get() == NULL);
2059 EXPECT_EQ("", username);
2060 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2061
2062 // BINDING-REQUEST from local to remote with valid ICE username and
2063 // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
2064 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2065 "rfrag:lfrag"));
2066 in_msg->AddMessageIntegrity("invalid");
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 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2074
2075 // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
2076 // by the Connection, not the Port, since they require the remote username.
2077 // Change this test to pass in data via Connection::OnReadPacket instead.
2078}
2079
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002080// Test handling STUN messages with missing or malformed FINGERPRINT.
2081TEST_F(PortTest, TestHandleStunMessageBadFingerprint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002082 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002083 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002084
kwiberg3ec46792016-04-27 07:22:53 -07002085 std::unique_ptr<IceMessage> in_msg, out_msg;
2086 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002087 rtc::SocketAddress addr(kLocalAddr1);
2088 std::string username;
2089
2090 // BINDING-REQUEST from local to remote with valid ICE username and
2091 // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
2092 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2093 "rfrag:lfrag"));
2094 in_msg->AddMessageIntegrity("rpass");
2095 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002096 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2097 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002098 EXPECT_EQ(0, port->last_stun_error_code());
2099
2100 // Now, add a fingerprint, but munge the message so it's not valid.
2101 in_msg->AddFingerprint();
2102 in_msg->SetTransactionID("TESTTESTBADD");
2103 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002104 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2105 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002106 EXPECT_EQ(0, port->last_stun_error_code());
2107
2108 // Valid BINDING-RESPONSE, except no FINGERPRINT.
2109 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
2110 in_msg->AddAttribute(
2111 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
2112 in_msg->AddMessageIntegrity("rpass");
2113 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002114 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2115 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002116 EXPECT_EQ(0, port->last_stun_error_code());
2117
2118 // Now, add a fingerprint, but munge the message so it's not valid.
2119 in_msg->AddFingerprint();
2120 in_msg->SetTransactionID("TESTTESTBADD");
2121 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002122 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2123 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002124 EXPECT_EQ(0, port->last_stun_error_code());
2125
2126 // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
2127 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
2128 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
2129 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
2130 in_msg->AddMessageIntegrity("rpass");
2131 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002132 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2133 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002134 EXPECT_EQ(0, port->last_stun_error_code());
2135
2136 // Now, add a fingerprint, but munge the message so it's not valid.
2137 in_msg->AddFingerprint();
2138 in_msg->SetTransactionID("TESTTESTBADD");
2139 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002140 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2141 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002142 EXPECT_EQ(0, port->last_stun_error_code());
2143}
2144
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002145// Test handling of STUN binding indication messages . STUN binding
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002146// indications are allowed only to the connection which is in read mode.
2147TEST_F(PortTest, TestHandleStunBindingIndication) {
kwiberg3ec46792016-04-27 07:22:53 -07002148 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002149 CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002150 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2151 lport->SetIceTiebreaker(kTiebreaker1);
2152
2153 // Verifying encoding and decoding STUN indication message.
kwiberg3ec46792016-04-27 07:22:53 -07002154 std::unique_ptr<IceMessage> in_msg, out_msg;
2155 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002156 rtc::SocketAddress addr(kLocalAddr1);
2157 std::string username;
2158
2159 in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
2160 in_msg->AddFingerprint();
2161 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002162 EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2163 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002164 EXPECT_TRUE(out_msg.get() != NULL);
2165 EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2166 EXPECT_EQ("", username);
2167
2168 // Verify connection can handle STUN indication and updates
2169 // last_ping_received.
kwiberg3ec46792016-04-27 07:22:53 -07002170 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002171 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002172 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2173 rport->SetIceTiebreaker(kTiebreaker2);
2174
2175 lport->PrepareAddress();
2176 rport->PrepareAddress();
2177 ASSERT_FALSE(lport->Candidates().empty());
2178 ASSERT_FALSE(rport->Candidates().empty());
2179
2180 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
2181 Port::ORIGIN_MESSAGE);
2182 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
2183 Port::ORIGIN_MESSAGE);
2184 rconn->Ping(0);
2185
Honghai Zhang161a5862016-10-20 11:47:02 -07002186 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002187 IceMessage* msg = rport->last_stun_msg();
2188 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2189 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07002190 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
2191 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002192 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07002193 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002194 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
honghaiz34b11eb2016-03-16 08:55:44 -07002195 int64_t last_ping_received1 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002196
2197 // Adding a delay of 100ms.
2198 rtc::Thread::Current()->ProcessMessages(100);
2199 // Pinging lconn using stun indication message.
2200 lconn->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
honghaiz34b11eb2016-03-16 08:55:44 -07002201 int64_t last_ping_received2 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002202 EXPECT_GT(last_ping_received2, last_ping_received1);
2203}
2204
2205TEST_F(PortTest, TestComputeCandidatePriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002206 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr1, "name", "pass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002207 port->set_type_preference(90);
2208 port->set_component(177);
2209 port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2210 port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2211 port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2212 port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2213 port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2214 port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2215 port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2216 port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2217 port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2218 // These should all be:
2219 // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
Peter Boström0c4e06b2015-10-07 12:23:21 +02002220 uint32_t expected_priority_v4 = 1509957199U;
2221 uint32_t expected_priority_v6 = 1509959759U;
2222 uint32_t expected_priority_ula = 1509962319U;
2223 uint32_t expected_priority_v4mapped = expected_priority_v4;
2224 uint32_t expected_priority_v4compat = 1509949775U;
2225 uint32_t expected_priority_6to4 = 1509954639U;
2226 uint32_t expected_priority_teredo = 1509952079U;
2227 uint32_t expected_priority_sitelocal = 1509949775U;
2228 uint32_t expected_priority_6bone = 1509949775U;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002229 ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2230 ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2231 ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2232 ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2233 ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2234 ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2235 ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2236 ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2237 ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2238}
2239
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002240// In the case of shared socket, one port may be shared by local and stun.
2241// Test that candidates with different types will have different foundation.
2242TEST_F(PortTest, TestFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002243 std::unique_ptr<TestPort> testport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002244 CreateTestPort(kLocalAddr1, "name", "pass"));
2245 testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2246 LOCAL_PORT_TYPE,
2247 cricket::ICE_TYPE_PREFERENCE_HOST, false);
2248 testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2249 STUN_PORT_TYPE,
2250 cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2251 EXPECT_NE(testport->Candidates()[0].foundation(),
2252 testport->Candidates()[1].foundation());
2253}
2254
2255// This test verifies the foundation of different types of ICE candidates.
2256TEST_F(PortTest, TestCandidateFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002257 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002258 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002259 std::unique_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002260 udpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002261 std::unique_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002262 udpport2->PrepareAddress();
2263 EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2264 udpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002265 std::unique_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002266 tcpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002267 std::unique_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002268 tcpport2->PrepareAddress();
2269 EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2270 tcpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002271 std::unique_ptr<Port> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002272 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2273 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002274 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002275 EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2276 stunport->Candidates()[0].foundation());
2277 EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2278 stunport->Candidates()[0].foundation());
2279 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2280 stunport->Candidates()[0].foundation());
2281 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2282 stunport->Candidates()[0].foundation());
2283 // Verify GTURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002284 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002285 relayport->AddServerAddress(
2286 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2287 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002288 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002289 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2290 relayport->Candidates()[0].foundation());
2291 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2292 relayport->Candidates()[0].foundation());
2293 // Verifying TURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002294 std::unique_ptr<Port> turnport1(
2295 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002296 turnport1->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002297 ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002298 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2299 turnport1->Candidates()[0].foundation());
2300 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2301 turnport1->Candidates()[0].foundation());
2302 EXPECT_NE(stunport->Candidates()[0].foundation(),
2303 turnport1->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002304 std::unique_ptr<Port> turnport2(
2305 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002306 turnport2->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002307 ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002308 EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2309 turnport2->Candidates()[0].foundation());
2310
2311 // Running a second turn server, to get different base IP address.
2312 SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2313 SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2314 TestTurnServer turn_server2(
2315 rtc::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
kwiberg3ec46792016-04-27 07:22:53 -07002316 std::unique_ptr<Port> turnport3(
2317 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
2318 kTurnUdpIntAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002319 turnport3->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002320 ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002321 EXPECT_NE(turnport3->Candidates()[0].foundation(),
2322 turnport2->Candidates()[0].foundation());
Honghai Zhang80f1db92016-01-27 11:54:45 -08002323
2324 // Start a TCP turn server, and check that two turn candidates have
2325 // different foundations if their relay protocols are different.
2326 TestTurnServer turn_server3(rtc::Thread::Current(), kTurnTcpIntAddr,
2327 kTurnUdpExtAddr, PROTO_TCP);
kwiberg3ec46792016-04-27 07:22:53 -07002328 std::unique_ptr<Port> turnport4(
Honghai Zhang80f1db92016-01-27 11:54:45 -08002329 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_TCP, PROTO_UDP));
2330 turnport4->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002331 ASSERT_EQ_WAIT(1U, turnport4->Candidates().size(), kDefaultTimeout);
Honghai Zhang80f1db92016-01-27 11:54:45 -08002332 EXPECT_NE(turnport2->Candidates()[0].foundation(),
2333 turnport4->Candidates()[0].foundation());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002334}
2335
2336// This test verifies the related addresses of different types of
2337// ICE candiates.
2338TEST_F(PortTest, TestCandidateRelatedAddress) {
kwiberg3ec46792016-04-27 07:22:53 -07002339 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002340 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002341 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002342 udpport->PrepareAddress();
2343 // For UDPPort, related address will be empty.
2344 EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2345 // Testing related address for stun candidates.
2346 // For stun candidate related address must be equal to the base
2347 // socket address.
kwiberg3ec46792016-04-27 07:22:53 -07002348 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002349 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2350 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002351 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002352 // Check STUN candidate address.
2353 EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2354 kNatAddr1.ipaddr());
2355 // Check STUN candidate related address.
2356 EXPECT_EQ(stunport->Candidates()[0].related_address(),
2357 stunport->GetLocalAddress());
2358 // Verifying the related address for the GTURN candidates.
2359 // NOTE: In case of GTURN related address will be equal to the mapped
2360 // address, but address(mapped) will not be XOR.
kwiberg3ec46792016-04-27 07:22:53 -07002361 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002362 relayport->AddServerAddress(
2363 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2364 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002365 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002366 // For Gturn related address is set to "0.0.0.0:0"
2367 EXPECT_EQ(rtc::SocketAddress(),
2368 relayport->Candidates()[0].related_address());
2369 // Verifying the related address for TURN candidate.
2370 // For TURN related address must be equal to the mapped address.
kwiberg3ec46792016-04-27 07:22:53 -07002371 std::unique_ptr<Port> turnport(
2372 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002373 turnport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002374 ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002375 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
2376 turnport->Candidates()[0].address().ipaddr());
2377 EXPECT_EQ(kNatAddr1.ipaddr(),
2378 turnport->Candidates()[0].related_address().ipaddr());
2379}
2380
2381// Test priority value overflow handling when preference is set to 3.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002382TEST_F(PortTest, TestCandidatePriority) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002383 cricket::Candidate cand1;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002384 cand1.set_priority(3);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002385 cricket::Candidate cand2;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002386 cand2.set_priority(1);
2387 EXPECT_TRUE(cand1.priority() > cand2.priority());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002388}
2389
2390// Test the Connection priority is calculated correctly.
2391TEST_F(PortTest, TestConnectionPriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002392 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002393 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2394 lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
kwiberg3ec46792016-04-27 07:22:53 -07002395 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002396 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
hnsl277b2502016-12-13 05:17:23 -08002397 rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002398 lport->set_component(123);
2399 lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2400 rport->set_component(23);
2401 rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2402
2403 EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2404 EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2405
2406 // RFC 5245
2407 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
2408 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2409 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2410 Connection* lconn = lport->CreateConnection(
2411 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2412#if defined(WEBRTC_WIN)
2413 EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2414#else
2415 EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2416#endif
2417
2418 lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2419 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2420 Connection* rconn = rport->CreateConnection(
2421 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2422#if defined(WEBRTC_WIN)
2423 EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2424#else
2425 EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2426#endif
2427}
2428
2429TEST_F(PortTest, TestWritableState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002430 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002431 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002432 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002433 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002434 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002435
2436 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002437 TestChannel ch1(port1);
2438 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002439
2440 // Acquire addresses.
2441 ch1.Start();
2442 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07002443 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
2444 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002445
2446 // Send a ping from src to dst.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002447 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002448 ASSERT_TRUE(ch1.conn() != NULL);
2449 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
Honghai Zhang161a5862016-10-20 11:47:02 -07002450 // for TCP connect
2451 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002452 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002453 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002454
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002455 // Data should be sendable before the connection is accepted.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002456 char data[] = "abcd";
tfarina5237aaf2015-11-10 23:44:30 -08002457 int data_size = arraysize(data);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002458 rtc::PacketOptions options;
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002459 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002460
2461 // Accept the connection to return the binding response, transition to
2462 // writable, and allow data to be sent.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002463 ch2.AcceptConnection(GetCandidate(port1));
Honghai Zhang161a5862016-10-20 11:47:02 -07002464 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2465 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002466 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2467
2468 // Ask the connection to update state as if enough time has passed to lose
2469 // full writability and 5 pings went unresponded to. We'll accomplish the
2470 // latter by sending pings but not pumping messages.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002471 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002472 ch1.Ping(i);
2473 }
honghaiz34b11eb2016-03-16 08:55:44 -07002474 int unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002475 ch1.conn()->UpdateState(unreliable_timeout_delay);
2476 EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2477
2478 // Data should be able to be sent in this state.
2479 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2480
2481 // And now allow the other side to process the pings and send binding
2482 // responses.
Honghai Zhang161a5862016-10-20 11:47:02 -07002483 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2484 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002485
2486 // Wait long enough for a full timeout (past however long we've already
2487 // waited).
Peter Boström0c4e06b2015-10-07 12:23:21 +02002488 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002489 ch1.Ping(unreliable_timeout_delay + i);
2490 }
2491 ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2492 500u);
2493 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2494
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002495 // Even if the connection has timed out, the Connection shouldn't block
2496 // the sending of data.
2497 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002498
2499 ch1.Stop();
2500 ch2.Stop();
2501}
2502
2503TEST_F(PortTest, TestTimeoutForNeverWritable) {
2504 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002505 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002506 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002507 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002508
2509 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002510 TestChannel ch1(port1);
2511 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002512
2513 // Acquire addresses.
2514 ch1.Start();
2515 ch2.Start();
2516
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002517 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002518 ASSERT_TRUE(ch1.conn() != NULL);
2519 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2520
2521 // Attempt to go directly to write timeout.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002522 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002523 ch1.Ping(i);
2524 }
2525 ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2526 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2527}
2528
2529// This test verifies the connection setup between ICEMODE_FULL
2530// and ICEMODE_LITE.
2531// In this test |ch1| behaves like FULL mode client and we have created
2532// port which responds to the ping message just like LITE client.
2533TEST_F(PortTest, TestIceLiteConnectivity) {
2534 TestPort* ice_full_port = CreateTestPort(
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002535 kLocalAddr1, "lfrag", "lpass",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002536 cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2537
kwiberg3ec46792016-04-27 07:22:53 -07002538 std::unique_ptr<TestPort> ice_lite_port(
2539 CreateTestPort(kLocalAddr2, "rfrag", "rpass", cricket::ICEROLE_CONTROLLED,
2540 kTiebreaker2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002541 // Setup TestChannel. This behaves like FULL mode client.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002542 TestChannel ch1(ice_full_port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002543 ch1.SetIceMode(ICEMODE_FULL);
2544
2545 // Start gathering candidates.
2546 ch1.Start();
2547 ice_lite_port->PrepareAddress();
2548
Honghai Zhang161a5862016-10-20 11:47:02 -07002549 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002550 ASSERT_FALSE(ice_lite_port->Candidates().empty());
2551
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002552 ch1.CreateConnection(GetCandidate(ice_lite_port.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002553 ASSERT_TRUE(ch1.conn() != NULL);
2554 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2555
2556 // Send ping from full mode client.
2557 // This ping must not have USE_CANDIDATE_ATTR.
2558 ch1.Ping();
2559
2560 // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2561 // from port.
Honghai Zhang161a5862016-10-20 11:47:02 -07002562 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002563 IceMessage* msg = ice_full_port->last_stun_msg();
2564 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2565
2566 // Respond with a BINDING-RESPONSE from litemode client.
2567 // NOTE: Ideally we should't create connection at this stage from lite
2568 // port, as it should be done only after receiving ping with USE_CANDIDATE.
2569 // But we need a connection to send a response message.
2570 ice_lite_port->CreateConnection(
2571 ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
kwiberg3ec46792016-04-27 07:22:53 -07002572 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002573 ice_lite_port->SendBindingResponse(
2574 request.get(), ice_full_port->Candidates()[0].address());
2575
2576 // Feeding the respone message from litemode to the full mode connection.
jbauchf1f87202016-03-30 06:43:37 -07002577 ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->data<char>(),
2578 ice_lite_port->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002579 rtc::PacketTime());
2580 // Verifying full mode connection becomes writable from the response.
2581 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002582 kDefaultTimeout);
2583 EXPECT_TRUE_WAIT(ch1.nominated(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002584
2585 // Clear existing stun messsages. Otherwise we will process old stun
2586 // message right after we send ping.
2587 ice_full_port->Reset();
2588 // Send ping. This must have USE_CANDIDATE_ATTR.
2589 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002590 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002591 msg = ice_full_port->last_stun_msg();
2592 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2593 ch1.Stop();
2594}
2595
Honghai Zhanga74363c2016-07-28 18:06:15 -07002596// This test case verifies that both the controlling port and the controlled
2597// port will time out after connectivity is lost, if they are not marked as
2598// "keep alive until pruned."
2599TEST_F(PortTest, TestPortTimeoutIfNotKeptAlive) {
2600 rtc::ScopedFakeClock clock;
2601 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002602 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2603 ConnectToSignalDestroyed(port1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002604 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002605 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2606 port1->SetIceTiebreaker(kTiebreaker1);
2607
2608 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002609 ConnectToSignalDestroyed(port2);
2610 port2->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002611 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2612 port2->SetIceTiebreaker(kTiebreaker2);
2613
2614 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002615 TestChannel ch1(port1);
2616 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002617
2618 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002619 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002620 // After the connection is destroyed, the port will be destroyed because
2621 // none of them is marked as "keep alive until pruned.
2622 EXPECT_EQ_SIMULATED_WAIT(2, ports_destroyed(), 110, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002623}
2624
Honghai Zhanga74363c2016-07-28 18:06:15 -07002625// Test that if after all connection are destroyed, new connections are created
2626// and destroyed again, ports won't be destroyed until a timeout period passes
2627// after the last set of connections are all destroyed.
2628TEST_F(PortTest, TestPortTimeoutAfterNewConnectionCreatedAndDestroyed) {
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002629 rtc::ScopedFakeClock clock;
Honghai Zhanga74363c2016-07-28 18:06:15 -07002630 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002631 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002632 ConnectToSignalDestroyed(port1);
2633 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002634 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2635 port1->SetIceTiebreaker(kTiebreaker1);
2636
2637 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2638 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002639 port2->set_timeout_delay(timeout_delay); // milliseconds
2640
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002641 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2642 port2->SetIceTiebreaker(kTiebreaker2);
2643
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002644 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002645 TestChannel ch1(port1);
2646 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002647
2648 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002649 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002650 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2651 EXPECT_EQ(0, ports_destroyed());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002652
Honghai Zhanga74363c2016-07-28 18:06:15 -07002653 // Start the second set of connection and destroy them.
2654 ch1.CreateConnection(GetCandidate(ch2.port()));
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002655 ch2.CreateConnection(GetCandidate(ch1.port()));
Honghai Zhanga74363c2016-07-28 18:06:15 -07002656 ch1.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002657 ch2.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002658
Honghai Zhanga74363c2016-07-28 18:06:15 -07002659 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2660 EXPECT_EQ(0, ports_destroyed());
2661
2662 // The ports on both sides should be destroyed after timeout.
2663 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 30, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002664}
honghaizd0b31432015-09-30 12:42:17 -07002665
Honghai Zhanga74363c2016-07-28 18:06:15 -07002666// This test case verifies that neither the controlling port nor the controlled
2667// port will time out after connectivity is lost if they are marked as "keep
2668// alive until pruned". They will time out after they are pruned.
2669TEST_F(PortTest, TestPortNotTimeoutUntilPruned) {
2670 rtc::ScopedFakeClock clock;
2671 int timeout_delay = 100;
honghaizd0b31432015-09-30 12:42:17 -07002672 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002673 ConnectToSignalDestroyed(port1);
2674 port1->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002675 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2676 port1->SetIceTiebreaker(kTiebreaker1);
2677
2678 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2679 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002680 port2->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002681 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2682 port2->SetIceTiebreaker(kTiebreaker2);
honghaizd0b31432015-09-30 12:42:17 -07002683 // The connection must not be destroyed before a connection is attempted.
Honghai Zhanga74363c2016-07-28 18:06:15 -07002684 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002685
2686 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2687 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2688
Honghai Zhanga74363c2016-07-28 18:06:15 -07002689 // Set up channels and keep the port alive.
honghaizd0b31432015-09-30 12:42:17 -07002690 TestChannel ch1(port1);
2691 TestChannel ch2(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002692 // Simulate a connection that succeeds, and then is destroyed. But ports
2693 // are kept alive. Ports won't be destroyed.
honghaizd0b31432015-09-30 12:42:17 -07002694 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002695 port1->KeepAliveUntilPruned();
2696 port2->KeepAliveUntilPruned();
2697 SIMULATED_WAIT(ports_destroyed() > 0, 150, clock);
2698 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002699
Honghai Zhanga74363c2016-07-28 18:06:15 -07002700 // If they are pruned now, they will be destroyed right away.
2701 port1->Prune();
2702 port2->Prune();
2703 // The ports on both sides should be destroyed after timeout.
2704 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 1, clock);
honghaizd0b31432015-09-30 12:42:17 -07002705}
Honghai Zhangf9945b22015-12-15 12:20:13 -08002706
2707TEST_F(PortTest, TestSupportsProtocol) {
kwiberg3ec46792016-04-27 07:22:53 -07002708 std::unique_ptr<Port> udp_port(CreateUdpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002709 EXPECT_TRUE(udp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2710 EXPECT_FALSE(udp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2711
kwiberg3ec46792016-04-27 07:22:53 -07002712 std::unique_ptr<Port> stun_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002713 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2714 EXPECT_TRUE(stun_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2715 EXPECT_FALSE(stun_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2716
kwiberg3ec46792016-04-27 07:22:53 -07002717 std::unique_ptr<Port> tcp_port(CreateTcpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002718 EXPECT_TRUE(tcp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2719 EXPECT_TRUE(tcp_port->SupportsProtocol(SSLTCP_PROTOCOL_NAME));
2720 EXPECT_FALSE(tcp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2721
kwiberg3ec46792016-04-27 07:22:53 -07002722 std::unique_ptr<Port> turn_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002723 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2724 EXPECT_TRUE(turn_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2725 EXPECT_FALSE(turn_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2726}
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002727
2728// Test that SetIceParameters updates the component, ufrag and password
2729// on both the port itself and its candidates.
2730TEST_F(PortTest, TestSetIceParameters) {
2731 std::unique_ptr<TestPort> port(
2732 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2733 port->PrepareAddress();
2734 EXPECT_EQ(1UL, port->Candidates().size());
2735 port->SetIceParameters(1, "ufrag2", "password2");
2736 EXPECT_EQ(1, port->component());
2737 EXPECT_EQ("ufrag2", port->username_fragment());
2738 EXPECT_EQ("password2", port->password());
2739 const Candidate& candidate = port->Candidates()[0];
2740 EXPECT_EQ(1, candidate.component());
2741 EXPECT_EQ("ufrag2", candidate.username());
2742 EXPECT_EQ("password2", candidate.password());
2743}
honghaiz36f50e82016-06-01 15:57:03 -07002744
2745TEST_F(PortTest, TestAddConnectionWithSameAddress) {
2746 std::unique_ptr<TestPort> port(
2747 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2748 port->PrepareAddress();
2749 EXPECT_EQ(1u, port->Candidates().size());
2750 rtc::SocketAddress address("1.1.1.1", 5000);
2751 cricket::Candidate candidate(1, "udp", address, 0, "", "", "relay", 0, "");
2752 cricket::Connection* conn1 =
2753 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2754 cricket::Connection* conn_in_use = port->GetConnection(address);
2755 EXPECT_EQ(conn1, conn_in_use);
2756 EXPECT_EQ(0u, conn_in_use->remote_candidate().generation());
2757
2758 // Creating with a candidate with the same address again will get us a
2759 // different connection with the new candidate.
2760 candidate.set_generation(2);
2761 cricket::Connection* conn2 =
2762 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2763 EXPECT_NE(conn1, conn2);
2764 conn_in_use = port->GetConnection(address);
2765 EXPECT_EQ(conn2, conn_in_use);
2766 EXPECT_EQ(2u, conn_in_use->remote_candidate().generation());
2767
2768 // Make sure the new connection was not deleted.
2769 rtc::Thread::Current()->ProcessMessages(300);
2770 EXPECT_TRUE(port->GetConnection(address) != nullptr);
2771}