diff --git a/.env b/.env new file mode 100644 index 0000000..016c2bc --- /dev/null +++ b/.env @@ -0,0 +1 @@ +INSTANCES=1 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7a6ab56..a532aa3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,14 @@ EXPOSE 9050 EXPOSE 53 +EXPOSE 9077 + ENV DNS_PORT 53 ENV SOCKS_PORT 9050 +ENV CONTROL_PORT 9077 + ENV INSTANCES 3 ENV PATH $PATH:/app/bin diff --git a/bin/tor-router b/bin/tor-router index 889974e..72c4dba 100755 --- a/bin/tor-router +++ b/bin/tor-router @@ -5,12 +5,14 @@ var TorRouter = require('../'); var SOCKSServer = TorRouter.SOCKSServer; var DNSServer = TorRouter.DNSServer; var TorPool = TorRouter.TorPool; +var ControlServer = TorRouter.ControlServer; var winston = require('winston') process.title = 'tor-router'; program .version('0.0.1') + .option('-c, --controlPort [9077]', 'Control Server port', Number) .option('-j, --instances <1>', 'Number of tor instances', Number) .option('-s, --socksPort [9050]', 'SOCKS Server port', Number) .option('-d, --dnsPort [9053]', 'DNS Server port', Number) @@ -27,30 +29,30 @@ let instances = program.instances || Number(process.env.INSTANCES); let log_level = program.logLevel || process.env.LOG_LEVEL; let socks_port = (program.socksPort === true ? 9050 : program.socksPort) || Number(process.env.SOCKS_PORT); let dns_port = (program.dnsPort === true ? 9053 : program.dnsPort) || Number(process.env.DNS_PORT); - -if (!instances) { - logger.error('Number of instances not specified'); - process.exit(1); -} +let control_port = (program.controlPort === true ? 9077 : program.controlPort) || Number(process.env.CONTROL_PORT) || 9077; let pool = new TorPool('tor', null, logger); if (log_level === 'null') logger = void(0); +let control = new ControlServer(logger); + if (socks_port) { - let socks = new SOCKSServer(pool, logger); - logger && logger.info(`[socks]: Listening on ${socks_port}`); - socks.listen((socks_port)); + let socks = control.createSOCKSServer(socks_port); } if (dns_port) { - let dns = new DNSServer(pool, logger); - logger && logger.info(`[dns]: Listening on ${dns_port}`); - dns.serve((dns_port)); + let dns = control.createDNSServer(dns_port); } -logger && logger.info('[tor]: starting tor...') -pool.create(instances, (err) => { - logger && logger.info('[tor]: tor started'); -}); \ No newline at end of file +if (instances) { + logger && logger.info('[tor]: starting ${instances} tor instances...') + pool.create(instances, (err) => { + logger && logger.info('[tor]: tor started'); + }); +} + +control.server.listen(control_port, () => { + logger && logger.info(`[control]: Control Server listening on ${control_port}`); +}) \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 7b03e4d..af9f656 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,4 +5,5 @@ services: build: . ports: - "9050:9050" - - "53:53/udp" \ No newline at end of file + - "53:53/udp" + - "9077:9077" \ No newline at end of file diff --git a/package.json b/package.json index 6d70f82..4f756b6 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "devDependencies": { "mocha": "^3.2.0", "request": "^2.79.0", + "socket.io-client": "^1.7.3", "socks5-http-client": "^1.0.2" }, "dependencies": { @@ -24,6 +25,7 @@ "get-port": "^2.1.0", "lodash": "^4.17.4", "native-dns": "https://github.com/znetstar/node-dns.git", + "socket.io": "^1.7.3", "socksv5": "git+https://github.com/lee-elenbaas/socksv5.git", "temp": "^0.8.3", "winston": "^2.3.1" diff --git a/src/ControlServer.js b/src/ControlServer.js new file mode 100644 index 0000000..acb884c --- /dev/null +++ b/src/ControlServer.js @@ -0,0 +1,53 @@ +const HTTPServer = require('http').Server; +const TorPool = require('./TorPool'); +const SOCKSServer = require('./SOCKSServer'); +const DNSServer = require('./DNSServer'); + +class ControlServer { + constructor(logger) { + this.server = new HTTPServer(); + this.io = require('socket.io')(this.server); + + this.torPool = new TorPool(null, null, logger); + this.logger = logger; + + this.io.use(this.handleConnection.bind(this)); + } + + listen() { this.server.listen.apply(this.server, arguments); } + close() { this.server.close.apply(this.server, arguments); } + + handleConnection(socket, next) { + socket.on('createTorPool', this.createTorPool.bind(this)); + socket.on('createSOCKSServer', this.createSOCKSServer.bind(this)); + socket.on('createDNSServer', this.createDNSServer.bind(this)); + + socket.on('createInstances', (instances, callback) => { this.torPool.create(instances, callback); }); + socket.on('newIps', () => { this.torPool.new_ips(); }); + socket.on('nextInstance', () => { this.torPool.next(); }); + socket.on('closeInstances', () => { this.torPool.exit(); }); + + next(); + } + + createTorPool(options) { + this.torPool = new TorPool(null, options, this.logger); + return this.torPool; + } + + createSOCKSServer(port) { + this.socksServer = new SOCKSServer(this.torPool, this.logger); + this.socksServer.listen(port || 9050); + this.logger && this.logger.info(`[socks]: Listening on ${port}`); + return this.socksServer; + } + + createDNSServer(port) { + this.dnsServer = new DNSServer(this.torPool, this.logger); + this.dnsServer.serve(port || 9053); + this.logger && this.logger.info(`[dns]: Listening on ${port}`); + return this.dnsServer; + } +}; + +module.exports = ControlServer; diff --git a/src/index.js b/src/index.js index df2b590..71288ce 100644 --- a/src/index.js +++ b/src/index.js @@ -2,5 +2,6 @@ module.exports = { TorProcess: require('./TorProcess'), TorPool: require('./TorPool'), DNSServer: require('./DNSServer'), - SOCKSServer: require('./SOCKSServer') + SOCKSServer: require('./SOCKSServer'), + ControlServer: require('./ControlServer') }; \ No newline at end of file diff --git a/test/test.js b/test/test.js index 4c8cb68..d388c26 100644 --- a/test/test.js +++ b/test/test.js @@ -6,6 +6,7 @@ temp.track(); const TorRouter = require('../'); const getPort = require('get-port'); const dns = require('native-dns'); +const io = require('socket.io-client'); const get_ip = function (callback) { request({ @@ -25,6 +26,74 @@ const get_ip = function (callback) { }; +describe('ControlServer', function () { + let ports = {}; + var controlServer; + var client; + + before((done) => { + async.autoInject({ + dnsPort: (cb) => { getPort().then((port) => { cb(null, port); }) }, + socksPort: (cb) => { getPort().then((port) => { cb(null, port); }) }, + controlPort: (cb) => { getPort().then((port) => { cb(null, port); }) } + }, (error, context) => { + ports = context; + + + done(error); + }); + }); + + controlServer = new ControlServer(); + + describe('#listen(port, callback)', () => { + it('should listen on the control port', (done) => { controlServer.listen(ports.controlPort, done); }) + it('should connect to control server', (done) => { + client = io.connect(`ws://127.0.0.1:${ports.controlPort}`); + client.once('connect_error', (err) => { + done(err); + }); + + client.once('connected', () => { + done(); + }) + }); + }); + + describe('#createTorPool(options)', function () { + it('should create a tor pool', () => { + client.emit('createTorPool', {}); + }); + }); + + describe('#createSOCKSServer(port)', function () { + it('should create a socks server', () => { + client.emit('createSOCKSServer', ports.socksPort); + }); + }); + + describe('#createInstances(instances, callback)', function () { + it('should create 1 instance', function (done) { + client.emit('createInstances', 1, (err) => { + if (err) return done(error); + + done(((controlServer.torPool.instances.length !== 1) && new Error(`It doesn't have 1 instance`))); + }); + }) + }) + + describe('#newIps()', function (done) { + done(); + }); + + after(() => { + controlServer.torPool.exit(); + client.close(); + controlServer.close(); + }); +}); + + describe('TorProcess', function () { const TOR_DATA_DIR = temp.mkdirSync(); const TorProcess = TorRouter.TorProcess; @@ -204,3 +273,4 @@ describe('SOCKSServer', function () { }); }); }); + diff --git a/x.js b/x.js new file mode 100644 index 0000000..5064e87 --- /dev/null +++ b/x.js @@ -0,0 +1,8 @@ +const shell = require('shelljs'); +const fs = require('fs'); +const DIR = '/tmp/x'; +shell.find(DIR) + .filter((path) => fs.lstatSync(path).isFile()) + .forEach((file) => { + + }); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 923e2be..2e806f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,17 @@ # yarn lockfile v1 +accepts@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -10,6 +21,10 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +arraybuffer.slice@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -48,16 +63,38 @@ aws4@^1.2.1: version "1.5.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + balanced-match@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + bcrypt-pbkdf@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4" dependencies: tweetnacl "^0.14.3" +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + dependencies: + callsite "1.0.0" + +blob@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" + boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" @@ -81,6 +118,10 @@ browser-stdout@1.3.0: dependencies: verror "^1.4.0" +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" @@ -136,10 +177,30 @@ commander@2.9.0, commander@^2.9.0: dependencies: graceful-readlink ">= 1.0.0" +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + +component-emitter@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -166,6 +227,12 @@ debug@2.2.0: dependencies: ms "0.7.1" +debug@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" + dependencies: + ms "0.7.2" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -180,6 +247,45 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +engine.io-client@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.3.tgz#1798ed93451246453d4c6f635d7a201fe940d5ab" + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "2.3.3" + engine.io-parser "1.3.2" + has-cors "1.1.0" + indexof "0.0.1" + parsejson "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + ws "1.1.2" + xmlhttprequest-ssl "1.5.3" + yeast "0.1.2" + +engine.io-parser@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a" + dependencies: + after "0.8.2" + arraybuffer.slice "0.0.6" + base64-arraybuffer "0.1.5" + blob "0.0.4" + has-binary "0.1.7" + wtf-8 "1.0.0" + +engine.io@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4" + dependencies: + accepts "1.3.3" + base64id "1.0.0" + cookie "0.3.1" + debug "2.3.3" + engine.io-parser "1.3.2" + ws "1.1.2" + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -287,6 +393,16 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-binary@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" + dependencies: + isarray "0.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -316,6 +432,10 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -367,6 +487,10 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -586,7 +710,7 @@ mime-db@~1.26.0: version "1.26.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" -mime-types@^2.1.12, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.7: version "2.1.14" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" dependencies: @@ -635,6 +759,10 @@ ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + "native-dns-cache@https://github.com/znetstar/native-dns-cache.git": version "0.0.2" resolved "https://github.com/znetstar/native-dns-cache.git#7743c19bd1b70d0ec32a364aadc77fbcfd5a67ad" @@ -657,20 +785,54 @@ ms@0.7.1: native-dns-cache "https://github.com/znetstar/native-dns-cache.git" native-dns-packet "~0.1.1" +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +object-assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + os-tmpdir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +parsejson@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" + dependencies: + better-assert "~1.0.0" + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + dependencies: + better-assert "~1.0.0" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -736,6 +898,50 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +socket.io-adapter@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b" + dependencies: + debug "2.3.3" + socket.io-parser "2.3.1" + +socket.io-client@1.7.3, socket.io-client@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377" + dependencies: + backo2 "1.0.2" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "2.3.3" + engine.io-client "1.8.3" + has-binary "0.1.7" + indexof "0.0.1" + object-component "0.0.3" + parseuri "0.0.5" + socket.io-parser "2.3.1" + to-array "0.1.4" + +socket.io-parser@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" + dependencies: + component-emitter "1.1.2" + debug "2.2.0" + isarray "0.0.1" + json3 "3.3.2" + +socket.io@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b" + dependencies: + debug "2.3.3" + engine.io "1.8.3" + has-binary "0.1.7" + object-assign "4.1.0" + socket.io-adapter "0.5.0" + socket.io-client "1.7.3" + socket.io-parser "2.3.1" + socks5-client@~1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/socks5-client/-/socks5-client-1.1.2.tgz#0878eeef0654102cf4239b13b5e68c214311c6b8" @@ -804,6 +1010,10 @@ temp@^0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" @@ -818,6 +1028,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + uuid@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" @@ -863,6 +1077,25 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" +ws@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f" + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +wtf-8@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" + +xmlhttprequest-ssl@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" + xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"