11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci'use strict';
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciconst {
251cb0ef41Sopenharmony_ci  ArrayIsArray,
261cb0ef41Sopenharmony_ci  ArrayPrototypeIndexOf,
271cb0ef41Sopenharmony_ci  ArrayPrototypePush,
281cb0ef41Sopenharmony_ci  Boolean,
291cb0ef41Sopenharmony_ci  FunctionPrototypeBind,
301cb0ef41Sopenharmony_ci  FunctionPrototypeCall,
311cb0ef41Sopenharmony_ci  MathMax,
321cb0ef41Sopenharmony_ci  Number,
331cb0ef41Sopenharmony_ci  NumberIsNaN,
341cb0ef41Sopenharmony_ci  NumberParseInt,
351cb0ef41Sopenharmony_ci  ObjectDefineProperty,
361cb0ef41Sopenharmony_ci  ObjectSetPrototypeOf,
371cb0ef41Sopenharmony_ci  Symbol,
381cb0ef41Sopenharmony_ci  ObjectCreate,
391cb0ef41Sopenharmony_ci  SymbolAsyncDispose,
401cb0ef41Sopenharmony_ci} = primordials;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciconst EventEmitter = require('events');
431cb0ef41Sopenharmony_ciconst stream = require('stream');
441cb0ef41Sopenharmony_cilet debug = require('internal/util/debuglog').debuglog('net', (fn) => {
451cb0ef41Sopenharmony_ci  debug = fn;
461cb0ef41Sopenharmony_ci});
471cb0ef41Sopenharmony_ciconst {
481cb0ef41Sopenharmony_ci  kReinitializeHandle,
491cb0ef41Sopenharmony_ci  isIP,
501cb0ef41Sopenharmony_ci  isIPv4,
511cb0ef41Sopenharmony_ci  isIPv6,
521cb0ef41Sopenharmony_ci  normalizedArgsSymbol,
531cb0ef41Sopenharmony_ci  makeSyncWrite,
541cb0ef41Sopenharmony_ci} = require('internal/net');
551cb0ef41Sopenharmony_ciconst assert = require('internal/assert');
561cb0ef41Sopenharmony_ciconst {
571cb0ef41Sopenharmony_ci  UV_EADDRINUSE,
581cb0ef41Sopenharmony_ci  UV_EINVAL,
591cb0ef41Sopenharmony_ci  UV_ENOTCONN,
601cb0ef41Sopenharmony_ci  UV_ECANCELED,
611cb0ef41Sopenharmony_ci} = internalBinding('uv');
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer');
641cb0ef41Sopenharmony_ciconst { guessHandleType } = internalBinding('util');
651cb0ef41Sopenharmony_ciconst { ShutdownWrap } = internalBinding('stream_wrap');
661cb0ef41Sopenharmony_ciconst {
671cb0ef41Sopenharmony_ci  TCP,
681cb0ef41Sopenharmony_ci  TCPConnectWrap,
691cb0ef41Sopenharmony_ci  constants: TCPConstants,
701cb0ef41Sopenharmony_ci} = internalBinding('tcp_wrap');
711cb0ef41Sopenharmony_ciconst {
721cb0ef41Sopenharmony_ci  Pipe,
731cb0ef41Sopenharmony_ci  PipeConnectWrap,
741cb0ef41Sopenharmony_ci  constants: PipeConstants,
751cb0ef41Sopenharmony_ci} = internalBinding('pipe_wrap');
761cb0ef41Sopenharmony_ciconst {
771cb0ef41Sopenharmony_ci  newAsyncId,
781cb0ef41Sopenharmony_ci  defaultTriggerAsyncIdScope,
791cb0ef41Sopenharmony_ci  symbols: { async_id_symbol, owner_symbol },
801cb0ef41Sopenharmony_ci} = require('internal/async_hooks');
811cb0ef41Sopenharmony_ciconst {
821cb0ef41Sopenharmony_ci  writevGeneric,
831cb0ef41Sopenharmony_ci  writeGeneric,
841cb0ef41Sopenharmony_ci  onStreamRead,
851cb0ef41Sopenharmony_ci  kAfterAsyncWrite,
861cb0ef41Sopenharmony_ci  kHandle,
871cb0ef41Sopenharmony_ci  kUpdateTimer,
881cb0ef41Sopenharmony_ci  setStreamTimeout,
891cb0ef41Sopenharmony_ci  kBuffer,
901cb0ef41Sopenharmony_ci  kBufferCb,
911cb0ef41Sopenharmony_ci  kBufferGen,
921cb0ef41Sopenharmony_ci} = require('internal/stream_base_commons');
931cb0ef41Sopenharmony_ciconst {
941cb0ef41Sopenharmony_ci  codes: {
951cb0ef41Sopenharmony_ci    ERR_INVALID_ADDRESS_FAMILY,
961cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_TYPE,
971cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_VALUE,
981cb0ef41Sopenharmony_ci    ERR_INVALID_FD_TYPE,
991cb0ef41Sopenharmony_ci    ERR_INVALID_IP_ADDRESS,
1001cb0ef41Sopenharmony_ci    ERR_INVALID_HANDLE_TYPE,
1011cb0ef41Sopenharmony_ci    ERR_SERVER_ALREADY_LISTEN,
1021cb0ef41Sopenharmony_ci    ERR_SERVER_NOT_RUNNING,
1031cb0ef41Sopenharmony_ci    ERR_SOCKET_CLOSED,
1041cb0ef41Sopenharmony_ci    ERR_SOCKET_CLOSED_BEFORE_CONNECTION,
1051cb0ef41Sopenharmony_ci    ERR_MISSING_ARGS,
1061cb0ef41Sopenharmony_ci  },
1071cb0ef41Sopenharmony_ci  aggregateErrors,
1081cb0ef41Sopenharmony_ci  errnoException,
1091cb0ef41Sopenharmony_ci  exceptionWithHostPort,
1101cb0ef41Sopenharmony_ci  genericNodeError,
1111cb0ef41Sopenharmony_ci  uvExceptionWithHostPort,
1121cb0ef41Sopenharmony_ci} = require('internal/errors');
1131cb0ef41Sopenharmony_ciconst { isUint8Array } = require('internal/util/types');
1141cb0ef41Sopenharmony_ciconst { queueMicrotask } = require('internal/process/task_queues');
1151cb0ef41Sopenharmony_ciconst { kEmptyObject, promisify } = require('internal/util');
1161cb0ef41Sopenharmony_ciconst {
1171cb0ef41Sopenharmony_ci  validateAbortSignal,
1181cb0ef41Sopenharmony_ci  validateBoolean,
1191cb0ef41Sopenharmony_ci  validateFunction,
1201cb0ef41Sopenharmony_ci  validateInt32,
1211cb0ef41Sopenharmony_ci  validateNumber,
1221cb0ef41Sopenharmony_ci  validatePort,
1231cb0ef41Sopenharmony_ci  validateString,
1241cb0ef41Sopenharmony_ci} = require('internal/validators');
1251cb0ef41Sopenharmony_ciconst kLastWriteQueueSize = Symbol('lastWriteQueueSize');
1261cb0ef41Sopenharmony_ciconst {
1271cb0ef41Sopenharmony_ci  DTRACE_NET_SERVER_CONNECTION,
1281cb0ef41Sopenharmony_ci  DTRACE_NET_STREAM_END,
1291cb0ef41Sopenharmony_ci} = require('internal/dtrace');
1301cb0ef41Sopenharmony_ciconst { getOptionValue } = require('internal/options');
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci// Lazy loaded to improve startup performance.
1331cb0ef41Sopenharmony_cilet cluster;
1341cb0ef41Sopenharmony_cilet dns;
1351cb0ef41Sopenharmony_cilet BlockList;
1361cb0ef41Sopenharmony_cilet SocketAddress;
1371cb0ef41Sopenharmony_cilet autoSelectFamilyDefault = getOptionValue('--enable-network-family-autoselection');
1381cb0ef41Sopenharmony_cilet autoSelectFamilyAttemptTimeoutDefault = 250;
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ciconst { clearTimeout, setTimeout } = require('timers');
1411cb0ef41Sopenharmony_ciconst { kTimeout } = require('internal/timers');
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciconst DEFAULT_IPV4_ADDR = '0.0.0.0';
1441cb0ef41Sopenharmony_ciconst DEFAULT_IPV6_ADDR = '::';
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciconst isWindows = process.platform === 'win32';
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciconst noop = () => {};
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ciconst kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_cilet netClientSocketChannel;
1531cb0ef41Sopenharmony_cilet netServerSocketChannel;
1541cb0ef41Sopenharmony_cifunction lazyChannels() {
1551cb0ef41Sopenharmony_ci  // TODO(joyeecheung): support diagnostics channels in the snapshot.
1561cb0ef41Sopenharmony_ci  // For now it is fine to create them lazily when there isn't a snapshot to
1571cb0ef41Sopenharmony_ci  // build. If users need the channels they would have to create them first
1581cb0ef41Sopenharmony_ci  // before invoking any built-ins that would publish to these channels
1591cb0ef41Sopenharmony_ci  // anyway.
1601cb0ef41Sopenharmony_ci  if (netClientSocketChannel === undefined) {
1611cb0ef41Sopenharmony_ci    const dc = require('diagnostics_channel');
1621cb0ef41Sopenharmony_ci    netClientSocketChannel = dc.channel('net.client.socket');
1631cb0ef41Sopenharmony_ci    netServerSocketChannel = dc.channel('net.server.socket');
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci}
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ciconst {
1681cb0ef41Sopenharmony_ci  hasObserver,
1691cb0ef41Sopenharmony_ci  startPerf,
1701cb0ef41Sopenharmony_ci  stopPerf,
1711cb0ef41Sopenharmony_ci} = require('internal/perf/observe');
1721cb0ef41Sopenharmony_ciconst { getDefaultHighWaterMark } = require('internal/streams/state');
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_cifunction getFlags(ipv6Only) {
1751cb0ef41Sopenharmony_ci  return ipv6Only === true ? TCPConstants.UV_TCP_IPV6ONLY : 0;
1761cb0ef41Sopenharmony_ci}
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_cifunction createHandle(fd, is_server) {
1791cb0ef41Sopenharmony_ci  validateInt32(fd, 'fd', 0);
1801cb0ef41Sopenharmony_ci  const type = guessHandleType(fd);
1811cb0ef41Sopenharmony_ci  if (type === 'PIPE') {
1821cb0ef41Sopenharmony_ci    return new Pipe(
1831cb0ef41Sopenharmony_ci      is_server ? PipeConstants.SERVER : PipeConstants.SOCKET,
1841cb0ef41Sopenharmony_ci    );
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  if (type === 'TCP') {
1881cb0ef41Sopenharmony_ci    return new TCP(
1891cb0ef41Sopenharmony_ci      is_server ? TCPConstants.SERVER : TCPConstants.SOCKET,
1901cb0ef41Sopenharmony_ci    );
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  throw new ERR_INVALID_FD_TYPE(type);
1941cb0ef41Sopenharmony_ci}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_cifunction getNewAsyncId(handle) {
1981cb0ef41Sopenharmony_ci  return (!handle || typeof handle.getAsyncId !== 'function') ?
1991cb0ef41Sopenharmony_ci    newAsyncId() : handle.getAsyncId();
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_cifunction isPipeName(s) {
2041cb0ef41Sopenharmony_ci  return typeof s === 'string' && toNumber(s) === false;
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci/**
2081cb0ef41Sopenharmony_ci * Creates a new TCP or IPC server
2091cb0ef41Sopenharmony_ci * @param {{
2101cb0ef41Sopenharmony_ci *   allowHalfOpen?: boolean;
2111cb0ef41Sopenharmony_ci *   pauseOnConnect?: boolean;
2121cb0ef41Sopenharmony_ci *   }} [options]
2131cb0ef41Sopenharmony_ci * @param {Function} [connectionListener]
2141cb0ef41Sopenharmony_ci * @returns {Server}
2151cb0ef41Sopenharmony_ci */
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_cifunction createServer(options, connectionListener) {
2181cb0ef41Sopenharmony_ci  return new Server(options, connectionListener);
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci// Target API:
2231cb0ef41Sopenharmony_ci//
2241cb0ef41Sopenharmony_ci// let s = net.connect({port: 80, host: 'google.com'}, function() {
2251cb0ef41Sopenharmony_ci//   ...
2261cb0ef41Sopenharmony_ci// });
2271cb0ef41Sopenharmony_ci//
2281cb0ef41Sopenharmony_ci// There are various forms:
2291cb0ef41Sopenharmony_ci//
2301cb0ef41Sopenharmony_ci// connect(options, [cb])
2311cb0ef41Sopenharmony_ci// connect(port, [host], [cb])
2321cb0ef41Sopenharmony_ci// connect(path, [cb]);
2331cb0ef41Sopenharmony_ci//
2341cb0ef41Sopenharmony_cifunction connect(...args) {
2351cb0ef41Sopenharmony_ci  const normalized = normalizeArgs(args);
2361cb0ef41Sopenharmony_ci  const options = normalized[0];
2371cb0ef41Sopenharmony_ci  debug('createConnection', normalized);
2381cb0ef41Sopenharmony_ci  const socket = new Socket(options);
2391cb0ef41Sopenharmony_ci  lazyChannels();
2401cb0ef41Sopenharmony_ci  if (netClientSocketChannel.hasSubscribers) {
2411cb0ef41Sopenharmony_ci    netClientSocketChannel.publish({
2421cb0ef41Sopenharmony_ci      socket,
2431cb0ef41Sopenharmony_ci    });
2441cb0ef41Sopenharmony_ci  }
2451cb0ef41Sopenharmony_ci  if (options.timeout) {
2461cb0ef41Sopenharmony_ci    socket.setTimeout(options.timeout);
2471cb0ef41Sopenharmony_ci  }
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci  return socket.connect(normalized);
2501cb0ef41Sopenharmony_ci}
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_cifunction getDefaultAutoSelectFamily() {
2531cb0ef41Sopenharmony_ci  return autoSelectFamilyDefault;
2541cb0ef41Sopenharmony_ci}
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_cifunction setDefaultAutoSelectFamily(value) {
2571cb0ef41Sopenharmony_ci  validateBoolean(value, 'value');
2581cb0ef41Sopenharmony_ci  autoSelectFamilyDefault = value;
2591cb0ef41Sopenharmony_ci}
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_cifunction getDefaultAutoSelectFamilyAttemptTimeout() {
2621cb0ef41Sopenharmony_ci  return autoSelectFamilyAttemptTimeoutDefault;
2631cb0ef41Sopenharmony_ci}
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_cifunction setDefaultAutoSelectFamilyAttemptTimeout(value) {
2661cb0ef41Sopenharmony_ci  validateInt32(value, 'value', 1);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  if (value < 10) {
2691cb0ef41Sopenharmony_ci    value = 10;
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  autoSelectFamilyAttemptTimeoutDefault = value;
2731cb0ef41Sopenharmony_ci}
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci// Returns an array [options, cb], where options is an object,
2761cb0ef41Sopenharmony_ci// cb is either a function or null.
2771cb0ef41Sopenharmony_ci// Used to normalize arguments of Socket.prototype.connect() and
2781cb0ef41Sopenharmony_ci// Server.prototype.listen(). Possible combinations of parameters:
2791cb0ef41Sopenharmony_ci//   (options[...][, cb])
2801cb0ef41Sopenharmony_ci//   (path[...][, cb])
2811cb0ef41Sopenharmony_ci//   ([port][, host][...][, cb])
2821cb0ef41Sopenharmony_ci// For Socket.prototype.connect(), the [...] part is ignored
2831cb0ef41Sopenharmony_ci// For Server.prototype.listen(), the [...] part is [, backlog]
2841cb0ef41Sopenharmony_ci// but will not be handled here (handled in listen())
2851cb0ef41Sopenharmony_cifunction normalizeArgs(args) {
2861cb0ef41Sopenharmony_ci  let arr;
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci  if (args.length === 0) {
2891cb0ef41Sopenharmony_ci    arr = [{}, null];
2901cb0ef41Sopenharmony_ci    arr[normalizedArgsSymbol] = true;
2911cb0ef41Sopenharmony_ci    return arr;
2921cb0ef41Sopenharmony_ci  }
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ci  const arg0 = args[0];
2951cb0ef41Sopenharmony_ci  let options = {};
2961cb0ef41Sopenharmony_ci  if (typeof arg0 === 'object' && arg0 !== null) {
2971cb0ef41Sopenharmony_ci    // (options[...][, cb])
2981cb0ef41Sopenharmony_ci    options = arg0;
2991cb0ef41Sopenharmony_ci  } else if (isPipeName(arg0)) {
3001cb0ef41Sopenharmony_ci    // (path[...][, cb])
3011cb0ef41Sopenharmony_ci    options.path = arg0;
3021cb0ef41Sopenharmony_ci  } else {
3031cb0ef41Sopenharmony_ci    // ([port][, host][...][, cb])
3041cb0ef41Sopenharmony_ci    options.port = arg0;
3051cb0ef41Sopenharmony_ci    if (args.length > 1 && typeof args[1] === 'string') {
3061cb0ef41Sopenharmony_ci      options.host = args[1];
3071cb0ef41Sopenharmony_ci    }
3081cb0ef41Sopenharmony_ci  }
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  const cb = args[args.length - 1];
3111cb0ef41Sopenharmony_ci  if (typeof cb !== 'function')
3121cb0ef41Sopenharmony_ci    arr = [options, null];
3131cb0ef41Sopenharmony_ci  else
3141cb0ef41Sopenharmony_ci    arr = [options, cb];
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  arr[normalizedArgsSymbol] = true;
3171cb0ef41Sopenharmony_ci  return arr;
3181cb0ef41Sopenharmony_ci}
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci// Called when creating new Socket, or when re-using a closed Socket
3221cb0ef41Sopenharmony_cifunction initSocketHandle(self) {
3231cb0ef41Sopenharmony_ci  self._undestroy();
3241cb0ef41Sopenharmony_ci  self._sockname = null;
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci  // Handle creation may be deferred to bind() or connect() time.
3271cb0ef41Sopenharmony_ci  if (self._handle) {
3281cb0ef41Sopenharmony_ci    self._handle[owner_symbol] = self;
3291cb0ef41Sopenharmony_ci    self._handle.onread = onStreamRead;
3301cb0ef41Sopenharmony_ci    self[async_id_symbol] = getNewAsyncId(self._handle);
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci    let userBuf = self[kBuffer];
3331cb0ef41Sopenharmony_ci    if (userBuf) {
3341cb0ef41Sopenharmony_ci      const bufGen = self[kBufferGen];
3351cb0ef41Sopenharmony_ci      if (bufGen !== null) {
3361cb0ef41Sopenharmony_ci        userBuf = bufGen();
3371cb0ef41Sopenharmony_ci        if (!isUint8Array(userBuf))
3381cb0ef41Sopenharmony_ci          return;
3391cb0ef41Sopenharmony_ci        self[kBuffer] = userBuf;
3401cb0ef41Sopenharmony_ci      }
3411cb0ef41Sopenharmony_ci      self._handle.useUserBuffer(userBuf);
3421cb0ef41Sopenharmony_ci    }
3431cb0ef41Sopenharmony_ci  }
3441cb0ef41Sopenharmony_ci}
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_cifunction closeSocketHandle(self, isException, isCleanupPending = false) {
3471cb0ef41Sopenharmony_ci  if (self._handle) {
3481cb0ef41Sopenharmony_ci    self._handle.close(() => {
3491cb0ef41Sopenharmony_ci      debug('emit close');
3501cb0ef41Sopenharmony_ci      self.emit('close', isException);
3511cb0ef41Sopenharmony_ci      if (isCleanupPending) {
3521cb0ef41Sopenharmony_ci        self._handle.onread = noop;
3531cb0ef41Sopenharmony_ci        self._handle = null;
3541cb0ef41Sopenharmony_ci        self._sockname = null;
3551cb0ef41Sopenharmony_ci      }
3561cb0ef41Sopenharmony_ci    });
3571cb0ef41Sopenharmony_ci  }
3581cb0ef41Sopenharmony_ci}
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ciconst kBytesRead = Symbol('kBytesRead');
3611cb0ef41Sopenharmony_ciconst kBytesWritten = Symbol('kBytesWritten');
3621cb0ef41Sopenharmony_ciconst kSetNoDelay = Symbol('kSetNoDelay');
3631cb0ef41Sopenharmony_ciconst kSetKeepAlive = Symbol('kSetKeepAlive');
3641cb0ef41Sopenharmony_ciconst kSetKeepAliveInitialDelay = Symbol('kSetKeepAliveInitialDelay');
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_cifunction Socket(options) {
3671cb0ef41Sopenharmony_ci  if (!(this instanceof Socket)) return new Socket(options);
3681cb0ef41Sopenharmony_ci  if (options?.objectMode) {
3691cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_VALUE(
3701cb0ef41Sopenharmony_ci      'options.objectMode',
3711cb0ef41Sopenharmony_ci      options.objectMode,
3721cb0ef41Sopenharmony_ci      'is not supported',
3731cb0ef41Sopenharmony_ci    );
3741cb0ef41Sopenharmony_ci  } else if (options?.readableObjectMode || options?.writableObjectMode) {
3751cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_VALUE(
3761cb0ef41Sopenharmony_ci      `options.${
3771cb0ef41Sopenharmony_ci        options.readableObjectMode ? 'readableObjectMode' : 'writableObjectMode'
3781cb0ef41Sopenharmony_ci      }`,
3791cb0ef41Sopenharmony_ci      options.readableObjectMode || options.writableObjectMode,
3801cb0ef41Sopenharmony_ci      'is not supported',
3811cb0ef41Sopenharmony_ci    );
3821cb0ef41Sopenharmony_ci  }
3831cb0ef41Sopenharmony_ci  if (typeof options?.keepAliveInitialDelay !== 'undefined') {
3841cb0ef41Sopenharmony_ci    validateNumber(
3851cb0ef41Sopenharmony_ci      options?.keepAliveInitialDelay, 'options.keepAliveInitialDelay',
3861cb0ef41Sopenharmony_ci    );
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci    if (options.keepAliveInitialDelay < 0) {
3891cb0ef41Sopenharmony_ci      options.keepAliveInitialDelay = 0;
3901cb0ef41Sopenharmony_ci    }
3911cb0ef41Sopenharmony_ci  }
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci  this.connecting = false;
3941cb0ef41Sopenharmony_ci  // Problem with this is that users can supply their own handle, that may not
3951cb0ef41Sopenharmony_ci  // have _handle.getAsyncId(). In this case an[async_id_symbol] should
3961cb0ef41Sopenharmony_ci  // probably be supplied by async_hooks.
3971cb0ef41Sopenharmony_ci  this[async_id_symbol] = -1;
3981cb0ef41Sopenharmony_ci  this._hadError = false;
3991cb0ef41Sopenharmony_ci  this[kHandle] = null;
4001cb0ef41Sopenharmony_ci  this._parent = null;
4011cb0ef41Sopenharmony_ci  this._host = null;
4021cb0ef41Sopenharmony_ci  this[kLastWriteQueueSize] = 0;
4031cb0ef41Sopenharmony_ci  this[kTimeout] = null;
4041cb0ef41Sopenharmony_ci  this[kBuffer] = null;
4051cb0ef41Sopenharmony_ci  this[kBufferCb] = null;
4061cb0ef41Sopenharmony_ci  this[kBufferGen] = null;
4071cb0ef41Sopenharmony_ci  this._closeAfterHandlingError = false;
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  if (typeof options === 'number')
4101cb0ef41Sopenharmony_ci    options = { fd: options }; // Legacy interface.
4111cb0ef41Sopenharmony_ci  else
4121cb0ef41Sopenharmony_ci    options = { ...options };
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci  // Default to *not* allowing half open sockets.
4151cb0ef41Sopenharmony_ci  options.allowHalfOpen = Boolean(options.allowHalfOpen);
4161cb0ef41Sopenharmony_ci  // For backwards compat do not emit close on destroy.
4171cb0ef41Sopenharmony_ci  options.emitClose = false;
4181cb0ef41Sopenharmony_ci  options.autoDestroy = true;
4191cb0ef41Sopenharmony_ci  // Handle strings directly.
4201cb0ef41Sopenharmony_ci  options.decodeStrings = false;
4211cb0ef41Sopenharmony_ci  stream.Duplex.call(this, options);
4221cb0ef41Sopenharmony_ci
4231cb0ef41Sopenharmony_ci  if (options.handle) {
4241cb0ef41Sopenharmony_ci    this._handle = options.handle; // private
4251cb0ef41Sopenharmony_ci    this[async_id_symbol] = getNewAsyncId(this._handle);
4261cb0ef41Sopenharmony_ci  } else if (options.fd !== undefined) {
4271cb0ef41Sopenharmony_ci    const { fd } = options;
4281cb0ef41Sopenharmony_ci    let err;
4291cb0ef41Sopenharmony_ci
4301cb0ef41Sopenharmony_ci    // createHandle will throw ERR_INVALID_FD_TYPE if `fd` is not
4311cb0ef41Sopenharmony_ci    // a valid `PIPE` or `TCP` descriptor
4321cb0ef41Sopenharmony_ci    this._handle = createHandle(fd, false);
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci    err = this._handle.open(fd);
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci    // While difficult to fabricate, in some architectures
4371cb0ef41Sopenharmony_ci    // `open` may return an error code for valid file descriptors
4381cb0ef41Sopenharmony_ci    // which cannot be opened. This is difficult to test as most
4391cb0ef41Sopenharmony_ci    // un-openable fds will throw on `createHandle`
4401cb0ef41Sopenharmony_ci    if (err)
4411cb0ef41Sopenharmony_ci      throw errnoException(err, 'open');
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci    this[async_id_symbol] = this._handle.getAsyncId();
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ci    if ((fd === 1 || fd === 2) &&
4461cb0ef41Sopenharmony_ci        (this._handle instanceof Pipe) && isWindows) {
4471cb0ef41Sopenharmony_ci      // Make stdout and stderr blocking on Windows
4481cb0ef41Sopenharmony_ci      err = this._handle.setBlocking(true);
4491cb0ef41Sopenharmony_ci      if (err)
4501cb0ef41Sopenharmony_ci        throw errnoException(err, 'setBlocking');
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci      this._writev = null;
4531cb0ef41Sopenharmony_ci      this._write = makeSyncWrite(fd);
4541cb0ef41Sopenharmony_ci      // makeSyncWrite adjusts this value like the original handle would, so
4551cb0ef41Sopenharmony_ci      // we need to let it do that by turning it into a writable, own
4561cb0ef41Sopenharmony_ci      // property.
4571cb0ef41Sopenharmony_ci      ObjectDefineProperty(this._handle, 'bytesWritten', {
4581cb0ef41Sopenharmony_ci        __proto__: null,
4591cb0ef41Sopenharmony_ci        value: 0, writable: true,
4601cb0ef41Sopenharmony_ci      });
4611cb0ef41Sopenharmony_ci    }
4621cb0ef41Sopenharmony_ci  }
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci  const onread = options.onread;
4651cb0ef41Sopenharmony_ci  if (onread !== null && typeof onread === 'object' &&
4661cb0ef41Sopenharmony_ci      (isUint8Array(onread.buffer) || typeof onread.buffer === 'function') &&
4671cb0ef41Sopenharmony_ci      typeof onread.callback === 'function') {
4681cb0ef41Sopenharmony_ci    if (typeof onread.buffer === 'function') {
4691cb0ef41Sopenharmony_ci      this[kBuffer] = true;
4701cb0ef41Sopenharmony_ci      this[kBufferGen] = onread.buffer;
4711cb0ef41Sopenharmony_ci    } else {
4721cb0ef41Sopenharmony_ci      this[kBuffer] = onread.buffer;
4731cb0ef41Sopenharmony_ci    }
4741cb0ef41Sopenharmony_ci    this[kBufferCb] = onread.callback;
4751cb0ef41Sopenharmony_ci  }
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci  this[kSetNoDelay] = Boolean(options.noDelay);
4781cb0ef41Sopenharmony_ci  this[kSetKeepAlive] = Boolean(options.keepAlive);
4791cb0ef41Sopenharmony_ci  this[kSetKeepAliveInitialDelay] = ~~(options.keepAliveInitialDelay / 1000);
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ci  // Shut down the socket when we're finished with it.
4821cb0ef41Sopenharmony_ci  this.on('end', onReadableStreamEnd);
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci  initSocketHandle(this);
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  this._pendingData = null;
4871cb0ef41Sopenharmony_ci  this._pendingEncoding = '';
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  // If we have a handle, then start the flow of data into the
4901cb0ef41Sopenharmony_ci  // buffer.  if not, then this will happen when we connect
4911cb0ef41Sopenharmony_ci  if (this._handle && options.readable !== false) {
4921cb0ef41Sopenharmony_ci    if (options.pauseOnCreate) {
4931cb0ef41Sopenharmony_ci      // Stop the handle from reading and pause the stream
4941cb0ef41Sopenharmony_ci      this._handle.reading = false;
4951cb0ef41Sopenharmony_ci      this._handle.readStop();
4961cb0ef41Sopenharmony_ci      this.readableFlowing = false;
4971cb0ef41Sopenharmony_ci    } else if (!options.manualStart) {
4981cb0ef41Sopenharmony_ci      this.read(0);
4991cb0ef41Sopenharmony_ci    }
5001cb0ef41Sopenharmony_ci  }
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci  // Reserve properties
5031cb0ef41Sopenharmony_ci  this.server = null;
5041cb0ef41Sopenharmony_ci  this._server = null;
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci  // Used after `.destroy()`
5071cb0ef41Sopenharmony_ci  this[kBytesRead] = 0;
5081cb0ef41Sopenharmony_ci  this[kBytesWritten] = 0;
5091cb0ef41Sopenharmony_ci}
5101cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Socket.prototype, stream.Duplex.prototype);
5111cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Socket, stream.Duplex);
5121cb0ef41Sopenharmony_ci
5131cb0ef41Sopenharmony_ci// Refresh existing timeouts.
5141cb0ef41Sopenharmony_ciSocket.prototype._unrefTimer = function _unrefTimer() {
5151cb0ef41Sopenharmony_ci  for (let s = this; s !== null; s = s._parent) {
5161cb0ef41Sopenharmony_ci    if (s[kTimeout])
5171cb0ef41Sopenharmony_ci      s[kTimeout].refresh();
5181cb0ef41Sopenharmony_ci  }
5191cb0ef41Sopenharmony_ci};
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci// The user has called .end(), and all the bytes have been
5231cb0ef41Sopenharmony_ci// sent out to the other side.
5241cb0ef41Sopenharmony_ciSocket.prototype._final = function(cb) {
5251cb0ef41Sopenharmony_ci  // If still connecting - defer handling `_final` until 'connect' will happen
5261cb0ef41Sopenharmony_ci  if (this.pending) {
5271cb0ef41Sopenharmony_ci    debug('_final: not yet connected');
5281cb0ef41Sopenharmony_ci    return this.once('connect', () => this._final(cb));
5291cb0ef41Sopenharmony_ci  }
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci  if (!this._handle)
5321cb0ef41Sopenharmony_ci    return cb();
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  debug('_final: not ended, call shutdown()');
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ci  const req = new ShutdownWrap();
5371cb0ef41Sopenharmony_ci  req.oncomplete = afterShutdown;
5381cb0ef41Sopenharmony_ci  req.handle = this._handle;
5391cb0ef41Sopenharmony_ci  req.callback = cb;
5401cb0ef41Sopenharmony_ci  const err = this._handle.shutdown(req);
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci  if (err === 1 || err === UV_ENOTCONN)  // synchronous finish
5431cb0ef41Sopenharmony_ci    return cb();
5441cb0ef41Sopenharmony_ci  else if (err !== 0)
5451cb0ef41Sopenharmony_ci    return cb(errnoException(err, 'shutdown'));
5461cb0ef41Sopenharmony_ci};
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_cifunction afterShutdown() {
5491cb0ef41Sopenharmony_ci  const self = this.handle[owner_symbol];
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci  debug('afterShutdown destroyed=%j', self.destroyed);
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  this.callback();
5541cb0ef41Sopenharmony_ci}
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci// Provide a better error message when we call end() as a result
5571cb0ef41Sopenharmony_ci// of the other side sending a FIN.  The standard 'write after end'
5581cb0ef41Sopenharmony_ci// is overly vague, and makes it seem like the user's code is to blame.
5591cb0ef41Sopenharmony_cifunction writeAfterFIN(chunk, encoding, cb) {
5601cb0ef41Sopenharmony_ci  if (!this.writableEnded) {
5611cb0ef41Sopenharmony_ci    return stream.Duplex.prototype.write.call(this, chunk, encoding, cb);
5621cb0ef41Sopenharmony_ci  }
5631cb0ef41Sopenharmony_ci
5641cb0ef41Sopenharmony_ci  if (typeof encoding === 'function') {
5651cb0ef41Sopenharmony_ci    cb = encoding;
5661cb0ef41Sopenharmony_ci    encoding = null;
5671cb0ef41Sopenharmony_ci  }
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci  const er = genericNodeError(
5701cb0ef41Sopenharmony_ci    'This socket has been ended by the other party',
5711cb0ef41Sopenharmony_ci    { code: 'EPIPE' },
5721cb0ef41Sopenharmony_ci  );
5731cb0ef41Sopenharmony_ci  if (typeof cb === 'function') {
5741cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(this[async_id_symbol], process.nextTick, cb, er);
5751cb0ef41Sopenharmony_ci  }
5761cb0ef41Sopenharmony_ci  this.destroy(er);
5771cb0ef41Sopenharmony_ci
5781cb0ef41Sopenharmony_ci  return false;
5791cb0ef41Sopenharmony_ci}
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ciSocket.prototype.setTimeout = setStreamTimeout;
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ciSocket.prototype._onTimeout = function() {
5851cb0ef41Sopenharmony_ci  const handle = this._handle;
5861cb0ef41Sopenharmony_ci  const lastWriteQueueSize = this[kLastWriteQueueSize];
5871cb0ef41Sopenharmony_ci  if (lastWriteQueueSize > 0 && handle) {
5881cb0ef41Sopenharmony_ci    // `lastWriteQueueSize !== writeQueueSize` means there is
5891cb0ef41Sopenharmony_ci    // an active write in progress, so we suppress the timeout.
5901cb0ef41Sopenharmony_ci    const { writeQueueSize } = handle;
5911cb0ef41Sopenharmony_ci    if (lastWriteQueueSize !== writeQueueSize) {
5921cb0ef41Sopenharmony_ci      this[kLastWriteQueueSize] = writeQueueSize;
5931cb0ef41Sopenharmony_ci      this._unrefTimer();
5941cb0ef41Sopenharmony_ci      return;
5951cb0ef41Sopenharmony_ci    }
5961cb0ef41Sopenharmony_ci  }
5971cb0ef41Sopenharmony_ci  debug('_onTimeout');
5981cb0ef41Sopenharmony_ci  this.emit('timeout');
5991cb0ef41Sopenharmony_ci};
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ciSocket.prototype.setNoDelay = function(enable) {
6031cb0ef41Sopenharmony_ci  // Backwards compatibility: assume true when `enable` is omitted
6041cb0ef41Sopenharmony_ci  enable = Boolean(enable === undefined ? true : enable);
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  if (!this._handle) {
6071cb0ef41Sopenharmony_ci    this[kSetNoDelay] = enable;
6081cb0ef41Sopenharmony_ci    return this;
6091cb0ef41Sopenharmony_ci  }
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci  if (this._handle.setNoDelay && enable !== this[kSetNoDelay]) {
6121cb0ef41Sopenharmony_ci    this[kSetNoDelay] = enable;
6131cb0ef41Sopenharmony_ci    this._handle.setNoDelay(enable);
6141cb0ef41Sopenharmony_ci  }
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  return this;
6171cb0ef41Sopenharmony_ci};
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ciSocket.prototype.setKeepAlive = function(enable, initialDelayMsecs) {
6211cb0ef41Sopenharmony_ci  enable = Boolean(enable);
6221cb0ef41Sopenharmony_ci  const initialDelay = ~~(initialDelayMsecs / 1000);
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci  if (!this._handle) {
6251cb0ef41Sopenharmony_ci    this[kSetKeepAlive] = enable;
6261cb0ef41Sopenharmony_ci    this[kSetKeepAliveInitialDelay] = initialDelay;
6271cb0ef41Sopenharmony_ci    return this;
6281cb0ef41Sopenharmony_ci  }
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  if (!this._handle.setKeepAlive) {
6311cb0ef41Sopenharmony_ci    return this;
6321cb0ef41Sopenharmony_ci  }
6331cb0ef41Sopenharmony_ci
6341cb0ef41Sopenharmony_ci  if (enable !== this[kSetKeepAlive] ||
6351cb0ef41Sopenharmony_ci      (
6361cb0ef41Sopenharmony_ci        enable &&
6371cb0ef41Sopenharmony_ci        this[kSetKeepAliveInitialDelay] !== initialDelay
6381cb0ef41Sopenharmony_ci      )
6391cb0ef41Sopenharmony_ci  ) {
6401cb0ef41Sopenharmony_ci    this[kSetKeepAlive] = enable;
6411cb0ef41Sopenharmony_ci    this[kSetKeepAliveInitialDelay] = initialDelay;
6421cb0ef41Sopenharmony_ci    this._handle.setKeepAlive(enable, initialDelay);
6431cb0ef41Sopenharmony_ci  }
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ci  return this;
6461cb0ef41Sopenharmony_ci};
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ciSocket.prototype.address = function() {
6501cb0ef41Sopenharmony_ci  return this._getsockname();
6511cb0ef41Sopenharmony_ci};
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, '_connecting', {
6551cb0ef41Sopenharmony_ci  __proto__: null,
6561cb0ef41Sopenharmony_ci  get: function() {
6571cb0ef41Sopenharmony_ci    return this.connecting;
6581cb0ef41Sopenharmony_ci  },
6591cb0ef41Sopenharmony_ci});
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, 'pending', {
6621cb0ef41Sopenharmony_ci  __proto__: null,
6631cb0ef41Sopenharmony_ci  get() {
6641cb0ef41Sopenharmony_ci    return !this._handle || this.connecting;
6651cb0ef41Sopenharmony_ci  },
6661cb0ef41Sopenharmony_ci  configurable: true,
6671cb0ef41Sopenharmony_ci});
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci
6701cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, 'readyState', {
6711cb0ef41Sopenharmony_ci  __proto__: null,
6721cb0ef41Sopenharmony_ci  get: function() {
6731cb0ef41Sopenharmony_ci    if (this.connecting) {
6741cb0ef41Sopenharmony_ci      return 'opening';
6751cb0ef41Sopenharmony_ci    } else if (this.readable && this.writable) {
6761cb0ef41Sopenharmony_ci      return 'open';
6771cb0ef41Sopenharmony_ci    } else if (this.readable && !this.writable) {
6781cb0ef41Sopenharmony_ci      return 'readOnly';
6791cb0ef41Sopenharmony_ci    } else if (!this.readable && this.writable) {
6801cb0ef41Sopenharmony_ci      return 'writeOnly';
6811cb0ef41Sopenharmony_ci    }
6821cb0ef41Sopenharmony_ci    return 'closed';
6831cb0ef41Sopenharmony_ci  },
6841cb0ef41Sopenharmony_ci});
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, 'bufferSize', {
6881cb0ef41Sopenharmony_ci  __proto__: null,
6891cb0ef41Sopenharmony_ci  get: function() {
6901cb0ef41Sopenharmony_ci    if (this._handle) {
6911cb0ef41Sopenharmony_ci      return this.writableLength;
6921cb0ef41Sopenharmony_ci    }
6931cb0ef41Sopenharmony_ci  },
6941cb0ef41Sopenharmony_ci});
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, kUpdateTimer, {
6971cb0ef41Sopenharmony_ci  __proto__: null,
6981cb0ef41Sopenharmony_ci  get: function() {
6991cb0ef41Sopenharmony_ci    return this._unrefTimer;
7001cb0ef41Sopenharmony_ci  },
7011cb0ef41Sopenharmony_ci});
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_cifunction tryReadStart(socket) {
7051cb0ef41Sopenharmony_ci  // Not already reading, start the flow
7061cb0ef41Sopenharmony_ci  debug('Socket._handle.readStart');
7071cb0ef41Sopenharmony_ci  socket._handle.reading = true;
7081cb0ef41Sopenharmony_ci  const err = socket._handle.readStart();
7091cb0ef41Sopenharmony_ci  if (err)
7101cb0ef41Sopenharmony_ci    socket.destroy(errnoException(err, 'read'));
7111cb0ef41Sopenharmony_ci}
7121cb0ef41Sopenharmony_ci
7131cb0ef41Sopenharmony_ci// Just call handle.readStart until we have enough in the buffer
7141cb0ef41Sopenharmony_ciSocket.prototype._read = function(n) {
7151cb0ef41Sopenharmony_ci  debug(
7161cb0ef41Sopenharmony_ci    '_read - n', n,
7171cb0ef41Sopenharmony_ci    'isConnecting?', !!this.connecting,
7181cb0ef41Sopenharmony_ci    'hasHandle?', !!this._handle,
7191cb0ef41Sopenharmony_ci  );
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci  if (this.connecting || !this._handle) {
7221cb0ef41Sopenharmony_ci    debug('_read wait for connection');
7231cb0ef41Sopenharmony_ci    this.once('connect', () => this._read(n));
7241cb0ef41Sopenharmony_ci  } else if (!this._handle.reading) {
7251cb0ef41Sopenharmony_ci    tryReadStart(this);
7261cb0ef41Sopenharmony_ci  }
7271cb0ef41Sopenharmony_ci};
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ciSocket.prototype.end = function(data, encoding, callback) {
7311cb0ef41Sopenharmony_ci  stream.Duplex.prototype.end.call(this,
7321cb0ef41Sopenharmony_ci                                   data, encoding, callback);
7331cb0ef41Sopenharmony_ci  DTRACE_NET_STREAM_END(this);
7341cb0ef41Sopenharmony_ci  return this;
7351cb0ef41Sopenharmony_ci};
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ciSocket.prototype.resetAndDestroy = function() {
7381cb0ef41Sopenharmony_ci  if (this._handle) {
7391cb0ef41Sopenharmony_ci    if (!(this._handle instanceof TCP))
7401cb0ef41Sopenharmony_ci      throw new ERR_INVALID_HANDLE_TYPE();
7411cb0ef41Sopenharmony_ci    if (this.connecting) {
7421cb0ef41Sopenharmony_ci      debug('reset wait for connection');
7431cb0ef41Sopenharmony_ci      this.once('connect', () => this._reset());
7441cb0ef41Sopenharmony_ci    } else {
7451cb0ef41Sopenharmony_ci      this._reset();
7461cb0ef41Sopenharmony_ci    }
7471cb0ef41Sopenharmony_ci  } else {
7481cb0ef41Sopenharmony_ci    this.destroy(new ERR_SOCKET_CLOSED());
7491cb0ef41Sopenharmony_ci  }
7501cb0ef41Sopenharmony_ci  return this;
7511cb0ef41Sopenharmony_ci};
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ciSocket.prototype.pause = function() {
7541cb0ef41Sopenharmony_ci  if (this[kBuffer] && !this.connecting && this._handle &&
7551cb0ef41Sopenharmony_ci      this._handle.reading) {
7561cb0ef41Sopenharmony_ci    this._handle.reading = false;
7571cb0ef41Sopenharmony_ci    if (!this.destroyed) {
7581cb0ef41Sopenharmony_ci      const err = this._handle.readStop();
7591cb0ef41Sopenharmony_ci      if (err)
7601cb0ef41Sopenharmony_ci        this.destroy(errnoException(err, 'read'));
7611cb0ef41Sopenharmony_ci    }
7621cb0ef41Sopenharmony_ci  }
7631cb0ef41Sopenharmony_ci  return stream.Duplex.prototype.pause.call(this);
7641cb0ef41Sopenharmony_ci};
7651cb0ef41Sopenharmony_ci
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_ciSocket.prototype.resume = function() {
7681cb0ef41Sopenharmony_ci  if (this[kBuffer] && !this.connecting && this._handle &&
7691cb0ef41Sopenharmony_ci      !this._handle.reading) {
7701cb0ef41Sopenharmony_ci    tryReadStart(this);
7711cb0ef41Sopenharmony_ci  }
7721cb0ef41Sopenharmony_ci  return stream.Duplex.prototype.resume.call(this);
7731cb0ef41Sopenharmony_ci};
7741cb0ef41Sopenharmony_ci
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_ciSocket.prototype.read = function(n) {
7771cb0ef41Sopenharmony_ci  if (this[kBuffer] && !this.connecting && this._handle &&
7781cb0ef41Sopenharmony_ci      !this._handle.reading) {
7791cb0ef41Sopenharmony_ci    tryReadStart(this);
7801cb0ef41Sopenharmony_ci  }
7811cb0ef41Sopenharmony_ci  return stream.Duplex.prototype.read.call(this, n);
7821cb0ef41Sopenharmony_ci};
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci// Called when the 'end' event is emitted.
7861cb0ef41Sopenharmony_cifunction onReadableStreamEnd() {
7871cb0ef41Sopenharmony_ci  if (!this.allowHalfOpen) {
7881cb0ef41Sopenharmony_ci    this.write = writeAfterFIN;
7891cb0ef41Sopenharmony_ci  }
7901cb0ef41Sopenharmony_ci}
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ciSocket.prototype.destroySoon = function() {
7941cb0ef41Sopenharmony_ci  if (this.writable)
7951cb0ef41Sopenharmony_ci    this.end();
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci  if (this.writableFinished)
7981cb0ef41Sopenharmony_ci    this.destroy();
7991cb0ef41Sopenharmony_ci  else
8001cb0ef41Sopenharmony_ci    this.once('finish', this.destroy);
8011cb0ef41Sopenharmony_ci};
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ciSocket.prototype._destroy = function(exception, cb) {
8051cb0ef41Sopenharmony_ci  debug('destroy');
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci  this.connecting = false;
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci  for (let s = this; s !== null; s = s._parent) {
8101cb0ef41Sopenharmony_ci    clearTimeout(s[kTimeout]);
8111cb0ef41Sopenharmony_ci  }
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci  debug('close');
8141cb0ef41Sopenharmony_ci  if (this._handle) {
8151cb0ef41Sopenharmony_ci    if (this !== process.stderr)
8161cb0ef41Sopenharmony_ci      debug('close handle');
8171cb0ef41Sopenharmony_ci    const isException = exception ? true : false;
8181cb0ef41Sopenharmony_ci    // `bytesRead` and `kBytesWritten` should be accessible after `.destroy()`
8191cb0ef41Sopenharmony_ci    this[kBytesRead] = this._handle.bytesRead;
8201cb0ef41Sopenharmony_ci    this[kBytesWritten] = this._handle.bytesWritten;
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci    if (this.resetAndClosing) {
8231cb0ef41Sopenharmony_ci      this.resetAndClosing = false;
8241cb0ef41Sopenharmony_ci      const err = this._handle.reset(() => {
8251cb0ef41Sopenharmony_ci        debug('emit close');
8261cb0ef41Sopenharmony_ci        this.emit('close', isException);
8271cb0ef41Sopenharmony_ci      });
8281cb0ef41Sopenharmony_ci      if (err)
8291cb0ef41Sopenharmony_ci        this.emit('error', errnoException(err, 'reset'));
8301cb0ef41Sopenharmony_ci    } else if (this._closeAfterHandlingError) {
8311cb0ef41Sopenharmony_ci      // Enqueue closing the socket as a microtask, so that the socket can be
8321cb0ef41Sopenharmony_ci      // accessible when an `error` event is handled in the `next tick queue`.
8331cb0ef41Sopenharmony_ci      queueMicrotask(() => closeSocketHandle(this, isException, true));
8341cb0ef41Sopenharmony_ci    } else {
8351cb0ef41Sopenharmony_ci      closeSocketHandle(this, isException);
8361cb0ef41Sopenharmony_ci    }
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci    if (!this._closeAfterHandlingError) {
8391cb0ef41Sopenharmony_ci      this._handle.onread = noop;
8401cb0ef41Sopenharmony_ci      this._handle = null;
8411cb0ef41Sopenharmony_ci      this._sockname = null;
8421cb0ef41Sopenharmony_ci    }
8431cb0ef41Sopenharmony_ci    cb(exception);
8441cb0ef41Sopenharmony_ci  } else {
8451cb0ef41Sopenharmony_ci    cb(exception);
8461cb0ef41Sopenharmony_ci    process.nextTick(emitCloseNT, this);
8471cb0ef41Sopenharmony_ci  }
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci  if (this._server) {
8501cb0ef41Sopenharmony_ci    debug('has server');
8511cb0ef41Sopenharmony_ci    this._server._connections--;
8521cb0ef41Sopenharmony_ci    if (this._server._emitCloseIfDrained) {
8531cb0ef41Sopenharmony_ci      this._server._emitCloseIfDrained();
8541cb0ef41Sopenharmony_ci    }
8551cb0ef41Sopenharmony_ci  }
8561cb0ef41Sopenharmony_ci};
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ciSocket.prototype._reset = function() {
8591cb0ef41Sopenharmony_ci  debug('reset connection');
8601cb0ef41Sopenharmony_ci  this.resetAndClosing = true;
8611cb0ef41Sopenharmony_ci  return this.destroy();
8621cb0ef41Sopenharmony_ci};
8631cb0ef41Sopenharmony_ci
8641cb0ef41Sopenharmony_ciSocket.prototype._getpeername = function() {
8651cb0ef41Sopenharmony_ci  if (!this._handle || !this._handle.getpeername || this.connecting) {
8661cb0ef41Sopenharmony_ci    return this._peername || {};
8671cb0ef41Sopenharmony_ci  } else if (!this._peername) {
8681cb0ef41Sopenharmony_ci    const out = {};
8691cb0ef41Sopenharmony_ci    const err = this._handle.getpeername(out);
8701cb0ef41Sopenharmony_ci    if (err) return out;
8711cb0ef41Sopenharmony_ci    this._peername = out;
8721cb0ef41Sopenharmony_ci  }
8731cb0ef41Sopenharmony_ci  return this._peername;
8741cb0ef41Sopenharmony_ci};
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_cifunction protoGetter(name, callback) {
8771cb0ef41Sopenharmony_ci  ObjectDefineProperty(Socket.prototype, name, {
8781cb0ef41Sopenharmony_ci    __proto__: null,
8791cb0ef41Sopenharmony_ci    configurable: false,
8801cb0ef41Sopenharmony_ci    enumerable: true,
8811cb0ef41Sopenharmony_ci    get: callback,
8821cb0ef41Sopenharmony_ci  });
8831cb0ef41Sopenharmony_ci}
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ciprotoGetter('bytesRead', function bytesRead() {
8861cb0ef41Sopenharmony_ci  return this._handle ? this._handle.bytesRead : this[kBytesRead];
8871cb0ef41Sopenharmony_ci});
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ciprotoGetter('remoteAddress', function remoteAddress() {
8901cb0ef41Sopenharmony_ci  return this._getpeername().address;
8911cb0ef41Sopenharmony_ci});
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ciprotoGetter('remoteFamily', function remoteFamily() {
8941cb0ef41Sopenharmony_ci  return this._getpeername().family;
8951cb0ef41Sopenharmony_ci});
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ciprotoGetter('remotePort', function remotePort() {
8981cb0ef41Sopenharmony_ci  return this._getpeername().port;
8991cb0ef41Sopenharmony_ci});
9001cb0ef41Sopenharmony_ci
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_ciSocket.prototype._getsockname = function() {
9031cb0ef41Sopenharmony_ci  if (!this._handle || !this._handle.getsockname) {
9041cb0ef41Sopenharmony_ci    return {};
9051cb0ef41Sopenharmony_ci  } else if (!this._sockname) {
9061cb0ef41Sopenharmony_ci    this._sockname = {};
9071cb0ef41Sopenharmony_ci    // FIXME(bnoordhuis) Throw when the return value is not 0?
9081cb0ef41Sopenharmony_ci    this._handle.getsockname(this._sockname);
9091cb0ef41Sopenharmony_ci  }
9101cb0ef41Sopenharmony_ci  return this._sockname;
9111cb0ef41Sopenharmony_ci};
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ciprotoGetter('localAddress', function localAddress() {
9151cb0ef41Sopenharmony_ci  return this._getsockname().address;
9161cb0ef41Sopenharmony_ci});
9171cb0ef41Sopenharmony_ci
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ciprotoGetter('localPort', function localPort() {
9201cb0ef41Sopenharmony_ci  return this._getsockname().port;
9211cb0ef41Sopenharmony_ci});
9221cb0ef41Sopenharmony_ci
9231cb0ef41Sopenharmony_ciprotoGetter('localFamily', function localFamily() {
9241cb0ef41Sopenharmony_ci  return this._getsockname().family;
9251cb0ef41Sopenharmony_ci});
9261cb0ef41Sopenharmony_ci
9271cb0ef41Sopenharmony_ciSocket.prototype[kAfterAsyncWrite] = function() {
9281cb0ef41Sopenharmony_ci  this[kLastWriteQueueSize] = 0;
9291cb0ef41Sopenharmony_ci};
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_ciSocket.prototype._writeGeneric = function(writev, data, encoding, cb) {
9321cb0ef41Sopenharmony_ci  // If we are still connecting, then buffer this for later.
9331cb0ef41Sopenharmony_ci  // The Writable logic will buffer up any more writes while
9341cb0ef41Sopenharmony_ci  // waiting for this one to be done.
9351cb0ef41Sopenharmony_ci  if (this.connecting) {
9361cb0ef41Sopenharmony_ci    this._pendingData = data;
9371cb0ef41Sopenharmony_ci    this._pendingEncoding = encoding;
9381cb0ef41Sopenharmony_ci    this.once('connect', function connect() {
9391cb0ef41Sopenharmony_ci      this.off('close', onClose);
9401cb0ef41Sopenharmony_ci      this._writeGeneric(writev, data, encoding, cb);
9411cb0ef41Sopenharmony_ci    });
9421cb0ef41Sopenharmony_ci    function onClose() {
9431cb0ef41Sopenharmony_ci      cb(new ERR_SOCKET_CLOSED_BEFORE_CONNECTION());
9441cb0ef41Sopenharmony_ci    }
9451cb0ef41Sopenharmony_ci    this.once('close', onClose);
9461cb0ef41Sopenharmony_ci    return;
9471cb0ef41Sopenharmony_ci  }
9481cb0ef41Sopenharmony_ci  this._pendingData = null;
9491cb0ef41Sopenharmony_ci  this._pendingEncoding = '';
9501cb0ef41Sopenharmony_ci
9511cb0ef41Sopenharmony_ci  if (!this._handle) {
9521cb0ef41Sopenharmony_ci    cb(new ERR_SOCKET_CLOSED());
9531cb0ef41Sopenharmony_ci    return false;
9541cb0ef41Sopenharmony_ci  }
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci  this._unrefTimer();
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci  let req;
9591cb0ef41Sopenharmony_ci  if (writev)
9601cb0ef41Sopenharmony_ci    req = writevGeneric(this, data, cb);
9611cb0ef41Sopenharmony_ci  else
9621cb0ef41Sopenharmony_ci    req = writeGeneric(this, data, encoding, cb);
9631cb0ef41Sopenharmony_ci  if (req.async)
9641cb0ef41Sopenharmony_ci    this[kLastWriteQueueSize] = req.bytes;
9651cb0ef41Sopenharmony_ci};
9661cb0ef41Sopenharmony_ci
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_ciSocket.prototype._writev = function(chunks, cb) {
9691cb0ef41Sopenharmony_ci  this._writeGeneric(true, chunks, '', cb);
9701cb0ef41Sopenharmony_ci};
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ciSocket.prototype._write = function(data, encoding, cb) {
9741cb0ef41Sopenharmony_ci  this._writeGeneric(false, data, encoding, cb);
9751cb0ef41Sopenharmony_ci};
9761cb0ef41Sopenharmony_ci
9771cb0ef41Sopenharmony_ci
9781cb0ef41Sopenharmony_ci// Legacy alias. Having this is probably being overly cautious, but it doesn't
9791cb0ef41Sopenharmony_ci// really hurt anyone either. This can probably be removed safely if desired.
9801cb0ef41Sopenharmony_ciprotoGetter('_bytesDispatched', function _bytesDispatched() {
9811cb0ef41Sopenharmony_ci  return this._handle ? this._handle.bytesWritten : this[kBytesWritten];
9821cb0ef41Sopenharmony_ci});
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ciprotoGetter('bytesWritten', function bytesWritten() {
9851cb0ef41Sopenharmony_ci  let bytes = this._bytesDispatched;
9861cb0ef41Sopenharmony_ci  const data = this._pendingData;
9871cb0ef41Sopenharmony_ci  const encoding = this._pendingEncoding;
9881cb0ef41Sopenharmony_ci  const writableBuffer = this.writableBuffer;
9891cb0ef41Sopenharmony_ci
9901cb0ef41Sopenharmony_ci  if (!writableBuffer)
9911cb0ef41Sopenharmony_ci    return undefined;
9921cb0ef41Sopenharmony_ci
9931cb0ef41Sopenharmony_ci  for (const el of writableBuffer) {
9941cb0ef41Sopenharmony_ci    bytes += el.chunk instanceof Buffer ?
9951cb0ef41Sopenharmony_ci      el.chunk.length :
9961cb0ef41Sopenharmony_ci      Buffer.byteLength(el.chunk, el.encoding);
9971cb0ef41Sopenharmony_ci  }
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ci  if (ArrayIsArray(data)) {
10001cb0ef41Sopenharmony_ci    // Was a writev, iterate over chunks to get total length
10011cb0ef41Sopenharmony_ci    for (let i = 0; i < data.length; i++) {
10021cb0ef41Sopenharmony_ci      const chunk = data[i];
10031cb0ef41Sopenharmony_ci
10041cb0ef41Sopenharmony_ci      if (data.allBuffers || chunk instanceof Buffer)
10051cb0ef41Sopenharmony_ci        bytes += chunk.length;
10061cb0ef41Sopenharmony_ci      else
10071cb0ef41Sopenharmony_ci        bytes += Buffer.byteLength(chunk.chunk, chunk.encoding);
10081cb0ef41Sopenharmony_ci    }
10091cb0ef41Sopenharmony_ci  } else if (data) {
10101cb0ef41Sopenharmony_ci    // Writes are either a string or a Buffer.
10111cb0ef41Sopenharmony_ci    if (typeof data !== 'string')
10121cb0ef41Sopenharmony_ci      bytes += data.length;
10131cb0ef41Sopenharmony_ci    else
10141cb0ef41Sopenharmony_ci      bytes += Buffer.byteLength(data, encoding);
10151cb0ef41Sopenharmony_ci  }
10161cb0ef41Sopenharmony_ci
10171cb0ef41Sopenharmony_ci  return bytes;
10181cb0ef41Sopenharmony_ci});
10191cb0ef41Sopenharmony_ci
10201cb0ef41Sopenharmony_ci
10211cb0ef41Sopenharmony_cifunction checkBindError(err, port, handle) {
10221cb0ef41Sopenharmony_ci  // EADDRINUSE may not be reported until we call listen() or connect().
10231cb0ef41Sopenharmony_ci  // To complicate matters, a failed bind() followed by listen() or connect()
10241cb0ef41Sopenharmony_ci  // will implicitly bind to a random port. Ergo, check that the socket is
10251cb0ef41Sopenharmony_ci  // bound to the expected port before calling listen() or connect().
10261cb0ef41Sopenharmony_ci  //
10271cb0ef41Sopenharmony_ci  // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
10281cb0ef41Sopenharmony_ci  // getsockname() method. Non-issue for now, the cluster module doesn't
10291cb0ef41Sopenharmony_ci  // really support pipes anyway.
10301cb0ef41Sopenharmony_ci  if (err === 0 && port > 0 && handle.getsockname) {
10311cb0ef41Sopenharmony_ci    const out = {};
10321cb0ef41Sopenharmony_ci    err = handle.getsockname(out);
10331cb0ef41Sopenharmony_ci    if (err === 0 && port !== out.port) {
10341cb0ef41Sopenharmony_ci      debug(`checkBindError, bound to ${out.port} instead of ${port}`);
10351cb0ef41Sopenharmony_ci      err = UV_EADDRINUSE;
10361cb0ef41Sopenharmony_ci    }
10371cb0ef41Sopenharmony_ci  }
10381cb0ef41Sopenharmony_ci  return err;
10391cb0ef41Sopenharmony_ci}
10401cb0ef41Sopenharmony_ci
10411cb0ef41Sopenharmony_ci
10421cb0ef41Sopenharmony_cifunction internalConnect(
10431cb0ef41Sopenharmony_ci  self, address, port, addressType, localAddress, localPort, flags) {
10441cb0ef41Sopenharmony_ci  // TODO return promise from Socket.prototype.connect which
10451cb0ef41Sopenharmony_ci  // wraps _connectReq.
10461cb0ef41Sopenharmony_ci
10471cb0ef41Sopenharmony_ci  assert(self.connecting);
10481cb0ef41Sopenharmony_ci
10491cb0ef41Sopenharmony_ci  let err;
10501cb0ef41Sopenharmony_ci
10511cb0ef41Sopenharmony_ci  if (localAddress || localPort) {
10521cb0ef41Sopenharmony_ci    if (addressType === 4) {
10531cb0ef41Sopenharmony_ci      localAddress = localAddress || DEFAULT_IPV4_ADDR;
10541cb0ef41Sopenharmony_ci      err = self._handle.bind(localAddress, localPort);
10551cb0ef41Sopenharmony_ci    } else { // addressType === 6
10561cb0ef41Sopenharmony_ci      localAddress = localAddress || DEFAULT_IPV6_ADDR;
10571cb0ef41Sopenharmony_ci      err = self._handle.bind6(localAddress, localPort, flags);
10581cb0ef41Sopenharmony_ci    }
10591cb0ef41Sopenharmony_ci    debug('connect: binding to localAddress: %s and localPort: %d (addressType: %d)',
10601cb0ef41Sopenharmony_ci          localAddress, localPort, addressType);
10611cb0ef41Sopenharmony_ci
10621cb0ef41Sopenharmony_ci    err = checkBindError(err, localPort, self._handle);
10631cb0ef41Sopenharmony_ci    if (err) {
10641cb0ef41Sopenharmony_ci      const ex = exceptionWithHostPort(err, 'bind', localAddress, localPort);
10651cb0ef41Sopenharmony_ci      self.destroy(ex);
10661cb0ef41Sopenharmony_ci      return;
10671cb0ef41Sopenharmony_ci    }
10681cb0ef41Sopenharmony_ci  }
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ci  debug('connect: attempting to connect to %s:%d (addressType: %d)', address, port, addressType);
10711cb0ef41Sopenharmony_ci
10721cb0ef41Sopenharmony_ci  if (addressType === 6 || addressType === 4) {
10731cb0ef41Sopenharmony_ci    const req = new TCPConnectWrap();
10741cb0ef41Sopenharmony_ci    req.oncomplete = afterConnect;
10751cb0ef41Sopenharmony_ci    req.address = address;
10761cb0ef41Sopenharmony_ci    req.port = port;
10771cb0ef41Sopenharmony_ci    req.localAddress = localAddress;
10781cb0ef41Sopenharmony_ci    req.localPort = localPort;
10791cb0ef41Sopenharmony_ci
10801cb0ef41Sopenharmony_ci    if (addressType === 4)
10811cb0ef41Sopenharmony_ci      err = self._handle.connect(req, address, port);
10821cb0ef41Sopenharmony_ci    else
10831cb0ef41Sopenharmony_ci      err = self._handle.connect6(req, address, port);
10841cb0ef41Sopenharmony_ci  } else {
10851cb0ef41Sopenharmony_ci    const req = new PipeConnectWrap();
10861cb0ef41Sopenharmony_ci    req.address = address;
10871cb0ef41Sopenharmony_ci    req.oncomplete = afterConnect;
10881cb0ef41Sopenharmony_ci
10891cb0ef41Sopenharmony_ci    err = self._handle.connect(req, address);
10901cb0ef41Sopenharmony_ci  }
10911cb0ef41Sopenharmony_ci
10921cb0ef41Sopenharmony_ci  if (err) {
10931cb0ef41Sopenharmony_ci    const sockname = self._getsockname();
10941cb0ef41Sopenharmony_ci    let details;
10951cb0ef41Sopenharmony_ci
10961cb0ef41Sopenharmony_ci    if (sockname) {
10971cb0ef41Sopenharmony_ci      details = sockname.address + ':' + sockname.port;
10981cb0ef41Sopenharmony_ci    }
10991cb0ef41Sopenharmony_ci
11001cb0ef41Sopenharmony_ci    const ex = exceptionWithHostPort(err, 'connect', address, port, details);
11011cb0ef41Sopenharmony_ci    self.destroy(ex);
11021cb0ef41Sopenharmony_ci  } else if ((addressType === 6 || addressType === 4) && hasObserver('net')) {
11031cb0ef41Sopenharmony_ci    startPerf(self, kPerfHooksNetConnectContext, { type: 'net', name: 'connect', detail: { host: address, port } });
11041cb0ef41Sopenharmony_ci  }
11051cb0ef41Sopenharmony_ci}
11061cb0ef41Sopenharmony_ci
11071cb0ef41Sopenharmony_ci
11081cb0ef41Sopenharmony_cifunction internalConnectMultiple(context, canceled) {
11091cb0ef41Sopenharmony_ci  clearTimeout(context[kTimeout]);
11101cb0ef41Sopenharmony_ci  const self = context.socket;
11111cb0ef41Sopenharmony_ci
11121cb0ef41Sopenharmony_ci  // All connections have been tried without success, destroy with error
11131cb0ef41Sopenharmony_ci  if (canceled || context.current === context.addresses.length) {
11141cb0ef41Sopenharmony_ci    self.destroy(aggregateErrors(context.errors));
11151cb0ef41Sopenharmony_ci    return;
11161cb0ef41Sopenharmony_ci  }
11171cb0ef41Sopenharmony_ci
11181cb0ef41Sopenharmony_ci  assert(self.connecting);
11191cb0ef41Sopenharmony_ci
11201cb0ef41Sopenharmony_ci  const current = context.current++;
11211cb0ef41Sopenharmony_ci  const handle = current === 0 ? self._handle : new TCP(TCPConstants.SOCKET);
11221cb0ef41Sopenharmony_ci  const { localPort, port, flags } = context;
11231cb0ef41Sopenharmony_ci  const { address, family: addressType } = context.addresses[current];
11241cb0ef41Sopenharmony_ci  let localAddress;
11251cb0ef41Sopenharmony_ci  let err;
11261cb0ef41Sopenharmony_ci
11271cb0ef41Sopenharmony_ci  if (localPort) {
11281cb0ef41Sopenharmony_ci    if (addressType === 4) {
11291cb0ef41Sopenharmony_ci      localAddress = DEFAULT_IPV4_ADDR;
11301cb0ef41Sopenharmony_ci      err = handle.bind(localAddress, localPort);
11311cb0ef41Sopenharmony_ci    } else { // addressType === 6
11321cb0ef41Sopenharmony_ci      localAddress = DEFAULT_IPV6_ADDR;
11331cb0ef41Sopenharmony_ci      err = handle.bind6(localAddress, localPort, flags);
11341cb0ef41Sopenharmony_ci    }
11351cb0ef41Sopenharmony_ci
11361cb0ef41Sopenharmony_ci    debug('connect/multiple: binding to localAddress: %s and localPort: %d (addressType: %d)',
11371cb0ef41Sopenharmony_ci          localAddress, localPort, addressType);
11381cb0ef41Sopenharmony_ci
11391cb0ef41Sopenharmony_ci    err = checkBindError(err, localPort, handle);
11401cb0ef41Sopenharmony_ci    if (err) {
11411cb0ef41Sopenharmony_ci      ArrayPrototypePush(context.errors, exceptionWithHostPort(err, 'bind', localAddress, localPort));
11421cb0ef41Sopenharmony_ci      internalConnectMultiple(context);
11431cb0ef41Sopenharmony_ci      return;
11441cb0ef41Sopenharmony_ci    }
11451cb0ef41Sopenharmony_ci  }
11461cb0ef41Sopenharmony_ci
11471cb0ef41Sopenharmony_ci  debug('connect/multiple: attempting to connect to %s:%d (addressType: %d)', address, port, addressType);
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_ci  const req = new TCPConnectWrap();
11501cb0ef41Sopenharmony_ci  req.oncomplete = FunctionPrototypeBind(afterConnectMultiple, undefined, context, current);
11511cb0ef41Sopenharmony_ci  req.address = address;
11521cb0ef41Sopenharmony_ci  req.port = port;
11531cb0ef41Sopenharmony_ci  req.localAddress = localAddress;
11541cb0ef41Sopenharmony_ci  req.localPort = localPort;
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_ci  ArrayPrototypePush(self.autoSelectFamilyAttemptedAddresses, `${address}:${port}`);
11571cb0ef41Sopenharmony_ci
11581cb0ef41Sopenharmony_ci  if (addressType === 4) {
11591cb0ef41Sopenharmony_ci    err = handle.connect(req, address, port);
11601cb0ef41Sopenharmony_ci  } else {
11611cb0ef41Sopenharmony_ci    err = handle.connect6(req, address, port);
11621cb0ef41Sopenharmony_ci  }
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ci  if (err) {
11651cb0ef41Sopenharmony_ci    const sockname = self._getsockname();
11661cb0ef41Sopenharmony_ci    let details;
11671cb0ef41Sopenharmony_ci
11681cb0ef41Sopenharmony_ci    if (sockname) {
11691cb0ef41Sopenharmony_ci      details = sockname.address + ':' + sockname.port;
11701cb0ef41Sopenharmony_ci    }
11711cb0ef41Sopenharmony_ci
11721cb0ef41Sopenharmony_ci    ArrayPrototypePush(context.errors, exceptionWithHostPort(err, 'connect', address, port, details));
11731cb0ef41Sopenharmony_ci    internalConnectMultiple(context);
11741cb0ef41Sopenharmony_ci    return;
11751cb0ef41Sopenharmony_ci  }
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_ci  if (current < context.addresses.length - 1) {
11781cb0ef41Sopenharmony_ci    debug('connect/multiple: setting the attempt timeout to %d ms', context.timeout);
11791cb0ef41Sopenharmony_ci
11801cb0ef41Sopenharmony_ci    // If the attempt has not returned an error, start the connection timer
11811cb0ef41Sopenharmony_ci    context[kTimeout] = setTimeout(internalConnectMultipleTimeout, context.timeout, context, req, handle);
11821cb0ef41Sopenharmony_ci  }
11831cb0ef41Sopenharmony_ci}
11841cb0ef41Sopenharmony_ci
11851cb0ef41Sopenharmony_ciSocket.prototype.connect = function(...args) {
11861cb0ef41Sopenharmony_ci  let normalized;
11871cb0ef41Sopenharmony_ci  // If passed an array, it's treated as an array of arguments that have
11881cb0ef41Sopenharmony_ci  // already been normalized (so we don't normalize more than once). This has
11891cb0ef41Sopenharmony_ci  // been solved before in https://github.com/nodejs/node/pull/12342, but was
11901cb0ef41Sopenharmony_ci  // reverted as it had unintended side effects.
11911cb0ef41Sopenharmony_ci  if (ArrayIsArray(args[0]) && args[0][normalizedArgsSymbol]) {
11921cb0ef41Sopenharmony_ci    normalized = args[0];
11931cb0ef41Sopenharmony_ci  } else {
11941cb0ef41Sopenharmony_ci    normalized = normalizeArgs(args);
11951cb0ef41Sopenharmony_ci  }
11961cb0ef41Sopenharmony_ci  const options = normalized[0];
11971cb0ef41Sopenharmony_ci  const cb = normalized[1];
11981cb0ef41Sopenharmony_ci
11991cb0ef41Sopenharmony_ci  // options.port === null will be checked later.
12001cb0ef41Sopenharmony_ci  if (options.port === undefined && options.path == null)
12011cb0ef41Sopenharmony_ci    throw new ERR_MISSING_ARGS(['options', 'port', 'path']);
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ci  if (this.write !== Socket.prototype.write)
12041cb0ef41Sopenharmony_ci    this.write = Socket.prototype.write;
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ci  if (this.destroyed) {
12071cb0ef41Sopenharmony_ci    this._handle = null;
12081cb0ef41Sopenharmony_ci    this._peername = null;
12091cb0ef41Sopenharmony_ci    this._sockname = null;
12101cb0ef41Sopenharmony_ci  }
12111cb0ef41Sopenharmony_ci
12121cb0ef41Sopenharmony_ci  const { path } = options;
12131cb0ef41Sopenharmony_ci  const pipe = !!path;
12141cb0ef41Sopenharmony_ci  debug('pipe', pipe, path);
12151cb0ef41Sopenharmony_ci
12161cb0ef41Sopenharmony_ci  if (!this._handle) {
12171cb0ef41Sopenharmony_ci    this._handle = pipe ?
12181cb0ef41Sopenharmony_ci      new Pipe(PipeConstants.SOCKET) :
12191cb0ef41Sopenharmony_ci      new TCP(TCPConstants.SOCKET);
12201cb0ef41Sopenharmony_ci    initSocketHandle(this);
12211cb0ef41Sopenharmony_ci  }
12221cb0ef41Sopenharmony_ci
12231cb0ef41Sopenharmony_ci  if (cb !== null) {
12241cb0ef41Sopenharmony_ci    this.once('connect', cb);
12251cb0ef41Sopenharmony_ci  }
12261cb0ef41Sopenharmony_ci
12271cb0ef41Sopenharmony_ci  this._unrefTimer();
12281cb0ef41Sopenharmony_ci
12291cb0ef41Sopenharmony_ci  this.connecting = true;
12301cb0ef41Sopenharmony_ci
12311cb0ef41Sopenharmony_ci  if (pipe) {
12321cb0ef41Sopenharmony_ci    validateString(path, 'options.path');
12331cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(
12341cb0ef41Sopenharmony_ci      this[async_id_symbol], internalConnect, this, path,
12351cb0ef41Sopenharmony_ci    );
12361cb0ef41Sopenharmony_ci  } else {
12371cb0ef41Sopenharmony_ci    lookupAndConnect(this, options);
12381cb0ef41Sopenharmony_ci  }
12391cb0ef41Sopenharmony_ci  return this;
12401cb0ef41Sopenharmony_ci};
12411cb0ef41Sopenharmony_ci
12421cb0ef41Sopenharmony_ciSocket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) {
12431cb0ef41Sopenharmony_ci  this._handle?.close();
12441cb0ef41Sopenharmony_ci
12451cb0ef41Sopenharmony_ci  this._handle = handle;
12461cb0ef41Sopenharmony_ci  this._handle[owner_symbol] = this;
12471cb0ef41Sopenharmony_ci
12481cb0ef41Sopenharmony_ci  initSocketHandle(this);
12491cb0ef41Sopenharmony_ci};
12501cb0ef41Sopenharmony_ci
12511cb0ef41Sopenharmony_cifunction socketToDnsFamily(family) {
12521cb0ef41Sopenharmony_ci  switch (family) {
12531cb0ef41Sopenharmony_ci    case 'IPv4':
12541cb0ef41Sopenharmony_ci      return 4;
12551cb0ef41Sopenharmony_ci    case 'IPv6':
12561cb0ef41Sopenharmony_ci      return 6;
12571cb0ef41Sopenharmony_ci  }
12581cb0ef41Sopenharmony_ci
12591cb0ef41Sopenharmony_ci  return family;
12601cb0ef41Sopenharmony_ci}
12611cb0ef41Sopenharmony_ci
12621cb0ef41Sopenharmony_cifunction lookupAndConnect(self, options) {
12631cb0ef41Sopenharmony_ci  const { localAddress, localPort } = options;
12641cb0ef41Sopenharmony_ci  const host = options.host || 'localhost';
12651cb0ef41Sopenharmony_ci  let { port, autoSelectFamilyAttemptTimeout, autoSelectFamily } = options;
12661cb0ef41Sopenharmony_ci
12671cb0ef41Sopenharmony_ci  if (localAddress && !isIP(localAddress)) {
12681cb0ef41Sopenharmony_ci    throw new ERR_INVALID_IP_ADDRESS(localAddress);
12691cb0ef41Sopenharmony_ci  }
12701cb0ef41Sopenharmony_ci
12711cb0ef41Sopenharmony_ci  if (localPort) {
12721cb0ef41Sopenharmony_ci    validateNumber(localPort, 'options.localPort');
12731cb0ef41Sopenharmony_ci  }
12741cb0ef41Sopenharmony_ci
12751cb0ef41Sopenharmony_ci  if (typeof port !== 'undefined') {
12761cb0ef41Sopenharmony_ci    if (typeof port !== 'number' && typeof port !== 'string') {
12771cb0ef41Sopenharmony_ci      throw new ERR_INVALID_ARG_TYPE('options.port',
12781cb0ef41Sopenharmony_ci                                     ['number', 'string'], port);
12791cb0ef41Sopenharmony_ci    }
12801cb0ef41Sopenharmony_ci    validatePort(port);
12811cb0ef41Sopenharmony_ci  }
12821cb0ef41Sopenharmony_ci  port |= 0;
12831cb0ef41Sopenharmony_ci
12841cb0ef41Sopenharmony_ci
12851cb0ef41Sopenharmony_ci  if (autoSelectFamily != null) {
12861cb0ef41Sopenharmony_ci    validateBoolean(autoSelectFamily, 'options.autoSelectFamily');
12871cb0ef41Sopenharmony_ci  } else {
12881cb0ef41Sopenharmony_ci    autoSelectFamily = autoSelectFamilyDefault;
12891cb0ef41Sopenharmony_ci  }
12901cb0ef41Sopenharmony_ci
12911cb0ef41Sopenharmony_ci  if (autoSelectFamilyAttemptTimeout != null) {
12921cb0ef41Sopenharmony_ci    validateInt32(autoSelectFamilyAttemptTimeout, 'options.autoSelectFamilyAttemptTimeout', 1);
12931cb0ef41Sopenharmony_ci
12941cb0ef41Sopenharmony_ci    if (autoSelectFamilyAttemptTimeout < 10) {
12951cb0ef41Sopenharmony_ci      autoSelectFamilyAttemptTimeout = 10;
12961cb0ef41Sopenharmony_ci    }
12971cb0ef41Sopenharmony_ci  } else {
12981cb0ef41Sopenharmony_ci    autoSelectFamilyAttemptTimeout = autoSelectFamilyAttemptTimeoutDefault;
12991cb0ef41Sopenharmony_ci  }
13001cb0ef41Sopenharmony_ci
13011cb0ef41Sopenharmony_ci  // If host is an IP, skip performing a lookup
13021cb0ef41Sopenharmony_ci  const addressType = isIP(host);
13031cb0ef41Sopenharmony_ci  if (addressType) {
13041cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(self[async_id_symbol], process.nextTick, () => {
13051cb0ef41Sopenharmony_ci      if (self.connecting)
13061cb0ef41Sopenharmony_ci        defaultTriggerAsyncIdScope(
13071cb0ef41Sopenharmony_ci          self[async_id_symbol],
13081cb0ef41Sopenharmony_ci          internalConnect,
13091cb0ef41Sopenharmony_ci          self, host, port, addressType, localAddress, localPort,
13101cb0ef41Sopenharmony_ci        );
13111cb0ef41Sopenharmony_ci    });
13121cb0ef41Sopenharmony_ci    return;
13131cb0ef41Sopenharmony_ci  }
13141cb0ef41Sopenharmony_ci
13151cb0ef41Sopenharmony_ci  if (options.lookup != null)
13161cb0ef41Sopenharmony_ci    validateFunction(options.lookup, 'options.lookup');
13171cb0ef41Sopenharmony_ci
13181cb0ef41Sopenharmony_ci  if (dns === undefined) dns = require('dns');
13191cb0ef41Sopenharmony_ci  const dnsopts = {
13201cb0ef41Sopenharmony_ci    family: socketToDnsFamily(options.family),
13211cb0ef41Sopenharmony_ci    hints: options.hints || 0,
13221cb0ef41Sopenharmony_ci  };
13231cb0ef41Sopenharmony_ci
13241cb0ef41Sopenharmony_ci  if (!isWindows &&
13251cb0ef41Sopenharmony_ci      dnsopts.family !== 4 &&
13261cb0ef41Sopenharmony_ci      dnsopts.family !== 6 &&
13271cb0ef41Sopenharmony_ci      dnsopts.hints === 0) {
13281cb0ef41Sopenharmony_ci    dnsopts.hints = dns.ADDRCONFIG;
13291cb0ef41Sopenharmony_ci  }
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_ci  debug('connect: find host', host);
13321cb0ef41Sopenharmony_ci  debug('connect: dns options', dnsopts);
13331cb0ef41Sopenharmony_ci  self._host = host;
13341cb0ef41Sopenharmony_ci  const lookup = options.lookup || dns.lookup;
13351cb0ef41Sopenharmony_ci
13361cb0ef41Sopenharmony_ci  if (dnsopts.family !== 4 && dnsopts.family !== 6 && !localAddress && autoSelectFamily) {
13371cb0ef41Sopenharmony_ci    debug('connect: autodetecting');
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ci    dnsopts.all = true;
13401cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(self[async_id_symbol], function() {
13411cb0ef41Sopenharmony_ci      lookupAndConnectMultiple(
13421cb0ef41Sopenharmony_ci        self,
13431cb0ef41Sopenharmony_ci        async_id_symbol,
13441cb0ef41Sopenharmony_ci        lookup,
13451cb0ef41Sopenharmony_ci        host,
13461cb0ef41Sopenharmony_ci        options,
13471cb0ef41Sopenharmony_ci        dnsopts,
13481cb0ef41Sopenharmony_ci        port,
13491cb0ef41Sopenharmony_ci        localPort,
13501cb0ef41Sopenharmony_ci        autoSelectFamilyAttemptTimeout,
13511cb0ef41Sopenharmony_ci      );
13521cb0ef41Sopenharmony_ci    });
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ci    return;
13551cb0ef41Sopenharmony_ci  }
13561cb0ef41Sopenharmony_ci
13571cb0ef41Sopenharmony_ci  defaultTriggerAsyncIdScope(self[async_id_symbol], function() {
13581cb0ef41Sopenharmony_ci    lookup(host, dnsopts, function emitLookup(err, ip, addressType) {
13591cb0ef41Sopenharmony_ci      self.emit('lookup', err, ip, addressType, host);
13601cb0ef41Sopenharmony_ci
13611cb0ef41Sopenharmony_ci      // It's possible we were destroyed while looking this up.
13621cb0ef41Sopenharmony_ci      // XXX it would be great if we could cancel the promise returned by
13631cb0ef41Sopenharmony_ci      // the look up.
13641cb0ef41Sopenharmony_ci      if (!self.connecting) return;
13651cb0ef41Sopenharmony_ci
13661cb0ef41Sopenharmony_ci      if (err) {
13671cb0ef41Sopenharmony_ci        // net.createConnection() creates a net.Socket object and immediately
13681cb0ef41Sopenharmony_ci        // calls net.Socket.connect() on it (that's us). There are no event
13691cb0ef41Sopenharmony_ci        // listeners registered yet so defer the error event to the next tick.
13701cb0ef41Sopenharmony_ci        process.nextTick(connectErrorNT, self, err);
13711cb0ef41Sopenharmony_ci      } else if (!isIP(ip)) {
13721cb0ef41Sopenharmony_ci        err = new ERR_INVALID_IP_ADDRESS(ip);
13731cb0ef41Sopenharmony_ci        process.nextTick(connectErrorNT, self, err);
13741cb0ef41Sopenharmony_ci      } else if (addressType !== 4 && addressType !== 6) {
13751cb0ef41Sopenharmony_ci        err = new ERR_INVALID_ADDRESS_FAMILY(addressType,
13761cb0ef41Sopenharmony_ci                                             options.host,
13771cb0ef41Sopenharmony_ci                                             options.port);
13781cb0ef41Sopenharmony_ci        process.nextTick(connectErrorNT, self, err);
13791cb0ef41Sopenharmony_ci      } else {
13801cb0ef41Sopenharmony_ci        self._unrefTimer();
13811cb0ef41Sopenharmony_ci        defaultTriggerAsyncIdScope(
13821cb0ef41Sopenharmony_ci          self[async_id_symbol],
13831cb0ef41Sopenharmony_ci          internalConnect,
13841cb0ef41Sopenharmony_ci          self, ip, port, addressType, localAddress, localPort,
13851cb0ef41Sopenharmony_ci        );
13861cb0ef41Sopenharmony_ci      }
13871cb0ef41Sopenharmony_ci    });
13881cb0ef41Sopenharmony_ci  });
13891cb0ef41Sopenharmony_ci}
13901cb0ef41Sopenharmony_ci
13911cb0ef41Sopenharmony_cifunction lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options, dnsopts, port, localPort, timeout) {
13921cb0ef41Sopenharmony_ci  defaultTriggerAsyncIdScope(self[async_id_symbol], function emitLookup() {
13931cb0ef41Sopenharmony_ci    lookup(host, dnsopts, function emitLookup(err, addresses) {
13941cb0ef41Sopenharmony_ci      // It's possible we were destroyed while looking this up.
13951cb0ef41Sopenharmony_ci      // XXX it would be great if we could cancel the promise returned by
13961cb0ef41Sopenharmony_ci      // the look up.
13971cb0ef41Sopenharmony_ci      if (!self.connecting) {
13981cb0ef41Sopenharmony_ci        return;
13991cb0ef41Sopenharmony_ci      } else if (err) {
14001cb0ef41Sopenharmony_ci        self.emit('lookup', err, undefined, undefined, host);
14011cb0ef41Sopenharmony_ci
14021cb0ef41Sopenharmony_ci        // net.createConnection() creates a net.Socket object and immediately
14031cb0ef41Sopenharmony_ci        // calls net.Socket.connect() on it (that's us). There are no event
14041cb0ef41Sopenharmony_ci        // listeners registered yet so defer the error event to the next tick.
14051cb0ef41Sopenharmony_ci        process.nextTick(connectErrorNT, self, err);
14061cb0ef41Sopenharmony_ci        return;
14071cb0ef41Sopenharmony_ci      }
14081cb0ef41Sopenharmony_ci
14091cb0ef41Sopenharmony_ci      // Filter addresses by only keeping the one which are either IPv4 or IPV6.
14101cb0ef41Sopenharmony_ci      // The first valid address determines which group has preference on the
14111cb0ef41Sopenharmony_ci      // alternate family sorting which happens later.
14121cb0ef41Sopenharmony_ci      const validIps = [[], []];
14131cb0ef41Sopenharmony_ci      let destinations;
14141cb0ef41Sopenharmony_ci      for (let i = 0, l = addresses.length; i < l; i++) {
14151cb0ef41Sopenharmony_ci        const address = addresses[i];
14161cb0ef41Sopenharmony_ci        const { address: ip, family: addressType } = address;
14171cb0ef41Sopenharmony_ci        self.emit('lookup', err, ip, addressType, host);
14181cb0ef41Sopenharmony_ci
14191cb0ef41Sopenharmony_ci        if (isIP(ip) && (addressType === 4 || addressType === 6)) {
14201cb0ef41Sopenharmony_ci          if (!destinations) {
14211cb0ef41Sopenharmony_ci            destinations = addressType === 6 ? { 6: 0, 4: 1 } : { 4: 0, 6: 1 };
14221cb0ef41Sopenharmony_ci          }
14231cb0ef41Sopenharmony_ci
14241cb0ef41Sopenharmony_ci          ArrayPrototypePush(validIps[destinations[addressType]], address);
14251cb0ef41Sopenharmony_ci        }
14261cb0ef41Sopenharmony_ci      }
14271cb0ef41Sopenharmony_ci
14281cb0ef41Sopenharmony_ci      // When no AAAA or A records are available, fail on the first one
14291cb0ef41Sopenharmony_ci      if (!validIps[0].length && !validIps[1].length) {
14301cb0ef41Sopenharmony_ci        const { address: firstIp, family: firstAddressType } = addresses[0];
14311cb0ef41Sopenharmony_ci
14321cb0ef41Sopenharmony_ci        if (!isIP(firstIp)) {
14331cb0ef41Sopenharmony_ci          err = new ERR_INVALID_IP_ADDRESS(firstIp);
14341cb0ef41Sopenharmony_ci          process.nextTick(connectErrorNT, self, err);
14351cb0ef41Sopenharmony_ci        } else if (firstAddressType !== 4 && firstAddressType !== 6) {
14361cb0ef41Sopenharmony_ci          err = new ERR_INVALID_ADDRESS_FAMILY(firstAddressType,
14371cb0ef41Sopenharmony_ci                                               options.host,
14381cb0ef41Sopenharmony_ci                                               options.port);
14391cb0ef41Sopenharmony_ci          process.nextTick(connectErrorNT, self, err);
14401cb0ef41Sopenharmony_ci        }
14411cb0ef41Sopenharmony_ci
14421cb0ef41Sopenharmony_ci        return;
14431cb0ef41Sopenharmony_ci      }
14441cb0ef41Sopenharmony_ci
14451cb0ef41Sopenharmony_ci      // Sort addresses alternating families
14461cb0ef41Sopenharmony_ci      const toAttempt = [];
14471cb0ef41Sopenharmony_ci      for (let i = 0, l = MathMax(validIps[0].length, validIps[1].length); i < l; i++) {
14481cb0ef41Sopenharmony_ci        if (i in validIps[0]) {
14491cb0ef41Sopenharmony_ci          ArrayPrototypePush(toAttempt, validIps[0][i]);
14501cb0ef41Sopenharmony_ci        }
14511cb0ef41Sopenharmony_ci        if (i in validIps[1]) {
14521cb0ef41Sopenharmony_ci          ArrayPrototypePush(toAttempt, validIps[1][i]);
14531cb0ef41Sopenharmony_ci        }
14541cb0ef41Sopenharmony_ci      }
14551cb0ef41Sopenharmony_ci
14561cb0ef41Sopenharmony_ci      self.autoSelectFamilyAttemptedAddresses = [];
14571cb0ef41Sopenharmony_ci
14581cb0ef41Sopenharmony_ci      const context = {
14591cb0ef41Sopenharmony_ci        socket: self,
14601cb0ef41Sopenharmony_ci        addresses: toAttempt,
14611cb0ef41Sopenharmony_ci        current: 0,
14621cb0ef41Sopenharmony_ci        port,
14631cb0ef41Sopenharmony_ci        localPort,
14641cb0ef41Sopenharmony_ci        timeout,
14651cb0ef41Sopenharmony_ci        [kTimeout]: null,
14661cb0ef41Sopenharmony_ci        errors: [],
14671cb0ef41Sopenharmony_ci      };
14681cb0ef41Sopenharmony_ci
14691cb0ef41Sopenharmony_ci      self._unrefTimer();
14701cb0ef41Sopenharmony_ci      defaultTriggerAsyncIdScope(self[async_id_symbol], internalConnectMultiple, context);
14711cb0ef41Sopenharmony_ci    });
14721cb0ef41Sopenharmony_ci  });
14731cb0ef41Sopenharmony_ci}
14741cb0ef41Sopenharmony_ci
14751cb0ef41Sopenharmony_cifunction connectErrorNT(self, err) {
14761cb0ef41Sopenharmony_ci  self.destroy(err);
14771cb0ef41Sopenharmony_ci}
14781cb0ef41Sopenharmony_ci
14791cb0ef41Sopenharmony_ci
14801cb0ef41Sopenharmony_ciSocket.prototype.ref = function() {
14811cb0ef41Sopenharmony_ci  if (!this._handle) {
14821cb0ef41Sopenharmony_ci    this.once('connect', this.ref);
14831cb0ef41Sopenharmony_ci    return this;
14841cb0ef41Sopenharmony_ci  }
14851cb0ef41Sopenharmony_ci
14861cb0ef41Sopenharmony_ci  if (typeof this._handle.ref === 'function') {
14871cb0ef41Sopenharmony_ci    this._handle.ref();
14881cb0ef41Sopenharmony_ci  }
14891cb0ef41Sopenharmony_ci
14901cb0ef41Sopenharmony_ci  return this;
14911cb0ef41Sopenharmony_ci};
14921cb0ef41Sopenharmony_ci
14931cb0ef41Sopenharmony_ci
14941cb0ef41Sopenharmony_ciSocket.prototype.unref = function() {
14951cb0ef41Sopenharmony_ci  if (!this._handle) {
14961cb0ef41Sopenharmony_ci    this.once('connect', this.unref);
14971cb0ef41Sopenharmony_ci    return this;
14981cb0ef41Sopenharmony_ci  }
14991cb0ef41Sopenharmony_ci
15001cb0ef41Sopenharmony_ci  if (typeof this._handle.unref === 'function') {
15011cb0ef41Sopenharmony_ci    this._handle.unref();
15021cb0ef41Sopenharmony_ci  }
15031cb0ef41Sopenharmony_ci
15041cb0ef41Sopenharmony_ci  return this;
15051cb0ef41Sopenharmony_ci};
15061cb0ef41Sopenharmony_ci
15071cb0ef41Sopenharmony_ci
15081cb0ef41Sopenharmony_cifunction afterConnect(status, handle, req, readable, writable) {
15091cb0ef41Sopenharmony_ci  const self = handle[owner_symbol];
15101cb0ef41Sopenharmony_ci
15111cb0ef41Sopenharmony_ci  // Callback may come after call to destroy
15121cb0ef41Sopenharmony_ci  if (self.destroyed) {
15131cb0ef41Sopenharmony_ci    return;
15141cb0ef41Sopenharmony_ci  }
15151cb0ef41Sopenharmony_ci
15161cb0ef41Sopenharmony_ci  debug('afterConnect');
15171cb0ef41Sopenharmony_ci
15181cb0ef41Sopenharmony_ci  assert(self.connecting);
15191cb0ef41Sopenharmony_ci  self.connecting = false;
15201cb0ef41Sopenharmony_ci  self._sockname = null;
15211cb0ef41Sopenharmony_ci
15221cb0ef41Sopenharmony_ci  if (status === 0) {
15231cb0ef41Sopenharmony_ci    if (self.readable && !readable) {
15241cb0ef41Sopenharmony_ci      self.push(null);
15251cb0ef41Sopenharmony_ci      self.read();
15261cb0ef41Sopenharmony_ci    }
15271cb0ef41Sopenharmony_ci    if (self.writable && !writable) {
15281cb0ef41Sopenharmony_ci      self.end();
15291cb0ef41Sopenharmony_ci    }
15301cb0ef41Sopenharmony_ci    self._unrefTimer();
15311cb0ef41Sopenharmony_ci
15321cb0ef41Sopenharmony_ci    if (self[kSetNoDelay] && self._handle.setNoDelay) {
15331cb0ef41Sopenharmony_ci      self._handle.setNoDelay(true);
15341cb0ef41Sopenharmony_ci    }
15351cb0ef41Sopenharmony_ci
15361cb0ef41Sopenharmony_ci    if (self[kSetKeepAlive] && self._handle.setKeepAlive) {
15371cb0ef41Sopenharmony_ci      self._handle.setKeepAlive(true, self[kSetKeepAliveInitialDelay]);
15381cb0ef41Sopenharmony_ci    }
15391cb0ef41Sopenharmony_ci
15401cb0ef41Sopenharmony_ci    self.emit('connect');
15411cb0ef41Sopenharmony_ci    self.emit('ready');
15421cb0ef41Sopenharmony_ci
15431cb0ef41Sopenharmony_ci    // Start the first read, or get an immediate EOF.
15441cb0ef41Sopenharmony_ci    // this doesn't actually consume any bytes, because len=0.
15451cb0ef41Sopenharmony_ci    if (readable && !self.isPaused())
15461cb0ef41Sopenharmony_ci      self.read(0);
15471cb0ef41Sopenharmony_ci    if (self[kPerfHooksNetConnectContext] && hasObserver('net')) {
15481cb0ef41Sopenharmony_ci      stopPerf(self, kPerfHooksNetConnectContext);
15491cb0ef41Sopenharmony_ci    }
15501cb0ef41Sopenharmony_ci  } else {
15511cb0ef41Sopenharmony_ci    let details;
15521cb0ef41Sopenharmony_ci    if (req.localAddress && req.localPort) {
15531cb0ef41Sopenharmony_ci      details = req.localAddress + ':' + req.localPort;
15541cb0ef41Sopenharmony_ci    }
15551cb0ef41Sopenharmony_ci    const ex = exceptionWithHostPort(status,
15561cb0ef41Sopenharmony_ci                                     'connect',
15571cb0ef41Sopenharmony_ci                                     req.address,
15581cb0ef41Sopenharmony_ci                                     req.port,
15591cb0ef41Sopenharmony_ci                                     details);
15601cb0ef41Sopenharmony_ci    if (details) {
15611cb0ef41Sopenharmony_ci      ex.localAddress = req.localAddress;
15621cb0ef41Sopenharmony_ci      ex.localPort = req.localPort;
15631cb0ef41Sopenharmony_ci    }
15641cb0ef41Sopenharmony_ci    self.destroy(ex);
15651cb0ef41Sopenharmony_ci  }
15661cb0ef41Sopenharmony_ci}
15671cb0ef41Sopenharmony_ci
15681cb0ef41Sopenharmony_cifunction afterConnectMultiple(context, current, status, handle, req, readable, writable) {
15691cb0ef41Sopenharmony_ci  // Make sure another connection is not spawned
15701cb0ef41Sopenharmony_ci  clearTimeout(context[kTimeout]);
15711cb0ef41Sopenharmony_ci
15721cb0ef41Sopenharmony_ci  // One of the connection has completed and correctly dispatched but after timeout, ignore this one
15731cb0ef41Sopenharmony_ci  if (status === 0 && current !== context.current - 1) {
15741cb0ef41Sopenharmony_ci    debug('connect/multiple: ignoring successful but timedout connection to %s:%s', req.address, req.port);
15751cb0ef41Sopenharmony_ci    handle.close();
15761cb0ef41Sopenharmony_ci    return;
15771cb0ef41Sopenharmony_ci  }
15781cb0ef41Sopenharmony_ci
15791cb0ef41Sopenharmony_ci  const self = context.socket;
15801cb0ef41Sopenharmony_ci
15811cb0ef41Sopenharmony_ci
15821cb0ef41Sopenharmony_ci  // Some error occurred, add to the list of exceptions
15831cb0ef41Sopenharmony_ci  if (status !== 0) {
15841cb0ef41Sopenharmony_ci    let details;
15851cb0ef41Sopenharmony_ci    if (req.localAddress && req.localPort) {
15861cb0ef41Sopenharmony_ci      details = req.localAddress + ':' + req.localPort;
15871cb0ef41Sopenharmony_ci    }
15881cb0ef41Sopenharmony_ci    const ex = exceptionWithHostPort(status,
15891cb0ef41Sopenharmony_ci                                     'connect',
15901cb0ef41Sopenharmony_ci                                     req.address,
15911cb0ef41Sopenharmony_ci                                     req.port,
15921cb0ef41Sopenharmony_ci                                     details);
15931cb0ef41Sopenharmony_ci    if (details) {
15941cb0ef41Sopenharmony_ci      ex.localAddress = req.localAddress;
15951cb0ef41Sopenharmony_ci      ex.localPort = req.localPort;
15961cb0ef41Sopenharmony_ci    }
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ci    ArrayPrototypePush(context.errors, ex);
15991cb0ef41Sopenharmony_ci
16001cb0ef41Sopenharmony_ci    // Try the next address
16011cb0ef41Sopenharmony_ci    internalConnectMultiple(context, status === UV_ECANCELED);
16021cb0ef41Sopenharmony_ci    return;
16031cb0ef41Sopenharmony_ci  }
16041cb0ef41Sopenharmony_ci
16051cb0ef41Sopenharmony_ci  // One of the connection has completed and correctly dispatched but after timeout, ignore this one
16061cb0ef41Sopenharmony_ci  if (status === 0 && current !== context.current - 1) {
16071cb0ef41Sopenharmony_ci    debug('connect/multiple: ignoring successful but timedout connection to %s:%s', req.address, req.port);
16081cb0ef41Sopenharmony_ci    handle.close();
16091cb0ef41Sopenharmony_ci    return;
16101cb0ef41Sopenharmony_ci  }
16111cb0ef41Sopenharmony_ci
16121cb0ef41Sopenharmony_ci  if (context.current > 1 && self[kReinitializeHandle]) {
16131cb0ef41Sopenharmony_ci    self[kReinitializeHandle](handle);
16141cb0ef41Sopenharmony_ci    handle = self._handle;
16151cb0ef41Sopenharmony_ci  }
16161cb0ef41Sopenharmony_ci
16171cb0ef41Sopenharmony_ci  if (hasObserver('net')) {
16181cb0ef41Sopenharmony_ci    startPerf(
16191cb0ef41Sopenharmony_ci      self,
16201cb0ef41Sopenharmony_ci      kPerfHooksNetConnectContext,
16211cb0ef41Sopenharmony_ci      { type: 'net', name: 'connect', detail: { host: req.address, port: req.port } },
16221cb0ef41Sopenharmony_ci    );
16231cb0ef41Sopenharmony_ci  }
16241cb0ef41Sopenharmony_ci
16251cb0ef41Sopenharmony_ci  afterConnect(status, handle, req, readable, writable);
16261cb0ef41Sopenharmony_ci}
16271cb0ef41Sopenharmony_ci
16281cb0ef41Sopenharmony_cifunction internalConnectMultipleTimeout(context, req, handle) {
16291cb0ef41Sopenharmony_ci  debug('connect/multiple: connection to %s:%s timed out', req.address, req.port);
16301cb0ef41Sopenharmony_ci  req.oncomplete = undefined;
16311cb0ef41Sopenharmony_ci  handle.close();
16321cb0ef41Sopenharmony_ci  internalConnectMultiple(context);
16331cb0ef41Sopenharmony_ci}
16341cb0ef41Sopenharmony_ci
16351cb0ef41Sopenharmony_cifunction addAbortSignalOption(self, options) {
16361cb0ef41Sopenharmony_ci  if (options?.signal === undefined) {
16371cb0ef41Sopenharmony_ci    return;
16381cb0ef41Sopenharmony_ci  }
16391cb0ef41Sopenharmony_ci  validateAbortSignal(options.signal, 'options.signal');
16401cb0ef41Sopenharmony_ci  const { signal } = options;
16411cb0ef41Sopenharmony_ci  const onAborted = () => {
16421cb0ef41Sopenharmony_ci    self.close();
16431cb0ef41Sopenharmony_ci  };
16441cb0ef41Sopenharmony_ci  if (signal.aborted) {
16451cb0ef41Sopenharmony_ci    process.nextTick(onAborted);
16461cb0ef41Sopenharmony_ci  } else {
16471cb0ef41Sopenharmony_ci    signal.addEventListener('abort', onAborted);
16481cb0ef41Sopenharmony_ci    self.once('close', () => signal.removeEventListener('abort', onAborted));
16491cb0ef41Sopenharmony_ci  }
16501cb0ef41Sopenharmony_ci}
16511cb0ef41Sopenharmony_ci
16521cb0ef41Sopenharmony_cifunction Server(options, connectionListener) {
16531cb0ef41Sopenharmony_ci  if (!(this instanceof Server))
16541cb0ef41Sopenharmony_ci    return new Server(options, connectionListener);
16551cb0ef41Sopenharmony_ci
16561cb0ef41Sopenharmony_ci  EventEmitter.call(this);
16571cb0ef41Sopenharmony_ci
16581cb0ef41Sopenharmony_ci  if (typeof options === 'function') {
16591cb0ef41Sopenharmony_ci    connectionListener = options;
16601cb0ef41Sopenharmony_ci    options = kEmptyObject;
16611cb0ef41Sopenharmony_ci    this.on('connection', connectionListener);
16621cb0ef41Sopenharmony_ci  } else if (options == null || typeof options === 'object') {
16631cb0ef41Sopenharmony_ci    options = { ...options };
16641cb0ef41Sopenharmony_ci
16651cb0ef41Sopenharmony_ci    if (typeof connectionListener === 'function') {
16661cb0ef41Sopenharmony_ci      this.on('connection', connectionListener);
16671cb0ef41Sopenharmony_ci    }
16681cb0ef41Sopenharmony_ci  } else {
16691cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
16701cb0ef41Sopenharmony_ci  }
16711cb0ef41Sopenharmony_ci  if (typeof options.keepAliveInitialDelay !== 'undefined') {
16721cb0ef41Sopenharmony_ci    validateNumber(
16731cb0ef41Sopenharmony_ci      options.keepAliveInitialDelay, 'options.keepAliveInitialDelay',
16741cb0ef41Sopenharmony_ci    );
16751cb0ef41Sopenharmony_ci
16761cb0ef41Sopenharmony_ci    if (options.keepAliveInitialDelay < 0) {
16771cb0ef41Sopenharmony_ci      options.keepAliveInitialDelay = 0;
16781cb0ef41Sopenharmony_ci    }
16791cb0ef41Sopenharmony_ci  }
16801cb0ef41Sopenharmony_ci  if (typeof options.highWaterMark !== 'undefined') {
16811cb0ef41Sopenharmony_ci    validateNumber(
16821cb0ef41Sopenharmony_ci      options.highWaterMark, 'options.highWaterMark',
16831cb0ef41Sopenharmony_ci    );
16841cb0ef41Sopenharmony_ci
16851cb0ef41Sopenharmony_ci    if (options.highWaterMark < 0) {
16861cb0ef41Sopenharmony_ci      options.highWaterMark = getDefaultHighWaterMark();
16871cb0ef41Sopenharmony_ci    }
16881cb0ef41Sopenharmony_ci  }
16891cb0ef41Sopenharmony_ci
16901cb0ef41Sopenharmony_ci  this._connections = 0;
16911cb0ef41Sopenharmony_ci
16921cb0ef41Sopenharmony_ci  this[async_id_symbol] = -1;
16931cb0ef41Sopenharmony_ci  this._handle = null;
16941cb0ef41Sopenharmony_ci  this._usingWorkers = false;
16951cb0ef41Sopenharmony_ci  this._workers = [];
16961cb0ef41Sopenharmony_ci  this._unref = false;
16971cb0ef41Sopenharmony_ci
16981cb0ef41Sopenharmony_ci  this.allowHalfOpen = options.allowHalfOpen || false;
16991cb0ef41Sopenharmony_ci  this.pauseOnConnect = !!options.pauseOnConnect;
17001cb0ef41Sopenharmony_ci  this.noDelay = Boolean(options.noDelay);
17011cb0ef41Sopenharmony_ci  this.keepAlive = Boolean(options.keepAlive);
17021cb0ef41Sopenharmony_ci  this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
17031cb0ef41Sopenharmony_ci  this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
17041cb0ef41Sopenharmony_ci}
17051cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype);
17061cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Server, EventEmitter);
17071cb0ef41Sopenharmony_ci
17081cb0ef41Sopenharmony_ci
17091cb0ef41Sopenharmony_cifunction toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_ci// Returns handle if it can be created, or error code if it can't
17121cb0ef41Sopenharmony_cifunction createServerHandle(address, port, addressType, fd, flags) {
17131cb0ef41Sopenharmony_ci  let err = 0;
17141cb0ef41Sopenharmony_ci  // Assign handle in listen, and clean up if bind or listen fails
17151cb0ef41Sopenharmony_ci  let handle;
17161cb0ef41Sopenharmony_ci
17171cb0ef41Sopenharmony_ci  let isTCP = false;
17181cb0ef41Sopenharmony_ci  if (typeof fd === 'number' && fd >= 0) {
17191cb0ef41Sopenharmony_ci    try {
17201cb0ef41Sopenharmony_ci      handle = createHandle(fd, true);
17211cb0ef41Sopenharmony_ci    } catch (e) {
17221cb0ef41Sopenharmony_ci      // Not a fd we can listen on.  This will trigger an error.
17231cb0ef41Sopenharmony_ci      debug('listen invalid fd=%d:', fd, e.message);
17241cb0ef41Sopenharmony_ci      return UV_EINVAL;
17251cb0ef41Sopenharmony_ci    }
17261cb0ef41Sopenharmony_ci
17271cb0ef41Sopenharmony_ci    err = handle.open(fd);
17281cb0ef41Sopenharmony_ci    if (err)
17291cb0ef41Sopenharmony_ci      return err;
17301cb0ef41Sopenharmony_ci
17311cb0ef41Sopenharmony_ci    assert(!address && !port);
17321cb0ef41Sopenharmony_ci  } else if (port === -1 && addressType === -1) {
17331cb0ef41Sopenharmony_ci    handle = new Pipe(PipeConstants.SERVER);
17341cb0ef41Sopenharmony_ci    if (isWindows) {
17351cb0ef41Sopenharmony_ci      const instances = NumberParseInt(process.env.NODE_PENDING_PIPE_INSTANCES);
17361cb0ef41Sopenharmony_ci      if (!NumberIsNaN(instances)) {
17371cb0ef41Sopenharmony_ci        handle.setPendingInstances(instances);
17381cb0ef41Sopenharmony_ci      }
17391cb0ef41Sopenharmony_ci    }
17401cb0ef41Sopenharmony_ci  } else {
17411cb0ef41Sopenharmony_ci    handle = new TCP(TCPConstants.SERVER);
17421cb0ef41Sopenharmony_ci    isTCP = true;
17431cb0ef41Sopenharmony_ci  }
17441cb0ef41Sopenharmony_ci
17451cb0ef41Sopenharmony_ci  if (address || port || isTCP) {
17461cb0ef41Sopenharmony_ci    debug('bind to', address || 'any');
17471cb0ef41Sopenharmony_ci    if (!address) {
17481cb0ef41Sopenharmony_ci      // Try binding to ipv6 first
17491cb0ef41Sopenharmony_ci      err = handle.bind6(DEFAULT_IPV6_ADDR, port, flags);
17501cb0ef41Sopenharmony_ci      if (err) {
17511cb0ef41Sopenharmony_ci        handle.close();
17521cb0ef41Sopenharmony_ci        // Fallback to ipv4
17531cb0ef41Sopenharmony_ci        return createServerHandle(DEFAULT_IPV4_ADDR, port);
17541cb0ef41Sopenharmony_ci      }
17551cb0ef41Sopenharmony_ci    } else if (addressType === 6) {
17561cb0ef41Sopenharmony_ci      err = handle.bind6(address, port, flags);
17571cb0ef41Sopenharmony_ci    } else {
17581cb0ef41Sopenharmony_ci      err = handle.bind(address, port);
17591cb0ef41Sopenharmony_ci    }
17601cb0ef41Sopenharmony_ci  }
17611cb0ef41Sopenharmony_ci
17621cb0ef41Sopenharmony_ci  if (err) {
17631cb0ef41Sopenharmony_ci    handle.close();
17641cb0ef41Sopenharmony_ci    return err;
17651cb0ef41Sopenharmony_ci  }
17661cb0ef41Sopenharmony_ci
17671cb0ef41Sopenharmony_ci  return handle;
17681cb0ef41Sopenharmony_ci}
17691cb0ef41Sopenharmony_ci
17701cb0ef41Sopenharmony_cifunction setupListenHandle(address, port, addressType, backlog, fd, flags) {
17711cb0ef41Sopenharmony_ci  debug('setupListenHandle', address, port, addressType, backlog, fd);
17721cb0ef41Sopenharmony_ci
17731cb0ef41Sopenharmony_ci  // If there is not yet a handle, we need to create one and bind.
17741cb0ef41Sopenharmony_ci  // In the case of a server sent via IPC, we don't need to do this.
17751cb0ef41Sopenharmony_ci  if (this._handle) {
17761cb0ef41Sopenharmony_ci    debug('setupListenHandle: have a handle already');
17771cb0ef41Sopenharmony_ci  } else {
17781cb0ef41Sopenharmony_ci    debug('setupListenHandle: create a handle');
17791cb0ef41Sopenharmony_ci
17801cb0ef41Sopenharmony_ci    let rval = null;
17811cb0ef41Sopenharmony_ci
17821cb0ef41Sopenharmony_ci    // Try to bind to the unspecified IPv6 address, see if IPv6 is available
17831cb0ef41Sopenharmony_ci    if (!address && typeof fd !== 'number') {
17841cb0ef41Sopenharmony_ci      rval = createServerHandle(DEFAULT_IPV6_ADDR, port, 6, fd, flags);
17851cb0ef41Sopenharmony_ci
17861cb0ef41Sopenharmony_ci      if (typeof rval === 'number') {
17871cb0ef41Sopenharmony_ci        rval = null;
17881cb0ef41Sopenharmony_ci        address = DEFAULT_IPV4_ADDR;
17891cb0ef41Sopenharmony_ci        addressType = 4;
17901cb0ef41Sopenharmony_ci      } else {
17911cb0ef41Sopenharmony_ci        address = DEFAULT_IPV6_ADDR;
17921cb0ef41Sopenharmony_ci        addressType = 6;
17931cb0ef41Sopenharmony_ci      }
17941cb0ef41Sopenharmony_ci    }
17951cb0ef41Sopenharmony_ci
17961cb0ef41Sopenharmony_ci    if (rval === null)
17971cb0ef41Sopenharmony_ci      rval = createServerHandle(address, port, addressType, fd, flags);
17981cb0ef41Sopenharmony_ci
17991cb0ef41Sopenharmony_ci    if (typeof rval === 'number') {
18001cb0ef41Sopenharmony_ci      const error = uvExceptionWithHostPort(rval, 'listen', address, port);
18011cb0ef41Sopenharmony_ci      process.nextTick(emitErrorNT, this, error);
18021cb0ef41Sopenharmony_ci      return;
18031cb0ef41Sopenharmony_ci    }
18041cb0ef41Sopenharmony_ci    this._handle = rval;
18051cb0ef41Sopenharmony_ci  }
18061cb0ef41Sopenharmony_ci
18071cb0ef41Sopenharmony_ci  this[async_id_symbol] = getNewAsyncId(this._handle);
18081cb0ef41Sopenharmony_ci  this._handle.onconnection = onconnection;
18091cb0ef41Sopenharmony_ci  this._handle[owner_symbol] = this;
18101cb0ef41Sopenharmony_ci
18111cb0ef41Sopenharmony_ci  // Use a backlog of 512 entries. We pass 511 to the listen() call because
18121cb0ef41Sopenharmony_ci  // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
18131cb0ef41Sopenharmony_ci  // which will thus give us a backlog of 512 entries.
18141cb0ef41Sopenharmony_ci  const err = this._handle.listen(backlog || 511);
18151cb0ef41Sopenharmony_ci
18161cb0ef41Sopenharmony_ci  if (err) {
18171cb0ef41Sopenharmony_ci    const ex = uvExceptionWithHostPort(err, 'listen', address, port);
18181cb0ef41Sopenharmony_ci    this._handle.close();
18191cb0ef41Sopenharmony_ci    this._handle = null;
18201cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(this[async_id_symbol],
18211cb0ef41Sopenharmony_ci                               process.nextTick,
18221cb0ef41Sopenharmony_ci                               emitErrorNT,
18231cb0ef41Sopenharmony_ci                               this,
18241cb0ef41Sopenharmony_ci                               ex);
18251cb0ef41Sopenharmony_ci    return;
18261cb0ef41Sopenharmony_ci  }
18271cb0ef41Sopenharmony_ci
18281cb0ef41Sopenharmony_ci  // Generate connection key, this should be unique to the connection
18291cb0ef41Sopenharmony_ci  this._connectionKey = addressType + ':' + address + ':' + port;
18301cb0ef41Sopenharmony_ci
18311cb0ef41Sopenharmony_ci  // Unref the handle if the server was unref'ed prior to listening
18321cb0ef41Sopenharmony_ci  if (this._unref)
18331cb0ef41Sopenharmony_ci    this.unref();
18341cb0ef41Sopenharmony_ci
18351cb0ef41Sopenharmony_ci  defaultTriggerAsyncIdScope(this[async_id_symbol],
18361cb0ef41Sopenharmony_ci                             process.nextTick,
18371cb0ef41Sopenharmony_ci                             emitListeningNT,
18381cb0ef41Sopenharmony_ci                             this);
18391cb0ef41Sopenharmony_ci}
18401cb0ef41Sopenharmony_ci
18411cb0ef41Sopenharmony_ciServer.prototype._listen2 = setupListenHandle;  // legacy alias
18421cb0ef41Sopenharmony_ci
18431cb0ef41Sopenharmony_cifunction emitErrorNT(self, err) {
18441cb0ef41Sopenharmony_ci  self.emit('error', err);
18451cb0ef41Sopenharmony_ci}
18461cb0ef41Sopenharmony_ci
18471cb0ef41Sopenharmony_ci
18481cb0ef41Sopenharmony_cifunction emitListeningNT(self) {
18491cb0ef41Sopenharmony_ci  // Ensure handle hasn't closed
18501cb0ef41Sopenharmony_ci  if (self._handle)
18511cb0ef41Sopenharmony_ci    self.emit('listening');
18521cb0ef41Sopenharmony_ci}
18531cb0ef41Sopenharmony_ci
18541cb0ef41Sopenharmony_ci
18551cb0ef41Sopenharmony_cifunction listenInCluster(server, address, port, addressType,
18561cb0ef41Sopenharmony_ci                         backlog, fd, exclusive, flags, options) {
18571cb0ef41Sopenharmony_ci  exclusive = !!exclusive;
18581cb0ef41Sopenharmony_ci
18591cb0ef41Sopenharmony_ci  if (cluster === undefined) cluster = require('cluster');
18601cb0ef41Sopenharmony_ci
18611cb0ef41Sopenharmony_ci  if (cluster.isPrimary || exclusive) {
18621cb0ef41Sopenharmony_ci    // Will create a new handle
18631cb0ef41Sopenharmony_ci    // _listen2 sets up the listened handle, it is still named like this
18641cb0ef41Sopenharmony_ci    // to avoid breaking code that wraps this method
18651cb0ef41Sopenharmony_ci    server._listen2(address, port, addressType, backlog, fd, flags);
18661cb0ef41Sopenharmony_ci    return;
18671cb0ef41Sopenharmony_ci  }
18681cb0ef41Sopenharmony_ci
18691cb0ef41Sopenharmony_ci  const serverQuery = {
18701cb0ef41Sopenharmony_ci    address: address,
18711cb0ef41Sopenharmony_ci    port: port,
18721cb0ef41Sopenharmony_ci    addressType: addressType,
18731cb0ef41Sopenharmony_ci    fd: fd,
18741cb0ef41Sopenharmony_ci    flags,
18751cb0ef41Sopenharmony_ci    backlog,
18761cb0ef41Sopenharmony_ci    ...options,
18771cb0ef41Sopenharmony_ci  };
18781cb0ef41Sopenharmony_ci  // Get the primary's server handle, and listen on it
18791cb0ef41Sopenharmony_ci  cluster._getServer(server, serverQuery, listenOnPrimaryHandle);
18801cb0ef41Sopenharmony_ci
18811cb0ef41Sopenharmony_ci  function listenOnPrimaryHandle(err, handle) {
18821cb0ef41Sopenharmony_ci    err = checkBindError(err, port, handle);
18831cb0ef41Sopenharmony_ci
18841cb0ef41Sopenharmony_ci    if (err) {
18851cb0ef41Sopenharmony_ci      const ex = exceptionWithHostPort(err, 'bind', address, port);
18861cb0ef41Sopenharmony_ci      return server.emit('error', ex);
18871cb0ef41Sopenharmony_ci    }
18881cb0ef41Sopenharmony_ci
18891cb0ef41Sopenharmony_ci    // Reuse primary's server handle
18901cb0ef41Sopenharmony_ci    server._handle = handle;
18911cb0ef41Sopenharmony_ci    // _listen2 sets up the listened handle, it is still named like this
18921cb0ef41Sopenharmony_ci    // to avoid breaking code that wraps this method
18931cb0ef41Sopenharmony_ci    server._listen2(address, port, addressType, backlog, fd, flags);
18941cb0ef41Sopenharmony_ci  }
18951cb0ef41Sopenharmony_ci}
18961cb0ef41Sopenharmony_ci
18971cb0ef41Sopenharmony_ci
18981cb0ef41Sopenharmony_ciServer.prototype.listen = function(...args) {
18991cb0ef41Sopenharmony_ci  const normalized = normalizeArgs(args);
19001cb0ef41Sopenharmony_ci  let options = normalized[0];
19011cb0ef41Sopenharmony_ci  const cb = normalized[1];
19021cb0ef41Sopenharmony_ci
19031cb0ef41Sopenharmony_ci  if (this._handle) {
19041cb0ef41Sopenharmony_ci    throw new ERR_SERVER_ALREADY_LISTEN();
19051cb0ef41Sopenharmony_ci  }
19061cb0ef41Sopenharmony_ci
19071cb0ef41Sopenharmony_ci  if (cb !== null) {
19081cb0ef41Sopenharmony_ci    this.once('listening', cb);
19091cb0ef41Sopenharmony_ci  }
19101cb0ef41Sopenharmony_ci  const backlogFromArgs =
19111cb0ef41Sopenharmony_ci    // (handle, backlog) or (path, backlog) or (port, backlog)
19121cb0ef41Sopenharmony_ci    toNumber(args.length > 1 && args[1]) ||
19131cb0ef41Sopenharmony_ci    toNumber(args.length > 2 && args[2]);  // (port, host, backlog)
19141cb0ef41Sopenharmony_ci
19151cb0ef41Sopenharmony_ci  options = options._handle || options.handle || options;
19161cb0ef41Sopenharmony_ci  const flags = getFlags(options.ipv6Only);
19171cb0ef41Sopenharmony_ci  // (handle[, backlog][, cb]) where handle is an object with a handle
19181cb0ef41Sopenharmony_ci  if (options instanceof TCP) {
19191cb0ef41Sopenharmony_ci    this._handle = options;
19201cb0ef41Sopenharmony_ci    this[async_id_symbol] = this._handle.getAsyncId();
19211cb0ef41Sopenharmony_ci    listenInCluster(this, null, -1, -1, backlogFromArgs);
19221cb0ef41Sopenharmony_ci    return this;
19231cb0ef41Sopenharmony_ci  }
19241cb0ef41Sopenharmony_ci  addAbortSignalOption(this, options);
19251cb0ef41Sopenharmony_ci  // (handle[, backlog][, cb]) where handle is an object with a fd
19261cb0ef41Sopenharmony_ci  if (typeof options.fd === 'number' && options.fd >= 0) {
19271cb0ef41Sopenharmony_ci    listenInCluster(this, null, null, null, backlogFromArgs, options.fd);
19281cb0ef41Sopenharmony_ci    return this;
19291cb0ef41Sopenharmony_ci  }
19301cb0ef41Sopenharmony_ci
19311cb0ef41Sopenharmony_ci  // ([port][, host][, backlog][, cb]) where port is omitted,
19321cb0ef41Sopenharmony_ci  // that is, listen(), listen(null), listen(cb), or listen(null, cb)
19331cb0ef41Sopenharmony_ci  // or (options[, cb]) where options.port is explicitly set as undefined or
19341cb0ef41Sopenharmony_ci  // null, bind to an arbitrary unused port
19351cb0ef41Sopenharmony_ci  if (args.length === 0 || typeof args[0] === 'function' ||
19361cb0ef41Sopenharmony_ci      (typeof options.port === 'undefined' && 'port' in options) ||
19371cb0ef41Sopenharmony_ci      options.port === null) {
19381cb0ef41Sopenharmony_ci    options.port = 0;
19391cb0ef41Sopenharmony_ci  }
19401cb0ef41Sopenharmony_ci  // ([port][, host][, backlog][, cb]) where port is specified
19411cb0ef41Sopenharmony_ci  // or (options[, cb]) where options.port is specified
19421cb0ef41Sopenharmony_ci  // or if options.port is normalized as 0 before
19431cb0ef41Sopenharmony_ci  let backlog;
19441cb0ef41Sopenharmony_ci  if (typeof options.port === 'number' || typeof options.port === 'string') {
19451cb0ef41Sopenharmony_ci    validatePort(options.port, 'options.port');
19461cb0ef41Sopenharmony_ci    backlog = options.backlog || backlogFromArgs;
19471cb0ef41Sopenharmony_ci    // start TCP server listening on host:port
19481cb0ef41Sopenharmony_ci    if (options.host) {
19491cb0ef41Sopenharmony_ci      lookupAndListen(this, options.port | 0, options.host, backlog,
19501cb0ef41Sopenharmony_ci                      options.exclusive, flags);
19511cb0ef41Sopenharmony_ci    } else { // Undefined host, listens on unspecified address
19521cb0ef41Sopenharmony_ci      // Default addressType 4 will be used to search for primary server
19531cb0ef41Sopenharmony_ci      listenInCluster(this, null, options.port | 0, 4,
19541cb0ef41Sopenharmony_ci                      backlog, undefined, options.exclusive);
19551cb0ef41Sopenharmony_ci    }
19561cb0ef41Sopenharmony_ci    return this;
19571cb0ef41Sopenharmony_ci  }
19581cb0ef41Sopenharmony_ci
19591cb0ef41Sopenharmony_ci  // (path[, backlog][, cb]) or (options[, cb])
19601cb0ef41Sopenharmony_ci  // where path or options.path is a UNIX domain socket or Windows pipe
19611cb0ef41Sopenharmony_ci  if (options.path && isPipeName(options.path)) {
19621cb0ef41Sopenharmony_ci    const pipeName = this._pipeName = options.path;
19631cb0ef41Sopenharmony_ci    backlog = options.backlog || backlogFromArgs;
19641cb0ef41Sopenharmony_ci    listenInCluster(this,
19651cb0ef41Sopenharmony_ci                    pipeName,
19661cb0ef41Sopenharmony_ci                    -1,
19671cb0ef41Sopenharmony_ci                    -1,
19681cb0ef41Sopenharmony_ci                    backlog,
19691cb0ef41Sopenharmony_ci                    undefined,
19701cb0ef41Sopenharmony_ci                    options.exclusive,
19711cb0ef41Sopenharmony_ci                    undefined,
19721cb0ef41Sopenharmony_ci                    {
19731cb0ef41Sopenharmony_ci                      readableAll: options.readableAll,
19741cb0ef41Sopenharmony_ci                      writableAll: options.writableAll,
19751cb0ef41Sopenharmony_ci                    });
19761cb0ef41Sopenharmony_ci
19771cb0ef41Sopenharmony_ci    if (!this._handle) {
19781cb0ef41Sopenharmony_ci      // Failed and an error shall be emitted in the next tick.
19791cb0ef41Sopenharmony_ci      // Therefore, we directly return.
19801cb0ef41Sopenharmony_ci      return this;
19811cb0ef41Sopenharmony_ci    }
19821cb0ef41Sopenharmony_ci
19831cb0ef41Sopenharmony_ci    let mode = 0;
19841cb0ef41Sopenharmony_ci    if (options.readableAll === true)
19851cb0ef41Sopenharmony_ci      mode |= PipeConstants.UV_READABLE;
19861cb0ef41Sopenharmony_ci    if (options.writableAll === true)
19871cb0ef41Sopenharmony_ci      mode |= PipeConstants.UV_WRITABLE;
19881cb0ef41Sopenharmony_ci    if (mode !== 0) {
19891cb0ef41Sopenharmony_ci      const err = this._handle.fchmod(mode);
19901cb0ef41Sopenharmony_ci      if (err) {
19911cb0ef41Sopenharmony_ci        this._handle.close();
19921cb0ef41Sopenharmony_ci        this._handle = null;
19931cb0ef41Sopenharmony_ci        throw errnoException(err, 'uv_pipe_chmod');
19941cb0ef41Sopenharmony_ci      }
19951cb0ef41Sopenharmony_ci    }
19961cb0ef41Sopenharmony_ci    return this;
19971cb0ef41Sopenharmony_ci  }
19981cb0ef41Sopenharmony_ci
19991cb0ef41Sopenharmony_ci  if (!(('port' in options) || ('path' in options))) {
20001cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_VALUE('options', options,
20011cb0ef41Sopenharmony_ci                                    'must have the property "port" or "path"');
20021cb0ef41Sopenharmony_ci  }
20031cb0ef41Sopenharmony_ci
20041cb0ef41Sopenharmony_ci  throw new ERR_INVALID_ARG_VALUE('options', options);
20051cb0ef41Sopenharmony_ci};
20061cb0ef41Sopenharmony_ci
20071cb0ef41Sopenharmony_cifunction lookupAndListen(self, port, address, backlog, exclusive, flags) {
20081cb0ef41Sopenharmony_ci  if (dns === undefined) dns = require('dns');
20091cb0ef41Sopenharmony_ci  dns.lookup(address, function doListen(err, ip, addressType) {
20101cb0ef41Sopenharmony_ci    if (err) {
20111cb0ef41Sopenharmony_ci      self.emit('error', err);
20121cb0ef41Sopenharmony_ci    } else {
20131cb0ef41Sopenharmony_ci      addressType = ip ? addressType : 4;
20141cb0ef41Sopenharmony_ci      listenInCluster(self, ip, port, addressType,
20151cb0ef41Sopenharmony_ci                      backlog, undefined, exclusive, flags);
20161cb0ef41Sopenharmony_ci    }
20171cb0ef41Sopenharmony_ci  });
20181cb0ef41Sopenharmony_ci}
20191cb0ef41Sopenharmony_ci
20201cb0ef41Sopenharmony_ciObjectDefineProperty(Server.prototype, 'listening', {
20211cb0ef41Sopenharmony_ci  __proto__: null,
20221cb0ef41Sopenharmony_ci  get: function() {
20231cb0ef41Sopenharmony_ci    return !!this._handle;
20241cb0ef41Sopenharmony_ci  },
20251cb0ef41Sopenharmony_ci  configurable: true,
20261cb0ef41Sopenharmony_ci  enumerable: true,
20271cb0ef41Sopenharmony_ci});
20281cb0ef41Sopenharmony_ci
20291cb0ef41Sopenharmony_ciServer.prototype.address = function() {
20301cb0ef41Sopenharmony_ci  if (this._handle && this._handle.getsockname) {
20311cb0ef41Sopenharmony_ci    const out = {};
20321cb0ef41Sopenharmony_ci    const err = this._handle.getsockname(out);
20331cb0ef41Sopenharmony_ci    if (err) {
20341cb0ef41Sopenharmony_ci      throw errnoException(err, 'address');
20351cb0ef41Sopenharmony_ci    }
20361cb0ef41Sopenharmony_ci    return out;
20371cb0ef41Sopenharmony_ci  } else if (this._pipeName) {
20381cb0ef41Sopenharmony_ci    return this._pipeName;
20391cb0ef41Sopenharmony_ci  }
20401cb0ef41Sopenharmony_ci  return null;
20411cb0ef41Sopenharmony_ci};
20421cb0ef41Sopenharmony_ci
20431cb0ef41Sopenharmony_cifunction onconnection(err, clientHandle) {
20441cb0ef41Sopenharmony_ci  const handle = this;
20451cb0ef41Sopenharmony_ci  const self = handle[owner_symbol];
20461cb0ef41Sopenharmony_ci
20471cb0ef41Sopenharmony_ci  debug('onconnection');
20481cb0ef41Sopenharmony_ci
20491cb0ef41Sopenharmony_ci  if (err) {
20501cb0ef41Sopenharmony_ci    self.emit('error', errnoException(err, 'accept'));
20511cb0ef41Sopenharmony_ci    return;
20521cb0ef41Sopenharmony_ci  }
20531cb0ef41Sopenharmony_ci
20541cb0ef41Sopenharmony_ci  if (self.maxConnections && self._connections >= self.maxConnections) {
20551cb0ef41Sopenharmony_ci    if (clientHandle.getsockname || clientHandle.getpeername) {
20561cb0ef41Sopenharmony_ci      const data = ObjectCreate(null);
20571cb0ef41Sopenharmony_ci      if (clientHandle.getsockname) {
20581cb0ef41Sopenharmony_ci        const localInfo = ObjectCreate(null);
20591cb0ef41Sopenharmony_ci        clientHandle.getsockname(localInfo);
20601cb0ef41Sopenharmony_ci        data.localAddress = localInfo.address;
20611cb0ef41Sopenharmony_ci        data.localPort = localInfo.port;
20621cb0ef41Sopenharmony_ci        data.localFamily = localInfo.family;
20631cb0ef41Sopenharmony_ci      }
20641cb0ef41Sopenharmony_ci      if (clientHandle.getpeername) {
20651cb0ef41Sopenharmony_ci        const remoteInfo = ObjectCreate(null);
20661cb0ef41Sopenharmony_ci        clientHandle.getpeername(remoteInfo);
20671cb0ef41Sopenharmony_ci        data.remoteAddress = remoteInfo.address;
20681cb0ef41Sopenharmony_ci        data.remotePort = remoteInfo.port;
20691cb0ef41Sopenharmony_ci        data.remoteFamily = remoteInfo.family;
20701cb0ef41Sopenharmony_ci      }
20711cb0ef41Sopenharmony_ci      self.emit('drop', data);
20721cb0ef41Sopenharmony_ci    } else {
20731cb0ef41Sopenharmony_ci      self.emit('drop');
20741cb0ef41Sopenharmony_ci    }
20751cb0ef41Sopenharmony_ci    clientHandle.close();
20761cb0ef41Sopenharmony_ci    return;
20771cb0ef41Sopenharmony_ci  }
20781cb0ef41Sopenharmony_ci
20791cb0ef41Sopenharmony_ci  const socket = new Socket({
20801cb0ef41Sopenharmony_ci    handle: clientHandle,
20811cb0ef41Sopenharmony_ci    allowHalfOpen: self.allowHalfOpen,
20821cb0ef41Sopenharmony_ci    pauseOnCreate: self.pauseOnConnect,
20831cb0ef41Sopenharmony_ci    readable: true,
20841cb0ef41Sopenharmony_ci    writable: true,
20851cb0ef41Sopenharmony_ci    readableHighWaterMark: self.highWaterMark,
20861cb0ef41Sopenharmony_ci    writableHighWaterMark: self.highWaterMark,
20871cb0ef41Sopenharmony_ci  });
20881cb0ef41Sopenharmony_ci
20891cb0ef41Sopenharmony_ci  if (self.noDelay && clientHandle.setNoDelay) {
20901cb0ef41Sopenharmony_ci    socket[kSetNoDelay] = true;
20911cb0ef41Sopenharmony_ci    clientHandle.setNoDelay(true);
20921cb0ef41Sopenharmony_ci  }
20931cb0ef41Sopenharmony_ci  if (self.keepAlive && clientHandle.setKeepAlive) {
20941cb0ef41Sopenharmony_ci    socket[kSetKeepAlive] = true;
20951cb0ef41Sopenharmony_ci    socket[kSetKeepAliveInitialDelay] = self.keepAliveInitialDelay;
20961cb0ef41Sopenharmony_ci    clientHandle.setKeepAlive(true, self.keepAliveInitialDelay);
20971cb0ef41Sopenharmony_ci  }
20981cb0ef41Sopenharmony_ci
20991cb0ef41Sopenharmony_ci  self._connections++;
21001cb0ef41Sopenharmony_ci  socket.server = self;
21011cb0ef41Sopenharmony_ci  socket._server = self;
21021cb0ef41Sopenharmony_ci
21031cb0ef41Sopenharmony_ci  DTRACE_NET_SERVER_CONNECTION(socket);
21041cb0ef41Sopenharmony_ci  self.emit('connection', socket);
21051cb0ef41Sopenharmony_ci  lazyChannels();
21061cb0ef41Sopenharmony_ci  if (netServerSocketChannel.hasSubscribers) {
21071cb0ef41Sopenharmony_ci    netServerSocketChannel.publish({
21081cb0ef41Sopenharmony_ci      socket,
21091cb0ef41Sopenharmony_ci    });
21101cb0ef41Sopenharmony_ci  }
21111cb0ef41Sopenharmony_ci}
21121cb0ef41Sopenharmony_ci
21131cb0ef41Sopenharmony_ci/**
21141cb0ef41Sopenharmony_ci * Gets the number of concurrent connections on the server
21151cb0ef41Sopenharmony_ci * @param {Function} cb
21161cb0ef41Sopenharmony_ci * @returns {Server}
21171cb0ef41Sopenharmony_ci */
21181cb0ef41Sopenharmony_ci
21191cb0ef41Sopenharmony_ciServer.prototype.getConnections = function(cb) {
21201cb0ef41Sopenharmony_ci  const self = this;
21211cb0ef41Sopenharmony_ci
21221cb0ef41Sopenharmony_ci  function end(err, connections) {
21231cb0ef41Sopenharmony_ci    defaultTriggerAsyncIdScope(self[async_id_symbol],
21241cb0ef41Sopenharmony_ci                               process.nextTick,
21251cb0ef41Sopenharmony_ci                               cb,
21261cb0ef41Sopenharmony_ci                               err,
21271cb0ef41Sopenharmony_ci                               connections);
21281cb0ef41Sopenharmony_ci  }
21291cb0ef41Sopenharmony_ci
21301cb0ef41Sopenharmony_ci  if (!this._usingWorkers) {
21311cb0ef41Sopenharmony_ci    end(null, this._connections);
21321cb0ef41Sopenharmony_ci    return this;
21331cb0ef41Sopenharmony_ci  }
21341cb0ef41Sopenharmony_ci
21351cb0ef41Sopenharmony_ci  // Poll workers
21361cb0ef41Sopenharmony_ci  let left = this._workers.length;
21371cb0ef41Sopenharmony_ci  let total = this._connections;
21381cb0ef41Sopenharmony_ci
21391cb0ef41Sopenharmony_ci  function oncount(err, count) {
21401cb0ef41Sopenharmony_ci    if (err) {
21411cb0ef41Sopenharmony_ci      left = -1;
21421cb0ef41Sopenharmony_ci      return end(err);
21431cb0ef41Sopenharmony_ci    }
21441cb0ef41Sopenharmony_ci
21451cb0ef41Sopenharmony_ci    total += count;
21461cb0ef41Sopenharmony_ci    if (--left === 0) return end(null, total);
21471cb0ef41Sopenharmony_ci  }
21481cb0ef41Sopenharmony_ci
21491cb0ef41Sopenharmony_ci  for (let n = 0; n < this._workers.length; n++) {
21501cb0ef41Sopenharmony_ci    this._workers[n].getConnections(oncount);
21511cb0ef41Sopenharmony_ci  }
21521cb0ef41Sopenharmony_ci
21531cb0ef41Sopenharmony_ci  return this;
21541cb0ef41Sopenharmony_ci};
21551cb0ef41Sopenharmony_ci
21561cb0ef41Sopenharmony_ci
21571cb0ef41Sopenharmony_ciServer.prototype.close = function(cb) {
21581cb0ef41Sopenharmony_ci  if (typeof cb === 'function') {
21591cb0ef41Sopenharmony_ci    if (!this._handle) {
21601cb0ef41Sopenharmony_ci      this.once('close', function close() {
21611cb0ef41Sopenharmony_ci        cb(new ERR_SERVER_NOT_RUNNING());
21621cb0ef41Sopenharmony_ci      });
21631cb0ef41Sopenharmony_ci    } else {
21641cb0ef41Sopenharmony_ci      this.once('close', cb);
21651cb0ef41Sopenharmony_ci    }
21661cb0ef41Sopenharmony_ci  }
21671cb0ef41Sopenharmony_ci
21681cb0ef41Sopenharmony_ci  if (this._handle) {
21691cb0ef41Sopenharmony_ci    this._handle.close();
21701cb0ef41Sopenharmony_ci    this._handle = null;
21711cb0ef41Sopenharmony_ci  }
21721cb0ef41Sopenharmony_ci
21731cb0ef41Sopenharmony_ci  if (this._usingWorkers) {
21741cb0ef41Sopenharmony_ci    let left = this._workers.length;
21751cb0ef41Sopenharmony_ci    const onWorkerClose = () => {
21761cb0ef41Sopenharmony_ci      if (--left !== 0) return;
21771cb0ef41Sopenharmony_ci
21781cb0ef41Sopenharmony_ci      this._connections = 0;
21791cb0ef41Sopenharmony_ci      this._emitCloseIfDrained();
21801cb0ef41Sopenharmony_ci    };
21811cb0ef41Sopenharmony_ci
21821cb0ef41Sopenharmony_ci    // Increment connections to be sure that, even if all sockets will be closed
21831cb0ef41Sopenharmony_ci    // during polling of workers, `close` event will be emitted only once.
21841cb0ef41Sopenharmony_ci    this._connections++;
21851cb0ef41Sopenharmony_ci
21861cb0ef41Sopenharmony_ci    // Poll workers
21871cb0ef41Sopenharmony_ci    for (let n = 0; n < this._workers.length; n++)
21881cb0ef41Sopenharmony_ci      this._workers[n].close(onWorkerClose);
21891cb0ef41Sopenharmony_ci  } else {
21901cb0ef41Sopenharmony_ci    this._emitCloseIfDrained();
21911cb0ef41Sopenharmony_ci  }
21921cb0ef41Sopenharmony_ci
21931cb0ef41Sopenharmony_ci  return this;
21941cb0ef41Sopenharmony_ci};
21951cb0ef41Sopenharmony_ci
21961cb0ef41Sopenharmony_ciServer.prototype[SymbolAsyncDispose] = async function() {
21971cb0ef41Sopenharmony_ci  if (!this._handle) {
21981cb0ef41Sopenharmony_ci    return;
21991cb0ef41Sopenharmony_ci  }
22001cb0ef41Sopenharmony_ci  return FunctionPrototypeCall(promisify(this.close), this);
22011cb0ef41Sopenharmony_ci};
22021cb0ef41Sopenharmony_ci
22031cb0ef41Sopenharmony_ciServer.prototype._emitCloseIfDrained = function() {
22041cb0ef41Sopenharmony_ci  debug('SERVER _emitCloseIfDrained');
22051cb0ef41Sopenharmony_ci
22061cb0ef41Sopenharmony_ci  if (this._handle || this._connections) {
22071cb0ef41Sopenharmony_ci    debug('SERVER handle? %j   connections? %d',
22081cb0ef41Sopenharmony_ci          !!this._handle, this._connections);
22091cb0ef41Sopenharmony_ci    return;
22101cb0ef41Sopenharmony_ci  }
22111cb0ef41Sopenharmony_ci
22121cb0ef41Sopenharmony_ci  defaultTriggerAsyncIdScope(this[async_id_symbol],
22131cb0ef41Sopenharmony_ci                             process.nextTick,
22141cb0ef41Sopenharmony_ci                             emitCloseNT,
22151cb0ef41Sopenharmony_ci                             this);
22161cb0ef41Sopenharmony_ci};
22171cb0ef41Sopenharmony_ci
22181cb0ef41Sopenharmony_ci
22191cb0ef41Sopenharmony_cifunction emitCloseNT(self) {
22201cb0ef41Sopenharmony_ci  debug('SERVER: emit close');
22211cb0ef41Sopenharmony_ci  self.emit('close');
22221cb0ef41Sopenharmony_ci}
22231cb0ef41Sopenharmony_ci
22241cb0ef41Sopenharmony_ci
22251cb0ef41Sopenharmony_ciServer.prototype[EventEmitter.captureRejectionSymbol] = function(
22261cb0ef41Sopenharmony_ci  err, event, sock) {
22271cb0ef41Sopenharmony_ci
22281cb0ef41Sopenharmony_ci  switch (event) {
22291cb0ef41Sopenharmony_ci    case 'connection':
22301cb0ef41Sopenharmony_ci      sock.destroy(err);
22311cb0ef41Sopenharmony_ci      break;
22321cb0ef41Sopenharmony_ci    default:
22331cb0ef41Sopenharmony_ci      this.emit('error', err);
22341cb0ef41Sopenharmony_ci  }
22351cb0ef41Sopenharmony_ci};
22361cb0ef41Sopenharmony_ci
22371cb0ef41Sopenharmony_ci
22381cb0ef41Sopenharmony_ci// Legacy alias on the C++ wrapper object. This is not public API, so we may
22391cb0ef41Sopenharmony_ci// want to runtime-deprecate it at some point. There's no hurry, though.
22401cb0ef41Sopenharmony_ciObjectDefineProperty(TCP.prototype, 'owner', {
22411cb0ef41Sopenharmony_ci  __proto__: null,
22421cb0ef41Sopenharmony_ci  get() { return this[owner_symbol]; },
22431cb0ef41Sopenharmony_ci  set(v) { return this[owner_symbol] = v; },
22441cb0ef41Sopenharmony_ci});
22451cb0ef41Sopenharmony_ci
22461cb0ef41Sopenharmony_ciObjectDefineProperty(Socket.prototype, '_handle', {
22471cb0ef41Sopenharmony_ci  __proto__: null,
22481cb0ef41Sopenharmony_ci  get() { return this[kHandle]; },
22491cb0ef41Sopenharmony_ci  set(v) { return this[kHandle] = v; },
22501cb0ef41Sopenharmony_ci});
22511cb0ef41Sopenharmony_ci
22521cb0ef41Sopenharmony_ciServer.prototype._setupWorker = function(socketList) {
22531cb0ef41Sopenharmony_ci  this._usingWorkers = true;
22541cb0ef41Sopenharmony_ci  this._workers.push(socketList);
22551cb0ef41Sopenharmony_ci  socketList.once('exit', (socketList) => {
22561cb0ef41Sopenharmony_ci    const index = ArrayPrototypeIndexOf(this._workers, socketList);
22571cb0ef41Sopenharmony_ci    this._workers.splice(index, 1);
22581cb0ef41Sopenharmony_ci  });
22591cb0ef41Sopenharmony_ci};
22601cb0ef41Sopenharmony_ci
22611cb0ef41Sopenharmony_ciServer.prototype.ref = function() {
22621cb0ef41Sopenharmony_ci  this._unref = false;
22631cb0ef41Sopenharmony_ci
22641cb0ef41Sopenharmony_ci  if (this._handle)
22651cb0ef41Sopenharmony_ci    this._handle.ref();
22661cb0ef41Sopenharmony_ci
22671cb0ef41Sopenharmony_ci  return this;
22681cb0ef41Sopenharmony_ci};
22691cb0ef41Sopenharmony_ci
22701cb0ef41Sopenharmony_ciServer.prototype.unref = function() {
22711cb0ef41Sopenharmony_ci  this._unref = true;
22721cb0ef41Sopenharmony_ci
22731cb0ef41Sopenharmony_ci  if (this._handle)
22741cb0ef41Sopenharmony_ci    this._handle.unref();
22751cb0ef41Sopenharmony_ci
22761cb0ef41Sopenharmony_ci  return this;
22771cb0ef41Sopenharmony_ci};
22781cb0ef41Sopenharmony_ci
22791cb0ef41Sopenharmony_cilet _setSimultaneousAccepts;
22801cb0ef41Sopenharmony_cilet warnSimultaneousAccepts = true;
22811cb0ef41Sopenharmony_ci
22821cb0ef41Sopenharmony_ciif (isWindows) {
22831cb0ef41Sopenharmony_ci  let simultaneousAccepts;
22841cb0ef41Sopenharmony_ci
22851cb0ef41Sopenharmony_ci  _setSimultaneousAccepts = function(handle) {
22861cb0ef41Sopenharmony_ci    if (warnSimultaneousAccepts) {
22871cb0ef41Sopenharmony_ci      process.emitWarning(
22881cb0ef41Sopenharmony_ci        'net._setSimultaneousAccepts() is deprecated and will be removed.',
22891cb0ef41Sopenharmony_ci        'DeprecationWarning', 'DEP0121');
22901cb0ef41Sopenharmony_ci      warnSimultaneousAccepts = false;
22911cb0ef41Sopenharmony_ci    }
22921cb0ef41Sopenharmony_ci    if (handle === undefined) {
22931cb0ef41Sopenharmony_ci      return;
22941cb0ef41Sopenharmony_ci    }
22951cb0ef41Sopenharmony_ci
22961cb0ef41Sopenharmony_ci    if (simultaneousAccepts === undefined) {
22971cb0ef41Sopenharmony_ci      simultaneousAccepts = (process.env.NODE_MANY_ACCEPTS &&
22981cb0ef41Sopenharmony_ci                             process.env.NODE_MANY_ACCEPTS !== '0');
22991cb0ef41Sopenharmony_ci    }
23001cb0ef41Sopenharmony_ci
23011cb0ef41Sopenharmony_ci    if (handle._simultaneousAccepts !== simultaneousAccepts) {
23021cb0ef41Sopenharmony_ci      handle.setSimultaneousAccepts(!!simultaneousAccepts);
23031cb0ef41Sopenharmony_ci      handle._simultaneousAccepts = simultaneousAccepts;
23041cb0ef41Sopenharmony_ci    }
23051cb0ef41Sopenharmony_ci  };
23061cb0ef41Sopenharmony_ci} else {
23071cb0ef41Sopenharmony_ci  _setSimultaneousAccepts = function() {
23081cb0ef41Sopenharmony_ci    if (warnSimultaneousAccepts) {
23091cb0ef41Sopenharmony_ci      process.emitWarning(
23101cb0ef41Sopenharmony_ci        'net._setSimultaneousAccepts() is deprecated and will be removed.',
23111cb0ef41Sopenharmony_ci        'DeprecationWarning', 'DEP0121');
23121cb0ef41Sopenharmony_ci      warnSimultaneousAccepts = false;
23131cb0ef41Sopenharmony_ci    }
23141cb0ef41Sopenharmony_ci  };
23151cb0ef41Sopenharmony_ci}
23161cb0ef41Sopenharmony_ci
23171cb0ef41Sopenharmony_cimodule.exports = {
23181cb0ef41Sopenharmony_ci  _createServerHandle: createServerHandle,
23191cb0ef41Sopenharmony_ci  _normalizeArgs: normalizeArgs,
23201cb0ef41Sopenharmony_ci  _setSimultaneousAccepts,
23211cb0ef41Sopenharmony_ci  get BlockList() {
23221cb0ef41Sopenharmony_ci    BlockList ??= require('internal/blocklist').BlockList;
23231cb0ef41Sopenharmony_ci    return BlockList;
23241cb0ef41Sopenharmony_ci  },
23251cb0ef41Sopenharmony_ci  get SocketAddress() {
23261cb0ef41Sopenharmony_ci    SocketAddress ??= require('internal/socketaddress').SocketAddress;
23271cb0ef41Sopenharmony_ci    return SocketAddress;
23281cb0ef41Sopenharmony_ci  },
23291cb0ef41Sopenharmony_ci  connect,
23301cb0ef41Sopenharmony_ci  createConnection: connect,
23311cb0ef41Sopenharmony_ci  createServer,
23321cb0ef41Sopenharmony_ci  isIP: isIP,
23331cb0ef41Sopenharmony_ci  isIPv4: isIPv4,
23341cb0ef41Sopenharmony_ci  isIPv6: isIPv6,
23351cb0ef41Sopenharmony_ci  Server,
23361cb0ef41Sopenharmony_ci  Socket,
23371cb0ef41Sopenharmony_ci  Stream: Socket, // Legacy naming
23381cb0ef41Sopenharmony_ci  getDefaultAutoSelectFamily,
23391cb0ef41Sopenharmony_ci  setDefaultAutoSelectFamily,
23401cb0ef41Sopenharmony_ci  getDefaultAutoSelectFamilyAttemptTimeout,
23411cb0ef41Sopenharmony_ci  setDefaultAutoSelectFamilyAttemptTimeout,
23421cb0ef41Sopenharmony_ci};
2343