Replaces callbacks with Promises throughout the rest of the application.

This commit is contained in:
Zachary Boyd 2018-09-09 01:45:12 -04:00
parent d1265253d2
commit a74409ddb7
7 changed files with 215 additions and 354 deletions

View file

@ -3,7 +3,8 @@
## [4.0.0] - 2018-09-09 ## [4.0.0] - 2018-09-09
### Changes ### Changes
- All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await resulting in clearer code. Compatibility with node < v8 will be broken. - All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await to increase readability.
- The `logger` argument to the constructor's of all classes is now optional
### Removes ### Removes
- The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead. - The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead.

View file

@ -3,12 +3,11 @@ const SOCKSServer = require('./SOCKSServer');
const DNSServer = require('./DNSServer'); const DNSServer = require('./DNSServer');
const HTTPServer = require('./HTTPServer'); const HTTPServer = require('./HTTPServer');
const rpc = require('jrpc2'); const rpc = require('jrpc2');
const async = require('async');
class ControlServer { class ControlServer {
constructor(logger, nconf) { constructor(logger, nconf) {
this.torPool = new TorPool(nconf.get('torPath'), null, nconf.get('parentDataDirectory'), nconf.get('loadBalanceMethod'), nconf.get('granaxOptions'),logger); this.torPool = new TorPool(nconf.get('torPath'), null, nconf.get('parentDataDirectory'), nconf.get('loadBalanceMethod'), nconf.get('granaxOptions'),logger);
this.logger = logger; this.logger = logger || require('./winston-silent-logger');
this.nconf = nconf; this.nconf = nconf;
let server = this.server = new rpc.Server(); let server = this.server = new rpc.Server();
@ -21,247 +20,99 @@ class ControlServer {
return { name: i.instance_name, dns_port: i.dns_port, socks_port: i.socks_port, process_id: i.process.pid, config: i.definition.Config, weight: i.definition.weight }; return { name: i.instance_name, dns_port: i.dns_port, socks_port: i.socks_port, process_id: i.process.pid, config: i.definition.Config, weight: i.definition.weight };
}; };
server.expose('queryInstances', (function () { server.expose('queryInstances', (async () => {
return new Promise((resolve, reject) => { if (!this.torPool)
if (!this.torPool) throw new Error('No instances created');
return reject({ message: 'No pool created' });
this.torPool.instances.map(instance_info);
resolve(this.torPool.instances.map(instance_info) );
});
}).bind(this)); }).bind(this));
server.expose('queryInstanceByName', (function (instance_name) { server.expose('queryInstanceByName', (async (instance_name) => {
return new Promise((resolve, reject) => { if (!this.torPool)
if (!this.torPool) throw new Error('No pool created');
return reject({ message: 'No pool created' });
let i = this.torPool.instance_by_name(instance_name); let instance = this.torPool.instance_by_name(instance_name);
if (!i) if (!instance)
return reject({ message: `Instance "${instance_name}"" does not exist` }); throw new Error(`Instance "${instance_name}"" does not exist`);
resolve(instance_info(i)); return instance_info(i)
});
}).bind(this)); }).bind(this));
server.expose('queryInstanceAt', (function (index) { server.expose('queryInstanceAt', (async (index) => {
return new Promise((resolve, reject) => { if (!this.torPool)
if (!this.torPool) throw new Error('No pool created');
return reject({ message: 'No pool created' });
let i = this.torPool.instance_at(index); let instance = this.torPool.instance_at(index);
if (!i) if (!instance)
return reject({ message: `Instance at "${i}"" does not exist` }); throw new Error(`Instance at "${i}"" does not exist`);
resolve(instance_info(this.torPool.instance_at(index))); return instance_info(this.torPool.instance_at(index));
});
}).bind(this)); }).bind(this));
server.expose('createInstances', (function (instances) { server.expose('createInstances', this.torPool.create.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.create(instances, (error, instances) => { server.expose('addInstances', this.torPool.add.bind(this.torPool));
if (error) reject(error);
else resolve();
});
});
}).bind(this) );
server.expose('addInstances', (function (instances) { server.expose('removeInstances', this.torPool.remove.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.add(instances, (error, instances) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this) );
server.expose('removeInstances', (function (instances) { server.expose('removeInstanceAt', this.torPool.remove_at.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.remove(instances, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this) );
server.expose('removeInstanceAt', (function (instance_index) { server.expose('removeInstanceByName', this.torPool.remove_by_name.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.remove_at(instance_index, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this) );
server.expose('removeInstanceByName', (function (instance_name) { server.expose('newIdentites', this.torPool.new_identites.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.remove_by_name(instance_name, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this) );
server.expose('newIdentites', (function() { server.expose('newIdentityAt', this.torPool.new_identity_at.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.new_identites((error) => { server.expose('newIdentityByName', this.torPool.new_identity_by_name.bind(this.torPool));
if (error) reject(error);
else resolve(); server.expose('nextInstance', (async () => this.torPool.next()).bind(this));
});
}); server.expose('closeInstances', (async () => this.torPool.exit()).bind(this));
server.expose('getDefaultTorConfig', (async () => {
return this.nconf.get('torConfig');
}).bind(this)); }).bind(this));
server.expose('newIdentityAt', (function(index) { server.expose('setDefaultTorConfig', (async (config) => {
return new Promise((resolve, reject) => {
this.torPool.new_identity_at(index, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('newIdentityByName', (function(name) {
return new Promise((resolve, reject) => {
this.torPool.new_identity_by_name(name, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
/* Begin Deprecated */
server.expose('newIps', (function() {
return new Promise((resolve, reject) => {
this.torPool.new_ips((error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('newIpAt', (function(index) {
return new Promise((resolve, reject) => {
this.torPool.new_ip_at(index, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
/* End Deprecated */
server.expose('nextInstance', (function () {
this.torPool.next();
return Promise.resolve();
}).bind(this) );
server.expose('closeInstances', (function () {
this.torPool.exit();
return Promise.resolve();
}).bind(this) );
server.expose('getDefaultTorConfig', (function () {
return Promise.resolve(this.nconf.get('torConfig'));
}).bind(this));
server.expose('setDefaultTorConfig', (function (config) {
this.nconf.set('torConfig', config); this.nconf.set('torConfig', config);
return Promise.resolve();
}).bind(this)); }).bind(this));
server.expose('setTorConfig', (function (config) { server.expose('setTorConfig', (async (config) => {
return new Promise((resolve, reject) => { await Promise.all(Object.keys(config).map((key) => {
async.each(Object.keys(config), function (key, next) { var value = config[key];
var value = config[key];
this.torPool.set_config_all(key, value, next); return this.torPool.set_config_all(key, value);
}, function (error){ }));
if (error) reject(error);
resolve();
});
});
}).bind(this)); }).bind(this));
server.expose('getLoadBalanceMethod', (function () { server.expose('getLoadBalanceMethod', (async () => {
return Promise.resolve(this.torPool.load_balance_method); return this.torPool.load_balance_method;
}).bind(this)); }).bind(this));
server.expose('setLoadBalanceMethod', (function (loadBalanceMethod) { server.expose('setLoadBalanceMethod', (async (loadBalanceMethod) => {
this.torPool.load_balance_method = loadBalanceMethod; this.torPool.load_balance_method = loadBalanceMethod;
return Promise.resolve();
}).bind(this)); }).bind(this));
server.expose('getInstanceConfigByName', (function (name, keyword) { server.expose('getInstanceConfigByName', this.torPool.get_config_by_name.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.get_config_by_name(name, keyword, (error, value) => {
if (error) reject(error);
else resolve(value);
});
});
}).bind(this));
server.expose('getInstanceConfigAt', (function (index, keyword) { server.expose('getInstanceConfigAt', this.torPool.get_config_at.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.get_config_at(index, keyword, (error, value) => {
if (error) reject(error);
else resolve(value);
});
});
}).bind(this));
server.expose('setInstanceConfigByName', (function (name, keyword, value) { server.expose('setInstanceConfigByName', this.torPool.set_config_by_name.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.set_config_by_name(name, keyword, value, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('setInstanceConfigAt', (function (index, keyword, value) { server.expose('setInstanceConfigAt', this.torPool.set_config_at.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.set_config_at(index, keyword, value, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('signalAllInstances', this.torPool.signal_all.bind(this.torPool));
server.expose('signalAllInstances', (function (signal) { server.expose('signalInstanceAt', this.torPool.signal_at.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.signal_all(signal, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('signalInstanceAt', (function (index, signal, callback) { server.expose('signalInstanceByName', this.torPool.signal_by_name.bind(this.torPool));
return new Promise((resolve, reject) => {
this.torPool.signal_at(index, signal, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
server.expose('signalInstanceByName', (function (name, signal, callback) {
return new Promise((resolve, reject) => {
this.torPool.signal_by_name(name, signal, (error) => {
if (error) reject(error);
else resolve();
});
});
}).bind(this));
} }
listen(port, callback) { listen(port) {
this.tcpTransport = new rpc.tcpTransport({ port }); this.tcpTransport = new rpc.tcpTransport({ port });
this.tcpTransport.listen(this.server); this.tcpTransport.listen(this.server);
callback && callback();
} }
close() { close() {
@ -273,28 +124,25 @@ class ControlServer {
return this.torPool; return this.torPool;
} }
createSOCKSServer(port, callback) { createSOCKSServer(port) {
this.socksServer = new SOCKSServer(this.torPool, this.logger); this.socksServer = new SOCKSServer(this.torPool, this.logger);
this.socksServer.listen(port || 9050); this.socksServer.listen(port || 9050);
this.logger.info(`[socks]: Listening on ${port}`); this.logger.info(`[socks]: Listening on ${port}`);
this.socksServer; this.socksServer;
callback && callback();
} }
createHTTPServer(port, callback) { createHTTPServer(port) {
this.httpServer = new HTTPServer(this.torPool, this.logger); this.httpServer = new HTTPServer(this.torPool, this.logger);
this.httpServer.listen(port || 9080); this.httpServer.listen(port || 9080);
this.logger.info(`[http]: Listening on ${port}`); this.logger.info(`[http]: Listening on ${port}`);
this.httpServer; this.httpServer;
callback && callback();
} }
createDNSServer(port, callback) { createDNSServer(port) {
this.dnsServer = new DNSServer(this.torPool, this.nconf.get('dns:options'), this.nconf.get('dns:timeout'), this.logger); this.dnsServer = new DNSServer(this.torPool, this.nconf.get('dns:options'), this.nconf.get('dns:timeout'), this.logger);
this.dnsServer.serve(port || 9053); this.dnsServer.serve(port || 9053);
this.logger.info(`[dns]: Listening on ${port}`); this.logger.info(`[dns]: Listening on ${port}`);
this.dnsServer; this.dnsServer;
callback && callback();
} }
}; };

View file

@ -1,13 +1,13 @@
const dns = require('native-dns'); const dns = require('native-dns');
const UDPServer = require('native-dns').UDPServer; const { UDPServer } = require('native-dns');
class DNSServer extends UDPServer { class DNSServer extends UDPServer {
constructor(tor_pool, dns_options, dns_timeout, logger) { constructor(tor_pool, dns_options, dns_timeout, logger) {
super(dns_options); super(dns_options);
this.logger = logger; this.logger = logger || require('./winston-silent-logger');
this.tor_pool = tor_pool; this.tor_pool = tor_pool;
var handle_dns_request = (req, res) => { const handle_dns_request = (req, res) => {
let connect = (tor_instance) => { let connect = (tor_instance) => {
for (let question of req.question) { for (let question of req.question) {
let dns_port = (tor_instance.dns_port); let dns_port = (tor_instance.dns_port);
@ -27,7 +27,7 @@ class DNSServer extends UDPServer {
}); });
outbound_req.on('error', (err) => { outbound_req.on('error', (err) => {
this.logger.error(`[dns]: an error occured while handling ar request: ${err.message}`);
}); });

View file

@ -1,16 +1,19 @@
const http = require('http'); const http = require('http');
const Server = http.Server;
const socks = require('socksv5');
const URL = require('url'); const URL = require('url');
const { Server } = http;
const socks = require('socksv5');
const SocksProxyAgent = require('socks-proxy-agent'); const SocksProxyAgent = require('socks-proxy-agent');
const TOR_ROUTER_PROXY_AGENT = 'tor-router';
class HTTPServer extends Server { class HTTPServer extends Server {
constructor(tor_pool, logger) { constructor(tor_pool, logger) {
let handle_http_connections = (req, res) => { let handle_http_connections = (req, res) => {
let url = URL.parse(req.url); let url = URL.parse(req.url);
url.port = url.port || 80; url.port = url.port || 80;
var buffer = []; let buffer = [];
function onIncomingData(chunk) { function onIncomingData(chunk) {
buffer.push(chunk); buffer.push(chunk);
@ -23,7 +26,7 @@ class HTTPServer extends Server {
req.on('data', onIncomingData); req.on('data', onIncomingData);
req.on('end', preConnectClosed); req.on('end', preConnectClosed);
req.on('error', function (err) { req.on('error', function (err) {
logger.error("[http-proxy]: an error occured\n"+err.stack); logger.error("[http-proxy]: an error occured: "+err.message);
}); });
let connect = (tor_instance) => { let connect = (tor_instance) => {
@ -112,7 +115,7 @@ class HTTPServer extends Server {
outbound_socket && outbound_socket.on('close', onClose); outbound_socket && outbound_socket.on('close', onClose);
outbound_socket && outbound_socket.on('error', onClose); outbound_socket && outbound_socket.on('error', onClose);
inbound_socket.write('HTTP/1.1 200 Connection Established\r\n'+'Proxy-agent: tor-router\r\n' +'\r\n'); inbound_socket.write(`HTTP/1.1 200 Connection Established\r\n'+'Proxy-agent: ${TOR_ROUTER_PROXY_AGENT}\r\n` +'\r\n');
outbound_socket.write(head); outbound_socket.write(head);
outbound_socket.pipe(inbound_socket); outbound_socket.pipe(inbound_socket);
@ -130,7 +133,7 @@ class HTTPServer extends Server {
super(handle_http_connections); super(handle_http_connections);
this.on('connect', handle_connect_connections); this.on('connect', handle_connect_connections);
this.logger = logger; this.logger = logger || require('./winston-silent-logger');
this.tor_pool = tor_pool; this.tor_pool = tor_pool;
} }
}; };

View file

@ -1,7 +1,7 @@
const socks = require('socksv5'); const socks = require('socksv5');
const SOCKS5Server = socks.Server; const { Server } = socks;
class SOCKSServer extends SOCKS5Server{ class SOCKSServer extends Server{
constructor(tor_pool, logger) { constructor(tor_pool, logger) {
let handleConnection = (info, accept, deny) => { let handleConnection = (info, accept, deny) => {
let inbound_socket = accept(true); let inbound_socket = accept(true);
@ -67,7 +67,7 @@ class SOCKSServer extends SOCKS5Server{
super(handleConnection); super(handleConnection);
this.logger = logger; this.logger = logger || require('./winston-silent-logger');;
this.useAuth(socks.auth.None()); this.useAuth(socks.auth.None());
} }

View file

@ -101,19 +101,20 @@ class TorProcess extends EventEmitter {
let controlPort = this._control_port = await getPort(); let controlPort = this._control_port = await getPort();
let options = { let options = {
DNSPort: `127.0.0.1:${context.dnsPort}`, DNSPort: `127.0.0.1:${dnsPort}`,
SocksPort: `127.0.0.1:${context.socksPort}`, SocksPort: `127.0.0.1:${socksPort}`,
ControlPort: `127.0.0.1:${context.controlPort}`, ControlPort: `127.0.0.1:${controlPort}`,
HashedControlPassword: shell.exec(`${this.tor_path} --quiet --hash-password "${this.control_password}"`, { async: false, silent: true }).stdout.trim() HashedControlPassword: shell.exec(`${this.tor_path} --quiet --hash-password "${this.control_password}"`, { async: false, silent: true }).stdout.trim()
}; };
let config = _.extend(_.extend({}, this.tor_config), options); let config = _.extend(_.extend({}, this.tor_config), options);
let text = Object.keys(config).map((key) => `${key} ${config[key]}`).join(os.EOL); let text = Object.keys(config).map((key) => `${key} ${config[key]}`).join(os.EOL);
let configFilePath = await temp.openAsync('tor-router').path; let configFile = await temp.openAsync('tor-router');
fs.writeFileAsync(configFilePath, text); let configPath = configFile.path;
fs.writeFileAsync(configPath, text);
let tor = spawn(this.tor_path, ['-f', context.configPath], { let tor = spawn(this.tor_path, ['-f', configPath], {
stdio: ['ignore', 'pipe', 'pipe'], stdio: ['ignore', 'pipe', 'pipe'],
detached: false detached: false
}); });
@ -121,7 +122,7 @@ class TorProcess extends EventEmitter {
tor.on('close', (code) => { tor.on('close', (code) => {
this.emit('process_exit', code); this.emit('process_exit', code);
if (this.definition && !this.definition.Name) { if (this.definition && !this.definition.Name) {
del.sync(this.tor_config.DataDirectory, { force: true }); del(this.tor_config.DataDirectory, { force: true });
} }
}); });
@ -139,7 +140,7 @@ class TorProcess extends EventEmitter {
this.on('control_listen', () => { this.on('control_listen', () => {
this._controller = new TorController(connect(this._control_port), _.extend({ authOnConnect: false }, this.granax_options)); this._controller = new TorController(connect(this._control_port), _.extend({ authOnConnect: false }, this.granax_options));
Promise.promisifyAll(this._controller); Promise.promisifyAll(this._controller);
this.controller.on('ready', () => { this.controller.on('ready', () => {
this.logger.debug(`[tor-${this.instance_name}]: connected to tor control port`); this.logger.debug(`[tor-${this.instance_name}]: connected to tor control port`);
this.controller.authenticate(`"${this.control_password}"`, (err) => { this.controller.authenticate(`"${this.control_password}"`, (err) => {

View file

@ -1,21 +1,16 @@
var nconf = require('nconf'); const fs = require('fs');
var yargs = require('yargs');
var fs = require('fs');
var TorRouter = require('../');
var SOCKSServer = TorRouter.SOCKSServer;
var DNSServer = TorRouter.DNSServer;
var TorPool = TorRouter.TorPool;
var ControlServer = TorRouter.ControlServer;
var winston = require('winston');
var async = require('async');
process.title = 'tor-router'; const nconf = require('nconf');
const yargs = require('yargs');
const winston = require('winston')
const Promise = require('bluebird');
let package_json = JSON.parse(fs.readFileSync(`${__dirname}/../package.json`, 'utf8')); const { ControlServer } = require('./');
function main(nconf, logger) { const package_json = JSON.parse(fs.readFileSync(`${__dirname}/../package.json`, 'utf8'));
async function main(nconf, logger) {
let instances = nconf.get('instances'); let instances = nconf.get('instances');
let log_level = logLevel;
let socks_port = nconf.get('socksPort'); let socks_port = nconf.get('socksPort');
let dns_port = nconf.get('dnsPort'); let dns_port = nconf.get('dnsPort');
let http_port = nconf.get('httpPort'); let http_port = nconf.get('httpPort');
@ -28,124 +23,137 @@ function main(nconf, logger) {
let control = new ControlServer(logger, nconf); let control = new ControlServer(logger, nconf);
process.on('SIGHUP', () => { try {
control.torPool.new_ips();
if (socks_port) {
if (typeof(socks_port) === 'boolean') {
socks_port = 9050;
nconf.set('socksPort', socks_port);
}
control.createSOCKSServer(socks_port);
}
if (http_port) {
if (typeof(http_port) === 'boolean') {
http_port = 9080;
nconf.set('httpPort', http_port);
}
control.createHTTPServer(http_port);
}
if (dns_port) {
if (typeof(dns_port) === 'boolean') {
dns_port = 9053;
nconf.set('dnsPort', dns_port);
}
control.createDNSServer(dns_port);
}
if (instances) {
logger.info(`[tor]: starting ${Array.isArray(instances) ? instances.length : instances} tor instances...`)
await control.torPool.create(instances);
logger.info('[tor]: tor started');
}
await control.listen(control_port);
logger.info(`[control]: control Server listening on ${control_port}`);
} catch (error) {
logger.error(`[global]: error starting application: ${error.stack}`);
process.exit(1);
}
const cleanUp = (async (error) => {
let thereWasAnExitError = false;
let { handleError } = this;
try {
await Promise.all(control.torPool.instances.map((instance) => instance.exit()));
} catch (exitError) {
logger.error(`[global]: error closing tor instances: ${exitError.message}`);
thereWasAnExitError = true;
}
if (handleError && error) {
console.log(error)
logger.error(`[global]: error shutting down: ${error.message}`);
}
process.exit(Number(Boolean(error || thereWasAnExitError)));
}); });
if (socks_port) { process.title = 'tor-router';
if (typeof(socks_port) === 'boolean') {
socks_port = 9050;
nconf.set('socksPort', socks_port);
}
control.createSOCKSServer(socks_port);
}
if (http_port) { process.on('SIGHUP', () => {
if (typeof(http_port) === 'boolean') { control.torPool.new_identites();
http_port = 9080; });
nconf.set('httpPort', http_port);
}
control.createHTTPServer(http_port);
}
if (dns_port) {
if (typeof(dns_port) === 'boolean') {
dns_port = 9053;
nconf.set('dnsPort', dns_port);
}
control.createDNSServer(dns_port);
}
if (instances) {
logger.info(`[tor]: starting ${Array.isArray(instances) ? instances.length : instances} tor instances...`)
control.torPool.create(instances, (err) => {
logger.info('[tor]: tor started');
});
}
control.listen(control_port, () => {
logger.info(`[control]: Control Server listening on ${control_port}`);
})
function cleanUp(error) {
async.each(control.torPool.instances, (instance, next) => {
instance.exit(next);
}, (exitError) => {
if (error) {
console.error(error.stack);
}
if (exitError){
console.error(exitError);
}
process.exit(Number(Boolean(error || exitError)));
});
}
process.on('exit', cleanUp); process.on('exit', cleanUp);
process.on('SIGINT', cleanUp); process.on('SIGINT', cleanUp);
process.on('uncaughtException', cleanUp); process.on('uncaughtException', cleanUp.bind({ handleError: true }));
} }
let argv_config = require('yargs') let argv_config =
.version(package_json.version) yargs
.usage('Usage: tor-router [arguments]') .version(package_json.version)
.options({ .usage('Usage: tor-router [arguments]')
f: { .options({
alias: 'config', f: {
describe: 'Path to a config file to use', alias: 'config',
demand: false describe: 'Path to a config file to use',
}, demand: false
c: { },
alias: 'controlPort', c: {
describe: 'Port the control server will bind to [default: 9077]', alias: 'controlPort',
demand: false describe: 'Port the control server will bind to [default: 9077]',
// ,default: 9077 demand: false
}, // ,default: 9077
j: { },
alias: 'instances', j: {
describe: 'Number of instances using the default config', alias: 'instances',
demand: false describe: 'Number of instances using the default config',
// ,default: 1 demand: false
}, // ,default: 1
s: { },
alias: 'socksPort', s: {
describe: 'Port the SOCKS5 Proxy server will bind to', alias: 'socksPort',
demand: false, describe: 'Port the SOCKS5 Proxy server will bind to',
// ,default: 9050 demand: false,
}, // ,default: 9050
d: { },
alias: 'dnsPort', d: {
describe: 'Port the DNS Proxy server will bind to', alias: 'dnsPort',
demand: false describe: 'Port the DNS Proxy server will bind to',
}, demand: false
h: { },
alias: 'httpPort', h: {
describe: 'Port the HTTP Proxy server will bind to', alias: 'httpPort',
demand: false describe: 'Port the HTTP Proxy server will bind to',
}, demand: false
l: { },
alias: 'logLevel', l: {
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]', alias: 'logLevel',
demand: false 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]',
// ,default: "info" demand: false
}, // ,default: "info"
p: { },
alias: 'parentDataDirectory', p: {
describe: 'Parent directory that will contain the data directories for the instances', alias: 'parentDataDirectory',
demand: false describe: 'Parent directory that will contain the data directories for the instances',
}, demand: false
b: { },
alias: "loadBalanceMethod", b: {
describe: 'Method that will be used to sort the instances between each request. Currently supports "round_robin" and "weighted". [default: round_robin]', alias: "loadBalanceMethod",
demand: false 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", t: {
describe: "Provide the path for the Tor executable that will be used", alias: "torPath",
demand: false describe: "Provide the path for the Tor executable that will be used",
} demand: false
}); }
});
nconf = require(`${__dirname}/../src/nconf_load_env.js`)(nconf); require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
nconf nconf
.argv(argv_config); .argv(argv_config);