@@ -43,11 +43,6 @@ function isIP(address) {
4343
4444
4545function lookup ( address , family , callback ) {
46- // implicit 'bind before send' needs to run on the same tick
47- var matchedFamily = isIP ( address ) ;
48- if ( matchedFamily )
49- return callback ( null , address , matchedFamily ) ;
50-
5146 if ( ! dns )
5247 dns = require ( 'dns' ) ;
5348
@@ -111,31 +106,36 @@ exports.createSocket = function(type, listener) {
111106} ;
112107
113108
114- Socket . prototype . bind = function ( port , address ) {
109+ Socket . prototype . bind = function ( port , address , callback ) {
115110 var self = this ;
116111
117112 self . _healthCheck ( ) ;
118113
114+ if ( typeof callback === 'function' )
115+ self . once ( 'listening' , callback ) ;
116+
119117 // resolve address first
120118 self . _handle . lookup ( address , function ( err , ip ) {
121- if ( ! err ) {
122- if ( self . _handle . bind ( ip , port || 0 , /*flags=*/ 0 ) ) {
123- err = errnoException ( errno , 'bind' ) ;
124- }
125- else {
126- self . _bound = true ;
127- self . _startReceiving ( ) ;
128- self . emit ( 'listening' ) ;
129- }
130- }
119+ if ( ! self . _handle )
120+ return ; // handle has been closed in the mean time
131121
132122 if ( err ) {
133- // caller may not have had a chance yet to register its
134- // error event listener so defer the error to the next tick
135- process . nextTick ( function ( ) {
136- self . emit ( 'error' , err ) ;
137- } ) ;
123+ self . emit ( 'error' , err ) ;
124+ return ;
125+ }
126+
127+ if ( self . _handle . bind ( ip , port || 0 , /*flags=*/ 0 ) ) {
128+ self . emit ( 'error' , errnoException ( errno , 'bind' ) ) ;
129+ return ;
138130 }
131+
132+ self . _handle . onmessage = onMessage ;
133+ self . _handle . recvStart ( ) ;
134+ self . _receiving = true ;
135+ self . _bound = true ;
136+ self . fd = - 42 ; // compatibility hack
137+
138+ self . emit ( 'listening' ) ;
139139 } ) ;
140140} ;
141141
@@ -174,7 +174,14 @@ Socket.prototype.send = function(buffer,
174174 callback = callback || noop ;
175175
176176 self . _healthCheck ( ) ;
177- self . _startReceiving ( ) ;
177+
178+ if ( ! self . _bound ) {
179+ self . bind ( 0 , null ) ;
180+ self . once ( 'listening' , function ( ) {
181+ self . send ( buffer , offset , length , port , address , callback ) ;
182+ } ) ;
183+ return ;
184+ }
178185
179186 self . _handle . lookup ( address , function ( err , ip ) {
180187 if ( err ) {
@@ -309,25 +316,6 @@ Socket.prototype._healthCheck = function() {
309316} ;
310317
311318
312- Socket . prototype . _startReceiving = function ( ) {
313- if ( this . _receiving )
314- return ;
315-
316- if ( ! this . _bound ) {
317- this . bind ( ) ; // bind to random port
318-
319- // sanity check
320- if ( ! this . _bound )
321- throw new Error ( 'implicit bind failed' ) ;
322- }
323-
324- this . _handle . onmessage = onMessage ;
325- this . _handle . recvStart ( ) ;
326- this . _receiving = true ;
327- this . fd = - 42 ; // compatibility hack
328- } ;
329-
330-
331319Socket . prototype . _stopReceiving = function ( ) {
332320 if ( ! this . _receiving )
333321 return ;
0 commit comments