lib: update

This commit is contained in:
Micooz 2017-08-02 17:54:40 +08:00
parent 0c35190a85
commit b9dedf0144
8 changed files with 8 additions and 5 deletions

File diff suppressed because one or more lines are too long

@ -1 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});exports.DNSCache=exports.DNS_SURVIVAL_TIME=undefined;var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i['return'])_i['return']()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError('Invalid attempt to destructure non-iterable instance')}}}();var _dns=require('dns');var _dns2=_interopRequireDefault(_dns);var _net=require('net');var _net2=_interopRequireDefault(_net);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step('next',value)},function(err){step('throw',err)})}}return step('next')})}}const DNS_SURVIVAL_TIME=exports.DNS_SURVIVAL_TIME=3600000;class DNSCache{constructor(){this._pool={}}static create(){return new DNSCache}_now(){return new Date().getTime()}_lookup(hostname){return new Promise((resolve,reject)=>{_dns2.default.lookup(hostname,function(err,address){if(err){reject(err)}else{resolve(address)}})})}_put(hostname,address){const expire=this._now()+DNS_SURVIVAL_TIME;this._pool[hostname]=[address,expire]}get(hostname){var _this=this;return _asyncToGenerator(function*(){if(_net2.default.isIP(hostname)){return hostname}let address=null;if(typeof _this._pool[hostname]==='undefined'){address=yield _this._lookup(hostname);_this._put(hostname,address)}else{var _pool$hostname=_slicedToArray(_this._pool[hostname],2);const addr=_pool$hostname[0],expire=_pool$hostname[1];if(_this._now()>=expire){delete _this._pool[hostname]}address=addr}return address})()}}exports.DNSCache=DNSCache;
'use strict';Object.defineProperty(exports,'__esModule',{value:true});exports.DNSCache=exports.DNS_DEFAULT_EXPIRE=undefined;var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i['return'])_i['return']()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError('Invalid attempt to destructure non-iterable instance')}}}();var _dns=require('dns');var _dns2=_interopRequireDefault(_dns);var _net=require('net');var _net2=_interopRequireDefault(_net);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step('next',value)},function(err){step('throw',err)})}}return step('next')})}}const DNS_DEFAULT_EXPIRE=exports.DNS_DEFAULT_EXPIRE=3600000;class DNSCache{constructor({expire}={}){this._pool={};this._expire=DNS_DEFAULT_EXPIRE;if(expire!==undefined){this._expire=expire}}_now(){return new Date().getTime()}_lookup(hostname){return new Promise((resolve,reject)=>{_dns2.default.lookup(hostname,function(err,address){if(err){reject(err)}else{resolve(address)}})})}_put(hostname,address){if(this._expire>0){const expire=this._now()+this._expire;this._pool[hostname]=[address,expire]}}get(hostname){var _this=this;return _asyncToGenerator(function*(){if(_net2.default.isIP(hostname)){return hostname}let address=null;if(typeof _this._pool[hostname]==='undefined'){address=yield _this._lookup(hostname);_this._put(hostname,address)}else{var _pool$hostname=_slicedToArray(_this._pool[hostname],2);const addr=_pool$hostname[0],expire=_pool$hostname[1];if(_this._now()>=expire){delete _this._pool[hostname]}address=addr}return address})()}}exports.DNSCache=DNSCache;

