本节主要说的是发送AllocateRequest到turn服务器的过程。

STUN/TURN消息类型

image.png

发送AllocateRequest调用栈

image.png

AllocationSequence::CreateRelayPorts

h:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\p2p\client\basic_port_allocator.cc
image.png

AllocationSequence::CreateTurnPort

image.png
一般只有一个ports,所以循环一般只执行一遍。

  1. void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
  2. PortList::const_iterator relay_port;
  3. for (relay_port = config.ports.begin(); relay_port != config.ports.end();
  4. ++relay_port) {
  5. // Skip UDP connections to relay servers if it's disallowed.
  6. if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP_RELAY) &&
  7. relay_port->proto == PROTO_UDP) {
  8. continue;
  9. }
  10. // Do not create a port if the server address family is known and does
  11. // not match the local IP address family.
  12. int server_ip_family = relay_port->address.ipaddr().family();
  13. int local_ip_family = network_->GetBestIP().family();
  14. if (server_ip_family != AF_UNSPEC && server_ip_family != local_ip_family) {
  15. RTC_LOG(LS_INFO)
  16. << "Server and local address families are not compatible. "
  17. "Server address: "
  18. << relay_port->address.ipaddr().ToSensitiveString()
  19. << " Local address: " << network_->GetBestIP().ToSensitiveString();
  20. continue;
  21. }
  22. CreateRelayPortArgs args;
  23. args.network_thread = session_->network_thread();
  24. args.socket_factory = session_->socket_factory();
  25. args.network = network_;
  26. args.username = session_->username();
  27. args.password = session_->password();
  28. args.server_address = &(*relay_port);
  29. args.config = &config;
  30. args.origin = session_->allocator()->origin();
  31. args.turn_customizer = session_->allocator()->turn_customizer();
  32. std::unique_ptr<cricket::Port> port;
  33. // Shared socket mode must be enabled only for UDP based ports. Hence
  34. // don't pass shared socket for ports which will create TCP sockets.
  35. // TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled
  36. // due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537
  37. if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
  38. relay_port->proto == PROTO_UDP && udp_socket_) {
  39. port = session_->allocator()->relay_port_factory()->Create(
  40. args, udp_socket_.get());
  41. if (!port) {
  42. RTC_LOG(LS_WARNING) << "Failed to create relay port with "
  43. << args.server_address->address.ToSensitiveString();
  44. continue;
  45. }
  46. relay_ports_.push_back(port.get());
  47. // Listen to the port destroyed signal, to allow AllocationSequence to
  48. // remove the entry from it's map.
  49. port->SubscribePortDestroyed(
  50. [this](PortInterface* port) { OnPortDestroyed(port); });
  51. } else {
  52. port = session_->allocator()->relay_port_factory()->Create(
  53. args, session_->allocator()->min_port(),
  54. session_->allocator()->max_port());
  55. if (!port) {
  56. RTC_LOG(LS_WARNING) << "Failed to create relay port with "
  57. << args.server_address->address.ToSensitiveString();
  58. continue;
  59. }
  60. }
  61. RTC_DCHECK(port != NULL);
  62. session_->AddAllocatedPort(port.release(), this, true);
  63. }
  64. }

BasicPortAllocatorSession::AddAllocatedPort

