Skip to content

Commit f073bdf

Browse files
committed
feat: added note regarding compatibility with wildcard local dns matching
1 parent 35a88ed commit f073bdf

File tree

3 files changed

+43
-28
lines changed

3 files changed

+43
-28
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
* [`tangerine.setServers(servers)`](#tangerinesetserversservers)
5959
* [Options](#options)
6060
* [Cache](#cache)
61+
* [Compatibility](#compatibility)
6162
* [Debugging](#debugging)
6263
* [Benchmarks](#benchmarks)
6364
* [Tangerine Benchmarks](#tangerine-benchmarks)
@@ -430,6 +431,15 @@ await tangerine.resolve('forwardemail.net'); // uses cached value
430431
This purge cache feature is useful for DNS records that have recently changed and have had their caches purged at the relevant DNS provider (e.g. [Cloudflare's Purge Cache tool](https://1.1.1.1/purge-cache/)).
431432
432433
434+
## Compatibility
435+
436+
The only known compatibility issue is for locally running DNS servers that have wildcard DNS matching.
437+
438+
If you are using `dnsmasq` with a wildcard match on "localhost" to "127.0.0.1", then the results may vary. For example, if your `dnsmasq` configuration has `address=/localhost/127.0.0.1`, then any match of `localhost` will resolve to `127.0.0.1`. This means that `dns.promises.lookup('foo.localhost')` will return `127.0.0.1` – however with :tangerine: Tangerine it will not return a value.
439+
440+
The reason is because :tangerine: Tangerine only looks at either `/etc/hosts` (macOS/Linux) and `C:/Windows/System32/drivers/etc/hosts` (Windows). It does not lookup BIND, dnsmasq, or other configurations running locally. We would welcome a PR to resolve this (see `isCI` usage in test folder) – however it is a non-issue, as the workaround is to simply append a new line to the hostfile of `127.0.0.1 foo.localhost`.
441+
442+
433443
## Debugging
434444
435445
If you run into issues while using :tangerine: Tangerine, then these recommendations may help:

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"husky": "^8.0.3",
4242
"ioredis": "^5.3.1",
4343
"ioredis-mock": "^8.2.6",
44+
"is-ci": "^3.0.1",
4445
"lint-staged": "^13.1.2",
4546
"lodash": "^4.17.21",
4647
"nock": "^13.3.0",

test/test.js

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const fs = require('node:fs');
33
const { Buffer } = require('node:buffer');
44
const { isIP, isIPv4, isIPv6 } = require('node:net');
55

6+
const isCI = require('is-ci');
67
const Redis = require('ioredis-mock');
78
const _ = require('lodash');
89
const got = require('got');
@@ -348,32 +349,39 @@ for (const host of [
348349
});
349350

350351
// tangerine.lookup"${host}"[, options])
351-
test(`lookup("${host}")`, async (t) => {
352-
// returns { address: IP , family: 4 || 6 }
353-
const tangerine = new Tangerine();
354-
let r1;
355-
let r2;
356-
try {
357-
r1 = await tangerine.lookup(host);
358-
} catch (err) {
359-
r1 = err;
360-
}
352+
//
353+
// TODO: if the local DNS resolver on the server that c-ares communicates with
354+
// is using a wildcard or regex based approach for matching hostnames
355+
// then it won't match in these tests because we only check for /etc/hosts
356+
// (see #compatibility section of README for more insight)
357+
//
358+
if (!isCI || !['.', 'foo.localhost', 'foo.bar.localhost'].includes(host))
359+
test(`lookup("${host}")`, async (t) => {
360+
// returns { address: IP , family: 4 || 6 }
361+
const tangerine = new Tangerine();
362+
let r1;
363+
let r2;
364+
try {
365+
r1 = await tangerine.lookup(host);
366+
} catch (err) {
367+
r1 = err;
368+
}
361369

362-
try {
363-
r2 = await dns.promises.lookup(host);
364-
} catch (err) {
365-
r2 = err;
366-
}
370+
try {
371+
r2 = await dns.promises.lookup(host);
372+
} catch (err) {
373+
r2 = err;
374+
}
367375

368-
t.log(r1);
369-
t.log(r2);
376+
t.log(r1);
377+
t.log(r2);
370378

371-
if (_.isPlainObject(r1)) r1 = [r1];
372-
if (_.isPlainObject(r2)) r2 = [r2];
373-
if (!_.isError(r1)) r1 = r1.every((o) => isIP(o.address) === o.family);
374-
if (!_.isError(r2)) r2 = r2.every((o) => isIP(o.address) === o.family);
375-
t.deepEqual(r1, r2);
376-
});
379+
if (_.isPlainObject(r1)) r1 = [r1];
380+
if (_.isPlainObject(r2)) r2 = [r2];
381+
if (!_.isError(r1)) r1 = r1.every((o) => isIP(o.address) === o.family);
382+
if (!_.isError(r2)) r2 = r2.every((o) => isIP(o.address) === o.family);
383+
t.deepEqual(r1, r2);
384+
});
377385

378386
// tangerine.resolve"${host}"[, rrtype])
379387
test(`resolve("${host}")`, async (t) => {
@@ -482,11 +490,7 @@ for (const host of [
482490
});
483491

484492
// tangerine.resolveAny"${host}"[, abortController])
485-
// TODO: figure out why we have to skip this (?)
486-
// basically it works locally, but on GitHub CI there is different results
487-
// r1 has results (e.g. ns servers)
488-
// r2 is err with ENODATA
489-
if (host !== '.')
493+
if (!isCI)
490494
test(`resolveAny("${host}")`, async (t) => {
491495
const tangerine = new Tangerine();
492496
const resolver = new Resolver();

0 commit comments

Comments
 (0)