diff --git a/src/dsl/word/TCP.hpp b/src/dsl/word/TCP.hpp index 8751c996..12c2ae96 100644 --- a/src/dsl/word/TCP.hpp +++ b/src/dsl/word/TCP.hpp @@ -66,17 +66,10 @@ namespace dsl { struct Connection { - struct Target { - /// The address of the connection - std::string address; - /// The port of the connection - uint16_t port; - }; - /// The local address of the connection - Target local; + util::network::sock_t local; /// The remote address of the connection - Target remote; + util::network::sock_t remote; /// The file descriptor for the connection fd_t fd; @@ -187,10 +180,7 @@ namespace dsl { return Connection{}; } - auto local_s = local.address(); - auto remote_s = remote.address(); - - return Connection{{local_s.first, local_s.second}, {remote_s.first, remote_s.second}, fd.release()}; + return Connection{local, remote, fd.release()}; } }; diff --git a/src/dsl/word/UDP.hpp b/src/dsl/word/UDP.hpp index ef2e12a5..4b9d62b3 100644 --- a/src/dsl/word/UDP.hpp +++ b/src/dsl/word/UDP.hpp @@ -102,20 +102,10 @@ namespace dsl { /// If the packet is valid (it contains data) bool valid{false}; - struct Target { - Target() = default; - Target(std::string address, const uint16_t& port) : address(std::move(address)), port(port) {} - - /// The address of the target - std::string address; - /// The port of the target - uint16_t port{0}; - }; - /// The information about this packets destination - Target local; + util::network::sock_t local{}; /// The information about this packets source - Target remote; + util::network::sock_t remote{}; /// The data to be sent in the packet std::vector payload; @@ -427,12 +417,10 @@ namespace dsl { RecvResult result = read(task); Packet p{}; - p.valid = result.valid; - p.payload = std::move(result.payload); - auto local_s = result.local.address(); - auto remote_s = result.remote.address(); - p.local = Packet::Target{local_s.first, local_s.second}; - p.remote = Packet::Target{remote_s.first, remote_s.second}; + p.valid = result.valid; + p.payload = std::move(result.payload); + p.local = result.local; + p.remote = result.remote; // Confirm that this packet was sent to one of our local addresses for (const auto& iface : util::network::get_interfaces()) { @@ -475,12 +463,10 @@ namespace dsl { if (result.local.sock.sa_family == AF_INET) { Packet p{}; - p.valid = result.valid; - p.payload = std::move(result.payload); - auto local_s = result.local.address(); - auto remote_s = result.remote.address(); - p.local = Packet::Target{local_s.first, local_s.second}; - p.remote = Packet::Target{remote_s.first, remote_s.second}; + p.valid = result.valid; + p.payload = std::move(result.payload); + p.local = result.local; + p.remote = result.remote; // 255.255.255.255 is always a valid broadcast address if (result.local.ipv4.sin_addr.s_addr == htonl(INADDR_BROADCAST)) { @@ -526,12 +512,10 @@ namespace dsl { // Only return multicast packets if (multicast) { Packet p{}; - p.valid = result.valid; - p.payload = std::move(result.payload); - auto local_s = result.local.address(); - auto remote_s = result.remote.address(); - p.local = Packet::Target{local_s.first, local_s.second}; - p.remote = Packet::Target{remote_s.first, remote_s.second}; + p.valid = result.valid; + p.payload = std::move(result.payload); + p.local = result.local; + p.remote = result.remote; return p; } diff --git a/src/util/network/sock_t.hpp b/src/util/network/sock_t.hpp index 0fd4c550..4c52b2c0 100644 --- a/src/util/network/sock_t.hpp +++ b/src/util/network/sock_t.hpp @@ -24,7 +24,9 @@ #define NUCLEAR_UTIL_NETWORK_SOCK_T_HPP #include +#include #include +#include #include "../platform.hpp" @@ -50,19 +52,23 @@ namespace util { } } - std::pair address() const { - std::array c = {0}; - switch (sock.sa_family) { - case AF_INET: - return std::make_pair(::inet_ntop(sock.sa_family, &ipv4.sin_addr, c.data(), c.size()), - ntohs(ipv4.sin_port)); - case AF_INET6: - return std::make_pair(::inet_ntop(sock.sa_family, &ipv6.sin6_addr, c.data(), c.size()), - ntohs(ipv6.sin6_port)); - default: - throw std::runtime_error("Cannot get address for socket address family " - + std::to_string(sock.sa_family)); + std::pair address(bool numeric_host = false) const { + std::array host{}; + std::array service{}; + const int result = ::getnameinfo(reinterpret_cast(&storage), + size(), + host.data(), + static_cast(host.size()), + service.data(), + static_cast(service.size()), + NI_NUMERICSERV | (numeric_host ? NI_NUMERICHOST : 0)); + if (result != 0) { + throw std::system_error( + network_errno, + std::system_category(), + "Cannot get address for socket address family " + std::to_string(sock.sa_family)); } + return std::make_pair(std::string(host.data()), static_cast(std::stoi(service.data()))); } }; diff --git a/tests/tests/dsl/UDP.cpp b/tests/tests/dsl/UDP.cpp index 16ca247d..1e53d36f 100644 --- a/tests/tests/dsl/UDP.cpp +++ b/tests/tests/dsl/UDP.cpp @@ -174,8 +174,9 @@ class TestReactor : public test_util::TestBase { void handle_data(const std::string& name, const UDP::Packet& packet) { const std::string data(packet.payload.begin(), packet.payload.end()); - // Convert IP address to string in dotted decimal format - const std::string local = packet.local.address + ":" + std::to_string(packet.local.port); + // Convert IP address to a numeric string + auto s = packet.local.address(true); + const std::string local = s.first + ":" + std::to_string(s.second); events.push_back(name + " <- " + data + " (" + local + ")");