Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb66fbae authored by Luke Huang's avatar Luke Huang
Browse files

Add getDnsNetId cmd in DnsProxyListener

This command is used to get the netId which resolver
will use for sending DNS query.

Correst ResponseCode.h from const to constexpr
for test.

Input:
    cmd format: getdnsnetid netId
               -netid: selected netid of the process

Output:
    Success: 1. ResponseCode::DnsProxyQueryResult
             2. dnsNetId

    Fail:    1. ResponseCode::DnsProxyQueryResult
             2. -errno

    Possible errno:
                   EINVAL
Bug: 129530368
Test: built, flashed, booted
          system/netd/tests/runtests.sh

Merged-In: Ie81751b762a780ed843bea255c1507ed03660c0e
(cherry picked from commit 4bd0e67a9568e72fe18ac4e0ab98c5bf5e6b75ee)

Change-Id: I18c4c04ab4547dc29cf97abc49ad01563e534e26
parent 2e4ad5bb
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -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,
@@ -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                      *
 *******************************************************/
+9 −1
Original line number Diff line number Diff line
@@ -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;
    };

@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,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;
+72 −0
Original line number Diff line number Diff line
@@ -36,7 +36,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>
@@ -58,6 +60,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.
@@ -70,9 +73,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 {
@@ -3277,3 +3283,69 @@ TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
        dns.clearQueries();
    }
}

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(&currentNetid).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));
}