@ -1 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});exports.Hub=undefined;var _net=require('net');var _net2=_interopRequireDefault(_net);var _logger=require('./logger');var _logger2=_interopRequireDefault(_logger);var _config=require('./config');var _socket=require('./socket');var _profile=require('./profile');var _balancer=require('./balancer');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const nextId=function(){let i=0;return()=>{if(i>Number.MAX_SAFE_INTEGER-1){i=0}return++i}}();class Hub{constructor(config){this._hub=null;this._sockets=[];this._isClosed=false;if(typeof config!=='undefined'){_config.Config.init(config)}_logger2.default.level=__LOG_LEVEL__;this._hub=_net2.default.createServer();this._hub.on('close',this.onClose.bind(this));this._hub.on('connection',this.onConnect.bind(this));this.onSocketClose=this.onSocketClose.bind(this)}onClose(){if(!this._isClosed){_logger2.default.info('==> [hub] shutdown');if(__IS_CLIENT__){_balancer.Balancer.destroy();_logger2.default.info('==> [balancer] stopped')}if(__PROFILE__){_logger2.default.info('==> [profile] saving...');_profile.Profile.save();_profile.Profile.stop();_logger2.default.info('==> [profile] stopped')}this._isClosed=true;this._sockets.forEach(socket=>socket.destroy());this._sockets=[]}}onSocketClose(socket){this._sockets=this._sockets.filter(({id})=>id!==socket.id);_profile.Profile.connections=this._sockets.length}onConnect(socket){const id=nextId();const instance=new _socket.Socket({id,socket,onClose:this.onSocketClose});this._sockets.push(instance);_logger2.default.info(`[hub] [${socket.remoteAddress}:${socket.remotePort}] connected`);_profile.Profile.connections+=1}run(callback){const options={host:__LOCAL_HOST__,port:__LOCAL_PORT__};this._hub.listen(options,()=>{_logger2.default.info(`==> [hub] use configuration: ${JSON.stringify(__ALL_CONFIG__)}`);_logger2.default.info(`==> [hub] running as: ${__IS_SERVER__?'Server':'Client'}`);_logger2.default.info(`==> [hub] listening on: ${JSON.stringify(this._hub.address())}`);if(__IS_CLIENT__){_logger2.default.info('==> [balancer] started');_balancer.Balancer.start(__SERVERS__)}if(__PROFILE__){_logger2.default.info('==> [profile] started');_profile.Profile.start()}if(typeof callback==='function'){callback()}})}terminate(){this._hub.close();this.onClose()}}exports.Hub=Hub;
'use strict';Object.defineProperty(exports,'__esModule',{value:true});exports.Hub=undefined;var _events=require('events');var _events2=_interopRequireDefault(_events);var _net=require('net');var _net2=_interopRequireDefault(_net);var _logger=require('./logger');var _logger2=_interopRequireDefault(_logger);var _config=require('./config');var _socket=require('./socket');var _profile=require('./profile');var _balancer=require('./balancer');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const nextId=function(){let i=0;return()=>{if(i>Number.MAX_SAFE_INTEGER-1){i=0}return++i}}();class Hub extends _events2.default{constructor(config){super();this._hub=null;this._sockets=[];this._isClosed=false;if(typeof config!=='undefined'){_config.Config.init(config)}_logger2.default.level=__LOG_LEVEL__;this._hub=_net2.default.createServer();this._hub.on('close',this.onClose.bind(this));this._hub.on('connection',this.onConnect.bind(this));this.onSocketClose=this.onSocketClose.bind(this)}onClose(){if(!this._isClosed){_logger2.default.info('==> [hub] shutdown');if(__IS_CLIENT__){_balancer.Balancer.destroy();_logger2.default.info('==> [balancer] stopped')}if(__PROFILE__){_logger2.default.info('==> [profile] saving...');_profile.Profile.save();_profile.Profile.stop();_logger2.default.info('==> [profile] stopped')}this._isClosed=true;this._sockets.forEach(socket=>socket.destroy());this._sockets=[];this.emit('close')}}onSocketClose(_id){this._sockets=this._sockets.filter(({id})=>_id!==id);this.emit('socketClose');_profile.Profile.connections=this._sockets.length}onConnect(socket){const id=nextId();const sok=new _socket.Socket({id,socket});sok.on('close',()=>this.onSocketClose(id));sok.on('stat',(...props)=>this.emit('socketStat',...props));this._sockets.push(sok);_logger2.default.info(`[hub] [${socket.remoteAddress}:${socket.remotePort}] connected`);_profile.Profile.connections+=1}run(callback){const options={host:__LOCAL_HOST__,port:__LOCAL_PORT__};this._hub.listen(options,()=>{_logger2.default.info(`==> [hub] use configuration: ${JSON.stringify(__ALL_CONFIG__)}`);_logger2.default.info(`==> [hub] running as: ${__IS_SERVER__?'Server':'Client'}`);_logger2.default.info(`==> [hub] listening on: ${JSON.stringify(this._hub.address())}`);if(__IS_CLIENT__){_logger2.default.info('==> [balancer] started');_balancer.Balancer.start(__SERVERS__)}if(__PROFILE__){_logger2.default.info('==> [profile] started');_profile.Profile.start()}if(typeof callback==='function'){callback()}})}terminate(){this._hub.close();this.onClose()}}exports.Hub=Hub;