image.png

  1. void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
  2. AllocationSequence* seq,
  3. bool prepare_address) {
  4. RTC_DCHECK_RUN_ON(network_thread_);
  5. if (!port)
  6. return;
  7. RTC_LOG(LS_INFO) << "Adding allocated port for " << content_name();
  8. port->set_content_name(content_name());
  9. port->set_component(component());
  10. port->set_generation(generation());
  11. if (allocator_->proxy().type != rtc::PROXY_NONE)
  12. port->set_proxy(allocator_->user_agent(), allocator_->proxy());
  13. port->set_send_retransmit_count_attribute(
  14. (flags() & PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
  15. PortData data(port, seq);
  16. ports_.push_back(data);
  17. port->SignalCandidateReady.connect(
  18. this, &BasicPortAllocatorSession::OnCandidateReady);
  19. port->SignalCandidateError.connect(
  20. this, &BasicPortAllocatorSession::OnCandidateError);
  21. port->SignalPortComplete.connect(this,
  22. &BasicPortAllocatorSession::OnPortComplete);
  23. port->SubscribePortDestroyed(
  24. [this](PortInterface* port) { OnPortDestroyed(port); });
  25. port->SignalPortError.connect(this, &BasicPortAllocatorSession::OnPortError);
  26. RTC_LOG(LS_INFO) << port->ToString() << ": Added port to allocator";
  27. if (prepare_address)
  28. port->PrepareAddress();
  29. }

TurnPort::PrepareAddress

image.png

  1. void TurnPort::PrepareAddress() {
  2. if (credentials_.username.empty() || credentials_.password.empty()) {
  3. RTC_LOG(LS_ERROR) << "Allocation can't be started without setting the"
  4. " TURN server credentials for the user.";
  5. OnAllocateError(STUN_ERROR_UNAUTHORIZED,
  6. "Missing TURN server credentials.");
  7. return;
  8. }
  9. if (!server_address_.address.port()) {
  10. // We will set default TURN port, if no port is set in the address.
  11. server_address_.address.SetPort(TURN_DEFAULT_PORT);
  12. }
  13. if (!AllowedTurnPort(server_address_.address.port())) {
  14. // This can only happen after a 300 ALTERNATE SERVER, since the port can't
  15. // be created with a disallowed port number.
  16. RTC_LOG(LS_ERROR) << "Attempt to start allocation with disallowed port# "
  17. << server_address_.address.port();
  18. OnAllocateError(STUN_ERROR_SERVER_ERROR,
  19. "Attempt to start allocation to a disallowed port");
  20. return;
  21. }
  22. if (server_address_.address.IsUnresolvedIP()) {
  23. ResolveTurnAddress(server_address_.address);
  24. } else {
  25. // If protocol family of server address doesn't match with local, return.
  26. if (!IsCompatibleAddress(server_address_.address)) {
  27. RTC_LOG(LS_ERROR) << "IP address family does not match. server: "
  28. << server_address_.address.family()
  29. << " local: " << Network()->GetBestIP().family();
  30. OnAllocateError(STUN_ERROR_GLOBAL_FAILURE,
  31. "IP address family does not match.");
  32. return;
  33. }
  34. // Insert the current address to prevent redirection pingpong.
  35. attempted_server_addresses_.insert(server_address_.address);
  36. RTC_LOG(LS_INFO) << ToString() << ": Trying to connect to TURN server via "
  37. << ProtoToString(server_address_.proto) << " @ "
  38. << server_address_.address.ToSensitiveString();
  39. if (!CreateTurnClientSocket()) {
  40. RTC_LOG(LS_ERROR) << "Failed to create TURN client socket";
  41. OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
  42. "Failed to create TURN client socket.");
  43. return;
  44. }
  45. if (server_address_.proto == PROTO_UDP) {
  46. // If its UDP, send AllocateRequest now.
  47. // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
  48. SendRequest(new TurnAllocateRequest(this), 0);
  49. }
  50. }
  51. }

TurnPort::ResolveTurnAddress域名解析

image.png

TurnPort::OnResolveResult

image.png

  1. void TurnPort::OnResolveResult(rtc::AsyncResolverInterface* resolver) {
  2. RTC_DCHECK(resolver == resolver_);
  3. // If DNS resolve is failed when trying to connect to the server using TCP,
  4. // one of the reason could be due to DNS queries blocked by firewall.
  5. // In such cases we will try to connect to the server with hostname, assuming
  6. // socket layer will resolve the hostname through a HTTP proxy (if any).
  7. if (resolver_->GetError() != 0 && (server_address_.proto == PROTO_TCP ||
  8. server_address_.proto == PROTO_TLS)) {
  9. if (!CreateTurnClientSocket()) {
  10. OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
  11. "TURN host lookup received error.");
  12. }
  13. return;
  14. }
  15. // Copy the original server address in |resolved_address|. For TLS based
  16. // sockets we need hostname along with resolved address.
  17. rtc::SocketAddress resolved_address = server_address_.address;
  18. if (resolver_->GetError() != 0 ||
  19. !resolver_->GetResolvedAddress(Network()->GetBestIP().family(),
  20. &resolved_address)) {
  21. RTC_LOG(LS_WARNING) << ToString() << ": TURN host lookup received error "
  22. << resolver_->GetError();
  23. error_ = resolver_->GetError();
  24. OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
  25. "TURN host lookup received error.");
  26. return;
  27. }
  28. // Signal needs both resolved and unresolved address. After signal is sent
  29. // we can copy resolved address back into |server_address_|.
  30. SignalResolvedServerAddress(this, server_address_.address, resolved_address);
  31. server_address_.address = resolved_address;
  32. PrepareAddress();
  33. }

域名解析完成后,再次回到 TurnPort::PrepareAddress

TurnPort::PrepareAddress

image.png