visaljs 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -4
- package/THIRD_PARTY_LICENSES +31 -1
- package/cli.js +3745 -890
- package/node/include/js_node.h +12 -1
- package/node/prelude/_http_common.js +29 -0
- package/node/prelude/async_hooks.js +50 -11
- package/node/prelude/child_process.js +31 -4
- package/node/prelude/console.js +311 -143
- package/node/prelude/crypto.js +6 -4
- package/node/prelude/dgram.js +1169 -0
- package/node/prelude/diagnostics_channel.js +3 -1
- package/node/prelude/dns.js +250 -45
- package/node/prelude/dns_promises.js +8 -2
- package/node/prelude/fs_promises.js +9 -1
- package/node/prelude/http.js +405 -94
- package/node/prelude/https.js +13 -4
- package/node/prelude/internal/console_class.js +7 -0
- package/node/prelude/internal/console_global.js +25 -0
- package/node/prelude/internal/crypto/key_encryption.js +217 -0
- package/node/prelude/internal/crypto/keys.js +161 -26
- package/node/prelude/internal/crypto/random.js +24 -0
- package/node/prelude/internal/crypto/util.js +2 -1
- package/node/prelude/internal/crypto_x509.js +161 -0
- package/node/prelude/internal/dns_classes.js +6 -0
- package/node/prelude/internal/dns_resolver.js +371 -0
- package/node/prelude/internal/errors.js +9 -0
- package/node/prelude/internal/events_on.js +82 -37
- package/node/prelude/internal/features.js +8 -4
- package/node/prelude/internal/fs_filehandle.js +10 -4
- package/node/prelude/internal/http_chars.ts +22 -0
- package/node/prelude/internal/perf_histogram.js +1 -1
- package/node/prelude/internal/process_more.js +32 -17
- package/node/prelude/internal/process_signals.js +8 -2
- package/node/prelude/internal/punycode.ts +163 -0
- package/node/prelude/internal/readline.js +648 -274
- package/node/prelude/internal/readline_editor.js +1240 -0
- package/node/prelude/internal/string_width.js +43 -0
- package/node/prelude/internal/tls/common.js +145 -33
- package/node/prelude/internal/tls/wrap.js +182 -49
- package/node/prelude/internal/tls/x509.js +4 -1
- package/node/prelude/internal/udp.js +177 -0
- package/node/prelude/net.js +30 -14
- package/node/prelude/os.js +24 -6
- package/node/prelude/perf_hooks.js +37 -2
- package/node/prelude/punycode.js +2 -130
- package/node/prelude/readline.js +113 -4
- package/node/prelude/readline_promises.js +56 -32
- package/node/prelude/tls.js +21 -4
- package/node/prelude/util.js +3 -16
- package/node/src/host_dns.c +623 -0
- package/node/src/host_http.c +12 -0
- package/node/src/host_net.c +46 -0
- package/node/src/host_os.c +1 -6
- package/node/src/host_sys.c +79 -0
- package/node/src/host_udp.c +418 -0
- package/node/third_party/c-ares/LICENSE.md +24 -0
- package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
- package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
- package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
- package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
- package/node/third_party/c-ares/include/ares.h +1237 -0
- package/node/third_party/c-ares/include/ares_build.h +202 -0
- package/node/third_party/c-ares/include/ares_dns.h +127 -0
- package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
- package/node/third_party/c-ares/include/ares_nameser.h +510 -0
- package/node/third_party/c-ares/include/ares_version.h +47 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
- package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
- package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
- package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
- package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
- package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
- package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
- package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
- package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
- package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
- package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
- package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
- package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
- package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
- package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
- package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
- package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
- package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
- package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
- package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
- package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
- package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
- package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
- package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
- package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
- package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
- package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
- package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
- package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
- package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
- package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
- package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
- package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
- package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
- package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
- package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
- package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
- package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
- package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
- package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
- package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
- package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
- package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
- package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
- package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
- package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
- package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
- package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
- package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
- package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
- package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
- package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
- package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
- package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
- package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
- package/package.json +1 -1
- package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
- package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
- package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
- package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
- package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
- package/runtime/include/js_buffer.h +185 -0
- package/runtime/include/js_builtins.h +58 -0
- package/runtime/include/js_crypto.h +11 -0
- package/runtime/include/js_exception.h +3 -0
- package/runtime/include/js_function.h +1 -1
- package/runtime/include/js_gc.h +13 -10
- package/runtime/include/js_jobs.h +2 -0
- package/runtime/include/js_object.h +79 -3
- package/runtime/include/js_ops.h +27 -0
- package/runtime/include/js_runtime.h +1 -0
- package/runtime/include/js_web.h +0 -3
- package/runtime/include/jscontext.h +8 -0
- package/runtime/src/builtins.c +17 -4
- package/runtime/src/crypto_internal.h +1 -0
- package/runtime/src/crypto_subtle.c +66 -7
- package/runtime/src/crypto_tls.c +265 -19
- package/runtime/src/function.c +37 -10
- package/runtime/src/gc.c +76 -93
- package/runtime/src/inspect.c +18 -1
- package/runtime/src/iterator.c +5 -1
- package/runtime/src/jobs.c +37 -22
- package/runtime/src/object.c +91 -8
- package/runtime/src/os.c +16 -6
- package/runtime/src/os.h +2 -0
- package/runtime/src/process.c +97 -10
- package/runtime/src/typedarray.c +23 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
/* MIT License
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 1998, 2011, 2013 Massachusetts Institute of Technology
|
|
4
|
+
* Copyright (c) 2017 Christian Ammer
|
|
5
|
+
* Copyright (c) 2019 Andrew Selivanov
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice (including the next
|
|
15
|
+
* paragraph) shall be included in all copies or substantial portions of the
|
|
16
|
+
* Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
* SOFTWARE.
|
|
25
|
+
*
|
|
26
|
+
* SPDX-License-Identifier: MIT
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
#include "ares_private.h"
|
|
30
|
+
|
|
31
|
+
#ifdef HAVE_GETSERVBYNAME_R
|
|
32
|
+
# if !defined(GETSERVBYNAME_R_ARGS) || (GETSERVBYNAME_R_ARGS < 4) || \
|
|
33
|
+
(GETSERVBYNAME_R_ARGS > 6)
|
|
34
|
+
# error "you MUST specify a valid number of arguments for getservbyname_r"
|
|
35
|
+
# endif
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
#ifdef HAVE_NETINET_IN_H
|
|
39
|
+
# include <netinet/in.h>
|
|
40
|
+
#endif
|
|
41
|
+
#ifdef HAVE_NETDB_H
|
|
42
|
+
# include <netdb.h>
|
|
43
|
+
#endif
|
|
44
|
+
#ifdef HAVE_ARPA_INET_H
|
|
45
|
+
# include <arpa/inet.h>
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#include "ares_nameser.h"
|
|
49
|
+
|
|
50
|
+
#ifdef HAVE_STRINGS_H
|
|
51
|
+
# include <strings.h>
|
|
52
|
+
#endif
|
|
53
|
+
#include <assert.h>
|
|
54
|
+
|
|
55
|
+
#ifdef HAVE_LIMITS_H
|
|
56
|
+
# include <limits.h>
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
#include "ares_dns.h"
|
|
60
|
+
|
|
61
|
+
struct host_query {
|
|
62
|
+
ares_channel_t *channel;
|
|
63
|
+
char *name;
|
|
64
|
+
unsigned short port; /* in host order */
|
|
65
|
+
ares_addrinfo_callback callback;
|
|
66
|
+
void *arg;
|
|
67
|
+
struct ares_addrinfo_hints hints;
|
|
68
|
+
int sent_family; /* this family is what was is being used */
|
|
69
|
+
size_t timeouts; /* number of timeouts we saw for this request */
|
|
70
|
+
char *lookups; /* Duplicate memory from channel because of ares_reinit() */
|
|
71
|
+
const char *remaining_lookups; /* types of lookup we need to perform ("fb" by
|
|
72
|
+
default, file and dns respectively) */
|
|
73
|
+
|
|
74
|
+
/* Search order for names */
|
|
75
|
+
char **names;
|
|
76
|
+
size_t names_cnt;
|
|
77
|
+
size_t next_name_idx; /* next name index being attempted */
|
|
78
|
+
|
|
79
|
+
struct ares_addrinfo *ai; /* store results between lookups */
|
|
80
|
+
unsigned short qid_a; /* qid for A request */
|
|
81
|
+
unsigned short qid_aaaa; /* qid for AAAA request */
|
|
82
|
+
|
|
83
|
+
size_t remaining; /* number of DNS answers waiting for */
|
|
84
|
+
|
|
85
|
+
/* Track nodata responses to possibly override final result */
|
|
86
|
+
size_t nodata_cnt;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
static const struct ares_addrinfo_hints default_hints = {
|
|
90
|
+
0, /* ai_flags */
|
|
91
|
+
AF_UNSPEC, /* ai_family */
|
|
92
|
+
0, /* ai_socktype */
|
|
93
|
+
0, /* ai_protocol */
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/* forward declarations */
|
|
97
|
+
static ares_bool_t next_dns_lookup(struct host_query *hquery);
|
|
98
|
+
|
|
99
|
+
struct ares_addrinfo_cname *
|
|
100
|
+
ares_append_addrinfo_cname(struct ares_addrinfo_cname **head)
|
|
101
|
+
{
|
|
102
|
+
struct ares_addrinfo_cname *tail = ares_malloc_zero(sizeof(*tail));
|
|
103
|
+
struct ares_addrinfo_cname *last = *head;
|
|
104
|
+
|
|
105
|
+
if (tail == NULL) {
|
|
106
|
+
return NULL; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!last) {
|
|
110
|
+
*head = tail;
|
|
111
|
+
return tail;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
while (last->next) {
|
|
115
|
+
last = last->next;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
last->next = tail;
|
|
119
|
+
return tail;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
void ares_addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
|
|
123
|
+
struct ares_addrinfo_cname *tail)
|
|
124
|
+
{
|
|
125
|
+
struct ares_addrinfo_cname *last = *head;
|
|
126
|
+
if (!last) {
|
|
127
|
+
*head = tail;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
while (last->next) {
|
|
132
|
+
last = last->next;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
last->next = tail;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Allocate new addrinfo and append to the tail. */
|
|
139
|
+
struct ares_addrinfo_node *
|
|
140
|
+
ares_append_addrinfo_node(struct ares_addrinfo_node **head)
|
|
141
|
+
{
|
|
142
|
+
struct ares_addrinfo_node *tail = ares_malloc_zero(sizeof(*tail));
|
|
143
|
+
struct ares_addrinfo_node *last = *head;
|
|
144
|
+
|
|
145
|
+
if (tail == NULL) {
|
|
146
|
+
return NULL; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!last) {
|
|
150
|
+
*head = tail;
|
|
151
|
+
return tail;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
while (last->ai_next) {
|
|
155
|
+
last = last->ai_next;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
last->ai_next = tail;
|
|
159
|
+
return tail;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void ares_addrinfo_cat_nodes(struct ares_addrinfo_node **head,
|
|
163
|
+
struct ares_addrinfo_node *tail)
|
|
164
|
+
{
|
|
165
|
+
struct ares_addrinfo_node *last = *head;
|
|
166
|
+
if (!last) {
|
|
167
|
+
*head = tail;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
while (last->ai_next) {
|
|
172
|
+
last = last->ai_next;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
last->ai_next = tail;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Resolve service name into port number given in host byte order.
|
|
179
|
+
* If not resolved, return 0.
|
|
180
|
+
*/
|
|
181
|
+
static unsigned short lookup_service(const char *service, int flags)
|
|
182
|
+
{
|
|
183
|
+
const char *proto;
|
|
184
|
+
struct servent *sep;
|
|
185
|
+
#ifdef HAVE_GETSERVBYNAME_R
|
|
186
|
+
struct servent se;
|
|
187
|
+
char tmpbuf[4096];
|
|
188
|
+
#endif
|
|
189
|
+
|
|
190
|
+
if (service) {
|
|
191
|
+
if (flags & ARES_NI_UDP) {
|
|
192
|
+
proto = "udp";
|
|
193
|
+
} else if (flags & ARES_NI_SCTP) {
|
|
194
|
+
proto = "sctp";
|
|
195
|
+
} else if (flags & ARES_NI_DCCP) {
|
|
196
|
+
proto = "dccp";
|
|
197
|
+
} else {
|
|
198
|
+
proto = "tcp";
|
|
199
|
+
}
|
|
200
|
+
#ifdef HAVE_GETSERVBYNAME_R
|
|
201
|
+
memset(&se, 0, sizeof(se));
|
|
202
|
+
sep = &se;
|
|
203
|
+
memset(tmpbuf, 0, sizeof(tmpbuf));
|
|
204
|
+
# if GETSERVBYNAME_R_ARGS == 6
|
|
205
|
+
if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf),
|
|
206
|
+
&sep) != 0) {
|
|
207
|
+
sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */
|
|
208
|
+
}
|
|
209
|
+
# elif GETSERVBYNAME_R_ARGS == 5
|
|
210
|
+
sep = getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
|
|
211
|
+
# elif GETSERVBYNAME_R_ARGS == 4
|
|
212
|
+
if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0) {
|
|
213
|
+
sep = NULL;
|
|
214
|
+
}
|
|
215
|
+
# else
|
|
216
|
+
/* Lets just hope the OS uses TLS! */
|
|
217
|
+
sep = getservbyname(service, proto);
|
|
218
|
+
# endif
|
|
219
|
+
#else
|
|
220
|
+
/* Lets just hope the OS uses TLS! */
|
|
221
|
+
# if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
|
|
222
|
+
sep = getservbyname(service, (char *)proto);
|
|
223
|
+
# else
|
|
224
|
+
sep = getservbyname(service, proto);
|
|
225
|
+
# endif
|
|
226
|
+
#endif
|
|
227
|
+
return (sep ? ntohs((unsigned short)sep->s_port) : 0);
|
|
228
|
+
}
|
|
229
|
+
return 0;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* If the name looks like an IP address or an error occurred,
|
|
233
|
+
* fake up a host entry, end the query immediately, and return true.
|
|
234
|
+
* Otherwise return false.
|
|
235
|
+
*/
|
|
236
|
+
static ares_bool_t fake_addrinfo(const char *name, unsigned short port,
|
|
237
|
+
const struct ares_addrinfo_hints *hints,
|
|
238
|
+
struct ares_addrinfo *ai,
|
|
239
|
+
ares_addrinfo_callback callback, void *arg)
|
|
240
|
+
{
|
|
241
|
+
struct ares_addrinfo_cname *cname;
|
|
242
|
+
ares_status_t status = ARES_SUCCESS;
|
|
243
|
+
ares_bool_t result = ARES_FALSE;
|
|
244
|
+
int family = hints->ai_family;
|
|
245
|
+
|
|
246
|
+
if (name == NULL) {
|
|
247
|
+
return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC) {
|
|
251
|
+
/* It only looks like an IP address if it's all numbers and dots. */
|
|
252
|
+
size_t numdots = 0;
|
|
253
|
+
ares_bool_t valid = ARES_TRUE;
|
|
254
|
+
const char *p;
|
|
255
|
+
for (p = name; *p; p++) {
|
|
256
|
+
if (!ares_isdigit(*p) && *p != '.') {
|
|
257
|
+
valid = ARES_FALSE;
|
|
258
|
+
break;
|
|
259
|
+
} else if (*p == '.') {
|
|
260
|
+
numdots++;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* if we don't have 3 dots, it is illegal
|
|
265
|
+
* (although inet_pton doesn't think so).
|
|
266
|
+
*/
|
|
267
|
+
if (numdots != 3 || !valid) {
|
|
268
|
+
result = ARES_FALSE;
|
|
269
|
+
} else {
|
|
270
|
+
struct in_addr addr4;
|
|
271
|
+
result =
|
|
272
|
+
ares_inet_pton(AF_INET, name, &addr4) < 1 ? ARES_FALSE : ARES_TRUE;
|
|
273
|
+
if (result) {
|
|
274
|
+
status = ares_append_ai_node(AF_INET, port, 0, &addr4, &ai->nodes);
|
|
275
|
+
if (status != ARES_SUCCESS) {
|
|
276
|
+
ares_freeaddrinfo(ai);
|
|
277
|
+
callback(arg, (int)status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */
|
|
278
|
+
return ARES_TRUE; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!result && (family == AF_INET6 || family == AF_UNSPEC)) {
|
|
285
|
+
struct ares_in6_addr addr6;
|
|
286
|
+
result =
|
|
287
|
+
ares_inet_pton(AF_INET6, name, &addr6) < 1 ? ARES_FALSE : ARES_TRUE;
|
|
288
|
+
if (result) {
|
|
289
|
+
status = ares_append_ai_node(AF_INET6, port, 0, &addr6, &ai->nodes);
|
|
290
|
+
if (status != ARES_SUCCESS) {
|
|
291
|
+
ares_freeaddrinfo(ai);
|
|
292
|
+
callback(arg, (int)status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */
|
|
293
|
+
return ARES_TRUE; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (!result) {
|
|
299
|
+
return ARES_FALSE;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (hints->ai_flags & ARES_AI_CANONNAME) {
|
|
303
|
+
cname = ares_append_addrinfo_cname(&ai->cnames);
|
|
304
|
+
if (!cname) {
|
|
305
|
+
/* LCOV_EXCL_START: OutOfMemory */
|
|
306
|
+
ares_freeaddrinfo(ai);
|
|
307
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
308
|
+
return ARES_TRUE;
|
|
309
|
+
/* LCOV_EXCL_STOP */
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* Duplicate the name, to avoid a constness violation. */
|
|
313
|
+
cname->name = ares_strdup(name);
|
|
314
|
+
if (!cname->name) {
|
|
315
|
+
ares_freeaddrinfo(ai);
|
|
316
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
317
|
+
return ARES_TRUE;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
ai->nodes->ai_socktype = hints->ai_socktype;
|
|
322
|
+
ai->nodes->ai_protocol = hints->ai_protocol;
|
|
323
|
+
|
|
324
|
+
callback(arg, ARES_SUCCESS, 0, ai);
|
|
325
|
+
return ARES_TRUE;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
static void hquery_free(struct host_query *hquery, ares_bool_t cleanup_ai)
|
|
329
|
+
{
|
|
330
|
+
if (cleanup_ai) {
|
|
331
|
+
ares_freeaddrinfo(hquery->ai);
|
|
332
|
+
}
|
|
333
|
+
ares_strsplit_free(hquery->names, hquery->names_cnt);
|
|
334
|
+
ares_free(hquery->name);
|
|
335
|
+
ares_free(hquery->lookups);
|
|
336
|
+
ares_free(hquery);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
static void end_hquery(struct host_query *hquery, ares_status_t status)
|
|
340
|
+
{
|
|
341
|
+
struct ares_addrinfo_node sentinel;
|
|
342
|
+
struct ares_addrinfo_node *next;
|
|
343
|
+
|
|
344
|
+
if (status == ARES_SUCCESS) {
|
|
345
|
+
if (!(hquery->hints.ai_flags & ARES_AI_NOSORT) && hquery->ai->nodes) {
|
|
346
|
+
sentinel.ai_next = hquery->ai->nodes;
|
|
347
|
+
ares_sortaddrinfo(hquery->channel, &sentinel);
|
|
348
|
+
hquery->ai->nodes = sentinel.ai_next;
|
|
349
|
+
}
|
|
350
|
+
next = hquery->ai->nodes;
|
|
351
|
+
|
|
352
|
+
while (next) {
|
|
353
|
+
next->ai_socktype = hquery->hints.ai_socktype;
|
|
354
|
+
next->ai_protocol = hquery->hints.ai_protocol;
|
|
355
|
+
next = next->ai_next;
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
/* Clean up what we have collected by so far. */
|
|
359
|
+
ares_freeaddrinfo(hquery->ai);
|
|
360
|
+
hquery->ai = NULL;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
hquery->callback(hquery->arg, (int)status, (int)hquery->timeouts, hquery->ai);
|
|
364
|
+
hquery_free(hquery, ARES_FALSE);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
ares_bool_t ares_is_localhost(const char *name)
|
|
368
|
+
{
|
|
369
|
+
/* RFC6761 6.3 says : The domain "localhost." and any names falling within
|
|
370
|
+
* ".localhost." */
|
|
371
|
+
size_t len;
|
|
372
|
+
|
|
373
|
+
if (name == NULL) {
|
|
374
|
+
return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (ares_strcaseeq(name, "localhost")) {
|
|
378
|
+
return ARES_TRUE;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
len = ares_strlen(name);
|
|
382
|
+
if (len < 10 /* strlen(".localhost") */) {
|
|
383
|
+
return ARES_FALSE;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (ares_strcaseeq(name + (len - 10 /* strlen(".localhost") */),
|
|
387
|
+
".localhost")) {
|
|
388
|
+
return ARES_TRUE;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return ARES_FALSE;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
static ares_status_t file_lookup(struct host_query *hquery)
|
|
395
|
+
{
|
|
396
|
+
const ares_hosts_entry_t *entry;
|
|
397
|
+
ares_status_t status;
|
|
398
|
+
|
|
399
|
+
/* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
|
|
400
|
+
if (ares_is_onion_domain(hquery->name)) {
|
|
401
|
+
return ARES_ENOTFOUND;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
status = ares_hosts_search_host(
|
|
405
|
+
hquery->channel,
|
|
406
|
+
(hquery->hints.ai_flags & ARES_AI_ENVHOSTS) ? ARES_TRUE : ARES_FALSE,
|
|
407
|
+
hquery->name, &entry);
|
|
408
|
+
|
|
409
|
+
if (status != ARES_SUCCESS) {
|
|
410
|
+
goto done;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
status = ares_hosts_entry_to_addrinfo(
|
|
414
|
+
entry, hquery->name, hquery->hints.ai_family, hquery->port,
|
|
415
|
+
(hquery->hints.ai_flags & ARES_AI_CANONNAME) ? ARES_TRUE : ARES_FALSE,
|
|
416
|
+
hquery->ai);
|
|
417
|
+
|
|
418
|
+
if (status != ARES_SUCCESS) {
|
|
419
|
+
goto done; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
done:
|
|
424
|
+
/* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries
|
|
425
|
+
* SHOULD recognize localhost names as special and SHOULD always return the
|
|
426
|
+
* IP loopback address for address queries".
|
|
427
|
+
* We will also ignore ALL errors when trying to resolve localhost, such
|
|
428
|
+
* as permissions errors reading /etc/hosts or a malformed /etc/hosts.
|
|
429
|
+
*
|
|
430
|
+
* Also, just because the query itself returned success from /etc/hosts
|
|
431
|
+
* lookup doesn't mean it returned everything it needed to for all requested
|
|
432
|
+
* address families. As long as we're not on a critical out of memory
|
|
433
|
+
* condition pass it through to fill in any other address classes. */
|
|
434
|
+
if (status != ARES_ENOMEM && ares_is_localhost(hquery->name)) {
|
|
435
|
+
return ares_addrinfo_localhost(hquery->name, hquery->port, &hquery->hints,
|
|
436
|
+
hquery->ai);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return status;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static void next_lookup(struct host_query *hquery, ares_status_t status)
|
|
443
|
+
{
|
|
444
|
+
switch (*hquery->remaining_lookups) {
|
|
445
|
+
case 'b':
|
|
446
|
+
/* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send
|
|
447
|
+
* queries for localhost names to their configured caching DNS
|
|
448
|
+
* server(s)."
|
|
449
|
+
* Otherwise, DNS lookup. */
|
|
450
|
+
if (!ares_is_localhost(hquery->name) && next_dns_lookup(hquery)) {
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
hquery->remaining_lookups++;
|
|
455
|
+
next_lookup(hquery, status);
|
|
456
|
+
break;
|
|
457
|
+
|
|
458
|
+
case 'f':
|
|
459
|
+
/* Host file lookup */
|
|
460
|
+
if (file_lookup(hquery) == ARES_SUCCESS) {
|
|
461
|
+
end_hquery(hquery, ARES_SUCCESS);
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
hquery->remaining_lookups++;
|
|
465
|
+
next_lookup(hquery, status);
|
|
466
|
+
break;
|
|
467
|
+
default:
|
|
468
|
+
/* No lookup left */
|
|
469
|
+
end_hquery(hquery, status);
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
static void terminate_retries(const struct host_query *hquery,
|
|
475
|
+
unsigned short qid)
|
|
476
|
+
{
|
|
477
|
+
unsigned short term_qid =
|
|
478
|
+
(qid == hquery->qid_a) ? hquery->qid_aaaa : hquery->qid_a;
|
|
479
|
+
const ares_channel_t *channel = hquery->channel;
|
|
480
|
+
ares_query_t *query = NULL;
|
|
481
|
+
|
|
482
|
+
/* No other outstanding queries, nothing to do */
|
|
483
|
+
if (!hquery->remaining) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
query = ares_htable_szvp_get_direct(channel->queries_by_qid, term_qid);
|
|
488
|
+
if (query == NULL) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
query->no_retries = ARES_TRUE;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
static ares_bool_t ai_has_ipv4(struct ares_addrinfo *ai)
|
|
496
|
+
{
|
|
497
|
+
struct ares_addrinfo_node *node;
|
|
498
|
+
|
|
499
|
+
for (node = ai->nodes; node != NULL; node = node->ai_next) {
|
|
500
|
+
if (node->ai_family == AF_INET) {
|
|
501
|
+
return ARES_TRUE;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return ARES_FALSE;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
static void host_callback(void *arg, ares_status_t status, size_t timeouts,
|
|
508
|
+
const ares_dns_record_t *dnsrec)
|
|
509
|
+
{
|
|
510
|
+
struct host_query *hquery = (struct host_query *)arg;
|
|
511
|
+
ares_status_t addinfostatus = ARES_SUCCESS;
|
|
512
|
+
hquery->timeouts += timeouts;
|
|
513
|
+
hquery->remaining--;
|
|
514
|
+
|
|
515
|
+
if (status == ARES_SUCCESS) {
|
|
516
|
+
if (dnsrec == NULL) {
|
|
517
|
+
addinfostatus = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */
|
|
518
|
+
} else {
|
|
519
|
+
addinfostatus =
|
|
520
|
+
ares_parse_into_addrinfo(dnsrec, ARES_TRUE, hquery->port, hquery->ai);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* We sent out ipv4 and ipv6 requests simultaneously. If we got a
|
|
524
|
+
* successful ipv4 response, we want to go ahead and tell the ipv6 request
|
|
525
|
+
* that if it fails or times out to not try again since we have the data
|
|
526
|
+
* we need.
|
|
527
|
+
*
|
|
528
|
+
* Our initial implementation of this would terminate retries if we got any
|
|
529
|
+
* successful response (ipv4 _or_ ipv6). But we did get some user-reported
|
|
530
|
+
* issues with this that had bad system configs and odd behavior:
|
|
531
|
+
* https://github.com/alpinelinux/docker-alpine/issues/366
|
|
532
|
+
*
|
|
533
|
+
* Essentially the ipv6 query succeeded but the ipv4 query failed or timed
|
|
534
|
+
* out, and so we only returned the ipv6 address, but the host couldn't
|
|
535
|
+
* use ipv6. If we continued to allow ipv4 retries it would have found a
|
|
536
|
+
* server that worked and returned both address classes (this is clearly
|
|
537
|
+
* unexpected behavior).
|
|
538
|
+
*
|
|
539
|
+
* At some point down the road if ipv6 actually becomes required and
|
|
540
|
+
* reliable we can drop this ipv4 check.
|
|
541
|
+
*/
|
|
542
|
+
if (addinfostatus == ARES_SUCCESS && ai_has_ipv4(hquery->ai)) {
|
|
543
|
+
terminate_retries(hquery, ares_dns_record_get_id(dnsrec));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (!hquery->remaining) {
|
|
548
|
+
if (status == ARES_EDESTRUCTION || status == ARES_ECANCELLED) {
|
|
549
|
+
/* must make sure we don't do next_lookup() on destroy or cancel,
|
|
550
|
+
* and return the appropriate status. We won't return a partial
|
|
551
|
+
* result in this case. */
|
|
552
|
+
end_hquery(hquery, status);
|
|
553
|
+
} else if (addinfostatus != ARES_SUCCESS && addinfostatus != ARES_ENODATA) {
|
|
554
|
+
/* error in parsing result e.g. no memory */
|
|
555
|
+
if (addinfostatus == ARES_EBADRESP && hquery->ai->nodes) {
|
|
556
|
+
/* We got a bad response from server, but at least one query
|
|
557
|
+
* ended with ARES_SUCCESS */
|
|
558
|
+
end_hquery(hquery, ARES_SUCCESS);
|
|
559
|
+
} else {
|
|
560
|
+
end_hquery(hquery, addinfostatus);
|
|
561
|
+
}
|
|
562
|
+
} else if (hquery->ai->nodes) {
|
|
563
|
+
/* at least one query ended with ARES_SUCCESS */
|
|
564
|
+
end_hquery(hquery, ARES_SUCCESS);
|
|
565
|
+
} else if (status == ARES_ENOTFOUND || status == ARES_ENODATA ||
|
|
566
|
+
addinfostatus == ARES_ENODATA) {
|
|
567
|
+
if (status == ARES_ENODATA || addinfostatus == ARES_ENODATA) {
|
|
568
|
+
hquery->nodata_cnt++;
|
|
569
|
+
}
|
|
570
|
+
next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status);
|
|
571
|
+
} else if ((status == ARES_ESERVFAIL || status == ARES_EREFUSED) &&
|
|
572
|
+
ares_name_label_cnt(hquery->names[hquery->next_name_idx - 1]) ==
|
|
573
|
+
1) {
|
|
574
|
+
/* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a
|
|
575
|
+
* single label domain name. */
|
|
576
|
+
next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status);
|
|
577
|
+
} else {
|
|
578
|
+
end_hquery(hquery, status);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/* at this point we keep on waiting for the next query to finish */
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/* Per POSIX getaddrinfo(), when no node/hostname is provided the returned
|
|
586
|
+
* addresses are synthesized from the service: the wildcard address when
|
|
587
|
+
* ARES_AI_PASSIVE is set (suitable for bind()ing a listening socket),
|
|
588
|
+
* otherwise the loopback address (suitable for connect()ing to a peer on the
|
|
589
|
+
* local host). */
|
|
590
|
+
static ares_status_t
|
|
591
|
+
ares_append_nulladdr(unsigned short port,
|
|
592
|
+
const struct ares_addrinfo_hints *hints,
|
|
593
|
+
struct ares_addrinfo *ai)
|
|
594
|
+
{
|
|
595
|
+
int family = hints->ai_family;
|
|
596
|
+
ares_bool_t passive = ARES_FALSE;
|
|
597
|
+
ares_status_t status;
|
|
598
|
+
struct ares_addrinfo_node *node;
|
|
599
|
+
|
|
600
|
+
if (hints->ai_flags & ARES_AI_PASSIVE) {
|
|
601
|
+
passive = ARES_TRUE;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
if (family == AF_INET6 || family == AF_UNSPEC) {
|
|
605
|
+
struct ares_in6_addr addr6;
|
|
606
|
+
memset(&addr6, 0, sizeof(addr6)); /* wildcard "::" */
|
|
607
|
+
if (!passive) {
|
|
608
|
+
ares_inet_pton(AF_INET6, "::1", &addr6);
|
|
609
|
+
}
|
|
610
|
+
status = ares_append_ai_node(AF_INET6, port, 0, &addr6, &ai->nodes);
|
|
611
|
+
if (status != ARES_SUCCESS) {
|
|
612
|
+
return status; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (family == AF_INET || family == AF_UNSPEC) {
|
|
617
|
+
struct in_addr addr4;
|
|
618
|
+
memset(&addr4, 0, sizeof(addr4)); /* wildcard "0.0.0.0" */
|
|
619
|
+
if (!passive) {
|
|
620
|
+
ares_inet_pton(AF_INET, "127.0.0.1", &addr4);
|
|
621
|
+
}
|
|
622
|
+
status = ares_append_ai_node(AF_INET, port, 0, &addr4, &ai->nodes);
|
|
623
|
+
if (status != ARES_SUCCESS) {
|
|
624
|
+
return status; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
for (node = ai->nodes; node != NULL; node = node->ai_next) {
|
|
629
|
+
node->ai_socktype = hints->ai_socktype;
|
|
630
|
+
node->ai_protocol = hints->ai_protocol;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
return ARES_SUCCESS;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
static void ares_getaddrinfo_int(ares_channel_t *channel, const char *name,
|
|
637
|
+
const char *service,
|
|
638
|
+
const struct ares_addrinfo_hints *hints,
|
|
639
|
+
ares_addrinfo_callback callback, void *arg)
|
|
640
|
+
{
|
|
641
|
+
struct host_query *hquery;
|
|
642
|
+
unsigned short port = 0;
|
|
643
|
+
int family;
|
|
644
|
+
struct ares_addrinfo *ai;
|
|
645
|
+
ares_status_t status;
|
|
646
|
+
|
|
647
|
+
if (!hints) {
|
|
648
|
+
hints = &default_hints;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
family = hints->ai_family;
|
|
652
|
+
|
|
653
|
+
/* Right now we only know how to look up Internet addresses
|
|
654
|
+
and unspec means try both basically. */
|
|
655
|
+
if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC) {
|
|
656
|
+
callback(arg, ARES_ENOTIMP, 0, NULL);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/* POSIX getaddrinfo() requires that at least one of node (name) or service
|
|
661
|
+
* be provided. */
|
|
662
|
+
if (name == NULL && service == NULL) {
|
|
663
|
+
callback(arg, ARES_ENOTFOUND, 0, NULL);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (ares_is_onion_domain(name)) {
|
|
668
|
+
callback(arg, ARES_ENOTFOUND, 0, NULL);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (service) {
|
|
673
|
+
if (hints->ai_flags & ARES_AI_NUMERICSERV) {
|
|
674
|
+
if (!ares_parse_port(service, &port, ARES_TRUE)) {
|
|
675
|
+
callback(arg, ARES_ESERVICE, 0, NULL);
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
port = lookup_service(service, 0);
|
|
680
|
+
if (!port) {
|
|
681
|
+
if (!ares_parse_port(service, &port, ARES_TRUE)) {
|
|
682
|
+
callback(arg, ARES_ESERVICE, 0, NULL);
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
ai = ares_malloc_zero(sizeof(*ai));
|
|
690
|
+
if (!ai) {
|
|
691
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/* No node/hostname was provided (service-only lookup): synthesize wildcard
|
|
696
|
+
* or loopback addresses from the resolved port instead of issuing a query. */
|
|
697
|
+
if (name == NULL) {
|
|
698
|
+
status = ares_append_nulladdr(port, hints, ai);
|
|
699
|
+
if (status != ARES_SUCCESS) {
|
|
700
|
+
ares_freeaddrinfo(ai); /* LCOV_EXCL_LINE: OutOfMemory */
|
|
701
|
+
callback(arg, (int)status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */
|
|
702
|
+
return; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
703
|
+
}
|
|
704
|
+
callback(arg, ARES_SUCCESS, 0, ai);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (fake_addrinfo(name, port, hints, ai, callback, arg)) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/* Allocate and fill in the host query structure. */
|
|
713
|
+
hquery = ares_malloc_zero(sizeof(*hquery));
|
|
714
|
+
if (!hquery) {
|
|
715
|
+
ares_freeaddrinfo(ai);
|
|
716
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
hquery->port = port;
|
|
721
|
+
hquery->channel = channel;
|
|
722
|
+
hquery->hints = *hints;
|
|
723
|
+
hquery->sent_family = -1; /* nothing is sent yet */
|
|
724
|
+
hquery->callback = callback;
|
|
725
|
+
hquery->arg = arg;
|
|
726
|
+
hquery->ai = ai;
|
|
727
|
+
hquery->name = ares_strdup(name);
|
|
728
|
+
if (hquery->name == NULL) {
|
|
729
|
+
hquery_free(hquery, ARES_TRUE);
|
|
730
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
status =
|
|
735
|
+
ares_search_name_list(channel, name, &hquery->names, &hquery->names_cnt);
|
|
736
|
+
if (status != ARES_SUCCESS) {
|
|
737
|
+
hquery_free(hquery, ARES_TRUE);
|
|
738
|
+
callback(arg, (int)status, 0, NULL);
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
hquery->next_name_idx = 0;
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
hquery->lookups = ares_strdup(channel->lookups);
|
|
745
|
+
if (hquery->lookups == NULL) {
|
|
746
|
+
hquery_free(hquery, ARES_TRUE);
|
|
747
|
+
callback(arg, ARES_ENOMEM, 0, NULL);
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
hquery->remaining_lookups = hquery->lookups;
|
|
751
|
+
|
|
752
|
+
/* Start performing lookups according to channel->lookups. */
|
|
753
|
+
next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
void ares_getaddrinfo(ares_channel_t *channel, const char *name,
|
|
757
|
+
const char *service,
|
|
758
|
+
const struct ares_addrinfo_hints *hints,
|
|
759
|
+
ares_addrinfo_callback callback, void *arg)
|
|
760
|
+
{
|
|
761
|
+
if (channel == NULL) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
ares_channel_lock(channel);
|
|
765
|
+
ares_getaddrinfo_int(channel, name, service, hints, callback, arg);
|
|
766
|
+
ares_channel_unlock(channel);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
static ares_bool_t next_dns_lookup(struct host_query *hquery)
|
|
770
|
+
{
|
|
771
|
+
const char *name = NULL;
|
|
772
|
+
|
|
773
|
+
if (hquery->next_name_idx >= hquery->names_cnt) {
|
|
774
|
+
return ARES_FALSE;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
name = hquery->names[hquery->next_name_idx++];
|
|
778
|
+
|
|
779
|
+
/* NOTE: hquery may be invalidated during the call to ares_query_qid(),
|
|
780
|
+
* so should not be referenced after this point */
|
|
781
|
+
switch (hquery->hints.ai_family) {
|
|
782
|
+
case AF_INET:
|
|
783
|
+
hquery->remaining += 1;
|
|
784
|
+
ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, ARES_REC_TYPE_A,
|
|
785
|
+
host_callback, hquery, &hquery->qid_a);
|
|
786
|
+
break;
|
|
787
|
+
case AF_INET6:
|
|
788
|
+
hquery->remaining += 1;
|
|
789
|
+
ares_query_nolock(hquery->channel, name, ARES_CLASS_IN,
|
|
790
|
+
ARES_REC_TYPE_AAAA, host_callback, hquery,
|
|
791
|
+
&hquery->qid_aaaa);
|
|
792
|
+
break;
|
|
793
|
+
case AF_UNSPEC:
|
|
794
|
+
hquery->remaining += 2;
|
|
795
|
+
ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, ARES_REC_TYPE_A,
|
|
796
|
+
host_callback, hquery, &hquery->qid_a);
|
|
797
|
+
ares_query_nolock(hquery->channel, name, ARES_CLASS_IN,
|
|
798
|
+
ARES_REC_TYPE_AAAA, host_callback, hquery,
|
|
799
|
+
&hquery->qid_aaaa);
|
|
800
|
+
break;
|
|
801
|
+
default:
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
return ARES_TRUE;
|
|
806
|
+
}
|