diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2020-11-05 19:44:46 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2020-11-27 19:31:17 +0900 |
commit | fa48d72548365c09b42853660d208cf1924f721c (patch) | |
tree | e294526e145293940d20fafad0df0fae57deb243 /multinetwork | |
parent | dacfcca550b5d72ffb08a6d1f0ac30fda8243aaf (diff) | |
download | extras-fa48d72548365c09b42853660d208cf1924f721c.tar.gz |
Support random destinations/multiple tests in dnschk and httpurl.
This adds two parameters to the dnschk and httpurl utilities that
can be used for network testing:
--randomname: connects to a random one-time DNS name.
--attempts: repeats the requested operation N times.
Also reformat the code per clang-format's suggestions.
Test: manual
Change-Id: Iab9966c489f8fa692eb9f7974ba25281ddf80b06
Diffstat (limited to 'multinetwork')
-rw-r--r-- | multinetwork/common.cpp | 32 | ||||
-rw-r--r-- | multinetwork/common.h | 13 | ||||
-rw-r--r-- | multinetwork/dnschk.cpp | 78 | ||||
-rw-r--r-- | multinetwork/httpurl.cpp | 38 |
4 files changed, 104 insertions, 57 deletions
diff --git a/multinetwork/common.cpp b/multinetwork/common.cpp index 7a5e7be4..44298191 100644 --- a/multinetwork/common.cpp +++ b/multinetwork/common.cpp @@ -54,16 +54,14 @@ bool parseNetworkHandle(const char *arg, net_handle_t *nethandle) { void printUsage(const char *progname) { - std::cerr << "Usage: " << progname - << " [--nethandle <nethandle>]" + std::cerr << "Usage: " << progname << " [--nethandle <nethandle>]" << " [--mode explicit|process]" << " [--family unspec|ipv4|ipv6]" - << " <argument>" - << std::endl; - std::cerr << std::endl; - std::cerr << "Learn nethandle values from 'dumpsys connectivity --short' " - << "or 'dumpsys connectivity --diag'" - << std::endl; + << " [--attempts <N>]" + << " --randomname | name" << std::endl + << std::endl + << "Learn nethandle values from 'dumpsys connectivity --short' " + << "or 'dumpsys connectivity --diag'" << std::endl; } Arguments::~Arguments() {} @@ -102,7 +100,21 @@ bool Arguments::parseArguments(int argc, const char* argv[]) { } else { break; } - } else if (arg1 == nullptr) { + } else if (strEqual(argv[i], "--attempts")) { + i++; + if (argc == i) break; + char* endptr; + attempts = strtoul(argv[i], &endptr, 10); + if (*endptr != '\0') { + std::cerr << "Failed to parse arguments: '" << argv[i] << "'" << std::endl; + break; + } + } else if (strEqual(argv[i], "--randomname")) { + time_t t; + time(&t); + srand((unsigned long)time); + random_name = true; + } else if (arg1 == nullptr && !random_name) { arg1 = argv[i]; } else { arg1 = nullptr; @@ -110,7 +122,7 @@ bool Arguments::parseArguments(int argc, const char* argv[]) { } } - if (arg1 != nullptr) { + if (random_name || arg1 != nullptr) { return true; } diff --git a/multinetwork/common.h b/multinetwork/common.h index f431ea99..a180fb55 100644 --- a/multinetwork/common.h +++ b/multinetwork/common.h @@ -31,10 +31,13 @@ enum class ApiMode { struct Arguments { - Arguments() : nethandle(NETWORK_UNSPECIFIED), - api_mode(ApiMode::EXPLICIT), - family(AF_UNSPEC), - arg1(nullptr) {} + Arguments() + : nethandle(NETWORK_UNSPECIFIED), + api_mode(ApiMode::EXPLICIT), + family(AF_UNSPEC), + attempts(1), + random_name(false), + arg1(nullptr) {} ~Arguments(); bool parseArguments(int argc, const char* argv[]); @@ -42,6 +45,8 @@ struct Arguments { net_handle_t nethandle; ApiMode api_mode; sa_family_t family; + unsigned attempts; + bool random_name; const char* arg1; }; diff --git a/multinetwork/dnschk.cpp b/multinetwork/dnschk.cpp index a2c42d4d..07338538 100644 --- a/multinetwork/dnschk.cpp +++ b/multinetwork/dnschk.cpp @@ -25,6 +25,7 @@ #include <iostream> #include <string> +#include <android-base/format.h> #include <android/multinetwork.h> #include "common.h" @@ -41,43 +42,54 @@ int main(int argc, const char* argv[]) { }; struct addrinfo *result = nullptr; - std::cout << "# " << args.arg1 - << " (via nethandle " << args.nethandle << "):" - << std::endl; - - switch (args.api_mode) { - case ApiMode::EXPLICIT: - rval = android_getaddrinfofornetwork(args.nethandle, - args.arg1, nullptr, &hints, &result); - break; - case ApiMode::PROCESS: - if (args.nethandle != NETWORK_UNSPECIFIED) { - rval = android_setprocnetwork(args.nethandle); - if (rval != 0) { - std::cerr << "android_setprocnetwork returned " << rval - << std::endl; - return rval; + time_t t; + time(&t); + srand((unsigned long)time); + + for (int i = 0; i < args.attempts; i++) { + std::string name; + + if (args.random_name) { + name = fmt::format("{}-{}-ds.metric.gstatic.com", rand(), rand()); + } else { + name = args.arg1; + } + + std::cout << "# " << name << " (via nethandle " << args.nethandle << "):" << std::endl; + + switch (args.api_mode) { + case ApiMode::EXPLICIT: + rval = android_getaddrinfofornetwork(args.nethandle, name.c_str(), nullptr, &hints, + &result); + break; + case ApiMode::PROCESS: + if (args.nethandle != NETWORK_UNSPECIFIED) { + rval = android_setprocnetwork(args.nethandle); + if (rval != 0) { + std::cerr << "android_setprocnetwork returned " << rval << std::endl; + return rval; + } } - } - rval = getaddrinfo(args.arg1, nullptr, &hints, &result); - break; - default: - // Unreachable. - std::cerr << "Unknown api mode." << std::endl; - return -1; - } + rval = getaddrinfo(name.c_str(), nullptr, &hints, &result); + break; + default: + // Unreachable. + std::cerr << "Unknown api mode." << std::endl; + return -1; + } - if (rval != 0) { - std::cerr << "DNS resolution failure; gaierror=" << rval - << " [" << gai_strerror(rval) << "]" - << std::endl; - return rval; - } + if (rval != 0) { + std::cerr << "DNS resolution failure; gaierror=" << rval << " [" << gai_strerror(rval) + << "]" << std::endl; + return rval; + } + + for (struct addrinfo* rp = result; rp != nullptr; rp = rp->ai_next) { + std::cout << inetSockaddrToString(rp->ai_addr) << std::endl; + } - for (struct addrinfo* rp = result; rp != nullptr; rp = rp->ai_next) { - std::cout << inetSockaddrToString(rp->ai_addr) << std::endl; + freeaddrinfo(result); } - freeaddrinfo(result); return 0; } diff --git a/multinetwork/httpurl.cpp b/multinetwork/httpurl.cpp index d78c0c93..a562ae2c 100644 --- a/multinetwork/httpurl.cpp +++ b/multinetwork/httpurl.cpp @@ -29,7 +29,7 @@ #include <android-base/stringprintf.h> #include "common.h" - +using android::base::StringPrintf; struct Parameters { Parameters() : ss({}), port("80"), path("/") {} @@ -41,10 +41,18 @@ struct Parameters { std::string path; }; +bool resolveHostname(const struct Arguments& args, struct Parameters* parameters); bool parseUrl(const struct Arguments& args, struct Parameters* parameters) { if (parameters == nullptr) { return false; } + if (args.random_name) { + parameters->host = StringPrintf("%d-%d-ipv6test.ds.metric.gstatic.com", rand(), rand()); + parameters->hostname = parameters->host; + parameters->path = "/ip.js?fmt=text"; + return resolveHostname(args, parameters); + } + static const char HTTP_PREFIX[] = "http://"; if (strncmp(args.arg1, HTTP_PREFIX, strlen(HTTP_PREFIX)) != 0) { std::cerr << "Only " << HTTP_PREFIX << " URLs supported." << std::endl; @@ -91,6 +99,10 @@ bool parseUrl(const struct Arguments& args, struct Parameters* parameters) { // TODO: find the request portion to send (before '#...'). + return resolveHostname(args, parameters); +} + +bool resolveHostname(const struct Arguments& args, struct Parameters* parameters) { std::cerr << "Resolving hostname=" << parameters->hostname << ", port=" << parameters->port << std::endl; @@ -136,7 +148,6 @@ bool parseUrl(const struct Arguments& args, struct Parameters* parameters) { return true; } - int makeTcpSocket(sa_family_t address_family, net_handle_t nethandle) { int fd = socket(address_family, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { @@ -233,13 +244,20 @@ int main(int argc, const char* argv[]) { struct Parameters parameters; if (!parseUrl(args, ¶meters)) { return -1; } - // TODO: Fall back from IPv6 to IPv4 if ss.ss_family is AF_UNSPEC. - // This will involve changes to parseUrl() as well. - struct FdAutoCloser closer = makeTcpSocket( - parameters.ss.ss_family, - (args.api_mode == ApiMode::EXPLICIT) ? args.nethandle - : NETWORK_UNSPECIFIED); - if (closer.fd < 0) { return closer.fd; } + int ret = 0; + + for (int i = 0; i < args.attempts; i++) { + // TODO: Fall back from IPv6 to IPv4 if ss.ss_family is AF_UNSPEC. + // This will involve changes to parseUrl() as well. + struct FdAutoCloser closer = makeTcpSocket( + parameters.ss.ss_family, + (args.api_mode == ApiMode::EXPLICIT) ? args.nethandle : NETWORK_UNSPECIFIED); + if (closer.fd < 0) { + return closer.fd; + } + + ret |= doHttpQuery(closer.fd, parameters); + } - return doHttpQuery(closer.fd, parameters); + return ret; } |