• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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