From 563aed0d9374f07fcb46436f437813d860ba39c9 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 20 Nov 2019 10:45:17 -0500 Subject: [PATCH] Code review for dns lookup code Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/780 - Handle DNS lookup failure - Skip DNS lookup for non network-based URLs - Benchmark code to be able to provide an estimate based on objective measurements regarding added overhead when DNS lookup is enabled (quick answer: a complete non-issue) --- platform/chromium/vapi-background.js | 33 ++++++++++++++++++++++++++++ platform/chromium/vapi-common.js | 8 +++++++ platform/firefox/vapi-webrequest.js | 13 ++++++----- src/js/filtering-context.js | 2 +- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index 450372c99..e294047cd 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -1252,6 +1252,39 @@ vAPI.Net = class { canSuspend() { return false; } + async benchmark() { + if ( typeof µBlock !== 'object' ) { return; } + const requests = await µBlock.loadBenchmarkDataset(); + if ( Array.isArray(requests) === false || requests.length === 0 ) { + console.info('No requests found to benchmark'); + return; + } + console.info('vAPI.net.onBeforeSuspendableRequest()...'); + const t0 = self.performance.now(); + const promises = []; + for ( const request of requests ) { + const details = { + documentUrl: request.frameUrl, + tabId: Number.MAX_SAFE_INTEGER, + parentFrameId: -1, + frameId: 0, + type: request.cpt, + url: request.url, + }; + promises.push(this.onBeforeSuspendableRequest(details)); + } + return Promise.all(promises).then(results => { + let blockCount = 0; + for ( const r of results ) { + if ( r !== undefined ) { blockCount += 1; } + } + const t1 = self.performance.now(); + const dur = t1 - t0; + console.info(`Evaluated ${requests.length} requests in ${dur.toFixed(0)} ms`); + console.info(`\tBlocked ${blockCount} requests`); + console.info(`\tAverage: ${(dur / requests.length).toFixed(3)} ms per request`); + }); + } }; /******************************************************************************/ diff --git a/platform/chromium/vapi-common.js b/platform/chromium/vapi-common.js index f9772f66f..dcd11d36f 100644 --- a/platform/chromium/vapi-common.js +++ b/platform/chromium/vapi-common.js @@ -149,6 +149,14 @@ vAPI.webextFlavor = { return hostname; }; + const reHostnameFromNetworkURL = + /^(?:http|ws|ftp)s?:\/\/([0-9a-z_][0-9a-z._-]*[0-9a-z])\//; + + vAPI.hostnameFromNetworkURL = function(url) { + const matches = reHostnameFromNetworkURL.exec(url); + return matches !== null ? matches[1] : ''; + }; + const psl = self.publicSuffixList; const reIPAddressNaive = /^\d+\.\d+\.\d+\.\d+$|^\[[\da-zA-Z:]+\]$/; diff --git a/platform/firefox/vapi-webrequest.js b/platform/firefox/vapi-webrequest.js index efbbce280..d0c95b9ec 100644 --- a/platform/firefox/vapi-webrequest.js +++ b/platform/firefox/vapi-webrequest.js @@ -60,7 +60,7 @@ constructor() { super(); this.pendingRequests = []; - this.cnames = new Map(); + this.cnames = new Map([ [ '', '' ] ]); this.cnameAliasList = null; this.cnameIgnoreList = null; this.url = new URL(vAPI.getURL('/')); @@ -73,7 +73,7 @@ this.cnameIgnoreList = this.regexFromStrList(options.cnameIgnoreList); this.cnameIgnore1stParty = options.cnameIgnore1stParty === true; this.cnameMaxTTL = options.cnameMaxTTL || 120; - this.cnames.clear(); + this.cnames.clear(); this.cnames.set('', ''); } normalizeDetails(details) { if ( mustPunycode && !reAsciiHostname.test(details.url) ) { @@ -148,7 +148,6 @@ this.cnameIgnoreList !== null && this.cnameIgnoreList.test(cname) ) { - cname = ''; } this.cnames.set(hn, cname); @@ -156,7 +155,7 @@ this.cnameTimer = self.setTimeout( ( ) => { this.cnameTimer = undefined; - this.cnames.clear(); + this.cnames.clear(); this.cnames.set('', ''); }, this.cnameMaxTTL * 60000 ); @@ -188,7 +187,7 @@ let r = super.onBeforeSuspendableRequest(details); if ( r !== undefined ) { return r; } if ( this.cnameAliasList === null ) { return; } - const hn = vAPI.hostnameFromURI(details.url); + const hn = vAPI.hostnameFromNetworkURL(details.url); let cname = this.cnames.get(hn); if ( cname === '' ) { return; } if ( cname !== undefined ) { @@ -202,7 +201,9 @@ const cname = this.recordCanonicalName(hn, rec); if ( cname === '' ) { return; } return this.processCanonicalName(cname, details); - + }).catch(( ) => { + this.cnames.set(hn, ''); + }).then(( ) => { }); } suspendOneRequest(details) { diff --git a/src/js/filtering-context.js b/src/js/filtering-context.js index e9dbe8f29..5be3afd21 100644 --- a/src/js/filtering-context.js +++ b/src/js/filtering-context.js @@ -66,7 +66,7 @@ this.realm = ''; this.type = details.type; this.setURL(details.url); - this.cnameOf = details.cnameOf !== undefined ? details.cnameOf : ''; + this.cnameOf = details.cnameOf || undefined; this.docId = details.type !== 'sub_frame' ? details.frameId : details.parentFrameId;