1 /*
2 * libjingle
3 * Copyright 2004--2005, 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/p2p/client/basicportallocator.h"
29
30 #include <string>
31 #include <vector>
32
33 #include "talk/p2p/base/basicpacketsocketfactory.h"
34 #include "talk/p2p/base/common.h"
35 #include "talk/p2p/base/port.h"
36 #include "talk/p2p/base/relayport.h"
37 #include "talk/p2p/base/stunport.h"
38 #include "talk/p2p/base/tcpport.h"
39 #include "talk/p2p/base/turnport.h"
40 #include "talk/p2p/base/udpport.h"
41 #include "webrtc/base/common.h"
42 #include "webrtc/base/helpers.h"
43 #include "webrtc/base/logging.h"
44
45 using rtc::CreateRandomId;
46 using rtc::CreateRandomString;
47
48 namespace {
49
50 enum {
51 MSG_CONFIG_START,
52 MSG_CONFIG_READY,
53 MSG_ALLOCATE,
54 MSG_ALLOCATION_PHASE,
55 MSG_SHAKE,
56 MSG_SEQUENCEOBJECTS_CREATED,
57 MSG_CONFIG_STOP,
58 };
59
60 const int PHASE_UDP = 0;
61 const int PHASE_RELAY = 1;
62 const int PHASE_TCP = 2;
63 const int PHASE_SSLTCP = 3;
64
65 const int kNumPhases = 4;
66
67 const int SHAKE_MIN_DELAY = 45 * 1000; // 45 seconds
68 const int SHAKE_MAX_DELAY = 90 * 1000; // 90 seconds
69
ShakeDelay()70 int ShakeDelay() {
71 int range = SHAKE_MAX_DELAY - SHAKE_MIN_DELAY + 1;
72 return SHAKE_MIN_DELAY + CreateRandomId() % range;
73 }
74
75 } // namespace
76
77 namespace cricket {
78
79 const uint32 DISABLE_ALL_PHASES =
80 PORTALLOCATOR_DISABLE_UDP
81 | PORTALLOCATOR_DISABLE_TCP
82 | PORTALLOCATOR_DISABLE_STUN
83 | PORTALLOCATOR_DISABLE_RELAY;
84
85 // Performs the allocation of ports, in a sequenced (timed) manner, for a given
86 // network and IP address.
87 class AllocationSequence : public rtc::MessageHandler,
88 public sigslot::has_slots<> {
89 public:
90 enum State {
91 kInit, // Initial state.
92 kRunning, // Started allocating ports.
93 kStopped, // Stopped from running.
94 kCompleted, // All ports are allocated.
95
96 // kInit --> kRunning --> {kCompleted|kStopped}
97 };
98
99 AllocationSequence(BasicPortAllocatorSession* session,
100 rtc::Network* network,
101 PortConfiguration* config,
102 uint32 flags);
103 ~AllocationSequence();
104 bool Init();
105 void Clear();
106
state() const107 State state() const { return state_; }
108
109 // Disables the phases for a new sequence that this one already covers for an
110 // equivalent network setup.
111 void DisableEquivalentPhases(rtc::Network* network,
112 PortConfiguration* config, uint32* flags);
113
114 // Starts and stops the sequence. When started, it will continue allocating
115 // new ports on its own timed schedule.
116 void Start();
117 void Stop();
118
119 // MessageHandler
120 void OnMessage(rtc::Message* msg);
121
122 void EnableProtocol(ProtocolType proto);
123 bool ProtocolEnabled(ProtocolType proto) const;
124
125 // Signal from AllocationSequence, when it's done with allocating ports.
126 // This signal is useful, when port allocation fails which doesn't result
127 // in any candidates. Using this signal BasicPortAllocatorSession can send
128 // its candidate discovery conclusion signal. Without this signal,
129 // BasicPortAllocatorSession doesn't have any event to trigger signal. This
130 // can also be achieved by starting timer in BPAS.
131 sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
132
133 private:
134 typedef std::vector<ProtocolType> ProtocolList;
135
IsFlagSet(uint32 flag)136 bool IsFlagSet(uint32 flag) {
137 return ((flags_ & flag) != 0);
138 }
139 void CreateUDPPorts();
140 void CreateTCPPorts();
141 void CreateStunPorts();
142 void CreateRelayPorts();
143 void CreateGturnPort(const RelayServerConfig& config);
144 void CreateTurnPort(const RelayServerConfig& config);
145
146 void OnReadPacket(rtc::AsyncPacketSocket* socket,
147 const char* data, size_t size,
148 const rtc::SocketAddress& remote_addr,
149 const rtc::PacketTime& packet_time);
150
151 void OnPortDestroyed(PortInterface* port);
152
153 BasicPortAllocatorSession* session_;
154 rtc::Network* network_;
155 rtc::IPAddress ip_;
156 PortConfiguration* config_;
157 State state_;
158 uint32 flags_;
159 ProtocolList protocols_;
160 rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
161 // There will be only one udp port per AllocationSequence.
162 UDPPort* udp_port_;
163 std::vector<TurnPort*> turn_ports_;
164 int phase_;
165 };
166
167 // BasicPortAllocator
BasicPortAllocator(rtc::NetworkManager * network_manager,rtc::PacketSocketFactory * socket_factory)168 BasicPortAllocator::BasicPortAllocator(
169 rtc::NetworkManager* network_manager,
170 rtc::PacketSocketFactory* socket_factory)
171 : network_manager_(network_manager),
172 socket_factory_(socket_factory) {
173 ASSERT(socket_factory_ != NULL);
174 Construct();
175 }
176
BasicPortAllocator(rtc::NetworkManager * network_manager)177 BasicPortAllocator::BasicPortAllocator(
178 rtc::NetworkManager* network_manager)
179 : network_manager_(network_manager),
180 socket_factory_(NULL) {
181 Construct();
182 }
183
BasicPortAllocator(rtc::NetworkManager * network_manager,rtc::PacketSocketFactory * socket_factory,const ServerAddresses & stun_servers)184 BasicPortAllocator::BasicPortAllocator(
185 rtc::NetworkManager* network_manager,
186 rtc::PacketSocketFactory* socket_factory,
187 const ServerAddresses& stun_servers)
188 : network_manager_(network_manager),
189 socket_factory_(socket_factory),
190 stun_servers_(stun_servers) {
191 ASSERT(socket_factory_ != NULL);
192 Construct();
193 }
194
BasicPortAllocator(rtc::NetworkManager * network_manager,const ServerAddresses & stun_servers,const rtc::SocketAddress & relay_address_udp,const rtc::SocketAddress & relay_address_tcp,const rtc::SocketAddress & relay_address_ssl)195 BasicPortAllocator::BasicPortAllocator(
196 rtc::NetworkManager* network_manager,
197 const ServerAddresses& stun_servers,
198 const rtc::SocketAddress& relay_address_udp,
199 const rtc::SocketAddress& relay_address_tcp,
200 const rtc::SocketAddress& relay_address_ssl)
201 : network_manager_(network_manager),
202 socket_factory_(NULL),
203 stun_servers_(stun_servers) {
204
205 RelayServerConfig config(RELAY_GTURN);
206 if (!relay_address_udp.IsNil())
207 config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP));
208 if (!relay_address_tcp.IsNil())
209 config.ports.push_back(ProtocolAddress(relay_address_tcp, PROTO_TCP));
210 if (!relay_address_ssl.IsNil())
211 config.ports.push_back(ProtocolAddress(relay_address_ssl, PROTO_SSLTCP));
212
213 if (!config.ports.empty())
214 AddRelay(config);
215
216 Construct();
217 }
218
Construct()219 void BasicPortAllocator::Construct() {
220 allow_tcp_listen_ = true;
221 }
222
~BasicPortAllocator()223 BasicPortAllocator::~BasicPortAllocator() {
224 }
225
CreateSessionInternal(const std::string & content_name,int component,const std::string & ice_ufrag,const std::string & ice_pwd)226 PortAllocatorSession *BasicPortAllocator::CreateSessionInternal(
227 const std::string& content_name, int component,
228 const std::string& ice_ufrag, const std::string& ice_pwd) {
229 return new BasicPortAllocatorSession(
230 this, content_name, component, ice_ufrag, ice_pwd);
231 }
232
233
234 // BasicPortAllocatorSession
BasicPortAllocatorSession(BasicPortAllocator * allocator,const std::string & content_name,int component,const std::string & ice_ufrag,const std::string & ice_pwd)235 BasicPortAllocatorSession::BasicPortAllocatorSession(
236 BasicPortAllocator *allocator,
237 const std::string& content_name,
238 int component,
239 const std::string& ice_ufrag,
240 const std::string& ice_pwd)
241 : PortAllocatorSession(content_name, component,
242 ice_ufrag, ice_pwd, allocator->flags()),
243 allocator_(allocator), network_thread_(NULL),
244 socket_factory_(allocator->socket_factory()),
245 allocation_started_(false),
246 network_manager_started_(false),
247 running_(false),
248 allocation_sequences_created_(false) {
249 allocator_->network_manager()->SignalNetworksChanged.connect(
250 this, &BasicPortAllocatorSession::OnNetworksChanged);
251 allocator_->network_manager()->StartUpdating();
252 }
253
~BasicPortAllocatorSession()254 BasicPortAllocatorSession::~BasicPortAllocatorSession() {
255 allocator_->network_manager()->StopUpdating();
256 if (network_thread_ != NULL)
257 network_thread_->Clear(this);
258
259 for (uint32 i = 0; i < sequences_.size(); ++i) {
260 // AllocationSequence should clear it's map entry for turn ports before
261 // ports are destroyed.
262 sequences_[i]->Clear();
263 }
264
265 std::vector<PortData>::iterator it;
266 for (it = ports_.begin(); it != ports_.end(); it++)
267 delete it->port();
268
269 for (uint32 i = 0; i < configs_.size(); ++i)
270 delete configs_[i];
271
272 for (uint32 i = 0; i < sequences_.size(); ++i)
273 delete sequences_[i];
274 }
275
StartGettingPorts()276 void BasicPortAllocatorSession::StartGettingPorts() {
277 network_thread_ = rtc::Thread::Current();
278 if (!socket_factory_) {
279 owned_socket_factory_.reset(
280 new rtc::BasicPacketSocketFactory(network_thread_));
281 socket_factory_ = owned_socket_factory_.get();
282 }
283
284 running_ = true;
285 network_thread_->Post(this, MSG_CONFIG_START);
286
287 if (flags() & PORTALLOCATOR_ENABLE_SHAKER)
288 network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
289 }
290
StopGettingPorts()291 void BasicPortAllocatorSession::StopGettingPorts() {
292 ASSERT(rtc::Thread::Current() == network_thread_);
293 running_ = false;
294 network_thread_->Clear(this, MSG_ALLOCATE);
295 for (uint32 i = 0; i < sequences_.size(); ++i)
296 sequences_[i]->Stop();
297 network_thread_->Post(this, MSG_CONFIG_STOP);
298 }
299
OnMessage(rtc::Message * message)300 void BasicPortAllocatorSession::OnMessage(rtc::Message *message) {
301 switch (message->message_id) {
302 case MSG_CONFIG_START:
303 ASSERT(rtc::Thread::Current() == network_thread_);
304 GetPortConfigurations();
305 break;
306
307 case MSG_CONFIG_READY:
308 ASSERT(rtc::Thread::Current() == network_thread_);
309 OnConfigReady(static_cast<PortConfiguration*>(message->pdata));
310 break;
311
312 case MSG_ALLOCATE:
313 ASSERT(rtc::Thread::Current() == network_thread_);
314 OnAllocate();
315 break;
316
317 case MSG_SHAKE:
318 ASSERT(rtc::Thread::Current() == network_thread_);
319 OnShake();
320 break;
321 case MSG_SEQUENCEOBJECTS_CREATED:
322 ASSERT(rtc::Thread::Current() == network_thread_);
323 OnAllocationSequenceObjectsCreated();
324 break;
325 case MSG_CONFIG_STOP:
326 ASSERT(rtc::Thread::Current() == network_thread_);
327 OnConfigStop();
328 break;
329 default:
330 ASSERT(false);
331 }
332 }
333
GetPortConfigurations()334 void BasicPortAllocatorSession::GetPortConfigurations() {
335 PortConfiguration* config = new PortConfiguration(allocator_->stun_servers(),
336 username(),
337 password());
338
339 for (size_t i = 0; i < allocator_->relays().size(); ++i) {
340 config->AddRelay(allocator_->relays()[i]);
341 }
342 ConfigReady(config);
343 }
344
ConfigReady(PortConfiguration * config)345 void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
346 network_thread_->Post(this, MSG_CONFIG_READY, config);
347 }
348
349 // Adds a configuration to the list.
OnConfigReady(PortConfiguration * config)350 void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
351 if (config)
352 configs_.push_back(config);
353
354 AllocatePorts();
355 }
356
OnConfigStop()357 void BasicPortAllocatorSession::OnConfigStop() {
358 ASSERT(rtc::Thread::Current() == network_thread_);
359
360 // If any of the allocated ports have not completed the candidates allocation,
361 // mark those as error. Since session doesn't need any new candidates
362 // at this stage of the allocation, it's safe to discard any new candidates.
363 bool send_signal = false;
364 for (std::vector<PortData>::iterator it = ports_.begin();
365 it != ports_.end(); ++it) {
366 if (!it->complete()) {
367 // Updating port state to error, which didn't finish allocating candidates
368 // yet.
369 it->set_error();
370 send_signal = true;
371 }
372 }
373
374 // Did we stop any running sequences?
375 for (std::vector<AllocationSequence*>::iterator it = sequences_.begin();
376 it != sequences_.end() && !send_signal; ++it) {
377 if ((*it)->state() == AllocationSequence::kStopped) {
378 send_signal = true;
379 }
380 }
381
382 // If we stopped anything that was running, send a done signal now.
383 if (send_signal) {
384 MaybeSignalCandidatesAllocationDone();
385 }
386 }
387
AllocatePorts()388 void BasicPortAllocatorSession::AllocatePorts() {
389 ASSERT(rtc::Thread::Current() == network_thread_);
390 network_thread_->Post(this, MSG_ALLOCATE);
391 }
392
OnAllocate()393 void BasicPortAllocatorSession::OnAllocate() {
394 if (network_manager_started_)
395 DoAllocate();
396
397 allocation_started_ = true;
398 }
399
400 // For each network, see if we have a sequence that covers it already. If not,
401 // create a new sequence to create the appropriate ports.
DoAllocate()402 void BasicPortAllocatorSession::DoAllocate() {
403 bool done_signal_needed = false;
404 std::vector<rtc::Network*> networks;
405 allocator_->network_manager()->GetNetworks(&networks);
406 if (networks.empty()) {
407 LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
408 done_signal_needed = true;
409 } else {
410 for (uint32 i = 0; i < networks.size(); ++i) {
411 PortConfiguration* config = NULL;
412 if (configs_.size() > 0)
413 config = configs_.back();
414
415 uint32 sequence_flags = flags();
416 if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
417 // If all the ports are disabled we should just fire the allocation
418 // done event and return.
419 done_signal_needed = true;
420 break;
421 }
422
423 // Disables phases that are not specified in this config.
424 if (!config || config->StunServers().empty()) {
425 // No STUN ports specified in this config.
426 sequence_flags |= PORTALLOCATOR_DISABLE_STUN;
427 }
428 if (!config || config->relays.empty()) {
429 // No relay ports specified in this config.
430 sequence_flags |= PORTALLOCATOR_DISABLE_RELAY;
431 }
432
433 if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6) &&
434 #ifdef USE_WEBRTC_DEV_BRANCH
435 networks[i]->GetBestIP().family() == AF_INET6) {
436 #else // USE_WEBRTC_DEV_BRANCH
437 networks[i]->ip().family() == AF_INET6) {
438 #endif // USE_WEBRTC_DEV_BRANCH
439 // Skip IPv6 networks unless the flag's been set.
440 continue;
441 }
442
443 // Disable phases that would only create ports equivalent to
444 // ones that we have already made.
445 DisableEquivalentPhases(networks[i], config, &sequence_flags);
446
447 if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
448 // New AllocationSequence would have nothing to do, so don't make it.
449 continue;
450 }
451
452 AllocationSequence* sequence =
453 new AllocationSequence(this, networks[i], config, sequence_flags);
454 if (!sequence->Init()) {
455 delete sequence;
456 continue;
457 }
458 done_signal_needed = true;
459 sequence->SignalPortAllocationComplete.connect(
460 this, &BasicPortAllocatorSession::OnPortAllocationComplete);
461 if (running_)
462 sequence->Start();
463 sequences_.push_back(sequence);
464 }
465 }
466 if (done_signal_needed) {
467 network_thread_->Post(this, MSG_SEQUENCEOBJECTS_CREATED);
468 }
469 }
470
471 void BasicPortAllocatorSession::OnNetworksChanged() {
472 network_manager_started_ = true;
473 if (allocation_started_)
474 DoAllocate();
475 }
476
477 void BasicPortAllocatorSession::DisableEquivalentPhases(
478 rtc::Network* network, PortConfiguration* config, uint32* flags) {
479 for (uint32 i = 0; i < sequences_.size() &&
480 (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; ++i) {
481 sequences_[i]->DisableEquivalentPhases(network, config, flags);
482 }
483 }
484
485 void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
486 AllocationSequence * seq,
487 bool prepare_address) {
488 if (!port)
489 return;
490
491 LOG(LS_INFO) << "Adding allocated port for " << content_name();
492 port->set_content_name(content_name());
493 port->set_component(component_);
494 port->set_generation(generation());
495 if (allocator_->proxy().type != rtc::PROXY_NONE)
496 port->set_proxy(allocator_->user_agent(), allocator_->proxy());
497 port->set_send_retransmit_count_attribute((allocator_->flags() &
498 PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
499
500 PortData data(port, seq);
501 ports_.push_back(data);
502
503 port->SignalCandidateReady.connect(
504 this, &BasicPortAllocatorSession::OnCandidateReady);
505 port->SignalPortComplete.connect(this,
506 &BasicPortAllocatorSession::OnPortComplete);
507 port->SignalDestroyed.connect(this,
508 &BasicPortAllocatorSession::OnPortDestroyed);
509 port->SignalPortError.connect(
510 this, &BasicPortAllocatorSession::OnPortError);
511 LOG_J(LS_INFO, port) << "Added port to allocator";
512
513 if (prepare_address)
514 port->PrepareAddress();
515 }
516
517 void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() {
518 allocation_sequences_created_ = true;
519 // Send candidate allocation complete signal if we have no sequences.
520 MaybeSignalCandidatesAllocationDone();
521 }
522
523 void BasicPortAllocatorSession::OnCandidateReady(
524 Port* port, const Candidate& c) {
525 ASSERT(rtc::Thread::Current() == network_thread_);
526 PortData* data = FindPort(port);
527 ASSERT(data != NULL);
528 // Discarding any candidate signal if port allocation status is
529 // already in completed state.
530 if (data->complete())
531 return;
532
533 // Send candidates whose protocol is enabled.
534 std::vector<Candidate> candidates;
535 ProtocolType pvalue;
536 bool candidate_allowed_to_send = CheckCandidateFilter(c);
537 if (StringToProto(c.protocol().c_str(), &pvalue) &&
538 data->sequence()->ProtocolEnabled(pvalue) &&
539 candidate_allowed_to_send) {
540 candidates.push_back(c);
541 }
542
543 if (!candidates.empty()) {
544 SignalCandidatesReady(this, candidates);
545 }
546
547 // Moving to READY state as we have atleast one candidate from the port.
548 // Since this port has atleast one candidate we should forward this port
549 // to listners, to allow connections from this port.
550 // Also we should make sure that candidate gathered from this port is allowed
551 // to send outside.
552 if (!data->ready() && candidate_allowed_to_send) {
553 data->set_ready();
554 SignalPortReady(this, port);
555 }
556 }
557
558 void BasicPortAllocatorSession::OnPortComplete(Port* port) {
559 ASSERT(rtc::Thread::Current() == network_thread_);
560 PortData* data = FindPort(port);
561 ASSERT(data != NULL);
562
563 // Ignore any late signals.
564 if (data->complete())
565 return;
566
567 // Moving to COMPLETE state.
568 data->set_complete();
569 // Send candidate allocation complete signal if this was the last port.
570 MaybeSignalCandidatesAllocationDone();
571 }
572
573 void BasicPortAllocatorSession::OnPortError(Port* port) {
574 ASSERT(rtc::Thread::Current() == network_thread_);
575 PortData* data = FindPort(port);
576 ASSERT(data != NULL);
577 // We might have already given up on this port and stopped it.
578 if (data->complete())
579 return;
580
581 // SignalAddressError is currently sent from StunPort/TurnPort.
582 // But this signal itself is generic.
583 data->set_error();
584 // Send candidate allocation complete signal if this was the last port.
585 MaybeSignalCandidatesAllocationDone();
586 }
587
588 void BasicPortAllocatorSession::OnProtocolEnabled(AllocationSequence* seq,
589 ProtocolType proto) {
590 std::vector<Candidate> candidates;
591 for (std::vector<PortData>::iterator it = ports_.begin();
592 it != ports_.end(); ++it) {
593 if (it->sequence() != seq)
594 continue;
595
596 const std::vector<Candidate>& potentials = it->port()->Candidates();
597 for (size_t i = 0; i < potentials.size(); ++i) {
598 if (!CheckCandidateFilter(potentials[i]))
599 continue;
600 ProtocolType pvalue;
601 if (!StringToProto(potentials[i].protocol().c_str(), &pvalue))
602 continue;
603 if (pvalue == proto) {
604 candidates.push_back(potentials[i]);
605 }
606 }
607 }
608
609 if (!candidates.empty()) {
610 SignalCandidatesReady(this, candidates);
611 }
612 }
613
614 bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) {
615 uint32 filter = allocator_->candidate_filter();
616 bool allowed = false;
617 if (filter & CF_RELAY) {
618 allowed |= (c.type() == RELAY_PORT_TYPE);
619 }
620
621 if (filter & CF_REFLEXIVE) {
622 // We allow host candidates if the filter allows server-reflexive candidates
623 // and the candidate is a public IP. Because we don't generate
624 // server-reflexive candidates if they have the same IP as the host
625 // candidate (i.e. when the host candidate is a public IP), filtering to
626 // only server-reflexive candidates won't work right when the host
627 // candidates have public IPs.
628 allowed |= (c.type() == STUN_PORT_TYPE) ||
629 (c.type() == LOCAL_PORT_TYPE && !c.address().IsPrivateIP());
630 }
631
632 if (filter & CF_HOST) {
633 allowed |= (c.type() == LOCAL_PORT_TYPE);
634 }
635
636 return allowed;
637 }
638
639 void BasicPortAllocatorSession::OnPortAllocationComplete(
640 AllocationSequence* seq) {
641 // Send candidate allocation complete signal if all ports are done.
642 MaybeSignalCandidatesAllocationDone();
643 }
644
645 void BasicPortAllocatorSession::MaybeSignalCandidatesAllocationDone() {
646 // Send signal only if all required AllocationSequence objects
647 // are created.
648 if (!allocation_sequences_created_)
649 return;
650
651 // Check that all port allocation sequences are complete.
652 for (std::vector<AllocationSequence*>::iterator it = sequences_.begin();
653 it != sequences_.end(); ++it) {
654 if ((*it)->state() == AllocationSequence::kRunning)
655 return;
656 }
657
658 // If all allocated ports are in complete state, session must have got all
659 // expected candidates. Session will trigger candidates allocation complete
660 // signal.
661 for (std::vector<PortData>::iterator it = ports_.begin();
662 it != ports_.end(); ++it) {
663 if (!it->complete())
664 return;
665 }
666 LOG(LS_INFO) << "All candidates gathered for " << content_name_ << ":"
667 << component_ << ":" << generation();
668 SignalCandidatesAllocationDone(this);
669 }
670
671 void BasicPortAllocatorSession::OnPortDestroyed(
672 PortInterface* port) {
673 ASSERT(rtc::Thread::Current() == network_thread_);
674 for (std::vector<PortData>::iterator iter = ports_.begin();
675 iter != ports_.end(); ++iter) {
676 if (port == iter->port()) {
677 ports_.erase(iter);
678 LOG_J(LS_INFO, port) << "Removed port from allocator ("
679 << static_cast<int>(ports_.size()) << " remaining)";
680 return;
681 }
682 }
683 ASSERT(false);
684 }
685
686 void BasicPortAllocatorSession::OnShake() {
687 LOG(INFO) << ">>>>> SHAKE <<<<< >>>>> SHAKE <<<<< >>>>> SHAKE <<<<<";
688
689 std::vector<Port*> ports;
690 std::vector<Connection*> connections;
691
692 for (size_t i = 0; i < ports_.size(); ++i) {
693 if (ports_[i].ready())
694 ports.push_back(ports_[i].port());
695 }
696
697 for (size_t i = 0; i < ports.size(); ++i) {
698 Port::AddressMap::const_iterator iter;
699 for (iter = ports[i]->connections().begin();
700 iter != ports[i]->connections().end();
701 ++iter) {
702 connections.push_back(iter->second);
703 }
704 }
705
706 LOG(INFO) << ">>>>> Destroying " << ports.size() << " ports and "
707 << connections.size() << " connections";
708
709 for (size_t i = 0; i < connections.size(); ++i)
710 connections[i]->Destroy();
711
712 if (running_ || (ports.size() > 0) || (connections.size() > 0))
713 network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
714 }
715
716 BasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort(
717 Port* port) {
718 for (std::vector<PortData>::iterator it = ports_.begin();
719 it != ports_.end(); ++it) {
720 if (it->port() == port) {
721 return &*it;
722 }
723 }
724 return NULL;
725 }
726
727 // AllocationSequence
728
729 AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
730 rtc::Network* network,
731 PortConfiguration* config,
732 uint32 flags)
733 : session_(session),
734 network_(network),
735
736 #ifdef USE_WEBRTC_DEV_BRANCH
737 ip_(network->GetBestIP()),
738 #else // USE_WEBRTC_DEV_BRANCH
739 ip_(network->ip()),
740 #endif // USE_WEBRTC_DEV_BRANCH
741 config_(config),
742 state_(kInit),
743 flags_(flags),
744 udp_socket_(),
745 udp_port_(NULL),
746 phase_(0) {
747 }
748
749 bool AllocationSequence::Init() {
750 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
751 !IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_UFRAG)) {
752 LOG(LS_ERROR) << "Shared socket option can't be set without "
753 << "shared ufrag.";
754 ASSERT(false);
755 return false;
756 }
757
758 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
759 udp_socket_.reset(session_->socket_factory()->CreateUdpSocket(
760 rtc::SocketAddress(ip_, 0), session_->allocator()->min_port(),
761 session_->allocator()->max_port()));
762 if (udp_socket_) {
763 udp_socket_->SignalReadPacket.connect(
764 this, &AllocationSequence::OnReadPacket);
765 }
766 // Continuing if |udp_socket_| is NULL, as local TCP and RelayPort using TCP
767 // are next available options to setup a communication channel.
768 }
769 return true;
770 }
771
772 void AllocationSequence::Clear() {
773 udp_port_ = NULL;
774 turn_ports_.clear();
775 }
776
777 AllocationSequence::~AllocationSequence() {
778 session_->network_thread()->Clear(this);
779 }
780
781 void AllocationSequence::DisableEquivalentPhases(rtc::Network* network,
782 PortConfiguration* config, uint32* flags) {
783 #ifdef USE_WEBRTC_DEV_BRANCH
784 if (!((network == network_) && (ip_ == network->GetBestIP()))) {
785 #else // USE_WEBRTC_DEV_BRANCH
786 if (!((network == network_) && (ip_ == network->ip()))) {
787 #endif // USE_WEBRTC_DEV_BRANCH
788 // Different network setup; nothing is equivalent.
789 return;
790 }
791
792 // Else turn off the stuff that we've already got covered.
793
794 // Every config implicitly specifies local, so turn that off right away.
795 *flags |= PORTALLOCATOR_DISABLE_UDP;
796 *flags |= PORTALLOCATOR_DISABLE_TCP;
797
798 if (config_ && config) {
799 if (config_->StunServers() == config->StunServers()) {
800 // Already got this STUN servers covered.
801 *flags |= PORTALLOCATOR_DISABLE_STUN;
802 }
803 if (!config_->relays.empty()) {
804 // Already got relays covered.
805 // NOTE: This will even skip a _different_ set of relay servers if we
806 // were to be given one, but that never happens in our codebase. Should
807 // probably get rid of the list in PortConfiguration and just keep a
808 // single relay server in each one.
809 *flags |= PORTALLOCATOR_DISABLE_RELAY;
810 }
811 }
812 }
813
814 void AllocationSequence::Start() {
815 state_ = kRunning;
816 session_->network_thread()->Post(this, MSG_ALLOCATION_PHASE);
817 }
818
819 void AllocationSequence::Stop() {
820 // If the port is completed, don't set it to stopped.
821 if (state_ == kRunning) {
822 state_ = kStopped;
823 session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE);
824 }
825 }
826
827 void AllocationSequence::OnMessage(rtc::Message* msg) {
828 ASSERT(rtc::Thread::Current() == session_->network_thread());
829 ASSERT(msg->message_id == MSG_ALLOCATION_PHASE);
830
831 const char* const PHASE_NAMES[kNumPhases] = {
832 "Udp", "Relay", "Tcp", "SslTcp"
833 };
834
835 // Perform all of the phases in the current step.
836 LOG_J(LS_INFO, network_) << "Allocation Phase="
837 << PHASE_NAMES[phase_];
838
839 switch (phase_) {
840 case PHASE_UDP:
841 CreateUDPPorts();
842 CreateStunPorts();
843 EnableProtocol(PROTO_UDP);
844 break;
845
846 case PHASE_RELAY:
847 CreateRelayPorts();
848 break;
849
850 case PHASE_TCP:
851 CreateTCPPorts();
852 EnableProtocol(PROTO_TCP);
853 break;
854
855 case PHASE_SSLTCP:
856 state_ = kCompleted;
857 EnableProtocol(PROTO_SSLTCP);
858 break;
859
860 default:
861 ASSERT(false);
862 }
863
864 if (state() == kRunning) {
865 ++phase_;
866 session_->network_thread()->PostDelayed(
867 session_->allocator()->step_delay(),
868 this, MSG_ALLOCATION_PHASE);
869 } else {
870 // If all phases in AllocationSequence are completed, no allocation
871 // steps needed further. Canceling pending signal.
872 session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE);
873 SignalPortAllocationComplete(this);
874 }
875 }
876
877 void AllocationSequence::EnableProtocol(ProtocolType proto) {
878 if (!ProtocolEnabled(proto)) {
879 protocols_.push_back(proto);
880 session_->OnProtocolEnabled(this, proto);
881 }
882 }
883
884 bool AllocationSequence::ProtocolEnabled(ProtocolType proto) const {
885 for (ProtocolList::const_iterator it = protocols_.begin();
886 it != protocols_.end(); ++it) {
887 if (*it == proto)
888 return true;
889 }
890 return false;
891 }
892
893 void AllocationSequence::CreateUDPPorts() {
894 if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP)) {
895 LOG(LS_VERBOSE) << "AllocationSequence: UDP ports disabled, skipping.";
896 return;
897 }
898
899 // TODO(mallinath) - Remove UDPPort creating socket after shared socket
900 // is enabled completely.
901 UDPPort* port = NULL;
902 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) {
903 port = UDPPort::Create(session_->network_thread(),
904 session_->socket_factory(), network_,
905 udp_socket_.get(),
906 session_->username(), session_->password());
907 } else {
908 port = UDPPort::Create(session_->network_thread(),
909 session_->socket_factory(),
910 network_, ip_,
911 session_->allocator()->min_port(),
912 session_->allocator()->max_port(),
913 session_->username(), session_->password());
914 }
915
916 if (port) {
917 // If shared socket is enabled, STUN candidate will be allocated by the
918 // UDPPort.
919 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
920 udp_port_ = port;
921
922 // If STUN is not disabled, setting stun server address to port.
923 if (!IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
924 // If config has stun_servers, use it to get server reflexive candidate
925 // otherwise use first TURN server which supports UDP.
926 if (config_ && !config_->StunServers().empty()) {
927 LOG(LS_INFO) << "AllocationSequence: UDPPort will be handling the "
928 << "STUN candidate generation.";
929 port->set_server_addresses(config_->StunServers());
930 } else if (config_ &&
931 config_->SupportsProtocol(RELAY_TURN, PROTO_UDP)) {
932 port->set_server_addresses(config_->GetRelayServerAddresses(
933 RELAY_TURN, PROTO_UDP));
934 LOG(LS_INFO) << "AllocationSequence: TURN Server address will be "
935 << " used for generating STUN candidate.";
936 }
937 }
938 }
939
940 session_->AddAllocatedPort(port, this, true);
941 port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
942 }
943 }
944
945 void AllocationSequence::CreateTCPPorts() {
946 if (IsFlagSet(PORTALLOCATOR_DISABLE_TCP)) {
947 LOG(LS_VERBOSE) << "AllocationSequence: TCP ports disabled, skipping.";
948 return;
949 }
950
951 Port* port = TCPPort::Create(session_->network_thread(),
952 session_->socket_factory(),
953 network_, ip_,
954 session_->allocator()->min_port(),
955 session_->allocator()->max_port(),
956 session_->username(), session_->password(),
957 session_->allocator()->allow_tcp_listen());
958 if (port) {
959 session_->AddAllocatedPort(port, this, true);
960 // Since TCPPort is not created using shared socket, |port| will not be
961 // added to the dequeue.
962 }
963 }
964
965 void AllocationSequence::CreateStunPorts() {
966 if (IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
967 LOG(LS_VERBOSE) << "AllocationSequence: STUN ports disabled, skipping.";
968 return;
969 }
970
971 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
972 return;
973 }
974
975 // If BasicPortAllocatorSession::OnAllocate left STUN ports enabled then we
976 // ought to have an address for them here.
977 ASSERT(config_ && !config_->StunServers().empty());
978 if (!(config_ && !config_->StunServers().empty())) {
979 LOG(LS_WARNING)
980 << "AllocationSequence: No STUN server configured, skipping.";
981 return;
982 }
983
984 StunPort* port = StunPort::Create(session_->network_thread(),
985 session_->socket_factory(),
986 network_, ip_,
987 session_->allocator()->min_port(),
988 session_->allocator()->max_port(),
989 session_->username(), session_->password(),
990 config_->StunServers());
991 if (port) {
992 session_->AddAllocatedPort(port, this, true);
993 // Since StunPort is not created using shared socket, |port| will not be
994 // added to the dequeue.
995 }
996 }
997
998 void AllocationSequence::CreateRelayPorts() {
999 if (IsFlagSet(PORTALLOCATOR_DISABLE_RELAY)) {
1000 LOG(LS_VERBOSE) << "AllocationSequence: Relay ports disabled, skipping.";
1001 return;
1002 }
1003
1004 // If BasicPortAllocatorSession::OnAllocate left relay ports enabled then we
1005 // ought to have a relay list for them here.
1006 ASSERT(config_ && !config_->relays.empty());
1007 if (!(config_ && !config_->relays.empty())) {
1008 LOG(LS_WARNING)
1009 << "AllocationSequence: No relay server configured, skipping.";
1010 return;
1011 }
1012
1013 PortConfiguration::RelayList::const_iterator relay;
1014 for (relay = config_->relays.begin();
1015 relay != config_->relays.end(); ++relay) {
1016 if (relay->type == RELAY_GTURN) {
1017 CreateGturnPort(*relay);
1018 } else if (relay->type == RELAY_TURN) {
1019 CreateTurnPort(*relay);
1020 } else {
1021 ASSERT(false);
1022 }
1023 }
1024 }
1025
1026 void AllocationSequence::CreateGturnPort(const RelayServerConfig& config) {
1027 // TODO(mallinath) - Rename RelayPort to GTurnPort.
1028 RelayPort* port = RelayPort::Create(session_->network_thread(),
1029 session_->socket_factory(),
1030 network_, ip_,
1031 session_->allocator()->min_port(),
1032 session_->allocator()->max_port(),
1033 config_->username, config_->password);
1034 if (port) {
1035 // Since RelayPort is not created using shared socket, |port| will not be
1036 // added to the dequeue.
1037 // Note: We must add the allocated port before we add addresses because
1038 // the latter will create candidates that need name and preference
1039 // settings. However, we also can't prepare the address (normally
1040 // done by AddAllocatedPort) until we have these addresses. So we
1041 // wait to do that until below.
1042 session_->AddAllocatedPort(port, this, false);
1043
1044 // Add the addresses of this protocol.
1045 PortList::const_iterator relay_port;
1046 for (relay_port = config.ports.begin();
1047 relay_port != config.ports.end();
1048 ++relay_port) {
1049 port->AddServerAddress(*relay_port);
1050 port->AddExternalAddress(*relay_port);
1051 }
1052 // Start fetching an address for this port.
1053 port->PrepareAddress();
1054 }
1055 }
1056
1057 void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
1058 PortList::const_iterator relay_port;
1059 for (relay_port = config.ports.begin();
1060 relay_port != config.ports.end(); ++relay_port) {
1061 TurnPort* port = NULL;
1062 // Shared socket mode must be enabled only for UDP based ports. Hence
1063 // don't pass shared socket for ports which will create TCP sockets.
1064 // TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled
1065 // due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537
1066 if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
1067 relay_port->proto == PROTO_UDP) {
1068 port = TurnPort::Create(session_->network_thread(),
1069 session_->socket_factory(),
1070 network_, udp_socket_.get(),
1071 session_->username(), session_->password(),
1072 *relay_port, config.credentials, config.priority);
1073
1074 turn_ports_.push_back(port);
1075 // Listen to the port destroyed signal, to allow AllocationSequence to
1076 // remove entrt from it's map.
1077 port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
1078 } else {
1079 port = TurnPort::Create(session_->network_thread(),
1080 session_->socket_factory(),
1081 network_, ip_,
1082 session_->allocator()->min_port(),
1083 session_->allocator()->max_port(),
1084 session_->username(),
1085 session_->password(),
1086 *relay_port, config.credentials, config.priority);
1087 }
1088 ASSERT(port != NULL);
1089 session_->AddAllocatedPort(port, this, true);
1090 }
1091 }
1092
1093 void AllocationSequence::OnReadPacket(
1094 rtc::AsyncPacketSocket* socket, const char* data, size_t size,
1095 const rtc::SocketAddress& remote_addr,
1096 const rtc::PacketTime& packet_time) {
1097 ASSERT(socket == udp_socket_.get());
1098
1099 bool turn_port_found = false;
1100
1101 // Try to find the TurnPort that matches the remote address. Note that the
1102 // message could be a STUN binding response if the TURN server is also used as
1103 // a STUN server. We don't want to parse every message here to check if it is
1104 // a STUN binding response, so we pass the message to TurnPort regardless of
1105 // the message type. The TurnPort will just ignore the message since it will
1106 // not find any request by transaction ID.
1107 for (std::vector<TurnPort*>::const_iterator it = turn_ports_.begin();
1108 it != turn_ports_.end(); ++it) {
1109 TurnPort* port = *it;
1110 if (port->server_address().address == remote_addr) {
1111 port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time);
1112 turn_port_found = true;
1113 break;
1114 }
1115 }
1116
1117 if (udp_port_) {
1118 const ServerAddresses& stun_servers = udp_port_->server_addresses();
1119
1120 // Pass the packet to the UdpPort if there is no matching TurnPort, or if
1121 // the TURN server is also a STUN server.
1122 if (!turn_port_found ||
1123 stun_servers.find(remote_addr) != stun_servers.end()) {
1124 udp_port_->HandleIncomingPacket(
1125 socket, data, size, remote_addr, packet_time);
1126 }
1127 }
1128 }
1129
1130 void AllocationSequence::OnPortDestroyed(PortInterface* port) {
1131 if (udp_port_ == port) {
1132 udp_port_ = NULL;
1133 return;
1134 }
1135
1136 turn_ports_.erase(std::find(turn_ports_.begin(), turn_ports_.end(), port));
1137 }
1138
1139 // PortConfiguration
1140 PortConfiguration::PortConfiguration(
1141 const rtc::SocketAddress& stun_address,
1142 const std::string& username,
1143 const std::string& password)
1144 : stun_address(stun_address), username(username), password(password) {
1145 if (!stun_address.IsNil())
1146 stun_servers.insert(stun_address);
1147 }
1148
1149 PortConfiguration::PortConfiguration(const ServerAddresses& stun_servers,
1150 const std::string& username,
1151 const std::string& password)
1152 : stun_servers(stun_servers),
1153 username(username),
1154 password(password) {
1155 if (!stun_servers.empty())
1156 stun_address = *(stun_servers.begin());
1157 }
1158
1159 ServerAddresses PortConfiguration::StunServers() {
1160 if (!stun_address.IsNil() &&
1161 stun_servers.find(stun_address) == stun_servers.end()) {
1162 stun_servers.insert(stun_address);
1163 }
1164 return stun_servers;
1165 }
1166
1167 void PortConfiguration::AddRelay(const RelayServerConfig& config) {
1168 relays.push_back(config);
1169 }
1170
1171 bool PortConfiguration::SupportsProtocol(
1172 const RelayServerConfig& relay, ProtocolType type) const {
1173 PortList::const_iterator relay_port;
1174 for (relay_port = relay.ports.begin();
1175 relay_port != relay.ports.end();
1176 ++relay_port) {
1177 if (relay_port->proto == type)
1178 return true;
1179 }
1180 return false;
1181 }
1182
1183 bool PortConfiguration::SupportsProtocol(RelayType turn_type,
1184 ProtocolType type) const {
1185 for (size_t i = 0; i < relays.size(); ++i) {
1186 if (relays[i].type == turn_type &&
1187 SupportsProtocol(relays[i], type))
1188 return true;
1189 }
1190 return false;
1191 }
1192
1193 ServerAddresses PortConfiguration::GetRelayServerAddresses(
1194 RelayType turn_type, ProtocolType type) const {
1195 ServerAddresses servers;
1196 for (size_t i = 0; i < relays.size(); ++i) {
1197 if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) {
1198 servers.insert(relays[i].ports.front().address);
1199 }
1200 }
1201 return servers;
1202 }
1203
1204 } // namespace cricket
1205