lib: make compile target to Node.js 8

This commit is contained in:
Micooz 2018-02-28 13:29:06 +08:00
parent 8b00b8a897
commit 0ddfd2463b
31 changed files with 462 additions and 1084 deletions

@ -4,7 +4,7 @@
"env",
{
"targets": {
"node": 6
"node": 8
}
}
]

@ -30,7 +30,7 @@
### Requirements
blinksocks is built on top of [Node.js](https://nodejs.org), if you want to use it in an ordinary way or do some hacking, please install **Node.js(v6.x and above)** on your operating system.
blinksocks is built on top of [Node.js](https://nodejs.org), if you want to use it in an ordinary way or do some hacking, please install **Node.js(v8.x and above)** on your operating system.
### Install or Upgrade

@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
exports.ACL = exports.ACL_RESUME_SEND = exports.ACL_RESUME_RECV = exports.ACL_PAUSE_SEND = exports.ACL_PAUSE_RECV = exports.ACL_CLOSE_CONNECTION = 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 _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
@ -33,8 +31,6 @@ var _utils = require('../utils');
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 ACL_CLOSE_CONNECTION = exports.ACL_CLOSE_CONNECTION = 'acl_close_connection';
const ACL_PAUSE_RECV = exports.ACL_PAUSE_RECV = 'acl_pause_recv';
const ACL_PAUSE_SEND = exports.ACL_PAUSE_SEND = 'acl_pause_send';
@ -42,9 +38,7 @@ const ACL_RESUME_RECV = exports.ACL_RESUME_RECV = 'acl_resume_recv';
const ACL_RESUME_SEND = exports.ACL_RESUME_SEND = 'acl_resume_send';
function ruleIsMatch(host, port) {
const rHost = this.host,
rPort = this.port;
const { host: rHost, port: rPort } = this;
const slashIndex = rHost.indexOf('/');
let isHostMatch = false;
@ -93,11 +87,7 @@ function parseSpeed(speed) {
const regex = /^(\d+)(b|k|kb|m|mb|g|gb)$/g;
const results = regex.exec(speed.toLowerCase());
if (results !== null) {
var _results = _slicedToArray(results, 3);
const num = _results[1],
unit = _results[2];
const [, num, unit] = results;
return +num * {
'b': 1,
'k': 1024,
@ -125,15 +115,7 @@ function parseLine(line) {
if (line.indexOf('#') > 0) {
line = line.substr(0, line.indexOf('#'));
}
var _line$split$filter = line.split(' ').filter(p => p.length > 0),
_line$split$filter2 = _slicedToArray(_line$split$filter, 4);
const addr = _line$split$filter2[0],
ban = _line$split$filter2[1],
up = _line$split$filter2[2],
dl = _line$split$filter2[3];
const [addr, ban, up, dl] = line.split(' ').filter(p => p.length > 0);
let _host = null;
let _port = null;
@ -199,30 +181,28 @@ const DEFAULT_MAX_TRIES = 2;
class ACL extends _events2.default {
static loadRules(aclPath) {
return _asyncToGenerator(function* () {
return new Promise(function (resolve, reject) {
_utils.logger.verbose('[acl] loading access control list');
const rs = _fs2.default.createReadStream(aclPath, { encoding: 'utf-8' });
rs.on('error', function (err) {
_utils.logger.warn(`[acl] fail to reload access control list: ${err.message}`);
reject(err);
});
const rl = _readline2.default.createInterface({ input: rs });
const _rules = [];
rl.on('line', function (line) {
const rule = parseLine(line);
if (rule !== null) {
_rules.push(rule);
}
});
rl.on('close', function () {
const rules = _rules.reverse();
_utils.logger.info(`[acl] ${rules.length} rules loaded`);
resolve(rules);
});
static async loadRules(aclPath) {
return new Promise((resolve, reject) => {
_utils.logger.verbose('[acl] loading access control list');
const rs = _fs2.default.createReadStream(aclPath, { encoding: 'utf-8' });
rs.on('error', err => {
_utils.logger.warn(`[acl] fail to reload access control list: ${err.message}`);
reject(err);
});
})();
const rl = _readline2.default.createInterface({ input: rs });
const _rules = [];
rl.on('line', line => {
const rule = parseLine(line);
if (rule !== null) {
_rules.push(rule);
}
});
rl.on('close', () => {
const rules = _rules.reverse();
_utils.logger.info(`[acl] ${rules.length} rules loaded`);
resolve(rules);
});
});
}
constructor({ remoteInfo, rules, max_tries = DEFAULT_MAX_TRIES }) {
@ -251,30 +231,9 @@ class ACL extends _events2.default {
if (cacheRule !== undefined) {
return cacheRule;
} else {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this._rules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const rule = _step.value;
if (rule.isMatch(host, port)) {
return this._cachedRules[cacheKey] = rule;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
for (const rule of this._rules) {
if (rule.isMatch(host, port)) {
return this._cachedRules[cacheKey] = rule;
}
}
@ -283,10 +242,7 @@ class ACL extends _events2.default {
}
applyRule(rule) {
const isBan = rule.isBan,
upLimit = rule.upLimit,
dlLimit = rule.dlLimit;
const { isBan, upLimit, dlLimit } = rule;
_utils.logger.debug(`[acl] [${this._sourceHost}:${this._sourcePort}] apply rule: "${rule}"`);
if (isBan) {
@ -296,12 +252,7 @@ class ACL extends _events2.default {
}
if (upLimit !== '-') {
var _process$hrtime = process.hrtime(this._hrTimeBegin),
_process$hrtime2 = _slicedToArray(_process$hrtime, 2);
const sec = _process$hrtime2[0],
nano = _process$hrtime2[1];
const [sec, nano] = process.hrtime(this._hrTimeBegin);
const speed = Math.ceil(this._totalIn / (sec + nano / 1e9));
_utils.logger.debug(`[acl] upload speed: ${speed}b/s`);
@ -323,12 +274,7 @@ class ACL extends _events2.default {
}
if (dlLimit !== '-') {
var _process$hrtime3 = process.hrtime(this._hrTimeBegin),
_process$hrtime4 = _slicedToArray(_process$hrtime3, 2);
const sec = _process$hrtime4[0],
nano = _process$hrtime4[1];
const [sec, nano] = process.hrtime(this._hrTimeBegin);
const speed = Math.ceil(this._totalOut / (sec + nano / 1e9));
_utils.logger.debug(`[acl] download speed: ${speed}b/s`);

@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
exports.Config = 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);
@ -95,13 +93,7 @@ class Config {
this.log_max_days = null;
this.stores = [];
var _url$parse = _url2.default.parse(json.service);
const protocol = _url$parse.protocol,
hostname = _url$parse.hostname,
port = _url$parse.port,
query = _url$parse.query;
const { protocol, hostname, port, query } = _url2.default.parse(json.service);
this.local_protocol = protocol.slice(0, -1);
this.local_host = hostname;
this.local_port = +port;
@ -132,15 +124,8 @@ class Config {
}
if (this.is_client && this.local_protocol === 'tcp') {
var _qs$parse = _qs2.default.parse(query);
const forward = _qs$parse.forward;
var _url$parse2 = _url2.default.parse('tcp://' + forward);
const hostname = _url$parse2.hostname,
port = _url$parse2.port;
const { forward } = _qs2.default.parse(query);
const { hostname, port } = _url2.default.parse('tcp://' + forward);
this.forward_host = hostname;
this.forward_port = +port;
}
@ -157,12 +142,7 @@ class Config {
}
_initServer(server) {
var _url$parse3 = _url2.default.parse(server.service);
const protocol = _url$parse3.protocol,
hostname = _url$parse3.hostname,
port = _url$parse3.port;
const { protocol, hostname, port } = _url2.default.parse(server.service);
this.transport = protocol.slice(0, -1);
this.server_host = hostname;
this.server_port = +port;
@ -204,11 +184,7 @@ class Config {
this.stores = new Array(this.presets.length).fill({});
for (let i = 0; i < server.presets.length; i++) {
var _server$presets$i = server.presets[i];
const name = _server$presets$i.name;
var _server$presets$i$par = _server$presets$i.params;
const params = _server$presets$i$par === undefined ? {} : _server$presets$i$par;
const { name, params = {} } = server.presets[i];
const clazz = (0, _presets.getPresetClassByName)(name);
const data = clazz.onCache(params, this.stores[i]);
if (data instanceof Promise) {
@ -273,12 +249,7 @@ class Config {
throw Error('"service" must be provided as "<protocol>://<host>:<port>[?params]"');
}
var _url$parse4 = _url2.default.parse(json.service);
const _protocol = _url$parse4.protocol,
hostname = _url$parse4.hostname,
port = _url$parse4.port,
query = _url$parse4.query;
const { protocol: _protocol, hostname, port, query } = _url2.default.parse(json.service);
if (typeof _protocol !== 'string') {
throw Error('service.protocol is invalid');
@ -299,19 +270,13 @@ class Config {
}
if (protocol === 'tcp') {
var _qs$parse2 = _qs2.default.parse(query);
const forward = _qs$parse2.forward;
const { forward } = _qs2.default.parse(query);
if (!forward) {
throw Error('require "?forward=<host>:<port>" parameter in service when using "tcp" on client side');
}
var _url$parse5 = _url2.default.parse('tcp://' + forward);
const hostname = _url$parse5.hostname,
port = _url$parse5.port;
const { hostname, port } = _url2.default.parse('tcp://' + forward);
if (!(0, _utils.isValidHostname)(hostname)) {
throw Error('service.?forward.host is invalid');
}
@ -349,12 +314,7 @@ class Config {
if (parts.length !== 2) {
throw Error('"redirect" must be "<host or ip>:<port>"');
}
var _parts = _slicedToArray(parts, 2);
const host = _parts[0],
port = _parts[1];
const [host, port] = parts;
if (!(0, _utils.isValidHostname)(host) && !_net2.default.isIP(host)) {
throw Error('"redirect" host is invalid');
}
@ -371,11 +331,7 @@ class Config {
throw Error('"service" must be provided as "<protocol>://<host>:<port>[?params]"');
}
var _url$parse6 = _url2.default.parse(server.service);
const _protocol = _url$parse6.protocol,
hostname = _url$parse6.hostname,
port = _url$parse6.port;
const { protocol: _protocol, hostname, port } = _url2.default.parse(server.service);
if (typeof _protocol !== 'string') {
throw Error('service.protocol is invalid');
@ -444,50 +400,27 @@ class Config {
throw Error('"server.presets" must contain at least one preset');
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = server.presets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const preset = _step.value;
const name = preset.name,
params = preset.params;
if (typeof name !== 'string') {
throw Error('"server.presets[].name" must be a string');
}
if (name === '') {
throw Error('"server.presets[].name" cannot be empty');
}
if (params !== undefined) {
if (!(0, _lodash2.default)(params)) {
throw Error('"server.presets[].params" must be an plain object');
}
const clazz = (0, _presets.getPresetClassByName)(name);
clazz.onCheckParams(params);
}
for (const preset of server.presets) {
const { name, params } = preset;
if (typeof name !== 'string') {
throw Error('"server.presets[].name" must be a string');
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
if (name === '') {
throw Error('"server.presets[].name" cannot be empty');
}
if (params !== undefined) {
if (!(0, _lodash2.default)(params)) {
throw Error('"server.presets[].params" must be an plain object');
}
const clazz = (0, _presets.getPresetClassByName)(name);
clazz.onCheckParams(params);
}
}
}
static _testCommon(common) {
if (common.timeout !== undefined) {
const timeout = common.timeout;
const { timeout } = common;
if (typeof timeout !== 'number') {
throw Error('"timeout" must be a number');
}
@ -513,8 +446,7 @@ class Config {
}
if (common.log_max_days !== undefined) {
const log_max_days = common.log_max_days;
const { log_max_days } = common;
if (typeof log_max_days !== 'number') {
throw Error('"log_max_days" must a number');
}
@ -524,42 +456,19 @@ class Config {
}
if (common.dns !== undefined) {
const dns = common.dns;
const { dns } = common;
if (!Array.isArray(dns)) {
throw Error('"dns" must be an array');
}
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = dns[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
const ip = _step2.value;
if (!_net2.default.isIP(ip)) {
throw Error(`"${ip}" is not an ip address`);
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
for (const ip of dns) {
if (!_net2.default.isIP(ip)) {
throw Error(`"${ip}" is not an ip address`);
}
}
}
if (common.dns_expire !== undefined) {
const dns_expire = common.dns_expire;
const { dns_expire } = common;
if (typeof dns_expire !== 'number') {
throw Error('"dns_expire" must be a number');
}

@ -49,8 +49,6 @@ var _constants = require('../constants');
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"); }); }; }
class Hub {
constructor(config) {
@ -106,224 +104,183 @@ class Hub {
this._udpRelays = (0, _lruCache2.default)({ max: 500, maxAge: 1e5, dispose: (_, relay) => relay.destroy() });
}
run() {
var _this = this;
async run() {
await _libsodiumWrappers2.default.ready;
if (!global.libsodium) {
global.libsodium = _libsodiumWrappers2.default;
}
return _asyncToGenerator(function* () {
yield _libsodiumWrappers2.default.ready;
if (!global.libsodium) {
global.libsodium = _libsodiumWrappers2.default;
}
if (this._tcpServer !== null) {
await this.terminate();
}
if (_this._tcpServer !== null) {
yield _this.terminate();
}
yield _this._createServer();
})();
await this._createServer();
}
terminate() {
var _this2 = this;
async terminate() {
this._udpRelays.reset();
return _asyncToGenerator(function* () {
_this2._udpRelays.reset();
if (this._config.mux) {
this._muxRelays.forEach(relay => relay.destroy());
this._muxRelays.clear();
}
if (_this2._config.mux) {
_this2._muxRelays.forEach(function (relay) {
return relay.destroy();
});
_this2._muxRelays.clear();
this._tcpRelays.forEach(relay => relay.destroy());
this._tcpRelays.clear();
this._udpServer.close();
this._tcpServer.close();
_utils.logger.info('[hub] shutdown');
}
async _createServer() {
if (this._config.is_client) {
this._tcpServer = await this._createServerOnClient();
} else {
this._tcpServer = await this._createServerOnServer();
}
this._udpServer = await this._createUdpServer();
}
async _createServerOnClient() {
return new Promise((resolve, reject) => {
let server = null;
switch (this._config.local_protocol) {
case 'tcp':
server = _proxies.tcp.createServer({ forwardHost: this._config.forward_host, forwardPort: this._config.forward_port });
break;
case 'socks':
case 'socks5':
case 'socks4':
case 'socks4a':
server = _proxies.socks.createServer({ bindAddress: this._config.local_host, bindPort: this._config.local_port });
break;
case 'http':
case 'https':
server = _proxies.http.createServer();
break;
default:
return reject(Error(`unsupported protocol: "${this._config.local_protocol}"`));
}
_this2._tcpRelays.forEach(function (relay) {
return relay.destroy();
const address = {
host: this._config.local_host,
port: this._config.local_port
};
server.on('proxyConnection', this._onConnection);
server.on('error', reject);
server.listen(address, () => {
const service = `${this._config.local_protocol}://${this._config.local_host}:${this._config.local_port}`;
_utils.logger.info(`[hub] blinksocks client is running at ${service}`);
resolve(server);
});
_this2._tcpRelays.clear();
_this2._udpServer.close();
_this2._tcpServer.close();
_utils.logger.info('[hub] shutdown');
})();
});
}
_createServer() {
var _this3 = this;
return _asyncToGenerator(function* () {
if (_this3._config.is_client) {
_this3._tcpServer = yield _this3._createServerOnClient();
} else {
_this3._tcpServer = yield _this3._createServerOnServer();
}
_this3._udpServer = yield _this3._createUdpServer();
})();
}
_createServerOnClient() {
var _this4 = this;
return _asyncToGenerator(function* () {
return new Promise(function (resolve, reject) {
let server = null;
switch (_this4._config.local_protocol) {
case 'tcp':
server = _proxies.tcp.createServer({ forwardHost: _this4._config.forward_host, forwardPort: _this4._config.forward_port });
async _createServerOnServer() {
return new Promise((resolve, reject) => {
const address = {
host: this._config.local_host,
port: this._config.local_port
};
const onListening = server => {
const service = `${this._config.local_protocol}://${this._config.local_host}:${this._config.local_port}`;
_utils.logger.info(`[hub] blinksocks server is running at ${service}`);
resolve(server);
};
let server = null;
switch (this._config.local_protocol) {
case 'tcp':
{
server = _net2.default.createServer();
server.on('connection', this._onConnection);
server.listen(address, () => onListening(server));
break;
case 'socks':
case 'socks5':
case 'socks4':
case 'socks4a':
server = _proxies.socks.createServer({ bindAddress: _this4._config.local_host, bindPort: _this4._config.local_port });
}
case 'ws':
{
server = new _ws2.default.Server(_extends({}, address, {
perMessageDeflate: false
}));
server.on('connection', (ws, req) => {
ws.remoteAddress = req.connection.remoteAddress;
ws.remotePort = req.connection.remotePort;
this._onConnection(ws);
});
server.on('listening', () => onListening(server));
break;
case 'http':
case 'https':
server = _proxies.http.createServer();
}
case 'tls':
{
server = _tls2.default.createServer({ key: [this._config.tls_key], cert: [this._config.tls_cert] });
server.on('secureConnection', this._onConnection);
server.listen(address, () => onListening(server));
break;
default:
return reject(Error(`unsupported protocol: "${_this4._config.local_protocol}"`));
}
const address = {
host: _this4._config.local_host,
port: _this4._config.local_port
};
server.on('proxyConnection', _this4._onConnection);
server.on('error', reject);
server.listen(address, function () {
const service = `${_this4._config.local_protocol}://${_this4._config.local_host}:${_this4._config.local_port}`;
_utils.logger.info(`[hub] blinksocks client is running at ${service}`);
resolve(server);
});
});
})();
}
default:
return reject(Error(`unsupported protocol: "${this._config.local_protocol}"`));
}
server.on('error', reject);
});
}
_createServerOnServer() {
var _this5 = this;
async _createUdpServer() {
return new Promise((resolve, reject) => {
const relays = this._udpRelays;
const server = _dgram2.default.createSocket('udp4');
return _asyncToGenerator(function* () {
return new Promise(function (resolve, reject) {
const address = {
host: _this5._config.local_host,
port: _this5._config.local_port
};
const onListening = function onListening(server) {
const service = `${_this5._config.local_protocol}://${_this5._config.local_host}:${_this5._config.local_port}`;
_utils.logger.info(`[hub] blinksocks server is running at ${service}`);
resolve(server);
};
let server = null;
switch (_this5._config.local_protocol) {
case 'tcp':
{
server = _net2.default.createServer();
server.on('connection', _this5._onConnection);
server.listen(address, function () {
return onListening(server);
});
break;
}
case 'ws':
{
server = new _ws2.default.Server(_extends({}, address, {
perMessageDeflate: false
}));
server.on('connection', function (ws, req) {
ws.remoteAddress = req.connection.remoteAddress;
ws.remotePort = req.connection.remotePort;
_this5._onConnection(ws);
});
server.on('listening', function () {
return onListening(server);
});
break;
}
case 'tls':
{
server = _tls2.default.createServer({ key: [_this5._config.tls_key], cert: [_this5._config.tls_cert] });
server.on('secureConnection', _this5._onConnection);
server.listen(address, function () {
return onListening(server);
});
break;
}
default:
return reject(Error(`unsupported protocol: "${_this5._config.local_protocol}"`));
server.on('message', (msg, rinfo) => {
const { address, port } = rinfo;
let proxyRequest = null;
let packet = msg;
if (this._config.is_client) {
const parsed = _proxies.socks.parseSocks5UdpRequest(msg);
if (parsed === null) {
_utils.logger.warn(`[hub] [${address}:${port}] drop invalid udp packet: ${(0, _utils.dumpHex)(msg)}`);
return;
}
const { host, port, data } = parsed;
proxyRequest = { host, port };
packet = data;
}
server.on('error', reject);
});
})();
}
_createUdpServer() {
var _this6 = this;
return _asyncToGenerator(function* () {
return new Promise(function (resolve, reject) {
const relays = _this6._udpRelays;
const server = _dgram2.default.createSocket('udp4');
server.on('message', function (msg, rinfo) {
const address = rinfo.address,
port = rinfo.port;
let proxyRequest = null;
let packet = msg;
if (_this6._config.is_client) {
const parsed = _proxies.socks.parseSocks5UdpRequest(msg);
if (parsed === null) {
_utils.logger.warn(`[hub] [${address}:${port}] drop invalid udp packet: ${(0, _utils.dumpHex)(msg)}`);
return;
}
const host = parsed.host,
port = parsed.port,
data = parsed.data;
proxyRequest = { host, port };
packet = data;
}
const key = `${address}:${port}`;
let relay = relays.get(key);
if (relay === undefined) {
const context = {
socket: server,
remoteInfo: { host: address, port: port }
};
relay = _this6._createUdpRelay(context);
relay.init({ proxyRequest });
relay.on('close', function onRelayClose() {});
relays.set(key, relay);
relays.prune();
}
if (relay._inbound) {
relay._inbound.onReceive(packet, rinfo);
}
});
server.on('error', reject);
if (_this6._config.is_client) {
server.send = function (send) {
return function (data, port, host, isSs, ...args) {
let packet = null;
if (isSs) {
packet = Buffer.from([0x00, 0x00, 0x00, ...data]);
} else {
packet = _proxies.socks.encodeSocks5UdpResponse({ host, port, data });
}
send.call(server, packet, port, host, ...args);
};
}(server.send);
const key = `${address}:${port}`;
let relay = relays.get(key);
if (relay === undefined) {
const context = {
socket: server,
remoteInfo: { host: address, port: port }
};
relay = this._createUdpRelay(context);
relay.init({ proxyRequest });
relay.on('close', function onRelayClose() {});
relays.set(key, relay);
relays.prune();
}
if (relay._inbound) {
relay._inbound.onReceive(packet, rinfo);
}
server.bind({ address: _this6._config.local_host, port: _this6._config.local_port }, function () {
const service = `udp://${_this6._config.local_host}:${_this6._config.local_port}`;
_utils.logger.info(`[hub] blinksocks udp server is running at ${service}`);
resolve(server);
});
});
})();
server.on('error', reject);
if (this._config.is_client) {
server.send = (send => (data, port, host, isSs, ...args) => {
let packet = null;
if (isSs) {
packet = Buffer.from([0x00, 0x00, 0x00, ...data]);
} else {
packet = _proxies.socks.encodeSocks5UdpResponse({ host, port, data });
}
send.call(server, packet, port, host, ...args);
})(server.send);
}
server.bind({ address: this._config.local_host, port: this._config.local_port }, () => {
const service = `udp://${this._config.local_host}:${this._config.local_port}`;
_utils.logger.info(`[hub] blinksocks udp server is running at ${service}`);
resolve(server);
});
});
}
_getMuxRelayOnClient(context, cid) {
@ -336,8 +293,7 @@ class Hub {
_utils.logger.info(`[mux-${muxRelay.id}] create mux connection, total: ${this._muxRelays.size}`);
}
const proxyRequest = context.proxyRequest;
const { proxyRequest } = context;
if (muxRelay.isOutboundReady()) {
proxyRequest.onConnected(buffer => {
if (buffer) {

@ -10,7 +10,7 @@ Object.keys(_config).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _config[key];
}
});
@ -22,7 +22,7 @@ Object.keys(_hub).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _hub[key];
}
});
@ -34,7 +34,7 @@ Object.keys(_pipe).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _pipe[key];
}
});
@ -46,7 +46,7 @@ Object.keys(_preset).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _preset[key];
}
});
@ -58,7 +58,7 @@ Object.keys(_relay).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _relay[key];
}
});
@ -70,7 +70,7 @@ Object.keys(_muxRelay).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _muxRelay[key];
}
});

@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
exports.MuxRelay = 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 _relay = require('./relay');
var _utils = require('../utils');
@ -28,13 +26,7 @@ class MuxRelay extends _relay.Relay {
'tls': [_transports.TlsInbound, _transports.TlsOutbound],
'ws': [_transports.WsInbound, _transports.WsOutbound]
};
var _ref = this._config.is_client ? [_transports.MuxInbound, mapping[transport][1]] : [mapping[transport][0], _transports.MuxOutbound],
_ref2 = _slicedToArray(_ref, 2);
const Inbound = _ref2[0],
Outbound = _ref2[1];
const [Inbound, Outbound] = this._config.is_client ? [_transports.MuxInbound, mapping[transport][1]] : [mapping[transport][0], _transports.MuxOutbound];
return { Inbound, Outbound };
}
@ -65,31 +57,10 @@ class MuxRelay extends _relay.Relay {
const subRelays = this.getSubRelays();
if (subRelays) {
_utils.logger.info(`[mux-${this.id}] connection destroyed, cleanup ${subRelays.size} sub connections`);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = subRelays.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const relay = _step.value;
relay.destroy();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
for (const relay of subRelays.values()) {
relay.destroy();
}
subRelays.clear();
this._subRelays = null;
}
@ -111,31 +82,9 @@ class MuxRelay extends _relay.Relay {
host: host,
port: port,
onConnected: () => {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = relay.__pendingFrames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
const frame = _step2.value;
relay.decode(frame);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
for (const frame of relay.__pendingFrames) {
relay.decode(frame);
}
relay.__pendingFrames = null;
}
};
@ -213,10 +162,7 @@ class MuxRelay extends _relay.Relay {
}
_getRandomMuxRelay() {
var _ctx = this._ctx;
const muxRelays = _ctx.muxRelays,
remoteInfo = _ctx.remoteInfo;
const { muxRelays, remoteInfo } = this._ctx;
const relays = [...muxRelays.values()].filter(relay => relay._ctx && relay._ctx.remoteInfo.host === remoteInfo.host && relay._ctx.remoteInfo.port === remoteInfo.port);
return relays[(0, _utils.getRandomInt)(0, relays.length - 1)];
}

@ -53,29 +53,8 @@ class Pipe extends _events2.default {
updatePresets(rawPresets) {
const mdIndex = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.getPresets()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const preset = _step.value;
mdIndex[preset.name] = preset;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
for (const preset of this.getPresets()) {
mdIndex[preset.name] = preset;
}
const presets = [];
@ -177,7 +156,7 @@ class Pipe extends _events2.default {
}
exports.Pipe = Pipe;
var _initialiseProps = function _initialiseProps() {
var _initialiseProps = function () {
this._config = null;
this._isPipingUdp = false;
this._encode_presets = [];
@ -189,30 +168,9 @@ var _initialiseProps = function _initialiseProps() {
this.broadcast = (name, action) => {
const presets = this.getPresets();
const results = [];
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = presets[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
const preset = _step2.value;
if (preset.name !== name) {
results.push(preset.notify(action));
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
for (const preset of presets) {
if (preset.name !== name) {
results.push(preset.notify(action));
}
}

@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
exports.Relay = 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 _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _events = require('events');
@ -57,11 +55,7 @@ class Relay extends _events2.default {
this._destroyed = false;
this.onChangePresetSuite = action => {
var _action$payload = action.payload;
const type = _action$payload.type,
suite = _action$payload.suite,
data = _action$payload.data;
const { type, suite, data } = action.payload;
_utils.logger.verbose(`[relay] changing presets suite to: ${JSON.stringify(suite)}`);
this.updatePresets(this.preparePresets([...suite.presets, { 'name': 'auto-conf' }]));
@ -128,11 +122,7 @@ class Relay extends _events2.default {
thisRelay: this
}, context);
var _getBounds = this.getBounds(transport);
const Inbound = _getBounds.Inbound,
Outbound = _getBounds.Outbound;
const { Inbound, Outbound } = this.getBounds(transport);
const props = { config, context: this._ctx };
const inbound = new Inbound(props);
const outbound = new Outbound(props);
@ -173,15 +163,9 @@ class Relay extends _events2.default {
let Inbound = null,
Outbound = null;
if (transport === 'udp') {
Inbound = _transports.UdpInbound;
Outbound = _transports.UdpOutbound;
[Inbound, Outbound] = [_transports.UdpInbound, _transports.UdpOutbound];
} else {
var _ref = this._config.is_client ? [_transports.TcpInbound, mapping[transport][1]] : [mapping[transport][0], _transports.TcpOutbound];
var _ref2 = _slicedToArray(_ref, 2);
Inbound = _ref2[0];
Outbound = _ref2[1];
[Inbound, Outbound] = this._config.is_client ? [_transports.TcpInbound, mapping[transport][1]] : [mapping[transport][0], _transports.TcpOutbound];
}
return { Inbound, Outbound };
}
@ -211,13 +195,8 @@ class Relay extends _events2.default {
onBroadcast(action) {
if (action.type === _actions.CONNECT_TO_REMOTE) {
var _remoteInfo = this._remoteInfo;
const sourceHost = _remoteInfo.host,
sourcePort = _remoteInfo.port;
var _action$payload2 = action.payload;
const targetHost = _action$payload2.host,
targetPort = _action$payload2.port;
const { host: sourceHost, port: sourcePort } = this._remoteInfo;
const { host: targetHost, port: targetPort } = action.payload;
const remote = `${sourceHost}:${sourcePort}`;
const target = `${targetHost}:${targetPort}`;

@ -44,47 +44,25 @@ class Tracker {
let up = 0,
ub = 0;
let ud = '';
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this._tracks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const el = _step.value;
if (el === TRACK_CHAR_UPLOAD || el === TRACK_CHAR_DOWNLOAD) {
if (ud === el) {
continue;
}
ud = el;
for (const el of this._tracks) {
if (el === TRACK_CHAR_UPLOAD || el === TRACK_CHAR_DOWNLOAD) {
if (ud === el) {
continue;
}
if (Number.isInteger(el)) {
if (ud === TRACK_CHAR_DOWNLOAD) {
dp += 1;
db += el;
}
if (ud === TRACK_CHAR_UPLOAD) {
up += 1;
ub += el;
}
}
strs.push(el);
ud = el;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
if (Number.isInteger(el)) {
if (ud === TRACK_CHAR_DOWNLOAD) {
dp += 1;
db += el;
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
if (ud === TRACK_CHAR_UPLOAD) {
up += 1;
ub += el;
}
}
strs.push(el);
}
const perSize = Math.floor(TRACK_MAX_SIZE / 2);
if (strs.length > TRACK_MAX_SIZE) {
strs = strs.slice(0, perSize).concat([' ... ']).concat(strs.slice(-perSize));

@ -10,7 +10,7 @@ Object.keys(_core).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _core[key];
}
});
@ -22,7 +22,7 @@ Object.keys(_presets).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _presets[key];
}
});
@ -34,7 +34,7 @@ Object.keys(_proxies).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _proxies[key];
}
});
@ -46,7 +46,7 @@ Object.keys(_transports).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _transports[key];
}
});
@ -58,7 +58,7 @@ Object.keys(_utils).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _utils[key];
}
});

@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
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 _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
@ -90,19 +88,9 @@ class AeadRandomCipherPreset extends _defs.IPreset {
const padding = _crypto2.default.randomBytes(paddingLen);
const dataLen = (0, _utils.numberToBuffer)(chunk.length);
const [encLen, lenTag] = this.encrypt(dataLen);
var _encrypt = this.encrypt(dataLen),
_encrypt2 = _slicedToArray(_encrypt, 2);
const encLen = _encrypt2[0],
lenTag = _encrypt2[1];
var _encrypt3 = this.encrypt(chunk),
_encrypt4 = _slicedToArray(_encrypt3, 2);
const encData = _encrypt4[0],
dataTag = _encrypt4[1];
const [encData, dataTag] = this.encrypt(chunk);
return Buffer.concat([padding, encLen, lenTag, encData, dataTag]);
});
if (salt) {
@ -140,10 +128,7 @@ class AeadRandomCipherPreset extends _defs.IPreset {
return;
}
var _ref = [buffer.slice(0, 2), buffer.slice(2, 2 + TAG_LEN)];
const encLen = _ref[0],
lenTag = _ref[1];
const [encLen, lenTag] = [buffer.slice(0, 2), buffer.slice(2, 2 + TAG_LEN)];
const dataLenBuf = this.decrypt(encLen, lenTag);
if (dataLenBuf === null) {
fail(`unexpected DataLen_TAG=${lenTag.toString('hex')} when verify DataLen=${encLen.toString('hex')}, dump=${buffer.slice(0, 60).toString('hex')}`);
@ -158,10 +143,7 @@ class AeadRandomCipherPreset extends _defs.IPreset {
}
onChunkReceived(chunk, { next, fail }) {
var _ref2 = [chunk.slice(2 + TAG_LEN, -TAG_LEN), chunk.slice(-TAG_LEN)];
const encData = _ref2[0],
dataTag = _ref2[1];
const [encData, dataTag] = [chunk.slice(2 + TAG_LEN, -TAG_LEN), chunk.slice(-TAG_LEN)];
const data = this.decrypt(encData, dataTag);
if (data === null) {
fail(`unexpected Data_TAG=${dataTag.toString('hex')} when verify Data=${encData.slice(0, 60).toString('hex')}, dump=${chunk.slice(0, 60).toString('hex')}`);

@ -30,8 +30,6 @@ var _constants = require('../constants');
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 MAX_TIME_DIFF = 30;
const NOOP = Buffer.alloc(0);
@ -48,24 +46,22 @@ class AutoConfPreset extends _defs.IPreset {
}
}
static onCache({ suites: uri }) {
return _asyncToGenerator(function* () {
_utils.logger.info(`[auto-conf] loading suites from: ${uri}`);
let suites = [];
if (uri.startsWith('http')) {
const res = yield (0, _nodeFetch2.default)(uri);
suites = yield res.json();
} else {
const suiteJson = _path2.default.resolve(process.cwd(), uri);
const rawText = _fs2.default.readFileSync(suiteJson, { encoding: 'utf-8' });
suites = JSON.parse(rawText);
}
if (suites.length < 1) {
throw Error(`you must provide at least one suite in ${uri}`);
}
_utils.logger.info(`[auto-conf] ${suites.length} suites loaded`);
return { suites };
})();
static async onCache({ suites: uri }) {
_utils.logger.info(`[auto-conf] loading suites from: ${uri}`);
let suites = [];
if (uri.startsWith('http')) {
const res = await (0, _nodeFetch2.default)(uri);
suites = await res.json();
} else {
const suiteJson = _path2.default.resolve(process.cwd(), uri);
const rawText = _fs2.default.readFileSync(suiteJson, { encoding: 'utf-8' });
suites = JSON.parse(rawText);
}
if (suites.length < 1) {
throw Error(`you must provide at least one suite in ${uri}`);
}
_utils.logger.info(`[auto-conf] ${suites.length} suites loaded`);
return { suites };
}
onDestroy() {
@ -86,19 +82,11 @@ class AutoConfPreset extends _defs.IPreset {
}
encodeChangeSuite({ buffer, broadcast, fail }) {
var _getStore = this.getStore();
const suites = _getStore.suites;
const { suites } = this.getStore();
if (suites.length < 1) {
return fail('suites are not initialized properly');
}
var _createRequestHeader = this.createRequestHeader(suites);
const header = _createRequestHeader.header,
suite = _createRequestHeader.suite;
const { header, suite } = this.createRequestHeader(suites);
this._header = header;
this._isSuiteChanged = true;
return broadcast({
@ -112,10 +100,7 @@ class AutoConfPreset extends _defs.IPreset {
}
decodeChangeSuite({ buffer, broadcast, fail }) {
var _getStore2 = this.getStore();
const suites = _getStore2.suites;
const { suites } = this.getStore();
if (suites.length < 1) {
return fail('suites are not initialized properly');
}

@ -59,10 +59,7 @@ class BaseAuthPreset extends _defs.IPresetAddressing {
onNotified(action) {
if (this._config.is_client && action.type === _actions.CONNECT_TO_REMOTE) {
var _action$payload = action.payload;
const host = _action$payload.host,
port = _action$payload.port;
const { host, port } = action.payload;
this._host = Buffer.from(host);
this._port = (0, _utils.numberToBuffer)(port);
}
@ -124,9 +121,7 @@ class BaseAuthPreset extends _defs.IPresetAddressing {
return;
}
const host = decoded.host,
port = decoded.port,
data = decoded.data;
const { host, port, data } = decoded;
this._isConnecting = true;
broadcast({
@ -156,10 +151,7 @@ class BaseAuthPreset extends _defs.IPresetAddressing {
if (!decoded) {
return;
}
const host = decoded.host,
port = decoded.port,
data = decoded.data;
const { host, port, data } = decoded;
broadcast({
type: _actions.CONNECT_TO_REMOTE,
payload: {

@ -21,44 +21,22 @@ function parseFile(file) {
const lines = txt.split(/\r\n|\n|\r/);
const parts = [];
let part = '';
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = lines[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const line = _step.value;
switch (line[0]) {
case '=':
case '-':
if (part !== '') {
part += '\r\n';
parts.push(part);
part = '';
}
break;
default:
part += line;
for (const line of lines) {
switch (line[0]) {
case '=':
case '-':
if (part !== '') {
part += '\r\n';
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
parts.push(part);
part = '';
}
break;
default:
part += line;
part += '\r\n';
break;
}
}
const pairs = [];
for (let i = 0; i < parts.length; i += 2) {
const prev = parts[i];
@ -96,14 +74,10 @@ class ObfsHttpPreset extends _defs.IPreset {
clientOut({ buffer }) {
if (!this._isHeaderSent) {
var _getStore = this.getStore();
const pairs = _getStore.pairs;
const { pairs } = this.getStore();
this._isHeaderSent = true;
const index = _crypto2.default.randomBytes(1)[0] % pairs.length;
const request = pairs[index].request;
const { request } = pairs[index];
return Buffer.concat([request, buffer]);
} else {
return buffer;

@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
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 _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
@ -54,12 +52,7 @@ class SsAeadCipherPreset extends _defs.IPreset {
}
onInit({ method }) {
var _ciphers$method = _slicedToArray(ciphers[method], 3);
const keySize = _ciphers$method[0],
saltSize = _ciphers$method[1],
nonceSize = _ciphers$method[2];
const [keySize, saltSize, nonceSize] = ciphers[method];
this._cipherName = method;
this._keySize = keySize;
this._saltSize = saltSize;
@ -87,19 +80,8 @@ class SsAeadCipherPreset extends _defs.IPreset {
}
const chunks = (0, _utils.getRandomChunks)(buffer, MIN_CHUNK_SPLIT_LEN, MAX_CHUNK_SPLIT_LEN).map(chunk => {
const dataLen = (0, _utils.numberToBuffer)(chunk.length);
var _encrypt = this.encrypt(dataLen),
_encrypt2 = _slicedToArray(_encrypt, 2);
const encLen = _encrypt2[0],
lenTag = _encrypt2[1];
var _encrypt3 = this.encrypt(chunk),
_encrypt4 = _slicedToArray(_encrypt3, 2);
const encData = _encrypt4[0],
dataTag = _encrypt4[1];
const [encLen, lenTag] = this.encrypt(dataLen);
const [encData, dataTag] = this.encrypt(chunk);
return Buffer.concat([encLen, lenTag, encData, dataTag]);
});
if (salt) {
@ -128,10 +110,7 @@ class SsAeadCipherPreset extends _defs.IPreset {
return;
}
var _ref = [buffer.slice(0, 2), buffer.slice(2, 2 + TAG_SIZE)];
const encLen = _ref[0],
lenTag = _ref[1];
const [encLen, lenTag] = [buffer.slice(0, 2), buffer.slice(2, 2 + TAG_SIZE)];
const dataLenBuf = this.decrypt(encLen, lenTag);
if (dataLenBuf === null) {
fail(`unexpected DataLen_TAG=${lenTag.toString('hex')} when verify DataLen=${encLen.toString('hex')}, dump=${buffer.slice(0, 60).toString('hex')}`);
@ -146,10 +125,7 @@ class SsAeadCipherPreset extends _defs.IPreset {
}
onChunkReceived(chunk, { next, fail }) {
var _ref2 = [chunk.slice(2 + TAG_SIZE, -TAG_SIZE), chunk.slice(-TAG_SIZE)];
const encData = _ref2[0],
dataTag = _ref2[1];
const [encData, dataTag] = [chunk.slice(2 + TAG_SIZE, -TAG_SIZE), chunk.slice(-TAG_SIZE)];
const data = this.decrypt(encData, dataTag);
if (data === null) {
return fail(`unexpected Data_TAG=${dataTag.toString('hex')} when verify Data=${encData.slice(0, 60).toString('hex')}, dump=${chunk.slice(0, 60).toString('hex')}`);
@ -207,13 +183,7 @@ class SsAeadCipherPreset extends _defs.IPreset {
const salt = _crypto2.default.randomBytes(this._saltSize);
this._cipherKey = (0, _utils.HKDF)(HKDF_HASH_ALGORITHM, salt, this._evpKey, this._info, this._keySize);
this._cipherNonce = 0;
var _encrypt5 = this.encrypt(buffer),
_encrypt6 = _slicedToArray(_encrypt5, 2);
const ciphertext = _encrypt6[0],
tag = _encrypt6[1];
const [ciphertext, tag] = this.encrypt(buffer);
return Buffer.concat([salt, ciphertext, tag]);
}
@ -228,10 +198,7 @@ class SsAeadCipherPreset extends _defs.IPreset {
if (buffer.length < saltSize + TAG_SIZE + 1) {
return fail(`too short to verify Data, len=${buffer.length} dump=${buffer.toString('hex')}`);
}
var _ref3 = [buffer.slice(saltSize, -TAG_SIZE), buffer.slice(-TAG_SIZE)];
const encData = _ref3[0],
dataTag = _ref3[1];
const [encData, dataTag] = [buffer.slice(saltSize, -TAG_SIZE), buffer.slice(-TAG_SIZE)];
const data = this.decrypt(encData, dataTag);
if (data === null) {
return fail(`unexpected Data_TAG=${dataTag.toString('hex')} when verify Data=${encData.slice(0, 60).toString('hex')}, dump=${buffer.slice(0, 60).toString('hex')}`);

@ -53,10 +53,7 @@ class SsBasePreset extends _defs.IPresetAddressing {
onNotified(action) {
if (this._config.is_client && action.type === _actions.CONNECT_TO_REMOTE) {
var _action$payload = action.payload;
const host = _action$payload.host,
port = _action$payload.port;
const { host, port } = action.payload;
const type = getHostType(host);
this._atyp = type;
this._port = (0, _utils.numberToBuffer)(port);
@ -134,9 +131,7 @@ class SsBasePreset extends _defs.IPresetAddressing {
return;
}
const host = decoded.host,
port = decoded.port,
data = decoded.data;
const { host, port, data } = decoded;
this._isConnecting = true;
broadcast({
@ -167,10 +162,7 @@ class SsBasePreset extends _defs.IPresetAddressing {
if (!decoded) {
return;
}
const host = decoded.host,
port = decoded.port,
data = decoded.data;
const { host, port, data } = decoded;
this._atyp = getHostType(host);
this._host = this._atyp === ATYP_DOMAIN ? Buffer.from(host) : _ip2.default.toBuffer(host);
this._port = (0, _utils.numberToBuffer)(port);

@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
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 _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
@ -54,11 +52,7 @@ class SsStreamCipherPreset extends _defs.IPreset {
}
onInit({ method }) {
var _ciphers$method = _slicedToArray(ciphers[method], 2);
const keySize = _ciphers$method[0],
ivSize = _ciphers$method[1];
const [keySize, ivSize] = ciphers[method];
const iv = _crypto2.default.randomBytes(ivSize);
this._algorithm = ['rc4-md5', 'rc4-md5-6'].includes(method) ? 'rc4' : method;
this._keySize = keySize;
@ -115,8 +109,7 @@ class SsStreamCipherPreset extends _defs.IPreset {
beforeIn({ buffer, fail }) {
if (!this._decipher) {
const _ivSize = this._ivSize;
const { _ivSize } = this;
if (buffer.length < _ivSize) {
return fail(`buffer is too short to get iv, len=${buffer.length} dump=${(0, _utils.dumpHex)(buffer)}`);
}
@ -135,8 +128,7 @@ class SsStreamCipherPreset extends _defs.IPreset {
}
beforeInUdp({ buffer, fail }) {
const _ivSize = this._ivSize;
const { _ivSize } = this;
if (buffer.length < _ivSize) {
return fail(`buffer is too short to get iv, len=${buffer.length} dump=${(0, _utils.dumpHex)(buffer)}`);
}

@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
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 _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
@ -91,12 +89,7 @@ const MAX_TIME_DIFF = 30;class SsrAuthAes128Preset extends _defs.IPreset {
createChunks(buffer) {
const userKey = this._userKey;
return (0, _utils.getRandomChunks)(buffer, 0x1fff - 0xff - 8 - 3, 0x2000 - 0xff - 8 - 3).map(payload => {
var _crypto$randomBytes = _crypto2.default.randomBytes(2),
_crypto$randomBytes2 = _slicedToArray(_crypto$randomBytes, 2);
const first = _crypto$randomBytes2[0],
len = _crypto$randomBytes2[1];
const [first, len] = _crypto2.default.randomBytes(2);
let random_bytes = null;
if (first < 128) {
random_bytes = Buffer.concat([Buffer.from([len + 1]), _crypto2.default.randomBytes(len)]);

@ -84,8 +84,7 @@ class V2rayVmessPreset extends _defs.IPresetAddressing {
const to = now + TIME_TOLERANCE;
let newItems = [];
if (items.length !== 0) {
const end = items[items.length - 1].timestamp;
const { timestamp: end } = items[items.length - 1];
newItems = items.slice(now - end - TIME_TOLERANCE - 1);
from = end + 1;
}
@ -123,10 +122,7 @@ class V2rayVmessPreset extends _defs.IPresetAddressing {
onNotified(action) {
if (this._config.is_client && action.type === _actions.CONNECT_TO_REMOTE) {
var _action$payload = action.payload;
const host = _action$payload.host,
port = _action$payload.port;
const { host, port } = action.payload;
const type = getAddrType(host);
this._atyp = type;
this._port = (0, _utils.numberToBuffer)(port);
@ -175,10 +171,7 @@ class V2rayVmessPreset extends _defs.IPresetAddressing {
}
const uuid = this._uuid;
var _getStore = this.getStore();
const userHashCache = _getStore.userHashCache;
const { userHashCache } = this.getStore();
const authInfo = buffer.slice(0, 16);
const cacheItem = userHashCache.find(({ authInfo: auth }) => auth.equals(authInfo));
@ -304,13 +297,9 @@ class V2rayVmessPreset extends _defs.IPresetAddressing {
this._opt = 0x05;
const uuid = this._uuid;
const { userHashCache } = this.getStore();
var _getStore2 = this.getStore();
const userHashCache = _getStore2.userHashCache;
var _userHashCache$getRan = userHashCache[(0, _utils.getRandomInt)(0, userHashCache.length - 1)];
const timestamp = _userHashCache$getRan.timestamp,
authInfo = _userHashCache$getRan.authInfo;
const { timestamp, authInfo } = userHashCache[(0, _utils.getRandomInt)(0, userHashCache.length - 1)];
const ts = (0, _utils.numberToBuffer)(timestamp, 8);

@ -21,16 +21,8 @@ function createServer() {
const server = _http2.default.createServer();
server.on('request', (req, res) => {
var _url$parse = _url2.default.parse(req.url);
const hostname = _url$parse.hostname,
port = _url$parse.port,
path = _url$parse.path;
const socket = req.socket,
method = req.method,
httpVersion = req.httpVersion,
headers = req.headers;
const { hostname, port, path } = _url2.default.parse(req.url);
const { socket, method, httpVersion, headers } = req;
const _port = +port || 80;
@ -51,32 +43,10 @@ function createServer() {
const headerKeys = Object.keys(headers);
const _headers = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = headerKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const key = _step.value;
const value = headers[key];
_headers.push(`${key}: ${value}\r\n`);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
for (const key of headerKeys) {
const value = headers[key];
_headers.push(`${key}: ${value}\r\n`);
}
const reqMsg = `${method} ${path} HTTP/${httpVersion}\r\n` + _headers.join('') + '\r\n';
send(Buffer.from(reqMsg));
@ -86,11 +56,7 @@ function createServer() {
});
server.on('connect', (req, socket) => {
var _url$parse2 = _url2.default.parse(`http://${req.url}`);
const hostname = _url$parse2.hostname,
port = _url$parse2.port;
const { hostname, port } = _url2.default.parse(`http://${req.url}`);
const _port = +port || 443;
@ -110,9 +76,7 @@ function createServer() {
});
server.on('clientError', (err, socket) => {
const remoteAddress = socket.remoteAddress,
remotePort = socket.remotePort;
const { remoteAddress, remotePort } = socket;
_utils.logger.error(`[http] [${remoteAddress}:${remotePort}] invalid http request: ${err.message}`);
socket.destroy();
});

@ -156,36 +156,14 @@ function parseSocks4Request(buffer) {
const rest = buffer.slice(8);
const fields = [];
let field = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = rest[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const byte = _step.value;
if (byte === NOOP) {
fields.push(field);
field = [];
} else {
field.push(byte);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
for (const byte of rest) {
if (byte === NOOP) {
fields.push(field);
field = [];
} else {
field.push(byte);
}
}
if (fields.length !== 2 || fields[1].length < 1) {
return null;
}
@ -237,10 +215,7 @@ function createServer({ bindAddress, bindPort }) {
request = parseSocks4Request(buffer);
if (request !== null) {
stage = STAGE_DONE;
var _request = request;
const host = _request.host,
port = _request.port;
const { host, port } = request;
server.emit('proxyConnection', socket, {
host: host,
port: port,
@ -271,10 +246,7 @@ function createServer({ bindAddress, bindPort }) {
}
case REQUEST_COMMAND_CONNECT:
{
var _request2 = request;
const host = _request2.host,
port = _request2.port;
const { host, port } = request;
server.emit('proxyConnection', socket, {
host: host,
port: port,

@ -10,7 +10,7 @@ Object.keys(_tcp).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _tcp[key];
}
});
@ -22,7 +22,7 @@ Object.keys(_udp).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _udp[key];
}
});
@ -34,7 +34,7 @@ Object.keys(_tls).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _tls[key];
}
});
@ -46,7 +46,7 @@ Object.keys(_ws).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _ws[key];
}
});
@ -58,7 +58,7 @@ Object.keys(_mux).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _mux[key];
}
});

@ -13,8 +13,6 @@ var _utils = require('../utils');
var _actions = require('../presets/actions');
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"); }); }; }
class MuxInbound extends _defs.Inbound {
constructor(props) {
@ -62,16 +60,9 @@ class MuxInbound extends _defs.Inbound {
}
}
onPresetFailed(action) {
var _this = this;
return _asyncToGenerator(function* () {
var _action$payload = action.payload;
const name = _action$payload.name,
message = _action$payload.message;
_utils.logger.error(`[${_this.name}] [${_this.remote}] preset "${name}" fail to process: ${message}`);
})();
async onPresetFailed(action) {
const { name, message } = action.payload;
_utils.logger.error(`[${this.name}] [${this.remote}] preset "${name}" fail to process: ${message}`);
}
onDrain() {
@ -80,10 +71,7 @@ class MuxInbound extends _defs.Inbound {
write(buffer) {
if (this._config.is_server) {
var _ctx = this.ctx;
const muxRelay = _ctx.muxRelay,
cid = _ctx.cid;
const { muxRelay, cid } = this.ctx;
muxRelay.encode(buffer, { cid });
}
}
@ -95,10 +83,7 @@ class MuxInbound extends _defs.Inbound {
close() {
const doClose = () => {
if (this._config.is_server) {
var _ctx2 = this.ctx;
const muxRelay = _ctx2.muxRelay,
cid = _ctx2.cid;
const { muxRelay, cid } = this.ctx;
const inbound = muxRelay.getInbound();
if (inbound) {
inbound.removeListener('drain', this.onDrain);
@ -153,11 +138,7 @@ class MuxOutbound extends _defs.Outbound {
write(buffer) {
if (this._config.is_client) {
var _ctx3 = this.ctx;
const muxRelay = _ctx3.muxRelay,
proxyRequest = _ctx3.proxyRequest,
cid = _ctx3.cid;
const { muxRelay, proxyRequest, cid } = this.ctx;
if (this._isFirstFrame) {
this._isFirstFrame = false;
muxRelay.encode(buffer, _extends({ cid }, proxyRequest));
@ -174,10 +155,7 @@ class MuxOutbound extends _defs.Outbound {
close() {
const doClose = () => {
if (this._config.is_client) {
var _ctx4 = this.ctx;
const muxRelay = _ctx4.muxRelay,
cid = _ctx4.cid;
const { muxRelay, cid } = this.ctx;
const outbound = muxRelay.getOutbound();
if (outbound) {
outbound.removeListener('drain', this.onDrain);

@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
exports.TcpOutbound = exports.TcpInbound = 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 _net = require('net');
var _net2 = _interopRequireDefault(_net);
@ -23,8 +21,6 @@ var _actions = require('../presets/actions');
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"); }); }; }
class TcpInbound extends _defs.Inbound {
constructor(props) {
@ -157,48 +153,35 @@ class TcpInbound extends _defs.Inbound {
}
}
onPresetFailed(action) {
var _this = this;
async onPresetFailed(action) {
const { name, message } = action.payload;
_utils.logger.error(`[${this.name}] [${this.remote}] preset "${name}" fail to process: ${message}`);
return _asyncToGenerator(function* () {
var _action$payload = action.payload;
const name = _action$payload.name,
message = _action$payload.message;
if (this._config.is_client) {
_utils.logger.warn(`[${this.name}] [${this.remote}] connection closed`);
this.onClose();
}
_utils.logger.error(`[${_this.name}] [${_this.remote}] preset "${name}" fail to process: ${message}`);
if (this._config.is_server && !this._config.mux) {
if (this._config.redirect) {
const { orgData } = action.payload;
const [host, port] = this._config.redirect.split(':');
if (_this._config.is_client) {
_utils.logger.warn(`[${_this.name}] [${_this.remote}] connection closed`);
_this.onClose();
}
_utils.logger.warn(`[${this.name}] [${this.remote}] connection is redirecting to: ${host}:${port}`);
if (_this._config.is_server && !_this._config.mux) {
if (_this._config.redirect) {
const orgData = action.payload.orgData;
this.updatePresets([{ name: 'tracker' }]);
var _config$redirect$spli = _this._config.redirect.split(':'),
_config$redirect$spli2 = _slicedToArray(_config$redirect$spli, 2);
const host = _config$redirect$spli2[0],
port = _config$redirect$spli2[1];
_utils.logger.warn(`[${_this.name}] [${_this.remote}] connection is redirecting to: ${host}:${port}`);
_this.updatePresets([{ name: 'tracker' }]);
yield _this._outbound.connect({ host, port: +port });
if (_this._outbound.writable) {
_this._outbound.write(orgData);
}
} else {
_this._socket && _this._socket.pause();
const timeout = (0, _utils.getRandomInt)(10, 40);
_utils.logger.warn(`[${_this.name}] [${_this.remote}] connection will be closed in ${timeout}s...`);
setTimeout(_this.onClose, timeout * 1e3);
await this._outbound.connect({ host, port: +port });
if (this._outbound.writable) {
this._outbound.write(orgData);
}
} else {
this._socket && this._socket.pause();
const timeout = (0, _utils.getRandomInt)(10, 40);
_utils.logger.warn(`[${this.name}] [${this.remote}] connection will be closed in ${timeout}s...`);
setTimeout(this.onClose, timeout * 1e3);
}
})();
}
}
}
@ -316,71 +299,54 @@ class TcpOutbound extends _defs.Outbound {
}
}
onConnectToRemote(action) {
var _this2 = this;
return _asyncToGenerator(function* () {
var _action$payload2 = action.payload;
const host = _action$payload2.host,
port = _action$payload2.port,
keepAlive = _action$payload2.keepAlive,
onConnected = _action$payload2.onConnected;
if (!keepAlive || !_this2._socket) {
try {
if (_this2._config.is_server) {
yield _this2.connect({ host, port });
}
if (_this2._config.is_client) {
yield _this2.connect({ host: _this2._config.server_host, port: _this2._config.server_port });
}
_this2._socket.on('connect', function () {
if (typeof onConnected === 'function') {
onConnected(function (buffer) {
if (buffer) {
const type = _this2._config.is_client ? _constants.PIPE_ENCODE : _constants.PIPE_DECODE;
_this2.ctx.pipe.feed(type, buffer, { cid: _this2.ctx.proxyRequest.cid, host, port });
}
});
}
_this2.ctx.pipe.broadcast(null, { type: _actions.CONNECTED_TO_REMOTE, payload: { host, port } });
});
} catch (err) {
_utils.logger.warn(`[${_this2.name}] [${_this2.remote}] cannot connect to ${host}:${port},`, err);
_this2.onClose();
async onConnectToRemote(action) {
const { host, port, keepAlive, onConnected } = action.payload;
if (!keepAlive || !this._socket) {
try {
if (this._config.is_server) {
await this.connect({ host, port });
}
} else {
_this2.ctx.pipe.broadcast(null, { type: _actions.CONNECTED_TO_REMOTE, payload: { host, port } });
if (this._config.is_client) {
await this.connect({ host: this._config.server_host, port: this._config.server_port });
}
this._socket.on('connect', () => {
if (typeof onConnected === 'function') {
onConnected(buffer => {
if (buffer) {
const type = this._config.is_client ? _constants.PIPE_ENCODE : _constants.PIPE_DECODE;
this.ctx.pipe.feed(type, buffer, { cid: this.ctx.proxyRequest.cid, host, port });
}
});
}
this.ctx.pipe.broadcast(null, { type: _actions.CONNECTED_TO_REMOTE, payload: { host, port } });
});
} catch (err) {
_utils.logger.warn(`[${this.name}] [${this.remote}] cannot connect to ${host}:${port},`, err);
this.onClose();
}
})();
} else {
this.ctx.pipe.broadcast(null, { type: _actions.CONNECTED_TO_REMOTE, payload: { host, port } });
}
}
connect({ host, port }) {
var _this3 = this;
return _asyncToGenerator(function* () {
if (_this3._socket && !_this3._socket.destroyed) {
_this3._socket.destroy();
}
_this3._socket = yield _this3._connect({ host, port });
_this3._socket.on('error', _this3.onError);
_this3._socket.on('end', _this3.onHalfClose);
_this3._socket.on('close', _this3.onClose);
_this3._socket.on('timeout', _this3.onTimeout);
_this3._socket.on('data', _this3.onReceive);
_this3._socket.on('drain', _this3.onDrain);
_this3._socket.setTimeout(_this3._config.timeout);
})();
async connect({ host, port }) {
if (this._socket && !this._socket.destroyed) {
this._socket.destroy();
}
this._socket = await this._connect({ host, port });
this._socket.on('error', this.onError);
this._socket.on('end', this.onHalfClose);
this._socket.on('close', this.onClose);
this._socket.on('timeout', this.onTimeout);
this._socket.on('data', this.onReceive);
this._socket.on('drain', this.onDrain);
this._socket.setTimeout(this._config.timeout);
}
_connect({ host, port }) {
var _this4 = this;
return _asyncToGenerator(function* () {
const ip = yield _utils.DNSCache.get(host);
_utils.logger.info(`[${_this4.name}] [${_this4.remote}] connecting to tcp://${host}:${port} resolved=${ip}`);
return _net2.default.connect({ host: ip, port });
})();
async _connect({ host, port }) {
const ip = await _utils.DNSCache.get(host);
_utils.logger.info(`[${this.name}] [${this.remote}] connecting to tcp://${host}:${port} resolved=${ip}`);
return _net2.default.connect({ host: ip, port });
}
}

@ -15,8 +15,6 @@ var _utils = require('../utils');
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"); }); }; }
class TlsInbound extends _tcp.TcpInbound {
get name() {
@ -40,13 +38,9 @@ class TlsOutbound extends _tcp.TcpOutbound {
return super.bufferSize - 1;
}
_connect({ host, port }) {
var _this = this;
return _asyncToGenerator(function* () {
_utils.logger.info(`[tls:outbound] [${_this.remote}] connecting to tls://${host}:${port}`);
return _tls2.default.connect({ host, port, ca: [_this._config.tls_cert] });
})();
async _connect({ host, port }) {
_utils.logger.info(`[tls:outbound] [${this.remote}] connecting to tls://${host}:${port}`);
return _tls2.default.connect({ host, port, ca: [this._config.tls_cert] });
}
}

@ -47,10 +47,7 @@ class UdpInbound extends _defs.Inbound {
}
onPresetFailed(action) {
var _action$payload = action.payload;
const name = _action$payload.name,
message = _action$payload.message;
const { name, message } = action.payload;
_utils.logger.error(`[udp:inbound] [${this.remote}] preset "${name}" fail to process: ${message}`);
if (this._outbound) {
this._outbound.close();
@ -61,10 +58,7 @@ class UdpInbound extends _defs.Inbound {
}
write(buffer) {
var _rinfo = this._rinfo;
const address = _rinfo.address,
port = _rinfo.port;
const { address, port } = this._rinfo;
const onSendError = err => {
if (err) {
_utils.logger.warn(`[udp:inbound] [${this.remote}]:`, err);
@ -134,11 +128,7 @@ class UdpOutbound extends _defs.Outbound {
}
onConnectToRemote(action) {
var _action$payload2 = action.payload;
const host = _action$payload2.host,
port = _action$payload2.port,
onConnected = _action$payload2.onConnected;
const { host, port, onConnected } = action.payload;
if (this._config.is_client) {
this._targetHost = this._config.server_host;
this._targetPort = this._config.server_port;

@ -15,8 +15,6 @@ var _utils = require('../utils');
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"); }); }; }
function patchWebsocket(ws) {
ws.write = buffer => ws.send(buffer, {
compress: false,
@ -70,18 +68,12 @@ class WsOutbound extends _tcp.TcpOutbound {
return this._socket && this._socket.readyState === _ws2.default.OPEN;
}
_connect({ host, port }) {
var _this = this;
return _asyncToGenerator(function* () {
_utils.logger.info(`[${_this.name}] [${_this.remote}] connecting to ws://${host}:${port}`);
const socket = new _ws2.default(`ws://${host}:${port}`, { perMessageDeflate: false });
socket.on('message', _this.onReceive);
socket.on('close', function () {
return socket.destroyed = true;
});
return patchWebsocket.call(_this, socket);
})();
async _connect({ host, port }) {
_utils.logger.info(`[${this.name}] [${this.remote}] connecting to ws://${host}:${port}`);
const socket = new _ws2.default(`ws://${host}:${port}`, { perMessageDeflate: false });
socket.on('message', this.onReceive);
socket.on('close', () => socket.destroyed = true);
return patchWebsocket.call(this, socket);
}
}

@ -5,26 +5,6 @@ Object.defineProperty(exports, "__esModule", {
});
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"); } }; }();
let lookup = (() => {
var _ref = _asyncToGenerator(function* (hostname) {
return new Promise(function (resolve, reject) {
_dns2.default.lookup(hostname, function (err, address) {
if (err) {
reject(err);
} else {
resolve(address);
}
});
});
});
return function lookup(_x) {
return _ref.apply(this, arguments);
};
})();
var _dns = require('dns');
var _dns2 = _interopRequireDefault(_dns);
@ -37,7 +17,17 @@ var _logger = require('./logger');
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"); }); }; }
async function lookup(hostname) {
return new Promise((resolve, reject) => {
_dns2.default.lookup(hostname, function (err, address) {
if (err) {
reject(err);
} else {
resolve(address);
}
});
});
}
function now() {
return Date.now();
@ -54,30 +44,24 @@ class DNSCache {
DNSCache.pool = {};
}
static get(hostname) {
return _asyncToGenerator(function* () {
if (_net2.default.isIP(hostname)) {
return hostname;
static async get(hostname) {
if (_net2.default.isIP(hostname)) {
return hostname;
}
let address = null;
if (!DNSCache.pool[hostname]) {
address = await lookup(hostname);
DNSCache._put(hostname, address);
} else {
const [addr, expire] = DNSCache.pool[hostname];
const _now = now();
if (_now >= expire) {
delete DNSCache.pool[hostname];
}
let address = null;
if (!DNSCache.pool[hostname]) {
address = yield lookup(hostname);
DNSCache._put(hostname, address);
} else {
var _DNSCache$pool$hostna = _slicedToArray(DNSCache.pool[hostname], 2);
const addr = _DNSCache$pool$hostna[0],
expire = _DNSCache$pool$hostna[1];
const _now = now();
if (_now >= expire) {
delete DNSCache.pool[hostname];
}
_logger.logger.verbose(`[dns-cache] hit: hostname=${hostname} resolved=${addr} ttl=${expire - _now}ms`);
address = addr;
}
return address;
})();
_logger.logger.verbose(`[dns-cache] hit: hostname=${hostname} resolved=${addr} ttl=${expire - _now}ms`);
address = addr;
}
return address;
}
static clear() {

@ -10,7 +10,7 @@ Object.keys(_common).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _common[key];
}
});
@ -22,7 +22,7 @@ Object.keys(_crypto).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _crypto[key];
}
});
@ -34,7 +34,7 @@ Object.keys(_date).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _date[key];
}
});
@ -46,7 +46,7 @@ Object.keys(_dnsCache).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _dnsCache[key];
}
});
@ -58,7 +58,7 @@ Object.keys(_string).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _string[key];
}
});
@ -70,7 +70,7 @@ Object.keys(_validator).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _validator[key];
}
});
@ -82,7 +82,7 @@ Object.keys(_advancedBuffer).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _advancedBuffer[key];
}
});
@ -94,7 +94,7 @@ Object.keys(_logger).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
get: function () {
return _logger[key];
}
});

@ -94,7 +94,7 @@
"author": "Micooz <micooz@hotmail.com>",
"license": "Apache-2.0",
"engines": {
"node": ">= 6"
"node": ">= 8"
},
"jest": {
"coverageDirectory": "./coverage/",