Loading Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ aidl_interface { local_include_dir: "binder", srcs: [ "binder/android/net/IDnsResolver.aidl", "binder/android/net/ResolverHostsParcel.aidl", "binder/android/net/ResolverParamsParcel.aidl", ], imports: [ Loading Loading @@ -185,8 +186,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ "dnsresolver_aidl_interface-cpp", "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-unstable-ndk_platform", "netd_event_listener_interface-ndk_platform", "libgmock", "liblog", Loading ResolverController.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -232,7 +232,7 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res res_params.retry_count = resolverParams.retryCount; return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, resolverParams.domains, res_params); resolverParams.domains, res_params, resolverParams.hosts); } int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, Loading binder/android/net/ResolverHostsParcel.aidl 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; /** * A mapping list which translates hostnames or domain names to IP addresses * locally. Mapping multiple addresses to one hostname is supported. * It's similar to /etc/hosts file. * * {@hide} */ parcelable ResolverHostsParcel { /** * The IPv4 or IPv6 address corresponding to |hostName| field. */ @utf8InCpp String ipAddr; /** * The hostname is a FQDN. */ @utf8InCpp String hostName = ""; } binder/android/net/ResolverParamsParcel.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.net; import android.net.ResolverHostsParcel; /** * Configuration for a resolver parameters. * Loading Loading @@ -97,4 +99,15 @@ parcelable ResolverParamsParcel { * by the experiement flag. */ int tlsConnectTimeoutMs = 0; /** * An IP/hostname mapping table for DNS local lookup customization. * WARNING: this is intended for local testing and other special situations. * Future versions of the DnsResolver module may break your assumptions. * Injecting static mappings for public hostnames is generally A VERY BAD IDEA, * since it makes it impossible for the domain owners to migrate the domain. * It is also not an effective domain blocking mechanism, because apps can * easily hardcode IPs or bypass the system DNS resolver. */ ResolverHostsParcel[] hosts = {}; } getaddrinfo.cpp +30 −7 Original line number Diff line number Diff line Loading @@ -140,7 +140,9 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai, static void _sethtent(FILE**); static void _endhtent(FILE**); static struct addrinfo* _gethtent(FILE**, const char*, const struct addrinfo*); static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res); static struct addrinfo* getCustomHosts(const size_t netid, const char*, const struct addrinfo*); static bool files_getaddrinfo(const size_t netid, const char* name, const addrinfo* pai, addrinfo** res); static int _find_src_addr(const struct sockaddr*, struct sockaddr*, unsigned, uid_t); static int res_queryN(const char* name, res_target* target, res_state res, int* herrno); Loading Loading @@ -464,7 +466,7 @@ static int explore_fqdn(const addrinfo* pai, const char* hostname, const char* s // If the servname does not match socktype/protocol, return error code. if ((error = get_portmatch(pai, servname))) return error; if (!files_getaddrinfo(hostname, pai, &result)) { if (!files_getaddrinfo(netcontext->dns_netid, hostname, pai, &result)) { error = dns_getaddrinfo(hostname, pai, netcontext, &result, event); } if (error) { Loading Loading @@ -1527,22 +1529,43 @@ found: return res0; } static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res) { static struct addrinfo* getCustomHosts(const size_t netid, const char* _Nonnull name, const struct addrinfo* _Nonnull pai) { struct addrinfo sentinel = {}; struct addrinfo *res0, *res; res = &sentinel; std::vector<std::string> hosts = getCustomizedTableByName(netid, name); for (const std::string& host : hosts) { int error = getaddrinfo_numeric(host.c_str(), nullptr, *pai, &res0); if (!error && res0 != nullptr) { res->ai_next = res0; res = res0; res0 = nullptr; } } return sentinel.ai_next; } static bool files_getaddrinfo(const size_t netid, const char* name, const addrinfo* pai, addrinfo** res) { struct addrinfo sentinel = {}; struct addrinfo *p, *cur; FILE* hostf = NULL; FILE* hostf = nullptr; cur = &sentinel; _sethtent(&hostf); while ((p = _gethtent(&hostf, name, pai)) != NULL) { while ((p = _gethtent(&hostf, name, pai)) != nullptr) { cur->ai_next = p; while (cur && cur->ai_next) cur = cur->ai_next; } _endhtent(&hostf); if ((p = getCustomHosts(netid, name, pai)) != nullptr) { cur->ai_next = p; } *res = sentinel.ai_next; return sentinel.ai_next != NULL; return sentinel.ai_next != nullptr; } /* resolver logic */ Loading Loading
Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ aidl_interface { local_include_dir: "binder", srcs: [ "binder/android/net/IDnsResolver.aidl", "binder/android/net/ResolverHostsParcel.aidl", "binder/android/net/ResolverParamsParcel.aidl", ], imports: [ Loading Loading @@ -185,8 +186,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ "dnsresolver_aidl_interface-cpp", "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-unstable-ndk_platform", "netd_event_listener_interface-ndk_platform", "libgmock", "liblog", Loading
ResolverController.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -232,7 +232,7 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res res_params.retry_count = resolverParams.retryCount; return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, resolverParams.domains, res_params); resolverParams.domains, res_params, resolverParams.hosts); } int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, Loading
binder/android/net/ResolverHostsParcel.aidl 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; /** * A mapping list which translates hostnames or domain names to IP addresses * locally. Mapping multiple addresses to one hostname is supported. * It's similar to /etc/hosts file. * * {@hide} */ parcelable ResolverHostsParcel { /** * The IPv4 or IPv6 address corresponding to |hostName| field. */ @utf8InCpp String ipAddr; /** * The hostname is a FQDN. */ @utf8InCpp String hostName = ""; }
binder/android/net/ResolverParamsParcel.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.net; import android.net.ResolverHostsParcel; /** * Configuration for a resolver parameters. * Loading Loading @@ -97,4 +99,15 @@ parcelable ResolverParamsParcel { * by the experiement flag. */ int tlsConnectTimeoutMs = 0; /** * An IP/hostname mapping table for DNS local lookup customization. * WARNING: this is intended for local testing and other special situations. * Future versions of the DnsResolver module may break your assumptions. * Injecting static mappings for public hostnames is generally A VERY BAD IDEA, * since it makes it impossible for the domain owners to migrate the domain. * It is also not an effective domain blocking mechanism, because apps can * easily hardcode IPs or bypass the system DNS resolver. */ ResolverHostsParcel[] hosts = {}; }
getaddrinfo.cpp +30 −7 Original line number Diff line number Diff line Loading @@ -140,7 +140,9 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai, static void _sethtent(FILE**); static void _endhtent(FILE**); static struct addrinfo* _gethtent(FILE**, const char*, const struct addrinfo*); static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res); static struct addrinfo* getCustomHosts(const size_t netid, const char*, const struct addrinfo*); static bool files_getaddrinfo(const size_t netid, const char* name, const addrinfo* pai, addrinfo** res); static int _find_src_addr(const struct sockaddr*, struct sockaddr*, unsigned, uid_t); static int res_queryN(const char* name, res_target* target, res_state res, int* herrno); Loading Loading @@ -464,7 +466,7 @@ static int explore_fqdn(const addrinfo* pai, const char* hostname, const char* s // If the servname does not match socktype/protocol, return error code. if ((error = get_portmatch(pai, servname))) return error; if (!files_getaddrinfo(hostname, pai, &result)) { if (!files_getaddrinfo(netcontext->dns_netid, hostname, pai, &result)) { error = dns_getaddrinfo(hostname, pai, netcontext, &result, event); } if (error) { Loading Loading @@ -1527,22 +1529,43 @@ found: return res0; } static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo** res) { static struct addrinfo* getCustomHosts(const size_t netid, const char* _Nonnull name, const struct addrinfo* _Nonnull pai) { struct addrinfo sentinel = {}; struct addrinfo *res0, *res; res = &sentinel; std::vector<std::string> hosts = getCustomizedTableByName(netid, name); for (const std::string& host : hosts) { int error = getaddrinfo_numeric(host.c_str(), nullptr, *pai, &res0); if (!error && res0 != nullptr) { res->ai_next = res0; res = res0; res0 = nullptr; } } return sentinel.ai_next; } static bool files_getaddrinfo(const size_t netid, const char* name, const addrinfo* pai, addrinfo** res) { struct addrinfo sentinel = {}; struct addrinfo *p, *cur; FILE* hostf = NULL; FILE* hostf = nullptr; cur = &sentinel; _sethtent(&hostf); while ((p = _gethtent(&hostf, name, pai)) != NULL) { while ((p = _gethtent(&hostf, name, pai)) != nullptr) { cur->ai_next = p; while (cur && cur->ai_next) cur = cur->ai_next; } _endhtent(&hostf); if ((p = getCustomHosts(netid, name, pai)) != nullptr) { cur->ai_next = p; } *res = sentinel.ai_next; return sentinel.ai_next != NULL; return sentinel.ai_next != nullptr; } /* resolver logic */ Loading