Commit 6d5cb946 authored by Joseph Noir's avatar Joseph Noir

Add overloads for ip addresses

parent 050ee590
...@@ -30,10 +30,16 @@ namespace ip { ...@@ -30,10 +30,16 @@ namespace ip {
/// Returns all IP addresses of to `host` (if any). /// Returns all IP addresses of to `host` (if any).
std::vector<ip_address> resolve(string_view host); std::vector<ip_address> resolve(string_view host);
/// Returns all IP addresses of to `host` (if any).
std::vector<ip_address> resolve(ip_address host);
/// Returns the IP addresses for a local endpoint, which is either an address, /// Returns the IP addresses for a local endpoint, which is either an address,
/// an interface, or localhost. /// an interface name, or the string "localhost".
std::vector<ip_address> local_addresses(string_view host); std::vector<ip_address> local_addresses(string_view host);
/// Returns the IP addresses for a local endpoint address.
std::vector<ip_address> local_addresses(ip_address host);
/// Returns the hostname of this device. /// Returns the hostname of this device.
std::string hostname(); std::string hostname();
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
* http://www.boost.org/LICENSE_1_0.txt. * * http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/ ******************************************************************************/
#include "caf/net/ip.hpp"
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <utility> #include <utility>
...@@ -25,6 +27,7 @@ ...@@ -25,6 +27,7 @@
#include "caf/detail/socket_sys_includes.hpp" #include "caf/detail/socket_sys_includes.hpp"
#include "caf/error.hpp" #include "caf/error.hpp"
#include "caf/ip_address.hpp" #include "caf/ip_address.hpp"
#include "caf/ip_subnet.hpp"
#include "caf/ipv4_address.hpp" #include "caf/ipv4_address.hpp"
#include "caf/logger.hpp" #include "caf/logger.hpp"
#include "caf/string_algorithms.hpp" #include "caf/string_algorithms.hpp"
...@@ -59,8 +62,6 @@ namespace { ...@@ -59,8 +62,6 @@ namespace {
// Dummy port to resolve empty string with getaddrinfo. // Dummy port to resolve empty string with getaddrinfo.
constexpr string_view dummy_port = "42"; constexpr string_view dummy_port = "42";
constexpr string_view v4_any_addr = "0.0.0.0";
constexpr string_view v6_any_addr = "::";
constexpr string_view localhost = "localhost"; constexpr string_view localhost = "localhost";
void* fetch_in_addr(int family, sockaddr* addr) { void* fetch_in_addr(int family, sockaddr* addr) {
...@@ -116,6 +117,10 @@ std::vector<ip_address> resolve(string_view host) { ...@@ -116,6 +117,10 @@ std::vector<ip_address> resolve(string_view host) {
return results; return results;
} }
std::vector<ip_address> resolve(ip_address host) {
return resolve(to_string(host));
}
std::string hostname() { std::string hostname() {
char buf[HOST_NAME_MAX + 1]; char buf[HOST_NAME_MAX + 1];
buf[HOST_NAME_MAX] = '\0'; buf[HOST_NAME_MAX] = '\0';
...@@ -126,7 +131,7 @@ std::string hostname() { ...@@ -126,7 +131,7 @@ std::string hostname() {
#ifdef CAF_WINDOWS #ifdef CAF_WINDOWS
template <class F> template <class F>
void for_each_adapter(F f, bool is_link_local) { void for_each_adapter(F f, bool is_link_local = false) {
using adapters_ptr = std::unique_ptr<IP_ADAPTER_ADDRESSES, void (*)(void*)>; using adapters_ptr = std::unique_ptr<IP_ADAPTER_ADDRESSES, void (*)(void*)>;
ULONG len = 0; ULONG len = 0;
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr,
...@@ -178,7 +183,7 @@ void for_each_adapter(F f, bool is_link_local) { ...@@ -178,7 +183,7 @@ void for_each_adapter(F f, bool is_link_local) {
#else // CAF_WINDOWS #else // CAF_WINDOWS
template <class F> template <class F>
void for_each_adapter(F f, bool is_link_local) { void for_each_adapter(F f, bool is_link_local = false) {
ifaddrs* tmp = nullptr; ifaddrs* tmp = nullptr;
if (getifaddrs(&tmp) != 0) if (getifaddrs(&tmp) != 0)
return; return;
...@@ -204,40 +209,50 @@ void for_each_adapter(F f, bool is_link_local) { ...@@ -204,40 +209,50 @@ void for_each_adapter(F f, bool is_link_local) {
#endif // CAF_WINDOWS #endif // CAF_WINDOWS
std::vector<ip_address> local_addresses(string_view host) { std::vector<ip_address> local_addresses(string_view host) {
// TODO: If is any addr, call resolve with PR #23. ip_address host_ip;
if (host == v4_any_addr)
return {ip_address{make_ipv4_address(0, 0, 0, 0)}};
if (host == v6_any_addr)
return {ip_address{}};
// Unless explicitly specified we are going to skip link-local addresses.
auto is_link_local = starts_with(host, "fe80:");
std::vector<ip_address> results; std::vector<ip_address> results;
ip_address host_addr;
if (host.empty()) { if (host.empty()) {
for_each_adapter([&](string_view, ip_address ip) { for_each_adapter([&](string_view, ip_address ip) {
results.push_back(ip); results.push_back(ip);
}, is_link_local); });
} else if (host == localhost) { } else if (host == localhost) {
auto v6_local = ip_address{{0}, {0x1}}; auto v6_local = ip_address{{0}, {0x1}};
auto v4_local = ip_address{make_ipv4_address(127, 0, 0, 1)}; auto v4_local = ip_address{make_ipv4_address(127, 0, 0, 1)};
for_each_adapter([&](string_view, ip_address ip) { for_each_adapter([&](string_view, ip_address ip) {
if (ip == v4_local || ip == v6_local) if (ip == v4_local || ip == v6_local)
results.push_back(ip); results.push_back(ip);
}, is_link_local); });
} else if (auto err = parse(host, host_addr)) { } else if (auto err = parse(host, host_ip)) {
for_each_adapter([&](string_view iface, ip_address ip) { for_each_adapter([&](string_view iface, ip_address ip) {
if (iface == host) if (iface == host)
results.push_back(ip); results.push_back(ip);
}, is_link_local); });
} else { } else {
for_each_adapter([&](string_view, ip_address ip) { return local_addresses(host_ip);
if (host_addr == ip)
results.push_back(ip);
}, is_link_local);
} }
return results; return results;
} }
std::vector<ip_address> local_addresses(ip_address host) {
auto v6_any = ip_address{{0}, {0}};
auto v4_any = ip_address{make_ipv4_address(0, 0, 0, 0)};
// TODO: If is any addr, call resolve with PR #23.
if (host == v4_any)
return {ip_address{make_ipv4_address(0, 0, 0, 0)}};
if (host == v6_any)
return {ip_address{}};
auto link_local = ip_address({0xfe, 0x8, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0});
auto ll_prefix = ip_subnet(link_local, 10);
// Unless explicitly specified we are going to skip link-local addresses.
auto is_link_local = ll_prefix.contains(host);
std::vector<ip_address> results;
for_each_adapter([&](string_view, ip_address ip) {
if (host == ip)
results.push_back(ip);
}, is_link_local);
return results;
}
} // namespace ip } // namespace ip
} // namespace net } // namespace net
} // namespace caf } // namespace caf
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment