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 <luigipinca@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent aa30eb5 commit 29c8199

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

‎lib/dgram.js‎

Lines changed: 15 additions & 2 deletions
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&&typeofarguments[arguments.length-1]==='function')
215-
this.once('listening',arguments[arguments.length-1]);
214+
constcb=arguments.length&&arguments[arguments.length-1];
215+
if(typeofcb==='function'){
216+
functionremoveListeners(){
217+
this.removeListener('error',removeListeners);
218+
this.removeListener('listening',onListening);
219+
}
220+
221+
functiononListening(){
222+
removeListeners.call(this);
223+
cb.call(this);
224+
}
225+
226+
this.on('error',removeListeners);
227+
this.on('listening',onListening);
228+
}
216229

217230
if(portinstanceofUDP){
218231
replaceHandle(this,port);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constdgram=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+
constreservePortSocket=dgram.createSocket('udp4');
12+
reservePortSocket.bind(()=>{
13+
const{ port }=reservePortSocket.address();
14+
15+
constnewSocket=dgram.createSocket('udp4');
16+
17+
leterrors=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)