3 const EventEmitter = require('events');
4 const stream = require('stream');
5 const timers = require('timers');
6 const util = require('util');
7 const internalUtil = require('internal/util');
8 const assert = require('assert');
9 const cares = process.binding('cares_wrap');
10 const uv = process.binding('uv');
12 const Buffer = require('buffer').Buffer;
13 const TTYWrap = process.binding('tty_wrap');
14 const TCP = process.binding('tcp_wrap').TCP;
15 const Pipe = process.binding('pipe_wrap').Pipe;
16 const TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap;
17 const PipeConnectWrap = process.binding('pipe_wrap').PipeConnectWrap;
18 const ShutdownWrap = process.binding('stream_wrap').ShutdownWrap;
19 const WriteWrap = process.binding('stream_wrap').WriteWrap;
23 const errnoException = util._errnoException;
24 const exceptionWithHostPort = util._exceptionWithHostPort;
28 function createHandle(fd) {
29 var type = TTYWrap.guessHandleType(fd);
30 if (type === 'PIPE') return new Pipe();
31 if (type === 'TCP') return new TCP();
32 throw new TypeError('Unsupported fd type: ' + type);
36 const debug = util.debuglog('net');
38 function isPipeName(s) {
39 return typeof s === 'string' && toNumber(s) === false;
42 exports.createServer = function(options, connectionListener) {
43 return new Server(options, connectionListener);
49 // var s = net.connect({port: 80, host: 'google.com'}, function() {
53 // There are various forms:
55 // connect(options, [cb])
56 // connect(port, [host], [cb])
57 // connect(path, [cb]);
59 exports.connect = exports.createConnection = function() {
60 var args = normalizeConnectArgs(arguments);
61 debug('createConnection', args);
62 var s = new Socket(args[0]);
63 return Socket.prototype.connect.apply(s, args);
66 // Returns an array [options] or [options, cb]
67 // It is the same as the argument of Socket.prototype.connect().
68 function normalizeConnectArgs(args) {
71 if (args[0] !== null && typeof args[0] === 'object') {
72 // connect(options, [cb])
74 } else if (isPipeName(args[0])) {
75 // connect(path, [cb]);
76 options.path = args[0];
78 // connect(port, [host], [cb])
79 options.port = args[0];
80 if (typeof args[1] === 'string') {
81 options.host = args[1];
85 var cb = args[args.length - 1];
86 return typeof cb === 'function' ? [options, cb] : [options];
88 exports._normalizeConnectArgs = normalizeConnectArgs;
91 // called when creating new Socket, or when re-using a closed Socket
92 function initSocketHandle(self) {
93 self.destroyed = false;
95 self._bytesDispatched = 0;
96 self._sockname = null;
98 // Handle creation may be deferred to bind() or connect() time.
100 self._handle.owner = self;
101 self._handle.onread = onread;
103 // If handle doesn't support writev - neither do we
104 if (!self._handle.writev)
109 function Socket(options) {
110 if (!(this instanceof Socket)) return new Socket(options);
112 this._connecting = false;
113 this._hadError = false;
118 if (typeof options === 'number')
119 options = { fd: options }; // Legacy interface.
120 else if (options === undefined)
123 stream.Duplex.call(this, options);
125 if (options.handle) {
126 this._handle = options.handle; // private
127 } else if (options.fd !== undefined) {
128 this._handle = createHandle(options.fd);
129 this._handle.open(options.fd);
130 if ((options.fd == 1 || options.fd == 2) &&
131 (this._handle instanceof Pipe) &&
132 process.platform === 'win32') {
133 // Make stdout and stderr blocking on Windows
134 var err = this._handle.setBlocking(true);
136 throw errnoException(err, 'setBlocking');
138 this.readable = options.readable !== false;
139 this.writable = options.writable !== false;
141 // these will be set once there is a connection
142 this.readable = this.writable = false;
145 // shut down the socket when we're finished with it.
146 this.on('finish', onSocketFinish);
147 this.on('_socketEnd', onSocketEnd);
149 initSocketHandle(this);
151 this._pendingData = null;
152 this._pendingEncoding = '';
154 // handle strings directly
155 this._writableState.decodeStrings = false;
157 // default to *not* allowing half open sockets
158 this.allowHalfOpen = options && options.allowHalfOpen || false;
160 // if we have a handle, then start the flow of data into the
161 // buffer. if not, then this will happen when we connect
162 if (this._handle && options.readable !== false) {
163 if (options.pauseOnCreate) {
164 // stop the handle from reading and pause the stream
165 this._handle.reading = false;
166 this._handle.readStop();
167 this._readableState.flowing = false;
173 util.inherits(Socket, stream.Duplex);
175 Socket.prototype._unrefTimer = function unrefTimer() {
176 for (var s = this; s !== null; s = s._parent)
177 timers._unrefActive(s);
180 // the user has called .end(), and all the bytes have been
181 // sent out to the other side.
182 // If allowHalfOpen is false, or if the readable side has
183 // ended already, then destroy.
184 // If allowHalfOpen is true, then we need to do a shutdown,
185 // so that only the writable side will be cleaned up.
186 function onSocketFinish() {
187 // If still connecting - defer handling 'finish' until 'connect' will happen
188 if (this._connecting) {
189 debug('osF: not yet connected');
190 return this.once('connect', onSocketFinish);
193 debug('onSocketFinish');
194 if (!this.readable || this._readableState.ended) {
195 debug('oSF: ended, destroy', this._readableState);
196 return this.destroy();
199 debug('oSF: not ended, call shutdown()');
201 // otherwise, just shutdown, or destroy() if not possible
202 if (!this._handle || !this._handle.shutdown)
203 return this.destroy();
205 var req = new ShutdownWrap();
206 req.oncomplete = afterShutdown;
207 req.handle = this._handle;
208 var err = this._handle.shutdown(req);
211 return this._destroy(errnoException(err, 'shutdown'));
215 function afterShutdown(status, handle, req) {
216 var self = handle.owner;
218 debug('afterShutdown destroyed=%j', self.destroyed,
219 self._readableState);
221 // callback may come after call to destroy.
225 if (self._readableState.ended) {
226 debug('readableState ended, destroying');
229 self.once('_socketEnd', self.destroy);
233 // the EOF has been received, and no more bytes are coming.
234 // if the writable side has ended already, then clean everything
236 function onSocketEnd() {
237 // XXX Should not have to do as much crap in this function.
238 // ended should already be true, since this is called *after*
239 // the EOF errno and onread has eof'ed
240 debug('onSocketEnd', this._readableState);
241 this._readableState.ended = true;
242 if (this._readableState.endEmitted) {
243 this.readable = false;
246 this.once('end', function() {
247 this.readable = false;
253 if (!this.allowHalfOpen) {
254 this.write = writeAfterFIN;
259 // Provide a better error message when we call end() as a result
260 // of the other side sending a FIN. The standard 'write after end'
261 // is overly vague, and makes it seem like the user's code is to blame.
262 function writeAfterFIN(chunk, encoding, cb) {
263 if (typeof encoding === 'function') {
268 var er = new Error('This socket has been ended by the other party');
271 // TODO: defer error events consistently everywhere, not just the cb
272 self.emit('error', er);
273 if (typeof cb === 'function') {
274 process.nextTick(cb, er);
278 exports.Socket = Socket;
279 exports.Stream = Socket; // Legacy naming.
281 Socket.prototype.read = function(n) {
283 return stream.Readable.prototype.read.call(this, n);
285 this.read = stream.Readable.prototype.read;
286 this._consuming = true;
291 Socket.prototype.listen = function() {
292 debug('socket.listen');
294 self.on('connection', arguments[0]);
295 listen(self, null, null, null);
299 Socket.prototype.setTimeout = function(msecs, callback) {
301 timers.unenroll(this);
303 this.removeListener('timeout', callback);
306 timers.enroll(this, msecs);
307 timers._unrefActive(this);
309 this.once('timeout', callback);
316 Socket.prototype._onTimeout = function() {
318 this.emit('timeout');
322 Socket.prototype.setNoDelay = function(enable) {
325 enable ? this.setNoDelay : this.setNoDelay.bind(this, enable));
329 // backwards compatibility: assume true when `enable` is omitted
330 if (this._handle.setNoDelay)
331 this._handle.setNoDelay(enable === undefined ? true : !!enable);
337 Socket.prototype.setKeepAlive = function(setting, msecs) {
339 this.once('connect', this.setKeepAlive.bind(this, setting, msecs));
343 if (this._handle.setKeepAlive)
344 this._handle.setKeepAlive(setting, ~~(msecs / 1000));
350 Socket.prototype.address = function() {
351 return this._getsockname();
355 Object.defineProperty(Socket.prototype, 'readyState', {
357 if (this._connecting) {
359 } else if (this.readable && this.writable) {
361 } else if (this.readable && !this.writable) {
363 } else if (!this.readable && this.writable) {
372 Object.defineProperty(Socket.prototype, 'bufferSize', {
375 return this._handle.writeQueueSize + this._writableState.length;
381 // Just call handle.readStart until we have enough in the buffer
382 Socket.prototype._read = function(n) {
385 if (this._connecting || !this._handle) {
386 debug('_read wait for connection');
387 this.once('connect', this._read.bind(this, n));
388 } else if (!this._handle.reading) {
389 // not already reading, start the flow
390 debug('Socket._read readStart');
391 this._handle.reading = true;
392 var err = this._handle.readStart();
394 this._destroy(errnoException(err, 'read'));
399 Socket.prototype.end = function(data, encoding) {
400 stream.Duplex.prototype.end.call(this, data, encoding);
401 this.writable = false;
402 DTRACE_NET_STREAM_END(this);
403 LTTNG_NET_STREAM_END(this);
405 // just in case we're waiting for an EOF.
406 if (this.readable && !this._readableState.endEmitted)
413 // Call whenever we set writable=false or readable=false
414 function maybeDestroy(socket) {
415 if (!socket.readable &&
418 !socket._connecting &&
419 !socket._writableState.length) {
425 Socket.prototype.destroySoon = function() {
429 if (this._writableState.finished)
432 this.once('finish', this.destroy);
436 Socket.prototype._destroy = function(exception, cb) {
441 function fireErrorCallbacks() {
442 if (cb) cb(exception);
443 if (exception && !self._writableState.errorEmitted) {
444 process.nextTick(emitErrorNT, self, exception);
445 self._writableState.errorEmitted = true;
449 if (this.destroyed) {
450 debug('already destroyed, fire error callbacks');
451 fireErrorCallbacks();
455 self._connecting = false;
457 this.readable = this.writable = false;
459 for (var s = this; s !== null; s = s._parent)
464 if (this !== process.stderr)
465 debug('close handle');
466 var isException = exception ? true : false;
467 this._handle.close(function() {
469 self.emit('close', isException);
471 this._handle.onread = noop;
473 this._sockname = null;
476 // we set destroyed to true before firing error callbacks in order
477 // to make it re-entrance safe in case Socket.prototype.destroy()
478 // is called within callbacks
479 this.destroyed = true;
480 fireErrorCallbacks();
483 COUNTER_NET_SERVER_CONNECTION_CLOSE(this);
485 this.server._connections--;
486 if (this.server._emitCloseIfDrained) {
487 this.server._emitCloseIfDrained();
493 Socket.prototype.destroy = function(exception) {
494 debug('destroy', exception);
495 this._destroy(exception);
499 // This function is called whenever the handle gets a
500 // buffer, or when there's an error reading.
501 function onread(nread, buffer) {
503 var self = handle.owner;
504 assert(handle === self._handle, 'handle != self._handle');
508 debug('onread', nread);
514 // In theory (and in practice) calling readStop right now
515 // will prevent this from being called again until _read() gets
518 // if it's not enough data, we'll just call handle.readStart()
520 self.bytesRead += nread;
522 // Optimization: emit the original buffer with end points
523 var ret = self.push(buffer);
525 if (handle.reading && !ret) {
526 handle.reading = false;
528 var err = handle.readStop();
530 self._destroy(errnoException(err, 'read'));
535 // if we didn't get any bytes, that doesn't necessarily mean EOF.
536 // wait for the next one.
538 debug('not any data, keep waiting');
542 // Error, possibly EOF.
543 if (nread !== uv.UV_EOF) {
544 return self._destroy(errnoException(nread, 'read'));
549 if (self._readableState.length === 0) {
550 self.readable = false;
554 // push a null to signal the end of data.
557 // internal end event so that we know that the actual socket
558 // is no longer readable, and we can start the shutdown
559 // procedure. No need to wait for all the data to be consumed.
560 self.emit('_socketEnd');
564 Socket.prototype._getpeername = function() {
565 if (!this._peername) {
566 if (!this._handle || !this._handle.getpeername) {
570 var err = this._handle.getpeername(out);
571 if (err) return {}; // FIXME(bnoordhuis) Throw?
572 this._peername = out;
574 return this._peername;
578 Socket.prototype.__defineGetter__('remoteAddress', function() {
579 return this._getpeername().address;
582 Socket.prototype.__defineGetter__('remoteFamily', function() {
583 return this._getpeername().family;
586 Socket.prototype.__defineGetter__('remotePort', function() {
587 return this._getpeername().port;
591 Socket.prototype._getsockname = function() {
592 if (!this._handle || !this._handle.getsockname) {
595 if (!this._sockname) {
597 var err = this._handle.getsockname(out);
598 if (err) return {}; // FIXME(bnoordhuis) Throw?
599 this._sockname = out;
601 return this._sockname;
605 Socket.prototype.__defineGetter__('localAddress', function() {
606 return this._getsockname().address;
610 Socket.prototype.__defineGetter__('localPort', function() {
611 return this._getsockname().port;
615 Socket.prototype.write = function(chunk, encoding, cb) {
616 if (typeof chunk !== 'string' && !(chunk instanceof Buffer))
617 throw new TypeError('invalid data');
618 return stream.Duplex.prototype.write.apply(this, arguments);
622 Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
623 // If we are still connecting, then buffer this for later.
624 // The Writable logic will buffer up any more writes while
625 // waiting for this one to be done.
626 if (this._connecting) {
627 this._pendingData = data;
628 this._pendingEncoding = encoding;
629 this.once('connect', function() {
630 this._writeGeneric(writev, data, encoding, cb);
634 this._pendingData = null;
635 this._pendingEncoding = '';
640 this._destroy(new Error('This socket is closed.'), cb);
644 var req = new WriteWrap();
645 req.handle = this._handle;
646 req.oncomplete = afterWrite;
651 var chunks = new Array(data.length << 1);
652 for (var i = 0; i < data.length; i++) {
654 var chunk = entry.chunk;
655 var enc = entry.encoding;
656 chunks[i * 2] = chunk;
657 chunks[i * 2 + 1] = enc;
659 err = this._handle.writev(req, chunks);
662 if (err === 0) req._chunks = chunks;
665 if (data instanceof Buffer) {
666 req.buffer = data; // Keep reference alive.
671 err = createWriteReq(req, this._handle, data, enc);
675 return this._destroy(errnoException(err, 'write', req.error), cb);
677 this._bytesDispatched += req.bytes;
679 // If it was entirely flushed, we can write some more right now.
680 // However, if more is left in the queue, then wait until that clears.
681 if (req.async && this._handle.writeQueueSize != 0)
688 Socket.prototype._writev = function(chunks, cb) {
689 this._writeGeneric(true, chunks, '', cb);
693 Socket.prototype._write = function(data, encoding, cb) {
694 this._writeGeneric(false, data, encoding, cb);
697 function createWriteReq(req, handle, data, encoding) {
700 return handle.writeBinaryString(req, data);
703 return handle.writeBuffer(req, data);
707 return handle.writeUtf8String(req, data);
710 return handle.writeAsciiString(req, data);
716 return handle.writeUcs2String(req, data);
719 return handle.writeBuffer(req, new Buffer(data, encoding));
724 Socket.prototype.__defineGetter__('bytesWritten', function() {
725 var bytes = this._bytesDispatched,
726 state = this._writableState,
727 data = this._pendingData,
728 encoding = this._pendingEncoding;
733 state.getBuffer().forEach(function(el) {
734 if (el.chunk instanceof Buffer)
735 bytes += el.chunk.length;
737 bytes += Buffer.byteLength(el.chunk, el.encoding);
741 if (data instanceof Buffer)
742 bytes += data.length;
744 bytes += Buffer.byteLength(data, encoding);
751 function afterWrite(status, handle, req, err) {
752 var self = handle.owner;
753 if (self !== process.stderr && self !== process.stdout)
754 debug('afterWrite', status);
756 // callback may come after call to destroy.
757 if (self.destroyed) {
758 debug('afterWrite destroyed');
763 var ex = exceptionWithHostPort(status, 'write', req.address, req.port);
764 debug('write failure', ex);
765 self._destroy(ex, req.cb);
771 if (self !== process.stderr && self !== process.stdout)
772 debug('afterWrite call cb');
779 function connect(self, address, port, addressType, localAddress, localPort) {
780 // TODO return promise from Socket.prototype.connect which
781 // wraps _connectReq.
783 assert.ok(self._connecting);
787 if (localAddress || localPort) {
790 if (addressType === 4) {
791 localAddress = localAddress || '0.0.0.0';
792 bind = self._handle.bind;
793 } else if (addressType === 6) {
794 localAddress = localAddress || '::';
795 bind = self._handle.bind6;
797 self._destroy(new TypeError('Invalid addressType: ' + addressType));
801 debug('binding to localAddress: %s and localPort: %d',
805 bind = bind.bind(self._handle);
806 err = bind(localAddress, localPort);
809 var ex = exceptionWithHostPort(err, 'bind', localAddress, localPort);
815 if (addressType === 6 || addressType === 4) {
816 var req = new TCPConnectWrap();
817 req.oncomplete = afterConnect;
818 req.address = address;
820 req.localAddress = localAddress;
821 req.localPort = localPort;
823 if (addressType === 4)
824 err = self._handle.connect(req, address, port);
826 err = self._handle.connect6(req, address, port);
829 var req = new PipeConnectWrap();
830 req.address = address;
831 req.oncomplete = afterConnect;
832 err = self._handle.connect(req, address, afterConnect);
836 var sockname = self._getsockname();
840 details = sockname.address + ':' + sockname.port;
843 var ex = exceptionWithHostPort(err, 'connect', address, port, details);
849 // Check that the port number is not NaN when coerced to a number,
850 // is an integer and that it falls within the legal range of port numbers.
851 function isLegalPort(port) {
852 if (typeof port === 'string' && port.trim() === '')
854 return +port === (port >>> 0) && port >= 0 && port <= 0xFFFF;
858 Socket.prototype.connect = function(options, cb) {
859 if (this.write !== Socket.prototype.write)
860 this.write = Socket.prototype.write;
862 if (options === null || typeof options !== 'object') {
864 // connect(port, [host], [cb])
865 // connect(path, [cb]);
866 var args = normalizeConnectArgs(arguments);
867 return Socket.prototype.connect.apply(this, args);
870 if (this.destroyed) {
871 this._readableState.reading = false;
872 this._readableState.ended = false;
873 this._readableState.endEmitted = false;
874 this._writableState.ended = false;
875 this._writableState.ending = false;
876 this._writableState.finished = false;
877 this._writableState.errorEmitted = false;
878 this.destroyed = false;
880 this._peername = null;
881 this._sockname = null;
885 var pipe = !!options.path;
886 debug('pipe', pipe, options.path);
889 this._handle = pipe ? new Pipe() : new TCP();
890 initSocketHandle(this);
893 if (typeof cb === 'function') {
894 self.once('connect', cb);
899 self._connecting = true;
900 self.writable = true;
903 connect(self, options.path);
906 lookupAndConnect(self, options);
912 function lookupAndConnect(self, options) {
913 const dns = require('dns');
914 var host = options.host || 'localhost';
915 var port = options.port;
916 var localAddress = options.localAddress;
917 var localPort = options.localPort;
919 if (localAddress && !exports.isIP(localAddress))
920 throw new TypeError('localAddress must be a valid IP: ' + localAddress);
922 if (localPort && typeof localPort !== 'number')
923 throw new TypeError('localPort should be a number: ' + localPort);
925 if (typeof port !== 'undefined') {
926 if (typeof port !== 'number' && typeof port !== 'string')
927 throw new TypeError('port should be a number or string: ' + port);
928 if (!isLegalPort(port))
929 throw new RangeError('port should be >= 0 and < 65536: ' + port);
933 // If host is an IP, skip performing a lookup
934 // TODO(evanlucas) should we hot path this for localhost?
935 var addressType = exports.isIP(host);
937 process.nextTick(function() {
938 if (self._connecting)
939 connect(self, host, port, addressType, localAddress, localPort);
944 if (options.lookup && typeof options.lookup !== 'function')
945 throw new TypeError('options.lookup should be a function.');
948 family: options.family,
952 if (dnsopts.family !== 4 && dnsopts.family !== 6) {
953 dnsopts.hints = dns.ADDRCONFIG;
954 // The AI_V4MAPPED hint is not supported on FreeBSD, and getaddrinfo
955 // returns EAI_BADFLAGS. However, it seems to be supported on most other
957 // http://lists.freebsd.org/pipermail/freebsd-bugs/2008-February/028260.html
958 // for more information on the lack of support for FreeBSD.
959 if (process.platform !== 'freebsd')
960 dnsopts.hints |= dns.V4MAPPED;
963 debug('connect: find host ' + host);
964 debug('connect: dns options', dnsopts);
966 var lookup = options.lookup || dns.lookup;
967 lookup(host, dnsopts, function(err, ip, addressType) {
968 self.emit('lookup', err, ip, addressType);
970 // It's possible we were destroyed while looking this up.
971 // XXX it would be great if we could cancel the promise returned by
973 if (!self._connecting) return;
976 // net.createConnection() creates a net.Socket object and
977 // immediately calls net.Socket.connect() on it (that's us).
978 // There are no event listeners registered yet so defer the
979 // error event to the next tick.
980 err.host = options.host;
981 err.port = options.port;
982 err.message = err.message + ' ' + options.host + ':' + options.port;
983 process.nextTick(connectErrorNT, self, err);
997 function connectErrorNT(self, err) {
998 self.emit('error', err);
1003 Socket.prototype.ref = function() {
1004 if (!this._handle) {
1005 this.once('connect', this.ref);
1015 Socket.prototype.unref = function() {
1016 if (!this._handle) {
1017 this.once('connect', this.unref);
1021 this._handle.unref();
1027 function afterConnect(status, handle, req, readable, writable) {
1028 var self = handle.owner;
1030 // callback may come after call to destroy
1031 if (self.destroyed) {
1035 // Update handle if it was wrapped
1036 // TODO(indutny): assert that the handle is actually an ancestor of old one
1037 handle = self._handle;
1039 debug('afterConnect');
1041 assert.ok(self._connecting);
1042 self._connecting = false;
1043 self._sockname = null;
1046 self.readable = readable;
1047 self.writable = writable;
1050 self.emit('connect');
1052 // start the first read, or get an immediate EOF.
1053 // this doesn't actually consume any bytes, because len=0.
1054 if (readable && !self.isPaused())
1058 self._connecting = false;
1060 if (req.localAddress && req.localPort) {
1061 details = req.localAddress + ':' + req.localPort;
1063 var ex = exceptionWithHostPort(status,
1069 ex.localAddress = req.localAddress;
1070 ex.localPort = req.localPort;
1077 function Server(options, connectionListener) {
1078 if (!(this instanceof Server))
1079 return new Server(options, connectionListener);
1081 EventEmitter.call(this);
1085 if (typeof options === 'function') {
1086 connectionListener = options;
1088 self.on('connection', connectionListener);
1090 options = options || {};
1092 if (typeof connectionListener === 'function') {
1093 self.on('connection', connectionListener);
1097 this._connections = 0;
1099 Object.defineProperty(this, 'connections', {
1100 get: internalUtil.deprecate(function() {
1102 if (self._usingSlaves) {
1105 return self._connections;
1106 }, 'Server.connections property is deprecated. ' +
1107 'Use Server.getConnections method instead.'),
1108 set: internalUtil.deprecate(function(val) {
1109 return (self._connections = val);
1110 }, 'Server.connections property is deprecated.'),
1111 configurable: true, enumerable: false
1114 this._handle = null;
1115 this._usingSlaves = false;
1117 this._unref = false;
1119 this.allowHalfOpen = options.allowHalfOpen || false;
1120 this.pauseOnConnect = !!options.pauseOnConnect;
1122 util.inherits(Server, EventEmitter);
1123 exports.Server = Server;
1126 function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
1128 function _listen(handle, backlog) {
1129 // Use a backlog of 512 entries. We pass 511 to the listen() call because
1130 // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
1131 // which will thus give us a backlog of 512 entries.
1132 return handle.listen(backlog || 511);
1135 var createServerHandle = exports._createServerHandle =
1136 function(address, port, addressType, fd) {
1138 // assign handle in listen, and clean up if bind or listen fails
1142 if (typeof fd === 'number' && fd >= 0) {
1144 handle = createHandle(fd);
1147 // Not a fd we can listen on. This will trigger an error.
1148 debug('listen invalid fd=' + fd + ': ' + e.message);
1149 return uv.UV_EINVAL;
1152 handle.readable = true;
1153 handle.writable = true;
1154 assert(!address && !port);
1155 } else if (port === -1 && addressType === -1) {
1156 handle = new Pipe();
1157 if (process.platform === 'win32') {
1158 var instances = parseInt(process.env.NODE_PENDING_PIPE_INSTANCES);
1159 if (!isNaN(instances)) {
1160 handle.setPendingInstances(instances);
1168 if (address || port || isTCP) {
1169 debug('bind to ' + (address || 'anycast'));
1171 // Try binding to ipv6 first
1172 err = handle.bind6('::', port);
1176 return createServerHandle('0.0.0.0', port);
1178 } else if (addressType === 6) {
1179 err = handle.bind6(address, port);
1181 err = handle.bind(address, port);
1194 Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
1195 debug('listen2', address, port, addressType, backlog, fd);
1198 // If there is not yet a handle, we need to create one and bind.
1199 // In the case of a server sent via IPC, we don't need to do this.
1201 debug('_listen2: have a handle already');
1203 debug('_listen2: create a handle');
1207 if (!address && typeof fd !== 'number') {
1208 rval = createServerHandle('::', port, 6, fd);
1210 if (typeof rval === 'number') {
1212 address = '0.0.0.0';
1221 rval = createServerHandle(address, port, addressType, fd);
1223 if (typeof rval === 'number') {
1224 var error = exceptionWithHostPort(rval, 'listen', address, port);
1225 process.nextTick(emitErrorNT, self, error);
1228 self._handle = rval;
1231 self._handle.onconnection = onconnection;
1232 self._handle.owner = self;
1234 var err = _listen(self._handle, backlog);
1237 var ex = exceptionWithHostPort(err, 'listen', address, port);
1238 self._handle.close();
1239 self._handle = null;
1240 process.nextTick(emitErrorNT, self, ex);
1244 // generate connection key, this should be unique to the connection
1245 this._connectionKey = addressType + ':' + address + ':' + port;
1247 // unref the handle if the server was unref'ed prior to listening
1251 process.nextTick(emitListeningNT, self);
1255 function emitErrorNT(self, err) {
1256 self.emit('error', err);
1260 function emitListeningNT(self) {
1261 // ensure handle hasn't closed
1263 self.emit('listening');
1267 function listen(self, address, port, addressType, backlog, fd, exclusive) {
1268 exclusive = !!exclusive;
1270 if (!cluster) cluster = require('cluster');
1272 if (cluster.isMaster || exclusive) {
1273 self._listen2(address, port, addressType, backlog, fd);
1277 cluster._getServer(self, {
1280 addressType: addressType,
1285 function cb(err, handle) {
1286 // EADDRINUSE may not be reported until we call listen(). To complicate
1287 // matters, a failed bind() followed by listen() will implicitly bind to
1288 // a random port. Ergo, check that the socket is bound to the expected
1289 // port before calling listen().
1291 // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
1292 // getsockname() method. Non-issue for now, the cluster module doesn't
1293 // really support pipes anyway.
1294 if (err === 0 && port > 0 && handle.getsockname) {
1296 err = handle.getsockname(out);
1297 if (err === 0 && port !== out.port)
1298 err = uv.UV_EADDRINUSE;
1302 var ex = exceptionWithHostPort(err, 'bind', address, port);
1303 return self.emit('error', ex);
1306 self._handle = handle;
1307 self._listen2(address, port, addressType, backlog, fd);
1312 Server.prototype.listen = function() {
1315 var lastArg = arguments[arguments.length - 1];
1316 if (typeof lastArg === 'function') {
1317 self.once('listening', lastArg);
1320 var port = toNumber(arguments[0]);
1322 // The third optional argument is the backlog size.
1323 // When the ip is omitted it can be the second argument.
1324 var backlog = toNumber(arguments[1]) || toNumber(arguments[2]);
1326 if (arguments.length === 0 || typeof arguments[0] === 'function') {
1327 // Bind to a random port.
1328 listen(self, null, 0, null, backlog);
1329 } else if (arguments[0] !== null && typeof arguments[0] === 'object') {
1330 var h = arguments[0];
1331 h = h._handle || h.handle || h;
1333 if (h instanceof TCP) {
1335 listen(self, null, -1, -1, backlog);
1336 } else if (typeof h.fd === 'number' && h.fd >= 0) {
1337 listen(self, null, null, null, backlog, h.fd);
1339 // The first argument is a configuration object
1341 backlog = h.backlog;
1343 if (typeof h.port === 'number' || typeof h.port === 'string' ||
1344 (typeof h.port === 'undefined' && 'port' in h)) {
1345 // Undefined is interpreted as zero (random port) for consistency
1346 // with net.connect().
1347 if (typeof h.port !== 'undefined' && !isLegalPort(h.port))
1348 throw new RangeError('port should be >= 0 and < 65536: ' + h.port);
1350 listenAfterLookup(h.port | 0, h.host, backlog, h.exclusive);
1352 listen(self, null, h.port | 0, 4, backlog, undefined, h.exclusive);
1353 } else if (h.path && isPipeName(h.path)) {
1354 var pipeName = self._pipeName = h.path;
1355 listen(self, pipeName, -1, -1, backlog, undefined, h.exclusive);
1357 throw new Error('Invalid listen argument: ' + h);
1360 } else if (isPipeName(arguments[0])) {
1361 // UNIX socket or Windows pipe.
1362 var pipeName = self._pipeName = arguments[0];
1363 listen(self, pipeName, -1, -1, backlog);
1365 } else if (arguments[1] === undefined ||
1366 typeof arguments[1] === 'function' ||
1367 typeof arguments[1] === 'number') {
1368 // The first argument is the port, no IP given.
1369 listen(self, null, port, 4, backlog);
1372 // The first argument is the port, the second an IP.
1373 listenAfterLookup(port, arguments[1], backlog);
1376 function listenAfterLookup(port, address, backlog, exclusive) {
1377 require('dns').lookup(address, function(err, ip, addressType) {
1379 self.emit('error', err);
1381 addressType = ip ? addressType : 4;
1382 listen(self, ip, port, addressType, backlog, undefined, exclusive);
1390 Server.prototype.address = function() {
1391 if (this._handle && this._handle.getsockname) {
1393 this._handle.getsockname(out);
1394 // TODO(bnoordhuis) Check err and throw?
1396 } else if (this._pipeName) {
1397 return this._pipeName;
1403 function onconnection(err, clientHandle) {
1405 var self = handle.owner;
1407 debug('onconnection');
1410 self.emit('error', errnoException(err, 'accept'));
1414 if (self.maxConnections && self._connections >= self.maxConnections) {
1415 clientHandle.close();
1419 var socket = new Socket({
1420 handle: clientHandle,
1421 allowHalfOpen: self.allowHalfOpen,
1422 pauseOnCreate: self.pauseOnConnect
1424 socket.readable = socket.writable = true;
1427 self._connections++;
1428 socket.server = self;
1430 DTRACE_NET_SERVER_CONNECTION(socket);
1431 LTTNG_NET_SERVER_CONNECTION(socket);
1432 COUNTER_NET_SERVER_CONNECTION(socket);
1433 self.emit('connection', socket);
1437 Server.prototype.getConnections = function(cb) {
1438 function end(err, connections) {
1439 process.nextTick(cb, err, connections);
1442 if (!this._usingSlaves) {
1443 return end(null, this._connections);
1447 var left = this._slaves.length,
1448 total = this._connections;
1450 function oncount(err, count) {
1457 if (--left === 0) return end(null, total);
1460 this._slaves.forEach(function(slave) {
1461 slave.getConnections(oncount);
1466 Server.prototype.close = function(cb) {
1467 function onSlaveClose() {
1468 if (--left !== 0) return;
1470 self._connections = 0;
1471 self._emitCloseIfDrained();
1474 if (typeof cb === 'function') {
1475 if (!this._handle) {
1476 this.once('close', function() {
1477 cb(new Error('Not running'));
1480 this.once('close', cb);
1485 this._handle.close();
1486 this._handle = null;
1489 if (this._usingSlaves) {
1491 left = this._slaves.length;
1493 // Increment connections to be sure that, even if all sockets will be closed
1494 // during polling of slaves, `close` event will be emitted only once.
1495 this._connections++;
1498 this._slaves.forEach(function(slave) {
1499 slave.close(onSlaveClose);
1502 this._emitCloseIfDrained();
1508 Server.prototype._emitCloseIfDrained = function() {
1509 debug('SERVER _emitCloseIfDrained');
1512 if (self._handle || self._connections) {
1513 debug('SERVER handle? %j connections? %d',
1514 !!self._handle, self._connections);
1518 process.nextTick(emitCloseNT, self);
1522 function emitCloseNT(self) {
1523 debug('SERVER: emit close');
1528 Server.prototype.listenFD = internalUtil.deprecate(function(fd, type) {
1529 return this.listen({ fd: fd });
1530 }, 'Server.listenFD is deprecated. Use Server.listen({fd: <number>}) instead.');
1532 Server.prototype._setupSlave = function(socketList) {
1533 this._usingSlaves = true;
1534 this._slaves.push(socketList);
1537 Server.prototype.ref = function() {
1538 this._unref = false;
1546 Server.prototype.unref = function() {
1550 this._handle.unref();
1556 exports.isIP = cares.isIP;
1559 exports.isIPv4 = function(input) {
1560 return exports.isIP(input) === 4;
1564 exports.isIPv6 = function(input) {
1565 return exports.isIP(input) === 6;
1569 if (process.platform === 'win32') {
1570 var simultaneousAccepts;
1572 exports._setSimultaneousAccepts = function(handle) {
1573 if (handle === undefined) {
1577 if (simultaneousAccepts === undefined) {
1578 simultaneousAccepts = (process.env.NODE_MANY_ACCEPTS &&
1579 process.env.NODE_MANY_ACCEPTS !== '0');
1582 if (handle._simultaneousAccepts !== simultaneousAccepts) {
1583 handle.setSimultaneousAccepts(simultaneousAccepts);
1584 handle._simultaneousAccepts = simultaneousAccepts;
1588 exports._setSimultaneousAccepts = function(handle) {};