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
(7f18afd5d7) 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: 7f18afd5d7 ("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")
This commit is contained in:
Kp 2016-03-18 02:05:16 +00:00
parent 8a09513934
commit 20e72128de
2 changed files with 40 additions and 0 deletions

View file

@ -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 <cstring>', 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 <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#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',

View file

@ -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<sockaddr_in &>(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<const in_addr *>(he->h_addr);
#endif
return 0;
}