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

Commit 69f8c1e5 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7080740 from d8420baa to mainline-wifi-release

Change-Id: I50cb2115545db5bdb14b5f1ed4ab25f9ad22426c
parents 38d92adb d8420baa
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -13,6 +13,10 @@ cc_library_headers {
cc_library_headers {
    name: "dnsproxyd_protocol_headers",
    export_include_dirs: ["include/dnsproxyd_protocol"],
    apex_available: [
        "//apex_available:platform",
        "com.android.tethering",
    ],
}

aidl_interface {
@@ -23,6 +27,8 @@ aidl_interface {
        "binder/android/net/ResolverHostsParcel.aidl",
        "binder/android/net/ResolverOptionsParcel.aidl",
        "binder/android/net/ResolverParamsParcel.aidl",
        // New AIDL classes should go into android.net.resolv.aidl so they can be clearly identified
        "binder/android/net/resolv/aidl/**/*.aidl",
    ],
    imports: [
        "netd_event_listener_interface",
@@ -50,6 +56,7 @@ aidl_interface {
        "4",
        "5",
        "6",
        "7",
    ],
}

@@ -101,7 +108,6 @@ cc_library {
        "res_cache.cpp",
        "res_comp.cpp",
        "res_debug.cpp",
        "res_init.cpp",
        "res_mkquery.cpp",
        "res_query.cpp",
        "res_send.cpp",
@@ -259,6 +265,8 @@ cc_test {
        "DnsQueryLogTest.cpp",
        "DnsStatsTest.cpp",
        "ExperimentsTest.cpp",
        "OperationLimiterTest.cpp",
        "PrivateDnsConfigurationTest.cpp",
    ],
    shared_libs: [
        "libcrypto",
@@ -268,7 +276,7 @@ cc_test {
    static_libs: [
        "dnsresolver_aidl_interface-unstable-ndk_platform",
        "netd_aidl_interface-ndk_platform",
        "netd_event_listener_interface-ndk_platform",
        "netd_event_listener_interface-unstable-ndk_platform",
        "libcutils",
        "libgmock",
        "libnetd_resolv",
+86 −140
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@
#include <cutils/misc.h>           // FIRST_APPLICATION_UID
#include <cutils/multiuser.h>
#include <netdutils/InternetAddresses.h>
#include <netdutils/OperationLimiter.h>
#include <netdutils/ResponseCode.h>
#include <netdutils/Slice.h>
#include <netdutils/Stopwatch.h>
@@ -50,6 +49,7 @@

#include "DnsResolver.h"
#include "NetdPermissions.h"
#include "OperationLimiter.h"
#include "PrivateDnsConfiguration.h"
#include "ResolverEventReporter.h"
#include "dnsproxyd_protocol/DnsProxydProtocol.h"  // NETID_USE_LOCAL_NAMESERVERS
@@ -84,25 +84,6 @@ void logArguments(int argc, char** argv) {
    }
}

template<typename T>
void tryThreadOrError(SocketClient* cli, T* handler) {
    cli->incRef();

    const int rval = netdutils::threadLaunch(handler);
    if (rval == 0) {
        // SocketClient decRef() happens in the handler's run() method.
        return;
    }

    char* msg = nullptr;
    asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
    cli->sendMsg(ResponseCode::OperationFailed, msg, false);
    free(msg);

    delete handler;
    cli->decRef();
}

bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
    if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
        return false;
@@ -563,21 +544,31 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
    registerCmd(new GetDnsNetIdCommand());
}

DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
                                                         addrinfo* hints,
                                                         const android_net_context& netcontext)
    : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
void DnsProxyListener::Handler::spawn() {
    const int rval = netdutils::threadLaunch(this);
    if (rval == 0) {
        return;
    }

DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
    free(mHost);
    free(mService);
    free(mHints);
    char* msg = nullptr;
    asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
    mClient->sendMsg(ResponseCode::OperationFailed, msg, false);
    free(msg);
    delete this;
}

static bool evaluate_domain_name(const android_net_context &netcontext,
                                 const char *host) {
    if (!gResNetdCallbacks.evaluate_domain_name)
        return true;
DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::string host,
                                                         std::string service,
                                                         std::unique_ptr<addrinfo> hints,
                                                         const android_net_context& netcontext)
    : Handler(c),
      mHost(move(host)),
      mService(move(service)),
      mHints(move(hints)),
      mNetContext(netcontext) {}

static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) {
    if (!gResNetdCallbacks.evaluate_domain_name) return true;
    return gResNetdCallbacks.evaluate_domain_name(netcontext, host);
}

@@ -634,11 +625,8 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {

    // Write the struct piece by piece because we might be a 64-bit netd
    // talking to a 32-bit process.
    bool success =
            sendBE32(c, ai->ai_flags) &&
            sendBE32(c, ai->ai_family) &&
            sendBE32(c, ai->ai_socktype) &&
            sendBE32(c, ai->ai_protocol);
    bool success = sendBE32(c, ai->ai_flags) && sendBE32(c, ai->ai_family) &&
                   sendBE32(c, ai->ai_socktype) && sendBE32(c, ai->ai_protocol);
    if (!success) {
        return false;
    }
@@ -658,8 +646,6 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {

void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
                                                            NetworkDnsEventReported* event) {
    if (mHost == nullptr) return;

    const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
    const bool unspecWantedButNoIPv6 =
            ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
@@ -677,10 +663,12 @@ void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinf
        // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
        const uid_t uid = mClient->getUid();
        if (queryLimiter.start(uid)) {
            const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
            const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
            mHints->ai_family = AF_INET;
            // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
            // DNS lookup is failed with error EAI_NODATA.
            *rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, res, event);
            *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, res, event);
            queryLimiter.finish(uid);
            if (*rv) {
                *rv = EAI_NODATA;  // return original error code
@@ -718,9 +706,10 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        if (evaluate_domain_name(mNetContext, mHost)) {
            rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result,
                                    &event);
        const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
        const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
        if (evaluate_domain_name(mNetContext, host)) {
            rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, &result, &event);
        } else {
            rv = EAI_SYSTEM;
        }
@@ -763,7 +752,6 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
    reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
                   ip_addrs, total_ip_addr_count);
    freeaddrinfo(result);
    mClient->decRef();
}

std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
@@ -789,8 +777,7 @@ void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* ad

DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}

