aboutsummaryrefslogtreecommitdiff
path: root/lib/dgram.js
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2012-12-31 17:42:54 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2012-12-31 17:53:00 +0100
commit9e32c2ef3ede29ba0ae2086bdf658f6cd44182df (patch)
tree01a1e283245baa1de7888700d3cf389ed899a6d8 /lib/dgram.js
parent30bd774fbd379c86dd4e1bbaecd593b56112ddc3 (diff)
downloadandroid-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.js16
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);
});