From c5764ae1d57aa84781471a3d555a361cdb4f3343 Mon Sep 17 00:00:00 2001 From: Ouyang Yadong Date: Sat, 27 Oct 2018 15:44:50 +0800 Subject: [PATCH 1/2] net: `net.Server.listen()` avoid operations on `null` when fail When `net.Server` fails to create a new handle, an error shall be emitted in the next tick. Therefore, we make `net.Server.listen()` directly return to avoid following operations on `null` `this._handle`. Fixes: https://github.com/nodejs/node/issues/23917 --- lib/net.js | 7 +++++++ test/parallel/test-net-server-listen-path.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/net.js b/lib/net.js index d4b8bfcc2aeee7..0781b8f33701a3 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1435,6 +1435,13 @@ Server.prototype.listen = function(...args) { backlog = options.backlog || backlogFromArgs; listenInCluster(this, pipeName, -1, -1, backlog, undefined, options.exclusive); + + if (!this._handle) { + // Failed and an error shall be emitted in the next tick. + // Therefore, we directly return. + return this; + } + let mode = 0; if (options.readableAll === true) mode |= PipeConstants.UV_READABLE; diff --git a/test/parallel/test-net-server-listen-path.js b/test/parallel/test-net-server-listen-path.js index cc73c3fd438abe..3e150c9aeb35a7 100644 --- a/test/parallel/test-net-server-listen-path.js +++ b/test/parallel/test-net-server-listen-path.js @@ -69,3 +69,17 @@ function randomPipePath() { srv.close(); })); } + +// Test should emit "error" events when listening fails. +{ + const srv = net.createServer() + .listen({ + path: tmpdir.path, + writableAll: true, + }, common.mustNotCall()); + + srv.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'EADDRINUSE'); + assert(/^listen EADDRINUSE: address already in use/.test(err.message)); + })); +} From f58c0f1c2e1fd49fd0f76c28ea7d75cb7fa65f9d Mon Sep 17 00:00:00 2001 From: Ouyang Yadong Date: Tue, 30 Oct 2018 19:05:35 +0800 Subject: [PATCH 2/2] fixup --- test/parallel/test-net-server-listen-path.js | 24 ++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/parallel/test-net-server-listen-path.js b/test/parallel/test-net-server-listen-path.js index 3e150c9aeb35a7..cc7c6678b04224 100644 --- a/test/parallel/test-net-server-listen-path.js +++ b/test/parallel/test-net-server-listen-path.js @@ -72,14 +72,20 @@ function randomPipePath() { // Test should emit "error" events when listening fails. { - const srv = net.createServer() - .listen({ - path: tmpdir.path, - writableAll: true, - }, common.mustNotCall()); + const handlePath = randomPipePath(); + const srv1 = net.createServer().listen({ path: handlePath }, () => { + // As the handlePath is in use, binding to the same address again should + // make the server emit an 'EADDRINUSE' error. + const srv2 = net.createServer() + .listen({ + path: handlePath, + writableAll: true, + }, common.mustNotCall()); - srv.on('error', common.mustCall((err) => { - assert.strictEqual(err.code, 'EADDRINUSE'); - assert(/^listen EADDRINUSE: address already in use/.test(err.message)); - })); + srv2.on('error', common.mustCall((err) => { + srv1.close(); + assert.strictEqual(err.code, 'EADDRINUSE'); + assert(/^listen EADDRINUSE: address already in use/.test(err.message)); + })); + }); }