summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile.am8
-rw-r--r--src/lib/Makefile.in220
-rw-r--r--src/lib/Makefile.inc6
-rw-r--r--src/lib/ares__addrinfo2hostent.c266
-rw-r--r--src/lib/ares__addrinfo_localhost.c240
-rw-r--r--src/lib/ares__parse_into_addrinfo.c143
-rw-r--r--src/lib/ares__readaddrinfo.c73
-rw-r--r--src/lib/ares__sortaddrinfo.c20
-rw-r--r--src/lib/ares_config.h.cmake4
-rw-r--r--src/lib/ares_config.h.in21
-rw-r--r--src/lib/ares_create_query.c17
-rw-r--r--src/lib/ares_data.c16
-rw-r--r--src/lib/ares_data.h2
-rw-r--r--src/lib/ares_expand_name.c146
-rw-r--r--src/lib/ares_expand_string.c7
-rw-r--r--src/lib/ares_free_hostent.c10
-rw-r--r--src/lib/ares_freeaddrinfo.c3
-rw-r--r--src/lib/ares_getaddrinfo.c175
-rw-r--r--src/lib/ares_gethostbyaddr.c10
-rw-r--r--src/lib/ares_gethostbyname.c466
-rw-r--r--src/lib/ares_getnameinfo.c10
-rw-r--r--src/lib/ares_init.c88
-rw-r--r--src/lib/ares_library_init.c9
-rw-r--r--src/lib/ares_library_init.h2
-rw-r--r--src/lib/ares_parse_a_reply.c175
-rw-r--r--src/lib/ares_parse_aaaa_reply.c174
-rw-r--r--src/lib/ares_parse_caa_reply.c14
-rw-r--r--src/lib/ares_parse_mx_reply.c10
-rw-r--r--src/lib/ares_parse_naptr_reply.c21
-rw-r--r--src/lib/ares_parse_ns_reply.c16
-rw-r--r--src/lib/ares_parse_ptr_reply.c99
-rw-r--r--src/lib/ares_parse_soa_reply.c24
-rw-r--r--src/lib/ares_parse_srv_reply.c15
-rw-r--r--src/lib/ares_parse_txt_reply.c10
-rw-r--r--src/lib/ares_parse_uri_reply.c184
-rw-r--r--src/lib/ares_private.h30
-rw-r--r--src/lib/ares_process.c11
-rw-r--r--src/lib/ares_query.c10
-rw-r--r--src/lib/ares_send.c10
-rw-r--r--src/lib/ares_setup.h5
-rw-r--r--src/lib/ares_strdup.c31
-rw-r--r--src/lib/ares_strsplit.c4
-rw-r--r--src/lib/cares.rc6
-rw-r--r--src/lib/inet_net_pton.c10
-rw-r--r--src/lib/inet_ntop.c10
-rw-r--r--src/lib/nameser.h218
46 files changed, 1653 insertions, 1396 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index c918667..4813621 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -8,7 +8,8 @@ ACLOCAL_AMFLAGS = -I m4 --install
AM_CPPFLAGS = -I$(top_builddir)/include \
-I$(top_builddir)/src/lib \
- -I$(top_srcdir)/include
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/lib
lib_LTLIBRARIES = libcares.la
@@ -58,9 +59,10 @@ libcares_la_CFLAGS_EXTRA += $(CFLAG_CARES_SYMBOL_HIDING)
libcares_la_CPPFLAGS_EXTRA += -DCARES_SYMBOL_HIDING
endif
-@CODE_COVERAGE_RULES@
-libcares_la_LDFLAGS += $(CODE_COVERAGE_LDFLAGS)
+include $(top_srcdir)/aminclude_static.am
+libcares_la_LIBS = $(CODE_COVERAGE_LIBS)
libcares_la_CFLAGS_EXTRA += $(CODE_COVERAGE_CFLAGS)
+libcares_la_CPPFLAGS_EXTRA += $(CODE_COVERAGE_CPPFLAGS)
libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA)
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 6ef01f4..6b42bb8 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,6 +14,9 @@
@SET_MAKE@
+# aminclude_static.am generated automatically by Autoconf
+# from AX_AM_MACROS_STATIC on Wed Oct 27 08:01:08 CEST 2021
+
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
@@ -97,12 +100,18 @@ host_triplet = @host@
subdir = src/lib
SUBDIRS =
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_ac_append_to_file.m4 \
+ $(top_srcdir)/m4/ax_ac_print_to_file.m4 \
+ $(top_srcdir)/m4/ax_add_am_macro_static.m4 \
+ $(top_srcdir)/m4/ax_am_macros_static.m4 \
+ $(top_srcdir)/m4/ax_check_gnu_make.m4 \
+ $(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
+ $(top_srcdir)/m4/ax_file_escapes.m4 \
+ $(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/cares-compilers.m4 \
$(top_srcdir)/m4/cares-confopts.m4 \
$(top_srcdir)/m4/cares-functions.m4 \
- $(top_srcdir)/m4/cares-override.m4 \
$(top_srcdir)/m4/cares-reentrant.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -112,9 +121,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/xc-lt-iface.m4 \
$(top_srcdir)/m4/xc-translit.m4 \
$(top_srcdir)/m4/xc-val-flgs.m4 \
- $(top_srcdir)/m4/zz40-xc-ovr.m4 \
- $(top_srcdir)/m4/zz50-xc-ovr.m4 \
- $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/m4/zz40-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -153,7 +160,9 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libcares_la_LIBADD =
-am__objects_1 = libcares_la-ares__close_sockets.lo \
+am__objects_1 = libcares_la-ares__addrinfo2hostent.lo \
+ libcares_la-ares__addrinfo_localhost.lo \
+ libcares_la-ares__close_sockets.lo \
libcares_la-ares__get_hostent.lo \
libcares_la-ares__parse_into_addrinfo.lo \
libcares_la-ares__readaddrinfo.lo \
@@ -183,6 +192,7 @@ am__objects_1 = libcares_la-ares__close_sockets.lo \
libcares_la-ares_parse_soa_reply.lo \
libcares_la-ares_parse_srv_reply.lo \
libcares_la-ares_parse_txt_reply.lo \
+ libcares_la-ares_parse_uri_reply.lo \
libcares_la-ares_platform.lo libcares_la-ares_process.lo \
libcares_la-ares_query.lo libcares_la-ares_search.lo \
libcares_la-ares_send.lo libcares_la-ares_strcasecmp.lo \
@@ -216,7 +226,10 @@ am__v_at_1 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
-am__depfiles_remade = ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo \
+am__depfiles_remade = \
+ ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo \
+ ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo \
+ ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo \
./$(DEPDIR)/libcares_la-ares__get_hostent.Plo \
./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo \
./$(DEPDIR)/libcares_la-ares__read_line.Plo \
@@ -256,6 +269,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo \
./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo \
./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo \
./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo \
+ ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo \
./$(DEPDIR)/libcares_la-ares_platform.Plo \
./$(DEPDIR)/libcares_la-ares_process.Plo \
./$(DEPDIR)/libcares_la-ares_query.Plo \
@@ -332,10 +346,9 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \
- $(srcdir)/ares_config.h.in $(top_srcdir)/depcomp
+ $(srcdir)/ares_config.h.in $(top_srcdir)/aminclude_static.am \
+ $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -374,6 +387,7 @@ AWK = @AWK@
BUILD_SUBDIRS = @BUILD_SUBDIRS@
CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@
CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@
+CARES_RANDOM_FILE = @CARES_RANDOM_FILE@
CARES_VERSION_INFO = @CARES_VERSION_INFO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -382,11 +396,15 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@ @CARES_CFLAG_EXTRAS@
CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
+CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
+CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
-CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
+CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
@@ -401,6 +419,7 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV = @GCOV@
@@ -440,7 +459,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-RANDOM_FILE = @RANDOM_FILE@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
@@ -478,6 +496,8 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+ifnGNUmake = @ifnGNUmake@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
@@ -510,7 +530,8 @@ ACLOCAL_AMFLAGS = -I m4 --install
# being currently built and tested are searched before the library which
# might possibly already be installed in the system.
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/src/lib \
- -I$(top_srcdir)/include $(am__append_4)
+ -I$(top_srcdir)/include -I$(top_srcdir)/src/lib \
+ $(am__append_4)
lib_LTLIBRARIES = libcares.la
man_MANS = $(MANPAGES)
@@ -525,13 +546,33 @@ DIST_SUBDIRS =
AM_LDFLAGS =
libcares_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \
$(am__append_3)
-libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA) \
- $(CODE_COVERAGE_LDFLAGS)
+libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA)
libcares_la_CFLAGS_EXTRA = $(am__append_5) $(CODE_COVERAGE_CFLAGS)
-libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY $(am__append_6)
+libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY $(am__append_6) \
+ $(CODE_COVERAGE_CPPFLAGS)
+@CODE_COVERAGE_ENABLED_TRUE@GITIGNOREFILES := $(GITIGNOREFILES) $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_cap_0 = @echo " LCOV --capture" $(CODE_COVERAGE_OUTPUT_FILE);
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN);
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_v_genhtml_0 = @echo " GEN " "$(CODE_COVERAGE_OUTPUT_DIRECTORY)";
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_quiet = $(code_coverage_quiet_$(V))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_quiet_0 = --quiet
+
+# sanitizes the test-name: replaces with underscores: dashes and dots
+@CODE_COVERAGE_ENABLED_TRUE@code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
+@CODE_COVERAGE_ENABLED_TRUE@AM_DISTCHECK_CONFIGURE_FLAGS := $(AM_DISTCHECK_CONFIGURE_FLAGS) --disable-code-coverage
+libcares_la_LIBS = $(CODE_COVERAGE_LIBS)
libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA)
libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA)
-CSOURCES = ares__close_sockets.c \
+CSOURCES = ares__addrinfo2hostent.c \
+ ares__addrinfo_localhost.c \
+ ares__close_sockets.c \
ares__get_hostent.c \
ares__parse_into_addrinfo.c \
ares__readaddrinfo.c \
@@ -571,6 +612,7 @@ CSOURCES = ares__close_sockets.c \
ares_parse_soa_reply.c \
ares_parse_srv_reply.c \
ares_parse_txt_reply.c \
+ ares_parse_uri_reply.c \
ares_platform.c \
ares_process.c \
ares_query.c \
@@ -604,7 +646,6 @@ HHEADERS = ares_android.h \
ares_strsplit.h \
ares_writev.h \
bitncmp.h \
- nameser.h \
ares_setup.h \
setup_once.h
@@ -616,7 +657,7 @@ all: ares_config.h
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/aminclude_static.am $(srcdir)/Makefile.inc $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -636,7 +677,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
-$(srcdir)/Makefile.inc $(am__empty):
+$(top_srcdir)/aminclude_static.am $(srcdir)/Makefile.inc $(am__empty):
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -706,6 +747,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__close_sockets.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__get_hostent.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo@am__quote@ # am--include-marker
@@ -746,6 +789,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_platform.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_process.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_query.Plo@am__quote@ # am--include-marker
@@ -793,6 +837,20 @@ am--depfiles: $(am__depfiles_remade)
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+libcares_la-ares__addrinfo2hostent.lo: ares__addrinfo2hostent.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__addrinfo2hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__addrinfo2hostent.Tpo -c -o libcares_la-ares__addrinfo2hostent.lo `test -f 'ares__addrinfo2hostent.c' || echo '$(srcdir)/'`ares__addrinfo2hostent.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__addrinfo2hostent.Tpo $(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__addrinfo2hostent.c' object='libcares_la-ares__addrinfo2hostent.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__addrinfo2hostent.lo `test -f 'ares__addrinfo2hostent.c' || echo '$(srcdir)/'`ares__addrinfo2hostent.c
+
+libcares_la-ares__addrinfo_localhost.lo: ares__addrinfo_localhost.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__addrinfo_localhost.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__addrinfo_localhost.Tpo -c -o libcares_la-ares__addrinfo_localhost.lo `test -f 'ares__addrinfo_localhost.c' || echo '$(srcdir)/'`ares__addrinfo_localhost.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__addrinfo_localhost.Tpo $(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__addrinfo_localhost.c' object='libcares_la-ares__addrinfo_localhost.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__addrinfo_localhost.lo `test -f 'ares__addrinfo_localhost.c' || echo '$(srcdir)/'`ares__addrinfo_localhost.c
+
libcares_la-ares__close_sockets.lo: ares__close_sockets.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__close_sockets.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__close_sockets.Tpo -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__close_sockets.Tpo $(DEPDIR)/libcares_la-ares__close_sockets.Plo
@@ -1073,6 +1131,13 @@ libcares_la-ares_parse_txt_reply.lo: ares_parse_txt_reply.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c
+libcares_la-ares_parse_uri_reply.lo: ares_parse_uri_reply.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_uri_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo -c -o libcares_la-ares_parse_uri_reply.lo `test -f 'ares_parse_uri_reply.c' || echo '$(srcdir)/'`ares_parse_uri_reply.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_uri_reply.c' object='libcares_la-ares_parse_uri_reply.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_uri_reply.lo `test -f 'ares_parse_uri_reply.c' || echo '$(srcdir)/'`ares_parse_uri_reply.c
+
libcares_la-ares_platform.lo: ares_platform.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_platform.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_platform.Tpo -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_platform.Tpo $(DEPDIR)/libcares_la-ares_platform.Plo
@@ -1289,7 +1354,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -1393,7 +1457,9 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
- -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__get_hostent.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__read_line.Plo
@@ -1433,6 +1499,7 @@ distclean: distclean-recursive
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo
@@ -1494,7 +1561,9 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
- -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__get_hostent.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares__read_line.Plo
@@ -1534,6 +1603,7 @@ maintainer-clean: maintainer-clean-recursive
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo
+ -rm -f ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo
-rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo
@@ -1589,7 +1659,105 @@ uninstall-am: uninstall-libLTLIBRARIES
.PRECIOUS: Makefile
-@CODE_COVERAGE_RULES@
+# Code coverage
+#
+# Optional:
+# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
+# Multiple directories may be specified, separated by whitespace.
+# (Default: $(top_builddir))
+# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
+# by lcov for code coverage. (Default:
+# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
+# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
+# reports to be created. (Default:
+# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
+# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
+# set to 0 to disable it and leave empty to stay with the default.
+# (Default: empty)
+# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
+# instances. (Default: based on )
+# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
+# instances. (Default: )
+# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
+# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
+# collecting lcov instance. (Default: )
+# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
+# instance. (Default: )
+# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
+# lcov instance. (Default: empty)
+# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
+# instance. (Default: )
+# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
+# genhtml instance. (Default: based on )
+# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
+# instance. (Default: )
+# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
+#
+# The generated report will be titled using the $(PACKAGE_NAME) and
+# $(PACKAGE_VERSION). In order to add the current git hash to the title,
+# use the git-version-gen script, available online.
+# Optional variables
+# run only on top dir
+@CODE_COVERAGE_ENABLED_TRUE@ ifeq ($(abs_builddir), $(abs_top_builddir))
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
+
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_BRANCH_COVERAGE ?=
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=$(if $(CODE_COVERAGE_BRANCH_COVERAGE),--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
+@CODE_COVERAGE_ENABLED_TRUE@CODE_COVERAGE_IGNORE_PATTERN ?=
+
+# Use recursive makes in order to ignore errors during check
+@CODE_COVERAGE_ENABLED_TRUE@check-code-coverage:
+@CODE_COVERAGE_ENABLED_TRUE@ -$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
+@CODE_COVERAGE_ENABLED_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
+
+# Capture code coverage data
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-capture: code-coverage-capture-hook
+@CODE_COVERAGE_ENABLED_TRUE@ $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
+@CODE_COVERAGE_ENABLED_TRUE@ $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
+@CODE_COVERAGE_ENABLED_TRUE@ -@rm -f "$(CODE_COVERAGE_OUTPUT_FILE).tmp"
+@CODE_COVERAGE_ENABLED_TRUE@ $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
+@CODE_COVERAGE_ENABLED_TRUE@ @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
+
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-clean:
+@CODE_COVERAGE_ENABLED_TRUE@ -$(LCOV) --directory $(top_builddir) -z
+@CODE_COVERAGE_ENABLED_TRUE@ -rm -rf "$(CODE_COVERAGE_OUTPUT_FILE)" "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "$(CODE_COVERAGE_OUTPUT_DIRECTORY)"
+@CODE_COVERAGE_ENABLED_TRUE@ -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
+
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-dist-clean:
+@CODE_COVERAGE_ENABLED_TRUE@ else # ifneq ($(abs_builddir), $(abs_top_builddir))
+@CODE_COVERAGE_ENABLED_TRUE@check-code-coverage:
+
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-capture: code-coverage-capture-hook
+
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-clean:
+
+@CODE_COVERAGE_ENABLED_TRUE@code-coverage-dist-clean:
+@CODE_COVERAGE_ENABLED_TRUE@ endif # ifeq ($(abs_builddir), $(abs_top_builddir))
+# Use recursive makes in order to ignore errors during check
+@CODE_COVERAGE_ENABLED_FALSE@check-code-coverage:
+@CODE_COVERAGE_ENABLED_FALSE@ @echo "Need to reconfigure with --enable-code-coverage"
+# Capture code coverage data
+@CODE_COVERAGE_ENABLED_FALSE@code-coverage-capture: code-coverage-capture-hook
+@CODE_COVERAGE_ENABLED_FALSE@ @echo "Need to reconfigure with --enable-code-coverage"
+
+@CODE_COVERAGE_ENABLED_FALSE@code-coverage-clean:
+
+@CODE_COVERAGE_ENABLED_FALSE@code-coverage-dist-clean:
+
+# Hook rule executed before code-coverage-capture, overridable by the user
+code-coverage-capture-hook:
+
+.PHONY: check-code-coverage code-coverage-capture code-coverage-dist-clean code-coverage-clean code-coverage-capture-hook
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 4695e11..a3b060c 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -1,5 +1,7 @@
-CSOURCES = ares__close_sockets.c \
+CSOURCES = ares__addrinfo2hostent.c \
+ ares__addrinfo_localhost.c \
+ ares__close_sockets.c \
ares__get_hostent.c \
ares__parse_into_addrinfo.c \
ares__readaddrinfo.c \
@@ -39,6 +41,7 @@ CSOURCES = ares__close_sockets.c \
ares_parse_soa_reply.c \
ares_parse_srv_reply.c \
ares_parse_txt_reply.c \
+ ares_parse_uri_reply.c \
ares_platform.c \
ares_process.c \
ares_query.c \
@@ -72,7 +75,6 @@ HHEADERS = ares_android.h \
ares_strsplit.h \
ares_writev.h \
bitncmp.h \
- nameser.h \
ares_setup.h \
setup_once.h
diff --git a/src/lib/ares__addrinfo2hostent.c b/src/lib/ares__addrinfo2hostent.c
new file mode 100644
index 0000000..efb145c
--- /dev/null
+++ b/src/lib/ares__addrinfo2hostent.c
@@ -0,0 +1,266 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright 2005 Dominick Meglio
+ * Copyright (C) 2019 by Andrew Selivanov
+ * Copyright (C) 2021 by Brad House
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_inet_net_pton.h"
+#include "ares_private.h"
+
+int ares__addrinfo2hostent(const struct ares_addrinfo *ai, int family,
+ struct hostent **host)
+{
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ char **aliases = NULL;
+ char *addrs = NULL;
+ int naliases = 0, naddrs = 0, alias = 0, i;
+
+ if (ai == NULL || host == NULL)
+ return ARES_EBADQUERY;
+
+ *host = ares_malloc(sizeof(**host));
+ if (!(*host))
+ {
+ goto enomem;
+ }
+ memset(*host, 0, sizeof(**host));
+
+ /* Use the first node of the response as the family, since hostent can only
+ * represent one family. We assume getaddrinfo() returned a sorted list if
+ * the user requested AF_UNSPEC. */
+ if (family == AF_UNSPEC && ai->nodes)
+ family = ai->nodes->ai_family;
+
+ next = ai->nodes;
+ while (next)
+ {
+ if(next->ai_family == family)
+ {
+ ++naddrs;
+ }
+ next = next->ai_next;
+ }
+
+ next_cname = ai->cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias)
+ ++naliases;
+ next_cname = next_cname->next;
+ }
+
+ aliases = ares_malloc((naliases + 1) * sizeof(char *));
+ if (!aliases)
+ {
+ goto enomem;
+ }
+ (*host)->h_aliases = aliases;
+ memset(aliases, 0, (naliases + 1) * sizeof(char *));
+
+ if (naliases)
+ {
+ next_cname = ai->cnames;
+ while (next_cname)
+ {
+ if(next_cname->alias) {
+ aliases[alias] = ares_strdup(next_cname->alias);
+ if (!aliases[alias]) {
+ goto enomem;
+ }
+ alias++;
+ }
+ next_cname = next_cname->next;
+ }
+ }
+
+
+ (*host)->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
+ if (!(*host)->h_addr_list)
+ {
+ goto enomem;
+ }
+
+ memset((*host)->h_addr_list, 0, (naddrs + 1) * sizeof(char *));
+
+ if (ai->cnames)
+ {
+ (*host)->h_name = ares_strdup(ai->cnames->name);
+ if ((*host)->h_name == NULL && ai->cnames->name)
+ {
+ goto enomem;
+ }
+ }
+ else
+ {
+ (*host)->h_name = ares_strdup(ai->name);
+ if ((*host)->h_name == NULL && ai->name)
+ {
+ goto enomem;
+ }
+ }
+
+ (*host)->h_addrtype = family;
+ (*host)->h_length = (family == AF_INET)?
+ sizeof(struct in_addr):sizeof(struct ares_in6_addr);
+
+ if (naddrs)
+ {
+ addrs = ares_malloc(naddrs * (*host)->h_length);
+ if (!addrs)
+ {
+ goto enomem;
+ }
+
+ i = 0;
+ next = ai->nodes;
+ while (next)
+ {
+ if(next->ai_family == family)
+ {
+ (*host)->h_addr_list[i] = addrs + (i * (*host)->h_length);
+ if (family == AF_INET6)
+ {
+ memcpy((*host)->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ (*host)->h_length);
+ }
+ else
+ {
+ memcpy((*host)->h_addr_list[i],
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ (*host)->h_length);
+ }
+ ++i;
+ }
+ next = next->ai_next;
+ }
+
+ if (i == 0)
+ {
+ ares_free(addrs);
+ }
+ }
+
+ if (naddrs == 0 && naliases == 0)
+ {
+ ares_free_hostent(*host);
+ *host = NULL;
+ return ARES_ENODATA;
+ }
+
+ return ARES_SUCCESS;
+
+enomem:
+ ares_free_hostent(*host);
+ *host = NULL;
+ return ARES_ENOMEM;
+}
+
+
+int ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family,
+ int req_naddrttls, struct ares_addrttl *addrttls,
+ struct ares_addr6ttl *addr6ttls, int *naddrttls)
+{
+ struct ares_addrinfo_node *next;
+ struct ares_addrinfo_cname *next_cname;
+ int cname_ttl = INT_MAX;
+
+ if (family != AF_INET && family != AF_INET6)
+ return ARES_EBADQUERY;
+
+ if (ai == NULL || naddrttls == NULL)
+ return ARES_EBADQUERY;
+
+ if (family == AF_INET && addrttls == NULL)
+ return ARES_EBADQUERY;
+
+ if (family == AF_INET6 && addr6ttls == NULL)
+ return ARES_EBADQUERY;
+
+ if (req_naddrttls == 0)
+ return ARES_EBADQUERY;
+
+ *naddrttls = 0;
+
+ next_cname = ai->cnames;
+ while (next_cname)
+ {
+ if(next_cname->ttl < cname_ttl)
+ cname_ttl = next_cname->ttl;
+ next_cname = next_cname->next;
+ }
+
+ next = ai->nodes;
+ while (next)
+ {
+ if(next->ai_family == family)
+ {
+ if (*naddrttls < req_naddrttls)
+ {
+ if (family == AF_INET6)
+ {
+ if(next->ai_ttl > cname_ttl)
+ addr6ttls[*naddrttls].ttl = cname_ttl;
+ else
+ addr6ttls[*naddrttls].ttl = next->ai_ttl;
+
+ memcpy(&addr6ttls[*naddrttls].ip6addr,
+ &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
+ sizeof(struct ares_in6_addr));
+ }
+ else
+ {
+ if(next->ai_ttl > cname_ttl)
+ addrttls[*naddrttls].ttl = cname_ttl;
+ else
+ addrttls[*naddrttls].ttl = next->ai_ttl;
+ memcpy(&addrttls[*naddrttls].ipaddr,
+ &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
+ sizeof(struct in_addr));
+ }
+ (*naddrttls)++;
+ }
+ }
+ next = next->ai_next;
+ }
+
+ return ARES_SUCCESS;
+}
+
diff --git a/src/lib/ares__addrinfo_localhost.c b/src/lib/ares__addrinfo_localhost.c
new file mode 100644
index 0000000..7940ecd
--- /dev/null
+++ b/src/lib/ares__addrinfo_localhost.c
@@ -0,0 +1,240 @@
+/* Copyright (C) 2021
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#if defined(_WIN32) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
+#include <ws2ipdef.h>
+#include <iphlpapi.h>
+#endif
+
+#include "ares.h"
+#include "ares_inet_net_pton.h"
+#include "ares_nowarn.h"
+#include "ares_private.h"
+
+int ares_append_ai_node(int aftype,
+ unsigned short port,
+ int ttl,
+ const void *adata,
+ struct ares_addrinfo_node **nodes)
+{
+ struct ares_addrinfo_node *node;
+
+ node = ares__append_addrinfo_node(nodes);
+ if (!node)
+ {
+ return ARES_ENOMEM;
+ }
+
+ memset(node, 0, sizeof(*node));
+
+ if (aftype == AF_INET)
+ {
+ struct sockaddr_in *sin = ares_malloc(sizeof(*sin));
+ if (!sin)
+ {
+ return ARES_ENOMEM;
+ }
+
+ memset(sin, 0, sizeof(*sin));
+ memcpy(&sin->sin_addr.s_addr, adata, sizeof(sin->sin_addr.s_addr));
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons(port);
+
+ node->ai_addr = (struct sockaddr *)sin;
+ node->ai_family = AF_INET;
+ node->ai_addrlen = sizeof(*sin);
+ node->ai_addr = (struct sockaddr *)sin;
+ node->ai_ttl = ttl;
+ }
+
+ if (aftype == AF_INET6)
+ {
+ struct sockaddr_in6 *sin6 = ares_malloc(sizeof(*sin6));
+ if (!sin6)
+ {
+ return ARES_ENOMEM;
+ }
+
+ memset(sin6, 0, sizeof(*sin6));
+ memcpy(&sin6->sin6_addr.s6_addr, adata, sizeof(sin6->sin6_addr.s6_addr));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons(port);
+
+ node->ai_addr = (struct sockaddr *)sin6;
+ node->ai_family = AF_INET6;
+ node->ai_addrlen = sizeof(*sin6);
+ node->ai_addr = (struct sockaddr *)sin6;
+ node->ai_ttl = ttl;
+ }
+
+ return ARES_SUCCESS;
+}
+
+
+static int ares__default_loopback_addrs(int aftype,
+ unsigned short port,
+ struct ares_addrinfo_node **nodes)
+{
+ int status = ARES_SUCCESS;
+
+ if (aftype == AF_UNSPEC || aftype == AF_INET6)
+ {
+ struct ares_in6_addr addr6;
+ ares_inet_pton(AF_INET6, "::1", &addr6);
+ status = ares_append_ai_node(AF_INET6, port, 0, &addr6, nodes);
+ if (status != ARES_SUCCESS)
+ {
+ return status;
+ }
+ }
+
+ if (aftype == AF_UNSPEC || aftype == AF_INET)
+ {
+ struct in_addr addr4;
+ ares_inet_pton(AF_INET, "127.0.0.1", &addr4);
+ status = ares_append_ai_node(AF_INET, port, 0, &addr4, nodes);
+ if (status != ARES_SUCCESS)
+ {
+ return status;
+ }
+ }
+
+ return status;
+}
+
+
+static int ares__system_loopback_addrs(int aftype,
+ unsigned short port,
+ struct ares_addrinfo_node **nodes)
+{
+#if defined(_WIN32) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
+ PMIB_UNICASTIPADDRESS_TABLE table;
+ unsigned int i;
+ int status;
+
+ *nodes = NULL;
+
+ if (GetUnicastIpAddressTable(aftype, &table) != NO_ERROR)
+ return ARES_ENOTFOUND;
+
+ for (i=0; i<table->NumEntries; i++)
+ {
+ if (table->Table[i].InterfaceLuid.Info.IfType !=
+ IF_TYPE_SOFTWARE_LOOPBACK)
+ {
+ continue;
+ }
+
+ if (table->Table[i].Address.si_family == AF_INET)
+ {
+ status = ares_append_ai_node(table->Table[i].Address.si_family, port, 0,
+ &table->Table[i].Address.Ipv4.sin_addr,
+ nodes);
+ }
+ else if (table->Table[i].Address.si_family == AF_INET6)
+ {
+ status = ares_append_ai_node(table->Table[i].Address.si_family, port, 0,
+ &table->Table[i].Address.Ipv6.sin6_addr,
+ nodes);
+ }
+ else
+ {
+ /* Ignore any others */
+ continue;
+ }
+
+ if (status != ARES_SUCCESS)
+ {
+ goto fail;
+ }
+ }
+
+ if (*nodes == NULL)
+ status = ARES_ENOTFOUND;
+
+fail:
+ FreeMibTable(table);
+
+ if (status != ARES_SUCCESS)
+ {
+ ares__freeaddrinfo_nodes(*nodes);
+ *nodes = NULL;
+ }
+
+ return status;
+
+#else
+ (void)aftype;
+ (void)port;
+ (void)nodes;
+ /* Not supported on any other OS at this time */
+ return ARES_ENOTFOUND;
+#endif
+}
+
+
+int ares__addrinfo_localhost(const char *name,
+ unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai)
+{
+ struct ares_addrinfo_node *nodes = NULL;
+ int result;
+
+ /* Validate family */
+ switch (hints->ai_family) {
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ break;
+ default:
+ return ARES_EBADFAMILY;
+ }
+
+ ai->name = ares_strdup(name);
+ if(!ai->name)
+ {
+ goto enomem;
+ }
+
+ result = ares__system_loopback_addrs(hints->ai_family, port, &nodes);
+
+ if (result == ARES_ENOTFOUND)
+ {
+ result = ares__default_loopback_addrs(hints->ai_family, port, &nodes);
+ }
+
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+
+ return result;
+
+enomem:
+ ares__freeaddrinfo_nodes(nodes);
+ ares_free(ai->name);
+ ai->name = NULL;
+ return ARES_ENOMEM;
+}
diff --git a/src/lib/ares__parse_into_addrinfo.c b/src/lib/ares__parse_into_addrinfo.c
index b080163..4393f04 100644
--- a/src/lib/ares__parse_into_addrinfo.c
+++ b/src/lib/ares__parse_into_addrinfo.c
@@ -24,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -45,23 +39,20 @@
#include "ares_dns.h"
#include "ares_private.h"
-int ares__parse_into_addrinfo2(const unsigned char *abuf,
- int alen,
- char **question_hostname,
- struct ares_addrinfo *ai)
+int ares__parse_into_addrinfo(const unsigned char *abuf,
+ int alen, int cname_only_is_enodata,
+ unsigned short port,
+ struct ares_addrinfo *ai)
{
unsigned int qdcount, ancount;
int status, i, rr_type, rr_class, rr_len, rr_ttl;
int got_a = 0, got_aaaa = 0, got_cname = 0;
long len;
const unsigned char *aptr;
+ char *question_hostname = NULL;
char *hostname, *rr_name = NULL, *rr_data;
struct ares_addrinfo_cname *cname, *cnames = NULL;
- struct ares_addrinfo_node *node, *nodes = NULL;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- *question_hostname = NULL;
+ struct ares_addrinfo_node *nodes = NULL;
/* Give up if abuf doesn't have room for a header. */
if (alen < HFIXEDSZ)
@@ -76,15 +67,16 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, question_hostname, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &question_hostname, &len, 0);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
{
- return ARES_EBADRESP;
+ status = ARES_EBADRESP;
+ goto failed_stat;
}
- hostname = *question_hostname;
+ hostname = question_hostname;
aptr += len + QFIXEDSZ;
@@ -92,7 +84,7 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len, 0);
if (status != ARES_SUCCESS)
{
rr_name = NULL;
@@ -127,30 +119,9 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
goto failed_stat;
} /* LCOV_EXCL_STOP */
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- sin = ares_malloc(sizeof(struct sockaddr_in));
- if (!sin)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
- memset(sin, 0, sizeof(struct sockaddr_in));
- memcpy(&sin->sin_addr.s_addr, aptr, sizeof(struct in_addr));
- sin->sin_family = AF_INET;
-
- node->ai_addr = (struct sockaddr *)sin;
- node->ai_family = AF_INET;
- node->ai_addrlen = sizeof(struct sockaddr_in);
-
- node->ai_ttl = rr_ttl;
-
- status = ARES_SUCCESS;
+ status = ares_append_ai_node(AF_INET, port, rr_ttl, aptr, &nodes);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
}
else if (rr_class == C_IN && rr_type == T_AAAA
&& rr_len == sizeof(struct ares_in6_addr)
@@ -163,38 +134,16 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
goto failed_stat;
} /* LCOV_EXCL_STOP */
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- sin6 = ares_malloc(sizeof(struct sockaddr_in6));
- if (!sin6)
- {
- status = ARES_ENOMEM;
- goto failed_stat;
- }
-
- memset(sin6, 0, sizeof(struct sockaddr_in6));
- memcpy(&sin6->sin6_addr.s6_addr, aptr, sizeof(struct ares_in6_addr));
- sin6->sin6_family = AF_INET6;
-
- node->ai_addr = (struct sockaddr *)sin6;
- node->ai_family = AF_INET6;
- node->ai_addrlen = sizeof(struct sockaddr_in6);
-
- node->ai_ttl = rr_ttl;
-
- status = ARES_SUCCESS;
+ status = ares_append_ai_node(AF_INET6, port, rr_ttl, aptr, &nodes);
+ if (status != ARES_SUCCESS)
+ goto failed_stat;
}
if (rr_class == C_IN && rr_type == T_CNAME)
{
got_cname = 1;
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if (status != ARES_SUCCESS)
{
goto failed_stat;
@@ -214,10 +163,13 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
cname->ttl = rr_ttl;
cname->alias = rr_name;
cname->name = rr_data;
+ rr_name = NULL;
}
else
{
+ /* rr_name is only saved for cname */
ares_free(rr_name);
+ rr_name = NULL;
}
@@ -231,36 +183,47 @@ int ares__parse_into_addrinfo2(const unsigned char *abuf,
if (status == ARES_SUCCESS)
{
- ares__addrinfo_cat_nodes(&ai->nodes, nodes);
- if (got_cname)
+ if (!got_a && !got_aaaa)
{
- ares__addrinfo_cat_cnames(&ai->cnames, cnames);
- return status;
+ if (!got_cname || (got_cname && cname_only_is_enodata))
+ {
+ status = ARES_ENODATA;
+ goto failed_stat;
+ }
+ }
+
+ /* save the question hostname as ai->name */
+ if (ai->name == NULL || strcasecmp(ai->name, question_hostname) != 0)
+ {
+ ares_free(ai->name);
+ ai->name = ares_strdup(question_hostname);
+ if (!ai->name)
+ {
+ status = ARES_ENOMEM;
+ goto failed_stat;
+ }
+ }
+
+ if (got_a || got_aaaa)
+ {
+ ares__addrinfo_cat_nodes(&ai->nodes, nodes);
+ nodes = NULL;
}
- else if (got_a == 0 && got_aaaa == 0)
+
+ if (got_cname)
{
- /* the check for naliases to be zero is to make sure CNAME responses
- don't get caught here */
- status = ARES_ENODATA;
+ ares__addrinfo_cat_cnames(&ai->cnames, cnames);
+ cnames = NULL;
}
}
+ ares_free(question_hostname);
return status;
failed_stat:
+ ares_free(question_hostname);
ares_free(rr_name);
ares__freeaddrinfo_cnames(cnames);
ares__freeaddrinfo_nodes(nodes);
return status;
}
-
-int ares__parse_into_addrinfo(const unsigned char *abuf,
- int alen,
- struct ares_addrinfo *ai)
-{
- int status;
- char *question_hostname;
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, ai);
- ares_free(question_hostname);
- return status;
-}
diff --git a/src/lib/ares__readaddrinfo.c b/src/lib/ares__readaddrinfo.c
index 2b5bb40..673de87 100644
--- a/src/lib/ares__readaddrinfo.c
+++ b/src/lib/ares__readaddrinfo.c
@@ -42,11 +42,10 @@ int ares__readaddrinfo(FILE *fp,
char *txtaddr, *txthost, *txtalias;
char *aliases[MAX_ALIASES];
unsigned int i, alias_count;
- int status;
+ int status = ARES_SUCCESS;
size_t linesize;
- ares_sockaddr addr;
struct ares_addrinfo_cname *cname = NULL, *cnames = NULL;
- struct ares_addrinfo_node *node = NULL, *nodes = NULL;
+ struct ares_addrinfo_node *nodes = NULL;
int match_with_alias, match_with_canonical;
int want_cname = hints->ai_flags & ARES_AI_CANONNAME;
@@ -60,6 +59,12 @@ int ares__readaddrinfo(FILE *fp,
return ARES_EBADFAMILY;
}
+ ai->name = ares_strdup(name);
+ if(!ai->name)
+ {
+ status = ARES_ENOMEM;
+ goto fail;
+ }
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
@@ -163,57 +168,36 @@ int ares__readaddrinfo(FILE *fp,
continue;
}
- /* Zero-out 'addr' struct, as there are members that we may not set, especially
- * for ipv6. We don't want garbage data */
- memset(&addr, 0, sizeof(addr));
-
/*
* Convert address string to network address for the requested families.
* Actual address family possible values are AF_INET and AF_INET6 only.
*/
if ((hints->ai_family == AF_INET) || (hints->ai_family == AF_UNSPEC))
{
- addr.sa4.sin_port = htons(port);
- if (ares_inet_pton(AF_INET, txtaddr, &addr.sa4.sin_addr) > 0)
+ struct in_addr addr4;
+ if (ares_inet_pton(AF_INET, txtaddr, &addr4) == 1)
{
- node = ares__append_addrinfo_node(&nodes);
- if(!node)
- {
- goto enomem;
- }
-
- node->ai_family = addr.sa.sa_family = AF_INET;
- node->ai_addrlen = sizeof(addr.sa4);
- node->ai_addr = ares_malloc(sizeof(addr.sa4));
- if (!node->ai_addr)
+ status = ares_append_ai_node(AF_INET, port, 0, &addr4, &nodes);
+ if (status != ARES_SUCCESS)
{
- goto enomem;
+ goto fail;
}
- memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
}
}
if ((hints->ai_family == AF_INET6) || (hints->ai_family == AF_UNSPEC))
{
- addr.sa6.sin6_port = htons(port);
- if (ares_inet_pton(AF_INET6, txtaddr, &addr.sa6.sin6_addr) > 0)
+ struct ares_in6_addr addr6;
+ if (ares_inet_pton(AF_INET6, txtaddr, &addr6) == 1)
{
- node = ares__append_addrinfo_node(&nodes);
- if (!node)
+ status = ares_append_ai_node(AF_INET6, port, 0, &addr6, &nodes);
+ if (status != ARES_SUCCESS)
{
- goto enomem;
+ goto fail;
}
-
- node->ai_family = addr.sa.sa_family = AF_INET6;
- node->ai_addrlen = sizeof(addr.sa6);
- node->ai_addr = ares_malloc(sizeof(addr.sa6));
- if (!node->ai_addr)
- {
- goto enomem;
- }
- memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
}
}
- if (!node)
+
+ if (status != ARES_SUCCESS)
/* Ignore line if invalid address string for the requested family. */
continue;
@@ -224,7 +208,8 @@ int ares__readaddrinfo(FILE *fp,
cname = ares__append_addrinfo_cname(&cnames);
if (!cname)
{
- goto enomem;
+ status = ARES_ENOMEM;
+ goto fail;
}
cname->alias = ares_strdup(aliases[i]);
cname->name = ares_strdup(txthost);
@@ -235,7 +220,8 @@ int ares__readaddrinfo(FILE *fp,
cname = ares__append_addrinfo_cname(&cnames);
if (!cname)
{
- goto enomem;
+ status = ARES_ENOMEM;
+ goto fail;
}
cname->name = ares_strdup(txthost);
}
@@ -245,20 +231,21 @@ int ares__readaddrinfo(FILE *fp,
/* Last read failed. */
if (status == ARES_ENOMEM)
{
- goto enomem;
+ goto fail;
}
/* Free line buffer. */
ares_free(line);
-
ares__addrinfo_cat_cnames(&ai->cnames, cnames);
ares__addrinfo_cat_nodes(&ai->nodes, nodes);
- return node ? ARES_SUCCESS : ARES_ENOTFOUND;
+ return nodes ? ARES_SUCCESS : ARES_ENOTFOUND;
-enomem:
+fail:
ares_free(line);
ares__freeaddrinfo_cnames(cnames);
ares__freeaddrinfo_nodes(nodes);
- return ARES_ENOMEM;
+ ares_free(ai->name);
+ ai->name = NULL;
+ return status;
}
diff --git a/src/lib/ares__sortaddrinfo.c b/src/lib/ares__sortaddrinfo.c
index 0ad3a5b..3f050ca 100644
--- a/src/lib/ares__sortaddrinfo.c
+++ b/src/lib/ares__sortaddrinfo.c
@@ -301,11 +301,15 @@ static int rfc6724_compare(const void *ptr1, const void *ptr2)
}
/* Rule 2: Prefer matching scope. */
- scope_src1 = get_scope(&a1->src_addr.sa);
+ scope_src1 = ARES_IPV6_ADDR_SCOPE_NODELOCAL;
+ if (a1->has_src_addr)
+ scope_src1 = get_scope(&a1->src_addr.sa);
scope_dst1 = get_scope(a1->ai->ai_addr);
scope_match1 = (scope_src1 == scope_dst1);
- scope_src2 = get_scope(&a2->src_addr.sa);
+ scope_src2 = ARES_IPV6_ADDR_SCOPE_NODELOCAL;
+ if (a2->has_src_addr)
+ scope_src2 = get_scope(&a2->src_addr.sa);
scope_dst2 = get_scope(a2->ai->ai_addr);
scope_match2 = (scope_src2 == scope_dst2);
@@ -319,11 +323,15 @@ static int rfc6724_compare(const void *ptr1, const void *ptr2)
/* Rule 4: Prefer home addresses. */
/* Rule 5: Prefer matching label. */
- label_src1 = get_label(&a1->src_addr.sa);
+ label_src1 = 1;
+ if (a1->has_src_addr)
+ label_src1 = get_label(&a1->src_addr.sa);
label_dst1 = get_label(a1->ai->ai_addr);
label_match1 = (label_src1 == label_dst1);
- label_src2 = get_label(&a2->src_addr.sa);
+ label_src2 = 1;
+ if (a2->has_src_addr)
+ label_src2 = get_label(&a2->src_addr.sa);
label_dst2 = get_label(a2->ai->ai_addr);
label_match2 = (label_src2 == label_dst2);
@@ -453,6 +461,10 @@ int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sen
++nelem;
cur = cur->ai_next;
}
+
+ if (!nelem)
+ return ARES_ENODATA;
+
elems = (struct addrinfo_sort_elem *)ares_malloc(
nelem * sizeof(struct addrinfo_sort_elem));
if (!elems)
diff --git a/src/lib/ares_config.h.cmake b/src/lib/ares_config.h.cmake
index b76acc1..fddb785 100644
--- a/src/lib/ares_config.h.cmake
+++ b/src/lib/ares_config.h.cmake
@@ -1,4 +1,4 @@
-/* Generated from ares_config.h.cmake*/
+/* Generated from ares_config.h.cmake */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
@@ -347,7 +347,7 @@
#cmakedefine NEED_MEMORY_H
/* a suitable file/device to read random data from */
-#cmakedefine RANDOM_FILE
+#cmakedefine CARES_RANDOM_FILE "@CARES_RANDOM_FILE@"
/* Define to the type qualifier pointed by arg 5 for recvfrom. */
#define RECVFROM_QUAL_ARG5 @RECVFROM_QUAL_ARG5@
diff --git a/src/lib/ares_config.h.in b/src/lib/ares_config.h.in
index 94dcff0..b260c08 100644
--- a/src/lib/ares_config.h.in
+++ b/src/lib/ares_config.h.in
@@ -9,6 +9,9 @@
/* Defined for build that exposes internal static functions for testing. */
#undef CARES_EXPOSE_STATICS
+/* a suitable file/device to read random data from */
+#undef CARES_RANDOM_FILE
+
/* Defined for build with symbol hiding. */
#undef CARES_SYMBOL_HIDING
@@ -241,6 +244,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -376,9 +382,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* a suitable file/device to read random data from */
-#undef RANDOM_FILE
-
/* Define to the type qualifier pointed by arg 5 for recvfrom. */
#undef RECVFROM_QUAL_ARG5
@@ -448,10 +451,13 @@
/* Define to the function return type for send. */
#undef SEND_TYPE_RETV
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
#undef STDC_HEADERS
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
+ macro is obsolete. */
#undef TIME_WITH_SYS_TIME
/* Define to disable non-blocking sockets. */
@@ -480,11 +486,6 @@
# undef _ALL_SOURCE
#endif
-/* Enable large inode numbers on Mac OS X 10.5. */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
diff --git a/src/lib/ares_create_query.c b/src/lib/ares_create_query.c
index 9efce17..e3d874b 100644
--- a/src/lib/ares_create_query.c
+++ b/src/lib/ares_create_query.c
@@ -19,22 +19,13 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_private.h"
-#ifndef T_OPT
-# define T_OPT 41 /* EDNS0 option (meta-RR) */
-#endif
/* Header format, from RFC 1035:
* 1 1 1 1 1 1
@@ -57,7 +48,7 @@
* of the remaining fields:
* ID Identifier to match responses with queries
* QR Query (0) or response (1)
- * Opcode For our purposes, always QUERY
+ * Opcode For our purposes, always O_QUERY
* RD Recursion desired
* Z Reserved (zero)
* QDCOUNT Number of queries
@@ -116,7 +107,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
q = buf;
memset(q, 0, HFIXEDSZ);
DNS_HEADER_SET_QID(q, id);
- DNS_HEADER_SET_OPCODE(q, QUERY);
+ DNS_HEADER_SET_OPCODE(q, O_QUERY);
if (rd) {
DNS_HEADER_SET_RD(q, 1);
}
diff --git a/src/lib/ares_data.c b/src/lib/ares_data.c
index aa925b8..69dff06 100644
--- a/src/lib/ares_data.c
+++ b/src/lib/ares_data.c
@@ -77,6 +77,14 @@ void ares_free_data(void *dataptr)
ares_free(ptr->data.srv_reply.host);
break;
+ case ARES_DATATYPE_URI_REPLY:
+
+ if (ptr->data.uri_reply.next)
+ next_data = ptr->data.uri_reply.next;
+ if (ptr->data.uri_reply.uri)
+ ares_free(ptr->data.uri_reply.uri);
+ break;
+
case ARES_DATATYPE_TXT_REPLY:
case ARES_DATATYPE_TXT_EXT:
@@ -174,6 +182,14 @@ void *ares_malloc_data(ares_datatype type)
ptr->data.srv_reply.port = 0;
break;
+ case ARES_DATATYPE_URI_REPLY:
+ ptr->data.uri_reply.next = NULL;
+ ptr->data.uri_reply.priority = 0;
+ ptr->data.uri_reply.weight = 0;
+ ptr->data.uri_reply.uri = NULL;
+ ptr->data.uri_reply.ttl = 0;
+ break;
+
case ARES_DATATYPE_TXT_EXT:
ptr->data.txt_ext.record_start = 0;
/* FALLTHROUGH */
diff --git a/src/lib/ares_data.h b/src/lib/ares_data.h
index b0182fd..6b9dd9f 100644
--- a/src/lib/ares_data.h
+++ b/src/lib/ares_data.h
@@ -23,6 +23,7 @@ typedef enum {
ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */
ARES_DATATYPE_SOA_REPLY, /* struct ares_soa_reply - introduced in 1.9.0 */
+ ARES_DATATYPE_URI_REPLY, /* struct ares_uri_reply */
#if 0
ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */
ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */
@@ -67,6 +68,7 @@ struct ares_data {
struct ares_naptr_reply naptr_reply;
struct ares_soa_reply soa_reply;
struct ares_caa_reply caa_reply;
+ struct ares_uri_reply uri_reply;
} data;
};
diff --git a/src/lib/ares_expand_name.c b/src/lib/ares_expand_name.c
index 3a38e67..fcd88a2 100644
--- a/src/lib/ares_expand_name.c
+++ b/src/lib/ares_expand_name.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_nowarn.h"
@@ -36,7 +30,61 @@
#define MAX_INDIRS 50
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen);
+ int alen, int is_hostname);
+
+/* Reserved characters for names that need to be escaped */
+static int is_reservedch(int ch)
+{
+ switch (ch) {
+ case '"':
+ case '.':
+ case ';':
+ case '\\':
+ case '(':
+ case ')':
+ case '@':
+ case '$':
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int ares__isprint(int ch)
+{
+ if (ch >= 0x20 && ch <= 0x7E)
+ return 1;
+ return 0;
+}
+
+/* Character set allowed by hostnames. This is to include the normal
+ * domain name character set plus:
+ * - underscores which are used in SRV records.
+ * - Forward slashes such as are used for classless in-addr.arpa
+ * delegation (CNAMEs)
+ * While RFC 2181 section 11 does state not to do validation,
+ * that applies to servers, not clients. Vulnerabilities have been
+ * reported when this validation is not performed. Security is more
+ * important than edge-case compatibility (which is probably invalid
+ * anyhow). */
+static int is_hostnamech(int ch)
+{
+ /* [A-Za-z0-9-._/]
+ * Don't use isalnum() as it is locale-specific
+ */
+ if (ch >= 'A' && ch <= 'Z')
+ return 1;
+ if (ch >= 'a' && ch <= 'z')
+ return 1;
+ if (ch >= '0' && ch <= '9')
+ return 1;
+ if (ch == '-' || ch == '.' || ch == '_' || ch == '/')
+ return 1;
+
+ return 0;
+}
/* Expand an RFC1035-encoded domain name given by encoded. The
* containing message is given by abuf and alen. The result given by
@@ -60,10 +108,15 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
*
* Since the expanded name uses '.' as a label separator, we use
* backslashes to escape periods or backslashes in the expanded name.
+ *
+ * If the result is expected to be a hostname, then no escaped data is allowed
+ * and will return error.
*/
-int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
- int alen, char **s, long *enclen)
+int ares__expand_name_validated(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen, char **s, long *enclen,
+ int is_hostname)
{
int len, indir = 0;
char *q;
@@ -73,7 +126,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
size_t uns;
} nlen;
- nlen.sig = name_length(encoded, abuf, alen);
+ nlen.sig = name_length(encoded, abuf, alen, is_hostname);
if (nlen.sig < 0)
return ARES_EBADNAME;
@@ -113,18 +166,36 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
}
else
{
- len = *p;
+ int name_len = *p;
+ len = name_len;
p++;
+
while (len--)
{
- if (*p == '.' || *p == '\\')
- *q++ = '\\';
- *q++ = *p;
+ /* Output as \DDD for consistency with RFC1035 5.1, except
+ * for the special case of a root name response */
+ if (!ares__isprint(*p) && !(name_len == 1 && *p == 0))
+ {
+ *q++ = '\\';
+ *q++ = '0' + *p / 100;
+ *q++ = '0' + (*p % 100) / 10;
+ *q++ = '0' + (*p % 10);
+ }
+ else if (is_reservedch(*p))
+ {
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ else
+ {
+ *q++ = *p;
+ }
p++;
}
*q++ = '.';
}
- }
+ }
+
if (!indir)
*enclen = aresx_uztosl(p + 1U - encoded);
@@ -137,11 +208,18 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
return ARES_SUCCESS;
}
+
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+ int alen, char **s, long *enclen)
+{
+ return ares__expand_name_validated(encoded, abuf, alen, s, enclen, 0);
+}
+
/* Return the length of the expansion of an encoded domain name, or
* -1 if the encoding is invalid.
*/
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
- int alen)
+ int alen, int is_hostname)
{
int n = 0, offset, indir = 0, top;
@@ -171,15 +249,35 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
}
else if (top == 0x00)
{
- offset = *encoded;
+ int name_len = *encoded;
+ offset = name_len;
if (encoded + offset + 1 >= abuf + alen)
return -1;
encoded++;
+
while (offset--)
{
- n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
+ if (!ares__isprint(*encoded) && !(name_len == 1 && *encoded == 0))
+ {
+ if (is_hostname)
+ return -1;
+ n += 4;
+ }
+ else if (is_reservedch(*encoded))
+ {
+ if (is_hostname)
+ return -1;
+ n += 2;
+ }
+ else
+ {
+ if (is_hostname && !is_hostnamech(*encoded))
+ return -1;
+ n += 1;
+ }
encoded++;
}
+
n++;
}
else
@@ -197,12 +295,14 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
return (n) ? n - 1 : n;
}
-/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
+/* Like ares_expand_name_validated but returns EBADRESP in case of invalid
+ * input. */
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
- char **s, long *enclen)
+ char **s, long *enclen, int is_hostname)
{
- int status = ares_expand_name(encoded, abuf, alen, s, enclen);
+ int status = ares__expand_name_validated(encoded, abuf, alen, s, enclen,
+ is_hostname);
if (status == ARES_EBADNAME)
status = ARES_EBADRESP;
return status;
diff --git a/src/lib/ares_expand_string.c b/src/lib/ares_expand_string.c
index d35df75..03e3929 100644
--- a/src/lib/ares_expand_string.c
+++ b/src/lib/ares_expand_string.c
@@ -19,11 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_private.h" /* for the memdebug */
diff --git a/src/lib/ares_free_hostent.c b/src/lib/ares_free_hostent.c
index cfc5f81..ea28ff0 100644
--- a/src/lib/ares_free_hostent.c
+++ b/src/lib/ares_free_hostent.c
@@ -31,11 +31,13 @@ void ares_free_hostent(struct hostent *host)
return;
ares_free((char *)(host->h_name));
- for (p = host->h_aliases; *p; p++)
+ for (p = host->h_aliases; p && *p; p++)
ares_free(*p);
ares_free(host->h_aliases);
- ares_free(host->h_addr_list[0]); /* no matter if there is one or many entries,
- there is only one malloc for all of them */
- ares_free(host->h_addr_list);
+ if (host->h_addr_list) {
+ ares_free(host->h_addr_list[0]); /* no matter if there is one or many entries,
+ there is only one malloc for all of them */
+ ares_free(host->h_addr_list);
+ }
ares_free(host);
}
diff --git a/src/lib/ares_freeaddrinfo.c b/src/lib/ares_freeaddrinfo.c
index 128f5da..ab87136 100644
--- a/src/lib/ares_freeaddrinfo.c
+++ b/src/lib/ares_freeaddrinfo.c
@@ -51,7 +51,10 @@ void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
void ares_freeaddrinfo(struct ares_addrinfo *ai)
{
+ if (ai == NULL)
+ return;
ares__freeaddrinfo_cnames(ai->cnames);
ares__freeaddrinfo_nodes(ai->nodes);
+ ares_free(ai->name);
ares_free(ai);
}
diff --git a/src/lib/ares_getaddrinfo.c b/src/lib/ares_getaddrinfo.c
index ecd5dd5..0a0225a 100644
--- a/src/lib/ares_getaddrinfo.c
+++ b/src/lib/ares_getaddrinfo.c
@@ -34,14 +34,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
@@ -78,6 +72,7 @@ struct host_query
struct ares_addrinfo *ai; /* store results between lookups */
int remaining; /* number of DNS answers waiting for */
int next_domain; /* next search domain to try */
+ int nodata_cnt; /* Track nodata responses to possibly override final result */
};
static const struct ares_addrinfo_hints default_hints = {
@@ -107,13 +102,15 @@ static const struct ares_addrinfo_node empty_addrinfo_node = {
static const struct ares_addrinfo empty_addrinfo = {
NULL, /* cnames */
- NULL /* nodes */
+ NULL, /* nodes */
+ NULL /* name */
};
/* forward declarations */
static void host_callback(void *arg, int status, int timeouts,
unsigned char *abuf, int alen);
static int as_is_first(const struct host_query *hquery);
+static int as_is_only(const struct host_query* hquery);
static int next_dns_lookup(struct host_query *hquery);
struct ares_addrinfo_cname *ares__malloc_addrinfo_cname()
@@ -287,9 +284,7 @@ static int fake_addrinfo(const char *name,
void *arg)
{
struct ares_addrinfo_cname *cname;
- struct ares_addrinfo_node *node;
- ares_sockaddr addr;
- size_t addrlen;
+ int status = ARES_SUCCESS;
int result = 0;
int family = hints->ai_family;
if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC)
@@ -310,62 +305,45 @@ static int fake_addrinfo(const char *name,
}
}
- memset(&addr, 0, sizeof(addr));
-
/* if we don't have 3 dots, it is illegal
* (although inet_pton doesn't think so).
*/
if (numdots != 3 || !valid)
result = 0;
else
- result =
- (ares_inet_pton(AF_INET, name, &addr.sa4.sin_addr) < 1 ? 0 : 1);
-
- if (result)
{
- family = addr.sa.sa_family = AF_INET;
- addr.sa4.sin_port = htons(port);
- addrlen = sizeof(addr.sa4);
+ struct in_addr addr4;
+ result = ares_inet_pton(AF_INET, name, &addr4) < 1 ? 0 : 1;
+ if (result)
+ {
+ status = ares_append_ai_node(AF_INET, port, 0, &addr4, &ai->nodes);
+ if (status != ARES_SUCCESS)
+ {
+ callback(arg, status, 0, NULL);
+ return 1;
+ }
+ }
}
}
if (family == AF_INET6 || family == AF_UNSPEC)
{
- result =
- (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1);
- addr.sa6.sin6_family = AF_INET6;
- addr.sa6.sin6_port = htons(port);
- addrlen = sizeof(addr.sa6);
+ struct ares_in6_addr addr6;
+ result = ares_inet_pton(AF_INET6, name, &addr6) < 1 ? 0 : 1;
+ if (result)
+ {
+ status = ares_append_ai_node(AF_INET6, port, 0, &addr6, &ai->nodes);
+ if (status != ARES_SUCCESS)
+ {
+ callback(arg, status, 0, NULL);
+ return 1;
+ }
+ }
}
if (!result)
return 0;
- node = ares__malloc_addrinfo_node();
- if (!node)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- ai->nodes = node;
-
- node->ai_addr = ares_malloc(addrlen);
- if (!node->ai_addr)
- {
- ares_freeaddrinfo(ai);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
- }
-
- node->ai_addrlen = (unsigned int)addrlen;
- node->ai_family = addr.sa.sa_family;
- if (addr.sa.sa_family == AF_INET)
- memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4));
- else
- memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6));
-
if (hints->ai_flags & ARES_AI_CANONNAME)
{
cname = ares__append_addrinfo_cname(&ai->cnames);
@@ -386,8 +364,8 @@ static int fake_addrinfo(const char *name,
}
}
- node->ai_socktype = hints->ai_socktype;
- node->ai_protocol = hints->ai_protocol;
+ ai->nodes->ai_socktype = hints->ai_socktype;
+ ai->nodes->ai_protocol = hints->ai_protocol;
callback(arg, ARES_SUCCESS, 0, ai);
return 1;
@@ -399,26 +377,18 @@ static void end_hquery(struct host_query *hquery, int status)
struct ares_addrinfo_node *next;
if (status == ARES_SUCCESS)
{
- if (!(hquery->hints.ai_flags & ARES_AI_NOSORT))
+ if (!(hquery->hints.ai_flags & ARES_AI_NOSORT) && hquery->ai->nodes)
{
sentinel.ai_next = hquery->ai->nodes;
ares__sortaddrinfo(hquery->channel, &sentinel);
hquery->ai->nodes = sentinel.ai_next;
}
next = hquery->ai->nodes;
- /* Set port into each address (resolved separately). */
+
while (next)
{
next->ai_socktype = hquery->hints.ai_socktype;
next->ai_protocol = hquery->hints.ai_protocol;
- if (next->ai_family == AF_INET)
- {
- (CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr))->sin_port = htons(hquery->port);
- }
- else
- {
- (CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr))->sin6_port = htons(hquery->port);
- }
next = next->ai_next;
}
}
@@ -506,6 +476,16 @@ static int file_lookup(struct host_query *hquery)
}
status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
fclose(fp);
+
+ /* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries
+ * SHOULD recognize localhost names as special and SHOULD always return the
+ * IP loopback address for address queries" */
+ if (status == ARES_ENOTFOUND && strcmp(hquery->name, "localhost") == 0)
+ {
+ return ares__addrinfo_localhost(hquery->name, hquery->port,
+ &hquery->hints, hquery->ai);
+ }
+
return status;
}
@@ -514,9 +494,16 @@ static void next_lookup(struct host_query *hquery, int status)
switch (*hquery->remaining_lookups)
{
case 'b':
- /* DNS lookup */
- if (next_dns_lookup(hquery))
- break;
+ /* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send
+ * queries for localhost names to their configured caching DNS
+ * server(s)." */
+ if (strcmp(hquery->name, "localhost") != 0)
+ {
+ /* DNS lookup */
+ if (next_dns_lookup(hquery))
+ break;
+ }
+
hquery->remaining_lookups++;
next_lookup(hquery, status);
break;
@@ -548,17 +535,12 @@ static void host_callback(void *arg, int status, int timeouts,
if (status == ARES_SUCCESS)
{
- addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai);
- }
- else if (status == ARES_EDESTRUCTION)
- {
- end_hquery(hquery, status);
- return;
+ addinfostatus = ares__parse_into_addrinfo(abuf, alen, 1, hquery->port, hquery->ai);
}
if (!hquery->remaining)
{
- if (addinfostatus != ARES_SUCCESS)
+ if (addinfostatus != ARES_SUCCESS && addinfostatus != ARES_ENODATA)
{
/* error in parsing result e.g. no memory */
end_hquery(hquery, addinfostatus);
@@ -568,9 +550,19 @@ static void host_callback(void *arg, int status, int timeouts,
/* at least one query ended with ARES_SUCCESS */
end_hquery(hquery, ARES_SUCCESS);
}
- else if (status == ARES_ENOTFOUND)
+ else if (status == ARES_ENOTFOUND || status == ARES_ENODATA ||
+ addinfostatus == ARES_ENODATA)
{
- next_lookup(hquery, status);
+ if (status == ARES_ENODATA || addinfostatus == ARES_ENODATA)
+ hquery->nodata_cnt++;
+ next_lookup(hquery, hquery->nodata_cnt?ARES_ENODATA:status);
+ }
+ else if (status == ARES_EDESTRUCTION)
+ {
+ /* NOTE: Could also be ARES_EDESTRUCTION. We need to only call this
+ * once all queries (there can be multiple for getaddrinfo) are
+ * terminated. */
+ end_hquery(hquery, status);
}
else
{
@@ -590,6 +582,8 @@ void ares_getaddrinfo(ares_channel channel,
unsigned short port = 0;
int family;
struct ares_addrinfo *ai;
+ char *alias_name = NULL;
+ int status;
if (!hints)
{
@@ -614,6 +608,17 @@ void ares_getaddrinfo(ares_channel channel,
return;
}
+ /* perform HOSTALIAS resolution (technically this function does some other
+ * things we are going to ignore) */
+ status = ares__single_domain(channel, name, &alias_name);
+ if (status != ARES_SUCCESS) {
+ callback(arg, status, 0, NULL);
+ return;
+ }
+
+ if (alias_name)
+ name = alias_name;
+
if (service)
{
if (hints->ai_flags & ARES_AI_NUMERICSERV)
@@ -621,6 +626,7 @@ void ares_getaddrinfo(ares_channel channel,
port = (unsigned short)strtoul(service, NULL, 0);
if (!port)
{
+ ares_free(alias_name);
callback(arg, ARES_ESERVICE, 0, NULL);
return;
}
@@ -633,6 +639,7 @@ void ares_getaddrinfo(ares_channel channel,
port = (unsigned short)strtoul(service, NULL, 0);
if (!port)
{
+ ares_free(alias_name);
callback(arg, ARES_ESERVICE, 0, NULL);
return;
}
@@ -643,12 +650,14 @@ void ares_getaddrinfo(ares_channel channel,
ai = ares__malloc_addrinfo();
if (!ai)
{
+ ares_free(alias_name);
callback(arg, ARES_ENOMEM, 0, NULL);
return;
}
if (fake_addrinfo(name, port, hints, ai, callback, arg))
{
+ ares_free(alias_name);
return;
}
@@ -656,12 +665,14 @@ void ares_getaddrinfo(ares_channel channel,
hquery = ares_malloc(sizeof(struct host_query));
if (!hquery)
{
+ ares_free(alias_name);
ares_freeaddrinfo(ai);
callback(arg, ARES_ENOMEM, 0, NULL);
return;
}
hquery->name = ares_strdup(name);
+ ares_free(alias_name);
if (!hquery->name)
{
ares_free(hquery);
@@ -681,6 +692,7 @@ void ares_getaddrinfo(ares_channel channel,
hquery->ai = ai;
hquery->next_domain = -1;
hquery->remaining = 0;
+ hquery->nodata_cnt = 0;
/* Start performing lookups according to channel->lookups. */
next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
@@ -711,7 +723,7 @@ static int next_dns_lookup(struct host_query *hquery)
hquery->next_domain++;
}
- if (!s && hquery->next_domain < hquery->channel->ndomains)
+ if (!s && hquery->next_domain < hquery->channel->ndomains && !as_is_only(hquery))
{
status = ares__cat_domain(
hquery->name,
@@ -759,7 +771,7 @@ static int as_is_first(const struct host_query* hquery)
{
char* p;
int ndots = 0;
- size_t nname = strlen(hquery->name);
+ size_t nname = hquery->name?strlen(hquery->name):0;
for (p = hquery->name; *p; p++)
{
if (*p == '.')
@@ -774,3 +786,12 @@ static int as_is_first(const struct host_query* hquery)
}
return ndots >= hquery->channel->ndots;
}
+
+static int as_is_only(const struct host_query* hquery)
+{
+ size_t nname = hquery->name?strlen(hquery->name):0;
+ if (nname && hquery->name[nname-1] == '.')
+ return 1;
+ return 0;
+}
+
diff --git a/src/lib/ares_gethostbyaddr.c b/src/lib/ares_gethostbyaddr.c
index 54eb599..c62d230 100644
--- a/src/lib/ares_gethostbyaddr.c
+++ b/src/lib/ares_gethostbyaddr.c
@@ -24,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_inet_net_pton.h"
diff --git a/src/lib/ares_gethostbyname.c b/src/lib/ares_gethostbyname.c
index 4e41898..8c71cc6 100644
--- a/src/lib/ares_gethostbyname.c
+++ b/src/lib/ares_gethostbyname.c
@@ -1,4 +1,3 @@
-
/* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
@@ -25,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
@@ -45,30 +38,6 @@
#include "ares_nowarn.h"
#include "ares_private.h"
-#ifdef WATT32
-#undef WIN32
-#endif
-
-struct host_query {
- /* Arguments passed to ares_gethostbyname() */
- ares_channel channel;
- char *name;
- ares_host_callback callback;
- void *arg;
- int sent_family; /* this family is what was is being used */
- int want_family; /* this family is what is asked for in the API */
- const char *remaining_lookups;
- int timeouts;
-};
-
-static void next_lookup(struct host_query *hquery, int status_code);
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen);
-static void end_hquery(struct host_query *hquery, int status,
- struct hostent *host);
-static int fake_hostent(const char *name, int family,
- ares_host_callback callback, void *arg);
-static int file_lookup(const char *name, int family, struct hostent **host);
static void sort_addresses(struct hostent *host,
const struct apattern *sortlist, int nsort);
static void sort6_addresses(struct hostent *host,
@@ -78,252 +47,182 @@ static int get_address_index(const struct in_addr *addr,
static int get6_address_index(const struct ares_in6_addr *addr,
const struct apattern *sortlist, int nsort);
-void ares_gethostbyname(ares_channel channel, const char *name, int family,
- ares_host_callback callback, void *arg)
+struct host_query {
+ ares_host_callback callback;
+ void *arg;
+ ares_channel channel;
+};
+
+static void ares_gethostbyname_callback(void *arg, int status, int timeouts,
+ struct ares_addrinfo *result)
{
- struct host_query *hquery;
-
- /* Right now we only know how to look up Internet addresses - and unspec
- means try both basically. */
- switch (family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- break;
- default:
- callback(arg, ARES_ENOTIMP, 0, NULL);
- return;
- }
+ struct hostent *hostent = NULL;
+ struct host_query *ghbn_arg = arg;
- /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
- if (ares__is_onion_domain(name))
+ if (status == ARES_SUCCESS)
{
- callback(arg, ARES_ENOTFOUND, 0, NULL);
- return;
+ status = ares__addrinfo2hostent(result, AF_UNSPEC, &hostent);
+ }
+
+ /* addrinfo2hostent will only return ENODATA if there are no addresses _and_
+ * no cname/aliases. However, gethostbyname will return ENODATA even if there
+ * is cname/alias data */
+ if (status == ARES_SUCCESS && hostent &&
+ (!hostent->h_addr_list || !hostent->h_addr_list[0]))
+ {
+ status = ARES_ENODATA;
}
- if (fake_hostent(name, family, callback, arg))
+ if (status == ARES_SUCCESS && ghbn_arg->channel->nsort && hostent)
+ {
+ if (hostent->h_addrtype == AF_INET6)
+ sort6_addresses(hostent, ghbn_arg->channel->sortlist,
+ ghbn_arg->channel->nsort);
+ if (hostent->h_addrtype == AF_INET)
+ sort_addresses(hostent, ghbn_arg->channel->sortlist,
+ ghbn_arg->channel->nsort);
+ }
+
+ ghbn_arg->callback(ghbn_arg->arg, status, timeouts, hostent);
+
+ ares_freeaddrinfo(result);
+ ares_free(ghbn_arg);
+ ares_free_hostent(hostent);
+}
+
+void ares_gethostbyname(ares_channel channel, const char *name, int family,
+ ares_host_callback callback, void *arg)
+{
+ const struct ares_addrinfo_hints hints = { ARES_AI_CANONNAME, family, 0, 0 };
+ struct host_query *ghbn_arg;
+
+ if (!callback)
return;
- /* Allocate and fill in the host query structure. */
- hquery = ares_malloc(sizeof(struct host_query));
- if (!hquery)
+ ghbn_arg = ares_malloc(sizeof(*ghbn_arg));
+ if (!ghbn_arg)
{
callback(arg, ARES_ENOMEM, 0, NULL);
return;
}
- hquery->channel = channel;
- hquery->name = ares_strdup(name);
- hquery->want_family = family;
- hquery->sent_family = -1; /* nothing is sent yet */
- if (!hquery->name) {
- ares_free(hquery);
- callback(arg, ARES_ENOMEM, 0, NULL);
- return;
- }
- hquery->callback = callback;
- hquery->arg = arg;
- hquery->remaining_lookups = channel->lookups;
- hquery->timeouts = 0;
- /* Start performing lookups according to channel->lookups. */
- next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
+ ghbn_arg->callback=callback;
+ ghbn_arg->arg=arg;
+ ghbn_arg->channel=channel;
+
+ ares_getaddrinfo(channel, name, NULL, &hints, ares_gethostbyname_callback,
+ ghbn_arg);
}
-static void next_lookup(struct host_query *hquery, int status_code)
+
+static void sort_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort)
{
- const char *p;
- struct hostent *host;
- int status = status_code;
+ struct in_addr a1, a2;
+ int i1, i2, ind1, ind2;
- for (p = hquery->remaining_lookups; *p; p++)
+ /* This is a simple insertion sort, not optimized at all. i1 walks
+ * through the address list, with the loop invariant that everything
+ * to the left of i1 is sorted. In the loop body, the value at i1 is moved
+ * back through the list (via i2) until it is in sorted order.
+ */
+ for (i1 = 0; host->h_addr_list[i1]; i1++)
{
- switch (*p)
+ memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
+ ind1 = get_address_index(&a1, sortlist, nsort);
+ for (i2 = i1 - 1; i2 >= 0; i2--)
{
- case 'b':
- /* DNS lookup */
- hquery->remaining_lookups = p + 1;
- if ((hquery->want_family == AF_INET6) ||
- (hquery->want_family == AF_UNSPEC)) {
- /* if inet6 or unspec, start out with AAAA */
- hquery->sent_family = AF_INET6;
- ares_search(hquery->channel, hquery->name, C_IN, T_AAAA,
- host_callback, hquery);
- }
- else {
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A,
- host_callback, hquery);
- }
- return;
-
- case 'f':
- /* Host file lookup */
- status = file_lookup(hquery->name, hquery->want_family, &host);
-
- /* this status check below previously checked for !ARES_ENOTFOUND,
- but we should not assume that this single error code is the one
- that can occur, as that is in fact no longer the case */
- if (status == ARES_SUCCESS)
- {
- end_hquery(hquery, status, host);
- return;
- }
- status = status_code; /* Use original status code */
- break;
+ memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
+ ind2 = get_address_index(&a2, sortlist, nsort);
+ if (ind2 <= ind1)
+ break;
+ memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
}
+ memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
}
- end_hquery(hquery, status, NULL);
}
-static void host_callback(void *arg, int status, int timeouts,
- unsigned char *abuf, int alen)
+/* Find the first entry in sortlist which matches addr. Return nsort
+ * if none of them match.
+ */
+static int get_address_index(const struct in_addr *addr,
+ const struct apattern *sortlist,
+ int nsort)
{
- struct host_query *hquery = (struct host_query *) arg;
- ares_channel channel = hquery->channel;
- struct hostent *host = NULL;
+ int i;
- hquery->timeouts += timeouts;
- if (status == ARES_SUCCESS)
+ for (i = 0; i < nsort; i++)
{
- if (hquery->sent_family == AF_INET)
+ if (sortlist[i].family != AF_INET)
+ continue;
+ if (sortlist[i].type == PATTERN_MASK)
{
- status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
- if (host && channel->nsort)
- sort_addresses(host, channel->sortlist, channel->nsort);
+ if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
+ == sortlist[i].addrV4.s_addr)
+ break;
}
- else if (hquery->sent_family == AF_INET6)
+ else
{
- status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
- if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
- (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)) &&
- hquery->want_family == AF_UNSPEC) {
- /* The query returned something but either there were no AAAA
- records (e.g. just CNAME) or the response was malformed. Try
- looking up A instead. */
- if (host)
- ares_free_hostent(host);
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A,
- host_callback, hquery);
- return;
- }
- if (host && channel->nsort)
- sort6_addresses(host, channel->sortlist, channel->nsort);
+ if (!ares__bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
+ sortlist[i].mask.bits))
+ break;
}
- if (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)
- {
- /* The query returned something but had no A/AAAA record
- (even after potentially retrying AAAA with A)
- so we should treat this as an error */
- status = ARES_ENODATA;
- }
- end_hquery(hquery, status, host);
- }
- else if ((status == ARES_ENODATA || status == ARES_EBADRESP ||
- status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 &&
- hquery->want_family == AF_UNSPEC))
- {
- /* The AAAA query yielded no useful result. Now look up an A instead. */
- hquery->sent_family = AF_INET;
- ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
- hquery);
}
- else if (status == ARES_EDESTRUCTION)
- end_hquery(hquery, status, NULL);
- else
- next_lookup(hquery, status);
+ return i;
}
-static void end_hquery(struct host_query *hquery, int status,
- struct hostent *host)
+static void sort6_addresses(struct hostent *host,
+ const struct apattern *sortlist, int nsort)
{
- hquery->callback(hquery->arg, status, hquery->timeouts, host);
- if (host)
- ares_free_hostent(host);
- ares_free(hquery->name);
- ares_free(hquery);
-}
+ struct ares_in6_addr a1, a2;
+ int i1, i2, ind1, ind2;
-/* If the name looks like an IP address, fake up a host entry, end the
- * query immediately, and return true. Otherwise return false.
- */
-static int fake_hostent(const char *name, int family,
- ares_host_callback callback, void *arg)
-{
- struct hostent hostent;
- char *aliases[1] = { NULL };
- char *addrs[2];
- int result = 0;
- struct in_addr in;
- struct ares_in6_addr in6;
-
- if (family == AF_INET || family == AF_UNSPEC)
+ /* This is a simple insertion sort, not optimized at all. i1 walks
+ * through the address list, with the loop invariant that everything
+ * to the left of i1 is sorted. In the loop body, the value at i1 is moved
+ * back through the list (via i2) until it is in sorted order.
+ */
+ for (i1 = 0; host->h_addr_list[i1]; i1++)
{
- /* It only looks like an IP address if it's all numbers and dots. */
- int numdots = 0, valid = 1;
- const char *p;
- for (p = name; *p; p++)
+ memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr));
+ ind1 = get6_address_index(&a1, sortlist, nsort);
+ for (i2 = i1 - 1; i2 >= 0; i2--)
{
- if (!ISDIGIT(*p) && *p != '.') {
- valid = 0;
+ memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr));
+ ind2 = get6_address_index(&a2, sortlist, nsort);
+ if (ind2 <= ind1)
break;
- } else if (*p == '.') {
- numdots++;
- }
+ memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr));
}
-
- /* if we don't have 3 dots, it is illegal
- * (although inet_pton doesn't think so).
- */
- if (numdots != 3 || !valid) {
- result = 0;
- } else {
- result = (ares_inet_pton(AF_INET, name, &in) < 1 ? 0 : 1);
- }
-
- /*
- * Set address family in case of failure,
- * as we will try to convert it later afterwards
- */
- family = result ? AF_INET : AF_INET6;
+ memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr));
}
- if (family == AF_INET6)
- result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
+}
- if (!result)
- return 0;
+/* Find the first entry in sortlist which matches addr. Return nsort
+ * if none of them match.
+ */
+static int get6_address_index(const struct ares_in6_addr *addr,
+ const struct apattern *sortlist,
+ int nsort)
+{
+ int i;
- if (family == AF_INET)
- {
- hostent.h_length = (int)sizeof(struct in_addr);
- addrs[0] = (char *)&in;
- }
- else if (family == AF_INET6)
- {
- hostent.h_length = (int)sizeof(struct ares_in6_addr);
- addrs[0] = (char *)&in6;
- }
- /* Duplicate the name, to avoid a constness violation. */
- hostent.h_name = ares_strdup(name);
- if (!hostent.h_name)
+ for (i = 0; i < nsort; i++)
{
- callback(arg, ARES_ENOMEM, 0, NULL);
- return 1;
+ if (sortlist[i].family != AF_INET6)
+ continue;
+ if (!ares__bitncmp(addr, &sortlist[i].addrV6, sortlist[i].mask.bits))
+ break;
}
+ return i;
+}
- /* Fill in the rest of the host structure and terminate the query. */
- addrs[1] = NULL;
- hostent.h_aliases = aliases;
- hostent.h_addrtype = aresx_sitoss(family);
- hostent.h_addr_list = addrs;
- callback(arg, ARES_SUCCESS, 0, &hostent);
- ares_free((char *)(hostent.h_name));
- return 1;
-}
-/* This is an API method */
+static int file_lookup(const char *name, int family, struct hostent **host);
+
+/* I really have no idea why this is exposed as a public function, but since
+ * it is, we can't kill this legacy function. */
int ares_gethostbyname_file(ares_channel channel, const char *name,
int family, struct hostent **host)
{
@@ -437,104 +336,3 @@ static int file_lookup(const char *name, int family, struct hostent **host)
return status;
}
-static void sort_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort)
-{
- struct in_addr a1, a2;
- int i1, i2, ind1, ind2;
-
- /* This is a simple insertion sort, not optimized at all. i1 walks
- * through the address list, with the loop invariant that everything
- * to the left of i1 is sorted. In the loop body, the value at i1 is moved
- * back through the list (via i2) until it is in sorted order.
- */
- for (i1 = 0; host->h_addr_list[i1]; i1++)
- {
- memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
- ind1 = get_address_index(&a1, sortlist, nsort);
- for (i2 = i1 - 1; i2 >= 0; i2--)
- {
- memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
- ind2 = get_address_index(&a2, sortlist, nsort);
- if (ind2 <= ind1)
- break;
- memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
- }
- memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
- }
-}
-
-/* Find the first entry in sortlist which matches addr. Return nsort
- * if none of them match.
- */
-static int get_address_index(const struct in_addr *addr,
- const struct apattern *sortlist,
- int nsort)
-{
- int i;
-
- for (i = 0; i < nsort; i++)
- {
- if (sortlist[i].family != AF_INET)
- continue;
- if (sortlist[i].type == PATTERN_MASK)
- {
- if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
- == sortlist[i].addrV4.s_addr)
- break;
- }
- else
- {
- if (!ares__bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
- sortlist[i].mask.bits))
- break;
- }
- }
- return i;
-}
-
-static void sort6_addresses(struct hostent *host,
- const struct apattern *sortlist, int nsort)
-{
- struct ares_in6_addr a1, a2;
- int i1, i2, ind1, ind2;
-
- /* This is a simple insertion sort, not optimized at all. i1 walks
- * through the address list, with the loop invariant that everything
- * to the left of i1 is sorted. In the loop body, the value at i1 is moved
- * back through the list (via i2) until it is in sorted order.
- */
- for (i1 = 0; host->h_addr_list[i1]; i1++)
- {
- memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr));
- ind1 = get6_address_index(&a1, sortlist, nsort);
- for (i2 = i1 - 1; i2 >= 0; i2--)
- {
- memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr));
- ind2 = get6_address_index(&a2, sortlist, nsort);
- if (ind2 <= ind1)
- break;
- memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr));
- }
- memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr));
- }
-}
-
-/* Find the first entry in sortlist which matches addr. Return nsort
- * if none of them match.
- */
-static int get6_address_index(const struct ares_in6_addr *addr,
- const struct apattern *sortlist,
- int nsort)
-{
- int i;
-
- for (i = 0; i < nsort; i++)
- {
- if (sortlist[i].family != AF_INET6)
- continue;
- if (!ares__bitncmp(addr, &sortlist[i].addrV6, sortlist[i].mask.bits))
- break;
- }
- return i;
-}
diff --git a/src/lib/ares_getnameinfo.c b/src/lib/ares_getnameinfo.c
index 53f91ca..966919a 100644
--- a/src/lib/ares_getnameinfo.c
+++ b/src/lib/ares_getnameinfo.c
@@ -31,14 +31,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_NET_IF_H
#include <net/if.h>
diff --git a/src/lib/ares_init.c b/src/lib/ares_init.c
index 92187e4..de5d86c 100644
--- a/src/lib/ares_init.c
+++ b/src/lib/ares_init.c
@@ -33,14 +33,7 @@
#include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+#include "ares_nameser.h"
#if defined(ANDROID) || defined(__ANDROID__)
#include <sys/system_properties.h>
@@ -1472,6 +1465,57 @@ static int init_by_resolv_conf(ares_channel channel)
/* Catch the case when all the above checks fail (which happens when there
is no network card or the cable is unplugged) */
status = ARES_EFILE;
+#elif defined(__MVS__)
+
+ struct __res_state *res = 0;
+ int count4, count6;
+ __STATEEXTIPV6 *v6;
+ struct server_state *pserver;
+ if (0 == res) {
+ int rc = res_init();
+ while (rc == -1 && h_errno == TRY_AGAIN) {
+ rc = res_init();
+ }
+ if (rc == -1) {
+ return ARES_ENOMEM;
+ }
+ res = __res();
+ }
+
+ v6 = res->__res_extIPv6;
+ count4 = res->nscount;
+ if (v6) {
+ count6 = v6->__stat_nscount;
+ } else {
+ count6 = 0;
+ }
+
+ nservers = count4 + count6;
+ servers = ares_malloc(nservers * sizeof(struct server_state));
+ if (!servers)
+ return ARES_ENOMEM;
+
+ memset(servers, 0, nservers * sizeof(struct server_state));
+
+ pserver = servers;
+ for (int i = 0; i < count4; ++i, ++pserver) {
+ struct sockaddr_in *addr_in = &(res->nsaddr_list[i]);
+ pserver->addr.addrV4.s_addr = addr_in->sin_addr.s_addr;
+ pserver->addr.family = AF_INET;
+ pserver->addr.udp_port = addr_in->sin_port;
+ pserver->addr.tcp_port = addr_in->sin_port;
+ }
+
+ for (int j = 0; j < count6; ++j, ++pserver) {
+ struct sockaddr_in6 *addr_in = &(v6->__stat_nsaddr_list[j]);
+ memcpy(&(pserver->addr.addr.addr6), &(addr_in->sin6_addr),
+ sizeof(addr_in->sin6_addr));
+ pserver->addr.family = AF_INET6;
+ pserver->addr.udp_port = addr_in->sin6_port;
+ pserver->addr.tcp_port = addr_in->sin6_port;
+ }
+
+ status = ARES_EOF;
#elif defined(__riscos__)
@@ -1621,17 +1665,18 @@ static int init_by_resolv_conf(ares_channel channel)
int entries = 0;
while ((entries < MAXDNSRCH) && res.dnsrch[entries])
entries++;
-
- channel->domains = ares_malloc(entries * sizeof(char *));
- if (!channel->domains) {
- status = ARES_ENOMEM;
- } else {
- int i;
- channel->ndomains = entries;
- for (i = 0; i < channel->ndomains; ++i) {
- channel->domains[i] = ares_strdup(res.dnsrch[i]);
- if (!channel->domains[i])
- status = ARES_ENOMEM;
+ if(entries) {
+ channel->domains = ares_malloc(entries * sizeof(char *));
+ if (!channel->domains) {
+ status = ARES_ENOMEM;
+ } else {
+ int i;
+ channel->ndomains = entries;
+ for (i = 0; i < channel->ndomains; ++i) {
+ channel->domains[i] = ares_strdup(res.dnsrch[i]);
+ if (!channel->domains[i])
+ status = ARES_ENOMEM;
+ }
}
}
}
@@ -2470,9 +2515,10 @@ static void randomize_key(unsigned char* key,int key_data_len)
randomized = 1;
}
#else /* !WIN32 */
-#ifdef RANDOM_FILE
- FILE *f = fopen(RANDOM_FILE, "rb");
+#ifdef CARES_RANDOM_FILE
+ FILE *f = fopen(CARES_RANDOM_FILE, "rb");
if(f) {
+ setvbuf(f, NULL, _IONBF, 0);
counter = aresx_uztosi(fread(key, 1, key_data_len, f));
fclose(f);
}
diff --git a/src/lib/ares_library_init.c b/src/lib/ares_library_init.c
index 6756349..e0055d4 100644
--- a/src/lib/ares_library_init.c
+++ b/src/lib/ares_library_init.c
@@ -40,13 +40,18 @@ static unsigned int ares_initialized;
static int ares_init_flags;
/* library-private global vars with visibility across the whole library */
+
+/* Some systems may return either NULL or a valid pointer on malloc(0). c-ares should
+ * never call malloc(0) so lets return NULL so we're more likely to find an issue if it
+ * were to occur. */
+
+static void *default_malloc(size_t size) { if (size == 0) { return NULL; } return malloc(size); }
+
#if defined(WIN32)
/* We need indirections to handle Windows DLL rules. */
-static void *default_malloc(size_t size) { return malloc(size); }
static void *default_realloc(void *p, size_t size) { return realloc(p, size); }
static void default_free(void *p) { free(p); }
#else
-# define default_malloc malloc
# define default_realloc realloc
# define default_free free
#endif
diff --git a/src/lib/ares_library_init.h b/src/lib/ares_library_init.h
index 2a2ba11..b3896d9 100644
--- a/src/lib/ares_library_init.h
+++ b/src/lib/ares_library_init.h
@@ -23,7 +23,7 @@
#ifdef USE_WINSOCK
#include <iphlpapi.h>
-#include <ares_iphlpapi.h>
+#include "ares_iphlpapi.h"
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
diff --git a/src/lib/ares_parse_a_reply.c b/src/lib/ares_parse_a_reply.c
index e71c993..ee903c7 100644
--- a/src/lib/ares_parse_a_reply.c
+++ b/src/lib/ares_parse_a_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -48,168 +42,49 @@
#include "ares_private.h"
int ares_parse_a_reply(const unsigned char *abuf, int alen,
- struct hostent **host,
- struct ares_addrttl *addrttls, int *naddrttls)
+ struct hostent **host, struct ares_addrttl *addrttls,
+ int *naddrttls)
{
struct ares_addrinfo ai;
- struct ares_addrinfo_node *next;
- struct ares_addrinfo_cname *next_cname;
- char **aliases = NULL;
char *question_hostname = NULL;
- struct hostent *hostent = NULL;
- struct in_addr *addrs = NULL;
- int naliases = 0, naddrs = 0, alias = 0, i;
- int cname_ttl = INT_MAX;
int status;
+ int req_naddrttls = 0;
- memset(&ai, 0, sizeof(ai));
-
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
- if (status != ARES_SUCCESS)
- {
- ares_free(question_hostname);
-
- if (naddrttls)
- {
- *naddrttls = 0;
- }
-
- return status;
- }
-
- hostent = ares_malloc(sizeof(struct hostent));
- if (!hostent)
- {
- goto enomem;
- }
-
- next = ai.nodes;
- while (next)
- {
- if (next->ai_family == AF_INET)
- {
- ++naddrs;
- }
- next = next->ai_next;
- }
-
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- ++naliases;
- next_cname = next_cname->next;
- }
-
- aliases = ares_malloc((naliases + 1) * sizeof(char *));
- if (!aliases)
- {
- goto enomem;
- }
-
- if (naliases)
- {
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- aliases[alias++] = strdup(next_cname->alias);
- if(next_cname->ttl < cname_ttl)
- cname_ttl = next_cname->ttl;
- next_cname = next_cname->next;
- }
- }
-
- aliases[alias] = NULL;
-
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (!hostent->h_addr_list)
+ if (naddrttls)
{
- goto enomem;
+ req_naddrttls = *naddrttls;
+ *naddrttls = 0;
}
- for (i = 0; i < naddrs + 1; ++i)
- {
- hostent->h_addr_list[i] = NULL;
- }
+ memset(&ai, 0, sizeof(ai));
- if (ai.cnames)
- {
- hostent->h_name = strdup(ai.cnames->name);
- ares_free(question_hostname);
- }
- else
+ status = ares__parse_into_addrinfo(abuf, alen, 0, 0, &ai);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- hostent->h_name = question_hostname;
+ goto fail;
}
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET;
- hostent->h_length = sizeof(struct in_addr);
-
- if (naddrs)
+ if (host != NULL)
{
- addrs = ares_malloc(naddrs * sizeof(struct in_addr));
- if (!addrs)
- {
- goto enomem;
- }
-
- i = 0;
- next = ai.nodes;
- while (next)
+ status = ares__addrinfo2hostent(&ai, AF_INET, host);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- if (next->ai_family == AF_INET)
- {
- hostent->h_addr_list[i] = (char *)&addrs[i];
- memcpy(hostent->h_addr_list[i],
- &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
- sizeof(struct in_addr));
- if (naddrttls && i < *naddrttls)
- {
- if (next->ai_ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- else
- addrttls[i].ttl = next->ai_ttl;
-
- memcpy(&addrttls[i].ipaddr,
- &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr),
- sizeof(struct in_addr));
- }
- ++i;
- }
- next = next->ai_next;
- }
- if (i == 0)
- {
- ares_free(addrs);
+ goto fail;
}
}
- if (host)
- {
- *host = hostent;
- }
- else
- {
- ares_free_hostent(hostent);
- }
+ if (addrttls != NULL && req_naddrttls)
+ {
+ ares__addrinfo2addrttl(&ai, AF_INET, req_naddrttls, addrttls,
+ NULL, naddrttls);
+ }
- if (naddrttls)
- {
- /* Truncated to at most *naddrttls entries */
- *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
- }
-
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- return ARES_SUCCESS;
-enomem:
- ares_free(aliases);
- ares_free(hostent);
+fail:
ares__freeaddrinfo_cnames(ai.cnames);
ares__freeaddrinfo_nodes(ai.nodes);
+ ares_free(ai.name);
ares_free(question_hostname);
- return ARES_ENOMEM;
+
+ return status;
}
diff --git a/src/lib/ares_parse_aaaa_reply.c b/src/lib/ares_parse_aaaa_reply.c
index 346d430..091065d 100644
--- a/src/lib/ares_parse_aaaa_reply.c
+++ b/src/lib/ares_parse_aaaa_reply.c
@@ -27,14 +27,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -54,165 +48,45 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
int *naddrttls)
{
struct ares_addrinfo ai;
- struct ares_addrinfo_node *next;
- struct ares_addrinfo_cname *next_cname;
- char **aliases = NULL;
char *question_hostname = NULL;
- struct hostent *hostent = NULL;
- struct ares_in6_addr *addrs = NULL;
- int naliases = 0, naddrs = 0, alias = 0, i;
- int cname_ttl = INT_MAX;
int status;
+ int req_naddrttls = 0;
- memset(&ai, 0, sizeof(ai));
-
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
- if (status != ARES_SUCCESS)
- {
- ares_free(question_hostname);
-
- if (naddrttls)
- {
- *naddrttls = 0;
- }
-
- return status;
- }
-
- hostent = ares_malloc(sizeof(struct hostent));
- if (!hostent)
- {
- goto enomem;
- }
-
- next = ai.nodes;
- while (next)
- {
- if(next->ai_family == AF_INET6)
- {
- ++naddrs;
- }
- next = next->ai_next;
- }
-
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- ++naliases;
- next_cname = next_cname->next;
- }
-
- aliases = ares_malloc((naliases + 1) * sizeof(char *));
- if (!aliases)
- {
- goto enomem;
- }
-
- if (naliases)
- {
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- aliases[alias++] = strdup(next_cname->alias);
- if(next_cname->ttl < cname_ttl)
- cname_ttl = next_cname->ttl;
- next_cname = next_cname->next;
- }
- }
-
- aliases[alias] = NULL;
-
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (!hostent->h_addr_list)
+ if (naddrttls)
{
- goto enomem;
+ req_naddrttls = *naddrttls;
+ *naddrttls = 0;
}
- for (i = 0; i < naddrs + 1; ++i)
- {
- hostent->h_addr_list[i] = NULL;
- }
+ memset(&ai, 0, sizeof(ai));
- if (ai.cnames)
+ status = ares__parse_into_addrinfo(abuf, alen, 0, 0, &ai);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- hostent->h_name = strdup(ai.cnames->name);
- ares_free(question_hostname);
+ goto fail;
}
- else
- {
- hostent->h_name = question_hostname;
- }
-
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET6;
- hostent->h_length = sizeof(struct ares_in6_addr);
- if (naddrs)
+ if (host != NULL)
{
- addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
- if (!addrs)
+ status = ares__addrinfo2hostent(&ai, AF_INET6, host);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- goto enomem;
+ goto fail;
}
-
- i = 0;
- next = ai.nodes;
- while (next)
- {
- if(next->ai_family == AF_INET6)
- {
- hostent->h_addr_list[i] = (char*)&addrs[i];
- memcpy(hostent->h_addr_list[i],
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
- if (naddrttls && i < *naddrttls)
- {
- if(next->ai_ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- else
- addrttls[i].ttl = next->ai_ttl;
-
- memcpy(&addrttls[i].ip6addr,
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
- }
- ++i;
- }
- next = next->ai_next;
- }
-
- if (i == 0)
- {
- ares_free(addrs);
- }
- }
-
- if (host)
- {
- *host = hostent;
- }
- else
- {
- ares_free_hostent(hostent);
- }
-
- if (naddrttls)
- {
- /* Truncated to at most *naddrttls entries */
- *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
}
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- return ARES_SUCCESS;
+ if (addrttls != NULL && req_naddrttls)
+ {
+ ares__addrinfo2addrttl(&ai, AF_INET6, req_naddrttls, NULL,
+ addrttls, naddrttls);
+ }
-enomem:
- ares_free(aliases);
- ares_free(hostent);
+fail:
ares__freeaddrinfo_cnames(ai.cnames);
ares__freeaddrinfo_nodes(ai.nodes);
ares_free(question_hostname);
- return ARES_ENOMEM;
+ ares_free(ai.name);
+
+ return status;
}
+
diff --git a/src/lib/ares_parse_caa_reply.c b/src/lib/ares_parse_caa_reply.c
index 620f444..f6d4d3c 100644
--- a/src/lib/ares_parse_caa_reply.c
+++ b/src/lib/ares_parse_caa_reply.c
@@ -25,14 +25,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -43,10 +37,6 @@
#include "ares_data.h"
#include "ares_private.h"
-#ifndef T_CAA
-# define T_CAA 257 /* Certification Authority Authorization */
-#endif
-
int
ares_parse_caa_reply (const unsigned char *abuf, int alen,
struct ares_caa_reply **caa_out)
diff --git a/src/lib/ares_parse_mx_reply.c b/src/lib/ares_parse_mx_reply.c
index e633647..a497f55 100644
--- a/src/lib/ares_parse_mx_reply.c
+++ b/src/lib/ares_parse_mx_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
diff --git a/src/lib/ares_parse_naptr_reply.c b/src/lib/ares_parse_naptr_reply.c
index 6216ca7..dd984c0 100644
--- a/src/lib/ares_parse_naptr_reply.c
+++ b/src/lib/ares_parse_naptr_reply.c
@@ -26,25 +26,14 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_data.h"
#include "ares_private.h"
-/* AIX portability check */
-#ifndef T_NAPTR
- #define T_NAPTR 35 /* naming authority pointer */
-#endif
-
int
ares_parse_naptr_reply (const unsigned char *abuf, int alen,
struct ares_naptr_reply **naptr_out)
@@ -110,12 +99,6 @@ 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)
diff --git a/src/lib/ares_parse_ns_reply.c b/src/lib/ares_parse_ns_reply.c
index 7bb5142..47d1299 100644
--- a/src/lib/ares_parse_ns_reply.c
+++ b/src/lib/ares_parse_ns_reply.c
@@ -29,14 +29,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
@@ -68,7 +62,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len);
+ status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len, 0);
if ( status != ARES_SUCCESS )
return status;
if ( aptr + len + QFIXEDSZ > abuf + alen )
@@ -91,7 +85,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
for ( i = 0; i < ( int ) ancount; i++ )
{
/* Decode the RR up to the data field. */
- status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len );
+ status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len, 0);
if ( status != ARES_SUCCESS )
break;
aptr += len;
@@ -116,7 +110,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
{
/* Decode the RR data and add it to the nameservers list */
status = ares__expand_name_for_response( aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if ( status != ARES_SUCCESS )
{
ares_free(rr_name);
diff --git a/src/lib/ares_parse_ptr_reply.c b/src/lib/ares_parse_ptr_reply.c
index 29e22cb..ae78edf 100644
--- a/src/lib/ares_parse_ptr_reply.c
+++ b/src/lib/ares_parse_ptr_reply.c
@@ -22,14 +22,8 @@
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -48,7 +42,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
long len;
const unsigned char *aptr;
char *ptrname, *hostname, *rr_name, *rr_data;
- struct hostent *hostent;
+ struct hostent *hostent = NULL;
int aliascnt = 0;
int alias_alloc = 8;
char ** aliases;
@@ -69,7 +63,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
- status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len, 0);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
@@ -90,7 +84,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
- status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len, 0);
if (status != ARES_SUCCESS)
break;
aptr += len;
@@ -116,7 +110,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
{
/* Decode the RR data and set hostname to it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -152,7 +146,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
{
/* Decode the RR data and replace ptrname with it. */
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
- &len);
+ &len, 1);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -175,41 +169,54 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
status = ARES_ENODATA;
if (status == ARES_SUCCESS)
{
- /* We got our answer. Allocate memory to build the host entry. */
- hostent = ares_malloc(sizeof(struct hostent));
- if (hostent)
- {
- hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
- if (hostent->h_addr_list)
- {
- hostent->h_addr_list[0] = ares_malloc(addrlen);
- if (hostent->h_addr_list[0])
- {
- hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *));
- if (hostent->h_aliases)
- {
- /* Fill in the hostent and return successfully. */
- hostent->h_name = hostname;
- for (i=0 ; i<aliascnt ; i++)
- hostent->h_aliases[i] = aliases[i];
- hostent->h_aliases[aliascnt] = NULL;
- hostent->h_addrtype = aresx_sitoss(family);
- hostent->h_length = aresx_sitoss(addrlen);
- memcpy(hostent->h_addr_list[0], addr, addrlen);
- hostent->h_addr_list[1] = NULL;
- *host = hostent;
- ares_free(aliases);
- ares_free(ptrname);
- return ARES_SUCCESS;
- }
- ares_free(hostent->h_addr_list[0]);
- }
- ares_free(hostent->h_addr_list);
- }
- ares_free(hostent);
- }
+ /* If we don't reach the end, we must have failed due to out of memory */
status = ARES_ENOMEM;
+
+ /* We got our answer. Allocate memory to build the host entry. */
+ hostent = ares_malloc(sizeof(*hostent));
+ if (!hostent)
+ goto fail;
+
+ /* If we don't memset here, cleanups may fail */
+ memset(hostent, 0, sizeof(*hostent));
+
+ hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
+ if (!hostent->h_addr_list)
+ goto fail;
+
+
+ if (addr && addrlen) {
+ hostent->h_addr_list[0] = ares_malloc(addrlen);
+ if (!hostent->h_addr_list[0])
+ goto fail;
+ } else {
+ hostent->h_addr_list[0] = NULL;
+ }
+
+ hostent->h_aliases = ares_malloc((aliascnt+1) * sizeof (char *));
+ if (!hostent->h_aliases)
+ goto fail;
+
+ /* Fill in the hostent and return successfully. */
+ hostent->h_name = hostname;
+ for (i=0 ; i<aliascnt ; i++)
+ hostent->h_aliases[i] = aliases[i];
+ hostent->h_aliases[aliascnt] = NULL;
+ hostent->h_addrtype = aresx_sitoss(family);
+ hostent->h_length = aresx_sitoss(addrlen);
+ if (addr && addrlen)
+ memcpy(hostent->h_addr_list[0], addr, addrlen);
+ hostent->h_addr_list[1] = NULL;
+ *host = hostent;
+ ares_free(aliases);
+ ares_free(ptrname);
+
+ return ARES_SUCCESS;
}
+
+fail:
+ ares_free_hostent(hostent);
+
for (i=0 ; i<aliascnt ; i++)
if (aliases[i])
ares_free(aliases[i]);
diff --git a/src/lib/ares_parse_soa_reply.c b/src/lib/ares_parse_soa_reply.c
index 7cfaed2..3935eec 100644
--- a/src/lib/ares_parse_soa_reply.c
+++ b/src/lib/ares_parse_soa_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
@@ -62,11 +56,11 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
return ARES_EBADRESP;
if (ancount == 0)
return ARES_EBADRESP;
-
+
aptr = abuf + HFIXEDSZ;
/* query name */
- status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len);
+ status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len, 0);
if (status != ARES_SUCCESS)
goto failed_stat;
@@ -89,7 +83,7 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
for (i = 0; i < ancount; i++)
{
rr_name = NULL;
- status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len);
+ status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len, 0);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -126,7 +120,7 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
/* nsname */
status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname,
- &len);
+ &len, 0);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -136,7 +130,7 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
/* hostmaster */
status = ares__expand_name_for_response(aptr, abuf, alen,
- &soa->hostmaster, &len);
+ &soa->hostmaster, &len, 0);
if (status != ARES_SUCCESS)
{
ares_free(rr_name);
@@ -164,9 +158,9 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen,
return ARES_SUCCESS;
}
aptr += rr_len;
-
+
ares_free(rr_name);
-
+
if (aptr > abuf + alen)
goto failed_stat;
}
diff --git a/src/lib/ares_parse_srv_reply.c b/src/lib/ares_parse_srv_reply.c
index 824ff3a..0d8f4d2 100644
--- a/src/lib/ares_parse_srv_reply.c
+++ b/src/lib/ares_parse_srv_reply.c
@@ -26,25 +26,14 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
#include "ares_data.h"
#include "ares_private.h"
-/* AIX portability check */
-#ifndef T_SRV
-# define T_SRV 33 /* server selection */
-#endif
-
int
ares_parse_srv_reply (const unsigned char *abuf, int alen,
struct ares_srv_reply **srv_out)
diff --git a/src/lib/ares_parse_txt_reply.c b/src/lib/ares_parse_txt_reply.c
index 3f47e23..6848a09 100644
--- a/src/lib/ares_parse_txt_reply.c
+++ b/src/lib/ares_parse_txt_reply.c
@@ -26,14 +26,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
diff --git a/src/lib/ares_parse_uri_reply.c b/src/lib/ares_parse_uri_reply.c
new file mode 100644
index 0000000..d79b5c4
--- /dev/null
+++ b/src/lib/ares_parse_uri_reply.c
@@ -0,0 +1,184 @@
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2009 by Jakub Hrozek <jhrozek@redhat.com>
+ *
+ * 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.
+ */
+
+#include "ares_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#include "ares_nameser.h"
+
+#include "ares.h"
+#include "ares_dns.h"
+#include "ares_data.h"
+#include "ares_private.h"
+
+/* AIX portability check */
+#ifndef T_URI
+# define T_URI 256 /* uri selection */
+#endif
+
+int
+ares_parse_uri_reply (const unsigned char *abuf, int alen,
+ struct ares_uri_reply **uri_out)
+{
+ unsigned int qdcount, ancount, i;
+ const unsigned char *aptr, *vptr;
+ int status, rr_type, rr_class, rr_len, rr_ttl;
+ long len;
+ char *uri_str = NULL, *rr_name = NULL;
+ struct ares_uri_reply *uri_head = NULL;
+ struct ares_uri_reply *uri_last = NULL;
+ struct ares_uri_reply *uri_curr;
+
+ /* Set *uri_out to NULL for all failure cases. */
+ *uri_out = NULL;
+
+ /* Give up if abuf doesn't have room for a header. */
+ if (alen < HFIXEDSZ){
+ return ARES_EBADRESP;
+ }
+
+ /* Fetch the question and answer count from the header. */
+ qdcount = DNS_HEADER_QDCOUNT (abuf);
+ ancount = DNS_HEADER_ANCOUNT (abuf);
+ if (qdcount != 1) {
+ return ARES_EBADRESP;
+ }
+ if (ancount == 0) {
+ return ARES_ENODATA;
+ }
+ /* Expand the name from the question, and skip past the question. */
+ aptr = abuf + HFIXEDSZ;
+
+ status = ares_expand_name (aptr, abuf, alen, &uri_str, &len);
+ if (status != ARES_SUCCESS){
+ return status;
+ }
+ if (aptr + len + QFIXEDSZ > abuf + alen)
+ {
+ ares_free (uri_str);
+ return ARES_EBADRESP;
+ }
+ aptr += len + QFIXEDSZ;
+
+ /* Examine each answer resource record (RR) in turn. */
+ for (i = 0; i < ancount; i++)
+ {
+ /* Decode the RR up to the data field. */
+ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
+ if (status != ARES_SUCCESS)
+ {
+ break;
+ }
+ aptr += len;
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+
+ rr_type = DNS_RR_TYPE (aptr);
+ rr_class = DNS_RR_CLASS (aptr);
+ rr_ttl = DNS_RR_TTL(aptr);
+ rr_len = DNS_RR_LEN (aptr);
+ aptr += RRFIXEDSZ;
+
+ if (aptr + rr_len > abuf + alen)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+
+ /* Check if we are really looking at a URI record */
+ if (rr_class == C_IN && rr_type == T_URI)
+ {
+ /* parse the URI record itself */
+ if (rr_len < 5)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
+ /* Allocate storage for this URI answer appending it to the list */
+ uri_curr = ares_malloc_data(ARES_DATATYPE_URI_REPLY);
+ if (!uri_curr)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ if (uri_last)
+ {
+ uri_last->next = uri_curr;
+ }
+ else
+ {
+ uri_head = uri_curr;
+ }
+ uri_last = uri_curr;
+
+ vptr = aptr;
+ uri_curr->priority = DNS__16BIT(vptr);
+ vptr += sizeof(unsigned short);
+ uri_curr->weight = DNS__16BIT(vptr);
+ vptr += sizeof(unsigned short);
+ uri_curr->uri = (char *)ares_malloc(rr_len-3);
+ if (!uri_curr->uri)
+ {
+ status = ARES_ENOMEM;
+ break;
+ }
+ uri_curr->uri = strncpy(uri_curr->uri, (const char *)vptr, rr_len-4);
+ uri_curr->uri[rr_len-4]='\0';
+ uri_curr->ttl = rr_ttl;
+
+ if (status != ARES_SUCCESS)
+ break;
+ }
+
+ /* Don't lose memory in the next iteration */
+ ares_free (rr_name);
+ rr_name = NULL;
+
+ /* Move on to the next record */
+ aptr += rr_len;
+ }
+
+ if (uri_str)
+ ares_free (uri_str);
+ if (rr_name)
+ ares_free (rr_name);
+
+ /* clean up on error */
+ if (status != ARES_SUCCESS)
+ {
+ if (uri_head)
+ ares_free_data (uri_head);
+ return status;
+ }
+
+ /* everything looks fine, return the data */
+ *uri_out = uri_head;
+
+ return ARES_SUCCESS;
+}
diff --git a/src/lib/ares_private.h b/src/lib/ares_private.h
index 50b2ba0..60d69e0 100644
--- a/src/lib/ares_private.h
+++ b/src/lib/ares_private.h
@@ -85,6 +85,11 @@ W32_FUNC const char *_w32_GetHostsFile (void);
#define PATH_HOSTS "InetDBase:Hosts"
+#elif defined(__HAIKU__)
+
+#define PATH_RESOLV_CONF "/system/settings/network/resolv.conf"
+#define PATH_HOSTS "/system/settings/network/hosts"
+
#else
#define PATH_RESOLV_CONF "/etc/resolv.conf"
@@ -356,9 +361,13 @@ int ares__read_line(FILE *fp, char **buf, size_t *bufsize);
void ares__free_query(struct query *query);
unsigned short ares__generate_new_id(rc4_key* key);
struct timeval ares__tvnow(void);
+int ares__expand_name_validated(const unsigned char *encoded,
+ const unsigned char *abuf,
+ int alen, char **s, long *enclen,
+ int is_hostname);
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
- char **s, long *enclen);
+ char **s, long *enclen, int is_hostname);
void ares__init_servers_state(ares_channel channel);
void ares__destroy_servers_state(ares_channel channel);
int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype);
@@ -383,17 +392,26 @@ void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname);
struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname);
+int ares_append_ai_node(int aftype, unsigned short port, int ttl,
+ const void *adata,
+ struct ares_addrinfo_node **nodes);
+
void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
struct ares_addrinfo_cname *tail);
int ares__parse_into_addrinfo(const unsigned char *abuf,
- int alen,
+ int alen, int cname_only_is_enodata,
+ unsigned short port,
struct ares_addrinfo *ai);
-int ares__parse_into_addrinfo2(const unsigned char *abuf,
- int alen,
- char **question_hostname,
- struct ares_addrinfo *ai);
+int ares__addrinfo2hostent(const struct ares_addrinfo *ai, int family,
+ struct hostent **host);
+int ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family,
+ int req_naddrttls, struct ares_addrttl *addrttls,
+ struct ares_addr6ttl *addr6ttls, int *naddrttls);
+int ares__addrinfo_localhost(const char *name, unsigned short port,
+ const struct ares_addrinfo_hints *hints,
+ struct ares_addrinfo *ai);
#if 0 /* Not used */
long ares__tvdiff(struct timeval t1, struct timeval t2);
diff --git a/src/lib/ares_process.c b/src/lib/ares_process.c
index 65c1b7f..87329e3 100644
--- a/src/lib/ares_process.c
+++ b/src/lib/ares_process.c
@@ -32,14 +32,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
-#include "nameser.h"
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -611,8 +605,7 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
packetsz = PACKETSZ;
/* If we use EDNS and server answers with FORMERR without an OPT RR, the protocol
* extension is not understood by the responder. We must retry the query
- * without EDNS enabled.
- */
+ * without EDNS enabled. */
if (channel->flags & ARES_FLAG_EDNS)
{
packetsz = channel->ednspsz;
diff --git a/src/lib/ares_query.c b/src/lib/ares_query.c
index 5bbb2f5..508274d 100644
--- a/src/lib/ares_query.c
+++ b/src/lib/ares_query.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
diff --git a/src/lib/ares_send.c b/src/lib/ares_send.c
index f4f1f95..75ba9e4 100644
--- a/src/lib/ares_send.c
+++ b/src/lib/ares_send.c
@@ -19,14 +19,8 @@
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_dns.h"
diff --git a/src/lib/ares_setup.h b/src/lib/ares_setup.h
index 4df7961..6ad2cee 100644
--- a/src/lib/ares_setup.h
+++ b/src/lib/ares_setup.h
@@ -178,8 +178,11 @@
/*
* Android does have the arpa/nameser.h header which is detected by configure
* but it appears to be empty with recent NDK r7b / r7c, so we undefine here.
+ * z/OS does have the arpa/nameser.h header which is detected by configure
+ * but it is not fully implemented and missing identifiers, so udefine here.
*/
-#if (defined(ANDROID) || defined(__ANDROID__)) && defined(HAVE_ARPA_NAMESER_H)
+#if (defined(ANDROID) || defined(__ANDROID__) || defined(__MVS__)) && \
+ defined(HAVE_ARPA_NAMESER_H)
# undef HAVE_ARPA_NAMESER_H
#endif
diff --git a/src/lib/ares_strdup.c b/src/lib/ares_strdup.c
index 0c3dcff..39fc869 100644
--- a/src/lib/ares_strdup.c
+++ b/src/lib/ares_strdup.c
@@ -22,28 +22,21 @@
char *ares_strdup(const char *s1)
{
-#ifdef HAVE_STRDUP
- if (ares_malloc == malloc)
- return strdup(s1);
- else
-#endif
- {
- size_t sz;
- char * s2;
+ size_t sz;
+ char * s2;
- if(s1) {
- sz = strlen(s1);
- if(sz < (size_t)-1) {
- sz++;
- if(sz < ((size_t)-1) / sizeof(char)) {
- s2 = ares_malloc(sz * sizeof(char));
- if(s2) {
- memcpy(s2, s1, sz * sizeof(char));
- return s2;
- }
+ if(s1) {
+ sz = strlen(s1);
+ if(sz < (size_t)-1) {
+ sz++;
+ if(sz < ((size_t)-1)) {
+ s2 = ares_malloc(sz);
+ if(s2) {
+ memcpy(s2, s1, sz);
+ return s2;
}
}
}
- return (char *)NULL;
}
+ return (char *)NULL;
}
diff --git a/src/lib/ares_strsplit.c b/src/lib/ares_strsplit.c
index b57a30f..97b4e5d 100644
--- a/src/lib/ares_strsplit.c
+++ b/src/lib/ares_strsplit.c
@@ -13,6 +13,10 @@
* without express or implied warranty.
*/
+#if defined(__MVS__)
+#include <strings.h>
+#endif
+
#include "ares_setup.h"
#include "ares_strsplit.h"
#include "ares.h"
diff --git a/src/lib/cares.rc b/src/lib/cares.rc
index 7da7e11..6360834 100644
--- a/src/lib/cares.rc
+++ b/src/lib/cares.rc
@@ -1,5 +1,5 @@
-/* Copyright (C) 2009-2016 by Daniel Stenberg
+/* Copyright (C) 2009-2021 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -39,7 +39,7 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "CompanyName", "The c-ares library, https://c-ares.haxx.se/\0"
+ VALUE "CompanyName", "The c-ares library, https://c-ares.org/\0"
#if defined(DEBUGBUILD) || defined(_DEBUG)
VALUE "FileDescription", "c-ares Debug Shared Library\0"
VALUE "FileVersion", ARES_VERSION_STR "\0"
@@ -54,7 +54,7 @@ BEGIN
VALUE "ProductName", "The c-ares library\0"
VALUE "ProductVersion", ARES_VERSION_STR "\0"
VALUE "LegalCopyright", "© " ARES_COPYRIGHT "\0"
- VALUE "License", "https://c-ares.haxx.se/license.html\0"
+ VALUE "License", "https://c-ares.org/license.html\0"
END
END
diff --git a/src/lib/inet_net_pton.c b/src/lib/inet_net_pton.c
index af1a534..840de50 100644
--- a/src/lib/inet_net_pton.c
+++ b/src/lib/inet_net_pton.c
@@ -24,14 +24,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_ipv6.h"
diff --git a/src/lib/inet_ntop.c b/src/lib/inet_ntop.c
index 1935a87..6645c0a 100644
--- a/src/lib/inet_ntop.c
+++ b/src/lib/inet_ntop.c
@@ -23,14 +23,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#include "ares.h"
#include "ares_ipv6.h"
diff --git a/src/lib/nameser.h b/src/lib/nameser.h
deleted file mode 100644
index 5c1acce..0000000
--- a/src/lib/nameser.h
+++ /dev/null
@@ -1,218 +0,0 @@
-
-#ifndef ARES_NAMESER_H
-#define ARES_NAMESER_H
-
-/* header file provided by liren@vivisimo.com */
-
-#ifndef HAVE_ARPA_NAMESER_H
-
-#define NS_PACKETSZ 512 /* maximum packet size */
-#define NS_MAXDNAME 256 /* maximum domain name */
-#define NS_MAXCDNAME 255 /* maximum compressed domain name */
-#define NS_MAXLABEL 63
-#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
-#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
-#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
-#define NS_INT16SZ 2
-#define NS_INADDRSZ 4
-#define NS_IN6ADDRSZ 16
-#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
-#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
-
-typedef enum __ns_class {
- ns_c_invalid = 0, /* Cookie. */
- ns_c_in = 1, /* Internet. */
- ns_c_2 = 2, /* unallocated/unsupported. */
- ns_c_chaos = 3, /* MIT Chaos-net. */
- ns_c_hs = 4, /* MIT Hesiod. */
- /* Query class values which do not appear in resource records */
- ns_c_none = 254, /* for prereq. sections in update requests */
- ns_c_any = 255, /* Wildcard match. */
- ns_c_max = 65536
-} ns_class;
-
-typedef enum __ns_type {
- ns_t_invalid = 0, /* Cookie. */
- ns_t_a = 1, /* Host address. */
- ns_t_ns = 2, /* Authoritative server. */
- ns_t_md = 3, /* Mail destination. */
- ns_t_mf = 4, /* Mail forwarder. */
- ns_t_cname = 5, /* Canonical name. */
- ns_t_soa = 6, /* Start of authority zone. */
- ns_t_mb = 7, /* Mailbox domain name. */
- ns_t_mg = 8, /* Mail group member. */
- ns_t_mr = 9, /* Mail rename name. */
- ns_t_null = 10, /* Null resource record. */
- ns_t_wks = 11, /* Well known service. */
- ns_t_ptr = 12, /* Domain name pointer. */
- ns_t_hinfo = 13, /* Host information. */
- ns_t_minfo = 14, /* Mailbox information. */
- ns_t_mx = 15, /* Mail routing information. */
- ns_t_txt = 16, /* Text strings. */
- ns_t_rp = 17, /* Responsible person. */
- ns_t_afsdb = 18, /* AFS cell database. */
- ns_t_x25 = 19, /* X_25 calling address. */
- ns_t_isdn = 20, /* ISDN calling address. */
- ns_t_rt = 21, /* Router. */
- ns_t_nsap = 22, /* NSAP address. */
- ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
- ns_t_sig = 24, /* Security signature. */
- ns_t_key = 25, /* Security key. */
- ns_t_px = 26, /* X.400 mail mapping. */
- ns_t_gpos = 27, /* Geographical position (withdrawn). */
- ns_t_aaaa = 28, /* Ip6 Address. */
- ns_t_loc = 29, /* Location Information. */
- ns_t_nxt = 30, /* Next domain (security). */
- ns_t_eid = 31, /* Endpoint identifier. */
- ns_t_nimloc = 32, /* Nimrod Locator. */
- ns_t_srv = 33, /* Server Selection. */
- ns_t_atma = 34, /* ATM Address */
- ns_t_naptr = 35, /* Naming Authority PoinTeR */
- ns_t_kx = 36, /* Key Exchange */
- ns_t_cert = 37, /* Certification record */
- ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
- ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
- ns_t_sink = 40, /* Kitchen sink (experimentatl) */
- ns_t_opt = 41, /* EDNS0 option (meta-RR) */
- ns_t_apl = 42, /* Address prefix list (RFC3123) */
- ns_t_ds = 43, /* Delegation Signer (RFC4034) */
- ns_t_sshfp = 44, /* SSH Key Fingerprint (RFC4255) */
- ns_t_rrsig = 46, /* Resource Record Signature (RFC4034) */
- ns_t_nsec = 47, /* Next Secure (RFC4034) */
- ns_t_dnskey = 48, /* DNS Public Key (RFC4034) */
- ns_t_tkey = 249, /* Transaction key */
- ns_t_tsig = 250, /* Transaction signature. */
- ns_t_ixfr = 251, /* Incremental zone transfer. */
- ns_t_axfr = 252, /* Transfer zone of authority. */
- ns_t_mailb = 253, /* Transfer mailbox records. */
- ns_t_maila = 254, /* Transfer mail agent records. */
- ns_t_any = 255, /* Wildcard match. */
- ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
- ns_t_caa = 257, /* Certification Authority Authorization. */
- ns_t_max = 65536
-} ns_type;
-
-typedef enum __ns_opcode {
- ns_o_query = 0, /* Standard query. */
- ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
- ns_o_status = 2, /* Name server status query (unsupported). */
- /* Opcode 3 is undefined/reserved. */
- ns_o_notify = 4, /* Zone change notification. */
- ns_o_update = 5, /* Zone update message. */
- ns_o_max = 6
-} ns_opcode;
-
-typedef enum __ns_rcode {
- ns_r_noerror = 0, /* No error occurred. */
- ns_r_formerr = 1, /* Format error. */
- ns_r_servfail = 2, /* Server failure. */
- ns_r_nxdomain = 3, /* Name error. */
- ns_r_notimpl = 4, /* Unimplemented. */
- ns_r_refused = 5, /* Operation refused. */
- /* these are for BIND_UPDATE */
- ns_r_yxdomain = 6, /* Name exists */
- ns_r_yxrrset = 7, /* RRset exists */
- ns_r_nxrrset = 8, /* RRset does not exist */
- ns_r_notauth = 9, /* Not authoritative for zone */
- ns_r_notzone = 10, /* Zone of record different from zone section */
- ns_r_max = 11,
- /* The following are TSIG extended errors */
- ns_r_badsig = 16,
- ns_r_badkey = 17,
- ns_r_badtime = 18
-} ns_rcode;
-
-#endif /* HAVE_ARPA_NAMESER_H */
-
-#ifndef HAVE_ARPA_NAMESER_COMPAT_H
-
-#define PACKETSZ NS_PACKETSZ
-#define MAXDNAME NS_MAXDNAME
-#define MAXCDNAME NS_MAXCDNAME
-#define MAXLABEL NS_MAXLABEL
-#define HFIXEDSZ NS_HFIXEDSZ
-#define QFIXEDSZ NS_QFIXEDSZ
-#define RRFIXEDSZ NS_RRFIXEDSZ
-#define INDIR_MASK NS_CMPRSFLGS
-#define NAMESERVER_PORT NS_DEFAULTPORT
-
-#define QUERY ns_o_query
-
-#define SERVFAIL ns_r_servfail
-#define NOTIMP ns_r_notimpl
-#define REFUSED ns_r_refused
-#undef NOERROR /* it seems this is already defined in winerror.h */
-#define NOERROR ns_r_noerror
-#define FORMERR ns_r_formerr
-#define NXDOMAIN ns_r_nxdomain
-
-#define C_IN ns_c_in
-#define C_CHAOS ns_c_chaos
-#define C_HS ns_c_hs
-#define C_NONE ns_c_none
-#define C_ANY ns_c_any
-
-#define T_A ns_t_a
-#define T_NS ns_t_ns
-#define T_MD ns_t_md
-#define T_MF ns_t_mf
-#define T_CNAME ns_t_cname
-#define T_SOA ns_t_soa
-#define T_MB ns_t_mb
-#define T_MG ns_t_mg
-#define T_MR ns_t_mr
-#define T_NULL ns_t_null
-#define T_WKS ns_t_wks
-#define T_PTR ns_t_ptr
-#define T_HINFO ns_t_hinfo
-#define T_MINFO ns_t_minfo
-#define T_MX ns_t_mx
-#define T_TXT ns_t_txt
-#define T_RP ns_t_rp
-#define T_AFSDB ns_t_afsdb
-#define T_X25 ns_t_x25
-#define T_ISDN ns_t_isdn
-#define T_RT ns_t_rt
-#define T_NSAP ns_t_nsap
-#define T_NSAP_PTR ns_t_nsap_ptr
-#define T_SIG ns_t_sig
-#define T_KEY ns_t_key
-#define T_PX ns_t_px
-#define T_GPOS ns_t_gpos
-#define T_AAAA ns_t_aaaa
-#define T_LOC ns_t_loc
-#define T_NXT ns_t_nxt
-#define T_EID ns_t_eid
-#define T_NIMLOC ns_t_nimloc
-#define T_SRV ns_t_srv
-#define T_ATMA ns_t_atma
-#define T_NAPTR ns_t_naptr
-#define T_KX ns_t_kx
-#define T_CERT ns_t_cert
-#define T_A6 ns_t_a6
-#define T_DNAME ns_t_dname
-#define T_SINK ns_t_sink
-#define T_OPT ns_t_opt
-#define T_APL ns_t_apl
-#define T_DS ns_t_ds
-#define T_SSHFP ns_t_sshfp
-#define T_RRSIG ns_t_rrsig
-#define T_NSEC ns_t_nsec
-#define T_DNSKEY ns_t_dnskey
-#define T_TKEY ns_t_tkey
-#define T_TSIG ns_t_tsig
-#define T_IXFR ns_t_ixfr
-#define T_AXFR ns_t_axfr
-#define T_MAILB ns_t_mailb
-#define T_MAILA ns_t_maila
-#define T_CAA ns_t_caa
-#define T_ANY ns_t_any
-
-#endif /* HAVE_ARPA_NAMESER_COMPAT_H */
-
-/* Android's bionic arpa/nameser_compat.h, nor glibc versions prior to 2.25 have T_OPT defined */
-#ifndef T_OPT
-# define T_OPT ns_t_opt
-#endif
-
-#endif /* ARES_NAMESER_H */