本节主要是说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);
}