@ -342,10 +342,11 @@ Socket.prototype.read = function(n) {
} ;
// FIXME(joyeecheung): this method is neither documented nor tested
Socket . prototype . listen = function ( ) {
debug ( 'socket.listen' ) ;
this . on ( 'connection' , arguments [ 0 ] ) ;
listen ( this , null , null , null ) ;
listenInCluster ( this , null , null , null ) ;
} ;
@ -1178,13 +1179,7 @@ util.inherits(Server, EventEmitter);
function toNumber ( x ) { return ( x = Number ( x ) ) >= 0 ? x : false ; }
function _ listen ( handle , backlog ) {
// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
return handle . listen ( backlog || 511 ) ;
}
// Returns handle if it can be created, or error code if it can't
function createServerHandle ( address , port , addressType , fd ) {
var err = 0 ;
// assign handle in listen, and clean up if bind or listen fails
@ -1241,19 +1236,19 @@ function createServerHandle(address, port, addressType, fd) {
return handle ;
}
Server . prototype . _ listen2 = function ( address , port , addressType , backlog , fd ) {
debug ( 'listen2' , address , port , addressType , backlog , fd ) ;
function setupListenHandle ( address , port , addressType , backlog , fd ) {
debug ( 'setupListenHandle' , address , port , addressType , backlog , fd ) ;
// If there is not yet a handle, we need to create one and bind.
// In the case of a server sent via IPC, we don't need to do this.
if ( this . _ handle ) {
debug ( '_listen2 : have a handle already' ) ;
debug ( 'setupListenHandle : have a handle already' ) ;
} else {
debug ( '_listen2 : create a handle' ) ;
debug ( 'setupListenHandle : create a handle' ) ;
var rval = null ;
// Try to bind to the unspecified IPv6 address, see if IPv6 is available
if ( ! address && typeof fd !== 'number' ) {
rval = createServerHandle ( '::' , port , 6 , fd ) ;
@ -1281,7 +1276,10 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
this . _ handle . onconnection = onconnection ;
this . _ handle . owner = this ;
var err = _ listen ( this . _ handle , backlog ) ;
// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
var err = this . _ handle . listen ( backlog || 511 ) ;
if ( err ) {
var ex = exceptionWithHostPort ( err , 'listen' , address , port ) ;
@ -1299,8 +1297,9 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
this . unref ( ) ;
process . nextTick ( emitListeningNT , this ) ;
} ;
}
Server . prototype . _ listen2 = setupListenHandle ; // legacy alias
function emitErrorNT ( self , err ) {
self . emit ( 'error' , err ) ;
@ -1314,25 +1313,32 @@ function emitListeningNT(self) {
}
function listen ( self , address , port , addressType , backlog , fd , exclusive ) {
function listenInCluster ( server , address , port , addressType ,
backlog , fd , exclusive ) {
exclusive = ! ! exclusive ;
if ( ! cluster ) cluster = require ( 'cluster' ) ;
if ( cluster . isMaster || exclusive ) {
self . _ listen2 ( address , port , addressType , backlog , fd ) ;
// Will create a new handle
// _listen2 sets up the listened handle, it is still named like this
// to avoid breaking code that wraps this method
server . _ listen2 ( address , port , addressType , backlog , fd ) ;
return ;
}
cluster . _ getServer ( self , {
const serverQuery = {
address : address ,
port : port ,
addressType : addressType ,
fd : fd ,
flags : 0
} , cb ) ;
} ;
// Get the master's server handle, and listen on it
cluster . _ getServer ( server , serverQuery , listenOnMasterHandle ) ;
function cb ( err , handle ) {
function listenOnMasterHandle ( err , handle ) {
// EADDRINUSE may not be reported until we call listen(). To complicate
// matters, a failed bind() followed by listen() will implicitly bind to
// a random port. Ergo, check that the socket is bound to the expected
@ -1350,11 +1356,14 @@ function listen(self, address, port, addressType, backlog, fd, exclusive) {
if ( err ) {
var ex = exceptionWithHostPort ( err , 'bind' , address , port ) ;
return self . emit ( 'error' , ex ) ;
return server . emit ( 'error' , ex ) ;
}
self . _ handle = handle ;
self . _ listen2 ( address , port , addressType , backlog , fd ) ;
// Reuse master's server handle
server . _ handle = handle ;
// _listen2 sets up the listened handle, it is still named like this
// to avoid breaking code that wraps this method
server . _ listen2 ( address , port , addressType , backlog , fd ) ;
}
}
@ -1381,12 +1390,12 @@ Server.prototype.listen = function() {
// (handle[, backlog][, cb]) where handle is an object with a handle
if ( options instanceof TCP ) {
this . _ handle = options ;
listen ( this , null , - 1 , - 1 , backlogFromArgs ) ;
listenInCluster ( this , null , - 1 , - 1 , backlogFromArgs ) ;
return this ;
}
// (handle[, backlog][, cb]) where handle is an object with a fd
if ( typeof options . fd === 'number' && options . fd >= 0 ) {
listen ( this , null , null , null , backlogFromArgs , options . fd ) ;
listenInCluster ( this , null , null , null , backlogFromArgs , options . fd ) ;
return this ;
}
@ -1411,8 +1420,9 @@ Server.prototype.listen = function() {
lookupAndListen ( this , options . port | 0 , options . host , backlog ,
options . exclusive ) ;
} else { // Undefined host, listens on unspecified address
listen ( this , null , options . port | 0 , 4 , // addressType will be ignored
backlog , undefined , options . exclusive ) ;
// Default addressType 4 will be used to search for master server
listenInCluster ( this , null , options . port | 0 , 4 ,
backlog , undefined , options . exclusive ) ;
}
return this ;
}
@ -1422,7 +1432,8 @@ Server.prototype.listen = function() {
if ( options . path && isPipeName ( options . path ) ) {
const pipeName = this . _ pipeName = options . path ;
const backlog = options . backlog || backlogFromArgs ;
listen ( this , pipeName , - 1 , - 1 , backlog , undefined , options . exclusive ) ;
listenInCluster ( this , pipeName , - 1 , - 1 ,
backlog , undefined , options . exclusive ) ;
return this ;
}
@ -1430,12 +1441,14 @@ Server.prototype.listen = function() {
} ;
function lookupAndListen ( self , port , address , backlog , exclusive ) {
require ( 'dns' ) . lookup ( address , function doListening ( err , ip , addressType ) {
const dns = require ( 'dns' ) ;
dns . lookup ( address , function doListen ( err , ip , addressType ) {
if ( err ) {
self . emit ( 'error' , err ) ;
} else {
addressType = ip ? addressType : 4 ;
listen ( self , ip , port , addressType , backlog , undefined , exclusive ) ;
listenInCluster ( self , ip , port , addressType ,
backlog , undefined , exclusive ) ;
}
} ) ;
}