lib: make compile target to Node.js 8
This commit is contained in:
parent
8b00b8a897
commit
0ddfd2463b
2
.babelrc
2
.babelrc
@ -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
|
||||
|
||||
|
114
lib/core/acl.js
114
lib/core/acl.js
@ -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');
|
||||
}
|
||||
|
362
lib/core/hub.js
362
lib/core/hub.js
@ -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
lib/index.js
10
lib/index.js
@ -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/",
|
||||
|
Loading…
Reference in New Issue
Block a user