Adds "queryInstanceByName" and "queryInstanceAt"

This commit is contained in:
Zachary Boyd 2018-08-10 13:06:40 -04:00
parent 58d3d1da17
commit 7d996ffa81
6 changed files with 111 additions and 51 deletions

View file

@ -1,5 +1,11 @@
# Changelog
## [3.4.3] - 2018-08-10
### Added
- Adds a changelog
- Adds `queryInstanceByName` and `queryInstanceAt` RPC methods to retrieve individual instances
## [3.4.2] - 2018-08-09
### Added
@ -30,7 +36,7 @@
## [3.3.0] - 2018-05-10
### Added
- Adds documentation on all RPC Methods available
- Adds documentation on all available RPC Methods
- Allows different load-balance methods to be defined, and changed at runtime and via RPC
- Each instance can have started with a specific configuration (torrc) by setting the `Config` property in the definition

View file

@ -4,6 +4,8 @@
Tor Router also includes a DNS proxy server and a HTTP proxy as well, which like the SOCKS proxy will distribute traffic across multiple instances of Tor in round-robin fashion. The HTTP proxy server can be used to access Tor via an HTTP Proxy.
A list of changes can be [found here](https://github.com/znetstar/tor-router/blob/master/CHANGELOG.md)
## Building and Running
The only installation requirement is node.js. Tor is bundled with the application. To use an external Tor executable use the `--torPath` command line switch or set the `TOR_PATH` environment variable.
@ -37,6 +39,10 @@ The following command line switches and their environment variable equivalents a
For example: `tor-router -j 3 -s 9050` would start the proxy with 3 tor instances and listen for SOCKS connections on 9050.
## Testing
Tests are written in mocha and can be found under `test/test.js` and can be run with `npm test`
## Configuration
Using the `--config` or `-f` command line switch you can set the path to a JSON file which can be used to load configuration on startup
@ -147,8 +153,4 @@ let rpcRequest = {
"id": 1
};
client.write(JSON.stringify(rpcRequest));
```
## Test
Tests are written in mocha, just run `npm test`
```

View file

@ -1,14 +1,22 @@
## RPC Functions
# RPC Functions
The following functions are available via the RPC
# queryInstances()
## queryInstances()
Returns an array containing information on the instances currently running under the router.
# createInstances(Array or Integrer)
## queryInstanceByName(String)
If passed an integrer, creates thats many Tor instances. An array can also be passed describing the names, weights and configurations of prospective instances. :
Returns information on an instance identified by name
## queryInstanceAt(Integer)
Returns information on an instance identified by index
## createInstances(Array or Integer)
If passed an Integer, creates thats many Tor instances. An array can also be passed describing the names, weights and configurations of prospective instances. :
```
var rpcRequest = {
@ -30,63 +38,63 @@ var rpcRequest = {
Will wait until the Tor Instance has fully connected to the network before returning
# addInstances(Array)
## addInstances(Array)
Serves the same purpose as "createInstances" but only takes an Array
# removeInstances(Integrer)
## removeInstances(Integer)
Removes a number of instances
# removeInstanceAt(Integrer)
## removeInstanceAt(Integer)
Remove a specific instance from the pool by its index
# removeInstanceByName(String)
## removeInstanceByName(String)
Remove a specific instance from the pool by its name
# newIdentites()
## newIdentites()
Get new identites for all instances
# newIdentityAt(Integrer)
## newIdentityAt(Integer)
Get a new identity for a specific instance by its index
# newIdentityByName(String)
## newIdentityByName(String)
Get a new identity for a specific instance by its name
# nextInstance()
## nextInstance()
Cycle to the next instance using the load balancing method
# closeInstances()
## closeInstances()
Shutdown all Tor instances
# setTorConfig(Object)
## setTorConfig(Object)
Applies the configuration to all active instances
# getDefaultTorConfig()
## getDefaultTorConfig()
Retrieve the default Tor Config for all future instances
# setDefaultTorConfig(Object)
## setDefaultTorConfig(Object)
Set the default Tor Config for all future instances
# getLoadBalanceMethod()
## getLoadBalanceMethod()
Get the current load balance method
# setLoadBalanceMethod(String)
## setLoadBalanceMethod(String)
Set the current load balance method
# getInstanceConfigAt(Integrer: index, String: keyword)
## getInstanceConfigAt(Integer: index, String: keyword)
Retrieves the current value of an option set in the configuration by the index of the instance using the control protocol.
@ -103,28 +111,28 @@ var rpcRequest = {
};
```
# getInstanceConfigByName(String: name, String: keyword)
## getInstanceConfigByName(String: name, String: keyword)
Works the same way as `getInstanceConfigAt` except takes an instance name instead of an index
# setInstanceConfigAt(Integrer: index, String: keyword, String: value)
## setInstanceConfigAt(Integer: index, String: keyword, String: value)
Sets the value in the configuration of an instance using the control protocol. Changes will be applied immediately.
# setInstanceConfigByName(Integrer: index, String: keyword, String: value)
## setInstanceConfigByName(Integer: index, String: keyword, String: value)
Works the same way as `setInstanceConfigAt` except takes an instance name instead of an index
# signalAllInstances(String)
## signalAllInstances(String)
Sends a signal using the control protocol to all instances
A list of all signals can be [found here](https://gitweb.torproject.org/torspec.git/tree/control-spec.txt)
# signalInstanceAt(Integrer: index, String: signal)
## signalInstanceAt(Integer: index, String: signal)
Sends a signal using the control protocol to an instance identified by its index
# signalInstanceByName(String: name, String: signal)
## signalInstanceByName(String: name, String: signal)
Sends a signal using the control protocol to an instance identified by its name

View file

@ -1,6 +1,6 @@
{
"name": "tor-router",
"version": "3.4.2",
"version": "3.4.3",
"main": "src/index.js",
"repository": "git@github.com:znetstar/tor-router.git",
"author": "Zachary Boyd <zachary@zacharyboyd.nyc>",

View file

@ -17,14 +17,44 @@ class ControlServer {
server.expose('createDNSServer', this.createDNSServer.bind(this));
server.expose('createHTTPServer', this.createHTTPServer.bind(this));
// queryInstanceAt, queryInstanceByName
const instance_info = (i) => {
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 () {
return new Promise((resolve, reject) => {
if (!this.torPool)
return reject({ message: 'No pool created' });
resolve(this.torPool.instances.map((i) => ( { 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 } )) );
resolve(this.torPool.instances.map(instance_info) );
});
}).bind(this));
server.expose('queryInstanceByName', (function (instance_name) {
return new Promise((resolve, reject) => {
if (!this.torPool)
return reject({ message: 'No pool created' });
let i = this.torPool.instance_by_name(instance_name);
if (!i)
return reject({ message: `Instance "${instance_name}"" does not exist` });
resolve(instance_info(i));
});
}).bind(this));
server.expose('queryInstanceAt', (function (index) {
return new Promise((resolve, reject) => {
if (!this.torPool)
return reject({ message: 'No pool created' });
let i = this.torPool.instance_at(index);
if (!i)
return reject({ message: `Instance at "${i}"" does not exist` });
resolve(instance_info(this.torPool.instance_at(index)));
});
}).bind(this));

View file

@ -23,7 +23,7 @@ var logger = winston.createLogger({
});
const WAIT_FOR_CREATE = 120000;
const PAGE_LOAD_TIME = 30000;
const PAGE_LOAD_TIME = 60000;
describe('TorProcess', function () {
var tor = new (TorRouter.TorProcess)(nconf.get('torPath'), { DataDirectory: nconf.get('parentDataDirectory'), ProtocolWarnings: 0 }, null, logger);
@ -281,20 +281,6 @@ describe('TorPool', function () {
});
describe('#new_ips(index)', function () {
this.timeout(5000);
it('should signal to retrieve a new identity to all instances', function (done) {
torPool.new_ips(done);
});
});
describe('#new_ip_at(instance_name)', function () {
this.timeout(5000);
it('should signal to retrieve a new identity identified by index', function (done) {
torPool.new_ip_at(0, done);
});
});
describe('#set_config_all(keyword, value)', function () {
it('should set configuration on all active instances', function (done) {
this.timeout(5000);
@ -457,7 +443,7 @@ describe('HTTPServer', function () {
req.on('response', function (res) {
done();
})
});
});
});
@ -476,7 +462,7 @@ describe('HTTPServer', function () {
req.on('response', function (res) {
done();
})
});
});
});
@ -652,6 +638,34 @@ describe('ControlServer - RPC', function () {
});
});
describe('#queryInstanceByName(instance_name)', function () {
this.timeout(3000);
it('should return a single instance', function (done) {
rpcClient.invoke('queryInstanceByName', ['instance-1'], function (error, raw) {
if (error)
return done(error);
var instance = JSON.parse(raw).result;
done(null, (typeof(instance.name) !== undefined) && (instance.name !== null));
});
});
});
describe('#queryInstanceAt(index)', function () {
this.timeout(3000);
it('should return a single instance', function (done) {
rpcClient.invoke('queryInstanceAt', [0], function (error, raw) {
if (error)
return done(error);
var instance = JSON.parse(raw).result;
done(null, (typeof(instance.name) !== undefined) && (instance.name !== null));
});
});
});
describe('#newIdentites()', function () {
this.timeout(3000);
it('should request new identities for all instances', function (done) {