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 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 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 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 177 BasicPortAllocator::BasicPortAllocator( 178 rtc::NetworkManager* network_manager) 179 : network_manager_(network_manager), 180 socket_factory_(NULL) { 181 Construct(); 182 } 183 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 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 219 void BasicPortAllocator::Construct() { 220 allow_tcp_listen_ = true; 221 } 222 223 BasicPortAllocator::~BasicPortAllocator() { 224 } 225 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 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 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 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 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 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 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 345 void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) { 346 network_thread_->Post(this, MSG_CONFIG_READY, config); 347 } 348 349 // Adds a configuration to the list. 350 void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) { 351 if (config) 352 configs_.push_back(config); 353 354 AllocatePorts(); 355 } 356 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 388 void BasicPortAllocatorSession::AllocatePorts() { 389 ASSERT(rtc::Thread::Current() == network_thread_); 390 network_thread_->Post(this, MSG_ALLOCATE); 391 } 392 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. 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