Skip to content

Instantly share code, notes, and snippets.

@eplawless
Last active April 18, 2016 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eplawless/51afd77bc6e8631f6b5cb117208d5fe0 to your computer and use it in GitHub Desktop.
Save eplawless/51afd77bc6e8631f6b5cb117208d5fe0 to your computer and use it in GitHub Desktop.
Implementation of "get next available TCP port"
var net = require('net');
var os = require('os');
function getLocalHosts() {
var hosts = ['0.0.0.0', '::'];
var interfaces = os.networkInterfaces();
Object.keys(interfaces).forEach(function(interfaceName) {
var interface = interfaces[interfaceName];
interface.forEach(function(info) {
var address = info.address;
// append the interface name onto link-local IPv6 addresses
// http://stackoverflow.com/a/34275391
if (address.indexOf('fe80:') === 0) {
address += '%' + interfaceName;
}
hosts.push(address);
});
});
return hosts;
}
function createServer(port, host) {
return new Promise(function(resolve, reject) {
var server = net.createServer();
server.listen(port, host, function() {
server.once('close', function() {
resolve(true);
});
server.close();
});
server.on('error', reject);
});
}
function _getNextAvailableTcpPort(port, hosts, callback) {
if (port < 1 || port > 65535) {
callback(new RangeError('expected port to be from 1 to 65535, got ' + port));
return;
}
var servers = hosts.reduce(function(lastServer, host) {
return lastServer
? lastServer.then(function() { return createServer(port, host); })
: createServer(port, host);
}, null);
servers.then(function() {
callback(null, port);
}, function(error) {
_getNextAvailableTcpPort(port + 1, hosts, callback);
});
}
function getNextAvailableTcpPort(port, callback) {
if (typeof callback !== 'function') {
throw new TypeError('expected callback to be a function, got ' + typeof callback);
}
if (typeof port !== 'number') {
callback(new TypeError('expected port to be a number, got ' + typeof port));
return;
}
var hosts = getLocalHosts();
return _getNextAvailableTcpPort(port, hosts, callback);
}
module.exports = getNextAvailableTcpPort;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment