Commit cdc54afd authored by Jason Madden's avatar Jason Madden

Upgrade c-ares to 1.13.0. Fixes #990

parent bee87cfd
......@@ -80,6 +80,8 @@
- ``socket.send()`` now catches ``EPROTYPE`` on macOS to handle a race
condition during shutdown. Fixed in :pr:`1035` by Jay Oster.
- Update c-ares to 1.13.0. See :issue:`990`.
1.2.2 (2017-06-05)
==================
......
Changelog for the c-ares project. Generated with git2changes.pl
Version 1.13.0 (20 Jun 2017)
Daniel Stenberg (20 Jun 2017)
- RELEASE-NOTES: 1.13.0
- ares_set_socket_functions.3: added in 1.13.0
David Drysdale (18 Jun 2017)
- ares_parse_naptr_reply: check sufficient data
Check that there is enough data for the required elements
of an NAPTR record (2 int16, 3 bytes for string lengths)
before processing a record.
- test: Feed in short NAPTR
- test: Add fuzz input with short NAPTR
- test: add ares_parse_naptr_reply to fuzzer
- [noiz brought this change]
Update ares.h to support compiling with QNX
- [Dionna Glaze brought this change]
Simple changes to appease stricter compilers.
ares_process.c uses htonl, which needs <arpa/inet.h> included.
ares_getnameinfo.c uses a dynamically selected format string for
sprintf, which -Wformat-literal doesn't like. Usually one would use
inttypes.h and a format string "%" PRIu32, but C99 is too new for some
supported platforms.
GitHub (16 Jun 2017)
- [Gregor Jasny brought this change]
CMake: Emulate interface library on import (#108)
Closes: #104
Signed-off-by: Gregor Jasny <gjasny@googlemail.com>
Brad House (6 Jun 2017)
- [ChristianAmmer brought this change]
Added support for Windows DNS Suffix Search List (#93)
This change solves issue #53.
Support for suffix search lists was already built in for Linux. The search list could be set via set_search. With this change the suffix search list from Windows is read from the registry and then set into the ares configuration via set_search. There are two sources for the search list:
The global DNS suffix search list.
The primary and connection specific DNS suffixes if the global is not available.
Contributed by @ChristianAmmer
Daniel Stenberg (25 May 2017)
- [Thomas Köckerbauer brought this change]
configure: do not heck for ar if specified manually
Closes #62
David Drysdale (23 May 2017)
- ares_expand_name: limit number of indirections
- test: fuzz input file that takes a while to process
- test: copy data in fuzz regression driver
Oops.
GitHub (23 May 2017)
- [David Drysdale brought this change]
Convert char from ISO-8859-1 to UTF-8 (#99)
Fixes #97
- [Gregor Jasny brought this change]
travis: Use trusty for cmake builds (#109)
kubuntu-backports dropped the CMake package for Precise
David Drysdale (2 May 2017)
- [David Hotham brought this change]
msvc_ver.inc support most recent Visual Studio 2017 (#101)
- test: use io.h not unistd.h for Windows
- test: try building fuzz binaries on Windows
- test: stick to int in ares-fuzz.c
Using int rather than ares_ssize_t means this file
needs no c-ares dependency - it's a general driver for
any libFuzzer-style entrypoint.
- test: force ARES_OPT_NOROTATE for no-rotate tests
- test: check expected NOROTATE value
- ares_create_query: use ares_free not naked free
Accidentally added in commit 65c71be1cbe5
("ares_create_query: avoid single-byte buffer overwrite")
Brad House (17 Mar 2017)
- Need ares.h for ares_ssize_t
- tests should not use ssize_t, use ares_ssize_t
GitHub (16 Mar 2017)
- [Brad House brought this change]
Portability updates for legacy systems. (#92)
Socklen_t should not be used in code, instead ares_socklen_t should be used.
Convert ssize_t to ares_ssize_t for portability since the public API now exposes this.
David Drysdale (14 Mar 2017)
- [Michael Osei brought this change]
Update msvc_ver.inc (#91)
For Visual Studio 2017 builds
Daniel Stenberg (13 Mar 2017)
- [Brad House brought this change]
Windows DNS server sorting (#81)
Original Patch From Brad Spencer:
https://c-ares.haxx.se/mail/c-ares-archive-2016-04/0000.shtml
My modifications include:
* Dynamically find GetBestRoute2 since it is a Windows Vista+ symbol, and will fall back to prior behavior when not available.
* Prefer get_DNS_AdaptersAddresses as the modifications should alleviate the concerns which caused us to prefer get_DNS_NetworkParams
* Update AppVeyor to use MinGW-w64 instead of the legacy MinGW
* Fix compile error in test suite for Windows.
Original message from patch below:
From: Brad Spencer <bspencer@blackberry.com>
Date: Fri, 29 Apr 2016 14:26:23 -0300
On Windows, the c-ares DNS resolver tries first to get a full list of
DNS server addresses by enumerating the system's IPv4/v6 interfaces and
then getting the per-interface DNS server lists from those interfaces
and joining them together. The OS, at least in the way the c-ares
prefers to query them (which also may be the only or best way in some
environments), does not provide a unified list of DNS servers ordered
according to "current network conditions". Currently, c-ares will then
try to use them in whatever order the nested enumeration produces, which
may result in DNS requests being sent to servers on one interface
(hosting the current default route, for example) that are only intended
to be used via another interface (intended to be used when the first
interface is not available, for example). This, in turn, can lead to
spurious failures and timeouts simply because of the server address
order that resulted because of the enumeration process.
This patch makes the (safe?) assumption that there is no other better
rule to chose which interface's DNS server list should be prioritized.
After all, a DNS lookup isn't something "per network"; applications
don't look up "these DNS names on this interface and those DNS names on
that interface". There is a single resource pool of DNS servers and the
application should presume that any server will give it the "right"
answer. However, even if all DNS servers are assumed to give equally
useful responses, it is reasonable to expect that some DNS servers will
not accept requests on all interfaces. This patch avoids the problem by
sorting the DNS server addresses using the Windows IPv4/v6 routing tables.
For example, a request to DNS server C on interface 2 that is actually
sent over interface 1 (which may happen to have the default route) may
be rejected by or not delivered to DNS server C. So, better to use DNS
servers A and B associated with interface 1, at least as a first try.
By using the metric of the route to the DNS server itself as a proxy for
priority of the DNS server in the list, this patch is able to adapt
dynamically to changes in the interface list, the DNS server lists per
interface, which interfaces are active, the routing table, and so on,
while always picking a good "best" DNS server first.
In cases where any DNS server on any interface will do, this patch still
seems useful because it will prioritize a lower-metric route's (and thus
interface's) servers.
David Drysdale (22 Feb 2017)
- [Sergii Pylypenko brought this change]
docs: fixed references to ares_set_local_ip4 and ares_set_local_ip6
- [Calle Wilund brought this change]
ares test: fix win32 build errors with virtual socket function tests
The added api requires both some typedefs not previously imported
into the test build + the test code did not fully deal with
socket differences on windows.
- [Calle Wilund brought this change]
ares_process: fix return type of socket_create function (win32 warning)
Daniel Stenberg (31 Jan 2017)
- [Calle Wilund brought this change]
ares_set_socket_functions: Add man page
Providing some rudimentary documentation for the added functionality
Closes #72
- [Calle Wilund brought this change]
ares-test: Add test helpers and cases for virtual socket IO
* Added test case macro to automatically run tests twice, once "normal",
once with virtual IO.
* Changed most "live" query tests to run in dual mode to verify
at least simple socket IO via virtual functions
* Added test case for settings/duping socket functions & callback data
- [elcallio brought this change]
Implement using virtual socket IO functions when set
Uses virtual socket IO functions when set on a channel.
Note that no socket options are set, nor is any binding
done by the library in this case, since the client defining
these is probably more suited to deal with this.
- [elcallio brought this change]
Add virtual function set for socket IO
Defines a structure of basic create, close, read/write
functions as virtual function calls, settable for individual
c-ares channels.
David Drysdale (30 Jan 2017)
- test: ignore aresfuzzname binary
Gregor Jasny (14 Jan 2017)
- [Stephen Sorley brought this change]
Always use check_symbol_exists instead of check_function_exists.
- Also add includes to TARGETS_INST_DEST
- [Stephen Sorley brought this change]
Windows build fixes
- CMake: Export targets
- CMake: Use GNUInstallDirs for install location defaults
David Drysdale (11 Jan 2017)
- Update Makefile.am for renamed INSTALL.md
GitHub (11 Jan 2017)
- [David Drysdale brought this change]
docs: convert INSTALL to MarkDown & tweak (#83)
- [Gregor Jasny brought this change]
Merge pull request #77 from stephen-sorley/cmake_modernize
Updated CMake minimum version to 2.8.12.
Stephen Sorley (4 Jan 2017)
- Changed executables to depend directly on internal libcares target, instead of against
the external-facing alias targets.
- Updated Travis to pull CMake 2.8.12 from kubuntu-backports ppa.
- Updated CMake minimum version to 2.8.12.
Changed the way usage requirements (include dirs, compile defs, dependent libraries) are specified, to match the recommended standard practice for modern CMake. This involves using target-specific functions (target_include_directories, target_compile_definitions, etc.), along with the PUBLIC, PRIVATE or INTERFACE modifiers.
Updated chain-building support to imitate new-style Find modules (import libs), instead of old-style Find modules (cache variables).
David Drysdale (26 Dec 2016)
- [Chris Araman brought this change]
configure: clock_gettime workaround (#75)
Commits 7518c26, c41726b, and bc14ee7 brought this workaround to the CMake build system. This expands it to the autoconf build system.
Fixes #71
- test: add fuzz entrypoint for ares_create_query()
- test: Add gTest/gMock files to SOURCES
Built tarballs are not including all of the files needed
to build the test suite because they are missing from the
<target>_SOURCES variable in Makefile.am.
- travis: Move build scripts under travis/
Travis doesn't always propagate errors in inline multi-line
scripts, so move them all to be explicit shell scripts, each
with set -e.
- travis: check distributed tarball builds
Daniel Stenberg (25 Oct 2016)
- dist: ship msvc_ver.inc too
Reported-by: Bruce Stephens
Fixes #69
- [Aaron Bieber brought this change]
fix build on OpenBSD
- ares_version.h: bump, working on 1.12.1 now
GitHub (18 Oct 2016)
- [Gregor Jasny brought this change]
Merge pull request #64 from bradh352/master
Add CMake build system support to C-Ares.
Brad House (5 Oct 2016)
- suggested PROJECT_NAME change broke chain building as it needs the magic PROJECT_NAME set in the ADD_LIBRARY for matching. Fix to make both goals work
- update MacOSX 10.12 detection
- Expand XCode clock_gettime fix to include MacOS 10.12, not just iOS10
David Drysdale (4 Oct 2016)
- Revert "travis: work around bug in PyCParser"
This reverts commit a24a10a348fc00b8cfd684d91894a1df14880ea9.
- travis: work around bug in PyCParser
See https://github.com/pyca/cryptography/issues/3187
Brad House (3 Oct 2016)
- PROJECT_SOURCE_DIR instead of CMAKE_CURRENT_SOURCE_DIR as per @gjasny
- use a project name of c-ares as per @gjasny
- Import curl conversion of Makefile.inc to cmake form dynamically as per bdoetsch@ameritech.net to make maintaining multiple build systems easier
Daniel Stenberg (30 Sep 2016)
- dist: add ares_library_initialized.* to the tarball
David Drysdale (30 Sep 2016)
- test: check ares_create_query with too-long name
Daniel Stenberg (30 Sep 2016)
- man pages: minor formatting edits
Brad House (29 Sep 2016)
- merge fc7917e from @daviddrysdale ... travis build updates for cmake
- cleanups as per @gjasny ... Use naked IF statements and use NOT DEFINED
Version 1.12.0 (29 Sep 2016)
Daniel Stenberg (29 Sep 2016)
......@@ -17,6 +385,10 @@ Daniel Stenberg (29 Sep 2016)
Bug: https://c-ares.haxx.se/adv_20160929.html
Brad House (29 Sep 2016)
- CMake: Unify library versioning with the libtool methodology to make keeping library versions in sync easier with the autotools build system
Daniel Stenberg (29 Sep 2016)
- ares_library_initialized.3: added
- make: bump CARES_VERSION_INFO for release
......@@ -27,6 +399,24 @@ David Drysdale (29 Sep 2016)
Daniel Stenberg (29 Sep 2016)
- ares_library_init.3: corrected the ares_library_init_mem proto
Brad House (28 Sep 2016)
- XCode v8 introduced clock_gettime() for iOS v10. However, it is a weak symbol, which means when earlier iOS versions try to use clock_gettime() it results in a crash due to the missing symbol. Detect this condition and do not set HAVE_CLOCK_GETTIME_MONOTONIC.
- Adds cmake build system support to C-Ares.
The patch does not modify any source files, it only adds 3 new files
(CMakelists.txt, ares_build.h.cmake, ares_config.h.cmake) which form the
build system. I've tried to go through as much of the autotools tests and
extracted what I thought was appropriate, though many of the tests aren't
as in-depth in CMake as they are for autotools ... it is unclear why some
of them exist at all, I'm guessing for legacy systems that CMake probably
doesn't support anyhow.
Building the library, and examples (adig, ahost, acountry) plus installation
should work across a large number of tested platforms. The tests have not
yet been integrated.
Daniel Stenberg (27 Sep 2016)
- README.md: remove space from link
- README: link to the correct c-ares badge!
......@@ -3731,238 +4121,3 @@ Yang Tse (16 Oct 2008)
Gisle Vanem (21 Sep 2008)
- Added HAVE_NETDB_H, HAVE_ARPA_INET_H, HAVE_STRCASECMP
and HAVE_STRNCASECMP.
Yang Tse (19 Sep 2008)
- icc adjustments:
Disable remark #981: operands are evaluated in unspecified order
Function calls which are triggering this remark, today, do not depend
on the order of evaluation of its arguments.
Disable remark #1469: "cc" clobber ignored
Remark triggered on htons() and ntohs() due to glibc header files.
- icc adjustments
- fix netdb.h prerequisite inclusion
- improve detection of getservbyport_r()
- On Linux Intel's icc uses gcc's header files, so
we select ANSI C89 dialect plus GNU extensions.
- improve detection of gethostname()
- NetWare builds include "nameser.h" from the c-ares subdir
- include <strings.h>
- Sync up with reality
- adjust inclusion of "nameser.h"
- reorder some lines in file
- code cleanup
- NetWare seems to have writev()
- rearrange to allow internal/private use of ares_writev to any system
that lacks the writev function.
- NetWare CLIB target has stricmp() and strnicmp()
- include header file only when available
- rearrange to allow internal/private use of ares_strcasecmp to any system that
lacks the strcasecmp function.
- improve detection of:
strcasecmp()
strcmpi()
stricmp()
strncasecmp()
strncmpi()
strnicmp()
- *** empty log message ***
Gisle Vanem (12 Sep 2008)
- djgpp does have strdup().
Yang Tse (12 Sep 2008)
- change CRLF into LF line endings
- strdup() clone for systems/configurations which lack it
- move inclusion of ares_private.h last
- icc adjustments
- icc adjustments
- Select strict ANSI C89 conformance for icc
- remove unnecessary typecasting of malloc()
- remove unnecessary typecasting of realloc()
Daniel Stenberg (29 Aug 2008)
- we start over working towards 1.5.4
Version 1.5.3 (29 Aug 2008)
Daniel Stenberg (29 Aug 2008)
- Version 1.5.3
- added the three people from RELEASE-NOTES and sorted the list alphabetically
Yang Tse (27 Aug 2008)
- Don't abort configuration if recvfrom() is not available.
- Functionality only possible if recvfrom() is available.
- George Neill's fix acountry sample application compilation failure.
- Brad House's validation that DNS response address matches the request address
- fix the output name
- Get rid of ENABLE_64BIT symbol definition and usage.
Improve HAVE_LONGLONG symbol description.
- Export 'ares_process_fd' too.
Gisle Vanem (16 Aug 2008)
- Ops, remove 'use_vc'.
- Support Watt-32 under Win32.
Yang Tse (10 Aug 2008)
- Fix: Remove now this SIZEOF_CURL_OFF_T symbol definition.
This should have been done with the initial 64-bit curl_off_t patch.
- Improve CURL_CHECK_DEF
- Fix IBM C and DEC/Compaq C compiler detection
- Initial support of curlbuild.h and curlrules.h which allows
to have a curl_off_t data type no longer gated to off_t.
- The minimum autoconf version required for this file is 2.50
Avoid dot notation in aclocal serial file number, use a single number now.
Daniel Stenberg (4 Aug 2008)
- - Fix by Tofu Linden:
The symptom:
* Users (usually, but not always) on 2-Wire routers and the Comcast service
and a wired connection to their router would find that the second and
subsequent DNS lookups from fresh processes using c-ares to resolve the same
address would cause the process to never see a reply (it keeps polling for
around 1m15s before giving up).
The repro:
* On such a machine (and yeah, it took us a lot of QA to find the systems
that reproduce such a specific problem!), do 'ahost www.secondlife.com',
then do it again. The first process's lookup will work, subsequent lookups
will time-out and fail.
The cause:
* init_id_key() was calling randomize_key() *before* it initialized
key->state, meaning that the randomness generated by randomize_key() is
immediately overwritten with deterministic values. (/dev/urandom was also
being read incorrectly in the c-ares version we were using, but this was
fixed in a later version.)
* This makes the stream of generated query-IDs from any new c-ares process
be an identical and predictable sequence of IDs.
* This makes the 2-Wire's default built-in DNS server detect these queries
as probable-duplicates and (erroneously) not respond at all.
Yang Tse (4 Aug 2008)
- Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use.
Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. But,
autoconf 2.62 version of AC_AIX defines _ALL_SOURCE along with other four
preprocessor symbols no matter if the system is AIX or not. To keep the
traditional behaviour, as well as an uniform one, across autoconf versions
AC_AIX is replaced with our own internal macro.
- Adjust DEC/Compaq C compiler settings.
- Another AC_TRY_LINK conversion to AC_LINK_IFELSE.
Proper definition of HAVE_function if function is found deeper.
- Sync up with reality
- Rename reentrant.m4 to avoid filename clash.
- Add file version serial number that might be used by 'aclocal' and others.
Keep the '#' character as the first one on the line.
- Update copyright year.
- Sync comment with reality.
- Reinstate the 'aclocal -I m4' in buildconf and 'ACLOCAL_AMFLAGS = -I m4' way of
including our local m4/reentrant.m4 file. This even takes care of including the
file in the distribution tarball.
- Add quoting for the AC_DEFINE arguments.
- Also remove the whitespace.
- Also remove the extra quoting.
- Replace some '@%:@' quadigraphs by its actual representation '#'.
This quadigraph used before a C preprocessor 'define' directive could
be fooling M4, when processing this file, and make it think that the
line contains a pure M4 'define' macro.
- Tests done using 'aclocal -I m4' in buildconf and 'ACLOCAL_AMFLAGS = -I m4
in top Makefile.am triggered a problem that prevented aclocal from running
successfully on SunOS 5.10 with GNU m4 1.4.5 and GNU Autoconf 2.61
A tarball which reproduces mentioned problem is the one dated July-28-2008
http://cool.haxx.se/curl-daily/curl-7.19.0-20080728.tar.gz
We actually don't need all the bells and whistles that the above mechanism
provides. We only need to include our m4/reentrant.m4 file in acinclude.m4
so here we go with this simpler mechanism.
- for debugging purposes show ACLOCAL_FLAGS
- These lines were unintentionally removed in previous commit
- Partially undo change that prevented SED, GREP, EGREP and AR from being changed by libtool or autoconf.
- Assert that SED and GREP are set
- Require autoconf 2.57 or newer
- When calling aclocal, user defined ACLOCAL_FLAGS will now precede ours.
- move ACLOCAL_AMFLAGS after AUTOMAKE_OPTIONS
- setup.h handles definition of _REENTRANT based on NEED_REENTRANT
definition which might be defined in config.h or config-*.h files
- Remove explicit inclusion of our m4 files first. It was interesting as a test,
but it breaks aclocal execution on some systems, with the following error:
Can't locate object method "rel2abs" via package "File::Spec" at /usr/local/bin/aclocal line 256.
- Another step towards detecting if _REENTRANT is already defined or actually
needed, and being able to define it if appropriate for further configure tests
as well as for the generated config file.
- Explicitly include our m4 files first. This might minimize the impact
that other package's underquoted m4 function definitions have on ours.
- Add a 3 argument check for getprotobyname_r
** This file is adapted from libcurl and not yet fully rewritten for c-ares! **
___ __ _ _ __ ___ ___
/ __| ___ / _` | '__/ _ \/ __|
| (_ |___| (_| | | | __/\__ \
\___| \__,_|_| \___||___/
How To Compile
Installing Binary Packages
==========================
Lots of people download binary distributions of c-ares. This document
does not describe how to install c-ares using such a binary package.
This document describes how to compile, build and install c-ares from
source code.
Building from git
=================
If you get your code off a git repository, see the GIT-INFO file in the
root directory for specific instructions on how to proceed.
UNIX
====
A normal unix installation is made in three or four steps (after you've
unpacked the source archive):
./configure
make
make ahost adig acountry (optional)
make install
You probably need to be root when doing the last command.
If you have checked out the sources from the git repository, read the
GIT-INFO on how to proceed.
Get a full listing of all available configure options by invoking it like:
./configure --help
If you want to install c-ares in a different file hierarchy than /usr/local,
you need to specify that already when running configure:
./configure --prefix=/path/to/c-ares/tree
If you happen to have write permission in that directory, you can do 'make
install' without being root. An example of this would be to make a local
install in your own home directory:
./configure --prefix=$HOME
make
make install
MORE OPTIONS
------------
To force configure to use the standard cc compiler if both cc and gcc are
present, run configure like
CC=cc ./configure
or
env CC=cc ./configure
To force a static library compile, disable the shared library creation
by running configure like:
./configure --disable-shared
If you're a c-ares developer and use gcc, you might want to enable more
debug options with the --enable-debug option.
SPECIAL CASES
-------------
Some versions of uClibc require configuring with CPPFLAGS=-D_GNU_SOURCE=1
to get correct large file support.
The Open Watcom C compiler on Linux requires configuring with the variables:
./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \
RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra
Win32
=====
Building Windows DLLs and C run-time (CRT) linkage issues
---------------------------------------------------------
As a general rule, building a DLL with static CRT linkage is highly
discouraged, and intermixing CRTs in the same app is something to
avoid at any cost.
Reading and comprehension of Microsoft Knowledge Base articles
KB94248 and KB140584 is a must for any Windows developer. Especially
important is full understanding if you are not going to follow the
advice given above.
KB94248 - How To Use the C Run-Time
http://support.microsoft.com/kb/94248/en-us
KB140584 - How to link with the correct C Run-Time (CRT) library
http://support.microsoft.com/kb/140584/en-us
KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries
http://msdn.microsoft.com/en-us/library/ms235460
If your app is misbehaving in some strange way, or it is suffering
from memory corruption, before asking for further help, please try
first to rebuild every single library your app uses as well as your
app using the debug multithreaded dynamic C runtime.
MingW32
-------
Make sure that MinGW32's bin dir is in the search path, for example:
set PATH=c:\mingw32\bin;%PATH%
then run 'make -f Makefile.m32' in the root dir.
Cygwin
------
Almost identical to the unix installation. Run the configure script in the
c-ares root with 'sh configure'. Make sure you have the sh executable in
/bin/ or you'll see the configure fail toward the end.
Run 'make'
Dev-Cpp
-------
See the separate INSTALL.devcpp file for details.
MSVC 6 caveats
--------------
If you use MSVC 6 it is required that you use the February 2003 edition PSDK:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
MSVC from command line
----------------------
Run the 'vcvars32.bat' file to get a proper environment. The
vcvars32.bat file is part of the Microsoft development environment and
you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin'
provided that you installed Visual C/C++ 6 in the default directory.
Further details in README.msvc
MSVC IDES
---------
Details in README.msvc
Important static c-ares usage note
----------------------------------
When building an application that uses the static c-ares library, you must
add '-DCARES_STATICLIB' to your CFLAGS. Otherwise the linker will look for
dynamic import symbols.
IBM OS/2
========
Building under OS/2 is not much different from building under unix.
You need:
- emx 0.9d
- GNU make
- GNU patch
- ksh
- GNU bison
- GNU file utilities
- GNU sed
- autoconf 2.13
If during the linking you get an error about _errno being an undefined
symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__
in your definitions.
If you're getting huge binaries, probably your makefiles have the -g in
CFLAGS.
QNX
===
(This section was graciously brought to us by David Bentham)
As QNX is targeted for resource constrained environments, the QNX headers
set conservative limits. This includes the FD_SETSIZE macro, set by default
to 32. Socket descriptors returned within the c-ares library may exceed this,
resulting in memory faults/SIGSEGV crashes when passed into select(..)
calls using fd_set macros.
A good all-round solution to this is to override the default when building
c-ares, by overriding CFLAGS during configure, example
# configure CFLAGS='-DFD_SETSIZE=64 -g -O2'
RISC OS
=======
The library can be cross-compiled using gccsdk as follows:
CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \
--host=arm-riscos-aof --without-random --disable-shared
make
where riscos-gcc and riscos-ar are links to the gccsdk tools.
You can then link your program with c-ares/lib/.libs/libcares.a
NetWare
=======
To compile libcares.a / libcares.lib you need:
- either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later.
- gnu make and awk running on the platform you compile on;
native Win32 versions can be downloaded from:
http://www.gknw.net/development/prgtools/
- recent Novell LibC SDK available from:
http://developer.novell.com/ndk/libc.htm
- or recent Novell CLib SDK available from:
http://developer.novell.com/ndk/clib.htm
Set a search path to your compiler, linker and tools; on Linux make
sure that the var OSTYPE contains the string 'linux'; set the var
NDKBASE to point to the base of your Novell NDK; and then type
'make -f Makefile.netware' from the top source directory;
Android
=======
Method using a configure cross-compile (tested with Android NDK r7b):
- prepare the toolchain of the Android NDK for standalone use; this can
be done by invoking the script:
./tools/make-standalone-toolchain.sh
which creates a usual cross-compile toolchain. Lets assume that you put
this toolchain below /opt then invoke configure with something like:
export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
./configure --host=arm-linux-androideabi [more configure options]
make
- if you want to compile directly from our GIT repo you might run into
this issue with older automake stuff:
checking host system type...
Invalid configuration `arm-linux-androideabi':
system `androideabi' not recognized
configure: error: /bin/sh ./config.sub arm-linux-androideabi failed
this issue can be fixed with using more recent versions of config.sub
and config.guess which can be obtained here:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree
you need to replace your system-own versions which usually can be
found in your automake folder:
find /usr -name config.sub
CROSS COMPILE
=============
(This section was graciously brought to us by Jim Duey, with additions by
Dan Fandrich)
Download and unpack the c-ares package.
'cd' to the new directory. (e.g. cd c-ares-1.7.6)
Set environment variables to point to the cross-compile toolchain and call
configure with any options you need. Be sure and specify the '--host' and
'--build' parameters at configuration time. The following script is an
example of cross-compiling for the IBM 405GP PowerPC processor using the
toolchain from MonteVista for Hardhat Linux.
(begin script)
#! /bin/sh
export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
export AR=ppc_405-ar
export AS=ppc_405-as
export LD=ppc_405-ld
export RANLIB=ppc_405-ranlib
export CC=ppc_405-gcc
export NM=ppc_405-nm
./configure --target=powerpc-hardhat-linux \
--host=powerpc-hardhat-linux \
--build=i586-pc-linux-gnu \
--prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \
--exec-prefix=/usr/local
(end script)
You may also need to provide a parameter like '--with-random=/dev/urandom'
to configure as it cannot detect the presence of a random number
generating device for a target system. The '--prefix' parameter
specifies where c-ares will be installed. If 'configure' completes
successfully, do 'make' and 'make install' as usual.
In some cases, you may be able to simplify the above commands to as
little as:
./configure --host=ARCH-OS
PORTS
=====
This is a probably incomplete list of known hardware and operating systems
that c-ares has been compiled for. If you know a system c-ares compiles and
runs on, that isn't listed, please let us know!
- Alpha Tru64 v5.0 5.1
- ARM Android 1.5, 2.1, 2.3
- MIPS IRIX 6.2, 6.5
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
- i386 Novell NetWare
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
- x86_64 Linux
Useful URLs
===========
c-ares https://c-ares.haxx.se/
MingW http://www.mingw.org/
MinGW-w64 http://mingw-w64.sourceforge.net/
OpenWatcom http://www.openwatcom.org/
** This file is adapted from libcurl and not yet fully rewritten for c-ares! **
```
___ __ _ _ __ ___ ___
/ __| ___ / _` | '__/ _ \/ __|
| (_ |___| (_| | | | __/\__ \
\___| \__,_|_| \___||___/
How To Compile
```
Installing Binary Packages
==========================
Lots of people download binary distributions of c-ares. This document
does not describe how to install c-ares using such a binary package.
This document describes how to compile, build and install c-ares from
source code.
Building from Git
=================
If you get your code off a Git repository rather than an official
release tarball, see the [GIT-INFO](GIT-INFO) file in the root directory
for specific instructions on how to proceed.
In particular, you will need to run `./buildconf` (Unix) or
`buildconf.bat` (Windows) to generate build files, and for the former
you will need a local installation of Autotools.
Unix
====
A normal Unix installation is made in three or four steps (after you've
unpacked the source archive):
./configure
make
make ahost adig acountry (optional)
make install
You probably need to be root when doing the last command.
If you have checked out the sources from the git repository, read the
[GIT-INFO](GIT_INFO) on how to proceed.
Get a full listing of all available configure options by invoking it like:
./configure --help
If you want to install c-ares in a different file hierarchy than /usr/local,
you need to specify that already when running configure:
./configure --prefix=/path/to/c-ares/tree
If you happen to have write permission in that directory, you can do `make
install` without being root. An example of this would be to make a local
install in your own home directory:
./configure --prefix=$HOME
make
make install
More Options
------------
To force configure to use the standard cc compiler if both cc and gcc are
present, run configure like
CC=cc ./configure
# or
env CC=cc ./configure
To force a static library compile, disable the shared library creation
by running configure like:
./configure --disable-shared
If you're a c-ares developer and use gcc, you might want to enable more
debug options with the `--enable-debug` option.
Special Cases
-------------
Some versions of uClibc require configuring with `CPPFLAGS=-D_GNU_SOURCE=1`
to get correct large file support.
The Open Watcom C compiler on Linux requires configuring with the variables:
./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \
RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra
Win32
=====
Building Windows DLLs and C run-time (CRT) linkage issues
---------------------------------------------------------
As a general rule, building a DLL with static CRT linkage is highly
discouraged, and intermixing CRTs in the same app is something to
avoid at any cost.
Reading and comprehension of Microsoft Knowledge Base articles
KB94248 and KB140584 is a must for any Windows developer. Especially
important is full understanding if you are not going to follow the
advice given above.
- [KB94248](http://support.microsoft.com/kb/94248/en-us) - How To Use the C Run-Time
- [KB140584](http://support.microsoft.com/kb/140584/en-us) - How to link with the correct C Run-Time (CRT) library
- [KB190799](http://msdn.microsoft.com/en-us/library/ms235460) - Potential Errors Passing CRT Objects Across DLL Boundaries
If your app is misbehaving in some strange way, or it is suffering
from memory corruption, before asking for further help, please try
first to rebuild every single library your app uses as well as your
app using the debug multithreaded dynamic C runtime.
MingW32
-------
Make sure that MinGW32's bin dir is in the search path, for example:
set PATH=c:\mingw32\bin;%PATH%
then run 'make -f Makefile.m32' in the root dir.
Cygwin
------
Almost identical to the unix installation. Run the configure script in the
c-ares root with `sh configure`. Make sure you have the sh executable in
`/bin/` or you'll see the configure fail toward the end.
Run `make`
MSVC 6 caveats
--------------
If you use MSVC 6 it is required that you use the February 2003 edition PSDK:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
MSVC from command line
----------------------
Run the `vcvars32.bat` file to get a proper environment. The
`vcvars32.bat` file is part of the Microsoft development environment and
you may find it in `C:\Program Files\Microsoft Visual Studio\vc98\bin`
provided that you installed Visual C/C++ 6 in the default directory.
Further details in [README.msvc](README.msvc)
MSVC IDEs
---------
Details in [README.msvc](README.msvc)
Important static c-ares usage note
----------------------------------
When building an application that uses the static c-ares library, you must
add `-DCARES_STATICLIB` to your `CFLAGS`. Otherwise the linker will look for
dynamic import symbols.
IBM OS/2
========
Building under OS/2 is not much different from building under unix.
You need:
- emx 0.9d
- GNU make
- GNU patch
- ksh
- GNU bison
- GNU file utilities
- GNU sed
- autoconf 2.13
If during the linking you get an error about `_errno` being an undefined
symbol referenced from the text segment, you need to add `-D__ST_MT_ERRNO__`
in your definitions.
If you're getting huge binaries, probably your makefiles have the `-g` in
`CFLAGS`.
QNX
===
(This section was graciously brought to us by David Bentham)
As QNX is targeted for resource constrained environments, the QNX headers
set conservative limits. This includes the `FD_SETSIZE` macro, set by default
to 32. Socket descriptors returned within the c-ares library may exceed this,
resulting in memory faults/SIGSEGV crashes when passed into `select(..)`
calls using `fd_set` macros.
A good all-round solution to this is to override the default when building
c-ares, by overriding `CFLAGS` during configure, example:
# configure CFLAGS='-DFD_SETSIZE=64 -g -O2'
RISC OS
=======
The library can be cross-compiled using gccsdk as follows:
CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \
--host=arm-riscos-aof --without-random --disable-shared
make
where `riscos-gcc` and `riscos-ar` are links to the gccsdk tools.
You can then link your program with `c-ares/lib/.libs/libcares.a`.
NetWare
=======
To compile `libcares.a` / `libcares.lib` you need:
- either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later.
- gnu make and awk running on the platform you compile on;
native Win32 versions can be downloaded from:
http://www.gknw.net/development/prgtools/
- recent Novell LibC SDK available from:
http://developer.novell.com/ndk/libc.htm
- or recent Novell CLib SDK available from:
http://developer.novell.com/ndk/clib.htm
Set a search path to your compiler, linker and tools; on Linux make
sure that the var `OSTYPE` contains the string 'linux'; set the var
`NDKBASE` to point to the base of your Novell NDK; and then type
`make -f Makefile.netware` from the top source directory;
Android
=======
Method using a configure cross-compile (tested with Android NDK r7b):
- prepare the toolchain of the Android NDK for standalone use; this can
be done by invoking the script:
./tools/make-standalone-toolchain.sh
which creates a usual cross-compile toolchain. Lets assume that you put
this toolchain below `/opt` then invoke configure with something
like:
```
export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
./configure --host=arm-linux-androideabi [more configure options]
make
```
- if you want to compile directly from our GIT repo you might run into
this issue with older automake stuff:
```
checking host system type...
Invalid configuration `arm-linux-androideabi':
system `androideabi' not recognized
configure: error: /bin/sh ./config.sub arm-linux-androideabi failed
```
this issue can be fixed with using more recent versions of `config.sub`
and `config.guess` which can be obtained here:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree
you need to replace your system-own versions which usually can be
found in your automake folder:
`find /usr -name config.sub`
CROSS COMPILE
=============
(This section was graciously brought to us by Jim Duey, with additions by
Dan Fandrich)
Download and unpack the c-ares package.
`cd` to the new directory. (e.g. `cd c-ares-1.7.6`)
Set environment variables to point to the cross-compile toolchain and call
configure with any options you need. Be sure and specify the `--host` and
`--build` parameters at configuration time. The following script is an
example of cross-compiling for the IBM 405GP PowerPC processor using the
toolchain from MonteVista for Hardhat Linux.
```sh
#! /bin/sh
export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
export AR=ppc_405-ar
export AS=ppc_405-as
export LD=ppc_405-ld
export RANLIB=ppc_405-ranlib
export CC=ppc_405-gcc
export NM=ppc_405-nm
./configure --target=powerpc-hardhat-linux \
--host=powerpc-hardhat-linux \
--build=i586-pc-linux-gnu \
--prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \
--exec-prefix=/usr/local
```
You may also need to provide a parameter like `--with-random=/dev/urandom`
to configure as it cannot detect the presence of a random number
generating device for a target system. The `--prefix` parameter
specifies where c-ares will be installed. If `configure` completes
successfully, do `make` and `make install` as usual.
In some cases, you may be able to simplify the above commands to as
little as:
./configure --host=ARCH-OS
PORTS
=====
This is a probably incomplete list of known hardware and operating systems
that c-ares has been compiled for. If you know a system c-ares compiles and
runs on, that isn't listed, please let us know!
- Alpha Tru64 v5.0 5.1
- ARM Android 1.5, 2.1, 2.3
- MIPS IRIX 6.2, 6.5
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
- i386 Novell NetWare
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
- x86_64 Linux
Useful URLs
===========
- c-ares: https://c-ares.haxx.se/
- MingW: http://www.mingw.org/
- MinGW-w64: http://mingw-w64.sourceforge.net/
- OpenWatcom: http://www.openwatcom.org/
......@@ -52,7 +52,7 @@ LFLAGS += debug all
CFLAGS += -d0
!endif
CFLAGS += -d_WIN32_WINNT=0x0501
CFLAGS += -d_WIN32_WINNT=0x0600
#
# Change to suite.
......
......@@ -38,8 +38,9 @@ lib_LTLIBRARIES = libcares.la
man_MANS = $(MANPAGES)
MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \
vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw
MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \
vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw \
msvc_ver.inc
if CURLDEBUG
PROGS =
......@@ -55,7 +56,7 @@ EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj \
Makefile.m32 Makefile.netware Makefile.msvc Makefile.Watcom $(man_MANS) \
config-win32.h RELEASE-NOTES libcares.pc.in buildconf get_ver.awk maketgz \
TODO ares_build.h.in $(PDFPAGES) cares.rc README.msvc $(MSVCFILES) \
$(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL \
$(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL.md \
README.md LICENSE.md
CLEANFILES = $(PDFPAGES) $(HTMLPAGES)
......
......@@ -321,7 +321,7 @@ CTAGS = ctags
CSCOPE = cscope
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \
$(srcdir)/ares_build.h.in $(srcdir)/ares_config.h.in \
$(srcdir)/libcares.pc.in AUTHORS INSTALL NEWS TODO compile \
$(srcdir)/libcares.pc.in AUTHORS NEWS TODO compile \
config.guess config.sub depcomp install-sh ltmain.sh missing \
mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
......@@ -535,8 +535,9 @@ ACLOCAL_AMFLAGS = -I m4
@CURLDEBUG_TRUE@ -I$(top_srcdir) $(am__append_4)
lib_LTLIBRARIES = libcares.la
man_MANS = $(MANPAGES)
MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \
vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw
MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \
vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw \
msvc_ver.inc
@CURLDEBUG_FALSE@PROGS = ahost adig acountry
@CURLDEBUG_TRUE@PROGS =
......@@ -547,7 +548,7 @@ EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj \
Makefile.m32 Makefile.netware Makefile.msvc Makefile.Watcom $(man_MANS) \
config-win32.h RELEASE-NOTES libcares.pc.in buildconf get_ver.awk maketgz \
TODO ares_build.h.in $(PDFPAGES) cares.rc README.msvc $(MSVCFILES) \
$(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL \
$(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL.md \
README.md LICENSE.md
CLEANFILES = $(PDFPAGES) $(HTMLPAGES)
......@@ -685,6 +686,7 @@ MANPAGES = ares_cancel.3 \
ares_init_options.3 \
ares_library_cleanup.3 \
ares_library_init.3 \
ares_library_initialized.3 \
ares_mkquery.3 \
ares_create_query.3 \
ares_parse_a_reply.3 \
......@@ -738,6 +740,7 @@ HTMLPAGES = ares_cancel.html \
ares_init_options.html \
ares_library_cleanup.html \
ares_library_init.html \
ares_library_initialized.html \
ares_mkquery.html \
ares_create_query.html \
ares_parse_a_reply.html \
......@@ -790,6 +793,7 @@ PDFPAGES = ares_cancel.pdf \
ares_init_options.pdf \
ares_library_cleanup.pdf \
ares_library_init.pdf \
ares_library_initialized.pdf \
ares_mkquery.pdf \
ares_create_query.pdf \
ares_parse_a_reply.pdf \
......
......@@ -92,6 +92,7 @@ MANPAGES = ares_cancel.3 \
ares_init_options.3 \
ares_library_cleanup.3 \
ares_library_init.3 \
ares_library_initialized.3 \
ares_mkquery.3 \
ares_create_query.3 \
ares_parse_a_reply.3 \
......@@ -145,6 +146,7 @@ HTMLPAGES = ares_cancel.html \
ares_init_options.html \
ares_library_cleanup.html \
ares_library_init.html \
ares_library_initialized.html \
ares_mkquery.html \
ares_create_query.html \
ares_parse_a_reply.html \
......@@ -197,6 +199,7 @@ PDFPAGES = ares_cancel.pdf \
ares_init_options.pdf \
ares_library_cleanup.pdf \
ares_library_init.pdf \
ares_library_initialized.pdf \
ares_mkquery.pdf \
ares_create_query.pdf \
ares_parse_a_reply.pdf \
......
......@@ -17,7 +17,7 @@ RANLIB = $(CROSSPREFIX)ranlib
#RM = rm -f
CP = cp -afv
CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I.
CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I. -D_WIN32_WINNT=0x0600
CFLAGS += -DCARES_STATICLIB
LDFLAGS = $(CARES_LDFLAG_EXTRAS) -s
LIBS = -lwsock32
......
......@@ -184,7 +184,7 @@ CFLAGS = /UWIN32 /DWATT32 /I$(WATT_ROOT)\inc
EX_LIBS_REL = $(WATT_ROOT)\lib\wattcpvc_imp.lib
EX_LIBS_DBG = $(WATT_ROOT)\lib\wattcpvc_imp_d.lib
!ELSE
CFLAGS = /DWIN32
CFLAGS = /DWIN32 /D_WIN32_WINNT=0x0600
EX_LIBS_REL = ws2_32.lib advapi32.lib kernel32.lib
EX_LIBS_DBG = ws2_32.lib advapi32.lib kernel32.lib
!ENDIF
......
......@@ -12,8 +12,9 @@ perform multiple DNS queries in parallel. The primary examples of such
applications are servers which communicate with multiple clients and programs
with graphical user interfaces.
The full source code is available in the 'c-ares' release archives, and in a
git repository: http://github.com/c-ares/c-ares
The full source code is available in the ['c-ares' release archives](https://c-ares.haxx.se/download/),
and in a git repository: http://github.com/c-ares/c-ares. See the
[INSTALL.md](INSTALL.md) file for build information.
If you find bugs, correct flaws, have questions or have comments in general in
regard to c-ares (or by all means the original ares too), get in touch with us
......
c-ares version 1.12.0
c-ares version 1.13.0
Changes:
o api: add ARES_OPT_NOROTATE optmask value
o cmake build system support added
o Add virtual function set for socket IO: ares_set_socket_functions [5]
Bug fixes:
o CVE-2016-5180: ares_create_query single byte out of buffer write [4]
o configure: acknowledge --disable-tests [1]
o man pages: fix typos detected by Lintian
o test: add missing #includes for dns-proto.cc
o test: avoid in6addr_* constants
o test: Build with MinGW on AppVeyor
o Makefile.m32: add support for extra flags
o Makefile.m32: add support for CROSSPREFIX
o configure: check if tests can get built before enabled
o ares_library_cleanup: reset ares_realloc too
o ahost.c: add cast to fix C++ compile
o test: Only pass unused args to GoogleTest
o build: commonize MSVC version detection
o msvc_ver.inc: support Visual Studio 2015 Update 1, 2, 3
o test: for AF_UNSPEC, return CNAME only for AAAA, but valid A record
o ares_getnameinfo: explicitly clear struct servent before use
o test: Update fuzzing function prototype
o init: fix nsort initialization
o test: add fuzzing check script to tests
o web: http => https
o read_tcp_data: remove superfluous NULL check
o LICENSE.md: add a stand-alone license file
o SECURITY.md: suggested "security process" for the project
o ares_init_options: only propagate init failures from options [2]
o headers: remove checks for and defines of variable sizes
o test: fix gMock to work with gcc >= 6.x [3]
o CVE-2017-1000381: c-ares NAPTR parser out of bounds access [1]
o macos: do not set HAVE_CLOCK_GETTIME_MONOTONIC
o test: check ares_create_query with too-long name
o dist: add ares_library_initialized.* to the tarball
o fix build on OpenBSD
o dist: ship msvc_ver.inc too [2]
o test: Add gTest/gMock files to SOURCES
o test: add fuzz entrypoint for ares_create_query()
o configure: clock_gettime workaround [3]
o docs: convert INSTALL to MarkDown & tweak [4]
o ares_process: fix return type of socket_create function (win32 warning)
o docs: fixed references to ares_set_local_ip4 and ares_set_local_ip6
o Windows DNS server sorting [6]
o Use ares_socklen_t instead of socket_t [7]
o ares_create_query: use ares_free not naked free
o msvc_ver.inc support most recent Visual Studio 2017 [8]
o acountry: Convert char from ISO-8859-1 to UTF-8 [9]
o ares_expand_name: limit number of indirections
o configure: do not check for ar if specified manually [10]
o Added support for Windows DNS Suffix Search List [11]
o ares.h: support compiling with QNX [12]
Thanks go to these friendly people for their efforts and contributions:
Alexander Drachevskiy, Brad House, Chris Araman, Daniel Stenberg,
David Drysdale, Gregor Jasny, Svante Karlsson, Viktor Szakats
Aaron Bieber, Andrew Sullivan, Brad House, Bruce Stephens, Calle Wilund,
Chris Araman, Christian Ammer, Daniel Stenberg, David Drysdale, David Hotham,
Dionna Glaze, Gregor Jasny, Michael Osei, Mulle kybernetiK, noiz at github,
Sergii Pylypenko, Stephen Sorley, Thomas Köckerbauer,
(18 contributors)
References to bug reports and discussions on issues:
[1] = https://github.com/c-ares/c-ares/issues/44
[2] = https://github.com/c-ares/c-ares/issues/60
[3] = https://github.com/google/googletest/issues/705#issuecomment-235067917
[4] = https://c-ares.haxx.se/adv_20160929.html
[1] = https://c-ares.haxx.se/adv_20170620.html
[2] = https://github.com/c-ares/c-ares/issues/69
[3] = https://github.com/c-ares/c-ares/issues/71
[4] = https://github.com/c-ares/c-ares/issues/83
[5] = https://github.com/c-ares/c-ares/issues/72
[6] = https://github.com/c-ares/c-ares/issues/81
[7] = https://github.com/c-ares/c-ares/issues/92
[8] = https://github.com/c-ares/c-ares/issues/101
[9] = https://github.com/c-ares/c-ares/issues/97
[10] = https://github.com/c-ares/c-ares/issues/62
[11] = https://github.com/c-ares/c-ares/issues/93
[12] = https://github.com/c-ares/c-ares/issues/113
......@@ -273,7 +273,7 @@ static const struct search_list *list_lookup(int number, const struct search_lis
*/
static const struct search_list country_list[] = {
{ 4, "af", "Afghanistan" },
{ 248, "ax", "land Island" },
{ 248, "ax", "Åland Island" },
{ 8, "al", "Albania" },
{ 12, "dz", "Algeria" },
{ 16, "as", "American Samoa" },
......
......@@ -38,7 +38,8 @@
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
defined(ANDROID) || defined(__ANDROID__)
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
defined(__QNXNTO__)
#include <sys/select.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
......@@ -356,6 +357,27 @@ CARES_EXTERN void ares_set_socket_configure_callback(ares_channel channel,
CARES_EXTERN int ares_set_sortlist(ares_channel channel,
const char *sortstr);
/*
* Virtual function set to have user-managed socket IO.
* Note that all functions need to be defined, and when
* set, the library will not do any bind nor set any
* socket options, assuming the client handles these
* through either socket creation or the
* ares_sock_config_callback call.
*/
struct iovec;
struct ares_socket_functions {
ares_socket_t(*asocket)(int, int, int, void *);
int(*aclose)(ares_socket_t, void *);
int(*aconnect)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *);
ares_ssize_t(*arecvfrom)(ares_socket_t, void *, size_t, int, struct sockaddr *, ares_socklen_t *, void *);
ares_ssize_t(*asendv)(ares_socket_t, const struct iovec *, int, void *);
};
CARES_EXTERN void ares_set_socket_functions(ares_channel channel,
const struct ares_socket_functions * funcs,
void *user_data);
CARES_EXTERN void ares_send(ares_channel channel,
const unsigned char *qbuf,
int qlen,
......
......@@ -48,14 +48,14 @@ void ares__close_sockets(ares_channel channel, struct server_state *server)
if (server->tcp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
sclose(server->tcp_socket);
ares__socket_close(channel, server->tcp_socket);
server->tcp_socket = ARES_SOCKET_BAD;
server->tcp_connection_generation = ++channel->tcp_connection_generation;
}
if (server->udp_socket != ARES_SOCKET_BAD)
{
SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
sclose(server->udp_socket);
ares__socket_close(channel, server->udp_socket);
server->udp_socket = ARES_SOCKET_BAD;
}
}
......@@ -191,4 +191,17 @@
typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
#endif
/* Data type definition of ares_ssize_t. */
#ifdef _WIN32
# ifdef _WIN64
# define CARES_TYPEOF_ARES_SSIZE_T __int64
# else
# define CARES_TYPEOF_ARES_SSIZE_T long
# endif
#else
# define CARES_TYPEOF_ARES_SSIZE_T ssize_t;
#endif
typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
#endif /* __CARES_BUILD_H */
......@@ -91,4 +91,10 @@
/* Data type definition of ares_socklen_t. */
typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
/* Integral data type used for ares_ssize_t. */
#undef CARES_TYPEOF_ARES_SSIZE_T
/* Data type definition of ares_ssize_t. */
typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
#endif /* __CARES_BUILD_H */
......@@ -18,9 +18,9 @@
ares_cancel \- Cancel a resolve
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_cancel(ares_channel \fIchannel\fP)
#include <ares.h>
void ares_cancel(ares_channel \fIchannel\fP)
.fi
.SH DESCRIPTION
The \fBares_cancel(3)\fP function cancels all lookups/requests made on the the
......
......@@ -18,6 +18,9 @@
/* Definition to make a library symbol externally visible. */
#undef CARES_SYMBOL_SCOPE_EXTERN
/* the signed version of size_t */
#undef CARES_TYPEOF_ARES_SSIZE_T
/* Use resolver library to configure cares */
#undef CARES_USE_LIBRESOLV
......@@ -496,6 +499,3 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* the signed version of size_t */
#undef ssize_t
......@@ -134,7 +134,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
while (*name)
{
if (*name == '.') {
free (buf);
ares_free (buf);
return ARES_EBADNAME;
}
......@@ -147,7 +147,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
len++;
}
if (len > MAXLABEL) {
free (buf);
ares_free (buf);
return ARES_EBADNAME;
}
......@@ -190,7 +190,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
* to 255 octets or less."). */
if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
(max_udp_size ? EDNSFIXEDSZ : 0))) {
free (buf);
ares_free (buf);
return ARES_EBADNAME;
}
......
......@@ -18,9 +18,9 @@
ares_destroy \- Destroy a resolver channel
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_destroy(ares_channel \fIchannel\fP)
#include <ares.h>
void ares_destroy(ares_channel \fIchannel\fP)
.fi
.SH DESCRIPTION
The \fBares_destroy(3)\fP function destroys the name service channel
......@@ -28,7 +28,7 @@ identified by \fIchannel\fP, freeing all memory and closing all sockets used
by the channel.
\fBares_destroy(3)\fP invokes the callbacks for each pending query on the
channel, passing a status of \IARES_EDESTRUCTION\fP. These calls give the
channel, passing a status of \fIARES_EDESTRUCTION\fP. These calls give the
callbacks a chance to clean up any state which might have been stored in their
arguments. A callback must not add new requests to a channel being destroyed.
.SH SEE ALSO
......
......@@ -32,6 +32,9 @@
#include "ares_nowarn.h"
#include "ares_private.h" /* for the memdebug */
/* Maximum number of indirections allowed for a name */
#define MAX_INDIRS 50
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen);
......@@ -66,7 +69,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
char *q;
const unsigned char *p;
union {
ssize_t sig;
ares_ssize_t sig;
size_t uns;
} nlen;
......@@ -162,7 +165,8 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
/* If we've seen more indirects than the message length,
* then there's a loop.
*/
if (++indir > alen)
++indir;
if (indir > alen || indir > MAX_INDIRS)
return -1;
}
else if (top == 0x00)
......
......@@ -41,7 +41,7 @@ int ares_expand_string(const unsigned char *encoded,
{
unsigned char *q;
union {
ssize_t sig;
ares_ssize_t sig;
size_t uns;
} elen;
......
......@@ -15,43 +15,30 @@
.\"
.TH ARES_FDS 3 "23 July 1998"
.SH NAME
ares_fds \- Get file descriptors to select on for name service
ares_fds \- return file descriptors to select on
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_fds(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP,
.B fd_set *\fIwrite_fds\fP)
#include <ares.h>
int ares_fds(ares_channel \fIchannel\fP,
fd_set *\fIread_fds\fP,
fd_set *\fIwrite_fds\fP)
.fi
.SH DESCRIPTION
The
.B ares_fds
function retrieves the set of file descriptors which the calling
application should select on for reading and writing for the
The \fBares_fds(3)\fP function retrieves the set of file descriptors which the
calling application should select on for reading and writing for the
processing of name service queries pending on the name service channel
identified by
.IR channel .
identified by \fIchannel\fP.
File descriptors will be set in the file descriptor sets pointed to by
.I read_fds
and
.I write_fds
as appropriate. File descriptors already set in
.I read_fds
and
.I write_fds
will remain set; initialization of the file descriptor sets
(using
.BR FD_ZERO )
is the responsibility of the caller.
\fIread_fds\fP and \fIwrite_fds\fP as appropriate. File descriptors already
set in \fIread_fds\fP and \fIwrite_fds\fP will remain set; initialization of
the file descriptor sets (using \fBFD_ZERO\fP) is the responsibility of the
caller.
.SH RETURN VALUES
.B ares_fds
returns one greater than the number of the highest socket set in either
.I read_fds
or
.IR write_fds .
If no queries are active,
.B ares_fds
will return 0.
\fBares_fds(3)\fP returns a value that is one greater than the number of the
highest socket set in either \fIread_fds\fP or \fIwrite_fds\fP. If no queries
are active, \fBares_fds(3)\fP returns 0.
.SH SEE ALSO
.BR ares_timeout (3),
.BR ares_process (3)
......
......@@ -356,12 +356,9 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
#ifdef HAVE_IF_INDEXTONAME
int is_ll, is_mcll;
#endif
static const char fmt_u[] = "%u";
static const char fmt_lu[] = "%lu";
char tmpbuf[IF_NAMESIZE + 2];
size_t bufl;
const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?
fmt_lu:fmt_u;
int is_scope_long = sizeof(addr6->sin6_scope_id) > sizeof(unsigned int);
tmpbuf[0] = '%';
......@@ -371,15 +368,38 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
if ((flags & ARES_NI_NUMERICSCOPE) ||
(!is_ll && !is_mcll))
{
sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
if (is_scope_long)
{
sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
}
else
{
sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
}
}
else
{
if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
{
if (is_scope_long)
{
sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
}
else
{
sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
}
}
}
#else
sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
if (is_scope_long)
{
sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id);
}
else
{
sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id);
}
(void) flags;
#endif
tmpbuf[IF_NAMESIZE + 1] = '\0';
......
......@@ -84,7 +84,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
const char *str);
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
struct apattern *pat);
static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr);
static void natural_mask(struct apattern *pat);
#if !defined(WIN32) && !defined(WATT32) && \
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
......@@ -166,6 +166,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->sock_create_cb_data = NULL;
channel->sock_config_cb = NULL;
channel->sock_config_cb_data = NULL;
channel->sock_funcs = NULL;
channel->sock_func_cb_data = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
......@@ -292,6 +294,8 @@ int ares_dup(ares_channel *dest, ares_channel src)
(*dest)->sock_create_cb_data = src->sock_create_cb_data;
(*dest)->sock_config_cb = src->sock_config_cb;
(*dest)->sock_config_cb_data = src->sock_config_cb_data;
(*dest)->sock_funcs = src->sock_funcs;
(*dest)->sock_func_cb_data = src->sock_func_cb_data;
strncpy((*dest)->local_dev_name, src->local_dev_name,
sizeof(src->local_dev_name));
......@@ -828,6 +832,24 @@ static int get_DNS_Registry(char **outptr)
return 1;
}
static void commanjoin(char** dst, const char* const src, const size_t len)
{
char *newbuf;
size_t newsize;
/* 1 for terminating 0 and 2 for , and terminating 0 */
newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
newbuf = ares_realloc(*dst, newsize);
if (!newbuf)
return;
if (*dst == NULL)
*newbuf = '\0';
*dst = newbuf;
if (strlen(*dst) != 0)
strcat(*dst, ",");
strncat(*dst, src, len);
}
/*
* commajoin()
*
......@@ -835,24 +857,7 @@ static int get_DNS_Registry(char **outptr)
*/
static void commajoin(char **dst, const char *src)
{
char *tmp;
if (*dst)
{
tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
if (!tmp)
return;
sprintf(tmp, "%s,%s", *dst, src);
ares_free(*dst);
*dst = tmp;
}
else
{
*dst = ares_malloc(strlen(src) + 1);
if (!*dst)
return;
strcpy(*dst, src);
}
commanjoin(dst, src, strlen(src));
}
/*
......@@ -939,6 +944,116 @@ done:
return 1;
}
static BOOL ares_IsWindowsVistaOrGreater(void)
{
OSVERSIONINFO vinfo;
memset(&vinfo, 0, sizeof(vinfo));
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
return FALSE;
return TRUE;
}
/* A structure to hold the string form of IPv4 and IPv6 addresses so we can
* sort them by a metric.
*/
typedef struct
{
/* The metric we sort them by. */
ULONG metric;
/* Room enough for the string form of any IPv4 or IPv6 address that
* ares_inet_ntop() will create. Based on the existing c-ares practice.
*/
char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
} Address;
/* Sort Address values \a left and \a right by metric, returning the usual
* indicators for qsort().
*/
static int compareAddresses(const void *arg1,
const void *arg2)
{
const Address * const left = arg1;
const Address * const right = arg2;
if(left->metric < right->metric) return -1;
if(left->metric > right->metric) return 1;
return 0;
}
/* 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
* servers may only respond if requested over their associated interface. But
* we also want to use "the preferred route to the Internet" whenever possible
* (and not use DNS servers on a non-preferred route even by forcing request
* to go out on the associated non-preferred interface). i.e. We want to use
* the DNS servers associated with the same interface that we would use to
* make a general request to anything else.
*
* But, Windows won't sort the DNS servers by the metrics associated with the
* routes and interfaces _even_ though it obviously sends IP packets based on
* those same routes and metrics. So, we must do it ourselves.
*
* So, we sort the DNS servers by the same metric values used to determine how
* an outgoing IP packet will go, thus effectively using the DNS servers
* associated with the interface that the DNS requests themselves will
* travel. This gives us optimal routing and avoids issues where DNS servers
* won't respond to requests that don't arrive via some specific subnetwork
* (and thus some specific interface).
*
* This function computes the metric we use to sort. On the interface
* identified by \a luid, it determines the best route to \a dest and combines
* that route's metric with \a interfaceMetric to compute a metric for the
* destination address on that interface. This metric can be used as a weight
* to sort the DNS server addresses associated with each interface (lower is
* better).
*
* Note that by restricting the route search to the specific interface with
* which the DNS servers are associated, this function asks the question "What
* is the metric for sending IP packets to this DNS server?" which allows us
* to sort the DNS servers correctly.
*/
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. */
MIB_IPFORWARD_ROW2 row;
SOCKADDR_INET ignored;
if(!ares_fpGetBestRoute2 ||
ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are
* passing a LUID.
*/
luid, 0,
/* No specific source address. */
NULL,
/* Our destination address. */
dest,
/* No options. */
0,
/* The route row. */
&row,
/* The best source address, which we don't need. */
&ignored) != NO_ERROR
/* If the metric is "unused" (-1) or too large for us to add the two
* metrics, use the worst possible, thus sorting this last.
*/
|| row.Metric == (ULONG)-1
|| row.Metric > ((ULONG)-1) - interfaceMetric) {
/* Return the worst possible metric. */
return (ULONG)-1;
}
/* Return the metric value from that row, plus the interface metric.
*
* See
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
* which describes the combination as a "sum".
*/
return row.Metric + interfaceMetric;
}
/*
* get_DNS_AdaptersAddresses()
*
......@@ -965,14 +1080,19 @@ static int get_DNS_AdaptersAddresses(char **outptr)
int trying = IPAA_MAX_TRIES;
int res;
/* The capacity of addresses, in elements. */
size_t addressesSize;
/* The number of elements in addresses. */
size_t addressesIndex = 0;
/* The addresses we will sort. */
Address *addresses;
union {
struct sockaddr *sa;
struct sockaddr_in *sa4;
struct sockaddr_in6 *sa6;
} namesrvr;
char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
*outptr = NULL;
/* Verify run-time availability of GetAdaptersAddresses() */
......@@ -983,6 +1103,17 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if (!ipaa)
return 0;
/* Start with enough room for a few DNS server addresses and we'll grow it
* as we encounter more.
*/
addressesSize = 4;
addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
if(addresses == NULL) {
/* We need room for at least some addresses to function. */
ares_free(ipaa);
return 0;
}
/* Usually this call suceeds with initial buffer size */
res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
ipaa, &ReqBufsz);
......@@ -1012,6 +1143,12 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if(ipaaEntry->OperStatus != IfOperStatusUp)
continue;
/* For each interface, find any associated DNS servers as IPv4 or IPv6
* addresses. For each found address, find the best route to that DNS
* server address _on_ _that_ _interface_ (at this moment in time) and
* compute the resulting total metric, just as Windows routing will do.
* Then, sort all the addresses found by the metric.
*/
for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
ipaDNSAddr;
ipaDNSAddr = ipaDNSAddr->Next)
......@@ -1023,35 +1160,117 @@ static int get_DNS_AdaptersAddresses(char **outptr)
if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
(namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
continue;
/* Allocate room for another address, if necessary, else skip. */
if(addressesIndex == addressesSize) {
const size_t newSize = addressesSize + 4;
Address * const newMem =
(Address*)ares_realloc(addresses, sizeof(Address) * newSize);
if(newMem == NULL) {
continue;
}
addresses = newMem;
addressesSize = newSize;
}
/* Vista required for Luid or Ipv4Metric */
if (ares_IsWindowsVistaOrGreater())
{
/* Save the address as the next element in addresses. */
addresses[addressesIndex].metric =
getBestRouteMetric(&ipaaEntry->Luid,
(SOCKADDR_INET*)(namesrvr.sa),
ipaaEntry->Ipv4Metric);
}
else
{
addresses[addressesIndex].metric = -1;
}
if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
txtaddr, sizeof(txtaddr)))
addresses[addressesIndex].text,
sizeof(addresses[0].text))) {
continue;
}
++addressesIndex;
}
else if (namesrvr.sa->sa_family == AF_INET6)
{
if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
sizeof(namesrvr.sa6->sin6_addr)) == 0)
continue;
/* Allocate room for another address, if necessary, else skip. */
if(addressesIndex == addressesSize) {
const size_t newSize = addressesSize + 4;
Address * const newMem =
(Address*)ares_realloc(addresses, sizeof(Address) * newSize);
if(newMem == NULL) {
continue;
}
addresses = newMem;
addressesSize = newSize;
}
/* Vista required for Luid or Ipv4Metric */
if (ares_IsWindowsVistaOrGreater())
{
/* Save the address as the next element in addresses. */
addresses[addressesIndex].metric =
getBestRouteMetric(&ipaaEntry->Luid,
(SOCKADDR_INET*)(namesrvr.sa),
ipaaEntry->Ipv6Metric);
}
else
{
addresses[addressesIndex].metric = -1;
}
if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
txtaddr, sizeof(txtaddr)))
addresses[addressesIndex].text,
sizeof(addresses[0].text))) {
continue;
}
++addressesIndex;
}
else
else {
/* Skip non-IPv4/IPv6 addresses completely. */
continue;
}
}
}
commajoin(outptr, txtaddr);
/* Sort all of the textual addresses by their metric. */
qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
if (!*outptr)
goto done;
/* Join them all into a single string, removing duplicates. */
{
size_t i;
for(i = 0; i < addressesIndex; ++i) {
size_t j;
/* Look for this address text appearing previously in the results. */
for(j = 0; j < i; ++j) {
if(strcmp(addresses[j].text, addresses[i].text) == 0) {
break;
}
}
/* Iff we didn't emit this address already, emit it now. */
if(j == i) {
/* Add that to outptr (if we can). */
commajoin(outptr, addresses[i].text);
}
}
}
done:
ares_free(addresses);
if (ipaa)
ares_free(ipaa);
if (!*outptr)
if (!*outptr) {
return 0;
}
return 1;
}
......@@ -1072,23 +1291,158 @@ done:
*/
static int get_DNS_Windows(char **outptr)
{
/*
Use GetNetworkParams First in case of
multiple adapter is enabled on this machine.
GetAdaptersAddresses will retrive dummy dns servers.
That will slowing DNS lookup.
*/
/* Try using IP helper API GetNetworkParams() */
if (get_DNS_NetworkParams(outptr))
/* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
* DNS servers by interface route metrics to try to use the best DNS server. */
if (get_DNS_AdaptersAddresses(outptr))
return 1;
/* Try using IP helper API GetAdaptersAddresses() */
if (get_DNS_AdaptersAddresses(outptr))
/* Try using IP helper API GetNetworkParams(). IPv4 only. */
if (get_DNS_NetworkParams(outptr))
return 1;
/* Fall-back to registry information */
return get_DNS_Registry(outptr);
}
static void replace_comma_by_space(char* str)
{
/* replace ',' by ' ' to coincide with resolv.conf search parameter */
char *p;
for (p = str; *p != '\0'; p++)
{
if (*p == ',')
*p = ' ';
}
}
/* Search if 'suffix' is containted in the 'searchlist'. Returns true if yes,
* otherwise false. 'searchlist' is a comma separated list of domain suffixes,
* 'suffix' is one domain suffix, 'len' is the length of 'suffix'.
* The search ignores case. E.g.:
* contains_suffix("abc.def,ghi.jkl", "ghi.JKL") returns true */
static bool contains_suffix(const char* const searchlist,
const char* const suffix, const size_t len)
{
const char* beg = searchlist;
const char* end;
if (!*suffix)
return true;
for (;;)
{
while (*beg && (ISSPACE(*beg) || (*beg == ',')))
++beg;
if (!*beg)
return false;
end = beg;
while (*end && !ISSPACE(*end) && (*end != ','))
++end;
if (len == (end - beg) && !strnicmp(beg, suffix, len))
return true;
beg = end;
}
}
/* advances list to the next suffix within a comma separated search list.
* len is the length of the next suffix. */
static size_t next_suffix(const char** list, const size_t advance)
{
const char* beg = *list + advance;
const char* end;
while (*beg && (ISSPACE(*beg) || (*beg == ',')))
++beg;
end = beg;
while (*end && !ISSPACE(*end) && (*end != ','))
++end;
*list = beg;
return end - beg;
}
/*
* get_SuffixList_Windows()
*
* Reads the "DNS Suffix Search List" from registry and writes the list items
* whitespace separated to outptr. If the Search List is empty, the
* "Primary Dns Suffix" is written to outptr.
*
* Returns 0 and nullifies *outptr upon inability to return the suffix list.
*
* Returns 1 and sets *outptr when returning a dynamically allocated string.
*
* Implementation supports Windows Server 2003 and newer
*/
static int get_SuffixList_Windows(char **outptr)
{
HKEY hKey, hKeyEnum;
char keyName[256];
DWORD keyNameBuffSize;
DWORD keyIdx = 0;
char *p = NULL;
char *pp;
size_t len = 0;
*outptr = NULL;
if (ares__getplatform() != WIN_NT)
return 0;
/* 1. Global DNS Suffix Search List */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
if (get_REG_SZ(hKey, SEARCHLIST_KEY, outptr))
replace_comma_by_space(*outptr);
RegCloseKey(hKey);
if (*outptr)
return 1;
}
/* 2. Connection Specific Search List composed of:
* a. Primary DNS Suffix */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, outptr);
RegCloseKey(hKey);
}
if (!*outptr)
return 0;
/* b. Interface SearchList, Domain, DhcpDomain */
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
return 0;
for(;;)
{
keyNameBuffSize = sizeof(keyName);
if (RegEnumKeyEx(hKey, keyIdx++, keyName, &keyNameBuffSize,
0, NULL, NULL, NULL)
!= ERROR_SUCCESS)
break;
if (RegOpenKeyEx(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
!= ERROR_SUCCESS)
continue;
if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p) ||
get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p) ||
get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
{
/* p can be comma separated (SearchList) */
pp = p;
while (len = next_suffix(&pp, len))
{
if (!contains_suffix(*outptr, pp, len))
commanjoin(outptr, pp, len);
}
ares_free(p);
p = NULL;
}
RegCloseKey(hKeyEnum);
}
RegCloseKey(hKey);
if (*outptr)
replace_comma_by_space(*outptr);
return *outptr != NULL;
}
#endif
static int init_by_resolv_conf(ares_channel channel)
......@@ -1112,6 +1466,12 @@ static int init_by_resolv_conf(ares_channel channel)
ares_free(line);
}
if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
{
status = set_search(channel, line);
ares_free(line);
}
if (status == ARES_SUCCESS)
status = ARES_EOF;
else
......@@ -1950,7 +2310,7 @@ static char *try_config(char *s, const char *opt, char scc)
}
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
{
/* Four octets and three periods yields at most 15 characters. */
......@@ -2103,6 +2463,14 @@ void ares_set_socket_configure_callback(ares_channel channel,
channel->sock_config_cb_data = data;
}
void ares_set_socket_functions(ares_channel channel,
const struct ares_socket_functions * funcs,
void *data)
{
channel->sock_funcs = funcs;
channel->sock_func_cb_data = data;
}
int ares_set_sortlist(ares_channel channel, const char *sortstr)
{
int nsort = 0;
......
......@@ -21,6 +21,27 @@ ares_init_options \- Initialize a resolver channel
.nf
#include <ares.h>
struct ares_options {
int flags;
int timeout; /* in seconds or milliseconds, depending on options */
int tries;
int ndots;
unsigned short udp_port;
unsigned short tcp_port;
int socket_send_buffer_size;
int socket_receive_buffer_size;
struct in_addr *servers;
int nservers;
char **domains;
int ndomains;
char *lookups;
ares_sock_state_cb sock_state_cb;
void *sock_state_cb_data;
struct apattern *sortlist;
int nsort;
int ednspsz;
};
int ares_init_options(ares_channel *\fIchannelptr\fP,
struct ares_options *\fIoptions\fP,
int \fIoptmask\fP)
......
......@@ -19,11 +19,9 @@
ares_library_cleanup \- c-ares library deinitialization
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_library_cleanup(void)
.PP
.B cc file.c -lcares
#include <ares.h>
void ares_library_cleanup(void)
.fi
.SH DESCRIPTION
.PP
......
......@@ -27,6 +27,7 @@
fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL;
#endif
/* library-private global vars with source visibility restricted to this file */
......@@ -71,6 +72,15 @@ static int ares_win32_init(void)
support Windows 2000 anymore */
}
ares_fpGetBestRoute2 = (fpGetBestRoute2_t)
GetProcAddress(hnd_iphlpapi, "GetBestRoute2");
if (!ares_fpGetBestRoute2)
{
/* This can happen on clients before Vista, I don't
think it should be an error, unless we don't want to
support Windows XP anymore */
}
/*
* When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
* also known as RtlGenRandom, which is the case for Windows versions prior
......
......@@ -28,13 +28,14 @@
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
typedef NETIO_STATUS (WINAPI *fpGetBestRoute2_t) ( NET_LUID *, NET_IFINDEX, const SOCKADDR_INET *, const SOCKADDR_INET *, ULONG, PMIB_IPFORWARD_ROW2, SOCKADDR_INET * );
/* Forward-declaration of variables defined in ares_library_init.c */
/* that are global and unique instances for whole c-ares library. */
extern fpGetNetworkParams_t ares_fpGetNetworkParams;
extern fpSystemFunction036_t ares_fpSystemFunction036;
extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
extern fpGetBestRoute2_t ares_fpGetBestRoute2;
#endif /* USE_WINSOCK */
......
.\"
.\" Copyright (C) 2016 by Daniel Stenberg
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_LIBRARY_INITIALIZED 3 "29 Sep 2016"
.SH NAME
ares_library_initialized \- get the initialization state
.SH SYNOPSIS
.nf
#include <ares.h>
int ares_library_initialized(void)
.fi
.SH DESCRIPTION
Returns information if c-ares needs to get initialized.
.SH RETURN VALUE
\fIARES_ENOTINITIALIZED\fP if not initialized and \fIARES_SUCCESS\fP if no
initialization is needed.
.SH AVAILABILITY
This function was first introduced in c-ares version 1.11.0
.SH SEE ALSO
.BR ares_library_init(3),
.BR ares_library_cleanup(3)
......@@ -151,10 +151,10 @@ int aresx_sltosi(long slnum)
}
/*
** signed ssize_t to signed int
** signed ares_ssize_t to signed int
*/
int aresx_sztosi(ssize_t sznum)
int aresx_sztosi(ares_ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
......@@ -162,7 +162,7 @@ int aresx_sztosi(ssize_t sznum)
#endif
DEBUGASSERT(sznum >= 0);
return (int)(sznum & (ssize_t) CARES_MASK_SINT);
return (int)(sznum & (ares_ssize_t) CARES_MASK_SINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
......@@ -170,10 +170,10 @@ int aresx_sztosi(ssize_t sznum)
}
/*
** signed ssize_t to unsigned int
** signed ares_ssize_t to unsigned int
*/
unsigned int aresx_sztoui(ssize_t sznum)
unsigned int aresx_sztoui(ares_ssize_t sznum)
{
#ifdef __INTEL_COMPILER
# pragma warning(push)
......@@ -181,7 +181,7 @@ unsigned int aresx_sztoui(ssize_t sznum)
#endif
DEBUGASSERT(sznum >= 0);
return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT);
return (unsigned int)(sznum & (ares_ssize_t) CARES_MASK_UINT);
#ifdef __INTEL_COMPILER
# pragma warning(pop)
......
......@@ -25,9 +25,9 @@ short aresx_sitoss(int sinum);
int aresx_sltosi(long slnum);
int aresx_sztosi(ssize_t sznum);
int aresx_sztosi(ares_ssize_t sznum);
unsigned int aresx_sztoui(ssize_t sznum);
unsigned int aresx_sztoui(ares_ssize_t sznum);
unsigned short aresx_sitous(int sinum);
......
......@@ -110,6 +110,12 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
status = ARES_EBADRESP;
break;
}
/* RR must contain at least 7 bytes = 2 x int16 + 3 x name */
if (rr_len < 7)
{
status = ARES_EBADRESP;
break;
}
/* Check if we are really looking at a NAPTR record */
if (rr_class == C_IN && rr_type == T_NAPTR)
......@@ -185,4 +191,3 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
return ARES_SUCCESS;
}
......@@ -54,10 +54,16 @@
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
#define NAMESERVER "NameServer"
#define DHCPNAMESERVER "DhcpNameServer"
#define DATABASEPATH "DatabasePath"
#define WIN_PATH_HOSTS "\\hosts"
#define SEARCHLIST_KEY "SearchList"
#define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix"
#define INTERFACES_KEY "Interfaces"
#define DOMAIN_KEY "Domain"
#define DHCPDOMAIN_KEY "DhcpDomain"
#elif defined(WATT32)
......@@ -314,6 +320,9 @@ struct ares_channeldata {
ares_sock_config_callback sock_config_cb;
void *sock_config_cb_data;
const struct ares_socket_functions * sock_funcs;
void *sock_func_cb_data;
};
/* Memory management functions */
......@@ -342,6 +351,8 @@ void ares__destroy_servers_state(ares_channel channel);
long ares__tvdiff(struct timeval t1, struct timeval t2);
#endif
void ares__socket_close(ares_channel, ares_socket_t);
#define ARES_SWAP_BYTE(a,b) \
{ unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; }
......
......@@ -18,15 +18,15 @@
ares_process \- Process events for name resolution
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP,
.B fd_set *\fIwrite_fds\fP)
.fi
.PP
.B void ares_process_fd(ares_channel \fIchannel\fP,
.B ares_socket_t \fIread_fd\fP,
.B ares_socket_t \fIwrite_fd\fP)
#include <ares.h>
void ares_process(ares_channel \fIchannel\fP,
fd_set *\fIread_fds\fP,
fd_set *\fIwrite_fds\fP)
void ares_process_fd(ares_channel \fIchannel\fP,
ares_socket_t \fIread_fd\fP,
ares_socket_t \fIwrite_fd\fP)
.fi
.SH DESCRIPTION
The \fBares_process(3)\fP function handles input/output events and timeouts
......@@ -35,42 +35,36 @@ associated with queries pending on the name service channel identified by
The file descriptor sets pointed to by \fIread_fds\fP and \fIwrite_fds\fP
should have file descriptors set in them according to whether the file
descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
(The easiest way to determine this information is to invoke
.B select
with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ).
.PP
The
.B ares_process
function will invoke callbacks for pending queries if they complete
successfully or fail.
(The easiest way to determine this information is to invoke \fBselect(3)\fP
with a timeout no greater than the timeout given by \fIares_timeout(3)\fP).
The \fBares_process(3)\fP function will invoke callbacks for pending queries
if they complete successfully or fail.
\fBares_process_fd(3)\fP works the same way but acts and operates only on the
specific file descriptors (sockets) you pass in to the function. Use
ARES_SOCKET_BAD for "no action". This function is of course provided to allow
users of c-ares to void select() in their applications and within c-ares.
.SS EXAMPLE
ARES_SOCKET_BAD for "no action". This function is provided to allow users of
c-ares to void \fIselect(3)\fP in their applications and within c-ares.
.SH EXAMPLE
The following code fragment waits for all pending queries on a channel
to complete:
.PP
.RS
.nf
int nfds, count;
fd_set readers, writers;
struct timeval tv, *tvp;
while (1)
{
FD_ZERO(&readers);
FD_ZERO(&writers);
nfds = ares_fds(channel, &readers, &writers);
if (nfds == 0)
break;
tvp = ares_timeout(channel, NULL, &tv);
count = select(nfds, &readers, &writers, NULL, tvp);
ares_process(channel, &readers, &writers);
}
while (1) {
FD_ZERO(&readers);
FD_ZERO(&writers);
nfds = ares_fds(channel, &readers, &writers);
if (nfds == 0)
break;
tvp = ares_timeout(channel, NULL, &tv);
count = select(nfds, &readers, &writers, NULL, tvp);
ares_process(channel, &readers, &writers);
}
.fi
.RE
.SH SEE ALSO
.BR ares_fds (3),
.BR ares_timeout (3)
......
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2004-2016 by Daniel Stenberg
* Copyright (C) 2004-2017 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
......@@ -29,6 +29,9 @@
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#else
......@@ -65,7 +68,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
static void read_udp_packets(ares_channel channel, fd_set *read_fds,
ares_socket_t read_fd, struct timeval *now);
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
ssize_t num_bytes);
ares_ssize_t num_bytes);
static void process_timeouts(ares_channel channel, struct timeval *now);
static void process_broken_connections(ares_channel channel,
struct timeval *now);
......@@ -175,6 +178,26 @@ static int try_again(int errnum)
return 0;
}
static ares_ssize_t socket_writev(ares_channel channel, ares_socket_t s, const struct iovec * vec, int len)
{
if (channel->sock_funcs)
return channel->sock_funcs->asendv(s, vec, len, channel->sock_func_cb_data);
return writev(s, vec, len);
}
static ares_ssize_t socket_write(ares_channel channel, ares_socket_t s, const void * data, size_t len)
{
if (channel->sock_funcs)
{
struct iovec vec;
vec.iov_base = (void*)data;
vec.iov_len = len;
return channel->sock_funcs->asendv(s, &vec, 1, channel->sock_func_cb_data);
}
return swrite(s, data, len);
}
/* If any TCP sockets select true for writing, write out queued data
* we have for them.
*/
......@@ -187,8 +210,8 @@ static void write_tcp_data(ares_channel channel,
struct send_request *sendreq;
struct iovec *vec;
int i;
ssize_t scount;
ssize_t wcount;
ares_ssize_t scount;
ares_ssize_t wcount;
size_t n;
if(!write_fds && (write_fd == ARES_SOCKET_BAD))
......@@ -238,7 +261,7 @@ static void write_tcp_data(ares_channel channel,
vec[n].iov_len = sendreq->len;
n++;
}
wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
wcount = socket_writev(channel, server->tcp_socket, vec, (int)n);
ares_free(vec);
if (wcount < 0)
{
......@@ -255,7 +278,7 @@ static void write_tcp_data(ares_channel channel,
/* Can't allocate iovecs; just send the first request. */
sendreq = server->qhead;
scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
scount = socket_write(channel, server->tcp_socket, sendreq->data, sendreq->len);
if (scount < 0)
{
if (!try_again(SOCKERRNO))
......@@ -271,7 +294,7 @@ static void write_tcp_data(ares_channel channel,
/* Consume the given number of bytes from the head of the TCP send queue. */
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
ssize_t num_bytes)
ares_ssize_t num_bytes)
{
struct send_request *sendreq;
struct server_state *server = &channel->servers[whichserver];
......@@ -299,6 +322,38 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
}
}
static ares_ssize_t socket_recvfrom(ares_channel channel,
ares_socket_t s,
void * data,
size_t data_len,
int flags,
struct sockaddr *from,
ares_socklen_t *from_len)
{
if (channel->sock_funcs)
return channel->sock_funcs->arecvfrom(s, data, data_len,
flags, from, from_len,
channel->sock_func_cb_data);
#ifdef HAVE_RECVFROM
return recvfrom(s, data, data_len, flags, from, from_len);
#else
return sread(s, data, data_len);
#endif
}
static ares_ssize_t socket_recv(ares_channel channel,
ares_socket_t s,
void * data,
size_t data_len)
{
if (channel->sock_funcs)
return channel->sock_funcs->arecvfrom(s, data, data_len, 0, 0, 0,
channel->sock_func_cb_data);
return sread(s, data, data_len);
}
/* If any TCP socket selects true for reading, read some data,
* allocate a buffer if we finish reading the length word, and process
* a packet if we finish reading one.
......@@ -308,7 +363,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
{
struct server_state *server;
int i;
ssize_t count;
ares_ssize_t count;
if(!read_fds && (read_fd == ARES_SOCKET_BAD))
/* no possible action */
......@@ -343,9 +398,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
/* We haven't yet read a length word, so read that (or
* what's left to read of it).
*/
count = sread(server->tcp_socket,
server->tcp_lenbuf + server->tcp_lenbuf_pos,
2 - server->tcp_lenbuf_pos);
count = socket_recv(channel, server->tcp_socket,
server->tcp_lenbuf + server->tcp_lenbuf_pos,
2 - server->tcp_lenbuf_pos);
if (count <= 0)
{
if (!(count == -1 && try_again(SOCKERRNO)))
......@@ -373,9 +428,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
else
{
/* Read data into the allocated buffer. */
count = sread(server->tcp_socket,
server->tcp_buffer + server->tcp_buffer_pos,
server->tcp_length - server->tcp_buffer_pos);
count = socket_recv(channel, server->tcp_socket,
server->tcp_buffer + server->tcp_buffer_pos,
server->tcp_length - server->tcp_buffer_pos);
if (count <= 0)
{
if (!(count == -1 && try_again(SOCKERRNO)))
......@@ -406,7 +461,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
{
struct server_state *server;
int i;
ssize_t count;
ares_ssize_t count;
unsigned char buf[MAXENDSSZ + 1];
#ifdef HAVE_RECVFROM
ares_socklen_t fromlen;
......@@ -453,16 +508,12 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
count = 0;
else {
#ifdef HAVE_RECVFROM
if (server->addr.family == AF_INET)
fromlen = sizeof(from.sa4);
else
fromlen = sizeof(from.sa6);
count = (ssize_t)recvfrom(server->udp_socket, (void *)buf,
sizeof(buf), 0, &from.sa, &fromlen);
#else
count = sread(server->udp_socket, buf, sizeof(buf));
#endif
count = socket_recvfrom(channel, server->udp_socket, (void *)buf,
sizeof(buf), 0, &from.sa, &fromlen);
}
if (count == -1 && try_again(SOCKERRNO))
......@@ -812,7 +863,7 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
if (socket_write(channel, server->udp_socket, query->qbuf, query->qlen) == -1)
{
/* FIXME: Handle EAGAIN here since it likely can happen. */
skip_server(channel, query, query->server);
......@@ -904,6 +955,10 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel)
struct sockaddr_in6 sa6;
} local;
/* do not set options for user-managed sockets */
if (channel->sock_funcs)
return 0;
(void)setsocknonblock(s, TRUE);
#if defined(FD_CLOEXEC) && !defined(MSDOS)
......@@ -959,6 +1014,30 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel)
return 0;
}
static ares_socket_t open_socket(ares_channel channel, int af, int type, int protocol)
{
if (channel->sock_funcs != 0)
return channel->sock_funcs->asocket(af,
type,
protocol,
channel->sock_func_cb_data);
return socket(af, type, protocol);
}
static int connect_socket(ares_channel channel, ares_socket_t sockfd,
const struct sockaddr * addr,
ares_socklen_t addrlen)
{
if (channel->sock_funcs != 0)
return channel->sock_funcs->aconnect(sockfd,
addr,
addrlen,
channel->sock_func_cb_data);
return connect(sockfd, addr, addrlen);
}
static int open_tcp_socket(ares_channel channel, struct server_state *server)
{
ares_socket_t s;
......@@ -1003,14 +1082,14 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
s = socket(server->addr.family, SOCK_STREAM, 0);
s = open_socket(channel, server->addr.family, SOCK_STREAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Configure it. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
sclose(s);
ares__socket_close(channel, s);
return -1;
}
......@@ -1022,10 +1101,12 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
* so batching isn't very interesting.
*/
opt = 1;
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
(void *)&opt, sizeof(opt)) == -1)
if (channel->sock_funcs == 0
&&
setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
(void *)&opt, sizeof(opt)) == -1)
{
sclose(s);
ares__socket_close(channel, s);
return -1;
}
#endif
......@@ -1036,19 +1117,19 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
sclose(s);
ares__socket_close(channel, s);
return err;
}
}
/* Connect to the server. */
if (connect(s, sa, salen) == -1)
if (connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
sclose(s);
ares__socket_close(channel, s);
return -1;
}
}
......@@ -1059,7 +1140,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
sclose(s);
ares__socket_close(channel, s);
return err;
}
}
......@@ -1114,14 +1195,14 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
}
/* Acquire a socket. */
s = socket(server->addr.family, SOCK_DGRAM, 0);
s = open_socket(channel, server->addr.family, SOCK_DGRAM, 0);
if (s == ARES_SOCKET_BAD)
return -1;
/* Set the socket non-blocking. */
if (configure_socket(s, server->addr.family, channel) < 0)
{
sclose(s);
ares__socket_close(channel, s);
return -1;
}
......@@ -1131,19 +1212,19 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_config_cb_data);
if (err < 0)
{
sclose(s);
ares__socket_close(channel, s);
return err;
}
}
/* Connect to the server. */
if (connect(s, sa, salen) == -1)
if (connect_socket(channel, s, sa, salen) == -1)
{
int err = SOCKERRNO;
if (err != EINPROGRESS && err != EWOULDBLOCK)
{
sclose(s);
ares__socket_close(channel, s);
return -1;
}
}
......@@ -1154,7 +1235,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
channel->sock_create_cb_data);
if (err < 0)
{
sclose(s);
ares__socket_close(channel, s);
return err;
}
}
......@@ -1357,3 +1438,11 @@ void ares__free_query(struct query *query)
ares_free(query->server_info);
ares_free(query);
}
void ares__socket_close(ares_channel channel, ares_socket_t s)
{
if (channel->sock_funcs)
channel->sock_funcs->aclose(s, channel->sock_func_cb_data);
else
sclose(s);
}
......@@ -31,8 +31,8 @@ for the option to work. If SO_BINDTODEVICE is not supported or the
setsocktop call fails (probably because of permissions), the error is
silently ignored.
.SH SEE ALSO
.BR ares_set_local_ipv4 (3)
.BR ares_set_local_ipv6 (3)
.BR ares_set_local_ip4 (3)
.BR ares_set_local_ip6 (3)
.SH NOTES
This function was added in c-ares 1.7.4
.SH AUTHOR
......
......@@ -18,43 +18,28 @@
ares_timeout \- return maximum time to wait
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B struct timeval *ares_timeout(ares_channel \fIchannel\fP,
.B struct timeval *\fImaxtv\fP, struct timeval *\fItv\fP)
#include <ares.h>
struct timeval *ares_timeout(ares_channel \fIchannel\fP,
struct timeval *\fImaxtv\fP,
struct timeval *\fItv\fP)
.fi
.SH DESCRIPTION
The
.B ares_timeout
function determines the maximum time for which the caller should wait before
invoking \fIares_process(3)\fP to process timeouts. The parameter
.I maxtv
specifies a existing maximum timeout, or
.B NULL
The \fBares_timeout(3)\fP function determines the maximum time for which the
caller should wait before invoking \fIares_process(3)\fP to process timeouts.
The parameter \fImaxtv\fP specifies a existing maximum timeout, or \fBNULL\fP
if the caller does not wish to apply a maximum timeout. The parameter
.I tv
must point to a writable buffer of type
.BR "struct timeval" .
It is valid for
.I maxtv
and
.I tv
to have the same value.
.PP
If no queries have timeouts pending sooner than the given maximum
timeout,
.B ares_timeout
returns the value of
.IR maxtv;
otherwise
.B ares_timeout
stores the appropriate timeout value into the buffer pointed to by
.I tv
and returns the value of
.IR tv .
\fItv\fP must point to a writable buffer of type \fBstruct timeval\fP It is
valid for \fImaxtv\fP and \fItv\fP to have the same value.
If no queries have timeouts pending sooner than the given maximum timeout,
\fBares_timeout(3)\fP returns the value of \fImaxtv\fP; otherwise
\fBares_timeout(3)\fP stores the appropriate timeout value into the buffer
pointed to by \fItv\fP and returns the value of \fItv\fP.
.SH SEE ALSO
.BR ares_fds (3),
.BR ares_process (3)
.BR ares_process (3),
.BR ares_process_fd (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
......
......@@ -18,23 +18,18 @@
ares_version \- Get the version number of the library
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B const char *ares_version(int *\fIversion\fP)
#include <ares.h>
const char *ares_version(int *\fIversion\fP)
.fi
.SH DESCRIPTION
The
.B ares_version
function gets the library version as a string and optionally as an integer
stored in the
.IR version ,
argument. If you pass a NULL, no integer is attempted to be returned.
The \fBares_version(3)\fP function gets the library version as a string and
optionally as an integer stored in the \fIversion\fP argument. If you pass a
NULL, no integer is attempted to be returned.
The integer is built up as 24bit number, with 8 separate bits used for major
number, minor number and patch number. This makes a version string such as
1.2.3 will be returned as the hexadecimal number 0x010203 (decimal 66051).
.SH NOTES
This function is not compatible with ares.
.SH AUTHOR
Daniel Stenberg
.SH "SEE ALSO"
.BR ares_init (3),
.BR ares_library_init (3)
......@@ -6,12 +6,12 @@
#define ARES_COPYRIGHT "2004 - 2016 Daniel Stenberg, <daniel@haxx.se>."
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 12
#define ARES_VERSION_MINOR 13
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.12.0"
#define ARES_VERSION_STR "1.13.0"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
......
......@@ -25,12 +25,12 @@
#include "ares_private.h"
#ifndef HAVE_WRITEV
ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt)
{
char *buffer, *bp;
int i;
size_t bytes = 0;
ssize_t result;
ares_ssize_t result;
/* Validate iovcnt */
if (iovcnt <= 0)
......
......@@ -29,7 +29,7 @@ struct iovec
size_t iov_len; /* Length of data. */
};
extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt);
extern ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt);
#endif
......
......@@ -60,11 +60,6 @@
#define BSD
#if defined(__HIGHC__) || \
(defined(__GNUC__) && (__GNUC__ < 4))
#define ssize_t int
#endif
/* Target HAVE_x section */
#if defined(DJGPP)
......
......@@ -216,20 +216,6 @@
#define HAVE_BOOL_T
#endif
/* Define if ssize_t is not an available 'typedefed' type. */
#ifndef _SSIZE_T_DEFINED
# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
defined(__POCC__) || \
defined(__MINGW32__)
# elif defined(_WIN64)
# define _SSIZE_T_DEFINED
# define ssize_t __int64
# else
# define _SSIZE_T_DEFINED
# define ssize_t int
# endif
#endif
/* ---------------------------------------------------------------- */
/* TYPE SIZES */
/* ---------------------------------------------------------------- */
......@@ -259,31 +245,19 @@
# define _CRT_NONSTDC_NO_DEPRECATE 1
#endif
/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
2000 as a supported build target. VS2008 default installations provide
an embedded Windows SDK v6.0A along with the claim that Windows 2000 is
a valid build target for VS2008. Popular belief is that binaries built
with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build
target are functional. */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
# define VS2008_MIN_TARGET 0x0500
#endif
/* When no build target is specified VS2008 default build target is Windows
Vista, which leaves out even Winsows XP. If no build target has been given
for VS2008 we will target the minimum Officially supported build target,
which happens to be Windows XP. */
/* Set the Target to Vista. However, any symbols required above Win2000
* should be loaded via LoadLibrary() */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
# define VS2008_DEF_TARGET 0x0501
# define VS2008_MIN_TARGET 0x0600
#endif
/* VS2008 default target settings and minimum build target check. */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
# ifndef _WIN32_WINNT
# define _WIN32_WINNT VS2008_DEF_TARGET
# define _WIN32_WINNT VS2008_MIN_TARGET
# endif
# ifndef WINVER
# define WINVER VS2008_DEF_TARGET
# define WINVER VS2008_MIN_TARGET
# endif
# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
# error VS2008 does not support Windows build targets prior to Windows 2000
......@@ -291,13 +265,13 @@
#endif
/* When no build target is specified Pelles C 5.00 and later default build
target is Windows Vista. We override default target to be Windows 2000. */
target is Windows Vista. */
#if defined(__POCC__) && (__POCC__ >= 500)
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0500
# define _WIN32_WINNT 0x0600
# endif
# ifndef WINVER
# define WINVER 0x0500
# define WINVER 0x0600
# endif
#endif
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for c-ares 1.12.0.
# Generated by GNU Autoconf 2.69 for c-ares 1.13.0.
#
# Report bugs to <c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares>.
#
......@@ -824,8 +824,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='c-ares'
PACKAGE_TARNAME='c-ares'
PACKAGE_VERSION='1.12.0'
PACKAGE_STRING='c-ares 1.12.0'
PACKAGE_VERSION='1.13.0'
PACKAGE_STRING='c-ares 1.13.0'
PACKAGE_BUGREPORT='c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares'
PACKAGE_URL=''
......@@ -1619,7 +1619,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures c-ares 1.12.0 to adapt to many kinds of systems.
\`configure' configures c-ares 1.13.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1690,7 +1690,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of c-ares 1.12.0:";;
short | recursive ) echo "Configuration of c-ares 1.13.0:";;
esac
cat <<\_ACEOF
......@@ -1831,7 +1831,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
c-ares configure 1.12.0
c-ares configure 1.13.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
......@@ -2412,7 +2412,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by c-ares $as_me 1.12.0, which was
It was created by c-ares $as_me 1.13.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
......@@ -3202,7 +3202,8 @@ if test -z "$EGREP" || test "$EGREP" = "not_found"; then
fi
if test -n "$ac_tool_prefix"; then
if test -z "$AR"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
......@@ -3302,8 +3303,9 @@ else
AR="$ac_cv_path_AR"
fi
if test -z "$AR" || test "$AR" = "not_found"; then
as_fn_error $? "ar not found in PATH. Cannot continue without ar." "$LINENO" 5
if test -z "$AR" || test "$AR" = "not_found"; then
as_fn_error $? "ar not found in PATH. Cannot continue without ar." "$LINENO" 5
fi
fi
......@@ -5944,7 +5946,7 @@ fi
# Define the identity of the package.
PACKAGE='c-ares'
VERSION='1.12.0'
VERSION='1.13.0'
cat >>confdefs.h <<_ACEOF
......@@ -22107,6 +22109,7 @@ _ACEOF
;;
esac
CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
;;
*)
ac_cv_header_winsock_h="no"
......@@ -22904,7 +22907,91 @@ $as_echo "$tst_connect_need_LIBS" >&6; }
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
if test "x$host_vendor" = "xapple"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iOS minimum version 10 or later" >&5
$as_echo_n "checking for iOS minimum version 10 or later... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
#include <TargetConditionals.h>
int main (void)
{
#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
#error Not iOS 10 or later
#endif
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ac_cv_ios_10="yes"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x$host_vendor" = "xapple"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for macOS minimum version 10.12 or later" >&5
$as_echo_n "checking for macOS minimum version 10.12 or later... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
#include <TargetConditionals.h>
int main (void)
{
#ifndef MAC_OS_X_VERSION_10_12
# define MAC_OS_X_VERSION_10_12 101200
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
#error Not macOS 10.12 or later
#endif
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ac_cv_macos_10_12="yes"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x$host_vendor" != "xapple" || test "x$ac_cv_ios_10" = "xyes" || test "x$ac_cv_macos_10_12" = "xyes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
if ${ac_cv_header_time+:} false; then :
$as_echo_n "(cached) " >&6
......@@ -23160,6 +23247,7 @@ _ACEOF
fi
#
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libgcc" >&5
$as_echo_n "checking whether to use libgcc... " >&6; }
......@@ -23794,12 +23882,17 @@ fi
# check for ssize_t
ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
if test "x$ac_cv_type_ssize_t" = xyes; then :
CARES_TYPEOF_ARES_SSIZE_T=ssize_t
else
CARES_TYPEOF_ARES_SSIZE_T=int
fi
$as_echo "#define ssize_t int" >>confdefs.h
fi
cat >>confdefs.h <<_ACEOF
#define CARES_TYPEOF_ARES_SSIZE_T ${CARES_TYPEOF_ARES_SSIZE_T}
_ACEOF
# check for bool type
......@@ -32470,7 +32563,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by c-ares $as_me 1.12.0, which was
This file was extended by c-ares $as_me 1.13.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -32536,7 +32629,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
c-ares config.status 1.12.0
c-ares config.status 1.13.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
......
AC_PREREQ(2.57)
dnl Version not hardcoded here. Fetched later from ares_version.h
AC_INIT([c-ares], [1.12.0],
AC_INIT([c-ares], [1.13.0],
[c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares])
XC_OVR_ZZ50
......@@ -59,10 +59,13 @@ AC_SUBST([EGREP])
dnl AR is mandatory for configure process and libtool.
dnl This is target dependent, so check it as a tool.
AC_PATH_TOOL([AR], [ar], [not_found],
[$PATH:/usr/bin:/usr/local/bin])
if test -z "$AR" || test "$AR" = "not_found"; then
AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.])
if test -z "$AR"; then
dnl allow it to be overridden
AC_PATH_TOOL([AR], [ar], [not_found],
[$PATH:/usr/bin:/usr/local/bin])
if test -z "$AR" || test "$AR" = "not_found"; then
AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.])
fi
fi
AC_SUBST([AR])
......@@ -194,6 +197,7 @@ case X-"$ac_cv_native_windows" in
CURL_CHECK_HEADER_WINSOCK
CURL_CHECK_HEADER_WINSOCK2
CURL_CHECK_HEADER_WS2TCPIP
CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
;;
*)
ac_cv_header_winsock_h="no"
......@@ -388,11 +392,62 @@ ac_cv_func_strcasecmp="no"
CARES_CHECK_LIBS_CONNECT
dnl iOS 10?
AS_IF([test "x$host_vendor" = "xapple"], [
AC_MSG_CHECKING([for iOS minimum version 10 or later])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <stdio.h>
#include <TargetConditionals.h>
]], [[
#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000
#error Not iOS 10 or later
#endif
return 0;
]])
],[
AC_MSG_RESULT([yes])
ac_cv_ios_10="yes"
],[
AC_MSG_RESULT([no])
])
])
dnl macOS 10.12?
AS_IF([test "x$host_vendor" = "xapple"], [
AC_MSG_CHECKING([for macOS minimum version 10.12 or later])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <stdio.h>
#include <TargetConditionals.h>
]], [[
#ifndef MAC_OS_X_VERSION_10_12
# define MAC_OS_X_VERSION_10_12 101200
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
#error Not macOS 10.12 or later
#endif
return 0;
]])
],[
AC_MSG_RESULT([yes])
ac_cv_macos_10_12="yes"
],[
AC_MSG_RESULT([no])
])
])
dnl **********************************************************************
dnl In case that function clock_gettime with monotonic timer is available,
dnl check for additional required libraries.
dnl **********************************************************************
CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC
dnl Xcode 8 bug: iOS when targeting less than 10, or macOS when targeting less than 10.12 will
dnl say clock_gettime exists, it is a weak symbol that only exists in iOS 10 or macOS 10.12 and will
dnl cause a crash at runtime when running on older versions. Skip finding CLOCK_MONOTONIC on older
dnl Apple OS's.
if test "x$host_vendor" != "xapple" || test "x$ac_cv_ios_10" = "xyes" || test "x$ac_cv_macos_10_12" = "xyes"; then
CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC
fi
AC_MSG_CHECKING([whether to use libgcc])
AC_ARG_ENABLE(libgcc,
......@@ -505,8 +560,12 @@ fi
# check for ssize_t
AC_CHECK_TYPE(ssize_t, ,
AC_DEFINE(ssize_t, int, [the signed version of size_t]))
AC_CHECK_TYPE(ssize_t, [ CARES_TYPEOF_ARES_SSIZE_T=ssize_t ],
[ CARES_TYPEOF_ARES_SSIZE_T=int ])
AC_DEFINE_UNQUOTED([CARES_TYPEOF_ARES_SSIZE_T], ${CARES_TYPEOF_ARES_SSIZE_T},
[the signed version of size_t])
# check for bool type
AC_CHECK_TYPE([bool],[
......
......@@ -357,8 +357,8 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const ssize_t n = tp - colonp;
ssize_t i;
const ares_ssize_t n = tp - colonp;
ares_ssize_t i;
if (tp == endp)
goto enoent;
......
......@@ -131,7 +131,7 @@ struct timeval {
#if defined(__minix)
/* Minix doesn't support recv on TCP sockets */
#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
#define sread(x,y,z) (ares_ssize_t)read((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z))
......@@ -167,7 +167,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_recv
/* */
#else
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
#define sread(x,y,z) (ares_ssize_t)recv((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z), \
(RECV_TYPE_ARG4)(0))
......@@ -183,7 +183,7 @@ struct timeval {
#if defined(__minix)
/* Minix doesn't support send on TCP sockets */
#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
#define swrite(x,y,z) (ares_ssize_t)write((SEND_TYPE_ARG1)(x), \
(SEND_TYPE_ARG2)(y), \
(SEND_TYPE_ARG3)(z))
......@@ -198,7 +198,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_send
/* */
#else
#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
#define swrite(x,y,z) (ares_ssize_t)send((SEND_TYPE_ARG1)(x), \
(SEND_TYPE_ARG2)(y), \
(SEND_TYPE_ARG3)(z), \
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
......@@ -228,7 +228,7 @@ struct timeval {
Error Missing_definition_of_return_and_arguments_types_of_recvfrom
/* */
#else
#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
#define sreadfrom(s,b,bl,f,fl) (ares_ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
(RECVFROM_TYPE_ARG2 *)(b), \
(RECVFROM_TYPE_ARG3) (bl), \
(RECVFROM_TYPE_ARG4) (0), \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment