feat: improve DNS cache handling by avoiding unnecessary flushes
CI / Windows x64 (push) Successful in 12m36s
CI / Windows x64 (push) Successful in 12m36s
This commit is contained in:
@@ -12,6 +12,13 @@ versioning follows [Semantic Versioning](https://semver.org/).
|
||||
- A live view of the last 200 queries the resolver handled, each marked as
|
||||
blocked, served from cache, or sent upstream, with a filter by name.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The system DNS cache is no longer flushed on every periodic re-apply. Adapters
|
||||
that already point at the resolver are left untouched, and the cache is only
|
||||
cleared when something actually changed — previously the whole machine's cache
|
||||
was discarded every five minutes for nothing.
|
||||
|
||||
### Notes
|
||||
|
||||
- The view is held in memory only. It is never written to the log file and is
|
||||
|
||||
+29
-5
@@ -179,6 +179,15 @@ fn parse_addrs(text: &str) -> Vec<IpAddr> {
|
||||
/// достаточно проставить его один раз и обновлять изредка.
|
||||
#[cfg(windows)]
|
||||
pub fn redirect_to_local() -> Result<(), String> {
|
||||
// Адаптер, уже смотрящий на нас, не трогаем вовсе, а кэш имён сбрасываем,
|
||||
// только если что-то действительно изменилось. Вызов приходит и по таймеру,
|
||||
// раз в пять минут, и безусловный сброс выбрасывал бы кэш всей системы на
|
||||
// ровном месте — при том, что менять там обычно нечего.
|
||||
//
|
||||
// Сравниваем склейкой в строку, а не массивом: у пустого списка серверов
|
||||
// сравнение массива с адресом даёт «равно», и адаптер без настройки молча
|
||||
// остался бы ненастроенным.
|
||||
//
|
||||
// Счётчик обязателен. Отдельная попытка на адаптер завёрнута в `try`, иначе
|
||||
// одна отключённая виртуальная карта срывала бы всю настройку, — но тогда
|
||||
// PowerShell завершается успешно, даже не тронув ни одного адаптера, и
|
||||
@@ -186,17 +195,32 @@ pub fn redirect_to_local() -> Result<(), String> {
|
||||
// идёт: на машине без IPv6 она падает законно.
|
||||
const SCRIPT: &str = "\
|
||||
$ErrorActionPreference='Stop';\
|
||||
$n=0;\
|
||||
$n=0;$changed=0;\
|
||||
foreach($a in Get-NetAdapter){\
|
||||
try{Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('127.0.0.1');$n++}catch{};\
|
||||
try{Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('::1')}catch{}\
|
||||
try{\
|
||||
$cur=((Get-DnsClientServerAddress -InterfaceIndex $a.ifIndex -AddressFamily IPv4).ServerAddresses -join ',');\
|
||||
if($cur -ne '127.0.0.1'){\
|
||||
Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('127.0.0.1');\
|
||||
$changed++\
|
||||
};\
|
||||
$n++\
|
||||
}catch{};\
|
||||
try{\
|
||||
$cur6=((Get-DnsClientServerAddress -InterfaceIndex $a.ifIndex -AddressFamily IPv6).ServerAddresses -join ',');\
|
||||
if($cur6 -ne '::1'){\
|
||||
Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('::1');\
|
||||
$changed++\
|
||||
}\
|
||||
}catch{}\
|
||||
};\
|
||||
Clear-DnsClientCache;\
|
||||
if($changed -gt 0){Clear-DnsClientCache};\
|
||||
$n";
|
||||
|
||||
// Считаются адаптеры, которые в итоге смотрят на нас, а не только те, что
|
||||
// пришлось переставить: холостой проход обязан заканчиваться успехом.
|
||||
let done = count_from(&powershell(SCRIPT)?);
|
||||
if done == 0 {
|
||||
return Err("ни один адаптер не переключился".to_string());
|
||||
return Err("ни один адаптер не удалось настроить".to_string());
|
||||
}
|
||||
set_marker(true);
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user