dns: add hardcoded icann fallback.
This commit is contained in:
parent
39331997ee
commit
f45bd0f63a
5 changed files with 1752 additions and 0 deletions
69
lib/dns/icann-browser.js
Normal file
69
lib/dns/icann-browser.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const tld = require('./tld.json');
|
||||
|
||||
/**
|
||||
* ICANN Root Zone
|
||||
*/
|
||||
|
||||
class ICANN {
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
has(name) {
|
||||
assert(typeof name === 'string');
|
||||
|
||||
name = trimFQDN(name);
|
||||
|
||||
if (name.length === 0 || name.length > 63)
|
||||
return false;
|
||||
|
||||
name = name.toLowerCase();
|
||||
|
||||
const data = this.data[name];
|
||||
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
return typeof data === 'string';
|
||||
}
|
||||
|
||||
get(name) {
|
||||
assert(typeof name === 'string');
|
||||
|
||||
name = trimFQDN(name);
|
||||
|
||||
if (name.length === 0 || name.length > 63)
|
||||
return null;
|
||||
|
||||
name = name.toLowerCase();
|
||||
|
||||
const data = this.data[name];
|
||||
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
if (typeof data !== 'string')
|
||||
return null;
|
||||
|
||||
return Buffer.from(data, 'base64');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function trimFQDN(name) {
|
||||
if (name.length > 0 && name[name.length - 1] === '.')
|
||||
name = name.slice(0, -1);
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = new ICANN(tld);
|
||||
139
lib/dns/icann.js
Normal file
139
lib/dns/icann.js
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const Path = require('path');
|
||||
const fs = require('bfile');
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const FILE = Path.resolve(__dirname, 'tld.db');
|
||||
const DATA = fs.readFileSync(FILE);
|
||||
|
||||
/**
|
||||
* ICANN Root Zone
|
||||
*/
|
||||
|
||||
class ICANN {
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
this.size = readU32(data, 0);
|
||||
this.nameSize = data[4];
|
||||
}
|
||||
|
||||
_compare(b, off) {
|
||||
const a = this.data;
|
||||
const alen = a[off - 1];
|
||||
const blen = b.length;
|
||||
const len = alen < blen ? alen : blen;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const x = a[off + i];
|
||||
const y = b[i];
|
||||
|
||||
if (x < y)
|
||||
return -1;
|
||||
|
||||
if (x > y)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (alen < blen)
|
||||
return -1;
|
||||
|
||||
if (alen > blen)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_find(key) {
|
||||
let start = 0;
|
||||
let end = this.size - 1;
|
||||
|
||||
while (start <= end) {
|
||||
const index = (start + end) >>> 1;
|
||||
const pos = 5 + index * (1 + this.nameSize + 4);
|
||||
const cmp = this._compare(key, pos + 1);
|
||||
|
||||
if (cmp === 0)
|
||||
return readU32(this.data, pos + 1 + this.nameSize);
|
||||
|
||||
if (cmp < 0)
|
||||
start = index + 1;
|
||||
else
|
||||
end = index - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
_data(pos) {
|
||||
const len = readU16(this.data, pos);
|
||||
return this.data.slice(pos + 2, pos + 2 + len);
|
||||
}
|
||||
|
||||
_has(key) {
|
||||
return this._find(key) !== -1;
|
||||
}
|
||||
|
||||
_get(key) {
|
||||
const pos = this._find(key);
|
||||
|
||||
if (pos === -1)
|
||||
return null;
|
||||
|
||||
return this._data(pos);
|
||||
}
|
||||
|
||||
has(name) {
|
||||
assert(typeof name === 'string');
|
||||
|
||||
name = trimFQDN(name);
|
||||
|
||||
if (name.length === 0 || name.length > 63)
|
||||
return false;
|
||||
|
||||
return this._has(toKey(name));
|
||||
}
|
||||
|
||||
get(name) {
|
||||
assert(typeof name === 'string');
|
||||
|
||||
name = trimFQDN(name);
|
||||
|
||||
if (name.length === 0 || name.length > 63)
|
||||
return null;
|
||||
|
||||
return this._get(toKey(name));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function readU16(data, off) {
|
||||
return data.readUInt16LE(off);
|
||||
}
|
||||
|
||||
function readU32(data, off) {
|
||||
return data.readUInt32LE(off);
|
||||
}
|
||||
|
||||
function trimFQDN(name) {
|
||||
if (name.length > 0 && name[name.length - 1] === '.')
|
||||
name = name.slice(0, -1);
|
||||
return name;
|
||||
}
|
||||
|
||||
function toKey(name) {
|
||||
return Buffer.from(name.toLowerCase(), 'ascii');
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = new ICANN(DATA);
|
||||
BIN
lib/dns/tld.db
Normal file
BIN
lib/dns/tld.db
Normal file
Binary file not shown.
1543
lib/dns/tld.json
Normal file
1543
lib/dns/tld.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -91,6 +91,7 @@
|
|||
},
|
||||
"browser": {
|
||||
"./lib/covenants/reserved": "./lib/covenants/reserved-browser.js",
|
||||
"./lib/dns/icann": "./lib/dns/icann-browser.js",
|
||||
"./lib/hd/nfkd": "./lib/hd/nfkd-compat.js",
|
||||
"./lib/hd/wordlist": "./lib/hd/wordlist-browser.js",
|
||||
"./lib/workers/child": "./lib/workers/child-browser.js",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue