-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat(dns): Add real-time DNS speed benchmark and 'Fastest' auto-selection option #4935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| function Get-WinUtilDNSBenchmark { | ||
| <# | ||
|
|
||
| .SYNOPSIS | ||
| Benchmarks configured DNS providers by measuring TCP port 53 latency (RTT in ms) to determine the fastest DNS server. | ||
|
|
||
| .PARAMETER TimeoutMs | ||
| Maximum timeout in milliseconds for each connection test. Default is 1500ms. | ||
|
|
||
| .OUTPUTS | ||
| Array of PSCustomObjects containing Provider, PrimaryIP, and LatencyMs sorted by lowest latency. | ||
|
|
||
| .EXAMPLE | ||
| $results = Get-WinUtilDNSBenchmark | ||
| $fastest = $results[0] | ||
|
|
||
| #> | ||
| [CmdletBinding()] | ||
| param( | ||
| [int]$TimeoutMs = 1500 | ||
| ) | ||
|
|
||
| Write-WinUtilLog -Component "DNS" -Message "Starting DNS latency benchmark scan (TCP port 53)..." | ||
|
|
||
| $dnsConfigs = $sync.configs.dns | ||
| if ($null -eq $dnsConfigs) { | ||
| Write-Warning "DNS configurations not found in `$sync.configs.dns." | ||
| Write-WinUtilLog -Level "ERROR" -Component "DNS" -Message "DNS configurations not found in `$sync.configs.dns." | ||
| return @() | ||
| } | ||
|
|
||
| $results = [System.Collections.Generic.List[PSObject]]::new() | ||
|
|
||
| foreach ($prop in $dnsConfigs.PSObject.Properties) { | ||
| $providerName = $prop.Name | ||
| $primaryIp = $prop.Value.Primary | ||
| if (-not $primaryIp) { continue } | ||
|
|
||
| $latency = 9999 | ||
| $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() | ||
| try { | ||
| $client = New-Object System.Net.Sockets.TcpClient | ||
| $asyncResult = $client.BeginConnect($primaryIp, 53, $null, $null) | ||
| $success = $asyncResult.AsyncWaitHandle.WaitOne($TimeoutMs, $false) | ||
| $stopwatch.Stop() | ||
| if ($success -and $client.Connected) { | ||
| $latency = [int]$stopwatch.ElapsedMilliseconds | ||
| $client.Close() | ||
| } else { | ||
| $latency = 9999 | ||
| if ($client) { $client.Close() } | ||
| } | ||
| } catch { | ||
| $latency = 9999 | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| $results.Add([PSCustomObject]@{ | ||
| Provider = $providerName | ||
| PrimaryIP = $primaryIp | ||
| LatencyMs = $latency | ||
| }) | ||
| } | ||
|
|
||
| $sortedResults = @($results | Sort-Object LatencyMs) | ||
| if ($sortedResults.Count -gt 0 -and $sortedResults[0].LatencyMs -lt 9999) { | ||
| $fastest = $sortedResults[0] | ||
| Write-WinUtilLog -Component "DNS" -Message "DNS Benchmark completed. Fastest: $($fastest.Provider) ($($fastest.LatencyMs) ms)" | ||
| } else { | ||
| Write-WinUtilLog -Component "DNS" -Message "DNS Benchmark completed. Could not determine latency for providers." | ||
| } | ||
|
|
||
| return $sortedResults | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,21 @@ function Set-WinUtilDNS { | |
| return | ||
| } | ||
|
|
||
| if($DNSProvider -eq "Fastest") { | ||
| Write-WinUtilLog -Component "DNS" -Message "Auto-detecting fastest DNS provider via latency benchmark..." | ||
| $benchmark = Get-WinUtilDNSBenchmark | ||
| $validFastest = $benchmark | Where-Object { $_.LatencyMs -lt 9999 } | Select-Object -First 1 | ||
| if ($validFastest) { | ||
| $DNSProvider = $validFastest.Provider | ||
| Write-Host "Auto-selected fastest DNS provider: $DNSProvider ($($validFastest.LatencyMs) ms)" | ||
| Write-WinUtilLog -Component "DNS" -Message "Auto-selected fastest DNS provider: $DNSProvider ($($validFastest.LatencyMs) ms)" | ||
| } else { | ||
| $DNSProvider = "Cloudflare" | ||
| Write-Warning "Could not measure DNS latency; defaulting to Cloudflare." | ||
| Write-WinUtilLog -Component "DNS" -Message "Benchmark timeout; defaulting to Cloudflare." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When AGENTS.md reference: AGENTS.md:L84-L91 Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Useful? React with 👍 / 👎. |
||
| } | ||
| } | ||
|
|
||
| try { | ||
| $Adapters = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | ||
| Write-Host "Ensuring DNS is set to $DNSProvider on the following interfaces:" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this benchmarks every entry in
config/dns.json, choosingFastestcan silently configure a policy/filtering resolver such asCloudflare_Malware_AdultorAdGuard_Ads_Trackers_Malware_Adultwhenever that primary IP has the lowest TCP latency. In that scenario a speed choice unexpectedly enables content blocking/rewriting behavior, so the auto-selection should be restricted to neutral providers or otherwise require an explicit filtering choice.Useful? React with 👍 / 👎.