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.
Files changed (221) hide show
  1. package/README.md +12 -4
  2. package/THIRD_PARTY_LICENSES +31 -1
  3. package/cli.js +962 -68
  4. package/node/include/js_node.h +11 -1
  5. package/node/prelude/_http_common.js +29 -0
  6. package/node/prelude/async_hooks.js +50 -11
  7. package/node/prelude/child_process.js +31 -4
  8. package/node/prelude/console.js +311 -143
  9. package/node/prelude/crypto.js +6 -4
  10. package/node/prelude/dgram.js +1169 -0
  11. package/node/prelude/diagnostics_channel.js +3 -1
  12. package/node/prelude/dns.js +250 -45
  13. package/node/prelude/dns_promises.js +8 -2
  14. package/node/prelude/fs_promises.js +9 -1
  15. package/node/prelude/http.js +395 -86
  16. package/node/prelude/https.js +13 -4
  17. package/node/prelude/internal/console_class.js +7 -0
  18. package/node/prelude/internal/console_global.js +25 -0
  19. package/node/prelude/internal/crypto/key_encryption.js +217 -0
  20. package/node/prelude/internal/crypto/keys.js +161 -26
  21. package/node/prelude/internal/crypto/random.js +24 -0
  22. package/node/prelude/internal/crypto/util.js +2 -1
  23. package/node/prelude/internal/crypto_x509.js +161 -0
  24. package/node/prelude/internal/dns_classes.js +6 -0
  25. package/node/prelude/internal/dns_resolver.js +371 -0
  26. package/node/prelude/internal/errors.js +9 -0
  27. package/node/prelude/internal/events_on.js +82 -37
  28. package/node/prelude/internal/features.js +8 -4
  29. package/node/prelude/internal/fs_filehandle.js +10 -4
  30. package/node/prelude/internal/perf_histogram.js +1 -1
  31. package/node/prelude/internal/process_more.js +32 -17
  32. package/node/prelude/internal/process_signals.js +8 -2
  33. package/node/prelude/internal/punycode.ts +163 -0
  34. package/node/prelude/internal/readline.js +648 -274
  35. package/node/prelude/internal/readline_editor.js +1240 -0
  36. package/node/prelude/internal/string_width.js +43 -0
  37. package/node/prelude/internal/tls/common.js +145 -33
  38. package/node/prelude/internal/tls/wrap.js +182 -49
  39. package/node/prelude/internal/tls/x509.js +4 -1
  40. package/node/prelude/internal/udp.js +177 -0
  41. package/node/prelude/net.js +13 -1
  42. package/node/prelude/os.js +24 -6
  43. package/node/prelude/perf_hooks.js +37 -2
  44. package/node/prelude/punycode.js +2 -130
  45. package/node/prelude/readline.js +113 -4
  46. package/node/prelude/readline_promises.js +56 -32
  47. package/node/prelude/tls.js +21 -4
  48. package/node/prelude/util.js +3 -16
  49. package/node/src/host_dns.c +623 -0
  50. package/node/src/host_http.c +12 -0
  51. package/node/src/host_net.c +46 -0
  52. package/node/src/host_os.c +1 -6
  53. package/node/src/host_sys.c +70 -0
  54. package/node/src/host_udp.c +418 -0
  55. package/node/third_party/c-ares/LICENSE.md +24 -0
  56. package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
  57. package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
  58. package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
  59. package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
  60. package/node/third_party/c-ares/include/ares.h +1237 -0
  61. package/node/third_party/c-ares/include/ares_build.h +202 -0
  62. package/node/third_party/c-ares/include/ares_dns.h +127 -0
  63. package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
  64. package/node/third_party/c-ares/include/ares_nameser.h +510 -0
  65. package/node/third_party/c-ares/include/ares_version.h +47 -0
  66. package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
  67. package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
  68. package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
  69. package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
  70. package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
  71. package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
  72. package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
  73. package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
  74. package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
  75. package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
  76. package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
  77. package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
  78. package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
  79. package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
  80. package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
  81. package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
  82. package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
  83. package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
  84. package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
  85. package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
  86. package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
  87. package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
  88. package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
  89. package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
  90. package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
  91. package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
  92. package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
  93. package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
  94. package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
  95. package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
  96. package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
  97. package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
  98. package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
  99. package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
  100. package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
  101. package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
  102. package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
  103. package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
  104. package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
  105. package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
  106. package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
  107. package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
  108. package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
  109. package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
  110. package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
  111. package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
  112. package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
  113. package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
  114. package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
  115. package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
  116. package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
  117. package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
  118. package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
  119. package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
  120. package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
  121. package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
  122. package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
  123. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  124. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  125. package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
  126. package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
  127. package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
  128. package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
  129. package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
  130. package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
  131. package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
  132. package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
  133. package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
  134. package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
  135. package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
  136. package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
  137. package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
  138. package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
  139. package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
  140. package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
  141. package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
  142. package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
  143. package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
  144. package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
  145. package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
  146. package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
  147. package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
  148. package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
  149. package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
  150. package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
  151. package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
  152. package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
  153. package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
  154. package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
  155. package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
  156. package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  157. package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  158. package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  159. package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  160. package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  161. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  162. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  163. package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  164. package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  165. package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  166. package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  167. package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
  168. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
  169. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
  170. package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
  171. package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
  172. package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
  173. package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
  174. package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
  175. package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
  176. package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
  177. package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
  178. package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
  179. package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  180. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
  181. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
  182. package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
  183. package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
  184. package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
  185. package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
  186. package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
  187. package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
  188. package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
  189. package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
  190. package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
  191. package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
  192. package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
  193. package/package.json +1 -1
  194. package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
  195. package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
  196. package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
  197. package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
  198. package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
  199. package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
  200. package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
  201. package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
  202. package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
  203. package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
  204. package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
  205. package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
  206. package/runtime/include/js_builtins.h +5 -0
  207. package/runtime/include/js_crypto.h +11 -0
  208. package/runtime/include/js_gc.h +13 -10
  209. package/runtime/include/js_jobs.h +2 -0
  210. package/runtime/include/js_object.h +58 -0
  211. package/runtime/include/jscontext.h +1 -0
  212. package/runtime/src/crypto_internal.h +1 -0
  213. package/runtime/src/crypto_subtle.c +66 -7
  214. package/runtime/src/crypto_tls.c +265 -19
  215. package/runtime/src/gc.c +73 -92
  216. package/runtime/src/inspect.c +18 -1
  217. package/runtime/src/jobs.c +37 -22
  218. package/runtime/src/object.c +49 -2
  219. package/runtime/src/os.c +16 -6
  220. package/runtime/src/os.h +2 -0
  221. package/runtime/src/process.c +97 -10
