330 lines
17 KiB
HTML
330 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
<title>launch.js - Documentation</title>
|
|
|
|
|
|
<script src="scripts/prettify/prettify.js"></script>
|
|
<script src="scripts/prettify/lang-css.js"></script>
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
</head>
|
|
<body>
|
|
|
|
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
<label for="nav-trigger" class="navicon-button x">
|
|
<div class="navicon"></div>
|
|
</label>
|
|
|
|
<label for="nav-trigger" class="overlay"></label>
|
|
|
|
<nav>
|
|
|
|
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="ControlServer.html">ControlServer</a><ul class='methods'><li data-type='method'><a href="ControlServer.html#.instance_info">instance_info</a></li><li data-type='method'><a href="ControlServer.html#close">close</a></li><li data-type='method'><a href="ControlServer.html#createDNSServer">createDNSServer</a></li><li data-type='method'><a href="ControlServer.html#createHTTPServer">createHTTPServer</a></li><li data-type='method'><a href="ControlServer.html#createSOCKSServer">createSOCKSServer</a></li><li data-type='method'><a href="ControlServer.html#createTorPool">createTorPool</a></li><li data-type='method'><a href="ControlServer.html#listen">listen</a></li><li data-type='method'><a href="ControlServer.html#listenTcp">listenTcp</a></li><li data-type='method'><a href="ControlServer.html#listenWs">listenWs</a></li></ul></li><li><a href="DNSServer.html">DNSServer</a><ul class='methods'><li data-type='method'><a href="DNSServer.html#listen">listen</a></li></ul></li><li><a href="HTTPServer.html">HTTPServer</a><ul class='methods'><li data-type='method'><a href="HTTPServer.html#listen">listen</a></li></ul></li><li><a href="SOCKSServer.html">SOCKSServer</a><ul class='methods'><li data-type='method'><a href="SOCKSServer.html#listen">listen</a></li></ul></li><li><a href="TorPool.html">TorPool</a><ul class='methods'><li data-type='method'><a href="TorPool.html#add">add</a></li><li data-type='method'><a href="TorPool.html#add_instance_to_group">add_instance_to_group</a></li><li data-type='method'><a href="TorPool.html#add_instance_to_group_at">add_instance_to_group_at</a></li><li data-type='method'><a href="TorPool.html#add_instance_to_group_by_name">add_instance_to_group_by_name</a></li><li data-type='method'><a href="TorPool.html#create">create</a></li><li data-type='method'><a href="TorPool.html#create_instance">create_instance</a></li><li data-type='method'><a href="TorPool.html#exit">exit</a></li><li data-type='method'><a href="TorPool.html#get_config_at">get_config_at</a></li><li data-type='method'><a href="TorPool.html#get_config_by_name">get_config_by_name</a></li><li data-type='method'><a href="TorPool.html#instance_at">instance_at</a></li><li data-type='method'><a href="TorPool.html#instance_by_name">instance_by_name</a></li><li data-type='method'><a href="TorPool.html#instances_by_group">instances_by_group</a></li><li data-type='method'><a href="TorPool.html#new_identites">new_identites</a></li><li data-type='method'><a href="TorPool.html#new_identites_by_group">new_identites_by_group</a></li><li data-type='method'><a href="TorPool.html#new_identity_at">new_identity_at</a></li><li data-type='method'><a href="TorPool.html#new_identity_by_name">new_identity_by_name</a></li><li data-type='method'><a href="TorPool.html#next">next</a></li><li data-type='method'><a href="TorPool.html#next_by_group">next_by_group</a></li><li data-type='method'><a href="TorPool.html#remove">remove</a></li><li data-type='method'><a href="TorPool.html#remove_at">remove_at</a></li><li data-type='method'><a href="TorPool.html#remove_by_name">remove_by_name</a></li><li data-type='method'><a href="TorPool.html#remove_instance_from_group">remove_instance_from_group</a></li><li data-type='method'><a href="TorPool.html#remove_instance_from_group_at">remove_instance_from_group_at</a></li><li data-type='method'><a href="TorPool.html#remove_instance_from_group_by_name">remove_instance_from_group_by_name</a></li><li data-type='method'><a href="TorPool.html#set_config_all">set_config_all</a></li><li data-type='method'><a href="TorPool.html#set_config_at">set_config_at</a></li><li data-type='method'><a href="TorPool.html#set_config_by_group">set_config_by_group</a></li><li data-type='method'><a href="TorPool.html#set_config_by_name">set_config_by_name</a></li><li data-type='method'><a href="TorPool.html#signal_all">signal_all</a></li><li data-type='method'><a href="TorPool.html#signal_at">signal_at</a></li><li data-type='method'><a href="TorPool.html#signal_by_group">signal_by_group</a></li><li data-type='method'><a href="TorPool.html#signal_by_name">signal_by_name</a></li></ul></li><li><a href="TorProcess.html">TorProcess</a><ul class='methods'><li data-type='method'><a href="TorProcess.html#create">create</a></li><li data-type='method'><a href="TorProcess.html#exit">exit</a></li><li data-type='method'><a href="TorProcess.html#get_config">get_config</a></li><li data-type='method'><a href="TorProcess.html#new_identity">new_identity</a></li><li data-type='method'><a href="TorProcess.html#set_config">set_config</a></li><li data-type='method'><a href="TorProcess.html#signal">signal</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-tor-router.html">tor-router</a></li><li><a href="module-tor-router_ControlServer.html">tor-router/ControlServer</a></li><li><a href="module-tor-router_default_config.html">tor-router/default_config</a></li><li><a href="module-tor-router_default_ports.html">tor-router/default_ports</a></li><li><a href="module-tor-router_DNSServer.html">tor-router/DNSServer</a></li><li><a href="module-tor-router_HTTPServer.html">tor-router/HTTPServer</a></li><li><a href="module-tor-router_launch.html">tor-router/launch</a></li><li><a href="module-tor-router_nconf_load_env.html">tor-router/nconf_load_env</a></li><li><a href="module-tor-router_SOCKSServer.html">tor-router/SOCKSServer</a></li><li><a href="module-tor-router_TorPool.html">tor-router/TorPool</a></li><li><a href="module-tor-router_TorProcess.html">tor-router/TorProcess</a></li><li><a href="module-tor-router_winston_silent_logger.html">tor-router/winston_silent_logger</a></li></ul><h3>Events</h3><ul><li><a href="DNSServer.html#event:instance-connection">instance-connection</a></li><li><a href="HTTPServer.html#event:instance-connection">instance-connection</a></li><li><a href="SOCKSServer.html#event:instance-connection">instance-connection</a></li><li><a href="TorPool.html#event:instance_created">instance_created</a></li><li><a href="TorProcess.html#event:control_listen">control_listen</a></li><li><a href="TorProcess.html#event:controller_ready">controller_ready</a></li><li><a href="TorProcess.html#event:dns_listen">dns_listen</a></li><li><a href="TorProcess.html#event:error">error</a></li><li><a href="TorProcess.html#event:process_exit">process_exit</a></li><li><a href="TorProcess.html#event:ready">ready</a></li><li><a href="TorProcess.html#event:socks_listen">socks_listen</a></li></ul><h3>Global</h3><ul><li><a href="global.html#assembleHost">assembleHost</a></li><li><a href="global.html#cleanUp">cleanUp</a></li><li><a href="global.html#env_whitelist">env_whitelist</a></li><li><a href="global.html#logger">logger</a></li><li><a href="global.html#main">main</a></li><li><a href="global.html#nconf">nconf</a></li><li><a href="global.html#REALM">REALM</a></li><li><a href="global.html#setup_nconf_env">setup_nconf_env</a></li><li><a href="global.html#TOR_ROUTER_PROXY_AGENT">TOR_ROUTER_PROXY_AGENT</a></li></ul>
|
|
</nav>
|
|
|
|
<div id="main">
|
|
|
|
<h1 class="page-title">launch.js</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<article>
|
|
<pre class="prettyprint source linenums"><code>const fs = require('fs');
|
|
|
|
const { Provider } = require('nconf');
|
|
const yargs = require('yargs');
|
|
const winston = require('winston')
|
|
const Promise = require('bluebird');
|
|
|
|
const { ControlServer } = require('./');
|
|
const default_ports = require('./default_ports');
|
|
|
|
const package_json = JSON.parse(fs.readFileSync(`${__dirname}/../package.json`, 'utf8'));
|
|
|
|
/**
|
|
* @typedef Host
|
|
* @property {string} hostname - The hostname
|
|
* @property {number} port - The port
|
|
* @private
|
|
*/
|
|
|
|
/**
|
|
* Extracts the host and port components from a string
|
|
* @param {string} host
|
|
* @returns {Host}
|
|
* @private
|
|
*/
|
|
function extractHost (host) {
|
|
if (typeof(host) === 'number')
|
|
return { hostname: (typeof(default_ports.default_host) === 'string' ? default_ports.default_host : ''), port: host };
|
|
else if (typeof(host) === 'string' && host.indexOf(':') !== -1)
|
|
return { hostname: host.split(':').shift(), port: Number(host.split(':').pop()) };
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Takes an object with a hostname and port returns a formatted string
|
|
* @param {Host} host
|
|
* @returns {string} - Formatted host (e.g. "0.0.0.0:1234")
|
|
*/
|
|
function assembleHost(host) {
|
|
return `${typeof(host.hostname) === 'string' ? host.hostname : '' }:${host.port}`;
|
|
}
|
|
|
|
/**
|
|
* Main function for the application
|
|
* @param {Provider} nconf - Instance of `nconf.Provider` used for configuration.
|
|
* @param {Logger} [logger] - Winston logger to be used for logging. If not provided will disable logging.
|
|
* @async
|
|
* @returns {Promise}
|
|
*/
|
|
async function main(nconf, logger) {
|
|
Promise.promisifyAll(nconf);
|
|
let instances = nconf.get('instances');
|
|
let socks_host = typeof(nconf.get('socksHost')) !== 'boolean' ? extractHost(nconf.get('socksHost')) : nconf.get('socksHost');
|
|
let dns_host = typeof(nconf.get('dnsHost')) !== 'boolean' ? extractHost(nconf.get('dnsHost')) : nconf.get('dnsHost');
|
|
let http_host = typeof(nconf.get('httpHost')) !== 'boolean' ? extractHost(nconf.get('httpHost')) : nconf.get('httpHost');
|
|
let control_host = typeof(nconf.get('controlHost')) !== 'boolean' ? extractHost(nconf.get('controlHost')) : nconf.get('controlHost');
|
|
let control_host_ws = typeof(nconf.get('websocketControlHost')) !== 'boolean' ? extractHost(nconf.get('websocketControlHost')) : nconf.get('websocketControlHost');
|
|
|
|
if (nconf.get('proxyByName') && nconf.get('proxyByName') === true)
|
|
nconf.set('proxyByName', 'individual');
|
|
|
|
if (typeof(control_host) === 'boolean') {
|
|
control_host = extractHost(9077);
|
|
nconf.set('controlHost', assembleHost(control_host));
|
|
}
|
|
|
|
if (typeof(control_host_ws) === 'boolean') {
|
|
control_host_ws = extractHost(9078);
|
|
nconf.set('websocketControlPort', assembleHost(control_host_ws));
|
|
}
|
|
|
|
let control = new ControlServer(nconf, logger);
|
|
|
|
try {
|
|
await control.listenTcp(control_host.port, control_host.hostname);
|
|
|
|
if (control_host_ws) {
|
|
control.listenWs(control_host_ws.port, control_host_ws.hostname);
|
|
}
|
|
|
|
if (socks_host) {
|
|
if (typeof(socks_host) === 'boolean') {
|
|
socks_host = extractHost(default_ports.socks);
|
|
nconf.set('socksHost', assembleHost(socks_host));
|
|
}
|
|
control.createSOCKSServer(socks_host.port, socks_host.hostname);
|
|
}
|
|
|
|
if (http_host) {
|
|
if (typeof(http_host) === 'boolean') {
|
|
http_host = extractHost(default_ports.http);
|
|
nconf.set('httpHost', assembleHost(http_host));
|
|
}
|
|
control.createHTTPServer(http_host.port, http_host.hostname);
|
|
}
|
|
|
|
if (dns_host) {
|
|
if (typeof(dns_host) === 'boolean') {
|
|
dns_host = extractHost(default_ports.dns);
|
|
nconf.set('dnsPort', assembleHost(dns_host));
|
|
}
|
|
control.createDNSServer(dns_host.port, dns_host.hostname);
|
|
}
|
|
|
|
if (instances) {
|
|
logger.info(`[tor]: starting ${Array.isArray(instances) ? instances.length : instances} tor instance(s)...`);
|
|
|
|
await control.tor_pool.create(instances);
|
|
|
|
logger.info('[tor]: tor started');
|
|
}
|
|
} catch (error) {
|
|
logger.error(`[global]: error starting application: ${error.stack}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
/**
|
|
* Kills all tor processes and exits, logging an error if one occurs.
|
|
* @function cleanUp
|
|
*
|
|
* @param {Error} error - Error or exit code
|
|
*/
|
|
const cleanUp = (async (error) => {
|
|
let thereWasAnExitError = false;
|
|
let { handleError } = this;
|
|
try {
|
|
await control.tor_pool.exit();
|
|
} catch (exitError) {
|
|
logger.error(`[global]: error closing tor instances: ${exitError.message}`);
|
|
thereWasAnExitError = true;
|
|
}
|
|
|
|
if (error instanceof Error) {
|
|
logger.error(`[global]: error shutting down: ${error.message}`);
|
|
} else {
|
|
error = 0;
|
|
}
|
|
|
|
process.exit(Number(Boolean(error || thereWasAnExitError)));
|
|
});
|
|
|
|
process.title = 'tor-router';
|
|
|
|
process.on('SIGHUP', () => {
|
|
control.tor_pool.new_identites();
|
|
});
|
|
|
|
process.on('exit', cleanUp);
|
|
process.on('SIGINT', cleanUp);
|
|
process.on('uncaughtException', cleanUp.bind({ handleError: true }));
|
|
}
|
|
|
|
/**
|
|
* Instance of `nconf.Provider`
|
|
* @type {Provider}
|
|
*/
|
|
let nconf = new Provider();
|
|
|
|
let argv_config =
|
|
yargs
|
|
.version(package_json.version)
|
|
.usage('Usage: tor-router [arguments]')
|
|
.options({
|
|
f: {
|
|
alias: 'config',
|
|
describe: 'Path to a config file to use',
|
|
demand: false
|
|
},
|
|
c: {
|
|
alias: 'controlHost',
|
|
describe: `Host the control server will bind to, handling TCP connections [default: ${default_ports.default_host}:9077]`,
|
|
demand: false
|
|
// ,default: 9077
|
|
},
|
|
w: {
|
|
alias: 'websocketControlHost',
|
|
describe: 'Host the control server will bind to, handling WebSocket connections. If no hostname is specified will bind to localhost',
|
|
demand: false
|
|
},
|
|
j: {
|
|
alias: 'instances',
|
|
describe: 'Number of instances using the default config',
|
|
demand: false
|
|
// ,default: 1
|
|
},
|
|
s: {
|
|
alias: 'socksHost',
|
|
describe: 'Host the SOCKS5 Proxy server will bind to. If no hostname is specified will bind to localhost',
|
|
demand: false,
|
|
// ,default: default_ports.socks
|
|
},
|
|
d: {
|
|
alias: 'dnsHost',
|
|
describe: 'Host the DNS Proxy server will bind to. If no hostname is specified will bind to localhost',
|
|
demand: false
|
|
},
|
|
h: {
|
|
alias: 'httpHost',
|
|
describe: 'Host the HTTP Proxy server will bind to. If no hostname is specified will bind to localhost',
|
|
demand: false
|
|
},
|
|
l: {
|
|
alias: 'logLevel',
|
|
describe: 'Controls the verbosity of console log output. Default level is "info". Set to "verbose" to see all network traffic logged or "null" to disable logging completely [default: info]',
|
|
demand: false
|
|
// ,default: "info"
|
|
},
|
|
p: {
|
|
alias: 'parentDataDirectory',
|
|
describe: 'Parent directory that will contain the data directories for the instances',
|
|
demand: false
|
|
},
|
|
b: {
|
|
alias: "loadBalanceMethod",
|
|
describe: 'Method that will be used to sort the instances between each request. Currently supports "round_robin" and "weighted". [default: round_robin]',
|
|
demand: false
|
|
},
|
|
t: {
|
|
alias: "torPath",
|
|
describe: "Provide the path for the Tor executable that will be used",
|
|
demand: false
|
|
},
|
|
n: {
|
|
alias: 'proxyByName',
|
|
describe: 'Allow connecting to a specific instance identified by the username field when connecting to a proxy',
|
|
demand: false
|
|
}
|
|
});
|
|
|
|
require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
|
|
nconf
|
|
.argv(argv_config);
|
|
|
|
let nconf_config = nconf.get('config');
|
|
if (nconf_config) {
|
|
if (!require('fs').existsSync(nconf_config)) {
|
|
console.error(`[global]: config file "${nconf_config}" does not exist. exiting.`);
|
|
process.exit(1);
|
|
}
|
|
nconf.file(nconf_config);
|
|
} else {
|
|
nconf.use('memory');
|
|
}
|
|
|
|
nconf.defaults(require(`${__dirname}/../src/default_config.js`));
|
|
|
|
let logLevel = nconf.get('logLevel');
|
|
|
|
/**
|
|
* Instnace of `winston.Logger`
|
|
* @type {Logger}
|
|
*/
|
|
let logger = winston.createLogger({
|
|
level: logLevel,
|
|
format: winston.format.simple(),
|
|
silent: (logLevel === 'null'),
|
|
transports: [ new (winston.transports.Console)({ level: (logLevel !== 'null' ? logLevel : void(0)), silent: (logLevel === 'null') }) ]
|
|
});
|
|
|
|
/**
|
|
* Exports the main function for the application, a configured `nconf.Provider` instance and a winston logger
|
|
* @module tor-router/launch
|
|
*/
|
|
module.exports = { main, nconf, logger };</code></pre>
|
|
</article>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<br class="clear">
|
|
|
|
<footer>
|
|
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Sep 25 2018 12:53:23 GMT-0400 (Eastern Daylight Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
</footer>
|
|
|
|
<script>prettyPrint();</script>
|
|
<script src="scripts/linenumber.js"></script>
|
|
|
|
|
|
</body>
|
|
</html>
|