int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
                                            int argc, char **argv) {
int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, char** argv) {
    logArguments(argc, argv);

    if (argc != 8) {
@@ -802,21 +789,8 @@ int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
        return -1;
    }

    char* name = argv[1];
    if (strcmp("^", name) == 0) {
        name = nullptr;
    } else {
        name = strdup(name);
    }

    char* service = argv[2];
    if (strcmp("^", service) == 0) {
        service = nullptr;
    } else {
        service = strdup(service);
    }

    addrinfo* hints = nullptr;
    const std::string name = argv[1];
    const std::string service = argv[2];
    int ai_flags = strtol(argv[3], nullptr, 10);
    int ai_family = strtol(argv[4], nullptr, 10);
    int ai_socktype = strtol(argv[5], nullptr, 10);
@@ -832,18 +806,16 @@ int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
    }

    if (ai_flags != -1 || ai_family != -1 ||
        ai_socktype != -1 || ai_protocol != -1) {
        hints = (addrinfo*) calloc(1, sizeof(addrinfo));
    std::unique_ptr<addrinfo> hints;
    if (ai_flags != -1 || ai_family != -1 || ai_socktype != -1 || ai_protocol != -1) {
        hints.reset((addrinfo*)calloc(1, sizeof(addrinfo)));
        hints->ai_flags = ai_flags;
        hints->ai_family = ai_family;
        hints->ai_socktype = ai_socktype;
        hints->ai_protocol = ai_protocol;
    }

    DnsProxyListener::GetAddrInfoHandler* handler =
            new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
    tryThreadOrError(cli, handler);
    (new GetAddrInfoHandler(cli, name, service, move(hints), netcontext))->spawn();
    return 0;
}

@@ -888,19 +860,13 @@ int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, c
        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
    }

    DnsProxyListener::ResNSendHandler* handler =
            new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
    tryThreadOrError(cli, handler);
    (new ResNSendHandler(cli, argv[3], flags, netcontext))->spawn();
    return 0;
}

DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
                                                   const android_net_context& netcontext)
    : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}

DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
    mClient->decRef();
}
    : Handler(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}

void DnsProxyListener::ResNSendHandler::run() {
    LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
@@ -1058,8 +1024,7 @@ int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc
 *******************************************************/
DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}

int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
                                            int argc, char **argv) {
int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, char** argv) {
    logArguments(argc, argv);

    if (argc != 4) {
@@ -1074,15 +1039,9 @@ int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
    uid_t uid = cli->getUid();
    unsigned netId = strtoul(argv[1], nullptr, 10);
    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
    char* name = argv[2];
    std::string name = argv[2];
    int af = strtol(argv[3], nullptr, 10);

    if (strcmp(name, "^") == 0) {
        name = nullptr;
    } else {
        name = strdup(name);
    }

    android_net_context netcontext;
    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);

@@ -1090,19 +1049,14 @@ int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
    }

    DnsProxyListener::GetHostByNameHandler* handler =
            new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
    tryThreadOrError(cli, handler);
    (new GetHostByNameHandler(cli, name, af, netcontext))->spawn();
    return 0;
}

DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name,
                                                             int af,
                                                             const android_net_context& netcontext)
    : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}

DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
    free(mName);
}
    : Handler(c), mName(move(name)), mAf(af), mNetContext(netcontext) {}

void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf,
                                                              size_t buflen, struct hostent** hpp,
@@ -1123,7 +1077,8 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hoste
    // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
    const uid_t uid = mClient->getUid();
    if (queryLimiter.start(uid)) {
        *rv = resolv_gethostbyname(mName, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
        const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
        *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
        queryLimiter.finish(uid);
        if (*rv) {
            *rv = EAI_NODATA;  // return original error code
@@ -1152,8 +1107,9 @@ void DnsProxyListener::GetHostByNameHandler::run() {
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        if (evaluate_domain_name(mNetContext, mName)) {
            rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
        const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
        if (evaluate_domain_name(mNetContext, name)) {
            rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
                                      &event);
        } else {
            rv = EAI_SYSTEM;
@@ -1190,7 +1146,6 @@ void DnsProxyListener::GetHostByNameHandler::run() {
    const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
                   mName, ip_addrs, total_ip_addr_count);
    mClient->decRef();
}

std::string DnsProxyListener::GetHostByNameHandler::threadName() {
@@ -1202,8 +1157,7 @@ std::string DnsProxyListener::GetHostByNameHandler::threadName() {
 *******************************************************/
DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}

int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
                                            int argc, char **argv) {
int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient* cli, int argc, char** argv) {
    logArguments(argc, argv);

    if (argc != 5) {
@@ -1222,15 +1176,14 @@ int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
    unsigned netId = strtoul(argv[4], nullptr, 10);
    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);

    void* addr = malloc(sizeof(in6_addr));
    in6_addr addr;
    errno = 0;
    int result = inet_pton(addrFamily, addrStr, addr);
    int result = inet_pton(addrFamily, addrStr, &addr);
    if (result <= 0) {
        char* msg = nullptr;
        asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
        LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
        cli->sendMsg(ResponseCode::OperationFailed, msg, false);
        free(addr);
        free(msg);
        return -1;
    }
@@ -1242,30 +1195,24 @@ int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
    }

    DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
            cli, addr, addrLen, addrFamily, netcontext);
    tryThreadOrError(cli, handler);
    (new GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netcontext))->spawn();
    return 0;
}

DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, in6_addr address,
                                                             int addressLen, int addressFamily,
                                                             const android_net_context& netcontext)
    : mClient(c),
    : Handler(c),
      mAddress(address),
      mAddressLen(addressLen),
      mAddressFamily(addressFamily),
      mNetContext(netcontext) {}

DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
    free(mAddress);
}

void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
                                                                  size_t buflen,
                                                                  struct hostent** hpp,
                                                                  NetworkDnsEventReported* event) {
    if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
    if (*hpp != nullptr || mAddressFamily != AF_INET6) {
        return;
    }

@@ -1280,7 +1227,7 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf,

    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
    struct in6_addr v6addr = *(in6_addr*) mAddress;
    struct in6_addr v6addr = mAddress;
    // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
    if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
        (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
@@ -1320,7 +1267,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() {
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        rv = resolv_gethostbyaddr(mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
        rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
                                  sizeof tmpbuf, &mNetContext, &hp, &event);
        queryLimiter.finish(uid);
    } else {
@@ -1351,7 +1298,6 @@ void DnsProxyListener::GetHostByAddrHandler::run() {

    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
                   (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
    mClient->decRef();
}

std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
+42 −30
Original line number Diff line number Diff line
@@ -38,6 +38,23 @@ class DnsProxyListener : public FrameworkListener {
    static constexpr const char* SOCKET_NAME = "dnsproxyd";

  private:
    class Handler {
      public:
        Handler(SocketClient* c) : mClient(c) { mClient->incRef(); }
        virtual ~Handler() { mClient->decRef(); }
        void operator=(const Handler&) = delete;

        // Attept to spawn the worker thread, or return an error to the client.
        // The Handler instance will self-delete in either case.
        void spawn();

        virtual void run() = 0;
        virtual std::string threadName() = 0;

        SocketClient* mClient;  // ref-counted
    };

    /* ------ getaddrinfo ------*/
    class GetAddrInfoCmd : public FrameworkCommand {
      public:
        GetAddrInfoCmd();
@@ -45,24 +62,22 @@ class DnsProxyListener : public FrameworkListener {
        int runCommand(SocketClient* c, int argc, char** argv) override;
    };

    /* ------ getaddrinfo ------*/
    class GetAddrInfoHandler {
    class GetAddrInfoHandler : public Handler {
      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();
        GetAddrInfoHandler(SocketClient* c, std::string host, std::string service,
                           std::unique_ptr<addrinfo> hints, const android_net_context& netcontext);
        ~GetAddrInfoHandler() override = default;

        void run();
        std::string threadName();
        void run() override;
        std::string threadName() override;

      private:
        void doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event);

        SocketClient* mClient;  // ref counted
        char* mHost;            // owned. TODO: convert to std::string.
        char* mService;         // owned. TODO: convert to std::string.
        addrinfo* mHints;       // owned
        std::string mHost;
        std::string mService;
        std::unique_ptr<addrinfo> mHints;
        android_net_context mNetContext;
    };

@@ -74,21 +89,20 @@ class DnsProxyListener : public FrameworkListener {
        int runCommand(SocketClient* c, int argc, char** argv) override;
    };

    class GetHostByNameHandler {
    class GetHostByNameHandler : public Handler {
      public:
        GetHostByNameHandler(SocketClient* c, char* name, int af,
        GetHostByNameHandler(SocketClient* c, std::string name, int af,
                             const android_net_context& netcontext);
        ~GetHostByNameHandler();
        ~GetHostByNameHandler() override = default;

        void run();
        std::string threadName();
        void run() override;
        std::string threadName() override;

      private:
        void doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf, size_t buflen, hostent** hpp,
                              NetworkDnsEventReported* event);

        SocketClient* mClient;  // ref counted
        char* mName;            // owned. TODO: convert to std::string.
        std::string mName;
        int mAf;
        android_net_context mNetContext;
    };
@@ -101,21 +115,20 @@ class DnsProxyListener : public FrameworkListener {
        int runCommand(SocketClient* c, int argc, char** argv) override;
    };

    class GetHostByAddrHandler {
    class GetHostByAddrHandler : public Handler {
      public:
        GetHostByAddrHandler(SocketClient* c, void* address, int addressLen, int addressFamily,
        GetHostByAddrHandler(SocketClient* c, in6_addr address, int addressLen, int addressFamily,
                             const android_net_context& netcontext);
        ~GetHostByAddrHandler();
        ~GetHostByAddrHandler() override = default;

        void run();
        std::string threadName();
        void run() override;
        std::string threadName() override;

      private:
        void doDns64ReverseLookup(hostent* hbuf, char* buf, size_t buflen, hostent** hpp,
                                  NetworkDnsEventReported* event);

        SocketClient* mClient;  // ref counted
        void* mAddress;         // address to lookup; owned
        in6_addr mAddress;
        int mAddressLen;        // length of address to look up
        int mAddressFamily;     // address family
        android_net_context mNetContext;
@@ -129,17 +142,16 @@ class DnsProxyListener : public FrameworkListener {
        int runCommand(SocketClient* c, int argc, char** argv) override;
    };

    class ResNSendHandler {
    class ResNSendHandler : public Handler {
      public:
        ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
                        const android_net_context& netcontext);
        ~ResNSendHandler();
        ~ResNSendHandler() override = default;

        void run();
        std::string threadName();
        void run() override;
        std::string threadName() override;

      private:
        SocketClient* mClient;  // ref counted
        std::string mMsg;
        uint32_t mFlags;
        android_net_context mNetContext;
+3 −19
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@

#include "DnsQueryLog.h"

#include <android-base/stringprintf.h>
#include "util.h"

namespace android::net {

@@ -45,25 +45,10 @@ std::string maskIps(const std::vector<std::string>& ips) {
    return ret.empty() ? "" : ret.substr(0, ret.length() - 2);
}

// Return the readable string format "hr:min:sec.ms".
std::string timestampToString(const std::chrono::system_clock::time_point& ts) {
    using std::chrono::duration_cast;
    using std::chrono::milliseconds;
    const auto time_sec = std::chrono::system_clock::to_time_t(ts);
    char buf[32];
    std::strftime(buf, sizeof(buf), "%H:%M:%S", std::localtime(&time_sec));
    int ms = duration_cast<milliseconds>(ts.time_since_epoch()).count() % 1000;
    return android::base::StringPrintf("%s.%03d", buf, ms);
}

}  // namespace

void DnsQueryLog::push(Record&& record) {
    std::lock_guard guard(mLock);
    mQueue.push_back(std::move(record));
    if (mQueue.size() > mCapacity) {
        mQueue.pop_front();
    }
    mQueue.push(std::move(record));
}

void DnsQueryLog::dump(netdutils::DumpWriter& dw) const {
@@ -71,8 +56,7 @@ void DnsQueryLog::dump(netdutils::DumpWriter& dw) const {
    netdutils::ScopedIndent indentStats(dw);
    const auto now = std::chrono::system_clock::now();

    std::lock_guard guard(mLock);
    for (const auto& record : mQueue) {
    for (const auto& record : mQueue.copy()) {
        if (now - record.timestamp > mValidityTimeMs) continue;

        const std::string maskedHostname = maskHostname(record.hostname);
+7 −9
Original line number Diff line number Diff line
@@ -17,16 +17,16 @@

#pragma once

#include <deque>
#include <string>
#include <vector>

#include <android-base/thread_annotations.h>
#include <netdutils/DumpWriter.h>

#include "LockedQueue.h"

namespace android::net {

// A circular buffer based class used for query logging. It's thread-safe for concurrent access.
// This class stores query records in a locked ring buffer. It's thread-safe for concurrent access.
class DnsQueryLog {
  public:
    static constexpr std::string_view DUMP_KEYWORD = "querylog";
@@ -52,15 +52,13 @@ class DnsQueryLog {
    // Allow the tests to set the capacity and the validaty time in milliseconds.
    DnsQueryLog(size_t size = kDefaultLogSize,
                std::chrono::milliseconds time = kDefaultValidityMinutes)
        : mCapacity(size), mValidityTimeMs(time) {}
        : mQueue(size), mValidityTimeMs(time) {}

    void push(Record&& record) EXCLUDES(mLock);
    void dump(netdutils::DumpWriter& dw) const EXCLUDES(mLock);
    void push(Record&& record);
    void dump(netdutils::DumpWriter& dw) const;

  private:
    mutable std::mutex mLock;
    std::deque<Record> mQueue GUARDED_BY(mLock);
    const size_t mCapacity;
    LockedRingBuffer<Record> mQueue;
    const std::chrono::milliseconds mValidityTimeMs;

    // The capacity of the circular buffer.
Loading