Skip to content

Commit

Permalink
Port: restore Windows XP minimal support (c-ares#958)
Browse files Browse the repository at this point in the history
Windows XP support was removed in 2021, but we've had a recent request
for basic Windows XP support. It looks like the needed changes are very
minimal these days, the only real requirement is to build without
threading support, everything else can be conditionally bypassed.

This changeset mostly just disables building the event subsystem if
threading is disabled then makes a couple minor build system changes to
allow overriding of the `_WIN32_WINNT` macro.

Fixes c-ares#956

---------

Signed-off-by: Brad House (@bradh352)
  • Loading branch information
bradh352 authored Jan 9, 2025
1 parent eeea199 commit 5d7abd1
Show file tree
Hide file tree
Showing 21 changed files with 131 additions and 64 deletions.
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,14 @@ ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "QNX")
LIST (APPEND SYSFLAGS -D_QNX_SOURCE)
ELSEIF (WIN32)
LIST (APPEND SYSFLAGS -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0602)
LIST (APPEND SYSFLAGS -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
IF (NOT CMAKE_C_FLAGS MATCHES ".*-D_WIN32_WINNT=.*")
LIST (APPEND SYSFLAGS -D_WIN32_WINNT=0x0602)
ENDIF ()
ENDIF ()
ADD_DEFINITIONS(${SYSFLAGS})



# Tell C-Ares about libraries to depend on
IF (HAVE_LIBRESOLV)
LIST (APPEND CARES_DEPENDENT_LIBS resolv)
Expand Down Expand Up @@ -426,6 +428,7 @@ CHECK_SYMBOL_EXISTS (getservbyname_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERV
CHECK_SYMBOL_EXISTS (gettimeofday "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETTIMEOFDAY)
CHECK_SYMBOL_EXISTS (if_indextoname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_INDEXTONAME)
CHECK_SYMBOL_EXISTS (if_nametoindex "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_NAMETOINDEX)
CHECK_SYMBOL_EXISTS (GetBestRoute2 "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETBESTROUTE2)
CHECK_SYMBOL_EXISTS (ConvertInterfaceIndexToLuid "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONVERTINTERFACEINDEXTOLUID)
CHECK_SYMBOL_EXISTS (ConvertInterfaceLuidToNameA "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONVERTINTERFACELUIDTONAMEA)
CHECK_SYMBOL_EXISTS (NotifyIpInterfaceChange "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_NOTIFYIPINTERFACECHANGE)
Expand Down
4 changes: 3 additions & 1 deletion Makefile.m32
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ RANLIB = $(CROSSPREFIX)ranlib
#RM = rm -f
CP = cp -afv

CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I./include -I./src/lib -I./src/lib/include -D_WIN32_WINNT=0x0602
WIN32_WINNT ?= 0x0602

CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I./include -I./src/lib -I./src/lib/include -D_WIN32_WINNT=$(WIN32_WINNT)
CFLAGS += -DCARES_STATICLIB
LDFLAGS = $(CARES_LDFLAG_EXTRAS) -s
LIBS = -lws2_32 -liphlpapi
Expand Down
17 changes: 9 additions & 8 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ configuration:
# CMAKE_EXTRA_OPTIONS: -DOPENSSL_ROOT_DIR=C:/OpenSSL-Win32
environment:
matrix:
# MSVC 2022, 32-bit x86 (cmake)
# MSVC 2022, 32-bit x86 (cmake, WindowsXP)
- COMPILER: MSVC
CONFTOOL: CMAKE
SYSTEM: CONSOLE
SKIP_TESTS: no
MSVC_SETUP_ARG: x86
MSVC_SETUP_PATH: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat
CMAKE_EXTRA_OPTIONS: -GNinja -DCARES_BUILD_TESTS=ON -DGTEST_ROOT=C:\projects\googletest -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL
CMAKE_EXTRA_OPTIONS: -GNinja -DCARES_BUILD_TESTS=ON -DGTEST_ROOT=C:\projects\googletest -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL -DCARES_THREADS=OFF -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0501" -DCMAKE_CXX_FLAGS="-D_WIN32_WINNT=0x0501"
TOOLSDIR: ./build/bin
TESTDIR: ./build/bin
BUILD_GOOGLETEST: yes
Expand Down Expand Up @@ -65,23 +65,24 @@ environment:
MSVC_SETUP_PATH: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat
BUILD_GOOGLETEST: yes

# MinGW, 32-bit x86 (makefiles)
# MinGW, 32-bit x86 (makefiles, Windows XP)
- COMPILER: MINGW
CONFTOOL: MAKE
SYSTEM: CONSOLE
SKIP_TESTS: no
PATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;%PATH%
BUILD_GOOGLETEST: yes
MAKE_FLAGS: WIN32_WINNT=0x0501

# MinGW, 32-bit x86 (cmake static only)
# MinGW, 32-bit x86 (cmake static only, Windows XP)
- COMPILER: MINGW
CONFTOOL: CMAKE
SYSTEM: CONSOLE
SKIP_TESTS: no
TOOLSDIR: ./build/bin
TESTDIR: ./build/bin
PATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;%PATH%
CMAKE_EXTRA_OPTIONS: -DCARES_SHARED=OFF -GNinja -DCARES_BUILD_TESTS=ON -DGTEST_ROOT=C:\projects\googletest
CMAKE_EXTRA_OPTIONS: -DCARES_SHARED=OFF -GNinja -DCARES_BUILD_TESTS=ON -DGTEST_ROOT=C:\projects\googletest -DCARES_THREADS=OFF -DCMAKE_C_FLAGS="-D_WIN32_WINNT=0x0501" -DCMAKE_CXX_FLAGS="-D_WIN32_WINNT=0x0501"
BUILD_GOOGLETEST: yes

# Disabled until AppVeyor updates their Visual Studio with this patch:
Expand Down Expand Up @@ -117,7 +118,7 @@ build_script:
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "CMAKE" cmake --build build --config Debug
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "CMAKE" cmake --install build --config Debug
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" copy .\include\ares_build.h.dist .\include\ares_build.h
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" mingw32-make.exe -f Makefile.m32 demos
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" mingw32-make.exe -f Makefile.m32 demos %MAKE_FLAGS%

test_script:
# We can't use powershell for tests due to treating stderr as an error
Expand All @@ -126,8 +127,8 @@ test_script:
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "NMAKE" if not "%SKIP_TESTS%" == "yes" nmake GTEST_ROOT=C:\projects\googletest /NOLOGO /f .\Makefile.msvc aresfuzz aresfuzzname dnsdump
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "NMAKE" if not "%SKIP_TESTS%" == "yes" .\msvc\arestest\lib-debug\dnsdump.exe fuzzinput\answer_a fuzzinput\answer_aaaa
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" cd test
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" mingw32-make.exe GTEST_ROOT=C:\projects\googletest -f Makefile.m32 vtest
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" mingw32-make.exe GTEST_ROOT=C:\projects\googletest -f Makefile.m32 aresfuzz.exe aresfuzzname.exe dnsdump.exe
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" mingw32-make.exe GTEST_ROOT=C:\projects\googletest -f Makefile.m32 vtest %MAKE_FLAGS%
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" mingw32-make.exe GTEST_ROOT=C:\projects\googletest -f Makefile.m32 aresfuzz.exe aresfuzzname.exe dnsdump.exe %MAKE_FLAGS%
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "MAKE" if not "%SKIP_TESTS%" == "yes" .\dnsdump.exe fuzzinput\answer_a fuzzinput\answer_aaaa
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "CMAKE" if not "%SKIP_TESTS%" == "yes" cd %TESTDIR%
- if "%SYSTEM%" == "CONSOLE" if "%CONFTOOL%" == "CMAKE" if not "%SKIP_TESTS%" == "yes" .\adig.exe www.google.com
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ AC_CHECK_DECL(pipe, [AC_DEFINE([HAVE_PIPE], 1, [Define t
AC_CHECK_DECL(pipe2, [AC_DEFINE([HAVE_PIPE2], 1, [Define to 1 if you have `pipe2`] )], [], $cares_all_includes)
AC_CHECK_DECL(kqueue, [AC_DEFINE([HAVE_KQUEUE], 1, [Define to 1 if you have `kqueue`] )], [], $cares_all_includes)
AC_CHECK_DECL(epoll_create1, [AC_DEFINE([HAVE_EPOLL], 1, [Define to 1 if you have `epoll_{create1,ctl,wait}`])], [], $cares_all_includes)
AC_CHECK_DECL(GetBestRoute2, [AC_DEFINE([HAVE_GETBESTROUTE2], 1, [Define to 1 if you have `GetBestRoute2`] )], [], $cares_all_includes)
AC_CHECK_DECL(ConvertInterfaceIndexToLuid, [AC_DEFINE([HAVE_CONVERTINTERFACEINDEXTOLUID], 1, [Define to 1 if you have `ConvertInterfaceIndexToLuid`])], [], $cares_all_includes)
AC_CHECK_DECL(ConvertInterfaceLuidToNameA, [AC_DEFINE([HAVE_CONVERTINTERFACELUIDTONAMEA], 1, [Define to 1 if you have `ConvertInterfaceLuidToNameA`])], [], $cares_all_includes)
AC_CHECK_DECL(NotifyIpInterfaceChange, [AC_DEFINE([HAVE_NOTIFYIPINTERFACECHANGE], 1, [Define to 1 if you have `NotifyIpInterfaceChange`] )], [], $cares_all_includes)
Expand Down
3 changes: 3 additions & 0 deletions src/lib/ares_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@
/* Define to 1 if you have the `if_nametoindex' function. */
#cmakedefine HAVE_IF_NAMETOINDEX 1

/* Define to 1 if you have the `GetBestRoute2' function. */
#cmakedefine HAVE_GETBESTROUTE2 1

/* Define to 1 if you have the `ConvertInterfaceIndexToLuid' function. */
#cmakedefine HAVE_CONVERTINTERFACEINDEXTOLUID 1

Expand Down
10 changes: 10 additions & 0 deletions src/lib/ares_ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ struct addrinfo {
# define NS_INT16SZ 2
#endif

/* Windows XP Compatibility with later MSVC/Mingw versions */
#if defined(_WIN32)
# if !defined(IF_MAX_STRING_SIZE)
# define IF_MAX_STRING_SIZE 256 /* =256 in <ifdef.h> */
# endif
# if !defined(NDIS_IF_MAX_STRING_SIZE)
# define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE /* =256 in <ifdef.h> */
# endif
#endif

#ifndef IF_NAMESIZE
# ifdef IFNAMSIZ
# define IF_NAMESIZE IFNAMSIZ
Expand Down
31 changes: 18 additions & 13 deletions src/lib/ares_sysconfig_win.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ static int compareAddresses(const void *arg1, const void *arg2)
return 0;
}

#if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__)
/* There can be multiple routes to "the Internet". And there can be different
* DNS servers associated with each of the interfaces that offer those routes.
* We have to assume that any DNS server can serve any request. But, some DNS
Expand Down Expand Up @@ -213,18 +214,6 @@ static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
const SOCKADDR_INET * const dest,
const ULONG interfaceMetric)
{
/* On this interface, get the best route to that destination. */
# if defined(__WATCOMC__)
/* OpenWatcom's builtin Windows SDK does not have a definition for
* MIB_IPFORWARD_ROW2, and also does not allow the usage of SOCKADDR_INET
* as a variable. Let's work around this by returning the worst possible
* metric, but only when using the OpenWatcom compiler.
* It may be worth investigating using a different version of the Windows
* SDK with OpenWatcom in the future, though this may be fixed in OpenWatcom
* 2.0.
*/
return (ULONG)-1;
# else
MIB_IPFORWARD_ROW2 row;
SOCKADDR_INET ignored;
if (GetBestRoute2(/* The interface to use. The index is ignored since we are
Expand Down Expand Up @@ -257,8 +246,8 @@ static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
* which describes the combination as a "sum".
*/
return row.Metric + interfaceMetric;
# endif /* __WATCOMC__ */
}
#endif

/*
* get_DNS_Windows()
Expand Down Expand Up @@ -379,9 +368,21 @@ static ares_bool_t get_DNS_Windows(char **outptr)
addressesSize = newSize;
}

# if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__)
/* OpenWatcom's builtin Windows SDK does not have a definition for
* MIB_IPFORWARD_ROW2, and also does not allow the usage of SOCKADDR_INET
* as a variable. Let's work around this by returning the worst possible
* metric, but only when using the OpenWatcom compiler.
* It may be worth investigating using a different version of the Windows
* SDK with OpenWatcom in the future, though this may be fixed in OpenWatcom
* 2.0.
*/
addresses[addressesIndex].metric = getBestRouteMetric(
&ipaaEntry->Luid, (SOCKADDR_INET *)((void *)(namesrvr.sa)),
ipaaEntry->Ipv4Metric);
# else
addresses[addressesIndex].metric = (ULONG)-1;
# endif

/* Record insertion index to make qsort stable */
addresses[addressesIndex].orig_idx = addressesIndex;
Expand Down Expand Up @@ -423,9 +424,13 @@ static ares_bool_t get_DNS_Windows(char **outptr)
ll_scope = ipaaEntry->Ipv6IfIndex;
}

# if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__)
addresses[addressesIndex].metric = getBestRouteMetric(
&ipaaEntry->Luid, (SOCKADDR_INET *)((void *)(namesrvr.sa)),
ipaaEntry->Ipv6Metric);
# else
addresses[addressesIndex].metric = (ULONG)-1;
# endif

/* Record insertion index to make qsort stable */
addresses[addressesIndex].orig_idx = addressesIndex;
Expand Down
8 changes: 6 additions & 2 deletions src/lib/config-win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,10 @@
# undef HAVE_NETIOAPI_H
#endif

/* Threading support enabled */
#define CARES_THREADS 1
/* Threading support enabled for Vista+ */
#if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0600
# define CARES_THREADS 1
#endif

/* ---------------------------------------------------------------- */
/* TYPEDEF REPLACEMENTS */
Expand Down Expand Up @@ -370,6 +372,8 @@
# define HAVE_CONVERTINTERFACELUIDTONAMEA 1
/* Define to 1 if you have the `NotifyIpInterfaceChange' function. */
# define HAVE_NOTIFYIPINTERFACECHANGE 1
/* Define to 1 if you have the `GetBestRoute2` function */
# define HAVE_GETBESTROUTE2 1
#endif

/* ---------------------------------------------------------------- */
Expand Down
25 changes: 14 additions & 11 deletions src/lib/event/ares_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,30 +159,33 @@ ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e,
ares_event_signal_cb_t signal_cb);


#ifdef HAVE_PIPE
#ifdef CARES_THREADS
# ifdef HAVE_PIPE
ares_event_t *ares_pipeevent_create(ares_event_thread_t *e);
#endif
# endif

#ifdef HAVE_POLL
# ifdef HAVE_POLL
extern const ares_event_sys_t ares_evsys_poll;
#endif
# endif

#ifdef HAVE_KQUEUE
# ifdef HAVE_KQUEUE
extern const ares_event_sys_t ares_evsys_kqueue;
#endif
# endif

#ifdef HAVE_EPOLL
# ifdef HAVE_EPOLL
extern const ares_event_sys_t ares_evsys_epoll;
#endif
# endif

#ifdef _WIN32
# ifdef _WIN32
extern const ares_event_sys_t ares_evsys_win32;
#endif
# endif

/* All systems have select(), but not all have a way to wake, so we require
* pipe() to wake the select() */
#ifdef HAVE_PIPE
# ifdef HAVE_PIPE
extern const ares_event_sys_t ares_evsys_select;
# endif

#endif

#endif
13 changes: 8 additions & 5 deletions src/lib/event/ares_event_configchg.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "ares_private.h"
#include "ares_event.h"

#ifdef __ANDROID__
#if defined(__ANDROID__) && defined(CARES_THREADS)

ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
ares_event_thread_t *e)
Expand All @@ -43,7 +43,7 @@ void ares_event_configchg_destroy(ares_event_configchg_t *configchg)
(void)configchg;
}

#elif defined(__linux__)
#elif defined(__linux__) && defined(CARES_THREADS)

# include <sys/inotify.h>

Expand Down Expand Up @@ -174,7 +174,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
return status;
}

#elif defined(USE_WINSOCK)
#elif defined(USE_WINSOCK) && defined(CARES_THREADS)

# include <winsock2.h>
# include <iphlpapi.h>
Expand Down Expand Up @@ -379,7 +379,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
return status;
}

#elif defined(__APPLE__)
#elif defined(__APPLE__) && defined(CARES_THREADS)

# include <sys/types.h>
# include <unistd.h>
Expand Down Expand Up @@ -531,7 +531,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
return status;
}

#elif defined(HAVE_STAT) && !defined(_WIN32)
#elif defined(HAVE_STAT) && !defined(_WIN32) && defined(CARES_THREADS)
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
Expand Down Expand Up @@ -722,13 +722,16 @@ void ares_event_configchg_destroy(ares_event_configchg_t *configchg)
ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
ares_event_thread_t *e)
{
(void)configchg;
(void)e;
/* No ability */
return ARES_ENOTIMP;
}

void ares_event_configchg_destroy(ares_event_configchg_t *configchg)
{
/* No-op */
(void)configchg;
}

#endif
4 changes: 2 additions & 2 deletions src/lib/event/ares_event_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
#include "ares_private.h"
#include "ares_event.h"

#if defined(HAVE_EPOLL) && defined(CARES_THREADS)

#ifdef HAVE_SYS_EPOLL_H
# include <sys/epoll.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif

#ifdef HAVE_EPOLL

typedef struct {
int epoll_fd;
} ares_evsys_epoll_t;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/event/ares_event_kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "ares_private.h"
#include "ares_event.h"

#if defined(HAVE_KQUEUE) && defined(CARES_THREADS)

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
Expand All @@ -39,8 +41,6 @@
# include <fcntl.h>
#endif

#ifdef HAVE_KQUEUE

typedef struct {
int kqueue_fd;
struct kevent *changelist;
Expand Down
5 changes: 3 additions & 2 deletions src/lib/event/ares_event_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
*/
#include "ares_private.h"
#include "ares_event.h"

#if defined(HAVE_POLL) && defined(CARES_THREADS)

#ifdef HAVE_POLL_H
# include <poll.h>
#endif

#if defined(HAVE_POLL)

static ares_bool_t ares_evsys_poll_init(ares_event_thread_t *e)
{
e->ev_signal = ares_pipeevent_create(e);
Expand Down
Loading

0 comments on commit 5d7abd1

Please sign in to comment.