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
45using rtc::CreateRandomId;
46using rtc::CreateRandomString;
47
48namespace {
49
50enum {
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
60const int PHASE_UDP = 0;
61const int PHASE_RELAY = 1;
62const int PHASE_TCP = 2;
63const int PHASE_SSLTCP = 3;
64
65const int kNumPhases = 4;
66
67const int SHAKE_MIN_DELAY = 45 * 1000;  // 45 seconds
68const int SHAKE_MAX_DELAY = 90 * 1000;  // 90 seconds
69
70int ShakeDelay() {
71  int range = SHAKE_MAX_DELAY - SHAKE_MIN_DELAY + 1;
72  return SHAKE_MIN_DELAY + CreateRandomId() % range;
73}
74
75}  // namespace
76
77namespace cricket {
78
79const 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.
87class 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
107  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
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
168BasicPortAllocator::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
177BasicPortAllocator::BasicPortAllocator(
178    rtc::NetworkManager* network_manager)
179    : network_manager_(network_manager),
180      socket_factory_(NULL) {
181  Construct();
182}
183
184BasicPortAllocator::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
195BasicPortAllocator::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
219void BasicPortAllocator::Construct() {
220  allow_tcp_listen_ = true;
221}
222
223BasicPortAllocator::~BasicPortAllocator() {
224}
225
226PortAllocatorSession *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
235BasicPortAllocatorSession::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
254BasicPortAllocatorSession::~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
276void 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
291void 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
300void 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
334void 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
345void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
346  network_thread_->Post(this, MSG_CONFIG_READY, config);
347}
348
349// Adds a configuration to the list.
350void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
351  if (config)
352    configs_.push_back(config);
353
354  AllocatePorts();
355}
356
357void 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
388void BasicPortAllocatorSession::AllocatePorts() {
389  ASSERT(rtc::Thread::Current() == network_thread_);
390  network_thread_->Post(this, MSG_ALLOCATE);
391}
392
393void 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.
402void 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
471void BasicPortAllocatorSession::OnNetworksChanged() {
472  network_manager_started_ = true;
473  if (allocation_started_)
474    DoAllocate();
475}
476
477void 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
485void 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
517void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() {
518  allocation_sequences_created_ = true;
519  // Send candidate allocation complete signal if we have no sequences.
520  MaybeSignalCandidatesAllocationDone();
521}
522
523void 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
558void 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
573void 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
588void 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
614bool 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
639void BasicPortAllocatorSession::OnPortAllocationComplete(
640    AllocationSequence* seq) {
641  // Send candidate allocation complete signal if all ports are done.
642  MaybeSignalCandidatesAllocationDone();
643}
644
645void 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
671void 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
686void 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
716BasicPortAllocatorSession::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
729AllocationSequence::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
749bool 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
772void AllocationSequence::Clear() {
773  udp_port_ = NULL;
774  turn_ports_.clear();
775}
776
777AllocationSequence::~AllocationSequence() {
778  session_->network_thread()->Clear(this);
779}
780
781void 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
814void AllocationSequence::Start() {
815  state_ = kRunning;
816  session_->network_thread()->Post(this, MSG_ALLOCATION_PHASE);
817}
818
819void 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
827void 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
877void AllocationSequence::EnableProtocol(ProtocolType proto) {
878  if (!ProtocolEnabled(proto)) {
879    protocols_.push_back(proto);
880    session_->OnProtocolEnabled(this, proto);
881  }
882}
883
884bool 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
893void 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
945void 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
965void 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
998void 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
1026void 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
1057void 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
1093void 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
1130void 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
1140PortConfiguration::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
1149PortConfiguration::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
1159ServerAddresses 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
1167void PortConfiguration::AddRelay(const RelayServerConfig& config) {
1168  relays.push_back(config);
1169}
1170
1171bool 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
1183bool 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
1193ServerAddresses 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