diff options
author | Håvard Pettersen <havardpe@oath.com> | 2018-05-08 15:53:40 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@oath.com> | 2018-05-09 13:02:59 +0000 |
commit | 4e953d4813d3384eaf4761f4930b36036b0dda21 (patch) | |
tree | fd4d012f7ea51138bb4d99d35006bf90acceba31 /vespalib/src/apps | |
parent | 57e7ff91fdb1a319087ced1748a05de159556024 (diff) |
added tools to detect and validate hostname
Diffstat (limited to 'vespalib/src/apps')
6 files changed, 140 insertions, 0 deletions
diff --git a/vespalib/src/apps/vespa-detect-hostname/.gitignore b/vespalib/src/apps/vespa-detect-hostname/.gitignore new file mode 100644 index 00000000000..d1570fb3d89 --- /dev/null +++ b/vespalib/src/apps/vespa-detect-hostname/.gitignore @@ -0,0 +1 @@ +/vespa-detect-hostname diff --git a/vespalib/src/apps/vespa-detect-hostname/CMakeLists.txt b/vespalib/src/apps/vespa-detect-hostname/CMakeLists.txt new file mode 100644 index 00000000000..51d2ba3b0b0 --- /dev/null +++ b/vespalib/src/apps/vespa-detect-hostname/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_vespa-detect-hostname_app + SOURCES + detect_hostname.cpp + OUTPUT_NAME vespa-detect-hostname + INSTALL bin + DEPENDS + vespalib +) diff --git a/vespalib/src/apps/vespa-detect-hostname/detect_hostname.cpp b/vespalib/src/apps/vespa-detect-hostname/detect_hostname.cpp new file mode 100644 index 00000000000..a1387c6519d --- /dev/null +++ b/vespalib/src/apps/vespa-detect-hostname/detect_hostname.cpp @@ -0,0 +1,50 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <stdio.h> +#include <stdlib.h> +#include <vespa/vespalib/net/socket_address.h> +#include <vespa/vespalib/stllike/string.h> +#include <set> + +using vespalib::SocketAddress; + +std::set<vespalib::string> make_ip_set() { + std::set<vespalib::string> result; + for (const auto &addr: SocketAddress::get_interfaces()) { + result.insert(addr.ip_address()); + } + return result; +} + +vespalib::string get_hostname() { + std::vector<char> result(4096, '\0'); + gethostname(&result[0], 4000); + return SocketAddress::normalize(&result[0]); +} + +bool check(const vespalib::string &name, const std::set<vespalib::string> &ip_set) { + auto addr_list = SocketAddress::resolve(80, name.c_str()); + if (addr_list.empty()) { + return false; + } + for (const SocketAddress &addr: addr_list) { + vespalib::string ip_addr = addr.ip_address(); + if (ip_set.count(ip_addr) == 0) { + return false; + } + } + return true; +} + +int main(int, char **) { + auto my_ip_set = make_ip_set(); + std::vector<vespalib::string> list({get_hostname(), "localhost", "127.0.0.1", "::1"}); + for (const vespalib::string &name: list) { + if (check(name, my_ip_set)) { + fprintf(stdout, "%s\n", name.c_str()); + return 0; + } + } + fprintf(stderr, "ERROR: failed to detect hostname\n"); + return 1; +} diff --git a/vespalib/src/apps/vespa-validate-hostname/.gitignore b/vespalib/src/apps/vespa-validate-hostname/.gitignore new file mode 100644 index 00000000000..9d95e867f73 --- /dev/null +++ b/vespalib/src/apps/vespa-validate-hostname/.gitignore @@ -0,0 +1 @@ +/vespa-validate-hostname diff --git a/vespalib/src/apps/vespa-validate-hostname/CMakeLists.txt b/vespalib/src/apps/vespa-validate-hostname/CMakeLists.txt new file mode 100644 index 00000000000..7ffa7d763ec --- /dev/null +++ b/vespalib/src/apps/vespa-validate-hostname/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_vespa-validate-hostname_app + SOURCES + validate_hostname.cpp + OUTPUT_NAME vespa-validate-hostname + INSTALL bin + DEPENDS + vespalib +) diff --git a/vespalib/src/apps/vespa-validate-hostname/validate_hostname.cpp b/vespalib/src/apps/vespa-validate-hostname/validate_hostname.cpp new file mode 100644 index 00000000000..da4907d4c91 --- /dev/null +++ b/vespalib/src/apps/vespa-validate-hostname/validate_hostname.cpp @@ -0,0 +1,70 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <stdio.h> +#include <stdlib.h> +#include <vespa/vespalib/net/socket_address.h> +#include <vespa/vespalib/stllike/string.h> +#include <set> + +using vespalib::SocketAddress; + +std::set<vespalib::string> make_ip_set() { + std::set<vespalib::string> result; + for (const auto &addr: SocketAddress::get_interfaces()) { + result.insert(addr.ip_address()); + } + return result; +} + +vespalib::string normalize(const vespalib::string &hostname) { + vespalib::string canon_name = SocketAddress::normalize(hostname); + if (canon_name != hostname) { + fprintf(stderr, "warning: host name (%s) is not canonical (canonical host name: %s)\n", + hostname.c_str(), canon_name.c_str()); + } + return canon_name; +} + +void check_reverse(const vespalib::string &hostname, const SocketAddress &addr) { + std::set<vespalib::string> seen({hostname}); + vespalib::string reverse = addr.reverse_lookup(); + for (size_t i = 0; !reverse.empty() && (i < 10); ++i) { + if (seen.count(reverse) == 0) { + seen.insert(reverse); + fprintf(stderr, "warning: conflicting reverse lookup: %s->%s->%s\n", + hostname.c_str(), addr.ip_address().c_str(), reverse.c_str()); + } + reverse = addr.reverse_lookup(); + } +} + +int usage(const char *self) { + fprintf(stderr, "usage: %s <hostname>\n", self); + return 1; +} + +int main(int argc, char **argv) { + if (argc != 2) { + return usage(argv[0]); + } + bool valid = true; + auto my_ip_set = make_ip_set(); + vespalib::string hostname = normalize(argv[1]); + auto addr_list = SocketAddress::resolve(80, hostname.c_str()); + if (addr_list.empty()) { + valid = false; + fprintf(stderr, "ERROR: host name (%s) could not be resolved\n", + hostname.c_str()); + } + for (const SocketAddress &addr: addr_list) { + vespalib::string ip_addr = addr.ip_address(); + if (my_ip_set.count(ip_addr) == 0) { + valid = false; + fprintf(stderr, "ERROR: host name (%s) resolves to ip address not owned by this host (%s)\n", + hostname.c_str(), ip_addr.c_str()); + } else { + check_reverse(hostname, addr); + } + } + return valid ? 0 : 1; +} |