summaryrefslogtreecommitdiff
path: root/multinetwork
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2020-11-05 19:44:46 +0900
committerLorenzo Colitti <lorenzo@google.com>2020-11-27 19:31:17 +0900
commitfa48d72548365c09b42853660d208cf1924f721c (patch)
treee294526e145293940d20fafad0df0fae57deb243 /multinetwork
parentdacfcca550b5d72ffb08a6d1f0ac30fda8243aaf (diff)
downloadextras-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.cpp32
-rw-r--r--multinetwork/common.h13
-rw-r--r--multinetwork/dnschk.cpp78
-rw-r--r--multinetwork/httpurl.cpp38
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, &parameters)) { 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;
}