12cf561722c2661cc0d4db502a44a3021609f307eRobin Lee/*
22cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Copyright (C) 2016 The Android Open Source Project
32cf561722c2661cc0d4db502a44a3021609f307eRobin Lee *
42cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Licensed under the Apache License, Version 2.0 (the "License");
52cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * you may not use this file except in compliance with the License.
62cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * You may obtain a copy of the License at
72cf561722c2661cc0d4db502a44a3021609f307eRobin Lee *
82cf561722c2661cc0d4db502a44a3021609f307eRobin Lee *      http://www.apache.org/licenses/LICENSE-2.0
92cf561722c2661cc0d4db502a44a3021609f307eRobin Lee *
102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Unless required by applicable law or agreed to in writing, software
112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * distributed under the License is distributed on an "AS IS" BASIS,
122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * See the License for the specific language governing permissions and
142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * limitations under the License.
152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee */
162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#define LOG_TAG "connect_benchmark"
182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
19711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee/*
20711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * See README.md for general notes.
21711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
22711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * This set of benchmarks measures the throughput of connect() calls on a single thread for IPv4 and
23711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * IPv6 under the following scenarios:
24711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
25711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - FWmark disabled (::ANDROID_NO_USE_FWMARK_CLIENT).
26711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
27711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      The control case for other high load benchmarks. Essentially just testing performance of
28711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      the kernel connect call. In real world use fwmark should stay on in order for traffic to
29711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      be routed properly.
30711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
31711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - FWmark enabled only for metrics (::ANDROID_FWMARK_METRICS_ONLY).
32711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
33711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      The default mode up to and including 7.1. Every time connect() is called on an AF_INET or
34711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      AF_INET6 socket, netdclient sends a synchronous message to fwmarkserver to get the socket
35711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      marked. Only the fields that are useful for marking or for metrics are sent in this mode;
36711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      other fields are set to null for the RPC and ignored.
37711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
38711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - FWmark enabled for all events.
39711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
40711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      The default mode starting from 7.1.2. As well as the normal connect() reporting, extra
41711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      fields are filled in to log the IP and port of the connection.
42711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
43711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      A second synchronous message is sent to fwmarkserver after the connection completes, to
44711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *      record latency. This message is forwarded to the system server over a oneway binder call.
45711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
46711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * Realtime timed tests
47711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * ====================
48711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
49711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The tests named *_high_load record the following useful information:
50711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
51711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *   - real_time: the mean roundtrip time for one connect() call under load
52711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
53711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *   - iterations: the number of times the test was run within the timelimit --- approximately
54711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *                 MinTime / real_time
55711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
56711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * Manually timed tests
57711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * ====================
58711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
59711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * All other sets of tests apart from *_high_load run with manual timing. The purpose of these is to
60711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * measure 90th-percentile latency for connect() calls compared to mean latency.
61711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
62711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * (TODO: ideally this should be against median latency, but google-benchmark only supports one
63711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *        custom 'label' output for graphing. Stddev isn't appropriate because the latency
64711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *        distribution is usually spiky, not in a nice neat normal-like distribution.)
65711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
66711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The manually timed tests record the following useful information:
67711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
68711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - real_time: the average time taken to complete a test run. Unlike the real_time used in high
69711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *               load tests, this is calculated from before-and-after values of the realtime clock
70711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *               over many iterations so may be less accurate than the under-load times.
71711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
72711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - iterations: the number of times the test was run within the timelimit --- approximately
73711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *                MinTime / real_time, although as explained, may not be as meaningful because of
74711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *                overhead from timing.
75711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
76711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *  - label: a manually-recorded time giving the 90th-percentile value of real_time over all
77711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *           individual runs. Should be compared to real_time.
78711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee *
79711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee */
80711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee
812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <arpa/inet.h>
822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <cutils/sockets.h>
832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <errno.h>
842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <netinet/in.h>
852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <time.h>
862cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
872cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <map>
882cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <functional>
892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <thread>
902cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
912cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <android-base/stringprintf.h>
922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <benchmark/benchmark.h>
932cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <log/log.h>
942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <utils/StrongPointer.h>
952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
962cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "FwmarkClient.h"
972cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "SockDiag.h"
982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "Stopwatch.h"
99d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski#include "android/net/metrics/INetdEventListener.h"
1002cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1012cf561722c2661cc0d4db502a44a3021609f307eRobin Leeusing android::base::StringPrintf;
102d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinskiusing android::net::metrics::INetdEventListener;
1032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1042cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic int bindAndListen(int s) {
1052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    sockaddr_in6 sin6 = { .sin6_family = AF_INET6 };
1062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (bind(s, (sockaddr*) &sin6, sizeof(sin6)) == 0) {
1072cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (listen(s, 1)) {
1082cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            return -1;
1092cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sockaddr_in sin = {};
1112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        socklen_t len = sizeof(sin);
1122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (getsockname(s, (sockaddr*) &sin, &len)) {
1132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            return -1;
1142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        return ntohs(sin.sin_port);
1162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    } else {
1172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        return -1;
1182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
1192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
1202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1212cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_loopback(benchmark::State& state, const bool waitBetweenRuns) {
1222cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const int listensocket = socket(AF_INET6, SOCK_STREAM, 0);
1232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const int port = bindAndListen(listensocket);
1242cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (port == -1) {
1252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        state.SkipWithError("Unable to bind server socket");
1262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        return;
1272cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
1282cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // ALOGW("Listening on port = %d", port);
1302cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    std::vector<uint64_t> latencies(state.max_iterations);
1312cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    uint64_t iterations = 0;
1322cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1332cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    while (state.KeepRunning()) {
1342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        int sock = socket(AF_INET, SOCK_STREAM, 0);
1352cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (sock < 0) {
1362cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("socket() failed with errno=%d", errno).c_str());
1372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
1382cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1392cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1402cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        const Stopwatch stopwatch;
1412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1422cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sockaddr_in server = { .sin_family = AF_INET, .sin_port = htons(port) };
143e65244b5a149fc8be8063ee0872f31b829bfa020Robin Lee        if (connect(sock, (sockaddr*) &server, sizeof(server))) {
1442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("connect() failed with errno=%d", errno).c_str());
1452cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            close(sock);
1462cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
1472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1482cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (waitBetweenRuns) {
1502cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            latencies[iterations] = stopwatch.timeTaken() * 1e6L;
1512cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SetIterationTime(latencies[iterations] / 1e9L);
1522cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            std::this_thread::sleep_for(std::chrono::milliseconds(10));
1532cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            ++iterations;
1542cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1552cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1562cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sockaddr_in6 client;
1572cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        socklen_t clientlen = sizeof(client);
1582cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        int accepted = accept(listensocket, (sockaddr *) &client, &clientlen);
1592cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (accepted < 0) {
1602cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("accept() failed with errno=%d", errno).c_str());
1612cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            close(sock);
1622cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
1632cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1642cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1652cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        close(accepted);
1662cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        close(sock);
1672cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
1682cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    close(listensocket);
1692cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // ALOGI("Finished test on port = %d", port);
1702cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1712cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (iterations > 0) {
1722cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        latencies.resize(iterations);
1732cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sort(latencies.begin(), latencies.end());
17403d6f38a0cb947f1576df3a73338852de00ea6cdChih-hung Hsieh        state.SetLabel(StringPrintf("%lld", (long long) latencies[iterations * 9 / 10]));
1752cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
1762cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
1772cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1782cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_loopback(benchmark::State& state, const bool waitBetweenRuns) {
1792cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const int listensocket = socket(AF_INET6, SOCK_STREAM, 0);
1802cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const int port = bindAndListen(listensocket);
1812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (port == -1) {
1822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        state.SkipWithError("Unable to bind server socket");
1832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        return;
1842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
1852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1862cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // ALOGW("Listening on port = %d", port);
1872cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    std::vector<uint64_t> latencies(state.max_iterations);
1882cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    uint64_t iterations = 0;
1892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1902cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    while (state.KeepRunning()) {
1912cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        int sock = socket(AF_INET6, SOCK_STREAM, 0);
1922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (sock < 0) {
1932cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("socket() failed with errno=%d", errno).c_str());
1942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
1952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
1962cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1972cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        const Stopwatch stopwatch;
1982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
1992cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sockaddr_in6 server = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
200e65244b5a149fc8be8063ee0872f31b829bfa020Robin Lee        if (connect(sock, (sockaddr*) &server, sizeof(server))) {
2012cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("connect() failed with errno=%d", errno).c_str());
2022cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            close(sock);
2032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
2042cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (waitBetweenRuns) {
2072cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            latencies[iterations] = stopwatch.timeTaken() * 1e6L;
2082cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SetIterationTime(latencies[iterations] / 1e9L);
2092cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            std::this_thread::sleep_for(std::chrono::milliseconds(10));
2102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            ++iterations;
2112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sockaddr_in6 client;
2142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        socklen_t clientlen = sizeof(client);
2152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        int accepted = accept(listensocket, (sockaddr *) &client, &clientlen);
2162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        if (accepted < 0) {
2172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            state.SkipWithError(StringPrintf("accept() failed with errno=%d", errno).c_str());
2182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            close(sock);
2192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            break;
2202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2212cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2222cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        close(accepted);
2232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        close(sock);
2242cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
2252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    close(listensocket);
2262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // ALOGI("Finished test on port = %d", port);
2272cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2282cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (iterations > 0) {
2292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        latencies.resize(iterations);
2302cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        sort(latencies.begin(), latencies.end());
23103d6f38a0cb947f1576df3a73338852de00ea6cdChih-hung Hsieh        state.SetLabel(StringPrintf("%lld", (long long) latencies[iterations * 9 / 10]));
2322cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
2332cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
2342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2352cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void run_at_reporting_level(decltype(ipv4_loopback) benchmarkFunction,
236d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski                                   ::benchmark::State& state, const int reportingLevel,
2372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                                   const bool waitBetweenRuns) {
2382cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // Our master thread (thread_index == 0) will control setup and teardown for other threads.
2392cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const bool isMaster = (state.thread_index == 0);
2402cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // Previous values of env variables used by fwmarkclient (only read/written by master thread)
2422cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    const std::string savedSettings[] = {
2432cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT,
2442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        FwmarkClient::ANDROID_FWMARK_METRICS_ONLY
2452cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    };
2462cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    std::map<std::string, std::string> prevSettings;
2472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2482cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // SETUP
2492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (isMaster) {
2502cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        for (const auto setting : savedSettings) {
2512cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            const char* prevEnvStr = getenv(setting.c_str());
2522cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            if (prevEnvStr != nullptr) {
2532cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                prevSettings[setting.c_str()] = prevEnvStr;
2542cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            }
2552cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2562cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        switch (reportingLevel) {
257d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski            case INetdEventListener::REPORTING_LEVEL_NONE:
2582cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                setenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT, "", 1);
2592cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                break;
260d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski            case INetdEventListener::REPORTING_LEVEL_METRICS:
2612cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                unsetenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT);
2622cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                setenv(FwmarkClient::ANDROID_FWMARK_METRICS_ONLY, "", 1);
2632cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                break;
264d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski            case INetdEventListener::REPORTING_LEVEL_FULL:
2652cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                unsetenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT);
2662cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                unsetenv(FwmarkClient::ANDROID_FWMARK_METRICS_ONLY);
2672cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                break;
2682cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2692cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
2702cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2712cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // TEST
2722cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    benchmarkFunction(state, waitBetweenRuns);
2732cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2742cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    // TEARDOWN
2752cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    if (isMaster) {
2762cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        for (const auto setting : savedSettings) {
2772cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            if (prevSettings.count(setting)) {
2782cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                setenv(setting.c_str(), prevSettings[setting].c_str(), 1);
2792cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            } else {
2802cf561722c2661cc0d4db502a44a3021609f307eRobin Lee                unsetenv(setting.c_str());
2812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee            }
2822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee        }
2832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    }
2842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
2852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2862cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr int MIN_THREADS = 1;
2872cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr int MAX_THREADS = 1;
2882cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr double MIN_TIME = 0.5 /* seconds */;
2892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2902cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_no_fwmark(::benchmark::State& state) {
291d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_NONE, true);
2922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
2932cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_no_fwmark)->MinTime(MIN_TIME)->UseManualTime();
2942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
2952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv4 metrics under low load
2962cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_no_load(::benchmark::State& state) {
297d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, true);
2982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
2992cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime();
3002cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3012cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_full_reporting_no_load(::benchmark::State& state) {
302d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, true);
3032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3042cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_full_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime();
3052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv4 benchmarks under high load
3072cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_high_load(::benchmark::State& state) {
308d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS,
309d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski            false);
3102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3112cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_high_load)
3122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime();
3132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3142cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_full_reporting_high_load(::benchmark::State& state) {
315d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, false);
3162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3172cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_full_reporting_high_load)
3182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime();
3192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 raw connect() without using fwmark
3212cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_no_fwmark(::benchmark::State& state) {
322d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_NONE, true);
3232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3242cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_no_fwmark)->MinTime(MIN_TIME)->UseManualTime();
3252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 metrics under low load
3272cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_no_load(::benchmark::State& state) {
328d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, true);
3292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3302cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime();
3312cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3322cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_full_reporting_no_load(::benchmark::State& state) {
333d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, true);
3342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3352cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_full_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime();
3362cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 benchmarks under high load
3382cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_high_load(::benchmark::State& state) {
339d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS,
340d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski            false);
3412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3422cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_high_load)
3432cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime();
3442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee
3452cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_full_reporting_high_load(::benchmark::State& state) {
346d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski    run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, false);
3472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee}
3482cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_full_reporting_high_load)
3492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee    ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime();
350