Server Reflexive Candidate,是通过主机候选地址向STUN服务器发送STUN请求获得的网络地址。实际上就是终端的网络包经过一重或多重NAT穿透之后,由STUN服务器观察到的经过NAT转换之后的地址。
解析StunBindingResponse过程
UDPPort::OnReadPacket

如果之前有向stun 服务器发送过请求,则serveraddresses会有记录,可以直接查找得到,这里得到的是reponse消息。UDPPort::OnResolveResult中插入到serveraddresses。
StunBindingRequest::OnResponse
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\p2p\base\stun_port.cc
class StunBindingRequest : public StunRequest {void OnResponse(StunMessage* response) override {const StunAddressAttribute* addr_attr =response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);if (!addr_attr) {RTC_LOG(LS_ERROR) << "Binding response missing mapped address.";} else if (addr_attr->family() != STUN_ADDRESS_IPV4 &&addr_attr->family() != STUN_ADDRESS_IPV6) {RTC_LOG(LS_ERROR) << "Binding address has bad family";} else {rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());port_->OnStunBindingRequestSucceeded(this->Elapsed(), server_addr_, addr);}// The keep-alive requests will be stopped after its lifetime has passed.if (WithinLifetime(rtc::TimeMillis())) {port_->requests_.SendDelayed(new StunBindingRequest(port_, server_addr_, start_time_),port_->stun_keepalive_delay());}}}
UDPPort::OnStunBindingRequestSucceeded

void UDPPort::OnStunBindingRequestSucceeded(int rtt_ms,const rtc::SocketAddress& stun_server_addr,const rtc::SocketAddress& stun_reflected_addr) {RTC_DCHECK(stats_.stun_binding_responses_received <stats_.stun_binding_requests_sent);stats_.stun_binding_responses_received++;stats_.stun_binding_rtt_ms_total += rtt_ms;stats_.stun_binding_rtt_ms_squared_total += rtt_ms * rtt_ms;if (bind_request_succeeded_servers_.find(stun_server_addr) !=bind_request_succeeded_servers_.end()) {return;}bind_request_succeeded_servers_.insert(stun_server_addr);// If socket is shared and |stun_reflected_addr| is equal to local socket// address, or if the same address has been added by another STUN server,// then discarding the stun address.// For STUN, related address is the local socket address.if ((!SharedSocket() || stun_reflected_addr != socket_->GetLocalAddress()) &&!HasCandidateWithAddress(stun_reflected_addr)) {rtc::SocketAddress related_address = socket_->GetLocalAddress();// If we can't stamp the related address correctly, empty it to avoid leak.if (!MaybeSetDefaultLocalAddress(&related_address)) {related_address =rtc::EmptySocketAddressWithFamily(related_address.family());}rtc::StringBuilder url;url << "stun:" << stun_server_addr.ipaddr().ToString() << ":"<< stun_server_addr.port();AddAddress(stun_reflected_addr, socket_->GetLocalAddress(), related_address,UDP_PROTOCOL_NAME, "", "", STUN_PORT_TYPE,ICE_TYPE_PREFERENCE_SRFLX, 0, url.str(), false);}MaybeSetPortCompleteOrError();}
