本节主要是说webrtc收到turn服务器发过来的AllocateResponse后的做法过程。
接收处理AllocateResponse调用栈

最后是OnAllocateSuccess之后生成turn类型的candidate。
AllocationSequence::OnReadpacket

判断是否是某个replay服务器发过来的消息。如果不是,则判断是否是其他webrtc发过来的,会判断udpport是否创建成功。。
void AllocationSequence::OnReadPacket(rtc::AsyncPacketSocket* socket,const char* data,size_t size,const rtc::SocketAddress& remote_addr,const int64_t& packet_time_us) {RTC_DCHECK(socket == udp_socket_.get());bool turn_port_found = false;// Try to find the TurnPort that matches the remote address. Note that the// message could be a STUN binding response if the TURN server is also used as// a STUN server. We don't want to parse every message here to check if it is// a STUN binding response, so we pass the message to TurnPort regardless of// the message type. The TurnPort will just ignore the message since it will// not find any request by transaction ID.for (auto* port : relay_ports_) {if (port->CanHandleIncomingPacketsFrom(remote_addr)) {if (port->HandleIncomingPacket(socket, data, size, remote_addr,packet_time_us)) {return;}turn_port_found = true;}}if (udp_port_) {const ServerAddresses& stun_servers = udp_port_->server_addresses();// Pass the packet to the UdpPort if there is no matching TurnPort, or if// the TURN server is also a STUN server.if (!turn_port_found ||stun_servers.find(remote_addr) != stun_servers.end()) {RTC_DCHECK(udp_port_->SharedSocket());udp_port_->HandleIncomingPacket(socket, data, size, remote_addr,packet_time_us);}}}
TurnPort::HandleIncomingPacket

StunRequestManager::CheckResponse(const char data, size_t size)
-》
StunRequestManager::CheckResponse(StunMessage msg)
—》
TurnAllocateRequest::OnResponse
TurnAllocateRequest::OnResponse

1、从映射中获取本机外网的映射地址
2、获取relay服务器的地址
3、生成candidate
void TurnAllocateRequest::OnResponse(StunMessage* response) {RTC_LOG(LS_INFO) << port_->ToString()<< ": TURN allocate requested successfully, id="<< rtc::hex_encode(id())<< ", code=0" // Makes logging easier to parse.", rtt="<< Elapsed();// Check mandatory attributes as indicated in RFC5766, Section 6.3.const StunAddressAttribute* mapped_attr =response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);if (!mapped_attr) {RTC_LOG(LS_WARNING) << port_->ToString()<< ": Missing STUN_ATTR_XOR_MAPPED_ADDRESS ""attribute in allocate success response";return;}// Using XOR-Mapped-Address for stun.port_->OnStunAddress(mapped_attr->GetAddress());const StunAddressAttribute* relayed_attr =response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);if (!relayed_attr) {RTC_LOG(LS_WARNING) << port_->ToString()<< ": Missing STUN_ATTR_XOR_RELAYED_ADDRESS ""attribute in allocate success response";return;}const StunUInt32Attribute* lifetime_attr =response->GetUInt32(STUN_ATTR_TURN_LIFETIME);if (!lifetime_attr) {RTC_LOG(LS_WARNING) << port_->ToString()<< ": Missing STUN_ATTR_TURN_LIFETIME attribute in ""allocate success response";return;}// Notify the port the allocate succeeded, and schedule a refresh request.port_->OnAllocateSuccess(relayed_attr->GetAddress(),mapped_attr->GetAddress());port_->ScheduleRefresh(lifetime_attr->value());}
TurnPort::OnAllocateSuccess

void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,const rtc::SocketAddress& stun_address) {state_ = STATE_READY;rtc::SocketAddress related_address = stun_address;// For relayed candidate, Base is the candidate itself.AddAddress(address, // Candidate address.address, // Base address.related_address, // Related address.UDP_PROTOCOL_NAME,ProtoToString(server_address_.proto), // The first hop protocol."", // TCP canddiate type, empty for turn candidates.RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto),server_priority_, ReconstructedServerUrl(false /* use_hostname */),true);}
