waits for a tor instance to come online before making a connection

This commit is contained in:
Zachary Boyd 2017-03-25 21:02:56 -04:00
parent fd1c08ff16
commit 7d0aba7d60
4 changed files with 90 additions and 70 deletions

View file

@ -9,33 +9,42 @@ class DNSServer extends UDPServer {
this.on('request', (req, res) => { this.on('request', (req, res) => {
for (let question of req.question) { for (let question of req.question) {
let dns_port = (tor_pool.next().dns_port); let connect = (tor_instance) => {
let dns_port = (tor_instance.dns_port);
let outbound_req = dns.Request({ let outbound_req = dns.Request({
question, question,
server: { address: '127.0.0.1', port: dns_port, type: 'udp' }, server: { address: '127.0.0.1', port: dns_port, type: 'udp' },
timeout: this.timeout timeout: this.timeout
}); });
outbound_req.on('message', (err, answer) => { outbound_req.on('message', (err, answer) => {
if (!err && answer) { if (!err && answer) {
for (let a of answer.answer){ for (let a of answer.answer){
res.answer.push(a); res.answer.push(a);
this.logger && this.logger.info(`[dns]: ${question.name} type ${dns.consts.QTYPE_TO_NAME[question.type]} → 127.0.0.1:${dns_port}${a.address}`) this.logger && this.logger.info(`[dns]: ${question.name} type ${dns.consts.QTYPE_TO_NAME[question.type]} → 127.0.0.1:${dns_port}${a.address}`)
}
} }
} });
});
outbound_req.on('error', (err) => { outbound_req.on('error', (err) => {
}); });
outbound_req.on('end', () => { outbound_req.on('end', () => {
res.send(); res.send();
}); });
outbound_req.send(); outbound_req.send();
};
if (this.tor_pool.instances.length) {
connect(this.tor_pool.next());
}
else {
this.log.debug(`[dns]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
this.tor_pool.once('instance_created', connect);
}
} }
}); });
} }

View file

@ -12,60 +12,68 @@ class SOCKSServer extends SOCKS5Server{
var outbound_socket; var outbound_socket;
let buffer = []; let buffer = [];
let socks_port = (tor_pool.next().socks_port); let connect = (tor_instance) => {
logger && logger.info(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${info.dstAddr}:${info.dstPort}`) let socks_port = tor_instance.socks_port;
logger && logger.info(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${info.dstAddr}:${info.dstPort}`)
let onClose = (error) => { let onClose = (error) => {
inbound_socket && inbound_socket.end(); inbound_socket && inbound_socket.end();
outbound_socket && outbound_socket.end(); outbound_socket && outbound_socket.end();
inbound_socket = outbound_socket = buffer = void(0); inbound_socket = outbound_socket = buffer = void(0);
if (error) if (error)
this.logger.error(`[socks]: an error occured: ${error.message}`) this.logger.error(`[socks]: an error occured: ${error.message}`)
d.exit(); d.exit();
};
d.on('error', onClose);
let onInboundData = (data) => buffer.push(data)
if (!inbound_socket) return;
inbound_socket.on('close', onClose);
inbound_socket.on('data', onInboundData);
inbound_socket.on('error', onClose);
d.run(() => {
socks.connect({
host: info.dstAddr,
port: info.dstPort,
proxyHost: '127.0.0.1',
proxyPort: socks_port,
localDNS: false,
auths: [ socks.auth.None() ]
}, ($outbound_socket) => {
outbound_socket = $outbound_socket;
d.add(outbound_socket);
outbound_socket && outbound_socket.on('close', onClose);
inbound_socket && inbound_socket.removeListener('data', onInboundData);
inbound_socket && inbound_socket.on('data', (data) => {
outbound_socket && outbound_socket.write(data);
});
outbound_socket && outbound_socket.on('data', (data) => {
inbound_socket && inbound_socket.write(data);
});
outbound_socket && outbound_socket.on('error', onClose);
while (buffer && buffer.length && outbound_socket) {
outbound_socket.write(buffer.shift());
}
})
});
}; };
if (tor_pool.instances.length) {
d.on('error', onClose); connect(tor_pool.next());
} else {
let onInboundData = (data) => buffer.push(data) logger.debug(`[socks]: a connection has been attempted, but no tor instances are live... waiting for an instance to come online`);
tor_pool.once('instance_created', connect);
if (!inbound_socket) return; }
inbound_socket.on('close', onClose);
inbound_socket.on('data', onInboundData);
inbound_socket.on('error', onClose);
d.run(() => {
socks.connect({
host: info.dstAddr,
port: info.dstPort,
proxyHost: '127.0.0.1',
proxyPort: socks_port,
localDNS: false,
auths: [ socks.auth.None() ]
}, ($outbound_socket) => {
outbound_socket = $outbound_socket;
d.add(outbound_socket);
outbound_socket && outbound_socket.on('close', onClose);
inbound_socket && inbound_socket.removeListener('data', onInboundData);
inbound_socket && inbound_socket.on('data', (data) => {
outbound_socket && outbound_socket.write(data);
});
outbound_socket && outbound_socket.on('data', (data) => {
inbound_socket && inbound_socket.write(data);
});
outbound_socket && outbound_socket.on('error', onClose);
while (buffer && buffer.length && outbound_socket) {
outbound_socket.write(buffer.shift());
}
})
});
}; };
super(handleConnection); super(handleConnection);

View file

@ -37,7 +37,7 @@ class TorPool extends EventEmitter {
this.logger = logger; this.logger = logger;
} }
get instances() { return this._instances.slice(0); } get instances() { return this._instances.filter((tor) => tor.ready).slice(0); }
create_instance(callback) { create_instance(callback) {
let config = _.extend({}, this.tor_config) let config = _.extend({}, this.tor_config)
@ -48,6 +48,7 @@ class TorPool extends EventEmitter {
instance.once('error', callback) instance.once('error', callback)
instance.once('ready', () => { instance.once('ready', () => {
this.emit('instance_created', instance);
callback && callback(null, instance); callback && callback(null, instance);
}); });
}); });

View file

@ -31,6 +31,7 @@ class TorProcess extends EventEmitter {
} }
new_ip() { new_ip() {
this.log.info(`[tor-${this.process.pid}]: has requested a new identity`);
this.process.kill('SIGHUP'); this.process.kill('SIGHUP');
} }
@ -82,6 +83,7 @@ class TorProcess extends EventEmitter {
}); });
this.once('ready', () => { this.once('ready', () => {
this.ready = true;
this.logger && this.logger.info(`[tor-${tor.pid}]: tor is ready`); this.logger && this.logger.info(`[tor-${tor.pid}]: tor is ready`);
}); });