#include "socket/address.h" #include namespace Network { //void Address::set(int type, gsl::czstring presentationAddr, // std::uint16_t port) { // zeroFill(); // setType(type); // // if (type == AF_INET) { // ::inet_pton(AF_INET, presentationAddr, &addr_in.sin_addr); // addr_in.sin_port = htons(port); // } else if (type == AF_INET6) { // ::inet_pton(AF_INET6, presentationAddr, &addr_in6.sin6_addr); // addr_in6.sin6_port = htons(port); // } // // BIO_ADDRINFO* res; // if (!BIO_lookup_ex(presentationAddr, std::to_string(port).c_str(), // BIO_LOOKUP_CLIENT, type, SOCK_DGRAM, 0, &res)) { // ::BIO_ADDRINFO_free(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), type, 0, 0); // if (sock == -1) // continue; // else { // auto bio_addr = ::BIO_ADDRINFO_address(ai); // BIO_ADDR_rawaddress(bio_addr, &addr, (unsigned long long*)&length); // bio_addr_info = ::BIO_ADDR_dup(bio_addr); // // break; // } // } // // if (sock != -1) // ::close(sock); // // ::BIO_ADDRINFO_free(res); // // addr_in.sin_family = type; // addr_in.sin_port = htons(port); //} 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(); 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 Address::setType(int type) { zeroFill(); if (type == AF_INET) length = sizeof(sockaddr_in); else if (type == AF_INET6) length = sizeof(sockaddr_in6); } Address::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::uint16_t Address::getPort() const { 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 0; } } // namespace Network