From 87eb070edda332b00a90a5ff2bbf7a0c91111e6c Mon Sep 17 00:00:00 2001 From: VioletXF Date: Thu, 14 Mar 2024 17:59:45 +0900 Subject: [PATCH 1/3] fix: check if port is in excluded port range --- lib/portscanner.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/portscanner.js b/lib/portscanner.js index 8784a93..5830423 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -129,7 +129,28 @@ function checkPortStatus (port) { // Return after the socket has closed socket.on('close', function (exception) { if (exception && !connectionRefused) { error = error || exception } else { error = null } - callback(error, status) + if (process.platform === 'win32' && status === "closed") { + // For windows, we should check if the port is in excluded range by actually binding to it + var net = require('net') + var server = net.createServer() + server.on('error', function (e) { + if (e.code === 'EACCES') { + status = 'open' + error = null + } + server.close() + }) + // on close, we should call the callback + server.on('close', function () { + callback(error, status) + }) + server.listen(port, host, function () { + server.close() + }) + + } else { + callback(error, status) + } }) socket.connect(port, host) From f72fed99965ce20d87ef7d2acd9347a68ef90513 Mon Sep 17 00:00:00 2001 From: VioletXF Date: Thu, 14 Mar 2024 19:07:54 +0900 Subject: [PATCH 2/3] fix: add 'reserved' status --- lib/portscanner.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/portscanner.js b/lib/portscanner.js index 5830423..5b7d2b5 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -129,13 +129,13 @@ function checkPortStatus (port) { // Return after the socket has closed socket.on('close', function (exception) { if (exception && !connectionRefused) { error = error || exception } else { error = null } - if (process.platform === 'win32' && status === "closed") { - // For windows, we should check if the port is in excluded range by actually binding to it - var net = require('net') + + // For windows localhost, we should check if the port is in excluded range by actually binding to it + if ((host === '127.0.0.1' || host === 'localhost') && process.platform === 'win32' && status === 'closed') { var server = net.createServer() server.on('error', function (e) { if (e.code === 'EACCES') { - status = 'open' + status = 'reserved' error = null } server.close() @@ -159,7 +159,7 @@ function checkPortStatus (port) { * Callback for {@link checkPortStatus} * @callback checkPortCallback * @param {Error|null} error - Any error that occurred while port scanning, or null. - * @param {String} status - Status: 'open' if the port is in use, 'closed' if the port is available. + * @param {String} status - Status: 'open' if the port is in use, 'closed' if the port is available, or 'reserved' if the port is reserved (Windows only). */ /** From 6f0a1cd3465597e0837c5d2df8e20263ae4a7673 Mon Sep 17 00:00:00 2001 From: Main Date: Sun, 8 Sep 2024 15:50:20 +0530 Subject: [PATCH 3/3] feat: add 'reserved' tests --- test.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test.js b/test.js index 4f47d84..146ae41 100644 --- a/test.js +++ b/test.js @@ -1,4 +1,5 @@ import net from 'net' +import { execSync } from 'child_process' import test from 'ava' import portScanner from '.' @@ -9,6 +10,7 @@ findPortNotInUse() promise() reverseOrder() portsAsStrings() +findExcludedPorts() function initialize () { test.before.cb('Set #1 test server', t => { @@ -487,3 +489,37 @@ function portsAsStrings () { }) }) } + +function findExcludedPorts () { + if (process.platform !== 'win32') return + const output = execSync( + 'netsh interface ipv4 show excludedportrange protocol=tcp' + ).toString() + const ports = output + .split('\n') + .filter((line) => line.match(/^ +[0-9]+ +[0-9]+/)) + .map((line) => line.match(/ +([0-9]+) +([0-9]+)/).slice(1, 3)) + console.log(`ports:`, ports) + const portsToCheck = [] + for (const [startPort, endPort] of ports) { + for ( + let i = Number(startPort); + i <= Math.min(Number(startPort) + 2, endPort); + i++ + ) { + portsToCheck.push(i) + } + } + if (!portsToCheck.length) return + console.log(`portsToCheck:`, portsToCheck) + test.cb('Test reserved ports on Windows', (t) => { + t.plan(portsToCheck.length) + for (const port of portsToCheck) { + console.log(`testing:`, port) + portScanner.checkPortStatus(port, function (error, status) { + console.log(port, { error, status }) + t.is(status, 'reserved') + }) + } + }) +}