mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-10-08 11:39:10 +11:00
feat(dns): Add real-time DNS speed benchmark and 'Fastest' auto-selection option (#4935)
* feat(dns): Add real-time DNS speed benchmark and 'Fastest' auto-selection option * fix(dns): Address CodeRabbit & Codex PR review feedback * fix(ci): Remove .biomeignore to keep repository root clean * Fix Fastest DNS eligibility and failed probe handling --------- Co-authored-by: Chris Titus <contact@christitus.com>
This commit is contained in:
co-authored by
Chris Titus
parent
f65d2631a0
commit
8e3998d9fd
@@ -0,0 +1,84 @@
|
||||
function Get-WinUtilDNSBenchmark {
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Benchmarks neutral 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(
|
||||
[ValidateRange(1, 9998)]
|
||||
[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 }
|
||||
|
||||
# Providers must explicitly opt in so new filtering services are never auto-selected.
|
||||
if ($prop.Value.BenchmarkEligible -ne $true) {
|
||||
continue
|
||||
}
|
||||
|
||||
$latency = 9999
|
||||
$client = $null
|
||||
try {
|
||||
$client = New-Object System.Net.Sockets.TcpClient
|
||||
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
$asyncResult = $client.BeginConnect($primaryIp, 53, $null, $null)
|
||||
$success = $asyncResult.AsyncWaitHandle.WaitOne($TimeoutMs, $false)
|
||||
$stopwatch.Stop()
|
||||
|
||||
if ($success) {
|
||||
$client.EndConnect($asyncResult)
|
||||
$latency = [int]$stopwatch.ElapsedMilliseconds
|
||||
} else {
|
||||
$latency = 9999
|
||||
}
|
||||
} catch {
|
||||
$latency = 9999
|
||||
} finally {
|
||||
if ($null -ne $client) {
|
||||
$client.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$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 neutral provider: $($fastest.Provider) ($($fastest.LatencyMs) ms)"
|
||||
} else {
|
||||
Write-WinUtilLog -Component "DNS" -Message "DNS Benchmark completed. Could not determine latency for providers."
|
||||
}
|
||||
|
||||
return $sortedResults
|
||||
}
|
||||
@@ -18,6 +18,21 @@ function Set-WinUtilDNS {
|
||||
return $true
|
||||
}
|
||||
|
||||
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 {
|
||||
Write-Warning "Could not measure DNS latency to any provider; keeping current network adapter DNS settings."
|
||||
Write-WinUtilLog -Component "DNS" -Message "Benchmark timeout or all probes failed; aborting DNS change to preserve existing settings."
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$Adapters = Get-NetAdapter | Where-Object {$_.Status -eq "Up"}
|
||||
Write-Host "Ensuring DNS is set to $DNSProvider on the following interfaces:"
|
||||
|
||||
Reference in New Issue
Block a user