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}
This commit is contained in:
Qingsi Wang
2018-09-16 17:48:10 -07:00
committed by Commit Bot
parent 377a231c0d
commit b49b8f115c
4 changed files with 22 additions and 6 deletions

View File

@ -4761,6 +4761,8 @@ TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMDnsName) {
// 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());

View File

@ -440,6 +440,11 @@ void Port::AddAddress(const rtc::SocketAddress& address,
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) {

View File

@ -496,13 +496,21 @@ void BasicPortAllocatorSession::GetCandidatesFromPort(
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 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port,
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.";

View File

@ -235,9 +235,10 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
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);