diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2012-12-31 17:42:54 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2012-12-31 17:53:00 +0100 |
commit | 9e32c2ef3ede29ba0ae2086bdf658f6cd44182df (patch) | |
tree | 01a1e283245baa1de7888700d3cf389ed899a6d8 /lib/dgram.js | |
parent | 30bd774fbd379c86dd4e1bbaecd593b56112ddc3 (diff) | |
download | android-node-v8-9e32c2ef3ede29ba0ae2086bdf658f6cd44182df.tar.gz android-node-v8-9e32c2ef3ede29ba0ae2086bdf658f6cd44182df.tar.bz2 android-node-v8-9e32c2ef3ede29ba0ae2086bdf658f6cd44182df.zip |
dgram: fix double implicit bind error
Calling send() on an unbound socket forces an implicit bind to
a random port.
332fea5 made the 'listening' event asynchronous. Unfortunately,
it also introduced a bug where the implicit bind was tried more
than once if send() was called again before the first bind operation
completed.
Address that by keeping track of the bind status and making sure that
bind() is called only once.
Fixes #4499.
Diffstat (limited to 'lib/dgram.js')
-rw-r--r-- | lib/dgram.js | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/dgram.js b/lib/dgram.js index 483794b725..8130bace80 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -24,6 +24,10 @@ var events = require('events'); var UDP = process.binding('udp_wrap').UDP; +var BIND_STATE_UNBOUND = 0; +var BIND_STATE_BINDING = 1; +var BIND_STATE_BOUND = 2; + // lazily loaded var dns = null; var net = null; @@ -90,7 +94,7 @@ function Socket(type, listener) { this._handle = handle; this._receiving = false; - this._bound = false; + this._bindState = BIND_STATE_UNBOUND; this.type = type; this.fd = null; // compatibility hack @@ -116,6 +120,8 @@ Socket.prototype.bind = function(port, address, callback) { // resolve address first self._handle.lookup(address, function(err, ip) { + self._bindState = BIND_STATE_UNBOUND; + if (!self._handle) return; // handle has been closed in the mean time @@ -132,11 +138,13 @@ Socket.prototype.bind = function(port, address, callback) { self._handle.onmessage = onMessage; self._handle.recvStart(); self._receiving = true; - self._bound = true; + self._bindState = BIND_STATE_BOUND; self.fd = -42; // compatibility hack self.emit('listening'); }); + + self._bindState = BIND_STATE_BINDING; }; @@ -175,8 +183,10 @@ Socket.prototype.send = function(buffer, self._healthCheck(); - if (!self._bound) { + if (self._bindState == BIND_STATE_UNBOUND) self.bind(0, null); + + if (self._bindState != BIND_STATE_BOUND) { self.once('listening', function() { self.send(buffer, offset, length, port, address, callback); }); |