blob: 8f5867f1c7d586b5fce1cc68d2b645c5fbd2868b [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
deadbeef5c3c1042017-08-04 15:01:57 -070011#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "p2p/base/basicpacketsocketfactory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "p2p/base/relayport.h"
16#include "p2p/base/stunport.h"
17#include "p2p/base/tcpport.h"
18#include "p2p/base/testrelayserver.h"
19#include "p2p/base/teststunserver.h"
20#include "p2p/base/testturnserver.h"
21#include "p2p/base/turnport.h"
22#include "rtc_base/arraysize.h"
23#include "rtc_base/buffer.h"
24#include "rtc_base/crc32.h"
25#include "rtc_base/gunit.h"
26#include "rtc_base/helpers.h"
27#include "rtc_base/logging.h"
28#include "rtc_base/natserver.h"
29#include "rtc_base/natsocketfactory.h"
30#include "rtc_base/ptr_util.h"
31#include "rtc_base/socketaddress.h"
32#include "rtc_base/ssladapter.h"
33#include "rtc_base/stringutils.h"
34#include "rtc_base/thread.h"
35#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000036
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;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000049
Steve Antonbabf9172017-11-29 10:19:02 -080050namespace cricket {
51namespace {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000052
Steve Antonbabf9172017-11-29 10:19:02 -080053constexpr int kDefaultTimeout = 3000;
54constexpr int kShortTimeout = 1000;
55const SocketAddress kLocalAddr1("192.168.1.2", 0);
56const SocketAddress kLocalAddr2("192.168.1.3", 0);
57const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
58const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
59const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
60const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
61const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
62const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
63const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
64const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
65const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
66const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
67const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
68const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
69const RelayCredentials kRelayCredentials("test", "test");
70
71// TODO(?): Update these when RFC5245 is completely supported.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072// Magic value of 30 is from RFC3484, for IPv4 addresses.
Steve Antonbabf9172017-11-29 10:19:02 -080073const uint32_t kDefaultPrflxPriority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
74 30 << 8 |
75 (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000076
Steve Antonbabf9172017-11-29 10:19:02 -080077constexpr int kTiebreaker1 = 11111;
78constexpr int kTiebreaker2 = 22222;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000079
Steve Antonbabf9172017-11-29 10:19:02 -080080const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
Guo-wei Shiehbe508a12015-04-06 12:48:47 -070081
Steve Antonbabf9172017-11-29 10:19:02 -080082constexpr int kGturnUserNameLength = 16;
zhihuang6d0d4bf2016-05-24 10:13:32 -070083
Steve Antonbabf9172017-11-29 10:19:02 -080084Candidate GetCandidate(Port* port) {
85 RTC_DCHECK_GE(port->Candidates().size(), 1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000086 return port->Candidates()[0];
87}
88
Steve Antonbabf9172017-11-29 10:19:02 -080089SocketAddress GetAddress(Port* port) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090 return GetCandidate(port).address();
91}
92
Steve Antonbabf9172017-11-29 10:19:02 -080093IceMessage* CopyStunMessage(const IceMessage* src) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000094 IceMessage* dst = new IceMessage();
jbauchf1f87202016-03-30 06:43:37 -070095 ByteBufferWriter buf;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000096 src->Write(&buf);
jbauchf1f87202016-03-30 06:43:37 -070097 ByteBufferReader read_buf(buf);
98 dst->Read(&read_buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000099 return dst;
100}
101
Steve Antonbabf9172017-11-29 10:19:02 -0800102bool WriteStunMessage(const StunMessage* msg, ByteBufferWriter* buf) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103 buf->Resize(0); // clear out any existing buffer contents
104 return msg->Write(buf);
105}
106
Steve Antonbabf9172017-11-29 10:19:02 -0800107} // namespace
108
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109// Stub port class for testing STUN generation and processing.
110class TestPort : public Port {
111 public:
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000112 TestPort(rtc::Thread* thread,
113 const std::string& type,
114 rtc::PacketSocketFactory* factory,
115 rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200116 uint16_t min_port,
117 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000118 const std::string& username_fragment,
119 const std::string& password)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200120 : Port(thread,
121 type,
122 factory,
123 network,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200124 min_port,
125 max_port,
126 username_fragment,
127 password) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 ~TestPort() {}
129
130 // Expose GetStunMessage so that we can test it.
131 using cricket::Port::GetStunMessage;
132
133 // The last StunMessage that was sent on this Port.
Steve Antonbabf9172017-11-29 10:19:02 -0800134 // TODO(?): Make these const; requires changes to SendXXXXResponse.
jbauchf1f87202016-03-30 06:43:37 -0700135 Buffer* last_stun_buf() { return last_stun_buf_.get(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000136 IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
137 int last_stun_error_code() {
138 int code = 0;
139 if (last_stun_msg_) {
140 const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
141 if (error_attr) {
142 code = error_attr->code();
143 }
144 }
145 return code;
146 }
147
148 virtual void PrepareAddress() {
deadbeef5c3c1042017-08-04 15:01:57 -0700149 // Act as if the socket was bound to the best IP on the network, to the
150 // first port in the allowed range.
151 rtc::SocketAddress addr(Network()->GetBestIP(), min_port());
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700152 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
zhihuang26d99c22017-02-13 12:47:27 -0800153 ICE_TYPE_PREFERENCE_HOST, 0, "", true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 }
155
Honghai Zhangf9945b22015-12-15 12:20:13 -0800156 virtual bool SupportsProtocol(const std::string& protocol) const {
157 return true;
158 }
159
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -0700160 virtual ProtocolType GetProtocol() const { return PROTO_UDP; }
161
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000162 // Exposed for testing candidate building.
163 void AddCandidateAddress(const rtc::SocketAddress& addr) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700164 AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
zhihuang26d99c22017-02-13 12:47:27 -0800165 type_preference_, 0, "", false);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166 }
167 void AddCandidateAddress(const rtc::SocketAddress& addr,
168 const rtc::SocketAddress& base_address,
169 const std::string& type,
170 int type_preference,
171 bool final) {
Guo-wei Shieh3d564c12015-08-19 16:51:15 -0700172 AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
zhihuang26d99c22017-02-13 12:47:27 -0800173 type_preference, 0, "", final);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000174 }
175
176 virtual Connection* CreateConnection(const Candidate& remote_candidate,
177 CandidateOrigin origin) {
178 Connection* conn = new ProxyConnection(this, 0, remote_candidate);
honghaiz36f50e82016-06-01 15:57:03 -0700179 AddOrReplaceConnection(conn);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180 // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
181 // in STUN binding requests.
182 conn->set_use_candidate_attr(true);
183 return conn;
184 }
185 virtual int SendTo(
186 const void* data, size_t size, const rtc::SocketAddress& addr,
187 const rtc::PacketOptions& options, bool payload) {
188 if (!payload) {
189 IceMessage* msg = new IceMessage;
jbauchf1f87202016-03-30 06:43:37 -0700190 Buffer* buf = new Buffer(static_cast<const char*>(data), size);
191 ByteBufferReader read_buf(*buf);
192 if (!msg->Read(&read_buf)) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193 delete msg;
194 delete buf;
195 return -1;
196 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197 last_stun_buf_.reset(buf);
198 last_stun_msg_.reset(msg);
199 }
200 return static_cast<int>(size);
201 }
202 virtual int SetOption(rtc::Socket::Option opt, int value) {
203 return 0;
204 }
205 virtual int GetOption(rtc::Socket::Option opt, int* value) {
206 return -1;
207 }
208 virtual int GetError() {
209 return 0;
210 }
211 void Reset() {
212 last_stun_buf_.reset();
213 last_stun_msg_.reset();
214 }
215 void set_type_preference(int type_preference) {
216 type_preference_ = type_preference;
217 }
218
219 private:
Stefan Holmer55674ff2016-01-14 15:49:16 +0100220 void OnSentPacket(rtc::AsyncPacketSocket* socket,
221 const rtc::SentPacket& sent_packet) {
222 PortInterface::SignalSentPacket(sent_packet);
223 }
kwiberg3ec46792016-04-27 07:22:53 -0700224 std::unique_ptr<Buffer> last_stun_buf_;
225 std::unique_ptr<IceMessage> last_stun_msg_;
pbos7640ffa2015-11-30 09:16:59 -0800226 int type_preference_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227};
228
hbosbf8d3e52017-02-28 06:34:47 -0800229static void SendPingAndReceiveResponse(
230 Connection* lconn, TestPort* lport, Connection* rconn, TestPort* rport,
231 rtc::ScopedFakeClock* clock, int64_t ms) {
232 lconn->Ping(rtc::TimeMillis());
233 ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
234 ASSERT_TRUE(lport->last_stun_buf());
235 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
236 lport->last_stun_buf()->size(),
237 rtc::PacketTime());
238 clock->AdvanceTime(rtc::TimeDelta::FromMilliseconds(ms));
239 ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
240 ASSERT_TRUE(rport->last_stun_buf());
241 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
242 rport->last_stun_buf()->size(),
243 rtc::PacketTime());
244}
245
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000246class TestChannel : public sigslot::has_slots<> {
247 public:
248 // Takes ownership of |p1| (but not |p2|).
Steve Antonbabf9172017-11-29 10:19:02 -0800249 explicit TestChannel(Port* p1)
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700250 : ice_mode_(ICEMODE_FULL),
251 port_(p1),
252 complete_count_(0),
253 conn_(NULL),
254 remote_request_(),
255 nominated_(false) {
256 port_->SignalPortComplete.connect(this, &TestChannel::OnPortComplete);
257 port_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
258 port_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000259 }
260
261 int complete_count() { return complete_count_; }
262 Connection* conn() { return conn_; }
263 const SocketAddress& remote_address() { return remote_address_; }
264 const std::string remote_fragment() { return remote_frag_; }
265
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700266 void Start() { port_->PrepareAddress(); }
267 void CreateConnection(const Candidate& remote_candidate) {
268 conn_ = port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000269 IceMode remote_ice_mode =
270 (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
271 conn_->set_remote_ice_mode(remote_ice_mode);
272 conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
273 conn_->SignalStateChange.connect(
274 this, &TestChannel::OnConnectionStateChange);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700275 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700276 conn_->SignalReadyToSend.connect(this,
277 &TestChannel::OnConnectionReadyToSend);
278 connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 }
280 void OnConnectionStateChange(Connection* conn) {
281 if (conn->write_state() == Connection::STATE_WRITABLE) {
282 conn->set_use_candidate_attr(true);
283 nominated_ = true;
284 }
285 }
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700286 void AcceptConnection(const Candidate& remote_candidate) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000287 ASSERT_TRUE(remote_request_.get() != NULL);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700288 Candidate c = remote_candidate;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000289 c.set_address(remote_address_);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700290 conn_ = port_->CreateConnection(c, Port::ORIGIN_MESSAGE);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700291 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700292 port_->SendBindingResponse(remote_request_.get(), remote_address_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000293 remote_request_.reset();
294 }
295 void Ping() {
296 Ping(0);
297 }
honghaiz34b11eb2016-03-16 08:55:44 -0700298 void Ping(int64_t now) { conn_->Ping(now); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000299 void Stop() {
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700300 if (conn_) {
301 conn_->Destroy();
302 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000303 }
304
305 void OnPortComplete(Port* port) {
306 complete_count_++;
307 }
308 void SetIceMode(IceMode ice_mode) {
309 ice_mode_ = ice_mode;
310 }
311
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700312 int SendData(const char* data, size_t len) {
313 rtc::PacketOptions options;
314 return conn_->Send(data, len, options);
315 }
316
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000317 void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
318 ProtocolType proto,
319 IceMessage* msg, const std::string& rf,
320 bool /*port_muxed*/) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700321 ASSERT_EQ(port_.get(), port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000322 if (!remote_address_.IsNil()) {
323 ASSERT_EQ(remote_address_, addr);
324 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000325 const cricket::StunUInt32Attribute* priority_attr =
326 msg->GetUInt32(STUN_ATTR_PRIORITY);
327 const cricket::StunByteStringAttribute* mi_attr =
328 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
329 const cricket::StunUInt32Attribute* fingerprint_attr =
330 msg->GetUInt32(STUN_ATTR_FINGERPRINT);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700331 EXPECT_TRUE(priority_attr != NULL);
332 EXPECT_TRUE(mi_attr != NULL);
333 EXPECT_TRUE(fingerprint_attr != NULL);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000334 remote_address_ = addr;
335 remote_request_.reset(CopyStunMessage(msg));
336 remote_frag_ = rf;
337 }
338
339 void OnDestroyed(Connection* conn) {
340 ASSERT_EQ(conn_, conn);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100341 RTC_LOG(INFO) << "OnDestroy connection " << conn << " deleted";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000342 conn_ = NULL;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700343 // When the connection is destroyed, also clear these fields so future
344 // connections are possible.
345 remote_request_.reset();
346 remote_address_.Clear();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000347 }
348
349 void OnSrcPortDestroyed(PortInterface* port) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700350 Port* destroyed_src = port_.release();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000351 ASSERT_EQ(destroyed_src, port);
352 }
353
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700354 Port* port() { return port_.get(); }
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700355
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000356 bool nominated() const { return nominated_; }
357
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700358 void set_connection_ready_to_send(bool ready) {
359 connection_ready_to_send_ = ready;
360 }
361 bool connection_ready_to_send() const {
362 return connection_ready_to_send_;
363 }
364
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000365 private:
skvladc309e0e2016-07-28 17:15:20 -0700366 // ReadyToSend will only issue after a Connection recovers from ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700367 void OnConnectionReadyToSend(Connection* conn) {
368 ASSERT_EQ(conn, conn_);
369 connection_ready_to_send_ = true;
370 }
371
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000372 IceMode ice_mode_;
kwiberg3ec46792016-04-27 07:22:53 -0700373 std::unique_ptr<Port> port_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000374
375 int complete_count_;
376 Connection* conn_;
377 SocketAddress remote_address_;
kwiberg3ec46792016-04-27 07:22:53 -0700378 std::unique_ptr<StunMessage> remote_request_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000379 std::string remote_frag_;
380 bool nominated_;
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700381 bool connection_ready_to_send_ = false;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000382};
383
384class PortTest : public testing::Test, public sigslot::has_slots<> {
385 public:
386 PortTest()
deadbeef98e186c2017-05-16 18:00:06 -0700387 : ss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700388 main_(ss_.get()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000389 socket_factory_(rtc::Thread::Current()),
deadbeefc5d0d952015-07-16 10:22:21 -0700390 nat_factory1_(ss_.get(), kNatAddr1, SocketAddress()),
391 nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000392 nat_socket_factory1_(&nat_factory1_),
393 nat_socket_factory2_(&nat_factory2_),
nisse7eaa4ea2017-05-08 05:25:41 -0700394 stun_server_(TestStunServer::Create(&main_, kStunAddr)),
395 turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
396 relay_server_(&main_,
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700397 kRelayUdpIntAddr,
398 kRelayUdpExtAddr,
399 kRelayTcpIntAddr,
400 kRelayTcpExtAddr,
401 kRelaySslTcpIntAddr,
402 kRelaySslTcpExtAddr),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000403 username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
404 password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000405 role_conflict_(false),
Honghai Zhanga74363c2016-07-28 18:06:15 -0700406 ports_destroyed_(0) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000407 }
408
409 protected:
410 void TestLocalToLocal() {
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 = CreateUdpPort(kLocalAddr2);
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, "udp", port2, true, true, true, true);
416 }
417 void TestLocalToStun(NATType ntype) {
418 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700419 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000420 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
421 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700422 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000423 TestConnectivity("udp", port1, StunName(ntype), port2,
424 ntype == NAT_OPEN_CONE, true,
425 ntype != NAT_SYMMETRIC, true);
426 }
427 void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
428 Port* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700429 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000430 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700431 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000432 TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
433 rtype == RELAY_GTURN, true, true, true);
434 }
435 void TestStunToLocal(NATType ntype) {
436 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
437 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700438 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000439 Port* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700440 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000441 TestConnectivity(StunName(ntype), port1, "udp", port2,
442 true, ntype != NAT_SYMMETRIC, true, true);
443 }
444 void TestStunToStun(NATType ntype1, NATType ntype2) {
445 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
446 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700447 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000448 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
449 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700450 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000451 TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
452 ntype2 == NAT_OPEN_CONE,
453 ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
454 ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
455 }
456 void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
457 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
458 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700459 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000460 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700461 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000462 TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
463 rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
464 }
465 void TestTcpToTcp() {
466 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700467 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000468 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700469 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000470 TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
471 }
472 void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
473 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700474 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000475 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700476 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000477 TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
478 rtype == RELAY_GTURN, false, true, true);
479 }
480 void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
481 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700482 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000483 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700484 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000485 TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
486 rtype == RELAY_GTURN, false, true, true);
487 }
deadbeef5c3c1042017-08-04 15:01:57 -0700488
489 rtc::Network* MakeNetwork(const SocketAddress& addr) {
490 networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
491 networks_.back().AddIP(addr.ipaddr());
492 return &networks_.back();
493 }
494
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000495 // helpers for above functions
496 UDPPort* CreateUdpPort(const SocketAddress& addr) {
497 return CreateUdpPort(addr, &socket_factory_);
498 }
499 UDPPort* CreateUdpPort(const SocketAddress& addr,
500 PacketSocketFactory* socket_factory) {
deadbeef5c3c1042017-08-04 15:01:57 -0700501 return UDPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
Qingsi Wang4ff54432018-03-01 18:25:20 -0800502 username_, password_, std::string(), true,
503 rtc::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000504 }
505 TCPPort* CreateTcpPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700506 return CreateTcpPort(addr, &socket_factory_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000507 }
508 TCPPort* CreateTcpPort(const SocketAddress& addr,
509 PacketSocketFactory* socket_factory) {
deadbeef5c3c1042017-08-04 15:01:57 -0700510 return TCPPort::Create(&main_, socket_factory, MakeNetwork(addr), 0, 0,
511 username_, password_, true);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000512 }
513 StunPort* CreateStunPort(const SocketAddress& addr,
514 rtc::PacketSocketFactory* factory) {
515 ServerAddresses stun_servers;
516 stun_servers.insert(kStunAddr);
deadbeef5c3c1042017-08-04 15:01:57 -0700517 return StunPort::Create(&main_, factory, MakeNetwork(addr), 0, 0, username_,
Qingsi Wang4ff54432018-03-01 18:25:20 -0800518 password_, stun_servers, std::string(),
519 rtc::nullopt);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000520 }
521 Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
522 ProtocolType int_proto, ProtocolType ext_proto) {
523 if (rtype == RELAY_TURN) {
524 return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
525 } else {
526 return CreateGturnPort(addr, int_proto, ext_proto);
527 }
528 }
529 TurnPort* CreateTurnPort(const SocketAddress& addr,
530 PacketSocketFactory* socket_factory,
531 ProtocolType int_proto, ProtocolType ext_proto) {
Honghai Zhang80f1db92016-01-27 11:54:45 -0800532 SocketAddress server_addr =
533 int_proto == PROTO_TCP ? kTurnTcpIntAddr : kTurnUdpIntAddr;
534 return CreateTurnPort(addr, socket_factory, int_proto, ext_proto,
535 server_addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000536 }
537 TurnPort* CreateTurnPort(const SocketAddress& addr,
538 PacketSocketFactory* socket_factory,
539 ProtocolType int_proto, ProtocolType ext_proto,
540 const rtc::SocketAddress& server_addr) {
Diogo Real1dca9d52017-08-29 12:18:32 -0700541 return TurnPort::Create(
542 &main_, socket_factory, MakeNetwork(addr), 0, 0, username_, password_,
543 ProtocolAddress(server_addr, int_proto), kRelayCredentials, 0,
Jonas Orelandbdcee282017-10-10 14:01:40 +0200544 std::string(), std::vector<std::string>(), std::vector<std::string>(),
545 nullptr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000546 }
547 RelayPort* CreateGturnPort(const SocketAddress& addr,
548 ProtocolType int_proto, ProtocolType ext_proto) {
549 RelayPort* port = CreateGturnPort(addr);
550 SocketAddress addrs[] =
551 { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
552 port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
553 return port;
554 }
555 RelayPort* CreateGturnPort(const SocketAddress& addr) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700556 // TODO(pthatcher): Remove GTURN.
zhihuang6d0d4bf2016-05-24 10:13:32 -0700557 // Generate a username with length of 16 for Gturn only.
558 std::string username = rtc::CreateRandomString(kGturnUserNameLength);
deadbeef5c3c1042017-08-04 15:01:57 -0700559 return RelayPort::Create(&main_, &socket_factory_, MakeNetwork(addr), 0, 0,
560 username, password_);
Steve Antonbabf9172017-11-29 10:19:02 -0800561 // TODO(?): Add an external address for ext_proto, so that the
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000562 // other side can connect to this port using a non-UDP protocol.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000563 }
564 rtc::NATServer* CreateNatServer(const SocketAddress& addr,
565 rtc::NATType type) {
deadbeefc5d0d952015-07-16 10:22:21 -0700566 return new rtc::NATServer(type, ss_.get(), addr, addr, ss_.get(), addr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000567 }
568 static const char* StunName(NATType type) {
569 switch (type) {
hnsl277b2502016-12-13 05:17:23 -0800570 case NAT_OPEN_CONE:
571 return "stun(open cone)";
572 case NAT_ADDR_RESTRICTED:
573 return "stun(addr restricted)";
574 case NAT_PORT_RESTRICTED:
575 return "stun(port restricted)";
576 case NAT_SYMMETRIC:
577 return "stun(symmetric)";
578 default:
579 return "stun(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000580 }
581 }
582 static const char* RelayName(RelayType type, ProtocolType proto) {
583 if (type == RELAY_TURN) {
584 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800585 case PROTO_UDP:
586 return "turn(udp)";
587 case PROTO_TCP:
588 return "turn(tcp)";
589 case PROTO_SSLTCP:
590 return "turn(ssltcp)";
591 case PROTO_TLS:
592 return "turn(tls)";
593 default:
594 return "turn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000595 }
596 } else {
597 switch (proto) {
hnsl277b2502016-12-13 05:17:23 -0800598 case PROTO_UDP:
599 return "gturn(udp)";
600 case PROTO_TCP:
601 return "gturn(tcp)";
602 case PROTO_SSLTCP:
603 return "gturn(ssltcp)";
604 case PROTO_TLS:
605 return "gturn(tls)";
606 default:
607 return "gturn(?)";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000608 }
609 }
610 }
611
612 void TestCrossFamilyPorts(int type);
613
Peter Thatcherb8b01432015-07-07 16:45:53 -0700614 void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2);
615
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000616 // This does all the work and then deletes |port1| and |port2|.
617 void TestConnectivity(const char* name1, Port* port1,
618 const char* name2, Port* port2,
619 bool accept, bool same_addr1,
620 bool same_addr2, bool possible);
621
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700622 // This connects the provided channels which have already started. |ch1|
623 // should have its Connection created (either through CreateConnection() or
624 // TCP reconnecting mechanism before entering this function.
625 void ConnectStartedChannels(TestChannel* ch1, TestChannel* ch2) {
626 ASSERT_TRUE(ch1->conn());
Honghai Zhang161a5862016-10-20 11:47:02 -0700627 EXPECT_TRUE_WAIT(ch1->conn()->connected(),
628 kDefaultTimeout); // for TCP connect
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700629 ch1->Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700630 WAIT(!ch2->remote_address().IsNil(), kShortTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700631
632 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700633 ch2->AcceptConnection(GetCandidate(ch1->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700634 ch2->Ping();
635 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -0700636 kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700637 }
638
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000639 // This connects and disconnects the provided channels in the same sequence as
640 // TestConnectivity with all options set to |true|. It does not delete either
641 // channel.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700642 void StartConnectAndStopChannels(TestChannel* ch1, TestChannel* ch2) {
643 // Acquire addresses.
644 ch1->Start();
645 ch2->Start();
646
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700647 ch1->CreateConnection(GetCandidate(ch2->port()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700648 ConnectStartedChannels(ch1, ch2);
649
650 // Destroy the connections.
651 ch1->Stop();
652 ch2->Stop();
653 }
654
655 // This disconnects both end's Connection and make sure ch2 ready for new
656 // connection.
657 void DisconnectTcpTestChannels(TestChannel* ch1, TestChannel* ch2) {
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700658 TCPConnection* tcp_conn1 = static_cast<TCPConnection*>(ch1->conn());
659 TCPConnection* tcp_conn2 = static_cast<TCPConnection*>(ch2->conn());
660 ASSERT_TRUE(
661 ss_->CloseTcpConnections(tcp_conn1->socket()->GetLocalAddress(),
662 tcp_conn2->socket()->GetLocalAddress()));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700663
664 // Wait for both OnClose are delivered.
Honghai Zhang161a5862016-10-20 11:47:02 -0700665 EXPECT_TRUE_WAIT(!ch1->conn()->connected(), kDefaultTimeout);
666 EXPECT_TRUE_WAIT(!ch2->conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700667
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700668 // Ensure redundant SignalClose events on TcpConnection won't break tcp
669 // reconnection. Chromium will fire SignalClose for all outstanding IPC
670 // packets during reconnection.
671 tcp_conn1->socket()->SignalClose(tcp_conn1->socket(), 0);
672 tcp_conn2->socket()->SignalClose(tcp_conn2->socket(), 0);
673
674 // Speed up destroying ch2's connection such that the test is ready to
675 // accept a new connection from ch1 before ch1's connection destroys itself.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700676 ch2->conn()->Destroy();
Honghai Zhang161a5862016-10-20 11:47:02 -0700677 EXPECT_TRUE_WAIT(ch2->conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700678 }
679
680 void TestTcpReconnect(bool ping_after_disconnected,
681 bool send_after_disconnected) {
682 Port* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700683 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700684 Port* port2 = CreateTcpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700685 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700686
687 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
688 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
689
690 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700691 TestChannel ch1(port1);
692 TestChannel ch2(port2);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700693 EXPECT_EQ(0, ch1.complete_count());
694 EXPECT_EQ(0, ch2.complete_count());
695
696 ch1.Start();
697 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700698 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
699 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700700
701 // Initial connecting the channel, create connection on channel1.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700702 ch1.CreateConnection(GetCandidate(port2));
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700703 ConnectStartedChannels(&ch1, &ch2);
704
705 // Shorten the timeout period.
Honghai Zhang161a5862016-10-20 11:47:02 -0700706 const int kTcpReconnectTimeout = kDefaultTimeout;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700707 static_cast<TCPConnection*>(ch1.conn())
708 ->set_reconnection_timeout(kTcpReconnectTimeout);
709 static_cast<TCPConnection*>(ch2.conn())
710 ->set_reconnection_timeout(kTcpReconnectTimeout);
711
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700712 EXPECT_FALSE(ch1.connection_ready_to_send());
713 EXPECT_FALSE(ch2.connection_ready_to_send());
714
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700715 // Once connected, disconnect them.
716 DisconnectTcpTestChannels(&ch1, &ch2);
717
718 if (send_after_disconnected || ping_after_disconnected) {
719 if (send_after_disconnected) {
720 // First SendData after disconnect should fail but will trigger
721 // reconnect.
722 EXPECT_EQ(-1, ch1.SendData(data, static_cast<int>(strlen(data))));
723 }
724
725 if (ping_after_disconnected) {
726 // Ping should trigger reconnect.
727 ch1.Ping();
728 }
729
730 // Wait for channel's outgoing TCPConnection connected.
Honghai Zhang161a5862016-10-20 11:47:02 -0700731 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700732
733 // Verify that we could still connect channels.
734 ConnectStartedChannels(&ch1, &ch2);
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700735 EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(),
736 kTcpReconnectTimeout);
737 // Channel2 is the passive one so a new connection is created during
skvladc309e0e2016-07-28 17:15:20 -0700738 // reconnect. This new connection should never have issued ENOTCONN
Guo-wei Shiehb5940412015-08-24 11:58:03 -0700739 // hence the connection_ready_to_send() should be false.
740 EXPECT_FALSE(ch2.connection_ready_to_send());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700741 } else {
742 EXPECT_EQ(ch1.conn()->write_state(), Connection::STATE_WRITABLE);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700743 // Since the reconnection never happens, the connections should have been
744 // destroyed after the timeout.
Honghai Zhang161a5862016-10-20 11:47:02 -0700745 EXPECT_TRUE_WAIT(!ch1.conn(), kTcpReconnectTimeout + kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700746 EXPECT_TRUE(!ch2.conn());
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700747 }
748
749 // Tear down and ensure that goes smoothly.
750 ch1.Stop();
751 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700752 EXPECT_TRUE_WAIT(ch1.conn() == NULL, kDefaultTimeout);
753 EXPECT_TRUE_WAIT(ch2.conn() == NULL, kDefaultTimeout);
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700754 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000755
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000756 IceMessage* CreateStunMessage(int type) {
757 IceMessage* msg = new IceMessage();
758 msg->SetType(type);
759 msg->SetTransactionID("TESTTESTTEST");
760 return msg;
761 }
762 IceMessage* CreateStunMessageWithUsername(int type,
763 const std::string& username) {
764 IceMessage* msg = CreateStunMessage(type);
765 msg->AddAttribute(
zsteinf42cc9d2017-03-27 16:17:19 -0700766 rtc::MakeUnique<StunByteStringAttribute>(STUN_ATTR_USERNAME, username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000767 return msg;
768 }
769 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
770 const std::string& username,
771 const std::string& password) {
deadbeef5c3c1042017-08-04 15:01:57 -0700772 TestPort* port = new TestPort(&main_, "test", &socket_factory_,
773 MakeNetwork(addr), 0, 0, username, password);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000774 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
775 return port;
776 }
777 TestPort* CreateTestPort(const rtc::SocketAddress& addr,
778 const std::string& username,
779 const std::string& password,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000780 cricket::IceRole role,
781 int tiebreaker) {
782 TestPort* port = CreateTestPort(addr, username, password);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000783 port->SetIceRole(role);
784 port->SetIceTiebreaker(tiebreaker);
785 return port;
786 }
deadbeef5c3c1042017-08-04 15:01:57 -0700787 // Overload to create a test port given an rtc::Network directly.
788 TestPort* CreateTestPort(rtc::Network* network,
789 const std::string& username,
790 const std::string& password) {
791 TestPort* port = new TestPort(&main_, "test", &socket_factory_, network, 0,
792 0, username, password);
793 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
794 return port;
795 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000796
797 void OnRoleConflict(PortInterface* port) {
798 role_conflict_ = true;
799 }
800 bool role_conflict() const { return role_conflict_; }
801
802 void ConnectToSignalDestroyed(PortInterface* port) {
803 port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
804 }
805
Honghai Zhanga74363c2016-07-28 18:06:15 -0700806 void OnDestroyed(PortInterface* port) { ++ports_destroyed_; }
807 int ports_destroyed() const { return ports_destroyed_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000808
809 rtc::BasicPacketSocketFactory* nat_socket_factory1() {
810 return &nat_socket_factory1_;
811 }
812
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700813 rtc::VirtualSocketServer* vss() { return ss_.get(); }
814
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000815 private:
deadbeef5c3c1042017-08-04 15:01:57 -0700816 // When a "create port" helper method is called with an IP, we create a
817 // Network with that IP and add it to this list. Using a list instead of a
818 // vector so that when it grows, pointers aren't invalidated.
819 std::list<rtc::Network> networks_;
kwiberg3ec46792016-04-27 07:22:53 -0700820 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700821 rtc::AutoSocketServerThread main_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000822 rtc::BasicPacketSocketFactory socket_factory_;
kwiberg3ec46792016-04-27 07:22:53 -0700823 std::unique_ptr<rtc::NATServer> nat_server1_;
824 std::unique_ptr<rtc::NATServer> nat_server2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000825 rtc::NATSocketFactory nat_factory1_;
826 rtc::NATSocketFactory nat_factory2_;
827 rtc::BasicPacketSocketFactory nat_socket_factory1_;
828 rtc::BasicPacketSocketFactory nat_socket_factory2_;
kwiberg3ec46792016-04-27 07:22:53 -0700829 std::unique_ptr<TestStunServer> stun_server_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000830 TestTurnServer turn_server_;
831 TestRelayServer relay_server_;
832 std::string username_;
833 std::string password_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000834 bool role_conflict_;
Honghai Zhanga74363c2016-07-28 18:06:15 -0700835 int ports_destroyed_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000836};
837
838void PortTest::TestConnectivity(const char* name1, Port* port1,
839 const char* name2, Port* port2,
840 bool accept, bool same_addr1,
841 bool same_addr2, bool possible) {
Honghai Zhang161a5862016-10-20 11:47:02 -0700842 rtc::ScopedFakeClock clock;
Mirko Bonadei675513b2017-11-09 11:09:25 +0100843 RTC_LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000844 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
845 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
846
847 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700848 TestChannel ch1(port1);
849 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000850 EXPECT_EQ(0, ch1.complete_count());
851 EXPECT_EQ(0, ch2.complete_count());
852
853 // Acquire addresses.
854 ch1.Start();
855 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -0700856 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
857 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000858
859 // Send a ping from src to dst. This may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700860 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000861 ASSERT_TRUE(ch1.conn() != NULL);
Honghai Zhang161a5862016-10-20 11:47:02 -0700862 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout,
863 clock); // for TCP connect
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000864 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700865 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000866
867 if (accept) {
868 // We are able to send a ping from src to dst. This is the case when
869 // sending to UDP ports and cone NATs.
870 EXPECT_TRUE(ch1.remote_address().IsNil());
871 EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
872
873 // Ensure the ping came from the same address used for src.
874 // This is the case unless the source NAT was symmetric.
875 if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
876 EXPECT_TRUE(same_addr2);
877
878 // Send a ping from dst to src.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700879 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000880 ASSERT_TRUE(ch2.conn() != NULL);
881 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700882 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
883 ch2.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000884 } else {
885 // We can't send a ping from src to dst, so flip it around. This will happen
886 // when the destination NAT is addr/port restricted or symmetric.
887 EXPECT_TRUE(ch1.remote_address().IsNil());
888 EXPECT_TRUE(ch2.remote_address().IsNil());
889
890 // Send a ping from dst to src. Again, this may or may not make it.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700891 ch2.CreateConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000892 ASSERT_TRUE(ch2.conn() != NULL);
893 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700894 SIMULATED_WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE,
895 kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000896
897 if (same_addr1 && same_addr2) {
898 // The new ping got back to the source.
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700899 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000900 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
901
902 // First connection may not be writable if the first ping did not get
903 // through. So we will have to do another.
904 if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
905 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700906 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
907 ch1.conn()->write_state(), kDefaultTimeout,
908 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000909 }
910 } else if (!same_addr1 && possible) {
911 // The new ping went to the candidate address, but that address was bad.
912 // This will happen when the source NAT is symmetric.
913 EXPECT_TRUE(ch1.remote_address().IsNil());
914 EXPECT_TRUE(ch2.remote_address().IsNil());
915
916 // However, since we have now sent a ping to the source IP, we should be
917 // able to get a ping from it. This gives us the real source address.
918 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700919 EXPECT_TRUE_SIMULATED_WAIT(!ch2.remote_address().IsNil(), kDefaultTimeout,
920 clock);
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700921 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000922 EXPECT_TRUE(ch1.remote_address().IsNil());
923
924 // Pick up the actual address and establish the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700925 ch2.AcceptConnection(GetCandidate(port1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000926 ASSERT_TRUE(ch2.conn() != NULL);
927 ch2.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700928 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
929 ch2.conn()->write_state(), kDefaultTimeout,
930 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000931 } else if (!same_addr2 && possible) {
932 // The new ping came in, but from an unexpected address. This will happen
933 // when the destination NAT is symmetric.
934 EXPECT_FALSE(ch1.remote_address().IsNil());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700935 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000936
937 // Update our address and complete the connection.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -0700938 ch1.AcceptConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000939 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700940 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
941 ch1.conn()->write_state(), kDefaultTimeout,
942 clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000943 } else { // (!possible)
944 // There should be s no way for the pings to reach each other. Check it.
945 EXPECT_TRUE(ch1.remote_address().IsNil());
946 EXPECT_TRUE(ch2.remote_address().IsNil());
947 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -0700948 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000949 EXPECT_TRUE(ch1.remote_address().IsNil());
950 EXPECT_TRUE(ch2.remote_address().IsNil());
951 }
952 }
953
954 // Everything should be good, unless we know the situation is impossible.
955 ASSERT_TRUE(ch1.conn() != NULL);
956 ASSERT_TRUE(ch2.conn() != NULL);
957 if (possible) {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700958 EXPECT_TRUE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000959 EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700960 EXPECT_TRUE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000961 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
962 } else {
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700963 EXPECT_FALSE(ch1.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000964 EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
Peter Thatcher04ac81f2015-09-21 11:48:28 -0700965 EXPECT_FALSE(ch2.conn()->receiving());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000966 EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
967 }
968
969 // Tear down and ensure that goes smoothly.
970 ch1.Stop();
971 ch2.Stop();
Honghai Zhang161a5862016-10-20 11:47:02 -0700972 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn() == NULL, kDefaultTimeout, clock);
973 EXPECT_TRUE_SIMULATED_WAIT(ch2.conn() == NULL, kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000974}
975
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000976class FakePacketSocketFactory : public rtc::PacketSocketFactory {
977 public:
978 FakePacketSocketFactory()
979 : next_udp_socket_(NULL),
980 next_server_tcp_socket_(NULL),
981 next_client_tcp_socket_(NULL) {
982 }
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000983 ~FakePacketSocketFactory() override { }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000984
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000985 AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200986 uint16_t min_port,
987 uint16_t max_port) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000988 EXPECT_TRUE(next_udp_socket_ != NULL);
989 AsyncPacketSocket* result = next_udp_socket_;
990 next_udp_socket_ = NULL;
991 return result;
992 }
993
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000994 AsyncPacketSocket* CreateServerTcpSocket(const SocketAddress& local_address,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200995 uint16_t min_port,
996 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000997 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000998 EXPECT_TRUE(next_server_tcp_socket_ != NULL);
999 AsyncPacketSocket* result = next_server_tcp_socket_;
1000 next_server_tcp_socket_ = NULL;
1001 return result;
1002 }
1003
Steve Antonbabf9172017-11-29 10:19:02 -08001004 // TODO(?): |proxy_info| and |user_agent| should be set
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001005 // per-factory and not when socket is created.
pkasting@chromium.org332331f2014-11-06 20:19:22 +00001006 AsyncPacketSocket* CreateClientTcpSocket(const SocketAddress& local_address,
1007 const SocketAddress& remote_address,
1008 const rtc::ProxyInfo& proxy_info,
1009 const std::string& user_agent,
1010 int opts) override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001011 EXPECT_TRUE(next_client_tcp_socket_ != NULL);
1012 AsyncPacketSocket* result = next_client_tcp_socket_;
1013 next_client_tcp_socket_ = NULL;
1014 return result;
1015 }
1016
1017 void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
1018 next_udp_socket_ = next_udp_socket;
1019 }
1020 void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
1021 next_server_tcp_socket_ = next_server_tcp_socket;
1022 }
1023 void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
1024 next_client_tcp_socket_ = next_client_tcp_socket;
1025 }
nisseef8b61e2016-04-29 06:09:15 -07001026 rtc::AsyncResolverInterface* CreateAsyncResolver() override {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001027 return NULL;
1028 }
1029
1030 private:
1031 AsyncPacketSocket* next_udp_socket_;
1032 AsyncPacketSocket* next_server_tcp_socket_;
1033 AsyncPacketSocket* next_client_tcp_socket_;
1034};
1035
1036class FakeAsyncPacketSocket : public AsyncPacketSocket {
1037 public:
1038 // Returns current local address. Address may be set to NULL if the
1039 // socket is not bound yet (GetState() returns STATE_BINDING).
1040 virtual SocketAddress GetLocalAddress() const {
1041 return SocketAddress();
1042 }
1043
1044 // Returns remote address. Returns zeroes if this is not a client TCP socket.
1045 virtual SocketAddress GetRemoteAddress() const {
1046 return SocketAddress();
1047 }
1048
1049 // Send a packet.
1050 virtual int Send(const void *pv, size_t cb,
1051 const rtc::PacketOptions& options) {
1052 return static_cast<int>(cb);
1053 }
1054 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
1055 const rtc::PacketOptions& options) {
1056 return static_cast<int>(cb);
1057 }
1058 virtual int Close() {
1059 return 0;
1060 }
1061
1062 virtual State GetState() const { return state_; }
1063 virtual int GetOption(Socket::Option opt, int* value) { return 0; }
1064 virtual int SetOption(Socket::Option opt, int value) { return 0; }
1065 virtual int GetError() const { return 0; }
1066 virtual void SetError(int error) { }
1067
1068 void set_state(State state) { state_ = state; }
1069
1070 private:
1071 State state_;
1072};
1073
1074// Local -> XXXX
1075TEST_F(PortTest, TestLocalToLocal) {
1076 TestLocalToLocal();
1077}
1078
1079TEST_F(PortTest, TestLocalToConeNat) {
1080 TestLocalToStun(NAT_OPEN_CONE);
1081}
1082
1083TEST_F(PortTest, TestLocalToARNat) {
1084 TestLocalToStun(NAT_ADDR_RESTRICTED);
1085}
1086
1087TEST_F(PortTest, TestLocalToPRNat) {
1088 TestLocalToStun(NAT_PORT_RESTRICTED);
1089}
1090
1091TEST_F(PortTest, TestLocalToSymNat) {
1092 TestLocalToStun(NAT_SYMMETRIC);
1093}
1094
1095// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
1096TEST_F(PortTest, DISABLED_TestLocalToTurn) {
1097 TestLocalToRelay(RELAY_TURN, PROTO_UDP);
1098}
1099
1100TEST_F(PortTest, TestLocalToGturn) {
1101 TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
1102}
1103
1104TEST_F(PortTest, TestLocalToTcpGturn) {
1105 TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
1106}
1107
1108TEST_F(PortTest, TestLocalToSslTcpGturn) {
1109 TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
1110}
1111
1112// Cone NAT -> XXXX
1113TEST_F(PortTest, TestConeNatToLocal) {
1114 TestStunToLocal(NAT_OPEN_CONE);
1115}
1116
1117TEST_F(PortTest, TestConeNatToConeNat) {
1118 TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
1119}
1120
1121TEST_F(PortTest, TestConeNatToARNat) {
1122 TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
1123}
1124
1125TEST_F(PortTest, TestConeNatToPRNat) {
1126 TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
1127}
1128
1129TEST_F(PortTest, TestConeNatToSymNat) {
1130 TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
1131}
1132
1133TEST_F(PortTest, TestConeNatToTurn) {
1134 TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
1135}
1136
1137TEST_F(PortTest, TestConeNatToGturn) {
1138 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
1139}
1140
1141TEST_F(PortTest, TestConeNatToTcpGturn) {
1142 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
1143}
1144
1145// Address-restricted NAT -> XXXX
1146TEST_F(PortTest, TestARNatToLocal) {
1147 TestStunToLocal(NAT_ADDR_RESTRICTED);
1148}
1149
1150TEST_F(PortTest, TestARNatToConeNat) {
1151 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
1152}
1153
1154TEST_F(PortTest, TestARNatToARNat) {
1155 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
1156}
1157
1158TEST_F(PortTest, TestARNatToPRNat) {
1159 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
1160}
1161
1162TEST_F(PortTest, TestARNatToSymNat) {
1163 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
1164}
1165
1166TEST_F(PortTest, TestARNatToTurn) {
1167 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
1168}
1169
1170TEST_F(PortTest, TestARNatToGturn) {
1171 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1172}
1173
1174TEST_F(PortTest, TestARNATNatToTcpGturn) {
1175 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1176}
1177
1178// Port-restricted NAT -> XXXX
1179TEST_F(PortTest, TestPRNatToLocal) {
1180 TestStunToLocal(NAT_PORT_RESTRICTED);
1181}
1182
1183TEST_F(PortTest, TestPRNatToConeNat) {
1184 TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
1185}
1186
1187TEST_F(PortTest, TestPRNatToARNat) {
1188 TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
1189}
1190
1191TEST_F(PortTest, TestPRNatToPRNat) {
1192 TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
1193}
1194
1195TEST_F(PortTest, TestPRNatToSymNat) {
1196 // Will "fail"
1197 TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1198}
1199
1200TEST_F(PortTest, TestPRNatToTurn) {
1201 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
1202}
1203
1204TEST_F(PortTest, TestPRNatToGturn) {
1205 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1206}
1207
1208TEST_F(PortTest, TestPRNatToTcpGturn) {
1209 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1210}
1211
1212// Symmetric NAT -> XXXX
1213TEST_F(PortTest, TestSymNatToLocal) {
1214 TestStunToLocal(NAT_SYMMETRIC);
1215}
1216
1217TEST_F(PortTest, TestSymNatToConeNat) {
1218 TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1219}
1220
1221TEST_F(PortTest, TestSymNatToARNat) {
1222 TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1223}
1224
1225TEST_F(PortTest, TestSymNatToPRNat) {
1226 // Will "fail"
1227 TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1228}
1229
1230TEST_F(PortTest, TestSymNatToSymNat) {
1231 // Will "fail"
1232 TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1233}
1234
1235TEST_F(PortTest, TestSymNatToTurn) {
1236 TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1237}
1238
1239TEST_F(PortTest, TestSymNatToGturn) {
1240 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1241}
1242
1243TEST_F(PortTest, TestSymNatToTcpGturn) {
1244 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1245}
1246
1247// Outbound TCP -> XXXX
1248TEST_F(PortTest, TestTcpToTcp) {
1249 TestTcpToTcp();
1250}
1251
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07001252TEST_F(PortTest, TestTcpReconnectOnSendPacket) {
1253 TestTcpReconnect(false /* ping */, true /* send */);
1254}
1255
1256TEST_F(PortTest, TestTcpReconnectOnPing) {
1257 TestTcpReconnect(true /* ping */, false /* send */);
1258}
1259
1260TEST_F(PortTest, TestTcpReconnectTimeout) {
1261 TestTcpReconnect(false /* ping */, false /* send */);
1262}
1263
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001264// Test when TcpConnection never connects, the OnClose() will be called to
1265// destroy the connection.
1266TEST_F(PortTest, TestTcpNeverConnect) {
1267 Port* port1 = CreateTcpPort(kLocalAddr1);
1268 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1269 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
1270
1271 // Set up a channel and ensure the port will be deleted.
1272 TestChannel ch1(port1);
1273 EXPECT_EQ(0, ch1.complete_count());
1274
1275 ch1.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001276 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001277
kwiberg3ec46792016-04-27 07:22:53 -07001278 std::unique_ptr<rtc::AsyncSocket> server(
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001279 vss()->CreateAsyncSocket(kLocalAddr2.family(), SOCK_STREAM));
1280 // Bind but not listen.
1281 EXPECT_EQ(0, server->Bind(kLocalAddr2));
1282
1283 Candidate c = GetCandidate(port1);
1284 c.set_address(server->GetLocalAddress());
1285
1286 ch1.CreateConnection(c);
1287 EXPECT_TRUE(ch1.conn());
Honghai Zhang161a5862016-10-20 11:47:02 -07001288 EXPECT_TRUE_WAIT(!ch1.conn(), kDefaultTimeout); // for TCP connect
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07001289}
1290
Steve Antonbabf9172017-11-29 10:19:02 -08001291/* TODO(?): Enable these once testrelayserver can accept external TCP.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001292TEST_F(PortTest, TestTcpToTcpRelay) {
1293 TestTcpToRelay(PROTO_TCP);
1294}
1295
1296TEST_F(PortTest, TestTcpToSslTcpRelay) {
1297 TestTcpToRelay(PROTO_SSLTCP);
1298}
1299*/
1300
1301// Outbound SSLTCP -> XXXX
Steve Antonbabf9172017-11-29 10:19:02 -08001302/* TODO(?): Enable these once testrelayserver can accept external SSL.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001303TEST_F(PortTest, TestSslTcpToTcpRelay) {
1304 TestSslTcpToRelay(PROTO_TCP);
1305}
1306
1307TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1308 TestSslTcpToRelay(PROTO_SSLTCP);
1309}
1310*/
1311
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001312// Test that a connection will be dead and deleted if
1313// i) it has never received anything for MIN_CONNECTION_LIFETIME milliseconds
1314// since it was created, or
1315// ii) it has not received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT
1316// milliseconds since last receiving.
1317TEST_F(PortTest, TestConnectionDead) {
1318 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1319 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1320 TestChannel ch1(port1);
1321 TestChannel ch2(port2);
1322 // Acquire address.
1323 ch1.Start();
1324 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07001325 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
1326 ASSERT_EQ_WAIT(1, ch2.complete_count(), kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001327
honghaiz37389b42016-01-04 21:57:33 -08001328 // Test case that the connection has never received anything.
nisse1bffc1d2016-05-02 08:18:55 -07001329 int64_t before_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001330 ch1.CreateConnection(GetCandidate(port2));
nisse1bffc1d2016-05-02 08:18:55 -07001331 int64_t after_created = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001332 Connection* conn = ch1.conn();
nissec8ee8822017-01-18 07:20:55 -08001333 ASSERT_NE(conn, nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001334 // It is not dead if it is after MIN_CONNECTION_LIFETIME but not pruned.
1335 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
1336 rtc::Thread::Current()->ProcessMessages(0);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001337 EXPECT_TRUE(ch1.conn() != nullptr);
honghaiz37389b42016-01-04 21:57:33 -08001338 // It is not dead if it is before MIN_CONNECTION_LIFETIME and pruned.
1339 conn->UpdateState(before_created + MIN_CONNECTION_LIFETIME - 1);
1340 conn->Prune();
1341 rtc::Thread::Current()->ProcessMessages(0);
1342 EXPECT_TRUE(ch1.conn() != nullptr);
1343 // It will be dead after MIN_CONNECTION_LIFETIME and pruned.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001344 conn->UpdateState(after_created + MIN_CONNECTION_LIFETIME + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001345 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001346
honghaiz37389b42016-01-04 21:57:33 -08001347 // Test case that the connection has received something.
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001348 // Create a connection again and receive a ping.
1349 ch1.CreateConnection(GetCandidate(port2));
1350 conn = ch1.conn();
nissec8ee8822017-01-18 07:20:55 -08001351 ASSERT_NE(conn, nullptr);
nisse1bffc1d2016-05-02 08:18:55 -07001352 int64_t before_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001353 conn->ReceivedPing();
nisse1bffc1d2016-05-02 08:18:55 -07001354 int64_t after_last_receiving = rtc::TimeMillis();
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001355 // The connection will be dead after DEAD_CONNECTION_RECEIVE_TIMEOUT
1356 conn->UpdateState(
1357 before_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT - 1);
1358 rtc::Thread::Current()->ProcessMessages(100);
1359 EXPECT_TRUE(ch1.conn() != nullptr);
1360 conn->UpdateState(after_last_receiving + DEAD_CONNECTION_RECEIVE_TIMEOUT + 1);
Honghai Zhang161a5862016-10-20 11:47:02 -07001361 EXPECT_TRUE_WAIT(ch1.conn() == nullptr, kDefaultTimeout);
Honghai Zhang2cd7afe2015-11-12 11:14:33 -08001362}
1363
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001364// This test case verifies standard ICE features in STUN messages. Currently it
1365// verifies Message Integrity attribute in STUN messages and username in STUN
1366// binding request will have colon (":") between remote and local username.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001367TEST_F(PortTest, TestLocalToLocalStandard) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001368 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1369 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1370 port1->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001371 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1372 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1373 port2->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001374 // Same parameters as TestLocalToLocal above.
1375 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1376}
1377
1378// This test is trying to validate a successful and failure scenario in a
1379// loopback test when protocol is RFC5245. For success IceTiebreaker, username
1380// should remain equal to the request generated by the port and role of port
1381// must be in controlling.
Honghai Zhang161a5862016-10-20 11:47:02 -07001382TEST_F(PortTest, TestLoopbackCall) {
kwiberg3ec46792016-04-27 07:22:53 -07001383 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001384 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001385 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1386 lport->SetIceTiebreaker(kTiebreaker1);
1387 lport->PrepareAddress();
1388 ASSERT_FALSE(lport->Candidates().empty());
1389 Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1390 Port::ORIGIN_MESSAGE);
1391 conn->Ping(0);
1392
Honghai Zhang161a5862016-10-20 11:47:02 -07001393 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001394 IceMessage* msg = lport->last_stun_msg();
1395 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
jbauchf1f87202016-03-30 06:43:37 -07001396 conn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1397 lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001398 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001399 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001400 msg = lport->last_stun_msg();
1401 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1402
1403 // If the tiebreaker value is different from port, we expect a error
1404 // response.
1405 lport->Reset();
1406 lport->AddCandidateAddress(kLocalAddr2);
Peter Thatcher04ac81f2015-09-21 11:48:28 -07001407 // Creating a different connection as |conn| is receiving.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001408 Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1409 Port::ORIGIN_MESSAGE);
1410 conn1->Ping(0);
1411
Honghai Zhang161a5862016-10-20 11:47:02 -07001412 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001413 msg = lport->last_stun_msg();
1414 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
kwiberg3ec46792016-04-27 07:22:53 -07001415 std::unique_ptr<IceMessage> modified_req(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001416 CreateStunMessage(STUN_BINDING_REQUEST));
1417 const StunByteStringAttribute* username_attr = msg->GetByteString(
1418 STUN_ATTR_USERNAME);
zsteinf42cc9d2017-03-27 16:17:19 -07001419 modified_req->AddAttribute(rtc::MakeUnique<StunByteStringAttribute>(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001420 STUN_ATTR_USERNAME, username_attr->GetString()));
1421 // To make sure we receive error response, adding tiebreaker less than
1422 // what's present in request.
zsteinf42cc9d2017-03-27 16:17:19 -07001423 modified_req->AddAttribute(rtc::MakeUnique<StunUInt64Attribute>(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001424 STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1425 modified_req->AddMessageIntegrity("lpass");
1426 modified_req->AddFingerprint();
1427
1428 lport->Reset();
kwiberg3ec46792016-04-27 07:22:53 -07001429 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001430 WriteStunMessage(modified_req.get(), buf.get());
1431 conn1->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07001432 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001433 msg = lport->last_stun_msg();
1434 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1435}
1436
1437// This test verifies role conflict signal is received when there is
1438// conflict in the role. In this case both ports are in controlling and
1439// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1440// value of tiebreaker, when it receives ping request from |rport| it will
1441// send role conflict signal.
1442TEST_F(PortTest, TestIceRoleConflict) {
kwiberg3ec46792016-04-27 07:22:53 -07001443 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001444 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001445 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1446 lport->SetIceTiebreaker(kTiebreaker1);
kwiberg3ec46792016-04-27 07:22:53 -07001447 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001448 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001449 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1450 rport->SetIceTiebreaker(kTiebreaker2);
1451
1452 lport->PrepareAddress();
1453 rport->PrepareAddress();
1454 ASSERT_FALSE(lport->Candidates().empty());
1455 ASSERT_FALSE(rport->Candidates().empty());
1456 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1457 Port::ORIGIN_MESSAGE);
1458 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1459 Port::ORIGIN_MESSAGE);
1460 rconn->Ping(0);
1461
Honghai Zhang161a5862016-10-20 11:47:02 -07001462 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001463 IceMessage* msg = rport->last_stun_msg();
1464 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1465 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07001466 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1467 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001468 rtc::PacketTime());
1469
Honghai Zhang161a5862016-10-20 11:47:02 -07001470 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001471 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1472 EXPECT_TRUE(role_conflict());
1473}
1474
1475TEST_F(PortTest, TestTcpNoDelay) {
1476 TCPPort* port1 = CreateTcpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001477 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001478 int option_value = -1;
1479 int success = port1->GetOption(rtc::Socket::OPT_NODELAY,
1480 &option_value);
1481 ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1482 ASSERT_EQ(1, option_value);
1483 delete port1;
1484}
1485
1486TEST_F(PortTest, TestDelayedBindingUdp) {
1487 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1488 FakePacketSocketFactory socket_factory;
1489
1490 socket_factory.set_next_udp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001491 std::unique_ptr<UDPPort> port(CreateUdpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001492
1493 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1494 port->PrepareAddress();
1495
1496 EXPECT_EQ(0U, port->Candidates().size());
1497 socket->SignalAddressReady(socket, kLocalAddr2);
1498
1499 EXPECT_EQ(1U, port->Candidates().size());
1500}
1501
1502TEST_F(PortTest, TestDelayedBindingTcp) {
1503 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1504 FakePacketSocketFactory socket_factory;
1505
1506 socket_factory.set_next_server_tcp_socket(socket);
kwiberg3ec46792016-04-27 07:22:53 -07001507 std::unique_ptr<TCPPort> port(CreateTcpPort(kLocalAddr1, &socket_factory));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001508
1509 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1510 port->PrepareAddress();
1511
1512 EXPECT_EQ(0U, port->Candidates().size());
1513 socket->SignalAddressReady(socket, kLocalAddr2);
1514
1515 EXPECT_EQ(1U, port->Candidates().size());
1516}
1517
1518void PortTest::TestCrossFamilyPorts(int type) {
1519 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001520 std::unique_ptr<Port> ports[4];
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001521 SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1522 SocketAddress("192.168.1.4", 0),
1523 SocketAddress("2001:db8::1", 0),
1524 SocketAddress("2001:db8::2", 0)};
1525 for (int i = 0; i < 4; i++) {
1526 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1527 if (type == SOCK_DGRAM) {
1528 factory.set_next_udp_socket(socket);
1529 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1530 } else if (type == SOCK_STREAM) {
1531 factory.set_next_server_tcp_socket(socket);
1532 ports[i].reset(CreateTcpPort(addresses[i], &factory));
1533 }
1534 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1535 socket->SignalAddressReady(socket, addresses[i]);
1536 ports[i]->PrepareAddress();
1537 }
1538
1539 // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1540 if (type == SOCK_STREAM) {
1541 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1542 factory.set_next_client_tcp_socket(clientsocket);
1543 }
1544 Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1545 Port::ORIGIN_MESSAGE);
1546 EXPECT_TRUE(NULL == c);
1547 EXPECT_EQ(0U, ports[0]->connections().size());
1548 c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1549 Port::ORIGIN_MESSAGE);
1550 EXPECT_FALSE(NULL == c);
1551 EXPECT_EQ(1U, ports[0]->connections().size());
1552
1553 // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1554 if (type == SOCK_STREAM) {
1555 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1556 factory.set_next_client_tcp_socket(clientsocket);
1557 }
1558 c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1559 Port::ORIGIN_MESSAGE);
1560 EXPECT_TRUE(NULL == c);
1561 EXPECT_EQ(0U, ports[2]->connections().size());
1562 c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1563 Port::ORIGIN_MESSAGE);
1564 EXPECT_FALSE(NULL == c);
1565 EXPECT_EQ(1U, ports[2]->connections().size());
1566}
1567
1568TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1569 TestCrossFamilyPorts(SOCK_STREAM);
1570}
1571
1572TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1573 TestCrossFamilyPorts(SOCK_DGRAM);
1574}
1575
Peter Thatcherb8b01432015-07-07 16:45:53 -07001576void PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) {
1577 Connection* c = p1->CreateConnection(GetCandidate(p2),
1578 Port::ORIGIN_MESSAGE);
1579 if (can_connect) {
1580 EXPECT_FALSE(NULL == c);
1581 EXPECT_EQ(1U, p1->connections().size());
1582 } else {
1583 EXPECT_TRUE(NULL == c);
1584 EXPECT_EQ(0U, p1->connections().size());
1585 }
1586}
1587
1588TEST_F(PortTest, TestUdpV6CrossTypePorts) {
1589 FakePacketSocketFactory factory;
kwiberg3ec46792016-04-27 07:22:53 -07001590 std::unique_ptr<Port> ports[4];
Peter Thatcherb8b01432015-07-07 16:45:53 -07001591 SocketAddress addresses[4] = {SocketAddress("2001:db8::1", 0),
1592 SocketAddress("fe80::1", 0),
1593 SocketAddress("fe80::2", 0),
1594 SocketAddress("::1", 0)};
1595 for (int i = 0; i < 4; i++) {
1596 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1597 factory.set_next_udp_socket(socket);
1598 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1599 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1600 socket->SignalAddressReady(socket, addresses[i]);
1601 ports[i]->PrepareAddress();
1602 }
1603
1604 Port* standard = ports[0].get();
1605 Port* link_local1 = ports[1].get();
1606 Port* link_local2 = ports[2].get();
1607 Port* localhost = ports[3].get();
1608
1609 ExpectPortsCanConnect(false, link_local1, standard);
1610 ExpectPortsCanConnect(false, standard, link_local1);
1611 ExpectPortsCanConnect(false, link_local1, localhost);
1612 ExpectPortsCanConnect(false, localhost, link_local1);
1613
1614 ExpectPortsCanConnect(true, link_local1, link_local2);
1615 ExpectPortsCanConnect(true, localhost, standard);
1616 ExpectPortsCanConnect(true, standard, localhost);
1617}
1618
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001619// This test verifies DSCP value set through SetOption interface can be
1620// get through DefaultDscpValue.
1621TEST_F(PortTest, TestDefaultDscpValue) {
1622 int dscp;
kwiberg3ec46792016-04-27 07:22:53 -07001623 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001624 EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP,
1625 rtc::DSCP_CS6));
1626 EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
kwiberg3ec46792016-04-27 07:22:53 -07001627 std::unique_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001628 EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP,
1629 rtc::DSCP_AF31));
1630 EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1631 EXPECT_EQ(rtc::DSCP_AF31, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001632 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001633 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
1634 EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP,
1635 rtc::DSCP_AF41));
1636 EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1637 EXPECT_EQ(rtc::DSCP_AF41, dscp);
kwiberg3ec46792016-04-27 07:22:53 -07001638 std::unique_ptr<TurnPort> turnport1(
1639 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001640 // Socket is created in PrepareAddress.
1641 turnport1->PrepareAddress();
1642 EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP,
1643 rtc::DSCP_CS7));
1644 EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1645 EXPECT_EQ(rtc::DSCP_CS7, dscp);
1646 // This will verify correct value returned without the socket.
kwiberg3ec46792016-04-27 07:22:53 -07001647 std::unique_ptr<TurnPort> turnport2(
1648 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001649 EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP,
1650 rtc::DSCP_CS6));
1651 EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1652 EXPECT_EQ(rtc::DSCP_CS6, dscp);
1653}
1654
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001655// Test sending STUN messages.
1656TEST_F(PortTest, TestSendStunMessage) {
kwiberg3ec46792016-04-27 07:22:53 -07001657 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001658 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001659 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001660 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001661 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1662 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001663 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1664 rport->SetIceTiebreaker(kTiebreaker2);
1665
1666 // Send a fake ping from lport to rport.
1667 lport->PrepareAddress();
1668 rport->PrepareAddress();
1669 ASSERT_FALSE(rport->Candidates().empty());
1670 Connection* lconn = lport->CreateConnection(
1671 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1672 Connection* rconn = rport->CreateConnection(
1673 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1674 lconn->Ping(0);
1675
1676 // Check that it's a proper BINDING-REQUEST.
Honghai Zhang161a5862016-10-20 11:47:02 -07001677 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001678 IceMessage* msg = lport->last_stun_msg();
1679 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1680 EXPECT_FALSE(msg->IsLegacy());
1681 const StunByteStringAttribute* username_attr =
1682 msg->GetByteString(STUN_ATTR_USERNAME);
1683 ASSERT_TRUE(username_attr != NULL);
1684 const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1685 ASSERT_TRUE(priority_attr != NULL);
1686 EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1687 EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1688 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1689 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001690 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001691 "rpass"));
1692 const StunUInt64Attribute* ice_controlling_attr =
1693 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1694 ASSERT_TRUE(ice_controlling_attr != NULL);
1695 EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
1696 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1697 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1698 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1699 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001700 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001701
1702 // Request should not include ping count.
1703 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1704
1705 // Save a copy of the BINDING-REQUEST for use below.
kwiberg3ec46792016-04-27 07:22:53 -07001706 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001707
zhihuang5ecf16c2016-06-01 17:09:15 -07001708 // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE.
1709 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1710 lport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001711 msg = rport->last_stun_msg();
1712 ASSERT_TRUE(msg != NULL);
1713 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
zhihuang5ecf16c2016-06-01 17:09:15 -07001714 // Received a BINDING-RESPONSE.
1715 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1716 rport->last_stun_buf()->size(), rtc::PacketTime());
1717 // Verify the STUN Stats.
1718 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total);
1719 EXPECT_EQ(1U, lconn->stats().sent_ping_requests_before_first_response);
1720 EXPECT_EQ(1U, lconn->stats().recv_ping_responses);
1721 EXPECT_EQ(1U, rconn->stats().recv_ping_requests);
1722 EXPECT_EQ(1U, rconn->stats().sent_ping_responses);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001723
1724 EXPECT_FALSE(msg->IsLegacy());
1725 const StunAddressAttribute* addr_attr = msg->GetAddress(
1726 STUN_ATTR_XOR_MAPPED_ADDRESS);
1727 ASSERT_TRUE(addr_attr != NULL);
1728 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1729 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1730 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001731 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001732 "rpass"));
1733 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1734 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001735 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001736 // No USERNAME or PRIORITY in ICE responses.
1737 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1738 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1739 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1740 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1741 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1742 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1743
1744 // Response should not include ping count.
1745 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1746
1747 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1748 // but we can do it here.
1749 rport->SendBindingErrorResponse(request.get(),
1750 lport->Candidates()[0].address(),
1751 STUN_ERROR_SERVER_ERROR,
1752 STUN_ERROR_REASON_SERVER_ERROR);
1753 msg = rport->last_stun_msg();
1754 ASSERT_TRUE(msg != NULL);
1755 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1756 EXPECT_FALSE(msg->IsLegacy());
1757 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1758 ASSERT_TRUE(error_attr != NULL);
1759 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1760 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1761 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1762 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
jbauchf1f87202016-03-30 06:43:37 -07001763 rport->last_stun_buf()->data<char>(), rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001764 "rpass"));
1765 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1766 EXPECT_TRUE(StunMessage::ValidateFingerprint(
jbauchf1f87202016-03-30 06:43:37 -07001767 lport->last_stun_buf()->data<char>(), lport->last_stun_buf()->size()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001768 // No USERNAME with ICE.
1769 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1770 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1771
1772 // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1773 // and (incremented) RETRANSMIT_COUNT attributes.
1774 rport->Reset();
1775 rport->set_send_retransmit_count_attribute(true);
1776 rconn->Ping(0);
1777 rconn->Ping(0);
1778 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001779 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001780 msg = rport->last_stun_msg();
1781 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1782 const StunUInt64Attribute* ice_controlled_attr =
1783 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1784 ASSERT_TRUE(ice_controlled_attr != NULL);
1785 EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
1786 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1787
1788 // Request should include ping count.
1789 const StunUInt32Attribute* retransmit_attr =
1790 msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1791 ASSERT_TRUE(retransmit_attr != NULL);
1792 EXPECT_EQ(2U, retransmit_attr->value());
1793
1794 // Respond with a BINDING-RESPONSE.
1795 request.reset(CopyStunMessage(msg));
zhihuang5ecf16c2016-06-01 17:09:15 -07001796 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1797 rport->last_stun_buf()->size(), rtc::PacketTime());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001798 msg = lport->last_stun_msg();
zhihuang5ecf16c2016-06-01 17:09:15 -07001799 // Receive the BINDING-RESPONSE.
1800 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1801 lport->last_stun_buf()->size(), rtc::PacketTime());
1802
1803 // Verify the Stun ping stats.
1804 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total);
1805 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
1806 EXPECT_EQ(1U, rconn->stats().recv_ping_responses);
1807 EXPECT_EQ(1U, lconn->stats().sent_ping_responses);
1808 EXPECT_EQ(1U, lconn->stats().recv_ping_requests);
1809 // Ping after receiver the first response
1810 rconn->Ping(0);
1811 rconn->Ping(0);
1812 EXPECT_EQ(5U, rconn->stats().sent_ping_requests_total);
1813 EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001814
1815 // Response should include same ping count.
1816 retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1817 ASSERT_TRUE(retransmit_attr != NULL);
1818 EXPECT_EQ(2U, retransmit_attr->value());
1819}
1820
hbos92eaec62017-02-27 01:38:08 -08001821TEST_F(PortTest, TestNomination) {
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
1831 lport->PrepareAddress();
1832 rport->PrepareAddress();
1833 ASSERT_FALSE(lport->Candidates().empty());
1834 ASSERT_FALSE(rport->Candidates().empty());
1835 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1836 Port::ORIGIN_MESSAGE);
1837 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1838 Port::ORIGIN_MESSAGE);
1839
1840 // |lconn| is controlling, |rconn| is controlled.
1841 uint32_t nomination = 1234;
1842 lconn->set_nomination(nomination);
1843
1844 EXPECT_FALSE(lconn->nominated());
1845 EXPECT_FALSE(rconn->nominated());
1846 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1847 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1848
1849 // Send ping (including the nomination value) from |lconn| to |rconn|. This
1850 // should set the remote nomination of |rconn|.
1851 lconn->Ping(0);
1852 ASSERT_TRUE_WAIT(lport->last_stun_msg(), kDefaultTimeout);
1853 ASSERT_TRUE(lport->last_stun_buf());
1854 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
1855 lport->last_stun_buf()->size(),
1856 rtc::PacketTime());
1857 EXPECT_EQ(nomination, rconn->remote_nomination());
1858 EXPECT_FALSE(lconn->nominated());
1859 EXPECT_TRUE(rconn->nominated());
1860 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1861 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1862
1863 // This should result in an acknowledgment sent back from |rconn| to |lconn|,
1864 // updating the acknowledged nomination of |lconn|.
1865 ASSERT_TRUE_WAIT(rport->last_stun_msg(), kDefaultTimeout);
1866 ASSERT_TRUE(rport->last_stun_buf());
1867 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
1868 rport->last_stun_buf()->size(),
1869 rtc::PacketTime());
1870 EXPECT_EQ(nomination, lconn->acked_nomination());
1871 EXPECT_TRUE(lconn->nominated());
1872 EXPECT_TRUE(rconn->nominated());
1873 EXPECT_EQ(lconn->nominated(), lconn->stats().nominated);
1874 EXPECT_EQ(rconn->nominated(), rconn->stats().nominated);
1875}
1876
hbosbf8d3e52017-02-28 06:34:47 -08001877TEST_F(PortTest, TestRoundTripTime) {
1878 rtc::ScopedFakeClock clock;
1879
1880 std::unique_ptr<TestPort> lport(
1881 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1882 std::unique_ptr<TestPort> rport(
1883 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1884 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1885 lport->SetIceTiebreaker(kTiebreaker1);
1886 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1887 rport->SetIceTiebreaker(kTiebreaker2);
1888
1889 lport->PrepareAddress();
1890 rport->PrepareAddress();
1891 ASSERT_FALSE(lport->Candidates().empty());
1892 ASSERT_FALSE(rport->Candidates().empty());
1893 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1894 Port::ORIGIN_MESSAGE);
1895 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1896 Port::ORIGIN_MESSAGE);
1897
1898 EXPECT_EQ(0u, lconn->stats().total_round_trip_time_ms);
1899 EXPECT_FALSE(lconn->stats().current_round_trip_time_ms);
1900
1901 SendPingAndReceiveResponse(
1902 lconn, lport.get(), rconn, rport.get(), &clock, 10);
1903 EXPECT_EQ(10u, lconn->stats().total_round_trip_time_ms);
1904 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1905 EXPECT_EQ(10u, *lconn->stats().current_round_trip_time_ms);
1906
1907 SendPingAndReceiveResponse(
1908 lconn, lport.get(), rconn, rport.get(), &clock, 20);
1909 EXPECT_EQ(30u, lconn->stats().total_round_trip_time_ms);
1910 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1911 EXPECT_EQ(20u, *lconn->stats().current_round_trip_time_ms);
1912
1913 SendPingAndReceiveResponse(
1914 lconn, lport.get(), rconn, rport.get(), &clock, 30);
1915 EXPECT_EQ(60u, lconn->stats().total_round_trip_time_ms);
1916 ASSERT_TRUE(lconn->stats().current_round_trip_time_ms);
1917 EXPECT_EQ(30u, *lconn->stats().current_round_trip_time_ms);
1918}
1919
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001920TEST_F(PortTest, TestUseCandidateAttribute) {
kwiberg3ec46792016-04-27 07:22:53 -07001921 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001922 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07001923 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001924 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001925 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1926 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001927 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1928 rport->SetIceTiebreaker(kTiebreaker2);
1929
1930 // Send a fake ping from lport to rport.
1931 lport->PrepareAddress();
1932 rport->PrepareAddress();
1933 ASSERT_FALSE(rport->Candidates().empty());
1934 Connection* lconn = lport->CreateConnection(
1935 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1936 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07001937 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001938 IceMessage* msg = lport->last_stun_msg();
1939 const StunUInt64Attribute* ice_controlling_attr =
1940 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1941 ASSERT_TRUE(ice_controlling_attr != NULL);
1942 const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1943 STUN_ATTR_USE_CANDIDATE);
1944 ASSERT_TRUE(use_candidate_attr != NULL);
1945}
1946
Honghai Zhang351d77b2016-05-20 15:08:29 -07001947// Tests that when the network type changes, the network cost of the port will
1948// change, the network cost of the local candidates will change. Also tests that
1949// the remote network costs are updated with the stun binding requests.
1950TEST_F(PortTest, TestNetworkCostChange) {
deadbeef5c3c1042017-08-04 15:01:57 -07001951 rtc::Network* test_network = MakeNetwork(kLocalAddr1);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001952 std::unique_ptr<TestPort> lport(
deadbeef5c3c1042017-08-04 15:01:57 -07001953 CreateTestPort(test_network, "lfrag", "lpass"));
Honghai Zhang351d77b2016-05-20 15:08:29 -07001954 std::unique_ptr<TestPort> rport(
deadbeef5c3c1042017-08-04 15:01:57 -07001955 CreateTestPort(test_network, "rfrag", "rpass"));
Honghai Zhang351d77b2016-05-20 15:08:29 -07001956 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1957 lport->SetIceTiebreaker(kTiebreaker1);
1958 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1959 rport->SetIceTiebreaker(kTiebreaker2);
1960 lport->PrepareAddress();
1961 rport->PrepareAddress();
1962
1963 // Default local port cost is rtc::kNetworkCostUnknown.
1964 EXPECT_EQ(rtc::kNetworkCostUnknown, lport->network_cost());
1965 ASSERT_TRUE(!lport->Candidates().empty());
1966 for (const cricket::Candidate& candidate : lport->Candidates()) {
1967 EXPECT_EQ(rtc::kNetworkCostUnknown, candidate.network_cost());
1968 }
1969
1970 // Change the network type to wifi.
deadbeef5c3c1042017-08-04 15:01:57 -07001971 test_network->set_type(rtc::ADAPTER_TYPE_WIFI);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001972 EXPECT_EQ(rtc::kNetworkCostLow, lport->network_cost());
1973 for (const cricket::Candidate& candidate : lport->Candidates()) {
1974 EXPECT_EQ(rtc::kNetworkCostLow, candidate.network_cost());
1975 }
1976
1977 // Add a connection and then change the network type.
1978 Connection* lconn =
1979 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1980 // Change the network type to cellular.
deadbeef5c3c1042017-08-04 15:01:57 -07001981 test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001982 EXPECT_EQ(rtc::kNetworkCostHigh, lport->network_cost());
1983 for (const cricket::Candidate& candidate : lport->Candidates()) {
1984 EXPECT_EQ(rtc::kNetworkCostHigh, candidate.network_cost());
1985 }
1986
deadbeef5c3c1042017-08-04 15:01:57 -07001987 test_network->set_type(rtc::ADAPTER_TYPE_WIFI);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001988 Connection* rconn =
1989 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
deadbeef5c3c1042017-08-04 15:01:57 -07001990 test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001991 lconn->Ping(0);
1992 // The rconn's remote candidate cost is rtc::kNetworkCostLow, but the ping
1993 // contains an attribute of network cost of rtc::kNetworkCostHigh. Once the
1994 // message is handled in rconn, The rconn's remote candidate will have cost
1995 // rtc::kNetworkCostHigh;
1996 EXPECT_EQ(rtc::kNetworkCostLow, rconn->remote_candidate().network_cost());
Honghai Zhang161a5862016-10-20 11:47:02 -07001997 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07001998 IceMessage* msg = lport->last_stun_msg();
1999 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2000 // Pass the binding request to rport.
2001 rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
2002 lport->last_stun_buf()->size(), rtc::PacketTime());
2003 // Wait until rport sends the response and then check the remote network cost.
Honghai Zhang161a5862016-10-20 11:47:02 -07002004 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
Honghai Zhang351d77b2016-05-20 15:08:29 -07002005 EXPECT_EQ(rtc::kNetworkCostHigh, rconn->remote_candidate().network_cost());
2006}
2007
honghaiza0c44ea2016-03-23 16:07:48 -07002008TEST_F(PortTest, TestNetworkInfoAttribute) {
deadbeef5c3c1042017-08-04 15:01:57 -07002009 rtc::Network* test_network = MakeNetwork(kLocalAddr1);
kwiberg3ec46792016-04-27 07:22:53 -07002010 std::unique_ptr<TestPort> lport(
deadbeef5c3c1042017-08-04 15:01:57 -07002011 CreateTestPort(test_network, "lfrag", "lpass"));
kwiberg3ec46792016-04-27 07:22:53 -07002012 std::unique_ptr<TestPort> rport(
deadbeef5c3c1042017-08-04 15:01:57 -07002013 CreateTestPort(test_network, "rfrag", "rpass"));
honghaiza0c44ea2016-03-23 16:07:48 -07002014 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2015 lport->SetIceTiebreaker(kTiebreaker1);
2016 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2017 rport->SetIceTiebreaker(kTiebreaker2);
2018
2019 uint16_t lnetwork_id = 9;
2020 lport->Network()->set_id(lnetwork_id);
2021 // Send a fake ping from lport to rport.
2022 lport->PrepareAddress();
2023 rport->PrepareAddress();
2024 Connection* lconn =
2025 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2026 lconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07002027 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07002028 IceMessage* msg = lport->last_stun_msg();
2029 const StunUInt32Attribute* network_info_attr =
2030 msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
2031 ASSERT_TRUE(network_info_attr != NULL);
2032 uint32_t network_info = network_info_attr->value();
2033 EXPECT_EQ(lnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07002034 // Default network has unknown type and cost kNetworkCostUnknown.
2035 EXPECT_EQ(rtc::kNetworkCostUnknown, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07002036
Honghai Zhang351d77b2016-05-20 15:08:29 -07002037 // Set the network type to be cellular so its cost will be kNetworkCostHigh.
honghaiza0c44ea2016-03-23 16:07:48 -07002038 // Send a fake ping from rport to lport.
deadbeef5c3c1042017-08-04 15:01:57 -07002039 test_network->set_type(rtc::ADAPTER_TYPE_CELLULAR);
honghaiza0c44ea2016-03-23 16:07:48 -07002040 uint16_t rnetwork_id = 8;
2041 rport->Network()->set_id(rnetwork_id);
2042 Connection* rconn =
2043 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2044 rconn->Ping(0);
Honghai Zhang161a5862016-10-20 11:47:02 -07002045 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
honghaiza0c44ea2016-03-23 16:07:48 -07002046 msg = rport->last_stun_msg();
2047 network_info_attr = msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
2048 ASSERT_TRUE(network_info_attr != NULL);
2049 network_info = network_info_attr->value();
2050 EXPECT_EQ(rnetwork_id, network_info >> 16);
Honghai Zhang351d77b2016-05-20 15:08:29 -07002051 EXPECT_EQ(rtc::kNetworkCostHigh, network_info & 0xFFFF);
honghaiza0c44ea2016-03-23 16:07:48 -07002052}
2053
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002054// Test handling STUN messages.
2055TEST_F(PortTest, TestHandleStunMessage) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002056 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002057 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002058
kwiberg3ec46792016-04-27 07:22:53 -07002059 std::unique_ptr<IceMessage> in_msg, out_msg;
2060 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002061 rtc::SocketAddress addr(kLocalAddr1);
2062 std::string username;
2063
2064 // BINDING-REQUEST from local to remote with valid ICE username,
2065 // MESSAGE-INTEGRITY, and FINGERPRINT.
2066 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2067 "rfrag:lfrag"));
2068 in_msg->AddMessageIntegrity("rpass");
2069 in_msg->AddFingerprint();
2070 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002071 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2072 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002073 EXPECT_TRUE(out_msg.get() != NULL);
2074 EXPECT_EQ("lfrag", username);
2075
2076 // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
2077 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002078 in_msg->AddAttribute(rtc::MakeUnique<StunXorAddressAttribute>(
2079 STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002080 in_msg->AddMessageIntegrity("rpass");
2081 in_msg->AddFingerprint();
2082 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002083 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2084 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002085 EXPECT_TRUE(out_msg.get() != NULL);
2086 EXPECT_EQ("", username);
2087
2088 // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
2089 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002090 in_msg->AddAttribute(rtc::MakeUnique<StunErrorCodeAttribute>(
2091 STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2092 STUN_ERROR_REASON_SERVER_ERROR));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002093 in_msg->AddFingerprint();
2094 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002095 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2096 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002097 EXPECT_TRUE(out_msg.get() != NULL);
2098 EXPECT_EQ("", username);
2099 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
2100 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
2101 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
2102 out_msg->GetErrorCode()->reason());
2103}
2104
guoweisd12140a2015-09-10 13:32:11 -07002105// Tests handling of ICE binding requests with missing or incorrect usernames.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002106TEST_F(PortTest, TestHandleStunMessageBadUsername) {
kwiberg3ec46792016-04-27 07:22:53 -07002107 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002108
kwiberg3ec46792016-04-27 07:22:53 -07002109 std::unique_ptr<IceMessage> in_msg, out_msg;
2110 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002111 rtc::SocketAddress addr(kLocalAddr1);
2112 std::string username;
2113
2114 // BINDING-REQUEST with no username.
2115 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
2116 in_msg->AddMessageIntegrity("rpass");
2117 in_msg->AddFingerprint();
2118 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002119 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2120 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002121 EXPECT_TRUE(out_msg.get() == NULL);
2122 EXPECT_EQ("", username);
2123 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2124
2125 // BINDING-REQUEST with empty username.
2126 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
2127 in_msg->AddMessageIntegrity("rpass");
2128 in_msg->AddFingerprint();
2129 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002130 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2131 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002132 EXPECT_TRUE(out_msg.get() == NULL);
2133 EXPECT_EQ("", username);
2134 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2135
2136 // BINDING-REQUEST with too-short username.
2137 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
2138 in_msg->AddMessageIntegrity("rpass");
2139 in_msg->AddFingerprint();
2140 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002141 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2142 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002143 EXPECT_TRUE(out_msg.get() == NULL);
2144 EXPECT_EQ("", username);
2145 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2146
2147 // BINDING-REQUEST with reversed username.
2148 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2149 "lfrag:rfrag"));
2150 in_msg->AddMessageIntegrity("rpass");
2151 in_msg->AddFingerprint();
2152 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002153 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2154 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002155 EXPECT_TRUE(out_msg.get() == NULL);
2156 EXPECT_EQ("", username);
2157 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2158
2159 // BINDING-REQUEST with garbage username.
2160 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2161 "abcd:efgh"));
2162 in_msg->AddMessageIntegrity("rpass");
2163 in_msg->AddFingerprint();
2164 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002165 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2166 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002167 EXPECT_TRUE(out_msg.get() == NULL);
2168 EXPECT_EQ("", username);
2169 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2170}
2171
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002172// Test handling STUN messages with missing or malformed M-I.
2173TEST_F(PortTest, TestHandleStunMessageBadMessageIntegrity) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002174 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002175 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002176
kwiberg3ec46792016-04-27 07:22:53 -07002177 std::unique_ptr<IceMessage> in_msg, out_msg;
2178 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002179 rtc::SocketAddress addr(kLocalAddr1);
2180 std::string username;
2181
2182 // BINDING-REQUEST from local to remote with valid ICE username and
2183 // FINGERPRINT, but no MESSAGE-INTEGRITY.
2184 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2185 "rfrag:lfrag"));
2186 in_msg->AddFingerprint();
2187 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002188 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2189 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002190 EXPECT_TRUE(out_msg.get() == NULL);
2191 EXPECT_EQ("", username);
2192 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
2193
2194 // BINDING-REQUEST from local to remote with valid ICE username and
2195 // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
2196 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2197 "rfrag:lfrag"));
2198 in_msg->AddMessageIntegrity("invalid");
2199 in_msg->AddFingerprint();
2200 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002201 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2202 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002203 EXPECT_TRUE(out_msg.get() == NULL);
2204 EXPECT_EQ("", username);
2205 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
2206
Steve Antonbabf9172017-11-29 10:19:02 -08002207 // TODO(?): BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002208 // by the Connection, not the Port, since they require the remote username.
2209 // Change this test to pass in data via Connection::OnReadPacket instead.
2210}
2211
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002212// Test handling STUN messages with missing or malformed FINGERPRINT.
2213TEST_F(PortTest, TestHandleStunMessageBadFingerprint) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002214 // Our port will act as the "remote" port.
kwiberg3ec46792016-04-27 07:22:53 -07002215 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002216
kwiberg3ec46792016-04-27 07:22:53 -07002217 std::unique_ptr<IceMessage> in_msg, out_msg;
2218 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002219 rtc::SocketAddress addr(kLocalAddr1);
2220 std::string username;
2221
2222 // BINDING-REQUEST from local to remote with valid ICE username and
2223 // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
2224 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
2225 "rfrag:lfrag"));
2226 in_msg->AddMessageIntegrity("rpass");
2227 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002228 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2229 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002230 EXPECT_EQ(0, port->last_stun_error_code());
2231
2232 // Now, add a fingerprint, but munge the message so it's not valid.
2233 in_msg->AddFingerprint();
2234 in_msg->SetTransactionID("TESTTESTBADD");
2235 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002236 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2237 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002238 EXPECT_EQ(0, port->last_stun_error_code());
2239
2240 // Valid BINDING-RESPONSE, except no FINGERPRINT.
2241 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002242 in_msg->AddAttribute(rtc::MakeUnique<StunXorAddressAttribute>(
2243 STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002244 in_msg->AddMessageIntegrity("rpass");
2245 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002246 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2247 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002248 EXPECT_EQ(0, port->last_stun_error_code());
2249
2250 // Now, add a fingerprint, but munge the message so it's not valid.
2251 in_msg->AddFingerprint();
2252 in_msg->SetTransactionID("TESTTESTBADD");
2253 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002254 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2255 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002256 EXPECT_EQ(0, port->last_stun_error_code());
2257
2258 // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
2259 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
zsteinf42cc9d2017-03-27 16:17:19 -07002260 in_msg->AddAttribute(rtc::MakeUnique<StunErrorCodeAttribute>(
2261 STUN_ATTR_ERROR_CODE, STUN_ERROR_SERVER_ERROR,
2262 STUN_ERROR_REASON_SERVER_ERROR));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002263 in_msg->AddMessageIntegrity("rpass");
2264 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002265 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2266 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002267 EXPECT_EQ(0, port->last_stun_error_code());
2268
2269 // Now, add a fingerprint, but munge the message so it's not valid.
2270 in_msg->AddFingerprint();
2271 in_msg->SetTransactionID("TESTTESTBADD");
2272 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002273 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2274 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002275 EXPECT_EQ(0, port->last_stun_error_code());
2276}
2277
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002278// Test handling of STUN binding indication messages . STUN binding
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002279// indications are allowed only to the connection which is in read mode.
2280TEST_F(PortTest, TestHandleStunBindingIndication) {
kwiberg3ec46792016-04-27 07:22:53 -07002281 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002282 CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002283 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2284 lport->SetIceTiebreaker(kTiebreaker1);
2285
2286 // Verifying encoding and decoding STUN indication message.
kwiberg3ec46792016-04-27 07:22:53 -07002287 std::unique_ptr<IceMessage> in_msg, out_msg;
2288 std::unique_ptr<ByteBufferWriter> buf(new ByteBufferWriter());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002289 rtc::SocketAddress addr(kLocalAddr1);
2290 std::string username;
2291
2292 in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
2293 in_msg->AddFingerprint();
2294 WriteStunMessage(in_msg.get(), buf.get());
kwiberg6baec032016-03-15 11:09:39 -07002295 EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr, &out_msg,
2296 &username));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002297 EXPECT_TRUE(out_msg.get() != NULL);
2298 EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2299 EXPECT_EQ("", username);
2300
2301 // Verify connection can handle STUN indication and updates
2302 // last_ping_received.
kwiberg3ec46792016-04-27 07:22:53 -07002303 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002304 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002305 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2306 rport->SetIceTiebreaker(kTiebreaker2);
2307
2308 lport->PrepareAddress();
2309 rport->PrepareAddress();
2310 ASSERT_FALSE(lport->Candidates().empty());
2311 ASSERT_FALSE(rport->Candidates().empty());
2312
2313 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
2314 Port::ORIGIN_MESSAGE);
2315 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
2316 Port::ORIGIN_MESSAGE);
2317 rconn->Ping(0);
2318
Honghai Zhang161a5862016-10-20 11:47:02 -07002319 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002320 IceMessage* msg = rport->last_stun_msg();
2321 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2322 // Send rport binding request to lport.
jbauchf1f87202016-03-30 06:43:37 -07002323 lconn->OnReadPacket(rport->last_stun_buf()->data<char>(),
2324 rport->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002325 rtc::PacketTime());
Honghai Zhang161a5862016-10-20 11:47:02 -07002326 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002327 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
honghaiz34b11eb2016-03-16 08:55:44 -07002328 int64_t last_ping_received1 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002329
2330 // Adding a delay of 100ms.
2331 rtc::Thread::Current()->ProcessMessages(100);
2332 // Pinging lconn using stun indication message.
2333 lconn->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
honghaiz34b11eb2016-03-16 08:55:44 -07002334 int64_t last_ping_received2 = lconn->last_ping_received();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002335 EXPECT_GT(last_ping_received2, last_ping_received1);
2336}
2337
2338TEST_F(PortTest, TestComputeCandidatePriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002339 std::unique_ptr<TestPort> port(CreateTestPort(kLocalAddr1, "name", "pass"));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002340 port->set_type_preference(90);
2341 port->set_component(177);
2342 port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2343 port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2344 port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2345 port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2346 port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2347 port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2348 port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2349 port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2350 port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2351 // These should all be:
2352 // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
Peter Boström0c4e06b2015-10-07 12:23:21 +02002353 uint32_t expected_priority_v4 = 1509957199U;
2354 uint32_t expected_priority_v6 = 1509959759U;
2355 uint32_t expected_priority_ula = 1509962319U;
2356 uint32_t expected_priority_v4mapped = expected_priority_v4;
2357 uint32_t expected_priority_v4compat = 1509949775U;
2358 uint32_t expected_priority_6to4 = 1509954639U;
2359 uint32_t expected_priority_teredo = 1509952079U;
2360 uint32_t expected_priority_sitelocal = 1509949775U;
2361 uint32_t expected_priority_6bone = 1509949775U;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002362 ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2363 ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2364 ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2365 ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2366 ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2367 ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2368 ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2369 ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2370 ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2371}
2372
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002373// In the case of shared socket, one port may be shared by local and stun.
2374// Test that candidates with different types will have different foundation.
2375TEST_F(PortTest, TestFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002376 std::unique_ptr<TestPort> testport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002377 CreateTestPort(kLocalAddr1, "name", "pass"));
2378 testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2379 LOCAL_PORT_TYPE,
2380 cricket::ICE_TYPE_PREFERENCE_HOST, false);
2381 testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2382 STUN_PORT_TYPE,
2383 cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2384 EXPECT_NE(testport->Candidates()[0].foundation(),
2385 testport->Candidates()[1].foundation());
2386}
2387
2388// This test verifies the foundation of different types of ICE candidates.
2389TEST_F(PortTest, TestCandidateFoundation) {
kwiberg3ec46792016-04-27 07:22:53 -07002390 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002391 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002392 std::unique_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002393 udpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002394 std::unique_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002395 udpport2->PrepareAddress();
2396 EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2397 udpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002398 std::unique_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002399 tcpport1->PrepareAddress();
kwiberg3ec46792016-04-27 07:22:53 -07002400 std::unique_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002401 tcpport2->PrepareAddress();
2402 EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2403 tcpport2->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002404 std::unique_ptr<Port> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002405 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2406 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002407 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002408 EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2409 stunport->Candidates()[0].foundation());
2410 EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2411 stunport->Candidates()[0].foundation());
2412 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2413 stunport->Candidates()[0].foundation());
2414 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2415 stunport->Candidates()[0].foundation());
2416 // Verify GTURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002417 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002418 relayport->AddServerAddress(
2419 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2420 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002421 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002422 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2423 relayport->Candidates()[0].foundation());
2424 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2425 relayport->Candidates()[0].foundation());
2426 // Verifying TURN candidate foundation.
kwiberg3ec46792016-04-27 07:22:53 -07002427 std::unique_ptr<Port> turnport1(
2428 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002429 turnport1->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002430 ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002431 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2432 turnport1->Candidates()[0].foundation());
2433 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2434 turnport1->Candidates()[0].foundation());
2435 EXPECT_NE(stunport->Candidates()[0].foundation(),
2436 turnport1->Candidates()[0].foundation());
kwiberg3ec46792016-04-27 07:22:53 -07002437 std::unique_ptr<Port> turnport2(
2438 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002439 turnport2->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002440 ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002441 EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2442 turnport2->Candidates()[0].foundation());
2443
2444 // Running a second turn server, to get different base IP address.
2445 SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2446 SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2447 TestTurnServer turn_server2(
2448 rtc::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
kwiberg3ec46792016-04-27 07:22:53 -07002449 std::unique_ptr<Port> turnport3(
2450 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
2451 kTurnUdpIntAddr2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002452 turnport3->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002453 ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002454 EXPECT_NE(turnport3->Candidates()[0].foundation(),
2455 turnport2->Candidates()[0].foundation());
Honghai Zhang80f1db92016-01-27 11:54:45 -08002456
2457 // Start a TCP turn server, and check that two turn candidates have
2458 // different foundations if their relay protocols are different.
2459 TestTurnServer turn_server3(rtc::Thread::Current(), kTurnTcpIntAddr,
2460 kTurnUdpExtAddr, PROTO_TCP);
kwiberg3ec46792016-04-27 07:22:53 -07002461 std::unique_ptr<Port> turnport4(
Honghai Zhang80f1db92016-01-27 11:54:45 -08002462 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_TCP, PROTO_UDP));
2463 turnport4->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002464 ASSERT_EQ_WAIT(1U, turnport4->Candidates().size(), kDefaultTimeout);
Honghai Zhang80f1db92016-01-27 11:54:45 -08002465 EXPECT_NE(turnport2->Candidates()[0].foundation(),
2466 turnport4->Candidates()[0].foundation());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002467}
2468
2469// This test verifies the related addresses of different types of
2470// ICE candiates.
2471TEST_F(PortTest, TestCandidateRelatedAddress) {
kwiberg3ec46792016-04-27 07:22:53 -07002472 std::unique_ptr<rtc::NATServer> nat_server(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002473 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
kwiberg3ec46792016-04-27 07:22:53 -07002474 std::unique_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002475 udpport->PrepareAddress();
2476 // For UDPPort, related address will be empty.
2477 EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2478 // Testing related address for stun candidates.
2479 // For stun candidate related address must be equal to the base
2480 // socket address.
kwiberg3ec46792016-04-27 07:22:53 -07002481 std::unique_ptr<StunPort> stunport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002482 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2483 stunport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002484 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002485 // Check STUN candidate address.
2486 EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2487 kNatAddr1.ipaddr());
2488 // Check STUN candidate related address.
2489 EXPECT_EQ(stunport->Candidates()[0].related_address(),
2490 stunport->GetLocalAddress());
2491 // Verifying the related address for the GTURN candidates.
2492 // NOTE: In case of GTURN related address will be equal to the mapped
2493 // address, but address(mapped) will not be XOR.
kwiberg3ec46792016-04-27 07:22:53 -07002494 std::unique_ptr<RelayPort> relayport(CreateGturnPort(kLocalAddr1));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002495 relayport->AddServerAddress(
2496 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2497 relayport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002498 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002499 // For Gturn related address is set to "0.0.0.0:0"
2500 EXPECT_EQ(rtc::SocketAddress(),
2501 relayport->Candidates()[0].related_address());
2502 // Verifying the related address for TURN candidate.
2503 // For TURN related address must be equal to the mapped address.
kwiberg3ec46792016-04-27 07:22:53 -07002504 std::unique_ptr<Port> turnport(
2505 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002506 turnport->PrepareAddress();
Honghai Zhang161a5862016-10-20 11:47:02 -07002507 ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002508 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
2509 turnport->Candidates()[0].address().ipaddr());
2510 EXPECT_EQ(kNatAddr1.ipaddr(),
2511 turnport->Candidates()[0].related_address().ipaddr());
2512}
2513
2514// Test priority value overflow handling when preference is set to 3.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002515TEST_F(PortTest, TestCandidatePriority) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002516 cricket::Candidate cand1;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002517 cand1.set_priority(3);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002518 cricket::Candidate cand2;
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002519 cand2.set_priority(1);
2520 EXPECT_TRUE(cand1.priority() > cand2.priority());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002521}
2522
2523// Test the Connection priority is calculated correctly.
2524TEST_F(PortTest, TestConnectionPriority) {
kwiberg3ec46792016-04-27 07:22:53 -07002525 std::unique_ptr<TestPort> lport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002526 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2527 lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
kwiberg3ec46792016-04-27 07:22:53 -07002528 std::unique_ptr<TestPort> rport(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002529 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
hnsl277b2502016-12-13 05:17:23 -08002530 rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY_UDP);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002531 lport->set_component(123);
2532 lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2533 rport->set_component(23);
2534 rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2535
2536 EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2537 EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2538
2539 // RFC 5245
2540 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
2541 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2542 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2543 Connection* lconn = lport->CreateConnection(
2544 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2545#if defined(WEBRTC_WIN)
2546 EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2547#else
2548 EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2549#endif
2550
2551 lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2552 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2553 Connection* rconn = rport->CreateConnection(
2554 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2555#if defined(WEBRTC_WIN)
2556 EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2557#else
2558 EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2559#endif
2560}
2561
2562TEST_F(PortTest, TestWritableState) {
Honghai Zhang161a5862016-10-20 11:47:02 -07002563 rtc::ScopedFakeClock clock;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002564 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002565 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002566 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002567 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002568
2569 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002570 TestChannel ch1(port1);
2571 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002572
2573 // Acquire addresses.
2574 ch1.Start();
2575 ch2.Start();
Honghai Zhang161a5862016-10-20 11:47:02 -07002576 ASSERT_EQ_SIMULATED_WAIT(1, ch1.complete_count(), kDefaultTimeout, clock);
2577 ASSERT_EQ_SIMULATED_WAIT(1, ch2.complete_count(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002578
2579 // Send a ping from src to dst.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002580 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002581 ASSERT_TRUE(ch1.conn() != NULL);
2582 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
Honghai Zhang161a5862016-10-20 11:47:02 -07002583 // for TCP connect
2584 EXPECT_TRUE_SIMULATED_WAIT(ch1.conn()->connected(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002585 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002586 SIMULATED_WAIT(!ch2.remote_address().IsNil(), kShortTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002587
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002588 // Data should be sendable before the connection is accepted.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002589 char data[] = "abcd";
tfarina5237aaf2015-11-10 23:44:30 -08002590 int data_size = arraysize(data);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002591 rtc::PacketOptions options;
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002592 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002593
2594 // Accept the connection to return the binding response, transition to
2595 // writable, and allow data to be sent.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002596 ch2.AcceptConnection(GetCandidate(port1));
Honghai Zhang161a5862016-10-20 11:47:02 -07002597 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2598 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002599 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2600
2601 // Ask the connection to update state as if enough time has passed to lose
2602 // full writability and 5 pings went unresponded to. We'll accomplish the
2603 // latter by sending pings but not pumping messages.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002604 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002605 ch1.Ping(i);
2606 }
honghaiz34b11eb2016-03-16 08:55:44 -07002607 int unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002608 ch1.conn()->UpdateState(unreliable_timeout_delay);
2609 EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2610
2611 // Data should be able to be sent in this state.
2612 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2613
2614 // And now allow the other side to process the pings and send binding
2615 // responses.
Honghai Zhang161a5862016-10-20 11:47:02 -07002616 EXPECT_EQ_SIMULATED_WAIT(Connection::STATE_WRITABLE,
2617 ch1.conn()->write_state(), kDefaultTimeout, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002618
2619 // Wait long enough for a full timeout (past however long we've already
2620 // waited).
Peter Boström0c4e06b2015-10-07 12:23:21 +02002621 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002622 ch1.Ping(unreliable_timeout_delay + i);
2623 }
2624 ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2625 500u);
2626 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2627
Taylor Brandstetter6bb1ef22016-06-27 18:09:03 -07002628 // Even if the connection has timed out, the Connection shouldn't block
2629 // the sending of data.
2630 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002631
2632 ch1.Stop();
2633 ch2.Stop();
2634}
2635
2636TEST_F(PortTest, TestTimeoutForNeverWritable) {
2637 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002638 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002639 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002640 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002641
2642 // Set up channels.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002643 TestChannel ch1(port1);
2644 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002645
2646 // Acquire addresses.
2647 ch1.Start();
2648 ch2.Start();
2649
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002650 ch1.CreateConnection(GetCandidate(port2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002651 ASSERT_TRUE(ch1.conn() != NULL);
2652 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2653
2654 // Attempt to go directly to write timeout.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002655 for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002656 ch1.Ping(i);
2657 }
2658 ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2659 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2660}
2661
2662// This test verifies the connection setup between ICEMODE_FULL
2663// and ICEMODE_LITE.
2664// In this test |ch1| behaves like FULL mode client and we have created
2665// port which responds to the ping message just like LITE client.
2666TEST_F(PortTest, TestIceLiteConnectivity) {
2667 TestPort* ice_full_port = CreateTestPort(
Peter Thatcher7cbd1882015-09-17 18:54:52 -07002668 kLocalAddr1, "lfrag", "lpass",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002669 cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2670
kwiberg3ec46792016-04-27 07:22:53 -07002671 std::unique_ptr<TestPort> ice_lite_port(
2672 CreateTestPort(kLocalAddr2, "rfrag", "rpass", cricket::ICEROLE_CONTROLLED,
2673 kTiebreaker2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002674 // Setup TestChannel. This behaves like FULL mode client.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002675 TestChannel ch1(ice_full_port);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002676 ch1.SetIceMode(ICEMODE_FULL);
2677
2678 // Start gathering candidates.
2679 ch1.Start();
2680 ice_lite_port->PrepareAddress();
2681
Honghai Zhang161a5862016-10-20 11:47:02 -07002682 ASSERT_EQ_WAIT(1, ch1.complete_count(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002683 ASSERT_FALSE(ice_lite_port->Candidates().empty());
2684
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002685 ch1.CreateConnection(GetCandidate(ice_lite_port.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002686 ASSERT_TRUE(ch1.conn() != NULL);
2687 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2688
2689 // Send ping from full mode client.
2690 // This ping must not have USE_CANDIDATE_ATTR.
2691 ch1.Ping();
2692
2693 // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2694 // from port.
Honghai Zhang161a5862016-10-20 11:47:02 -07002695 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002696 IceMessage* msg = ice_full_port->last_stun_msg();
2697 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2698
2699 // Respond with a BINDING-RESPONSE from litemode client.
2700 // NOTE: Ideally we should't create connection at this stage from lite
2701 // port, as it should be done only after receiving ping with USE_CANDIDATE.
2702 // But we need a connection to send a response message.
2703 ice_lite_port->CreateConnection(
2704 ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
kwiberg3ec46792016-04-27 07:22:53 -07002705 std::unique_ptr<IceMessage> request(CopyStunMessage(msg));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002706 ice_lite_port->SendBindingResponse(
2707 request.get(), ice_full_port->Candidates()[0].address());
2708
2709 // Feeding the respone message from litemode to the full mode connection.
jbauchf1f87202016-03-30 06:43:37 -07002710 ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->data<char>(),
2711 ice_lite_port->last_stun_buf()->size(),
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002712 rtc::PacketTime());
2713 // Verifying full mode connection becomes writable from the response.
2714 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
Honghai Zhang161a5862016-10-20 11:47:02 -07002715 kDefaultTimeout);
2716 EXPECT_TRUE_WAIT(ch1.nominated(), kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002717
2718 // Clear existing stun messsages. Otherwise we will process old stun
2719 // message right after we send ping.
2720 ice_full_port->Reset();
2721 // Send ping. This must have USE_CANDIDATE_ATTR.
2722 ch1.Ping();
Honghai Zhang161a5862016-10-20 11:47:02 -07002723 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, kDefaultTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002724 msg = ice_full_port->last_stun_msg();
2725 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2726 ch1.Stop();
2727}
2728
Honghai Zhanga74363c2016-07-28 18:06:15 -07002729// This test case verifies that both the controlling port and the controlled
2730// port will time out after connectivity is lost, if they are not marked as
2731// "keep alive until pruned."
2732TEST_F(PortTest, TestPortTimeoutIfNotKeptAlive) {
2733 rtc::ScopedFakeClock clock;
2734 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002735 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2736 ConnectToSignalDestroyed(port1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002737 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002738 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2739 port1->SetIceTiebreaker(kTiebreaker1);
2740
2741 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002742 ConnectToSignalDestroyed(port2);
2743 port2->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002744 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2745 port2->SetIceTiebreaker(kTiebreaker2);
2746
2747 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002748 TestChannel ch1(port1);
2749 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002750
2751 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002752 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002753 // After the connection is destroyed, the port will be destroyed because
2754 // none of them is marked as "keep alive until pruned.
2755 EXPECT_EQ_SIMULATED_WAIT(2, ports_destroyed(), 110, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002756}
2757
Honghai Zhanga74363c2016-07-28 18:06:15 -07002758// Test that if after all connection are destroyed, new connections are created
2759// and destroyed again, ports won't be destroyed until a timeout period passes
2760// after the last set of connections are all destroyed.
2761TEST_F(PortTest, TestPortTimeoutAfterNewConnectionCreatedAndDestroyed) {
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002762 rtc::ScopedFakeClock clock;
Honghai Zhanga74363c2016-07-28 18:06:15 -07002763 int timeout_delay = 100;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002764 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002765 ConnectToSignalDestroyed(port1);
2766 port1->set_timeout_delay(timeout_delay); // milliseconds
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002767 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2768 port1->SetIceTiebreaker(kTiebreaker1);
2769
2770 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2771 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002772 port2->set_timeout_delay(timeout_delay); // milliseconds
2773
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002774 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2775 port2->SetIceTiebreaker(kTiebreaker2);
2776
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002777 // Set up channels and ensure both ports will be deleted.
Guo-wei Shieh1eb87c72015-08-25 11:02:55 -07002778 TestChannel ch1(port1);
2779 TestChannel ch2(port2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002780
2781 // Simulate a connection that succeeds, and then is destroyed.
Guo-wei Shiehbe508a12015-04-06 12:48:47 -07002782 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002783 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2784 EXPECT_EQ(0, ports_destroyed());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002785
Honghai Zhanga74363c2016-07-28 18:06:15 -07002786 // Start the second set of connection and destroy them.
2787 ch1.CreateConnection(GetCandidate(ch2.port()));
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002788 ch2.CreateConnection(GetCandidate(ch1.port()));
Honghai Zhanga74363c2016-07-28 18:06:15 -07002789 ch1.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002790 ch2.Stop();
Honghai Zhangb5db1ec2016-07-28 13:23:05 -07002791
Honghai Zhanga74363c2016-07-28 18:06:15 -07002792 SIMULATED_WAIT(ports_destroyed() > 0, 80, clock);
2793 EXPECT_EQ(0, ports_destroyed());
2794
2795 // The ports on both sides should be destroyed after timeout.
2796 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 30, clock);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00002797}
honghaizd0b31432015-09-30 12:42:17 -07002798
Honghai Zhanga74363c2016-07-28 18:06:15 -07002799// This test case verifies that neither the controlling port nor the controlled
2800// port will time out after connectivity is lost if they are marked as "keep
2801// alive until pruned". They will time out after they are pruned.
2802TEST_F(PortTest, TestPortNotTimeoutUntilPruned) {
2803 rtc::ScopedFakeClock clock;
2804 int timeout_delay = 100;
honghaizd0b31432015-09-30 12:42:17 -07002805 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002806 ConnectToSignalDestroyed(port1);
2807 port1->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002808 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2809 port1->SetIceTiebreaker(kTiebreaker1);
2810
2811 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2812 ConnectToSignalDestroyed(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002813 port2->set_timeout_delay(timeout_delay); // milliseconds
honghaizd0b31432015-09-30 12:42:17 -07002814 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2815 port2->SetIceTiebreaker(kTiebreaker2);
honghaizd0b31432015-09-30 12:42:17 -07002816 // The connection must not be destroyed before a connection is attempted.
Honghai Zhanga74363c2016-07-28 18:06:15 -07002817 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002818
2819 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2820 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2821
Honghai Zhanga74363c2016-07-28 18:06:15 -07002822 // Set up channels and keep the port alive.
honghaizd0b31432015-09-30 12:42:17 -07002823 TestChannel ch1(port1);
2824 TestChannel ch2(port2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002825 // Simulate a connection that succeeds, and then is destroyed. But ports
2826 // are kept alive. Ports won't be destroyed.
honghaizd0b31432015-09-30 12:42:17 -07002827 StartConnectAndStopChannels(&ch1, &ch2);
Honghai Zhanga74363c2016-07-28 18:06:15 -07002828 port1->KeepAliveUntilPruned();
2829 port2->KeepAliveUntilPruned();
2830 SIMULATED_WAIT(ports_destroyed() > 0, 150, clock);
2831 EXPECT_EQ(0, ports_destroyed());
honghaizd0b31432015-09-30 12:42:17 -07002832
Honghai Zhanga74363c2016-07-28 18:06:15 -07002833 // If they are pruned now, they will be destroyed right away.
2834 port1->Prune();
2835 port2->Prune();
2836 // The ports on both sides should be destroyed after timeout.
2837 EXPECT_TRUE_SIMULATED_WAIT(ports_destroyed() == 2, 1, clock);
honghaizd0b31432015-09-30 12:42:17 -07002838}
Honghai Zhangf9945b22015-12-15 12:20:13 -08002839
2840TEST_F(PortTest, TestSupportsProtocol) {
kwiberg3ec46792016-04-27 07:22:53 -07002841 std::unique_ptr<Port> udp_port(CreateUdpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002842 EXPECT_TRUE(udp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2843 EXPECT_FALSE(udp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2844
kwiberg3ec46792016-04-27 07:22:53 -07002845 std::unique_ptr<Port> stun_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002846 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2847 EXPECT_TRUE(stun_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2848 EXPECT_FALSE(stun_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2849
kwiberg3ec46792016-04-27 07:22:53 -07002850 std::unique_ptr<Port> tcp_port(CreateTcpPort(kLocalAddr1));
Honghai Zhangf9945b22015-12-15 12:20:13 -08002851 EXPECT_TRUE(tcp_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2852 EXPECT_TRUE(tcp_port->SupportsProtocol(SSLTCP_PROTOCOL_NAME));
2853 EXPECT_FALSE(tcp_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2854
kwiberg3ec46792016-04-27 07:22:53 -07002855 std::unique_ptr<Port> turn_port(
Honghai Zhangf9945b22015-12-15 12:20:13 -08002856 CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2857 EXPECT_TRUE(turn_port->SupportsProtocol(UDP_PROTOCOL_NAME));
2858 EXPECT_FALSE(turn_port->SupportsProtocol(TCP_PROTOCOL_NAME));
2859}
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002860
2861// Test that SetIceParameters updates the component, ufrag and password
2862// on both the port itself and its candidates.
2863TEST_F(PortTest, TestSetIceParameters) {
2864 std::unique_ptr<TestPort> port(
2865 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2866 port->PrepareAddress();
2867 EXPECT_EQ(1UL, port->Candidates().size());
2868 port->SetIceParameters(1, "ufrag2", "password2");
2869 EXPECT_EQ(1, port->component());
2870 EXPECT_EQ("ufrag2", port->username_fragment());
2871 EXPECT_EQ("password2", port->password());
2872 const Candidate& candidate = port->Candidates()[0];
2873 EXPECT_EQ(1, candidate.component());
2874 EXPECT_EQ("ufrag2", candidate.username());
2875 EXPECT_EQ("password2", candidate.password());
2876}
honghaiz36f50e82016-06-01 15:57:03 -07002877
2878TEST_F(PortTest, TestAddConnectionWithSameAddress) {
2879 std::unique_ptr<TestPort> port(
2880 CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
2881 port->PrepareAddress();
2882 EXPECT_EQ(1u, port->Candidates().size());
2883 rtc::SocketAddress address("1.1.1.1", 5000);
2884 cricket::Candidate candidate(1, "udp", address, 0, "", "", "relay", 0, "");
2885 cricket::Connection* conn1 =
2886 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2887 cricket::Connection* conn_in_use = port->GetConnection(address);
2888 EXPECT_EQ(conn1, conn_in_use);
2889 EXPECT_EQ(0u, conn_in_use->remote_candidate().generation());
2890
2891 // Creating with a candidate with the same address again will get us a
2892 // different connection with the new candidate.
2893 candidate.set_generation(2);
2894 cricket::Connection* conn2 =
2895 port->CreateConnection(candidate, Port::ORIGIN_MESSAGE);
2896 EXPECT_NE(conn1, conn2);
2897 conn_in_use = port->GetConnection(address);
2898 EXPECT_EQ(conn2, conn_in_use);
2899 EXPECT_EQ(2u, conn_in_use->remote_candidate().generation());
2900
2901 // Make sure the new connection was not deleted.
2902 rtc::Thread::Current()->ProcessMessages(300);
2903 EXPECT_TRUE(port->GetConnection(address) != nullptr);
2904}
Steve Antonbabf9172017-11-29 10:19:02 -08002905
2906} // namespace cricket