2017-01-31 23:11:36 +00:00
|
|
|
const socks = require('socksv5');
|
|
|
|
const SOCKS5Server = socks.Server;
|
2017-02-26 21:07:47 +00:00
|
|
|
const domain = require('domain');
|
2017-01-31 23:11:36 +00:00
|
|
|
|
|
|
|
class SOCKSServer extends SOCKS5Server{
|
2018-05-10 01:15:58 +00:00
|
|
|
constructor(tor_pool, logger, nconf) {
|
2017-02-26 21:07:47 +00:00
|
|
|
let handleConnection = (info, accept, deny) => {
|
|
|
|
let d = domain.create();
|
|
|
|
|
2017-01-31 23:11:36 +00:00
|
|
|
let inbound_socket = accept(true);
|
2017-02-26 21:07:47 +00:00
|
|
|
d.add(inbound_socket);
|
2017-01-31 23:11:36 +00:00
|
|
|
var outbound_socket;
|
|
|
|
let buffer = [];
|
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
let onInboundData = (data) => buffer.push(data)
|
|
|
|
|
|
|
|
let onClose = (error) => {
|
|
|
|
inbound_socket && inbound_socket.end();
|
|
|
|
outbound_socket && outbound_socket.end();
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
inbound_socket = outbound_socket = buffer = void(0);
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
if (error)
|
|
|
|
this.logger.error(`[socks]: an error occured: ${error.message}`)
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
d.exit();
|
|
|
|
};
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
if (!inbound_socket) return;
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
inbound_socket.on('close', onClose);
|
|
|
|
inbound_socket.on('data', onInboundData);
|
|
|
|
inbound_socket.on('error', onClose);
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
let connect = (tor_instance) => {
|
|
|
|
let socks_port = tor_instance.socks_port;
|
2018-05-10 04:09:38 +00:00
|
|
|
logger && logger.verbose(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${info.dstAddr}:${info.dstPort}`)
|
2017-03-26 01:02:56 +00:00
|
|
|
|
2017-03-26 01:14:46 +00:00
|
|
|
d.on('error', onClose);
|
2017-03-26 01:02:56 +00:00
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
2017-01-31 23:11:36 +00:00
|
|
|
};
|
2017-03-26 01:02:56 +00:00
|
|
|
if (tor_pool.instances.length) {
|
|
|
|
connect(tor_pool.next());
|
|
|
|
} else {
|
|
|
|
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);
|
|
|
|
}
|
2017-02-26 21:07:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
super(handleConnection);
|
2017-01-31 23:11:36 +00:00
|
|
|
|
|
|
|
this.logger = logger;
|
2018-05-10 01:15:58 +00:00
|
|
|
this.nconf = nconf;
|
2017-01-31 23:11:36 +00:00
|
|
|
|
|
|
|
this.useAuth(socks.auth.None());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = SOCKSServer;
|