Files
stvpn/resolver.cpp
T
Олег Бородин e52e90c222 working commit
2026-05-18 12:58:08 +02:00

64 lines
2.5 KiB
C++

extern "C" {
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
}
#include <cstring>
#include <expected>
#include <string>
#include <resolver.hpp>
std::expected<Address, std::string> Resolver::Resolve(std::string hostname) {
struct sockaddr_in sa;
if (inet_pton(AF_INET, hostname.data(), &(sa.sin_addr)) == 1) {
family = AF_INET;
return Address(hostname, AF_INET);
}
if (inet_pton(AF_INET6, hostname.data(), &(sa.sin_addr)) == 1) {
return Address(hostname, AF_INET6);
}
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
int status = 0;
if ((status = getaddrinfo(hostname.data(), NULL, &hints, &res)) != 0) {
std::string error = gai_strerror(status);
return std::unexpected("Resolve adress error: " + error);
}
struct addrinfo* p;
char ipaddr[INET6_ADDRSTRLEN + 1];
for (p = res; p != NULL; p = p->ai_next) {
if (p->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
void* addr = &(ipv4->sin_addr);
if (inet_ntop(p->ai_family, addr, ipaddr, sizeof(ipaddr)) == NULL) {
int errnocopy = errno;
std::string error = std::strerror(errnocopy);
return std::unexpected("Cannot conver address: " + error);
}
std::string address(ipaddr);
return Address(address, AF_INET);;
}
}
for (p = res; p != NULL; p = p->ai_next) {
if (p->ai_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
void* addr = &(ipv6->sin6_addr);
if (inet_ntop(p->ai_family, addr, ipaddr, sizeof(ipaddr)) == NULL) {
int errnocopy = errno;
std::string error = std::strerror(errnocopy);
return std::unexpected("Cannot conver address: " + error);
}
std::string address(ipaddr);
return Address(address, AF_INET6);
}
}
return std::unexpected("Cannot resolve hostname " + hostname);
}