'use strict' const socks_client = require('socks').SocksClient const net = require('net') const controlPort = net.connect(9051, "127.0.0.1") controlPort.setEncoding('utf8'); const do_cmd = (cmd, content) => new Promise((resolve, reject) => { const cb = data => { data.includes(content) ? resolve(data) : reject(data) controlPort.removeListener('data', cb) } controlPort.on('data', cb) controlPort.write(cmd+"\n") }) const sock_connect = socks_opt => new Promise((resolve, reject) => socks_client.createConnection(socks_opt, (err, info) => err ? reject(err) : resolve(info))) const get_stream_id = url => new Promise((resolve, reject) => { const cb = data => { const m = data.match(`650 STREAM (\\d+) NEW \\d+ ${url}`) if (m) { controlPort.removeListener('data', cb) resolve(m[1]) } } controlPort.on('data', cb) }) const wait_for_circ = cid => new Promise((resolve, reject) => { const cb = data => { const m = data.match(`650 CIRC ${cid} BUILT`) if (m) { controlPort.removeListener('data', cb) resolve(m[1]) } } controlPort.on('data', cb) }) const do_one_measurement = info => new Promise((resolve, reject) => { const begin = Date.now().toString() const cb = recv_data => { const parsed = recv_data.split("\n") .filter(e => e.includes(begin)) if (parsed.length > 1) { reject("There is an error in the code", parsed) info.socket.removeListener('data', cb) } else if (parsed.length == 1) { resolve(`${begin},${Date.now().toString()}`) info.socket.removeListener('data', cb) } } info.socket.on('data', cb) info.socket.setNoDelay(true) info.socket.setEncoding("utf-8") info.socket.write(begin + "\n") }) const do_measurements = info => new Promise((resolve, reject) => { setInterval(() => { do_one_measurement(info).then(r => console.log(r)) }, 1000) }) const circuitToBuild = process.argv.length > 2 ? process.argv[2] : 'IPredator,UOfMichigan,PrivacyRepublic0001' console.log("Circuit to be built: "+circuitToBuild) // Init do_cmd('authenticate ""', "250 OK") .then(r => do_cmd('setconf __LeaveStreamsUnattached=1', "250 OK")) .then(r => do_cmd('setconf FastFirstHopPK=0', '250 OK')) .then(r => do_cmd('setconf EnforceDistinctSubnets=0', '250 OK')) .then(r => do_cmd('setconf UseEntryGuards=0', '250 OK')) .then(r => do_cmd('setconf AllowSingleHopExits=1', '250 OK')) .then(r => do_cmd('extendcircuit 0 '+circuitToBuild, "250 EXTENDED")) .then(r => r.match(/250 EXTENDED (\d+)/)[1]) .then(cid => Promise.all([cid, do_cmd('setevents CIRC', '250 OK')])) .then(([cid, garb]) => Promise.all([cid, wait_for_circ(cid)])) .then(([cid, garb]) => Promise.all([cid, do_cmd('setevents STREAM', '250 OK')])) .then(([cid, garb]) => Promise.all([ sock_connect({ proxy: {ipaddress: '127.0.0.1', port: 9050, type: 5}, command: 'connect', destination: { host: `lupine.machine.deuxfleurs.fr`, port: 1337 } }), get_stream_id("lupine.machine.deuxfleurs.fr:1337") .then(sid => Promise.all([cid, sid, do_cmd(`attachstream ${sid} ${cid}`, "250 OK")])) ])) .then(([sock, ids]) => Promise.all([sock, ids, do_cmd('setevents', '250 OK')])) .then(([sock, ids, garb]) => Promise.all([sock, ids, do_measurements(sock)])) .then(([sock, ids, res]) => console.log(res)) .catch(err => console.error("AN ERROR OCCURED", err))