From 20e72128de76c230920c029b169e617866224129 Mon Sep 17 00:00:00 2001 From: Kp Date: Fri, 18 Mar 2016 02:05:16 +0000 Subject: [PATCH] Add configure test and fallback code to support ancient Windows Windows 2000 has no support for getaddrinfo. Five years ago (Apr 5 2011), the addition of tracker support (7f18afd5d7a0fd4146a4ead16e3de09bc1684bdf) brought a requirement for getaddrinfo. Recently, someone with a working Windows 2000 system reported that Rebirth no longer starts on Windows 2000. Although such systems should not be connected to the Internet, they may still need name resolution on a LAN. Add a configure test to probe for getaddrinfo support and fall back to gethostbyname if needed. Compiling a binary that works on Windows 2000 requires one of: * using an ancient SDK that does not declare getaddrinfo * defining _WIN32_WINNT to exclude Windows XP support * overriding the SConf test to force failure Fixes: 7f18afd5d7a0fd4146a4ead16e3de09bc1684bdf ("Client-side implementation for Tracker support by Matt 1360 Vandermeulen including improvements in udp_dns_filladdr and IPv4/IPv6 compability; Very little adjustments by me, too including IPv6 support for Windows (untested); Actual tracker code will follow later as seperate branch when it's done") --- SConstruct | 22 ++++++++++++++++++++++ similar/main/net_udp.cpp | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/SConstruct b/SConstruct index e8b7cc4b0..2910bf8e4 100644 --- a/SConstruct +++ b/SConstruct @@ -1743,6 +1743,28 @@ help:always wipe certain freed memory return !strcasecmp(argv[0], argv[0] + 1) && !strncasecmp(argv[0] + 1, argv[0], 1); ''' self.Compile(context, text='#include ', main=main, msg='for strcasecmp', successflags=_successflags) + @_custom_test + def check_getaddrinfo_present(self,context,_successflags={'CPPDEFINES' : ['DXX_HAVE_GETADDRINFO']}): + self.Compile(context, text=''' +#ifdef WIN32 +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#include +#include +#else +#include +#include +#include +#endif +''', main=''' + addrinfo *res = nullptr; + const addrinfo *hints = nullptr; + int i = getaddrinfo("", "", hints, &res); + (void)i; + freeaddrinfo(res); + return 0; +''', msg='for getaddrinfo', successflags=_successflags) __preferred_compiler_options = ( '-fvisibility=hidden', '-Wsuggest-attribute=noreturn', diff --git a/similar/main/net_udp.cpp b/similar/main/net_udp.cpp index bdd3694c4..3cce1d670 100644 --- a/similar/main/net_udp.cpp +++ b/similar/main/net_udp.cpp @@ -523,6 +523,7 @@ public: // Resolve address int udp_dns_filladdr_t::apply(sockaddr &addr, socklen_t addrlen, int ai_family, const char *host, uint16_t port) { +#ifdef DXX_HAVE_GETADDRINFO // Variables addrinfo hints{}; char sPort[6]; @@ -568,6 +569,23 @@ int udp_dns_filladdr_t::apply(sockaddr &addr, socklen_t addrlen, int ai_family, */ // Free memory +#else + sockaddr_in &sai = reinterpret_cast(addr); + if (addrlen < sizeof(sai)) + return -1; + const auto he = gethostbyname(host); + if (!he) + { + con_printf(CON_URGENT, "udp_dns_filladdr (gethostbyname) failed for host %s", host); + nm_messagebox(TXT_ERROR, 1, TXT_OK, "Could not resolve IPv4 address\n%s", host); + addr.sa_family = AF_UNSPEC; + return -1; + } + sai = {}; + sai.sin_family = ai_family; + sai.sin_port = htons(port); + sai.sin_addr = *reinterpret_cast(he->h_addr); +#endif return 0; }