blob: f3400f1e4a5893ce7ddc0f57f273a5e738e9f98c [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2009 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/base/fakenetwork.h"
29#include "talk/base/firewallsocketserver.h"
30#include "talk/base/gunit.h"
31#include "talk/base/helpers.h"
32#include "talk/base/logging.h"
33#include "talk/base/natserver.h"
34#include "talk/base/natsocketfactory.h"
35#include "talk/base/network.h"
36#include "talk/base/physicalsocketserver.h"
37#include "talk/base/socketaddress.h"
38#include "talk/base/thread.h"
39#include "talk/base/virtualsocketserver.h"
40#include "talk/p2p/base/basicpacketsocketfactory.h"
41#include "talk/p2p/base/constants.h"
42#include "talk/p2p/base/p2ptransportchannel.h"
43#include "talk/p2p/base/portallocatorsessionproxy.h"
44#include "talk/p2p/base/testrelayserver.h"
45#include "talk/p2p/base/teststunserver.h"
46#include "talk/p2p/client/basicportallocator.h"
47#include "talk/p2p/client/httpportallocator.h"
48
49using talk_base::SocketAddress;
50using talk_base::Thread;
51
52static const SocketAddress kClientAddr("11.11.11.11", 0);
wu@webrtc.org97077a32013-10-25 21:18:33 +000053static const SocketAddress kClientIPv6Addr(
54 "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055static const SocketAddress kNatAddr("77.77.77.77", talk_base::NAT_SERVER_PORT);
56static const SocketAddress kRemoteClientAddr("22.22.22.22", 0);
57static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
58static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
59static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
60static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
61static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
62static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
63static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
64
65// Minimum and maximum port for port range tests.
66static const int kMinPort = 10000;
67static const int kMaxPort = 10099;
68
69// Based on ICE_UFRAG_LENGTH
70static const char kIceUfrag0[] = "TESTICEUFRAG0000";
71// Based on ICE_PWD_LENGTH
72static const char kIcePwd0[] = "TESTICEPWD00000000000000";
73
74static const char kContentName[] = "test content";
75
76static const int kDefaultAllocationTimeout = 1000;
77
78namespace cricket {
79
80// Helper for dumping candidates
81std::ostream& operator<<(std::ostream& os, const cricket::Candidate& c) {
82 os << c.ToString();
83 return os;
84}
85
86} // namespace cricket
87
88class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
89 public:
90 static void SetUpTestCase() {
91 // Ensure the RNG is inited.
92 talk_base::InitRandom(NULL, 0);
93 }
94 PortAllocatorTest()
95 : pss_(new talk_base::PhysicalSocketServer),
96 vss_(new talk_base::VirtualSocketServer(pss_.get())),
97 fss_(new talk_base::FirewallSocketServer(vss_.get())),
98 ss_scope_(fss_.get()),
99 nat_factory_(vss_.get(), kNatAddr),
100 nat_socket_factory_(&nat_factory_),
101 stun_server_(Thread::Current(), kStunAddr),
102 relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr,
103 kRelayTcpIntAddr, kRelayTcpExtAddr,
104 kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
105 allocator_(new cricket::BasicPortAllocator(
106 &network_manager_, kStunAddr,
107 kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr)),
108 candidate_allocation_done_(false) {
109 allocator_->set_step_delay(cricket::kMinimumStepDelay);
110 }
111
112 void AddInterface(const SocketAddress& addr) {
113 network_manager_.AddInterface(addr);
114 }
115 bool SetPortRange(int min_port, int max_port) {
116 return allocator_->SetPortRange(min_port, max_port);
117 }
118 talk_base::NATServer* CreateNatServer(const SocketAddress& addr,
119 talk_base::NATType type) {
120 return new talk_base::NATServer(type, vss_.get(), addr, vss_.get(), addr);
121 }
122
123 bool CreateSession(int component) {
124 session_.reset(CreateSession("session", component));
125 if (!session_)
126 return false;
127 return true;
128 }
129
130 bool CreateSession(int component, const std::string& content_name) {
131 session_.reset(CreateSession("session", content_name, component));
132 if (!session_)
133 return false;
134 return true;
135 }
136
137 cricket::PortAllocatorSession* CreateSession(
138 const std::string& sid, int component) {
139 return CreateSession(sid, kContentName, component);
140 }
141
142 cricket::PortAllocatorSession* CreateSession(
143 const std::string& sid, const std::string& content_name, int component) {
144 return CreateSession(sid, content_name, component, kIceUfrag0, kIcePwd0);
145 }
146
147 cricket::PortAllocatorSession* CreateSession(
148 const std::string& sid, const std::string& content_name, int component,
149 const std::string& ice_ufrag, const std::string& ice_pwd) {
150 cricket::PortAllocatorSession* session =
151 allocator_->CreateSession(
152 sid, content_name, component, ice_ufrag, ice_pwd);
153 session->SignalPortReady.connect(this,
154 &PortAllocatorTest::OnPortReady);
155 session->SignalCandidatesReady.connect(this,
156 &PortAllocatorTest::OnCandidatesReady);
157 session->SignalCandidatesAllocationDone.connect(this,
158 &PortAllocatorTest::OnCandidatesAllocationDone);
159 return session;
160 }
161
162 static bool CheckCandidate(const cricket::Candidate& c,
163 int component, const std::string& type,
164 const std::string& proto,
165 const SocketAddress& addr) {
166 return (c.component() == component && c.type() == type &&
167 c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
168 ((addr.port() == 0 && (c.address().port() != 0)) ||
169 (c.address().port() == addr.port())));
170 }
171 static bool CheckPort(const talk_base::SocketAddress& addr,
172 int min_port, int max_port) {
173 return (addr.port() >= min_port && addr.port() <= max_port);
174 }
175
176 void OnCandidatesAllocationDone(cricket::PortAllocatorSession* session) {
177 // We should only get this callback once, except in the mux test where
178 // we have multiple port allocation sessions.
179 if (session == session_.get()) {
180 ASSERT_FALSE(candidate_allocation_done_);
181 candidate_allocation_done_ = true;
182 }
183 }
184
185 // Check if all ports allocated have send-buffer size |expected|. If
186 // |expected| == -1, check if GetOptions returns SOCKET_ERROR.
187 void CheckSendBufferSizesOfAllPorts(int expected) {
188 std::vector<cricket::PortInterface*>::iterator it;
189 for (it = ports_.begin(); it < ports_.end(); ++it) {
190 int send_buffer_size;
191 if (expected == -1) {
192 EXPECT_EQ(SOCKET_ERROR,
193 (*it)->GetOption(talk_base::Socket::OPT_SNDBUF,
194 &send_buffer_size));
195 } else {
196 EXPECT_EQ(0, (*it)->GetOption(talk_base::Socket::OPT_SNDBUF,
197 &send_buffer_size));
198 ASSERT_EQ(expected, send_buffer_size);
199 }
200 }
201 }
202
203 protected:
204 cricket::BasicPortAllocator& allocator() {
205 return *allocator_;
206 }
207
208 void OnPortReady(cricket::PortAllocatorSession* ses,
209 cricket::PortInterface* port) {
210 LOG(LS_INFO) << "OnPortReady: " << port->ToString();
211 ports_.push_back(port);
212 }
213 void OnCandidatesReady(cricket::PortAllocatorSession* ses,
214 const std::vector<cricket::Candidate>& candidates) {
215 for (size_t i = 0; i < candidates.size(); ++i) {
216 LOG(LS_INFO) << "OnCandidatesReady: " << candidates[i].ToString();
217 candidates_.push_back(candidates[i]);
218 }
219 }
220
221 bool HasRelayAddress(const cricket::ProtocolAddress& proto_addr) {
222 for (size_t i = 0; i < allocator_->relays().size(); ++i) {
223 cricket::RelayServerConfig server_config = allocator_->relays()[i];
224 cricket::PortList::const_iterator relay_port;
225 for (relay_port = server_config.ports.begin();
226 relay_port != server_config.ports.end(); ++relay_port) {
227 if (proto_addr.address == relay_port->address &&
228 proto_addr.proto == relay_port->proto)
229 return true;
230 }
231 }
232 return false;
233 }
234
235 talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
236 talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
237 talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
238 talk_base::SocketServerScope ss_scope_;
239 talk_base::NATSocketFactory nat_factory_;
240 talk_base::BasicPacketSocketFactory nat_socket_factory_;
241 cricket::TestStunServer stun_server_;
242 cricket::TestRelayServer relay_server_;
243 talk_base::FakeNetworkManager network_manager_;
244 talk_base::scoped_ptr<cricket::BasicPortAllocator> allocator_;
245 talk_base::scoped_ptr<cricket::PortAllocatorSession> session_;
246 std::vector<cricket::PortInterface*> ports_;
247 std::vector<cricket::Candidate> candidates_;
248 bool candidate_allocation_done_;
249};
250
251// Tests that we can init the port allocator and create a session.
252TEST_F(PortAllocatorTest, TestBasic) {
253 EXPECT_EQ(&network_manager_, allocator().network_manager());
254 EXPECT_EQ(kStunAddr, allocator().stun_address());
255 ASSERT_EQ(1u, allocator().relays().size());
256 EXPECT_EQ(cricket::RELAY_GTURN, allocator().relays()[0].type);
257 // Empty relay credentials are used for GTURN.
258 EXPECT_TRUE(allocator().relays()[0].credentials.username.empty());
259 EXPECT_TRUE(allocator().relays()[0].credentials.password.empty());
260 EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
261 kRelayUdpIntAddr, cricket::PROTO_UDP)));
262 EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
263 kRelayTcpIntAddr, cricket::PROTO_TCP)));
264 EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
265 kRelaySslTcpIntAddr, cricket::PROTO_SSLTCP)));
266 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
267}
268
269// Tests that we can get all the desired addresses successfully.
270TEST_F(PortAllocatorTest, TestGetAllPortsWithMinimumStepDelay) {
271 AddInterface(kClientAddr);
272 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
273 session_->StartGettingPorts();
274 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
275 EXPECT_EQ(4U, ports_.size());
276 EXPECT_PRED5(CheckCandidate, candidates_[0],
277 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
278 EXPECT_PRED5(CheckCandidate, candidates_[1],
279 cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
280 EXPECT_PRED5(CheckCandidate, candidates_[2],
281 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
282 EXPECT_PRED5(CheckCandidate, candidates_[3],
283 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
284 EXPECT_PRED5(CheckCandidate, candidates_[4],
285 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
286 EXPECT_PRED5(CheckCandidate, candidates_[5],
287 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
288 EXPECT_PRED5(CheckCandidate, candidates_[6],
289 cricket::ICE_CANDIDATE_COMPONENT_RTP,
290 "relay", "ssltcp", kRelaySslTcpIntAddr);
291 EXPECT_TRUE(candidate_allocation_done_);
292}
293
294// Verify candidates with default step delay of 1sec.
295TEST_F(PortAllocatorTest, TestGetAllPortsWithOneSecondStepDelay) {
296 AddInterface(kClientAddr);
297 allocator_->set_step_delay(cricket::kDefaultStepDelay);
298 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
299 session_->StartGettingPorts();
300 ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
301 EXPECT_EQ(2U, ports_.size());
302 ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
303 EXPECT_EQ(3U, ports_.size());
304 EXPECT_PRED5(CheckCandidate, candidates_[2],
305 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
306 EXPECT_PRED5(CheckCandidate, candidates_[3],
307 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
308 ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
309 EXPECT_PRED5(CheckCandidate, candidates_[4],
310 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
311 EXPECT_PRED5(CheckCandidate, candidates_[5],
312 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
313 EXPECT_EQ(4U, ports_.size());
314 ASSERT_EQ_WAIT(7U, candidates_.size(), 2000);
315 EXPECT_PRED5(CheckCandidate, candidates_[6],
316 cricket::ICE_CANDIDATE_COMPONENT_RTP,
317 "relay", "ssltcp", kRelaySslTcpIntAddr);
318 EXPECT_EQ(4U, ports_.size());
319 EXPECT_TRUE(candidate_allocation_done_);
320 // If we Stop gathering now, we shouldn't get a second "done" callback.
321 session_->StopGettingPorts();
322}
323
324TEST_F(PortAllocatorTest, TestSetupVideoRtpPortsWithNormalSendBuffers) {
325 AddInterface(kClientAddr);
326 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP,
327 cricket::CN_VIDEO));
328 session_->StartGettingPorts();
329 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
330 EXPECT_TRUE(candidate_allocation_done_);
331 // If we Stop gathering now, we shouldn't get a second "done" callback.
332 session_->StopGettingPorts();
333
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000334 // All ports should have unset send-buffer sizes.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 CheckSendBufferSizesOfAllPorts(-1);
336}
337
338// Tests that we can get callback after StopGetAllPorts.
339TEST_F(PortAllocatorTest, TestStopGetAllPorts) {
340 AddInterface(kClientAddr);
341 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
342 session_->StartGettingPorts();
343 ASSERT_EQ_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout);
344 EXPECT_EQ(2U, ports_.size());
345 session_->StopGettingPorts();
346 EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
347}
348
349// Test that we restrict client ports appropriately when a port range is set.
350// We check the candidates for udp/stun/tcp ports, and the from address
351// for relay ports.
352TEST_F(PortAllocatorTest, TestGetAllPortsPortRange) {
353 AddInterface(kClientAddr);
354 // Check that an invalid port range fails.
355 EXPECT_FALSE(SetPortRange(kMaxPort, kMinPort));
356 // Check that a null port range succeeds.
357 EXPECT_TRUE(SetPortRange(0, 0));
358 // Check that a valid port range succeeds.
359 EXPECT_TRUE(SetPortRange(kMinPort, kMaxPort));
360 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
361 session_->StartGettingPorts();
362 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
363 EXPECT_EQ(4U, ports_.size());
364 // Check the port number for the UDP port object.
365 EXPECT_PRED3(CheckPort, candidates_[0].address(), kMinPort, kMaxPort);
366 // Check the port number for the STUN port object.
367 EXPECT_PRED3(CheckPort, candidates_[1].address(), kMinPort, kMaxPort);
368 // Check the port number used to connect to the relay server.
369 EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(),
370 kMinPort, kMaxPort);
371 // Check the port number for the TCP port object.
372 EXPECT_PRED3(CheckPort, candidates_[5].address(), kMinPort, kMaxPort);
373 EXPECT_TRUE(candidate_allocation_done_);
374}
375
376// Test that we don't crash or malfunction if we have no network adapters.
377TEST_F(PortAllocatorTest, TestGetAllPortsNoAdapters) {
378 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
379 session_->StartGettingPorts();
380 talk_base::Thread::Current()->ProcessMessages(100);
381 // Without network adapter, we should not get any candidate.
382 EXPECT_EQ(0U, candidates_.size());
383 EXPECT_TRUE(candidate_allocation_done_);
384}
385
386// Test that we can get OnCandidatesAllocationDone callback when all the ports
387// are disabled.
388TEST_F(PortAllocatorTest, TestDisableAllPorts) {
389 AddInterface(kClientAddr);
390 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
391 session_->set_flags(cricket::PORTALLOCATOR_DISABLE_UDP |
392 cricket::PORTALLOCATOR_DISABLE_STUN |
393 cricket::PORTALLOCATOR_DISABLE_RELAY |
394 cricket::PORTALLOCATOR_DISABLE_TCP);
395 session_->StartGettingPorts();
396 talk_base::Thread::Current()->ProcessMessages(100);
397 EXPECT_EQ(0U, candidates_.size());
398 EXPECT_TRUE(candidate_allocation_done_);
399}
400
401// Test that we don't crash or malfunction if we can't create UDP sockets.
402TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSockets) {
403 AddInterface(kClientAddr);
404 fss_->set_udp_sockets_enabled(false);
405 EXPECT_TRUE(CreateSession(1));
406 session_->StartGettingPorts();
407 ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
408 EXPECT_EQ(2U, ports_.size());
409 EXPECT_PRED5(CheckCandidate, candidates_[0],
410 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
411 EXPECT_PRED5(CheckCandidate, candidates_[1],
412 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
413 EXPECT_PRED5(CheckCandidate, candidates_[2],
414 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
415 EXPECT_PRED5(CheckCandidate, candidates_[3],
416 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
417 EXPECT_PRED5(CheckCandidate, candidates_[4],
418 cricket::ICE_CANDIDATE_COMPONENT_RTP,
419 "relay", "ssltcp", kRelaySslTcpIntAddr);
420 EXPECT_TRUE(candidate_allocation_done_);
421}
422
423// Test that we don't crash or malfunction if we can't create UDP sockets or
424// listen on TCP sockets. We still give out a local TCP address, since
425// apparently this is needed for the remote side to accept our connection.
426TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
427 AddInterface(kClientAddr);
428 fss_->set_udp_sockets_enabled(false);
429 fss_->set_tcp_listen_enabled(false);
430 EXPECT_TRUE(CreateSession(1));
431 session_->StartGettingPorts();
432 ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
433 EXPECT_EQ(2U, ports_.size());
434 EXPECT_PRED5(CheckCandidate, candidates_[0],
435 1, "relay", "udp", kRelayUdpIntAddr);
436 EXPECT_PRED5(CheckCandidate, candidates_[1],
437 1, "relay", "udp", kRelayUdpExtAddr);
438 EXPECT_PRED5(CheckCandidate, candidates_[2],
439 1, "relay", "tcp", kRelayTcpIntAddr);
440 EXPECT_PRED5(CheckCandidate, candidates_[3],
441 1, "local", "tcp", kClientAddr);
442 EXPECT_PRED5(CheckCandidate, candidates_[4],
443 1, "relay", "ssltcp", kRelaySslTcpIntAddr);
444 EXPECT_TRUE(candidate_allocation_done_);
445}
446
447// Test that we don't crash or malfunction if we can't create any sockets.
448// TODO: Find a way to exit early here.
449TEST_F(PortAllocatorTest, TestGetAllPortsNoSockets) {
450 AddInterface(kClientAddr);
451 fss_->set_tcp_sockets_enabled(false);
452 fss_->set_udp_sockets_enabled(false);
453 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
454 session_->StartGettingPorts();
455 WAIT(candidates_.size() > 0, 2000);
456 // TODO - Check candidate_allocation_done signal.
457 // In case of Relay, ports creation will succeed but sockets will fail.
458 // There is no error reporting from RelayEntry to handle this failure.
459}
460
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000461// Testing STUN timeout.
462TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
463 fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr);
464 AddInterface(kClientAddr);
465 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
466 session_->StartGettingPorts();
467 EXPECT_EQ_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout);
468 EXPECT_EQ(2U, ports_.size());
469 EXPECT_PRED5(CheckCandidate, candidates_[0],
470 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
471 EXPECT_PRED5(CheckCandidate, candidates_[1],
472 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
473 // RelayPort connection timeout is 3sec. TCP connection with RelayServer
474 // will be tried after 3 seconds.
475 EXPECT_EQ_WAIT(6U, candidates_.size(), 4000);
476 EXPECT_EQ(3U, ports_.size());
477 EXPECT_PRED5(CheckCandidate, candidates_[2],
478 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
479 EXPECT_PRED5(CheckCandidate, candidates_[3],
480 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
481 EXPECT_PRED5(CheckCandidate, candidates_[4],
482 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
483 kRelaySslTcpIntAddr);
484 EXPECT_PRED5(CheckCandidate, candidates_[5],
485 cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
486 // Stun Timeout is 9sec.
487 EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000);
488}
489
490// Test to verify ICE restart process.
491TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) {
492 AddInterface(kClientAddr);
493 EXPECT_TRUE(CreateSession(1));
494 session_->StartGettingPorts();
495 EXPECT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
496 EXPECT_EQ(4U, ports_.size());
497 EXPECT_TRUE(candidate_allocation_done_);
498 // TODO - Extend this to verify ICE restart.
499}
500
501TEST_F(PortAllocatorTest, TestBasicMuxFeatures) {
502 AddInterface(kClientAddr);
503 allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_BUNDLE);
504 // Session ID - session1.
505 talk_base::scoped_ptr<cricket::PortAllocatorSession> session1(
506 CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTP));
507 talk_base::scoped_ptr<cricket::PortAllocatorSession> session2(
508 CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTCP));
509 session1->StartGettingPorts();
510 session2->StartGettingPorts();
511 // Each session should receive two proxy ports of local and stun.
512 ASSERT_EQ_WAIT(14U, candidates_.size(), kDefaultAllocationTimeout);
513 EXPECT_EQ(8U, ports_.size());
514
515 talk_base::scoped_ptr<cricket::PortAllocatorSession> session3(
516 CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTP));
517 session3->StartGettingPorts();
518 // Already allocated candidates and ports will be sent to the newly
519 // allocated proxy session.
520 ASSERT_EQ_WAIT(21U, candidates_.size(), kDefaultAllocationTimeout);
521 EXPECT_EQ(12U, ports_.size());
522}
523
524// This test verifies by changing ice_ufrag and/or ice_pwd
525// will result in different set of candidates when BUNDLE is enabled.
526// If BUNDLE is disabled, CreateSession will always allocate new
527// set of candidates.
528TEST_F(PortAllocatorTest, TestBundleIceRestart) {
529 AddInterface(kClientAddr);
530 allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_BUNDLE);
531 // Session ID - session1.
532 talk_base::scoped_ptr<cricket::PortAllocatorSession> session1(
533 CreateSession("session1", kContentName,
534 cricket::ICE_CANDIDATE_COMPONENT_RTP,
535 kIceUfrag0, kIcePwd0));
536 session1->StartGettingPorts();
537 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
538 EXPECT_EQ(4U, ports_.size());
539
540 // Allocate a different session with sid |session1| and different ice_ufrag.
541 talk_base::scoped_ptr<cricket::PortAllocatorSession> session2(
542 CreateSession("session1", kContentName,
543 cricket::ICE_CANDIDATE_COMPONENT_RTP,
544 "TestIceUfrag", kIcePwd0));
545 session2->StartGettingPorts();
546 ASSERT_EQ_WAIT(14U, candidates_.size(), kDefaultAllocationTimeout);
547 EXPECT_EQ(8U, ports_.size());
548 // Verifying the candidate address different from previously allocated
549 // address.
550 // Skipping verification of component id and candidate type.
551 EXPECT_NE(candidates_[0].address(), candidates_[7].address());
552 EXPECT_NE(candidates_[1].address(), candidates_[8].address());
553
554 // Allocating a different session with sid |session1| and
555 // different ice_pwd.
556 talk_base::scoped_ptr<cricket::PortAllocatorSession> session3(
557 CreateSession("session1", kContentName,
558 cricket::ICE_CANDIDATE_COMPONENT_RTP,
559 kIceUfrag0, "TestIcePwd"));
560 session3->StartGettingPorts();
561 ASSERT_EQ_WAIT(21U, candidates_.size(), kDefaultAllocationTimeout);
562 EXPECT_EQ(12U, ports_.size());
563 // Verifying the candidate address different from previously
564 // allocated address.
565 EXPECT_NE(candidates_[7].address(), candidates_[14].address());
566 EXPECT_NE(candidates_[8].address(), candidates_[15].address());
567
568 // Allocating a session with by changing both ice_ufrag and ice_pwd.
569 talk_base::scoped_ptr<cricket::PortAllocatorSession> session4(
570 CreateSession("session1", kContentName,
571 cricket::ICE_CANDIDATE_COMPONENT_RTP,
572 "TestIceUfrag", "TestIcePwd"));
573 session4->StartGettingPorts();
574 ASSERT_EQ_WAIT(28U, candidates_.size(), kDefaultAllocationTimeout);
575 EXPECT_EQ(16U, ports_.size());
576 // Verifying the candidate address different from previously
577 // allocated address.
578 EXPECT_NE(candidates_[14].address(), candidates_[21].address());
579 EXPECT_NE(candidates_[15].address(), candidates_[22].address());
580}
581
582// Test that when the PORTALLOCATOR_ENABLE_SHARED_UFRAG is enabled we got same
583// ufrag and pwd for the collected candidates.
584TEST_F(PortAllocatorTest, TestEnableSharedUfrag) {
585 allocator().set_flags(allocator().flags() |
586 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
587 AddInterface(kClientAddr);
588 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
589 session_->StartGettingPorts();
590 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
591 EXPECT_PRED5(CheckCandidate, candidates_[0],
592 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
593 EXPECT_PRED5(CheckCandidate, candidates_[1],
594 cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
595 EXPECT_PRED5(CheckCandidate, candidates_[5],
596 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
597 EXPECT_EQ(4U, ports_.size());
598 EXPECT_EQ(kIceUfrag0, candidates_[0].username());
599 EXPECT_EQ(kIceUfrag0, candidates_[1].username());
600 EXPECT_EQ(kIceUfrag0, candidates_[2].username());
601 EXPECT_EQ(kIcePwd0, candidates_[0].password());
602 EXPECT_EQ(kIcePwd0, candidates_[1].password());
603 EXPECT_TRUE(candidate_allocation_done_);
604}
605
606// Test that when the PORTALLOCATOR_ENABLE_SHARED_UFRAG isn't enabled we got
607// different ufrag and pwd for the collected candidates.
608TEST_F(PortAllocatorTest, TestDisableSharedUfrag) {
609 allocator().set_flags(allocator().flags() &
610 ~cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
611 AddInterface(kClientAddr);
612 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
613 session_->StartGettingPorts();
614 ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
615 EXPECT_PRED5(CheckCandidate, candidates_[0],
616 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
617 EXPECT_PRED5(CheckCandidate, candidates_[1],
618 cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
619 EXPECT_EQ(4U, ports_.size());
620 // Port should generate random ufrag and pwd.
621 EXPECT_NE(kIceUfrag0, candidates_[0].username());
622 EXPECT_NE(kIceUfrag0, candidates_[1].username());
623 EXPECT_NE(candidates_[0].username(), candidates_[1].username());
624 EXPECT_NE(kIcePwd0, candidates_[0].password());
625 EXPECT_NE(kIcePwd0, candidates_[1].password());
626 EXPECT_NE(candidates_[0].password(), candidates_[1].password());
627 EXPECT_TRUE(candidate_allocation_done_);
628}
629
630// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
631// is allocated for udp and stun. Also verify there is only one candidate
632// (local) if stun candidate is same as local candidate, which will be the case
633// in a public network like the below test.
634TEST_F(PortAllocatorTest, TestEnableSharedSocketWithoutNat) {
635 AddInterface(kClientAddr);
636 allocator_->set_flags(allocator().flags() |
637 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
638 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
639 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
640 session_->StartGettingPorts();
641 ASSERT_EQ_WAIT(6U, candidates_.size(), kDefaultAllocationTimeout);
642 EXPECT_EQ(3U, ports_.size());
643 EXPECT_PRED5(CheckCandidate, candidates_[0],
644 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
645 EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
646}
647
648// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
649// is allocated for udp and stun. In this test we should expect both stun and
650// local candidates as client behind a nat.
651TEST_F(PortAllocatorTest, TestEnableSharedSocketWithNat) {
652 AddInterface(kClientAddr);
653 talk_base::scoped_ptr<talk_base::NATServer> nat_server(
654 CreateNatServer(kNatAddr, talk_base::NAT_OPEN_CONE));
655 allocator_.reset(new cricket::BasicPortAllocator(
656 &network_manager_, &nat_socket_factory_, kStunAddr));
657 allocator_->set_step_delay(cricket::kMinimumStepDelay);
658 allocator_->set_flags(allocator().flags() |
659 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
660 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
661 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
662 session_->StartGettingPorts();
663 ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
664 ASSERT_EQ(2U, ports_.size());
665 EXPECT_PRED5(CheckCandidate, candidates_[0],
666 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
667 EXPECT_PRED5(CheckCandidate, candidates_[1],
668 cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
669 talk_base::SocketAddress(kNatAddr.ipaddr(), 0));
670 EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
671 EXPECT_EQ(3U, candidates_.size());
672}
673
674// This test verifies when PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is enabled
675// and fail to generate STUN candidate, local UDP candidate is generated
676// properly.
677TEST_F(PortAllocatorTest, TestEnableSharedSocketNoUdpAllowed) {
678 allocator().set_flags(allocator().flags() |
679 cricket::PORTALLOCATOR_DISABLE_RELAY |
680 cricket::PORTALLOCATOR_DISABLE_TCP |
681 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
682 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
683 fss_->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY, kClientAddr);
684 AddInterface(kClientAddr);
685 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
686 session_->StartGettingPorts();
687 ASSERT_EQ_WAIT(1U, ports_.size(), kDefaultAllocationTimeout);
688 EXPECT_EQ(1U, candidates_.size());
689 EXPECT_PRED5(CheckCandidate, candidates_[0],
690 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
691 // STUN timeout is 9sec. We need to wait to get candidate done signal.
692 EXPECT_TRUE_WAIT(candidate_allocation_done_, 10000);
693 EXPECT_EQ(1U, candidates_.size());
694}
695
wu@webrtc.org97077a32013-10-25 21:18:33 +0000696// This test verifies allocator can use IPv6 addresses along with IPv4.
697TEST_F(PortAllocatorTest, TestEnableIPv6Addresses) {
698 allocator().set_flags(allocator().flags() |
699 cricket::PORTALLOCATOR_DISABLE_RELAY |
700 cricket::PORTALLOCATOR_ENABLE_IPV6 |
701 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
702 cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
703 AddInterface(kClientIPv6Addr);
704 AddInterface(kClientAddr);
705 allocator_->set_step_delay(cricket::kMinimumStepDelay);
706 EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
707 session_->StartGettingPorts();
708 ASSERT_EQ_WAIT(4U, ports_.size(), kDefaultAllocationTimeout);
709 EXPECT_EQ(4U, candidates_.size());
710 EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
711 EXPECT_PRED5(CheckCandidate, candidates_[0],
712 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
713 kClientIPv6Addr);
714 EXPECT_PRED5(CheckCandidate, candidates_[1],
715 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
716 kClientAddr);
717 EXPECT_PRED5(CheckCandidate, candidates_[2],
718 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
719 kClientIPv6Addr);
720 EXPECT_PRED5(CheckCandidate, candidates_[3],
721 cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
722 kClientAddr);
723 EXPECT_EQ(4U, candidates_.size());
724}
725
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726// Test that the httpportallocator correctly maintains its lists of stun and
727// relay servers, by never allowing an empty list.
728TEST(HttpPortAllocatorTest, TestHttpPortAllocatorHostLists) {
729 talk_base::FakeNetworkManager network_manager;
730 cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
731 EXPECT_EQ(1U, alloc.relay_hosts().size());
732 EXPECT_EQ(1U, alloc.stun_hosts().size());
733
734 std::vector<std::string> relay_servers;
735 std::vector<talk_base::SocketAddress> stun_servers;
736
737 alloc.SetRelayHosts(relay_servers);
738 alloc.SetStunHosts(stun_servers);
739 EXPECT_EQ(1U, alloc.relay_hosts().size());
740 EXPECT_EQ(1U, alloc.stun_hosts().size());
741
742 relay_servers.push_back("1.unittest.corp.google.com");
743 relay_servers.push_back("2.unittest.corp.google.com");
744 stun_servers.push_back(
745 talk_base::SocketAddress("1.unittest.corp.google.com", 0));
746 stun_servers.push_back(
747 talk_base::SocketAddress("2.unittest.corp.google.com", 0));
748 alloc.SetRelayHosts(relay_servers);
749 alloc.SetStunHosts(stun_servers);
750 EXPECT_EQ(2U, alloc.relay_hosts().size());
751 EXPECT_EQ(2U, alloc.stun_hosts().size());
752}
753
754// Test that the HttpPortAllocator uses correct URL to create sessions.
755TEST(HttpPortAllocatorTest, TestSessionRequestUrl) {
756 talk_base::FakeNetworkManager network_manager;
757 cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
758
759 // Disable PORTALLOCATOR_ENABLE_SHARED_UFRAG.
760 alloc.set_flags(alloc.flags() & ~cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
761 talk_base::scoped_ptr<cricket::HttpPortAllocatorSessionBase> session(
762 static_cast<cricket::HttpPortAllocatorSession*>(
763 alloc.CreateSessionInternal(
764 "test content", 0, kIceUfrag0, kIcePwd0)));
765 std::string url = session->GetSessionRequestUrl();
766 LOG(LS_INFO) << "url: " << url;
767 EXPECT_EQ(std::string(cricket::HttpPortAllocator::kCreateSessionURL), url);
768
769 // Enable PORTALLOCATOR_ENABLE_SHARED_UFRAG.
770 alloc.set_flags(alloc.flags() | cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
771 session.reset(static_cast<cricket::HttpPortAllocatorSession*>(
772 alloc.CreateSessionInternal("test content", 0, kIceUfrag0, kIcePwd0)));
773 url = session->GetSessionRequestUrl();
774 LOG(LS_INFO) << "url: " << url;
775 std::vector<std::string> parts;
776 talk_base::split(url, '?', &parts);
777 ASSERT_EQ(2U, parts.size());
778
779 std::vector<std::string> args_parts;
780 talk_base::split(parts[1], '&', &args_parts);
781
782 std::map<std::string, std::string> args;
783 for (std::vector<std::string>::iterator it = args_parts.begin();
784 it != args_parts.end(); ++it) {
785 std::vector<std::string> parts;
786 talk_base::split(*it, '=', &parts);
787 ASSERT_EQ(2U, parts.size());
788 args[talk_base::s_url_decode(parts[0])] = talk_base::s_url_decode(parts[1]);
789 }
790
791 EXPECT_EQ(kIceUfrag0, args["username"]);
792 EXPECT_EQ(kIcePwd0, args["password"]);
793}