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,161 @@
|
|
|
1
|
+
// crypto.X509Certificate (Node's lib/internal/crypto/x509.js): what it shows comes from our DER
|
|
2
|
+
// reader (internal/tls/x509.js, OpenSSL's printing); the checks are BoringSSL's X509 functions.
|
|
3
|
+
// A feature module (internal/features.js): linked into programs that name the class.
|
|
4
|
+
// Ported from Node.js (Copyright Node.js contributors, MIT): node/third_party/nodejs/LICENSE.
|
|
5
|
+
import { x509Check, x509CheckIssued, x509CheckKey } from "visaljs:host";
|
|
6
|
+
import { X509Certificate as X509CertificateWrapper } from "../crypto.js";
|
|
7
|
+
import { inspect } from "../util.js";
|
|
8
|
+
import { codeError, invalidArgType, invalidArgValue, validateString } from "./errors.js";
|
|
9
|
+
import { features, provideClass } from "./features.js";
|
|
10
|
+
import { altNamesString, certificatesOf, fingerprint, legacyObject, nameString, opensslTime, parseCertificate, toPem } from "./tls/x509.js";
|
|
11
|
+
import { createPublicKey, KeyObject } from "./crypto/keys.js";
|
|
12
|
+
import { kHandle } from "./crypto/util.js";
|
|
13
|
+
|
|
14
|
+
/* BoringSSL's X509_CHECK_FLAG_*: it has no multi-label wildcards or single-label subdomains, and
|
|
15
|
+
* always checks the subject when a certificate has no names of the kind */
|
|
16
|
+
const NO_WILDCARDS = 0x2, NEVER_CHECK_SUBJECT = 0x20;
|
|
17
|
+
|
|
18
|
+
/* OpenSSL's long names (OBJ_nid2ln) of the signature algorithms certificates use */
|
|
19
|
+
const SIGNATURE_ALGORITHMS = {
|
|
20
|
+
"1.2.840.113549.1.1.4": "md5WithRSAEncryption", "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
|
|
21
|
+
"1.2.840.113549.1.1.10": "rsassaPss", "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
|
|
22
|
+
"1.2.840.113549.1.1.12": "sha384WithRSAEncryption", "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
|
|
23
|
+
"1.2.840.113549.1.1.14": "sha224WithRSAEncryption", "1.2.840.10045.4.1": "ecdsa-with-SHA1",
|
|
24
|
+
"1.2.840.10045.4.3.1": "ecdsa-with-SHA224", "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
|
|
25
|
+
"1.2.840.10045.4.3.3": "ecdsa-with-SHA384", "1.2.840.10045.4.3.4": "ecdsa-with-SHA512", "1.3.101.112": "ED25519",
|
|
26
|
+
"1.3.101.113": "ED448",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const kCert = Symbol("kCert");
|
|
30
|
+
const kIssuer = Symbol("kIssuer");
|
|
31
|
+
const kCache = Symbol("kCache");
|
|
32
|
+
|
|
33
|
+
const noCertificate = () => codeError(Error, "ERR_OSSL_PEM_NO_START_LINE", "error:0480006C:PEM routines::no start line");
|
|
34
|
+
|
|
35
|
+
function checkFlags(options = {}) {
|
|
36
|
+
if (typeof options !== "object" || options === null || Array.isArray(options)) throw invalidArgType("options", "of type object", options);
|
|
37
|
+
const { subject = "default", wildcards = true, partialWildcards = true, multiLabelWildcards = false, singleLabelSubdomains = false } = options;
|
|
38
|
+
validateString(subject, "options.subject");
|
|
39
|
+
for (const [name, value] of [["wildcards", wildcards], ["partialWildcards", partialWildcards], ["multiLabelWildcards", multiLabelWildcards],
|
|
40
|
+
["singleLabelSubdomains", singleLabelSubdomains]]) {
|
|
41
|
+
if (typeof value !== "boolean") throw invalidArgType(`options.${name}`, "of type boolean", value);
|
|
42
|
+
}
|
|
43
|
+
let flags = 0;
|
|
44
|
+
switch (subject) {
|
|
45
|
+
case "default":
|
|
46
|
+
case "always":
|
|
47
|
+
break;
|
|
48
|
+
case "never":
|
|
49
|
+
flags |= NEVER_CHECK_SUBJECT;
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
throw invalidArgValue("options.subject", "is invalid", subject);
|
|
53
|
+
}
|
|
54
|
+
if (!wildcards) flags |= NO_WILDCARDS;
|
|
55
|
+
return flags;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function isX509Certificate(value) {
|
|
59
|
+
return value?.[kCert] !== undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
class X509Certificate {
|
|
63
|
+
constructor(buffer) {
|
|
64
|
+
if (typeof buffer === "string") buffer = Buffer.from(buffer);
|
|
65
|
+
if (!ArrayBuffer.isView(buffer)) throw invalidArgType("buffer", "of type string or an instance of Buffer, TypedArray, or DataView", buffer);
|
|
66
|
+
const der = certificatesOf(buffer)[0];
|
|
67
|
+
if (der === undefined) throw noCertificate();
|
|
68
|
+
let cert;
|
|
69
|
+
try {
|
|
70
|
+
cert = parseCertificate(der);
|
|
71
|
+
} catch {
|
|
72
|
+
throw codeError(Error, "ERR_OSSL_ASN1_HEADER_TOO_LONG", "error:0680007B:asn1 encoding routines::header too long");
|
|
73
|
+
}
|
|
74
|
+
this[kCert] = cert;
|
|
75
|
+
this[kIssuer] = undefined;
|
|
76
|
+
this[kCache] = new Map();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
#cached(name, compute) {
|
|
80
|
+
const cache = this[kCache];
|
|
81
|
+
if (!cache.has(name)) cache.set(name, compute(this[kCert]));
|
|
82
|
+
return cache.get(name);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[inspect.custom](depth, options) {
|
|
86
|
+
if (depth < 0) return this;
|
|
87
|
+
const opts = { ...options, depth: options.depth == null ? null : options.depth - 1 };
|
|
88
|
+
return `X509Certificate ${inspect({
|
|
89
|
+
subject: this.subject, subjectAltName: this.subjectAltName, issuer: this.issuer, infoAccess: this.infoAccess,
|
|
90
|
+
validFrom: this.validFrom, validTo: this.validTo, validFromDate: this.validFromDate, validToDate: this.validToDate,
|
|
91
|
+
fingerprint: this.fingerprint, fingerprint256: this.fingerprint256, fingerprint512: this.fingerprint512, keyUsage: this.keyUsage,
|
|
92
|
+
serialNumber: this.serialNumber, signatureAlgorithm: this.signatureAlgorithm, signatureAlgorithmOid: this.signatureAlgorithmOid,
|
|
93
|
+
}, opts)}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get subject() { return this.#cached("subject", (c) => nameString(c.subject)); }
|
|
97
|
+
get subjectAltName() { return this.#cached("subjectAltName", altNamesString); }
|
|
98
|
+
get issuer() { return this.#cached("issuer", (c) => nameString(c.issuer)); }
|
|
99
|
+
get issuerCertificate() { return this[kIssuer]; }
|
|
100
|
+
get infoAccess() { return this.#cached("infoAccess", (c) => c.infoAccess?.join("\n")); }
|
|
101
|
+
get validFrom() { return this.#cached("validFrom", (c) => opensslTime(c.validFrom)); }
|
|
102
|
+
get validTo() { return this.#cached("validTo", (c) => opensslTime(c.validTo)); }
|
|
103
|
+
get validFromDate() { return this.#cached("validFromDate", (c) => new Date(c.validFrom)); }
|
|
104
|
+
get validToDate() { return this.#cached("validToDate", (c) => new Date(c.validTo)); }
|
|
105
|
+
get fingerprint() { return this.#cached("fingerprint", (c) => fingerprint("sha1", c.der)); }
|
|
106
|
+
get fingerprint256() { return this.#cached("fingerprint256", (c) => fingerprint("sha256", c.der)); }
|
|
107
|
+
get fingerprint512() { return this.#cached("fingerprint512", (c) => fingerprint("sha512", c.der)); }
|
|
108
|
+
/* Node's keyUsage: the extended key usages' OIDs */
|
|
109
|
+
get keyUsage() { return this.#cached("keyUsage", (c) => c.extKeyUsage ?? undefined); }
|
|
110
|
+
get serialNumber() { return this.#cached("serialNumber", (c) => c.serialNumber); }
|
|
111
|
+
get signatureAlgorithm() { return this.#cached("signatureAlgorithm", (c) => SIGNATURE_ALGORITHMS[c.signatureAlgorithm]); }
|
|
112
|
+
get signatureAlgorithmOid() { return this.#cached("signatureAlgorithmOid", (c) => c.signatureAlgorithm); }
|
|
113
|
+
get raw() { return this.#cached("raw", (c) => Buffer.from(c.der)); }
|
|
114
|
+
get publicKey() { return this.#cached("publicKey", (c) => createPublicKey({ key: Buffer.from(c.spki), format: "der", type: "spki" })); }
|
|
115
|
+
get ca() { return this.#cached("ca", (c) => c.ca); }
|
|
116
|
+
|
|
117
|
+
toString() { return this.#cached("pem", (c) => toPem(c.der)); }
|
|
118
|
+
toJSON() { return this.toString(); }
|
|
119
|
+
toLegacyObject() { return legacyObject(this[kCert]); }
|
|
120
|
+
|
|
121
|
+
checkHost(name, options) {
|
|
122
|
+
validateString(name, "name");
|
|
123
|
+
return x509Check(this[kCert].der, 0, name, checkFlags(options));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
checkEmail(email, options) {
|
|
127
|
+
validateString(email, "email");
|
|
128
|
+
return x509Check(this[kCert].der, 1, email, checkFlags(options));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
checkIP(ip, options) {
|
|
132
|
+
validateString(ip, "ip");
|
|
133
|
+
return x509Check(this[kCert].der, 2, ip, checkFlags(options));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
checkIssued(otherCert) {
|
|
137
|
+
if (!isX509Certificate(otherCert)) throw invalidArgType("otherCert", "an instance of X509Certificate", otherCert);
|
|
138
|
+
return x509CheckIssued(this[kCert].der, otherCert[kCert].der);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
checkPrivateKey(pkey) {
|
|
142
|
+
if (!(pkey instanceof KeyObject)) throw invalidArgType("pkey", "an instance of KeyObject", pkey);
|
|
143
|
+
if (pkey.type !== "private") throw invalidArgValue("pkey", "is invalid", pkey);
|
|
144
|
+
return x509CheckKey(this[kCert].der, pkey[kHandle]);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
verify(pkey) {
|
|
148
|
+
if (!(pkey instanceof KeyObject)) throw invalidArgType("pkey", "an instance of KeyObject", pkey);
|
|
149
|
+
if (pkey.type !== "public") throw invalidArgValue("pkey", "is invalid", pkey);
|
|
150
|
+
return x509CheckKey(this[kCert].der, pkey[kHandle]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
provideClass(X509CertificateWrapper, X509Certificate);
|
|
155
|
+
|
|
156
|
+
/* a chain's first certificate, each one's issuerCertificate the next (getPeerX509Certificate) */
|
|
157
|
+
features.x509CertificateChain = (ders) => {
|
|
158
|
+
const certs = ders.map((der) => new X509Certificate(der));
|
|
159
|
+
for (let i = 0; i + 1 < certs.length; i++) certs[i][kIssuer] = certs[i + 1];
|
|
160
|
+
return certs[0];
|
|
161
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// dns.Resolver and dns.promises.Resolver as node:dns exports them: wrappers internal/dns_resolver.js
|
|
2
|
+
// gives its classes (internal/features.js), so programs that don't name them don't link c-ares.
|
|
3
|
+
import { lazyClass } from "./features.js";
|
|
4
|
+
|
|
5
|
+
export const Resolver = /* @__PURE__ */ lazyClass("Resolver", "dnsResolver");
|
|
6
|
+
export const PromisesResolver = /* @__PURE__ */ lazyClass("Resolver", "dnsPromisesResolver");
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
// dns.Resolver, dns.promises.Resolver, and the resolve* functions of node:dns and dns/promises
|
|
2
|
+
// (Node's lib/internal/dns/utils.js, callback_resolver.js and promises.js) over c-ares
|
|
3
|
+
// (src/host_dns.c). A feature module (internal/features.js): linked into programs that name them.
|
|
4
|
+
// The queries' answers are read by c-ares's parsers, and shaped here as Node's cares_wrap shapes them.
|
|
5
|
+
// Ported from Node.js (Copyright Node.js contributors, MIT): node/third_party/nodejs/LICENSE.
|
|
6
|
+
import {
|
|
7
|
+
dnsCancel, dnsChannel, dnsGetServers, dnsParse, dnsQuery, dnsReverse, dnsSetLocalAddress, dnsSetServers, dnsStrerror, errnoName,
|
|
8
|
+
} from "visaljs:host";
|
|
9
|
+
import { PromisesResolver as PromisesResolverWrapper, Resolver as ResolverWrapper } from "./dns_classes.js";
|
|
10
|
+
import { domainToASCII } from "../url.js";
|
|
11
|
+
import { bindContext } from "./async_context.js";
|
|
12
|
+
import { codeError, invalidArgType, invalidArgValue, outOfRange, validateFunction, validatePort, validateString } from "./errors.js";
|
|
13
|
+
import { features, provideClass } from "./features.js";
|
|
14
|
+
import { isIP } from "./net.js";
|
|
15
|
+
|
|
16
|
+
const IANA_DNS_PORT = 53;
|
|
17
|
+
const IPv6RE = /^\[([^[\]]*)\]/;
|
|
18
|
+
const addrSplitRE = /(^.+?)(?::(\d+))?$/;
|
|
19
|
+
|
|
20
|
+
/* ARES_* statuses, by number (ares.h), as Node's ToErrorCodeString names them */
|
|
21
|
+
const ARES_CODES = [undefined, "ENODATA", "EFORMERR", "ESERVFAIL", "ENOTFOUND", "ENOTIMP", "EREFUSED", "EBADQUERY", "EBADNAME", "EBADFAMILY",
|
|
22
|
+
"EBADRESP", "ECONNREFUSED", "ETIMEOUT", "EOF", "EFILE", "ENOMEM", "EDESTRUCTION", "EBADSTR", "EBADFLAGS", "ENONAME", "EBADHINTS",
|
|
23
|
+
"ENOTINITIALIZED", "ELOADIPHLPAPI", "EADDRGETNETWORKPARAMS", "ECANCELLED"];
|
|
24
|
+
const ARES_SUCCESS = 0, ARES_ENODATA = 1;
|
|
25
|
+
const aresCode = (status) => ARES_CODES[status] ?? "UNKNOWN_ARES_ERROR";
|
|
26
|
+
|
|
27
|
+
/** Node's DNSException: a libuv errno, or a c-ares code */
|
|
28
|
+
function dnsException(code, syscall, hostname) {
|
|
29
|
+
let errno;
|
|
30
|
+
if (typeof code === "number") {
|
|
31
|
+
errno = code;
|
|
32
|
+
code = errnoName(code);
|
|
33
|
+
if (code === "EAI_NODATA" || code === "EAI_NONAME") code = "ENOTFOUND";
|
|
34
|
+
}
|
|
35
|
+
const error = new Error(`${syscall} ${code}${hostname ? ` ${hostname}` : ""}`);
|
|
36
|
+
error.errno = errno;
|
|
37
|
+
error.code = code;
|
|
38
|
+
error.syscall = syscall;
|
|
39
|
+
if (hostname) error.hostname = hostname;
|
|
40
|
+
return error;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ---- the binding: Node's ChannelWrap queries, as cares_wrap shapes their answers ------------- */
|
|
44
|
+
|
|
45
|
+
/* the DNS types (ares_dns_rec_type_t) */
|
|
46
|
+
const T = { A: 1, NS: 2, CNAME: 5, SOA: 6, PTR: 12, MX: 15, TXT: 16, AAAA: 28, SRV: 33, NAPTR: 35, TLSA: 52, ANY: 255, CAA: 257 };
|
|
47
|
+
/* dnsParse's kinds for a CNAME or A records (Node's ns_t_cname_or_a), and for ANY's SOA */
|
|
48
|
+
const CNAME_OR_A = 0x10000;
|
|
49
|
+
const SOA_IN_ANY = 0x10006;
|
|
50
|
+
|
|
51
|
+
const TYPES = {
|
|
52
|
+
queryA: T.A, queryAaaa: T.AAAA, queryCname: T.CNAME, queryMx: T.MX, queryNs: T.NS, queryTxt: T.TXT, querySrv: T.SRV, queryPtr: T.PTR,
|
|
53
|
+
queryNaptr: T.NAPTR, querySoa: T.SOA, queryCaa: T.CAA, queryTlsa: T.TLSA, queryAny: T.ANY,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const mxRecord = ([priority, exchange]) => ({ exchange, priority, type: "MX" });
|
|
57
|
+
const srvRecord = ([name, port, priority, weight]) => ({ name, port, priority, weight, type: "SRV" });
|
|
58
|
+
const naptrRecord = ([flags, service, regexp, replacement, order, preference]) => ({ flags, service, regexp, replacement, order, preference, type: "NAPTR" });
|
|
59
|
+
const soaRecord = ([nsname, hostmaster, serial, refresh, retry, expire, minttl]) => ({ nsname, hostmaster, serial, refresh, retry, expire, minttl });
|
|
60
|
+
function caaRecord([critical, property, value]) {
|
|
61
|
+
const record = { critical, type: "CAA" };
|
|
62
|
+
record[property] = value;
|
|
63
|
+
return record;
|
|
64
|
+
}
|
|
65
|
+
const tlsaRecord = ([certUsage, selector, match, data]) =>
|
|
66
|
+
({ certUsage, selector, match, data: data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) });
|
|
67
|
+
|
|
68
|
+
/* a query's answer → [status, result, ttls] (Node's Traits::Parse) */
|
|
69
|
+
function shape(bindingName, answer) {
|
|
70
|
+
const kind = TYPES[bindingName];
|
|
71
|
+
if (kind === T.ANY) return parseAny(answer);
|
|
72
|
+
const [status, records, ttls] = dnsParse(answer, kind);
|
|
73
|
+
if (status !== ARES_SUCCESS) return [status];
|
|
74
|
+
switch (kind) {
|
|
75
|
+
case T.A:
|
|
76
|
+
case T.AAAA: return [status, records, ttls];
|
|
77
|
+
case T.MX: return [status, records.map(mxRecord)];
|
|
78
|
+
case T.SRV: return [status, records.map(srvRecord)];
|
|
79
|
+
case T.NAPTR: return [status, records.map(naptrRecord)];
|
|
80
|
+
case T.SOA: return records.length ? [status, soaRecord(records[0])] : [ARES_ENODATA];
|
|
81
|
+
case T.CAA: return [status, records.map(caaRecord)];
|
|
82
|
+
case T.TLSA: return [status, records.map(tlsaRecord)];
|
|
83
|
+
default: return [status, records];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ANY: every kind's records, each with its type, in Node's order; a kind without any is skipped */
|
|
88
|
+
function parseAny(answer) {
|
|
89
|
+
const out = [];
|
|
90
|
+
const parse = (kind, add) => {
|
|
91
|
+
const [status, records, ttls, cname] = dnsParse(answer, kind);
|
|
92
|
+
if (status === ARES_SUCCESS) add(records, ttls, cname);
|
|
93
|
+
return status === ARES_SUCCESS || status === ARES_ENODATA ? 0 : status;
|
|
94
|
+
};
|
|
95
|
+
const steps = [
|
|
96
|
+
[CNAME_OR_A, (records, ttls, cname) => {
|
|
97
|
+
for (const [i, value] of records.entries()) out.push(cname ? { value, type: "CNAME" } : { address: value, ttl: ttls[i], type: "A" });
|
|
98
|
+
}],
|
|
99
|
+
[T.AAAA, (records, ttls) => records.forEach((address, i) => out.push({ address, ttl: ttls[i], type: "AAAA" }))],
|
|
100
|
+
[T.MX, (records) => records.forEach((r) => out.push(mxRecord(r)))],
|
|
101
|
+
[T.NS, (records) => records.forEach((value) => out.push({ value, type: "NS" }))],
|
|
102
|
+
[T.TXT, (records) => records.forEach((entries) => out.push({ entries, type: "TXT" }))],
|
|
103
|
+
[T.SRV, (records) => records.forEach((r) => out.push(srvRecord(r)))],
|
|
104
|
+
[T.PTR, (records) => records.forEach((value) => out.push({ value, type: "PTR" }))],
|
|
105
|
+
[T.NAPTR, (records) => records.forEach((r) => out.push(naptrRecord(r)))],
|
|
106
|
+
[SOA_IN_ANY, (records) => records.forEach((r) => out.push({ ...soaRecord(r), type: "SOA" }))],
|
|
107
|
+
[T.TLSA, (records) => records.forEach((r) => out.push({ ...tlsaRecord(r), type: "TLSA" }))],
|
|
108
|
+
[T.CAA, (records) => records.forEach((r) => out.push(caaRecord(r)))],
|
|
109
|
+
];
|
|
110
|
+
for (const [kind, add] of steps) {
|
|
111
|
+
const status = parse(kind, add);
|
|
112
|
+
if (status !== 0) return [status];
|
|
113
|
+
}
|
|
114
|
+
return [ARES_SUCCESS, out];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Node's QueryWrap::Send: 0, or what went wrong at once; req.oncomplete(code | null, result, ttls) later */
|
|
118
|
+
function send(channel, bindingName, req, name) {
|
|
119
|
+
const done = bindContext((status, answer) => {
|
|
120
|
+
let result, ttls;
|
|
121
|
+
if (status === ARES_SUCCESS) {
|
|
122
|
+
if (bindingName === "getHostByAddr") result = answer;
|
|
123
|
+
else [status, result, ttls] = shape(bindingName, answer);
|
|
124
|
+
}
|
|
125
|
+
if (status !== ARES_SUCCESS) req.oncomplete(aresCode(status));
|
|
126
|
+
else req.oncomplete(null, result, ttls);
|
|
127
|
+
});
|
|
128
|
+
if (bindingName === "getHostByAddr") return dnsReverse(channel, name, done);
|
|
129
|
+
return dnsQuery(channel, domainToASCII(name) || name, TYPES[bindingName], done);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* ---- ResolverBase (Node's internal/dns/utils.js) -------------------------------------------- */
|
|
133
|
+
|
|
134
|
+
function validateInt32(value, name, min) {
|
|
135
|
+
if (typeof value !== "number") throw invalidArgType(name, "of type number", value);
|
|
136
|
+
if (!Number.isInteger(value)) throw outOfRange(name, "an integer", value);
|
|
137
|
+
if (value < min || value > 2 ** 31 - 1) throw outOfRange(name, `>= ${min} && <= ${2 ** 31 - 1}`, value);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function validateOptions(options) {
|
|
141
|
+
let { timeout = -1, tries = 4, maxTimeout = 0 } = { ...options };
|
|
142
|
+
validateInt32(timeout, "options.timeout", -1);
|
|
143
|
+
validateInt32(tries, "options.tries", 1);
|
|
144
|
+
if (typeof maxTimeout !== "number") throw invalidArgType("options.maxTimeout", "of type number", maxTimeout);
|
|
145
|
+
if (!Number.isInteger(maxTimeout)) throw outOfRange("options.maxTimeout", "an integer", maxTimeout);
|
|
146
|
+
if (maxTimeout < 0 || maxTimeout > 2 ** 32 - 1) throw outOfRange("options.maxTimeout", `>= 0 && <= ${2 ** 32 - 1}`, maxTimeout);
|
|
147
|
+
/* -0 as +0 */
|
|
148
|
+
timeout += 0;
|
|
149
|
+
maxTimeout += 0;
|
|
150
|
+
return [timeout, tries, maxTimeout];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
const invalidIP = (ip) => codeError(TypeError, "ERR_INVALID_IP_ADDRESS", `Invalid IP address: ${ip}`);
|
|
155
|
+
|
|
156
|
+
/* The channel's handle, as Node's ChannelWrap: queries by binding name */
|
|
157
|
+
class ChannelWrap {
|
|
158
|
+
constructor(timeout, tries, maxTimeout) {
|
|
159
|
+
this.channel = dnsChannel(timeout, tries, maxTimeout);
|
|
160
|
+
}
|
|
161
|
+
getServers() { return dnsGetServers(this.channel); }
|
|
162
|
+
setServers(servers) { return dnsSetServers(this.channel, servers); }
|
|
163
|
+
setLocalAddress(ipv4, ipv6) {
|
|
164
|
+
const ips = [ipv4, ipv6];
|
|
165
|
+
if (isIP(ipv4) === 0 || (ipv6 !== undefined && isIP(ipv6) === 0)) {
|
|
166
|
+
throw codeError(TypeError, "ERR_INVALID_ARG_VALUE", "Invalid IP address.");
|
|
167
|
+
}
|
|
168
|
+
if (ipv6 !== undefined && isIP(ipv4) === isIP(ipv6)) {
|
|
169
|
+
throw codeError(TypeError, "ERR_INVALID_ARG_VALUE", `Cannot specify two IPv${isIP(ipv4)} addresses.`);
|
|
170
|
+
}
|
|
171
|
+
dnsSetLocalAddress(this.channel, ips.find((ip) => isIP(ip) === 4) ?? null, ips.find((ip) => ip !== undefined && isIP(ip) === 6) ?? null);
|
|
172
|
+
}
|
|
173
|
+
cancel() { dnsCancel(this.channel); }
|
|
174
|
+
}
|
|
175
|
+
for (const bindingName of [...Object.keys(TYPES), "getHostByAddr"]) {
|
|
176
|
+
ChannelWrap.prototype[bindingName] = function (req, name) {
|
|
177
|
+
return send(this.channel, bindingName, req, name);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
class ResolverBase {
|
|
182
|
+
constructor(options = undefined) {
|
|
183
|
+
const [timeout, tries, maxTimeout] = validateOptions(options);
|
|
184
|
+
this._handle = new ChannelWrap(timeout, tries, maxTimeout);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
cancel() {
|
|
188
|
+
this._handle.cancel();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
getServers() {
|
|
192
|
+
return (this._handle.getServers() || []).map((val) => {
|
|
193
|
+
if (!val[1] || val[1] === IANA_DNS_PORT) return val[0];
|
|
194
|
+
const host = isIP(val[0]) === 6 ? `[${val[0]}]` : val[0];
|
|
195
|
+
return `${host}:${val[1]}`;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setServers(servers) {
|
|
200
|
+
if (!Array.isArray(servers)) throw invalidArgType("servers", "an instance of Array", servers);
|
|
201
|
+
const newSet = [];
|
|
202
|
+
servers.forEach((serv, index) => {
|
|
203
|
+
validateString(serv, `servers[${index}]`);
|
|
204
|
+
let ipVersion = isIP(serv);
|
|
205
|
+
if (ipVersion !== 0) return newSet.push([ipVersion, serv, IANA_DNS_PORT]);
|
|
206
|
+
const match = IPv6RE.exec(serv);
|
|
207
|
+
if (match) {
|
|
208
|
+
ipVersion = isIP(match[1]);
|
|
209
|
+
if (ipVersion !== 0) {
|
|
210
|
+
const port = Number.parseInt(serv.replace(addrSplitRE, "$2")) || IANA_DNS_PORT;
|
|
211
|
+
validatePort(port);
|
|
212
|
+
return newSet.push([ipVersion, match[1], port]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const addrSplitMatch = addrSplitRE.exec(serv);
|
|
216
|
+
if (addrSplitMatch) {
|
|
217
|
+
const hostIP = addrSplitMatch[1];
|
|
218
|
+
const port = Number.parseInt(addrSplitMatch[2]) || IANA_DNS_PORT;
|
|
219
|
+
ipVersion = isIP(hostIP);
|
|
220
|
+
if (ipVersion !== 0) {
|
|
221
|
+
validatePort(port);
|
|
222
|
+
return newSet.push([ipVersion, hostIP, port]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
throw invalidIP(serv);
|
|
226
|
+
});
|
|
227
|
+
const orig = (this._handle.getServers() || []).map((val) => [isIP(val[0]), ...val]);
|
|
228
|
+
const errorNumber = this._handle.setServers(newSet);
|
|
229
|
+
if (errorNumber !== 0) {
|
|
230
|
+
this._handle.setServers(orig);
|
|
231
|
+
throw codeError(Error, "ERR_DNS_SET_SERVERS_FAILED", `c-ares failed to set servers: "${dnsStrerror(errorNumber)}" [${servers}]`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
setLocalAddress(ipv4, ipv6) {
|
|
236
|
+
validateString(ipv4, "ipv4");
|
|
237
|
+
if (ipv6 !== undefined) validateString(ipv6, "ipv6");
|
|
238
|
+
this._handle.setLocalAddress(ipv4, ipv6);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function createResolverClass(resolver) {
|
|
243
|
+
const resolveMap = { __proto__: null };
|
|
244
|
+
class Resolver extends ResolverBase {}
|
|
245
|
+
Resolver.prototype.resolveAny = resolveMap.ANY = resolver("queryAny");
|
|
246
|
+
Resolver.prototype.resolve4 = resolveMap.A = resolver("queryA");
|
|
247
|
+
Resolver.prototype.resolve6 = resolveMap.AAAA = resolver("queryAaaa");
|
|
248
|
+
Resolver.prototype.resolveCaa = resolveMap.CAA = resolver("queryCaa");
|
|
249
|
+
Resolver.prototype.resolveCname = resolveMap.CNAME = resolver("queryCname");
|
|
250
|
+
Resolver.prototype.resolveMx = resolveMap.MX = resolver("queryMx");
|
|
251
|
+
Resolver.prototype.resolveNs = resolveMap.NS = resolver("queryNs");
|
|
252
|
+
Resolver.prototype.resolveTlsa = resolveMap.TLSA = resolver("queryTlsa");
|
|
253
|
+
Resolver.prototype.resolveTxt = resolveMap.TXT = resolver("queryTxt");
|
|
254
|
+
Resolver.prototype.resolveSrv = resolveMap.SRV = resolver("querySrv");
|
|
255
|
+
Resolver.prototype.resolvePtr = resolveMap.PTR = resolver("queryPtr");
|
|
256
|
+
Resolver.prototype.resolveNaptr = resolveMap.NAPTR = resolver("queryNaptr");
|
|
257
|
+
Resolver.prototype.resolveSoa = resolveMap.SOA = resolver("querySoa");
|
|
258
|
+
Resolver.prototype.reverse = resolver("getHostByAddr");
|
|
259
|
+
return { resolveMap, Resolver };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* ---- the callback Resolver (Node's callback_resolver.js) ------------------------------------- */
|
|
263
|
+
|
|
264
|
+
function onresolve(err, result, ttls) {
|
|
265
|
+
if (ttls && this.ttl) result = result.map((address, index) => ({ address, ttl: ttls[index] }));
|
|
266
|
+
if (err) this.callback(dnsException(err, this.bindingName, this.hostname));
|
|
267
|
+
else this.callback(null, result);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function callbackResolver(bindingName) {
|
|
271
|
+
function query(name, /* options, */ callback) {
|
|
272
|
+
let options;
|
|
273
|
+
if (arguments.length > 2) {
|
|
274
|
+
options = callback;
|
|
275
|
+
callback = arguments[2];
|
|
276
|
+
}
|
|
277
|
+
validateString(name, "name");
|
|
278
|
+
validateFunction(callback, "callback");
|
|
279
|
+
const req = { bindingName, callback, hostname: name, oncomplete: onresolve, ttl: !!options?.ttl };
|
|
280
|
+
const err = this._handle[bindingName](req, name);
|
|
281
|
+
if (err) throw dnsException(err, bindingName, name);
|
|
282
|
+
return req;
|
|
283
|
+
}
|
|
284
|
+
Object.defineProperty(query, "name", { value: bindingName });
|
|
285
|
+
return query;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const callbacks = createResolverClass(callbackResolver);
|
|
289
|
+
const Resolver = callbacks.Resolver;
|
|
290
|
+
Resolver.prototype.resolve = function resolve(hostname, rrtype, callback) {
|
|
291
|
+
let resolver;
|
|
292
|
+
if (typeof rrtype === "string") {
|
|
293
|
+
resolver = callbacks.resolveMap[rrtype];
|
|
294
|
+
} else if (typeof rrtype === "function") {
|
|
295
|
+
resolver = callbacks.resolveMap.A;
|
|
296
|
+
callback = rrtype;
|
|
297
|
+
} else {
|
|
298
|
+
throw invalidArgType("rrtype", "of type string", rrtype);
|
|
299
|
+
}
|
|
300
|
+
if (typeof resolver === "function") return resolver.call(this, hostname, callback);
|
|
301
|
+
throw invalidArgValue("rrtype", "is invalid", rrtype);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/* ---- the promises Resolver (Node's promises.js) -------------------------------------------- */
|
|
305
|
+
|
|
306
|
+
function onresolvePromise(err, result, ttls) {
|
|
307
|
+
if (err) {
|
|
308
|
+
this.reject(dnsException(err, this.bindingName, this.hostname));
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (ttls && this.ttl) result = result.map((address, index) => ({ address, ttl: ttls[index] }));
|
|
312
|
+
this.resolve(result);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function promiseResolver(bindingName) {
|
|
316
|
+
function query(name, options) {
|
|
317
|
+
validateString(name, "name");
|
|
318
|
+
const ttl = !!options?.ttl;
|
|
319
|
+
return new Promise((resolve, reject) => {
|
|
320
|
+
const req = { bindingName, hostname: name, oncomplete: onresolvePromise, resolve, reject, ttl };
|
|
321
|
+
const err = this._handle[bindingName](req, name);
|
|
322
|
+
if (err) reject(dnsException(err, bindingName, name));
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
Object.defineProperty(query, "name", { value: bindingName });
|
|
326
|
+
return query;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const promises = createResolverClass(promiseResolver);
|
|
330
|
+
const PromisesResolver = promises.Resolver;
|
|
331
|
+
PromisesResolver.prototype.resolve = function resolve(hostname, rrtype) {
|
|
332
|
+
let resolver;
|
|
333
|
+
if (rrtype !== undefined) {
|
|
334
|
+
validateString(rrtype, "rrtype");
|
|
335
|
+
resolver = promises.resolveMap[rrtype];
|
|
336
|
+
if (typeof resolver !== "function") throw invalidArgValue("rrtype", "is invalid", rrtype);
|
|
337
|
+
} else {
|
|
338
|
+
resolver = promises.resolveMap.A;
|
|
339
|
+
}
|
|
340
|
+
return resolver.call(this, hostname);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/* ---- the default resolver, whose methods node:dns and dns/promises export ------------------- */
|
|
344
|
+
|
|
345
|
+
const resolverKeys = ["getServers", "resolve", "resolve4", "resolve6", "resolveAny", "resolveCaa", "resolveCname", "resolveMx", "resolveNaptr",
|
|
346
|
+
"resolveNs", "resolvePtr", "resolveSoa", "resolveSrv", "resolveTlsa", "resolveTxt", "reverse"];
|
|
347
|
+
|
|
348
|
+
let defaultResolver;
|
|
349
|
+
const getDefaultResolver = () => (defaultResolver ??= new ResolverBase());
|
|
350
|
+
|
|
351
|
+
/* each module's exported functions, bound to the default resolver (features["dns.resolve4"], …) */
|
|
352
|
+
function bindDefaultResolver() {
|
|
353
|
+
const resolver = getDefaultResolver();
|
|
354
|
+
for (const key of resolverKeys) {
|
|
355
|
+
features[`dns.${key}`] = Resolver.prototype[key].bind(resolver);
|
|
356
|
+
features[`dns.promises.${key}`] = PromisesResolver.prototype[key].bind(resolver);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
bindDefaultResolver();
|
|
360
|
+
|
|
361
|
+
/* dns.setServers and dns.promises.setServers: a new default resolver */
|
|
362
|
+
function defaultResolverSetServers(servers) {
|
|
363
|
+
const resolver = new Resolver();
|
|
364
|
+
resolver.setServers(servers);
|
|
365
|
+
defaultResolver = resolver;
|
|
366
|
+
bindDefaultResolver();
|
|
367
|
+
}
|
|
368
|
+
features["dns.setServers"] = defaultResolverSetServers;
|
|
369
|
+
features["dns.promises.setServers"] = defaultResolverSetServers;
|
|
370
|
+
provideClass(ResolverWrapper, Resolver);
|
|
371
|
+
provideClass(PromisesResolverWrapper, PromisesResolver);
|
|
@@ -83,6 +83,15 @@ export function errnoException(errno, syscall) {
|
|
|
83
83
|
return error;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
/** Node's validatePort: a port as a number or numeric string, 0 to 65535 (1 to 65535 without allowZero) */
|
|
87
|
+
export function validatePort(port, name = "Port", allowZero = true) {
|
|
88
|
+
if ((typeof port !== "number" && typeof port !== "string") || (typeof port === "string" && port.trim().length === 0) ||
|
|
89
|
+
+port !== (+port >>> 0) || port > 0xFFFF || (port === 0 && !allowZero)) {
|
|
90
|
+
throw withCode(new RangeError(`${name} should be ${allowZero ? ">=" : ">"} 0 and < 65536.${received(port)}.`), "ERR_SOCKET_BAD_PORT");
|
|
91
|
+
}
|
|
92
|
+
return +port;
|
|
93
|
+
}
|
|
94
|
+
|
|
86
95
|
export function validateString(value, name) {
|
|
87
96
|
if (typeof value !== "string") throw invalidArgType(name, "of type string", value);
|
|
88
97
|
}
|