Get the latest tech news
Rewrite cname uncloaking code to account for new ipaddress= option
This commit makes the DNS resolution code better suited for both filtering on cname and ip address. The change allows early availability of ip address so that `ipaddress=` option can be matched at ...
Expand Up@@ -26,8 +26,10 @@ import {/******************************************************************************/// Canonical name-uncloaking feature.letcnameUncloakEnabled=browser.dnsinstanceofObject;constdnsAPI=browser.dns;constisPromise=o=>oinstanceofPromise;constreIPv4=/^\d+\.\d+\.\d+\.\d+$/// Related issues:// - https://github.com/gorhill/uBlock/issues/1327Expand All@@ -40,21 +42,24 @@ vAPI.Net = class extends vAPI.Net {constructor(){super();this.pendingRequests=[];this.canUncloakCnames=browser.dnsinstanceofObject;this.cnames=newMap([['',null]]);this.dnsList=[];// ring bufferthis.dnsWritePtr=0;// next write pointer in ring bufferthis.dnsMaxCount=256;// max size of ring bufferthis.dnsDict=newMap();// hn to index in ring bufferthis.dnsEntryTTL=60000;// delay after which an entry is obsoletethis.canUncloakCnames=true;this.cnameUncloakEnabled=true;this.cnameIgnoreList=null;this.cnameIgnore1stParty=true;this.cnameIgnoreExceptions=true;this.cnameIgnoreRootDocument=true;this.cnameMaxTTL=120;this.cnameReplayFullURL=false;this.cnameFlushTime=Date.now()+this.cnameMaxTTL*60000;}setOptions(options){super.setOptions(options);if('cnameUncloakEnabled'inoptions){cnameUncloakEnabled=this.canUncloakCnames&&this.cnameUncloakEnabled=options.cnameUncloakEnabled!==false;}if('cnameIgnoreList'inoptions){Expand All@@ -73,15 +78,13 @@ vAPI.Net = class extends vAPI.Net {this.cnameIgnoreRootDocument=options.cnameIgnoreRootDocument!==false;}if('cnameMaxTTL'inoptions){this.cnameMaxTTL=options.cnameMaxTTL||120;}if('cnameReplayFullURL'inoptions){this.cnameReplayFullURL=options.cnameReplayFullURL===true;}this.cnames.clear();this.cnames.set('',null);this.cnameFlushTime=Date.now()+this.cnameMaxTTL*60000;this.dnsList.fill(null);this.dnsDict.clear();}normalizeDetails(details){consttype=details.type;Expand All@@ -104,6 +107,7 @@ vAPI.Net = class extends vAPI.Net {}}}denormalizeTypes(types){if(types.length===0){returnArray.from(this.validTypes);Expand All@@ -122,75 +126,19 @@ vAPI.Net = class extends vAPI.Net {}returnArray.from(out);}canonicalNameFromHostname(hn){constcnRecord=this.cnames.get(hn);if(cnRecord!==undefined&&cnRecord!==null){returncnRecord.cname;}}processCanonicalName(hn,cnRecord,details){if(cnRecord===null){return;}if(cnRecord.isRootDocument){return;}consthnBeg=details.url.indexOf(hn);if(hnBeg===-1){return;}constoldURL=details.url;letnewURL=oldURL.slice(0,hnBeg)+cnRecord.cname;consthnEnd=hnBeg+hn.length;if(this.cnameReplayFullURL){newURL+=oldURL.slice(hnEnd);}else{constpathBeg=oldURL.indexOf('/',hnEnd);if(pathBeg!==-1){newURL+=oldURL.slice(hnEnd,pathBeg+1);}}details.url=newURL;details.aliasURL=oldURL;returnsuper.onBeforeSuspendableRequest(details);}recordCanonicalName(hn,record,isRootDocument){if((this.cnames.size&0b111111)===0){constnow=Date.now();if(now>=this.cnameFlushTime){this.cnames.clear();this.cnames.set('',null);this.cnameFlushTime=now+this.cnameMaxTTL*60000;}}letcname=typeofrecord.canonicalName==='string'&&record.canonicalName!==hn ? { cname, isRootDocument } : null;this.cnames.set(hn,cnRecord);returncnRecord;if(hn===''){return;}constdnsEntry=this.dnsFromCache(hn);if(isPromise(dnsEntry)){return;}returndnsEntry?.cname;}regexFromStrList(list){if(typeoflist!=='string'||list.length===0||list==='unset'||browser.dnsinstanceofObject===false){if(typeoflist!=='string'||list.length===0||list==='unset'){returnnull;}if(list==='*'){return/^./;}if(list==='*'){return/^./;}returnnewRegExp('(?:^|\\.)(? :'+list.trim()Expand All@@ -200,9 +148,14 @@ vAPI.Net = class extends vAPI.Net {')$');}onBeforeSuspendableRequest(details){consthn=hostnameFromNetworkURL(details.url);constdnsEntry=this.dnsFromCache(hn);if(dnsEntry?.ip){details.ip=dnsEntry.ip;}constr=super.onBeforeSuspendableRequest(details);if(cnameUncloakEnabled===false){returnr;}if(r!==undefined){if(r.cancel===true||Expand All@@ -212,25 +165,128 @@ vAPI.Net = class extends vAPI.Net {returnr;}}consthn=hostnameFromNetworkURL(details.url);constcnRecord=this.cnames.get(hn);if(cnRecord!==undefined){returnthis.processCanonicalName(hn,cnRecord,details);if(dnsEntry!==undefined){if(isPromise(dnsEntry)===false){returnthis.onAfterDNSResolution(hn,details,dnsEntry);}}if(details.proxyInfo&&details.proxyInfo.proxyDNS){return;}constdocumentUrl=details.documentUrl||details.url;constisRootDocument=this.cnameIgnoreRootDocument&&hn===hostnameFromNetworkURL(documentUrl);returnbrowser.dns.resolve(hn,['canonical_name']).then(rec=>{constcnRecord=this.recordCanonicalName(hn,rec,isRootDocument);returnthis.processCanonicalName(hn,cnRecord,details);},()=>{this.cnames.set(hn,null);if(this.dnsShouldResolve(hn)===false){return;}if(details.proxyInfo?.proxyDNS){return;}constpromise=dnsEntry||this.dnsResolve(hn,details);returnpromise.then(()=>this.onAfterDNSResolution(hn,details));}onAfterDNSResolution(hn,details,dnsEntry){if(dnsEntry===undefined){dnsEntry=this.dnsFromCache(hn);if(dnsEntry===undefined||isPromise(dnsEntry)){return;}}letproceed=false;if(dnsEntry.cname&&this.cnameUncloakEnabled){constnewURL=this.uncloakURL(hn,dnsEntry,details);if(newURL){details.aliasURL=details.url;details.url=newURL;proceed=true;}}if(dnsEntry.ip&&details.ip!==dnsEntry.ip){details.ip=dnsEntry.ipproceed=true;}if(proceed===false){return;}// Must call method on base classreturnsuper.onBeforeSuspendableRequest(details);}dnsToCache(hn,record,details){consti=this.dnsDict.get(hn);if(i===undefined){return;}constdnsEntry={ hn,until: Date.now()+this.dnsEntryTTL,};if(record){constcname=this.cnameFromRecord(hn,record,details);if(cname){dnsEntry.cname=cname;}constip=this.ipFromRecord(record);if(ip){dnsEntry.ip=ip;}}this.dnsList[i]=dnsEntry;returndnsEntry;}dnsFromCache(hn){consti=this.dnsDict.get(hn);if(i===undefined){return;}constdnsEntry=this.dnsList[i];if(dnsEntry===null){return;}if(isPromise(dnsEntry)){returndnsEntry;}if(dnsEntry.hn!==hn){return;}if(dnsEntry.until>=Date.now()){returndnsEntry;}this.dnsList[i]=null;this.dnsDict.delete(hn)}dnsShouldResolve(hn){if(hn===''){returnfalse;}constc0=hn.charCodeAt(0);if(c0===0x5B/* [ */){returnfalse;}if(c0>0x39/* 9 */){returntrue;}returnreIPv4.test(hn)===false;}dnsResolve(hn,details){consti=this.dnsWritePtr++;this.dnsWritePtr%=this.dnsMaxCount;this.dnsDict.set(hn,i);constpromise=dnsAPI.resolve(hn,['canonical_name']).then(rec=>this.dnsToCache(hn,rec,details),()=>this.dnsToCache(hn));return(this.dnsList[i]=promise);}cnameFromRecord(hn,record,details){constcn=record.canonicalName;if(cn===undefined){return;}if(cn===hn){return;}if(this.cnameIgnore1stParty){if(domainFromHostname(cn)===domainFromHostname(hn)){return;}}if(this.cnameIgnoreList!==null){if(this.cnameIgnoreList.test(cn)===false){return;}}if(this.cnameIgnoreRootDocument){constorigin=hostnameFromNetworkURL(details.documentUrl||details.url);if(hn===origin){return;}}returncn;}uncloakURL(hn,dnsEntry,details){consthnBeg=details.url.indexOf(hn);if(hnBeg===-1){return;}constoldURL=details.url;constnewURL=oldURL.slice(0,hnBeg)+dnsEntry.cname;consthnEnd=hnBeg+hn.length;if(this.cnameReplayFullURL){returnnewURL+oldURL.slice(hnEnd);}constpathBeg=oldURL.indexOf('/',hnEnd);if(pathBeg!==-1){returnnewURL+oldURL.slice(hnEnd,pathBeg+1);}returnnewURL;}ipFromRecord(record){const{ addresses }=record;if(Array.isArray(addresses)===false){return;}if(addresses.length===0){return;}returnaddresses[0];}suspendOneRequest(details){constpending={details: Object.assign({},details),Expand All@@ -243,6 +299,7 @@ vAPI.Net = class extends vAPI.Net {this.pendingRequests.push(pending);returnpending.promise;}unsuspendAllRequests(discard=false){constpendingRequests=this.pendingRequests;this.pendingRequests=[];Expand All@@ -254,6 +311,7 @@ vAPI.Net = class extends vAPI.Net {);}}staticcanSuspend(){returntrue;}Expand Down
Or read this on Hacker News