From 0801a67257f130c00035c34a01ddfa5ef665a0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedrich=20Scho=CC=88ller?= Date: Thu, 11 May 2017 00:43:58 +0200 Subject: [PATCH] Fix server name resolution When resolving the name of a server, the result was always assumed to be an IPv4 address, even if an IPv6 address was actually returned. Use `getaddrinfo` instead of `gethostbyname` and specify that we are only interested in IPv4 addresses. --- src/main.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 46ef37e..4730c4a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,10 @@ #include #include +#ifndef AI_V4MAPPED // Not supported on OpenBSD 6.0 +#define AI_V4MAPPED 0 +#endif + static Worker *worker = NULL; static void sig_term_handler(int) @@ -208,19 +212,22 @@ int main(int argc, char *argv[]) } else { - uint32_t serverIp = inet_addr(serverName); - if (serverIp == INADDR_NONE) - { - struct hostent* he = gethostbyname(serverName); - if (!he) - { - syslog(LOG_ERR, "gethostbyname: %s", hstrerror(h_errno)); - return 1; - } + struct addrinfo hints = {0}; + struct addrinfo *res = NULL; - serverIp = *(uint32_t *)he->h_addr; + hints.ai_family = AF_INET; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + + int err = getaddrinfo(serverName, NULL, &hints, &res); + if (err) + { + syslog(LOG_ERR, "getaddrinfo: %s", gai_strerror(err)); + return 1; } + sockaddr_in *sockaddr = reinterpret_cast(res->ai_addr); + uint32_t serverIp = sockaddr->sin_addr.s_addr; + worker = new Client(mtu, device, ntohl(serverIp), maxPolls, password, uid, gid, changeEchoId, changeEchoSeq, clientIp); }