dns: primero el resolutor del sistema, los publicos de respaldo
main.js preguntaba siempre a 8.8.8.8/1.1.1.1. Las VPN que evitan fugas de DNS (Mullvad) y las redes que bloquean DNS externos los rechazan, y entonces no se encontraba ningun pub por nombre: unirse a uno no hacia nada y no decia nada. Ahora va primero getaddrinfo, que respeta la VPN y el DNS privado de Android; a los 5 s, o si falla, tambien los publicos. Probado en Android 15 detras de Mullvad: antes no resolvia hacklab.laenre.net y ahora si.
This commit is contained in:
parent
b3172ed1c3
commit
ed77a13c85
1 changed files with 39 additions and 5 deletions
44
main.js
44
main.js
|
|
@ -26,6 +26,8 @@ try {
|
|||
const dns = require('dns');
|
||||
const net = require('net');
|
||||
const servers = ['8.8.8.8', '1.1.1.1', '8.8.4.4'];
|
||||
const systemLookup = dns.lookup;
|
||||
const SYSTEM_LOOKUP_MS = 5000;
|
||||
try { dns.setServers(servers); } catch (e) {}
|
||||
try { if (dns.promises && dns.promises.setServers) dns.promises.setServers(servers); } catch (e) {}
|
||||
|
||||
|
|
@ -48,11 +50,43 @@ try {
|
|||
? callback(null, [direct])
|
||||
: callback(null, direct.address, direct.family));
|
||||
}
|
||||
const resolver = family === 6 ? dns.resolve6 : dns.resolve4;
|
||||
resolver.call(dns, hostname, (err, addrs) => {
|
||||
if (err || !addrs || !addrs.length) return callback(err || new Error('ENOTFOUND ' + hostname));
|
||||
if (options.all) return callback(null, addrs.map((a) => ({ address: a, family })));
|
||||
return callback(null, addrs[0], family);
|
||||
// rama movil: primero el resolutor del sistema (getaddrinfo), que es el que
|
||||
// respeta la VPN y el DNS privado de Android. Upstream iba siempre a
|
||||
// 8.8.8.8/1.1.1.1, y las VPN que evitan fugas de DNS (Mullvad, por ejemplo)
|
||||
// o las redes que bloquean DNS externos los rechazan: no se encontraba
|
||||
// ningun pub por nombre y unirse a uno "no hacia nada". Los publicos quedan
|
||||
// de respaldo, para los moviles donde getaddrinfo no contesta.
|
||||
// Los dos caminos compiten: el del sistema sale ya y, si en SYSTEM_LOOKUP_MS
|
||||
// no ha contestado o falla, se pregunta tambien a los publicos. Gana la primera
|
||||
// respuesta buena; si fallan los dos, se devuelve el error del sistema, que
|
||||
// dice mas ("no existe") que el de unos servidores quiza bloqueados.
|
||||
let done = false, sysErr = null, pubErr = null, sysDone = false, pubDone = false, pubStarted = false;
|
||||
const finish = (err, address, fam) => {
|
||||
if (done) return;
|
||||
done = true;
|
||||
clearTimeout(timer);
|
||||
if (err) return callback(err);
|
||||
if (options.all) return callback(null, Array.isArray(address) ? address : [{ address, family: fam }]);
|
||||
if (Array.isArray(address)) return callback(null, address[0].address, address[0].family);
|
||||
return callback(null, address, fam);
|
||||
};
|
||||
const bothFailed = () => { if (sysDone && pubDone) finish(sysErr || pubErr || new Error('ENOTFOUND ' + hostname)); };
|
||||
const viaPublic = () => {
|
||||
if (pubStarted) return;
|
||||
pubStarted = true;
|
||||
const resolver = family === 6 ? dns.resolve6 : dns.resolve4;
|
||||
resolver.call(dns, hostname, (err, addrs) => {
|
||||
pubDone = true;
|
||||
if (err || !addrs || !addrs.length) { pubErr = err || new Error('ENOTFOUND ' + hostname); return bothFailed(); }
|
||||
finish(null, options.all ? addrs.map((x) => ({ address: x, family })) : addrs[0], family);
|
||||
});
|
||||
};
|
||||
const timer = setTimeout(viaPublic, SYSTEM_LOOKUP_MS);
|
||||
systemLookup.call(dns, hostname, { family, all: !!options.all }, (err, address, fam) => {
|
||||
sysDone = true;
|
||||
if (!err) return finish(null, address, fam);
|
||||
sysErr = err;
|
||||
if (pubStarted) bothFailed(); else viaPublic();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue