Skip to content

Commit 29c8199

Browse files
addaleaxtargos
authored andcommitted
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 <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent aa30eb5 commit 29c8199

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

lib/dgram.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,21 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) {
211211

212212
state.bindState = BIND_STATE_BINDING;
213213

214-
if (arguments.length && typeof arguments[arguments.length - 1] === 'function')
215-
this.once('listening', arguments[arguments.length - 1]);
214+
const cb = arguments.length && arguments[arguments.length - 1];
215+
if (typeof cb === 'function') {
216+
function removeListeners() {
217+
this.removeListener('error', removeListeners);
218+
this.removeListener('listening', onListening);
219+
}
220+
221+
function onListening() {
222+
removeListeners.call(this);
223+
cb.call(this);
224+
}
225+
226+
this.on('error', removeListeners);
227+
this.on('listening', onListening);
228+
}
216229

217230
if (port instanceof UDP) {
218231
replaceHandle(this, port);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
const common = require('../common');
3+
const dgram = require('dgram');
4+
5+
// Regression test for https://github.com/nodejs/node/issues/30209
6+
// No warning should be emitted when re-trying `.bind()` on UDP sockets
7+
// repeatedly.
8+
9+
process.on('warning', common.mustNotCall());
10+
11+
const reservePortSocket = dgram.createSocket('udp4');
12+
reservePortSocket.bind(() => {
13+
const { port } = reservePortSocket.address();
14+
15+
const newSocket = dgram.createSocket('udp4');
16+
17+
let errors = 0;
18+
newSocket.on('error', common.mustCall(() => {
19+
if (++errors < 20) {
20+
newSocket.bind(port, common.mustNotCall());
21+
} else {
22+
newSocket.close();
23+
reservePortSocket.close();
24+
}
25+
}, 20));
26+
newSocket.bind(port, common.mustNotCall());
27+
});

0 commit comments

Comments
 (0)