File diff suppressed because one or more lines are too long

1
lib/presets/proxy.js Normal file

@ -0,0 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var _ip=require('ip');var _ip2=_interopRequireDefault(_ip);var _defs=require('./defs');var _proxies=require('../proxies');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}class ProxyPreset extends _defs.IPreset{constructor(...args){var _temp;return _temp=super(...args),this._proxy=null,_temp}beforeIn({buffer,direct,broadcast}){if(this._proxy===null){this._proxy=new _proxies.Proxifier({onHandshakeDone:(addr,callback)=>{var _ref=[addr.type===_proxies.ATYP_DOMAIN?addr.host.toString():_ip2.default.toString(addr.host),addr.port.readUInt16BE(0)];const host=_ref[0],port=_ref[1];broadcast({type:_defs.SOCKET_CONNECT_TO_DST,payload:{targetAddress:{host,port},onConnected:()=>callback(direct)}})}})}if(!this._proxy.isDone()){this._proxy.makeHandshake(buf=>direct(buf,true),buffer)}else{return buffer}}}exports.default=ProxyPreset;

@ -1 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var _crypto=require('crypto');var _crypto2=_interopRequireDefault(_crypto);var _utils=require('../utils');var _defs=require('./defs');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const IV_LEN=16;const ciphers=['aes-128-ctr','aes-192-ctr','aes-256-ctr','aes-128-cfb','aes-192-cfb','aes-256-cfb','camellia-128-cfb','camellia-192-cfb','camellia-256-cfb','aes-128-ofb','aes-192-ofb','aes-256-ofb','aes-128-cbc','aes-192-cbc','aes-256-cbc'];class SSStreamCipherPreset extends _defs.IPreset{constructor({method}){super();this._cipherName='';this._key=null;this._cipher=null;this._decipher=null;if(typeof method!=='string'||method===''){throw Error('\'method\' must be set')}if(!ciphers.includes(method)){throw Error(`method '${method}' is not supported.`)}this._cipherName=method;if(global.__KEY__){this._key=(0,_utils.EVP_BytesToKey)(__KEY__,this._cipherName.split('-')[1]/8,IV_LEN)}}beforeOut({buffer}){if(!this._cipher){const iv=_crypto2.default.randomBytes(IV_LEN);this._cipher=_crypto2.default.createCipheriv(this._cipherName,this._key,iv);return Buffer.concat([iv,this.encrypt(buffer)])}else{return this.encrypt(buffer)}}beforeIn({buffer}){if(!this._decipher){const iv=buffer.slice(0,IV_LEN);this._decipher=_crypto2.default.createDecipheriv(this._cipherName,this._key,iv);return this.decrypt(buffer.slice(IV_LEN))}else{return this.decrypt(buffer)}}encrypt(buffer){return this._cipher.update(buffer)}decrypt(buffer){return this._decipher.update(buffer)}}exports.default=SSStreamCipherPreset;
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var _crypto=require('crypto');var _crypto2=_interopRequireDefault(_crypto);var _utils=require('../utils');var _defs=require('./defs');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}const IV_LEN=16;const ciphers=['aes-128-ctr','aes-192-ctr','aes-256-ctr','aes-128-cfb','aes-192-cfb','aes-256-cfb','camellia-128-cfb','camellia-192-cfb','camellia-256-cfb'];class SSStreamCipherPreset extends _defs.IPreset{constructor({method}){super();this._cipherName='';this._key=null;this._cipher=null;this._decipher=null;if(typeof method!=='string'||method===''){throw Error('\'method\' must be set')}if(!ciphers.includes(method)){throw Error(`method '${method}' is not supported.`)}this._cipherName=method;if(global.__KEY__){this._key=(0,_utils.EVP_BytesToKey)(__KEY__,this._cipherName.split('-')[1]/8,IV_LEN)}}beforeOut({buffer}){if(!this._cipher){const iv=_crypto2.default.randomBytes(IV_LEN);this._cipher=_crypto2.default.createCipheriv(this._cipherName,this._key,iv);return Buffer.concat([iv,this.encrypt(buffer)])}else{return this.encrypt(buffer)}}beforeIn({buffer}){if(!this._decipher){const iv=buffer.slice(0,IV_LEN);this._decipher=_crypto2.default.createDecipheriv(this._cipherName,this._key,iv);return this.decrypt(buffer.slice(IV_LEN))}else{return this.decrypt(buffer)}}encrypt(buffer){return this._cipher.update(buffer)}decrypt(buffer){return this._decipher.update(buffer)}}exports.default=SSStreamCipherPreset;

