Add MDnsResponderInterface and obfuscate local IP addresses in gathering.

MDnsResponderInterface can be accessed by rtc::NetworkManager to
generate mDNS hostnames for local IP addresses, so that the addresses of
ICE host candidates are obfuscated in gathering whenever an mDNS
responder is present. The mDNS responder will handle incoming mDNS
queries about the generated mDNS hostnames, e.g. queries received from
the AsyncResolverInterface of the remote ICE endpoint.

Bug: webrtc:9605
Change-Id: Ib9e77427327b3d1fabdb1f3854d5e8457db40375
Reviewed-on: https://webrtc-review.googlesource.com/97881
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Qingsi Wang <qingsi@google.com>
Cr-Commit-Position: refs/heads/master@{#24714}
diff --git a/p2p/client/basicportallocator_unittest.cc b/p2p/client/basicportallocator_unittest.cc
index b49be8a..2b6dd3a 100644
--- a/p2p/client/basicportallocator_unittest.cc
+++ b/p2p/client/basicportallocator_unittest.cc
@@ -2246,4 +2246,53 @@
                    static_cast<int>(IceRegatheringReason::NETWORK_CHANGE)));
 }
 
+// Test that when an mDNS responder is present, the local address of a host
+// candidate is masked by an mDNS hostname and the related address of any other
+// type of candidates is set to 0.0.0.0 or ::0.
+TEST_F(BasicPortAllocatorTest, HostCandidateAddressIsReplacedByHostname) {
+  // Default config uses GTURN and no NAT, so replace that with the
+  // desired setup (NAT, STUN server, TURN server, UDP/TCP).
+  ResetWithStunServerAndNat(kStunAddr);
+  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
+  AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr);
+  AddTurnServers(kTurnUdpIntIPv6Addr, kTurnTcpIntIPv6Addr);
+
+  ASSERT_EQ(&network_manager_, allocator().network_manager());
+  network_manager_.CreateMDnsResponder();
+  AddInterface(kClientAddr);
+  ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
+  session_->StartGettingPorts();
+  ASSERT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
+                             kDefaultAllocationTimeout, fake_clock);
+  EXPECT_EQ(5u, candidates_.size());
+  int num_host_udp_candidates = 0;
+  int num_host_tcp_candidates = 0;
+  int num_srflx_candidates = 0;
+  int num_relay_candidates = 0;
+  for (const auto& candidate : candidates_) {
+    if (candidate.type() == LOCAL_PORT_TYPE) {
+      EXPECT_TRUE(candidate.address().IsUnresolvedIP());
+      if (candidate.protocol() == UDP_PROTOCOL_NAME) {
+        ++num_host_udp_candidates;
+      } else {
+        ++num_host_tcp_candidates;
+      }
+    } else {
+      EXPECT_NE(PRFLX_PORT_TYPE, candidate.type());
+      // The related address should be set to 0.0.0.0 or ::0 for srflx and
+      // relay candidates.
+      EXPECT_EQ(rtc::SocketAddress(), candidate.related_address());
+      if (candidate.type() == STUN_PORT_TYPE) {
+        ++num_srflx_candidates;
+      } else {
+        ++num_relay_candidates;
+      }
+    }
+  }
+  EXPECT_EQ(1, num_host_udp_candidates);
+  EXPECT_EQ(1, num_host_tcp_candidates);
+  EXPECT_EQ(1, num_srflx_candidates);
+  EXPECT_EQ(2, num_relay_candidates);
+}
+
 }  // namespace cricket