Loading DnsProxyListener.cpp +39 −0 Original line number Diff line number Diff line Loading @@ -498,6 +498,7 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { registerCmd(new GetHostByAddrCmd()); registerCmd(new GetHostByNameCmd()); registerCmd(new ResNSendCommand()); registerCmd(new GetDnsNetIdCommand()); } DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service, Loading Loading @@ -896,6 +897,44 @@ void DnsProxyListener::ResNSendHandler::run() { } } namespace { bool sendCodeAndBe32(SocketClient* c, int code, int data) { return c->sendCode(code) || sendBE32(c, data); } } // namespace /******************************************************* * GetDnsNetId * *******************************************************/ DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {} int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) { logArguments(argc, argv); const uid_t uid = cli->getUid(); if (argc != 2) { LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid << ", invalid number of arguments to getdnsnetid: " << argc; sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL); return -1; } unsigned netId; if (!simpleStrtoul(argv[1], &netId)) { LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid << ", invalid netId"; sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL); return -1; } android_net_context netcontext; gResNetdCallbacks.get_network_context(netId, uid, &netcontext); return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.dns_netid); } /******************************************************* * GetHostByName * *******************************************************/ Loading DnsProxyListener.h +9 −1 Original line number Diff line number Diff line Loading @@ -116,7 +116,7 @@ class DnsProxyListener : public FrameworkListener { class ResNSendCommand : public FrameworkCommand { public: ResNSendCommand(); ~ResNSendCommand() override {} virtual ~ResNSendCommand() {} int runCommand(SocketClient* c, int argc, char** argv) override; }; Loading @@ -134,6 +134,14 @@ class DnsProxyListener : public FrameworkListener { uint32_t mFlags; android_net_context mNetContext; }; /* ------ getdnsnetid ------*/ class GetDnsNetIdCommand : public FrameworkCommand { public: GetDnsNetIdCommand(); virtual ~GetDnsNetIdCommand() {} int runCommand(SocketClient* c, int argc, char** argv) override; }; }; } // namespace net Loading dns_responder/dns_responder_client.h +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public: virtual void TearDown(); android::net::IDnsResolver* resolvService() const { return mDnsResolvSrv.get(); } android::net::INetd* netdService() const { return mNetdSrv.get(); } private: android::sp<android::net::INetd> mNetdSrv = nullptr; Loading resolver_test.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ #include <numeric> #include <thread> #include <android-base/parseint.h> #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <android/multinetwork.h> // ResNsendFlags #include <cutils/sockets.h> #include <gmock/gmock-matchers.h> Loading @@ -57,6 +59,7 @@ #include "android/net/IDnsResolver.h" #include "binder/IServiceManager.h" #include "netdutils/ResponseCode.h" #include "netdutils/SocketOption.h" // TODO: make this dynamic and stop depending on implementation details. Loading @@ -69,9 +72,12 @@ extern "C" int android_getaddrinfofornet(const char* hostname, const char* servn const addrinfo* hints, unsigned netid, unsigned mark, struct addrinfo** result); using android::base::ParseInt; using android::base::StringPrintf; using android::base::unique_fd; using android::net::ResolverStats; using android::netdutils::enableSockopt; using android::netdutils::ResponseCode; // TODO: move into libnetdutils? namespace { Loading Loading @@ -3314,3 +3320,69 @@ TEST_F(ResolverTest, PrefixDiscoveryBypassTls) { EXPECT_EQ(0, tls.queries()); EXPECT_EQ(1U, GetNumQueries(dns, dns64_name)); } namespace { void sendCommand(int fd, const std::string& cmd) { ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1)); EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1)); } int32_t readBE32(int fd) { int32_t tmp; int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp))); EXPECT_TRUE(n > 0); return ntohl(tmp); } int readResonseCode(int fd) { char buf[4]; int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf))); EXPECT_TRUE(n > 0); // The format of response code is that 4 bytes for the code & null. buf[3] = '\0'; int result; EXPECT_TRUE(ParseInt(buf, &result)); return result; } } // namespace TEST_F(ResolverTest, getDnsNetId) { // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first. setNetworkForProcess(NETID_UNSET); int currentNetid; EXPECT_TRUE(mDnsClient.netdService()->networkGetDefault(¤tNetid).isOk()); int dnsNetId = getNetworkForDns(); // Assume no vpn. EXPECT_EQ(currentNetid, dnsNetId); // Test with setNetworkForProcess setNetworkForProcess(TEST_NETID); dnsNetId = getNetworkForDns(); EXPECT_EQ(TEST_NETID, dnsNetId); // Set back setNetworkForProcess(NETID_UNSET); // Test with setNetworkForResolv setNetworkForResolv(TEST_NETID); dnsNetId = getNetworkForDns(); EXPECT_EQ(TEST_NETID, dnsNetId); // Set back setNetworkForResolv(NETID_UNSET); // Create socket connected to DnsProxyListener int fd = dns_open_proxy(); EXPECT_TRUE(fd > 0); unique_fd ufd(fd); // Test command with wrong netId sendCommand(fd, "getdnsnetid abc"); EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResonseCode(fd)); EXPECT_EQ(-EINVAL, readBE32(fd)); // Test unsupported command sendCommand(fd, "getdnsnetidNotSupported"); // Keep in sync with FrameworkListener.cpp (500, "Command not recognized") EXPECT_EQ(500, readResonseCode(fd)); } Loading
DnsProxyListener.cpp +39 −0 Original line number Diff line number Diff line Loading @@ -498,6 +498,7 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { registerCmd(new GetHostByAddrCmd()); registerCmd(new GetHostByNameCmd()); registerCmd(new ResNSendCommand()); registerCmd(new GetDnsNetIdCommand()); } DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service, Loading Loading @@ -896,6 +897,44 @@ void DnsProxyListener::ResNSendHandler::run() { } } namespace { bool sendCodeAndBe32(SocketClient* c, int code, int data) { return c->sendCode(code) || sendBE32(c, data); } } // namespace /******************************************************* * GetDnsNetId * *******************************************************/ DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {} int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) { logArguments(argc, argv); const uid_t uid = cli->getUid(); if (argc != 2) { LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid << ", invalid number of arguments to getdnsnetid: " << argc; sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL); return -1; } unsigned netId; if (!simpleStrtoul(argv[1], &netId)) { LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid << ", invalid netId"; sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL); return -1; } android_net_context netcontext; gResNetdCallbacks.get_network_context(netId, uid, &netcontext); return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.dns_netid); } /******************************************************* * GetHostByName * *******************************************************/ Loading
DnsProxyListener.h +9 −1 Original line number Diff line number Diff line Loading @@ -116,7 +116,7 @@ class DnsProxyListener : public FrameworkListener { class ResNSendCommand : public FrameworkCommand { public: ResNSendCommand(); ~ResNSendCommand() override {} virtual ~ResNSendCommand() {} int runCommand(SocketClient* c, int argc, char** argv) override; }; Loading @@ -134,6 +134,14 @@ class DnsProxyListener : public FrameworkListener { uint32_t mFlags; android_net_context mNetContext; }; /* ------ getdnsnetid ------*/ class GetDnsNetIdCommand : public FrameworkCommand { public: GetDnsNetIdCommand(); virtual ~GetDnsNetIdCommand() {} int runCommand(SocketClient* c, int argc, char** argv) override; }; }; } // namespace net Loading
dns_responder/dns_responder_client.h +1 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public: virtual void TearDown(); android::net::IDnsResolver* resolvService() const { return mDnsResolvSrv.get(); } android::net::INetd* netdService() const { return mNetdSrv.get(); } private: android::sp<android::net::INetd> mNetdSrv = nullptr; Loading
resolver_test.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ #include <numeric> #include <thread> #include <android-base/parseint.h> #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <android/multinetwork.h> // ResNsendFlags #include <cutils/sockets.h> #include <gmock/gmock-matchers.h> Loading @@ -57,6 +59,7 @@ #include "android/net/IDnsResolver.h" #include "binder/IServiceManager.h" #include "netdutils/ResponseCode.h" #include "netdutils/SocketOption.h" // TODO: make this dynamic and stop depending on implementation details. Loading @@ -69,9 +72,12 @@ extern "C" int android_getaddrinfofornet(const char* hostname, const char* servn const addrinfo* hints, unsigned netid, unsigned mark, struct addrinfo** result); using android::base::ParseInt; using android::base::StringPrintf; using android::base::unique_fd; using android::net::ResolverStats; using android::netdutils::enableSockopt; using android::netdutils::ResponseCode; // TODO: move into libnetdutils? namespace { Loading Loading @@ -3314,3 +3320,69 @@ TEST_F(ResolverTest, PrefixDiscoveryBypassTls) { EXPECT_EQ(0, tls.queries()); EXPECT_EQ(1U, GetNumQueries(dns, dns64_name)); } namespace { void sendCommand(int fd, const std::string& cmd) { ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1)); EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1)); } int32_t readBE32(int fd) { int32_t tmp; int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp))); EXPECT_TRUE(n > 0); return ntohl(tmp); } int readResonseCode(int fd) { char buf[4]; int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf))); EXPECT_TRUE(n > 0); // The format of response code is that 4 bytes for the code & null. buf[3] = '\0'; int result; EXPECT_TRUE(ParseInt(buf, &result)); return result; } } // namespace TEST_F(ResolverTest, getDnsNetId) { // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first. setNetworkForProcess(NETID_UNSET); int currentNetid; EXPECT_TRUE(mDnsClient.netdService()->networkGetDefault(¤tNetid).isOk()); int dnsNetId = getNetworkForDns(); // Assume no vpn. EXPECT_EQ(currentNetid, dnsNetId); // Test with setNetworkForProcess setNetworkForProcess(TEST_NETID); dnsNetId = getNetworkForDns(); EXPECT_EQ(TEST_NETID, dnsNetId); // Set back setNetworkForProcess(NETID_UNSET); // Test with setNetworkForResolv setNetworkForResolv(TEST_NETID); dnsNetId = getNetworkForDns(); EXPECT_EQ(TEST_NETID, dnsNetId); // Set back setNetworkForResolv(NETID_UNSET); // Create socket connected to DnsProxyListener int fd = dns_open_proxy(); EXPECT_TRUE(fd > 0); unique_fd ufd(fd); // Test command with wrong netId sendCommand(fd, "getdnsnetid abc"); EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResonseCode(fd)); EXPECT_EQ(-EINVAL, readBE32(fd)); // Test unsupported command sendCommand(fd, "getdnsnetidNotSupported"); // Keep in sync with FrameworkListener.cpp (500, "Command not recognized") EXPECT_EQ(500, readResonseCode(fd)); }