Move DnsProxyListener to libnetd_resolv
[1] Support APIs for netd to set callbacks and bring up
DnsProxyListener.
[2] Keep DnsProxyListener functioning as usual by function pointers,
including getNetworkContext(), checkCallingPermission(), and
getPrefix64().
[3] Use libbinder_ndk to report onDnsEvent().
Test: as follows
- built, flashed, booted
- system/netd/tests/runtests.sh passed
- netd_benchmark passed
- Browsing websites passed
Change-Id: Ib6575833c248579aa079e302795b6d6cddde1f2b
diff --git a/resolv/include/netd_resolv/DnsProxyListener.h b/resolv/include/netd_resolv/DnsProxyListener.h
new file mode 100644
index 0000000..ef9a3da
--- /dev/null
+++ b/resolv/include/netd_resolv/DnsProxyListener.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 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 _DNSPROXYLISTENER_H__
+#define _DNSPROXYLISTENER_H__
+
+#include <sysutils/FrameworkCommand.h>
+#include <sysutils/FrameworkListener.h>
+
+#include "resolv.h" // android_net_context
+
+namespace android {
+namespace net {
+
+class DnsProxyListener : public FrameworkListener {
+ public:
+ 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:
+ GetAddrInfoCmd();
+ virtual ~GetAddrInfoCmd() {}
+ int runCommand(SocketClient* c, int argc, char** argv) override;
+ };
+
+ /* ------ getaddrinfo ------*/
+ class GetAddrInfoHandler {
+ public:
+ // Note: All of host, service, and hints may be NULL
+ GetAddrInfoHandler(SocketClient* c, char* host, char* service, addrinfo* hints,
+ const android_net_context& netcontext);
+ ~GetAddrInfoHandler();
+
+ void run();
+
+ private:
+ void doDns64Synthesis(int32_t* rv, addrinfo** res);
+
+ SocketClient* mClient; // ref counted
+ char* mHost; // owned. TODO: convert to std::string.
+ char* mService; // owned. TODO: convert to std::string.
+ addrinfo* mHints; // owned
+ android_net_context mNetContext;
+ };
+
+ /* ------ gethostbyname ------*/
+ class GetHostByNameCmd : public FrameworkCommand {
+ public:
+ GetHostByNameCmd();
+ virtual ~GetHostByNameCmd() {}
+ int runCommand(SocketClient* c, int argc, char** argv) override;
+ };
+
+ class GetHostByNameHandler {
+ public:
+ GetHostByNameHandler(SocketClient* c, char* name, int af,
+ const android_net_context& netcontext);
+ ~GetHostByNameHandler();
+
+ void run();
+
+ private:
+ void doDns64Synthesis(int32_t* rv, hostent** hpp);
+
+ SocketClient* mClient; //ref counted
+ char* mName; // owned. TODO: convert to std::string.
+ int mAf;
+ android_net_context mNetContext;
+ };
+
+ /* ------ gethostbyaddr ------*/
+ class GetHostByAddrCmd : public FrameworkCommand {
+ public:
+ GetHostByAddrCmd();
+ virtual ~GetHostByAddrCmd() {}
+ int runCommand(SocketClient* c, int argc, char** argv) override;
+ };
+
+ class GetHostByAddrHandler {
+ public:
+ GetHostByAddrHandler(SocketClient* c, void* address, int addressLen, int addressFamily,
+ const android_net_context& netcontext);
+ ~GetHostByAddrHandler();
+
+ void run();
+
+ private:
+ void doDns64ReverseLookup(hostent** hpp);
+
+ SocketClient* mClient; // ref counted
+ void* mAddress; // address to lookup; owned
+ int mAddressLen; // length of address to look up
+ int mAddressFamily; // address family
+ android_net_context mNetContext;
+ };
+
+ /* ------ resnsend ------*/
+ class ResNSendCommand : public FrameworkCommand {
+ public:
+ ResNSendCommand();
+ ~ResNSendCommand() override {}
+ int runCommand(SocketClient* c, int argc, char** argv) override;
+ };
+
+ class ResNSendHandler {
+ public:
+ ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
+ const android_net_context& netcontext);
+ ~ResNSendHandler();
+
+ void run();
+
+ private:
+ SocketClient* mClient; // ref counted
+ std::string mMsg;
+ uint32_t mFlags;
+ android_net_context mNetContext;
+ };
+};
+
+} // namespace net
+} // namespace android
+
+#endif
diff --git a/resolv/include/netd_resolv/resolv.h b/resolv/include/netd_resolv/resolv.h
index 4f43107..dde600d 100644
--- a/resolv/include/netd_resolv/resolv.h
+++ b/resolv/include/netd_resolv/resolv.h
@@ -45,7 +45,7 @@
} sockaddr_union;
/*
- * Passing NETID_UNSET as the netId causes system/netd/server/DnsProxyListener.cpp to
+ * Passing NETID_UNSET as the netId causes system/netd/resolv/DnsProxyListener.cpp to
* fill in the appropriate default netId for the query.
*/
#define NETID_UNSET 0u
@@ -101,9 +101,31 @@
} serverStatus[MAXNS];
};
+/*
+ * Some of functions (e.g. checkCallingPermission()) require the dependency on libbinder.so,
+ * but we can't include the library since it's not stable. Move the functions to netd and use
+ * these function pointers pointing to them.
+ */
+typedef void (*get_network_context_callback)(unsigned netid, uid_t uid,
+ android_net_context* netcontext);
+
+// TODO: investigate having the resolver check permissions itself, either by adding support to
+// libbinder_ndk or by converting IPermissionController into a stable AIDL interface.
+typedef bool (*check_calling_permission_callback)(const char* permission);
+
+// TODO: Remove the callback.
typedef void (*private_dns_validated_callback)(unsigned netid, const char* server,
const char* hostname, bool success);
+// 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 {
+ check_calling_permission_callback check_calling_permission;
+ get_network_context_callback get_network_context;
+ get_dns64_prefix_callback get_dns64_prefix;
+};
+
LIBNETD_RESOLV_PUBLIC int android_gethostbyaddrfornetcontext(const void*, socklen_t, int,
const android_net_context*, hostent**);
LIBNETD_RESOLV_PUBLIC int android_gethostbynamefornetcontext(const char*, int,
@@ -136,10 +158,14 @@
ExternalPrivateDnsStatus* status);
// Register callback to listen whether private DNS validated
+// TODO: Remove it. Use ResolverEventReporter instead.
LIBNETD_RESOLV_PUBLIC void resolv_register_private_dns_callback(
private_dns_validated_callback callback);
// 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);
+
#endif // NETD_RESOLV_RESOLV_H
diff --git a/resolv/include/netd_resolv/resolv_stub.h b/resolv/include/netd_resolv/resolv_stub.h
index b4364ba..9e09b44 100644
--- a/resolv/include/netd_resolv/resolv_stub.h
+++ b/resolv/include/netd_resolv/resolv_stub.h
@@ -63,6 +63,8 @@
bool (*resolv_has_nameservers)(unsigned netid);
+ bool (*resolv_init)(const dnsproxylistener_callbacks& callbacks);
+
void (*resolv_register_private_dns_callback)(private_dns_validated_callback callback);
int (*resolv_res_nsend)(const android_net_context* netContext, const u_char* msg, int msgLen,