mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
javascript is Ready for IPv6
This commit is contained in:
parent
ad78dbe547
commit
4507c2f706
0
binding/javascript/ReadMe.md
Normal file
0
binding/javascript/ReadMe.md
Normal file
7
binding/javascript/ip2region.js
Normal file
7
binding/javascript/ip2region.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a Apache2.0-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// ip2region.js
|
||||||
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "ip2region",
|
"name": "ip2region",
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"description": "javascript (ES6) binding for ip2region with both IPv4 and IPv6 supported ",
|
"description": "javascript binding for ip2region with both IPv4 and IPv6 supported ",
|
||||||
"main": "index.js",
|
"type": "module",
|
||||||
|
"main": "ip2region.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
@ -13,10 +14,20 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"ip2region",
|
"ip2region",
|
||||||
"ip-address",
|
"ip-address",
|
||||||
"ip-lookup",
|
"ip-region",
|
||||||
"ip-location",
|
"ip-location",
|
||||||
|
"ip-lookup",
|
||||||
|
"ip-search",
|
||||||
|
"ipv4-address",
|
||||||
|
"ipv4-region",
|
||||||
|
"ipv4-location",
|
||||||
"ipv4-lookup",
|
"ipv4-lookup",
|
||||||
"ipv6-lookup"
|
"ipv4-search",
|
||||||
|
"ipv6-address",
|
||||||
|
"ipv6-region",
|
||||||
|
"ipv6-location",
|
||||||
|
"ipv6-lookup",
|
||||||
|
"ipv6-search"
|
||||||
],
|
],
|
||||||
"author": "lionsoul2014",
|
"author": "lionsoul2014",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {
|
const {
|
||||||
parseIP,
|
parseIP,
|
||||||
HeaderInfoLength, VectorIndexCols, VectorIndexSize
|
HeaderInfoLength, VectorIndexCols, VectorIndexSize,
|
||||||
|
ipToString
|
||||||
} = require('./util');
|
} = require('./util');
|
||||||
|
|
||||||
class Searcher {
|
class Searcher {
|
||||||
@ -30,17 +31,13 @@ class Searcher {
|
|||||||
return this.ioCount;
|
return this.ioCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
async search(ip) {
|
search(ip) {
|
||||||
let ipBytes;
|
// check and parse the string ip
|
||||||
if (Buffer.isBuffer(ip)) {
|
const ipBytes = Buffer.isBuffer(ip) ? ip : parseIP(ip);
|
||||||
ipBytes = ip;
|
|
||||||
} else {
|
|
||||||
ipBytes = parseIP(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ip version check
|
// ip version check
|
||||||
if (ipBytes.length != this.version.bytes) {
|
if (ipBytes.length != this.version.bytes) {
|
||||||
throw new Error(`invalid ip address (${this.version.name} expected)`);
|
throw new Error(`invalid ip address '${ipToString(ipBytes)}' (${this.version.name} expected)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the global counter
|
// reset the global counter
|
||||||
@ -48,14 +45,14 @@ class Searcher {
|
|||||||
|
|
||||||
// located the segment index block based on the vector index
|
// located the segment index block based on the vector index
|
||||||
let sPtr = 0, ePtr = 0;
|
let sPtr = 0, ePtr = 0;
|
||||||
let il0 = ipBytes[0] & 0xFF, il1 = ipBytes[1] & 0xFF;
|
let il0 = ipBytes[0], il1 = ipBytes[1];
|
||||||
let idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize;
|
let idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize;
|
||||||
if (this.vectorIndex != null) {
|
if (this.vectorIndex != null) {
|
||||||
sPtr = this.vectorIndex.readUint32LE(idx);
|
sPtr = this.vectorIndex.readUint32LE(idx);
|
||||||
ePtr = this.vectorIndex.readUint32LE(idx + 4);
|
ePtr = this.vectorIndex.readUint32LE(idx + 4);
|
||||||
} else if (this.cBuffer != null) {
|
} else if (this.cBuffer != null) {
|
||||||
sPtr = this.vectorIndex.readUint32LE(HeaderInfoLength + idx);
|
sPtr = this.cBuffer.readUint32LE(HeaderInfoLength + idx);
|
||||||
ePtr = this.vectorIndex.readUint32LE(HeaderInfoLength + idx + 4);
|
ePtr = this.cBuffer.readUint32LE(HeaderInfoLength + idx + 4);
|
||||||
} else {
|
} else {
|
||||||
const buff = Buffer.alloc(VectorIndexSize);
|
const buff = Buffer.alloc(VectorIndexSize);
|
||||||
this.read(HeaderInfoLength + idx, buff);
|
this.read(HeaderInfoLength + idx, buff);
|
||||||
@ -67,7 +64,7 @@ class Searcher {
|
|||||||
// binary search the segment index block to get the region info
|
// binary search the segment index block to get the region info
|
||||||
const bytes = ipBytes.length, dBytes = ipBytes.length << 1;
|
const bytes = ipBytes.length, dBytes = ipBytes.length << 1;
|
||||||
const indexSize = this.version.indexSize;
|
const indexSize = this.version.indexSize;
|
||||||
let buff = Buffer.alloc(indexSize);
|
const buff = Buffer.alloc(indexSize);
|
||||||
let dLen = -1, dPtr = -1, l = 0, h = (ePtr - sPtr) / indexSize;
|
let dLen = -1, dPtr = -1, l = 0, h = (ePtr - sPtr) / indexSize;
|
||||||
while (l <= h) {
|
while (l <= h) {
|
||||||
const m = (l + h) >> 1;
|
const m = (l + h) >> 1;
|
||||||
@ -77,7 +74,7 @@ class Searcher {
|
|||||||
this.read(p, buff);
|
this.read(p, buff);
|
||||||
if (this.version.ipSubCompare(ipBytes, buff, 0) < 0) {
|
if (this.version.ipSubCompare(ipBytes, buff, 0) < 0) {
|
||||||
h = m - 1;
|
h = m - 1;
|
||||||
} else if (this.version.ipSubCompare(ip, buff, bytes) > 0) {
|
} else if (this.version.ipSubCompare(ipBytes, buff, bytes) > 0) {
|
||||||
l = m + 1;
|
l = m + 1;
|
||||||
} else {
|
} else {
|
||||||
dLen = buff.readUint16LE(dBytes);
|
dLen = buff.readUint16LE(dBytes);
|
||||||
@ -87,12 +84,6 @@ class Searcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`dLen: ${dLen}, dPtr: ${dPtr}`);
|
// console.log(`dLen: ${dLen}, dPtr: ${dPtr}`);
|
||||||
// empty match interception
|
|
||||||
// @Note: could this even be a case ?
|
|
||||||
if (dPtr < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const region = Buffer.alloc(dLen);
|
const region = Buffer.alloc(dLen);
|
||||||
this.read(dPtr, region);
|
this.read(dPtr, region);
|
||||||
return region.toString('utf-8');
|
return region.toString('utf-8');
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// util test script
|
// util test script
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const util = require('../util');
|
const util = require('../util.js');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb')
|
const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb')
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// util test script
|
// util test script
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const util = require('../util');
|
const util = require('../util.js');
|
||||||
|
|
||||||
test('parse ip address', () => {
|
test('parse ip address', () => {
|
||||||
let ip_list = [
|
let ip_list = [
|
||||||
|
|||||||
56
binding/javascript/tests/search.test.js
Normal file
56
binding/javascript/tests/search.test.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2022 The Ip2Region Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a Apache2.0-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// searcher search tester
|
||||||
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
|
const {IPv4, IPv6, parseIP, ipToString} = require('../util');
|
||||||
|
const {newWithFileOnly} = require('../searcher');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const dbPath = {
|
||||||
|
v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'),
|
||||||
|
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
||||||
|
}
|
||||||
|
|
||||||
|
test('ipv4 search test', () => {
|
||||||
|
try {
|
||||||
|
let searcher = newWithFileOnly(IPv4, dbPath.v4);
|
||||||
|
let ip_list = [
|
||||||
|
'1.0.0.0',
|
||||||
|
parseIP('113.118.112.93'),
|
||||||
|
'240e:3b7::'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < ip_list.length; i++) {
|
||||||
|
let ip = ip_list[i];
|
||||||
|
let region = searcher.search(ip);
|
||||||
|
let ipStr = Buffer.isBuffer(ip) ? ipToString(ip) : ip;
|
||||||
|
console.log(`search(${ipStr}): {region: ${region}, ioCount: ${searcher.getIOCount()}}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`${e.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ipv6 search test', async () => {
|
||||||
|
try {
|
||||||
|
let searcher = newWithFileOnly(IPv6, dbPath.v6);
|
||||||
|
let ip_list = [
|
||||||
|
'2a02:26f7:c409:4001::',
|
||||||
|
parseIP('2a11:8080:200::a:a05c'),
|
||||||
|
'240e:3b7::',
|
||||||
|
'120.229.45.92'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < ip_list.length; i++) {
|
||||||
|
let ip = ip_list[i];
|
||||||
|
let region = searcher.search(ip);
|
||||||
|
let ipStr = Buffer.isBuffer(ip) ? ipToString(ip) : ip;
|
||||||
|
console.log(`search(${ipStr}): {region: ${region}, ioCount: ${searcher.getIOCount()}}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`${e.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -2,11 +2,11 @@
|
|||||||
// Use of this source code is governed by a Apache2.0-style
|
// Use of this source code is governed by a Apache2.0-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// searcher tester
|
// searcher new tester
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const {IPv4, parseIP, ipToString} = require('../util');
|
const {IPv4, IPv6, loadVectorIndexFromFile, XdbIPv4Id, loadContentFromFile} = require('../util');
|
||||||
const {newWithFileOnly} = require('../searcher');
|
const {newWithFileOnly, newWithVectorIndex, newWithBuffer} = require('../searcher');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const dbPath = {
|
const dbPath = {
|
||||||
@ -14,22 +14,53 @@ const dbPath = {
|
|||||||
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
||||||
}
|
}
|
||||||
|
|
||||||
test('ipv4 searcher test', async () => {
|
function _get_creater_list(version) {
|
||||||
try {
|
let dbFile = version.id == XdbIPv4Id ? dbPath.v4 : dbPath.v6;
|
||||||
let searcher = newWithFileOnly(IPv4, dbPath.v4);
|
return [function(){
|
||||||
let ip_list = [
|
return ["newWithFileOnly", newWithFileOnly(version, dbFile)];
|
||||||
'1.0.0.0',
|
}, function(){
|
||||||
parseIP('113.118.112.93'),
|
const vIndex = loadVectorIndexFromFile(dbFile);
|
||||||
'240e:3b7::'
|
return ["newWithVectorIndex", newWithVectorIndex(version, dbFile, vIndex)];
|
||||||
];
|
}, function(){
|
||||||
|
const cBuffer = loadContentFromFile(dbFile);
|
||||||
|
return ["newWithBuffer", newWithBuffer(version, cBuffer)];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < ip_list.length; i++) {
|
test('ipv4 searcher test', () => {
|
||||||
let ip = ip_list[i];
|
const ip_Str = '120.229.45.92';
|
||||||
let region = await searcher.search(ip);
|
const c_list = _get_creater_list(IPv4);
|
||||||
let ipStr = Buffer.isBuffer(ip) ? ipToString(ip) : ip;
|
try {
|
||||||
console.log(`search(${ipStr}): {region: ${region}, ioCount: ${searcher.getIOCount()}}`);
|
let bRegion = null;
|
||||||
|
for (var i = 0; i < c_list.length; i++) {
|
||||||
|
const meta = c_list[i]();
|
||||||
|
const region = meta[1].search(ip_Str);
|
||||||
|
if (bRegion != null) {
|
||||||
|
expect(region).toBe(region);
|
||||||
|
}
|
||||||
|
bRegion = region;
|
||||||
|
console.log(`${meta[0]}.search(${ip_Str}): ${region}`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`${e.message}`);
|
console.error(`${e.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ipv6 searcher test', async () => {
|
||||||
|
const ip_Str = '240e:57f:32ff:ffff:ffff:ffff:ffff:ffff';
|
||||||
|
const c_list = _get_creater_list(IPv6);
|
||||||
|
try {
|
||||||
|
let bRegion = null;
|
||||||
|
for (var i = 0; i < c_list.length; i++) {
|
||||||
|
const meta = c_list[i]();
|
||||||
|
const region = meta[1].search(ip_Str);
|
||||||
|
if (bRegion != null) {
|
||||||
|
expect(region).toBe(region);
|
||||||
|
}
|
||||||
|
bRegion = region;
|
||||||
|
console.log(`${meta[0]}.search(${ip_Str}): ${region}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`${e.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -47,87 +47,6 @@ class Header {
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
class Version {
|
|
||||||
constructor(id, name, bytes, indexSize, ipCompareFunc) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.bytes = bytes;
|
|
||||||
this.indexSize = indexSize;
|
|
||||||
this.ipCompareFunc = ipCompareFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipCompare(ip1, ip2) {
|
|
||||||
return this.ipCompareFunc(ip1, ip2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipSubCompare(ip1, ip2, offset) {
|
|
||||||
return this.ipCompareFunc(ip1, ip2, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
toString() {
|
|
||||||
return `{"id": ${this.id}, "name": "${this.name}", "bytes":${this.bytes}, "index_size": ${this.indexSize}}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 14 = 4 + 4 + 2 + 4
|
|
||||||
const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
|
||||||
// ip1: Big endian byte order parsed from input
|
|
||||||
// ip2: Little endian byte order read from xdb index.
|
|
||||||
// @Note: to compatible with the old Litten endian index encode implementation.
|
|
||||||
let i, j = offset + ip1.length - 1;
|
|
||||||
for (i = 0; i < ip1.length; i++, j--) {
|
|
||||||
const i1 = ip1[i] & 0xFF;
|
|
||||||
const i2 = buff[j] & 0xFF;
|
|
||||||
if (i1 < i2) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i1 > i2) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 38 = 16 + 16 + 2 + 4
|
|
||||||
const IPv6 = new Version(XdbIPv6Id, "IPv6", 6, 38, ipSubCompare);
|
|
||||||
|
|
||||||
function versionFromName(name) {
|
|
||||||
let n = name.toUpperCase();
|
|
||||||
if (n == "V4" || n == "IPV4") {
|
|
||||||
return IPv4;
|
|
||||||
} else if (n == "V6" || n == "IPV6") {
|
|
||||||
return IPv6;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function versionFromHeader(h) {
|
|
||||||
let v = h.version();
|
|
||||||
|
|
||||||
// old structure with ONLY IPv4 supporting
|
|
||||||
if (v == XdbStructure20) {
|
|
||||||
return IPv4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// structure 3.0 with IPv6 supporting
|
|
||||||
if (v != XdbStructure30) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ipVer = h.ipVersion();
|
|
||||||
if (ipVer == XdbIPv4Id) {
|
|
||||||
return IPv4;
|
|
||||||
} else if (ipVer == XdbIPv6Id) {
|
|
||||||
return IPv6;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ---
|
|
||||||
|
|
||||||
// parse ipv4 address
|
// parse ipv4 address
|
||||||
function _parse_ipv4_addr(v4String) {
|
function _parse_ipv4_addr(v4String) {
|
||||||
let ps = v4String.split('.', 4);
|
let ps = v4String.split('.', 4);
|
||||||
@ -223,7 +142,7 @@ function parseIP(ipString) {
|
|||||||
} else if (cDot > -1) {
|
} else if (cDot > -1) {
|
||||||
return _parse_ipv6_addr(ipString);
|
return _parse_ipv6_addr(ipString);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
throw new Error(`invalid ip address '${ipString}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +243,90 @@ function ipCompare(ip1, ip2) {
|
|||||||
return ipSubCompare(ip1, ip2, 0);
|
return ipSubCompare(ip1, ip2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
class Version {
|
||||||
|
constructor(id, name, bytes, indexSize, ipCompareFunc) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.indexSize = indexSize;
|
||||||
|
this.ipCompareFunc = ipCompareFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipCompare(ip1, ip2) {
|
||||||
|
return this.ipCompareFunc(ip1, ip2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipSubCompare(ip1, ip2, offset) {
|
||||||
|
return this.ipCompareFunc(ip1, ip2, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `{"id": ${this.id}, "name": "${this.name}", "bytes":${this.bytes}, "index_size": ${this.indexSize}}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 14 = 4 + 4 + 2 + 4
|
||||||
|
const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
||||||
|
// ip1: Big endian byte order parsed from input
|
||||||
|
// ip2: Little endian byte order read from xdb index.
|
||||||
|
// @Note: to compatible with the old Litten endian index encode implementation.
|
||||||
|
let i, j = offset + ip1.length - 1;
|
||||||
|
for (i = 0; i < ip1.length; i++, j--) {
|
||||||
|
const i1 = ip1[i] & 0xFF;
|
||||||
|
const i2 = buff[j] & 0xFF;
|
||||||
|
if (i1 < i2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i1 > i2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 38 = 16 + 16 + 2 + 4
|
||||||
|
const IPv6 = new Version(XdbIPv6Id, "IPv6", 16, 38, ipSubCompare);
|
||||||
|
|
||||||
|
function versionFromName(name) {
|
||||||
|
let n = name.toUpperCase();
|
||||||
|
if (n == "V4" || n == "IPV4") {
|
||||||
|
return IPv4;
|
||||||
|
} else if (n == "V6" || n == "IPV6") {
|
||||||
|
return IPv6;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function versionFromHeader(h) {
|
||||||
|
let v = h.version();
|
||||||
|
|
||||||
|
// old structure with ONLY IPv4 supporting
|
||||||
|
if (v == XdbStructure20) {
|
||||||
|
return IPv4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// structure 3.0 with IPv6 supporting
|
||||||
|
if (v != XdbStructure30) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ipVer = h.ipVersion();
|
||||||
|
if (ipVer == XdbIPv4Id) {
|
||||||
|
return IPv4;
|
||||||
|
} else if (ipVer == XdbIPv6Id) {
|
||||||
|
return IPv6;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
function loadHeader(fd) {
|
function loadHeader(fd) {
|
||||||
const buffer = Buffer.alloc(HeaderInfoLength);
|
const buffer = Buffer.alloc(HeaderInfoLength);
|
||||||
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user