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#4935MADHACKER85 wants to merge 3 commits into
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a ChangesDNS fastest-provider selection
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant WPFchangedns
participant SetWinUtilDNS
participant GetWinUtilDNSBenchmark
participant DNSProvider
WPFchangedns->>SetWinUtilDNS: Select Fastest
SetWinUtilDNS->>GetWinUtilDNSBenchmark: Benchmark configured providers
GetWinUtilDNSBenchmark->>DNSProvider: Test TCP port 53
DNSProvider-->>GetWinUtilDNSBenchmark: Return latency or failure
GetWinUtilDNSBenchmark-->>SetWinUtilDNS: Return sorted results
SetWinUtilDNS-->>WPFchangedns: Apply selected provider or preserve adapter DNS settings
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3df14ad33
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| $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.
Avoid changing DNS when no benchmark succeeds
When Fastest is selected on networks where outbound TCP/53 is blocked or every benchmark probe times out, this branch still rewrites the adapter DNS to Cloudflare even though no provider was measured as reachable. That can replace a working DHCP/corporate resolver with a public resolver the network may block and leave the machine without DNS; in the no-result case, keep the current settings or abort instead of applying an unverified fallback.
AGENTS.md reference: AGENTS.md:L84-L91
Useful? React with 👍 / 👎.
| $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.
Avoid changing DNS when no benchmark succeeds
When Fastest is selected on networks where outbound TCP/53 is blocked or every benchmark probe times out, this branch still rewrites the adapter DNS to Cloudflare even though no provider was measured as reachable. That can replace a working DHCP/corporate resolver with a public resolver the network may block and leave the machine without DNS; in the no-result case, keep the current settings or abort instead of applying an unverified fallback.
Useful? React with 👍 / 👎.
| foreach ($prop in $dnsConfigs.PSObject.Properties) { | ||
| $providerName = $prop.Name | ||
| $primaryIp = $prop.Value.Primary |
There was a problem hiding this comment.
Do not let Fastest select filtering resolvers
Because this benchmarks every entry in config/dns.json, choosing Fastest can silently configure a policy/filtering resolver such as Cloudflare_Malware_Adult or AdGuard_Ads_Trackers_Malware_Adult whenever 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 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@functions/private/Get-WinUtilDNSBenchmark.ps1`:
- Around line 42-55: Update the TCP probe around the visible $client and
$asyncResult operations to use try/finally cleanup: after a successful wait,
call $asyncResult.EndConnect() and ensure $client is closed or disposed on every
success, timeout, and exception path. Preserve the 9999 fallback latency, and do
not dispose $asyncResult.AsyncWaitHandle.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 16975faa-5874-48d4-93ce-bfa656774f1e
📒 Files selected for processing (3)
config/tweaks.jsonfunctions/private/Get-WinUtilDNSBenchmark.ps1functions/private/Set-WinUtilDNS.ps1
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.biomeignore:
- Line 4: Remove the broad *.json rule from .biomeignore so JSON files under
docs, including package-lock.json, package.json, and tsconfig.json, remain
included; retain the existing config-specific ignore rules.
- Around line 1-4: Remove the inert .biomeignore file and move its JSON
exclusion patterns into a supported Biome ignore mechanism, preferably the
excludes configuration in biome.json; preserve coverage for config/*.json,
nested config/*.json, and all *.json files.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 14808587-468d-44cb-b543-75eed0159b70
📒 Files selected for processing (3)
.biomeignorefunctions/private/Get-WinUtilDNSBenchmark.ps1functions/private/Set-WinUtilDNS.ps1
🚧 Files skipped from review as they are similar to previous changes (2)
- functions/private/Set-WinUtilDNS.ps1
- functions/private/Get-WinUtilDNSBenchmark.ps1
| # Biome ignore rules for PowerShell JSON config files | ||
| config/*.json | ||
| **/config/*.json | ||
| *.json |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
unexpected=0
while IFS= read -r file; do
case "$file" in
config/*.json|*/config/*.json) ;;
*) printf 'JSON file outside config/: %s\n' "$file"; unexpected=1 ;;
esac
done < <(git ls-files -- '*.json')
exit "$unexpected"Repository: ChrisTitusTech/winutil
Length of output: 213
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== .biomeignore =="
if [ -f .biomeignore ]; then
cat -n .biomeignore
else
echo "MISSING .biomeignore"
fi
echo
echo "== tracked top-level JSON files =="
git ls-files '*.json' | sed -n '1,120p'
echo
echo "== tracked JSON files outside config paths =="
git ls-files '*.json' | grep -Ev '(^|/)config/' || true
echo
echo "== Biomignore config JSON exclusions in package =="
git ls-files '*biome*' 'biome*' '.*biome*' | sort | sed -n '1,120p'Repository: ChrisTitusTech/winutil
Length of output: 728
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import subprocess
files = subprocess.check_output(['git', 'ls-files', '*.json'], text=True).splitlines()
config_files = [f for f in files if f.startswith('config/') or '/config/' in f or f in ('config', 'configs')]
outside = [f for f in files if f not in config_files]
print('total tracked JSON:', len(files))
print('config-path JSON:', len(config_files))
print('non-config JSON:', len(outside))
for f in outside[:120]:
print(f)
PYRepository: ChrisTitusTech/winutil
Length of output: 282
Scope the Biome ignore rule to keep docs JSON files included.
*.json also excludes docs/package-lock.json, docs/package.json, and docs/tsconfig.json, while the config/ rules already cover the configuration JSON files. Remove line [4] unless every repository JSON file should be ignored.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.biomeignore at line 4, Remove the broad *.json rule from .biomeignore so
JSON files under docs, including package-lock.json, package.json, and
tsconfig.json, remain included; retain the existing config-specific ignore
rules.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 614cb6b21c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (-not $primaryIp) { continue } | ||
|
|
||
| # Skip specialized policy/filtering variants (e.g. Malware, Adult, Family) for neutral auto-selection | ||
| if ($providerName -like "*Malware*" -or $providerName -like "*Adult*" -or $providerName -like "*Family*") { |
There was a problem hiding this comment.
Exclude all filtering DNS providers from Fastest
Fresh evidence in this update is that the new exclusion condition only skips Malware/Adult/Family, so Fastest still benchmarks and can select configured filtering providers like AdGuard_Ads_Trackers and Quad9 when their primary IP has the lowest TCP/53 latency. In that scenario a user choosing the speed-only option silently gets system-wide DNS content filtering they did not select; use an explicit neutral allow-list or provider metadata instead of this partial name filter.
AGENTS.md reference: AGENTS.md:L86-L86
Useful? React with 👍 / 👎.
Summary
Users frequently set custom DNS in WinUtil without knowing which provider offers the lowest latency for their local connection/ISP. This PR adds a lightweight, firewall-safe TCP port 53 latency benchmark (Get-WinUtilDNSBenchmark) and adds a Fastest option to the DNS dropdown (WPFchangedns).
Key Changes
Verification
Tested in PowerShell 5.1 / 7+ environment across 8 DNS providers: