@webvpn/dgram 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/build/index.cjs +2235 -2327
  2. package/build/index.cjs.map +1 -1
  3. package/build/index.d.ts +5 -184
  4. package/build/index.js +10094 -2664
  5. package/build/index.js.map +1 -1
  6. package/package.json +4 -6
  7. package/src/index.ts +5 -698
  8. package/vite-plugin-node-stdlib-browser.cjs +61 -61
  9. package/vite.config.ts +29 -29
  10. package/build/index.mjs +0 -3252
  11. package/build/index.mjs.map +0 -1
  12. package/build/test.d.ts +0 -1
  13. package/build/utils.d.ts +0 -13
  14. package/index.html +0 -11
  15. package/src/chrome-dgram.js +0 -503
  16. package/src/flatbuffers/client-packet-type.ts +0 -40
  17. package/src/flatbuffers/client-packet.ts +0 -162
  18. package/src/flatbuffers/client-tcpserver-close.ts +0 -93
  19. package/src/flatbuffers/client-tcpserver-get-connections.ts +0 -93
  20. package/src/flatbuffers/client-tcpserver-listen.ts +0 -211
  21. package/src/flatbuffers/client-tcpserver.ts +0 -159
  22. package/src/flatbuffers/client-tcpsocket-connect.ts +0 -253
  23. package/src/flatbuffers/client-tcpsocket-destroy-soon.ts +0 -75
  24. package/src/flatbuffers/client-tcpsocket-destroy.ts +0 -93
  25. package/src/flatbuffers/client-tcpsocket-end.ts +0 -93
  26. package/src/flatbuffers/client-tcpsocket-pause.ts +0 -75
  27. package/src/flatbuffers/client-tcpsocket-reset-and-destroy.ts +0 -75
  28. package/src/flatbuffers/client-tcpsocket-resume.ts +0 -75
  29. package/src/flatbuffers/client-tcpsocket-set-encoding.ts +0 -93
  30. package/src/flatbuffers/client-tcpsocket-set-keep-alive.ts +0 -103
  31. package/src/flatbuffers/client-tcpsocket-set-no-delay.ts +0 -89
  32. package/src/flatbuffers/client-tcpsocket-set-timeout.ts +0 -107
  33. package/src/flatbuffers/client-tcpsocket-write.ts +0 -147
  34. package/src/flatbuffers/client-tcpsocket.ts +0 -89
  35. package/src/flatbuffers/client-udpsocket-add-membership.ts +0 -110
  36. package/src/flatbuffers/client-udpsocket-add-source-specific-membership.ts +0 -127
  37. package/src/flatbuffers/client-udpsocket-bind.ts +0 -138
  38. package/src/flatbuffers/client-udpsocket-close.ts +0 -93
  39. package/src/flatbuffers/client-udpsocket-disconnect.ts +0 -75
  40. package/src/flatbuffers/client-udpsocket-drop-membership.ts +0 -110
  41. package/src/flatbuffers/client-udpsocket-drop-source-specific-membership.ts +0 -127
  42. package/src/flatbuffers/client-udpsocket-send.ts +0 -189
  43. package/src/flatbuffers/client-udpsocket-set-broadcast.ts +0 -89
  44. package/src/flatbuffers/client-udpsocket-set-multicast-interface.ts +0 -93
  45. package/src/flatbuffers/client-udpsocket-set-multicast-loopback.ts +0 -89
  46. package/src/flatbuffers/client-udpsocket-set-multicast-ttl.ts +0 -89
  47. package/src/flatbuffers/client-udpsocket-set-recv-buffer-size.ts +0 -89
  48. package/src/flatbuffers/client-udpsocket-set-send-buffer-size.ts +0 -89
  49. package/src/flatbuffers/client-udpsocket-set-ttl.ts +0 -89
  50. package/src/flatbuffers/client-udpsocket.ts +0 -149
  51. package/src/flatbuffers/packet-handshake-type.ts +0 -9
  52. package/src/flatbuffers/packet.ts +0 -210
  53. package/src/flatbuffers/schema.ts +0 -75
  54. package/src/flatbuffers/server-packet-type.ts +0 -38
  55. package/src/flatbuffers/server-packet.ts +0 -158
  56. package/src/flatbuffers/server-tcpserver-callback-close.ts +0 -93
  57. package/src/flatbuffers/server-tcpserver-callback-get-connections.ts +0 -124
  58. package/src/flatbuffers/server-tcpserver-callback-listen.ts +0 -141
  59. package/src/flatbuffers/server-tcpserver-event-close.ts +0 -75
  60. package/src/flatbuffers/server-tcpserver-event-drop.ts +0 -75
  61. package/src/flatbuffers/server-tcpserver-event-error.ts +0 -75
  62. package/src/flatbuffers/server-tcpserver-event-listening.ts +0 -124
  63. package/src/flatbuffers/server-tcpsocket-callback-connect.ts +0 -189
  64. package/src/flatbuffers/server-tcpsocket-callback-end.ts +0 -93
  65. package/src/flatbuffers/server-tcpsocket-callback-set-timeout.ts +0 -93
  66. package/src/flatbuffers/server-tcpsocket-callback-write.ts +0 -93
  67. package/src/flatbuffers/server-tcpsocket-event-close.ts +0 -89
  68. package/src/flatbuffers/server-tcpsocket-event-connect.ts +0 -172
  69. package/src/flatbuffers/server-tcpsocket-event-connection-attempt-failed.ts +0 -138
  70. package/src/flatbuffers/server-tcpsocket-event-connection-attempt-timeout.ts +0 -121
  71. package/src/flatbuffers/server-tcpsocket-event-connection-attempt.ts +0 -121
  72. package/src/flatbuffers/server-tcpsocket-event-data.ts +0 -113
  73. package/src/flatbuffers/server-tcpsocket-event-drain.ts +0 -75
  74. package/src/flatbuffers/server-tcpsocket-event-end.ts +0 -75
  75. package/src/flatbuffers/server-tcpsocket-event-error.ts +0 -93
  76. package/src/flatbuffers/server-tcpsocket-event-lookup.ts +0 -141
  77. package/src/flatbuffers/server-tcpsocket-event-ready.ts +0 -75
  78. package/src/flatbuffers/server-tcpsocket-event-timeout.ts +0 -75
  79. package/src/flatbuffers/server-udpsocket-callback-bind.ts +0 -141
  80. package/src/flatbuffers/server-udpsocket-callback-close.ts +0 -93
  81. package/src/flatbuffers/server-udpsocket-callback-connect.ts +0 -141
  82. package/src/flatbuffers/server-udpsocket-callback-send.ts +0 -93
  83. package/src/flatbuffers/server-udpsocket-event-close.ts +0 -75
  84. package/src/flatbuffers/server-udpsocket-event-connect.ts +0 -75
  85. package/src/flatbuffers/server-udpsocket-event-error.ts +0 -93
  86. package/src/flatbuffers/server-udpsocket-event-listening.ts +0 -124
  87. package/src/flatbuffers/server-udpsocket-event-message.ts +0 -175
  88. package/src/net.js +0 -2442
  89. package/src/test.ts +0 -34
  90. package/src/types.ts +0 -16
  91. package/src/utils.ts +0 -45
package/src/net.js DELETED
@@ -1,2442 +0,0 @@
1
- // Copyright Joyent, Inc. and other Node contributors.
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a
4
- // copy of this software and associated documentation files (the
5
- // "Software"), to deal in the Software without restriction, including
6
- // without limitation the rights to use, copy, modify, merge, publish,
7
- // distribute, sublicense, and/or sell copies of the Software, and to permit
8
- // persons to whom the Software is furnished to do so, subject to the
9
- // following conditions:
10
- //
11
- // The above copyright notice and this permission notice shall be included
12
- // in all copies or substantial portions of the Software.
13
- //
14
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- 'use strict';
23
-
24
- const {
25
- ArrayIsArray,
26
- ArrayPrototypeIncludes,
27
- ArrayPrototypeIndexOf,
28
- ArrayPrototypePush,
29
- Boolean,
30
- FunctionPrototypeBind,
31
- FunctionPrototypeCall,
32
- MathMax,
33
- Number,
34
- NumberIsNaN,
35
- NumberParseInt,
36
- ObjectDefineProperty,
37
- ObjectSetPrototypeOf,
38
- Symbol,
39
- SymbolAsyncDispose,
40
- SymbolDispose,
41
- } = primordials;
42
-
43
- const EventEmitter = require('events');
44
- const { addAbortListener } = require('internal/events/abort_listener');
45
- const stream = require('stream');
46
- let debug = require('internal/util/debuglog').debuglog('net', (fn) => {
47
- debug = fn;
48
- });
49
- const {
50
- kReinitializeHandle,
51
- isIP,
52
- isIPv4,
53
- isIPv6,
54
- normalizedArgsSymbol,
55
- makeSyncWrite,
56
- } = require('internal/net');
57
- const assert = require('internal/assert');
58
- const {
59
- UV_EADDRINUSE,
60
- UV_EINVAL,
61
- UV_ENOTCONN,
62
- UV_ECANCELED,
63
- UV_ETIMEDOUT,
64
- } = internalBinding('uv');
65
-
66
- const { Buffer } = require('buffer');
67
- const { ShutdownWrap } = internalBinding('stream_wrap');
68
- const {
69
- TCP,
70
- TCPConnectWrap,
71
- constants: TCPConstants,
72
- } = internalBinding('tcp_wrap');
73
- const {
74
- Pipe,
75
- PipeConnectWrap,
76
- constants: PipeConstants,
77
- } = internalBinding('pipe_wrap');
78
- const {
79
- newAsyncId,
80
- defaultTriggerAsyncIdScope,
81
- symbols: { async_id_symbol, owner_symbol },
82
- } = require('internal/async_hooks');
83
- const {
84
- writevGeneric,
85
- writeGeneric,
86
- onStreamRead,
87
- kAfterAsyncWrite,
88
- kHandle,
89
- kUpdateTimer,
90
- setStreamTimeout,
91
- kBuffer,
92
- kBufferCb,
93
- kBufferGen,
94
- } = require('internal/stream_base_commons');
95
- const {
96
- ErrnoException,
97
- ExceptionWithHostPort,
98
- NodeAggregateError,
99
- UVExceptionWithHostPort,
100
- codes: {
101
- ERR_INVALID_ADDRESS_FAMILY,
102
- ERR_INVALID_ARG_TYPE,
103
- ERR_INVALID_ARG_VALUE,
104
- ERR_INVALID_FD_TYPE,
105
- ERR_INVALID_HANDLE_TYPE,
106
- ERR_INVALID_IP_ADDRESS,
107
- ERR_MISSING_ARGS,
108
- ERR_SERVER_ALREADY_LISTEN,
109
- ERR_SERVER_NOT_RUNNING,
110
- ERR_SOCKET_CLOSED,
111
- ERR_SOCKET_CLOSED_BEFORE_CONNECTION,
112
- ERR_SOCKET_CONNECTION_TIMEOUT,
113
- },
114
- genericNodeError,
115
- } = require('internal/errors');
116
- const { isUint8Array } = require('internal/util/types');
117
- const { queueMicrotask } = require('internal/process/task_queues');
118
- const { kEmptyObject, guessHandleType, promisify } = require('internal/util');
119
- const {
120
- validateAbortSignal,
121
- validateBoolean,
122
- validateFunction,
123
- validateInt32,
124
- validateNumber,
125
- validatePort,
126
- validateString,
127
- } = require('internal/validators');
128
- const kLastWriteQueueSize = Symbol('lastWriteQueueSize');
129
- const { getOptionValue } = require('internal/options');
130
-
131
- // Lazy loaded to improve startup performance.
132
- let cluster;
133
- let dns;
134
- let BlockList;
135
- let SocketAddress;
136
- let autoSelectFamilyDefault = getOptionValue('--network-family-autoselection');
137
- let autoSelectFamilyAttemptTimeoutDefault = getOptionValue('--network-family-autoselection-attempt-timeout');
138
-
139
- const { clearTimeout, setTimeout } = require('timers');
140
- const { kTimeout } = require('internal/timers');
141
-
142
- const DEFAULT_IPV4_ADDR = '0.0.0.0';
143
- const DEFAULT_IPV6_ADDR = '::';
144
-
145
- const isWindows = process.platform === 'win32';
146
-
147
- const noop = () => {};
148
-
149
- const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
150
-
151
- const dc = require('diagnostics_channel');
152
- const netClientSocketChannel = dc.channel('net.client.socket');
153
- const netServerSocketChannel = dc.channel('net.server.socket');
154
-
155
- const {
156
- hasObserver,
157
- startPerf,
158
- stopPerf,
159
- } = require('internal/perf/observe');
160
- const { getDefaultHighWaterMark } = require('internal/streams/state');
161
-
162
- function getFlags(ipv6Only) {
163
- return ipv6Only === true ? TCPConstants.UV_TCP_IPV6ONLY : 0;
164
- }
165
-
166
- function createHandle(fd, is_server) {
167
- validateInt32(fd, 'fd', 0);
168
- const type = guessHandleType(fd);
169
- if (type === 'PIPE') {
170
- return new Pipe(
171
- is_server ? PipeConstants.SERVER : PipeConstants.SOCKET,
172
- );
173
- }
174
-
175
- if (type === 'TCP') {
176
- return new TCP(
177
- is_server ? TCPConstants.SERVER : TCPConstants.SOCKET,
178
- );
179
- }
180
-
181
- throw new ERR_INVALID_FD_TYPE(type);
182
- }
183
-
184
-
185
- function getNewAsyncId(handle) {
186
- return (!handle || typeof handle.getAsyncId !== 'function') ?
187
- newAsyncId() : handle.getAsyncId();
188
- }
189
-
190
-
191
- function isPipeName(s) {
192
- return typeof s === 'string' && toNumber(s) === false;
193
- }
194
-
195
- /**
196
- * Creates a new TCP or IPC server
197
- * @param {{
198
- * allowHalfOpen?: boolean;
199
- * pauseOnConnect?: boolean;
200
- * }} [options]
201
- * @param {Function} [connectionListener]
202
- * @returns {Server}
203
- */
204
-
205
- function createServer(options, connectionListener) {
206
- return new Server(options, connectionListener);
207
- }
208
-
209
-
210
- // Target API:
211
- //
212
- // let s = net.connect({port: 80, host: 'google.com'}, function() {
213
- // ...
214
- // });
215
- //
216
- // There are various forms:
217
- //
218
- // connect(options, [cb])
219
- // connect(port, [host], [cb])
220
- // connect(path, [cb]);
221
- //
222
- function connect(...args) {
223
- const normalized = normalizeArgs(args);
224
- const options = normalized[0];
225
- debug('createConnection', normalized);
226
- const socket = new Socket(options);
227
-
228
- if (netClientSocketChannel.hasSubscribers) {
229
- netClientSocketChannel.publish({
230
- socket,
231
- });
232
- }
233
- if (options.timeout) {
234
- socket.setTimeout(options.timeout);
235
- }
236
-
237
- return socket.connect(normalized);
238
- }
239
-
240
- function getDefaultAutoSelectFamily() {
241
- return autoSelectFamilyDefault;
242
- }
243
-
244
- function setDefaultAutoSelectFamily(value) {
245
- validateBoolean(value, 'value');
246
- autoSelectFamilyDefault = value;
247
- }
248
-
249
- function getDefaultAutoSelectFamilyAttemptTimeout() {
250
- return autoSelectFamilyAttemptTimeoutDefault;
251
- }
252
-
253
- function setDefaultAutoSelectFamilyAttemptTimeout(value) {
254
- validateInt32(value, 'value', 1);
255
-
256
- if (value < 10) {
257
- value = 10;
258
- }
259
-
260
- autoSelectFamilyAttemptTimeoutDefault = value;
261
- }
262
-
263
- // Returns an array [options, cb], where options is an object,
264
- // cb is either a function or null.
265
- // Used to normalize arguments of Socket.prototype.connect() and
266
- // Server.prototype.listen(). Possible combinations of parameters:
267
- // (options[...][, cb])
268
- // (path[...][, cb])
269
- // ([port][, host][...][, cb])
270
- // For Socket.prototype.connect(), the [...] part is ignored
271
- // For Server.prototype.listen(), the [...] part is [, backlog]
272
- // but will not be handled here (handled in listen())
273
- function normalizeArgs(args) {
274
- let arr;
275
-
276
- if (args.length === 0) {
277
- arr = [{}, null];
278
- arr[normalizedArgsSymbol] = true;
279
- return arr;
280
- }
281
-
282
- const arg0 = args[0];
283
- let options = {};
284
- if (typeof arg0 === 'object' && arg0 !== null) {
285
- // (options[...][, cb])
286
- options = arg0;
287
- } else if (isPipeName(arg0)) {
288
- // (path[...][, cb])
289
- options.path = arg0;
290
- } else {
291
- // ([port][, host][...][, cb])
292
- options.port = arg0;
293
- if (args.length > 1 && typeof args[1] === 'string') {
294
- options.host = args[1];
295
- }
296
- }
297
-
298
- const cb = args[args.length - 1];
299
- if (typeof cb !== 'function')
300
- arr = [options, null];
301
- else
302
- arr = [options, cb];
303
-
304
- arr[normalizedArgsSymbol] = true;
305
- return arr;
306
- }
307
-
308
-
309
- // Called when creating new Socket, or when re-using a closed Socket
310
- function initSocketHandle(self) {
311
- self._undestroy();
312
- self._sockname = null;
313
-
314
- // Handle creation may be deferred to bind() or connect() time.
315
- if (self._handle) {
316
- self._handle[owner_symbol] = self;
317
- self._handle.onread = onStreamRead;
318
- self[async_id_symbol] = getNewAsyncId(self._handle);
319
-
320
- let userBuf = self[kBuffer];
321
- if (userBuf) {
322
- const bufGen = self[kBufferGen];
323
- if (bufGen !== null) {
324
- userBuf = bufGen();
325
- if (!isUint8Array(userBuf))
326
- return;
327
- self[kBuffer] = userBuf;
328
- }
329
- self._handle.useUserBuffer(userBuf);
330
- }
331
- }
332
- }
333
-
334
- function closeSocketHandle(self, isException, isCleanupPending = false) {
335
- if (self._handle) {
336
- self._handle.close(() => {
337
- debug('emit close');
338
- self.emit('close', isException);
339
- if (isCleanupPending) {
340
- self._handle.onread = noop;
341
- self._handle = null;
342
- self._sockname = null;
343
- }
344
- });
345
- }
346
- }
347
-
348
- const kBytesRead = Symbol('kBytesRead');
349
- const kBytesWritten = Symbol('kBytesWritten');
350
- const kSetNoDelay = Symbol('kSetNoDelay');
351
- const kSetKeepAlive = Symbol('kSetKeepAlive');
352
- const kSetKeepAliveInitialDelay = Symbol('kSetKeepAliveInitialDelay');
353
-
354
- function Socket(options) {
355
- if (!(this instanceof Socket)) return new Socket(options);
356
- if (options?.objectMode) {
357
- throw new ERR_INVALID_ARG_VALUE(
358
- 'options.objectMode',
359
- options.objectMode,
360
- 'is not supported',
361
- );
362
- } else if (options?.readableObjectMode || options?.writableObjectMode) {
363
- throw new ERR_INVALID_ARG_VALUE(
364
- `options.${
365
- options.readableObjectMode ? 'readableObjectMode' : 'writableObjectMode'
366
- }`,
367
- options.readableObjectMode || options.writableObjectMode,
368
- 'is not supported',
369
- );
370
- }
371
- if (typeof options?.keepAliveInitialDelay !== 'undefined') {
372
- validateNumber(
373
- options?.keepAliveInitialDelay, 'options.keepAliveInitialDelay',
374
- );
375
-
376
- if (options.keepAliveInitialDelay < 0) {
377
- options.keepAliveInitialDelay = 0;
378
- }
379
- }
380
-
381
- this.connecting = false;
382
- // Problem with this is that users can supply their own handle, that may not
383
- // have _handle.getAsyncId(). In this case an[async_id_symbol] should
384
- // probably be supplied by async_hooks.
385
- this[async_id_symbol] = -1;
386
- this._hadError = false;
387
- this[kHandle] = null;
388
- this._parent = null;
389
- this._host = null;
390
- this[kLastWriteQueueSize] = 0;
391
- this[kTimeout] = null;
392
- this[kBuffer] = null;
393
- this[kBufferCb] = null;
394
- this[kBufferGen] = null;
395
- this._closeAfterHandlingError = false;
396
-
397
- if (typeof options === 'number')
398
- options = { fd: options }; // Legacy interface.
399
- else
400
- options = { ...options };
401
-
402
- // Default to *not* allowing half open sockets.
403
- options.allowHalfOpen = Boolean(options.allowHalfOpen);
404
- // For backwards compat do not emit close on destroy.
405
- options.emitClose = false;
406
- options.autoDestroy = true;
407
- // Handle strings directly.
408
- options.decodeStrings = false;
409
- stream.Duplex.call(this, options);
410
-
411
- if (options.handle) {
412
- this._handle = options.handle; // private
413
- this[async_id_symbol] = getNewAsyncId(this._handle);
414
- } else if (options.fd !== undefined) {
415
- const { fd } = options;
416
- let err;
417
-
418
- // createHandle will throw ERR_INVALID_FD_TYPE if `fd` is not
419
- // a valid `PIPE` or `TCP` descriptor
420
- this._handle = createHandle(fd, false);
421
-
422
- err = this._handle.open(fd);
423
-
424
- // While difficult to fabricate, in some architectures
425
- // `open` may return an error code for valid file descriptors
426
- // which cannot be opened. This is difficult to test as most
427
- // un-openable fds will throw on `createHandle`
428
- if (err)
429
- throw new ErrnoException(err, 'open');
430
-
431
- this[async_id_symbol] = this._handle.getAsyncId();
432
-
433
- if ((fd === 1 || fd === 2) &&
434
- (this._handle instanceof Pipe) && isWindows) {
435
- // Make stdout and stderr blocking on Windows
436
- err = this._handle.setBlocking(true);
437
- if (err)
438
- throw new ErrnoException(err, 'setBlocking');
439
-
440
- this._writev = null;
441
- this._write = makeSyncWrite(fd);
442
- // makeSyncWrite adjusts this value like the original handle would, so
443
- // we need to let it do that by turning it into a writable, own
444
- // property.
445
- ObjectDefineProperty(this._handle, 'bytesWritten', {
446
- __proto__: null,
447
- value: 0, writable: true,
448
- });
449
- }
450
- }
451
-
452
- const onread = options.onread;
453
- if (onread !== null && typeof onread === 'object' &&
454
- (isUint8Array(onread.buffer) || typeof onread.buffer === 'function') &&
455
- typeof onread.callback === 'function') {
456
- if (typeof onread.buffer === 'function') {
457
- this[kBuffer] = true;
458
- this[kBufferGen] = onread.buffer;
459
- } else {
460
- this[kBuffer] = onread.buffer;
461
- }
462
- this[kBufferCb] = onread.callback;
463
- }
464
-
465
- this[kSetNoDelay] = Boolean(options.noDelay);
466
- this[kSetKeepAlive] = Boolean(options.keepAlive);
467
- this[kSetKeepAliveInitialDelay] = ~~(options.keepAliveInitialDelay / 1000);
468
-
469
- // Shut down the socket when we're finished with it.
470
- this.on('end', onReadableStreamEnd);
471
-
472
- initSocketHandle(this);
473
-
474
- this._pendingData = null;
475
- this._pendingEncoding = '';
476
-
477
- // If we have a handle, then start the flow of data into the
478
- // buffer. if not, then this will happen when we connect
479
- if (this._handle && options.readable !== false) {
480
- if (options.pauseOnCreate) {
481
- // Stop the handle from reading and pause the stream
482
- this._handle.reading = false;
483
- this._handle.readStop();
484
- this.readableFlowing = false;
485
- } else if (!options.manualStart) {
486
- this.read(0);
487
- }
488
- }
489
-
490
- if (options.signal) {
491
- addClientAbortSignalOption(this, options);
492
- }
493
-
494
- // Reserve properties
495
- this.server = null;
496
- this._server = null;
497
-
498
- // Used after `.destroy()`
499
- this[kBytesRead] = 0;
500
- this[kBytesWritten] = 0;
501
- }
502
- ObjectSetPrototypeOf(Socket.prototype, stream.Duplex.prototype);
503
- ObjectSetPrototypeOf(Socket, stream.Duplex);
504
-
505
- // Refresh existing timeouts.
506
- Socket.prototype._unrefTimer = function _unrefTimer() {
507
- for (let s = this; s !== null; s = s._parent) {
508
- if (s[kTimeout])
509
- s[kTimeout].refresh();
510
- }
511
- };
512
-
513
-
514
- // The user has called .end(), and all the bytes have been
515
- // sent out to the other side.
516
- Socket.prototype._final = function(cb) {
517
- // If still connecting - defer handling `_final` until 'connect' will happen
518
- if (this.connecting) {
519
- debug('_final: not yet connected');
520
- return this.once('connect', () => this._final(cb));
521
- }
522
-
523
- if (!this._handle)
524
- return cb();
525
-
526
- debug('_final: not ended, call shutdown()');
527
-
528
- const req = new ShutdownWrap();
529
- req.oncomplete = afterShutdown;
530
- req.handle = this._handle;
531
- req.callback = cb;
532
- const err = this._handle.shutdown(req);
533
-
534
- if (err === 1 || err === UV_ENOTCONN) // synchronous finish
535
- return cb();
536
- else if (err !== 0)
537
- return cb(new ErrnoException(err, 'shutdown'));
538
- };
539
-
540
- function afterShutdown() {
541
- const self = this.handle[owner_symbol];
542
-
543
- debug('afterShutdown destroyed=%j', self.destroyed);
544
-
545
- this.callback();
546
- }
547
-
548
- // Provide a better error message when we call end() as a result
549
- // of the other side sending a FIN. The standard 'write after end'
550
- // is overly vague, and makes it seem like the user's code is to blame.
551
- function writeAfterFIN(chunk, encoding, cb) {
552
- if (!this.writableEnded) {
553
- return stream.Duplex.prototype.write.call(this, chunk, encoding, cb);
554
- }
555
-
556
- if (typeof encoding === 'function') {
557
- cb = encoding;
558
- encoding = null;
559
- }
560
-
561
- const er = genericNodeError(
562
- 'This socket has been ended by the other party',
563
- { code: 'EPIPE' },
564
- );
565
- if (typeof cb === 'function') {
566
- defaultTriggerAsyncIdScope(this[async_id_symbol], process.nextTick, cb, er);
567
- }
568
- this.destroy(er);
569
-
570
- return false;
571
- }
572
-
573
- Socket.prototype.setTimeout = setStreamTimeout;
574
-
575
-
576
- Socket.prototype._onTimeout = function() {
577
- const handle = this._handle;
578
- const lastWriteQueueSize = this[kLastWriteQueueSize];
579
- if (lastWriteQueueSize > 0 && handle) {
580
- // `lastWriteQueueSize !== writeQueueSize` means there is
581
- // an active write in progress, so we suppress the timeout.
582
- const { writeQueueSize } = handle;
583
- if (lastWriteQueueSize !== writeQueueSize) {
584
- this[kLastWriteQueueSize] = writeQueueSize;
585
- this._unrefTimer();
586
- return;
587
- }
588
- }
589
- debug('_onTimeout');
590
- this.emit('timeout');
591
- };
592
-
593
-
594
- Socket.prototype.setNoDelay = function(enable) {
595
- // Backwards compatibility: assume true when `enable` is omitted
596
- enable = Boolean(enable === undefined ? true : enable);
597
-
598
- if (!this._handle) {
599
- this[kSetNoDelay] = enable;
600
- return this;
601
- }
602
-
603
- if (this._handle.setNoDelay && enable !== this[kSetNoDelay]) {
604
- this[kSetNoDelay] = enable;
605
- this._handle.setNoDelay(enable);
606
- }
607
-
608
- return this;
609
- };
610
-
611
-
612
- Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs) {
613
- enable = Boolean(enable);
614
- const initialDelay = ~~(initialDelayMsecs / 1000);
615
-
616
- if (!this._handle) {
617
- this[kSetKeepAlive] = enable;
618
- this[kSetKeepAliveInitialDelay] = initialDelay;
619
- return this;
620
- }
621
-
622
- if (!this._handle.setKeepAlive) {
623
- return this;
624
- }
625
-
626
- if (enable !== this[kSetKeepAlive] ||
627
- (
628
- enable &&
629
- this[kSetKeepAliveInitialDelay] !== initialDelay
630
- )
631
- ) {
632
- this[kSetKeepAlive] = enable;
633
- this[kSetKeepAliveInitialDelay] = initialDelay;
634
- this._handle.setKeepAlive(enable, initialDelay);
635
- }
636
-
637
- return this;
638
- };
639
-
640
-
641
- Socket.prototype.address = function() {
642
- return this._getsockname();
643
- };
644
-
645
-
646
- ObjectDefineProperty(Socket.prototype, '_connecting', {
647
- __proto__: null,
648
- get: function() {
649
- return this.connecting;
650
- },
651
- });
652
-
653
- ObjectDefineProperty(Socket.prototype, 'pending', {
654
- __proto__: null,
655
- get() {
656
- return !this._handle || this.connecting;
657
- },
658
- configurable: true,
659
- });
660
-
661
-
662
- ObjectDefineProperty(Socket.prototype, 'readyState', {
663
- __proto__: null,
664
- get: function() {
665
- if (this.connecting) {
666
- return 'opening';
667
- } else if (this.readable && this.writable) {
668
- return 'open';
669
- } else if (this.readable && !this.writable) {
670
- return 'readOnly';
671
- } else if (!this.readable && this.writable) {
672
- return 'writeOnly';
673
- }
674
- return 'closed';
675
- },
676
- });
677
-
678
-
679
- ObjectDefineProperty(Socket.prototype, 'bufferSize', {
680
- __proto__: null,
681
- get: function() {
682
- if (this._handle) {
683
- return this.writableLength;
684
- }
685
- },
686
- });
687
-
688
- ObjectDefineProperty(Socket.prototype, kUpdateTimer, {
689
- __proto__: null,
690
- get: function() {
691
- return this._unrefTimer;
692
- },
693
- });
694
-
695
-
696
- function tryReadStart(socket) {
697
- // Not already reading, start the flow
698
- debug('Socket._handle.readStart');
699
- socket._handle.reading = true;
700
- const err = socket._handle.readStart();
701
- if (err)
702
- socket.destroy(new ErrnoException(err, 'read'));
703
- }
704
-
705
- // Just call handle.readStart until we have enough in the buffer
706
- Socket.prototype._read = function(n) {
707
- debug(
708
- '_read - n', n,
709
- 'isConnecting?', !!this.connecting,
710
- 'hasHandle?', !!this._handle,
711
- );
712
-
713
- if (this.connecting || !this._handle) {
714
- debug('_read wait for connection');
715
- this.once('connect', () => this._read(n));
716
- } else if (!this._handle.reading) {
717
- tryReadStart(this);
718
- }
719
- };
720
-
721
-
722
- Socket.prototype.end = function(data, encoding, callback) {
723
- stream.Duplex.prototype.end.call(this,
724
- data, encoding, callback);
725
- return this;
726
- };
727
-
728
- Socket.prototype.resetAndDestroy = function() {
729
- if (this._handle) {
730
- if (!(this._handle instanceof TCP))
731
- throw new ERR_INVALID_HANDLE_TYPE();
732
- if (this.connecting) {
733
- debug('reset wait for connection');
734
- this.once('connect', () => this._reset());
735
- } else {
736
- this._reset();
737
- }
738
- } else {
739
- this.destroy(new ERR_SOCKET_CLOSED());
740
- }
741
- return this;
742
- };
743
-
744
- Socket.prototype.pause = function() {
745
- if (this[kBuffer] && !this.connecting && this._handle &&
746
- this._handle.reading) {
747
- this._handle.reading = false;
748
- if (!this.destroyed) {
749
- const err = this._handle.readStop();
750
- if (err)
751
- this.destroy(new ErrnoException(err, 'read'));
752
- }
753
- }
754
- return stream.Duplex.prototype.pause.call(this);
755
- };
756
-
757
-
758
- Socket.prototype.resume = function() {
759
- if (this[kBuffer] && !this.connecting && this._handle &&
760
- !this._handle.reading) {
761
- tryReadStart(this);
762
- }
763
- return stream.Duplex.prototype.resume.call(this);
764
- };
765
-
766
-
767
- Socket.prototype.read = function(n) {
768
- if (this[kBuffer] && !this.connecting && this._handle &&
769
- !this._handle.reading) {
770
- tryReadStart(this);
771
- }
772
- return stream.Duplex.prototype.read.call(this, n);
773
- };
774
-
775
-
776
- // Called when the 'end' event is emitted.
777
- function onReadableStreamEnd() {
778
- if (!this.allowHalfOpen) {
779
- this.write = writeAfterFIN;
780
- }
781
- }
782
-
783
-
784
- Socket.prototype.destroySoon = function() {
785
- if (this.writable)
786
- this.end();
787
-
788
- if (this.writableFinished)
789
- this.destroy();
790
- else
791
- this.once('finish', this.destroy);
792
- };
793
-
794
-
795
- Socket.prototype._destroy = function(exception, cb) {
796
- debug('destroy');
797
-
798
- this.connecting = false;
799
-
800
- for (let s = this; s !== null; s = s._parent) {
801
- clearTimeout(s[kTimeout]);
802
- }
803
-
804
- debug('close');
805
- if (this._handle) {
806
- if (this !== process.stderr)
807
- debug('close handle');
808
- const isException = exception ? true : false;
809
- // `bytesRead` and `kBytesWritten` should be accessible after `.destroy()`
810
- this[kBytesRead] = this._handle.bytesRead;
811
- this[kBytesWritten] = this._handle.bytesWritten;
812
-
813
- if (this.resetAndClosing) {
814
- this.resetAndClosing = false;
815
- const err = this._handle.reset(() => {
816
- debug('emit close');
817
- this.emit('close', isException);
818
- });
819
- if (err)
820
- this.emit('error', new ErrnoException(err, 'reset'));
821
- } else if (this._closeAfterHandlingError) {
822
- // Enqueue closing the socket as a microtask, so that the socket can be
823
- // accessible when an `error` event is handled in the `next tick queue`.
824
- queueMicrotask(() => closeSocketHandle(this, isException, true));
825
- } else {
826
- closeSocketHandle(this, isException);
827
- }
828
-
829
- if (!this._closeAfterHandlingError) {
830
- this._handle.onread = noop;
831
- this._handle = null;
832
- this._sockname = null;
833
- }
834
- cb(exception);
835
- } else {
836
- cb(exception);
837
- process.nextTick(emitCloseNT, this);
838
- }
839
-
840
- if (this._server) {
841
- debug('has server');
842
- this._server._connections--;
843
- if (this._server._emitCloseIfDrained) {
844
- this._server._emitCloseIfDrained();
845
- }
846
- }
847
- };
848
-
849
- Socket.prototype._reset = function() {
850
- debug('reset connection');
851
- this.resetAndClosing = true;
852
- return this.destroy();
853
- };
854
-
855
- Socket.prototype._getpeername = function() {
856
- if (!this._handle || !this._handle.getpeername || this.connecting) {
857
- return this._peername || {};
858
- } else if (!this._peername) {
859
- const out = {};
860
- const err = this._handle.getpeername(out);
861
- if (err) return out;
862
- this._peername = out;
863
- }
864
- return this._peername;
865
- };
866
-
867
- function protoGetter(name, callback) {
868
- ObjectDefineProperty(Socket.prototype, name, {
869
- __proto__: null,
870
- configurable: false,
871
- enumerable: true,
872
- get: callback,
873
- });
874
- }
875
-
876
- protoGetter('bytesRead', function bytesRead() {
877
- return this._handle ? this._handle.bytesRead : this[kBytesRead];
878
- });
879
-
880
- protoGetter('remoteAddress', function remoteAddress() {
881
- return this._getpeername().address;
882
- });
883
-
884
- protoGetter('remoteFamily', function remoteFamily() {
885
- return this._getpeername().family;
886
- });
887
-
888
- protoGetter('remotePort', function remotePort() {
889
- return this._getpeername().port;
890
- });
891
-
892
-
893
- Socket.prototype._getsockname = function() {
894
- if (!this._handle || !this._handle.getsockname) {
895
- return {};
896
- } else if (!this._sockname) {
897
- this._sockname = {};
898
- // FIXME(bnoordhuis) Throw when the return value is not 0?
899
- this._handle.getsockname(this._sockname);
900
- }
901
- return this._sockname;
902
- };
903
-
904
-
905
- protoGetter('localAddress', function localAddress() {
906
- return this._getsockname().address;
907
- });
908
-
909
-
910
- protoGetter('localPort', function localPort() {
911
- return this._getsockname().port;
912
- });
913
-
914
- protoGetter('localFamily', function localFamily() {
915
- return this._getsockname().family;
916
- });
917
-
918
- Socket.prototype[kAfterAsyncWrite] = function() {
919
- this[kLastWriteQueueSize] = 0;
920
- };
921
-
922
- Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
923
- // If we are still connecting, then buffer this for later.
924
- // The Writable logic will buffer up any more writes while
925
- // waiting for this one to be done.
926
- if (this.connecting) {
927
- this._pendingData = data;
928
- this._pendingEncoding = encoding;
929
- this.once('connect', function connect() {
930
- this.off('close', onClose);
931
- this._writeGeneric(writev, data, encoding, cb);
932
- });
933
- function onClose() {
934
- cb(new ERR_SOCKET_CLOSED_BEFORE_CONNECTION());
935
- }
936
- this.once('close', onClose);
937
- return;
938
- }
939
- this._pendingData = null;
940
- this._pendingEncoding = '';
941
-
942
- if (!this._handle) {
943
- cb(new ERR_SOCKET_CLOSED());
944
- return false;
945
- }
946
-
947
- this._unrefTimer();
948
-
949
- let req;
950
- if (writev)
951
- req = writevGeneric(this, data, cb);
952
- else
953
- req = writeGeneric(this, data, encoding, cb);
954
- if (req.async)
955
- this[kLastWriteQueueSize] = req.bytes;
956
- };
957
-
958
-
959
- Socket.prototype._writev = function(chunks, cb) {
960
- this._writeGeneric(true, chunks, '', cb);
961
- };
962
-
963
-
964
- Socket.prototype._write = function(data, encoding, cb) {
965
- this._writeGeneric(false, data, encoding, cb);
966
- };
967
-
968
-
969
- // Legacy alias. Having this is probably being overly cautious, but it doesn't
970
- // really hurt anyone either. This can probably be removed safely if desired.
971
- protoGetter('_bytesDispatched', function _bytesDispatched() {
972
- return this._handle ? this._handle.bytesWritten : this[kBytesWritten];
973
- });
974
-
975
- protoGetter('bytesWritten', function bytesWritten() {
976
- let bytes = this._bytesDispatched;
977
- const data = this._pendingData;
978
- const encoding = this._pendingEncoding;
979
- const writableBuffer = this.writableBuffer;
980
-
981
- if (!writableBuffer)
982
- return undefined;
983
-
984
- for (const el of writableBuffer) {
985
- bytes += el.chunk instanceof Buffer ?
986
- el.chunk.length :
987
- Buffer.byteLength(el.chunk, el.encoding);
988
- }
989
-
990
- if (ArrayIsArray(data)) {
991
- // Was a writev, iterate over chunks to get total length
992
- for (let i = 0; i < data.length; i++) {
993
- const chunk = data[i];
994
-
995
- if (data.allBuffers || chunk instanceof Buffer)
996
- bytes += chunk.length;
997
- else
998
- bytes += Buffer.byteLength(chunk.chunk, chunk.encoding);
999
- }
1000
- } else if (data) {
1001
- // Writes are either a string or a Buffer.
1002
- if (typeof data !== 'string')
1003
- bytes += data.length;
1004
- else
1005
- bytes += Buffer.byteLength(data, encoding);
1006
- }
1007
-
1008
- return bytes;
1009
- });
1010
-
1011
-
1012
- function checkBindError(err, port, handle) {
1013
- // EADDRINUSE may not be reported until we call listen() or connect().
1014
- // To complicate matters, a failed bind() followed by listen() or connect()
1015
- // will implicitly bind to a random port. Ergo, check that the socket is
1016
- // bound to the expected port before calling listen() or connect().
1017
- //
1018
- // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
1019
- // getsockname() method. Non-issue for now, the cluster module doesn't
1020
- // really support pipes anyway.
1021
- if (err === 0 && port > 0 && handle.getsockname) {
1022
- const out = {};
1023
- err = handle.getsockname(out);
1024
- if (err === 0 && port !== out.port) {
1025
- debug(`checkBindError, bound to ${out.port} instead of ${port}`);
1026
- err = UV_EADDRINUSE;
1027
- }
1028
- }
1029
- return err;
1030
- }
1031
-
1032
-
1033
- function internalConnect(
1034
- self, address, port, addressType, localAddress, localPort, flags) {
1035
- // TODO return promise from Socket.prototype.connect which
1036
- // wraps _connectReq.
1037
-
1038
- assert(self.connecting);
1039
-
1040
- let err;
1041
-
1042
- if (localAddress || localPort) {
1043
- if (addressType === 4) {
1044
- localAddress = localAddress || DEFAULT_IPV4_ADDR;
1045
- err = self._handle.bind(localAddress, localPort);
1046
- } else { // addressType === 6
1047
- localAddress = localAddress || DEFAULT_IPV6_ADDR;
1048
- err = self._handle.bind6(localAddress, localPort, flags);
1049
- }
1050
- debug('connect: binding to localAddress: %s and localPort: %d (addressType: %d)',
1051
- localAddress, localPort, addressType);
1052
-
1053
- err = checkBindError(err, localPort, self._handle);
1054
- if (err) {
1055
- const ex = new ExceptionWithHostPort(err, 'bind', localAddress, localPort);
1056
- self.destroy(ex);
1057
- return;
1058
- }
1059
- }
1060
-
1061
- debug('connect: attempting to connect to %s:%d (addressType: %d)', address, port, addressType);
1062
- self.emit('connectionAttempt', address, port, addressType);
1063
-
1064
- if (addressType === 6 || addressType === 4) {
1065
- const req = new TCPConnectWrap();
1066
- req.oncomplete = afterConnect;
1067
- req.address = address;
1068
- req.port = port;
1069
- req.localAddress = localAddress;
1070
- req.localPort = localPort;
1071
- req.addressType = addressType;
1072
-
1073
- if (addressType === 4)
1074
- err = self._handle.connect(req, address, port);
1075
- else
1076
- err = self._handle.connect6(req, address, port);
1077
- } else {
1078
- const req = new PipeConnectWrap();
1079
- req.address = address;
1080
- req.oncomplete = afterConnect;
1081
-
1082
- err = self._handle.connect(req, address);
1083
- }
1084
-
1085
- if (err) {
1086
- const sockname = self._getsockname();
1087
- let details;
1088
-
1089
- if (sockname) {
1090
- details = sockname.address + ':' + sockname.port;
1091
- }
1092
-
1093
- const ex = new ExceptionWithHostPort(err, 'connect', address, port, details);
1094
- self.destroy(ex);
1095
- } else if ((addressType === 6 || addressType === 4) && hasObserver('net')) {
1096
- startPerf(self, kPerfHooksNetConnectContext, { type: 'net', name: 'connect', detail: { host: address, port } });
1097
- }
1098
- }
1099
-
1100
-
1101
- function internalConnectMultiple(context, canceled) {
1102
- clearTimeout(context[kTimeout]);
1103
- const self = context.socket;
1104
-
1105
- // We were requested to abort. Stop all operations
1106
- if (self._aborted) {
1107
- return;
1108
- }
1109
-
1110
- // All connections have been tried without success, destroy with error
1111
- if (canceled || context.current === context.addresses.length) {
1112
- if (context.errors.length === 0) {
1113
- self.destroy(new ERR_SOCKET_CONNECTION_TIMEOUT());
1114
- return;
1115
- }
1116
-
1117
- self.destroy(new NodeAggregateError(context.errors));
1118
- return;
1119
- }
1120
-
1121
- assert(self.connecting);
1122
-
1123
- const current = context.current++;
1124
-
1125
- if (current > 0) {
1126
- self[kReinitializeHandle](new TCP(TCPConstants.SOCKET));
1127
- }
1128
-
1129
- const { localPort, port, flags } = context;
1130
- const { address, family: addressType } = context.addresses[current];
1131
- let localAddress;
1132
- let err;
1133
-
1134
- if (localPort) {
1135
- if (addressType === 4) {
1136
- localAddress = DEFAULT_IPV4_ADDR;
1137
- err = self._handle.bind(localAddress, localPort);
1138
- } else { // addressType === 6
1139
- localAddress = DEFAULT_IPV6_ADDR;
1140
- err = self._handle.bind6(localAddress, localPort, flags);
1141
- }
1142
-
1143
- debug('connect/multiple: binding to localAddress: %s and localPort: %d (addressType: %d)',
1144
- localAddress, localPort, addressType);
1145
-
1146
- err = checkBindError(err, localPort, self._handle);
1147
- if (err) {
1148
- ArrayPrototypePush(context.errors, new ExceptionWithHostPort(err, 'bind', localAddress, localPort));
1149
- internalConnectMultiple(context);
1150
- return;
1151
- }
1152
- }
1153
-
1154
- debug('connect/multiple: attempting to connect to %s:%d (addressType: %d)', address, port, addressType);
1155
- self.emit('connectionAttempt', address, port, addressType);
1156
-
1157
- const req = new TCPConnectWrap();
1158
- req.oncomplete = FunctionPrototypeBind(afterConnectMultiple, undefined, context, current);
1159
- req.address = address;
1160
- req.port = port;
1161
- req.localAddress = localAddress;
1162
- req.localPort = localPort;
1163
- req.addressType = addressType;
1164
-
1165
- ArrayPrototypePush(self.autoSelectFamilyAttemptedAddresses, `${address}:${port}`);
1166
-
1167
- if (addressType === 4) {
1168
- err = self._handle.connect(req, address, port);
1169
- } else {
1170
- err = self._handle.connect6(req, address, port);
1171
- }
1172
-
1173
- if (err) {
1174
- const sockname = self._getsockname();
1175
- let details;
1176
-
1177
- if (sockname) {
1178
- details = sockname.address + ':' + sockname.port;
1179
- }
1180
-
1181
- const ex = new ExceptionWithHostPort(err, 'connect', address, port, details);
1182
- ArrayPrototypePush(context.errors, ex);
1183
-
1184
- self.emit('connectionAttemptFailed', address, port, addressType, ex);
1185
- internalConnectMultiple(context);
1186
- return;
1187
- }
1188
-
1189
- if (current < context.addresses.length - 1) {
1190
- debug('connect/multiple: setting the attempt timeout to %d ms', context.timeout);
1191
-
1192
- // If the attempt has not returned an error, start the connection timer
1193
- context[kTimeout] = setTimeout(internalConnectMultipleTimeout, context.timeout, context, req, self._handle);
1194
- }
1195
- }
1196
-
1197
- Socket.prototype.connect = function(...args) {
1198
- let normalized;
1199
- // If passed an array, it's treated as an array of arguments that have
1200
- // already been normalized (so we don't normalize more than once). This has
1201
- // been solved before in https://github.com/nodejs/node/pull/12342, but was
1202
- // reverted as it had unintended side effects.
1203
- if (ArrayIsArray(args[0]) && args[0][normalizedArgsSymbol]) {
1204
- normalized = args[0];
1205
- } else {
1206
- normalized = normalizeArgs(args);
1207
- }
1208
- const options = normalized[0];
1209
- const cb = normalized[1];
1210
-
1211
- if (cb !== null) {
1212
- this.once('connect', cb);
1213
- }
1214
-
1215
- // If the parent is already connecting, do not attempt to connect again
1216
- if (this._parent && this._parent.connecting) {
1217
- return this;
1218
- }
1219
-
1220
- // options.port === null will be checked later.
1221
- if (options.port === undefined && options.path == null)
1222
- throw new ERR_MISSING_ARGS(['options', 'port', 'path']);
1223
-
1224
- if (this.write !== Socket.prototype.write)
1225
- this.write = Socket.prototype.write;
1226
-
1227
- if (this.destroyed) {
1228
- this._handle = null;
1229
- this._peername = null;
1230
- this._sockname = null;
1231
- }
1232
-
1233
- const { path } = options;
1234
- const pipe = !!path;
1235
- debug('pipe', pipe, path);
1236
-
1237
- if (!this._handle) {
1238
- this._handle = pipe ?
1239
- new Pipe(PipeConstants.SOCKET) :
1240
- new TCP(TCPConstants.SOCKET);
1241
- initSocketHandle(this);
1242
- }
1243
-
1244
- this._unrefTimer();
1245
-
1246
- this.connecting = true;
1247
-
1248
- if (pipe) {
1249
- validateString(path, 'options.path');
1250
- defaultTriggerAsyncIdScope(
1251
- this[async_id_symbol], internalConnect, this, path,
1252
- );
1253
- } else {
1254
- lookupAndConnect(this, options);
1255
- }
1256
- return this;
1257
- };
1258
-
1259
- Socket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) {
1260
- this._handle?.close();
1261
-
1262
- this._handle = handle;
1263
- this._handle[owner_symbol] = this;
1264
-
1265
- initSocketHandle(this);
1266
- };
1267
-
1268
- function socketToDnsFamily(family) {
1269
- switch (family) {
1270
- case 'IPv4':
1271
- return 4;
1272
- case 'IPv6':
1273
- return 6;
1274
- }
1275
-
1276
- return family;
1277
- }
1278
-
1279
- function lookupAndConnect(self, options) {
1280
- const { localAddress, localPort } = options;
1281
- const host = options.host || 'localhost';
1282
- let { port, autoSelectFamilyAttemptTimeout, autoSelectFamily } = options;
1283
-
1284
- if (localAddress && !isIP(localAddress)) {
1285
- throw new ERR_INVALID_IP_ADDRESS(localAddress);
1286
- }
1287
-
1288
- if (localPort) {
1289
- validateNumber(localPort, 'options.localPort');
1290
- }
1291
-
1292
- if (typeof port !== 'undefined') {
1293
- if (typeof port !== 'number' && typeof port !== 'string') {
1294
- throw new ERR_INVALID_ARG_TYPE('options.port',
1295
- ['number', 'string'], port);
1296
- }
1297
- validatePort(port);
1298
- }
1299
- port |= 0;
1300
-
1301
-
1302
- if (autoSelectFamily != null) {
1303
- validateBoolean(autoSelectFamily, 'options.autoSelectFamily');
1304
- } else {
1305
- autoSelectFamily = autoSelectFamilyDefault;
1306
- }
1307
-
1308
- if (autoSelectFamilyAttemptTimeout != null) {
1309
- validateInt32(autoSelectFamilyAttemptTimeout, 'options.autoSelectFamilyAttemptTimeout', 1);
1310
-
1311
- if (autoSelectFamilyAttemptTimeout < 10) {
1312
- autoSelectFamilyAttemptTimeout = 10;
1313
- }
1314
- } else {
1315
- autoSelectFamilyAttemptTimeout = autoSelectFamilyAttemptTimeoutDefault;
1316
- }
1317
-
1318
- // If host is an IP, skip performing a lookup
1319
- const addressType = isIP(host);
1320
- if (addressType) {
1321
- defaultTriggerAsyncIdScope(self[async_id_symbol], process.nextTick, () => {
1322
- if (self.connecting)
1323
- defaultTriggerAsyncIdScope(
1324
- self[async_id_symbol],
1325
- internalConnect,
1326
- self, host, port, addressType, localAddress, localPort,
1327
- );
1328
- });
1329
- return;
1330
- }
1331
-
1332
- if (options.lookup != null)
1333
- validateFunction(options.lookup, 'options.lookup');
1334
-
1335
- if (dns === undefined) dns = require('dns');
1336
- const dnsopts = {
1337
- family: socketToDnsFamily(options.family),
1338
- hints: options.hints || 0,
1339
- };
1340
-
1341
- if (!isWindows &&
1342
- dnsopts.family !== 4 &&
1343
- dnsopts.family !== 6 &&
1344
- dnsopts.hints === 0) {
1345
- dnsopts.hints = dns.ADDRCONFIG;
1346
- }
1347
-
1348
- debug('connect: find host', host);
1349
- debug('connect: dns options', dnsopts);
1350
- self._host = host;
1351
- const lookup = options.lookup || dns.lookup;
1352
-
1353
- if (dnsopts.family !== 4 && dnsopts.family !== 6 && !localAddress && autoSelectFamily) {
1354
- debug('connect: autodetecting');
1355
-
1356
- dnsopts.all = true;
1357
- defaultTriggerAsyncIdScope(self[async_id_symbol], function() {
1358
- lookupAndConnectMultiple(
1359
- self,
1360
- async_id_symbol,
1361
- lookup,
1362
- host,
1363
- options,
1364
- dnsopts,
1365
- port,
1366
- localAddress,
1367
- localPort,
1368
- autoSelectFamilyAttemptTimeout,
1369
- );
1370
- });
1371
-
1372
- return;
1373
- }
1374
-
1375
- defaultTriggerAsyncIdScope(self[async_id_symbol], function() {
1376
- lookup(host, dnsopts, function emitLookup(err, ip, addressType) {
1377
- self.emit('lookup', err, ip, addressType, host);
1378
-
1379
- // It's possible we were destroyed while looking this up.
1380
- // XXX it would be great if we could cancel the promise returned by
1381
- // the look up.
1382
- if (!self.connecting) return;
1383
-
1384
- if (err) {
1385
- // net.createConnection() creates a net.Socket object and immediately
1386
- // calls net.Socket.connect() on it (that's us). There are no event
1387
- // listeners registered yet so defer the error event to the next tick.
1388
- process.nextTick(connectErrorNT, self, err);
1389
- } else if (!isIP(ip)) {
1390
- err = new ERR_INVALID_IP_ADDRESS(ip);
1391
- process.nextTick(connectErrorNT, self, err);
1392
- } else if (addressType !== 4 && addressType !== 6) {
1393
- err = new ERR_INVALID_ADDRESS_FAMILY(addressType,
1394
- options.host,
1395
- options.port);
1396
- process.nextTick(connectErrorNT, self, err);
1397
- } else {
1398
- self._unrefTimer();
1399
- defaultTriggerAsyncIdScope(
1400
- self[async_id_symbol],
1401
- internalConnect,
1402
- self, ip, port, addressType, localAddress, localPort,
1403
- );
1404
- }
1405
- });
1406
- });
1407
- }
1408
-
1409
- function lookupAndConnectMultiple(
1410
- self, async_id_symbol, lookup, host, options, dnsopts, port, localAddress, localPort, timeout,
1411
- ) {
1412
- defaultTriggerAsyncIdScope(self[async_id_symbol], function emitLookup() {
1413
- lookup(host, dnsopts, function emitLookup(err, addresses) {
1414
- // It's possible we were destroyed while looking this up.
1415
- // XXX it would be great if we could cancel the promise returned by
1416
- // the look up.
1417
- if (!self.connecting) {
1418
- return;
1419
- } else if (err) {
1420
- self.emit('lookup', err, undefined, undefined, host);
1421
-
1422
- // net.createConnection() creates a net.Socket object and immediately
1423
- // calls net.Socket.connect() on it (that's us). There are no event
1424
- // listeners registered yet so defer the error event to the next tick.
1425
- process.nextTick(connectErrorNT, self, err);
1426
- return;
1427
- }
1428
-
1429
- // Filter addresses by only keeping the one which are either IPv4 or IPV6.
1430
- // The first valid address determines which group has preference on the
1431
- // alternate family sorting which happens later.
1432
- const validAddresses = [[], []];
1433
- const validIps = [[], []];
1434
- let destinations;
1435
- for (let i = 0, l = addresses.length; i < l; i++) {
1436
- const address = addresses[i];
1437
- const { address: ip, family: addressType } = address;
1438
- self.emit('lookup', err, ip, addressType, host);
1439
- // It's possible we were destroyed while looking this up.
1440
- if (!self.connecting) {
1441
- return;
1442
- }
1443
- if (isIP(ip) && (addressType === 4 || addressType === 6)) {
1444
- if (!destinations) {
1445
- destinations = addressType === 6 ? { 6: 0, 4: 1 } : { 4: 0, 6: 1 };
1446
- }
1447
-
1448
- const destination = destinations[addressType];
1449
-
1450
- // Only try an address once
1451
- if (!ArrayPrototypeIncludes(validIps[destination], ip)) {
1452
- ArrayPrototypePush(validAddresses[destination], address);
1453
- ArrayPrototypePush(validIps[destination], ip);
1454
- }
1455
- }
1456
- }
1457
-
1458
-
1459
- // When no AAAA or A records are available, fail on the first one
1460
- if (!validAddresses[0].length && !validAddresses[1].length) {
1461
- const { address: firstIp, family: firstAddressType } = addresses[0];
1462
-
1463
- if (!isIP(firstIp)) {
1464
- err = new ERR_INVALID_IP_ADDRESS(firstIp);
1465
- process.nextTick(connectErrorNT, self, err);
1466
- } else if (firstAddressType !== 4 && firstAddressType !== 6) {
1467
- err = new ERR_INVALID_ADDRESS_FAMILY(firstAddressType,
1468
- options.host,
1469
- options.port);
1470
- process.nextTick(connectErrorNT, self, err);
1471
- }
1472
-
1473
- return;
1474
- }
1475
-
1476
- // Sort addresses alternating families
1477
- const toAttempt = [];
1478
- for (let i = 0, l = MathMax(validAddresses[0].length, validAddresses[1].length); i < l; i++) {
1479
- if (i in validAddresses[0]) {
1480
- ArrayPrototypePush(toAttempt, validAddresses[0][i]);
1481
- }
1482
- if (i in validAddresses[1]) {
1483
- ArrayPrototypePush(toAttempt, validAddresses[1][i]);
1484
- }
1485
- }
1486
-
1487
- if (toAttempt.length === 1) {
1488
- debug('connect/multiple: only one address found, switching back to single connection');
1489
- const { address: ip, family: addressType } = toAttempt[0];
1490
-
1491
- self._unrefTimer();
1492
- defaultTriggerAsyncIdScope(
1493
- self[async_id_symbol],
1494
- internalConnect,
1495
- self,
1496
- ip,
1497
- port,
1498
- addressType,
1499
- localAddress,
1500
- localPort,
1501
- );
1502
-
1503
- return;
1504
- }
1505
-
1506
- self.autoSelectFamilyAttemptedAddresses = [];
1507
- debug('connect/multiple: will try the following addresses', toAttempt);
1508
-
1509
- const context = {
1510
- socket: self,
1511
- addresses: toAttempt,
1512
- current: 0,
1513
- port,
1514
- localPort,
1515
- timeout,
1516
- [kTimeout]: null,
1517
- errors: [],
1518
- };
1519
-
1520
- self._unrefTimer();
1521
- defaultTriggerAsyncIdScope(self[async_id_symbol], internalConnectMultiple, context);
1522
- });
1523
- });
1524
- }
1525
-
1526
- function connectErrorNT(self, err) {
1527
- self.destroy(err);
1528
- }
1529
-
1530
-
1531
- Socket.prototype.ref = function() {
1532
- if (!this._handle) {
1533
- this.once('connect', this.ref);
1534
- return this;
1535
- }
1536
-
1537
- if (typeof this._handle.ref === 'function') {
1538
- this._handle.ref();
1539
- }
1540
-
1541
- return this;
1542
- };
1543
-
1544
-
1545
- Socket.prototype.unref = function() {
1546
- if (!this._handle) {
1547
- this.once('connect', this.unref);
1548
- return this;
1549
- }
1550
-
1551
- if (typeof this._handle.unref === 'function') {
1552
- this._handle.unref();
1553
- }
1554
-
1555
- return this;
1556
- };
1557
-
1558
-
1559
- function afterConnect(status, handle, req, readable, writable) {
1560
- const self = handle[owner_symbol];
1561
-
1562
- // Callback may come after call to destroy
1563
- if (self.destroyed) {
1564
- return;
1565
- }
1566
-
1567
- debug('afterConnect');
1568
-
1569
- assert(self.connecting);
1570
- self.connecting = false;
1571
- self._sockname = null;
1572
-
1573
- if (status === 0) {
1574
- if (self.readable && !readable) {
1575
- self.push(null);
1576
- self.read();
1577
- }
1578
- if (self.writable && !writable) {
1579
- self.end();
1580
- }
1581
- self._unrefTimer();
1582
-
1583
- if (self[kSetNoDelay] && self._handle.setNoDelay) {
1584
- self._handle.setNoDelay(true);
1585
- }
1586
-
1587
- if (self[kSetKeepAlive] && self._handle.setKeepAlive) {
1588
- self._handle.setKeepAlive(true, self[kSetKeepAliveInitialDelay]);
1589
- }
1590
-
1591
- self.emit('connect');
1592
- self.emit('ready');
1593
-
1594
- // Start the first read, or get an immediate EOF.
1595
- // this doesn't actually consume any bytes, because len=0.
1596
- if (readable && !self.isPaused())
1597
- self.read(0);
1598
- if (self[kPerfHooksNetConnectContext] && hasObserver('net')) {
1599
- stopPerf(self, kPerfHooksNetConnectContext);
1600
- }
1601
- } else {
1602
- let details;
1603
- if (req.localAddress && req.localPort) {
1604
- details = req.localAddress + ':' + req.localPort;
1605
- }
1606
- const ex = new ExceptionWithHostPort(status,
1607
- 'connect',
1608
- req.address,
1609
- req.port,
1610
- details);
1611
- if (details) {
1612
- ex.localAddress = req.localAddress;
1613
- ex.localPort = req.localPort;
1614
- }
1615
-
1616
- self.emit('connectionAttemptFailed', req.address, req.port, req.addressType, ex);
1617
- self.destroy(ex);
1618
- }
1619
- }
1620
-
1621
- function addClientAbortSignalOption(self, options) {
1622
- validateAbortSignal(options.signal, 'options.signal');
1623
- const { signal } = options;
1624
- let disposable;
1625
-
1626
- function onAbort() {
1627
- disposable?.[SymbolDispose]();
1628
- self._aborted = true;
1629
- }
1630
-
1631
- if (signal.aborted) {
1632
- process.nextTick(onAbort);
1633
- } else {
1634
- process.nextTick(() => {
1635
- disposable = addAbortListener(signal, onAbort);
1636
- });
1637
- }
1638
- }
1639
-
1640
- function createConnectionError(req, status) {
1641
- let details;
1642
-
1643
- if (req.localAddress && req.localPort) {
1644
- details = req.localAddress + ':' + req.localPort;
1645
- }
1646
-
1647
- const ex = new ExceptionWithHostPort(status,
1648
- 'connect',
1649
- req.address,
1650
- req.port,
1651
- details);
1652
- if (details) {
1653
- ex.localAddress = req.localAddress;
1654
- ex.localPort = req.localPort;
1655
- }
1656
-
1657
- return ex;
1658
- }
1659
-
1660
- function afterConnectMultiple(context, current, status, handle, req, readable, writable) {
1661
- debug('connect/multiple: connection attempt to %s:%s completed with status %s', req.address, req.port, status);
1662
-
1663
- // Make sure another connection is not spawned
1664
- clearTimeout(context[kTimeout]);
1665
-
1666
- // One of the connection has completed and correctly dispatched but after timeout, ignore this one
1667
- if (status === 0 && current !== context.current - 1) {
1668
- debug('connect/multiple: ignoring successful but timedout connection to %s:%s', req.address, req.port);
1669
- handle.close();
1670
- return;
1671
- }
1672
-
1673
- const self = context.socket;
1674
-
1675
- // Some error occurred, add to the list of exceptions
1676
- if (status !== 0) {
1677
- const ex = createConnectionError(req, status);
1678
- ArrayPrototypePush(context.errors, ex);
1679
-
1680
- self.emit('connectionAttemptFailed', req.address, req.port, req.addressType, ex);
1681
-
1682
- // Try the next address, unless we were aborted
1683
- if (context.socket.connecting) {
1684
- internalConnectMultiple(context, status === UV_ECANCELED);
1685
- }
1686
-
1687
- return;
1688
- }
1689
-
1690
- if (hasObserver('net')) {
1691
- startPerf(
1692
- self,
1693
- kPerfHooksNetConnectContext,
1694
- { type: 'net', name: 'connect', detail: { host: req.address, port: req.port } },
1695
- );
1696
- }
1697
-
1698
- afterConnect(status, self._handle, req, readable, writable);
1699
- }
1700
-
1701
- function internalConnectMultipleTimeout(context, req, handle) {
1702
- debug('connect/multiple: connection to %s:%s timed out', req.address, req.port);
1703
- context.socket.emit('connectionAttemptTimeout', req.address, req.port, req.addressType);
1704
-
1705
- req.oncomplete = undefined;
1706
- ArrayPrototypePush(context.errors, createConnectionError(req, UV_ETIMEDOUT));
1707
- handle.close();
1708
-
1709
- // Try the next address, unless we were aborted
1710
- if (context.socket.connecting) {
1711
- internalConnectMultiple(context);
1712
- }
1713
- }
1714
-
1715
- function addServerAbortSignalOption(self, options) {
1716
- if (options?.signal === undefined) {
1717
- return;
1718
- }
1719
- validateAbortSignal(options.signal, 'options.signal');
1720
- const { signal } = options;
1721
- const onAborted = () => {
1722
- self.close();
1723
- };
1724
- if (signal.aborted) {
1725
- process.nextTick(onAborted);
1726
- } else {
1727
- const disposable = addAbortListener(signal, onAborted);
1728
- self.once('close', disposable[SymbolDispose]);
1729
- }
1730
- }
1731
-
1732
- function Server(options, connectionListener) {
1733
- if (!(this instanceof Server))
1734
- return new Server(options, connectionListener);
1735
-
1736
- EventEmitter.call(this);
1737
-
1738
- if (typeof options === 'function') {
1739
- connectionListener = options;
1740
- options = kEmptyObject;
1741
- this.on('connection', connectionListener);
1742
- } else if (options == null || typeof options === 'object') {
1743
- options = { ...options };
1744
-
1745
- if (typeof connectionListener === 'function') {
1746
- this.on('connection', connectionListener);
1747
- }
1748
- } else {
1749
- throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
1750
- }
1751
- if (typeof options.keepAliveInitialDelay !== 'undefined') {
1752
- validateNumber(
1753
- options.keepAliveInitialDelay, 'options.keepAliveInitialDelay',
1754
- );
1755
-
1756
- if (options.keepAliveInitialDelay < 0) {
1757
- options.keepAliveInitialDelay = 0;
1758
- }
1759
- }
1760
- if (typeof options.highWaterMark !== 'undefined') {
1761
- validateNumber(
1762
- options.highWaterMark, 'options.highWaterMark',
1763
- );
1764
-
1765
- if (options.highWaterMark < 0) {
1766
- options.highWaterMark = getDefaultHighWaterMark();
1767
- }
1768
- }
1769
-
1770
- this._connections = 0;
1771
-
1772
- this[async_id_symbol] = -1;
1773
- this._handle = null;
1774
- this._usingWorkers = false;
1775
- this._workers = [];
1776
- this._unref = false;
1777
- this._listeningId = 1;
1778
-
1779
- this.allowHalfOpen = options.allowHalfOpen || false;
1780
- this.pauseOnConnect = !!options.pauseOnConnect;
1781
- this.noDelay = Boolean(options.noDelay);
1782
- this.keepAlive = Boolean(options.keepAlive);
1783
- this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
1784
- this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
1785
- }
1786
- ObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype);
1787
- ObjectSetPrototypeOf(Server, EventEmitter);
1788
-
1789
-
1790
- function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
1791
-
1792
- // Returns handle if it can be created, or error code if it can't
1793
- function createServerHandle(address, port, addressType, fd, flags) {
1794
- let err = 0;
1795
- // Assign handle in listen, and clean up if bind or listen fails
1796
- let handle;
1797
-
1798
- let isTCP = false;
1799
- if (typeof fd === 'number' && fd >= 0) {
1800
- try {
1801
- handle = createHandle(fd, true);
1802
- } catch (e) {
1803
- // Not a fd we can listen on. This will trigger an error.
1804
- debug('listen invalid fd=%d:', fd, e.message);
1805
- return UV_EINVAL;
1806
- }
1807
-
1808
- err = handle.open(fd);
1809
- if (err)
1810
- return err;
1811
-
1812
- assert(!address && !port);
1813
- } else if (port === -1 && addressType === -1) {
1814
- handle = new Pipe(PipeConstants.SERVER);
1815
- if (isWindows) {
1816
- const instances = NumberParseInt(process.env.NODE_PENDING_PIPE_INSTANCES);
1817
- if (!NumberIsNaN(instances)) {
1818
- handle.setPendingInstances(instances);
1819
- }
1820
- }
1821
- } else {
1822
- handle = new TCP(TCPConstants.SERVER);
1823
- isTCP = true;
1824
- }
1825
-
1826
- if (address || port || isTCP) {
1827
- debug('bind to', address || 'any');
1828
- if (!address) {
1829
- // Try binding to ipv6 first
1830
- err = handle.bind6(DEFAULT_IPV6_ADDR, port, flags);
1831
- if (err) {
1832
- handle.close();
1833
- // Fallback to ipv4
1834
- return createServerHandle(DEFAULT_IPV4_ADDR, port);
1835
- }
1836
- } else if (addressType === 6) {
1837
- err = handle.bind6(address, port, flags);
1838
- } else {
1839
- err = handle.bind(address, port);
1840
- }
1841
- }
1842
-
1843
- if (err) {
1844
- handle.close();
1845
- return err;
1846
- }
1847
-
1848
- return handle;
1849
- }
1850
-
1851
- function setupListenHandle(address, port, addressType, backlog, fd, flags) {
1852
- debug('setupListenHandle', address, port, addressType, backlog, fd);
1853
-
1854
- // If there is not yet a handle, we need to create one and bind.
1855
- // In the case of a server sent via IPC, we don't need to do this.
1856
- if (this._handle) {
1857
- debug('setupListenHandle: have a handle already');
1858
- } else {
1859
- debug('setupListenHandle: create a handle');
1860
-
1861
- let rval = null;
1862
-
1863
- // Try to bind to the unspecified IPv6 address, see if IPv6 is available
1864
- if (!address && typeof fd !== 'number') {
1865
- rval = createServerHandle(DEFAULT_IPV6_ADDR, port, 6, fd, flags);
1866
-
1867
- if (typeof rval === 'number') {
1868
- rval = null;
1869
- address = DEFAULT_IPV4_ADDR;
1870
- addressType = 4;
1871
- } else {
1872
- address = DEFAULT_IPV6_ADDR;
1873
- addressType = 6;
1874
- }
1875
- }
1876
-
1877
- if (rval === null)
1878
- rval = createServerHandle(address, port, addressType, fd, flags);
1879
-
1880
- if (typeof rval === 'number') {
1881
- const error = new UVExceptionWithHostPort(rval, 'listen', address, port);
1882
- process.nextTick(emitErrorNT, this, error);
1883
- return;
1884
- }
1885
- this._handle = rval;
1886
- }
1887
-
1888
- this[async_id_symbol] = getNewAsyncId(this._handle);
1889
- this._handle.onconnection = onconnection;
1890
- this._handle[owner_symbol] = this;
1891
-
1892
- // Use a backlog of 512 entries. We pass 511 to the listen() call because
1893
- // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
1894
- // which will thus give us a backlog of 512 entries.
1895
- const err = this._handle.listen(backlog || 511);
1896
-
1897
- if (err) {
1898
- const ex = new UVExceptionWithHostPort(err, 'listen', address, port);
1899
- this._handle.close();
1900
- this._handle = null;
1901
- defaultTriggerAsyncIdScope(this[async_id_symbol],
1902
- process.nextTick,
1903
- emitErrorNT,
1904
- this,
1905
- ex);
1906
- return;
1907
- }
1908
-
1909
- // Generate connection key, this should be unique to the connection
1910
- this._connectionKey = addressType + ':' + address + ':' + port;
1911
-
1912
- // Unref the handle if the server was unref'ed prior to listening
1913
- if (this._unref)
1914
- this.unref();
1915
-
1916
- defaultTriggerAsyncIdScope(this[async_id_symbol],
1917
- process.nextTick,
1918
- emitListeningNT,
1919
- this);
1920
- }
1921
-
1922
- Server.prototype._listen2 = setupListenHandle; // legacy alias
1923
-
1924
- function emitErrorNT(self, err) {
1925
- self.emit('error', err);
1926
- }
1927
-
1928
-
1929
- function emitListeningNT(self) {
1930
- // Ensure handle hasn't closed
1931
- if (self._handle)
1932
- self.emit('listening');
1933
- }
1934
-
1935
-
1936
- function listenInCluster(server, address, port, addressType,
1937
- backlog, fd, exclusive, flags, options) {
1938
- exclusive = !!exclusive;
1939
-
1940
- if (cluster === undefined) cluster = require('cluster');
1941
-
1942
- if (cluster.isPrimary || exclusive) {
1943
- // Will create a new handle
1944
- // _listen2 sets up the listened handle, it is still named like this
1945
- // to avoid breaking code that wraps this method
1946
- server._listen2(address, port, addressType, backlog, fd, flags);
1947
- return;
1948
- }
1949
-
1950
- const serverQuery = {
1951
- address: address,
1952
- port: port,
1953
- addressType: addressType,
1954
- fd: fd,
1955
- flags,
1956
- backlog,
1957
- ...options,
1958
- };
1959
- const listeningId = server._listeningId;
1960
- // Get the primary's server handle, and listen on it
1961
- cluster._getServer(server, serverQuery, listenOnPrimaryHandle);
1962
- function listenOnPrimaryHandle(err, handle) {
1963
- if (listeningId !== server._listeningId) {
1964
- handle.close();
1965
- return;
1966
- }
1967
- err = checkBindError(err, port, handle);
1968
-
1969
- if (err) {
1970
- const ex = new ExceptionWithHostPort(err, 'bind', address, port);
1971
- return server.emit('error', ex);
1972
- }
1973
- // If there was a handle, just close it to avoid fd leak
1974
- // but it doesn't look like that's going to happen right now
1975
- if (server._handle) {
1976
- server._handle.close();
1977
- }
1978
- // Reuse primary's server handle
1979
- server._handle = handle;
1980
- // _listen2 sets up the listened handle, it is still named like this
1981
- // to avoid breaking code that wraps this method
1982
- server._listen2(address, port, addressType, backlog, fd, flags);
1983
- }
1984
- }
1985
-
1986
-
1987
- Server.prototype.listen = function(...args) {
1988
- const normalized = normalizeArgs(args);
1989
- let options = normalized[0];
1990
- const cb = normalized[1];
1991
-
1992
- if (this._handle) {
1993
- throw new ERR_SERVER_ALREADY_LISTEN();
1994
- }
1995
-
1996
- if (cb !== null) {
1997
- this.once('listening', cb);
1998
- }
1999
- const backlogFromArgs =
2000
- // (handle, backlog) or (path, backlog) or (port, backlog)
2001
- toNumber(args.length > 1 && args[1]) ||
2002
- toNumber(args.length > 2 && args[2]); // (port, host, backlog)
2003
-
2004
- options = options._handle || options.handle || options;
2005
- const flags = getFlags(options.ipv6Only);
2006
- // Refresh the id to make the previous call invalid
2007
- this._listeningId++;
2008
- // (handle[, backlog][, cb]) where handle is an object with a handle
2009
- if (options instanceof TCP) {
2010
- this._handle = options;
2011
- this[async_id_symbol] = this._handle.getAsyncId();
2012
- listenInCluster(this, null, -1, -1, backlogFromArgs, undefined, true);
2013
- return this;
2014
- }
2015
- addServerAbortSignalOption(this, options);
2016
- // (handle[, backlog][, cb]) where handle is an object with a fd
2017
- if (typeof options.fd === 'number' && options.fd >= 0) {
2018
- listenInCluster(this, null, null, null, backlogFromArgs, options.fd);
2019
- return this;
2020
- }
2021
-
2022
- // ([port][, host][, backlog][, cb]) where port is omitted,
2023
- // that is, listen(), listen(null), listen(cb), or listen(null, cb)
2024
- // or (options[, cb]) where options.port is explicitly set as undefined or
2025
- // null, bind to an arbitrary unused port
2026
- if (args.length === 0 || typeof args[0] === 'function' ||
2027
- (typeof options.port === 'undefined' && 'port' in options) ||
2028
- options.port === null) {
2029
- options.port = 0;
2030
- }
2031
- // ([port][, host][, backlog][, cb]) where port is specified
2032
- // or (options[, cb]) where options.port is specified
2033
- // or if options.port is normalized as 0 before
2034
- let backlog;
2035
- if (typeof options.port === 'number' || typeof options.port === 'string') {
2036
- validatePort(options.port, 'options.port');
2037
- backlog = options.backlog || backlogFromArgs;
2038
- // start TCP server listening on host:port
2039
- if (options.host) {
2040
- lookupAndListen(this, options.port | 0, options.host, backlog,
2041
- options.exclusive, flags);
2042
- } else { // Undefined host, listens on unspecified address
2043
- // Default addressType 4 will be used to search for primary server
2044
- listenInCluster(this, null, options.port | 0, 4,
2045
- backlog, undefined, options.exclusive);
2046
- }
2047
- return this;
2048
- }
2049
-
2050
- // (path[, backlog][, cb]) or (options[, cb])
2051
- // where path or options.path is a UNIX domain socket or Windows pipe
2052
- if (options.path && isPipeName(options.path)) {
2053
- // We can not call fchmod on abstract unix socket
2054
- if (options.path[0] === '\0' &&
2055
- (options.readableAll || options.writableAll)) {
2056
- const msg = 'can not set readableAll or writableAllt to true when path is abstract unix socket';
2057
- throw new ERR_INVALID_ARG_VALUE('options', options, msg);
2058
- }
2059
- const pipeName = this._pipeName = options.path;
2060
- backlog = options.backlog || backlogFromArgs;
2061
- listenInCluster(this,
2062
- pipeName,
2063
- -1,
2064
- -1,
2065
- backlog,
2066
- undefined,
2067
- options.exclusive,
2068
- undefined,
2069
- {
2070
- readableAll: options.readableAll,
2071
- writableAll: options.writableAll,
2072
- });
2073
-
2074
- if (!this._handle) {
2075
- // Failed and an error shall be emitted in the next tick.
2076
- // Therefore, we directly return.
2077
- return this;
2078
- }
2079
-
2080
- let mode = 0;
2081
- if (options.readableAll === true)
2082
- mode |= PipeConstants.UV_READABLE;
2083
- if (options.writableAll === true)
2084
- mode |= PipeConstants.UV_WRITABLE;
2085
- if (mode !== 0) {
2086
- const err = this._handle.fchmod(mode);
2087
- if (err) {
2088
- this._handle.close();
2089
- this._handle = null;
2090
- throw new ErrnoException(err, 'uv_pipe_chmod');
2091
- }
2092
- }
2093
- return this;
2094
- }
2095
-
2096
- if (!(('port' in options) || ('path' in options))) {
2097
- throw new ERR_INVALID_ARG_VALUE('options', options,
2098
- 'must have the property "port" or "path"');
2099
- }
2100
-
2101
- throw new ERR_INVALID_ARG_VALUE('options', options);
2102
- };
2103
-
2104
- function lookupAndListen(self, port, address, backlog,
2105
- exclusive, flags) {
2106
- if (dns === undefined) dns = require('dns');
2107
- const listeningId = self._listeningId;
2108
- dns.lookup(address, function doListen(err, ip, addressType) {
2109
- if (listeningId !== self._listeningId) {
2110
- return;
2111
- }
2112
- if (err) {
2113
- self.emit('error', err);
2114
- } else {
2115
- addressType = ip ? addressType : 4;
2116
- listenInCluster(self, ip, port, addressType,
2117
- backlog, undefined, exclusive, flags);
2118
- }
2119
- });
2120
- }
2121
-
2122
- ObjectDefineProperty(Server.prototype, 'listening', {
2123
- __proto__: null,
2124
- get: function() {
2125
- return !!this._handle;
2126
- },
2127
- configurable: true,
2128
- enumerable: true,
2129
- });
2130
-
2131
- Server.prototype.address = function() {
2132
- if (this._handle && this._handle.getsockname) {
2133
- const out = {};
2134
- const err = this._handle.getsockname(out);
2135
- if (err) {
2136
- throw new ErrnoException(err, 'address');
2137
- }
2138
- return out;
2139
- } else if (this._pipeName) {
2140
- return this._pipeName;
2141
- }
2142
- return null;
2143
- };
2144
-
2145
- function onconnection(err, clientHandle) {
2146
- const handle = this;
2147
- const self = handle[owner_symbol];
2148
-
2149
- debug('onconnection');
2150
-
2151
- if (err) {
2152
- self.emit('error', new ErrnoException(err, 'accept'));
2153
- return;
2154
- }
2155
-
2156
- if (self.maxConnections != null && self._connections >= self.maxConnections) {
2157
- if (clientHandle.getsockname || clientHandle.getpeername) {
2158
- const data = { __proto__: null };
2159
- if (clientHandle.getsockname) {
2160
- const localInfo = { __proto__: null };
2161
- clientHandle.getsockname(localInfo);
2162
- data.localAddress = localInfo.address;
2163
- data.localPort = localInfo.port;
2164
- data.localFamily = localInfo.family;
2165
- }
2166
- if (clientHandle.getpeername) {
2167
- const remoteInfo = { __proto__: null };
2168
- clientHandle.getpeername(remoteInfo);
2169
- data.remoteAddress = remoteInfo.address;
2170
- data.remotePort = remoteInfo.port;
2171
- data.remoteFamily = remoteInfo.family;
2172
- }
2173
- self.emit('drop', data);
2174
- } else {
2175
- self.emit('drop');
2176
- }
2177
- clientHandle.close();
2178
- return;
2179
- }
2180
-
2181
- const socket = new Socket({
2182
- handle: clientHandle,
2183
- allowHalfOpen: self.allowHalfOpen,
2184
- pauseOnCreate: self.pauseOnConnect,
2185
- readable: true,
2186
- writable: true,
2187
- readableHighWaterMark: self.highWaterMark,
2188
- writableHighWaterMark: self.highWaterMark,
2189
- });
2190
-
2191
- if (self.noDelay && clientHandle.setNoDelay) {
2192
- socket[kSetNoDelay] = true;
2193
- clientHandle.setNoDelay(true);
2194
- }
2195
- if (self.keepAlive && clientHandle.setKeepAlive) {
2196
- socket[kSetKeepAlive] = true;
2197
- socket[kSetKeepAliveInitialDelay] = self.keepAliveInitialDelay;
2198
- clientHandle.setKeepAlive(true, self.keepAliveInitialDelay);
2199
- }
2200
-
2201
- self._connections++;
2202
- socket.server = self;
2203
- socket._server = self;
2204
- self.emit('connection', socket);
2205
- if (netServerSocketChannel.hasSubscribers) {
2206
- netServerSocketChannel.publish({
2207
- socket,
2208
- });
2209
- }
2210
- }
2211
-
2212
- /**
2213
- * Gets the number of concurrent connections on the server
2214
- * @param {Function} cb
2215
- * @returns {Server}
2216
- */
2217
-
2218
- Server.prototype.getConnections = function(cb) {
2219
- const self = this;
2220
-
2221
- function end(err, connections) {
2222
- defaultTriggerAsyncIdScope(self[async_id_symbol],
2223
- process.nextTick,
2224
- cb,
2225
- err,
2226
- connections);
2227
- }
2228
-
2229
- if (!this._usingWorkers) {
2230
- end(null, this._connections);
2231
- return this;
2232
- }
2233
-
2234
- // Poll workers
2235
- let left = this._workers.length;
2236
- let total = this._connections;
2237
-
2238
- function oncount(err, count) {
2239
- if (err) {
2240
- left = -1;
2241
- return end(err);
2242
- }
2243
-
2244
- total += count;
2245
- if (--left === 0) return end(null, total);
2246
- }
2247
-
2248
- for (let n = 0; n < this._workers.length; n++) {
2249
- this._workers[n].getConnections(oncount);
2250
- }
2251
-
2252
- return this;
2253
- };
2254
-
2255
-
2256
- Server.prototype.close = function(cb) {
2257
- this._listeningId++;
2258
- if (typeof cb === 'function') {
2259
- if (!this._handle) {
2260
- this.once('close', function close() {
2261
- cb(new ERR_SERVER_NOT_RUNNING());
2262
- });
2263
- } else {
2264
- this.once('close', cb);
2265
- }
2266
- }
2267
-
2268
- if (this._handle) {
2269
- this._handle.close();
2270
- this._handle = null;
2271
- }
2272
-
2273
- if (this._usingWorkers) {
2274
- let left = this._workers.length;
2275
- const onWorkerClose = () => {
2276
- if (--left !== 0) return;
2277
-
2278
- this._connections = 0;
2279
- this._emitCloseIfDrained();
2280
- };
2281
-
2282
- // Increment connections to be sure that, even if all sockets will be closed
2283
- // during polling of workers, `close` event will be emitted only once.
2284
- this._connections++;
2285
-
2286
- // Poll workers
2287
- for (let n = 0; n < this._workers.length; n++)
2288
- this._workers[n].close(onWorkerClose);
2289
- } else {
2290
- this._emitCloseIfDrained();
2291
- }
2292
-
2293
- return this;
2294
- };
2295
-
2296
- Server.prototype[SymbolAsyncDispose] = async function() {
2297
- if (!this._handle) {
2298
- return;
2299
- }
2300
- return FunctionPrototypeCall(promisify(this.close), this);
2301
- };
2302
-
2303
- Server.prototype._emitCloseIfDrained = function() {
2304
- debug('SERVER _emitCloseIfDrained');
2305
-
2306
- if (this._handle || this._connections) {
2307
- debug('SERVER handle? %j connections? %d',
2308
- !!this._handle, this._connections);
2309
- return;
2310
- }
2311
-
2312
- defaultTriggerAsyncIdScope(this[async_id_symbol],
2313
- process.nextTick,
2314
- emitCloseNT,
2315
- this);
2316
- };
2317
-
2318
-
2319
- function emitCloseNT(self) {
2320
- debug('SERVER: emit close');
2321
- self.emit('close');
2322
- }
2323
-
2324
-
2325
- Server.prototype[EventEmitter.captureRejectionSymbol] = function(
2326
- err, event, sock) {
2327
-
2328
- switch (event) {
2329
- case 'connection':
2330
- sock.destroy(err);
2331
- break;
2332
- default:
2333
- this.emit('error', err);
2334
- }
2335
- };
2336
-
2337
-
2338
- // Legacy alias on the C++ wrapper object. This is not public API, so we may
2339
- // want to runtime-deprecate it at some point. There's no hurry, though.
2340
- ObjectDefineProperty(TCP.prototype, 'owner', {
2341
- __proto__: null,
2342
- get() { return this[owner_symbol]; },
2343
- set(v) { return this[owner_symbol] = v; },
2344
- });
2345
-
2346
- ObjectDefineProperty(Socket.prototype, '_handle', {
2347
- __proto__: null,
2348
- get() { return this[kHandle]; },
2349
- set(v) { return this[kHandle] = v; },
2350
- });
2351
-
2352
- Server.prototype._setupWorker = function(socketList) {
2353
- this._usingWorkers = true;
2354
- this._workers.push(socketList);
2355
- socketList.once('exit', (socketList) => {
2356
- const index = ArrayPrototypeIndexOf(this._workers, socketList);
2357
- this._workers.splice(index, 1);
2358
- });
2359
- };
2360
-
2361
- Server.prototype.ref = function() {
2362
- this._unref = false;
2363
-
2364
- if (this._handle)
2365
- this._handle.ref();
2366
-
2367
- return this;
2368
- };
2369
-
2370
- Server.prototype.unref = function() {
2371
- this._unref = true;
2372
-
2373
- if (this._handle)
2374
- this._handle.unref();
2375
-
2376
- return this;
2377
- };
2378
-
2379
- let _setSimultaneousAccepts;
2380
- let warnSimultaneousAccepts = true;
2381
-
2382
- if (isWindows) {
2383
- let simultaneousAccepts;
2384
-
2385
- _setSimultaneousAccepts = function(handle) {
2386
- if (warnSimultaneousAccepts) {
2387
- process.emitWarning(
2388
- 'net._setSimultaneousAccepts() is deprecated and will be removed.',
2389
- 'DeprecationWarning', 'DEP0121');
2390
- warnSimultaneousAccepts = false;
2391
- }
2392
- if (handle === undefined) {
2393
- return;
2394
- }
2395
-
2396
- if (simultaneousAccepts === undefined) {
2397
- simultaneousAccepts = (process.env.NODE_MANY_ACCEPTS &&
2398
- process.env.NODE_MANY_ACCEPTS !== '0');
2399
- }
2400
-
2401
- if (handle._simultaneousAccepts !== simultaneousAccepts) {
2402
- handle.setSimultaneousAccepts(!!simultaneousAccepts);
2403
- handle._simultaneousAccepts = simultaneousAccepts;
2404
- }
2405
- };
2406
- } else {
2407
- _setSimultaneousAccepts = function() {
2408
- if (warnSimultaneousAccepts) {
2409
- process.emitWarning(
2410
- 'net._setSimultaneousAccepts() is deprecated and will be removed.',
2411
- 'DeprecationWarning', 'DEP0121');
2412
- warnSimultaneousAccepts = false;
2413
- }
2414
- };
2415
- }
2416
-
2417
- module.exports = {
2418
- _createServerHandle: createServerHandle,
2419
- _normalizeArgs: normalizeArgs,
2420
- _setSimultaneousAccepts,
2421
- get BlockList() {
2422
- BlockList ??= require('internal/blocklist').BlockList;
2423
- return BlockList;
2424
- },
2425
- get SocketAddress() {
2426
- SocketAddress ??= require('internal/socketaddress').SocketAddress;
2427
- return SocketAddress;
2428
- },
2429
- connect,
2430
- createConnection: connect,
2431
- createServer,
2432
- isIP: isIP,
2433
- isIPv4: isIPv4,
2434
- isIPv6: isIPv6,
2435
- Server,
2436
- Socket,
2437
- Stream: Socket, // Legacy naming
2438
- getDefaultAutoSelectFamily,
2439
- setDefaultAutoSelectFamily,
2440
- getDefaultAutoSelectFamilyAttemptTimeout,
2441
- setDefaultAutoSelectFamilyAttemptTimeout,
2442
- };