tangerine 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -0
- package/index.js +228 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,8 @@
|
|
|
51
51
|
* [`tangerine.resolveSoa(hostname[, options, abortController]))`](#tangerineresolvesoahostname-options-abortcontroller)
|
|
52
52
|
* [`tangerine.resolveSrv(hostname[, options, abortController]))`](#tangerineresolvesrvhostname-options-abortcontroller)
|
|
53
53
|
* [`tangerine.resolveTxt(hostname[, options, abortController]))`](#tangerineresolvetxthostname-options-abortcontroller)
|
|
54
|
+
* [`tangerine.resolveCert(hostname, [, options, abortController]))`](#tangerineresolvecerthostname--options-abortcontroller)
|
|
55
|
+
* [`tangerine.resolveTlsa(hostname, [, options, abortController]))`](#tangerineresolvetlsahostname--options-abortcontroller)
|
|
54
56
|
* [`tangerine.reverse(ip[, abortController, purgeCache])`](#tangerinereverseip-abortcontroller-purgecache)
|
|
55
57
|
* [`tangerine.setDefaultResultOrder(order)`](#tangerinesetdefaultresultorderorder)
|
|
56
58
|
* [`tangerine.setServers(servers)`](#tangerinesetserversservers)
|
|
@@ -156,6 +158,7 @@ Thanks to the authors of [dohdec](https://github.com/hildjj/dohdec), [dns-packet
|
|
|
156
158
|
* `resolveNs` → `queryNs`
|
|
157
159
|
* `resolveNs` → `queryNs`
|
|
158
160
|
* `resolveTxt` → `queryTxt`
|
|
161
|
+
* `resolveTsla` → `queryTsla`
|
|
159
162
|
* `resolveSrv` → `querySrv`
|
|
160
163
|
* `resolvePtr` → `queryPtr`
|
|
161
164
|
* `resolveNaptr` → `queryNaptr`
|
|
@@ -230,6 +233,7 @@ tangerine.resolve('forwardemail.net').then(console.log);
|
|
|
230
233
|
* If set to `true`, then the result will be re-queried and re-cached – see [Cache](#cache) documentation for more insight.
|
|
231
234
|
* Instances of `new Tangerine()` are instances of `dns.promises.Resolver` via `class Tangerine extends dns.promises.Resolver { ... }` (namely for compatibility with projects such as [cacheable-lookup](https://github.com/szmarczak/cacheable-lookup)).
|
|
232
235
|
* See the complete list of [Options](#options) below.
|
|
236
|
+
* Any `rrtype` from the list at <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4> is supported (unlike the native Node.js DNS module which only supports a limited set).
|
|
233
237
|
|
|
234
238
|
### `tangerine.cancel()`
|
|
235
239
|
|
|
@@ -269,6 +273,58 @@ Tangerine supports a new `ecsSubnet` property in the `options` Object argument.
|
|
|
269
273
|
|
|
270
274
|
### `tangerine.resolveTxt(hostname[, options, abortController]))`
|
|
271
275
|
|
|
276
|
+
### `tangerine.resolveCert(hostname, [, options, abortController]))`
|
|
277
|
+
|
|
278
|
+
This function returns a Promise that resolves with an Array with parsed values from results:
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
[
|
|
282
|
+
{
|
|
283
|
+
algorithm: 0,
|
|
284
|
+
certificate: 'MIIEoTCCA4mgAwIBAgICAacwDQYJKoZIhvcNAQELBQAwgY0xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDEOMAwGA1UEBwwFQm95ZHMxEzARBgNVBAoMCkRyYWplciBMTEMxIjAgBgNVBAMMGWludGVybWVkaWF0ZS5oZWFsdGhpdC5nb3YxKDAmBgkqhkiG9w0BCQEWGWludGVybWVkaWF0ZS5oZWFsdGhpdC5nb3YwHhcNMTgwOTI1MTgyNDIzWhcNMjgwOTIyMTgyNDIzWjB7MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTUQxDjAMBgNVBAcMBUJveWRzMRMwEQYDVQQKDApEcmFqZXIgTExDMRkwFwYDVQQDDBBldHQuaGVhbHRoaXQuZ292MR8wHQYJKoZIhvcNAQkBFhBldHQuaGVhbHRoaXQuZ292MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxaA2MIuaqpvP2Id85KIhUVA6zlj+CgZh/3prgJ1q4leP3T5F1tSSgrQ/WYTFglEwN7FJx4yJ324NaKncaMPDBIg3IUgC3Q5nrPUbIJAUgM5+67pXnGgt6s9bQelEsTdbyA/JlLC7Hsv184mqo0yrueC9NJEea4/yTV51G9S4jLjnKhr0XUTw0Fb/PFNL9ZwaEdFgQfUaE1maleazKGDyLLuEGvpXsRNs1Ju/kdHkOUVLf741Cq8qLlqOKN2v5jQkUdFUKHbYIF5KXt4ToV9mvxTaz6Mps1UbS+a73Xr+VqmBqmEQnXA5DZ7ucikzv9DLokDwtmPzhdqye2msgDpw0QIDAQABo4IBGjCCARYwCQYDVR0TBAIwADAbBgNVHREEFDASghBldHQuaGVhbHRoaXQuZ292MB0GA1UdDgQWBBQ6E22jc99mm+WraUj93IvQcw6JHDAfBgNVHSMEGDAWgBRfW20fzencvG+Attm1rcvQV+3rOTALBgNVHQ8EBAMCBaAwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NhLmRpcmVjdGNhLm9yZy9jcmwvaW50ZXJtZWRpYXRlLmhlYWx0aGl0Lmdvdi5jcmwwVAYIKwYBBQUHAQEESDBGMEQGCCsGAQUFBzAChjhodHRwOi8vY2EuZGlyZWN0Y2Eub3JnL2FpYS9pbnRlcm1lZGlhdGUuaGVhbHRoaXQuZ292LmRlcjANBgkqhkiG9w0BAQsFAAOCAQEAhCASLubdxWp+XzXO4a8zMgWOMpjft+ilIy2ROVKOKslbB7lKx0NR7chrTPxCmK+YTL2ttLaTpOniw/vTGrZgeFPyXzJCNtpnx8fFipPE18OAlKMc2nyy7RfUscf28UAEmFo2cEJfpsZjyynkBsTnQ5rQVNgM7TbXXfboxwWwhg4HnWIcmlTs2YM1a9v+idK6LSfX9y/Nvhf9pl0DQflc9ym4z/XCq87erCce+11kxH1+36N6rRqeiHVBYnoYIGMH690r4cgE8cW5B4eK7kaD3iCbmpChO0gZSa5Lex49WLXeFfM+ukd9y3AB00KMZcsUV5bCgwShH053ZQa+FMON8w==',
|
|
285
|
+
certificate_type: 'PKIX',
|
|
286
|
+
key_tag: 0,
|
|
287
|
+
name: 'ett.healthit.gov',
|
|
288
|
+
ttl: 19045,
|
|
289
|
+
},
|
|
290
|
+
]
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
This mirrors output from <https://github.com/rthalley/dnspython>.
|
|
294
|
+
|
|
295
|
+
### `tangerine.resolveTlsa(hostname, [, options, abortController]))`
|
|
296
|
+
|
|
297
|
+
This method was added for DANE and TSLA support. See this [excellent article](https://www.mailhardener.com/kb/dane), [index.js](https://github.com/forwardemail/tangerine/blob/main/index.js), and <https://github.com/nodejs/node/issues/39569> for more insight.
|
|
298
|
+
|
|
299
|
+
This function returns a Promise that resolves with an Array with parsed values from results:
|
|
300
|
+
|
|
301
|
+
```js
|
|
302
|
+
[
|
|
303
|
+
{
|
|
304
|
+
cert: Buffer @Uint8Array [
|
|
305
|
+
e1ae9c3d e848ece1 ba72e0d9 91ae4d0d 9ec547c6 bad1ddda b9d6beb0 a7e0e0d8
|
|
306
|
+
],
|
|
307
|
+
mtype: 1,
|
|
308
|
+
name: 'proloprod.mail._dane.internet.nl',
|
|
309
|
+
selector: 1,
|
|
310
|
+
ttl: 622,
|
|
311
|
+
usage: 2,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
cert: Buffer @Uint8Array [
|
|
315
|
+
d6fea64d 4e68caea b7cbb2e0 f905d7f3 ca3308b1 2fd88c5b 469f08ad 7e05c7c7
|
|
316
|
+
],
|
|
317
|
+
mtype: 1,
|
|
318
|
+
name: 'proloprod.mail._dane.internet.nl',
|
|
319
|
+
selector: 1,
|
|
320
|
+
ttl: 622,
|
|
321
|
+
usage: 3,
|
|
322
|
+
},
|
|
323
|
+
]
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
This mirrors output from <https://github.com/rthalley/dnspython>.
|
|
327
|
+
|
|
272
328
|
### `tangerine.reverse(ip[, abortController, purgeCache])`
|
|
273
329
|
|
|
274
330
|
### `tangerine.setDefaultResultOrder(order)`
|
package/index.js
CHANGED
|
@@ -38,6 +38,19 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
38
38
|
return Number.isSafeInteger(port) && port >= 0 && port <= 65535;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
static CTYPE_BY_VALUE = {
|
|
42
|
+
1: 'PKIX',
|
|
43
|
+
2: 'SPKI',
|
|
44
|
+
3: 'PGP',
|
|
45
|
+
4: 'IPKIX',
|
|
46
|
+
5: 'ISPKI',
|
|
47
|
+
6: 'IPGP',
|
|
48
|
+
7: 'ACPKIX',
|
|
49
|
+
8: 'IACPKIX',
|
|
50
|
+
253: 'URI',
|
|
51
|
+
254: 'OID'
|
|
52
|
+
};
|
|
53
|
+
|
|
41
54
|
static getAddrConfigTypes() {
|
|
42
55
|
const networkInterfaces = os.networkInterfaces();
|
|
43
56
|
let hasIPv4 = false;
|
|
@@ -138,7 +151,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
138
151
|
dns.TIMEOUT
|
|
139
152
|
]);
|
|
140
153
|
|
|
141
|
-
static
|
|
154
|
+
static DNS_TYPES = new Set([
|
|
142
155
|
'A',
|
|
143
156
|
'AAAA',
|
|
144
157
|
'CAA',
|
|
@@ -152,6 +165,99 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
152
165
|
'TXT'
|
|
153
166
|
]);
|
|
154
167
|
|
|
168
|
+
// <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4>
|
|
169
|
+
static TYPES = new Set([
|
|
170
|
+
'A',
|
|
171
|
+
'A6',
|
|
172
|
+
'AAAA',
|
|
173
|
+
'AFSDB',
|
|
174
|
+
'AMTRELAY',
|
|
175
|
+
'APL',
|
|
176
|
+
'ATMA',
|
|
177
|
+
'AVC',
|
|
178
|
+
'AXFR',
|
|
179
|
+
'CAA',
|
|
180
|
+
'CDNSKEY',
|
|
181
|
+
'CDS',
|
|
182
|
+
'CERT',
|
|
183
|
+
'CNAME',
|
|
184
|
+
'CSYNC',
|
|
185
|
+
'DHCID',
|
|
186
|
+
'DLV',
|
|
187
|
+
'DNAME',
|
|
188
|
+
'DNSKEY',
|
|
189
|
+
'DOA',
|
|
190
|
+
'DS',
|
|
191
|
+
'EID',
|
|
192
|
+
'EUI48',
|
|
193
|
+
'EUI64',
|
|
194
|
+
'GID',
|
|
195
|
+
'GPOS',
|
|
196
|
+
'HINFO',
|
|
197
|
+
'HIP',
|
|
198
|
+
'HTTPS',
|
|
199
|
+
'IPSECKEY',
|
|
200
|
+
'ISDN',
|
|
201
|
+
'IXFR',
|
|
202
|
+
'KEY',
|
|
203
|
+
'KX',
|
|
204
|
+
'L32',
|
|
205
|
+
'L64',
|
|
206
|
+
'LOC',
|
|
207
|
+
'LP',
|
|
208
|
+
'MAILA',
|
|
209
|
+
'MAILB',
|
|
210
|
+
'MB',
|
|
211
|
+
'MD',
|
|
212
|
+
'MF',
|
|
213
|
+
'MG',
|
|
214
|
+
'MINFO',
|
|
215
|
+
'MR',
|
|
216
|
+
'MX',
|
|
217
|
+
'NAPTR',
|
|
218
|
+
'NID',
|
|
219
|
+
'NIMLOC',
|
|
220
|
+
'NINFO',
|
|
221
|
+
'NS',
|
|
222
|
+
'NSAP',
|
|
223
|
+
'NSAP-PTR',
|
|
224
|
+
'NSEC',
|
|
225
|
+
'NSEC3',
|
|
226
|
+
'NSEC3PARAM',
|
|
227
|
+
'NULL',
|
|
228
|
+
'NXT',
|
|
229
|
+
'OPENPGPKEY',
|
|
230
|
+
'OPT',
|
|
231
|
+
'PTR',
|
|
232
|
+
'PX',
|
|
233
|
+
'RKEY',
|
|
234
|
+
'RP',
|
|
235
|
+
'RRSIG',
|
|
236
|
+
'RT',
|
|
237
|
+
'Reserved',
|
|
238
|
+
'SIG',
|
|
239
|
+
'SINK',
|
|
240
|
+
'SMIMEA',
|
|
241
|
+
'SOA',
|
|
242
|
+
'SPF',
|
|
243
|
+
'SRV',
|
|
244
|
+
'SSHFP',
|
|
245
|
+
'SVCB',
|
|
246
|
+
'TA',
|
|
247
|
+
'TALINK',
|
|
248
|
+
'TKEY',
|
|
249
|
+
'TLSA',
|
|
250
|
+
'TSIG',
|
|
251
|
+
'TXT',
|
|
252
|
+
'UID',
|
|
253
|
+
'UINFO',
|
|
254
|
+
'UNSPEC',
|
|
255
|
+
'URI',
|
|
256
|
+
'WKS',
|
|
257
|
+
'X25',
|
|
258
|
+
'ZONEMD'
|
|
259
|
+
]);
|
|
260
|
+
|
|
155
261
|
static ANY_TYPES = [
|
|
156
262
|
'A',
|
|
157
263
|
'AAAA',
|
|
@@ -805,6 +911,15 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
805
911
|
return this.resolve(name, 'TXT', options, abortController);
|
|
806
912
|
}
|
|
807
913
|
|
|
914
|
+
resolveCert(name, options, abortController) {
|
|
915
|
+
return this.resolve(name, 'CERT', options, abortController);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// NOTE: parse this properly according to spec (see below default case)
|
|
919
|
+
resolveTlsa(name, options, abortController) {
|
|
920
|
+
return this.resolve(name, 'TLSA', options, abortController);
|
|
921
|
+
}
|
|
922
|
+
|
|
808
923
|
// 1:1 mapping with node's official dns.promises API
|
|
809
924
|
// (this means it's a drop-in replacement for `dns`)
|
|
810
925
|
// <https://github.com/nodejs/node/blob/9bbde3d7baef584f14569ef79f116e9d288c7aaa/lib/internal/dns/utils.js#L87-L95>
|
|
@@ -1243,7 +1358,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1243
1358
|
data = await this.options.cache.get(key);
|
|
1244
1359
|
// safeguard in case cache pollution
|
|
1245
1360
|
if (data && typeof data === 'object') {
|
|
1246
|
-
debug('cache retrieved',
|
|
1361
|
+
debug('cache retrieved', key);
|
|
1247
1362
|
const now = Date.now();
|
|
1248
1363
|
// safeguard in case cache pollution
|
|
1249
1364
|
if (
|
|
@@ -1252,6 +1367,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1252
1367
|
!Number.isFinite(data.ttl) ||
|
|
1253
1368
|
data.ttl < 1
|
|
1254
1369
|
) {
|
|
1370
|
+
debug('cache expired', key);
|
|
1255
1371
|
data = undefined;
|
|
1256
1372
|
} else if (options?.ttl) {
|
|
1257
1373
|
// clone the data so that we don't mutate cache (e.g. if it's in-memory)
|
|
@@ -1271,6 +1387,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1271
1387
|
|
|
1272
1388
|
// eslint-disable-next-line max-depth
|
|
1273
1389
|
if (data.answers[i].ttl <= 0) {
|
|
1390
|
+
debug('answer cache expired', key);
|
|
1274
1391
|
data = undefined;
|
|
1275
1392
|
break;
|
|
1276
1393
|
}
|
|
@@ -1384,7 +1501,7 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1384
1501
|
// this supports both redis-based key/value/ttl and simple key/value implementations
|
|
1385
1502
|
result.expires = Date.now() + Math.round(result.ttl * 1000);
|
|
1386
1503
|
const args = [key, result, ...this.options.setCacheArgs(key, result)];
|
|
1387
|
-
debug('setting cache',
|
|
1504
|
+
debug('setting cache', { args });
|
|
1388
1505
|
await this.options.cache.set(...args);
|
|
1389
1506
|
}
|
|
1390
1507
|
|
|
@@ -1517,17 +1634,117 @@ class Tangerine extends dns.promises.Resolver {
|
|
|
1517
1634
|
|
|
1518
1635
|
case 'TXT': {
|
|
1519
1636
|
// text records `dnsPromises.resolveTxt()`
|
|
1520
|
-
return result.answers.flatMap((a) =>
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1637
|
+
return result.answers.flatMap((a) => {
|
|
1638
|
+
//
|
|
1639
|
+
// NOTE: we need to support buffer conversion
|
|
1640
|
+
// (e.g. JSON.stringify from most cache stores will convert this as such below)
|
|
1641
|
+
//
|
|
1642
|
+
// a {
|
|
1643
|
+
// name: 'forwardemail.net',
|
|
1644
|
+
// type: 'TXT',
|
|
1645
|
+
// ttl: 3600,
|
|
1646
|
+
// class: 'IN',
|
|
1647
|
+
// flush: false,
|
|
1648
|
+
// data: [ { type: 'Buffer', data: [Array] } ]
|
|
1649
|
+
// }
|
|
1650
|
+
//
|
|
1651
|
+
// (or)
|
|
1652
|
+
//
|
|
1653
|
+
// a {
|
|
1654
|
+
// name: 'forwardemail.net',
|
|
1655
|
+
// type: 'TXT',
|
|
1656
|
+
// ttl: 3600,
|
|
1657
|
+
// class: 'IN',
|
|
1658
|
+
// flush: false,
|
|
1659
|
+
// data: { type: 'Buffer', data: [Array] }
|
|
1660
|
+
// }
|
|
1661
|
+
//
|
|
1662
|
+
if (Array.isArray(a.data)) {
|
|
1663
|
+
a.data = a.data.map((d) => {
|
|
1664
|
+
if (
|
|
1665
|
+
typeof d === 'object' &&
|
|
1666
|
+
d.type === 'Buffer' &&
|
|
1667
|
+
Array.isArray(d.data)
|
|
1668
|
+
)
|
|
1669
|
+
return Buffer.from(d.data);
|
|
1670
|
+
return d;
|
|
1671
|
+
});
|
|
1672
|
+
} else if (
|
|
1673
|
+
typeof a.data === 'object' &&
|
|
1674
|
+
a.data.type === 'Buffer' &&
|
|
1675
|
+
Array.isArray(a.data.data)
|
|
1676
|
+
) {
|
|
1677
|
+
a.data = Buffer.from(a.data.data);
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
return [
|
|
1681
|
+
Buffer.isBuffer(a.data)
|
|
1682
|
+
? a.data.toString()
|
|
1683
|
+
: Array.isArray(a.data)
|
|
1684
|
+
? a.data.map((d) => (Buffer.isBuffer(d) ? d.toString() : d))
|
|
1685
|
+
: a.data
|
|
1686
|
+
];
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
case 'CERT': {
|
|
1691
|
+
// CERT records `tangerine.resolveCert`
|
|
1692
|
+
// <https://github.com/jpnarkinsky/tangerine/commit/5f70954875aa93ef4acf076172d7540298b0a16b>
|
|
1693
|
+
// <https://www.rfc-editor.org/rfc/rfc4398.html>
|
|
1694
|
+
return result.answers.map((answer) => {
|
|
1695
|
+
if (!Buffer.isBuffer(answer.data))
|
|
1696
|
+
throw new Error('Buffer was not available');
|
|
1697
|
+
|
|
1698
|
+
try {
|
|
1699
|
+
// <https://github.com/rthalley/dnspython/blob/98b12e9e43847dac615bb690355d2fabaff969d2/dns/rdtypes/ANY/CERT.py#L69>
|
|
1700
|
+
const obj = {
|
|
1701
|
+
name: answer.name,
|
|
1702
|
+
ttl: answer.ttl,
|
|
1703
|
+
certificate_type: answer.data.subarray(0, 2).readUInt16BE(),
|
|
1704
|
+
key_tag: answer.data.subarray(2, 4).readUInt16BE(),
|
|
1705
|
+
algorithm: answer.data.subarray(4, 5).readUInt8(),
|
|
1706
|
+
certificate: answer.data.subarray(5).toString('base64')
|
|
1707
|
+
};
|
|
1708
|
+
obj.certificate_type = this.constructor.CTYPE_BY_VALUE[
|
|
1709
|
+
obj.certificate_type
|
|
1710
|
+
]
|
|
1711
|
+
? this.constructor.CTYPE_BY_VALUE[obj.certificate_type]
|
|
1712
|
+
: obj.certificate_type.toString();
|
|
1713
|
+
return obj;
|
|
1714
|
+
} catch (err) {
|
|
1715
|
+
console.error(err);
|
|
1716
|
+
throw err;
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
case 'TLSA': {
|
|
1722
|
+
// if it returns answers with `type: TLSA` then recursively lookup
|
|
1723
|
+
// 3 1 1 D6FEA64D4E68CAEAB7CBB2E0F905D7F3CA3308B12FD88C5B469F08AD 7E05C7C7
|
|
1724
|
+
return result.answers.map((answer) => {
|
|
1725
|
+
if (!Buffer.isBuffer(answer.data))
|
|
1726
|
+
throw new Error('Buffer was not available');
|
|
1727
|
+
|
|
1728
|
+
// <https://www.mailhardener.com/kb/dane>
|
|
1729
|
+
return {
|
|
1730
|
+
name: answer.name,
|
|
1731
|
+
ttl: answer.ttl,
|
|
1732
|
+
// <https://github.com/rthalley/dnspython/blob/98b12e9e43847dac615bb690355d2fabaff969d2/dns/rdtypes/tlsabase.py#L35>
|
|
1733
|
+
usage: answer.data.subarray(0, 1).readUInt8(),
|
|
1734
|
+
selector: answer.data.subarray(1, 2).readUInt8(),
|
|
1735
|
+
mtype: answer.data.subarray(2, 3).readUInt8(),
|
|
1736
|
+
cert: answer.data.subarray(3)
|
|
1737
|
+
};
|
|
1738
|
+
});
|
|
1527
1739
|
}
|
|
1528
1740
|
|
|
1529
1741
|
default: {
|
|
1530
|
-
|
|
1742
|
+
this.options.logger.error(
|
|
1743
|
+
new Error(
|
|
1744
|
+
`Submit a PR at <https://github.com/forwardemail/tangerine> with proper parsing for ${rrtype} records. You can reference <https://github.com/rthalley/dnspython/tree/master/dns/rdtypes/ANY> for inspiration.`
|
|
1745
|
+
)
|
|
1746
|
+
);
|
|
1747
|
+
return result.answers;
|
|
1531
1748
|
}
|
|
1532
1749
|
}
|
|
1533
1750
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tangerine",
|
|
3
3
|
"description": "Tangerine is the best Node.js drop-in replacement for dns.promises.Resolver using DNS over HTTPS (\"DoH\") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support).",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.4",
|
|
5
5
|
"author": "Forward Email (https://forwardemail.net)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/forwardemail/tangerine/issues"
|