Move resolv_init out and make callbacks of libnetd_resolv global
1. Revise init flow of libnetd_resolv
- A better and generic design for it
2. Rename and make callbacks from netd global
- libnetd_resolv has multiple components need to use it
- res* component could use it easily
Bug: 126141549
Test: built, flashed, booted
system/netd/tests/runtests.sh pass
Change-Id: Iacb4fd708a26fd9c9139a606f0320fc12b4fc7e1
diff --git a/Android.bp b/Android.bp
index 7f0df77..2b84a67 100644
--- a/Android.bp
+++ b/Android.bp
@@ -31,6 +31,7 @@
"res_state.cpp",
"res_stats.cpp",
"DnsProxyListener.cpp",
+ "DnsResolver.cpp",
"DnsResolverService.cpp",
"DnsTlsDispatcher.cpp",
"DnsTlsQueryMap.cpp",
diff --git a/DnsProxyListener.cpp b/DnsProxyListener.cpp
index 94ba354..edd701c 100644
--- a/DnsProxyListener.cpp
+++ b/DnsProxyListener.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "DnsProxyListener.h"
+
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
@@ -33,8 +35,6 @@
#include <list>
#include <vector>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android/multinetwork.h> // ResNsendFlags
#include <cutils/misc.h> // FIRST_APPLICATION_UID
@@ -47,8 +47,7 @@
#include <sysutils/SocketClient.h>
// TODO: Considering moving ResponseCode.h Stopwatch.h thread_util.h to libnetdutils.
-#include "DnsProxyListener.h"
-#include "DnsResolverService.h"
+#include "DnsResolver.h"
#include "NetdClient.h" // NETID_USE_LOCAL_NAMESERVERS
#include "NetdPermissions.h"
#include "ResolverEventReporter.h"
@@ -61,32 +60,6 @@
using aidl::android::net::metrics::INetdEventListener;
-static android::net::DnsProxyListener gDnsProxyListener;
-
-bool resolv_init(const dnsproxylistener_callbacks& callbacks) {
- android::base::InitLogging(/*argv=*/nullptr);
- android::base::SetDefaultTag("libnetd_resolv");
- ALOGI("Initializing resolver");
- const std::string logSeverityStr =
- android::base::GetProperty("persist.sys.nw_dns_resolver_log", "WARNING");
- android::base::SetMinimumLogSeverity(logSeverityStrToEnum(logSeverityStr));
-
- if (!gDnsProxyListener.setCallbacks(callbacks)) {
- ALOGE("Unable to set callbacks to DnsProxyListener");
- return false;
- }
- if (gDnsProxyListener.startListener()) {
- ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
- return false;
- }
- binder_status_t ret;
- if ((ret = android::net::DnsResolverService::start(callbacks)) != STATUS_OK) {
- ALOGE("Unable to start DnsResolverService: %d", ret);
- return false;
- }
- return true;
-}
-
namespace android {
namespace net {
@@ -166,7 +139,7 @@
for (const char* const permission :
{PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
PERM_MAINLINE_NETWORK_STACK}) {
- if (gDnsProxyListener.mCallbacks.check_calling_permission(permission)) {
+ if (gResNetdCallbacks.check_calling_permission(permission)) {
return true;
}
}
@@ -506,7 +479,7 @@
bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
in6_addr v6addr{};
uint8_t prefixLen = 0;
- if (!gDnsProxyListener.mCallbacks.get_dns64_prefix(netId, &v6addr, &prefixLen)) {
+ if (!gResNetdCallbacks.get_dns64_prefix(netId, &v6addr, &prefixLen)) {
return false;
}
const netdutils::IPAddress ipv6(v6addr);
@@ -516,12 +489,6 @@
} // namespace
-bool DnsProxyListener::setCallbacks(const dnsproxylistener_callbacks& callbacks) {
- mCallbacks = callbacks;
- return mCallbacks.check_calling_permission && mCallbacks.get_network_context &&
- mCallbacks.get_dns64_prefix;
-}
-
DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
registerCmd(new GetAddrInfoCmd());
registerCmd(new GetHostByAddrCmd());
@@ -765,7 +732,7 @@
const uid_t uid = cli->getUid();
android_net_context netcontext;
- gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+ gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
if (useLocalNameservers) {
netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
@@ -820,7 +787,7 @@
}
android_net_context netcontext;
- gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+ gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
if (checkAndClearUseLocalNameserversFlag(&netId)) {
netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
}
@@ -949,7 +916,7 @@
}
android_net_context netcontext;
- gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+ gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
if (useLocalNameservers) {
netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
@@ -1087,7 +1054,7 @@
}
android_net_context netcontext;
- gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+ gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
if (useLocalNameservers) {
netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
diff --git a/DnsProxyListener.h b/DnsProxyListener.h
index 048744e..ea2b869 100644
--- a/DnsProxyListener.h
+++ b/DnsProxyListener.h
@@ -17,6 +17,8 @@
#ifndef _DNSPROXYLISTENER_H__
#define _DNSPROXYLISTENER_H__
+#include <string>
+
#include <netd_resolv/resolv.h> // android_net_context
#include <sysutils/FrameworkCommand.h>
#include <sysutils/FrameworkListener.h>
@@ -29,13 +31,8 @@
DnsProxyListener();
virtual ~DnsProxyListener() {}
- bool setCallbacks(const dnsproxylistener_callbacks& callbacks);
-
static constexpr const char* SOCKET_NAME = "dnsproxyd";
- // TODO: Considering putting this callbacks structure in its own file.
- dnsproxylistener_callbacks mCallbacks{};
-
private:
class GetAddrInfoCmd : public FrameworkCommand {
public:
diff --git a/DnsResolver.cpp b/DnsResolver.cpp
new file mode 100644
index 0000000..a9d2f85
--- /dev/null
+++ b/DnsResolver.cpp
@@ -0,0 +1,79 @@
+/**
+ * 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.
+ */
+
+#include "DnsResolver.h"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+
+#include <resolv.h>
+#include "DnsProxyListener.h"
+#include "DnsResolverService.h"
+#include "resolv_private.h"
+
+bool resolv_init(const ResolverNetdCallbacks& callbacks) {
+ android::base::InitLogging(/*argv=*/nullptr);
+ android::base::SetDefaultTag("libnetd_resolv");
+ LOG(INFO) << "Initializing resolver";
+ const std::string logSeverityStr =
+ android::base::GetProperty("persist.sys.nw_dns_resolver_log", "WARNING");
+ android::base::SetMinimumLogSeverity(logSeverityStrToEnum(logSeverityStr));
+
+ android::net::gResNetdCallbacks = callbacks;
+ android::net::gDnsResolv = android::net::DnsResolver::getInstance();
+ return android::net::gDnsResolv->start();
+}
+
+namespace android {
+namespace net {
+
+namespace {
+
+bool verifyCallbacks() {
+ return gResNetdCallbacks.check_calling_permission && gResNetdCallbacks.get_network_context &&
+ gResNetdCallbacks.get_dns64_prefix;
+}
+
+} // namespace
+
+DnsResolver* gDnsResolv = nullptr;
+ResolverNetdCallbacks gResNetdCallbacks;
+
+DnsResolver* DnsResolver::getInstance() {
+ // Instantiated on first use.
+ static DnsResolver instance;
+ return &instance;
+}
+
+bool DnsResolver::start() {
+ if (!verifyCallbacks()) {
+ LOG(ERROR) << "Callback verification failed";
+ return false;
+ }
+ if (mDnsProxyListener.startListener()) {
+ PLOG(ERROR) << "Unable to start DnsProxyListener";
+ return false;
+ }
+ binder_status_t ret;
+ if ((ret = DnsResolverService::start()) != STATUS_OK) {
+ LOG(ERROR) << "Unable to start DnsResolverService: " << ret;
+ return false;
+ }
+ return true;
+}
+
+} // namespace net
+} // namespace android
diff --git a/DnsResolver.h b/DnsResolver.h
new file mode 100644
index 0000000..e038c89
--- /dev/null
+++ b/DnsResolver.h
@@ -0,0 +1,45 @@
+/**
+ * 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.
+ */
+
+#ifndef _DNS_RESOLVER_H_
+#define _DNS_RESOLVER_H_
+
+#include <resolv.h>
+#include "DnsProxyListener.h"
+
+namespace android {
+namespace net {
+
+class DnsResolver {
+ public:
+ static DnsResolver* getInstance();
+ bool start();
+
+ DnsResolver(DnsResolver const&) = delete;
+ void operator=(DnsResolver const&) = delete;
+
+ private:
+ DnsResolver() {}
+ DnsProxyListener mDnsProxyListener;
+};
+
+extern DnsResolver* gDnsResolv;
+extern ResolverNetdCallbacks gResNetdCallbacks;
+
+} // namespace net
+} // namespace android
+
+#endif // _DNS_RESOLVER_H_
diff --git a/DnsResolverService.cpp b/DnsResolverService.cpp
index adf698b..fa61f9d 100644
--- a/DnsResolverService.cpp
+++ b/DnsResolverService.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "DnsResolverService"
+#include "DnsResolverService.h"
+
#include <set>
#include <vector>
@@ -26,7 +28,7 @@
#include <log/log.h>
#include <private/android_filesystem_config.h> // AID_SYSTEM
-#include "DnsResolverService.h"
+#include "DnsResolver.h"
#include "NetdPermissions.h" // PERM_*
using android::base::Join;
@@ -53,10 +55,10 @@
} // namespace
-binder_status_t DnsResolverService::start(const dnsproxylistener_callbacks& callbacks) {
+binder_status_t DnsResolverService::start() {
// TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010
// NetdNativeService does call disableBackgroundScheduling currently, so it is fine now.
- DnsResolverService* resolverService = new DnsResolverService(callbacks);
+ DnsResolverService* resolverService = new DnsResolverService();
binder_status_t status =
AServiceManager_addService(resolverService->asBinder().get(), getServiceName());
if (status != STATUS_OK) {
@@ -82,7 +84,7 @@
const std::vector<const char*>& permissions) {
// TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports
// check_permission.
- if (!mCallbacks.check_calling_permission) {
+ if (!gResNetdCallbacks.check_calling_permission) {
return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
EX_NULL_POINTER, "check_calling_permission is null"));
}
@@ -103,7 +105,7 @@
}
for (const char* permission : permissions) {
- if (mCallbacks.check_calling_permission(permission)) {
+ if (gResNetdCallbacks.check_calling_permission(permission)) {
return ::ndk::ScopedAStatus(AStatus_newOk());
}
}
diff --git a/DnsResolverService.h b/DnsResolverService.h
index f8a83bf..3100cc6 100644
--- a/DnsResolverService.h
+++ b/DnsResolverService.h
@@ -29,18 +29,16 @@
class DnsResolverService : public aidl::android::net::BnDnsResolver {
public:
- DnsResolverService(const dnsproxylistener_callbacks& callbacks) : mCallbacks(callbacks) {}
- static binder_status_t start(const dnsproxylistener_callbacks& callbacks);
+ static binder_status_t start();
static char const* getServiceName() { return "dnsresolver"; }
// TODO: Add dump() after libbinder_ndk support it.
::ndk::ScopedAStatus isAlive(bool* alive) override;
private:
+ DnsResolverService() {}
// TODO: Remove below items after libbiner_ndk supports check_permission.
::ndk::ScopedAStatus checkAnyPermission(const std::vector<const char*>& permissions);
-
- dnsproxylistener_callbacks mCallbacks{};
};
} // namespace net
diff --git a/include/netd_resolv/resolv.h b/include/netd_resolv/resolv.h
index 2e65370..b5518e4 100644
--- a/include/netd_resolv/resolv.h
+++ b/include/netd_resolv/resolv.h
@@ -110,7 +110,7 @@
// TODO: Remove the callback after moving NAT64 prefix discovery out of netd to libnetd_resolv.
typedef bool (*get_dns64_prefix_callback)(unsigned netid, in6_addr* prefix, uint8_t* prefix_len);
-struct dnsproxylistener_callbacks {
+struct ResolverNetdCallbacks {
check_calling_permission_callback check_calling_permission;
get_network_context_callback get_network_context;
get_dns64_prefix_callback get_dns64_prefix;
@@ -150,7 +150,7 @@
// Delete the cache associated with a certain network
LIBNETD_RESOLV_PUBLIC void resolv_delete_cache_for_net(unsigned netid);
-// Set callbacks to DnsProxyListener, and bring it up.
-LIBNETD_RESOLV_PUBLIC bool resolv_init(const dnsproxylistener_callbacks& callbacks);
+// Set callbacks and bring DnsResolver up.
+LIBNETD_RESOLV_PUBLIC bool resolv_init(const ResolverNetdCallbacks& callbacks);
#endif // NETD_RESOLV_RESOLV_H
diff --git a/include/netd_resolv/resolv_stub.h b/include/netd_resolv/resolv_stub.h
index 9168ab2..5f78908 100644
--- a/include/netd_resolv/resolv_stub.h
+++ b/include/netd_resolv/resolv_stub.h
@@ -58,7 +58,7 @@
bool (*resolv_has_nameservers)(unsigned netid);
- bool (*resolv_init)(const dnsproxylistener_callbacks& callbacks);
+ bool (*resolv_init)(const ResolverNetdCallbacks& callbacks);
int (*resolv_set_nameservers_for_net)(unsigned netid, const char** servers, unsigned numservers,
const char* domains, const res_params* params);