visaljs 0.0.10 → 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 +962 -68
- package/node/include/js_node.h +11 -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 +395 -86
- 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/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 +13 -1
- 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 +70 -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_builtins.h +5 -0
- package/runtime/include/js_crypto.h +11 -0
- package/runtime/include/js_gc.h +13 -10
- package/runtime/include/js_jobs.h +2 -0
- package/runtime/include/js_object.h +58 -0
- package/runtime/include/jscontext.h +1 -0
- 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/gc.c +73 -92
- package/runtime/src/inspect.c +18 -1
- package/runtime/src/jobs.c +37 -22
- package/runtime/src/object.c +49 -2
- package/runtime/src/os.c +16 -6
- package/runtime/src/os.h +2 -0
- package/runtime/src/process.c +97 -10
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* MIT License
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 1998 Massachusetts Institute of Technology
|
|
4
|
+
* Copyright (c) The c-ares project and its contributors
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice (including the next
|
|
14
|
+
* paragraph) shall be included in all copies or substantial portions of the
|
|
15
|
+
* Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* SPDX-License-Identifier: MIT
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include "ares_private.h"
|
|
29
|
+
#include <assert.h>
|
|
30
|
+
|
|
31
|
+
static void ares_requeue_queries(ares_conn_t *conn,
|
|
32
|
+
ares_status_t requeue_status)
|
|
33
|
+
{
|
|
34
|
+
ares_query_t *query;
|
|
35
|
+
ares_timeval_t now;
|
|
36
|
+
|
|
37
|
+
ares_tvnow(&now);
|
|
38
|
+
|
|
39
|
+
while ((query = ares_llist_first_val(conn->queries_to_conn)) != NULL) {
|
|
40
|
+
ares_requeue_query(query, &now, requeue_status, ARES_TRUE, NULL, NULL);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void ares_close_connection(ares_conn_t *conn, ares_status_t requeue_status)
|
|
45
|
+
{
|
|
46
|
+
ares_server_t *server = conn->server;
|
|
47
|
+
ares_channel_t *channel = server->channel;
|
|
48
|
+
|
|
49
|
+
/* Unlink */
|
|
50
|
+
ares_llist_node_claim(
|
|
51
|
+
ares_htable_asvp_get_direct(channel->connnode_by_socket, conn->fd));
|
|
52
|
+
ares_htable_asvp_remove(channel->connnode_by_socket, conn->fd);
|
|
53
|
+
|
|
54
|
+
if (conn->flags & ARES_CONN_FLAG_TCP) {
|
|
55
|
+
server->tcp_conn = NULL;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ares_buf_destroy(conn->in_buf);
|
|
59
|
+
ares_buf_destroy(conn->out_buf);
|
|
60
|
+
|
|
61
|
+
/* Requeue queries to other connections */
|
|
62
|
+
ares_requeue_queries(conn, requeue_status);
|
|
63
|
+
|
|
64
|
+
ares_llist_destroy(conn->queries_to_conn);
|
|
65
|
+
|
|
66
|
+
ares_conn_sock_state_cb_update(conn, ARES_CONN_STATE_NONE);
|
|
67
|
+
|
|
68
|
+
ares_socket_close(channel, conn->fd);
|
|
69
|
+
|
|
70
|
+
ares_free(conn);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void ares_close_sockets(ares_server_t *server)
|
|
74
|
+
{
|
|
75
|
+
ares_llist_node_t *node;
|
|
76
|
+
|
|
77
|
+
while ((node = ares_llist_node_first(server->connections)) != NULL) {
|
|
78
|
+
ares_conn_t *conn = ares_llist_node_val(node);
|
|
79
|
+
ares_close_connection(conn, ARES_SUCCESS);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void ares_check_cleanup_conns(const ares_channel_t *channel)
|
|
84
|
+
{
|
|
85
|
+
ares_slist_node_t *snode;
|
|
86
|
+
|
|
87
|
+
if (channel == NULL) {
|
|
88
|
+
return; /* LCOV_EXCL_LINE: DefensiveCoding */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Iterate across each server */
|
|
92
|
+
for (snode = ares_slist_node_first(channel->servers); snode != NULL;
|
|
93
|
+
snode = ares_slist_node_next(snode)) {
|
|
94
|
+
ares_server_t *server = ares_slist_node_val(snode);
|
|
95
|
+
ares_llist_node_t *cnode;
|
|
96
|
+
|
|
97
|
+
/* Iterate across each connection */
|
|
98
|
+
cnode = ares_llist_node_first(server->connections);
|
|
99
|
+
while (cnode != NULL) {
|
|
100
|
+
ares_llist_node_t *next = ares_llist_node_next(cnode);
|
|
101
|
+
ares_conn_t *conn = ares_llist_node_val(cnode);
|
|
102
|
+
ares_bool_t do_cleanup = ARES_FALSE;
|
|
103
|
+
cnode = next;
|
|
104
|
+
|
|
105
|
+
/* Has connections, not eligible */
|
|
106
|
+
if (ares_llist_len(conn->queries_to_conn)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* If we are configured not to stay open, close it out */
|
|
111
|
+
if (!(channel->flags & ARES_FLAG_STAYOPEN)) {
|
|
112
|
+
do_cleanup = ARES_TRUE;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* If the connection has been retired for new queries, close it out once
|
|
116
|
+
* idle. Resetting the connection (and specifically the source port
|
|
117
|
+
* number) can help resolve situations where packets are being dropped.
|
|
118
|
+
*/
|
|
119
|
+
if (conn->flags & ARES_CONN_FLAG_NONEW) {
|
|
120
|
+
do_cleanup = ARES_TRUE;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* If the udp connection hit its max queries, always close it */
|
|
124
|
+
if (!(conn->flags & ARES_CONN_FLAG_TCP) && channel->udp_max_queries > 0 &&
|
|
125
|
+
conn->total_queries >= channel->udp_max_queries) {
|
|
126
|
+
do_cleanup = ARES_TRUE;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!do_cleanup) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Clean it up */
|
|
134
|
+
ares_close_connection(conn, ARES_SUCCESS);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
/* MIT License
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) Massachusetts Institute of Technology
|
|
4
|
+
* Copyright (c) The c-ares project and its contributors
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice (including the next
|
|
14
|
+
* paragraph) shall be included in all copies or substantial portions of the
|
|
15
|
+
* Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* SPDX-License-Identifier: MIT
|
|
26
|
+
*/
|
|
27
|
+
#include "ares_private.h"
|
|
28
|
+
|
|
29
|
+
void ares_conn_sock_state_cb_update(ares_conn_t *conn,
|
|
30
|
+
ares_conn_state_flags_t flags)
|
|
31
|
+
{
|
|
32
|
+
ares_channel_t *channel = conn->server->channel;
|
|
33
|
+
|
|
34
|
+
if ((conn->state_flags & ARES_CONN_STATE_CBFLAGS) != flags &&
|
|
35
|
+
channel->sock_state_cb) {
|
|
36
|
+
channel->sock_state_cb(channel->sock_state_cb_data, conn->fd,
|
|
37
|
+
flags & ARES_CONN_STATE_READ ? 1 : 0,
|
|
38
|
+
flags & ARES_CONN_STATE_WRITE ? 1 : 0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
conn->state_flags &= ~((unsigned int)ARES_CONN_STATE_CBFLAGS);
|
|
42
|
+
conn->state_flags |= flags;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
ares_conn_err_t ares_conn_read(ares_conn_t *conn, void *data, size_t len,
|
|
46
|
+
size_t *read_bytes)
|
|
47
|
+
{
|
|
48
|
+
ares_channel_t *channel = conn->server->channel;
|
|
49
|
+
ares_conn_err_t err;
|
|
50
|
+
|
|
51
|
+
if (!(conn->flags & ARES_CONN_FLAG_TCP)) {
|
|
52
|
+
struct sockaddr_storage sa_storage;
|
|
53
|
+
ares_socklen_t salen = sizeof(sa_storage);
|
|
54
|
+
|
|
55
|
+
memset(&sa_storage, 0, sizeof(sa_storage));
|
|
56
|
+
|
|
57
|
+
err =
|
|
58
|
+
ares_socket_recvfrom(channel, conn->fd, ARES_FALSE, data, len, 0,
|
|
59
|
+
(struct sockaddr *)&sa_storage, &salen, read_bytes);
|
|
60
|
+
|
|
61
|
+
#ifdef HAVE_RECVFROM
|
|
62
|
+
if (err == ARES_CONN_ERR_SUCCESS &&
|
|
63
|
+
!ares_sockaddr_addr_eq((struct sockaddr *)&sa_storage,
|
|
64
|
+
&conn->server->addr)) {
|
|
65
|
+
err = ARES_CONN_ERR_WOULDBLOCK;
|
|
66
|
+
}
|
|
67
|
+
#endif
|
|
68
|
+
} else {
|
|
69
|
+
err = ares_socket_recv(channel, conn->fd, ARES_TRUE, data, len, read_bytes);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Toggle connected state if needed */
|
|
73
|
+
if (err == ARES_CONN_ERR_SUCCESS) {
|
|
74
|
+
conn->state_flags |= ARES_CONN_STATE_CONNECTED;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return err;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Use like:
|
|
81
|
+
* struct sockaddr_storage sa_storage;
|
|
82
|
+
* ares_socklen_t salen = sizeof(sa_storage);
|
|
83
|
+
* struct sockaddr *sa = (struct sockaddr *)&sa_storage;
|
|
84
|
+
* ares_conn_set_sockaddr(conn, sa, &salen);
|
|
85
|
+
*/
|
|
86
|
+
static ares_status_t ares_conn_set_sockaddr(const ares_conn_t *conn,
|
|
87
|
+
struct sockaddr *sa,
|
|
88
|
+
ares_socklen_t *salen)
|
|
89
|
+
{
|
|
90
|
+
const ares_server_t *server = conn->server;
|
|
91
|
+
unsigned short port =
|
|
92
|
+
conn->flags & ARES_CONN_FLAG_TCP ? server->tcp_port : server->udp_port;
|
|
93
|
+
struct sockaddr_in *sin;
|
|
94
|
+
struct sockaddr_in6 *sin6;
|
|
95
|
+
|
|
96
|
+
switch (server->addr.family) {
|
|
97
|
+
case AF_INET:
|
|
98
|
+
sin = (struct sockaddr_in *)(void *)sa;
|
|
99
|
+
if (*salen < (ares_socklen_t)sizeof(*sin)) {
|
|
100
|
+
return ARES_EFORMERR;
|
|
101
|
+
}
|
|
102
|
+
*salen = sizeof(*sin);
|
|
103
|
+
memset(sin, 0, sizeof(*sin));
|
|
104
|
+
sin->sin_family = AF_INET;
|
|
105
|
+
sin->sin_port = htons(port);
|
|
106
|
+
memcpy(&sin->sin_addr, &server->addr.addr.addr4, sizeof(sin->sin_addr));
|
|
107
|
+
return ARES_SUCCESS;
|
|
108
|
+
case AF_INET6:
|
|
109
|
+
sin6 = (struct sockaddr_in6 *)(void *)sa;
|
|
110
|
+
if (*salen < (ares_socklen_t)sizeof(*sin6)) {
|
|
111
|
+
return ARES_EFORMERR;
|
|
112
|
+
}
|
|
113
|
+
*salen = sizeof(*sin6);
|
|
114
|
+
memset(sin6, 0, sizeof(*sin6));
|
|
115
|
+
sin6->sin6_family = AF_INET6;
|
|
116
|
+
sin6->sin6_port = htons(port);
|
|
117
|
+
memcpy(&sin6->sin6_addr, &server->addr.addr.addr6,
|
|
118
|
+
sizeof(sin6->sin6_addr));
|
|
119
|
+
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
|
|
120
|
+
sin6->sin6_scope_id = server->ll_scope;
|
|
121
|
+
#endif
|
|
122
|
+
return ARES_SUCCESS;
|
|
123
|
+
default:
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return ARES_EBADFAMILY;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static ares_status_t ares_conn_set_self_ip(ares_conn_t *conn, ares_bool_t early)
|
|
131
|
+
{
|
|
132
|
+
ares_channel_t *channel = conn->server->channel;
|
|
133
|
+
struct sockaddr_storage sa_storage;
|
|
134
|
+
int rv;
|
|
135
|
+
ares_socklen_t len = sizeof(sa_storage);
|
|
136
|
+
|
|
137
|
+
/* We call this twice on TFO, if we already have the IP we can go ahead and
|
|
138
|
+
* skip processing */
|
|
139
|
+
if (!early && conn->self_ip.family != AF_UNSPEC) {
|
|
140
|
+
return ARES_SUCCESS;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
memset(&sa_storage, 0, sizeof(sa_storage));
|
|
144
|
+
|
|
145
|
+
if (channel->sock_funcs.agetsockname == NULL) {
|
|
146
|
+
/* Not specified, we can still use cookies cooked with an empty self_ip */
|
|
147
|
+
memset(&conn->self_ip, 0, sizeof(conn->self_ip));
|
|
148
|
+
return ARES_SUCCESS;
|
|
149
|
+
}
|
|
150
|
+
rv = channel->sock_funcs.agetsockname(conn->fd,
|
|
151
|
+
(struct sockaddr *)(void *)&sa_storage,
|
|
152
|
+
&len, channel->sock_func_cb_data);
|
|
153
|
+
if (rv != 0) {
|
|
154
|
+
/* During TCP FastOpen, we can't get the IP this early since connect()
|
|
155
|
+
* may not be called. That's ok, we'll try again later */
|
|
156
|
+
if (early && conn->flags & ARES_CONN_FLAG_TCP &&
|
|
157
|
+
conn->flags & ARES_CONN_FLAG_TFO) {
|
|
158
|
+
memset(&conn->self_ip, 0, sizeof(conn->self_ip));
|
|
159
|
+
return ARES_SUCCESS;
|
|
160
|
+
}
|
|
161
|
+
return ARES_ECONNREFUSED;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!ares_sockaddr_to_ares_addr(&conn->self_ip, NULL,
|
|
165
|
+
(struct sockaddr *)(void *)&sa_storage)) {
|
|
166
|
+
return ARES_ECONNREFUSED;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return ARES_SUCCESS;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
ares_conn_err_t ares_conn_write(ares_conn_t *conn, const void *data, size_t len,
|
|
173
|
+
size_t *written)
|
|
174
|
+
{
|
|
175
|
+
ares_channel_t *channel = conn->server->channel;
|
|
176
|
+
ares_bool_t is_tfo = ARES_FALSE;
|
|
177
|
+
ares_conn_err_t err = ARES_CONN_ERR_SUCCESS;
|
|
178
|
+
struct sockaddr_storage sa_storage;
|
|
179
|
+
ares_socklen_t salen = 0;
|
|
180
|
+
struct sockaddr *sa = NULL;
|
|
181
|
+
|
|
182
|
+
*written = 0;
|
|
183
|
+
|
|
184
|
+
/* Don't try to write if not doing initial TFO and not connected */
|
|
185
|
+
if (conn->flags & ARES_CONN_FLAG_TCP &&
|
|
186
|
+
!(conn->state_flags & ARES_CONN_STATE_CONNECTED) &&
|
|
187
|
+
!(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) {
|
|
188
|
+
return ARES_CONN_ERR_WOULDBLOCK;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* On initial write during TFO we need to send an address */
|
|
192
|
+
if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) {
|
|
193
|
+
salen = sizeof(sa_storage);
|
|
194
|
+
sa = (struct sockaddr *)&sa_storage;
|
|
195
|
+
|
|
196
|
+
conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO_INITIAL);
|
|
197
|
+
is_tfo = ARES_TRUE;
|
|
198
|
+
|
|
199
|
+
if (ares_conn_set_sockaddr(conn, sa, &salen) != ARES_SUCCESS) {
|
|
200
|
+
return ARES_CONN_ERR_FAILURE;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
err = ares_socket_write(channel, conn->fd, data, len, written, sa, salen);
|
|
205
|
+
if (err != ARES_CONN_ERR_SUCCESS) {
|
|
206
|
+
goto done;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (is_tfo) {
|
|
210
|
+
/* If using TFO, we might not have been able to get an IP earlier, since
|
|
211
|
+
* we hadn't informed the OS of the destination. When using sendto()
|
|
212
|
+
* now we have so we should be able to fetch it */
|
|
213
|
+
ares_conn_set_self_ip(conn, ARES_FALSE);
|
|
214
|
+
goto done;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
done:
|
|
218
|
+
if (err == ARES_CONN_ERR_SUCCESS && len == *written) {
|
|
219
|
+
/* Wrote all data, make sure we're not listening for write events unless
|
|
220
|
+
* using TFO, in which case we'll need a write event to know when
|
|
221
|
+
* we're connected. */
|
|
222
|
+
ares_conn_sock_state_cb_update(
|
|
223
|
+
conn, ARES_CONN_STATE_READ |
|
|
224
|
+
(is_tfo ? ARES_CONN_STATE_WRITE : ARES_CONN_STATE_NONE));
|
|
225
|
+
} else if (err == ARES_CONN_ERR_WOULDBLOCK) {
|
|
226
|
+
/* Need to wait on more buffer space to write */
|
|
227
|
+
ares_conn_sock_state_cb_update(conn, ARES_CONN_STATE_READ |
|
|
228
|
+
ARES_CONN_STATE_WRITE);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return err;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
ares_status_t ares_conn_flush(ares_conn_t *conn)
|
|
235
|
+
{
|
|
236
|
+
const unsigned char *data;
|
|
237
|
+
size_t data_len;
|
|
238
|
+
size_t count;
|
|
239
|
+
ares_conn_err_t err;
|
|
240
|
+
ares_status_t status;
|
|
241
|
+
ares_bool_t tfo = ARES_FALSE;
|
|
242
|
+
|
|
243
|
+
if (conn == NULL) {
|
|
244
|
+
return ARES_EFORMERR;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) {
|
|
248
|
+
tfo = ARES_TRUE;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
do {
|
|
252
|
+
if (ares_buf_len(conn->out_buf) == 0) {
|
|
253
|
+
status = ARES_SUCCESS;
|
|
254
|
+
goto done;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (conn->flags & ARES_CONN_FLAG_TCP) {
|
|
258
|
+
data = ares_buf_peek(conn->out_buf, &data_len);
|
|
259
|
+
} else {
|
|
260
|
+
unsigned short msg_len;
|
|
261
|
+
|
|
262
|
+
/* Read length, then provide buffer without length */
|
|
263
|
+
ares_buf_tag(conn->out_buf);
|
|
264
|
+
status = ares_buf_fetch_be16(conn->out_buf, &msg_len);
|
|
265
|
+
if (status != ARES_SUCCESS) {
|
|
266
|
+
return status;
|
|
267
|
+
}
|
|
268
|
+
ares_buf_tag_rollback(conn->out_buf);
|
|
269
|
+
|
|
270
|
+
data = ares_buf_peek(conn->out_buf, &data_len);
|
|
271
|
+
if (data_len < (size_t)(msg_len + 2)) {
|
|
272
|
+
status = ARES_EFORMERR;
|
|
273
|
+
goto done;
|
|
274
|
+
}
|
|
275
|
+
data += 2;
|
|
276
|
+
data_len = msg_len;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
err = ares_conn_write(conn, data, data_len, &count);
|
|
280
|
+
if (err != ARES_CONN_ERR_SUCCESS) {
|
|
281
|
+
if (err != ARES_CONN_ERR_WOULDBLOCK) {
|
|
282
|
+
status = ARES_ECONNREFUSED;
|
|
283
|
+
goto done;
|
|
284
|
+
}
|
|
285
|
+
status = ARES_SUCCESS;
|
|
286
|
+
goto done;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* UDP didn't send the length prefix so augment that here */
|
|
290
|
+
if (!(conn->flags & ARES_CONN_FLAG_TCP)) {
|
|
291
|
+
count += 2;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Strip data written from the buffer */
|
|
295
|
+
ares_buf_consume(conn->out_buf, count);
|
|
296
|
+
status = ARES_SUCCESS;
|
|
297
|
+
|
|
298
|
+
/* Loop only for UDP since we have to send per-packet. We already
|
|
299
|
+
* sent everything we could if using tcp */
|
|
300
|
+
} while (!(conn->flags & ARES_CONN_FLAG_TCP));
|
|
301
|
+
|
|
302
|
+
done:
|
|
303
|
+
if (status == ARES_SUCCESS) {
|
|
304
|
+
ares_conn_state_flags_t flags = ARES_CONN_STATE_READ;
|
|
305
|
+
|
|
306
|
+
/* When using TFO, the we need to enabling waiting on a write event to
|
|
307
|
+
* be notified of when a connection is actually established */
|
|
308
|
+
if (tfo) {
|
|
309
|
+
flags |= ARES_CONN_STATE_WRITE;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* If using TCP and not all data was written (partial write), that means
|
|
313
|
+
* we need to also wait on a write event */
|
|
314
|
+
if (conn->flags & ARES_CONN_FLAG_TCP && ares_buf_len(conn->out_buf)) {
|
|
315
|
+
flags |= ARES_CONN_STATE_WRITE;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
ares_conn_sock_state_cb_update(conn, flags);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return status;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
static ares_status_t ares_conn_connect(ares_conn_t *conn,
|
|
325
|
+
const struct sockaddr *sa,
|
|
326
|
+
ares_socklen_t salen)
|
|
327
|
+
{
|
|
328
|
+
ares_conn_err_t err;
|
|
329
|
+
|
|
330
|
+
err = ares_socket_connect(
|
|
331
|
+
conn->server->channel, conn->fd,
|
|
332
|
+
(conn->flags & ARES_CONN_FLAG_TFO) ? ARES_TRUE : ARES_FALSE, sa, salen);
|
|
333
|
+
|
|
334
|
+
if (err != ARES_CONN_ERR_WOULDBLOCK && err != ARES_CONN_ERR_SUCCESS) {
|
|
335
|
+
return ARES_ECONNREFUSED;
|
|
336
|
+
}
|
|
337
|
+
return ARES_SUCCESS;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
ares_status_t ares_open_connection(ares_conn_t **conn_out,
|
|
341
|
+
ares_channel_t *channel,
|
|
342
|
+
ares_server_t *server, ares_bool_t is_tcp)
|
|
343
|
+
{
|
|
344
|
+
ares_status_t status;
|
|
345
|
+
struct sockaddr_storage sa_storage;
|
|
346
|
+
ares_socklen_t salen = sizeof(sa_storage);
|
|
347
|
+
struct sockaddr *sa = (struct sockaddr *)&sa_storage;
|
|
348
|
+
ares_conn_t *conn;
|
|
349
|
+
ares_llist_node_t *node = NULL;
|
|
350
|
+
int stype = is_tcp ? SOCK_STREAM : SOCK_DGRAM;
|
|
351
|
+
ares_conn_state_flags_t state_flags;
|
|
352
|
+
|
|
353
|
+
*conn_out = NULL;
|
|
354
|
+
|
|
355
|
+
conn = ares_malloc(sizeof(*conn));
|
|
356
|
+
if (conn == NULL) {
|
|
357
|
+
return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
memset(conn, 0, sizeof(*conn));
|
|
361
|
+
conn->fd = ARES_SOCKET_BAD;
|
|
362
|
+
conn->server = server;
|
|
363
|
+
conn->queries_to_conn = ares_llist_create(NULL);
|
|
364
|
+
conn->flags = is_tcp ? ARES_CONN_FLAG_TCP : ARES_CONN_FLAG_NONE;
|
|
365
|
+
conn->out_buf = ares_buf_create();
|
|
366
|
+
conn->in_buf = ares_buf_create();
|
|
367
|
+
|
|
368
|
+
if (conn->queries_to_conn == NULL || conn->out_buf == NULL ||
|
|
369
|
+
conn->in_buf == NULL) {
|
|
370
|
+
/* LCOV_EXCL_START: OutOfMemory */
|
|
371
|
+
status = ARES_ENOMEM;
|
|
372
|
+
goto done;
|
|
373
|
+
/* LCOV_EXCL_STOP */
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* Try to enable TFO always if using TCP. it will fail later on if its
|
|
377
|
+
* really not supported when we try to enable it on the socket. */
|
|
378
|
+
if (conn->flags & ARES_CONN_FLAG_TCP) {
|
|
379
|
+
conn->flags |= ARES_CONN_FLAG_TFO;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* Convert into the struct sockaddr structure needed by the OS */
|
|
383
|
+
status = ares_conn_set_sockaddr(conn, sa, &salen);
|
|
384
|
+
if (status != ARES_SUCCESS) {
|
|
385
|
+
goto done;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Acquire a socket. */
|
|
389
|
+
if (ares_socket_open(&conn->fd, channel, server->addr.family, stype, 0) !=
|
|
390
|
+
ARES_CONN_ERR_SUCCESS) {
|
|
391
|
+
status = ARES_ECONNREFUSED;
|
|
392
|
+
goto done;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* Configure channel configured options */
|
|
396
|
+
status = ares_socket_configure(
|
|
397
|
+
channel, server->addr.family,
|
|
398
|
+
(conn->flags & ARES_CONN_FLAG_TCP) ? ARES_TRUE : ARES_FALSE, conn->fd);
|
|
399
|
+
if (status != ARES_SUCCESS) {
|
|
400
|
+
goto done;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* Enable TFO if possible */
|
|
404
|
+
if (conn->flags & ARES_CONN_FLAG_TFO &&
|
|
405
|
+
ares_socket_enable_tfo(channel, conn->fd) != ARES_CONN_ERR_SUCCESS) {
|
|
406
|
+
conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (channel->sock_config_cb) {
|
|
410
|
+
int err =
|
|
411
|
+
channel->sock_config_cb(conn->fd, stype, channel->sock_config_cb_data);
|
|
412
|
+
if (err < 0) {
|
|
413
|
+
status = ARES_ECONNREFUSED;
|
|
414
|
+
goto done;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Connect */
|
|
419
|
+
status = ares_conn_connect(conn, sa, salen);
|
|
420
|
+
if (status != ARES_SUCCESS) {
|
|
421
|
+
goto done;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (channel->sock_create_cb) {
|
|
425
|
+
int err =
|
|
426
|
+
channel->sock_create_cb(conn->fd, stype, channel->sock_create_cb_data);
|
|
427
|
+
if (err < 0) {
|
|
428
|
+
status = ARES_ECONNREFUSED;
|
|
429
|
+
goto done;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/* Let the connection know we haven't written our first packet yet for TFO */
|
|
434
|
+
if (conn->flags & ARES_CONN_FLAG_TFO) {
|
|
435
|
+
conn->flags |= ARES_CONN_FLAG_TFO_INITIAL;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/* Need to store our own ip for DNS cookie support */
|
|
439
|
+
status = ares_conn_set_self_ip(conn, ARES_TRUE);
|
|
440
|
+
if (status != ARES_SUCCESS) {
|
|
441
|
+
goto done; /* LCOV_EXCL_LINE: UntestablePath */
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/* TCP connections are thrown to the end as we don't spawn multiple TCP
|
|
445
|
+
* connections. UDP connections are put on front where the newest connection
|
|
446
|
+
* can be quickly pulled */
|
|
447
|
+
if (is_tcp) {
|
|
448
|
+
node = ares_llist_insert_last(server->connections, conn);
|
|
449
|
+
} else {
|
|
450
|
+
node = ares_llist_insert_first(server->connections, conn);
|
|
451
|
+
}
|
|
452
|
+
if (node == NULL) {
|
|
453
|
+
/* LCOV_EXCL_START: OutOfMemory */
|
|
454
|
+
status = ARES_ENOMEM;
|
|
455
|
+
goto done;
|
|
456
|
+
/* LCOV_EXCL_STOP */
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* Register globally to quickly map event on file descriptor to connection
|
|
460
|
+
* node object */
|
|
461
|
+
if (!ares_htable_asvp_insert(channel->connnode_by_socket, conn->fd, node)) {
|
|
462
|
+
/* LCOV_EXCL_START: OutOfMemory */
|
|
463
|
+
status = ARES_ENOMEM;
|
|
464
|
+
goto done;
|
|
465
|
+
/* LCOV_EXCL_STOP */
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
state_flags = ARES_CONN_STATE_READ;
|
|
469
|
+
|
|
470
|
+
/* Get notified on connect if using TCP */
|
|
471
|
+
if (conn->flags & ARES_CONN_FLAG_TCP) {
|
|
472
|
+
state_flags |= ARES_CONN_STATE_WRITE;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/* Dot no attempt to update sock state callbacks on TFO until *after* the
|
|
476
|
+
* initial write is performed. Due to the notification event, its possible
|
|
477
|
+
* an erroneous read can come in before the attempt to write the data which
|
|
478
|
+
* might be used to set the ip address */
|
|
479
|
+
if (!(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) {
|
|
480
|
+
ares_conn_sock_state_cb_update(conn, state_flags);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (is_tcp) {
|
|
484
|
+
server->tcp_conn = conn;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
done:
|
|
488
|
+
if (status != ARES_SUCCESS) {
|
|
489
|
+
ares_llist_node_claim(node);
|
|
490
|
+
ares_llist_destroy(conn->queries_to_conn);
|
|
491
|
+
ares_socket_close(channel, conn->fd);
|
|
492
|
+
ares_buf_destroy(conn->out_buf);
|
|
493
|
+
ares_buf_destroy(conn->in_buf);
|
|
494
|
+
ares_free(conn);
|
|
495
|
+
} else {
|
|
496
|
+
*conn_out = conn;
|
|
497
|
+
}
|
|
498
|
+
return status;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
ares_conn_t *ares_conn_from_fd(const ares_channel_t *channel, ares_socket_t fd)
|
|
502
|
+
{
|
|
503
|
+
ares_llist_node_t *node;
|
|
504
|
+
|
|
505
|
+
node = ares_htable_asvp_get_direct(channel->connnode_by_socket, fd);
|
|
506
|
+
if (node == NULL) {
|
|
507
|
+
return NULL;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return ares_llist_node_val(node);
|
|
511
|
+
}
|