Compare commits

...

6 Commits

Author SHA1 Message Date
David Wood
c8798ac242
Merge ac9e9f72820ec44173f4f8cc47a36645c4abff61 into 1e0873aa71849de9ffc6814b620dbbf920ffa9f8 2025-02-19 18:29:19 +01:00
Stanislav Chzhen
1e0873aa71 Pull request 2347: AGDNS-2690-global-context
Some checks failed
build / test (macOS-latest) (push) Has been cancelled
build / test (ubuntu-latest) (push) Has been cancelled
build / test (windows-latest) (push) Has been cancelled
lint / go-lint (push) Has been cancelled
lint / eslint (push) Has been cancelled
build / build-release (push) Has been cancelled
build / notify (push) Has been cancelled
lint / notify (push) Has been cancelled
Merge in DNS/adguard-home from AGDNS-2690-global-context to master

Squashed commit of the following:

commit 58d5999e5d9112b3391f988ed76e87eff2919d6b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Feb 19 18:51:41 2025 +0300

    home: imp naming

commit cfb371df59c816be1022d499cc41ffaf2b72d124
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Feb 19 18:42:52 2025 +0300

    home: global context
2025-02-19 19:02:56 +03:00
Ainar Garipov
a5b073d070 Pull request 2344: fix-chlog
Some checks are pending
build / test (macOS-latest) (push) Waiting to run
build / test (ubuntu-latest) (push) Waiting to run
build / test (windows-latest) (push) Waiting to run
build / build-release (push) Blocked by required conditions
build / notify (push) Blocked by required conditions
lint / go-lint (push) Waiting to run
lint / eslint (push) Waiting to run
lint / notify (push) Blocked by required conditions
Merge in DNS/adguard-home from fix-chlog to master

Squashed commit of the following:

commit 3f209c99936f40ec67acd70e64f53368adac83dd
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Feb 18 19:45:25 2025 +0300

    all: fix chlog
2025-02-18 19:54:36 +03:00
Ainar Garipov
9c5a7a5544 Pull request 2343: upd-i18n
Some checks failed
build / test (macOS-latest) (push) Has been cancelled
build / test (ubuntu-latest) (push) Has been cancelled
build / test (windows-latest) (push) Has been cancelled
lint / go-lint (push) Has been cancelled
lint / eslint (push) Has been cancelled
build / build-release (push) Has been cancelled
build / notify (push) Has been cancelled
lint / notify (push) Has been cancelled
Merge in DNS/adguard-home from upd-i18n to master

Squashed commit of the following:

commit da6c09136c3e2495a6117f92752f18b190ce4f7b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Feb 18 17:53:36 2025 +0300

    client: upd i18n
2025-02-18 18:17:47 +03:00
Ainar Garipov
da8132e127 Pull request 2342: 7627-dhcp-client-hostname
Updates #7627.

Squashed commit of the following:

commit 5eb677f5b91d2664094d759b4b07c64c1889c57b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Feb 14 17:21:35 2025 +0300

    client: fix test

commit e7c6ee81ef9aa6627538c82f150f4707df92d820
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Feb 14 17:00:00 2025 +0300

    client: imp test

commit b59ca8b3ca4d00007d5c48b96fcc630342414ae7
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Feb 14 16:53:02 2025 +0300

    client: fix dhcp
2025-02-18 14:09:14 +03:00
David Wood
ac9e9f7282
chore: fix function name in comment 2024-10-21 14:45:15 +08:00
40 changed files with 521 additions and 358 deletions

View File

