Fix a bug that the local hostname candidate with a known address is
updated to prflx.
When the address of a local candidate is intentionally removed after
gathered, its would be incorrectly updated to prflx when receiving a
STUN message from a remote candidate after forming a candidate pair and
starting the connectivity check.
Bug: webrtc:9756, webrtc:9605
Change-Id: I6c699250565c1458e825eba742c2991a82229817
Reviewed-on: https://webrtc-review.googlesource.com/100624
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Qingsi Wang <qingsi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24837}
diff --git a/p2p/base/p2ptransportchannel_unittest.cc b/p2p/base/p2ptransportchannel_unittest.cc
index fadcb0a..03a3103 100644
--- a/p2p/base/p2ptransportchannel_unittest.cc
+++ b/p2p/base/p2ptransportchannel_unittest.cc
@@ -4761,6 +4761,8 @@
// with a peer reflexive candidate from ep2.
ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr,
kMediumTimeout);
+ EXPECT_EQ(LOCAL_PORT_TYPE,
+ ep1_ch1()->selected_connection()->local_candidate().type());
EXPECT_EQ(PRFLX_PORT_TYPE,
ep1_ch1()->selected_connection()->remote_candidate().type());
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index 095b3a6..1fe7305 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -440,6 +440,11 @@
const std::string& name) mutable {
RTC_DCHECK(c.address().ipaddr() == addr);
rtc::SocketAddress hostname_address(name, c.address().port());
+ // In Port and Connection, we need the IP address information to
+ // correctly handle the update of candidate type to prflx. The removal
+ // of IP address when signaling this candidate will take place in
+ // BasicPortAllocatorSession::OnCandidateReady, via SanitizeCandidate.
+ hostname_address.SetResolvedIP(addr);
c.set_address(hostname_address);
RTC_DCHECK(c.related_address() == rtc::SocketAddress());
if (weak_ptr != nullptr) {
diff --git a/p2p/client/basicportallocator.cc b/p2p/client/basicportallocator.cc
index 5b48f5e..92c8338 100644
--- a/p2p/client/basicportallocator.cc
+++ b/p2p/client/basicportallocator.cc
@@ -496,13 +496,21 @@
if (!CheckCandidateFilter(candidate)) {
continue;
}
- candidates->push_back(SanitizeRelatedAddress(candidate));
+ auto sanitized_candidate = SanitizeCandidate(candidate);
+ candidates->push_back(sanitized_candidate);
}
}
-Candidate BasicPortAllocatorSession::SanitizeRelatedAddress(
+Candidate BasicPortAllocatorSession::SanitizeCandidate(
const Candidate& c) const {
Candidate copy = c;
+ // If the candidate has a generated hostname, we need to obfuscate its IP
+ // address when signaling this candidate.
+ if (!c.address().hostname().empty() && !c.address().IsUnresolvedIP()) {
+ rtc::SocketAddress hostname_only_addr(c.address().hostname(),
+ c.address().port());
+ copy.set_address(hostname_only_addr);
+ }
// If adapter enumeration is disabled or host candidates are disabled,
// clear the raddr of STUN candidates to avoid local address leakage.
bool filter_stun_related_address =
@@ -916,7 +924,7 @@
if (data->ready() && CheckCandidateFilter(c)) {
std::vector<Candidate> candidates;
- candidates.push_back(SanitizeRelatedAddress(c));
+ candidates.push_back(SanitizeCandidate(c));
SignalCandidatesReady(this, candidates);
} else {
RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter.";
diff --git a/p2p/client/basicportallocator.h b/p2p/client/basicportallocator.h
index 07bf2f9..8b951ca 100644
--- a/p2p/client/basicportallocator.h
+++ b/p2p/client/basicportallocator.h
@@ -235,9 +235,10 @@
bool CheckCandidateFilter(const Candidate& c) const;
bool CandidatePairable(const Candidate& c, const Port* port) const;
- // Clear the related address according to the flags and candidate filter
- // in order to avoid leaking any information.
- Candidate SanitizeRelatedAddress(const Candidate& c) const;
+ // Clears 1) the address if the candidate is supposedly a hostname candidate;
+ // 2) the related address according to the flags and candidate filter in order
+ // to avoid leaking any information.
+ Candidate SanitizeCandidate(const Candidate& c) const;
std::vector<PortData*> GetUnprunedPorts(
const std::vector<rtc::Network*>& networks);