From f4538a4f53af0b786b9d86ddda2d9cb84e20dd3e Mon Sep 17 00:00:00 2001 From: Buffrr Date: Thu, 8 Jul 2021 23:48:03 -0700 Subject: [PATCH 1/2] Add error handling to Ethereum lookups --- lib/ethereum.js | 8 ++++++ lib/handover.js | 72 ++++++++++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/lib/ethereum.js b/lib/ethereum.js index a7298d1..26f474e 100644 --- a/lib/ethereum.js +++ b/lib/ethereum.js @@ -55,6 +55,10 @@ class Ethereum { async getResolverFromRegistry(name, registry) { const resolverAddr = await registry.resolver(this.namehash(name)); + if (resolverAddr === '0x0000000000000000000000000000000000000000') { + return null; + } + return new ethers.Contract(resolverAddr, RESOLVER_ABI, this.infura); } @@ -101,6 +105,10 @@ class Ethereum { } async resolveDnsWithResolver(name, type, node, resolver) { + if (!resolver) { + return null; + } + let record = this.cache.getRecord(name, type, resolver.address); if (!record) { record = await resolver.dnsRecord( diff --git a/lib/handover.js b/lib/handover.js index 36f995f..2a78d11 100644 --- a/lib/handover.js +++ b/lib/handover.js @@ -48,13 +48,17 @@ class Plugin { case 'eth.': if (labels.length < 2) { return this.sendSOA(); - } else { - data = await this.ethereum.resolveDnsFromEns(name, type); - if (!data || data.length === 0) - return this.sendSOA(); + } - return this.sendData(data, type); + try { + data = await this.ethereum.resolveDnsFromEns(name, type); + if (data && data.length > 0) + return this.sendData(data, type); + } catch (e) { + this.logger.warning('Resolution failed for name: %s', name); + this.logger.debug(e.stack); } + return this.sendSOA(); case '_eth.': return this.sendSOA(); } @@ -68,14 +72,16 @@ class Plugin { return res; let hasEnsReferral = false; - // Check NS records for referals to TLDs `.eth` and `._eth` + // Check NS records for referrals to TLDs `.eth` and `._eth` for (const rr of res.authority) { if (rr.type !== wire.types.NS) continue; + const ending = util.label(rr.data.ns, util.split(rr.data.ns), -1); + // Look up the ENS resolver specified in the NS record // and query it for the user's original request - if (rr.data.ns.slice(-5) === '.eth.') { + if (ending === '_eth' || ending === 'eth') { hasEnsReferral = true; // If the recursive is being minimal, don't look up the name. @@ -83,43 +89,35 @@ class Plugin { if (labels.length < 2) { return this.sendSOA(); } - this.logger.debug( - 'Intercepted referral to .eth: %s %s -> NS: %s', + 'Intercepted referral to .%s: %s %s -> %s NS: %s', + ending, name, wire.typesByVal[type], + rr.name, rr.data.ns ); - data = await this.ethereum.resolveDnsFromEns( - name, - type, - rr.data.ns - ); - } - - // Look up an alternate (forked) ENS contract by the Ethereum - // address specified in the NS record, and query it for - // the user's original request - if (rr.data.ns.slice(-6) === '._eth.') { - hasEnsReferral = true; - // If the recursive is being minimal, don't look up the name. - // Send the SOA back and get the full query from the recursive . - if (labels.length < 2) { - return this.sendSOA(); + try { + if (ending === 'eth') { + data = await this.ethereum.resolveDnsFromEns( + name, + type, + rr.data.ns + ); + } else { + // Look up an alternate (forked) ENS contract by the Ethereum + // address specified in the NS record + data = await this.ethereum.resolveDnsFromAbstractEns( + name, + type, + rr.data.ns + ); + } + } catch (e) { + this.logger.warning('Resolution failed for name: %s', name); + this.logger.debug(e.stack); } - this.logger.debug( - 'Intercepted referral to ._eth: %s %s -> %s NS: %s', - name, - wire.typesByVal[type], - rr.name, - rr.data.ns - ); - data = await this.ethereum.resolveDnsFromAbstractEns( - name, - type, - rr.data.ns - ); } } From b59cc92d9f18cc5f1b49e2292cb379ab59360ae6 Mon Sep 17 00:00:00 2001 From: Buffrr Date: Tue, 13 Jul 2021 20:54:57 -0700 Subject: [PATCH 2/2] Update comments/refactor for future HIP-5 extensions --- lib/handover.js | 55 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/lib/handover.js b/lib/handover.js index 2a78d11..0105056 100644 --- a/lib/handover.js +++ b/lib/handover.js @@ -58,6 +58,7 @@ class Plugin { this.logger.warning('Resolution failed for name: %s', name); this.logger.debug(e.stack); } + return this.sendSOA(); case '_eth.': return this.sendSOA(); @@ -71,18 +72,18 @@ class Plugin { if (!res.authority.length) return res; - let hasEnsReferral = false; - // Check NS records for referrals to TLDs `.eth` and `._eth` + let hip5Referral = false; + // Check NS records for HIP-5 referrals for (const rr of res.authority) { if (rr.type !== wire.types.NS) continue; const ending = util.label(rr.data.ns, util.split(rr.data.ns), -1); - // Look up the ENS resolver specified in the NS record - // and query it for the user's original request + // Look for any supported HIP-5 extension in the NS record + // and query it for the user's original request. if (ending === '_eth' || ending === 'eth') { - hasEnsReferral = true; + hip5Referral = true; // If the recursive is being minimal, don't look up the name. // Send the SOA back and get the full query from the recursive . @@ -99,20 +100,23 @@ class Plugin { ); try { - if (ending === 'eth') { - data = await this.ethereum.resolveDnsFromEns( - name, - type, - rr.data.ns - ); - } else { - // Look up an alternate (forked) ENS contract by the Ethereum - // address specified in the NS record - data = await this.ethereum.resolveDnsFromAbstractEns( - name, - type, - rr.data.ns - ); + switch (ending) { + case 'eth': + data = await this.ethereum.resolveDnsFromEns( + name, + type, + rr.data.ns + ); + break; + case '_eth': + // Look up an alternate (forked) ENS contract by the Ethereum + // address specified in the NS record + data = await this.ethereum.resolveDnsFromAbstractEns( + name, + type, + rr.data.ns + ); + break; } } catch (e) { this.logger.warning('Resolution failed for name: %s', name); @@ -121,20 +125,19 @@ class Plugin { } } - // If the Ethereum stuff came up empty, return the - // HNS root server response unmodified. if (!data || data.length === 0) { - // never send referrals that end with .eth or ._eth - // since recursive may cache these referrals causing a servfail - // for future lookups - if (hasEnsReferral) { + // Never send HIP-5 type referrals to recursive resolvers + // since they aren't real delegations and it could end up + // poisoning their cache. + if (hip5Referral) { return this.sendSOA(); } + // return the HNS root server response unmodified. return res; } - // If we did get an answer from Ethereum, mark the response + // If we did get an answer, mark the response // as authoritative and send the new answer. this.logger.debug('Returning answers from alternate naming system'); return this.sendData(data, type);