OSDN Git Service

DO NOT MERGE Extending DNS event reporting
authorMichal Karpinski <mkarpinski@google.com>
Thu, 6 Oct 2016 17:06:00 +0000 (18:06 +0100)
committerMichal Karpinski <mkarpinski@google.com>
Fri, 2 Dec 2016 17:20:17 +0000 (17:20 +0000)
This adds hostname, array of addresses, total count of IP addresses
and uid to the existing pipeline.
Currently ignores the new data it receives, further work will be
done in the subsequent CLs.

Test: for now just the benchmarking, in the future CTS

Bug: 29748723

(cherry picked from commit 36deff74215db202db9e29aa7ff1375ae5f2bc5d)

Change-Id: I16d690052fb01fc6d2bc3a57d4550f22236cd0fa

server/DnsProxyListener.cpp
server/DnsProxyListener.h
server/EventReporter.h
server/binder/android/net/metrics/INetdEventListener.aidl

index 0e4058f..dc31b1a 100644 (file)
 #define VDBG 0
 
 #include <chrono>
+#include <vector>
 
 #include <cutils/log.h>
+#include <utils/String16.h>
 #include <sysutils/SocketClient.h>
 
 #include "Fwmark.h"
@@ -46,6 +48,7 @@
 #include "Stopwatch.h"
 #include "android/net/metrics/INetdEventListener.h"
 
+using android::String16;
 using android::net::metrics::INetdEventListener;
 
 DnsProxyListener::DnsProxyListener(const NetworkController* netCtrl, EventReporter* eventReporter) :
@@ -192,7 +195,19 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
             ALOGW("Error writing DNS result to client");
         }
     }
+    std::vector<String16> ip_addrs;
+    int total_ip_addr_count = 0;
     if (result) {
+        if (mNetdEventListener != nullptr
+                && mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
+            for (addrinfo* ai = result; ai; ai = ai->ai_next) {
+                sockaddr* ai_addr = ai->ai_addr;
+                if (ai_addr) {
+                    addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
+                    total_ip_addr_count++;
+                }
+            }
+        }
         freeaddrinfo(result);
     }
     mClient->decRef();
@@ -202,13 +217,17 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
                 // Skip reporting.
                 break;
             case INetdEventListener::REPORTING_LEVEL_METRICS:
-                // Reporting is on. Send metrics.
+                // Metrics reporting is on. Send metrics.
                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
-                                              INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
-                                              latencyMs);
+                                               INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
+                                               latencyMs, String16(""), {}, -1, -1);
                 break;
             case INetdEventListener::REPORTING_LEVEL_FULL:
-                // TODO add full info reporting
+                // Full event info reporting is on. Send full info.
+                mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
+                                               INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
+                                               latencyMs, String16(mHost), ip_addrs,
+                                               total_ip_addr_count, mNetContext.uid);
                 break;
         }
     } else {
@@ -216,6 +235,19 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
     }
 }
 
+void DnsProxyListener::addIpAddrWithinLimit(std::vector<android::String16>& ip_addrs,
+        const sockaddr* addr, socklen_t addrlen) {
+    // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
+    // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
+    // some addresses didn't get logged.
+    if (ip_addrs.size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
+        char ip_addr[INET6_ADDRSTRLEN];
+        if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
+            ip_addrs.push_back(String16(ip_addr));
+        }
+    }
+}
+
 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(DnsProxyListener* dnsProxyListener) :
     NetdCommand("getaddrinfo"),
     mDnsProxyListener(dnsProxyListener) {
@@ -399,17 +431,39 @@ void DnsProxyListener::GetHostByNameHandler::run() {
     mClient->decRef();
 
     if (mNetdEventListener != nullptr) {
+        std::vector<String16> ip_addrs;
+        int total_ip_addr_count = 0;
+        if (mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
+            if (hp->h_addrtype == AF_INET) {
+                in_addr** list = (in_addr**) hp->h_addr_list;
+                for (int i = 0; list[i] != NULL; i++) {
+                    sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = *list[i] };
+                    addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
+                    total_ip_addr_count++;
+                }
+            } else if (hp->h_addrtype == AF_INET6) {
+                in6_addr** list = (in6_addr**) hp->h_addr_list;
+                for (int i = 0; list[i] != NULL; i++) {
+                    sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_addr = *list[i] };
+                    addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
+                    total_ip_addr_count++;
+                }
+            }
+        }
         switch (mReportingLevel) {
             case INetdEventListener::REPORTING_LEVEL_NONE:
                 // Reporting is off.
                 break;
             case INetdEventListener::REPORTING_LEVEL_METRICS:
-                // Reporting is on. Send metrics.
+                // Metrics reporting is on. Send metrics.
                 mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME,
-                                              h_errno, latencyMs);
+                                               h_errno, latencyMs, String16(""), {}, -1, -1);
                 break;
             case INetdEventListener::REPORTING_LEVEL_FULL:
-                // TODO add full info reporting
+                // Full event info reporting is on. Send full info.
+                mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME,
+                                               h_errno, latencyMs, String16(mName), ip_addrs,
+                                               total_ip_addr_count, mClient->getUid());
                 break;
         }
     }
index b08f79e..c3bee73 100644 (file)
@@ -35,6 +35,8 @@ public:
 private:
     const NetworkController *mNetCtrl;
     EventReporter *mEventReporter;
+    static void addIpAddrWithinLimit(std::vector<android::String16>& ip_addrs, const sockaddr* addr,
+            socklen_t addrlen);
 
     class GetAddrInfoCmd : public NetdCommand {
     public:
index 1152812..cc0e912 100644 (file)
@@ -39,7 +39,7 @@ public:
 
 private:
     std::atomic_int mReportingLevel{
-            android::net::metrics::INetdEventListener::REPORTING_LEVEL_METRICS};
+            android::net::metrics::INetdEventListener::REPORTING_LEVEL_FULL};
     android::sp<android::net::metrics::INetdEventListener> mNetdEventListener;
 
 };
index c3ca317..3d3774b 100644 (file)
@@ -29,6 +29,23 @@ oneway interface INetdEventListener {
     const int REPORTING_LEVEL_METRICS = 4;
     const int REPORTING_LEVEL_FULL = 5;
 
-    // Logs a single DNS lookup.
-    void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs);
+    // Maximum number of IP addresses logged for DNS lookups before we truncate the full list.
+    const int DNS_REPORTED_IP_ADDRESSES_LIMIT = 10;
+
+    /**
+     * Logs a DNS lookup function call (getaddrinfo and gethostbyname).
+     *
+     * @param netId the ID of the network the lookup was performed on.
+     * @param eventType one of the EVENT_* constants in this interface.
+     * @param returnCode the return value of the function call.
+     * @param latencyMs the latency of the function call.
+     * @param hostname the name that was looked up.
+     * @param ipAddresses (possibly a subset of) the IP addresses returned.
+     *        At most {@link #DNS_REPORTED_IP_ADDRESSES_LIMIT} addresses are logged.
+     * @param ipAddressesCount the number of IP addresses returned. May be different from the length
+     *        of ipAddresses if there were too many addresses to log.
+     * @param uid the UID of the application that performed the query.
+     */
+    void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, String hostname,
+            in String[] ipAddresses, int ipAddressesCount, int uid);
 }