Skip to content
Permalink
Browse files

dgram: remove listeners on bind error

This avoids piling up `'listening'` event listeners if
`.bind()` fails repeatedly.

Fixes: #30209

PR-URL: #30210
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information...
addaleax committed Nov 1, 2019
1 parent 99e874e commit 115792dfde436354c82f38361cbff75ad226b8d0
Showing with 42 additions and 2 deletions.
  1. +15 −2 lib/dgram.js
  2. +27 −0 test/parallel/test-dgram-bind-error-repeat.js
@@ -211,8 +211,21 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) {

state.bindState = BIND_STATE_BINDING;

if (arguments.length && typeof arguments[arguments.length - 1] === 'function')
this.once('listening', arguments[arguments.length - 1]);
const cb = arguments.length && arguments[arguments.length - 1];
if (typeof cb === 'function') {
function removeListeners() {
this.removeListener('error', removeListeners);
this.removeListener('listening', onListening);
}

function onListening() {
removeListeners.call(this);
cb.call(this);
}

this.on('error', removeListeners);
this.on('listening', onListening);
}

if (port instanceof UDP) {
replaceHandle(this, port);
@@ -0,0 +1,27 @@
'use strict';
const common = require('../common');
const dgram = require('dgram');

// Regression test for https://github.com/nodejs/node/issues/30209
// No warning should be emitted when re-trying `.bind()` on UDP sockets
// repeatedly.

process.on('warning', common.mustNotCall());

const reservePortSocket = dgram.createSocket('udp4');
reservePortSocket.bind(() => {
const { port } = reservePortSocket.address();

const newSocket = dgram.createSocket('udp4');

let errors = 0;
newSocket.on('error', common.mustCall(() => {
if (++errors < 20) {
newSocket.bind(port, common.mustNotCall());
} else {
newSocket.close();
reservePortSocket.close();
}
}, 20));
newSocket.bind(port, common.mustNotCall());
});

0 comments on commit 115792d

Please sign in to comment.
You can’t perform that action at this time.