@ -28,13 +28,15 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Changed ### Changed
- The *Fastest IP adddress* upstream mode now collects statistics for the all upstream DNS servers. - The *Fastest IP address* upstream mode now collects statistics for the all upstream DNS servers.
### Fixed ### Fixed
- The hostnames of DHCP clients not being shown in the *Top clients* table on the dashboard ([#7627]).
- The formatting of large numbers in the upstream table and query log ([#7590]). - The formatting of large numbers in the upstream table and query log ([#7590]).
[#7590]: https://github.com/AdguardTeam/AdGuardHome/issues/7590 [#7590]: https://github.com/AdguardTeam/AdGuardHome/issues/7590
[#7627]: https://github.com/AdguardTeam/AdGuardHome/issues/7627
[go-1.23.6]: https://groups.google.com/g/golang-announce/c/xU1ZCHUZw3k [go-1.23.6]: https://groups.google.com/g/golang-announce/c/xU1ZCHUZw3k

View File

@ -284,6 +284,7 @@
"blocklist": "Черен списък", "blocklist": "Черен списък",
"filter_category_general": "General", "filter_category_general": "General",
"filter_category_security": "Сигурност", "filter_category_security": "Сигурност",
"filter_category_other": "Друго",
"port_53_faq_link": "Порт 53 често е зает от \"DNSStubListener\" или \"systemd-resolved\" услуги. Моля, прочетете <0>тази инструкция</0> как да решите това.", "port_53_faq_link": "Порт 53 често е зает от \"DNSStubListener\" или \"systemd-resolved\" услуги. Моля, прочетете <0>тази инструкция</0> как да решите това.",
"parental_control": "Родителски контрол", "parental_control": "Родителски контрол",
"sunday_short": "Нд", "sunday_short": "Нд",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Použijte paralelní požadavky na urychlení řešení simultánním dotazováním na všechny navazující servery.", "upstream_parallel": "Použijte paralelní požadavky na urychlení řešení simultánním dotazováním na všechny navazující servery.",
"parallel_requests": "Paralelní požadavky", "parallel_requests": "Paralelní požadavky",
"load_balancing": "Optimalizace vytížení", "load_balancing": "Optimalizace vytížení",
"load_balancing_desc": "Dotazy jednoho odchozího serveru ve stejný čas. AdGuard Home používá náhodný algoritmus pro výběr serverů s nejnižším počtem neúspěšných vyhledávání a nejnižší průměrnou dobou vyhledávání.", "load_balancing_desc": "Dotazy jednoho odchozího serveru ve stejný čas.<br/>AdGuard Home používá náhodný algoritmus pro výběr serverů s nejnižším počtem neúspěšných vyhledávání a nejnižší průměrnou dobou vyhledávání.",
"bootstrap_dns": "Bootstrap DNS servery", "bootstrap_dns": "Bootstrap DNS servery",
"bootstrap_dns_desc": "IP adresy DNS serverů používaných k překladu IP adres řešitelů DoH/DoT, které zadáte jako odchozí servery. Komentáře nejsou povoleny.", "bootstrap_dns_desc": "IP adresy DNS serverů používaných k překladu IP adres řešitelů DoH/DoT, které zadáte jako odchozí servery. Komentáře nejsou povoleny.",
"fallback_dns_title": "Záložní DNS servery", "fallback_dns_title": "Záložní DNS servery",
@ -294,6 +294,9 @@
"blocked_response_ttl": "TTL blokované odezvy", "blocked_response_ttl": "TTL blokované odezvy",
"blocked_response_ttl_desc": "Určuje, na kolik sekund by měli klienti ukládat filtrovanou odezvu do mezipaměti", "blocked_response_ttl_desc": "Určuje, na kolik sekund by měli klienti ukládat filtrovanou odezvu do mezipaměti",
"form_enter_blocked_response_ttl": "Zadejte TTL blokované odezvy (v sekundách)", "form_enter_blocked_response_ttl": "Zadejte TTL blokované odezvy (v sekundách)",
"upstream_timeout": "Časový limit odchozího serveru",
"upstream_timeout_desc": "Určuje počet sekund čekání na odpověď od odchozího serveru",
"form_enter_upstream_timeout": "Zadejte dobu časového limitu odchozího serveru v sekundách",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS skrze HTTPS", "dns_over_https": "DNS skrze HTTPS",
"dns_over_tls": "DNS skrze TLS", "dns_over_tls": "DNS skrze TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Zakázat řešení IPv6 adres", "disable_ipv6": "Zakázat řešení IPv6 adres",
"disable_ipv6_desc": "Odstranění všech dotazů DNS na adresy IPv6 (typ AAAA) a odstranění náznaků IPv6 z odpovědí HTTPS.", "disable_ipv6_desc": "Odstranění všech dotazů DNS na adresy IPv6 (typ AAAA) a odstranění náznaků IPv6 z odpovědí HTTPS.",
"fastest_addr": "Nejrychlejší IP adresa", "fastest_addr": "Nejrychlejší IP adresa",
"fastest_addr_desc": "Dotazovat všechny DNS servery a vrátit nejrychlejší IP adresu ze všech odpovědí. To zpomalí dotazy DNS, protože AdGuard Home musí čekat na odpovědi ze všech serverů DNS, ale celková konektivita se zlepší.", "fastest_addr_desc": "Počká na odpovědi <b>všech</b> serverů DNS, změří rychlost připojení TCP pro každý server a vrátí IP adresu serveru s nejvyšší rychlostí připojení.<br/>Tento režim může výrazně zpomalit dotazy DNS, pokud jeden nebo více odchozích serverů neodpovídá. Ujistěte se, že vaše odchozí servery jsou stabilní a že časový limit odchozích serverů je nízký.",
"autofix_warning_text": "Pokud kliknete na „Opravit“, AdGuard Home nakonfiguruje váš systém tak, aby používal DNS server AdGuard Home.", "autofix_warning_text": "Pokud kliknete na „Opravit“, AdGuard Home nakonfiguruje váš systém tak, aby používal DNS server AdGuard Home.",
"autofix_warning_list": "Jsou prováděny následující úlohy: <0>Deaktivace systému DNSStubListener</0> <0>Nastavení adresy serveru DNS na 127.0.0.1</0> <0>Nahrazení cíle symbolického odkazu z /etc/resolv.conf do /run/systemd/resolve/resolv.conf</0> <0>Zastavení služby DNSStubListener (znovu načtení služby systemd-resolved)</0>", "autofix_warning_list": "Jsou prováděny následující úlohy: <0>Deaktivace systému DNSStubListener</0> <0>Nastavení adresy serveru DNS na 127.0.0.1</0> <0>Nahrazení cíle symbolického odkazu z /etc/resolv.conf do /run/systemd/resolve/resolv.conf</0> <0>Zastavení služby DNSStubListener (znovu načtení služby systemd-resolved)</0>",
"autofix_warning_result": "Výsledkem je, že všechny požadavky DNS z vašeho systému jsou ve výchozím nastavení zpracovány službou AdGuard Home.", "autofix_warning_result": "Výsledkem je, že všechny požadavky DNS z vašeho systému jsou ve výchozím nastavení zpracovány službou AdGuard Home.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Brug parallelforespørgsler til at accelerere fortolkningen ved at forespørge alle upstream-servere samtidigt.", "upstream_parallel": "Brug parallelforespørgsler til at accelerere fortolkningen ved at forespørge alle upstream-servere samtidigt.",
"parallel_requests": "Parallelle forespørgsler", "parallel_requests": "Parallelle forespørgsler",
"load_balancing": "Belastningsfordeling", "load_balancing": "Belastningsfordeling",
"load_balancing_desc": "Forespørg én upstream-server ad gangen. AdGuard Home bruger en vægtet tilfældighedsalgoritme til vælg af servere med det laveste antal fejlslagne opslag og den laveste gennemsnitlige opslagstid.", "load_balancing_desc": "Forespørg én upstream-server ad gangen.<br/>AdGuard Home bruger en vægtet tilfældighedsalgoritme til vælg af servere med det laveste antal fejlslagne opslag og den laveste gennemsnitlige opslagstid.",
"bootstrap_dns": "Bootstrap DNS-servere", "bootstrap_dns": "Bootstrap DNS-servere",
"bootstrap_dns_desc": "IP-adresser på DNS-servere, som bruges til at opløse IP-adresser på de DoH/DoT-opløsere, som angives som upstreams. Kommentarer er ikke tilladt.", "bootstrap_dns_desc": "IP-adresser på DNS-servere, som bruges til at opløse IP-adresser på de DoH/DoT-opløsere, som angives som upstreams. Kommentarer er ikke tilladt.",
"fallback_dns_title": "Reserve DNS-servere", "fallback_dns_title": "Reserve DNS-servere",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Blokeret svar TTL", "blocked_response_ttl": "Blokeret svar TTL",
"blocked_response_ttl_desc": "Angiver, i hvor mange sekunder klienterne skal cache-lagre et filtreret svar", "blocked_response_ttl_desc": "Angiver, i hvor mange sekunder klienterne skal cache-lagre et filtreret svar",
"form_enter_blocked_response_ttl": "Angiv blokeringssvar TTL (sekunder)", "form_enter_blocked_response_ttl": "Angiv blokeringssvar TTL (sekunder)",
"upstream_timeout": "Upstream-timeout",
"upstream_timeout_desc": "Angiver antallet af sekunder, der skal ventes på et svar fra upstream-serveren",
"form_enter_upstream_timeout": "Angiv varigheden af upstream-server timeout i sekunder",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Deaktivér IPv6-adresseopløsning", "disable_ipv6": "Deaktivér IPv6-adresseopløsning",
"disable_ipv6_desc": "Drop alle DNS-forespørgsler for IPv6-adresser (type AAAA), og fjern IPv6-tips fra HTTPS-svar.", "disable_ipv6_desc": "Drop alle DNS-forespørgsler for IPv6-adresser (type AAAA), og fjern IPv6-tips fra HTTPS-svar.",
"fastest_addr": "Hurtigste IP-adresse", "fastest_addr": "Hurtigste IP-adresse",
"fastest_addr_desc": "Forespørger alle DNS-servere og returner den hurtigste IP-adresse blandt alle svar. Dette vil gøre DNS-forespørgslerne langsommere grundet afventning af svar fra alle DNS-servere, men forbedrer samlet set forbindelsen.", "fastest_addr_desc": "Vent på svar fra <b>alle</b> DNS-servere, mål TCP-forbindelseshastigheden for hver server, og returner IP-adressen på serveren med den hurtigste forbindelseshastighed.<br/>Denne tilstand kan sinke DNS-forespørgsler, betydeligt hvis en eller flere upstream-servere ikke svarer. Sørg for, at upstream-serverene er stabile, og at upstream-timeouten er lav.",
"autofix_warning_text": "Klikker du på \"Reparér\", opsætter AdGuard Home dit system til brug med AdGuard Home DNS-server.", "autofix_warning_text": "Klikker du på \"Reparér\", opsætter AdGuard Home dit system til brug med AdGuard Home DNS-server.",
"autofix_warning_list": "Den vil udføre disse opgaver: <0>Deaktivere system DNSStubListener</0> <0>Opsætte DNS-serveradressen til 127.0.0.1</0> <0>Erstatte symbolsk linkmål for /etc/resolv.conf med /run/systemd/resolve/resolv.conf</0> <0>Stoppe DNSStubListener (genindlæs systemd-opløst tjeneste)</0>", "autofix_warning_list": "Den vil udføre disse opgaver: <0>Deaktivere system DNSStubListener</0> <0>Opsætte DNS-serveradressen til 127.0.0.1</0> <0>Erstatte symbolsk linkmål for /etc/resolv.conf med /run/systemd/resolve/resolv.conf</0> <0>Stoppe DNSStubListener (genindlæs systemd-opløst tjeneste)</0>",
"autofix_warning_result": "Det betyder, at alle DNS-forespørgsler fra dit system som standard behandles af AdGuard Home.", "autofix_warning_result": "Det betyder, at alle DNS-forespørgsler fra dit system som standard behandles af AdGuard Home.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Parallele Abfragen verwenden, um das Auflösen zu beschleunigen, indem alle Upstream-Server gleichzeitig abgefragt werden.", "upstream_parallel": "Parallele Abfragen verwenden, um das Auflösen zu beschleunigen, indem alle Upstream-Server gleichzeitig abgefragt werden.",
"parallel_requests": "Paralleles Abfragen", "parallel_requests": "Paralleles Abfragen",
"load_balancing": "Lastverteilung", "load_balancing": "Lastverteilung",
"load_balancing_desc": "Es wird jeweils ein Upstream-Server abgefragt. AdGuard Home verwendet einen gewichteten Zufallsalgorithmus, um die Server mit der geringsten Anzahl an fehlgeschlagenen Suchvorgängen und der niedrigsten durchschnittlichen Suchzeit auszuwählen.", "load_balancing_desc": "Es wird jeweils ein Upstream-Server abgefragt.<br/> AdGuard Home verwendet einen gewichteten Zufallsalgorithmus, um die Server mit der geringsten Anzahl an fehlgeschlagenen Suchvorgängen und der niedrigsten durchschnittlichen Suchzeit auszuwählen.",
"bootstrap_dns": "Bootstrap-DNS-Server", "bootstrap_dns": "Bootstrap-DNS-Server",
"bootstrap_dns_desc": "IP-Adressen der DNS-Server, die zum Auflösen der IP-Adressen von DoH/DoT Upstream-Servern verwendet werden, die Sie angegeben haben. Kommentare sind nicht erlaubt.", "bootstrap_dns_desc": "IP-Adressen der DNS-Server, die zum Auflösen der IP-Adressen von DoH/DoT Upstream-Servern verwendet werden, die Sie angegeben haben. Kommentare sind nicht erlaubt.",
"fallback_dns_title": "Fallback-DNS-Server", "fallback_dns_title": "Fallback-DNS-Server",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Gültigkeitsdauer der blockierten Antwort", "blocked_response_ttl": "Gültigkeitsdauer der blockierten Antwort",
"blocked_response_ttl_desc": "Gibt an, wie viele Sekunden lang die Clients eine gefilterte Antwort zwischenspeichern sollen", "blocked_response_ttl_desc": "Gibt an, wie viele Sekunden lang die Clients eine gefilterte Antwort zwischenspeichern sollen",
"form_enter_blocked_response_ttl": "Geben Sie die Gültigkeitsdauer für blockierte Antworten ein (in Sekunden)", "form_enter_blocked_response_ttl": "Geben Sie die Gültigkeitsdauer für blockierte Antworten ein (in Sekunden)",
"upstream_timeout": "Upstream-Timeout",
"upstream_timeout_desc": "Gibt die Anzahl der Sekunden an, die auf eine Antwort des Upstream-Servers gewartet werden soll",
"form_enter_upstream_timeout": "Geben Sie die Timeout-Dauer des Upstream-Servers in Sekunden ein",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "IPv6 deaktivieren", "disable_ipv6": "IPv6 deaktivieren",
"disable_ipv6_desc": "Alle DNS-Anfragen für IPv6-Adressen (Typ AAAA) verwerfen und IPv6-Hinweise aus HTTPS-Antworten entfernen.", "disable_ipv6_desc": "Alle DNS-Anfragen für IPv6-Adressen (Typ AAAA) verwerfen und IPv6-Hinweise aus HTTPS-Antworten entfernen.",
"fastest_addr": "Schnellste IP-Adresse", "fastest_addr": "Schnellste IP-Adresse",
"fastest_addr_desc": "Fragen Sie alle DNS-Server ab und geben Sie die schnellste IP-Adresse unter allen Antworten zurück. Dies verlangsamt DNS-Abfragen, da AdGuard Home auf Antworten von allen DNS-Servern warten muss, verbessert jedoch die Gesamtkonnektivität.", "fastest_addr_desc": "Auf Antworten von <b>allen</b> DNS-Servern warten, die TCP-Verbindungsgeschwindigkeit für jeden Server messen und die IP-Adresse des Servers mit der schnellsten Verbindungsgeschwindigkeit zurückgeben.<br/>Dieser Modus kann DNS-Anfragen erheblich verlangsamen, wenn ein oder mehrere Server nicht antworten. Stellen Sie sicher, dass Ihre Server stabil laufen und das Upstream-Timeout niedrig ist.",
"autofix_warning_text": "Wenn Sie auf „Beheben“ klicken, konfiguriert AdGuardHome Ihr System für die Verwendung des AdGuardHome-DNS-Servers.", "autofix_warning_text": "Wenn Sie auf „Beheben“ klicken, konfiguriert AdGuardHome Ihr System für die Verwendung des AdGuardHome-DNS-Servers.",
"autofix_warning_list": "Es werden folgende Aufgaben ausgeführt: <0>Deaktivieren des DNSStubListener-Systems</0> <0>Festlegen der DNS-Server-Adresse auf 127.0.0.1</0> <0>Ersetzen des symbolischen Linkziels von /etc/resolv.conf auf /run/systemd/resolve/resolv.conf</0> <0>Anhalten des DNSStubListener (systemseitig aufgelöster Dienst wird nachladen)</0>", "autofix_warning_list": "Es werden folgende Aufgaben ausgeführt: <0>Deaktivieren des DNSStubListener-Systems</0> <0>Festlegen der DNS-Server-Adresse auf 127.0.0.1</0> <0>Ersetzen des symbolischen Linkziels von /etc/resolv.conf auf /run/systemd/resolve/resolv.conf</0> <0>Anhalten des DNSStubListener (systemseitig aufgelöster Dienst wird nachladen)</0>",
"autofix_warning_result": "Als Folge daraus werden alle DNS-Anforderungen von Ihrem System standardmäßig von AdGuardHome verarbeitet.", "autofix_warning_result": "Als Folge daraus werden alle DNS-Anforderungen von Ihrem System standardmäßig von AdGuardHome verarbeitet.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Usar consultas paralelas para acelerar la resolución al consultar simultáneamente a todos los servidores DNS de subida.", "upstream_parallel": "Usar consultas paralelas para acelerar la resolución al consultar simultáneamente a todos los servidores DNS de subida.",
"parallel_requests": "Consultas paralelas", "parallel_requests": "Consultas paralelas",
"load_balancing": "Balanceo de carga", "load_balancing": "Balanceo de carga",
"load_balancing_desc": "Consulta un servidor upstream a la vez. AdGuard Home utiliza un algoritmo aleatorio ponderado para seleccionar los servidores con el menor número de fallos y el menor tiempo medio de búsqueda.", "load_balancing_desc": "Consulta un servidor Dns upstream a la vez.<br/>AdGuard Home utiliza un algoritmo aleatorio ponderado para seleccionar los servidores con el menor número de fallos y el menor tiempo medio de búsqueda.",
"bootstrap_dns": "Servidores DNS de arranque", "bootstrap_dns": "Servidores DNS de arranque",
"bootstrap_dns_desc": "Direcciones IP de servidores DNS utilizadas para resolver direcciones IP de los solucionadores DoH/DoT que especifiques como ascendentes. No se permiten comentarios.", "bootstrap_dns_desc": "Direcciones IP de servidores DNS utilizadas para resolver direcciones IP de los solucionadores DoH/DoT que especifiques como ascendentes. No se permiten comentarios.",
"fallback_dns_title": "Servidores DNS alternativos", "fallback_dns_title": "Servidores DNS alternativos",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Respuesta TTL bloqueada", "blocked_response_ttl": "Respuesta TTL bloqueada",
"blocked_response_ttl_desc": "Especifica durante cuántos segundos los clientes deben almacenar en cache una respuesta filtrada", "blocked_response_ttl_desc": "Especifica durante cuántos segundos los clientes deben almacenar en cache una respuesta filtrada",
"form_enter_blocked_response_ttl": "Ingresa el TTL de respuesta bloqueada (segundos)", "form_enter_blocked_response_ttl": "Ingresa el TTL de respuesta bloqueada (segundos)",
"upstream_timeout": "Tiempo de espera del upstream",
"upstream_timeout_desc": "Especifica el número de segundos que se debe esperar para recibir una respuesta del servidor upstream",
"form_enter_upstream_timeout": "Ingresa la duración del tiempo de espera del servidor DNS upstream en segundos",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS mediante HTTPS", "dns_over_https": "DNS mediante HTTPS",
"dns_over_tls": "DNS mediante TLS", "dns_over_tls": "DNS mediante TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Deshabilitar resolución de direcciones IPv6", "disable_ipv6": "Deshabilitar resolución de direcciones IPv6",
"disable_ipv6_desc": "Descarta todas las consultas de DNS para direcciones IPv6 (tipo AAAA) y elimina las sugerencias de IPv6 de las respuestas HTTPS.", "disable_ipv6_desc": "Descarta todas las consultas de DNS para direcciones IPv6 (tipo AAAA) y elimina las sugerencias de IPv6 de las respuestas HTTPS.",
"fastest_addr": "Dirección IP más rápida", "fastest_addr": "Dirección IP más rápida",
"fastest_addr_desc": "Consulta todos los servidores DNS y devuelve la dirección IP más rápida de todas las respuestas. Esto ralentiza las consultas DNS ya que AdGuard Home tiene que esperar las respuestas de todos los servidores DNS, pero mejora la conectividad general.", "fastest_addr_desc": "Espera a que respondan <b>todos</b> los servidores DNS, mide la velocidad de conexión TCP de cada servidor y devuelve la Dirección IP del servidor con la velocidad de conexión más rápida.<br/>Este modo puede ralentizar significativamente las consultas DNS, si uno o más servidores DNS de upstream no están respondiendo. Asegúrate de que tus servidores DNS upstream sean estables y tu tiempo de espera de upstream sea bajo.",
"autofix_warning_text": "Si haces clic en \"Corregir\", AdGuard Home configurará tu sistema para utilizar el servidor DNS de AdGuard Home.", "autofix_warning_text": "Si haces clic en \"Corregir\", AdGuard Home configurará tu sistema para utilizar el servidor DNS de AdGuard Home.",
"autofix_warning_list": "Realizará estas tareas: <0>Deshabilitar el sistema DNSStubListener</0> <0>Establecer la dirección del servidor DNS en 127.0.0.1</0> <0>Reemplazar el destino del enlace simbólico de /etc/resolv.conf por /run/systemd/resolve/resolv.conf</0> <0>Detener DNSStubListener (recargar el servicio systemd-resolved)</0>", "autofix_warning_list": "Realizará estas tareas: <0>Deshabilitar el sistema DNSStubListener</0> <0>Establecer la dirección del servidor DNS en 127.0.0.1</0> <0>Reemplazar el destino del enlace simbólico de /etc/resolv.conf por /run/systemd/resolve/resolv.conf</0> <0>Detener DNSStubListener (recargar el servicio systemd-resolved)</0>",
"autofix_warning_result": "Como resultado, todas las peticiones DNS de tu sistema serán procesadas por AdGuard Home de manera predeterminada.", "autofix_warning_result": "Como resultado, todas las peticiones DNS de tu sistema serán procesadas por AdGuard Home de manera predeterminada.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Utilisez des requêtes parallèles pour accélérer la résolution en requêtant simultanément tous les serveurs en amont.", "upstream_parallel": "Utilisez des requêtes parallèles pour accélérer la résolution en requêtant simultanément tous les serveurs en amont.",
"parallel_requests": "Requêtes en parallèle", "parallel_requests": "Requêtes en parallèle",
"load_balancing": "Équilibrage de charge", "load_balancing": "Équilibrage de charge",
"load_balancing_desc": "Une requête par serveur en amont à la fois. AdGuard Home utilise un algorithme aléatoire pondéré pour sélectionner les serveurs avec le plus petit nombre d'échecs de recherche et le temps de recherche moyen le plus bas.", "load_balancing_desc": "Une requête par serveur en amont à la fois.<br/>AdGuard Home utilise un algorithme aléatoire pondéré pour sélectionner les serveurs avec le plus petit nombre d'échecs de recherche et le temps de recherche moyen le plus bas.",
"bootstrap_dns": "Serveurs DNS d'amorçage", "bootstrap_dns": "Serveurs DNS d'amorçage",
"bootstrap_dns_desc": "Les adresses IP des serveurs DNS utilisées pour résoudre les adresses IP des résolveurs DoH/DoT que vous spécifiez comme en amont. Les commentaires ne sont pas autorisés.", "bootstrap_dns_desc": "Les adresses IP des serveurs DNS utilisées pour résoudre les adresses IP des résolveurs DoH/DoT que vous spécifiez comme en amont. Les commentaires ne sont pas autorisés.",
"fallback_dns_title": "Serveurs DNS de repli", "fallback_dns_title": "Serveurs DNS de repli",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Réponse bloquée TTL", "blocked_response_ttl": "Réponse bloquée TTL",
"blocked_response_ttl_desc": "Spécifie pendant combien de secondes les clients doivent mettre en cache une réponse filtrée", "blocked_response_ttl_desc": "Spécifie pendant combien de secondes les clients doivent mettre en cache une réponse filtrée",
"form_enter_blocked_response_ttl": "Saisir le TTL de la réponse bloquée (secondes)", "form_enter_blocked_response_ttl": "Saisir le TTL de la réponse bloquée (secondes)",
"upstream_timeout": "Délai d'attente en amont",
"upstream_timeout_desc": "Spécifie le nombre de secondes à attendre pour une réponse du serveur en amont",
"form_enter_upstream_timeout": "Saisir le délai d'attente du serveur en amont en secondes",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Désactiver la résolution des adresses IPv6", "disable_ipv6": "Désactiver la résolution des adresses IPv6",
"disable_ipv6_desc": "Supprimer toutes les requêtes DNS pour les adresses IPv6 (type AAAA) et supprimer les indices IPv6 des réponses HTTPS.", "disable_ipv6_desc": "Supprimer toutes les requêtes DNS pour les adresses IPv6 (type AAAA) et supprimer les indices IPv6 des réponses HTTPS.",
"fastest_addr": "Adresse IP la plus rapide", "fastest_addr": "Adresse IP la plus rapide",
"fastest_addr_desc": "Rechercher tous les serveurs DNS et renvoyer ladresse IP la plus rapide parmi toutes les réponses. Cela ralentit les requêtes DNS car AdGuard Home doit attendre les réponses de tous les serveurs DNS, mais la connectivité globale s'améliore.", "fastest_addr_desc": "Attente les réponses de <b>tous</b> les serveurs DNS, mesure de la vitesse de connexion TCP pour chaque serveur et renvoi de l'adresse IP du serveur avec la vitesse de connexion la plus rapide.<br/>Ce mode peut considérablement ralentir les requêtes DNS, si un ou plusieurs serveurs en amont ne répondent pas. Assurez-vous que vos serveurs en amont sont stables et que votre délai dépassé en amont est faible.",
"autofix_warning_text": "Si vous cliquez sur « Réparer », AdGuard Home configurera votre système pour utiliser le serveur DNS AdGuard Home.", "autofix_warning_text": "Si vous cliquez sur « Réparer », AdGuard Home configurera votre système pour utiliser le serveur DNS AdGuard Home.",
"autofix_warning_list": "Ceci effectuera les tâches suivantes : <0>Désactiver le système DNSStubListener</0> <0>Définir ladresse du serveur DNS à 127.0.0.1 </0> <0>Remplacer la cible du lien symbolique de /etc/resolv.conf par /run/systemd/resolve/resolv.conf</0> <0>Arrêter DNSStubListener (recharger le service résolu par systemd)</0>", "autofix_warning_list": "Ceci effectuera les tâches suivantes : <0>Désactiver le système DNSStubListener</0> <0>Définir ladresse du serveur DNS à 127.0.0.1 </0> <0>Remplacer la cible du lien symbolique de /etc/resolv.conf par /run/systemd/resolve/resolv.conf</0> <0>Arrêter DNSStubListener (recharger le service résolu par systemd)</0>",
"autofix_warning_result": "Par conséquent, toutes les demandes DNS de votre système seront traitées par AdGuardHome par défaut.", "autofix_warning_result": "Par conséquent, toutes les demandes DNS de votre système seront traitées par AdGuardHome par défaut.",

View File

@ -1,26 +1,26 @@
{ {
"client_settings": "Pengaturan klien", "client_settings": "Pengaturan klien",
"example_upstream_reserved": "upstream <0>untuk domain spesifik</0>;", "example_upstream_reserved": "hulu <0>untuk domain tertentu</0>;",
"example_multiple_upstreams_reserved": "beberapa server upstream <0>untuk domain spesifik</0>;", "example_multiple_upstreams_reserved": "beberapa hulu <0>untuk domain tertentu</0>;",
"example_upstream_comment": "komentar.", "example_upstream_comment": "komentar.",
"upstream_parallel": "Gunakan kueri paralel untuk mempercepat resoluasi dengan menanyakan semua server upstream secara bersamaan", "upstream_parallel": "Gunakan kueri paralel untuk mempercepat penyelesaian dengan mengkueri seluruh server hulu secara bersamaan.",
"parallel_requests": "Permintaan paralel", "parallel_requests": "Permintaan paralel",
"load_balancing": "Penyeimbang beban", "load_balancing": "Penyeimbang beban",
"load_balancing_desc": "Permintaan satu server pada satu waktu. AdGuard Home akan menggunakan algoritma acak tertimbang untuk memilih server sehingga server tercepat akan lebih sering digunakan.", "load_balancing_desc": "Permintaan satu server pada satu waktu. AdGuard Home akan menggunakan algoritma acak tertimbang untuk memilih server sehingga server tercepat akan lebih sering digunakan.",
"bootstrap_dns": "Server DNS bootstrap", "bootstrap_dns": "Server DNS bootstrap",
"bootstrap_dns_desc": "Alamat IP server DNS yang digunakan untuk menyelesaikan alamat IP resolver DoH/DoT yang Anda tentukan sebagai upstream. Komentar tidak diizinkan.", "bootstrap_dns_desc": "Alamat IP server DNS yang digunakan untuk menyelesaikan alamat IP penyelesai DoH/DoT yang Anda tentukan sebagai hulu. Tidak diizinkan untuk berkomentar.",
"fallback_dns_title": "Server DNS cadangan", "fallback_dns_title": "Server DNS cadangan",
"fallback_dns_desc": "Daftar server DNS cadangan yang digunakan ketika server hulu DNS tidak merespons. Sintaksnya sama dengan kolom hulu utama di atas.", "fallback_dns_desc": "Daftar server DNS cadangan yang digunakan ketika server hulu DNS tidak merespons. Sintaksnya sama dengan kolom hulu utama di atas.",
"fallback_dns_placeholder": "Masukkan satu server DNS cadangan per baris", "fallback_dns_placeholder": "Masukkan satu server DNS cadangan per baris",
"local_ptr_title": "Server pembalik DNS pribadi", "local_ptr_title": "Server pembalik DNS pribadi",
"local_ptr_desc": "Server DNS yang digunakan AdGuard Home untuk kueri PTR lokal. Server ini digunakan untuk menyelesaikan nama host klien dengan alamat IP pribadi, misalnya \"192.168.12.34\", menggunakan DNS terbalik. Jika tidak disetel, AdGuard Home menggunakan alamat resolver DNS default OS Anda kecuali untuk alamat AdGuard Home itu sendiri.", "local_ptr_desc": "Server DNS yang digunakan oleh AdGuard Home untuk permintaan PTR, SOA, dan NS pribadi. Permintaan dianggap pribadi jika meminta domain ARPA yang berisi subnet dalam rentang IP pribadi (seperti \"192.168.12.34\") dan berasal dari klien dengan alamat IP pribadi. Jika tidak ditetapkan, standar pemecah DNS milik OS Anda akan digunakan, kecuali untuk alamat IP AdGuard Home.",
"local_ptr_default_resolver": "Secara bawaan, AdGuard Home menggunakan pemecah DNS terbalik: {{ip}}.", "local_ptr_default_resolver": "Secara bawaan, AdGuard Home menggunakan pemecah DNS terbalik: {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home tidak dapat menentukan pemecah DNS terbalik yang sesuai untuk sistem ini.", "local_ptr_no_default_resolver": "AdGuard Home tidak dapat menentukan pemecah DNS terbalik yang sesuai untuk sistem ini.",
"local_ptr_placeholder": "Masukkan satu alamat IP per baris", "local_ptr_placeholder": "Masukkan satu alamat IP per baris",
"resolve_clients_title": "Aktifkan resolusi hostname klien", "resolve_clients_title": "Aktifkan resolusi hostname klien",
"resolve_clients_desc": "Menyelesaikan alamat IP klien secara terbalik ke nama host mereka dengan mengirimkan kueri PTR ke resolver yang sesuai (server DNS pribadi untuk klien lokal, server upstream untuk klien dengan alamat IP publik).", "resolve_clients_desc": "Selesaikan alamat IP klien secara terbalik ke dalam nama host mereka dengan mengirimkan kueri PTR ke penyelesai yang sesuai (server DNS pribadi untuk klien lokal, server hulu untuk klien dengan alamat IP publik).",
"use_private_ptr_resolvers_title": "Gunakan server pembalik DNS pribadi", "use_private_ptr_resolvers_title": "Gunakan server pembalik DNS pribadi",
"use_private_ptr_resolvers_desc": "Lakukan pencarian DNS terbalik untuk alamat yang disajikan secara lokal menggunakan server hulu ini. Jika dinonaktifkan, Adguard Home merespons dengan NXDOMAIN untuk semua permintaan PTR tersebut kecuali untuk klien yang diketahui dari DHCP, /etc/hosts, dan seterusnya.", "use_private_ptr_resolvers_desc": "Menyelesaikan permintaan PTR, SOA, dan NS untuk domain ARPA yang berisi alamat IP pribadi melalui server hulu pribadi, DHCP, /etc/hosts, dll. Jika dinonaktifkan, AdGuard Home akan merespons semua permintaan tersebut dengan NXDOMAIN.",
"check_dhcp_servers": "Cek untuk server DHCP", "check_dhcp_servers": "Cek untuk server DHCP",
"save_config": "Simpan pengaturan", "save_config": "Simpan pengaturan",
"enabled_dhcp": "Server DHCP diaktifkan", "enabled_dhcp": "Server DHCP diaktifkan",
@ -49,12 +49,12 @@
"form_error_server_name": "Nama server tidak valid", "form_error_server_name": "Nama server tidak valid",
"form_error_subnet": "Subnet \"{{cidr}}\" tidak berisi alamat IP \"{{ip}}\"", "form_error_subnet": "Subnet \"{{cidr}}\" tidak berisi alamat IP \"{{ip}}\"",
"form_error_positive": "Harus lebih dari 0", "form_error_positive": "Harus lebih dari 0",
"form_error_gateway_ip": "Sewa tidak dapat memiliki alamat IP gateway", "form_error_gateway_ip": "Lease tidak dapat memiliki gerbang alamat IP",
"out_of_range_error": "Harus di luar rentang \"{{start}}\"-\"{{end}}\"", "out_of_range_error": "Harus di luar rentang \"{{start}}\"-\"{{end}}\"",
"lower_range_start_error": "Harus lebih rendah dari rentang awal", "lower_range_start_error": "Harus lebih rendah dari rentang awal",
"greater_range_start_error": "Harus lebih besar dari rentang awal", "greater_range_start_error": "Harus lebih besar dari rentang awal",
"subnet_error": "Alamat harus dalam satu subnet", "subnet_error": "Alamat harus dalam satu subnet",
"gateway_or_subnet_invalid": "Subnet mask tidak valid", "gateway_or_subnet_invalid": "Subnet samaran tidak valid",
"dhcp_form_gateway_input": "IP gateway", "dhcp_form_gateway_input": "IP gateway",
"dhcp_form_subnet_input": "Subnet mask", "dhcp_form_subnet_input": "Subnet mask",
"dhcp_form_range_title": "Rentang alamat IP", "dhcp_form_range_title": "Rentang alamat IP",
@ -132,8 +132,8 @@
"top_clients": "Klien teratas", "top_clients": "Klien teratas",
"no_clients_found": "Tidak ditemukan klien", "no_clients_found": "Tidak ditemukan klien",
"general_statistics": "Statistik umum", "general_statistics": "Statistik umum",
"top_upstreams": "Top servers upstream", "top_upstreams": "Hulu teratas",
"no_upstreams_data_found": "Tidak ada data server upstream yang ditemukan", "no_upstreams_data_found": "Tidak ada data hulu yang ditemukan",
"number_of_dns_query_days": "Jumlah kueri DNS diproses selama {{value}} hari terakhir", "number_of_dns_query_days": "Jumlah kueri DNS diproses selama {{value}} hari terakhir",
"number_of_dns_query_days_plural": "Jumlah kueri DNS yang diproses selama {{count}} hari terakhir", "number_of_dns_query_days_plural": "Jumlah kueri DNS yang diproses selama {{count}} hari terakhir",
"number_of_dns_query_hours": "Jumlah kueri DNS diproses selama {{{count}} jam terakhir", "number_of_dns_query_hours": "Jumlah kueri DNS diproses selama {{{count}} jam terakhir",
@ -154,7 +154,7 @@
"use_adguard_parental": "Gunakan layanan web kontrol orang tua AdGuard", "use_adguard_parental": "Gunakan layanan web kontrol orang tua AdGuard",
"use_adguard_parental_hint": "AdGuard Home akan mengecek jika domain mengandung materi dewasa. Akan menggunakan API yang ramah privasi yang sama sebagai layanan web keamanan penjelajahan.", "use_adguard_parental_hint": "AdGuard Home akan mengecek jika domain mengandung materi dewasa. Akan menggunakan API yang ramah privasi yang sama sebagai layanan web keamanan penjelajahan.",
"enforce_safe_search": "Pakai pencarian aman", "enforce_safe_search": "Pakai pencarian aman",
"enforce_save_search_hint": "AdGuard Home dapat memaksa penelusuran aman pada mesin pencari berikut: Google, Youtube, Bing, DuckDuckGo, Yandex, dan Pixabay.", "enforce_save_search_hint": "AdGuard Home akan memberlakukan pencarian yang aman di mesin pencari berikut ini: Google, YouTube, Bing, DuckDuckGo, Ecosia, Yandex, Pixabay.",
"no_servers_specified": "Sever tidak disebutkan", "no_servers_specified": "Sever tidak disebutkan",
"general_settings": "Pengaturan umum", "general_settings": "Pengaturan umum",
"dns_settings": "Pengaturan DNS", "dns_settings": "Pengaturan DNS",
@ -169,8 +169,8 @@
"upstream_dns_help": "Masukkan satu alamat server per baris. <a>Pelajari lebih lanjut</a> mengenai cara mengonfigurasi server DNS hulu.", "upstream_dns_help": "Masukkan satu alamat server per baris. <a>Pelajari lebih lanjut</a> mengenai cara mengonfigurasi server DNS hulu.",
"upstream_dns_configured_in_file": "Diatur dalam {{path}}", "upstream_dns_configured_in_file": "Diatur dalam {{path}}",
"test_upstream_btn": "Uji hulu", "test_upstream_btn": "Uji hulu",
"upstreams": "Upstream", "upstreams": "Hulu",
"upstream": "Server upstream", "upstream": "Hulu",
"apply_btn": "Terapkan", "apply_btn": "Terapkan",
"disabled_filtering_toast": "Penyaringan nonaktif", "disabled_filtering_toast": "Penyaringan nonaktif",
"enabled_filtering_toast": "Penyaringan aktif", "enabled_filtering_toast": "Penyaringan aktif",
@ -215,29 +215,29 @@
"system_host_files": "Berkas host sistem", "system_host_files": "Berkas host sistem",
"examples_title": "Contoh", "examples_title": "Contoh",
"example_meaning_filter_block": "blokir akses ke example.org dan seluruh subdomainnya;", "example_meaning_filter_block": "blokir akses ke example.org dan seluruh subdomainnya;",
"example_meaning_filter_whitelist": "buka blokir akses ke domain example.orf dan seluruh subdomainnya;", "example_meaning_filter_whitelist": "buka blokir akses ke domain example.org dan seluruh subdomainnya;",
"example_meaning_host_block": "merespons dengan 127.0.0.1 untuk example.org (tetapi tidak untuk subdomainnya);", "example_meaning_host_block": "merespons dengan 127.0.0.1 untuk example.org (tetapi tidak untuk subdomainnya);",
"example_comment": "! Komentar di sini.", "example_comment": "! Komentar di sini.",
"example_comment_meaning": "hanya sebuah komentar;", "example_comment_meaning": "hanya sebuah komentar;",
"example_comment_hash": "# Juga sebuah komentar.", "example_comment_hash": "# Juga sebuah komentar.",
"example_regex_meaning": "blokir akses ke domain yang cocok dengan ekspresi reguler yang ditentukan.", "example_regex_meaning": "blokir akses ke domain yang cocok dengan ekspresi reguler yang ditentukan.",
"example_upstream_regular": "DNS reguler (melalui UDP);", "example_upstream_regular": "DNS biasa (melalui UDP);",
"example_upstream_regular_port": "DNS biasa (lebih dari UDP, dengan port);", "example_upstream_regular_port": "DNS biasa (melalui UDP, dengan port);",
"example_upstream_udp": "DNS biasa (lebih dari UDP, nama host);", "example_upstream_udp": "DNS biasa (melalui UDP, nama host);",
"example_upstream_dot": "<0>DNS melalui TLS</0> terenkripsi;", "example_upstream_dot": "<0>DNS melalui TLS</0> terenkripsi;",
"example_upstream_doh": "<0>DNS melalui HTTPS</0> terenkripsi;", "example_upstream_doh": "<0>DNS melalui HTTPS</0> terenkripsi;",
"example_upstream_doh3": "DNS melalui HTTPS terenkripsi dengan <0>HTTP/3</0> secara paksa dan tidak ada cadangan ke HTTP/2 atau lebih rendah;", "example_upstream_doh3": "DNS melalui HTTPS terenkripsi dengan <0>HTTP/3</0> secara paksa dan tidak ada cadangan ke HTTP/2 atau lebih rendah;",
"example_upstream_doq": "<0>DNS melalui QUIC</0> terenkripsi;", "example_upstream_doq": "<0>DNS melalui QUIC</0> terenkripsi;",
"example_upstream_sdns": "<0>Stempel DNS</0> untuk <1>DNSCrypt</1> atau pengarah <2>DNS-over-HTTPS</2>;", "example_upstream_sdns": "<0>Stempel DNS</0> untuk <1>DNSCrypt</1> atau pengarah <2>DNS melalui HTTPS</2>;",
"example_upstream_tcp": "DNS reguler (melalui TCP);", "example_upstream_tcp": "DNS biasa (melalui TCP);",
"example_upstream_tcp_port": "DNS biasa (melalui TCP, dengan port);", "example_upstream_tcp_port": "DNS biasa (melalui TCP, dengan port);",
"example_upstream_tcp_hostname": "DNS biasa (lebih dari TCP, nama host);", "example_upstream_tcp_hostname": "DNS biasa (melalui TCP, nama host);",
"all_lists_up_to_date_toast": "Semua daftar sudah diperbarui", "all_lists_up_to_date_toast": "Semua daftar sudah diperbarui",
"updated_upstream_dns_toast": "Server upstream berhasil disimpan", "updated_upstream_dns_toast": "Server hulu berhasil disimpan",
"dns_test_ok_toast": "Server DNS yang ditentukan bekerja dengan benar", "dns_test_ok_toast": "Server DNS yang ditentukan bekerja dengan benar",
"dns_test_not_ok_toast": "Server \"{{key}}\": tidak dapat digunakan, mohon cek bahwa Anda telah menulisnya dengan benar", "dns_test_not_ok_toast": "Server \"{{key}}\": tidak dapat digunakan, mohon cek bahwa Anda telah menulisnya dengan benar",
"dns_test_parsing_error_toast": "Bagian {{section}}: baris {{line}}: tidak dapat digunakan, mohon cek bahwa Anda telah menulisnya dengan benar", "dns_test_parsing_error_toast": "Bagian {{section}}: baris {{line}}: tidak dapat digunakan, mohon cek bahwa Anda telah menulisnya dengan benar",
"dns_test_warning_toast": "Upstream \"{{key}}\" tidak menanggapi permintaan pengujian dan mungkin tidak berfungsi dengan baik", "dns_test_warning_toast": "Hulu \"{{key}}\" tidak menanggapi permintaan pengujian dan mungkin tidak berfungsi dengan benar",
"unblock": "Buka Blokir", "unblock": "Buka Blokir",
"block": "Blok", "block": "Blok",
"disallow_this_client": "Cabut ijin untuk klien ini", "disallow_this_client": "Cabut ijin untuk klien ini",
@ -268,18 +268,18 @@
"rule_added_to_custom_filtering_toast": "Aturan ditambah ke aturan penyaringan khusus: {{rule}}", "rule_added_to_custom_filtering_toast": "Aturan ditambah ke aturan penyaringan khusus: {{rule}}",
"query_log_response_status": "Status: {{value}}", "query_log_response_status": "Status: {{value}}",
"query_log_filtered": "Difilter oleh {{filter}}", "query_log_filtered": "Difilter oleh {{filter}}",
"query_log_confirm_clear": "Apakah Anda yakin ingin menghapus seluruh kueri log?", "query_log_confirm_clear": "Apakah Anda yakin ingin menghapus seluruh catatan kueri?",
"query_log_cleared": "Kueri log telah berhasil dihapus", "query_log_cleared": "Catatan kueri berhasil dihapus",
"query_log_updated": "Log permintaan telah berhasil diperbarui", "query_log_updated": "Catatan kueri berhasil diperbarui",
"query_log_clear": "Hapus kueri log", "query_log_clear": "Hapus catatan kueri",
"query_log_retention": "Rotasi kueri log", "query_log_retention": "Rotasi kueri log",
"query_log_enable": "Aktifkan log", "query_log_enable": "Aktifkan catatan",
"query_log_configuration": "Konfigurasi log", "query_log_configuration": "Konfigurasi catatan",
"query_log_disabled": "Kueri log dinonaktifkan dan dapat dikonfigurasi di <0>pengaturan</0>", "query_log_disabled": "Catatan kueri dinonaktifkan dan dapat dikonfigurasi di <0>pengaturan</0>",
"query_log_strict_search": "Gunakan tanda kutip ganda untuk pencarian ketat", "query_log_strict_search": "Gunakan tanda kutip ganda untuk pencarian ketat",
"query_log_retention_confirm": "Apakah Anda yakin ingin mengubah rotasi kueri log? Jika Anda menurunkan nilai interval, beberapa data akan hilang", "query_log_retention_confirm": "Apakah Anda yakin ingin mengubah rotasi kueri log? Jika Anda menurunkan nilai interval, beberapa data akan hilang",
"anonymize_client_ip": "Anonim IP klien", "anonymize_client_ip": "Anonim IP klien",
"anonymize_client_ip_desc": "Jangan simpan alamat lengkap IP klien dalam log dan statistik", "anonymize_client_ip_desc": "Jangan simpan alamat lengkap IP klien dalam catatan atau statistik",
"dns_config": "Konfigurasi server DNS", "dns_config": "Konfigurasi server DNS",
"dns_cache_config": "Konfigurasi cache DNS", "dns_cache_config": "Konfigurasi cache DNS",
"dns_cache_config_desc": "Disini Anda bisa mengonfigurasi cache DNS", "dns_cache_config_desc": "Disini Anda bisa mengonfigurasi cache DNS",
@ -308,8 +308,8 @@
"form_enter_rate_limit": "Masukkan batas nilai", "form_enter_rate_limit": "Masukkan batas nilai",
"rate_limit": "Batas nilai", "rate_limit": "Batas nilai",
"edns_enable": "Aktifkan EDNS Klien Subnet", "edns_enable": "Aktifkan EDNS Klien Subnet",
"edns_cs_desc": "Tambahkan opsi EDNS Client Subnet (ECS) ke permintaan upstream dan catat nilai yang dikirim oleh klien di log kueri.", "edns_cs_desc": "Tambahkan opsi EDNS Client Subnet (ECS) ke permintaan hulu dan catat nilai yang dikirim oleh klien dalam catatan kueri.",
"edns_use_custom_ip": "Gunakan IP khusus untuk EDNS", "edns_use_custom_ip": "Gunakan IP kustom untuk EDNS",
"edns_use_custom_ip_desc": "Izinkan untuk menggunakan IP kustom untuk EDNS", "edns_use_custom_ip_desc": "Izinkan untuk menggunakan IP kustom untuk EDNS",
"rate_limit_desc": "Jumlah permintaan per detik yang diperbolehkan untuk satu klien. Atur ke 0 untuk tidak terbatas.", "rate_limit_desc": "Jumlah permintaan per detik yang diperbolehkan untuk satu klien. Atur ke 0 untuk tidak terbatas.",
"rate_limit_subnet_len_ipv4": "Panjang awalan subnet untuk alamat IPv4", "rate_limit_subnet_len_ipv4": "Panjang awalan subnet untuk alamat IPv4",
@ -329,13 +329,13 @@
"blocking_mode_nxdomain": "NXDOMAIN: Respon pakai kode NXDOMAIN", "blocking_mode_nxdomain": "NXDOMAIN: Respon pakai kode NXDOMAIN",
"blocking_mode_null_ip": "Null IP: Respon pakai alamat IP kosong (0.0.0.0 untuk A; :: untuk AAAA)", "blocking_mode_null_ip": "Null IP: Respon pakai alamat IP kosong (0.0.0.0 untuk A; :: untuk AAAA)",
"blocking_mode_custom_ip": "IP kustom: respon dengan alamat IP yang diset secara manual", "blocking_mode_custom_ip": "IP kustom: respon dengan alamat IP yang diset secara manual",
"theme_auto": "Auto", "theme_auto": "Otomatis",
"theme_light": "Terang", "theme_light": "Terang",
"theme_dark": "Gelap", "theme_dark": "Gelap",
"upstream_dns_client_desc": "Jika Anda biarkan kolom ini kosong, AdGuard Home akan menggunakan server yang dikonfigurasi di <0>pengaturan DNS</0>.", "upstream_dns_client_desc": "Jika Anda biarkan kolom ini kosong, AdGuard Home akan menggunakan server yang dikonfigurasi di <0>pengaturan DNS</0>.",
"tracker_source": "Sumber pelacak", "tracker_source": "Sumber pelacak",
"source_label": "Sumber", "source_label": "Sumber",
"found_in_known_domain_db": "Ditemukan di database domain dikenal", "found_in_known_domain_db": "Ditemukan di basis data domain yang dikenal.",
"category_label": "Kategori", "category_label": "Kategori",
"rule_label": "Atura(n)", "rule_label": "Atura(n)",
"list_label": "Daftar", "list_label": "Daftar",
@ -366,18 +366,18 @@
"install_devices_router": "Router", "install_devices_router": "Router",
"install_devices_router_desc": "Penyiapan ini secara otomatis mencakup semua perangkat yang terhubung ke router rumah Anda, tidak perlu mengkonfigurasi masing-masing perangkat secara manual.", "install_devices_router_desc": "Penyiapan ini secara otomatis mencakup semua perangkat yang terhubung ke router rumah Anda, tidak perlu mengkonfigurasi masing-masing perangkat secara manual.",
"install_devices_address": "Server DNS AdGuard Home akan menggunakan alamat berikut", "install_devices_address": "Server DNS AdGuard Home akan menggunakan alamat berikut",
"install_devices_router_list_1": "Buka preferensi untuk router Anda. Biasanya, Anda dapat mengaksesnya dari browser Anda melalui URL, seperti http://192.168.0.1/ atau http://192.168.1.1/. Anda mungkin diminta untuk memasukkan kata sandi. Jika Anda tidak mengingatnya, Anda sering kali dapat mengatur ulang kata sandi dengan menekan tombol pada perute itu sendiri, tetapi perlu diketahui bahwa jika prosedur ini dipilih, Anda mungkin akan kehilangan seluruh konfigurasi perute. Jika router Anda memerlukan aplikasi untuk menyiapkannya, instal aplikasi tersebut di ponsel atau PC Anda dan gunakan untuk mengakses pengaturan router.", "install_devices_router_list_1": "Buka preferensi untuk router Anda. Biasanya, Anda dapat mengaksesnya dari peramban Anda melalui URL, seperti http://192.168.0.1/ atau http://192.168.1.1/. Anda mungkin diminta untuk memasukkan kata sandi. Jika Anda tidak mengingatnya, Anda sering kali dapat mengatur ulang kata sandi dengan menekan tombol pada router itu sendiri, tetapi perlu diketahui bahwa jika prosedur ini dipilih, Anda mungkin akan kehilangan seluruh konfigurasi router. Jika router Anda memerlukan aplikasi untuk menyiapkannya, pasang aplikasi tersebut di ponsel atau PC Anda dan gunakan untuk mengakses pengaturan router.",
"install_devices_router_list_2": "Temukan pengaturan DHCP / DNS. Cari huruf DNS di sebelah kolom yang memungkinkan dua atau tiga set angka, masing-masing dipecah menjadi empat kelompok dengan satu hingga tiga digit.", "install_devices_router_list_2": "Temukan pengaturan DHCP / DNS. Cari huruf DNS di sebelah kolom yang memungkinkan dua atau tiga set angka, masing-masing dipecah menjadi empat kelompok dengan satu hingga tiga digit.",
"install_devices_router_list_3": "Masukkan alamat server AdGuard Home disana", "install_devices_router_list_3": "Masukkan alamat server AdGuard Home disana",
"install_devices_router_list_4": "Anda tidak dapat menyetel server DNS kustom pada beberapa tipe router. Dalam hal ini mungkin membantu jika Anda mengatur AdGuard Home sebagai <0>server DHCP</0>. Jika tidak, Anda harus mencari petunjuk tentang cara mengkustomisasi server DNS untuk model router khusus Anda.", "install_devices_router_list_4": "Anda tidak dapat menyetel server DNS kustom pada beberapa tipe router. Dalam hal ini mungkin membantu jika Anda mengatur AdGuard Home sebagai <0>server DHCP</0>. Jika tidak, Anda harus mencari petunjuk tentang cara mengkustomisasi server DNS untuk model router khusus Anda.",
"install_devices_windows_list_1": "Buka Panel Kontrol melalui menu Start atau pencarian Windows.", "install_devices_windows_list_1": "Buka Panel Kontrol melalui menu Start atau pencarian Windows.",
"install_devices_windows_list_2": "Masuk ke kategori Jaringan dan Internet (Network and Internet) dan kemudian ke Pusat Jaringan dan Berbagi (Network and Sharing Center).", "install_devices_windows_list_2": "Masuk ke kategori Jaringan dan Internet (Network and Internet) dan kemudian ke Pusat Jaringan dan Berbagi (Network and Sharing Center).",
"install_devices_windows_list_3": "Di panel kiri, klik \"Ubah pengaturan adaptor\".", "install_devices_windows_list_3": "Di panel kiri, klik \"Ubah pengaturan adaptor\".",
"install_devices_windows_list_4": "Klik kanan koneksi aktif Anda dan pilih Properties.", "install_devices_windows_list_4": "Klik kanan koneksi aktif Anda dan pilih Properti.",
"install_devices_windows_list_5": "Temukan \"Internet Protocol Version 4 (TCP/IPv4)\" (atau, untuk IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\") dalam daftar, pilih dan kemudian klik Properties lagi.", "install_devices_windows_list_5": "Temukan \"Protokol Internet Versi 4 (TCP/IPv4)\" (atau, untuk IPv6, \"Protokol Internet Versi 6 (TCP/IPv6)\") dalam daftar, pilih dan kemudian klik Properti lagi.",
"install_devices_windows_list_6": "Pilih \"Gunakan alamat server DNS berikut\" dan masukkan alamat server Beranda AdGuard Anda.", "install_devices_windows_list_6": "Pilih \"Gunakan alamat server DNS berikut\" dan masukkan alamat server Beranda AdGuard Anda.",
"install_devices_macos_list_1": "Klik ikon Apple dan pergi ke System Preferences.", "install_devices_macos_list_1": "Klik ikon Apple dan buka Preferensi Sistem.",
"install_devices_macos_list_2": "Klik Network.", "install_devices_macos_list_2": "Klik Jaringan.",
"install_devices_macos_list_3": "Pilih koneksi pertama dalam daftar dan klik Advanced.", "install_devices_macos_list_3": "Pilih koneksi pertama dalam daftar dan klik Advanced.",
"install_devices_macos_list_4": "Pilih tab DNS dan masukkan alamat server AdGuard Anda.", "install_devices_macos_list_4": "Pilih tab DNS dan masukkan alamat server AdGuard Anda.",
"install_devices_android_list_1": "Dari layar beranda Menu Android, ketuk Pengaturan.", "install_devices_android_list_1": "Dari layar beranda Menu Android, ketuk Pengaturan.",
@ -394,7 +394,7 @@
"open_dashboard": "Buka Beranda", "open_dashboard": "Buka Beranda",
"install_saved": "Berhasil disimpan", "install_saved": "Berhasil disimpan",
"encryption_title": "Enkripsi", "encryption_title": "Enkripsi",
"encryption_desc": "Enkripsi (HTTPS/QUIC/TLS) untuk DNS dan antarmuka admin", "encryption_desc": "Dukungan enkripsi (HTTPS/QUIC/TLS) untuk DNS dan antarmuka web admin",
"encryption_config_saved": "Pengaturan enkripsi telah tersimpan", "encryption_config_saved": "Pengaturan enkripsi telah tersimpan",
"encryption_server": "Nama server", "encryption_server": "Nama server",
"encryption_server_enter": "Masukkan nama domain anda", "encryption_server_enter": "Masukkan nama domain anda",
@ -406,7 +406,7 @@
"encryption_dot": "Port DNS-over-TLS", "encryption_dot": "Port DNS-over-TLS",
"encryption_dot_desc": "Jika port ini terkonfigurasi, AdGuard Home akan menjalankan server DNS-over-TLS dalam port ini", "encryption_dot_desc": "Jika port ini terkonfigurasi, AdGuard Home akan menjalankan server DNS-over-TLS dalam port ini",
"encryption_doq": "Port DNS-over-QUIC ", "encryption_doq": "Port DNS-over-QUIC ",
"encryption_doq_desc": "Jika port ini diatur secara sepesifik, AdGuard Home akan menjalankan server DNS-lewat-QUIC pada port ini.", "encryption_doq_desc": "Jika port ini dikonfigurasi, AdGuard Home akan menjalankan server DNS melalui QUIC pada port ini.",
"encryption_certificates": "Sertifikat", "encryption_certificates": "Sertifikat",
"encryption_certificates_desc": "Untuk menggunakan enkripsi, Anda perlu memberikan rantai sertifikat SSL yang valid untuk domain Anda. Anda bisa mendapatkan sertifikat gratis di <0>{{link}}</0> atau Anda dapat membelinya dari salah satu Otoritas Sertifikat tepercaya.", "encryption_certificates_desc": "Untuk menggunakan enkripsi, Anda perlu memberikan rantai sertifikat SSL yang valid untuk domain Anda. Anda bisa mendapatkan sertifikat gratis di <0>{{link}}</0> atau Anda dapat membelinya dari salah satu Otoritas Sertifikat tepercaya.",
"encryption_certificates_input": "Salin / rekatkan sertifikat PEM yang disandikan di sini.", "encryption_certificates_input": "Salin / rekatkan sertifikat PEM yang disandikan di sini.",
@ -431,8 +431,8 @@
"topline_expiring_certificate": "Sertifikat SSL Anda hampir kedaluwarsa. Perbarui <0>Pengaturan enkripsi</0>.", "topline_expiring_certificate": "Sertifikat SSL Anda hampir kedaluwarsa. Perbarui <0>Pengaturan enkripsi</0>.",
"topline_expired_certificate": "Sertifikat SSL Anda kedaluwarsa. Perbarui <0>Pengaturan enkripsi</0>.", "topline_expired_certificate": "Sertifikat SSL Anda kedaluwarsa. Perbarui <0>Pengaturan enkripsi</0>.",
"form_error_port_range": "Masukkan nomor port di kisaran 80-65535", "form_error_port_range": "Masukkan nomor port di kisaran 80-65535",
"form_error_port_unsafe": "Ini adalah port yang tidak aman", "form_error_port_unsafe": "Port tidak aman",
"form_error_equal": "Seharusnya tidak sama", "form_error_equal": "Tidak boleh sama",
"form_error_password": "Kata sandi tidak cocok", "form_error_password": "Kata sandi tidak cocok",
"reset_settings": "Setel ulang pengaturan", "reset_settings": "Setel ulang pengaturan",
"update_announcement": "AdGuard Home {{version}} sekarang tersedia! <0>Klik di sini</0> untuk info lebih lanjut.", "update_announcement": "AdGuard Home {{version}} sekarang tersedia! <0>Klik di sini</0> untuk info lebih lanjut.",
@ -447,7 +447,7 @@
"update_failed": "Pembaruan otomatis gagal. Silakan <a>ikuti langkah-langkah berikut</a> untuk memperbarui secara manual.", "update_failed": "Pembaruan otomatis gagal. Silakan <a>ikuti langkah-langkah berikut</a> untuk memperbarui secara manual.",
"manual_update": "Silakan <a>mengikuti langkah berikut</a> untuk memperbarui secara manual.", "manual_update": "Silakan <a>mengikuti langkah berikut</a> untuk memperbarui secara manual.",
"processing_update": "Silahkan tunggu, AdGuard Home sedang diperbarui", "processing_update": "Silahkan tunggu, AdGuard Home sedang diperbarui",
"clients_title": "Klien yang gigih", "clients_title": "Klien persisten",
"clients_desc": "Konfigurasikan catatan klien persisten untuk perangkat yang terhubung ke AdGuard Home", "clients_desc": "Konfigurasikan catatan klien persisten untuk perangkat yang terhubung ke AdGuard Home",
"settings_global": "Global", "settings_global": "Global",
"settings_custom": "Kustom", "settings_custom": "Kustom",
@ -459,7 +459,7 @@
"client_edit": "Ubah Klien", "client_edit": "Ubah Klien",
"client_identifier": "Identifikasi", "client_identifier": "Identifikasi",
"ip_address": "Alamat IP", "ip_address": "Alamat IP",
"client_identifier_desc": "Klien dapat diidentifikasi oleh alamat IP, CIDR, alamat MAC atau ClientID (dapat digunakan untuk DoT/DoH/DoQ). <0>Di sini</0> Anda dapat mempelajari lebih lanjut tentang cara mengidentifikasi klien.", "client_identifier_desc": "Klien dapat diidentifikasi berdasarkan alamat IP, CIDR, alamat MAC, atau ClientID (dapat digunakan untuk DoT/DoH/DoQ). Pelajari lebih lanjut tentang cara mengidentifikasi klien <0>di sini</0>.",
"form_enter_ip": "Masukkan IP", "form_enter_ip": "Masukkan IP",
"form_enter_subnet_ip": "Masukkan alamat IP di subnet \"{{cidr}}\"", "form_enter_subnet_ip": "Masukkan alamat IP di subnet \"{{cidr}}\"",
"form_enter_mac": "Masukkan MAC", "form_enter_mac": "Masukkan MAC",
@ -475,7 +475,7 @@
"clients_not_found": "Tidak ada klien ditemukan", "clients_not_found": "Tidak ada klien ditemukan",
"client_confirm_delete": "Apakah anda yakin ingin menghapus klien \"{{key}}\"?", "client_confirm_delete": "Apakah anda yakin ingin menghapus klien \"{{key}}\"?",
"list_confirm_delete": "Anda yakin ingin menghapus daftar ini?", "list_confirm_delete": "Anda yakin ingin menghapus daftar ini?",
"auto_clients_title": "Klien (waktu berjalan)", "auto_clients_title": "Klien runtime",
"auto_clients_desc": "Informasi tentang alamat IP perangkat yang menggunakan atau mungkin menggunakan AdGuard Home. Informasi ini dikumpulkan dari beberapa sumber, termasuk berkas host, DNS terbalik, dll.", "auto_clients_desc": "Informasi tentang alamat IP perangkat yang menggunakan atau mungkin menggunakan AdGuard Home. Informasi ini dikumpulkan dari beberapa sumber, termasuk berkas host, DNS terbalik, dll.",
"access_title": "Pengaturan akses", "access_title": "Pengaturan akses",
"access_desc": "Disini anda dapat mengatur aturan akses untuk server AdGuard Home DNS", "access_desc": "Disini anda dapat mengatur aturan akses untuk server AdGuard Home DNS",
@ -484,9 +484,9 @@
"access_disallowed_title": "Klien yang tidak diizinkan", "access_disallowed_title": "Klien yang tidak diizinkan",
"access_disallowed_desc": "Daftar CIDR, alamat IP, atau <a>ClientID</a>. Jika daftar ini memiliki entri, AdGuard Home akan membatalkan permintaan dari klien ini. Kolom ini diabaikan jika ada entri di daftar putih klien.", "access_disallowed_desc": "Daftar CIDR, alamat IP, atau <a>ClientID</a>. Jika daftar ini memiliki entri, AdGuard Home akan membatalkan permintaan dari klien ini. Kolom ini diabaikan jika ada entri di daftar putih klien.",
"access_blocked_title": "Domain yang diblokir", "access_blocked_title": "Domain yang diblokir",
"access_blocked_desc": "Jangan bingung dengan filter. AdGuard Home menghapus kueri DNS yang cocok dengan domain ini, dan kueri ini bahkan tidak muncul di log kueri. Anda dapat menentukan nama domain, karakter pengganti, atau aturan filter URL yang tepat, mis. \"example.org\", \"*.example.org\", atau \"||example.org^\" yang sesuai.", "access_blocked_desc": "Jangan dikelirukan dengan filter. AdGuard Home membuang kueri DNS yang cocok dengan domain ini, dan kueri ini bahkan tidak muncul di catatan kueri. Anda dapat menentukan nama domain, karakter pengganti, atau aturan filter URL yang tepat, misalnya \"example.org\", \"*.example.org\", atau \"||example.org^\" secara bersamaan.",
"access_settings_saved": "Pengaturan akses berhasil disimpan", "access_settings_saved": "Pengaturan akses berhasil disimpan",
"updates_checked": "Versi baru AdGuard Home tersedia\n", "updates_checked": "Versi baru AdGuard Home tersedia",
"updates_version_equal": "AdGuard Home sudah tebaru", "updates_version_equal": "AdGuard Home sudah tebaru",
"check_updates_now": "Periksa pembaruan sekarang", "check_updates_now": "Periksa pembaruan sekarang",
"version_request_error": "Pemeriksaan pembaruan gagal. Harap periksa koneksi internet anda.", "version_request_error": "Pemeriksaan pembaruan gagal. Harap periksa koneksi internet anda.",
@ -563,7 +563,7 @@
"ignore_domains": "Domain yang diabaikan (dipisahkan oleh baris baru)", "ignore_domains": "Domain yang diabaikan (dipisahkan oleh baris baru)",
"ignore_domains_title": "Domain yang diabaikan", "ignore_domains_title": "Domain yang diabaikan",
"ignore_domains_desc_stats": "Kueri yang cocok dengan aturan ini tidak ditulis ke statistik", "ignore_domains_desc_stats": "Kueri yang cocok dengan aturan ini tidak ditulis ke statistik",
"ignore_domains_desc_query": "Kueri yang cocok dengan aturan ini tidak ditulis ke log kueri", "ignore_domains_desc_query": "Kueri yang cocok dengan aturan ini tidak ditulis ke catatan kueri",
"interval_hours": "{{count}} jam", "interval_hours": "{{count}} jam",
"interval_hours_plural": "{{count}} jam", "interval_hours_plural": "{{count}} jam",
"filters_configuration": "Konfigurasi filter", "filters_configuration": "Konfigurasi filter",
@ -593,8 +593,8 @@
"example_rewrite_wildcard": "tulis ulang respon untuk semua subdomain <0>contoh.org</0>.", "example_rewrite_wildcard": "tulis ulang respon untuk semua subdomain <0>contoh.org</0>.",
"rewrite_ip_address": "Alamat IP: pakai IP ini dalam respons A atau AAAA", "rewrite_ip_address": "Alamat IP: pakai IP ini dalam respons A atau AAAA",
"rewrite_domain_name": "Nama domain: tambah ke rekaman CNAME", "rewrite_domain_name": "Nama domain: tambah ke rekaman CNAME",
"rewrite_A": "<0>A</0>: nilai khusus, biarkan <0>A</0> merekam dari upstream", "rewrite_A": "<0>A</0>: nilai khusus, biarkan <0>A</0> merekam dari hulu",
"rewrite_AAAA": "<0>AAAA</0>: nilai khusus, biarkan <0>AAAA</0> merekam dari upstream", "rewrite_AAAA": "<0>AAAA</0>: nilai khusus, biarkan <0>AAAA</0> merekam dari hulu",
"disable_ipv6": "Nonaktifkan penyelesaian alamat IPv6", "disable_ipv6": "Nonaktifkan penyelesaian alamat IPv6",
"disable_ipv6_desc": "Hapus semua kueri DNS untuk alamat IPv6 (ketik AAAA) dan hapus petunjuk IPv6 dari respons HTTPS.", "disable_ipv6_desc": "Hapus semua kueri DNS untuk alamat IPv6 (ketik AAAA) dan hapus petunjuk IPv6 dari respons HTTPS.",
"fastest_addr": "Alamat IP tercepat", "fastest_addr": "Alamat IP tercepat",
@ -655,8 +655,8 @@
"enter_cache_size": "Masukkan ukuran cache (bytes)", "enter_cache_size": "Masukkan ukuran cache (bytes)",
"enter_cache_ttl_min_override": "Masukkan TTL minimum (detik)", "enter_cache_ttl_min_override": "Masukkan TTL minimum (detik)",
"enter_cache_ttl_max_override": "Masukkan TTL maksimum (detik)", "enter_cache_ttl_max_override": "Masukkan TTL maksimum (detik)",
"cache_ttl_min_override_desc": "Perpanjang nilai waktu untuk hidup (detik) yang diterima dari server hulu saat menyimpan respons DNS.", "cache_ttl_min_override_desc": "Perpanjang nilai time-to-live (detik) yang diterima dari server hulu saat menyimpan respons DNS.",
"cache_ttl_max_override_desc": "Tetapkan nilai waktu-online maksimum (detik) untuk entri di cache DNS.", "cache_ttl_max_override_desc": "Tetapkan nilai maksimum time-to-live (detik) untuk entri dalam cache DNS.",
"ttl_cache_validation": "Nilai TTL cache minimum harus kurang dari atau sama dengan nilai maksimum", "ttl_cache_validation": "Nilai TTL cache minimum harus kurang dari atau sama dengan nilai maksimum",
"cache_optimistic": "Caching yang optimis", "cache_optimistic": "Caching yang optimis",
"cache_optimistic_desc": "Buat AdGuard Home merespons dari cache bahkan ketika entri telah kedaluwarsa dan juga mencoba untuk menyegarkannya.", "cache_optimistic_desc": "Buat AdGuard Home merespons dari cache bahkan ketika entri telah kedaluwarsa dan juga mencoba untuk menyegarkannya.",
@ -678,7 +678,7 @@
"use_saved_key": "Gunakan kunci yang disimpan sebelumnya", "use_saved_key": "Gunakan kunci yang disimpan sebelumnya",
"parental_control": "Pengawasan Orang Tua", "parental_control": "Pengawasan Orang Tua",
"safe_browsing": "Penjelajahan Aman", "safe_browsing": "Penjelajahan Aman",
"served_from_cache": "{{value}} <i>(disajikan dari cache)</i>", "served_from_cache_label": "Disajikan dari cache",
"form_error_password_length": "Kata sandi harus terdiri dari {{min}} hingga {{max}}", "form_error_password_length": "Kata sandi harus terdiri dari {{min}} hingga {{max}}",
"anonymizer_notification": "<0>Catatan:</0> Anonimisasi IP diaktifkan. Anda dapat menonaktifkannya di <1>Pengaturan umum</1> .", "anonymizer_notification": "<0>Catatan:</0> Anonimisasi IP diaktifkan. Anda dapat menonaktifkannya di <1>Pengaturan umum</1> .",
"confirm_dns_cache_clear": "Apakah Anda yakin ingin menghapus cache DNS?", "confirm_dns_cache_clear": "Apakah Anda yakin ingin menghapus cache DNS?",
@ -688,11 +688,11 @@
"theme_auto_desc": "Otomatis (berdasarkan skema warna perangkat anda)", "theme_auto_desc": "Otomatis (berdasarkan skema warna perangkat anda)",
"theme_dark_desc": "Tema gelap", "theme_dark_desc": "Tema gelap",
"theme_light_desc": "Tema terang", "theme_light_desc": "Tema terang",
"disable_for_seconds": "Untuk {{count}} detik", "disable_for_seconds": "Selama {{count}} detik",
"disable_for_seconds_plural": "Untuk {{count}} detik", "disable_for_seconds_plural": "Selama {{count}} detik",
"disable_for_minutes": "Untuk {{count}} menit", "disable_for_minutes": "Selama {{count}} menit",
"disable_for_minutes_plural": "Untuk {{count}} menit", "disable_for_minutes_plural": "Selama {{count}} menit",
"disable_for_hours": "Untuk {{count}} jam", "disable_for_hours": "Selama {{count}} jam",
"disable_for_hours_plural": "Untuk {{count}} jam", "disable_for_hours_plural": "Untuk {{count}} jam",
"disable_until_tomorrow": "Sampai besok", "disable_until_tomorrow": "Sampai besok",
"disable_notify_for_seconds": "Hentikan perlindungan selama {{count}} detik", "disable_notify_for_seconds": "Hentikan perlindungan selama {{count}} detik",
@ -706,10 +706,10 @@
"custom_retention_input": "Masukkan retensi dalam hitungan jam", "custom_retention_input": "Masukkan retensi dalam hitungan jam",
"custom_rotation_input": "Masukkan rotasi dalam hitungan jam", "custom_rotation_input": "Masukkan rotasi dalam hitungan jam",
"protection_section_label": "Perlindungan", "protection_section_label": "Perlindungan",
"log_and_stats_section_label": "Log kueri dan statistik", "log_and_stats_section_label": "Catatan kueri dan statistik",
"ignore_query_log": "Abaikan klien ini di log kueri", "ignore_query_log": "Abaikan klien ini di catatan kueri",
"ignore_statistics": "Abaikan klien ini di statistik", "ignore_statistics": "Abaikan klien ini di statistik",
"schedule_services": "Menjeda pemblokiran layanan", "schedule_services": "Jeda pemblokiran layanan",
"schedule_services_desc": "Mengonfigurasi jadwal jeda filter pemblokiran layanan", "schedule_services_desc": "Mengonfigurasi jadwal jeda filter pemblokiran layanan",
"schedule_services_desc_client": "Mengonfigurasi jadwal jeda filter pemblokiran layanan untuk klien ini", "schedule_services_desc_client": "Mengonfigurasi jadwal jeda filter pemblokiran layanan untuk klien ini",
"schedule_desc": "Tetapkan periode tidak aktif untuk layanan yang diblokir", "schedule_desc": "Tetapkan periode tidak aktif untuk layanan yang diblokir",
@ -741,7 +741,7 @@
"thursday_short": "Kam", "thursday_short": "Kam",
"friday_short": "Jum", "friday_short": "Jum",
"saturday_short": "Sab", "saturday_short": "Sab",
"upstream_dns_cache_configuration": "Konfigurasi cache DNS upstream", "upstream_dns_cache_configuration": "Konfigurasi cache DNS hulu",
"enable_upstream_dns_cache": "Aktifkan cache DNS untuk konfigurasi hulu kustom pada klien ini", "enable_upstream_dns_cache": "Aktifkan cache DNS untuk konfigurasi hulu kustom pada klien ini",
"dns_cache_size": "Ukuran cache DNS, dalam byte" "dns_cache_size": "Ukuran cache DNS, dalam byte"
} }

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Utilizza richieste parallele per accelerare la risoluzione interrogando simultaneamente tutti i server upstream.", "upstream_parallel": "Utilizza richieste parallele per accelerare la risoluzione interrogando simultaneamente tutti i server upstream.",
"parallel_requests": "Richieste parallele", "parallel_requests": "Richieste parallele",
"load_balancing": "Bilanciamento del carico", "load_balancing": "Bilanciamento del carico",
"load_balancing_desc": "Esegui una query su un server upstream alla volta. AdGuard Home utilizza un algoritmo casuale ponderato per selezionare i server con il minor numero di ricerche fallite e il tempo medio di ricerca più basso.", "load_balancing_desc": "Esegui una query su un server upstream alla volta.<br/>AdGuard Home utilizza un algoritmo casuale ponderato per selezionare i server con il minor numero di ricerche fallite e il tempo medio di ricerca più basso.",
"bootstrap_dns": "Server DNS bootstrap", "bootstrap_dns": "Server DNS bootstrap",
"bootstrap_dns_desc": "Indirizzi IP dei server DNS utilizzati per risolvere gli indirizzi IP dei resolver DoH/DoT specificati come upstream. I commenti non sono ammessi.", "bootstrap_dns_desc": "Indirizzi IP dei server DNS utilizzati per risolvere gli indirizzi IP dei resolver DoH/DoT specificati come upstream. I commenti non sono ammessi.",
"fallback_dns_title": "Server DNS di fallback", "fallback_dns_title": "Server DNS di fallback",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Risposta TTL bloccata", "blocked_response_ttl": "Risposta TTL bloccata",
"blocked_response_ttl_desc": "Specifica per quanti secondi i client devono tenere nella cache una risposta filtrata", "blocked_response_ttl_desc": "Specifica per quanti secondi i client devono tenere nella cache una risposta filtrata",
"form_enter_blocked_response_ttl": "Inserisci tempo di vita (TTL) della risposta bloccata (secondi)", "form_enter_blocked_response_ttl": "Inserisci tempo di vita (TTL) della risposta bloccata (secondi)",
"upstream_timeout": "Timeout upstream",
"upstream_timeout_desc": "Specifica il numero di secondi da attendere per una risposta dal server upstream",
"form_enter_upstream_timeout": "Inserisci la durata del timeout del server upstream in secondi",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS su HTTPS", "dns_over_https": "DNS su HTTPS",
"dns_over_tls": "DNS su TLS", "dns_over_tls": "DNS su TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Disattiva risoluzione indirizzi IPv6", "disable_ipv6": "Disattiva risoluzione indirizzi IPv6",
"disable_ipv6_desc": "Eliminare tutte le query DNS per gli indirizzi IPv6 (tipo AAAA) e rimuovere i suggerimenti IPv6 dalle risposte HTTPS.", "disable_ipv6_desc": "Eliminare tutte le query DNS per gli indirizzi IPv6 (tipo AAAA) e rimuovere i suggerimenti IPv6 dalle risposte HTTPS.",
"fastest_addr": "Indirizzo IP più veloce", "fastest_addr": "Indirizzo IP più veloce",
"fastest_addr_desc": "Interroga tutti i server DNS e restituisci l'indirizzo IP più veloce tra tutte le risposte. Ciò rallenterà le richieste DNS poiché AdGuard Home dovrà attendere le risposte da tutti i server DNS, ma ciò migliorerà complessivamente la connettività.", "fastest_addr_desc": "Attendi le risposte da <b>tutti i</b> server DNS, misura la velocità di connessione TCP per ogni server e restituisci l'indirizzo IP del server con la velocità di connessione più elevata.<br/>Questa modalità può rallentare notevolmente le query DNS, se uno o più server upstream non rispondono. Assicurati che i tuoi server upstream siano stabili e che il timeout upstream sia basso.",
"autofix_warning_text": "Se fai clic su \"Correggi\", AdGuardHome configurerà il tuo sistema per utilizzare il server DNS AdGuardHome.", "autofix_warning_text": "Se fai clic su \"Correggi\", AdGuardHome configurerà il tuo sistema per utilizzare il server DNS AdGuardHome.",
"autofix_warning_list": "Eseguirà queste attività: <0> Disattiva DNSStubListener di sistema </0> <0> Imposta l'indirizzo del server DNS su 127.0.0.1 </0> <0> Sostituisci la destinazione del collegamento simbolico di /etc/resolv.conf su / run / systemd /resolve/resolv.conf </0> <0> Arresta DNSStubListener (ricarica il servizio systemd-resolved) </0>", "autofix_warning_list": "Eseguirà queste attività: <0> Disattiva DNSStubListener di sistema </0> <0> Imposta l'indirizzo del server DNS su 127.0.0.1 </0> <0> Sostituisci la destinazione del collegamento simbolico di /etc/resolv.conf su / run / systemd /resolve/resolv.conf </0> <0> Arresta DNSStubListener (ricarica il servizio systemd-resolved) </0>",
"autofix_warning_result": "Di conseguenza, tutte le richieste DNS dal sistema verranno elaborate da AdGuardHome per impostazione predefinita.", "autofix_warning_result": "Di conseguenza, tutte le richieste DNS dal sistema verranno elaborate da AdGuardHome per impostazione predefinita.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "並列リクエストを使用する(同時にすべてのアップストリームサーバーに処理要求することで解決スピードが向上)", "upstream_parallel": "並列リクエストを使用する(同時にすべてのアップストリームサーバーに処理要求することで解決スピードが向上)",
"parallel_requests": "並列リクエスト", "parallel_requests": "並列リクエスト",
"load_balancing": "ロードバランシング", "load_balancing": "ロードバランシング",
"load_balancing_desc": "一度に1つのアップストリームサーバーをクエリします。AdGuard Home は、重み付き乱択アルゴリズムを使用して、ルックアップに失敗した回数が最も少なく、平均ルックアップ時間が最も短いサーバーを選択します。", "load_balancing_desc": "一度に1つのアップストリームサーバーをクエリします。<br/>AdGuard Home は、重み付き乱択アルゴリズムを使用して、ルックアップに失敗した回数が最も少なく、平均ルックアップ時間が最も短いサーバーを選択します。",
"bootstrap_dns": "ブートストラップDNSサーバ", "bootstrap_dns": "ブートストラップDNSサーバ",
"bootstrap_dns_desc": "アップストリームとして指定したDoH/DoTリゾルバのIPアドレスを解決するために使用されるDNSサーバーのIPアドレスです。コメントは許可されていません", "bootstrap_dns_desc": "アップストリームとして指定したDoH/DoTリゾルバのIPアドレスを解決するために使用されるDNSサーバーのIPアドレスです。コメントは許可されていません",
"fallback_dns_title": "フォールバックDNSサーバー", "fallback_dns_title": "フォールバックDNSサーバー",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Blocked Response TTLブロック済み応答のTTL", "blocked_response_ttl": "Blocked Response TTLブロック済み応答のTTL",
"blocked_response_ttl_desc": "フィルタリングされた応答をクライアントがキャッシュしておく時間(秒)を指定します。", "blocked_response_ttl_desc": "フィルタリングされた応答をクライアントがキャッシュしておく時間(秒)を指定します。",
"form_enter_blocked_response_ttl": "ブロック済み応答のTTL秒単位を入力してください", "form_enter_blocked_response_ttl": "ブロック済み応答のTTL秒単位を入力してください",
"upstream_timeout": "Upstream timeoutアップストリームタイムアウト",
"upstream_timeout_desc": "アップストリームサーバーからの応答を待つ秒数を指定します。",
"form_enter_upstream_timeout": "アップストリームサーバーのタイムアウト時間を秒単位で入力します。",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "IPv6アドレスの解決を無効にする", "disable_ipv6": "IPv6アドレスの解決を無効にする",
"disable_ipv6_desc": "IPv6アドレスタイプAAAAに対するDNSクエリをすべて破棄し、HTTPS応答から IPv6 hint を削除します。", "disable_ipv6_desc": "IPv6アドレスタイプAAAAに対するDNSクエリをすべて破棄し、HTTPS応答から IPv6 hint を削除します。",
"fastest_addr": "最速のIPアドレス", "fastest_addr": "最速のIPアドレス",
"fastest_addr_desc": "すべてのDNSサーバーに処理要求し、全応答の中で最速のIPアドレスを返します。これにより、AdGuard HomeがすべてのDNSサーバーからの応答を待つ必要があるため、DNSクエリが遅くなりますが、全体的な接続性は向上します。", "fastest_addr_desc": "<b>すべての</b>DNSサーバーからの応答を待ち、各サーバーのTCP接続速度を測定し、最も接続速度の速いサーバーのIPアドレスを返します。<br/>※このモードでは、1つまたは複数のアップストリームサーバーが応答しない場合、DNSクエリが大幅に遅くなることがあります。アップストリームサーバーが安定していることを確認し、アップストリームタイムアウトは小さくしておいてください。",
"autofix_warning_text": "「修正」をクリックすると、AdGuardHomeはAdGuardHome DNSサーバを使用するようにシステムを構成します。", "autofix_warning_text": "「修正」をクリックすると、AdGuardHomeはAdGuardHome DNSサーバを使用するようにシステムを構成します。",
"autofix_warning_list": "次のタスクを実行します:<0>システムDNSStubListenerを非アクティブ化します</0> <0>DNSサーバのアドレスを127.0.0.1に設定します</0> <0>/etc/resolv.confのシンボリックリンクの対象を/run/systemd/resolve/resolv.confに置換します</0> <0>DNSStubListenerを停止しますsystemd-resolvedサービスをリロードします</0>", "autofix_warning_list": "次のタスクを実行します:<0>システムDNSStubListenerを非アクティブ化します</0> <0>DNSサーバのアドレスを127.0.0.1に設定します</0> <0>/etc/resolv.confのシンボリックリンクの対象を/run/systemd/resolve/resolv.confに置換します</0> <0>DNSStubListenerを停止しますsystemd-resolvedサービスをリロードします</0>",
"autofix_warning_result": "その結果、システムからのすべてのDNSリクエストは、デフォルトでAdGuard Homeによって処理されます。", "autofix_warning_result": "その結果、システムからのすべてのDNSリクエストは、デフォルトでAdGuard Homeによって処理されます。",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "쿼리 처리 속도를 높이려면 모든 업스트림 서버에서 동시에 병렬 쿼리를 사용해주세요.", "upstream_parallel": "쿼리 처리 속도를 높이려면 모든 업스트림 서버에서 동시에 병렬 쿼리를 사용해주세요.",
"parallel_requests": "병렬 처리 요청", "parallel_requests": "병렬 처리 요청",
"load_balancing": "로드 밸런싱", "load_balancing": "로드 밸런싱",
"load_balancing_desc": "한 번에 하나의 업스트림 서버를 쿼리합니다. AdGuard Home은 가중 무작위 알고리즘을 사용하여 조회 실패 횟수가 가장 적고 평균 조회 시간이 가장 짧은 서버를 선택합니다.", "load_balancing_desc": "한 번에 하나의 업스트림 서버를 쿼리합니다.<br/>AdGuard Home은 가중 무작위 알고리즘을 사용하여 조회 실패 횟수가 가장 적고 평균 조회 시간이 가장 짧은 서버를 선택합니다.",
"bootstrap_dns": "부트스트랩 DNS 서버", "bootstrap_dns": "부트스트랩 DNS 서버",
"bootstrap_dns_desc": "업스트림으로 지정한 DoH/DoT 리졸버의 IP 주소를 확인하는 데 사용되는 DNS 서버의 IP 주소입니다. 주석은 허용되지 않습니다.", "bootstrap_dns_desc": "업스트림으로 지정한 DoH/DoT 리졸버의 IP 주소를 확인하는 데 사용되는 DNS 서버의 IP 주소입니다. 주석은 허용되지 않습니다.",
"fallback_dns_title": "폴백 DNS 서버", "fallback_dns_title": "폴백 DNS 서버",
@ -294,6 +294,9 @@
"blocked_response_ttl": "차단된 TTL 응답", "blocked_response_ttl": "차단된 TTL 응답",
"blocked_response_ttl_desc": "클라이언트가 필터링된 응답을 캐시해야 하는 시간(초)을 지정합니다.", "blocked_response_ttl_desc": "클라이언트가 필터링된 응답을 캐시해야 하는 시간(초)을 지정합니다.",
"form_enter_blocked_response_ttl": "차단된 응답 TTL(초)을 입력하세요.", "form_enter_blocked_response_ttl": "차단된 응답 TTL(초)을 입력하세요.",
"upstream_timeout": "업스트림 제한 시간",
"upstream_timeout_desc": "업스트림 서버의 응답을 기다리는 시간(초)을 지정합니다.",
"form_enter_upstream_timeout": "업스트림 서버 응답 제한 시간을 초 단위로 입력하세요.",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "IPv6 주소 확인 비활성화", "disable_ipv6": "IPv6 주소 확인 비활성화",
"disable_ipv6_desc": "IPv6 주소(AAAA 유형)에 대한 모든 DNS 쿼리를 무시하고 HTTPS 유형 응답에서 IPv6 데이터를 제거합니다.", "disable_ipv6_desc": "IPv6 주소(AAAA 유형)에 대한 모든 DNS 쿼리를 무시하고 HTTPS 유형 응답에서 IPv6 데이터를 제거합니다.",
"fastest_addr": "가장 빠른 IP 주소", "fastest_addr": "가장 빠른 IP 주소",
"fastest_addr_desc": "모든 DNS 서버에 쿼리를 수행한 다음 반응이 가장 빠른 IP주소를 반송합니다. AdGuard Home이 모든 DNS 서버의 응답을 기다려야 하기 때문에 DNS 쿼리 속도가 느려지지만 전반적인 연결이 향상됩니다.", "fastest_addr_desc": "<b>모든</b> DNS 서버의 응답을 기다렸다가 각 서버의 TCP 연결 속도를 측정하여 연결 속도가 가장 빠른 서버의 IP 주소를 반환합니다.<br/>이 모드는 하나 이상의 업스트림 서버가 응답하지 않는 경우, DNS 쿼리 속도가 상당히 느려질 수 있습니다. 업스트림 서버가 안정적이고 업스트림 타임아웃이 짧은지 확인하세요.",
"autofix_warning_text": "'수정'을 클릭하면 AdGuard Home이 AdGuard Home DNS 서버를 사용하도록 시스템을 설정합니다.", "autofix_warning_text": "'수정'을 클릭하면 AdGuard Home이 AdGuard Home DNS 서버를 사용하도록 시스템을 설정합니다.",
"autofix_warning_list": "다음 작업을 진행합니다: <0>DNSStubListener 시스템 비활성화</0> <0>DNS 서버 주소를 127.0.0.1로 설정</0> <0>/etc/resolv.conf의 심볼릭 링크 타겟을 /run/systemd/resolve/resolv.conf로 변경</0> <0>DNSStubListener 중지 (systemd-resolved 서비스 새로고침)</0>", "autofix_warning_list": "다음 작업을 진행합니다: <0>DNSStubListener 시스템 비활성화</0> <0>DNS 서버 주소를 127.0.0.1로 설정</0> <0>/etc/resolv.conf의 심볼릭 링크 타겟을 /run/systemd/resolve/resolv.conf로 변경</0> <0>DNSStubListener 중지 (systemd-resolved 서비스 새로고침)</0>",
"autofix_warning_result": "결과적으로 시스템의 모든 DNS 요청은 기본적으로 AdGuard Home에 의해 처리됩니다.", "autofix_warning_result": "결과적으로 시스템의 모든 DNS 요청은 기본적으로 AdGuard Home에 의해 처리됩니다.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Parallelle verzoeken gebruiken om te versnellen door gelijktijdig verzoeken te sturen naar alle upstream servers.", "upstream_parallel": "Parallelle verzoeken gebruiken om te versnellen door gelijktijdig verzoeken te sturen naar alle upstream servers.",
"parallel_requests": "Parallelle verzoeken", "parallel_requests": "Parallelle verzoeken",
"load_balancing": "Volume balanceren", "load_balancing": "Volume balanceren",
"load_balancing_desc": "Voer zoekopdrachten uit op één upstream-server tegelijk. AdGuard Home gebruikt een gewogen willekeurig algoritme om servers te selecteren met het laagste aantal mislukte zoekopdrachten en de laagste gemiddelde opzoektijd.", "load_balancing_desc": "Voer zoekopdrachten uit op één upstream-server tegelijk.<br/>AdGuard Home gebruikt een gewogen willekeurig algoritme om servers te selecteren met het laagste aantal mislukte zoekopdrachten en de laagste gemiddelde opzoektijd.",
"bootstrap_dns": "Bootstrap DNS-servers", "bootstrap_dns": "Bootstrap DNS-servers",
"bootstrap_dns_desc": "IP-adressen van DNS-servers die worden gebruikt om IP-adressen om te zetten van de DoH/DoT-resolvers die je opgeeft als upstreams. Opmerkingen zijn niet toegestaan.", "bootstrap_dns_desc": "IP-adressen van DNS-servers die worden gebruikt om IP-adressen om te zetten van de DoH/DoT-resolvers die je opgeeft als upstreams. Opmerkingen zijn niet toegestaan.",
"fallback_dns_title": "Back-up DNS-servers", "fallback_dns_title": "Back-up DNS-servers",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Geblokkeerde reactie TTL", "blocked_response_ttl": "Geblokkeerde reactie TTL",
"blocked_response_ttl_desc": "Hiermee geef je op hoeveel seconden de clients een gefilterd antwoord in de cache moeten opslaan", "blocked_response_ttl_desc": "Hiermee geef je op hoeveel seconden de clients een gefilterd antwoord in de cache moeten opslaan",
"form_enter_blocked_response_ttl": "Voer geblokkeerd antwoord TTL in (seconden)", "form_enter_blocked_response_ttl": "Voer geblokkeerd antwoord TTL in (seconden)",
"upstream_timeout": "Upstream time-out",
"upstream_timeout_desc": "Geeft het aantal seconden aan dat moet worden gewacht op een reactie van de upstream-server",
"form_enter_upstream_timeout": "Voer de time-outduur van de upstream-server in seconden in",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-via-HTTPS", "dns_over_https": "DNS-via-HTTPS",
"dns_over_tls": "DNS-via-TLS", "dns_over_tls": "DNS-via-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Oplossen IPv6-adressen uitschakelen", "disable_ipv6": "Oplossen IPv6-adressen uitschakelen",
"disable_ipv6_desc": "Alle DNS-query's voor IPv6-adressen (type AAAA) verwijderen en IPv6-hints uit HTTPS-antwoorden verwijderen.", "disable_ipv6_desc": "Alle DNS-query's voor IPv6-adressen (type AAAA) verwijderen en IPv6-hints uit HTTPS-antwoorden verwijderen.",
"fastest_addr": "Snelste IP adres", "fastest_addr": "Snelste IP adres",
"fastest_addr_desc": "Alle DNS-servers bevragen en het snelste IP adres terugkoppelen. Dit zal de DNS verzoeken vertragen omdat AdGuard Home moet wachten op de antwoorden van alles DNS-servers, maar verbetert wel de connectiviteit.", "fastest_addr_desc": "Wacht op reacties van <b>alle</b> DNS-servers, meet de TCP-verbindingssnelheid voor elke server en retourneer het IP-adres van de server met de hoogste verbindingssnelheid.<br/>Deze modus kan DNS-query's aanzienlijk vertragen als een of meer upstream-servers niet reageren. Zorg ervoor dat je upstream-servers stabiel zijn en dat je upstream-time-out laag is.",
"autofix_warning_text": "Als je op \"Repareren\" klikt, configureert AdGuard Home jouw systeem om de AdGuard Home DNS-server te gebruiken.", "autofix_warning_text": "Als je op \"Repareren\" klikt, configureert AdGuard Home jouw systeem om de AdGuard Home DNS-server te gebruiken.",
"autofix_warning_list": "De volgende taken worden uitgevoerd: <0> Deactiveren van Systeem DNSStubListener</0> <0> DNS-serveradres instellen op 127.0.0.1 </0> <0> Symbolisch koppelingsdoel van /etc/resolv.conf vervangen door /run/systemd/resolve/resolv.conf </0> <0> Stop DNSStubListener (herlaad systemd-resolved service) </0>", "autofix_warning_list": "De volgende taken worden uitgevoerd: <0> Deactiveren van Systeem DNSStubListener</0> <0> DNS-serveradres instellen op 127.0.0.1 </0> <0> Symbolisch koppelingsdoel van /etc/resolv.conf vervangen door /run/systemd/resolve/resolv.conf </0> <0> Stop DNSStubListener (herlaad systemd-resolved service) </0>",
"autofix_warning_result": "Als gevolg hiervan worden alle DNS-aanvragen van je systeem standaard door AdGuard Home verwerkt.", "autofix_warning_result": "Als gevolg hiervan worden alle DNS-aanvragen van je systeem standaard door AdGuard Home verwerkt.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Usar consultas paralelas para acelerar a resolução consultando simultaneamente todos os servidores DNS primário", "upstream_parallel": "Usar consultas paralelas para acelerar a resolução consultando simultaneamente todos os servidores DNS primário",
"parallel_requests": "Solicitações paralelas", "parallel_requests": "Solicitações paralelas",
"load_balancing": "Balanceamento de carga", "load_balancing": "Balanceamento de carga",
"load_balancing_desc": "Consulte um servidor upstream por vez. O AdGuard Home usa um algoritmo aleatório ponderado para selecionar servidores com o menor número de falhas e o menor tempo médio de consulta.", "load_balancing_desc": "Consulte um servidor upstream por vez.<br/>O AdGuard Home usa um algoritmo aleatório ponderado para selecionar servidores com o menor número de falhas e o menor tempo médio de consulta.",
"bootstrap_dns": "Servidores DNS de inicialização", "bootstrap_dns": "Servidores DNS de inicialização",
"bootstrap_dns_desc": "Endereços IP de servidores DNS usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams. Comentários não são permitidos.", "bootstrap_dns_desc": "Endereços IP de servidores DNS usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams. Comentários não são permitidos.",
"fallback_dns_title": "Servidores DNS Fallback", "fallback_dns_title": "Servidores DNS Fallback",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Resposta bloqueada TTL", "blocked_response_ttl": "Resposta bloqueada TTL",
"blocked_response_ttl_desc": "Especifica por quantos segundos os clientes devem armazenar em cache uma resposta filtrada", "blocked_response_ttl_desc": "Especifica por quantos segundos os clientes devem armazenar em cache uma resposta filtrada",
"form_enter_blocked_response_ttl": "Insira o TTL da resposta bloqueada (segundos)", "form_enter_blocked_response_ttl": "Insira o TTL da resposta bloqueada (segundos)",
"upstream_timeout": "Tempo limite de upstream",
"upstream_timeout_desc": "Especifica o número de segundos para esperar por uma resposta do servidor upstream",
"form_enter_upstream_timeout": "Insira a duração do tempo limite do servidor upstream em segundos",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-sobre-HTTPS", "dns_over_https": "DNS-sobre-HTTPS",
"dns_over_tls": "DNS-sobre-TLS", "dns_over_tls": "DNS-sobre-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Desativar resolução de endereços IPv6", "disable_ipv6": "Desativar resolução de endereços IPv6",
"disable_ipv6_desc": "Descarta todas as consultas DNS para endereços IPv6 (tipo AAAA) e remove dicas de IPv6 das respostas HTTPS.", "disable_ipv6_desc": "Descarta todas as consultas DNS para endereços IPv6 (tipo AAAA) e remove dicas de IPv6 das respostas HTTPS.",
"fastest_addr": "Endereço de IP mais rápido", "fastest_addr": "Endereço de IP mais rápido",
"fastest_addr_desc": "Consulta todos os servidores DNS e retorna o endereço IP mais rápido entre todas as respostas. Isso torna as consultas DNS mais lentas, pois o AdGuard Home tem que esperar pelas respostas de todos os servidores DNS, mas melhora a conectividade geral.", "fastest_addr_desc": "Aguarde as respostas de <b>todos</b> os servidores DNS, meça a velocidade da conexão TCP para cada servidor e retorne o endereço de IP do servidor com a velocidade de conexão mais rápida.<br/>Esse modo pode retardar significativamente as consultas de DNS, se um ou mais servidores DNS primários não estiverem respondendo. Certifique-se de que seus servidores DNS primários sejam estáveis e que seu tempo de espera para DNS seja baixo.",
"autofix_warning_text": "Se clicar em \"Corrigir\", o AdGuardHome irá configurar o seu sistema para utilizar o servidor DNS do AdGuardHome.", "autofix_warning_text": "Se clicar em \"Corrigir\", o AdGuardHome irá configurar o seu sistema para utilizar o servidor DNS do AdGuardHome.",
"autofix_warning_list": "Ele irá realizar estas tarefas: <0>Desativar sistema DNSStubListener</0> <0>Definir endereço do servidor DNS para 127.0.0.1</0> <0>Substituir o alvo simbólico do link /etc/resolv.conf para /run/systemd/resolv.conf</0> <0>Parar DNSStubListener (recarregar serviço resolvido pelo sistema)</0>", "autofix_warning_list": "Ele irá realizar estas tarefas: <0>Desativar sistema DNSStubListener</0> <0>Definir endereço do servidor DNS para 127.0.0.1</0> <0>Substituir o alvo simbólico do link /etc/resolv.conf para /run/systemd/resolv.conf</0> <0>Parar DNSStubListener (recarregar serviço resolvido pelo sistema)</0>",
"autofix_warning_result": "Como resultado, todos as solicitações DNS do seu sistema serão processadas pelo AdGuard Home por padrão.", "autofix_warning_result": "Como resultado, todos as solicitações DNS do seu sistema serão processadas pelo AdGuard Home por padrão.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Usar consultas paralelas para acelerar a resolução consultando simultaneamente todos os servidores DNS", "upstream_parallel": "Usar consultas paralelas para acelerar a resolução consultando simultaneamente todos os servidores DNS",
"parallel_requests": "Solicitações paralelas", "parallel_requests": "Solicitações paralelas",
"load_balancing": "Balanceamento de carga", "load_balancing": "Balanceamento de carga",
"load_balancing_desc": "Consulta um servidor a montante de cada vez. O AdGuard Home usa um algoritmo aleatório ponderado para selecionar servidores com o menor número de pesquisas com falha e o menor tempo médio de pesquisa.", "load_balancing_desc": "Consulta um servidor upstream de cada vez. <br/>O AdGuard Home usa um algoritmo aleatório ponderado para selecionar servidores com o menor número de pesquisas falhadas e o menor tempo médio de pesquisa.",
"bootstrap_dns": "Servidores DNS de arranque", "bootstrap_dns": "Servidores DNS de arranque",
"bootstrap_dns_desc": "Endereços IP de servidores DNS usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams. Comentários não são permitidos.", "bootstrap_dns_desc": "Endereços IP de servidores DNS usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams. Comentários não são permitidos.",
"fallback_dns_title": "Servidores DNS de fallback", "fallback_dns_title": "Servidores DNS de fallback",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Resposta bloqueada TTL", "blocked_response_ttl": "Resposta bloqueada TTL",
"blocked_response_ttl_desc": "Especifica por quantos segundos os clientes devem armazenar em cache uma resposta filtrada", "blocked_response_ttl_desc": "Especifica por quantos segundos os clientes devem armazenar em cache uma resposta filtrada",
"form_enter_blocked_response_ttl": "Insira o TTL da resposta bloqueada (segundos)", "form_enter_blocked_response_ttl": "Insira o TTL da resposta bloqueada (segundos)",
"upstream_timeout": "Tempo esgotado de upstream",
"upstream_timeout_desc": "Especifica o número de segundos a aguardar por uma resposta do servidor upstream",
"form_enter_upstream_timeout": "Insira a duração do tempo esgotado do servidor upstream em segundos",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-sobre-HTTPS", "dns_over_https": "DNS-sobre-HTTPS",
"dns_over_tls": "DNS-sobre-TLS", "dns_over_tls": "DNS-sobre-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Desativar resolução de endereços IPv6", "disable_ipv6": "Desativar resolução de endereços IPv6",
"disable_ipv6_desc": "Descarte todas as consultas DNS para endereços IPv6 (tipo AAAA) e remova as dicas IPv6 das respostas HTTPS.", "disable_ipv6_desc": "Descarte todas as consultas DNS para endereços IPv6 (tipo AAAA) e remova as dicas IPv6 das respostas HTTPS.",
"fastest_addr": "Endereço de IP mais rápido", "fastest_addr": "Endereço de IP mais rápido",
"fastest_addr_desc": "Consulta todos os servidores DNS e retorna o endereço IP mais rápido entre todas as respostas. Isso torna as consultas DNS mais lentas, pois o AdGuard Home tem que esperar pelas respostas de todos os servidores DNS, mas melhora a conectividade geral.", "fastest_addr_desc": "Aguarda por respostas de <b>todos</b> os servidores DNS, mede a velocidade da ligação TCP para cada servidor e devolva o endereço IP do servidor com a velocidade de ligação mais rápida.<br/>Este modo pode abrandar significativamente as consultas DNS, se um ou mais servidores upstream não estiverem a responder. Certifique-se de que os seus servidores upstream são estáveis e que o tempo esgotado de upstream é baixo.",
"autofix_warning_text": "Se clicar em \"Corrigir\", o AdGuardHome irá configurar o seu sistema para utilizar o servidor DNS do AdGuardHome.", "autofix_warning_text": "Se clicar em \"Corrigir\", o AdGuardHome irá configurar o seu sistema para utilizar o servidor DNS do AdGuardHome.",
"autofix_warning_list": "Irá realizar estas tarefas: <0>Desativar sistema DNSStubListener</0> <0>Definir endereço do servidor DNS para 127.0.0.1</0> <0>Substituir o alvo simbólico do link /etc/resolv.conf para /run/systemd/resolv.conf</0> <0>Parar DNSStubListener (recarregar serviço resolvido pelo sistema)</0>", "autofix_warning_list": "Irá realizar estas tarefas: <0>Desativar sistema DNSStubListener</0> <0>Definir endereço do servidor DNS para 127.0.0.1</0> <0>Substituir o alvo simbólico do link /etc/resolv.conf para /run/systemd/resolv.conf</0> <0>Parar DNSStubListener (recarregar serviço resolvido pelo sistema)</0>",
"autofix_warning_result": "Como resultado, todos as solicitações DNS do seu sistema serão processadas pelo AdGuard Home por predefinição.", "autofix_warning_result": "Como resultado, todos as solicitações DNS do seu sistema serão processadas pelo AdGuard Home por predefinição.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Использовать параллельные запросы ко всем серверам одновременно для ускорения обработки запроса.", "upstream_parallel": "Использовать параллельные запросы ко всем серверам одновременно для ускорения обработки запроса.",
"parallel_requests": "Параллельные запросы", "parallel_requests": "Параллельные запросы",
"load_balancing": "Распределение нагрузки\n", "load_balancing": "Распределение нагрузки\n",
"load_balancing_desc": "Запрашивайте по одному серверу за раз. AdGuard Home использует алгоритм случайной выборки с учётом веса для выбора серверов с наименьшим количеством неудачных запросов и наименьшим средним временем выполнения запроса.", "load_balancing_desc": "Запрашивать по одному upstream-серверу.<br/>AdGuard Home использует алгоритм случайной выборки с учётом веса для выбора серверов с наименьшим количеством неудачных запросов и наименьшим средним временем выполнения запроса.",
"bootstrap_dns": "Bootstrap DNS-серверы", "bootstrap_dns": "Bootstrap DNS-серверы",
"bootstrap_dns_desc": "IP-адреса DNS-серверов, используемых для поиска IP-адресов DoH/DoT upstream-серверов, которые вы указали. Комментарии не допускаются.", "bootstrap_dns_desc": "IP-адреса DNS-серверов, используемых для поиска IP-адресов DoH/DoT upstream-серверов, которые вы указали. Комментарии не допускаются.",
"fallback_dns_title": "Резервные DNS-серверы", "fallback_dns_title": "Резервные DNS-серверы",
@ -294,6 +294,9 @@
"blocked_response_ttl": "TTL заблокированного ответа", "blocked_response_ttl": "TTL заблокированного ответа",
"blocked_response_ttl_desc": "Указывает, в течение скольких секунд клиенты должны кешировать отфильтрованный ответ", "blocked_response_ttl_desc": "Указывает, в течение скольких секунд клиенты должны кешировать отфильтрованный ответ",
"form_enter_blocked_response_ttl": "Введите TTL заблокированного ответа (в секундах)", "form_enter_blocked_response_ttl": "Введите TTL заблокированного ответа (в секундах)",
"upstream_timeout": "Время ожидания ответов от upstream-серверов",
"upstream_timeout_desc": "Длительность ожидания ответа от upstream-серверов в секундах",
"form_enter_upstream_timeout": "Введите время ожидания для upstream-сервера в секундах",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Отключить обработку IPv6-адресов", "disable_ipv6": "Отключить обработку IPv6-адресов",
"disable_ipv6_desc": "Игнорировать все DNS-запросы адресов IPv6 (тип AAAA) и удалять IPv6-данные из ответов типа HTTPS.", "disable_ipv6_desc": "Игнорировать все DNS-запросы адресов IPv6 (тип AAAA) и удалять IPv6-данные из ответов типа HTTPS.",
"fastest_addr": "Самый быстрый IP-адрес", "fastest_addr": "Самый быстрый IP-адрес",
"fastest_addr_desc": "Опросить все DNS-серверы и вернуть самый быстрый IP-адрес из полученных ответов. Это замедлит DNS-запросы, так как нужно будет дождаться ответов со всех DNS-серверов, но улучшит соединение.", "fastest_addr_desc": "Дождаться ответов от <b>всех</b> DNS-серверов, измерить скорость TCP-соединения для каждого сервера и вернуть IP-адрес сервера с самой высокой скоростью соединения.<br/>Этот режим может значительно замедлить выполнение DNS-запросов, если один или несколько серверов не отвечают. Убедитесь, что ваши серверы работают стабильно, а время ожидания серверов мало.",
"autofix_warning_text": "При нажатии «Исправить» AdGuard Home настроит вашу систему на использование DNS-сервера AdGuard Home.", "autofix_warning_text": "При нажатии «Исправить» AdGuard Home настроит вашу систему на использование DNS-сервера AdGuard Home.",
"autofix_warning_list": "Будут выполняться следующие задачи: <0>Деактивировать системный DNSStubListener</0> <0>Установить адрес сервера DNS на 127.0.0.1</0> <0>Создать символическую ссылку /etc/resolv.conf на /run/systemd/resolve/resolv.conf</0> <0>Остановить DNSStubListener (перезагрузить системную службу)</0>.", "autofix_warning_list": "Будут выполняться следующие задачи: <0>Деактивировать системный DNSStubListener</0> <0>Установить адрес сервера DNS на 127.0.0.1</0> <0>Создать символическую ссылку /etc/resolv.conf на /run/systemd/resolve/resolv.conf</0> <0>Остановить DNSStubListener (перезагрузить системную службу)</0>.",
"autofix_warning_result": "В результате все DNS-запросы от вашей системы будут по умолчанию обрабатываться AdGuard Home.\n", "autofix_warning_result": "В результате все DNS-запросы от вашей системы будут по умолчанию обрабатываться AdGuard Home.\n",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "Používať paralelné dopyty na zrýchlenie súčasným dopytovaním všetkých upstream serverov súčasne.", "upstream_parallel": "Používať paralelné dopyty na zrýchlenie súčasným dopytovaním všetkých upstream serverov súčasne.",
"parallel_requests": "Paralelné dopyty", "parallel_requests": "Paralelné dopyty",
"load_balancing": "Vyrovnávanie záťaže", "load_balancing": "Vyrovnávanie záťaže",
"load_balancing_desc": "Dopytuje sa súčasne len jeden upstream server. AdGuard Home používa vážený náhodný algoritmus na výber serverov s najnižším počtom neúspešných vyhľadávaní a najnižším priemerným časom vyhľadávania.", "load_balancing_desc": "Dopytuje sa súčasne len jeden upstream server.<br/>AdGuard Home používa vážený náhodný algoritmus na výber serverov s najnižším počtom neúspešných vyhľadávaní a najnižším priemerným časom vyhľadávania.",
"bootstrap_dns": "Bootstrap DNS servery", "bootstrap_dns": "Bootstrap DNS servery",
"bootstrap_dns_desc": "IP adresy serverov DNS používaných na rozlíšenie IP adries prekladačov DoH/DoT, ktoré zadáte ako upstream. Komentáre nie sú povolené.", "bootstrap_dns_desc": "IP adresy serverov DNS používaných na rozlíšenie IP adries prekladačov DoH/DoT, ktoré zadáte ako upstream. Komentáre nie sú povolené.",
"fallback_dns_title": "Záložné servery DNS", "fallback_dns_title": "Záložné servery DNS",
@ -294,6 +294,9 @@
"blocked_response_ttl": "Blokovaná odozva TTL", "blocked_response_ttl": "Blokovaná odozva TTL",
"blocked_response_ttl_desc": "Určuje, na koľko sekúnd by mali klienti uložiť filtrovanú odozvu do vyrovnávacej pamäte", "blocked_response_ttl_desc": "Určuje, na koľko sekúnd by mali klienti uložiť filtrovanú odozvu do vyrovnávacej pamäte",
"form_enter_blocked_response_ttl": "Zadajte TTL blokovanej odozve (sekundy)", "form_enter_blocked_response_ttl": "Zadajte TTL blokovanej odozve (sekundy)",
"upstream_timeout": "Časový limit pre upstream",
"upstream_timeout_desc": "Určuje počet sekúnd čakania na odpoveď z upstream servera",
"form_enter_upstream_timeout": "Zadajte trvanie časového limitu upstream servera v sekundách",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "Vypnúť rozlišovanie IPv6 adries", "disable_ipv6": "Vypnúť rozlišovanie IPv6 adries",
"disable_ipv6_desc": "Ignorovať všetky dotazy DNS na adresy IPv6 (typ AAAA) a odstrániť IPv6 údaje z HTTPS odpovedí.", "disable_ipv6_desc": "Ignorovať všetky dotazy DNS na adresy IPv6 (typ AAAA) a odstrániť IPv6 údaje z HTTPS odpovedí.",
"fastest_addr": "Najrýchlejšia IP adresa", "fastest_addr": "Najrýchlejšia IP adresa",
"fastest_addr_desc": "Dopytovať všetky servery DNS a vrátiť najrýchlejšiu IP adresu zo všetkých odpovedí. Toto spomalí DNS dopyty, pretože AdGuard Home musí čakať na odpovede zo všetkých serverov DNS, ale zlepší sa celkové pripojenie.", "fastest_addr_desc": "Čaká na odpovede od <b>všetkých</b> DNS serverov, zmeria rýchlosť pripojenia TCP pre každý server a vráti adresu IP servera s najväčšou rýchlosťou pripojenia.<br/>Tento režim môže výrazne spomaliť DNS dopyty, ak jeden alebo viac upstream serverov neodpovedá. Uistite sa, že Vaše upstream servery sú stabilné a upstream upstream je nízky.",
"autofix_warning_text": "Ak kliknete na „Opraviť“, AdGuardHome nakonfiguruje Váš systém tak, aby používal DNS server AdGuardHome.", "autofix_warning_text": "Ak kliknete na „Opraviť“, AdGuardHome nakonfiguruje Váš systém tak, aby používal DNS server AdGuardHome.",
"autofix_warning_list": "Bude vykonávať tieto úlohy: <0>Deaktivovať systém DNSStubListener</0> <0>Nastaviť adresu servera DNS na 127.0.0.1</0> <0>Nahradiť cieľový symbolický odkaz /etc/resolv.conf na /run/systemd/resolve/resolv.conf</0> <0>Zastaviť službu DNSStubListener (znova načítať službu systemd-resolved)</0>", "autofix_warning_list": "Bude vykonávať tieto úlohy: <0>Deaktivovať systém DNSStubListener</0> <0>Nastaviť adresu servera DNS na 127.0.0.1</0> <0>Nahradiť cieľový symbolický odkaz /etc/resolv.conf na /run/systemd/resolve/resolv.conf</0> <0>Zastaviť službu DNSStubListener (znova načítať službu systemd-resolved)</0>",
"autofix_warning_result": "Výsledkom bude, že všetky DNS dopyty z Vášho systému budú štandardne spracované službou AdGuard Home.", "autofix_warning_result": "Výsledkom bude, že všetky DNS dopyty z Vášho systému budú štandardne spracované službou AdGuard Home.",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "使用并行请求以同时查询所有上游服务器来加快解析速度。", "upstream_parallel": "使用并行请求以同时查询所有上游服务器来加快解析速度。",
"parallel_requests": "并行请求", "parallel_requests": "并行请求",
"load_balancing": "负载均衡", "load_balancing": "负载均衡",
"load_balancing_desc": "一次查询一台服务器。AdGuard Home 使用加权随机算法来选择具有最少失败查找和最低平均查找时间的服务器。", "load_balancing_desc": "一次查询一台上游服务器。<br/>AdGuard Home 使用加权随机算法来选择具有最少失败查找和最低平均查找时间的服务器。",
"bootstrap_dns": "Bootstrap DNS 服务器", "bootstrap_dns": "Bootstrap DNS 服务器",
"bootstrap_dns_desc": "DNS 服务器的 IP 地址,用于解析指定为上游的 DoH/DoT 解析器的 IP 地址。不允许添加注释。", "bootstrap_dns_desc": "DNS 服务器的 IP 地址,用于解析指定为上游的 DoH/DoT 解析器的 IP 地址。不允许添加注释。",
"fallback_dns_title": "后备 DNS 服务器", "fallback_dns_title": "后备 DNS 服务器",
@ -294,6 +294,9 @@
"blocked_response_ttl": "屏蔽的 TTL 应答", "blocked_response_ttl": "屏蔽的 TTL 应答",
"blocked_response_ttl_desc": "指定客户端应缓存已过滤响应的秒数", "blocked_response_ttl_desc": "指定客户端应缓存已过滤响应的秒数",
"form_enter_blocked_response_ttl": "输入拦截的 TTL 应答(秒)", "form_enter_blocked_response_ttl": "输入拦截的 TTL 应答(秒)",
"upstream_timeout": "上游超时",
"upstream_timeout_desc": "指定等待上游服务器响应的秒数",
"form_enter_upstream_timeout": "输入上游服务器超时时间(以秒为单位)",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -598,7 +601,7 @@
"disable_ipv6": "禁用 IPv6 地址的解析", "disable_ipv6": "禁用 IPv6 地址的解析",
"disable_ipv6_desc": "丢弃对 IPv6 地址(类型 AAAA的所有 DNS 查询,并从 HTTPS 响应中删除 IPv6 相关的信息。", "disable_ipv6_desc": "丢弃对 IPv6 地址(类型 AAAA的所有 DNS 查询,并从 HTTPS 响应中删除 IPv6 相关的信息。",
"fastest_addr": "最快的 IP 地址", "fastest_addr": "最快的 IP 地址",
"fastest_addr_desc": "查询所有 DNS 服务器并返回所有响应中速度最快的 IP 地址。因 AdGuard Home 必须等待全部 DNS 服务器响应,这会降低 DNS 查询的速度,但此举将会在总体上改善连接速度。", "fastest_addr_desc": "等待<b>所有</b> DNS 服务器的响应,测量每个服务器的 TCP 连接速度,并返回连接速度最快的服务器的 IP 地址。<br/>如果一个或多个上游服务器没有响应,此模式会显著减慢 DNS 查询速度。确保您的上游服务器稳定且上游超时时间短。",
"autofix_warning_text": "若您单击「修复」AdGuard Home 将会配置您的系统以使用 AdGuard Home 的 DNS 服务器。", "autofix_warning_text": "若您单击「修复」AdGuard Home 将会配置您的系统以使用 AdGuard Home 的 DNS 服务器。",
"autofix_warning_list": "其将会进行如下工作:<0>停用系统DNSStubListener</0><0>设置DNS服务器地址为127.0.0.1</0><0>将/etc/resolv.conf的符号链接目标替换为/run/systemd/resolv/resolv.conf</0><0>停止DNSStubListener重新加载系统解析服务</0>", "autofix_warning_list": "其将会进行如下工作:<0>停用系统DNSStubListener</0><0>设置DNS服务器地址为127.0.0.1</0><0>将/etc/resolv.conf的符号链接目标替换为/run/systemd/resolv/resolv.conf</0><0>停止DNSStubListener重新加载系统解析服务</0>",
"autofix_warning_result": "因此,默认情况下所有来自系统的 DNS 请求都将由 AdGuard Home 处理。", "autofix_warning_result": "因此,默认情况下所有来自系统的 DNS 请求都将由 AdGuard Home 处理。",

View File

@ -6,7 +6,7 @@
"upstream_parallel": "透過同時地查詢所有上游的伺服器,使用並行的查詢以加速解析。", "upstream_parallel": "透過同時地查詢所有上游的伺服器,使用並行的查詢以加速解析。",
"parallel_requests": "並行的請求", "parallel_requests": "並行的請求",
"load_balancing": "負載平衡", "load_balancing": "負載平衡",
"load_balancing_desc": "一次查詢一台伺服器。AdGuard Home 使用加權隨機演算法來選擇具有最少失敗查詢和最低平均查詢時間的伺服器。", "load_balancing_desc": "一次查詢一台上游伺服器。<br/>AdGuard Home 使用加權隨機演算法來選擇具有最少失敗查詢和最低平均查詢時間的伺服器。",
"bootstrap_dns": "自我啟動BootstrapDNS 伺服器", "bootstrap_dns": "自我啟動BootstrapDNS 伺服器",
"bootstrap_dns_desc": "DNS 伺服器的 IP 位址,用於解析您指定為上游伺服器的 DoH/DoT 解析器的 IP 位址。不允許註釋。", "bootstrap_dns_desc": "DNS 伺服器的 IP 位址,用於解析您指定為上游伺服器的 DoH/DoT 解析器的 IP 位址。不允許註釋。",
"fallback_dns_title": "應變 DNS 伺服器", "fallback_dns_title": "應變 DNS 伺服器",
@ -20,17 +20,17 @@
"resolve_clients_title": "啟用用戶端的 IP 位址之反向的解析", "resolve_clients_title": "啟用用戶端的 IP 位址之反向的解析",
"resolve_clients_desc": "透過傳送指標PTR查詢到對應的解析器私人 DNS 伺服器供區域的用戶端,上游的伺服器供有公共 IP 位址的用戶端),反向地解析用戶端的 IP 位址變為它們的主機名稱。", "resolve_clients_desc": "透過傳送指標PTR查詢到對應的解析器私人 DNS 伺服器供區域的用戶端,上游的伺服器供有公共 IP 位址的用戶端),反向地解析用戶端的 IP 位址變為它們的主機名稱。",
"use_private_ptr_resolvers_title": "使用私人反向的 DNS 解析器", "use_private_ptr_resolvers_title": "使用私人反向的 DNS 解析器",
"use_private_ptr_resolvers_desc": "通過私人上游伺服器、DHCP、/etc/hosts 等等,對包含私人 IP 位址的 ARPA 網域解析 PTR、SOA 和 NS 請求。如果被禁用AdGuard Home 將對所有此類的請求以 NXDOMAIN 回覆。", "use_private_ptr_resolvers_desc": "使用私人上游伺服器、DHCP、/etc/hosts 等方式解析包含私人 IP 位址的 ARPA 網域的 PTR、SOA 和 NS 請求。如果停用AdGuard Home 將對所有此類請求以 NXDOMAIN 回應。",
"check_dhcp_servers": "檢查動態主機設定協定DHCP伺服器", "check_dhcp_servers": "檢查動態主機設定協定DHCP伺服器",
"save_config": "儲存配置", "save_config": "儲存配置",
"enabled_dhcp": "動態主機設定協定DHCP伺服器被啟用", "enabled_dhcp": "動態主機設定協定DHCP伺服器被啟用",
"disabled_dhcp": "動態主機設定協定DHCP伺服器被禁用", "disabled_dhcp": "DHCP 伺服器已停用",
"unavailable_dhcp": "DHCP 為不可用的", "unavailable_dhcp": "DHCP 為不可用的",
"unavailable_dhcp_desc": "AdGuard Home 無法於您的作業系統上執行 DHCP 伺服器", "unavailable_dhcp_desc": "AdGuard Home 無法於您的作業系統上執行 DHCP 伺服器",
"dhcp_title": "動態主機設定協定DHCP伺服器實驗性的", "dhcp_title": "動態主機設定協定DHCP伺服器實驗性的",
"dhcp_description": "如果您的路由器未提供動態主機設定協定DHCP設定您可使用 AdGuard 自身內建的 DHCP 伺服器。", "dhcp_description": "如果您的路由器未提供動態主機設定協定DHCP設定您可使用 AdGuard 自身內建的 DHCP 伺服器。",
"dhcp_enable": "啟用動態主機設定協定DHCP伺服器", "dhcp_enable": "啟用動態主機設定協定DHCP伺服器",
"dhcp_disable": "禁用動態主機設定協定DHCP伺服器", "dhcp_disable": "停用 DHCP 伺服器",
"dhcp_not_found": "因為 AdGuard Home 於該網路上未發現任何現行的 DHCP 伺服器啟用內建的動態主機設定協定DHCP伺服器為安全的。然而您應手動地重新檢查那個因為自動的探查目前不予 100 保證。", "dhcp_not_found": "因為 AdGuard Home 於該網路上未發現任何現行的 DHCP 伺服器啟用內建的動態主機設定協定DHCP伺服器為安全的。然而您應手動地重新檢查那個因為自動的探查目前不予 100 保證。",
"dhcp_found": "於該網路上一個現行的動態主機設定協定DHCP伺服器被發現。啟用內建的 DHCP 伺服器為不安全的。", "dhcp_found": "於該網路上一個現行的動態主機設定協定DHCP伺服器被發現。啟用內建的 DHCP 伺服器為不安全的。",
"dhcp_leases": "動態主機設定協定DHCP租約", "dhcp_leases": "動態主機設定協定DHCP租約",
@ -294,6 +294,9 @@
"blocked_response_ttl": "已封鎖的回應之存活時間TTL", "blocked_response_ttl": "已封鎖的回應之存活時間TTL",
"blocked_response_ttl_desc": "對用戶端應快取受過濾的回應,指定多少秒數", "blocked_response_ttl_desc": "對用戶端應快取受過濾的回應,指定多少秒數",
"form_enter_blocked_response_ttl": "請輸入已封鎖回應的存活時間(秒)", "form_enter_blocked_response_ttl": "請輸入已封鎖回應的存活時間(秒)",
"upstream_timeout": "上游超時",
"upstream_timeout_desc": "指定等待來自此上游伺服器回應的秒數",
"form_enter_upstream_timeout": "輸入上游伺服器超時時間(以秒為單位)",
"dnscrypt": "DNSCrypt", "dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS", "dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS", "dns_over_tls": "DNS-over-TLS",
@ -479,7 +482,7 @@
"auto_clients_desc": "AdGuard Home 使用或可能使用的裝置的 IP 地址資訊。這些資訊來自多個來源,包括主機檔案、反向 DNS 等。", "auto_clients_desc": "AdGuard Home 使用或可能使用的裝置的 IP 地址資訊。這些資訊來自多個來源,包括主機檔案、反向 DNS 等。",
"access_title": "存取設定", "access_title": "存取設定",
"access_desc": "於此您可配置用於 AdGuard Home DNS 伺服器之存取規則", "access_desc": "於此您可配置用於 AdGuard Home DNS 伺服器之存取規則",
"access_allowed_title": "允許的用戶端", "access_allowed_title": "允許的用戶端",
"access_allowed_desc": "無類別網域間路由CIDRs、IP 位址或<a>用戶端 IDs</a> 之清單。如果此清單有項目AdGuard Home 將接受僅來自這些用戶端的請求。", "access_allowed_desc": "無類別網域間路由CIDRs、IP 位址或<a>用戶端 IDs</a> 之清單。如果此清單有項目AdGuard Home 將接受僅來自這些用戶端的請求。",
"access_disallowed_title": "未被允許的用戶端", "access_disallowed_title": "未被允許的用戶端",
"access_disallowed_desc": "無類別網域間路由CIDRs、IP 位址或<a>用戶端 IDs</a> 之清單。如果此清單有項目AdGuard Home 將排除來自這些用戶端的請求。如果在已允許的用戶端中有項目,此欄位被忽略。", "access_disallowed_desc": "無類別網域間路由CIDRs、IP 位址或<a>用戶端 IDs</a> 之清單。如果此清單有項目AdGuard Home 將排除來自這些用戶端的請求。如果在已允許的用戶端中有項目,此欄位被忽略。",
@ -560,7 +563,7 @@
"statistics_retention_confirm": "您確定您想要更改統計資料保留嗎?如果您減少該間隔值,某些資料將被丟失", "statistics_retention_confirm": "您確定您想要更改統計資料保留嗎?如果您減少該間隔值,某些資料將被丟失",
"statistics_cleared": "統計資料被成功地清除", "statistics_cleared": "統計資料被成功地清除",
"statistics_enable": "啟用統計資料", "statistics_enable": "啟用統計資料",
"ignore_domains": "忽略的網域(以換行符分隔)", "ignore_domains": "被忽略的網域(被換行分隔)",
"ignore_domains_title": "被忽略的網域", "ignore_domains_title": "被忽略的網域",
"ignore_domains_desc_stats": "符合這些規則的查詢不會被記錄在統計資料中", "ignore_domains_desc_stats": "符合這些規則的查詢不會被記錄在統計資料中",
"ignore_domains_desc_query": "符合這些規則的查詢不會被寫入查詢記錄中", "ignore_domains_desc_query": "符合這些規則的查詢不會被寫入查詢記錄中",
@ -598,7 +601,7 @@
"disable_ipv6": "禁用 IPv6 位址之解析", "disable_ipv6": "禁用 IPv6 位址之解析",
"disable_ipv6_desc": "停止所有對於 IPv6 位址(類型 AAAA的 DNS 查詢,並從 HTTPS 回應中移除 IPv6 的提示。", "disable_ipv6_desc": "停止所有對於 IPv6 位址(類型 AAAA的 DNS 查詢,並從 HTTPS 回應中移除 IPv6 的提示。",
"fastest_addr": "最快的 IP 位址", "fastest_addr": "最快的 IP 位址",
"fastest_addr_desc": "查詢所有的 DNS 伺服器並返回在所有的回應之中最快的 IP 位址。因為 AdGuard Home 必須等待來自所有的 DNS 伺服器之回應,這使 DNS 查詢變慢,但改善總體的連線。", "fastest_addr_desc": "等待<b>所有</b> DNS 伺服器的回應,測量每個伺服器的 TCP 連線速度,並返回連線速度最快的伺服器的 IP 位址。<br/>如果一個或多個上游伺服器沒有回應,此模式會顯著減慢 DNS 查詢速度。確保您的上游伺服器穩定且上游超時時間短。",
"autofix_warning_text": "如果您點擊\"修復\"AdGuard Home 將配置您的系統使用 AdGuard Home DNS 伺服器。", "autofix_warning_text": "如果您點擊\"修復\"AdGuard Home 將配置您的系統使用 AdGuard Home DNS 伺服器。",
"autofix_warning_list": "它將執行這些任務:<0>撤銷系統 DNSStubListener</0> <0>設定 DNS 伺服器位址為 127.0.0.1</0> <0>用 /run/systemd/resolve/resolv.conf 取代 /etc/resolv.conf 的符號連結目標</0> <0>停止 DNSStubListener重新載入 systemd-resolved 服務)</0>", "autofix_warning_list": "它將執行這些任務:<0>撤銷系統 DNSStubListener</0> <0>設定 DNS 伺服器位址為 127.0.0.1</0> <0>用 /run/systemd/resolve/resolv.conf 取代 /etc/resolv.conf 的符號連結目標</0> <0>停止 DNSStubListener重新載入 systemd-resolved 服務)</0>",
"autofix_warning_result": "因此,預設下,來自您的系統之所有的 DNS 請求將被 AdGuard Home 處理。", "autofix_warning_result": "因此,預設下,來自您的系統之所有的 DNS 請求將被 AdGuard Home 處理。",
@ -637,7 +640,7 @@
"validated_with_dnssec": "已用網域名稱系統安全性擴充功能DNSSEC驗證", "validated_with_dnssec": "已用網域名稱系統安全性擴充功能DNSSEC驗證",
"all_queries": "所有的查詢", "all_queries": "所有的查詢",
"show_blocked_responses": "已封鎖的", "show_blocked_responses": "已封鎖的",
"show_whitelisted_responses": "允許的", "show_whitelisted_responses": "允許的",
"show_processed_responses": "已處理的", "show_processed_responses": "已處理的",
"blocked_safebrowsing": "被安全瀏覽封鎖", "blocked_safebrowsing": "被安全瀏覽封鎖",
"blocked_adult_websites": "被家長控制封鎖", "blocked_adult_websites": "被家長控制封鎖",
@ -673,8 +676,8 @@
"click_to_view_queries": "點擊以檢視查詢", "click_to_view_queries": "點擊以檢視查詢",
"port_53_faq_link": "連接埠 53 常被 \"DNSStubListener\" 或 \"systemd-resolved\" 服務佔用。請閱讀有關如何解決這個的<0>用法說明</0>。", "port_53_faq_link": "連接埠 53 常被 \"DNSStubListener\" 或 \"systemd-resolved\" 服務佔用。請閱讀有關如何解決這個的<0>用法說明</0>。",
"adg_will_drop_dns_queries": "AdGuard Home 將持續排除來自此用戶端之所有的 DNS 查詢。", "adg_will_drop_dns_queries": "AdGuard Home 將持續排除來自此用戶端之所有的 DNS 查詢。",
"filter_allowlist": "警告:此動作也將把 \"{{disallowed_rule}}\" 規則排除在允許的用戶端的清單之外。", "filter_allowlist": "警告:此動作也將把 \"{{disallowed_rule}}\" 規則排除在允許的用戶端的清單之外。",
"last_rule_in_allowlist": "因為排除 \"{{disallowed_rule}}\" 規則將禁用\"允許的用戶端\"清單,無法不允許此用戶端。", "last_rule_in_allowlist": "因為排除 \"{{disallowed_rule}}\" 規則將禁用\"允許的用戶端\"清單,無法不允許此用戶端。",
"use_saved_key": "使用該先前已儲存的金鑰", "use_saved_key": "使用該先前已儲存的金鑰",
"parental_control": "家長控制", "parental_control": "家長控制",
"safe_browsing": "安全瀏覽", "safe_browsing": "安全瀏覽",

View File

@ -178,8 +178,12 @@ func (r *Runtime) Addr() (ip netip.Addr) {
return r.ip return r.ip
} }
// clone returns a deep copy of the runtime client. // clone returns a deep copy of the runtime client. If r is nil, c is nil.
func (r *Runtime) clone() (c *Runtime) { func (r *Runtime) clone() (c *Runtime) {
if r == nil {
return nil
}
return &Runtime{ return &Runtime{
ip: r.ip, ip: r.ip,
whois: r.whois.Clone(), whois: r.whois.Clone(),

View File

@ -591,17 +591,21 @@ func (s *Storage) ClientRuntime(ip netip.Addr) (rc *Runtime) {
defer s.mu.Unlock() defer s.mu.Unlock()
rc = s.runtimeIndex.client(ip) rc = s.runtimeIndex.client(ip)
if rc != nil { if !s.runtimeSourceDHCP {
return rc.clone() return rc.clone()
} }
if !s.runtimeSourceDHCP { // SourceHostsFile > SourceDHCP, so return immediately if the client is from
return nil // the hosts file.
if rc != nil && rc.hostsFile != nil {
return rc.clone()
} }
// Otherwise, check the DHCP server and add the client information if there
// is any.
host := s.dhcp.HostByIP(ip) host := s.dhcp.HostByIP(ip)
if host == "" { if host == "" {
return nil return rc.clone()
} }
rc = s.runtimeIndex.setInfo(ip, SourceDHCP, []string{host}) rc = s.runtimeIndex.setInfo(ip, SourceDHCP, []string{host})

View File

@ -353,6 +353,9 @@ func TestClientsDHCP(t *testing.T) {
prsCliIP = netip.MustParseAddr("4.3.2.1") prsCliIP = netip.MustParseAddr("4.3.2.1")
prsCliMAC = mustParseMAC("AA:AA:AA:AA:AA:AA") prsCliMAC = mustParseMAC("AA:AA:AA:AA:AA:AA")
prsCliName = "persistent.dhcp" prsCliName = "persistent.dhcp"
otherARPCliName = "other.arp"
otherARPCliIP = netip.MustParseAddr("192.0.2.1")
) )
ipToHost := map[netip.Addr]string{ ipToHost := map[netip.Addr]string{
@ -372,7 +375,20 @@ func TestClientsDHCP(t *testing.T) {
HWAddr: cliMAC3, HWAddr: cliMAC3,
}} }}
d := &testDHCP{ arpCh := make(chan []arpdb.Neighbor, 1)
arpDB := &testARPDB{
onRefresh: func() (err error) { return nil },
onNeighbors: func() (ns []arpdb.Neighbor) {
select {
case ns = <-arpCh:
return ns
default:
return nil
}
},
}
dhcp := &testDHCP{
OnLeases: func() (ls []*dhcpsvc.Lease) { OnLeases: func() (ls []*dhcpsvc.Lease) {
return leases return leases
}, },
@ -384,22 +400,111 @@ func TestClientsDHCP(t *testing.T) {
}, },
} }
etcHostsCh := make(chan *hostsfile.DefaultStorage, 1)
etcHosts := &testHostsContainer{
onUpd: func() (updates <-chan *hostsfile.DefaultStorage) {
return etcHostsCh
},
}
ctx := testutil.ContextWithTimeout(t, testTimeout) ctx := testutil.ContextWithTimeout(t, testTimeout)
storage, err := client.NewStorage(ctx, &client.StorageConfig{ storage, err := client.NewStorage(ctx, &client.StorageConfig{
Logger: slogutil.NewDiscardLogger(), Logger: slogutil.NewDiscardLogger(),
DHCP: d, ARPDB: arpDB,
RuntimeSourceDHCP: true, DHCP: dhcp,
EtcHosts: etcHosts,
RuntimeSourceDHCP: true,
ARPClientsUpdatePeriod: testTimeout / 10,
}) })
require.NoError(t, err) require.NoError(t, err)
t.Run("find_runtime", func(t *testing.T) { err = storage.Start(testutil.ContextWithTimeout(t, testTimeout))
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, func() (err error) {
return storage.Shutdown(testutil.ContextWithTimeout(t, testTimeout))
})
require.True(t, t.Run("find_runtime_lower_priority", func(t *testing.T) {
// Add a lower-priority client.
ns := []arpdb.Neighbor{{
Name: cliName1,
IP: cliIP1,
}}
testutil.RequireSend(t, arpCh, ns, testTimeout)
storage.ReloadARP(testutil.ContextWithTimeout(t, testTimeout))
cli1 := storage.ClientRuntime(cliIP1) cli1 := storage.ClientRuntime(cliIP1)
require.NotNil(t, cli1) require.NotNil(t, cli1)
assert.True(t, compareRuntimeInfo(cli1, client.SourceDHCP, cliName1)) assert.True(t, compareRuntimeInfo(cli1, client.SourceDHCP, cliName1))
})
t.Run("find_persistent", func(t *testing.T) { // Remove the matching client.
//
// TODO(a.garipov): Consider adding ways of explicitly clearing runtime
// sources by source.
ns = []arpdb.Neighbor{{
Name: otherARPCliName,
IP: otherARPCliIP,
}}
testutil.RequireSend(t, arpCh, ns, testTimeout)
storage.ReloadARP(testutil.ContextWithTimeout(t, testTimeout))
}))
require.True(t, t.Run("find_runtime", func(t *testing.T) {
cli1 := storage.ClientRuntime(cliIP1)
require.NotNil(t, cli1)
assert.True(t, compareRuntimeInfo(cli1, client.SourceDHCP, cliName1))
}))
require.True(t, t.Run("find_runtime_higher_priority", func(t *testing.T) {
// Add a higher-priority client.
s, strgErr := hostsfile.NewDefaultStorage()
require.NoError(t, strgErr)
s.Add(&hostsfile.Record{
Addr: cliIP1,
Names: []string{cliName1},
})
testutil.RequireSend(t, etcHostsCh, s, testTimeout)
cli1 := storage.ClientRuntime(cliIP1)
require.NotNil(t, cli1)
require.Eventually(t, func() (ok bool) {
cli := storage.ClientRuntime(cliIP1)
if cli == nil {
return false
}
assert.True(t, compareRuntimeInfo(cli, client.SourceHostsFile, cliName1))
return true
}, testTimeout, testTimeout/10)
// Remove the matching client.
//
// TODO(a.garipov): Consider adding ways of explicitly clearing runtime
// sources by source.
s, strgErr = hostsfile.NewDefaultStorage()
require.NoError(t, strgErr)
testutil.RequireSend(t, etcHostsCh, s, testTimeout)
require.Eventually(t, func() (ok bool) {
cli := storage.ClientRuntime(cliIP1)
return compareRuntimeInfo(cli, client.SourceDHCP, cliName1)
}, testTimeout, testTimeout/10)
}))
require.True(t, t.Run("find_persistent", func(t *testing.T) {
err = storage.Add(ctx, &client.Persistent{ err = storage.Add(ctx, &client.Persistent{
Name: prsCliName, Name: prsCliName,
UID: client.MustNewUID(), UID: client.MustNewUID(),
@ -411,9 +516,9 @@ func TestClientsDHCP(t *testing.T) {
require.True(t, ok) require.True(t, ok)
assert.Equal(t, prsCliName, prsCli.Name) assert.Equal(t, prsCliName, prsCli.Name)
}) }))
t.Run("leases", func(t *testing.T) { require.True(t, t.Run("leases", func(t *testing.T) {
delete(ipToHost, cliIP1) delete(ipToHost, cliIP1)
storage.UpdateDHCP(ctx) storage.UpdateDHCP(ctx)
@ -428,18 +533,20 @@ func TestClientsDHCP(t *testing.T) {
assert.Equal(t, client.SourceDHCP, src) assert.Equal(t, client.SourceDHCP, src)
assert.Equal(t, leases[i].Hostname, host) assert.Equal(t, leases[i].Hostname, host)
} }
}) }))
t.Run("range", func(t *testing.T) { require.True(t, t.Run("range", func(t *testing.T) {
s := 0 s := 0
storage.RangeRuntime(func(rc *client.Runtime) (cont bool) { storage.RangeRuntime(func(rc *client.Runtime) (cont bool) {
s++ if src, _ := rc.Info(); src == client.SourceDHCP {
s++
}
return true return true
}) })
assert.Equal(t, len(leases), s) assert.Equal(t, len(leases), s)
}) }))
} }
func TestClientsAddExisting(t *testing.T) { func TestClientsAddExisting(t *testing.T) {

View File

@ -356,7 +356,7 @@ func (a *Auth) getCurrentUser(r *http.Request) (u webUser) {
// There's no Cookie, check Basic authentication. // There's no Cookie, check Basic authentication.
user, pass, ok := r.BasicAuth() user, pass, ok := r.BasicAuth()
if ok { if ok {
u, _ = Context.auth.findUser(user, pass) u, _ = globalContext.auth.findUser(user, pass)
return u return u
} }

View File

@ -155,7 +155,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
return return
} }
if rateLimiter := Context.auth.rateLimiter; rateLimiter != nil { if rateLimiter := globalContext.auth.rateLimiter; rateLimiter != nil {
if left := rateLimiter.check(remoteIP); left > 0 { if left := rateLimiter.check(remoteIP); left > 0 {
w.Header().Set(httphdr.RetryAfter, strconv.Itoa(int(left.Seconds()))) w.Header().Set(httphdr.RetryAfter, strconv.Itoa(int(left.Seconds())))
writeErrorWithIP( writeErrorWithIP(
@ -176,10 +176,10 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
log.Error("auth: getting real ip from request with remote ip %s: %s", remoteIP, err) log.Error("auth: getting real ip from request with remote ip %s: %s", remoteIP, err)
} }
cookie, err := Context.auth.newCookie(req, remoteIP) cookie, err := globalContext.auth.newCookie(req, remoteIP)
if err != nil { if err != nil {
logIP := remoteIP logIP := remoteIP
if Context.auth.trustedProxies.Contains(ip.Unmap()) { if globalContext.auth.trustedProxies.Contains(ip.Unmap()) {
logIP = ip.String() logIP = ip.String()
} }
@ -213,7 +213,7 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
return return
} }
Context.auth.removeSession(c.Value) globalContext.auth.removeSession(c.Value)
c = &http.Cookie{ c = &http.Cookie{
Name: sessionCookieName, Name: sessionCookieName,
@ -232,7 +232,7 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
// RegisterAuthHandlers - register handlers // RegisterAuthHandlers - register handlers
func RegisterAuthHandlers() { func RegisterAuthHandlers() {
Context.mux.Handle("/control/login", postInstallHandler(ensureHandler(http.MethodPost, handleLogin))) globalContext.mux.Handle("/control/login", postInstallHandler(ensureHandler(http.MethodPost, handleLogin)))
httpRegister(http.MethodGet, "/control/logout", handleLogout) httpRegister(http.MethodGet, "/control/logout", handleLogout)
} }
@ -254,13 +254,13 @@ func optionalAuthThird(w http.ResponseWriter, r *http.Request) (mustAuth bool) {
// Check Basic authentication. // Check Basic authentication.
user, pass, hasBasic := r.BasicAuth() user, pass, hasBasic := r.BasicAuth()
if hasBasic { if hasBasic {
_, isAuthenticated = Context.auth.findUser(user, pass) _, isAuthenticated = globalContext.auth.findUser(user, pass)
if !isAuthenticated { if !isAuthenticated {
log.Info("%s: invalid basic authorization value", pref) log.Info("%s: invalid basic authorization value", pref)
} }
} }
} else { } else {
res := Context.auth.checkSession(cookie.Value) res := globalContext.auth.checkSession(cookie.Value)
isAuthenticated = res == checkSessionOK isAuthenticated = res == checkSessionOK
if !isAuthenticated { if !isAuthenticated {
log.Debug("%s: invalid cookie value: %q", pref, cookie) log.Debug("%s: invalid cookie value: %q", pref, cookie)
@ -294,12 +294,12 @@ func optionalAuth(
) (wrapped func(http.ResponseWriter, *http.Request)) { ) (wrapped func(http.ResponseWriter, *http.Request)) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path p := r.URL.Path
authRequired := Context.auth != nil && Context.auth.authRequired() authRequired := globalContext.auth != nil && globalContext.auth.authRequired()
if p == "/login.html" { if p == "/login.html" {
cookie, err := r.Cookie(sessionCookieName) cookie, err := r.Cookie(sessionCookieName)
if authRequired && err == nil { if authRequired && err == nil {
// Redirect to the dashboard if already authenticated. // Redirect to the dashboard if already authenticated.
res := Context.auth.checkSession(cookie.Value) res := globalContext.auth.checkSession(cookie.Value)
if res == checkSessionOK { if res == checkSessionOK {
http.Redirect(w, r, "", http.StatusFound) http.Redirect(w, r, "", http.StatusFound)

View File

@ -39,7 +39,7 @@ func TestAuthHTTP(t *testing.T) {
users := []webUser{ users := []webUser{
{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"}, {Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
} }
Context.auth = InitAuth(fn, users, 60, nil, nil) globalContext.auth = InitAuth(fn, users, 60, nil, nil)
handlerCalled := false handlerCalled := false
handler := func(_ http.ResponseWriter, _ *http.Request) { handler := func(_ http.ResponseWriter, _ *http.Request) {
@ -68,7 +68,7 @@ func TestAuthHTTP(t *testing.T) {
assert.True(t, handlerCalled) assert.True(t, handlerCalled)
// perform login // perform login
cookie, err := Context.auth.newCookie(loginJSON{Name: "name", Password: "password"}, "") cookie, err := globalContext.auth.newCookie(loginJSON{Name: "name", Password: "password"}, "")
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, cookie) require.NotNil(t, cookie)
@ -114,7 +114,7 @@ func TestAuthHTTP(t *testing.T) {
assert.True(t, handlerCalled) assert.True(t, handlerCalled)
r.Header.Del(httphdr.Cookie) r.Header.Del(httphdr.Cookie)
Context.auth.Close() globalContext.auth.Close()
} }
func TestRealIP(t *testing.T) { func TestRealIP(t *testing.T) {

View File

@ -528,7 +528,7 @@ func (clients *clientsContainer) findRuntime(ip netip.Addr, idStr string) (cj *c
return cj return cj
} }
// RegisterClientsHandlers registers HTTP handlers // registerWebHandlers registers HTTP handlers
func (clients *clientsContainer) registerWebHandlers() { func (clients *clientsContainer) registerWebHandlers() {
httpRegister(http.MethodGet, "/control/clients", clients.handleGetClients) httpRegister(http.MethodGet, "/control/clients", clients.handleGetClients)
httpRegister(http.MethodPost, "/control/clients/add", clients.handleAddClient) httpRegister(http.MethodPost, "/control/clients/add", clients.handleAddClient)

View File

@ -486,9 +486,9 @@ var config = &configuration{
// configFilePath returns the absolute path to the symlink-evaluated path to the // configFilePath returns the absolute path to the symlink-evaluated path to the
// current config file. // current config file.
func configFilePath() (confPath string) { func configFilePath() (confPath string) {
confPath, err := filepath.EvalSymlinks(Context.confFilePath) confPath, err := filepath.EvalSymlinks(globalContext.confFilePath)
if err != nil { if err != nil {
confPath = Context.confFilePath confPath = globalContext.confFilePath
logFunc := log.Error logFunc := log.Error
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
logFunc = log.Debug logFunc = log.Debug
@ -498,7 +498,7 @@ func configFilePath() (confPath string) {
} }
if !filepath.IsAbs(confPath) { if !filepath.IsAbs(confPath) {
confPath = filepath.Join(Context.workDir, confPath) confPath = filepath.Join(globalContext.workDir, confPath)
} }
return confPath return confPath
@ -530,8 +530,8 @@ func parseConfig() (err error) {
} }
migrator := configmigrate.New(&configmigrate.Config{ migrator := configmigrate.New(&configmigrate.Config{
WorkingDir: Context.workDir, WorkingDir: globalContext.workDir,
DataDir: Context.getDataDir(), DataDir: globalContext.getDataDir(),
}) })
var upgraded bool var upgraded bool
@ -644,27 +644,27 @@ func (c *configuration) write() (err error) {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
if Context.auth != nil { if globalContext.auth != nil {
config.Users = Context.auth.usersList() config.Users = globalContext.auth.usersList()
} }
if Context.tls != nil { if globalContext.tls != nil {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
Context.tls.WriteDiskConfig(&tlsConf) globalContext.tls.WriteDiskConfig(&tlsConf)
config.TLS = tlsConf config.TLS = tlsConf
} }
if Context.stats != nil { if globalContext.stats != nil {
statsConf := stats.Config{} statsConf := stats.Config{}
Context.stats.WriteDiskConfig(&statsConf) globalContext.stats.WriteDiskConfig(&statsConf)
config.Stats.Interval = timeutil.Duration(statsConf.Limit) config.Stats.Interval = timeutil.Duration(statsConf.Limit)
config.Stats.Enabled = statsConf.Enabled config.Stats.Enabled = statsConf.Enabled
config.Stats.Ignored = statsConf.Ignored.Values() config.Stats.Ignored = statsConf.Ignored.Values()
} }
if Context.queryLog != nil { if globalContext.queryLog != nil {
dc := querylog.Config{} dc := querylog.Config{}
Context.queryLog.WriteDiskConfig(&dc) globalContext.queryLog.WriteDiskConfig(&dc)
config.DNS.AnonymizeClientIP = dc.AnonymizeClientIP config.DNS.AnonymizeClientIP = dc.AnonymizeClientIP
config.QueryLog.Enabled = dc.Enabled config.QueryLog.Enabled = dc.Enabled
config.QueryLog.FileEnabled = dc.FileEnabled config.QueryLog.FileEnabled = dc.FileEnabled
@ -673,14 +673,14 @@ func (c *configuration) write() (err error) {
config.QueryLog.Ignored = dc.Ignored.Values() config.QueryLog.Ignored = dc.Ignored.Values()
} }
if Context.filters != nil { if globalContext.filters != nil {
Context.filters.WriteDiskConfig(config.Filtering) globalContext.filters.WriteDiskConfig(config.Filtering)
config.Filters = config.Filtering.Filters config.Filters = config.Filtering.Filters
config.WhitelistFilters = config.Filtering.WhitelistFilters config.WhitelistFilters = config.Filtering.WhitelistFilters
config.UserRules = config.Filtering.UserRules config.UserRules = config.Filtering.UserRules
} }
if s := Context.dnsServer; s != nil { if s := globalContext.dnsServer; s != nil {
c := dnsforward.Config{} c := dnsforward.Config{}
s.WriteDiskConfig(&c) s.WriteDiskConfig(&c)
dns := &config.DNS dns := &config.DNS
@ -695,11 +695,11 @@ func (c *configuration) write() (err error) {
dns.UpstreamTimeout = timeutil.Duration(s.UpstreamTimeout()) dns.UpstreamTimeout = timeutil.Duration(s.UpstreamTimeout())
} }
if Context.dhcpServer != nil { if globalContext.dhcpServer != nil {
Context.dhcpServer.WriteDiskConfig(config.DHCP) globalContext.dhcpServer.WriteDiskConfig(config.DHCP)
} }
config.Clients.Persistent = Context.clients.forConfig() config.Clients.Persistent = globalContext.clients.forConfig()
confPath := configFilePath() confPath := configFilePath()
log.Debug("writing config file %q", confPath) log.Debug("writing config file %q", confPath)
@ -726,14 +726,14 @@ func setContextTLSCipherIDs() (err error) {
if len(config.TLS.OverrideTLSCiphers) == 0 { if len(config.TLS.OverrideTLSCiphers) == 0 {
log.Info("tls: using default ciphers") log.Info("tls: using default ciphers")
Context.tlsCipherIDs = aghtls.SaferCipherSuites() globalContext.tlsCipherIDs = aghtls.SaferCipherSuites()
return nil return nil
} }
log.Info("tls: overriding ciphers: %s", config.TLS.OverrideTLSCiphers) log.Info("tls: overriding ciphers: %s", config.TLS.OverrideTLSCiphers)
Context.tlsCipherIDs, err = aghtls.ParseCiphers(config.TLS.OverrideTLSCiphers) globalContext.tlsCipherIDs, err = aghtls.ParseCiphers(config.TLS.OverrideTLSCiphers)
if err != nil { if err != nil {
return fmt.Errorf("parsing override ciphers: %w", err) return fmt.Errorf("parsing override ciphers: %w", err)
} }

View File

@ -129,10 +129,10 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
protectionDisabledUntil *time.Time protectionDisabledUntil *time.Time
protectionEnabled bool protectionEnabled bool
) )
if Context.dnsServer != nil { if globalContext.dnsServer != nil {
fltConf = &dnsforward.Config{} fltConf = &dnsforward.Config{}
Context.dnsServer.WriteDiskConfig(fltConf) globalContext.dnsServer.WriteDiskConfig(fltConf)
protectionEnabled, protectionDisabledUntil = Context.dnsServer.UpdatedProtectionStatus() protectionEnabled, protectionDisabledUntil = globalContext.dnsServer.UpdatedProtectionStatus()
} }
var resp statusResponse var resp statusResponse
@ -162,7 +162,7 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
// IsDHCPAvailable field is now false by default for Windows. // IsDHCPAvailable field is now false by default for Windows.
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
resp.IsDHCPAvailable = Context.dhcpServer != nil resp.IsDHCPAvailable = globalContext.dhcpServer != nil
} }
aghhttp.WriteJSONResponseOK(w, r, resp) aghhttp.WriteJSONResponseOK(w, r, resp)
@ -172,7 +172,7 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
// registration of handlers // registration of handlers
// ------------------------ // ------------------------
func registerControlHandlers(web *webAPI) { func registerControlHandlers(web *webAPI) {
Context.mux.HandleFunc( globalContext.mux.HandleFunc(
"/control/version.json", "/control/version.json",
postInstall(optionalAuth(web.handleVersionJSON)), postInstall(optionalAuth(web.handleVersionJSON)),
) )
@ -185,19 +185,19 @@ func registerControlHandlers(web *webAPI) {
httpRegister(http.MethodPut, "/control/profile/update", handlePutProfile) httpRegister(http.MethodPut, "/control/profile/update", handlePutProfile)
// No auth is necessary for DoH/DoT configurations // No auth is necessary for DoH/DoT configurations
Context.mux.HandleFunc("/apple/doh.mobileconfig", postInstall(handleMobileConfigDoH)) globalContext.mux.HandleFunc("/apple/doh.mobileconfig", postInstall(handleMobileConfigDoH))
Context.mux.HandleFunc("/apple/dot.mobileconfig", postInstall(handleMobileConfigDoT)) globalContext.mux.HandleFunc("/apple/dot.mobileconfig", postInstall(handleMobileConfigDoT))
RegisterAuthHandlers() RegisterAuthHandlers()
} }
func httpRegister(method, url string, handler http.HandlerFunc) { func httpRegister(method, url string, handler http.HandlerFunc) {
if method == "" { if method == "" {
// "/dns-query" handler doesn't need auth, gzip and isn't restricted by 1 HTTP method // "/dns-query" handler doesn't need auth, gzip and isn't restricted by 1 HTTP method
Context.mux.HandleFunc(url, postInstall(handler)) globalContext.mux.HandleFunc(url, postInstall(handler))
return return
} }
Context.mux.Handle(url, postInstallHandler(optionalAuthHandler(gziphandler.GzipHandler(ensureHandler(method, handler))))) globalContext.mux.Handle(url, postInstallHandler(optionalAuthHandler(gziphandler.GzipHandler(ensureHandler(method, handler)))))
} }
// ensure returns a wrapped handler that makes sure that the request has the // ensure returns a wrapped handler that makes sure that the request has the
@ -223,8 +223,8 @@ func ensure(
return return
} }
Context.controlLock.Lock() globalContext.controlLock.Lock()
defer Context.controlLock.Unlock() defer globalContext.controlLock.Unlock()
} }
handler(w, r) handler(w, r)
@ -293,7 +293,7 @@ func ensureHandler(method string, handler func(http.ResponseWriter, *http.Reques
// preInstall lets the handler run only if firstRun is true, no redirects // preInstall lets the handler run only if firstRun is true, no redirects
func preInstall(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { func preInstall(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if !Context.firstRun { if !globalContext.firstRun {
// if it's not first run, don't let users access it (for example /install.html when configuration is done) // if it's not first run, don't let users access it (for example /install.html when configuration is done)
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return return
@ -320,7 +320,7 @@ func preInstallHandler(handler http.Handler) http.Handler {
// HTTPS-related headers. If proceed is true, the middleware must continue // HTTPS-related headers. If proceed is true, the middleware must continue
// handling the request. // handling the request.
func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool) { func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool) {
web := Context.web web := globalContext.web
if web.httpsServer.server == nil { if web.httpsServer.server == nil {
return true return true
} }
@ -409,7 +409,7 @@ func httpsURL(u *url.URL, host string, portHTTPS uint16) (redirectURL *url.URL)
func postInstall(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) { func postInstall(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path path := r.URL.Path
if Context.firstRun && !strings.HasPrefix(path, "/install.") && if globalContext.firstRun && !strings.HasPrefix(path, "/install.") &&
!strings.HasPrefix(path, "/assets/") { !strings.HasPrefix(path, "/assets/") {
http.Redirect(w, r, "install.html", http.StatusFound) http.Redirect(w, r, "install.html", http.StatusFound)

View File

@ -428,20 +428,20 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
curConfig := &configuration{} curConfig := &configuration{}
copyInstallSettings(curConfig, config) copyInstallSettings(curConfig, config)
Context.firstRun = false globalContext.firstRun = false
config.DNS.BindHosts = []netip.Addr{req.DNS.IP} config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
config.DNS.Port = req.DNS.Port config.DNS.Port = req.DNS.Port
config.Filtering.SafeFSPatterns = []string{ config.Filtering.SafeFSPatterns = []string{
filepath.Join(Context.workDir, userFilterDataDir, "*"), filepath.Join(globalContext.workDir, userFilterDataDir, "*"),
} }
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port) config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
u := &webUser{ u := &webUser{
Name: req.Username, Name: req.Username,
} }
err = Context.auth.addUser(u, req.Password) err = globalContext.auth.addUser(u, req.Password)
if err != nil { if err != nil {
Context.firstRun = true globalContext.firstRun = true
copyInstallSettings(config, curConfig) copyInstallSettings(config, curConfig)
aghhttp.Error(r, w, http.StatusUnprocessableEntity, "%s", err) aghhttp.Error(r, w, http.StatusUnprocessableEntity, "%s", err)
@ -454,7 +454,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
// functions potentially restart the HTTPS server. // functions potentially restart the HTTPS server.
err = startMods(web.baseLogger) err = startMods(web.baseLogger)
if err != nil { if err != nil {
Context.firstRun = true globalContext.firstRun = true
copyInstallSettings(config, curConfig) copyInstallSettings(config, curConfig)
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err) aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)
@ -463,7 +463,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
err = config.write() err = config.write()
if err != nil { if err != nil {
Context.firstRun = true globalContext.firstRun = true
copyInstallSettings(config, curConfig) copyInstallSettings(config, curConfig)
aghhttp.Error(r, w, http.StatusInternalServerError, "Couldn't write config: %s", err) aghhttp.Error(r, w, http.StatusInternalServerError, "Couldn't write config: %s", err)
@ -528,7 +528,7 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
} }
func (web *webAPI) registerInstallHandlers() { func (web *webAPI) registerInstallHandlers() {
Context.mux.HandleFunc("/control/install/get_addresses", preInstall(ensureGET(web.handleInstallGetAddresses))) globalContext.mux.HandleFunc("/control/install/get_addresses", preInstall(ensureGET(web.handleInstallGetAddresses)))
Context.mux.HandleFunc("/control/install/check_config", preInstall(ensurePOST(web.handleInstallCheckConfig))) globalContext.mux.HandleFunc("/control/install/check_config", preInstall(ensurePOST(web.handleInstallCheckConfig)))
Context.mux.HandleFunc("/control/install/configure", preInstall(ensurePOST(web.handleInstallConfigure))) globalContext.mux.HandleFunc("/control/install/configure", preInstall(ensurePOST(web.handleInstallConfigure)))
} }

View File

@ -165,7 +165,7 @@ func (vr *versionResponse) setAllowedToAutoUpdate() (err error) {
} }
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
Context.tls.WriteDiskConfig(tlsConf) globalContext.tls.WriteDiskConfig(tlsConf)
canUpdate := true canUpdate := true
if tlsConfUsesPrivilegedPorts(tlsConf) || if tlsConfUsesPrivilegedPorts(tlsConf) ||

View File

@ -45,9 +45,9 @@ func onConfigModified() {
} }
} }
// initDNS updates all the fields of the [Context] needed to initialize the DNS // initDNS updates all the fields of the [globalContext] needed to initialize the DNS
// server and initializes it at last. It also must not be called unless // server and initializes it at last. It also must not be called unless
// [config] and [Context] are initialized. baseLogger must not be nil. // [config] and [globalContext] are initialized. baseLogger must not be nil.
func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error) { func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error) {
anonymizer := config.anonymizer() anonymizer := config.anonymizer()
@ -58,7 +58,7 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
ConfigModified: onConfigModified, ConfigModified: onConfigModified,
HTTPRegister: httpRegister, HTTPRegister: httpRegister,
Enabled: config.Stats.Enabled, Enabled: config.Stats.Enabled,
ShouldCountClient: Context.clients.shouldCountClient, ShouldCountClient: globalContext.clients.shouldCountClient,
} }
engine, err := aghnet.NewIgnoreEngine(config.Stats.Ignored) engine, err := aghnet.NewIgnoreEngine(config.Stats.Ignored)
@ -67,7 +67,7 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
} }
statsConf.Ignored = engine statsConf.Ignored = engine
Context.stats, err = stats.New(statsConf) globalContext.stats, err = stats.New(statsConf)
if err != nil { if err != nil {
return fmt.Errorf("init stats: %w", err) return fmt.Errorf("init stats: %w", err)
} }
@ -77,7 +77,7 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
Anonymizer: anonymizer, Anonymizer: anonymizer,
ConfigModified: onConfigModified, ConfigModified: onConfigModified,
HTTPRegister: httpRegister, HTTPRegister: httpRegister,
FindClient: Context.clients.findMultiple, FindClient: globalContext.clients.findMultiple,
BaseDir: querylogDir, BaseDir: querylogDir,
AnonymizeClientIP: config.DNS.AnonymizeClientIP, AnonymizeClientIP: config.DNS.AnonymizeClientIP,
RotationIvl: time.Duration(config.QueryLog.Interval), RotationIvl: time.Duration(config.QueryLog.Interval),
@ -92,25 +92,25 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
} }
conf.Ignored = engine conf.Ignored = engine
Context.queryLog, err = querylog.New(conf) globalContext.queryLog, err = querylog.New(conf)
if err != nil { if err != nil {
return fmt.Errorf("init querylog: %w", err) return fmt.Errorf("init querylog: %w", err)
} }
Context.filters, err = filtering.New(config.Filtering, nil) globalContext.filters, err = filtering.New(config.Filtering, nil)
if err != nil { if err != nil {
// Don't wrap the error, since it's informative enough as is. // Don't wrap the error, since it's informative enough as is.
return err return err
} }
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
Context.tls.WriteDiskConfig(tlsConf) globalContext.tls.WriteDiskConfig(tlsConf)
return initDNSServer( return initDNSServer(
Context.filters, globalContext.filters,
Context.stats, globalContext.stats,
Context.queryLog, globalContext.queryLog,
Context.dhcpServer, globalContext.dhcpServer,
anonymizer, anonymizer,
httpRegister, httpRegister,
tlsConf, tlsConf,
@ -121,7 +121,7 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
// initDNSServer initializes the [context.dnsServer]. To only use the internal // initDNSServer initializes the [context.dnsServer]. To only use the internal
// proxy, none of the arguments are required, but tlsConf and l still must not // proxy, none of the arguments are required, but tlsConf and l still must not
// be nil, in other cases all the arguments also must not be nil. It also must // be nil, in other cases all the arguments also must not be nil. It also must
// not be called unless [config] and [Context] are initialized. // not be called unless [config] and [globalContext] are initialized.
// //
// TODO(e.burkov): Use [dnsforward.DNSCreateParams] as a parameter. // TODO(e.burkov): Use [dnsforward.DNSCreateParams] as a parameter.
func initDNSServer( func initDNSServer(
@ -134,7 +134,7 @@ func initDNSServer(
tlsConf *tlsConfigSettings, tlsConf *tlsConfigSettings,
l *slog.Logger, l *slog.Logger,
) (err error) { ) (err error) {
Context.dnsServer, err = dnsforward.NewServer(dnsforward.DNSCreateParams{ globalContext.dnsServer, err = dnsforward.NewServer(dnsforward.DNSCreateParams{
Logger: l, Logger: l,
DNSFilter: filters, DNSFilter: filters,
Stats: sts, Stats: sts,
@ -142,7 +142,7 @@ func initDNSServer(
PrivateNets: parseSubnetSet(config.DNS.PrivateNets), PrivateNets: parseSubnetSet(config.DNS.PrivateNets),
Anonymizer: anonymizer, Anonymizer: anonymizer,
DHCPServer: dhcpSrv, DHCPServer: dhcpSrv,
EtcHosts: Context.etcHosts, EtcHosts: globalContext.etcHosts,
LocalDomain: config.DHCP.LocalDomainName, LocalDomain: config.DHCP.LocalDomainName,
}) })
defer func() { defer func() {
@ -154,7 +154,7 @@ func initDNSServer(
return fmt.Errorf("dnsforward.NewServer: %w", err) return fmt.Errorf("dnsforward.NewServer: %w", err)
} }
Context.clients.clientChecker = Context.dnsServer globalContext.clients.clientChecker = globalContext.dnsServer
dnsConf, err := newServerConfig(&config.DNS, config.Clients.Sources, tlsConf, httpReg) dnsConf, err := newServerConfig(&config.DNS, config.Clients.Sources, tlsConf, httpReg)
if err != nil { if err != nil {
@ -163,12 +163,12 @@ func initDNSServer(
// Try to prepare the server with disabled private RDNS resolution if it // Try to prepare the server with disabled private RDNS resolution if it
// failed to prepare as is. See TODO on [dnsforward.PrivateRDNSError]. // failed to prepare as is. See TODO on [dnsforward.PrivateRDNSError].
err = Context.dnsServer.Prepare(dnsConf) err = globalContext.dnsServer.Prepare(dnsConf)
if privRDNSErr := (&dnsforward.PrivateRDNSError{}); errors.As(err, &privRDNSErr) { if privRDNSErr := (&dnsforward.PrivateRDNSError{}); errors.As(err, &privRDNSErr) {
log.Info("WARNING: %s; trying to disable private RDNS resolution", err) log.Info("WARNING: %s; trying to disable private RDNS resolution", err)
dnsConf.UsePrivateRDNS = false dnsConf.UsePrivateRDNS = false
err = Context.dnsServer.Prepare(dnsConf) err = globalContext.dnsServer.Prepare(dnsConf)
} }
if err != nil { if err != nil {
@ -194,7 +194,7 @@ func parseSubnetSet(nets []netutil.Prefix) (s netutil.SubnetSet) {
} }
func isRunning() bool { func isRunning() bool {
return Context.dnsServer != nil && Context.dnsServer.IsRunning() return globalContext.dnsServer != nil && globalContext.dnsServer.IsRunning()
} }
func ipsToTCPAddrs(ips []netip.Addr, port uint16) (tcpAddrs []*net.TCPAddr) { func ipsToTCPAddrs(ips []netip.Addr, port uint16) (tcpAddrs []*net.TCPAddr) {
@ -235,7 +235,7 @@ func newServerConfig(
fwdConf := dnsConf.Config fwdConf := dnsConf.Config
fwdConf.FilterHandler = applyAdditionalFiltering fwdConf.FilterHandler = applyAdditionalFiltering
fwdConf.ClientsContainer = &Context.clients fwdConf.ClientsContainer = &globalContext.clients
newConf = &dnsforward.ServerConfig{ newConf = &dnsforward.ServerConfig{
UDPListenAddrs: ipsToUDPAddrs(hosts, dnsConf.Port), UDPListenAddrs: ipsToUDPAddrs(hosts, dnsConf.Port),
@ -244,7 +244,7 @@ func newServerConfig(
TLSConfig: newDNSTLSConfig(tlsConf, hosts), TLSConfig: newDNSTLSConfig(tlsConf, hosts),
TLSAllowUnencryptedDoH: tlsConf.AllowUnencryptedDoH, TLSAllowUnencryptedDoH: tlsConf.AllowUnencryptedDoH,
UpstreamTimeout: time.Duration(dnsConf.UpstreamTimeout), UpstreamTimeout: time.Duration(dnsConf.UpstreamTimeout),
TLSv12Roots: Context.tlsRoots, TLSv12Roots: globalContext.tlsRoots,
ConfigModified: onConfigModified, ConfigModified: onConfigModified,
HTTPRegister: httpReg, HTTPRegister: httpReg,
LocalPTRResolvers: dnsConf.PrivateRDNSResolvers, LocalPTRResolvers: dnsConf.PrivateRDNSResolvers,
@ -259,16 +259,16 @@ func newServerConfig(
var initialAddresses []netip.Addr var initialAddresses []netip.Addr
// Context.stats may be nil here if initDNSServer is called from // Context.stats may be nil here if initDNSServer is called from
// [cmdlineUpdate]. // [cmdlineUpdate].
if sts := Context.stats; sts != nil { if sts := globalContext.stats; sts != nil {
const initialClientsNum = 100 const initialClientsNum = 100
initialAddresses = Context.stats.TopClientsIP(initialClientsNum) initialAddresses = globalContext.stats.TopClientsIP(initialClientsNum)
} }
// Do not set DialContext, PrivateSubnets, and UsePrivateRDNS, because they // Do not set DialContext, PrivateSubnets, and UsePrivateRDNS, because they
// are set by [dnsforward.Server.Prepare]. // are set by [dnsforward.Server.Prepare].
newConf.AddrProcConf = &client.DefaultAddrProcConfig{ newConf.AddrProcConf = &client.DefaultAddrProcConfig{
Exchanger: Context.dnsServer, Exchanger: globalContext.dnsServer,
AddressUpdater: &Context.clients, AddressUpdater: &globalContext.clients,
InitialAddresses: initialAddresses, InitialAddresses: initialAddresses,
CatchPanics: true, CatchPanics: true,
UseRDNS: clientSrcConf.RDNS, UseRDNS: clientSrcConf.RDNS,
@ -359,7 +359,7 @@ type dnsEncryption struct {
func getDNSEncryption() (de dnsEncryption) { func getDNSEncryption() (de dnsEncryption) {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
Context.tls.WriteDiskConfig(&tlsConf) globalContext.tls.WriteDiskConfig(&tlsConf)
if !tlsConf.Enabled || len(tlsConf.ServerName) == 0 { if !tlsConf.Enabled || len(tlsConf.ServerName) == 0 {
return dnsEncryption{} return dnsEncryption{}
@ -402,7 +402,7 @@ func applyAdditionalFiltering(clientIP netip.Addr, clientID string, setts *filte
// pref is a prefix for logging messages around the scope. // pref is a prefix for logging messages around the scope.
const pref = "applying filters" const pref = "applying filters"
Context.filters.ApplyBlockedServices(setts) globalContext.filters.ApplyBlockedServices(setts)
log.Debug("%s: looking for client with ip %s and clientid %q", pref, clientIP, clientID) log.Debug("%s: looking for client with ip %s and clientid %q", pref, clientIP, clientID)
@ -412,9 +412,9 @@ func applyAdditionalFiltering(clientIP netip.Addr, clientID string, setts *filte
setts.ClientIP = clientIP setts.ClientIP = clientIP
c, ok := Context.clients.storage.Find(clientID) c, ok := globalContext.clients.storage.Find(clientID)
if !ok { if !ok {
c, ok = Context.clients.storage.Find(clientIP.String()) c, ok = globalContext.clients.storage.Find(clientIP.String())
if !ok { if !ok {
log.Debug("%s: no clients with ip %s and clientid %q", pref, clientIP, clientID) log.Debug("%s: no clients with ip %s and clientid %q", pref, clientIP, clientID)
@ -429,7 +429,7 @@ func applyAdditionalFiltering(clientIP netip.Addr, clientID string, setts *filte
setts.ServicesRules = nil setts.ServicesRules = nil
svcs := c.BlockedServices.IDs svcs := c.BlockedServices.IDs
if !c.BlockedServices.Schedule.Contains(time.Now()) { if !c.BlockedServices.Schedule.Contains(time.Now()) {
Context.filters.ApplyBlockedServicesList(setts, svcs) globalContext.filters.ApplyBlockedServicesList(setts, svcs)
log.Debug("%s: services for client %q set: %s", pref, c.Name, svcs) log.Debug("%s: services for client %q set: %s", pref, c.Name, svcs)
} }
} }
@ -455,24 +455,24 @@ func startDNSServer() error {
return fmt.Errorf("unable to start forwarding DNS server: Already running") return fmt.Errorf("unable to start forwarding DNS server: Already running")
} }
Context.filters.EnableFilters(false) globalContext.filters.EnableFilters(false)
// TODO(s.chzhen): Pass context. // TODO(s.chzhen): Pass context.
ctx := context.TODO() ctx := context.TODO()
err := Context.clients.Start(ctx) err := globalContext.clients.Start(ctx)
if err != nil { if err != nil {
return fmt.Errorf("starting clients container: %w", err) return fmt.Errorf("starting clients container: %w", err)
} }
err = Context.dnsServer.Start() err = globalContext.dnsServer.Start()
if err != nil { if err != nil {
return fmt.Errorf("starting dns server: %w", err) return fmt.Errorf("starting dns server: %w", err)
} }
Context.filters.Start() globalContext.filters.Start()
Context.stats.Start() globalContext.stats.Start()
err = Context.queryLog.Start(ctx) err = globalContext.queryLog.Start(ctx)
if err != nil { if err != nil {
return fmt.Errorf("starting query log: %w", err) return fmt.Errorf("starting query log: %w", err)
} }
@ -482,14 +482,14 @@ func startDNSServer() error {
func reconfigureDNSServer() (err error) { func reconfigureDNSServer() (err error) {
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
Context.tls.WriteDiskConfig(tlsConf) globalContext.tls.WriteDiskConfig(tlsConf)
newConf, err := newServerConfig(&config.DNS, config.Clients.Sources, tlsConf, httpRegister) newConf, err := newServerConfig(&config.DNS, config.Clients.Sources, tlsConf, httpRegister)
if err != nil { if err != nil {
return fmt.Errorf("generating forwarding dns server config: %w", err) return fmt.Errorf("generating forwarding dns server config: %w", err)
} }
err = Context.dnsServer.Reconfigure(newConf) err = globalContext.dnsServer.Reconfigure(newConf)
if err != nil { if err != nil {
return fmt.Errorf("starting forwarding dns server: %w", err) return fmt.Errorf("starting forwarding dns server: %w", err)
} }
@ -502,12 +502,12 @@ func stopDNSServer() (err error) {
return nil return nil
} }
err = Context.dnsServer.Stop() err = globalContext.dnsServer.Stop()
if err != nil { if err != nil {
return fmt.Errorf("stopping forwarding dns server: %w", err) return fmt.Errorf("stopping forwarding dns server: %w", err)
} }
err = Context.clients.close(context.TODO()) err = globalContext.clients.close(context.TODO())
if err != nil { if err != nil {
return fmt.Errorf("closing clients container: %w", err) return fmt.Errorf("closing clients container: %w", err)
} }
@ -519,25 +519,25 @@ func stopDNSServer() (err error) {
func closeDNSServer() { func closeDNSServer() {
// DNS forward module must be closed BEFORE stats or queryLog because it depends on them // DNS forward module must be closed BEFORE stats or queryLog because it depends on them
if Context.dnsServer != nil { if globalContext.dnsServer != nil {
Context.dnsServer.Close() globalContext.dnsServer.Close()
Context.dnsServer = nil globalContext.dnsServer = nil
} }
if Context.filters != nil { if globalContext.filters != nil {
Context.filters.Close() globalContext.filters.Close()
} }
if Context.stats != nil { if globalContext.stats != nil {
err := Context.stats.Close() err := globalContext.stats.Close()
if err != nil { if err != nil {
log.Error("closing stats: %s", err) log.Error("closing stats: %s", err)
} }
} }
if Context.queryLog != nil { if globalContext.queryLog != nil {
// TODO(s.chzhen): Pass context. // TODO(s.chzhen): Pass context.
err := Context.queryLog.Shutdown(context.TODO()) err := globalContext.queryLog.Shutdown(context.TODO())
if err != nil { if err != nil {
log.Error("closing query log: %s", err) log.Error("closing query log: %s", err)
} }

View File

@ -37,14 +37,14 @@ func newStorage(tb testing.TB, clients []*client.Persistent) (s *client.Storage)
func TestApplyAdditionalFiltering(t *testing.T) { func TestApplyAdditionalFiltering(t *testing.T) {
var err error var err error
Context.filters, err = filtering.New(&filtering.Config{ globalContext.filters, err = filtering.New(&filtering.Config{
BlockedServices: &filtering.BlockedServices{ BlockedServices: &filtering.BlockedServices{
Schedule: schedule.EmptyWeekly(), Schedule: schedule.EmptyWeekly(),
}, },
}, nil) }, nil)
require.NoError(t, err) require.NoError(t, err)
Context.clients.storage = newStorage(t, []*client.Persistent{{ globalContext.clients.storage = newStorage(t, []*client.Persistent{{
Name: "default", Name: "default",
ClientIDs: []string{"default"}, ClientIDs: []string{"default"},
UseOwnSettings: false, UseOwnSettings: false,
@ -124,7 +124,7 @@ func TestApplyAdditionalFiltering_blockedServices(t *testing.T) {
err error err error
) )
Context.filters, err = filtering.New(&filtering.Config{ globalContext.filters, err = filtering.New(&filtering.Config{
BlockedServices: &filtering.BlockedServices{ BlockedServices: &filtering.BlockedServices{
Schedule: schedule.EmptyWeekly(), Schedule: schedule.EmptyWeekly(),
IDs: globalBlockedServices, IDs: globalBlockedServices,
@ -132,7 +132,7 @@ func TestApplyAdditionalFiltering_blockedServices(t *testing.T) {
}, nil) }, nil)
require.NoError(t, err) require.NoError(t, err)
Context.clients.storage = newStorage(t, []*client.Persistent{{ globalContext.clients.storage = newStorage(t, []*client.Persistent{{
Name: "default", Name: "default",
ClientIDs: []string{"default"}, ClientIDs: []string{"default"},
UseOwnBlockedServices: false, UseOwnBlockedServices: false,

View File

@ -91,10 +91,10 @@ func (c *homeContext) getDataDir() string {
return filepath.Join(c.workDir, dataDir) return filepath.Join(c.workDir, dataDir)
} }
// Context - a global context object // globalContext is a global context object.
// //
// TODO(a.garipov): Refactor. // TODO(a.garipov): Refactor.
var Context homeContext var globalContext homeContext
// Main is the entry point // Main is the entry point
func Main(clientBuildFS fs.FS) { func Main(clientBuildFS fs.FS) {
@ -120,8 +120,8 @@ func Main(clientBuildFS fs.FS) {
log.Info("Received signal %q", sig) log.Info("Received signal %q", sig)
switch sig { switch sig {
case syscall.SIGHUP: case syscall.SIGHUP:
Context.clients.storage.ReloadARP(ctx) globalContext.clients.storage.ReloadARP(ctx)
Context.tls.reload() globalContext.tls.reload()
default: default:
cleanup(ctx) cleanup(ctx)
cleanupAlways() cleanupAlways()
@ -140,13 +140,13 @@ func Main(clientBuildFS fs.FS) {
run(opts, clientBuildFS, done) run(opts, clientBuildFS, done)
} }
// setupContext initializes [Context] fields. It also reads and upgrades // setupContext initializes [globalContext] fields. It also reads and upgrades
// config file if necessary. // config file if necessary.
func setupContext(opts options) (err error) { func setupContext(opts options) (err error) {
Context.firstRun = detectFirstRun() globalContext.firstRun = detectFirstRun()
Context.tlsRoots = aghtls.SystemRootCAs() globalContext.tlsRoots = aghtls.SystemRootCAs()
Context.mux = http.NewServeMux() globalContext.mux = http.NewServeMux()
if !opts.noEtcHosts { if !opts.noEtcHosts {
err = setupHostsContainer() err = setupHostsContainer()
@ -156,7 +156,7 @@ func setupContext(opts options) (err error) {
} }
} }
if Context.firstRun { if globalContext.firstRun {
log.Info("This is the first time AdGuard Home is launched") log.Info("This is the first time AdGuard Home is launched")
checkNetworkPermissions() checkNetworkPermissions()
@ -247,7 +247,7 @@ func setupHostsContainer() (err error) {
return fmt.Errorf("getting default system hosts paths: %w", err) return fmt.Errorf("getting default system hosts paths: %w", err)
} }
Context.etcHosts, err = aghnet.NewHostsContainer(osutil.RootDirFS(), hostsWatcher, paths...) globalContext.etcHosts, err = aghnet.NewHostsContainer(osutil.RootDirFS(), hostsWatcher, paths...)
if err != nil { if err != nil {
closeErr := hostsWatcher.Close() closeErr := hostsWatcher.Close()
if errors.Is(err, aghnet.ErrNoHostsPaths) { if errors.Is(err, aghnet.ErrNoHostsPaths) {
@ -271,7 +271,7 @@ func setupOpts(opts options) (err error) {
} }
if len(opts.pidFile) != 0 && writePIDFile(opts.pidFile) { if len(opts.pidFile) != 0 && writePIDFile(opts.pidFile) {
Context.pidFileName = opts.pidFile globalContext.pidFileName = opts.pidFile
} }
return nil return nil
@ -286,13 +286,13 @@ func initContextClients(ctx context.Context, logger *slog.Logger) (err error) {
} }
//lint:ignore SA1019 Migration is not over. //lint:ignore SA1019 Migration is not over.
config.DHCP.WorkDir = Context.workDir config.DHCP.WorkDir = globalContext.workDir
config.DHCP.DataDir = Context.getDataDir() config.DHCP.DataDir = globalContext.getDataDir()
config.DHCP.HTTPRegister = httpRegister config.DHCP.HTTPRegister = httpRegister
config.DHCP.ConfigModified = onConfigModified config.DHCP.ConfigModified = onConfigModified
Context.dhcpServer, err = dhcpd.Create(config.DHCP) globalContext.dhcpServer, err = dhcpd.Create(config.DHCP)
if Context.dhcpServer == nil || err != nil { if globalContext.dhcpServer == nil || err != nil {
// TODO(a.garipov): There are a lot of places in the code right // TODO(a.garipov): There are a lot of places in the code right
// now which assume that the DHCP server can be nil despite this // now which assume that the DHCP server can be nil despite this
// condition. Inspect them and perhaps rewrite them to use // condition. Inspect them and perhaps rewrite them to use
@ -305,12 +305,12 @@ func initContextClients(ctx context.Context, logger *slog.Logger) (err error) {
arpDB = arpdb.New(logger.With(slogutil.KeyError, "arpdb")) arpDB = arpdb.New(logger.With(slogutil.KeyError, "arpdb"))
} }
return Context.clients.Init( return globalContext.clients.Init(
ctx, ctx,
logger, logger,
config.Clients.Persistent, config.Clients.Persistent,
Context.dhcpServer, globalContext.dhcpServer,
Context.etcHosts, globalContext.etcHosts,
arpDB, arpDB,
config.Filtering, config.Filtering,
) )
@ -374,15 +374,15 @@ func setupDNSFilteringConf(
pcTXTSuffix = `pc.dns.adguard.com.` pcTXTSuffix = `pc.dns.adguard.com.`
) )
conf.EtcHosts = Context.etcHosts conf.EtcHosts = globalContext.etcHosts
// TODO(s.chzhen): Use empty interface. // TODO(s.chzhen): Use empty interface.
if Context.etcHosts == nil || !config.DNS.HostsFileEnabled { if globalContext.etcHosts == nil || !config.DNS.HostsFileEnabled {
conf.EtcHosts = nil conf.EtcHosts = nil
} }
conf.ConfigModified = onConfigModified conf.ConfigModified = onConfigModified
conf.HTTPRegister = httpRegister conf.HTTPRegister = httpRegister
conf.DataDir = Context.getDataDir() conf.DataDir = globalContext.getDataDir()
conf.Filters = slices.Clone(config.Filters) conf.Filters = slices.Clone(config.Filters)
conf.WhitelistFilters = slices.Clone(config.WhitelistFilters) conf.WhitelistFilters = slices.Clone(config.WhitelistFilters)
conf.UserRules = slices.Clone(config.UserRules) conf.UserRules = slices.Clone(config.UserRules)
@ -560,7 +560,7 @@ func initWeb(
ReadHeaderTimeout: readHdrTimeout, ReadHeaderTimeout: readHdrTimeout,
WriteTimeout: writeTimeout, WriteTimeout: writeTimeout,
firstRun: Context.firstRun, firstRun: globalContext.firstRun,
disableUpdate: disableUpdate, disableUpdate: disableUpdate,
runningAsService: opts.runningAsService, runningAsService: opts.runningAsService,
serveHTTP3: config.DNS.ServeHTTP3, serveHTTP3: config.DNS.ServeHTTP3,
@ -602,7 +602,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
// Print the first message after logger is configured. // Print the first message after logger is configured.
log.Info(version.Full()) log.Info(version.Full())
log.Debug("current working directory is %s", Context.workDir) log.Debug("current working directory is %s", globalContext.workDir)
if opts.runningAsService { if opts.runningAsService {
log.Info("AdGuard Home is running as a service") log.Info("AdGuard Home is running as a service")
} }
@ -632,13 +632,13 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
confPath := configFilePath() confPath := configFilePath()
upd, customURL := newUpdater(ctx, slogLogger, Context.workDir, confPath, execPath, config) upd, customURL := newUpdater(ctx, slogLogger, globalContext.workDir, confPath, execPath, config)
// TODO(e.burkov): This could be made earlier, probably as the option's // TODO(e.burkov): This could be made earlier, probably as the option's
// effect. // effect.
cmdlineUpdate(ctx, slogLogger, opts, upd) cmdlineUpdate(ctx, slogLogger, opts, upd)
if !Context.firstRun { if !globalContext.firstRun {
// Save the updated config. // Save the updated config.
err = config.write() err = config.write()
fatalOnError(err) fatalOnError(err)
@ -648,33 +648,33 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
} }
} }
dataDir := Context.getDataDir() dataDir := globalContext.getDataDir()
err = os.MkdirAll(dataDir, aghos.DefaultPermDir) err = os.MkdirAll(dataDir, aghos.DefaultPermDir)
fatalOnError(errors.Annotate(err, "creating DNS data dir at %s: %w", dataDir)) fatalOnError(errors.Annotate(err, "creating DNS data dir at %s: %w", dataDir))
GLMode = opts.glinetMode GLMode = opts.glinetMode
// Init auth module. // Init auth module.
Context.auth, err = initUsers() globalContext.auth, err = initUsers()
fatalOnError(err) fatalOnError(err)
Context.tls, err = newTLSManager(config.TLS, config.DNS.ServePlainDNS) globalContext.tls, err = newTLSManager(config.TLS, config.DNS.ServePlainDNS)
if err != nil { if err != nil {
log.Error("initializing tls: %s", err) log.Error("initializing tls: %s", err)
onConfigModified() onConfigModified()
} }
Context.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, customURL) globalContext.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, customURL)
fatalOnError(err) fatalOnError(err)
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config) statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
fatalOnError(err) fatalOnError(err)
if !Context.firstRun { if !globalContext.firstRun {
err = initDNS(slogLogger, statsDir, querylogDir) err = initDNS(slogLogger, statsDir, querylogDir)
fatalOnError(err) fatalOnError(err)
Context.tls.start() globalContext.tls.start()
go func() { go func() {
startErr := startDNSServer() startErr := startDNSServer()
@ -684,8 +684,8 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
} }
}() }()
if Context.dhcpServer != nil { if globalContext.dhcpServer != nil {
err = Context.dhcpServer.Start() err = globalContext.dhcpServer.Start()
if err != nil { if err != nil {
log.Error("starting dhcp server: %s", err) log.Error("starting dhcp server: %s", err)
} }
@ -693,10 +693,10 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
} }
if !opts.noPermCheck { if !opts.noPermCheck {
checkPermissions(ctx, slogLogger, Context.workDir, confPath, dataDir, statsDir, querylogDir) checkPermissions(ctx, slogLogger, globalContext.workDir, confPath, dataDir, statsDir, querylogDir)
} }
Context.web.start(ctx) globalContext.web.start(ctx)
// Wait for other goroutines to complete their job. // Wait for other goroutines to complete their job.
<-done <-done
@ -775,7 +775,7 @@ func checkPermissions(
// initUsers initializes context auth module. Clears config users field. // initUsers initializes context auth module. Clears config users field.
func initUsers() (auth *Auth, err error) { func initUsers() (auth *Auth, err error) {
sessFilename := filepath.Join(Context.getDataDir(), "sessions.db") sessFilename := filepath.Join(globalContext.getDataDir(), "sessions.db")
var rateLimiter *authRateLimiter var rateLimiter *authRateLimiter
if config.AuthAttempts > 0 && config.AuthBlockMin > 0 { if config.AuthAttempts > 0 && config.AuthBlockMin > 0 {
@ -810,7 +810,7 @@ func (c *configuration) anonymizer() (ipmut *aghnet.IPMut) {
// startMods initializes and starts the DNS server after installation. // startMods initializes and starts the DNS server after installation.
// baseLogger must not be nil. // baseLogger must not be nil.
func startMods(baseLogger *slog.Logger) (err error) { func startMods(baseLogger *slog.Logger) (err error) {
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config) statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
if err != nil { if err != nil {
return err return err
} }
@ -820,7 +820,7 @@ func startMods(baseLogger *slog.Logger) (err error) {
return err return err
} }
Context.tls.start() globalContext.tls.start()
err = startDNSServer() err = startDNSServer()
if err != nil { if err != nil {
@ -883,14 +883,14 @@ func writePIDFile(fn string) bool {
func initConfigFilename(opts options) { func initConfigFilename(opts options) {
confPath := opts.confFilename confPath := opts.confFilename
if confPath == "" { if confPath == "" {
Context.confFilePath = filepath.Join(Context.workDir, "AdGuardHome.yaml") globalContext.confFilePath = filepath.Join(globalContext.workDir, "AdGuardHome.yaml")
return return
} }
log.Debug("config path overridden to %q from cmdline", confPath) log.Debug("config path overridden to %q from cmdline", confPath)
Context.confFilePath = confPath globalContext.confFilePath = confPath
} }
// initWorkingDir initializes the workDir. If no command-line arguments are // initWorkingDir initializes the workDir. If no command-line arguments are
@ -904,18 +904,18 @@ func initWorkingDir(opts options) (err error) {
if opts.workDir != "" { if opts.workDir != "" {
// If there is a custom config file, use it's directory as our working dir // If there is a custom config file, use it's directory as our working dir
Context.workDir = opts.workDir globalContext.workDir = opts.workDir
} else { } else {
Context.workDir = filepath.Dir(execPath) globalContext.workDir = filepath.Dir(execPath)
} }
workDir, err := filepath.EvalSymlinks(Context.workDir) workDir, err := filepath.EvalSymlinks(globalContext.workDir)
if err != nil { if err != nil {
// Don't wrap the error, because it's informative enough as is. // Don't wrap the error, because it's informative enough as is.
return err return err
} }
Context.workDir = workDir globalContext.workDir = workDir
return nil return nil
} }
@ -924,13 +924,13 @@ func initWorkingDir(opts options) (err error) {
func cleanup(ctx context.Context) { func cleanup(ctx context.Context) {
log.Info("stopping AdGuard Home") log.Info("stopping AdGuard Home")
if Context.web != nil { if globalContext.web != nil {
Context.web.close(ctx) globalContext.web.close(ctx)
Context.web = nil globalContext.web = nil
} }
if Context.auth != nil { if globalContext.auth != nil {
Context.auth.Close() globalContext.auth.Close()
Context.auth = nil globalContext.auth = nil
} }
err := stopDNSServer() err := stopDNSServer()
@ -938,28 +938,28 @@ func cleanup(ctx context.Context) {
log.Error("stopping dns server: %s", err) log.Error("stopping dns server: %s", err)
} }
if Context.dhcpServer != nil { if globalContext.dhcpServer != nil {
err = Context.dhcpServer.Stop() err = globalContext.dhcpServer.Stop()
if err != nil { if err != nil {
log.Error("stopping dhcp server: %s", err) log.Error("stopping dhcp server: %s", err)
} }
} }
if Context.etcHosts != nil { if globalContext.etcHosts != nil {
if err = Context.etcHosts.Close(); err != nil { if err = globalContext.etcHosts.Close(); err != nil {
log.Error("closing hosts container: %s", err) log.Error("closing hosts container: %s", err)
} }
} }
if Context.tls != nil { if globalContext.tls != nil {
Context.tls = nil globalContext.tls = nil
} }
} }
// This function is called before application exits // This function is called before application exits
func cleanupAlways() { func cleanupAlways() {
if len(Context.pidFileName) != 0 { if len(globalContext.pidFileName) != 0 {
_ = os.Remove(Context.pidFileName) _ = os.Remove(globalContext.pidFileName)
} }
log.Info("stopped") log.Info("stopped")
@ -1007,8 +1007,8 @@ func printWebAddrs(proto, addr string, port uint16) {
// admin interface. proto is either schemeHTTP or schemeHTTPS. // admin interface. proto is either schemeHTTP or schemeHTTPS.
func printHTTPAddresses(proto string) { func printHTTPAddresses(proto string) {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
if Context.tls != nil { if globalContext.tls != nil {
Context.tls.WriteDiskConfig(&tlsConf) globalContext.tls.WriteDiskConfig(&tlsConf)
} }
port := config.HTTPConfig.Address.Port() port := config.HTTPConfig.Address.Port()
@ -1050,9 +1050,9 @@ func printHTTPAddresses(proto string) {
// detectFirstRun returns true if this is the first run of AdGuard Home. // detectFirstRun returns true if this is the first run of AdGuard Home.
func detectFirstRun() (ok bool) { func detectFirstRun() (ok bool) {
confPath := Context.confFilePath confPath := globalContext.confFilePath
if !filepath.IsAbs(confPath) { if !filepath.IsAbs(confPath) {
confPath = filepath.Join(Context.workDir, Context.confFilePath) confPath = filepath.Join(globalContext.workDir, globalContext.confFilePath)
} }
_, err := os.Stat(confPath) _, err := os.Stat(confPath)
@ -1105,7 +1105,7 @@ func cmdlineUpdate(ctx context.Context, l *slog.Logger, opts options, upd *updat
os.Exit(osutil.ExitCodeSuccess) os.Exit(osutil.ExitCodeSuccess)
} }
err = upd.Update(Context.firstRun) err = upd.Update(globalContext.firstRun)
fatalOnError(err) fatalOnError(err)
err = restartService() err = restartService()

View File

@ -17,7 +17,7 @@ func httpClient() (c *http.Client) {
// Do not use Context.dnsServer.DialContext directly in the struct literal // Do not use Context.dnsServer.DialContext directly in the struct literal
// below, since Context.dnsServer may be nil when this function is called. // below, since Context.dnsServer may be nil when this function is called.
dialContext := func(ctx context.Context, network, addr string) (conn net.Conn, err error) { dialContext := func(ctx context.Context, network, addr string) (conn net.Conn, err error) {
return Context.dnsServer.DialContext(ctx, network, addr) return globalContext.dnsServer.DialContext(ctx, network, addr)
} }
return &http.Client{ return &http.Client{
@ -27,8 +27,8 @@ func httpClient() (c *http.Client) {
DialContext: dialContext, DialContext: dialContext,
Proxy: httpProxy, Proxy: httpProxy,
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
RootCAs: Context.tlsRoots, RootCAs: globalContext.tlsRoots,
CipherSuites: Context.tlsCipherIDs, CipherSuites: globalContext.tlsCipherIDs,
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
}, },
}, },

View File

@ -66,7 +66,7 @@ func configureLogger(ls *logSettings) (err error) {
logFilePath := ls.File logFilePath := ls.File
if !filepath.IsAbs(logFilePath) { if !filepath.IsAbs(logFilePath) {
logFilePath = filepath.Join(Context.workDir, logFilePath) logFilePath = filepath.Join(globalContext.workDir, logFilePath)
} }
log.SetOutput(&lumberjack.Logger{ log.SetOutput(&lumberjack.Logger{

View File

@ -19,10 +19,10 @@ func setupDNSIPs(t testing.TB) {
t.Helper() t.Helper()
prevConfig := config prevConfig := config
prevTLS := Context.tls prevTLS := globalContext.tls
t.Cleanup(func() { t.Cleanup(func() {
config = prevConfig config = prevConfig
Context.tls = prevTLS globalContext.tls = prevTLS
}) })
config = &configuration{ config = &configuration{
@ -32,7 +32,7 @@ func setupDNSIPs(t testing.TB) {
}, },
} }
Context.tls = &tlsManager{} globalContext.tls = &tlsManager{}
} }
func TestHandleMobileConfigDoH(t *testing.T) { func TestHandleMobileConfigDoH(t *testing.T) {
@ -62,10 +62,10 @@ func TestHandleMobileConfigDoH(t *testing.T) {
}) })
t.Run("error_no_host", func(t *testing.T) { t.Run("error_no_host", func(t *testing.T) {
oldTLSConf := Context.tls oldTLSConf := globalContext.tls
t.Cleanup(func() { Context.tls = oldTLSConf }) t.Cleanup(func() { globalContext.tls = oldTLSConf })
Context.tls = &tlsManager{conf: tlsConfigSettings{}} globalContext.tls = &tlsManager{conf: tlsConfigSettings{}}
r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/doh.mobileconfig", nil) r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/doh.mobileconfig", nil)
require.NoError(t, err) require.NoError(t, err)
@ -134,10 +134,10 @@ func TestHandleMobileConfigDoT(t *testing.T) {
}) })
t.Run("error_no_host", func(t *testing.T) { t.Run("error_no_host", func(t *testing.T) {
oldTLSConf := Context.tls oldTLSConf := globalContext.tls
t.Cleanup(func() { Context.tls = oldTLSConf }) t.Cleanup(func() { globalContext.tls = oldTLSConf })
Context.tls = &tlsManager{conf: tlsConfigSettings{}} globalContext.tls = &tlsManager{conf: tlsConfigSettings{}}
r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/dot.mobileconfig", nil) r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/dot.mobileconfig", nil)
require.NoError(t, err) require.NoError(t, err)

View File

@ -47,7 +47,7 @@ type profileJSON struct {
// handleGetProfile is the handler for GET /control/profile endpoint. // handleGetProfile is the handler for GET /control/profile endpoint.
func handleGetProfile(w http.ResponseWriter, r *http.Request) { func handleGetProfile(w http.ResponseWriter, r *http.Request) {
u := Context.auth.getCurrentUser(r) u := globalContext.auth.getCurrentUser(r)
var resp profileJSON var resp profileJSON
func() { func() {

View File

@ -112,7 +112,7 @@ func (m *tlsManager) start() {
// The background context is used because the TLSConfigChanged wraps context // The background context is used because the TLSConfigChanged wraps context
// with timeout on its own and shuts down the server, which handles current // with timeout on its own and shuts down the server, which handles current
// request. // request.
Context.web.tlsConfigChanged(context.Background(), tlsConf) globalContext.web.tlsConfigChanged(context.Background(), tlsConf)
} }
// reload updates the configuration and restarts t. // reload updates the configuration and restarts t.
@ -160,7 +160,7 @@ func (m *tlsManager) reload() {
// The background context is used because the TLSConfigChanged wraps context // The background context is used because the TLSConfigChanged wraps context
// with timeout on its own and shuts down the server, which handles current // with timeout on its own and shuts down the server, which handles current
// request. // request.
Context.web.tlsConfigChanged(context.Background(), tlsConf) globalContext.web.tlsConfigChanged(context.Background(), tlsConf)
} }
// loadTLSConf loads and validates the TLS configuration. The returned error is // loadTLSConf loads and validates the TLS configuration. The returned error is
@ -463,7 +463,7 @@ func (m *tlsManager) handleTLSConfigure(w http.ResponseWriter, r *http.Request)
// same reason. // same reason.
if restartHTTPS { if restartHTTPS {
go func() { go func() {
Context.web.tlsConfigChanged(context.Background(), req.tlsConfigSettings) globalContext.web.tlsConfigChanged(context.Background(), req.tlsConfigSettings)
}() }()
} }
} }
@ -539,7 +539,7 @@ func validateCertChain(certs []*x509.Certificate, srvName string) (err error) {
opts := x509.VerifyOptions{ opts := x509.VerifyOptions{
DNSName: srvName, DNSName: srvName,
Roots: Context.tlsRoots, Roots: globalContext.tlsRoots,
Intermediates: pool, Intermediates: pool,
} }
_, err = main.Verify(opts) _, err = main.Verify(opts)

View File

@ -129,7 +129,7 @@ func newWebAPI(ctx context.Context, conf *webConfig) (w *webAPI) {
clientFS := http.FileServer(http.FS(conf.clientFS)) clientFS := http.FileServer(http.FS(conf.clientFS))
// if not configured, redirect / to /install.html, otherwise redirect /install.html to / // if not configured, redirect / to /install.html, otherwise redirect /install.html to /
Context.mux.Handle("/", withMiddlewares(clientFS, gziphandler.GzipHandler, optionalAuthHandler, postInstallHandler)) globalContext.mux.Handle("/", withMiddlewares(clientFS, gziphandler.GzipHandler, optionalAuthHandler, postInstallHandler))
// add handlers for /install paths, we only need them when we're not configured yet // add handlers for /install paths, we only need them when we're not configured yet
if conf.firstRun { if conf.firstRun {
@ -138,7 +138,7 @@ func newWebAPI(ctx context.Context, conf *webConfig) (w *webAPI) {
"This is the first launch of AdGuard Home, redirecting everything to /install.html", "This is the first launch of AdGuard Home, redirecting everything to /install.html",
) )
Context.mux.Handle("/install.html", preInstallHandler(clientFS)) globalContext.mux.Handle("/install.html", preInstallHandler(clientFS))
w.registerInstallHandlers() w.registerInstallHandlers()
} else { } else {
registerControlHandlers(w) registerControlHandlers(w)
@ -154,7 +154,7 @@ func newWebAPI(ctx context.Context, conf *webConfig) (w *webAPI) {
// //
// TODO(a.garipov): Adapt for HTTP/3. // TODO(a.garipov): Adapt for HTTP/3.
func webCheckPortAvailable(port uint16) (ok bool) { func webCheckPortAvailable(port uint16) (ok bool) {
if Context.web.httpsServer.server != nil { if globalContext.web.httpsServer.server != nil {
return true return true
} }
@ -224,7 +224,7 @@ func (web *webAPI) start(ctx context.Context) {
errs := make(chan error, 2) errs := make(chan error, 2)
// Use an h2c handler to support unencrypted HTTP/2, e.g. for proxies. // Use an h2c handler to support unencrypted HTTP/2, e.g. for proxies.
hdlr := h2c.NewHandler(withMiddlewares(Context.mux, limitRequestBody), &http2.Server{}) hdlr := h2c.NewHandler(withMiddlewares(globalContext.mux, limitRequestBody), &http2.Server{})
logger := web.baseLogger.With(loggerKeyServer, "plain") logger := web.baseLogger.With(loggerKeyServer, "plain")
@ -307,11 +307,11 @@ func (web *webAPI) tlsServerLoop(ctx context.Context) {
web.httpsServer.server = &http.Server{ web.httpsServer.server = &http.Server{
Addr: addr, Addr: addr,
Handler: withMiddlewares(Context.mux, limitRequestBody), Handler: withMiddlewares(globalContext.mux, limitRequestBody),
TLSConfig: &tls.Config{ TLSConfig: &tls.Config{
Certificates: []tls.Certificate{web.httpsServer.cert}, Certificates: []tls.Certificate{web.httpsServer.cert},
RootCAs: Context.tlsRoots, RootCAs: globalContext.tlsRoots,
CipherSuites: Context.tlsCipherIDs, CipherSuites: globalContext.tlsCipherIDs,
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
}, },
ReadTimeout: web.conf.ReadTimeout, ReadTimeout: web.conf.ReadTimeout,
@ -344,11 +344,11 @@ func (web *webAPI) mustStartHTTP3(ctx context.Context, address string) {
Addr: address, Addr: address,
TLSConfig: &tls.Config{ TLSConfig: &tls.Config{
Certificates: []tls.Certificate{web.httpsServer.cert}, Certificates: []tls.Certificate{web.httpsServer.cert},
RootCAs: Context.tlsRoots, RootCAs: globalContext.tlsRoots,
CipherSuites: Context.tlsCipherIDs, CipherSuites: globalContext.tlsCipherIDs,
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
}, },
Handler: withMiddlewares(Context.mux, limitRequestBody), Handler: withMiddlewares(globalContext.mux, limitRequestBody),
} }
web.logger.DebugContext(ctx, "starting http/3 server") web.logger.DebugContext(ctx, "starting http/3 server")

View File

@ -8,14 +8,14 @@ require (
github.com/gordonklaus/ineffassign v0.1.0 github.com/gordonklaus/ineffassign v0.1.0
github.com/jstemmer/go-junit-report/v2 v2.1.0 github.com/jstemmer/go-junit-report/v2 v2.1.0
github.com/kisielk/errcheck v1.8.0 github.com/kisielk/errcheck v1.8.0
github.com/securego/gosec/v2 v2.22.0 github.com/securego/gosec/v2 v2.22.1
github.com/uudashr/gocognit v1.2.0 github.com/uudashr/gocognit v1.2.0
golang.org/x/tools v0.29.0 golang.org/x/tools v0.30.0
golang.org/x/vuln v1.1.4 golang.org/x/vuln v1.1.4
honnef.co/go/tools v0.5.1 honnef.co/go/tools v0.6.0
mvdan.cc/gofumpt v0.7.0 mvdan.cc/gofumpt v0.7.0
mvdan.cc/sh/v3 v3.10.0 mvdan.cc/sh/v3 v3.10.0
mvdan.cc/unparam v0.0.0-20241226123437-447d509598f3 mvdan.cc/unparam v0.0.0-20250211232406-0e51248738fc
) )
require ( require (
@ -46,21 +46,21 @@ require (
go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/otel/trace v1.34.0 // indirect
golang.org/x/crypto v0.32.0 // indirect golang.org/x/crypto v0.33.0 // indirect
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 // indirect golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 // indirect
golang.org/x/exp/typeparams v0.0.0-20250207012021-f9890c6ad9f3 // indirect golang.org/x/exp/typeparams v0.0.0-20250218142911-aa4b98e5adaa // indirect
golang.org/x/mod v0.23.0 // indirect golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.34.0 // indirect golang.org/x/net v0.35.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/sync v0.11.0 // indirect golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect golang.org/x/sys v0.30.0 // indirect
golang.org/x/telemetry v0.0.0-20250206143958-557cf9c30e9f // indirect golang.org/x/telemetry v0.0.0-20250214215356-6f9b61db478c // indirect
golang.org/x/term v0.29.0 // indirect golang.org/x/term v0.29.0 // indirect
golang.org/x/text v0.22.0 // indirect golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.10.0 // indirect golang.org/x/time v0.10.0 // indirect
google.golang.org/api v0.220.0 // indirect google.golang.org/api v0.221.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect
google.golang.org/grpc v1.70.0 // indirect google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@ -74,8 +74,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM=
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY=
github.com/securego/gosec/v2 v2.22.0 h1:bV/Ii5YSQtbobXuIFBXrfr91l5N4qslEdFHE9E0I/10= github.com/securego/gosec/v2 v2.22.1 h1:IcBt3TpI5Y9VN1YlwjSpM2cHu0i3Iw52QM+PQeg7jN8=
github.com/securego/gosec/v2 v2.22.0/go.mod h1:sR5n3LzZ/52rn4xxRBJk38iPe/hjiA0CkVcyiAHNCrM= github.com/securego/gosec/v2 v2.22.1/go.mod h1:4bb95X4Jz7VSEPdVjC0hD7C/yR6kdeUBvCPOy9gDQ0g=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
@ -103,20 +103,20 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 h1:qNgPs5exUA+G0C96DrPwNrvLSj7GT/9D+3WMWUcUg34= golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 h1:qNgPs5exUA+G0C96DrPwNrvLSj7GT/9D+3WMWUcUg34=
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
golang.org/x/exp/typeparams v0.0.0-20250207012021-f9890c6ad9f3 h1:w2c+/ogVo2eFFhGTMddgOF7WQkdOPwjh+MRS8wUnujk= golang.org/x/exp/typeparams v0.0.0-20250218142911-aa4b98e5adaa h1:Br3+0EZZohShrmVVc85znGpxw7Ca8hsUJlrdT/JQGw8=
golang.org/x/exp/typeparams v0.0.0-20250207012021-f9890c6ad9f3/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -130,8 +130,8 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20250206143958-557cf9c30e9f h1:C8gBEOYcNZK84ngc8O5MU4ouNcnlgqsKinp/gLXK0+A= golang.org/x/telemetry v0.0.0-20250214215356-6f9b61db478c h1:cA79rhMsZfyISI2vyH5j2XJb+QKQ7w/qWJNsR1PsRCI=
golang.org/x/telemetry v0.0.0-20250206143958-557cf9c30e9f/go.mod h1:Ng+6E7PnWNge4EifZkPKeQUnm5iyAoH8qQgw3pLCiF4= golang.org/x/telemetry v0.0.0-20250214215356-6f9b61db478c/go.mod h1:bDzXkYUaHzz51CtDy5kh/jR4lgPxsdbqC37kp/dzhCc=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
@ -144,19 +144,19 @@ golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I= golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s= golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.220.0 h1:3oMI4gdBgB72WFVwE1nerDD8W3HUOS4kypK6rRLbGns= google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU=
google.golang.org/api v0.220.0/go.mod h1:26ZAlY6aN/8WgpCzjPNy18QpYaz7Zgg1h0qe1GkZEmY= google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b h1:i+d0RZa8Hs2L/MuaOQYI+krthcxdEbEM2N+Tf3kJ4zk=
google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
@ -166,13 +166,13 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= honnef.co/go/tools v0.6.0 h1:TAODvD3knlq75WCp2nyGJtT4LeRV/o7NN9nYPeVJXf8=
honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= honnef.co/go/tools v0.6.0/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
mvdan.cc/editorconfig v0.3.0 h1:D1D2wLYEYGpawWT5SpM5pRivgEgXjtEXwC9MWhEY0gQ= mvdan.cc/editorconfig v0.3.0 h1:D1D2wLYEYGpawWT5SpM5pRivgEgXjtEXwC9MWhEY0gQ=
mvdan.cc/editorconfig v0.3.0/go.mod h1:NcJHuDtNOTEJ6251indKiWuzK6+VcrMuLzGMLKBFupQ= mvdan.cc/editorconfig v0.3.0/go.mod h1:NcJHuDtNOTEJ6251indKiWuzK6+VcrMuLzGMLKBFupQ=
mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU=
mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo=
mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4= mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4=
mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY= mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY=
mvdan.cc/unparam v0.0.0-20241226123437-447d509598f3 h1:OPdLMIX29kquQXSiXmnwzHP1bc+JlH0S2l8SfVK9yWE= mvdan.cc/unparam v0.0.0-20250211232406-0e51248738fc h1:mEpjEutR7Qjdis+HqGQNdsJY/uRbH/MnyGXzLKMhDFo=
mvdan.cc/unparam v0.0.0-20241226123437-447d509598f3/go.mod h1:VQc4l9ccF55E7EwPxcGqwierxEf0KG8MRR8hJ9tpngw= mvdan.cc/unparam v0.0.0-20250211232406-0e51248738fc/go.mod h1:rthT7OuvRbaGcd5ginj6dA2oLE7YNlta9qhBNNdCaLE=