summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/dgram.js17
-rw-r--r--test/parallel/test-dgram-bind-error-repeat.js27
2 files changed, 42 insertions, 2 deletions
diff --git a/lib/dgram.js b/lib/dgram.js
index 35d414320a..94f44d5202 100644
--- a/lib/dgram.js
+++ b/lib/dgram.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);
diff --git a/test/parallel/test-dgram-bind-error-repeat.js b/test/parallel/test-dgram-bind-error-repeat.js
new file mode 100644
index 0000000000..a520d30a51
--- /dev/null
+++ b/test/parallel/test-dgram-bind-error-repeat.js
@@ -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());
+});