Browse Source

dgram: introduce `reuseAddr` option

Introduce new signature for both `dgram.createSocket` method and
`dgram.Socket` constructor:

    dgram.createSocket(options, [listener])

Options should contain `type` property and may contain `reuseAddr`
property. When `reuseAddr` is `true` - SO_REUSEADDR will be issued on
socket on bind.

fix #7415

Signed-off-by: Fedor Indutny <fedor@indutny.com>
v0.11.13-release
Fedor Indutny 11 years ago
parent
commit
592be014b6
No known key found for this signature in database GPG Key ID: FB0E1095B1797999
  1. 7
      doc/api/dgram.markdown
  2. 15
      lib/dgram.js
  3. 5
      src/node_constants.cc
  4. 10
      test/simple/test-dgram-broadcast-multi-process.js

7
doc/api/dgram.markdown

@ -22,8 +22,13 @@ You have to change it to this:
## dgram.createSocket(type, [callback])
## dgram.createSocket(options, [callback])
* `type` String. Either 'udp4' or 'udp6'
* `options` Object. Should contain a `type` property and could contain
`reuseAddr` property. `false` by default.
When `reuseAddr` is `true` - `socket.bind()` will reuse address, even if the
other process has already bound a socket on it.
* `callback` Function. Attached as a listener to `message` events.
Optional
* Returns: Socket object
@ -41,7 +46,7 @@ with `socket.address().address` and `socket.address().port`.
## Class: dgram.Socket
The dgram Socket class encapsulates the datagram functionality. It
should be created via `dgram.createSocket(type, [callback])`.
should be created via `dgram.createSocket(...)`
### Event: 'message'

15
lib/dgram.js

@ -22,6 +22,7 @@
var assert = require('assert');
var util = require('util');
var events = require('events');
var constants = require('constants');
var UDP = process.binding('udp_wrap').UDP;
@ -96,6 +97,11 @@ exports._createSocketHandle = function(address, port, addressType, fd) {
function Socket(type, listener) {
events.EventEmitter.call(this);
if (typeof type === 'object') {
var options = type;
type = options.type;
}
var handle = newHandle(type);
handle.owner = this;
@ -105,6 +111,9 @@ function Socket(type, listener) {
this.type = type;
this.fd = null; // compatibility hack
// If true - UV_UDP_REUSEADDR flag will be set
this._reuseAddr = options && options.reuseAddr;
if (util.isFunction(listener))
this.on('message', listener);
}
@ -196,7 +205,11 @@ Socket.prototype.bind = function(/*port, address, callback*/) {
if (!self._handle)
return; // handle has been closed in the mean time
var err = self._handle.bind(ip, port || 0, /*flags=*/ 0);
var flags = 0;
if (self._reuseAddr)
flags |= constants.UV_UDP_REUSEADDR;
var err = self._handle.bind(ip, port || 0, flags);
if (err) {
self.emit('error', errnoException(err, 'bind'));
self._bindState = BIND_STATE_UNBOUND;

5
src/node_constants.cc

@ -1071,12 +1071,17 @@ void DefineSystemConstants(Handle<Object> target) {
#endif
}
void DefineUVConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, UV_UDP_REUSEADDR);
}
void DefineConstants(Handle<Object> target) {
DefineErrnoConstants(target);
DefineWindowsErrorConstants(target);
DefineSignalConstants(target);
DefineOpenSSLConstants(target);
DefineSystemConstants(target);
DefineUVConstants(target);
}
} // namespace node

10
test/simple/test-dgram-broadcast-multi-process.js

@ -157,7 +157,10 @@ if (process.argv[2] !== 'child') {
})(x);
}
var sendSocket = dgram.createSocket('udp4');
var sendSocket = dgram.createSocket({
type: 'udp4',
reuseAddr: true
});
// bind the address explicitly for sending
// INADDR_BROADCAST to only one interface
@ -201,7 +204,10 @@ if (process.argv[2] !== 'child') {
if (process.argv[2] === 'child') {
var receivedMessages = [];
var listenSocket = dgram.createSocket('udp4');
var listenSocket = dgram.createSocket({
type: 'udp4',
reuseAddr: true
});
listenSocket.on('message', function(buf, rinfo) {
// receive udp messages only sent from parent

Loading…
Cancel
Save