net: use `_server` for internal book-keeping
[platform/upstream/nodejs.git] / lib / net.js
1 'use strict';
2
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 internalNet = require('internal/net');
9 const assert = require('assert');
10 const cares = process.binding('cares_wrap');
11 const uv = process.binding('uv');
12
13 const Buffer = require('buffer').Buffer;
14 const TTYWrap = process.binding('tty_wrap');
15 const TCP = process.binding('tcp_wrap').TCP;
16 const Pipe = process.binding('pipe_wrap').Pipe;
17 const TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap;
18 const PipeConnectWrap = process.binding('pipe_wrap').PipeConnectWrap;
19 const ShutdownWrap = process.binding('stream_wrap').ShutdownWrap;
20 const WriteWrap = process.binding('stream_wrap').WriteWrap;
21
22
23 var cluster;
24 const errnoException = util._errnoException;
25 const exceptionWithHostPort = util._exceptionWithHostPort;
26 const isLegalPort = internalNet.isLegalPort;
27
28 function noop() {}
29
30 function createHandle(fd) {
31   var type = TTYWrap.guessHandleType(fd);
32   if (type === 'PIPE') return new Pipe();
33   if (type === 'TCP') return new TCP();
34   throw new TypeError('Unsupported fd type: ' + type);
35 }
36
37
38 const debug = util.debuglog('net');
39
40 function isPipeName(s) {
41   return typeof s === 'string' && toNumber(s) === false;
42 }
43
44 exports.createServer = function(options, connectionListener) {
45   return new Server(options, connectionListener);
46 };
47
48
49 // Target API:
50 //
51 // var s = net.connect({port: 80, host: 'google.com'}, function() {
52 //   ...
53 // });
54 //
55 // There are various forms:
56 //
57 // connect(options, [cb])
58 // connect(port, [host], [cb])
59 // connect(path, [cb]);
60 //
61 exports.connect = exports.createConnection = function() {
62   var args = normalizeConnectArgs(arguments);
63   debug('createConnection', args);
64   var s = new Socket(args[0]);
65   return Socket.prototype.connect.apply(s, args);
66 };
67
68 // Returns an array [options] or [options, cb]
69 // It is the same as the argument of Socket.prototype.connect().
70 function normalizeConnectArgs(args) {
71   var options = {};
72
73   if (args[0] !== null && typeof args[0] === 'object') {
74     // connect(options, [cb])
75     options = args[0];
76   } else if (isPipeName(args[0])) {
77     // connect(path, [cb]);
78     options.path = args[0];
79   } else {
80     // connect(port, [host], [cb])
81     options.port = args[0];
82     if (typeof args[1] === 'string') {
83       options.host = args[1];
84     }
85   }
86
87   var cb = args[args.length - 1];
88   return typeof cb === 'function' ? [options, cb] : [options];
89 }
90 exports._normalizeConnectArgs = normalizeConnectArgs;
91
92
93 // called when creating new Socket, or when re-using a closed Socket
94 function initSocketHandle(self) {
95   self.destroyed = false;
96   self.bytesRead = 0;
97   self._bytesDispatched = 0;
98   self._sockname = null;
99
100   // Handle creation may be deferred to bind() or connect() time.
101   if (self._handle) {
102     self._handle.owner = self;
103     self._handle.onread = onread;
104
105     // If handle doesn't support writev - neither do we
106     if (!self._handle.writev)
107       self._writev = null;
108   }
109 }
110
111 function Socket(options) {
112   if (!(this instanceof Socket)) return new Socket(options);
113
114   this._connecting = false;
115   this._hadError = false;
116   this._handle = null;
117   this._parent = null;
118   this._host = null;
119
120   if (typeof options === 'number')
121     options = { fd: options }; // Legacy interface.
122   else if (options === undefined)
123     options = {};
124
125   stream.Duplex.call(this, options);
126
127   if (options.handle) {
128     this._handle = options.handle; // private
129   } else if (options.fd !== undefined) {
130     this._handle = createHandle(options.fd);
131     this._handle.open(options.fd);
132     if ((options.fd == 1 || options.fd == 2) &&
133         (this._handle instanceof Pipe) &&
134         process.platform === 'win32') {
135       // Make stdout and stderr blocking on Windows
136       var err = this._handle.setBlocking(true);
137       if (err)
138         throw errnoException(err, 'setBlocking');
139     }
140     this.readable = options.readable !== false;
141     this.writable = options.writable !== false;
142   } else {
143     // these will be set once there is a connection
144     this.readable = this.writable = false;
145   }
146
147   // shut down the socket when we're finished with it.
148   this.on('finish', onSocketFinish);
149   this.on('_socketEnd', onSocketEnd);
150
151   initSocketHandle(this);
152
153   this._pendingData = null;
154   this._pendingEncoding = '';
155
156   // handle strings directly
157   this._writableState.decodeStrings = false;
158
159   // default to *not* allowing half open sockets
160   this.allowHalfOpen = options && options.allowHalfOpen || false;
161
162   // if we have a handle, then start the flow of data into the
163   // buffer.  if not, then this will happen when we connect
164   if (this._handle && options.readable !== false) {
165     if (options.pauseOnCreate) {
166       // stop the handle from reading and pause the stream
167       this._handle.reading = false;
168       this._handle.readStop();
169       this._readableState.flowing = false;
170     } else {
171       this.read(0);
172     }
173   }
174
175   // Reserve properties
176   this.server = null;
177   this._server = null;
178 }
179 util.inherits(Socket, stream.Duplex);
180
181 Socket.prototype._unrefTimer = function unrefTimer() {
182   for (var s = this; s !== null; s = s._parent)
183     timers._unrefActive(s);
184 };
185
186 // the user has called .end(), and all the bytes have been
187 // sent out to the other side.
188 // If allowHalfOpen is false, or if the readable side has
189 // ended already, then destroy.
190 // If allowHalfOpen is true, then we need to do a shutdown,
191 // so that only the writable side will be cleaned up.
192 function onSocketFinish() {
193   // If still connecting - defer handling 'finish' until 'connect' will happen
194   if (this._connecting) {
195     debug('osF: not yet connected');
196     return this.once('connect', onSocketFinish);
197   }
198
199   debug('onSocketFinish');
200   if (!this.readable || this._readableState.ended) {
201     debug('oSF: ended, destroy', this._readableState);
202     return this.destroy();
203   }
204
205   debug('oSF: not ended, call shutdown()');
206
207   // otherwise, just shutdown, or destroy() if not possible
208   if (!this._handle || !this._handle.shutdown)
209     return this.destroy();
210
211   var req = new ShutdownWrap();
212   req.oncomplete = afterShutdown;
213   req.handle = this._handle;
214   var err = this._handle.shutdown(req);
215
216   if (err)
217     return this._destroy(errnoException(err, 'shutdown'));
218 }
219
220
221 function afterShutdown(status, handle, req) {
222   var self = handle.owner;
223
224   debug('afterShutdown destroyed=%j', self.destroyed,
225         self._readableState);
226
227   // callback may come after call to destroy.
228   if (self.destroyed)
229     return;
230
231   if (self._readableState.ended) {
232     debug('readableState ended, destroying');
233     self.destroy();
234   } else {
235     self.once('_socketEnd', self.destroy);
236   }
237 }
238
239 // the EOF has been received, and no more bytes are coming.
240 // if the writable side has ended already, then clean everything
241 // up.
242 function onSocketEnd() {
243   // XXX Should not have to do as much crap in this function.
244   // ended should already be true, since this is called *after*
245   // the EOF errno and onread has eof'ed
246   debug('onSocketEnd', this._readableState);
247   this._readableState.ended = true;
248   if (this._readableState.endEmitted) {
249     this.readable = false;
250     maybeDestroy(this);
251   } else {
252     this.once('end', function() {
253       this.readable = false;
254       maybeDestroy(this);
255     });
256     this.read(0);
257   }
258
259   if (!this.allowHalfOpen) {
260     this.write = writeAfterFIN;
261     this.destroySoon();
262   }
263 }
264
265 // Provide a better error message when we call end() as a result
266 // of the other side sending a FIN.  The standard 'write after end'
267 // is overly vague, and makes it seem like the user's code is to blame.
268 function writeAfterFIN(chunk, encoding, cb) {
269   if (typeof encoding === 'function') {
270     cb = encoding;
271     encoding = null;
272   }
273
274   var er = new Error('This socket has been ended by the other party');
275   er.code = 'EPIPE';
276   var self = this;
277   // TODO: defer error events consistently everywhere, not just the cb
278   self.emit('error', er);
279   if (typeof cb === 'function') {
280     process.nextTick(cb, er);
281   }
282 }
283
284 exports.Socket = Socket;
285 exports.Stream = Socket; // Legacy naming.
286
287 Socket.prototype.read = function(n) {
288   if (n === 0)
289     return stream.Readable.prototype.read.call(this, n);
290
291   this.read = stream.Readable.prototype.read;
292   this._consuming = true;
293   return this.read(n);
294 };
295
296
297 Socket.prototype.listen = function() {
298   debug('socket.listen');
299   var self = this;
300   self.on('connection', arguments[0]);
301   listen(self, null, null, null);
302 };
303
304
305 Socket.prototype.setTimeout = function(msecs, callback) {
306   if (msecs === 0) {
307     timers.unenroll(this);
308     if (callback) {
309       this.removeListener('timeout', callback);
310     }
311   } else {
312     timers.enroll(this, msecs);
313     timers._unrefActive(this);
314     if (callback) {
315       this.once('timeout', callback);
316     }
317   }
318   return this;
319 };
320
321
322 Socket.prototype._onTimeout = function() {
323   debug('_onTimeout');
324   this.emit('timeout');
325 };
326
327
328 Socket.prototype.setNoDelay = function(enable) {
329   if (!this._handle) {
330     this.once('connect',
331               enable ? this.setNoDelay : () => this.setNoDelay(enable));
332     return this;
333   }
334
335   // backwards compatibility: assume true when `enable` is omitted
336   if (this._handle.setNoDelay)
337     this._handle.setNoDelay(enable === undefined ? true : !!enable);
338
339   return this;
340 };
341
342
343 Socket.prototype.setKeepAlive = function(setting, msecs) {
344   if (!this._handle) {
345     this.once('connect', () => this.setKeepAlive(setting, msecs));
346     return this;
347   }
348
349   if (this._handle.setKeepAlive)
350     this._handle.setKeepAlive(setting, ~~(msecs / 1000));
351
352   return this;
353 };
354
355
356 Socket.prototype.address = function() {
357   return this._getsockname();
358 };
359
360
361 Object.defineProperty(Socket.prototype, 'readyState', {
362   get: function() {
363     if (this._connecting) {
364       return 'opening';
365     } else if (this.readable && this.writable) {
366       return 'open';
367     } else if (this.readable && !this.writable) {
368       return 'readOnly';
369     } else if (!this.readable && this.writable) {
370       return 'writeOnly';
371     } else {
372       return 'closed';
373     }
374   }
375 });
376
377
378 Object.defineProperty(Socket.prototype, 'bufferSize', {
379   get: function() {
380     if (this._handle) {
381       return this._handle.writeQueueSize + this._writableState.length;
382     }
383   }
384 });
385
386
387 // Just call handle.readStart until we have enough in the buffer
388 Socket.prototype._read = function(n) {
389   debug('_read');
390
391   if (this._connecting || !this._handle) {
392     debug('_read wait for connection');
393     this.once('connect', () => this._read(n));
394   } else if (!this._handle.reading) {
395     // not already reading, start the flow
396     debug('Socket._read readStart');
397     this._handle.reading = true;
398     var err = this._handle.readStart();
399     if (err)
400       this._destroy(errnoException(err, 'read'));
401   }
402 };
403
404
405 Socket.prototype.end = function(data, encoding) {
406   stream.Duplex.prototype.end.call(this, data, encoding);
407   this.writable = false;
408   DTRACE_NET_STREAM_END(this);
409   LTTNG_NET_STREAM_END(this);
410
411   // just in case we're waiting for an EOF.
412   if (this.readable && !this._readableState.endEmitted)
413     this.read(0);
414   else
415     maybeDestroy(this);
416 };
417
418
419 // Call whenever we set writable=false or readable=false
420 function maybeDestroy(socket) {
421   if (!socket.readable &&
422       !socket.writable &&
423       !socket.destroyed &&
424       !socket._connecting &&
425       !socket._writableState.length) {
426     socket.destroy();
427   }
428 }
429
430
431 Socket.prototype.destroySoon = function() {
432   if (this.writable)
433     this.end();
434
435   if (this._writableState.finished)
436     this.destroy();
437   else
438     this.once('finish', this.destroy);
439 };
440
441
442 Socket.prototype._destroy = function(exception, cb) {
443   debug('destroy');
444
445   var self = this;
446
447   function fireErrorCallbacks() {
448     if (cb) cb(exception);
449     if (exception && !self._writableState.errorEmitted) {
450       process.nextTick(emitErrorNT, self, exception);
451       self._writableState.errorEmitted = true;
452     }
453   }
454
455   if (this.destroyed) {
456     debug('already destroyed, fire error callbacks');
457     fireErrorCallbacks();
458     return;
459   }
460
461   self._connecting = false;
462
463   this.readable = this.writable = false;
464
465   for (var s = this; s !== null; s = s._parent)
466     timers.unenroll(s);
467
468   debug('close');
469   if (this._handle) {
470     if (this !== process.stderr)
471       debug('close handle');
472     var isException = exception ? true : false;
473     this._handle.close(function() {
474       debug('emit close');
475       self.emit('close', isException);
476     });
477     this._handle.onread = noop;
478     this._handle = null;
479     this._sockname = null;
480   }
481
482   // we set destroyed to true before firing error callbacks in order
483   // to make it re-entrance safe in case Socket.prototype.destroy()
484   // is called within callbacks
485   this.destroyed = true;
486   fireErrorCallbacks();
487
488   if (this._server) {
489     COUNTER_NET_SERVER_CONNECTION_CLOSE(this);
490     debug('has server');
491     this._server._connections--;
492     if (this._server._emitCloseIfDrained) {
493       this._server._emitCloseIfDrained();
494     }
495   }
496 };
497
498
499 Socket.prototype.destroy = function(exception) {
500   debug('destroy', exception);
501   this._destroy(exception);
502 };
503
504
505 // This function is called whenever the handle gets a
506 // buffer, or when there's an error reading.
507 function onread(nread, buffer) {
508   var handle = this;
509   var self = handle.owner;
510   assert(handle === self._handle, 'handle != self._handle');
511
512   self._unrefTimer();
513
514   debug('onread', nread);
515
516   if (nread > 0) {
517     debug('got data');
518
519     // read success.
520     // In theory (and in practice) calling readStop right now
521     // will prevent this from being called again until _read() gets
522     // called again.
523
524     // if it's not enough data, we'll just call handle.readStart()
525     // again right away.
526     self.bytesRead += nread;
527
528     // Optimization: emit the original buffer with end points
529     var ret = self.push(buffer);
530
531     if (handle.reading && !ret) {
532       handle.reading = false;
533       debug('readStop');
534       var err = handle.readStop();
535       if (err)
536         self._destroy(errnoException(err, 'read'));
537     }
538     return;
539   }
540
541   // if we didn't get any bytes, that doesn't necessarily mean EOF.
542   // wait for the next one.
543   if (nread === 0) {
544     debug('not any data, keep waiting');
545     return;
546   }
547
548   // Error, possibly EOF.
549   if (nread !== uv.UV_EOF) {
550     return self._destroy(errnoException(nread, 'read'));
551   }
552
553   debug('EOF');
554
555   if (self._readableState.length === 0) {
556     self.readable = false;
557     maybeDestroy(self);
558   }
559
560   // push a null to signal the end of data.
561   self.push(null);
562
563   // internal end event so that we know that the actual socket
564   // is no longer readable, and we can start the shutdown
565   // procedure. No need to wait for all the data to be consumed.
566   self.emit('_socketEnd');
567 }
568
569
570 Socket.prototype._getpeername = function() {
571   if (!this._peername) {
572     if (!this._handle || !this._handle.getpeername) {
573       return {};
574     }
575     var out = {};
576     var err = this._handle.getpeername(out);
577     if (err) return {};  // FIXME(bnoordhuis) Throw?
578     this._peername = out;
579   }
580   return this._peername;
581 };
582
583
584 Socket.prototype.__defineGetter__('remoteAddress', function() {
585   return this._getpeername().address;
586 });
587
588 Socket.prototype.__defineGetter__('remoteFamily', function() {
589   return this._getpeername().family;
590 });
591
592 Socket.prototype.__defineGetter__('remotePort', function() {
593   return this._getpeername().port;
594 });
595
596
597 Socket.prototype._getsockname = function() {
598   if (!this._handle || !this._handle.getsockname) {
599     return {};
600   }
601   if (!this._sockname) {
602     var out = {};
603     var err = this._handle.getsockname(out);
604     if (err) return {};  // FIXME(bnoordhuis) Throw?
605     this._sockname = out;
606   }
607   return this._sockname;
608 };
609
610
611 Socket.prototype.__defineGetter__('localAddress', function() {
612   return this._getsockname().address;
613 });
614
615
616 Socket.prototype.__defineGetter__('localPort', function() {
617   return this._getsockname().port;
618 });
619
620
621 Socket.prototype.write = function(chunk, encoding, cb) {
622   if (typeof chunk !== 'string' && !(chunk instanceof Buffer))
623     throw new TypeError('invalid data');
624   return stream.Duplex.prototype.write.apply(this, arguments);
625 };
626
627
628 Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
629   // If we are still connecting, then buffer this for later.
630   // The Writable logic will buffer up any more writes while
631   // waiting for this one to be done.
632   if (this._connecting) {
633     this._pendingData = data;
634     this._pendingEncoding = encoding;
635     this.once('connect', function() {
636       this._writeGeneric(writev, data, encoding, cb);
637     });
638     return;
639   }
640   this._pendingData = null;
641   this._pendingEncoding = '';
642
643   this._unrefTimer();
644
645   if (!this._handle) {
646     this._destroy(new Error('This socket is closed.'), cb);
647     return false;
648   }
649
650   var req = new WriteWrap();
651   req.handle = this._handle;
652   req.oncomplete = afterWrite;
653   req.async = false;
654   var err;
655
656   if (writev) {
657     var chunks = new Array(data.length << 1);
658     for (var i = 0; i < data.length; i++) {
659       var entry = data[i];
660       chunks[i * 2] = entry.chunk;
661       chunks[i * 2 + 1] = entry.encoding;
662     }
663     err = this._handle.writev(req, chunks);
664
665     // Retain chunks
666     if (err === 0) req._chunks = chunks;
667   } else {
668     var enc;
669     if (data instanceof Buffer) {
670       req.buffer = data;  // Keep reference alive.
671       enc = 'buffer';
672     } else {
673       enc = encoding;
674     }
675     err = createWriteReq(req, this._handle, data, enc);
676   }
677
678   if (err)
679     return this._destroy(errnoException(err, 'write', req.error), cb);
680
681   this._bytesDispatched += req.bytes;
682
683   // If it was entirely flushed, we can write some more right now.
684   // However, if more is left in the queue, then wait until that clears.
685   if (req.async && this._handle.writeQueueSize != 0)
686     req.cb = cb;
687   else
688     cb();
689 };
690
691
692 Socket.prototype._writev = function(chunks, cb) {
693   this._writeGeneric(true, chunks, '', cb);
694 };
695
696
697 Socket.prototype._write = function(data, encoding, cb) {
698   this._writeGeneric(false, data, encoding, cb);
699 };
700
701 function createWriteReq(req, handle, data, encoding) {
702   switch (encoding) {
703     case 'binary':
704       return handle.writeBinaryString(req, data);
705
706     case 'buffer':
707       return handle.writeBuffer(req, data);
708
709     case 'utf8':
710     case 'utf-8':
711       return handle.writeUtf8String(req, data);
712
713     case 'ascii':
714       return handle.writeAsciiString(req, data);
715
716     case 'ucs2':
717     case 'ucs-2':
718     case 'utf16le':
719     case 'utf-16le':
720       return handle.writeUcs2String(req, data);
721
722     default:
723       return handle.writeBuffer(req, new Buffer(data, encoding));
724   }
725 }
726
727
728 Socket.prototype.__defineGetter__('bytesWritten', function() {
729   var bytes = this._bytesDispatched;
730   const state = this._writableState;
731   const data = this._pendingData;
732   const encoding = this._pendingEncoding;
733
734   if (!state)
735     return undefined;
736
737   state.getBuffer().forEach(function(el) {
738     if (el.chunk instanceof Buffer)
739       bytes += el.chunk.length;
740     else
741       bytes += Buffer.byteLength(el.chunk, el.encoding);
742   });
743
744   if (data) {
745     if (data instanceof Buffer)
746       bytes += data.length;
747     else
748       bytes += Buffer.byteLength(data, encoding);
749   }
750
751   return bytes;
752 });
753
754
755 function afterWrite(status, handle, req, err) {
756   var self = handle.owner;
757   if (self !== process.stderr && self !== process.stdout)
758     debug('afterWrite', status);
759
760   // callback may come after call to destroy.
761   if (self.destroyed) {
762     debug('afterWrite destroyed');
763     return;
764   }
765
766   if (status < 0) {
767     var ex = errnoException(status, 'write', req.error);
768     debug('write failure', ex);
769     self._destroy(ex, req.cb);
770     return;
771   }
772
773   self._unrefTimer();
774
775   if (self !== process.stderr && self !== process.stdout)
776     debug('afterWrite call cb');
777
778   if (req.cb)
779     req.cb.call(self);
780 }
781
782
783 function connect(self, address, port, addressType, localAddress, localPort) {
784   // TODO return promise from Socket.prototype.connect which
785   // wraps _connectReq.
786
787   assert.ok(self._connecting);
788
789   var err;
790
791   if (localAddress || localPort) {
792     var bind;
793
794     if (addressType === 4) {
795       localAddress = localAddress || '0.0.0.0';
796       bind = self._handle.bind;
797     } else if (addressType === 6) {
798       localAddress = localAddress || '::';
799       bind = self._handle.bind6;
800     } else {
801       self._destroy(new TypeError('Invalid addressType: ' + addressType));
802       return;
803     }
804
805     debug('binding to localAddress: %s and localPort: %d',
806           localAddress,
807           localPort);
808
809     bind = bind.bind(self._handle);
810     err = bind(localAddress, localPort);
811
812     if (err) {
813       const ex = exceptionWithHostPort(err, 'bind', localAddress, localPort);
814       self._destroy(ex);
815       return;
816     }
817   }
818
819   if (addressType === 6 || addressType === 4) {
820     const req = new TCPConnectWrap();
821     req.oncomplete = afterConnect;
822     req.address = address;
823     req.port = port;
824     req.localAddress = localAddress;
825     req.localPort = localPort;
826
827     if (addressType === 4)
828       err = self._handle.connect(req, address, port);
829     else
830       err = self._handle.connect6(req, address, port);
831
832   } else {
833     const req = new PipeConnectWrap();
834     req.address = address;
835     req.oncomplete = afterConnect;
836     err = self._handle.connect(req, address, afterConnect);
837   }
838
839   if (err) {
840     var sockname = self._getsockname();
841     var details;
842
843     if (sockname) {
844       details = sockname.address + ':' + sockname.port;
845     }
846
847     const ex = exceptionWithHostPort(err, 'connect', address, port, details);
848     self._destroy(ex);
849   }
850 }
851
852
853 Socket.prototype.connect = function(options, cb) {
854   if (this.write !== Socket.prototype.write)
855     this.write = Socket.prototype.write;
856
857   if (options === null || typeof options !== 'object') {
858     // Old API:
859     // connect(port, [host], [cb])
860     // connect(path, [cb]);
861     var args = normalizeConnectArgs(arguments);
862     return Socket.prototype.connect.apply(this, args);
863   }
864
865   if (this.destroyed) {
866     this._readableState.reading = false;
867     this._readableState.ended = false;
868     this._readableState.endEmitted = false;
869     this._writableState.ended = false;
870     this._writableState.ending = false;
871     this._writableState.finished = false;
872     this._writableState.errorEmitted = false;
873     this.destroyed = false;
874     this._handle = null;
875     this._peername = null;
876     this._sockname = null;
877   }
878
879   var self = this;
880   var pipe = !!options.path;
881   debug('pipe', pipe, options.path);
882
883   if (!this._handle) {
884     this._handle = pipe ? new Pipe() : new TCP();
885     initSocketHandle(this);
886   }
887
888   if (typeof cb === 'function') {
889     self.once('connect', cb);
890   }
891
892   this._unrefTimer();
893
894   self._connecting = true;
895   self.writable = true;
896
897   if (pipe) {
898     connect(self, options.path);
899
900   } else {
901     lookupAndConnect(self, options);
902   }
903   return self;
904 };
905
906
907 function lookupAndConnect(self, options) {
908   const dns = require('dns');
909   var host = options.host || 'localhost';
910   var port = options.port;
911   var localAddress = options.localAddress;
912   var localPort = options.localPort;
913
914   if (localAddress && !exports.isIP(localAddress))
915     throw new TypeError('localAddress must be a valid IP: ' + localAddress);
916
917   if (localPort && typeof localPort !== 'number')
918     throw new TypeError('localPort should be a number: ' + localPort);
919
920   if (typeof port !== 'undefined') {
921     if (typeof port !== 'number' && typeof port !== 'string')
922       throw new TypeError('port should be a number or string: ' + port);
923     if (!isLegalPort(port))
924       throw new RangeError('port should be >= 0 and < 65536: ' + port);
925   }
926   port |= 0;
927
928   // If host is an IP, skip performing a lookup
929   var addressType = exports.isIP(host);
930   if (addressType) {
931     process.nextTick(function() {
932       if (self._connecting)
933         connect(self, host, port, addressType, localAddress, localPort);
934     });
935     return;
936   }
937
938   if (options.lookup && typeof options.lookup !== 'function')
939     throw new TypeError('options.lookup should be a function.');
940
941   var dnsopts = {
942     family: options.family,
943     hints: 0
944   };
945
946   if (dnsopts.family !== 4 && dnsopts.family !== 6) {
947     dnsopts.hints = dns.ADDRCONFIG;
948     // The AI_V4MAPPED hint is not supported on FreeBSD or Android,
949     // and getaddrinfo returns EAI_BADFLAGS. However, it seems to be
950     // supported on most other systems. See
951     // http://lists.freebsd.org/pipermail/freebsd-bugs/2008-February/028260.html
952     // for more information on the lack of support for FreeBSD.
953     if (process.platform !== 'freebsd' && process.platform !== 'android')
954       dnsopts.hints |= dns.V4MAPPED;
955   }
956
957   debug('connect: find host ' + host);
958   debug('connect: dns options', dnsopts);
959   self._host = host;
960   var lookup = options.lookup || dns.lookup;
961   lookup(host, dnsopts, function(err, ip, addressType) {
962     self.emit('lookup', err, ip, addressType);
963
964     // It's possible we were destroyed while looking this up.
965     // XXX it would be great if we could cancel the promise returned by
966     // the look up.
967     if (!self._connecting) return;
968
969     if (err) {
970       // net.createConnection() creates a net.Socket object and
971       // immediately calls net.Socket.connect() on it (that's us).
972       // There are no event listeners registered yet so defer the
973       // error event to the next tick.
974       err.host = options.host;
975       err.port = options.port;
976       err.message = err.message + ' ' + options.host + ':' + options.port;
977       process.nextTick(connectErrorNT, self, err);
978     } else {
979       self._unrefTimer();
980       connect(self,
981               ip,
982               port,
983               addressType,
984               localAddress,
985               localPort);
986     }
987   });
988 }
989
990
991 function connectErrorNT(self, err) {
992   self.emit('error', err);
993   self._destroy();
994 }
995
996
997 Socket.prototype.ref = function() {
998   if (!this._handle) {
999     this.once('connect', this.ref);
1000     return this;
1001   }
1002
1003   this._handle.ref();
1004
1005   return this;
1006 };
1007
1008
1009 Socket.prototype.unref = function() {
1010   if (!this._handle) {
1011     this.once('connect', this.unref);
1012     return this;
1013   }
1014
1015   this._handle.unref();
1016
1017   return this;
1018 };
1019
1020
1021 function afterConnect(status, handle, req, readable, writable) {
1022   var self = handle.owner;
1023
1024   // callback may come after call to destroy
1025   if (self.destroyed) {
1026     return;
1027   }
1028
1029   // Update handle if it was wrapped
1030   // TODO(indutny): assert that the handle is actually an ancestor of old one
1031   handle = self._handle;
1032
1033   debug('afterConnect');
1034
1035   assert.ok(self._connecting);
1036   self._connecting = false;
1037   self._sockname = null;
1038
1039   if (status == 0) {
1040     self.readable = readable;
1041     self.writable = writable;
1042     self._unrefTimer();
1043
1044     self.emit('connect');
1045
1046     // start the first read, or get an immediate EOF.
1047     // this doesn't actually consume any bytes, because len=0.
1048     if (readable && !self.isPaused())
1049       self.read(0);
1050
1051   } else {
1052     self._connecting = false;
1053     var details;
1054     if (req.localAddress && req.localPort) {
1055       details = req.localAddress + ':' + req.localPort;
1056     }
1057     var ex = exceptionWithHostPort(status,
1058                                    'connect',
1059                                    req.address,
1060                                    req.port,
1061                                    details);
1062     if (details) {
1063       ex.localAddress = req.localAddress;
1064       ex.localPort = req.localPort;
1065     }
1066     self._destroy(ex);
1067   }
1068 }
1069
1070
1071 function Server(options, connectionListener) {
1072   if (!(this instanceof Server))
1073     return new Server(options, connectionListener);
1074
1075   EventEmitter.call(this);
1076
1077   var self = this;
1078
1079   if (typeof options === 'function') {
1080     connectionListener = options;
1081     options = {};
1082     self.on('connection', connectionListener);
1083   } else {
1084     options = options || {};
1085
1086     if (typeof connectionListener === 'function') {
1087       self.on('connection', connectionListener);
1088     }
1089   }
1090
1091   this._connections = 0;
1092
1093   Object.defineProperty(this, 'connections', {
1094     get: internalUtil.deprecate(function() {
1095
1096       if (self._usingSlaves) {
1097         return null;
1098       }
1099       return self._connections;
1100     }, 'Server.connections property is deprecated. ' +
1101        'Use Server.getConnections method instead.'),
1102     set: internalUtil.deprecate(function(val) {
1103       return (self._connections = val);
1104     }, 'Server.connections property is deprecated.'),
1105     configurable: true, enumerable: false
1106   });
1107
1108   this._handle = null;
1109   this._usingSlaves = false;
1110   this._slaves = [];
1111   this._unref = false;
1112
1113   this.allowHalfOpen = options.allowHalfOpen || false;
1114   this.pauseOnConnect = !!options.pauseOnConnect;
1115 }
1116 util.inherits(Server, EventEmitter);
1117 exports.Server = Server;
1118
1119
1120 function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
1121
1122 function _listen(handle, backlog) {
1123   // Use a backlog of 512 entries. We pass 511 to the listen() call because
1124   // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
1125   // which will thus give us a backlog of 512 entries.
1126   return handle.listen(backlog || 511);
1127 }
1128
1129 function createServerHandle(address, port, addressType, fd) {
1130   var err = 0;
1131   // assign handle in listen, and clean up if bind or listen fails
1132   var handle;
1133
1134   var isTCP = false;
1135   if (typeof fd === 'number' && fd >= 0) {
1136     try {
1137       handle = createHandle(fd);
1138     }
1139     catch (e) {
1140       // Not a fd we can listen on.  This will trigger an error.
1141       debug('listen invalid fd=' + fd + ': ' + e.message);
1142       return uv.UV_EINVAL;
1143     }
1144     handle.open(fd);
1145     handle.readable = true;
1146     handle.writable = true;
1147     assert(!address && !port);
1148   } else if (port === -1 && addressType === -1) {
1149     handle = new Pipe();
1150     if (process.platform === 'win32') {
1151       var instances = parseInt(process.env.NODE_PENDING_PIPE_INSTANCES);
1152       if (!isNaN(instances)) {
1153         handle.setPendingInstances(instances);
1154       }
1155     }
1156   } else {
1157     handle = new TCP();
1158     isTCP = true;
1159   }
1160
1161   if (address || port || isTCP) {
1162     debug('bind to ' + (address || 'anycast'));
1163     if (!address) {
1164       // Try binding to ipv6 first
1165       err = handle.bind6('::', port);
1166       if (err) {
1167         handle.close();
1168         // Fallback to ipv4
1169         return createServerHandle('0.0.0.0', port);
1170       }
1171     } else if (addressType === 6) {
1172       err = handle.bind6(address, port);
1173     } else {
1174       err = handle.bind(address, port);
1175     }
1176   }
1177
1178   if (err) {
1179     handle.close();
1180     return err;
1181   }
1182
1183   return handle;
1184 }
1185 exports._createServerHandle = createServerHandle;
1186
1187
1188 Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
1189   debug('listen2', address, port, addressType, backlog, fd);
1190   var self = this;
1191
1192   // If there is not yet a handle, we need to create one and bind.
1193   // In the case of a server sent via IPC, we don't need to do this.
1194   if (self._handle) {
1195     debug('_listen2: have a handle already');
1196   } else {
1197     debug('_listen2: create a handle');
1198
1199     var rval = null;
1200
1201     if (!address && typeof fd !== 'number') {
1202       rval = createServerHandle('::', port, 6, fd);
1203
1204       if (typeof rval === 'number') {
1205         rval = null;
1206         address = '0.0.0.0';
1207         addressType = 4;
1208       } else {
1209         address = '::';
1210         addressType = 6;
1211       }
1212     }
1213
1214     if (rval === null)
1215       rval = createServerHandle(address, port, addressType, fd);
1216
1217     if (typeof rval === 'number') {
1218       var error = exceptionWithHostPort(rval, 'listen', address, port);
1219       process.nextTick(emitErrorNT, self, error);
1220       return;
1221     }
1222     self._handle = rval;
1223   }
1224
1225   self._handle.onconnection = onconnection;
1226   self._handle.owner = self;
1227
1228   var err = _listen(self._handle, backlog);
1229
1230   if (err) {
1231     var ex = exceptionWithHostPort(err, 'listen', address, port);
1232     self._handle.close();
1233     self._handle = null;
1234     process.nextTick(emitErrorNT, self, ex);
1235     return;
1236   }
1237
1238   // generate connection key, this should be unique to the connection
1239   this._connectionKey = addressType + ':' + address + ':' + port;
1240
1241   // unref the handle if the server was unref'ed prior to listening
1242   if (this._unref)
1243     this.unref();
1244
1245   process.nextTick(emitListeningNT, self);
1246 };
1247
1248
1249 function emitErrorNT(self, err) {
1250   self.emit('error', err);
1251 }
1252
1253
1254 function emitListeningNT(self) {
1255   // ensure handle hasn't closed
1256   if (self._handle)
1257     self.emit('listening');
1258 }
1259
1260
1261 function listen(self, address, port, addressType, backlog, fd, exclusive) {
1262   exclusive = !!exclusive;
1263
1264   if (!cluster) cluster = require('cluster');
1265
1266   if (cluster.isMaster || exclusive) {
1267     self._listen2(address, port, addressType, backlog, fd);
1268     return;
1269   }
1270
1271   cluster._getServer(self, {
1272     address: address,
1273     port: port,
1274     addressType: addressType,
1275     fd: fd,
1276     flags: 0
1277   }, cb);
1278
1279   function cb(err, handle) {
1280     // EADDRINUSE may not be reported until we call listen(). To complicate
1281     // matters, a failed bind() followed by listen() will implicitly bind to
1282     // a random port. Ergo, check that the socket is bound to the expected
1283     // port before calling listen().
1284     //
1285     // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
1286     // getsockname() method. Non-issue for now, the cluster module doesn't
1287     // really support pipes anyway.
1288     if (err === 0 && port > 0 && handle.getsockname) {
1289       var out = {};
1290       err = handle.getsockname(out);
1291       if (err === 0 && port !== out.port)
1292         err = uv.UV_EADDRINUSE;
1293     }
1294
1295     if (err) {
1296       var ex = exceptionWithHostPort(err, 'bind', address, port);
1297       return self.emit('error', ex);
1298     }
1299
1300     self._handle = handle;
1301     self._listen2(address, port, addressType, backlog, fd);
1302   }
1303 }
1304
1305
1306 Server.prototype.listen = function() {
1307   var self = this;
1308
1309   var lastArg = arguments[arguments.length - 1];
1310   if (typeof lastArg === 'function') {
1311     self.once('listening', lastArg);
1312   }
1313
1314   var port = toNumber(arguments[0]);
1315
1316   // The third optional argument is the backlog size.
1317   // When the ip is omitted it can be the second argument.
1318   var backlog = toNumber(arguments[1]) || toNumber(arguments[2]);
1319
1320   if (arguments.length === 0 || typeof arguments[0] === 'function') {
1321     // Bind to a random port.
1322     listen(self, null, 0, null, backlog);
1323   } else if (arguments[0] !== null && typeof arguments[0] === 'object') {
1324     var h = arguments[0];
1325     h = h._handle || h.handle || h;
1326
1327     if (h instanceof TCP) {
1328       self._handle = h;
1329       listen(self, null, -1, -1, backlog);
1330     } else if (typeof h.fd === 'number' && h.fd >= 0) {
1331       listen(self, null, null, null, backlog, h.fd);
1332     } else {
1333       // The first argument is a configuration object
1334       if (h.backlog)
1335         backlog = h.backlog;
1336
1337       if (typeof h.port === 'number' || typeof h.port === 'string' ||
1338           (typeof h.port === 'undefined' && 'port' in h)) {
1339         // Undefined is interpreted as zero (random port) for consistency
1340         // with net.connect().
1341         if (typeof h.port !== 'undefined' && !isLegalPort(h.port))
1342           throw new RangeError('port should be >= 0 and < 65536: ' + h.port);
1343         if (h.host)
1344           listenAfterLookup(h.port | 0, h.host, backlog, h.exclusive);
1345         else
1346           listen(self, null, h.port | 0, 4, backlog, undefined, h.exclusive);
1347       } else if (h.path && isPipeName(h.path)) {
1348         const pipeName = self._pipeName = h.path;
1349         listen(self, pipeName, -1, -1, backlog, undefined, h.exclusive);
1350       } else {
1351         throw new Error('Invalid listen argument: ' + h);
1352       }
1353     }
1354   } else if (isPipeName(arguments[0])) {
1355     // UNIX socket or Windows pipe.
1356     const pipeName = self._pipeName = arguments[0];
1357     listen(self, pipeName, -1, -1, backlog);
1358
1359   } else if (arguments[1] === undefined ||
1360              typeof arguments[1] === 'function' ||
1361              typeof arguments[1] === 'number') {
1362     // The first argument is the port, no IP given.
1363     listen(self, null, port, 4, backlog);
1364
1365   } else {
1366     // The first argument is the port, the second an IP.
1367     listenAfterLookup(port, arguments[1], backlog);
1368   }
1369
1370   function listenAfterLookup(port, address, backlog, exclusive) {
1371     require('dns').lookup(address, function(err, ip, addressType) {
1372       if (err) {
1373         self.emit('error', err);
1374       } else {
1375         addressType = ip ? addressType : 4;
1376         listen(self, ip, port, addressType, backlog, undefined, exclusive);
1377       }
1378     });
1379   }
1380
1381   return self;
1382 };
1383
1384 Server.prototype.address = function() {
1385   if (this._handle && this._handle.getsockname) {
1386     var out = {};
1387     this._handle.getsockname(out);
1388     // TODO(bnoordhuis) Check err and throw?
1389     return out;
1390   } else if (this._pipeName) {
1391     return this._pipeName;
1392   } else {
1393     return null;
1394   }
1395 };
1396
1397 function onconnection(err, clientHandle) {
1398   var handle = this;
1399   var self = handle.owner;
1400
1401   debug('onconnection');
1402
1403   if (err) {
1404     self.emit('error', errnoException(err, 'accept'));
1405     return;
1406   }
1407
1408   if (self.maxConnections && self._connections >= self.maxConnections) {
1409     clientHandle.close();
1410     return;
1411   }
1412
1413   var socket = new Socket({
1414     handle: clientHandle,
1415     allowHalfOpen: self.allowHalfOpen,
1416     pauseOnCreate: self.pauseOnConnect
1417   });
1418   socket.readable = socket.writable = true;
1419
1420
1421   self._connections++;
1422   socket.server = self;
1423   socket._server = self;
1424
1425   DTRACE_NET_SERVER_CONNECTION(socket);
1426   LTTNG_NET_SERVER_CONNECTION(socket);
1427   COUNTER_NET_SERVER_CONNECTION(socket);
1428   self.emit('connection', socket);
1429 }
1430
1431
1432 Server.prototype.getConnections = function(cb) {
1433   function end(err, connections) {
1434     process.nextTick(cb, err, connections);
1435   }
1436
1437   if (!this._usingSlaves) {
1438     return end(null, this._connections);
1439   }
1440
1441   // Poll slaves
1442   var left = this._slaves.length;
1443   var total = this._connections;
1444
1445   function oncount(err, count) {
1446     if (err) {
1447       left = -1;
1448       return end(err);
1449     }
1450
1451     total += count;
1452     if (--left === 0) return end(null, total);
1453   }
1454
1455   this._slaves.forEach(function(slave) {
1456     slave.getConnections(oncount);
1457   });
1458 };
1459
1460
1461 Server.prototype.close = function(cb) {
1462   function onSlaveClose() {
1463     if (--left !== 0) return;
1464
1465     self._connections = 0;
1466     self._emitCloseIfDrained();
1467   }
1468
1469   if (typeof cb === 'function') {
1470     if (!this._handle) {
1471       this.once('close', function() {
1472         cb(new Error('Not running'));
1473       });
1474     } else {
1475       this.once('close', cb);
1476     }
1477   }
1478
1479   if (this._handle) {
1480     this._handle.close();
1481     this._handle = null;
1482   }
1483
1484   if (this._usingSlaves) {
1485     var self = this;
1486     var left = this._slaves.length;
1487
1488     // Increment connections to be sure that, even if all sockets will be closed
1489     // during polling of slaves, `close` event will be emitted only once.
1490     this._connections++;
1491
1492     // Poll slaves
1493     this._slaves.forEach(function(slave) {
1494       slave.close(onSlaveClose);
1495     });
1496   } else {
1497     this._emitCloseIfDrained();
1498   }
1499
1500   return this;
1501 };
1502
1503 Server.prototype._emitCloseIfDrained = function() {
1504   debug('SERVER _emitCloseIfDrained');
1505   var self = this;
1506
1507   if (self._handle || self._connections) {
1508     debug('SERVER handle? %j   connections? %d',
1509           !!self._handle, self._connections);
1510     return;
1511   }
1512
1513   process.nextTick(emitCloseNT, self);
1514 };
1515
1516
1517 function emitCloseNT(self) {
1518   debug('SERVER: emit close');
1519   self.emit('close');
1520 }
1521
1522
1523 Server.prototype.listenFD = internalUtil.deprecate(function(fd, type) {
1524   return this.listen({ fd: fd });
1525 }, 'Server.listenFD is deprecated. Use Server.listen({fd: <number>}) instead.');
1526
1527 Server.prototype._setupSlave = function(socketList) {
1528   this._usingSlaves = true;
1529   this._slaves.push(socketList);
1530 };
1531
1532 Server.prototype.ref = function() {
1533   this._unref = false;
1534
1535   if (this._handle)
1536     this._handle.ref();
1537
1538   return this;
1539 };
1540
1541 Server.prototype.unref = function() {
1542   this._unref = true;
1543
1544   if (this._handle)
1545     this._handle.unref();
1546
1547   return this;
1548 };
1549
1550
1551 exports.isIP = cares.isIP;
1552
1553
1554 exports.isIPv4 = function(input) {
1555   return exports.isIP(input) === 4;
1556 };
1557
1558
1559 exports.isIPv6 = function(input) {
1560   return exports.isIP(input) === 6;
1561 };
1562
1563
1564 if (process.platform === 'win32') {
1565   var simultaneousAccepts;
1566
1567   exports._setSimultaneousAccepts = function(handle) {
1568     if (handle === undefined) {
1569       return;
1570     }
1571
1572     if (simultaneousAccepts === undefined) {
1573       simultaneousAccepts = (process.env.NODE_MANY_ACCEPTS &&
1574                              process.env.NODE_MANY_ACCEPTS !== '0');
1575     }
1576
1577     if (handle._simultaneousAccepts !== simultaneousAccepts) {
1578       handle.setSimultaneousAccepts(simultaneousAccepts);
1579       handle._simultaneousAccepts = simultaneousAccepts;
1580     }
1581   };
1582 } else {
1583   exports._setSimultaneousAccepts = function(handle) {};
1584 }