@@ -0,0 +1,1169 @@
1
+ // node:dgram, Node 24's lib/dgram.js and lib/internal/dgram.js over Node's UDP binding
2
+ // (internal/udp.js, on src/host_udp.c). A compiled program is never a cluster worker, so a bind is
3
+ // always its own; async_hooks' ids are the handle's own count.
4
+ // Ported from Node.js (Copyright Node.js contributors, MIT): node/third_party/nodejs/LICENSE.
5
+
6
+ // Copyright Joyent, Inc. and other Node contributors.
7
+ //
8
+ // Permission is hereby granted, free of charge, to any person obtaining a
9
+ // copy of this software and associated documentation files (the
10
+ // "Software"), to deal in the Software without restriction, including
11
+ // without limitation the rights to use, copy, modify, merge, publish,
12
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
13
+ // persons to whom the Software is furnished to do so, subject to the
14
+ // following conditions:
15
+ //
16
+ // The above copyright notice and this permission notice shall be included
17
+ // in all copies or substantial portions of the Software.
18
+ //
19
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
22
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+
27
+ import { errnoName, netGuessHandle } from "visaljs:host";
28
+ import { Buffer } from "./buffer.js";
29
+ import { channel } from "./diagnostics_channel.js";
30
+ import dns from "./dns.js";
31
+ import { EventEmitter } from "./events.js";
32
+ import { codeError, errnoException } from "./internal/errors.js";
33
+ import { isIP } from "./internal/net.js";
34
+ import { BlockList } from "./internal/socketaddress.js";
35
+ import { codes, determineSpecificType, fsSystemError } from "./internal/streams/errors.js";
36
+ import {
37
+ addAbortListener, kEmptyObject, validateAbortSignal, validateFunction, validateObject, validateString, validateUint32,
38
+ } from "./internal/streams/validators.js";
39
+ import { SendWrap, UDP } from "./internal/udp.js";
40
+ import { deprecate } from "./util.js";
41
+
42
+ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_MISSING_ARGS } = codes;
43
+
44
+ /* ---- the errors dgram throws, as Node's lib/internal/errors.js makes them ---------------------- */
45
+
46
+ const ERR_BUFFER_OUT_OF_BOUNDS = (name) =>
47
+ codeError(RangeError, "ERR_BUFFER_OUT_OF_BOUNDS", name ? `"${name}" is outside of buffer bounds` : "Attempt to access memory outside buffer bounds");
48
+ const ERR_INVALID_FD_TYPE = (type) => codeError(TypeError, "ERR_INVALID_FD_TYPE", `Unsupported fd type: ${type}`);
49
+ const ERR_IP_BLOCKED = (ip) => codeError(Error, "ERR_IP_BLOCKED", `IP(${ip}) is blocked by net.BlockList`);
50
+ const ERR_SOCKET_ALREADY_BOUND = () => codeError(Error, "ERR_SOCKET_ALREADY_BOUND", "Socket is already bound");
51
+ const ERR_SOCKET_BAD_BUFFER_SIZE = () => codeError(TypeError, "ERR_SOCKET_BAD_BUFFER_SIZE", "Buffer size must be a positive integer");
52
+ const ERR_SOCKET_BAD_PORT = (name, port, allowZero) =>
53
+ codeError(RangeError, "ERR_SOCKET_BAD_PORT", `${name} should be ${allowZero ? ">=" : ">"} 0 and < 65536. Received ${determineSpecificType(port)}.`);
54
+ const ERR_SOCKET_BAD_TYPE = () => codeError(TypeError, "ERR_SOCKET_BAD_TYPE", "Bad socket type specified. Valid types are: udp4, udp6");
55
+ const ERR_SOCKET_BUFFER_SIZE = (ctx) => fsSystemError("ERR_SOCKET_BUFFER_SIZE", "Could not get or set buffer size", ctx);
56
+ const ERR_SOCKET_DGRAM_IS_CONNECTED = () => codeError(Error, "ERR_SOCKET_DGRAM_IS_CONNECTED", "Already connected");
57
+ const ERR_SOCKET_DGRAM_NOT_CONNECTED = () => codeError(Error, "ERR_SOCKET_DGRAM_NOT_CONNECTED", "Not connected");
58
+ const ERR_SOCKET_DGRAM_NOT_RUNNING = () => codeError(Error, "ERR_SOCKET_DGRAM_NOT_RUNNING", "Not running");
59
+
60
+ const ErrnoException = errnoException;
61
+
62
+ /* Node's ExceptionWithHostPort: `send EINVAL 127.0.0.1:41234` */
63
+ function ExceptionWithHostPort(err, syscall, address, port) {
64
+ const code = errnoName(err);
65
+ const details = port && port > 0 ? ` ${address}:${port}` : address ? ` ${address}` : "";
66
+ const ex = new Error(`${syscall} ${code}${details}`);
67
+ ex.errno = err;
68
+ ex.code = code;
69
+ ex.syscall = syscall;
70
+ ex.address = address;
71
+ if (port) ex.port = port;
72
+ return ex;
73
+ }
74
+
75
+ function isInt32(value) {
76
+ return value === (value | 0);
77
+ }
78
+
79
+ function validateNumber(value, name) {
80
+ if (typeof value !== "number") throw new ERR_INVALID_ARG_TYPE(name, "number", value);
81
+ }
82
+
83
+ function validatePort(port, name = "Port", allowZero = true) {
84
+ if ((typeof port !== "number" && typeof port !== "string") ||
85
+ (typeof port === "string" && port.trim().length === 0) ||
86
+ +port !== (+port >>> 0) ||
87
+ port > 0xFFFF ||
88
+ (port === 0 && !allowZero)) {
89
+ throw ERR_SOCKET_BAD_PORT(name, port, allowZero);
90
+ }
91
+ return port | 0;
92
+ }
93
+
94
+ function guessHandleType(fd) {
95
+ return netGuessHandle(fd);
96
+ }
97
+
98
+ /* ---- lib/internal/dgram.js ---------------------------------------------------------------------- */
99
+
100
+ const UV_EINVAL = -22;
101
+ /* libuv's uv_udp_flags */
102
+ const UV_UDP_IPV6ONLY = 1, UV_UDP_REUSEADDR = 4, UV_UDP_REUSEPORT = 64;
103
+
104
+ const kStateSymbol = Symbol("state symbol");
105
+ const owner_symbol = Symbol("owner_symbol");
106
+ const async_id_symbol = Symbol("async_id_symbol");
107
+
108
+ function lookup4(lookup, address, callback) {
109
+ return lookup(address || "127.0.0.1", 4, callback);
110
+ }
111
+
112
+ function lookup6(lookup, address, callback) {
113
+ return lookup(address || "::1", 6, callback);
114
+ }
115
+
116
+ function defaultLookup(address, family, callback) {
117
+ if (isIP(address) === family) {
118
+ process.nextTick(callback, null, address, family);
119
+ return;
120
+ }
121
+ return dns.lookup(address, family, callback); /* the module's, as a program may replace it */
122
+ }
123
+
124
+ function newHandle(type, lookup) {
125
+ if (lookup === undefined) {
126
+ lookup = defaultLookup;
127
+ } else {
128
+ validateFunction(lookup, "lookup");
129
+ }
130
+
131
+ if (type === "udp4") {
132
+ const handle = new UDP();
133
+
134
+ handle.lookup = lookup4.bind(handle, lookup);
135
+ return handle;
136
+ }
137
+
138
+ if (type === "udp6") {
139
+ const handle = new UDP();
140
+
141
+ handle.lookup = lookup6.bind(handle, lookup);
142
+ handle.bind = handle.bind6;
143
+ handle.connect = handle.connect6;
144
+ handle.send = handle.send6;
145
+ return handle;
146
+ }
147
+
148
+ throw ERR_SOCKET_BAD_TYPE();
149
+ }
150
+
151
+ function _createSocketHandle(address, port, addressType, fd, flags) {
152
+ const handle = newHandle(addressType);
153
+ let err;
154
+
155
+ if (isInt32(fd) && fd > 0) {
156
+ const type = guessHandleType(fd);
157
+ if (type !== "UDP") {
158
+ err = UV_EINVAL;
159
+ } else {
160
+ err = handle.open(fd);
161
+ }
162
+ } else if (port || address) {
163
+ err = handle.bind(address, port || 0, flags);
164
+ }
165
+
166
+ if (err) {
167
+ handle.close();
168
+ return err;
169
+ }
170
+
171
+ return handle;
172
+ }
173
+
174
+ /* ---- lib/dgram.js ------------------------------------------------------------------------------- */
175
+
176
+ const udpSocketChannel = channel("udp.socket");
177
+
178
+ const BIND_STATE_UNBOUND = 0;
179
+ const BIND_STATE_BINDING = 1;
180
+ const BIND_STATE_BOUND = 2;
181
+
182
+ const CONNECT_STATE_DISCONNECTED = 0;
183
+ const CONNECT_STATE_CONNECTING = 1;
184
+ const CONNECT_STATE_CONNECTED = 2;
185
+
186
+ const RECV_BUFFER = true;
187
+ const SEND_BUFFER = false;
188
+
189
+ export function Socket(type, listener) {
190
+ EventEmitter.call(this);
191
+ let lookup;
192
+ let recvBufferSize;
193
+ let sendBufferSize;
194
+ let receiveBlockList;
195
+ let sendBlockList;
196
+
197
+ let options;
198
+ if (type !== null && typeof type === "object") {
199
+ options = type;
200
+ type = options.type;
201
+ lookup = options.lookup;
202
+ if (options.recvBufferSize) {
203
+ validateUint32(options.recvBufferSize, "options.recvBufferSize");
204
+ }
205
+ if (options.sendBufferSize) {
206
+ validateUint32(options.sendBufferSize, "options.sendBufferSize");
207
+ }
208
+ recvBufferSize = options.recvBufferSize;
209
+ sendBufferSize = options.sendBufferSize;
210
+ if (options.receiveBlockList) {
211
+ if (!BlockList.isBlockList(options.receiveBlockList)) {
212
+ throw new ERR_INVALID_ARG_TYPE("options.receiveBlockList", "net.BlockList", options.receiveBlockList);
213
+ }
214
+ receiveBlockList = options.receiveBlockList;
215
+ }
216
+ if (options.sendBlockList) {
217
+ if (!BlockList.isBlockList(options.sendBlockList)) {
218
+ throw new ERR_INVALID_ARG_TYPE("options.sendBlockList", "net.BlockList", options.sendBlockList);
219
+ }
220
+ sendBlockList = options.sendBlockList;
221
+ }
222
+ }
223
+
224
+ const handle = newHandle(type, lookup);
225
+ handle[owner_symbol] = this;
226
+
227
+ this[async_id_symbol] = handle.getAsyncId();
228
+ this.type = type;
229
+
230
+ if (typeof listener === "function")
231
+ this.on("message", listener);
232
+
233
+ this[kStateSymbol] = {
234
+ handle,
235
+ receiving: false,
236
+ bindState: BIND_STATE_UNBOUND,
237
+ connectState: CONNECT_STATE_DISCONNECTED,
238
+ queue: undefined,
239
+ reuseAddr: options?.reuseAddr, // Use UV_UDP_REUSEADDR if true.
240
+ reusePort: options?.reusePort,
241
+ ipv6Only: options?.ipv6Only,
242
+ recvBufferSize,
243
+ sendBufferSize,
244
+ receiveBlockList,
245
+ sendBlockList,
246
+ };
247
+
248
+ if (options?.signal !== undefined) {
249
+ const { signal } = options;
250
+ validateAbortSignal(signal, "options.signal");
251
+ const onAborted = () => {
252
+ if (this[kStateSymbol].handle) this.close();
253
+ };
254
+ if (signal.aborted) {
255
+ onAborted();
256
+ } else {
257
+ const disposable = addAbortListener(signal, onAborted);
258
+ this.once("close", disposable[Symbol.dispose]);
259
+ }
260
+ }
261
+ if (udpSocketChannel.hasSubscribers) {
262
+ udpSocketChannel.publish({
263
+ socket: this,
264
+ });
265
+ }
266
+ }
267
+ Object.setPrototypeOf(Socket.prototype, EventEmitter.prototype);
268
+ Object.setPrototypeOf(Socket, EventEmitter);
269
+
270
+ export function createSocket(type, listener) {
271
+ return new Socket(type, listener);
272
+ }
273
+
274
+ function startReceiving(socket) {
275
+ const state = socket[kStateSymbol];
276
+
277
+ state.handle.onmessage = onMessage;
278
+ state.handle.onerror = onError;
279
+ state.handle.recvStart();
280
+ state.receiving = true;
281
+ state.bindState = BIND_STATE_BOUND;
282
+
283
+ if (state.recvBufferSize)
284
+ bufferSize(socket, state.recvBufferSize, RECV_BUFFER);
285
+
286
+ if (state.sendBufferSize)
287
+ bufferSize(socket, state.sendBufferSize, SEND_BUFFER);
288
+ }
289
+
290
+ function startListening(socket) {
291
+ startReceiving(socket);
292
+ socket.emit("listening");
293
+ }
294
+
295
+ function emitListeningNT(socket) {
296
+ // Ensure the socket was not closed before the next tick.
297
+ if (socket[kStateSymbol].handle)
298
+ socket.emit("listening");
299
+ }
300
+
301
+ function emitConnectNT(socket) {
302
+ // Ensure the socket was not closed before the next tick.
303
+ if (socket[kStateSymbol].handle)
304
+ socket.emit("connect");
305
+ }
306
+
307
+ function replaceHandle(self, newHandle) {
308
+ const state = self[kStateSymbol];
309
+ const oldHandle = state.handle;
310
+ // Sync the old handle state to new handle
311
+ if (!oldHandle.hasRef() && typeof newHandle.unref === "function") {
312
+ newHandle.unref();
313
+ }
314
+ // Set up the handle that we got from primary.
315
+ newHandle.lookup = oldHandle.lookup;
316
+ newHandle.bind = oldHandle.bind;
317
+ newHandle.send = oldHandle.send;
318
+ newHandle[owner_symbol] = self;
319
+
320
+ // Replace the existing handle by the handle we got from primary.
321
+ oldHandle.close();
322
+ state.handle = newHandle;
323
+ }
324
+
325
+ function bufferSize(self, size, buffer) {
326
+ if (size >>> 0 !== size)
327
+ throw ERR_SOCKET_BAD_BUFFER_SIZE();
328
+
329
+ const ctx = {};
330
+ const ret = self[kStateSymbol].handle.bufferSize(size, buffer, ctx);
331
+ if (ret === undefined) {
332
+ throw ERR_SOCKET_BUFFER_SIZE(ctx);
333
+ }
334
+ return ret;
335
+ }
336
+
337
+ Socket.prototype.bind = function(port_, address_ /* , callback */) {
338
+ let port = port_;
339
+
340
+ healthCheck(this);
341
+ const state = this[kStateSymbol];
342
+
343
+ if (state.bindState !== BIND_STATE_UNBOUND)
344
+ throw ERR_SOCKET_ALREADY_BOUND();
345
+
346
+ state.bindState = BIND_STATE_BINDING;
347
+
348
+ const cb = arguments.length && arguments[arguments.length - 1];
349
+ if (typeof cb === "function") {
350
+ function removeListeners() {
351
+ this.removeListener(EventEmitter.errorMonitor, removeListeners);
352
+ this.removeListener("listening", onListening);
353
+ }
354
+
355
+ function onListening() {
356
+ removeListeners.call(this);
357
+ cb.call(this);
358
+ }
359
+
360
+ this.on(EventEmitter.errorMonitor, removeListeners);
361
+ this.on("listening", onListening);
362
+ }
363
+
364
+ if (port !== null &&
365
+ typeof port === "object" &&
366
+ typeof port.recvStart === "function") {
367
+ replaceHandle(this, port);
368
+ startListening(this);
369
+ return this;
370
+ }
371
+
372
+ // Open an existing fd instead of creating a new one.
373
+ if (port !== null && typeof port === "object" &&
374
+ isInt32(port.fd) && port.fd > 0) {
375
+ const fd = port.fd;
376
+ const state = this[kStateSymbol];
377
+
378
+ const type = guessHandleType(fd);
379
+ if (type !== "UDP")
380
+ throw ERR_INVALID_FD_TYPE(type);
381
+ const err = state.handle.open(fd);
382
+
383
+ if (err)
384
+ throw ErrnoException(err, "open");
385
+
386
+ startListening(this);
387
+ return this;
388
+ }
389
+
390
+ let address;
391
+
392
+ if (port !== null && typeof port === "object") {
393
+ address = port.address || "";
394
+ port = port.port;
395
+ } else {
396
+ address = typeof address_ === "function" ? "" : address_;
397
+ }
398
+
399
+ // Defaulting address for bind to all interfaces
400
+ if (!address) {
401
+ if (this.type === "udp4")
402
+ address = "0.0.0.0";
403
+ else
404
+ address = "::";
405
+ }
406
+
407
+ // Resolve address first
408
+ state.handle.lookup(address, (err, ip) => {
409
+ if (!state.handle)
410
+ return; // Handle has been closed in the mean time
411
+
412
+ if (err) {
413
+ state.bindState = BIND_STATE_UNBOUND;
414
+ this.emit("error", err);
415
+ return;
416
+ }
417
+
418
+ let flags = 0;
419
+ if (state.reuseAddr)
420
+ flags |= UV_UDP_REUSEADDR;
421
+ if (state.ipv6Only)
422
+ flags |= UV_UDP_IPV6ONLY;
423
+ if (state.reusePort)
424
+ flags |= UV_UDP_REUSEPORT;
425
+
426
+ const bindErr = state.handle.bind(ip, port || 0, flags);
427
+ if (bindErr) {
428
+ const ex = ExceptionWithHostPort(bindErr, "bind", ip, port);
429
+ state.bindState = BIND_STATE_UNBOUND;
430
+ this.emit("error", ex);
431
+ // Todo: close?
432
+ return;
433
+ }
434
+
435
+ startListening(this);
436
+ });
437
+
438
+ return this;
439
+ };
440
+
441
+ // Synchronous counterpart of bind(): bind(2) is a local, non-blocking system call, so this binds
442
+ // inline and returns the resolved address. The address must be a numeric IP literal.
443
+ Socket.prototype.bindSync = function(options = kEmptyObject) {
444
+ healthCheck(this);
445
+ validateObject(options, "options");
446
+ const state = this[kStateSymbol];
447
+
448
+ if (state.bindState !== BIND_STATE_UNBOUND)
449
+ throw ERR_SOCKET_ALREADY_BOUND();
450
+
451
+ // Validate arguments before mutating state so a bad argument leaves the
452
+ // socket unbound and reusable.
453
+ const port = validatePort(options.port ?? 0, "options.port");
454
+ let { address } = options;
455
+ if (!address) {
456
+ address = this.type === "udp4" ? "0.0.0.0" : "::";
457
+ } else {
458
+ validateString(address, "options.address");
459
+ if (isIP(address) === 0) {
460
+ throw new ERR_INVALID_ARG_VALUE(
461
+ "options.address", address,
462
+ "must be a numeric IP address; bindSync does not perform DNS resolution");
463
+ }
464
+ }
465
+
466
+ state.bindState = BIND_STATE_BINDING;
467
+
468
+ let flags = 0;
469
+ if (state.reuseAddr)
470
+ flags |= UV_UDP_REUSEADDR;
471
+ if (state.ipv6Only)
472
+ flags |= UV_UDP_IPV6ONLY;
473
+ if (state.reusePort)
474
+ flags |= UV_UDP_REUSEPORT;
475
+
476
+ const err = state.handle.bind(address, port, flags);
477
+ if (err) {
478
+ state.bindState = BIND_STATE_UNBOUND;
479
+ throw ExceptionWithHostPort(err, "bind", address, port);
480
+ }
481
+
482
+ startReceiving(this);
483
+ process.nextTick(emitListeningNT, this);
484
+ return this.address();
485
+ };
486
+
487
+ Socket.prototype.connect = function(port, address, callback) {
488
+ port = validatePort(port, "Port", false);
489
+ if (typeof address === "function") {
490
+ callback = address;
491
+ address = "";
492
+ } else if (address === undefined) {
493
+ address = "";
494
+ }
495
+
496
+ validateString(address, "address");
497
+
498
+ const state = this[kStateSymbol];
499
+
500
+ if (state.connectState !== CONNECT_STATE_DISCONNECTED)
501
+ throw ERR_SOCKET_DGRAM_IS_CONNECTED();
502
+
503
+ state.connectState = CONNECT_STATE_CONNECTING;
504
+ if (state.bindState === BIND_STATE_UNBOUND)
505
+ this.bind({ port: 0, exclusive: true }, null);
506
+
507
+ if (state.bindState !== BIND_STATE_BOUND) {
508
+ enqueue(this, _connect.bind(this, port, address, callback));
509
+ return;
510
+ }
511
+
512
+ _connect.call(this, port, address, callback);
513
+ };
514
+
515
+ // Synchronous counterpart of connect(): connect(2) on a UDP socket only records the default peer
516
+ // locally. The address must be a numeric IP literal since DNS resolution is async.
517
+ Socket.prototype.connectSync = function(port, address) {
518
+ healthCheck(this);
519
+ port = validatePort(port, "Port", false);
520
+
521
+ const state = this[kStateSymbol];
522
+
523
+ if (state.connectState !== CONNECT_STATE_DISCONNECTED)
524
+ throw ERR_SOCKET_DGRAM_IS_CONNECTED();
525
+
526
+ // Validate arguments before mutating state so a bad argument leaves the
527
+ // socket reusable.
528
+ if (address == null || address === "") {
529
+ address = this.type === "udp4" ? "127.0.0.1" : "::1";
530
+ } else {
531
+ validateString(address, "address");
532
+ if (isIP(address) === 0) {
533
+ throw new ERR_INVALID_ARG_VALUE(
534
+ "address", address,
535
+ "must be a numeric IP address; connectSync does not perform DNS resolution");
536
+ }
537
+ }
538
+
539
+ if (state.bindState === BIND_STATE_UNBOUND)
540
+ this.bindSync();
541
+ else if (state.bindState !== BIND_STATE_BOUND)
542
+ throw ERR_SOCKET_ALREADY_BOUND();
543
+
544
+ state.connectState = CONNECT_STATE_CONNECTING;
545
+
546
+ if (state.sendBlockList?.check(address, `ipv${isIP(address)}`)) {
547
+ state.connectState = CONNECT_STATE_DISCONNECTED;
548
+ throw ERR_IP_BLOCKED(address);
549
+ }
550
+
551
+ const err = state.handle.connect(address, port);
552
+ if (err) {
553
+ state.connectState = CONNECT_STATE_DISCONNECTED;
554
+ throw ExceptionWithHostPort(err, "connect", address, port);
555
+ }
556
+
557
+ state.connectState = CONNECT_STATE_CONNECTED;
558
+ process.nextTick(emitConnectNT, this);
559
+ };
560
+
561
+ function _connect(port, address, callback) {
562
+ const state = this[kStateSymbol];
563
+ if (callback)
564
+ this.once("connect", callback);
565
+
566
+ const afterDns = (ex, ip) => {
567
+ doConnect(ex, this, ip, address, port, callback);
568
+ };
569
+
570
+ state.handle.lookup(address, afterDns);
571
+ }
572
+
573
+ function doConnect(ex, self, ip, address, port, callback) {
574
+ const state = self[kStateSymbol];
575
+ if (!state.handle)
576
+ return;
577
+ if (!ex && state.sendBlockList?.check(ip, `ipv${isIP(ip)}`)) {
578
+ ex = ERR_IP_BLOCKED(ip);
579
+ }
580
+ if (!ex) {
581
+ const err = state.handle.connect(ip, port);
582
+ if (err) {
583
+ ex = ExceptionWithHostPort(err, "connect", address, port);
584
+ }
585
+ }
586
+
587
+ if (ex) {
588
+ state.connectState = CONNECT_STATE_DISCONNECTED;
589
+ return process.nextTick(() => {
590
+ if (callback) {
591
+ self.removeListener("connect", callback);
592
+ callback(ex);
593
+ } else {
594
+ self.emit("error", ex);
595
+ }
596
+ });
597
+ }
598
+
599
+ state.connectState = CONNECT_STATE_CONNECTED;
600
+ process.nextTick(() => self.emit("connect"));
601
+ }
602
+
603
+ Socket.prototype.disconnect = function() {
604
+ const state = this[kStateSymbol];
605
+ if (state.connectState !== CONNECT_STATE_CONNECTED)
606
+ throw ERR_SOCKET_DGRAM_NOT_CONNECTED();
607
+
608
+ const err = state.handle.disconnect();
609
+ if (err)
610
+ throw ErrnoException(err, "connect");
611
+ else
612
+ state.connectState = CONNECT_STATE_DISCONNECTED;
613
+ };
614
+
615
+ // Thin wrapper around `send`, here for compatibility with dgram_legacy.js
616
+ Socket.prototype.sendto = function(buffer,
617
+ offset,
618
+ length,
619
+ port,
620
+ address,
621
+ callback) {
622
+ validateNumber(offset, "offset");
623
+ validateNumber(length, "length");
624
+ validateNumber(port, "port");
625
+ validateString(address, "address");
626
+
627
+ this.send(buffer, offset, length, port, address, callback);
628
+ };
629
+
630
+ function sliceBuffer(buffer, offset, length) {
631
+ if (typeof buffer === "string") {
632
+ buffer = Buffer.from(buffer);
633
+ } else if (!ArrayBuffer.isView(buffer)) {
634
+ throw new ERR_INVALID_ARG_TYPE("buffer",
635
+ ["Buffer",
636
+ "TypedArray",
637
+ "DataView",
638
+ "string"],
639
+ buffer);
640
+ }
641
+
642
+ offset = offset >>> 0;
643
+ length = length >>> 0;
644
+ if (offset > buffer.byteLength) {
645
+ throw ERR_BUFFER_OUT_OF_BOUNDS("offset");
646
+ }
647
+
648
+ if (offset + length > buffer.byteLength) {
649
+ throw ERR_BUFFER_OUT_OF_BOUNDS("length");
650
+ }
651
+
652
+ return Buffer.from(buffer.buffer, buffer.byteOffset + offset, length);
653
+ }
654
+
655
+ function fixBufferList(list) {
656
+ const newlist = new Array(list.length);
657
+
658
+ for (let i = 0, l = list.length; i < l; i++) {
659
+ const buf = list[i];
660
+ if (typeof buf === "string")
661
+ newlist[i] = Buffer.from(buf);
662
+ else if (Buffer.isBuffer(buf))
663
+ newlist[i] = buf;
664
+ else if (!ArrayBuffer.isView(buf))
665
+ return null;
666
+ else
667
+ newlist[i] = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
668
+ }
669
+
670
+ return newlist;
671
+ }
672
+
673
+ function enqueue(self, toEnqueue) {
674
+ const state = self[kStateSymbol];
675
+
676
+ // If the send queue hasn't been initialized yet, do it, and install an
677
+ // event handler that flushes the send queue after binding is done.
678
+ if (state.queue === undefined) {
679
+ state.queue = [];
680
+ self.once(EventEmitter.errorMonitor, onListenError);
681
+ self.once("listening", onListenSuccess);
682
+ }
683
+ state.queue.push(toEnqueue);
684
+ }
685
+
686
+ function onListenSuccess() {
687
+ this.removeListener(EventEmitter.errorMonitor, onListenError);
688
+ clearQueue.call(this);
689
+ }
690
+
691
+ function onListenError() {
692
+ this.removeListener("listening", onListenSuccess);
693
+ this[kStateSymbol].queue = undefined;
694
+ }
695
+
696
+ function clearQueue() {
697
+ const state = this[kStateSymbol];
698
+ const queue = state.queue;
699
+ state.queue = undefined;
700
+
701
+ // Flush the send queue.
702
+ for (const queueEntry of queue)
703
+ queueEntry();
704
+ }
705
+
706
+ // valid combinations
707
+ // For connectionless sockets
708
+ // send(buffer, offset, length, port, address, callback)
709
+ // send(buffer, offset, length, port, address)
710
+ // send(buffer, offset, length, port, callback)
711
+ // send(buffer, offset, length, port)
712
+ // send(bufferOrList, port, address, callback)
713
+ // send(bufferOrList, port, address)
714
+ // send(bufferOrList, port, callback)
715
+ // send(bufferOrList, port)
716
+ // For connected sockets
717
+ // send(buffer, offset, length, callback)
718
+ // send(buffer, offset, length)
719
+ // send(bufferOrList, callback)
720
+ // send(bufferOrList)
721
+ Socket.prototype.send = function(buffer,
722
+ offset,
723
+ length,
724
+ port,
725
+ address,
726
+ callback) {
727
+
728
+ let list;
729
+ const state = this[kStateSymbol];
730
+ const connected = state.connectState === CONNECT_STATE_CONNECTED;
731
+ if (!connected) {
732
+ if (address || (port && typeof port !== "function")) {
733
+ buffer = sliceBuffer(buffer, offset, length);
734
+ } else {
735
+ callback = port;
736
+ port = offset;
737
+ address = length;
738
+ }
739
+ } else {
740
+ if (typeof length === "number") {
741
+ buffer = sliceBuffer(buffer, offset, length);
742
+ if (typeof port === "function") {
743
+ callback = port;
744
+ port = null;
745
+ }
746
+ } else {
747
+ callback = offset;
748
+ }
749
+
750
+ if (port || address)
751
+ throw ERR_SOCKET_DGRAM_IS_CONNECTED();
752
+ }
753
+
754
+ if (!Array.isArray(buffer)) {
755
+ if (typeof buffer === "string") {
756
+ list = [ Buffer.from(buffer) ];
757
+ } else if (!ArrayBuffer.isView(buffer)) {
758
+ throw new ERR_INVALID_ARG_TYPE("buffer",
759
+ ["Buffer",
760
+ "TypedArray",
761
+ "DataView",
762
+ "string"],
763
+ buffer);
764
+ } else {
765
+ list = [ buffer ];
766
+ }
767
+ } else if (!(list = fixBufferList(buffer))) {
768
+ throw new ERR_INVALID_ARG_TYPE("buffer list arguments",
769
+ ["Buffer",
770
+ "TypedArray",
771
+ "DataView",
772
+ "string"],
773
+ buffer);
774
+ }
775
+
776
+ if (!connected)
777
+ port = validatePort(port, "Port", false);
778
+
779
+ // Normalize callback so it's either a function or undefined but not anything
780
+ // else.
781
+ if (typeof callback !== "function")
782
+ callback = undefined;
783
+
784
+ if (typeof address === "function") {
785
+ callback = address;
786
+ address = undefined;
787
+ } else if (address != null) {
788
+ validateString(address, "address");
789
+ }
790
+
791
+ healthCheck(this);
792
+
793
+ if (state.bindState === BIND_STATE_UNBOUND)
794
+ this.bind({ port: 0, exclusive: true }, null);
795
+
796
+ if (list.length === 0)
797
+ list.push(Buffer.alloc(0));
798
+
799
+ // If the socket hasn't been bound yet, push the outbound packet onto the
800
+ // send queue and send after binding is complete.
801
+ if (state.bindState !== BIND_STATE_BOUND) {
802
+ enqueue(this, this.send.bind(this, list, port, address, callback));
803
+ return;
804
+ }
805
+
806
+ const afterDns = (ex, ip) => {
807
+ doSend(ex, this, ip, list, address, port, callback);
808
+ };
809
+
810
+ if (!connected) {
811
+ state.handle.lookup(address, afterDns);
812
+ } else {
813
+ afterDns(null, null);
814
+ }
815
+ };
816
+
817
+ function doSend(ex, self, ip, list, address, port, callback) {
818
+ const state = self[kStateSymbol];
819
+
820
+ if (ex) {
821
+ if (typeof callback === "function") {
822
+ process.nextTick(callback, ex);
823
+ return;
824
+ }
825
+
826
+ process.nextTick(() => self.emit("error", ex));
827
+ return;
828
+ } else if (!state.handle) {
829
+ return;
830
+ }
831
+
832
+ if (ip && state.sendBlockList?.check(ip, `ipv${isIP(ip)}`)) {
833
+ if (callback) {
834
+ process.nextTick(callback, ERR_IP_BLOCKED(ip));
835
+ }
836
+ return;
837
+ }
838
+
839
+ const req = new SendWrap();
840
+ req.list = list; // Keep reference alive.
841
+ req.address = address;
842
+ req.port = port;
843
+ if (callback) {
844
+ req.callback = callback;
845
+ req.oncomplete = afterSend;
846
+ }
847
+
848
+ let err;
849
+ if (port)
850
+ err = state.handle.send(req, list, list.length, port, ip, !!callback);
851
+ else
852
+ err = state.handle.send(req, list, list.length, !!callback);
853
+
854
+ if (err >= 1) {
855
+ // Synchronous finish. The return code is msg_length + 1 so that we can
856
+ // distinguish between synchronous success and asynchronous success.
857
+ if (callback)
858
+ process.nextTick(callback, null, err - 1);
859
+ return;
860
+ }
861
+
862
+ if (err && callback) {
863
+ // Don't emit as error, dgram_legacy.js compatibility
864
+ const ex = ExceptionWithHostPort(err, "send", address, port);
865
+ process.nextTick(callback, ex);
866
+ }
867
+ }
868
+
869
+ function afterSend(err, sent) {
870
+ if (err) {
871
+ err = ExceptionWithHostPort(err, "send", this.address, this.port);
872
+ } else {
873
+ err = null;
874
+ }
875
+
876
+ this.callback(err, sent);
877
+ }
878
+
879
+ Socket.prototype.close = function(callback) {
880
+ const state = this[kStateSymbol];
881
+ const queue = state.queue;
882
+
883
+ if (typeof callback === "function")
884
+ this.on("close", callback);
885
+
886
+ if (queue !== undefined) {
887
+ queue.push(this.close.bind(this));
888
+ return this;
889
+ }
890
+
891
+ healthCheck(this);
892
+ stopReceiving(this);
893
+ state.handle.close();
894
+ state.handle = null;
895
+ process.nextTick(socketCloseNT, this);
896
+
897
+ return this;
898
+ };
899
+
900
+ Socket.prototype[Symbol.asyncDispose] = async function() {
901
+ if (!this[kStateSymbol].handle) {
902
+ return;
903
+ }
904
+ await new Promise((resolve) => this.close(resolve));
905
+ };
906
+
907
+ function socketCloseNT(self) {
908
+ self.emit("close");
909
+ }
910
+
911
+ Socket.prototype.address = function() {
912
+ healthCheck(this);
913
+
914
+ const out = {};
915
+ const err = this[kStateSymbol].handle.getsockname(out);
916
+ if (err) {
917
+ throw ErrnoException(err, "getsockname");
918
+ }
919
+
920
+ return out;
921
+ };
922
+
923
+ Socket.prototype.remoteAddress = function() {
924
+ healthCheck(this);
925
+
926
+ const state = this[kStateSymbol];
927
+ if (state.connectState !== CONNECT_STATE_CONNECTED)
928
+ throw ERR_SOCKET_DGRAM_NOT_CONNECTED();
929
+
930
+ const out = {};
931
+ const err = state.handle.getpeername(out);
932
+ if (err)
933
+ throw ErrnoException(err, "getpeername");
934
+
935
+ return out;
936
+ };
937
+
938
+ Socket.prototype.setBroadcast = function(arg) {
939
+ const err = this[kStateSymbol].handle.setBroadcast(arg ? 1 : 0);
940
+ if (err) {
941
+ throw ErrnoException(err, "setBroadcast");
942
+ }
943
+ };
944
+
945
+ Socket.prototype.setTTL = function(ttl) {
946
+ validateNumber(ttl, "ttl");
947
+
948
+ const err = this[kStateSymbol].handle.setTTL(ttl);
949
+ if (err) {
950
+ throw ErrnoException(err, "setTTL");
951
+ }
952
+
953
+ return ttl;
954
+ };
955
+
956
+ Socket.prototype.setMulticastTTL = function(ttl) {
957
+ validateNumber(ttl, "ttl");
958
+
959
+ const err = this[kStateSymbol].handle.setMulticastTTL(ttl);
960
+ if (err) {
961
+ throw ErrnoException(err, "setMulticastTTL");
962
+ }
963
+
964
+ return ttl;
965
+ };
966
+
967
+ Socket.prototype.setMulticastLoopback = function(arg) {
968
+ const err = this[kStateSymbol].handle.setMulticastLoopback(arg ? 1 : 0);
969
+ if (err) {
970
+ throw ErrnoException(err, "setMulticastLoopback");
971
+ }
972
+
973
+ return arg; // 0.4 compatibility
974
+ };
975
+
976
+ Socket.prototype.setMulticastInterface = function(interfaceAddress) {
977
+ healthCheck(this);
978
+ validateString(interfaceAddress, "interfaceAddress");
979
+
980
+ const err = this[kStateSymbol].handle.setMulticastInterface(interfaceAddress);
981
+ if (err) {
982
+ throw ErrnoException(err, "setMulticastInterface");
983
+ }
984
+ };
985
+
986
+ Socket.prototype.addMembership = function(multicastAddress,
987
+ interfaceAddress) {
988
+ healthCheck(this);
989
+
990
+ if (!multicastAddress) {
991
+ throw new ERR_MISSING_ARGS("multicastAddress");
992
+ }
993
+
994
+ const { handle } = this[kStateSymbol];
995
+ const err = handle.addMembership(multicastAddress, interfaceAddress);
996
+ if (err) {
997
+ throw ErrnoException(err, "addMembership");
998
+ }
999
+ };
1000
+
1001
+ Socket.prototype.dropMembership = function(multicastAddress,
1002
+ interfaceAddress) {
1003
+ healthCheck(this);
1004
+
1005
+ if (!multicastAddress) {
1006
+ throw new ERR_MISSING_ARGS("multicastAddress");
1007
+ }
1008
+
1009
+ const { handle } = this[kStateSymbol];
1010
+ const err = handle.dropMembership(multicastAddress, interfaceAddress);
1011
+ if (err) {
1012
+ throw ErrnoException(err, "dropMembership");
1013
+ }
1014
+ };
1015
+
1016
+ Socket.prototype.addSourceSpecificMembership = function(sourceAddress,
1017
+ groupAddress,
1018
+ interfaceAddress) {
1019
+ healthCheck(this);
1020
+
1021
+ validateString(sourceAddress, "sourceAddress");
1022
+ validateString(groupAddress, "groupAddress");
1023
+
1024
+ const err =
1025
+ this[kStateSymbol].handle.addSourceSpecificMembership(sourceAddress,
1026
+ groupAddress,
1027
+ interfaceAddress);
1028
+ if (err) {
1029
+ throw ErrnoException(err, "addSourceSpecificMembership");
1030
+ }
1031
+ };
1032
+
1033
+ Socket.prototype.dropSourceSpecificMembership = function(sourceAddress,
1034
+ groupAddress,
1035
+ interfaceAddress) {
1036
+ healthCheck(this);
1037
+
1038
+ validateString(sourceAddress, "sourceAddress");
1039
+ validateString(groupAddress, "groupAddress");
1040
+
1041
+ const err =
1042
+ this[kStateSymbol].handle.dropSourceSpecificMembership(sourceAddress,
1043
+ groupAddress,
1044
+ interfaceAddress);
1045
+ if (err) {
1046
+ throw ErrnoException(err, "dropSourceSpecificMembership");
1047
+ }
1048
+ };
1049
+
1050
+ function healthCheck(socket) {
1051
+ if (!socket[kStateSymbol].handle) {
1052
+ // Error message from dgram_legacy.js.
1053
+ throw ERR_SOCKET_DGRAM_NOT_RUNNING();
1054
+ }
1055
+ }
1056
+
1057
+ function stopReceiving(socket) {
1058
+ const state = socket[kStateSymbol];
1059
+
1060
+ if (!state.receiving)
1061
+ return;
1062
+
1063
+ state.handle.recvStop();
1064
+ state.receiving = false;
1065
+ }
1066
+
1067
+ function onMessage(nread, handle, buf, rinfo) {
1068
+ const self = handle[owner_symbol];
1069
+ if (nread < 0) {
1070
+ return self.emit("error", ErrnoException(nread, "recvmsg"));
1071
+ }
1072
+ if (self[kStateSymbol]?.receiveBlockList?.check(rinfo.address,
1073
+ rinfo.family?.toLocaleLowerCase())) {
1074
+ return;
1075
+ }
1076
+ rinfo.size = buf.length; // compatibility
1077
+ self.emit("message", buf, rinfo);
1078
+ }
1079
+
1080
+ function onError(nread, handle, error) {
1081
+ const self = handle[owner_symbol];
1082
+ return self.emit("error", error);
1083
+ }
1084
+
1085
+ Socket.prototype.ref = function() {
1086
+ const handle = this[kStateSymbol].handle;
1087
+
1088
+ if (handle)
1089
+ handle.ref();
1090
+
1091
+ return this;
1092
+ };
1093
+
1094
+ Socket.prototype.unref = function() {
1095
+ const handle = this[kStateSymbol].handle;
1096
+
1097
+ if (handle)
1098
+ handle.unref();
1099
+
1100
+ return this;
1101
+ };
1102
+
1103
+ Socket.prototype.setRecvBufferSize = function(size) {
1104
+ bufferSize(this, size, RECV_BUFFER);
1105
+ };
1106
+
1107
+ Socket.prototype.setSendBufferSize = function(size) {
1108
+ bufferSize(this, size, SEND_BUFFER);
1109
+ };
1110
+
1111
+ Socket.prototype.getRecvBufferSize = function() {
1112
+ return bufferSize(this, 0, RECV_BUFFER);
1113
+ };
1114
+
1115
+ Socket.prototype.getSendBufferSize = function() {
1116
+ return bufferSize(this, 0, SEND_BUFFER);
1117
+ };
1118
+
1119
+ Socket.prototype.getSendQueueSize = function() {
1120
+ return this[kStateSymbol].handle.getSendQueueSize();
1121
+ };
1122
+
1123
+ Socket.prototype.getSendQueueCount = function() {
1124
+ return this[kStateSymbol].handle.getSendQueueCount();
1125
+ };
1126
+
1127
+ // Deprecated private APIs.
1128
+ for (const [name, key] of [["_handle", "handle"], ["_receiving", "receiving"], ["_bindState", "bindState"], ["_queue", "queue"],
1129
+ ["_reuseAddr", "reuseAddr"]]) {
1130
+ Object.defineProperty(Socket.prototype, name, {
1131
+ __proto__: null,
1132
+ get: deprecate(function() {
1133
+ return this[kStateSymbol][key];
1134
+ }, `Socket.prototype.${name} is deprecated`, "DEP0112"),
1135
+ set: deprecate(function(val) {
1136
+ this[kStateSymbol][key] = val;
1137
+ }, `Socket.prototype.${name} is deprecated`, "DEP0112"),
1138
+ });
1139
+ }
1140
+
1141
+ Socket.prototype._healthCheck = deprecate(function() {
1142
+ healthCheck(this);
1143
+ }, "Socket.prototype._healthCheck() is deprecated", "DEP0112");
1144
+
1145
+ Socket.prototype._stopReceiving = deprecate(function() {
1146
+ stopReceiving(this);
1147
+ }, "Socket.prototype._stopReceiving() is deprecated", "DEP0112");
1148
+
1149
+ // Legacy alias on the C++ wrapper object. This is not public API, so we may
1150
+ // want to runtime-deprecate it at some point. There's no hurry, though.
1151
+ Object.defineProperty(UDP.prototype, "owner", {
1152
+ __proto__: null,
1153
+ get() { return this[owner_symbol]; },
1154
+ set(v) { this[owner_symbol] = v; },
1155
+ });
1156
+
1157
+ const _createSocketHandleDeprecated = deprecate(
1158
+ _createSocketHandle,
1159
+ "dgram._createSocketHandle() is deprecated",
1160
+ "DEP0112",
1161
+ );
1162
+
1163
+ export { _createSocketHandleDeprecated as _createSocketHandle };
1164
+
1165
+ export default {
1166
+ _createSocketHandle: _createSocketHandleDeprecated,
1167
+ createSocket,
1168
+ Socket,
1169
+ };