Loading Android.bp +28 −0 Original line number Diff line number Diff line Loading @@ -381,3 +381,31 @@ rust_ffi_static { ], min_sdk_version: "29", } rust_ffi_static { // Combines libdoh_frontend_ffi and libdoh_ffi for fuzzing test. // Includes multiple static rust libraries will cause duplicate symbol error. name: "libdoh_fuzz_ffi", crate_name: "doh_fuzz_ffi", srcs: [ "doh/doh_test_superset_for_fuzzer.rs", ], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblazy_static", "liblibc", "liblog_rust", "libquiche_static", "libring", "libthiserror", "libtokio", "liburl", ], whole_static_libs: ["libunwind"], } DnsProxyListener.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -681,9 +681,9 @@ DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::s std::unique_ptr<addrinfo> hints, const android_net_context& netcontext) : Handler(c), mHost(move(host)), mService(move(service)), mHints(move(hints)), mHost(std::move(host)), mService(std::move(service)), mHints(std::move(hints)), mNetContext(netcontext) {} static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) { Loading Loading @@ -954,7 +954,7 @@ int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, ch hints->ai_protocol = ai_protocol; } (new GetAddrInfoHandler(cli, name, service, move(hints), netcontext))->spawn(); (new GetAddrInfoHandler(cli, name, service, std::move(hints), netcontext))->spawn(); return 0; } Loading Loading @@ -1202,7 +1202,7 @@ int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name, int af, const android_net_context& netcontext) : Handler(c), mName(move(name)), mAf(af), mNetContext(netcontext) {} : Handler(c), mName(std::move(name)), mAf(af), mNetContext(netcontext) {} void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf, size_t buflen, struct hostent** hpp, Loading Experiments.h +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ class Experiments { "dot_validation_latency_offset_ms", "dot_xport_unusable_threshold", "keep_listening_udp", "max_cache_entries", "max_queries_global", "mdns_resolution", "parallel_lookup_release", Loading PrivateDnsConfiguration.cpp +85 −7 Original line number Diff line number Diff line Loading @@ -61,18 +61,36 @@ bool ensureNoInvalidIp(const std::vector<std::string>& servers) { } // namespace PrivateDnsModes convert_enum_type(PrivateDnsMode mode) { switch (mode) { case PrivateDnsMode::OFF: return PrivateDnsModes::PDM_OFF; case PrivateDnsMode::OPPORTUNISTIC: return PrivateDnsModes::PDM_OPPORTUNISTIC; case PrivateDnsMode::STRICT: return PrivateDnsModes::PDM_STRICT; default: return PrivateDnsModes::PDM_UNKNOWN; } } int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) { const std::vector<std::string>& unencryptedServers, const std::vector<std::string>& encryptedServers, const std::string& name, const std::string& caCert) { LOG(DEBUG) << "PrivateDnsConfiguration::set(" << netId << ", 0x" << std::hex << mark << std::dec << ", " << servers.size() << ", " << name << ")"; << ", " << encryptedServers.size() << ", " << name << ")"; if (!ensureNoInvalidIp(servers)) return -EINVAL; if (!ensureNoInvalidIp(encryptedServers)) return -EINVAL; std::lock_guard guard(mPrivateDnsLock); mUnorderedDnsTracker[netId] = unencryptedServers; mUnorderedDotTracker[netId] = encryptedServers; mUnorderedDohTracker[netId] = encryptedServers; if (!name.empty()) { mPrivateDnsModes[netId] = PrivateDnsMode::STRICT; } else if (!servers.empty()) { } else if (!encryptedServers.empty()) { mPrivateDnsModes[netId] = PrivateDnsMode::OPPORTUNISTIC; } else { mPrivateDnsModes[netId] = PrivateDnsMode::OFF; Loading @@ -82,11 +100,11 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, // TODO: signal validation threads to stop. } if (int n = setDot(netId, mark, servers, name, caCert); n != 0) { if (int n = setDot(netId, mark, encryptedServers, name, caCert); n != 0) { return n; } if (isDoHEnabled()) { return setDoh(netId, mark, servers, name, caCert); return setDoh(netId, mark, encryptedServers, name, caCert); } return 0; Loading Loading @@ -170,10 +188,70 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { return status; } NetworkDnsServerSupportReported PrivateDnsConfiguration::getStatusForMetrics(unsigned netId) const { NetworkDnsServerSupportReported event; { std::lock_guard guard(mPrivateDnsLock); if (const auto it = mPrivateDnsModes.find(netId); it != mPrivateDnsModes.end()) { event.set_private_dns_modes(convert_enum_type(it->second)); } else { return event; } } event.set_network_type(resolv_get_network_types_for_net(netId)); const PrivateDnsStatus status = getStatus(netId); std::lock_guard guard(mPrivateDnsLock); if (const auto it = mUnorderedDnsTracker.find(netId); it != mUnorderedDnsTracker.end()) { for (size_t i = 0; i < it->second.size(); i++) { Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_UDP); server->set_index(i); server->set_validated(false); } } if (const auto it = mUnorderedDotTracker.find(netId); it != mUnorderedDotTracker.end()) { int index = 0; const std::list<DnsTlsServer> validatedServers = status.validatedServers(); for (const std::string& s : it->second) { const IPSockAddr target = IPSockAddr::toIPSockAddr(s, kDotPort); bool validated = std::any_of(validatedServers.begin(), validatedServers.end(), [&target](DnsTlsServer server) { return server.addr() == target; }); Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_DOT); server->set_index(index++); server->set_validated(validated); } } if (const auto it = mUnorderedDohTracker.find(netId); it != mUnorderedDohTracker.end()) { int index = 0; for (const std::string& s : it->second) { const IPSockAddr target = IPSockAddr::toIPSockAddr(s, kDohPort); bool validated = std::any_of(status.dohServersMap.begin(), status.dohServersMap.end(), [&target](const auto& entry) { return entry.first == target && entry.second == Validation::success; }); Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_DOH); server->set_index(index++); server->set_validated(validated); } } return event; } void PrivateDnsConfiguration::clear(unsigned netId) { LOG(DEBUG) << "PrivateDnsConfiguration::clear(" << netId << ")"; std::lock_guard guard(mPrivateDnsLock); mPrivateDnsModes.erase(netId); mUnorderedDnsTracker.erase(netId); mUnorderedDotTracker.erase(netId); mUnorderedDohTracker.erase(netId); clearDot(netId); clearDoh(netId); Loading PrivateDnsConfiguration.h +15 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <netdutils/DumpWriter.h> #include <netdutils/InternetAddresses.h> #include <netdutils/Slice.h> #include <stats.pb.h> #include "DnsTlsServer.h" #include "LockedQueue.h" Loading @@ -39,6 +40,8 @@ namespace android { namespace net { PrivateDnsModes convert_enum_type(PrivateDnsMode mode); struct PrivateDnsStatus { PrivateDnsMode mode; Loading Loading @@ -99,12 +102,15 @@ class PrivateDnsConfiguration { return instance; } int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); int set(int32_t netId, uint32_t mark, const std::vector<std::string>& unencryptedServers, const std::vector<std::string>& encryptedServers, const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); void initDoh() EXCLUDES(mPrivateDnsLock); PrivateDnsStatus getStatus(unsigned netId) const EXCLUDES(mPrivateDnsLock); NetworkDnsServerSupportReported getStatusForMetrics(unsigned netId) const EXCLUDES(mPrivateDnsLock); void clear(unsigned netId) EXCLUDES(mPrivateDnsLock); Loading Loading @@ -184,7 +190,7 @@ class PrivateDnsConfiguration { // TODO: fix the reentrancy problem. PrivateDnsValidationObserver* mObserver GUARDED_BY(mPrivateDnsLock); DohDispatcher* mDohDispatcher; DohDispatcher* mDohDispatcher = nullptr; std::condition_variable mCv; friend class PrivateDnsConfigurationTest; Loading Loading @@ -265,6 +271,12 @@ class PrivateDnsConfiguration { false}, }}; // For the metrics. Store the current DNS server list in the same order as what is passed // in setResolverConfiguration(). std::map<unsigned, std::vector<std::string>> mUnorderedDnsTracker GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::vector<std::string>> mUnorderedDotTracker GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::vector<std::string>> mUnorderedDohTracker GUARDED_BY(mPrivateDnsLock); struct RecordEntry { RecordEntry(uint32_t netId, const ServerIdentity& identity, Validation state) : netId(netId), serverIdentity(identity), state(state) {} Loading Loading
Android.bp +28 −0 Original line number Diff line number Diff line Loading @@ -381,3 +381,31 @@ rust_ffi_static { ], min_sdk_version: "29", } rust_ffi_static { // Combines libdoh_frontend_ffi and libdoh_ffi for fuzzing test. // Includes multiple static rust libraries will cause duplicate symbol error. name: "libdoh_fuzz_ffi", crate_name: "doh_fuzz_ffi", srcs: [ "doh/doh_test_superset_for_fuzzer.rs", ], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblazy_static", "liblibc", "liblog_rust", "libquiche_static", "libring", "libthiserror", "libtokio", "liburl", ], whole_static_libs: ["libunwind"], }
DnsProxyListener.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -681,9 +681,9 @@ DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::s std::unique_ptr<addrinfo> hints, const android_net_context& netcontext) : Handler(c), mHost(move(host)), mService(move(service)), mHints(move(hints)), mHost(std::move(host)), mService(std::move(service)), mHints(std::move(hints)), mNetContext(netcontext) {} static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) { Loading Loading @@ -954,7 +954,7 @@ int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, ch hints->ai_protocol = ai_protocol; } (new GetAddrInfoHandler(cli, name, service, move(hints), netcontext))->spawn(); (new GetAddrInfoHandler(cli, name, service, std::move(hints), netcontext))->spawn(); return 0; } Loading Loading @@ -1202,7 +1202,7 @@ int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name, int af, const android_net_context& netcontext) : Handler(c), mName(move(name)), mAf(af), mNetContext(netcontext) {} : Handler(c), mName(std::move(name)), mAf(af), mNetContext(netcontext) {} void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf, size_t buflen, struct hostent** hpp, Loading
Experiments.h +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ class Experiments { "dot_validation_latency_offset_ms", "dot_xport_unusable_threshold", "keep_listening_udp", "max_cache_entries", "max_queries_global", "mdns_resolution", "parallel_lookup_release", Loading
PrivateDnsConfiguration.cpp +85 −7 Original line number Diff line number Diff line Loading @@ -61,18 +61,36 @@ bool ensureNoInvalidIp(const std::vector<std::string>& servers) { } // namespace PrivateDnsModes convert_enum_type(PrivateDnsMode mode) { switch (mode) { case PrivateDnsMode::OFF: return PrivateDnsModes::PDM_OFF; case PrivateDnsMode::OPPORTUNISTIC: return PrivateDnsModes::PDM_OPPORTUNISTIC; case PrivateDnsMode::STRICT: return PrivateDnsModes::PDM_STRICT; default: return PrivateDnsModes::PDM_UNKNOWN; } } int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) { const std::vector<std::string>& unencryptedServers, const std::vector<std::string>& encryptedServers, const std::string& name, const std::string& caCert) { LOG(DEBUG) << "PrivateDnsConfiguration::set(" << netId << ", 0x" << std::hex << mark << std::dec << ", " << servers.size() << ", " << name << ")"; << ", " << encryptedServers.size() << ", " << name << ")"; if (!ensureNoInvalidIp(servers)) return -EINVAL; if (!ensureNoInvalidIp(encryptedServers)) return -EINVAL; std::lock_guard guard(mPrivateDnsLock); mUnorderedDnsTracker[netId] = unencryptedServers; mUnorderedDotTracker[netId] = encryptedServers; mUnorderedDohTracker[netId] = encryptedServers; if (!name.empty()) { mPrivateDnsModes[netId] = PrivateDnsMode::STRICT; } else if (!servers.empty()) { } else if (!encryptedServers.empty()) { mPrivateDnsModes[netId] = PrivateDnsMode::OPPORTUNISTIC; } else { mPrivateDnsModes[netId] = PrivateDnsMode::OFF; Loading @@ -82,11 +100,11 @@ int PrivateDnsConfiguration::set(int32_t netId, uint32_t mark, // TODO: signal validation threads to stop. } if (int n = setDot(netId, mark, servers, name, caCert); n != 0) { if (int n = setDot(netId, mark, encryptedServers, name, caCert); n != 0) { return n; } if (isDoHEnabled()) { return setDoh(netId, mark, servers, name, caCert); return setDoh(netId, mark, encryptedServers, name, caCert); } return 0; Loading Loading @@ -170,10 +188,70 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) const { return status; } NetworkDnsServerSupportReported PrivateDnsConfiguration::getStatusForMetrics(unsigned netId) const { NetworkDnsServerSupportReported event; { std::lock_guard guard(mPrivateDnsLock); if (const auto it = mPrivateDnsModes.find(netId); it != mPrivateDnsModes.end()) { event.set_private_dns_modes(convert_enum_type(it->second)); } else { return event; } } event.set_network_type(resolv_get_network_types_for_net(netId)); const PrivateDnsStatus status = getStatus(netId); std::lock_guard guard(mPrivateDnsLock); if (const auto it = mUnorderedDnsTracker.find(netId); it != mUnorderedDnsTracker.end()) { for (size_t i = 0; i < it->second.size(); i++) { Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_UDP); server->set_index(i); server->set_validated(false); } } if (const auto it = mUnorderedDotTracker.find(netId); it != mUnorderedDotTracker.end()) { int index = 0; const std::list<DnsTlsServer> validatedServers = status.validatedServers(); for (const std::string& s : it->second) { const IPSockAddr target = IPSockAddr::toIPSockAddr(s, kDotPort); bool validated = std::any_of(validatedServers.begin(), validatedServers.end(), [&target](DnsTlsServer server) { return server.addr() == target; }); Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_DOT); server->set_index(index++); server->set_validated(validated); } } if (const auto it = mUnorderedDohTracker.find(netId); it != mUnorderedDohTracker.end()) { int index = 0; for (const std::string& s : it->second) { const IPSockAddr target = IPSockAddr::toIPSockAddr(s, kDohPort); bool validated = std::any_of(status.dohServersMap.begin(), status.dohServersMap.end(), [&target](const auto& entry) { return entry.first == target && entry.second == Validation::success; }); Server* server = event.mutable_servers()->add_server(); server->set_protocol(PROTO_DOH); server->set_index(index++); server->set_validated(validated); } } return event; } void PrivateDnsConfiguration::clear(unsigned netId) { LOG(DEBUG) << "PrivateDnsConfiguration::clear(" << netId << ")"; std::lock_guard guard(mPrivateDnsLock); mPrivateDnsModes.erase(netId); mUnorderedDnsTracker.erase(netId); mUnorderedDotTracker.erase(netId); mUnorderedDohTracker.erase(netId); clearDot(netId); clearDoh(netId); Loading
PrivateDnsConfiguration.h +15 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <netdutils/DumpWriter.h> #include <netdutils/InternetAddresses.h> #include <netdutils/Slice.h> #include <stats.pb.h> #include "DnsTlsServer.h" #include "LockedQueue.h" Loading @@ -39,6 +40,8 @@ namespace android { namespace net { PrivateDnsModes convert_enum_type(PrivateDnsMode mode); struct PrivateDnsStatus { PrivateDnsMode mode; Loading Loading @@ -99,12 +102,15 @@ class PrivateDnsConfiguration { return instance; } int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); int set(int32_t netId, uint32_t mark, const std::vector<std::string>& unencryptedServers, const std::vector<std::string>& encryptedServers, const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); void initDoh() EXCLUDES(mPrivateDnsLock); PrivateDnsStatus getStatus(unsigned netId) const EXCLUDES(mPrivateDnsLock); NetworkDnsServerSupportReported getStatusForMetrics(unsigned netId) const EXCLUDES(mPrivateDnsLock); void clear(unsigned netId) EXCLUDES(mPrivateDnsLock); Loading Loading @@ -184,7 +190,7 @@ class PrivateDnsConfiguration { // TODO: fix the reentrancy problem. PrivateDnsValidationObserver* mObserver GUARDED_BY(mPrivateDnsLock); DohDispatcher* mDohDispatcher; DohDispatcher* mDohDispatcher = nullptr; std::condition_variable mCv; friend class PrivateDnsConfigurationTest; Loading Loading @@ -265,6 +271,12 @@ class PrivateDnsConfiguration { false}, }}; // For the metrics. Store the current DNS server list in the same order as what is passed // in setResolverConfiguration(). std::map<unsigned, std::vector<std::string>> mUnorderedDnsTracker GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::vector<std::string>> mUnorderedDotTracker GUARDED_BY(mPrivateDnsLock); std::map<unsigned, std::vector<std::string>> mUnorderedDohTracker GUARDED_BY(mPrivateDnsLock); struct RecordEntry { RecordEntry(uint32_t netId, const ServerIdentity& identity, Validation state) : netId(netId), serverIdentity(identity), state(state) {} Loading