1
lib/proxies/index.js Normal file

@ -0,0 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var _common=require('./common');Object.keys(_common).forEach(function(key){if(key==='default'||key==='__esModule')return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _common[key]}})});var _proxifier=require('./proxifier');Object.keys(_proxifier).forEach(function(key){if(key==='default'||key==='__esModule')return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _proxifier[key]}})});

1
lib/proxies/proxifier.js Normal file

@ -0,0 +1 @@
'use strict';Object.defineProperty(exports,'__esModule',{value:true});exports.Proxifier=undefined;var _net=require('net');var _net2=_interopRequireDefault(_net);var _ip=require('ip');var _ip2=_interopRequireDefault(_ip);var _utils=require('../utils');var _socks=require('./socks5');var _socks2=require('./socks4');var _http=require('./http');var _common=require('./common');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}class Proxifier{constructor(props){this._socksTcpReady=false;this._socksUdpReady=false;this._httpReady=false;this.onHandshakeDone=props.onHandshakeDone}isDone(){return this._socksTcpReady||this._socksUdpReady||this._httpReady}makeHandshake(feedback,buffer){this._trySocksHandshake(feedback,buffer);if(!this.isDone()){this._tryHttpHandshake(feedback,buffer)}}_trySocksHandshake(feedback,buffer){if(!this.isDone()){this._trySocks5Handshake(feedback,buffer)}if(!this.isDone()){this._trySocks4Handshake(feedback,buffer)}}_trySocks4Handshake(feedback,buffer){const request=_socks2.RequestMessage.parse(buffer);if(request!==null){const CMD=request.CMD,DSTIP=request.DSTIP,DSTADDR=request.DSTADDR,DSTPORT=request.DSTPORT;if(CMD===_common.REQUEST_COMMAND_CONNECT){const addr={type:DSTADDR.length>0?_common.ATYP_DOMAIN:_common.ATYP_V4,host:DSTADDR.length>0?DSTADDR:DSTIP,port:DSTPORT};this.onHandshakeDone(addr,()=>{const message=new _socks2.ReplyMessage({CMD:_common.REPLY_GRANTED});feedback(message.toBuffer());this._socksTcpReady=true})}}}_trySocks5Handshake(feedback,buffer){const identifier=_socks.IdentifierMessage.parse(buffer);if(identifier!==null){const message=new _socks.SelectMessage;feedback(message.toBuffer());return}const request=_socks.RequestMessage.parse(buffer);if(request!==null){const type=request.CMD;switch(type){case _common.REQUEST_COMMAND_UDP:case _common.REQUEST_COMMAND_CONNECT:{const addr={type:request.ATYP,host:request.DSTADDR,port:request.DSTPORT};this.onHandshakeDone(addr,()=>{const message=new _socks.ReplyMessage({REP:_common.REPLY_SUCCEEDED});feedback(message.toBuffer());if(type===_common.REQUEST_COMMAND_CONNECT){this._socksTcpReady=true}else{this._socksUdpReady=true}});break}default:{const message=new _socks.ReplyMessage({REP:_common.REPLY_COMMAND_NOT_SUPPORTED});feedback(message.toBuffer());break}}}}_tryHttpHandshake(feedback,buffer){const request=_http.HttpRequestMessage.parse(buffer);if(request!==null){const METHOD=request.METHOD,URI=request.URI,HOST=request.HOST;const method=METHOD.toString();let addr={};if(method==='CONNECT'){addr=(0,_utils.parseURI)(URI.toString())}else{let type=null;let host=HOST.toString();if(_net2.default.isIP(host)){if(_net2.default.isIPv4(host)){type=_common.ATYP_V4}else{type=_common.ATYP_V6}host=_ip2.default.toBuffer(host)}else{type=_common.ATYP_DOMAIN;host=HOST}addr={type,host,port:Buffer.from([0,80])}}this.onHandshakeDone(addr,onForward=>{if(method==='CONNECT'){const message=new _http.ConnectReplyMessage;feedback(message.toBuffer())}else{onForward(buffer)}this._httpReady=true})}}}exports.Proxifier=Proxifier;