Comparing version 2.1.3 to 2.1.4
{ | ||
"name": "js2ray", | ||
"version": "2.1.3", | ||
"version": "2.1.4", | ||
"description": "The v2ray vmess protocol, based on nodejs javascript which you can use on hosts and servers", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -137,3 +137,3 @@ | ||
} | ||
function Match(AuthIDDecoderHolder, authID) { | ||
function Match(AuthIDDecoderHolder, authID) { | ||
for (var v in AuthIDDecoderHolder.decoders) { | ||
@@ -159,4 +159,3 @@ var decode = Decode(AuthIDDecoderHolder.decoders[v].dec, authID) | ||
return undefined | ||
} | ||
} | ||
// ====================================================== FUNCTIONS | ||
@@ -163,0 +162,0 @@ |
@@ -225,2 +225,3 @@ | ||
} | ||
function DecodeResponseBody(chunk, app) { | ||
@@ -241,29 +242,50 @@ if ([consts.SECURITY_TYPE_AES_128_GCM, consts.SECURITY_TYPE_CHACHA20_POLY1305].includes(app._security)) { | ||
// ================================================= functions | ||
// ================================================= functions | ||
function resolveChunk(chunk) { | ||
let _chunk = chunk; | ||
if ([consts.SECURITY_TYPE_AES_128_GCM, consts.SECURITY_TYPE_CHACHA20_POLY1305].includes(this._security)) { | ||
_chunk = common.encrypt(_chunk, this); | ||
_chunk = common.encrypt(_chunk, this) | ||
} | ||
let _len = _chunk.length; | ||
if (this._option >= 0x05) { | ||
const mask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
_len = mask ^ _len; | ||
if (this._option >= 0x01) { | ||
let _len = _chunk.length; | ||
var pad = 0 | ||
if (this._option >= 0x05) { | ||
if (this._option >= 0x08) { | ||
const padmask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
pad = (padmask % 64) | ||
} | ||
const mask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
_len = mask ^ (_len + pad); | ||
} | ||
if (pad == 0) | ||
_chunk = Buffer.concat([common.ntb(_len), _chunk]); | ||
else | ||
_chunk = Buffer.concat([common.ntb(_len), _chunk, crypto.randomBytes(pad)]); | ||
} | ||
return Buffer.concat([common.ntb(_len), _chunk]); | ||
return _chunk | ||
} | ||
function onReceivingLength(buffer, app) { | ||
if (buffer.length < 2) { | ||
var len = buffer.length | ||
if (len < 2) { | ||
return; | ||
} | ||
let len = buffer.readUInt16BE(0); | ||
if (app._option >= 0x05) { | ||
const mask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
len = mask ^ len; | ||
if (app._option >= 0x01) { | ||
len = buffer.readUInt16BE(0); | ||
if (app._option >= 0x05) { | ||
var pad = 0 | ||
if (app._option >= 0x08) { | ||
const padmask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
pad = (padmask % 64) | ||
} | ||
app.paddingLenght = pad | ||
const mask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
len = (mask ^ len); | ||
} | ||
len += 2; | ||
} | ||
return 2 + len; | ||
return len | ||
} | ||
function getAddrType(host) { | ||
@@ -270,0 +292,0 @@ if (net.isIPv4(host)) { |
@@ -172,5 +172,5 @@ | ||
} | ||
if (user.maxip) | ||
user.maxip = false | ||
} | ||
if (user.maxip) | ||
user.maxip = false | ||
user.ipList[ip] = now | ||
@@ -177,0 +177,0 @@ } |
@@ -47,3 +47,3 @@ | ||
if (buffer.length < 16) { | ||
return log(`fail to parse request header: ${buffer.toString("hex")}`,1); | ||
return log(`fail to parse request header: ${buffer.toString("hex")}`, 1); | ||
} | ||
@@ -57,3 +57,3 @@ | ||
if (user == undefined) | ||
return log(`cannot find ${buffer.subarray(0, 16).toString("hex")} in cache, maybe a wrong auth info`,1); | ||
return log(`cannot find ${buffer.subarray(0, 16).toString("hex")} in cache, maybe a wrong auth info`, 1); | ||
var ts = user[1] | ||
@@ -73,3 +73,3 @@ aeadUser = user[0] | ||
if (decipher == undefined) { | ||
return log(`AEAD read failed`,1) | ||
return log(`AEAD read failed`, 1) | ||
} | ||
@@ -79,16 +79,16 @@ app.user = aeadUser | ||
} else { | ||
return log(`invalid user`,1); | ||
return log(`invalid user`, 1); | ||
} | ||
if (aeadUser.ipCount != 0 && common.iplimit(app.ip, aeadUser)) | ||
return log(`maximum ip used by user ${aeadUser.id.UUID.toString("hex")}`,1) | ||
return log(`maximum ip used by user ${aeadUser.id.UUID.toString("hex")}`, 1) | ||
if (aeadUser.traffic != 0 && common.trafficlimit(aeadUser)) { | ||
return log(`maximum traffic ${aeadUser.traffic / 1024 / 1024}MB (bytesRead:${aeadUser.bytesRead},bytesWrit:${aeadUser.bytesWrit}) used by user ${aeadUser.id.UUID.toString("hex")}`,1) | ||
return log(`maximum traffic ${aeadUser.traffic / 1024 / 1024}MB (bytesRead:${aeadUser.bytesRead},bytesWrit:${aeadUser.bytesWrit}) used by user ${aeadUser.id.UUID.toString("hex")}`, 1) | ||
} | ||
if (aeadUser.expire && aeadUser.expire < new Date().getTime()) { | ||
return log(`expire user ${aeadUser.id.UUID.toString("hex")}`,1) | ||
return log(`expire user ${aeadUser.id.UUID.toString("hex")}`, 1) | ||
} | ||
if (reqCommand.length < 41) { | ||
return log(`request command is too short: ${reqCommand.length}bytes, command=${reqCommand.toString('hex')}`,1); | ||
return log(`request command is too short: ${reqCommand.length}bytes, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
@@ -100,3 +100,3 @@ | ||
if (ver !== 0x01) { | ||
return log(`invalid version number: ${ver}`,1); | ||
return log(`invalid version number: ${ver}`, 1); | ||
} | ||
@@ -132,3 +132,3 @@ | ||
if (!(aeadUser.security == 2 || aeadUser.security == undefined || securityType == 2) && securityType != aeadUser.security) { | ||
return log(`not match securety type`,1); | ||
return log(`not match securety type`, 1); | ||
} | ||
@@ -140,43 +140,50 @@ if (securityType == consts.SECURITY_TYPE_CHACHA20_POLY1305) { | ||
//=========== | ||
const cmd = reqHeader[37]; | ||
let offset = 40; | ||
var cmd = reqHeader[37]; | ||
if (![0x01, 0x02].includes(cmd)) { | ||
return log(`unsupported cmd: ${cmd}`,1); | ||
return log(`unsupported cmd: ${cmd}`, 1); | ||
} | ||
const port = reqHeader.readUInt16BE(38); | ||
const addrType = reqHeader[40]; | ||
let addr = null; | ||
let offset = 40; | ||
if (addrType === ATYP_V4) { | ||
if (reqCommand.length < 45) { | ||
return log(`request command is too short ${reqCommand.length}bytes to get ipv4, command=${reqCommand.toString('hex')}`,1); | ||
} | ||
if (cmd == 0x03) { | ||
var port = 0 | ||
var addr = "v1.mux.cool" | ||
var addrType = ATYP_DOMAIN | ||
} | ||
else { | ||
var port = reqHeader.readUInt16BE(38); | ||
var addrType = reqHeader[40]; | ||
var addr = null; | ||
if (addrType === ATYP_V4) { | ||
if (reqCommand.length < 45) { | ||
return log(`request command is too short ${reqCommand.length}bytes to get ipv4, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
addr = decipher.subarray(41, 45); | ||
offset += 4; | ||
} else if (addrType === ATYP_V6) { | ||
if (reqCommand.length < 57) { | ||
return log(`request command is too short: ${reqCommand.length}bytes to get ipv6, command=${reqCommand.toString('hex')}`,1); | ||
} | ||
addr = decipher.subarray(41, 45); | ||
offset += 4; | ||
} else if (addrType === ATYP_V6) { | ||
if (reqCommand.length < 57) { | ||
return log(`request command is too short: ${reqCommand.length}bytes to get ipv6, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
addr = decipher.subarray(41, 57); | ||
offset += 16; | ||
} else if (addrType === ATYP_DOMAIN) { | ||
if (reqCommand.length < 42) { | ||
return log(`request command is too short: ${reqCommand.length}bytes to get host name, command=${reqCommand.toString('hex')}`,1); | ||
} | ||
addr = decipher.subarray(41, 57); | ||
offset += 16; | ||
} else if (addrType === ATYP_DOMAIN) { | ||
if (reqCommand.length < 42) { | ||
return log(`request command is too short: ${reqCommand.length}bytes to get host name, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
const addrLen = decipher.subarray(41, 42)[0]; | ||
const addrLen = decipher.subarray(41, 42)[0]; | ||
if (reqCommand.length < 42 + addrLen) { | ||
return log(`request command is too short: ${reqCommand.length}bytes, command=${reqCommand.toString('hex')}`,1); | ||
if (reqCommand.length < 42 + addrLen) { | ||
return log(`request command is too short: ${reqCommand.length}bytes, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
addr = decipher.subarray(42, 42 + addrLen); | ||
offset += 1 + addrLen; | ||
} else { | ||
return log(`unknown address type: ${addrType}, command=${reqHeader.toString('hex')}`, 1); | ||
} | ||
addr = decipher.subarray(42, 42 + addrLen); | ||
offset += 1 + addrLen; | ||
} else { | ||
return log(`unknown address type: ${addrType}, command=${reqHeader.toString('hex')}`,1); | ||
} | ||
if (reqCommand.length < offset + paddingLen + 4) { | ||
return log(`request command is too short: ${reqCommand.length}bytes to get padding and f, command=${reqCommand.toString('hex')}`,1); | ||
return log(`request command is too short: ${reqCommand.length}bytes to get padding and f, command=${reqCommand.toString('hex')}`, 1); | ||
} | ||
@@ -191,3 +198,3 @@ | ||
if (common.fnv1a(plainReqHeader).equals(f)) { | ||
return log('fail to verify request command',1); | ||
return log('fail to verify request command', 1); | ||
} | ||
@@ -216,5 +223,5 @@ const data = buffer.subarray(dataoffset + plainReqHeader.length + 4); | ||
if (app.user.traffic != 0 && common.trafficlimit(app.user)) | ||
return log(`maximum traffic ${app.user.traffic / 1024 / 1024}MB (bytesRead:${app.user.bytesRead},bytesWrit:${app.user.bytesWrit}) used by user ${app.user.id.UUID.toString("hex")}`,1); | ||
return log(`maximum traffic ${app.user.traffic / 1024 / 1024}MB (bytesRead:${app.user.bytesRead},bytesWrit:${app.user.bytesWrit}) used by user ${app.user.id.UUID.toString("hex")}`, 1); | ||
if (app.user.expire && app.user.expire < new Date().getTime()) { | ||
return log(`expire user ${app.user.id.UUID.toString("hex")}`,1) | ||
return log(`expire user ${app.user.id.UUID.toString("hex")}`, 1) | ||
} | ||
@@ -224,19 +231,4 @@ app._adBuf.put(buffer, app); | ||
} | ||
function DecodeRequestBody(chunk, app) { | ||
if ([consts.SECURITY_TYPE_AES_128_GCM, consts.SECURITY_TYPE_CHACHA20_POLY1305].includes(app._security)) { | ||
const data = common.decrypt(chunk.subarray(2), app); | ||
if (data === null) { | ||
return log("fail to decrypt data chunk",1); | ||
} | ||
app.user.bytesWrit += data.length | ||
if (app.remote) | ||
return app.remote.message(data); | ||
} | ||
app.user.bytesWrit += chunk.length - 2 | ||
if (app.remote) | ||
return app.remote.message(chunk.subarray(2)); | ||
} | ||
function EncodeResponseHeader(app) { | ||
function EncodeResponseHeader(app) { | ||
var outBuffer = Buffer.from([app._responseHeader, 0x00, 0x00, 0x00]) | ||
@@ -271,3 +263,4 @@ try { | ||
const chunks = common.getChunks(buffer, 0x3fff).map(resolveChunk.bind(app)); | ||
this.localMessage(Buffer.concat([header, ...chunks])) | ||
this.localMessage(header) | ||
this.localMessage(Buffer.concat([...chunks])) | ||
} else { | ||
@@ -279,2 +272,16 @@ app.user.bytesRead += buffer.length | ||
} | ||
function DecodeRequestBody(chunk, app) { | ||
if ([consts.SECURITY_TYPE_AES_128_GCM, consts.SECURITY_TYPE_CHACHA20_POLY1305].includes(app._security)) { | ||
const data = common.decrypt(chunk.subarray(2, chunk.length - app.paddingLenght), app); | ||
if (data === null) { | ||
return log("fail to decrypt data chunk", 1); | ||
} | ||
app.user.bytesWrit += data.length | ||
if (app.remote) | ||
return app.remote.message(data); | ||
} | ||
app.user.bytesWrit += chunk.length - 2 | ||
if (app.remote) | ||
return app.remote.message(chunk.subarray(2)); | ||
} | ||
@@ -286,20 +293,43 @@ function resolveChunk(chunk) { | ||
} | ||
let _len = _chunk.length; | ||
if (this._option >= 0x05) { | ||
const mask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
_len = mask ^ _len; | ||
if (this._option >= 0x01) { | ||
let _len = _chunk.length; | ||
var pad = 0 | ||
if (this._option >= 0x05) { | ||
if (this._option >= 0x08) { | ||
const padmask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
pad = (padmask % 64) | ||
} | ||
const mask = this._chunkLenEncMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
_len = mask ^ (_len + pad); | ||
} | ||
if (pad == 0) | ||
_chunk = Buffer.concat([common.ntb(_len), _chunk]); | ||
else | ||
_chunk = Buffer.concat([common.ntb(_len), _chunk, crypto.randomBytes(pad)]); | ||
} | ||
return Buffer.concat([common.ntb(_len), _chunk]); | ||
return _chunk | ||
} | ||
function onReceivingLength(buffer, app) { | ||
if (buffer.length < 2) { | ||
var len = buffer.length | ||
if (len < 2) { | ||
return; | ||
} | ||
let len = buffer.readUInt16BE(0); | ||
if (app._option >= 0x05) { | ||
const mask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
len = mask ^ len; | ||
if (app._option >= 0x01) { | ||
len = buffer.readUInt16BE(0); | ||
if (app._option >= 0x05) { | ||
var pad = 0 | ||
if (app._option >= 0x08) { | ||
const padmask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
pad = (padmask % 64) | ||
} | ||
app.paddingLenght = pad | ||
const mask = app._chunkLenDecMaskGenerator.nextBytes(2).readUInt16BE(0); | ||
len = (mask ^ len); | ||
} | ||
len += 2; | ||
} | ||
return 2 + len; | ||
return len | ||
} | ||
@@ -310,2 +340,3 @@ | ||
this.app.remote.close() | ||
this.app.remote = null | ||
@@ -315,3 +346,4 @@ this.app._isConnecting = false; | ||
this.app._isHeaderRecv = false; | ||
this.app._adBuf.clear(); | ||
if (this.app._adBuf) | ||
this.app._adBuf.clear(); | ||
this.app._adBuf = null; | ||
@@ -332,2 +364,2 @@ this.app._host = null; | ||
module.exports = init | ||
module.exports = init |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
125202
3220