77 lines
2.7 KiB
C++
77 lines
2.7 KiB
C++
|
|
extern "C" {
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
}
|
|
|
|
#include <cstring>
|
|
#include <expected>
|
|
#include <string>
|
|
|
|
#include <resolver.hpp>
|
|
|
|
Address::Address(std::string iaddress, int ifamily) {
|
|
address = iaddress;
|
|
family = ifamily;
|
|
}
|
|
|
|
int Address::GetFamily() {
|
|
return family;
|
|
}
|
|
|
|
std::string Address::GetAddress() {
|
|
return address;
|
|
}
|
|
|
|
std::expected<Address, std::string> Resolver::Resolve(std::string hostname) {
|
|
struct sockaddr_in sa;
|
|
if (inet_pton(AF_INET, hostname.c_str(), &(sa.sin_addr)) == 1) {
|
|
family = AF_INET;
|
|
return Address(hostname, AF_INET);
|
|
}
|
|
if (inet_pton(AF_INET6, hostname.c_str(), &(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.c_str(), 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);
|
|
}
|