Improve DNS code

This commit is contained in:
Younes Aassila 2024-03-10 14:26:35 +01:00
parent 8c08879522
commit c891597ac7
2 changed files with 50 additions and 31 deletions

View File

@ -1,74 +1,74 @@
import ip from "ip"; import ip from "ip";
import store from "../../store"; import store from "../../store";
import type { DnsResponse } from "../../types"; import type { DnsResponse, DnsResponseJson } from "../../types";
import { getProxyInfoFromUrl } from "./proxyInfo"; import { getProxyInfoFromUrl } from "./proxyInfo";
export default async function updateDnsResponses() { export default async function updateDnsResponses() {
const proxies = [ const proxies = store.state.optimizedProxiesEnabled
...store.state.optimizedProxies, ? store.state.optimizedProxies
...store.state.normalProxies, : store.state.normalProxies;
];
const proxyInfoArray = proxies.map(getProxyInfoFromUrl); const proxyInfoArray = proxies.map(getProxyInfoFromUrl);
for (const proxyInfo of proxyInfoArray) { for (const proxyInfo of proxyInfoArray) {
const { host } = proxyInfo; const { host } = proxyInfo;
// Check if we already have a valid DNS response for this host.
const dnsResponseIndex = store.state.dnsResponses.findIndex( const dnsResponseIndex = store.state.dnsResponses.findIndex(
dnsResponse => dnsResponse.host === host dnsResponse => dnsResponse.host === host
); );
const dnsResponse = const isDnsResponseValid =
dnsResponseIndex !== -1 dnsResponseIndex !== -1 &&
? store.state.dnsResponses[dnsResponseIndex] Date.now() - store.state.dnsResponses[dnsResponseIndex].timestamp <
: null; store.state.dnsResponses[dnsResponseIndex].ttl * 1000;
if ( if (isDnsResponseValid) {
dnsResponse != null &&
Date.now() - dnsResponse.timestamp < dnsResponse.ttl * 1000
) {
continue; continue;
} }
if (ip.isV4Format(host) || ip.isV6Format(host)) { // If the host is an IP address, we don't need to make a DNS request.
const isIp = ip.isV4Format(host) || ip.isV6Format(host);
if (isIp) {
if (dnsResponseIndex !== -1) { if (dnsResponseIndex !== -1) {
store.state.dnsResponses.splice(dnsResponseIndex, 1); store.state.dnsResponses.splice(dnsResponseIndex, 1);
} }
store.state.dnsResponses.push({ const dnsResponse: DnsResponse = {
host, host,
ips: [host], ips: [host],
timestamp: Date.now(), timestamp: Date.now(),
ttl: Infinity, ttl: Infinity,
} as DnsResponse); };
store.state.dnsResponses.push(dnsResponse);
continue; continue;
} }
// Make the DNS request.
try { try {
const response = await fetch( const response = await fetch(
`https://cloudflare-dns.com/dns-query?name=${host}`, `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(host)}`,
{ {
headers: { headers: {
Accept: "application/dns-json", Accept: "application/dns-json",
}, },
} }
); );
const json = await response.json(); if (!response.ok) {
const { Answer } = json; throw new Error(`HTTP ${response.status}`);
if (!Array.isArray(Answer)) {
console.error("Answer is not an array:", Answer);
continue;
} }
const ips = Answer.map((answer: any) => answer.data as string); const data: DnsResponseJson = await response.json();
const ttl = Math.max( if (data.Status !== 0) {
Math.max(...Answer.map((answer: any) => answer.TTL as number)), throw new Error(`DNS status ${data.Status}`);
300 }
); const { Answer } = data;
if (dnsResponseIndex !== -1) { if (dnsResponseIndex !== -1) {
store.state.dnsResponses.splice(dnsResponseIndex, 1); store.state.dnsResponses.splice(dnsResponseIndex, 1);
} }
store.state.dnsResponses.push({ const dnsResponse: DnsResponse = {
host, host,
ips, ips: Answer.map(answer => answer.data),
timestamp: Date.now(), timestamp: Date.now(),
ttl, ttl: Math.max(Math.max(...Answer.map(answer => answer.TTL)), 300),
} as DnsResponse); };
store.state.dnsResponses.push(dnsResponse);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }

View File

@ -51,6 +51,25 @@ export interface DnsResponse {
ttl: number; ttl: number;
} }
export interface DnsResponseJson {
Status: number;
TC: boolean; // Truncated
RD: boolean; // Recursion Desired
RA: boolean; // Recursion Available
AD: boolean; // Authentic Data
CD: boolean; // Checking Disabled
Question: {
name: string;
type: number;
}[];
Answer: {
name: string;
type: number;
TTL: number;
data: string;
}[];
}
export const enum MessageType { export const enum MessageType {
ContentScriptMessage = "TLP_ContentScriptMessage", ContentScriptMessage = "TLP_ContentScriptMessage",
PageScriptMessage = "TLP_PageScriptMessage", PageScriptMessage = "TLP_PageScriptMessage",