diff options
Diffstat (limited to 'src')
50 files changed, 1722 insertions, 1457 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 094b00d..999e965 100644 --- a/src/Makefile.in +++ b/src/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, @@ -89,12 +89,18 @@ build_triplet = @build@ host_triplet = @host@ subdir = src 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 \ @@ -104,9 +110,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) @@ -168,8 +172,6 @@ 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 DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -210,17 +212,22 @@ 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@ CFLAGS = @CFLAGS@ 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@ @@ -235,6 +242,7 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV = @GCOV@ @@ -274,7 +282,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@ @@ -312,6 +319,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@ @@ -350,9 +359,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile + $(AUTOMAKE) --foreign src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -475,7 +484,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 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 *)∈ - } - 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 a14c226..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) 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 */ diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 3fe2814..c503723 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -15,6 +15,10 @@ AM_CPPFLAGS = -I$(top_builddir)/include \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/lib +if USE_CPPFLAG_CARES_STATICLIB +AM_CPPFLAGS += $(CPPFLAG_CARES_STATICLIB) +endif + include Makefile.inc LDADD = $(top_builddir)/src/lib/libcares.la diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in index 38b7cc6..e665ac9 100644 --- a/src/tools/Makefile.in +++ b/src/tools/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, @@ -89,14 +89,21 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = $(am__EXEEXT_1) +@USE_CPPFLAG_CARES_STATICLIB_TRUE@am__append_1 = $(CPPFLAG_CARES_STATICLIB) subdir = src/tools 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 \ @@ -106,9 +113,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) @@ -227,8 +232,6 @@ 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 \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -244,17 +247,22 @@ 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@ CFLAGS = @CFLAGS@ 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@ @@ -269,6 +277,7 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV = @GCOV@ @@ -308,7 +317,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@ @@ -346,6 +354,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@ @@ -378,11 +388,9 @@ EXTRA_DIST = CMakeLists.txt Makefile.inc # $(top_builddir), to ensure that these paths which belong to the library # 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 \ - -I$(top_srcdir)/src/lib - +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/src/lib \ + -I$(top_srcdir)/include -I$(top_srcdir)/src/lib \ + $(am__append_1) SAMPLESOURCES = ares_getopt.c \ ../lib/ares_nowarn.c \ ../lib/ares_strcasecmp.c @@ -750,7 +758,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 diff --git a/src/tools/adig.c b/src/tools/adig.c index 9c3747a..412ad46 100644 --- a/src/tools/adig.c +++ b/src/tools/adig.c @@ -25,14 +25,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> @@ -62,30 +56,6 @@ #undef WIN32 /* Redefined in MingW headers */ #endif -#ifndef T_SRV -# define T_SRV 33 /* Server selection */ -#endif -#ifndef T_NAPTR -# define T_NAPTR 35 /* Naming authority pointer */ -#endif -#ifndef T_DS -# define T_DS 43 /* Delegation Signer (RFC4034) */ -#endif -#ifndef T_SSHFP -# define T_SSHFP 44 /* SSH Key Fingerprint (RFC4255) */ -#endif -#ifndef T_RRSIG -# define T_RRSIG 46 /* Resource Record Signature (RFC4034) */ -#endif -#ifndef T_NSEC -# define T_NSEC 47 /* Next Secure (RFC4034) */ -#endif -#ifndef T_DNSKEY -# define T_DNSKEY 48 /* DNS Public Key (RFC4034) */ -#endif -#ifndef T_CAA -# define T_CAA 257 /* Certification Authority Authorization */ -#endif struct nv { const char *name; @@ -151,6 +121,7 @@ static const struct nv types[] = { { "NSEC", T_NSEC }, { "DNSKEY", T_DNSKEY }, { "CAA", T_CAA }, + { "URI", T_URI }, { "ANY", T_ANY } }; static const int ntypes = sizeof(types) / sizeof(types[0]); @@ -335,7 +306,7 @@ int main(int argc, char **argv) options.udp_port = (unsigned short)strtol(optarg, NULL, 0); optmask |= ARES_OPT_UDP_PORT; break; - + case 'x': use_ptr_helper++; break; @@ -546,7 +517,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen) { const unsigned char *p; - int type, dnsclass, ttl, dlen, status; + int type, dnsclass, ttl, dlen, status, i; long len; int vlen; char addr[46]; @@ -703,7 +674,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, p += len; } break; - + case T_CAA: p = aptr; @@ -767,6 +738,18 @@ static const unsigned char *display_rr(const unsigned char *aptr, ares_free_string(name.as_char); break; + case T_URI: + /* The RR data is two two-byte numbers representing the + * priority and weight, followed by a target. + */ + + printf("\t%d ", (int)DNS__16BIT(aptr)); + printf("%d \t\t", (int)DNS__16BIT(aptr+2)); + p = aptr +4; + for (i=0; i <dlen-4; ++i) + printf("%c",p[i]); + break; + case T_NAPTR: printf("\t%d", (int)DNS__16BIT(aptr)); /* order */ @@ -992,7 +975,7 @@ static void print_help_info_adig(void) { " KEY, LOC, MAILA, MAILB, MB, MD,\n" " MF, MG, MINFO, MR, MX, NAPTR, NS,\n" " NSAP, NSAP_PTR, NULL, PTR, PX, RP,\n" - " RT, SIG, SOA, SRV, TXT, WKS, X25\n\n" + " RT, SIG, SOA, SRV, TXT, URI, WKS, X25\n\n" " -x : For a '-t PTR a.b.c.d' lookup, query for 'd.c.b.a.in-addr.arpa.'\n" " -xx : As above, but for IPv6, compact the format into a bitstring like\n" " '[xabcdef00000000000000000000000000].IP6.ARPA.'\n"); |