From eb5a2dde964c6a40802e336c4a9d0e64111feb36 Mon Sep 17 00:00:00 2001 From: darthneko Date: Sat, 24 Jan 2015 00:04:53 +0100 Subject: [PATCH 1/4] Accept lists of ports Modified existing methods to work with a list of ports instead of a starting port and ending port. --- lib/portscanner.js | 106 ++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/lib/portscanner.js b/lib/portscanner.js index a27ba84..22037bf 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -1,16 +1,14 @@ -var net = require('net') - , Socket = net.Socket - , async = require('async') +var net = require('net'); +var Socket = net.Socket; +var async = require('async'); -var portscanner = exports +var portscanner = exports; /** * Finds the first port with a status of 'open', implying the port is in use and * there is likely a service listening on it. * - * @param {Number} startPort - Port to begin status check on (inclusive). - * @param {Number} endPort - Last port to check status on (inclusive). - * Defaults to 65535. + * @param {List} portList - List of ports to check on. * @param {String} host - Where to scan. Defaults to '127.0.0.1'. * @param {Function} callback - function (error, port) { ... } * - {Object|null} error - Any errors that occurred while port scanning. @@ -19,17 +17,15 @@ var portscanner = exports * necessarily the first open port checked. If no * open port is found, the value is false. */ -portscanner.findAPortInUse = function(startPort, endPort, host, callback) { - findAPortWithStatus('open', startPort, endPort, host, callback) +portscanner.findAPortInUse = function(portList, host, callback) { + findAPortWithStatus('open', portList, host, callback); } /** * Finds the first port with a status of 'closed', implying the port is not in * use. * - * @param {Number} startPort - Port to begin status check on (inclusive). - * @param {Number} endPort - Last port to check status on (inclusive). - * Defaults to 65535. + * @param {List} portList - List of ports to check on. * @param {String} host - Where to scan. Defaults to '127.0.0.1'. * @param {Function} callback - function (error, port) { ... } * - {Object|null} error - Any errors that occurred while port scanning. @@ -38,8 +34,8 @@ portscanner.findAPortInUse = function(startPort, endPort, host, callback) { * necessarily the first closed port checked. If no * closed port is found, the value is false. */ -portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { - findAPortWithStatus('closed', startPort, endPort, host, callback) +portscanner.findAPortNotInUse = function(portList, host, callback) { + findAPortWithStatus('closed', portList, host, callback); } /** @@ -59,30 +55,30 @@ portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { portscanner.checkPortStatus = function(port, options, callback) { if (typeof options === 'string') { // Assume this param is the host option - options = {host: options} + options = {host: options}; } - var host = options.host || '127.0.0.1' - var timeout = options.timeout || 400 + var host = options.host || '127.0.0.1'; + var timeout = options.timeout || 400; var connectionRefused = false; - var socket = new Socket() - , status = null - , error = null + var socket = new Socket(); + var status = null; + var error = null; // Socket connection established, port is open socket.on('connect', function() { - status = 'open' - socket.destroy() - }) + status = 'open'; + socket.destroy(); + }); // If no response, assume port is not listening - socket.setTimeout(timeout) + socket.setTimeout(timeout); socket.on('timeout', function() { - status = 'closed' - error = new Error('Timeout (' + timeout + 'ms) occurred waiting for ' + host + ':' + port + ' to be available') - socket.destroy() - }) + status = 'closed'; + error = new Error('Timeout (' + timeout + 'ms) occurred waiting for ' + host + ':' + port + ' to be available'); + socket.destroy(); + }); // Assuming the port is not open if an error. May need to refine based on // exception @@ -93,7 +89,7 @@ portscanner.checkPortStatus = function(port, options, callback) { else connectionRefused = true; status = 'closed' - }) + }); // Return after the socket has closed socket.on('close', function(exception) { @@ -101,51 +97,45 @@ portscanner.checkPortStatus = function(port, options, callback) { error = exception; else error = null; - callback(error, status) - }) + callback(error, status); + }); - socket.connect(port, host) + socket.connect(port, host); } -function findAPortWithStatus(status, startPort, endPort, host, callback) { - endPort = endPort || 65535 - var foundPort = false - var numberOfPortsChecked = 0 - var port = startPort +function findAPortWithStatus(status, portList, host, callback) { + var foundPort = false; + var portIndex = 0; + var port = portList[portIndex]; // Returns true if a port with matching status has been found or if checked // the entire range of ports var hasFoundPort = function() { - return foundPort || numberOfPortsChecked === (endPort - startPort + 1) - } + return foundPort || (portIndex === portList.length); + }; // Checks the status of the port var checkNextPort = function(callback) { portscanner.checkPortStatus(port, host, function(error, statusOfPort) { - numberOfPortsChecked++ if (statusOfPort === status) { - foundPort = true - callback(error) + foundPort = true; + callback(error); + } else { + port = portList[++portIndex]; + callback(null); } - else { - port++ - callback(null) - } - }) - } + }); + }; // Check the status of each port until one with a matching status has been // found or the range of ports has been exhausted async.until(hasFoundPort, checkNextPort, function(error) { if (error) { - callback(error, port) + callback(error, port); + } else if (foundPort) { + callback(null, port); + } else { + callback(null, false); } - else if (foundPort) { - callback(null, port) - } - else { - callback(null, false) - } - }) -} - + }); +} \ No newline at end of file From 2d6e0522d4f7e1e3abadfb5c21411718ac618c76 Mon Sep 17 00:00:00 2001 From: darthneko Date: Sat, 24 Jan 2015 01:23:24 +0100 Subject: [PATCH 2/4] Revert "Accept lists of ports" This reverts commit eb5a2dde964c6a40802e336c4a9d0e64111feb36. --- lib/portscanner.js | 106 +++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/lib/portscanner.js b/lib/portscanner.js index 22037bf..a27ba84 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -1,14 +1,16 @@ -var net = require('net'); -var Socket = net.Socket; -var async = require('async'); +var net = require('net') + , Socket = net.Socket + , async = require('async') -var portscanner = exports; +var portscanner = exports /** * Finds the first port with a status of 'open', implying the port is in use and * there is likely a service listening on it. * - * @param {List} portList - List of ports to check on. + * @param {Number} startPort - Port to begin status check on (inclusive). + * @param {Number} endPort - Last port to check status on (inclusive). + * Defaults to 65535. * @param {String} host - Where to scan. Defaults to '127.0.0.1'. * @param {Function} callback - function (error, port) { ... } * - {Object|null} error - Any errors that occurred while port scanning. @@ -17,15 +19,17 @@ var portscanner = exports; * necessarily the first open port checked. If no * open port is found, the value is false. */ -portscanner.findAPortInUse = function(portList, host, callback) { - findAPortWithStatus('open', portList, host, callback); +portscanner.findAPortInUse = function(startPort, endPort, host, callback) { + findAPortWithStatus('open', startPort, endPort, host, callback) } /** * Finds the first port with a status of 'closed', implying the port is not in * use. * - * @param {List} portList - List of ports to check on. + * @param {Number} startPort - Port to begin status check on (inclusive). + * @param {Number} endPort - Last port to check status on (inclusive). + * Defaults to 65535. * @param {String} host - Where to scan. Defaults to '127.0.0.1'. * @param {Function} callback - function (error, port) { ... } * - {Object|null} error - Any errors that occurred while port scanning. @@ -34,8 +38,8 @@ portscanner.findAPortInUse = function(portList, host, callback) { * necessarily the first closed port checked. If no * closed port is found, the value is false. */ -portscanner.findAPortNotInUse = function(portList, host, callback) { - findAPortWithStatus('closed', portList, host, callback); +portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { + findAPortWithStatus('closed', startPort, endPort, host, callback) } /** @@ -55,30 +59,30 @@ portscanner.findAPortNotInUse = function(portList, host, callback) { portscanner.checkPortStatus = function(port, options, callback) { if (typeof options === 'string') { // Assume this param is the host option - options = {host: options}; + options = {host: options} } - var host = options.host || '127.0.0.1'; - var timeout = options.timeout || 400; + var host = options.host || '127.0.0.1' + var timeout = options.timeout || 400 var connectionRefused = false; - var socket = new Socket(); - var status = null; - var error = null; + var socket = new Socket() + , status = null + , error = null // Socket connection established, port is open socket.on('connect', function() { - status = 'open'; - socket.destroy(); - }); + status = 'open' + socket.destroy() + }) // If no response, assume port is not listening - socket.setTimeout(timeout); + socket.setTimeout(timeout) socket.on('timeout', function() { - status = 'closed'; - error = new Error('Timeout (' + timeout + 'ms) occurred waiting for ' + host + ':' + port + ' to be available'); - socket.destroy(); - }); + status = 'closed' + error = new Error('Timeout (' + timeout + 'ms) occurred waiting for ' + host + ':' + port + ' to be available') + socket.destroy() + }) // Assuming the port is not open if an error. May need to refine based on // exception @@ -89,7 +93,7 @@ portscanner.checkPortStatus = function(port, options, callback) { else connectionRefused = true; status = 'closed' - }); + }) // Return after the socket has closed socket.on('close', function(exception) { @@ -97,45 +101,51 @@ portscanner.checkPortStatus = function(port, options, callback) { error = exception; else error = null; - callback(error, status); - }); + callback(error, status) + }) - socket.connect(port, host); + socket.connect(port, host) } -function findAPortWithStatus(status, portList, host, callback) { - var foundPort = false; - var portIndex = 0; - var port = portList[portIndex]; +function findAPortWithStatus(status, startPort, endPort, host, callback) { + endPort = endPort || 65535 + var foundPort = false + var numberOfPortsChecked = 0 + var port = startPort // Returns true if a port with matching status has been found or if checked // the entire range of ports var hasFoundPort = function() { - return foundPort || (portIndex === portList.length); - }; + return foundPort || numberOfPortsChecked === (endPort - startPort + 1) + } // Checks the status of the port var checkNextPort = function(callback) { portscanner.checkPortStatus(port, host, function(error, statusOfPort) { + numberOfPortsChecked++ if (statusOfPort === status) { - foundPort = true; - callback(error); - } else { - port = portList[++portIndex]; - callback(null); + foundPort = true + callback(error) } - }); - }; + else { + port++ + callback(null) + } + }) + } // Check the status of each port until one with a matching status has been // found or the range of ports has been exhausted async.until(hasFoundPort, checkNextPort, function(error) { if (error) { - callback(error, port); - } else if (foundPort) { - callback(null, port); - } else { - callback(null, false); + callback(error, port) } - }); -} \ No newline at end of file + else if (foundPort) { + callback(null, port) + } + else { + callback(null, false) + } + }) +} + From ea48def6fa2676e479726dd3860835537f7c2a97 Mon Sep 17 00:00:00 2001 From: darthneko Date: Sat, 24 Jan 2015 01:39:22 +0100 Subject: [PATCH 3/4] Accept list of ports - Revised changes Implemented changes suggested. Cohesive code style and backwards compatibility. New methods are named as the old method with a "inList" suffix - for instance, findAPortNotInUseInList. --- example/portscan-list.js | 11 ++++++ lib/portscanner.js | 76 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 example/portscan-list.js diff --git a/example/portscan-list.js b/example/portscan-list.js new file mode 100644 index 0000000..5585f6f --- /dev/null +++ b/example/portscan-list.js @@ -0,0 +1,11 @@ +var http = require('http') + , portscanner = require('../lib/portscanner.js') + +// Check if one of the ports in the list is available +portscanner.findAPortNotInUseInList([4443, 4444, 4447], '127.0.0.1', function(error, port) { + if (!error) { + console.log('Available port: ' + port); + } else { + console.log('There was an error'); + } +}); \ No newline at end of file diff --git a/lib/portscanner.js b/lib/portscanner.js index a27ba84..0bf2439 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -23,6 +23,23 @@ portscanner.findAPortInUse = function(startPort, endPort, host, callback) { findAPortWithStatus('open', startPort, endPort, host, callback) } +/** + * Finds the first port with a status of 'open', implying the port is in use and + * there is likely a service listening on it. + * + * @param {List} portList - List of ports to check on. + * @param {String} host - Where to scan. Defaults to '127.0.0.1'. + * @param {Function} callback - function (error, port) { ... } + * - {Object|null} error - Any errors that occurred while port scanning. + * - {Number|Boolean} port - The first open port found. Note, this is the + * first port that returns status as 'open', not + * necessarily the first open port checked. If no + * open port is found, the value is false. + */ +portscanner.findAPortInUseInList = function(portList, host, callback) { + findAPortWithStatusInList('open', portList, host, callback) +} + /** * Finds the first port with a status of 'closed', implying the port is not in * use. @@ -42,6 +59,23 @@ portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { findAPortWithStatus('closed', startPort, endPort, host, callback) } +/** + * Finds the first port with a status of 'closed', implying the port is not in + * use. + * + * @param {List} portList - List of ports to check on. + * @param {String} host - Where to scan. Defaults to '127.0.0.1'. + * @param {Function} callback - function (error, port) { ... } + * - {Object|null} error - Any errors that occurred while port scanning. + * - {Number|Boolean} port - The first closed port found. Note, this is the + * first port that returns status as 'closed', not + * necessarily the first closed port checked. If no + * closed port is found, the value is false. + */ +portscanner.findAPortNotInUseInList = function(portList, host, callback) { + findAPortWithStatusInList('closed', portList, host, callback) +} + /** * Checks the status of an individual port. * @@ -108,7 +142,7 @@ portscanner.checkPortStatus = function(port, options, callback) { } function findAPortWithStatus(status, startPort, endPort, host, callback) { - endPort = endPort || 65535 + var endPort = endPort || 65535 var foundPort = false var numberOfPortsChecked = 0 var port = startPort @@ -149,3 +183,43 @@ function findAPortWithStatus(status, startPort, endPort, host, callback) { }) } +function findAPortWithStatusInList(status, portList, host, callback) { + var foundPort = false + var portIndex = 0 + var port = portList[portIndex] + + // Returns true if a port with matching status has been found or if checked + // the entire range of ports + var hasFoundPort = function() { + return foundPort || portIndex === portList.length + } + + // Checks the status of the port + var checkNextPort = function(callback) { + portscanner.checkPortStatus(port, host, function(error, statusOfPort) { + if (statusOfPort === status) { + foundPort = true + callback(error) + } + else { + port = portList[++portIndex] + callback(null) + } + }) + } + + // Check the status of each port until one with a matching status has been + // found or the range of ports has been exhausted + async.until(hasFoundPort, checkNextPort, function(error) { + if (error) { + callback(error, port) + } + else if (foundPort) { + callback(null, port) + } + else { + callback(null, false) + } + }) +} + From 5a714b265b36a281cde6b836c08bb34f30f4f2f7 Mon Sep 17 00:00:00 2001 From: darthneko Date: Wed, 28 Jan 2015 17:30:31 +0100 Subject: [PATCH 4/4] Detect Arrays from original API Now the original API works with both arrays and start/end ports. Detection on which method to use is based on argument number. --- example/portscan-list.js | 2 +- lib/portscanner.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/portscan-list.js b/example/portscan-list.js index 5585f6f..558a1f4 100644 --- a/example/portscan-list.js +++ b/example/portscan-list.js @@ -2,7 +2,7 @@ var http = require('http') , portscanner = require('../lib/portscanner.js') // Check if one of the ports in the list is available -portscanner.findAPortNotInUseInList([4443, 4444, 4447], '127.0.0.1', function(error, port) { +portscanner.findAPortNotInUse([4443, 4444, 4447], '127.0.0.1', function(error, port) { if (!error) { console.log('Available port: ' + port); } else { diff --git a/lib/portscanner.js b/lib/portscanner.js index 0bf2439..2931303 100644 --- a/lib/portscanner.js +++ b/lib/portscanner.js @@ -36,8 +36,8 @@ portscanner.findAPortInUse = function(startPort, endPort, host, callback) { * necessarily the first open port checked. If no * open port is found, the value is false. */ -portscanner.findAPortInUseInList = function(portList, host, callback) { - findAPortWithStatusInList('open', portList, host, callback) +portscanner.findAPortInUse = function(portList, host, callback) { + findAPortWithStatus('open', portList, host, callback) } /** @@ -72,8 +72,8 @@ portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { * necessarily the first closed port checked. If no * closed port is found, the value is false. */ -portscanner.findAPortNotInUseInList = function(portList, host, callback) { - findAPortWithStatusInList('closed', portList, host, callback) +portscanner.findAPortNotInUse = function(portList, host, callback) { + findAPortWithStatus('closed', portList, host, callback) } /** @@ -183,7 +183,7 @@ function findAPortWithStatus(status, startPort, endPort, host, callback) { }) } -function findAPortWithStatusInList(status, portList, host, callback) { +function findAPortWithStatus(status, portList, host, callback) { var foundPort = false var portIndex = 0 var port = portList[portIndex]