| 383 | #address = {}; |
| 384 | |
| 385 | constructor(options = kEmptyObject) { |
| 386 | validateObject(options, 'options'); |
| 387 | |
| 388 | const port = validatePort(options.port ?? 0, 'options.port'); |
| 389 | |
| 390 | const ipv6Only = options.ipv6Only ?? false; |
| 391 | validateBoolean(ipv6Only, 'options.ipv6Only'); |
| 392 | |
| 393 | const reusePort = options.reusePort ?? false; |
| 394 | validateBoolean(reusePort, 'options.reusePort'); |
| 395 | |
| 396 | let { host } = options; |
| 397 | let addressType; |
| 398 | if (host === undefined || host === null) { |
| 399 | host = ipv6Only ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR; |
| 400 | addressType = ipv6Only ? 6 : 4; |
| 401 | } else { |
| 402 | validateString(host, 'options.host'); |
| 403 | addressType = isIP(host); |
| 404 | if (addressType === 0) { |
| 405 | throw new ERR_INVALID_ARG_VALUE( |
| 406 | 'options.host', host, |
| 407 | 'must be a numeric IP address; net.BoundSocket does not perform DNS resolution'); |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | let flags = 0; |
| 412 | if (ipv6Only) { |
| 413 | flags |= TCPConstants.UV_TCP_IPV6ONLY; |
| 414 | } |
| 415 | if (reusePort) { |
| 416 | flags |= TCPConstants.UV_TCP_REUSEPORT; |
| 417 | } |
| 418 | |
| 419 | const handle = new TCP(TCPConstants.SOCKET); |
| 420 | let err = addressType === 6 ? |
| 421 | handle.bind6(host, port, flags) : |
| 422 | handle.bind(host, port, flags); |
| 423 | // EADDRINUSE is deferred by libuv's uv_tcp_bind(), which returns 0 and |
| 424 | // surfaces it on the next getsockname/listen/connect. Force getsockname() |
| 425 | // now so conflicts throw synchronously; the address is cached since the |
| 426 | // handle is immutable. |
| 427 | if (err === 0) { |
| 428 | err = handle.getsockname(this.#address); |
| 429 | } |
| 430 | if (err) { |
| 431 | handle.close(); |
| 432 | throw new ExceptionWithHostPort(err, 'bind', host, port); |
| 433 | } |
| 434 | |
| 435 | this.#handle = handle; |
| 436 | } |
| 437 | |
| 438 | // The kernel-assigned local address, resolved at construction; reflects the |
| 439 | // OS-assigned ephemeral port when the bind requested port 0. |