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
|
- 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.
|
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
|
### Notes
|
||||||
|
|
||||||
- The view is held in memory only. It is never written to the log file and is
|
- 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)]
|
#[cfg(windows)]
|
||||||
pub fn redirect_to_local() -> Result<(), String> {
|
pub fn redirect_to_local() -> Result<(), String> {
|
||||||
|
// Адаптер, уже смотрящий на нас, не трогаем вовсе, а кэш имён сбрасываем,
|
||||||
|
// только если что-то действительно изменилось. Вызов приходит и по таймеру,
|
||||||
|
// раз в пять минут, и безусловный сброс выбрасывал бы кэш всей системы на
|
||||||
|
// ровном месте — при том, что менять там обычно нечего.
|
||||||
|
//
|
||||||
|
// Сравниваем склейкой в строку, а не массивом: у пустого списка серверов
|
||||||
|
// сравнение массива с адресом даёт «равно», и адаптер без настройки молча
|
||||||
|
// остался бы ненастроенным.
|
||||||
|
//
|
||||||
// Счётчик обязателен. Отдельная попытка на адаптер завёрнута в `try`, иначе
|
// Счётчик обязателен. Отдельная попытка на адаптер завёрнута в `try`, иначе
|
||||||
// одна отключённая виртуальная карта срывала бы всю настройку, — но тогда
|
// одна отключённая виртуальная карта срывала бы всю настройку, — но тогда
|
||||||
// PowerShell завершается успешно, даже не тронув ни одного адаптера, и
|
// PowerShell завершается успешно, даже не тронув ни одного адаптера, и
|
||||||
@@ -186,17 +195,32 @@ pub fn redirect_to_local() -> Result<(), String> {
|
|||||||
// идёт: на машине без IPv6 она падает законно.
|
// идёт: на машине без IPv6 она падает законно.
|
||||||
const SCRIPT: &str = "\
|
const SCRIPT: &str = "\
|
||||||
$ErrorActionPreference='Stop';\
|
$ErrorActionPreference='Stop';\
|
||||||
$n=0;\
|
$n=0;$changed=0;\
|
||||||
foreach($a in Get-NetAdapter){\
|
foreach($a in Get-NetAdapter){\
|
||||||
try{Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('127.0.0.1');$n++}catch{};\
|
try{\
|
||||||
try{Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses ('::1')}catch{}\
|
$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";
|
$n";
|
||||||
|
|
||||||
|
// Считаются адаптеры, которые в итоге смотрят на нас, а не только те, что
|
||||||
|
// пришлось переставить: холостой проход обязан заканчиваться успехом.
|
||||||
let done = count_from(&powershell(SCRIPT)?);
|
let done = count_from(&powershell(SCRIPT)?);
|
||||||
if done == 0 {
|
if done == 0 {
|
||||||
return Err("ни один адаптер не переключился".to_string());
|
return Err("ни один адаптер не удалось настроить".to_string());
|
||||||
}
|
}
|
||||||
set_marker(true);
|
set_marker(true);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user