本节主要说的是发送AllocateRequest到turn服务器的过程。
STUN/TURN消息类型
发送AllocateRequest调用栈
AllocationSequence::CreateRelayPorts
h:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\p2p\client\basic_port_allocator.cc
AllocationSequence::CreateTurnPort

一般只有一个ports,所以循环一般只执行一遍。
void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {PortList::const_iterator relay_port;for (relay_port = config.ports.begin(); relay_port != config.ports.end();++relay_port) {// Skip UDP connections to relay servers if it's disallowed.if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP_RELAY) &&relay_port->proto == PROTO_UDP) {continue;}// Do not create a port if the server address family is known and does// not match the local IP address family.int server_ip_family = relay_port->address.ipaddr().family();int local_ip_family = network_->GetBestIP().family();if (server_ip_family != AF_UNSPEC && server_ip_family != local_ip_family) {RTC_LOG(LS_INFO)<< "Server and local address families are not compatible. ""Server address: "<< relay_port->address.ipaddr().ToSensitiveString()<< " Local address: " << network_->GetBestIP().ToSensitiveString();continue;}CreateRelayPortArgs args;args.network_thread = session_->network_thread();args.socket_factory = session_->socket_factory();args.network = network_;args.username = session_->username();args.password = session_->password();args.server_address = &(*relay_port);args.config = &config;args.origin = session_->allocator()->origin();args.turn_customizer = session_->allocator()->turn_customizer();std::unique_ptr<cricket::Port> port;// Shared socket mode must be enabled only for UDP based ports. Hence// don't pass shared socket for ports which will create TCP sockets.// TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled// due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&relay_port->proto == PROTO_UDP && udp_socket_) {port = session_->allocator()->relay_port_factory()->Create(args, udp_socket_.get());if (!port) {RTC_LOG(LS_WARNING) << "Failed to create relay port with "<< args.server_address->address.ToSensitiveString();continue;}relay_ports_.push_back(port.get());// Listen to the port destroyed signal, to allow AllocationSequence to// remove the entry from it's map.port->SubscribePortDestroyed([this](PortInterface* port) { OnPortDestroyed(port); });} else {port = session_->allocator()->relay_port_factory()->Create(args, session_->allocator()->min_port(),session_->allocator()->max_port());if (!port) {RTC_LOG(LS_WARNING) << "Failed to create relay port with "<< args.server_address->address.ToSensitiveString();continue;}}RTC_DCHECK(port != NULL);session_->AddAllocatedPort(port.release(), this, true);}}
BasicPortAllocatorSession::AddAllocatedPort

void BasicPortAllocatorSession::AddAllocatedPort(Port* port,AllocationSequence* seq,bool prepare_address) {RTC_DCHECK_RUN_ON(network_thread_);if (!port)return;RTC_LOG(LS_INFO) << "Adding allocated port for " << content_name();port->set_content_name(content_name());port->set_component(component());port->set_generation(generation());if (allocator_->proxy().type != rtc::PROXY_NONE)port->set_proxy(allocator_->user_agent(), allocator_->proxy());port->set_send_retransmit_count_attribute((flags() & PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);PortData data(port, seq);ports_.push_back(data);port->SignalCandidateReady.connect(this, &BasicPortAllocatorSession::OnCandidateReady);port->SignalCandidateError.connect(this, &BasicPortAllocatorSession::OnCandidateError);port->SignalPortComplete.connect(this,&BasicPortAllocatorSession::OnPortComplete);port->SubscribePortDestroyed([this](PortInterface* port) { OnPortDestroyed(port); });port->SignalPortError.connect(this, &BasicPortAllocatorSession::OnPortError);RTC_LOG(LS_INFO) << port->ToString() << ": Added port to allocator";if (prepare_address)port->PrepareAddress();}
TurnPort::PrepareAddress

void TurnPort::PrepareAddress() {if (credentials_.username.empty() || credentials_.password.empty()) {RTC_LOG(LS_ERROR) << "Allocation can't be started without setting the"" TURN server credentials for the user.";OnAllocateError(STUN_ERROR_UNAUTHORIZED,"Missing TURN server credentials.");return;}if (!server_address_.address.port()) {// We will set default TURN port, if no port is set in the address.server_address_.address.SetPort(TURN_DEFAULT_PORT);}if (!AllowedTurnPort(server_address_.address.port())) {// This can only happen after a 300 ALTERNATE SERVER, since the port can't// be created with a disallowed port number.RTC_LOG(LS_ERROR) << "Attempt to start allocation with disallowed port# "<< server_address_.address.port();OnAllocateError(STUN_ERROR_SERVER_ERROR,"Attempt to start allocation to a disallowed port");return;}if (server_address_.address.IsUnresolvedIP()) {ResolveTurnAddress(server_address_.address);} else {// If protocol family of server address doesn't match with local, return.if (!IsCompatibleAddress(server_address_.address)) {RTC_LOG(LS_ERROR) << "IP address family does not match. server: "<< server_address_.address.family()<< " local: " << Network()->GetBestIP().family();OnAllocateError(STUN_ERROR_GLOBAL_FAILURE,"IP address family does not match.");return;}// Insert the current address to prevent redirection pingpong.attempted_server_addresses_.insert(server_address_.address);RTC_LOG(LS_INFO) << ToString() << ": Trying to connect to TURN server via "<< ProtoToString(server_address_.proto) << " @ "<< server_address_.address.ToSensitiveString();if (!CreateTurnClientSocket()) {RTC_LOG(LS_ERROR) << "Failed to create TURN client socket";OnAllocateError(SERVER_NOT_REACHABLE_ERROR,"Failed to create TURN client socket.");return;}if (server_address_.proto == PROTO_UDP) {// If its UDP, send AllocateRequest now.// For TCP and TLS AllcateRequest will be sent by OnSocketConnect.SendRequest(new TurnAllocateRequest(this), 0);}}}
TurnPort::ResolveTurnAddress域名解析
TurnPort::OnResolveResult

void TurnPort::OnResolveResult(rtc::AsyncResolverInterface* resolver) {RTC_DCHECK(resolver == resolver_);// If DNS resolve is failed when trying to connect to the server using TCP,// one of the reason could be due to DNS queries blocked by firewall.// In such cases we will try to connect to the server with hostname, assuming// socket layer will resolve the hostname through a HTTP proxy (if any).if (resolver_->GetError() != 0 && (server_address_.proto == PROTO_TCP ||server_address_.proto == PROTO_TLS)) {if (!CreateTurnClientSocket()) {OnAllocateError(SERVER_NOT_REACHABLE_ERROR,"TURN host lookup received error.");}return;}// Copy the original server address in |resolved_address|. For TLS based// sockets we need hostname along with resolved address.rtc::SocketAddress resolved_address = server_address_.address;if (resolver_->GetError() != 0 ||!resolver_->GetResolvedAddress(Network()->GetBestIP().family(),&resolved_address)) {RTC_LOG(LS_WARNING) << ToString() << ": TURN host lookup received error "<< resolver_->GetError();error_ = resolver_->GetError();OnAllocateError(SERVER_NOT_REACHABLE_ERROR,"TURN host lookup received error.");return;}// Signal needs both resolved and unresolved address. After signal is sent// we can copy resolved address back into |server_address_|.SignalResolvedServerAddress(this, server_address_.address, resolved_address);server_address_.address = resolved_address;PrepareAddress();}
域名解析完成后,再次回到 TurnPort::PrepareAddress
TurnPort::PrepareAddress

