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
package/node/src/host_net.c
CHANGED
|
@@ -607,3 +607,49 @@ HOST_FN(js_host_dns_lookup) {
|
|
|
607
607
|
return js_int32(r);
|
|
608
608
|
}
|
|
609
609
|
|
|
610
|
+
/* ---- dns.lookupService --------------------------------------------------------------------- */
|
|
611
|
+
|
|
612
|
+
typedef struct NameInfo {
|
|
613
|
+
uv_getnameinfo_t req;
|
|
614
|
+
JSValue cb; /* a root */
|
|
615
|
+
} NameInfo;
|
|
616
|
+
|
|
617
|
+
static void on_nameinfo(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) {
|
|
618
|
+
NameInfo *n = (NameInfo *)req;
|
|
619
|
+
JSContext *ctx = js_uv_context();
|
|
620
|
+
JSValue args[4] = { js_int32(status), JS_NULL, JS_NULL, JS_NULL };
|
|
621
|
+
if (status == 0) {
|
|
622
|
+
args[1] = js_new_string_cstr(ctx, hostname);
|
|
623
|
+
args[2] = js_new_string_cstr(ctx, service);
|
|
624
|
+
} else {
|
|
625
|
+
args[3] = js_new_string_cstr(ctx, uv_err_name(status));
|
|
626
|
+
}
|
|
627
|
+
JSValue cb = n->cb;
|
|
628
|
+
js_remove_root(ctx->rt, &n->cb);
|
|
629
|
+
free(n);
|
|
630
|
+
(void)js_uv_call(cb, 4, args, NULL);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/* dnsLookupService(ip, port, cb) → 0 | -errno; cb(errno, hostname | null, service | null, code | null): getnameinfo, a
|
|
634
|
+
* name required (NI_NAMEREQD), as Node's */
|
|
635
|
+
HOST_FN(js_host_dns_lookup_service) {
|
|
636
|
+
UNUSED;
|
|
637
|
+
if (argc < 3 || !js_is_string(argv[0]) || !js_is_number(argv[1])) return js_throw_type_error(ctx, "dnsLookupService: (ip, port, cb) expected");
|
|
638
|
+
char ip[64];
|
|
639
|
+
size_t len = js_view_to_utf8(js_string_view(ctx, argv[0]), ip, sizeof ip - 1);
|
|
640
|
+
ip[len] = '\0';
|
|
641
|
+
int port = (int)js_as_number(argv[1]);
|
|
642
|
+
struct sockaddr_storage addr;
|
|
643
|
+
if (uv_ip4_addr(ip, port, (struct sockaddr_in *)&addr) != 0 && uv_ip6_addr(ip, port, (struct sockaddr_in6 *)&addr) != 0) return js_int32(UV_EINVAL);
|
|
644
|
+
NameInfo *n = malloc(sizeof *n);
|
|
645
|
+
if (!n) js_fatal("out of memory in dns");
|
|
646
|
+
n->cb = argv[2];
|
|
647
|
+
js_add_root(ctx->rt, &n->cb);
|
|
648
|
+
int r = uv_getnameinfo(js_uv_loop(ctx), &n->req, on_nameinfo, (const struct sockaddr *)&addr, NI_NAMEREQD);
|
|
649
|
+
if (r < 0) {
|
|
650
|
+
js_remove_root(ctx->rt, &n->cb);
|
|
651
|
+
free(n);
|
|
652
|
+
}
|
|
653
|
+
return js_int32(r);
|
|
654
|
+
}
|
|
655
|
+
|
package/node/src/host_os.c
CHANGED
|
@@ -98,7 +98,7 @@ static JSValue path_result(JSContext *ctx, PathFn fn) {
|
|
|
98
98
|
return e ? js_int32(e) : js_new_string_utf8(ctx, buf, n);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
/* osHostname(), osHomedir()
|
|
101
|
+
/* osHostname(), osHomedir(): a string, or -errno. */
|
|
102
102
|
PRIMITIVE(js_host_os_hostname) {
|
|
103
103
|
UNUSED_PRIMITIVE_ARGS;
|
|
104
104
|
return path_result(ctx, uv_os_gethostname);
|
|
@@ -109,11 +109,6 @@ PRIMITIVE(js_host_os_homedir) {
|
|
|
109
109
|
return path_result(ctx, uv_os_homedir);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
PRIMITIVE(js_host_os_tmpdir) {
|
|
113
|
-
UNUSED_PRIMITIVE_ARGS;
|
|
114
|
-
return path_result(ctx, uv_os_tmpdir);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
112
|
/* osMemory(): [total, free] in bytes. */
|
|
118
113
|
PRIMITIVE(js_host_os_memory) {
|
|
119
114
|
UNUSED_PRIMITIVE_ARGS;
|
package/node/src/host_sys.c
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
#include "jscontext.h"
|
|
20
20
|
#include "js_ops.h"
|
|
21
21
|
#include "jsstring.h"
|
|
22
|
+
#include "js_uv.h"
|
|
22
23
|
|
|
23
24
|
/* Each error by its C errno and its libuv code: the same number on POSIX, but on Windows libuv
|
|
24
25
|
* has codes of its own (UV_ECONNREFUSED is -4078) while the C library's errno has the C values. */
|
|
@@ -74,6 +75,58 @@ static const struct { int code, uv; const char *name, *message; } ERRORS[] = {
|
|
|
74
75
|
E(ENXIO, "no such device or address"),
|
|
75
76
|
E(EMLINK, "too many links"),
|
|
76
77
|
E(ENOTTY, "inappropriate ioctl for device"),
|
|
78
|
+
/* the rest of libuv's: some C libraries (Windows') lack a few */
|
|
79
|
+
#ifdef EALREADY
|
|
80
|
+
E(EALREADY, "connection already in progress"),
|
|
81
|
+
#endif
|
|
82
|
+
#ifdef EDESTADDRREQ
|
|
83
|
+
E(EDESTADDRREQ, "destination address required"),
|
|
84
|
+
#endif
|
|
85
|
+
#ifdef EISCONN
|
|
86
|
+
E(EISCONN, "socket is already connected"),
|
|
87
|
+
#endif
|
|
88
|
+
#ifdef ENETDOWN
|
|
89
|
+
E(ENETDOWN, "network is down"),
|
|
90
|
+
#endif
|
|
91
|
+
#ifdef ENODEV
|
|
92
|
+
E(ENODEV, "no such device"),
|
|
93
|
+
#endif
|
|
94
|
+
#ifdef ENONET
|
|
95
|
+
E(ENONET, "machine is not on the network"),
|
|
96
|
+
#endif
|
|
97
|
+
#ifdef ENOPROTOOPT
|
|
98
|
+
E(ENOPROTOOPT, "protocol not available"),
|
|
99
|
+
#endif
|
|
100
|
+
#ifdef EPROTONOSUPPORT
|
|
101
|
+
E(EPROTONOSUPPORT, "protocol not supported"),
|
|
102
|
+
#endif
|
|
103
|
+
#ifdef EPROTOTYPE
|
|
104
|
+
E(EPROTOTYPE, "protocol wrong type for socket"),
|
|
105
|
+
#endif
|
|
106
|
+
#ifdef ESHUTDOWN
|
|
107
|
+
E(ESHUTDOWN, "cannot send after transport endpoint shutdown"),
|
|
108
|
+
#endif
|
|
109
|
+
#ifdef EHOSTDOWN
|
|
110
|
+
E(EHOSTDOWN, "host is down"),
|
|
111
|
+
#endif
|
|
112
|
+
#ifdef EREMOTEIO
|
|
113
|
+
E(EREMOTEIO, "remote I/O error"),
|
|
114
|
+
#endif
|
|
115
|
+
#ifdef EILSEQ
|
|
116
|
+
E(EILSEQ, "illegal byte sequence"),
|
|
117
|
+
#endif
|
|
118
|
+
#ifdef ESOCKTNOSUPPORT
|
|
119
|
+
E(ESOCKTNOSUPPORT, "socket type not supported"),
|
|
120
|
+
#endif
|
|
121
|
+
#ifdef ENODATA
|
|
122
|
+
E(ENODATA, "no data available"),
|
|
123
|
+
#endif
|
|
124
|
+
#ifdef EUNATCH
|
|
125
|
+
E(EUNATCH, "protocol driver not attached"),
|
|
126
|
+
#endif
|
|
127
|
+
#ifdef ENOEXEC
|
|
128
|
+
E(ENOEXEC, "exec format error"),
|
|
129
|
+
#endif
|
|
77
130
|
};
|
|
78
131
|
#undef E
|
|
79
132
|
|
|
@@ -155,6 +208,14 @@ JSValue js_host_timer_unref(JSContext *ctx, JSValue callee, JSValue this_val, ui
|
|
|
155
208
|
return js_int32((int32_t)js_add_timer(ctx, argv[0], js_as_number(argv[1]), true));
|
|
156
209
|
}
|
|
157
210
|
|
|
211
|
+
/* loopNow() → libuv's time in ms, as of the last poll (Node's getLibuvNow): what a socket's
|
|
212
|
+
* activity is measured with, without a clock read or an allocation per read and write */
|
|
213
|
+
JSValue js_host_loop_now(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv,
|
|
214
|
+
JSValue new_target) {
|
|
215
|
+
(void)callee, (void)this_val, (void)argc, (void)argv, (void)new_target;
|
|
216
|
+
return js_number((double)uv_now(js_uv_loop(ctx)));
|
|
217
|
+
}
|
|
218
|
+
|
|
158
219
|
/* the id a timer primitive takes: a positive int32, else 0 */
|
|
159
220
|
static uint32_t timer_id(uint32_t argc, const JSValue *argv, uint32_t i) {
|
|
160
221
|
return i < argc && js_is_int32(argv[i]) && js_as_int32(argv[i]) > 0 ? (uint32_t)js_as_int32(argv[i]) : 0;
|
|
@@ -216,3 +277,21 @@ JSValue js_host_process_memory(JSContext *ctx, JSValue callee, JSValue this_val,
|
|
|
216
277
|
js_number((double)(h->live_after_gc + h->allocated_since_gc)) };
|
|
217
278
|
return js_new_array_from(ctx, items, 3);
|
|
218
279
|
}
|
|
280
|
+
|
|
281
|
+
/* previewEntries(value, isIterator): Node's util binding: a Map's, Set's or iterator's entries,
|
|
282
|
+
* the iterator not advanced ([k1, v1, …] for a Map or an entries iterator, else the values);
|
|
283
|
+
* with isIterator, [entries, isKeyValue]. Undefined for any other value, or when the program
|
|
284
|
+
* has no collections. */
|
|
285
|
+
JSValue js_host_preview_entries(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv,
|
|
286
|
+
JSValue new_target) {
|
|
287
|
+
(void)callee, (void)this_val, (void)new_target;
|
|
288
|
+
if (argc < 1 || !ctx->rt->collection_preview) return JS_UNDEFINED;
|
|
289
|
+
JSCollectionPreview what = JS_PREVIEW_MAP;
|
|
290
|
+
JSValue entries = ctx->rt->collection_preview(ctx, argv[0], &what);
|
|
291
|
+
if (js_is_exception(entries)) return entries;
|
|
292
|
+
if (js_is_empty(entries)) return JS_UNDEFINED;
|
|
293
|
+
if (argc < 2 || !js_truthy(argv[1])) return entries;
|
|
294
|
+
bool pairs = what == JS_PREVIEW_MAP || what == JS_PREVIEW_MAP_ENTRIES || what == JS_PREVIEW_SET_ENTRIES;
|
|
295
|
+
JSValue items[2] = { entries, js_bool(pairs) };
|
|
296
|
+
return js_new_array_from(ctx, items, 2);
|
|
297
|
+
}
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/* Host primitives for node:dgram: UDP handles on libuv, the calls Node's UDPWrap makes. The
|
|
2
|
+
* prelude's internal/udp.js is Node's UDP binding over them, and dgram.js Node's own. Handles are
|
|
3
|
+
* numbered; each has one JS callback (a root), called as cb(event, …) from the loop:
|
|
4
|
+
*
|
|
5
|
+
* UDP_MESSAGE cb(0, bytes, address, family, port): a datagram (a Uint8Array); or cb(0, -errno)
|
|
6
|
+
* UDP_SENT cb(1, status, bytes): the oldest pending send finished (in order)
|
|
7
|
+
* UDP_CLOSE cb(2): the handle is closed and its id free
|
|
8
|
+
*
|
|
9
|
+
* udpOpen(cb) → id
|
|
10
|
+
* udpOpenFd(id, fd), udpFd(id) → fd | -errno
|
|
11
|
+
* udpBind(id, ip, port, flags), udpConnect(id, ip, port), udpDisconnect(id) → 0 | -errno
|
|
12
|
+
* flags: libuv's (UV_UDP_IPV6ONLY 1, UV_UDP_REUSEADDR 4, UV_UDP_REUSEPORT 64)
|
|
13
|
+
* udpSend(id, [bytes, …], ip | null, port) → length + 1 (sent now) | 0 (a UDP_SENT follows) | -errno
|
|
14
|
+
* udpRecvStart(id), udpRecvStop(id) → 0 | -errno
|
|
15
|
+
* udpAddress(id, peer) → [address, family, port] | -errno
|
|
16
|
+
* udpSetBroadcast(id, on), udpSetTTL(id, ttl), udpSetMulticastTTL(id, ttl), udpSetMulticastLoopback(id, on),
|
|
17
|
+
* udpSetMulticastInterface(id, ip), udpMembership(id, group, iface | null, join),
|
|
18
|
+
* udpSourceMembership(id, source, group, iface | null, join) → 0 | -errno
|
|
19
|
+
* udpBufferSize(id, size, recv) → size | -errno (size 0 reads it)
|
|
20
|
+
* udpSendQueue(id, count) → bytes | requests waiting to go out
|
|
21
|
+
* udpClose(id), udpRef(id, ref), udpHasRef(id) → bool */
|
|
22
|
+
#define _POSIX_C_SOURCE 200809L /* libuv's headers: pthread_rwlock_t, struct addrinfo */
|
|
23
|
+
#include <stdlib.h>
|
|
24
|
+
#include <string.h>
|
|
25
|
+
|
|
26
|
+
#include "js_buffer.h"
|
|
27
|
+
#include "js_convert.h"
|
|
28
|
+
#include "js_exception.h"
|
|
29
|
+
#include "js_gc.h"
|
|
30
|
+
#include "js_node.h"
|
|
31
|
+
#include "js_ops.h"
|
|
32
|
+
#include "js_uv.h"
|
|
33
|
+
#include "jscontext.h"
|
|
34
|
+
#include "jsstring.h"
|
|
35
|
+
|
|
36
|
+
enum { UDP_MESSAGE, UDP_SENT, UDP_CLOSE };
|
|
37
|
+
|
|
38
|
+
typedef struct UdpHandle {
|
|
39
|
+
uv_udp_t udp;
|
|
40
|
+
int id;
|
|
41
|
+
bool closing;
|
|
42
|
+
JSValue cb; /* a root */
|
|
43
|
+
} UdpHandle;
|
|
44
|
+
|
|
45
|
+
static UdpHandle **handles;
|
|
46
|
+
static size_t nhandles;
|
|
47
|
+
|
|
48
|
+
static void emit(UdpHandle *h, uint32_t argc, JSValue *args) {
|
|
49
|
+
if (js_is_callable(h->cb)) (void)js_uv_call(h->cb, argc, args, NULL);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static UdpHandle *open_handle(int32_t id) {
|
|
53
|
+
UdpHandle *h = id >= 0 && (size_t)id < nhandles ? handles[id] : NULL;
|
|
54
|
+
return h && !h->closing ? h : NULL;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static UdpHandle *handle_arg(uint32_t argc, const JSValue *argv) {
|
|
58
|
+
return argc > 0 && js_is_int32(argv[0]) ? open_handle(js_as_int32(argv[0])) : NULL;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static size_t string_arg(JSContext *ctx, JSValue v, char *buf, size_t size) {
|
|
62
|
+
size_t n = js_is_string(v) ? js_view_to_utf8(js_string_view(ctx, v), buf, size - 1) : 0;
|
|
63
|
+
buf[n] = '\0';
|
|
64
|
+
return n;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static int sockaddr_arg(JSContext *ctx, JSValue ip, JSValue port, struct sockaddr_storage *addr) {
|
|
68
|
+
char host[64];
|
|
69
|
+
string_arg(ctx, ip, host, sizeof host);
|
|
70
|
+
int p = js_is_int32(port) ? js_as_int32(port) : 0;
|
|
71
|
+
return strchr(host, ':') ? uv_ip6_addr(host, p, (struct sockaddr_in6 *)addr) : uv_ip4_addr(host, p, (struct sockaddr_in *)addr);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static int32_t int_arg(uint32_t argc, const JSValue *argv, uint32_t i) {
|
|
75
|
+
return argc > i && js_is_number(argv[i]) ? (int32_t)js_as_number(argv[i]) : 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* [address, family, port] of a socket address */
|
|
79
|
+
static JSValue address_value(JSContext *ctx, const struct sockaddr *sa) {
|
|
80
|
+
char ip[64] = "";
|
|
81
|
+
int port = 0;
|
|
82
|
+
const char *family = "IPv4";
|
|
83
|
+
if (sa->sa_family == AF_INET6) {
|
|
84
|
+
const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)sa;
|
|
85
|
+
uv_ip6_name(a, ip, sizeof ip);
|
|
86
|
+
port = ntohs(a->sin6_port);
|
|
87
|
+
family = "IPv6";
|
|
88
|
+
} else {
|
|
89
|
+
const struct sockaddr_in *a = (const struct sockaddr_in *)sa;
|
|
90
|
+
uv_ip4_name(a, ip, sizeof ip);
|
|
91
|
+
port = ntohs(a->sin_port);
|
|
92
|
+
}
|
|
93
|
+
JSValue out = js_new_array(ctx, 3);
|
|
94
|
+
if (js_array_append(ctx, out, js_new_string_cstr(ctx, ip)) < 0 || js_array_append(ctx, out, js_new_string_cstr(ctx, family)) < 0 ||
|
|
95
|
+
js_array_append(ctx, out, js_int32(port)) < 0)
|
|
96
|
+
js_fatal("out of memory in dgram");
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#define HOST_FN(name) JSValue name(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target)
|
|
101
|
+
#define UNUSED (void)ctx, (void)callee, (void)this_val, (void)new_target
|
|
102
|
+
|
|
103
|
+
/* ---- Handles ----------------------------------------------------------------------------------- */
|
|
104
|
+
|
|
105
|
+
HOST_FN(js_host_udp_open) {
|
|
106
|
+
UNUSED;
|
|
107
|
+
UdpHandle *h = calloc(1, sizeof *h);
|
|
108
|
+
if (!h) js_fatal("out of memory in dgram");
|
|
109
|
+
uv_udp_init(js_uv_loop(ctx), &h->udp);
|
|
110
|
+
size_t id = 0;
|
|
111
|
+
while (id < nhandles && handles[id]) id++;
|
|
112
|
+
if (id == nhandles) {
|
|
113
|
+
size_t n = nhandles ? nhandles * 2 : 8;
|
|
114
|
+
UdpHandle **v = realloc(handles, n * sizeof *v);
|
|
115
|
+
if (!v) js_fatal("out of memory in dgram");
|
|
116
|
+
memset(v + nhandles, 0, (n - nhandles) * sizeof *v);
|
|
117
|
+
handles = v;
|
|
118
|
+
nhandles = n;
|
|
119
|
+
}
|
|
120
|
+
handles[id] = h;
|
|
121
|
+
h->id = (int)id;
|
|
122
|
+
h->cb = argc > 0 ? argv[0] : JS_UNDEFINED;
|
|
123
|
+
js_add_root(ctx->rt, &h->cb);
|
|
124
|
+
return js_int32(h->id);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static void on_closed(uv_handle_t *uh) {
|
|
128
|
+
UdpHandle *h = (UdpHandle *)uh;
|
|
129
|
+
handles[h->id] = NULL;
|
|
130
|
+
JSValue args[1] = { js_int32(UDP_CLOSE) };
|
|
131
|
+
emit(h, 1, args);
|
|
132
|
+
js_remove_root(js_uv_context()->rt, &h->cb);
|
|
133
|
+
free(h);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
HOST_FN(js_host_udp_close) {
|
|
137
|
+
UNUSED;
|
|
138
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
139
|
+
if (h) {
|
|
140
|
+
h->closing = true;
|
|
141
|
+
uv_close((uv_handle_t *)&h->udp, on_closed);
|
|
142
|
+
}
|
|
143
|
+
return JS_UNDEFINED;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
HOST_FN(js_host_udp_open_fd) {
|
|
147
|
+
UNUSED;
|
|
148
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
149
|
+
if (!h || argc < 2 || !js_is_int32(argv[1])) return js_int32(UV_EBADF);
|
|
150
|
+
return js_int32(uv_udp_open(&h->udp, (uv_os_sock_t)js_as_int32(argv[1])));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
HOST_FN(js_host_udp_fd) {
|
|
154
|
+
UNUSED;
|
|
155
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
156
|
+
if (!h) return js_int32(UV_EBADF);
|
|
157
|
+
#ifdef _WIN32
|
|
158
|
+
return js_int32(-1);
|
|
159
|
+
#else
|
|
160
|
+
uv_os_fd_t fd;
|
|
161
|
+
int r = uv_fileno((uv_handle_t *)&h->udp, &fd);
|
|
162
|
+
return js_int32(r < 0 ? r : fd);
|
|
163
|
+
#endif
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
HOST_FN(js_host_udp_ref) {
|
|
167
|
+
UNUSED;
|
|
168
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
169
|
+
if (h && argc > 1) {
|
|
170
|
+
if (js_truthy(argv[1])) uv_ref((uv_handle_t *)&h->udp);
|
|
171
|
+
else uv_unref((uv_handle_t *)&h->udp);
|
|
172
|
+
}
|
|
173
|
+
return JS_UNDEFINED;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
HOST_FN(js_host_udp_has_ref) {
|
|
177
|
+
UNUSED;
|
|
178
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
179
|
+
return js_bool(h && uv_has_ref((uv_handle_t *)&h->udp));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* ---- Binding and connecting -------------------------------------------------------------------- */
|
|
183
|
+
|
|
184
|
+
HOST_FN(js_host_udp_bind) {
|
|
185
|
+
UNUSED;
|
|
186
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
187
|
+
if (!h || argc < 2) return js_int32(UV_EBADF);
|
|
188
|
+
struct sockaddr_storage addr;
|
|
189
|
+
int r = sockaddr_arg(ctx, argv[1], argc > 2 ? argv[2] : JS_UNDEFINED, &addr);
|
|
190
|
+
if (r < 0) return js_int32(r);
|
|
191
|
+
return js_int32(uv_udp_bind(&h->udp, (const struct sockaddr *)&addr, (unsigned)int_arg(argc, argv, 3)));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
HOST_FN(js_host_udp_connect) {
|
|
195
|
+
UNUSED;
|
|
196
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
197
|
+
if (!h || argc < 2) return js_int32(UV_EBADF);
|
|
198
|
+
struct sockaddr_storage addr;
|
|
199
|
+
int r = sockaddr_arg(ctx, argv[1], argc > 2 ? argv[2] : JS_UNDEFINED, &addr);
|
|
200
|
+
if (r < 0) return js_int32(r);
|
|
201
|
+
return js_int32(uv_udp_connect(&h->udp, (const struct sockaddr *)&addr));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
HOST_FN(js_host_udp_disconnect) {
|
|
205
|
+
UNUSED;
|
|
206
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
207
|
+
return js_int32(h ? uv_udp_connect(&h->udp, NULL) : UV_EBADF);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
HOST_FN(js_host_udp_address) {
|
|
211
|
+
UNUSED;
|
|
212
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
213
|
+
if (!h) return js_int32(UV_EBADF);
|
|
214
|
+
struct sockaddr_storage addr;
|
|
215
|
+
int len = sizeof addr;
|
|
216
|
+
int r = argc > 1 && js_truthy(argv[1]) ? uv_udp_getpeername(&h->udp, (struct sockaddr *)&addr, &len)
|
|
217
|
+
: uv_udp_getsockname(&h->udp, (struct sockaddr *)&addr, &len);
|
|
218
|
+
return r < 0 ? js_int32(r) : address_value(ctx, (const struct sockaddr *)&addr);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* ---- Sending ----------------------------------------------------------------------------------- */
|
|
222
|
+
|
|
223
|
+
typedef struct SendReq {
|
|
224
|
+
uv_udp_send_t req;
|
|
225
|
+
size_t length;
|
|
226
|
+
char data[];
|
|
227
|
+
} SendReq;
|
|
228
|
+
|
|
229
|
+
static void on_sent(uv_udp_send_t *req, int status) {
|
|
230
|
+
UdpHandle *h = (UdpHandle *)req->handle;
|
|
231
|
+
SendReq *s = (SendReq *)req;
|
|
232
|
+
JSValue args[3] = { js_int32(UDP_SENT), js_int32(status), js_number((double)s->length) };
|
|
233
|
+
free(s);
|
|
234
|
+
emit(h, 3, args);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* udpSend(id, chunks, ip | null, port): as Node's UDPWrap::DoSend, tried at once (length + 1 when it
|
|
238
|
+
* all went), else queued with a copy of the bytes */
|
|
239
|
+
HOST_FN(js_host_udp_send) {
|
|
240
|
+
UNUSED;
|
|
241
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
242
|
+
if (!h || argc < 2 || !js_is_object(argv[1])) return js_int32(UV_EBADF);
|
|
243
|
+
struct sockaddr_storage addr;
|
|
244
|
+
const struct sockaddr *to = NULL;
|
|
245
|
+
if (argc > 2 && js_is_string(argv[2])) {
|
|
246
|
+
int r = sockaddr_arg(ctx, argv[2], argc > 3 ? argv[3] : JS_UNDEFINED, &addr);
|
|
247
|
+
if (r < 0) return js_int32(r);
|
|
248
|
+
to = (const struct sockaddr *)&addr;
|
|
249
|
+
}
|
|
250
|
+
uint32_t count = js_array_length(js_as_object(argv[1]));
|
|
251
|
+
uv_buf_t small[8];
|
|
252
|
+
uv_buf_t *bufs = count <= 8 ? small : malloc(count * sizeof *bufs);
|
|
253
|
+
if (!bufs) js_fatal("out of memory in dgram");
|
|
254
|
+
size_t total = 0;
|
|
255
|
+
for (uint32_t i = 0; i < count; i++) {
|
|
256
|
+
JSValue chunk = js_get_index(ctx, argv[1], js_int32((int32_t)i));
|
|
257
|
+
uint8_t *p;
|
|
258
|
+
size_t n;
|
|
259
|
+
if (!js_buffer_source_bytes(chunk, &p, &n)) {
|
|
260
|
+
if (bufs != small) free(bufs);
|
|
261
|
+
return js_throw_type_error(ctx, "udpSend: bytes expected");
|
|
262
|
+
}
|
|
263
|
+
bufs[i] = uv_buf_init((char *)p, (unsigned)n);
|
|
264
|
+
total += n;
|
|
265
|
+
}
|
|
266
|
+
int r = uv_udp_try_send(&h->udp, bufs, count, to);
|
|
267
|
+
if (r >= 0 && (size_t)r == total) {
|
|
268
|
+
if (bufs != small) free(bufs);
|
|
269
|
+
return js_number((double)total + 1);
|
|
270
|
+
}
|
|
271
|
+
if (r < 0 && r != UV_EAGAIN && r != UV_ENOSYS) {
|
|
272
|
+
if (bufs != small) free(bufs);
|
|
273
|
+
return js_int32(r);
|
|
274
|
+
}
|
|
275
|
+
/* a datagram goes whole or not at all: a partial r doesn't happen, queue all of it */
|
|
276
|
+
SendReq *s = malloc(sizeof *s + (total ? total : 1));
|
|
277
|
+
if (!s) js_fatal("out of memory in dgram");
|
|
278
|
+
s->length = total;
|
|
279
|
+
size_t off = 0;
|
|
280
|
+
for (uint32_t i = 0; i < count; i++) {
|
|
281
|
+
memcpy(s->data + off, bufs[i].base, bufs[i].len);
|
|
282
|
+
off += bufs[i].len;
|
|
283
|
+
}
|
|
284
|
+
if (bufs != small) free(bufs);
|
|
285
|
+
uv_buf_t one = uv_buf_init(s->data, (unsigned)total);
|
|
286
|
+
r = uv_udp_send(&s->req, &h->udp, &one, 1, to, on_sent);
|
|
287
|
+
if (r < 0) {
|
|
288
|
+
free(s);
|
|
289
|
+
return js_int32(r);
|
|
290
|
+
}
|
|
291
|
+
return js_int32(0);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
HOST_FN(js_host_udp_send_queue) {
|
|
295
|
+
UNUSED;
|
|
296
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
297
|
+
if (!h) return js_int32(0);
|
|
298
|
+
return js_number((double)(argc > 1 && js_truthy(argv[1]) ? uv_udp_get_send_queue_count(&h->udp) : uv_udp_get_send_queue_size(&h->udp)));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* ---- Receiving --------------------------------------------------------------------------------- */
|
|
302
|
+
|
|
303
|
+
static void on_alloc(uv_handle_t *uh, size_t suggested, uv_buf_t *buf) {
|
|
304
|
+
(void)uh;
|
|
305
|
+
buf->base = malloc(suggested);
|
|
306
|
+
buf->len = buf->base ? suggested : 0;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
static void on_recv(uv_udp_t *u, ssize_t n, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
|
|
310
|
+
(void)flags;
|
|
311
|
+
UdpHandle *h = (UdpHandle *)u;
|
|
312
|
+
if (n == 0 && addr == NULL) { /* nothing more to read for now */
|
|
313
|
+
free(buf->base);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
JSContext *ctx = js_uv_context();
|
|
317
|
+
if (n < 0) {
|
|
318
|
+
free(buf->base);
|
|
319
|
+
JSValue args[2] = { js_int32(UDP_MESSAGE), js_int32((int32_t)n) };
|
|
320
|
+
emit(h, 2, args);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
JSValue chunk = js_new_uint8_array(ctx, (size_t)n);
|
|
324
|
+
if (js_is_exception(chunk)) js_fatal("out of memory in dgram");
|
|
325
|
+
uint8_t *data;
|
|
326
|
+
size_t len;
|
|
327
|
+
js_buffer_source_bytes(chunk, &data, &len);
|
|
328
|
+
memcpy(data, buf->base, (size_t)n);
|
|
329
|
+
free(buf->base);
|
|
330
|
+
JSValue args[3] = { js_int32(UDP_MESSAGE), chunk, address_value(ctx, addr) };
|
|
331
|
+
emit(h, 3, args);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
HOST_FN(js_host_udp_recv_start) {
|
|
335
|
+
UNUSED;
|
|
336
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
337
|
+
if (!h) return js_int32(UV_EBADF);
|
|
338
|
+
int r = uv_udp_recv_start(&h->udp, on_alloc, on_recv);
|
|
339
|
+
return js_int32(r == UV_EALREADY ? 0 : r); /* as Node's: starting twice is fine */
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
HOST_FN(js_host_udp_recv_stop) {
|
|
343
|
+
UNUSED;
|
|
344
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
345
|
+
return js_int32(h ? uv_udp_recv_stop(&h->udp) : UV_EBADF);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* ---- Options ----------------------------------------------------------------------------------- */
|
|
349
|
+
|
|
350
|
+
HOST_FN(js_host_udp_set_broadcast) {
|
|
351
|
+
UNUSED;
|
|
352
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
353
|
+
return js_int32(h ? uv_udp_set_broadcast(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
HOST_FN(js_host_udp_set_ttl) {
|
|
357
|
+
UNUSED;
|
|
358
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
359
|
+
return js_int32(h ? uv_udp_set_ttl(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
HOST_FN(js_host_udp_set_multicast_ttl) {
|
|
363
|
+
UNUSED;
|
|
364
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
365
|
+
return js_int32(h ? uv_udp_set_multicast_ttl(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
HOST_FN(js_host_udp_set_multicast_loopback) {
|
|
369
|
+
UNUSED;
|
|
370
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
371
|
+
return js_int32(h ? uv_udp_set_multicast_loop(&h->udp, int_arg(argc, argv, 1)) : UV_EBADF);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
HOST_FN(js_host_udp_set_multicast_interface) {
|
|
375
|
+
UNUSED;
|
|
376
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
377
|
+
if (!h) return js_int32(UV_EBADF);
|
|
378
|
+
char iface[64];
|
|
379
|
+
string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, iface, sizeof iface);
|
|
380
|
+
return js_int32(uv_udp_set_multicast_interface(&h->udp, iface));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
HOST_FN(js_host_udp_membership) {
|
|
384
|
+
UNUSED;
|
|
385
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
386
|
+
if (!h) return js_int32(UV_EBADF);
|
|
387
|
+
char group[64], iface[64];
|
|
388
|
+
string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, group, sizeof group);
|
|
389
|
+
bool has_iface = argc > 2 && js_is_string(argv[2]);
|
|
390
|
+
if (has_iface) string_arg(ctx, argv[2], iface, sizeof iface);
|
|
391
|
+
return js_int32(uv_udp_set_membership(&h->udp, group, has_iface ? iface : NULL,
|
|
392
|
+
argc > 3 && js_truthy(argv[3]) ? UV_JOIN_GROUP : UV_LEAVE_GROUP));
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
HOST_FN(js_host_udp_source_membership) {
|
|
396
|
+
UNUSED;
|
|
397
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
398
|
+
if (!h) return js_int32(UV_EBADF);
|
|
399
|
+
char source[64], group[64], iface[64];
|
|
400
|
+
string_arg(ctx, argc > 1 ? argv[1] : JS_UNDEFINED, source, sizeof source);
|
|
401
|
+
string_arg(ctx, argc > 2 ? argv[2] : JS_UNDEFINED, group, sizeof group);
|
|
402
|
+
bool has_iface = argc > 3 && js_is_string(argv[3]);
|
|
403
|
+
if (has_iface) string_arg(ctx, argv[3], iface, sizeof iface);
|
|
404
|
+
return js_int32(uv_udp_set_source_membership(&h->udp, group, has_iface ? iface : NULL, source,
|
|
405
|
+
argc > 4 && js_truthy(argv[4]) ? UV_JOIN_GROUP : UV_LEAVE_GROUP));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* udpBufferSize(id, size, recv): the kernel's buffer size, set when size isn't 0 (Linux reports it
|
|
409
|
+
* doubled, as Node shows it) */
|
|
410
|
+
HOST_FN(js_host_udp_buffer_size) {
|
|
411
|
+
UNUSED;
|
|
412
|
+
UdpHandle *h = handle_arg(argc, argv);
|
|
413
|
+
if (!h) return js_int32(UV_EBADF);
|
|
414
|
+
int size = int_arg(argc, argv, 1);
|
|
415
|
+
int r = argc > 2 && js_truthy(argv[2]) ? uv_recv_buffer_size((uv_handle_t *)&h->udp, &size)
|
|
416
|
+
: uv_send_buffer_size((uv_handle_t *)&h->udp, &size);
|
|
417
|
+
return js_int32(r < 0 ? r : size);
|
|
418
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 1998 Massachusetts Institute of Technology
|
|
4
|
+
Copyright (c) 2007 - 2023 Daniel Stenberg with many contributors, see AUTHORS
|
|
5
|
+
file.
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
8
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
9
|
+
the Software without restriction, including without limitation the rights to
|
|
10
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
11
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
12
|
+
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.
|