#include "socket/address.h" #include #include #include #include namespace Network { Address::Address() { zeroFill(); } Address::Address(int type, gsl::czstring presentationAddr, std::uint16_t port) { set(type, presentationAddr, port); } void Address::zeroFill() { memset(&addr_in6, 0, sizeof(addr_in6)); } void Address::set(int type, gsl::czstring presentationAddr, std::uint16_t port) { zeroFill(); setType(type); BIO_ADDRINFO* res; if (!BIO_lookup_ex(presentationAddr, std::to_string(port).c_str(), BIO_LOOKUP_CLIENT, type, SOCK_DGRAM, 0, &res)) { throw std::runtime_error("can't resolve address"); } int sock = -1; for (const BIO_ADDRINFO* ai = res; ai != nullptr; ai = ::BIO_ADDRINFO_next(ai)) { sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0); if (sock == -1) continue; } ::close(sock); addr_in.sin_family = type; ::inet_pton(type, presentationAddr, &addr_in.sin_addr); addr_in.sin_port = htons(port); } void Address::set(int type, in_addr_t addr, std::uint16_t port) { zeroFill(); setType(type); addr_in.sin_family = type; addr_in.sin_addr.s_addr = htonl(addr); addr_in.sin_port = htons(port); } void Address::set(int type, in_addr addr, std::uint16_t port) { zeroFill(); setType(type); addr_in.sin_family = type; addr_in.sin_addr = addr; addr_in.sin_port = htons(port); } void Address::set(int type, in6_addr addr, std::uint16_t port) { zeroFill(); setType(type); addr_in6.sin6_family = type; addr_in6.sin6_addr = addr; addr_in6.sin6_port = htons(port); } void Address::setType(int type) { family = type; if (type == AF_INET) length = sizeof(sockaddr_in); else if (type == AF_INET6) length = sizeof(sockaddr_in6); } Address::operator std::string() { char addrStr[INET6_ADDRSTRLEN]; if (family != AF_INET && family != AF_INET6 || !getPort()) return std::string(); ::inet_ntop(family, &addr, addrStr, sizeof(addrStr)); return std::format("{}:{}", addrStr, getPort()); } std::uint16_t Address::getPort() const { if (family == AF_INET) return ntohs(addr_in.sin_port); else if (family == AF_INET6) return ntohs(addr_in6.sin6_port); else return 0; } } // namespace Network