#pragma once #include "precomp.hpp" #include namespace Chattr { struct Address { Address() { zeroFill(); } Address(int type, gsl::czstring presentationAddr, std::uint16_t port) { set(type, presentationAddr, port); } void zeroFill() { memset(&addr_in6, 0, sizeof(addr_in6)); } void set(int type, gsl::czstring presentationAddr, std::uint16_t port) { zeroFill(); if (type == AF_INET) { addr_in.sin_family = AF_INET; ::inet_pton(AF_INET, presentationAddr, &addr_in.sin_addr); addr_in.sin_port = htons(port); length = sizeof(sockaddr_in); } else if (type == AF_INET6) { addr_in6.sin6_family = AF_INET6; ::inet_pton(AF_INET6, presentationAddr, &addr_in6.sin6_addr); addr_in6.sin6_port = htons(port); length = sizeof(sockaddr_in6); } } void set(int type, in_addr_t addr, std::uint16_t port) { zeroFill(); if (type == AF_INET) { addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(addr); addr_in.sin_port = htons(port); length = sizeof(sockaddr_in); } } void set(int type, in_addr addr, std::uint16_t port) { zeroFill(); if (type == AF_INET) { addr_in.sin_family = AF_INET; addr_in.sin_addr = addr; addr_in.sin_port = htons(port); length = sizeof(sockaddr_in); } } void set(int type, in6_addr addr, std::uint16_t port) { zeroFill(); if (type == AF_INET6) { addr_in6.sin6_family = AF_INET6; addr_in6.sin6_addr = addr; addr_in6.sin6_port = htons(port); length = sizeof(sockaddr_in6); } } operator std::string() { std::optional port = getPort(); if (!port) return std::string(); if (length == sizeof(addr_in)) { char addrStr[INET_ADDRSTRLEN]; ::inet_ntop(AF_INET, &addr_in.sin_addr, addrStr, sizeof(addrStr)); return std::format("{}:{}", addrStr, port.value()); } else if (length == sizeof(addr_in6)) { char addrStr[INET6_ADDRSTRLEN]; ::inet_ntop(AF_INET6, &addr_in6.sin6_addr, addrStr, sizeof(addrStr)); return std::format("{}:{}", addrStr, port.value()); } return std::string(); } std::optional getPort() { if (length == sizeof(addr_in)) return ntohs(addr_in.sin_port); else if (length == sizeof(addr_in6)) return ntohs(addr_in6.sin6_port); else return std::nullopt; } union { struct sockaddr addr; struct sockaddr_in addr_in; struct sockaddr_in6 addr_in6; }; socklen_t length; }; }