@@ -877,6 +877,27 @@ function afterWrite(status, handle, req, err) {
877877}
878878
879879
880+ function checkBindError ( err , port , handle ) {
881+ // EADDRINUSE may not be reported until we call listen() or connect().
882+ // To complicate matters, a failed bind() followed by listen() or connect()
883+ // will implicitly bind to a random port. Ergo, check that the socket is
884+ // bound to the expected port before calling listen() or connect().
885+ //
886+ // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
887+ // getsockname() method. Non-issue for now, the cluster module doesn't
888+ // really support pipes anyway.
889+ if ( err === 0 && port > 0 && handle . getsockname ) {
890+ var out = { } ;
891+ err = handle . getsockname ( out ) ;
892+ if ( err === 0 && port !== out . port ) {
893+ debug ( `checkBindError, bound to ${ out . port } instead of ${ port } ` ) ;
894+ err = UV_EADDRINUSE ;
895+ }
896+ }
897+ return err ;
898+ }
899+
900+
880901function internalConnect (
881902 self , address , port , addressType , localAddress , localPort ) {
882903 // TODO return promise from Socket.prototype.connect which
@@ -900,6 +921,7 @@ function internalConnect(
900921 debug ( 'binding to localAddress: %s and localPort: %d (addressType: %d)' ,
901922 localAddress , localPort , addressType ) ;
902923
924+ err = checkBindError ( err , localPort , self . _handle ) ;
903925 if ( err ) {
904926 const ex = exceptionWithHostPort ( err , 'bind' , localAddress , localPort ) ;
905927 self . destroy ( ex ) ;
@@ -1380,20 +1402,7 @@ function listenInCluster(server, address, port, addressType,
13801402 cluster . _getServer ( server , serverQuery , listenOnMasterHandle ) ;
13811403
13821404 function listenOnMasterHandle ( err , handle ) {
1383- // EADDRINUSE may not be reported until we call listen(). To complicate
1384- // matters, a failed bind() followed by listen() will implicitly bind to
1385- // a random port. Ergo, check that the socket is bound to the expected
1386- // port before calling listen().
1387- //
1388- // FIXME(bnoordhuis) Doesn't work for pipe handles, they don't have a
1389- // getsockname() method. Non-issue for now, the cluster module doesn't
1390- // really support pipes anyway.
1391- if ( err === 0 && port > 0 && handle . getsockname ) {
1392- var out = { } ;
1393- err = handle . getsockname ( out ) ;
1394- if ( err === 0 && port !== out . port )
1395- err = UV_EADDRINUSE ;
1396- }
1405+ err = checkBindError ( err , port , handle ) ;
13971406
13981407 if ( err ) {
13991408 var ex = exceptionWithHostPort ( err , 'bind' , address , port ) ;
0 commit comments