Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e667ec1b60 | ||
|
|
86df748209 | ||
|
|
ba04b38a5f | ||
|
|
318ed0dafb | ||
|
|
3b9d758510 | ||
|
|
0ef8e5cdae | ||
|
|
b3ddae7f85 | ||
|
|
995373c74b | ||
|
|
87bcb67f8f | ||
|
|
688a5d84c8 | ||
|
|
0cd25cf598 | ||
|
|
84b11ff7a5 | ||
|
|
d309a7e33c | ||
|
|
e28fdd37cd | ||
|
|
358a36b138 | ||
|
|
d4789c5d93 | ||
|
|
8d2a9ce923 | ||
|
|
29998a8959 | ||
|
|
4386e8ddde | ||
|
|
94d86eee10 |
@@ -118,7 +118,7 @@ AdGuard Home provides a lot of features out-of-the-box with no need to install a
|
||||
|
||||
It depends.
|
||||
|
||||
"DNS sinkholing" is capable of blocking a big percentage of ads, but it lacks flexibility and power of traditional ad blockers. You can get a good impression about the difference between these methods by reading [this article](https://adguard.com/en/blog/adguard-vs-adaway-dns66/). It compares AdGuard for Android (a traditional ad blocker) to hosts-level ad blockers (which are almost identical to DNS-based blockers in their capabilities). However, this level of protection is enough for some users.
|
||||
"DNS sinkholing" is capable of blocking a big percentage of ads, but it lacks flexibility and power of traditional ad blockers. You can get a good impression about the difference between these methods by reading [this article](https://adguard.com/en/blog/adguard-vs-adaway-dns66/). It compares AdGuard for Android (a traditional ad blocker) to hosts-level ad blockers (which are almost identical to DNS-based blockers in their capabilities). However, this level of protection is enough for some users. Additionally, using a DNS-based blocker can help to block ads, tracking and analytics requests on other types of devices, such as SmartTVs, smart speakers or other kinds of IoT devices (on which you can't install tradtional ad blockers).
|
||||
|
||||
<a id="how-to-build"></a>
|
||||
## How to build from source
|
||||
|
||||
@@ -17,9 +17,14 @@
|
||||
"dhcp_leases": "Locations des serveurs DHCP",
|
||||
"dhcp_static_leases": "Baux statiques DHCP",
|
||||
"dhcp_leases_not_found": "Aucune location des serveurs DHCP trouvée",
|
||||
"dhcp_config_saved": "La configuration du serveur DHCP est sauvegardée",
|
||||
"form_error_required": "Champ requis",
|
||||
"form_error_ip4_format": "Format IPv4 invalide",
|
||||
"form_error_ip6_format": "Format IPv6 invalide",
|
||||
"form_error_ip_format": "Format IPv4 invalide",
|
||||
"form_error_mac_format": "Format MAC invalide",
|
||||
"form_error_positive": "Doit être supérieur à 0",
|
||||
"form_error_negative": "Doit être égal à 0 ou supérieur",
|
||||
"dhcp_form_gateway_input": "IP de la passerelle",
|
||||
"dhcp_form_subnet_input": "Masque de sous-réseau",
|
||||
"dhcp_form_range_title": "Rangée des adresses IP",
|
||||
@@ -41,6 +46,7 @@
|
||||
"dhcp_new_static_lease": "Nouveau bail statique",
|
||||
"dhcp_static_leases_not_found": "Aucun bail statique DHCP trouvé",
|
||||
"dhcp_add_static_lease": "Ajoutez un bail statique",
|
||||
"dhcp_reset": "Voulez-vous vraiment réinitialiser votre configuration DHCP ?",
|
||||
"delete_confirm": "Voulez-vous vraiment supprimer \"{{key}}\" ?",
|
||||
"form_enter_hostname": "Saisissez un nom d'hôte",
|
||||
"error_details": "Détails des erreurs",
|
||||
@@ -240,6 +246,13 @@
|
||||
"install_devices_windows_list_6": "Sélectionnez Utiliser l’adresse de serveur DNS suivante et saisissez votre adresse de seveur AdGuard Home.",
|
||||
"install_devices_macos_list_1": "Cliquez sur l'icône Apple et allez dans les Préférences Système.",
|
||||
"install_devices_macos_list_2": "Cliquez sur Réseau.",
|
||||
"encryption_https_desc": "Si le port HTTPS est configuré, l'interface administrateur de AdGuard Home sera accessible via HTTPS et fournira aussi un service DNS-over-HTTPS sur l'emplacement '/dns-query'.",
|
||||
"encryption_chain_valid": "Chaîne de certificat valide",
|
||||
"encryption_chain_invalid": "Chaîne de certificat invalide",
|
||||
"encryption_key_valid": "Ceci est une clé privée {{type}} valide",
|
||||
"encryption_reset": "Voulez-vous vraiment réinitialiser les paramètres de chiffrement ?",
|
||||
"topline_expiring_certificate": "Votre certificat SSL est sur le point d'expirer. Mettez à jour vos <0>Paramètres de chiffrement</0>.",
|
||||
"topline_expired_certificate": "Votre certificat SSL a expiré. Mettez à jour vos <0>Paramètres de chiffrement</0>.",
|
||||
"form_error_port_range": "Saisissez une valeur de port entre 80 et 65535",
|
||||
"form_error_port_unsafe": "C'est un port non fiable",
|
||||
"form_error_equal": "Ne devrait pas être égal",
|
||||
@@ -329,13 +342,24 @@
|
||||
"blocked_services": "Services bloqués",
|
||||
"blocked_services_desc": "Permet de bloquer les sites et services populaires rapidement.",
|
||||
"blocked_services_saved": "Services bloqués enregistrés",
|
||||
"blocked_services_global": "Utiliser les services bloqués globaux",
|
||||
"blocked_service": "Service bloqué",
|
||||
"block_all": "Tout bloquer",
|
||||
"unblock_all": "Tout débloquer",
|
||||
"encryption_certificate_path": "Emplacement du certificat",
|
||||
"encryption_private_key_path": "Emplacement de la clef privée",
|
||||
"encryption_certificates_source_path": "Définir un emplacement du fichier des certificats",
|
||||
"encryption_certificates_source_content": "Coller les contenus des certificats",
|
||||
"encryption_key_source_path": "Définir un fichier pour la clef privée",
|
||||
"encryption_key_source_content": "Coller les contenus de la clef privée",
|
||||
"stats_params": "Configuration des statistiques",
|
||||
"config_successfully_saved": "Configuration sauvegardée",
|
||||
"interval_24_hour": "24 heures",
|
||||
"interval_days": "{{count}} jour",
|
||||
"interval_days_plural": "{{count}} jours",
|
||||
"domain": "Domaine",
|
||||
"answer": "Réponse",
|
||||
"filter_added_successfully": "Le filtre a été ajouté",
|
||||
"statistics_configuration": "Configuration des statistiques",
|
||||
"statistics_retention": "Maintien des statistiques",
|
||||
"statistics_retention_desc": "Si vous baissez la valeur de l'intervalle, des données seront perdues",
|
||||
@@ -347,6 +371,7 @@
|
||||
"interval_hours_plural": "{{count}} heures",
|
||||
"filters_configuration": "Configuration des filtres",
|
||||
"filters_enable": "Activer les filtres",
|
||||
"filters_interval": "Intervalle de mise à jour des filtres",
|
||||
"disabled": "Désactivé",
|
||||
"username_label": "Nom d'utilisateur",
|
||||
"username_placeholder": "Saisir un nom d'utilisateur",
|
||||
|
||||
@@ -72,12 +72,14 @@
|
||||
"stats_malware_phishing": "Blokkert skadevare/phishing",
|
||||
"stats_adult": "Blokkerte voksennettsteder",
|
||||
"stats_query_domain": "Mest forespurte domener",
|
||||
"for_last_days_plural": "de siste {{count}} dagene",
|
||||
"no_domains_found": "Ingen domener ble funnet",
|
||||
"requests_count": "Antall forespørsler",
|
||||
"top_blocked_domains": "Mest blokkerte domener",
|
||||
"top_clients": "Vanligste klienter",
|
||||
"no_clients_found": "Ingen klienter ble funnet",
|
||||
"general_statistics": "Generelle statistikker",
|
||||
"number_of_dns_query_days_plural": "Antall DNS-forespørsler som ble behandlet de siste {{count}} dagene",
|
||||
"number_of_dns_query_24_hours": "Antall DNS-forespørsler som ble behandlet de siste 24 timene",
|
||||
"number_of_dns_query_blocked_24_hours": "Antall DNS-forespørsler som ble blokkert av adblock-filtre, hosts-lister, og domene-lister",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "Antall DNS-forespørsler som ble blokkert av AdGuard sin nettlesersikkerhetsmodul",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"form_error_ip6_format": "Formato de endereço IPv6 inválido",
|
||||
"form_error_ip_format": "Formato de endereço IPv inválido",
|
||||
"form_error_mac_format": "Formato do endereço MAC inválido",
|
||||
"form_error_client_id_format": "Formato do ID de cliente inválido",
|
||||
"form_error_positive": "Deve ser maior que 0",
|
||||
"form_error_negative": "Deve ser igual ou superior a 0",
|
||||
"dhcp_form_gateway_input": "IP do gateway",
|
||||
@@ -371,6 +372,7 @@
|
||||
"rewrite_desc": "Permite configurar uma resposta personalizada do DNS para um nome de domínio específico.",
|
||||
"rewrite_applied": "Regra de reescrita aplicada",
|
||||
"dns_rewrites": "Reescritas de DNS",
|
||||
"form_domain": "Digite o nome do domínio ou wildcard",
|
||||
"form_answer": "Digite o endereço de IP ou nome de domínio",
|
||||
"form_error_domain_format": "Formato de domínio inválido",
|
||||
"form_error_answer_format": "Formato de resposta inválido",
|
||||
@@ -426,5 +428,8 @@
|
||||
"whois": "Whois",
|
||||
"filtering_rules_learn_more": "<0>Saiba mais</0> sobre como criar as suas próprias listas negras de servidores.",
|
||||
"blocked_by_response": "Bloqueado por CNAME ou IP na resposta",
|
||||
"try_again": "Tente novamente"
|
||||
"try_again": "Tente novamente",
|
||||
"domain_desc": "Digite o nome do domínio ou wildcard que pretende reescrever.",
|
||||
"example_rewrite_domain": "reescrever respostas apenas para este nome de domínio.",
|
||||
"example_rewrite_wildcard": "reescrever respostas para todos subdomínios <0>exemplo.org</0>."
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
"enabled_dhcp": "DHCP 服务器已启用",
|
||||
"disabled_dhcp": "DHCP 服务器已禁用",
|
||||
"dhcp_title": "DHCP 服务器(实验性)",
|
||||
"dhcp_description": "如果你的路由器没有提供动态主机设置协议(DHCP)设置,你可以使用 AdGuard 内置的 DHCP 服务器。",
|
||||
"dhcp_description": "如果你的路由器没有提供 DHCP (动态主机配置协议)设置,你可以使用 AdGuard 内置的 DHCP 服务器。",
|
||||
"dhcp_enable": "启用 DHCP 服务器",
|
||||
"dhcp_disable": "禁用 DHCP 服务器",
|
||||
"dhcp_not_found": "在当前网络中未检测到 DHCP 服务器。您可以安全地启用内置 DHCP 服务器。",
|
||||
"dhcp_disable": "停用 DHCP 服务器",
|
||||
"dhcp_not_found": "您可以安全地启用内置 DHCP 服务器 - 在当前网络中未检测到任何起作用的 DHCP 服务器。然而,我们鼓励您以手动方式重新检测,因为当前我们的自动检测不能确保100%准确。",
|
||||
"dhcp_found": "在当前网络中检测到 DHCP 服务器。如果启用内置的 DHCP 服务器可能不安全。",
|
||||
"dhcp_leases": "DHCP 租约",
|
||||
"dhcp_static_leases": "DHCP 静态租约",
|
||||
@@ -38,12 +38,12 @@
|
||||
"dhcp_ip_addresses": "IP 地址",
|
||||
"dhcp_table_hostname": "主机名",
|
||||
"dhcp_table_expires": "到期",
|
||||
"dhcp_warning": "如果你想要启用内置的 DHCP 服务器,请确保在当前网络中没有其它活动的 DHCP 服务器。否则,此操作可能会破坏已连接设备的网络连接!",
|
||||
"dhcp_error": "我们无法确定网络上是否有其它 DHCP 服务器。",
|
||||
"dhcp_static_ip_error": "要使用 DHCP 服务器,则必须设置静态 IP。我们无法确定此网络接口是否是使用静态 IP 配置的。请手动设置静态 IP 地址。",
|
||||
"dhcp_dynamic_ip_found": "您的系统使用了动态 IP 地址配置 <0>{{interfaceName}}</0> 接口。要使用 DHCP 服务器,则必须设置为静态 IP 地址。您当前的 IP 地址为 <0>{{ipAddress}}</0>。如您点击 开启 DHCP 按钮,则我们会自动设置此 IP 地址为静态。",
|
||||
"dhcp_lease_added": "静态租约 \"{{key}}\" 添加成功",
|
||||
"dhcp_lease_deleted": "静态租约 \"{{key}}\" 删除成功",
|
||||
"dhcp_warning": "如果你想要启用内置的 DHCP 服务器,请确保在当前网络中没有其它起作用的 DHCP 服务器。否则,此操作可能会破坏已连接设备的网络连接!",
|
||||
"dhcp_error": "我们无法确定在当前网络中是否存在其它 DHCP 服务器。",
|
||||
"dhcp_static_ip_error": "要使用 DHCP 服务器,则必须设置静态 IP 地址。我们无法确定此网络接口是否已被配置为使用静态 IP 地址。请手动为此网络接口设置静态 IP 地址。",
|
||||
"dhcp_dynamic_ip_found": "您的系统对网络接口 <0>{{interfaceName}}</0> 使用了动态 IP 地址配置。要使用 DHCP 服务器,则必须对此网络接口使用静态 IP 地址配置。此网络接口当前的 IP 地址为 <0>{{ipAddress}}</0>。如您点击 启用 DHCP 按钮,我们将自动修改此网络接口以使用静态 IP 地址配置。",
|
||||
"dhcp_lease_added": "静态租约 \"{{key}}\" 已成功添加",
|
||||
"dhcp_lease_deleted": "静态租约 \"{{key}}\" 已成功删除",
|
||||
"dhcp_new_static_lease": "新建静态租约",
|
||||
"dhcp_static_leases_not_found": "未找到 DHCP 静态租约",
|
||||
"dhcp_add_static_lease": "添加静态租约",
|
||||
@@ -108,7 +108,7 @@
|
||||
"encryption_settings": "加密设置",
|
||||
"dhcp_settings": "DHCP 设置",
|
||||
"upstream_dns": "上游 DNS 服务器",
|
||||
"upstream_dns_hint": "如果此处留空,AdGuard Home 将会使用 <a href='https://www.quad9.net/' target='_blank'>Quad9</a> 作为上游 DNS。如果想要使用使用 DNS over TLS,请以 tls:// 为开头。",
|
||||
"upstream_dns_hint": "如果此处留空,AdGuard Home 将会使用 <a href='https://www.quad9.net/' target='_blank'>Cloudflare DNS</a> 作为上游 DNS。如果想要使用 DNS over TLS,请以 tls:// 为开头。",
|
||||
"test_upstream_btn": "测试上游 DNS",
|
||||
"upstreams": "上游服务器",
|
||||
"apply_btn": "应用",
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
"dhcp_disable": "禁用動態主機設定協定(DHCP)伺服器",
|
||||
"dhcp_not_found": "啟用內建的動態主機設定協定(DHCP)伺服器為安全的 - 於該網路上,我們未發現任何現行的 DHCP 伺服器。然而,我們鼓勵您手動地重新檢查它,因為我們的自動之測試目前不予 100% 保證。",
|
||||
"dhcp_found": "於該網路上,一個現行的動態主機設定協定(DHCP)伺服器被發現。啟用內建的 DHCP 伺服器為不安全的。",
|
||||
"dhcp_leases": "動態主機設定協定(DHCP)租賃",
|
||||
"dhcp_static_leases": "動態主機設定協定(DHCP)靜態租賃",
|
||||
"dhcp_leases_not_found": "無已發現之動態主機設定協定(DHCP)租賃",
|
||||
"dhcp_leases": "動態主機設定協定(DHCP)租約",
|
||||
"dhcp_static_leases": "動態主機設定協定(DHCP)靜態租約",
|
||||
"dhcp_leases_not_found": "無已發現之動態主機設定協定(DHCP)租約",
|
||||
"dhcp_config_saved": "動態主機設定協定(DHCP)配置被成功地儲存",
|
||||
"form_error_required": "必填的欄位",
|
||||
"form_error_ip4_format": "無效的 IPv4 格式",
|
||||
@@ -25,14 +25,14 @@
|
||||
"form_error_mac_format": "無效的媒體存取控制(MAC)格式",
|
||||
"form_error_client_id_format": "無效的用戶端 ID 格式",
|
||||
"form_error_positive": "必須大於 0",
|
||||
"form_error_negative": "必須等於 0 或更大",
|
||||
"form_error_negative": "必須等於或大於 0",
|
||||
"dhcp_form_gateway_input": "閘道 IP",
|
||||
"dhcp_form_subnet_input": "子網路遮罩",
|
||||
"dhcp_form_range_title": "IP 位址範圍",
|
||||
"dhcp_form_range_start": "範圍開始",
|
||||
"dhcp_form_range_end": "範圍結束",
|
||||
"dhcp_form_lease_title": "動態主機設定協定(DHCP)租賃時間(以秒數)",
|
||||
"dhcp_form_lease_input": "租賃持續時間",
|
||||
"dhcp_form_lease_title": "動態主機設定協定(DHCP)租約時間(以秒數)",
|
||||
"dhcp_form_lease_input": "租約期間",
|
||||
"dhcp_interface_select": "選擇動態主機設定協定(DHCP)介面",
|
||||
"dhcp_hardware_address": "硬體位址",
|
||||
"dhcp_ip_addresses": "IP 位址",
|
||||
@@ -42,11 +42,11 @@
|
||||
"dhcp_error": "我們無法確定在該網路是否有另外的動態主機設定協定(DHCP)伺服器。",
|
||||
"dhcp_static_ip_error": "為了使用動態主機設定協定(DHCP)伺服器,靜態 IP 位址必須被設定。我們未能確定該網路介面是否被配置使用靜態 IP 位址。請手動地設定靜態 IP 位址。",
|
||||
"dhcp_dynamic_ip_found": "您的系統使用動態 IP 位址配置供介面 <0>{{interfaceName}}</0>。為了使用動態主機設定協定(DHCP)伺服器,靜態 IP 位址必須被設定。您現行的 IP 位址為 <0>{{ipAddress}}</0>。如果您按啟用 DHCP 按鈕,我們將自動地設定此 IP 位址作為靜態。",
|
||||
"dhcp_lease_added": "靜態租賃 \"{{key}}\" 被成功地加入",
|
||||
"dhcp_lease_deleted": "靜態租賃 \"{{key}}\" 被成功地刪除",
|
||||
"dhcp_new_static_lease": "新的靜態租賃",
|
||||
"dhcp_static_leases_not_found": "無已發現之動態主機設定協定(DHCP)靜態租賃",
|
||||
"dhcp_add_static_lease": "增加靜態租賃",
|
||||
"dhcp_lease_added": "靜態租約 \"{{key}}\" 被成功地加入",
|
||||
"dhcp_lease_deleted": "靜態租約 \"{{key}}\" 被成功地刪除",
|
||||
"dhcp_new_static_lease": "新的靜態租約",
|
||||
"dhcp_static_leases_not_found": "無已發現之動態主機設定協定(DHCP)靜態租約",
|
||||
"dhcp_add_static_lease": "增加靜態租約",
|
||||
"dhcp_reset": "您確定您想要重置動態主機設定協定(DHCP)配置嗎?",
|
||||
"delete_confirm": "您確定您想要刪除 \"{{key}}\" 嗎?",
|
||||
"form_enter_hostname": "輸入主機名稱",
|
||||
|
||||
@@ -44,7 +44,7 @@ const checkFilteredLogs = async (data, filter, dispatch, total) => {
|
||||
|
||||
try {
|
||||
const additionalLogs = await getLogsWithParams({ older_than: oldest, filter });
|
||||
if (additionalLogs.logs.length > 0) {
|
||||
if (additionalLogs.oldest.length > 0) {
|
||||
return await checkFilteredLogs(additionalLogs, filter, dispatch, {
|
||||
logs: [...totalData.logs, ...additionalLogs.logs],
|
||||
oldest: additionalLogs.oldest,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dnsfilter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
@@ -538,24 +537,15 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16) (Result, error) {
|
||||
|
||||
} else if hostRule, ok := rule.(*rules.HostRule); ok {
|
||||
|
||||
res.IP = net.IP{}
|
||||
if qtype == dns.TypeA && hostRule.IP.To4() != nil {
|
||||
// either IPv4 or IPv4-mapped IPv6 address
|
||||
res.IP = hostRule.IP.To4()
|
||||
return res, nil
|
||||
|
||||
} else if qtype == dns.TypeAAAA {
|
||||
ip4 := hostRule.IP.To4()
|
||||
if ip4 == nil {
|
||||
res.IP = hostRule.IP
|
||||
return res, nil
|
||||
}
|
||||
if bytes.Equal(ip4, []byte{0, 0, 0, 0}) {
|
||||
// send IP="::" response for a rule "0.0.0.0 blockdomain"
|
||||
res.IP = net.IPv6zero
|
||||
return res, nil
|
||||
}
|
||||
} else if qtype == dns.TypeAAAA && hostRule.IP.To4() == nil {
|
||||
res.IP = hostRule.IP
|
||||
}
|
||||
continue
|
||||
return res, nil
|
||||
|
||||
} else {
|
||||
log.Tracef("Rule type is unsupported: '%s' list_id: %d",
|
||||
|
||||
@@ -98,7 +98,7 @@ func (d *Dnsfilter) checkMatchEmpty(t *testing.T, hostname string) {
|
||||
func TestEtcHostsMatching(t *testing.T) {
|
||||
addr := "216.239.38.120"
|
||||
addr6 := "::1"
|
||||
text := fmt.Sprintf(" %s google.com www.google.com # enforce google's safesearch \n%s google.com\n0.0.0.0 block.com\n",
|
||||
text := fmt.Sprintf(" %s google.com www.google.com # enforce google's safesearch \n%s ipv6.com\n0.0.0.0 block.com\n",
|
||||
addr, addr6)
|
||||
filters := make(map[int]string)
|
||||
filters[0] = text
|
||||
@@ -110,12 +110,19 @@ func TestEtcHostsMatching(t *testing.T) {
|
||||
d.checkMatchEmpty(t, "subdomain.google.com")
|
||||
d.checkMatchEmpty(t, "example.org")
|
||||
|
||||
// IPv6 address
|
||||
d.checkMatchIP(t, "google.com", addr6, dns.TypeAAAA)
|
||||
|
||||
// block both IPv4 and IPv6
|
||||
// IPv4
|
||||
d.checkMatchIP(t, "block.com", "0.0.0.0", dns.TypeA)
|
||||
d.checkMatchIP(t, "block.com", "::", dns.TypeAAAA)
|
||||
|
||||
// ...but empty IPv6
|
||||
ret, err := d.CheckHost("block.com", dns.TypeAAAA, &setts)
|
||||
assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
|
||||
|
||||
// IPv6
|
||||
d.checkMatchIP(t, "ipv6.com", addr6, dns.TypeAAAA)
|
||||
|
||||
// ...but empty IPv4
|
||||
ret, err = d.CheckHost("ipv6.com", dns.TypeA, &setts)
|
||||
assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
|
||||
}
|
||||
|
||||
// SAFE BROWSING
|
||||
|
||||
@@ -445,7 +445,15 @@ func (s *Server) handleDNSRequest(p *proxy.Proxy, d *proxy.DNSContext) error {
|
||||
// A better approach is for proxy.Stop() to wait until all its workers exit,
|
||||
// but this would require the Upstream interface to have Close() function
|
||||
// (to prevent from hanging while waiting for unresponsive DNS server to respond).
|
||||
res, err := s.filterDNSRequest(d)
|
||||
|
||||
var setts *dnsfilter.RequestFilteringSettings
|
||||
var err error
|
||||
res := &dnsfilter.Result{}
|
||||
protectionEnabled := s.conf.ProtectionEnabled && s.dnsFilter != nil
|
||||
if protectionEnabled {
|
||||
setts = s.getClientRequestFilteringSettings(d)
|
||||
res, err = s.filterDNSRequest(d, setts)
|
||||
}
|
||||
s.RUnlock()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -486,9 +494,9 @@ func (s *Server) handleDNSRequest(p *proxy.Proxy, d *proxy.DNSContext) error {
|
||||
d.Res.Answer = answer
|
||||
}
|
||||
|
||||
} else if res.Reason != dnsfilter.NotFilteredWhiteList {
|
||||
} else if res.Reason != dnsfilter.NotFilteredWhiteList && protectionEnabled {
|
||||
origResp2 := d.Res
|
||||
res, err = s.filterDNSResponse(d)
|
||||
res, err = s.filterDNSResponse(d, setts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -602,12 +610,7 @@ func (s *Server) getClientRequestFilteringSettings(d *proxy.DNSContext) *dnsfilt
|
||||
}
|
||||
|
||||
// filterDNSRequest applies the dnsFilter and sets d.Res if the request was filtered
|
||||
func (s *Server) filterDNSRequest(d *proxy.DNSContext) (*dnsfilter.Result, error) {
|
||||
if !s.conf.ProtectionEnabled || s.dnsFilter == nil {
|
||||
return &dnsfilter.Result{}, nil
|
||||
}
|
||||
|
||||
setts := s.getClientRequestFilteringSettings(d)
|
||||
func (s *Server) filterDNSRequest(d *proxy.DNSContext, setts *dnsfilter.RequestFilteringSettings) (*dnsfilter.Result, error) {
|
||||
req := d.Req
|
||||
host := strings.TrimSuffix(req.Question[0].Name, ".")
|
||||
res, err := s.dnsFilter.CheckHost(host, d.Req.Question[0].Qtype, setts)
|
||||
@@ -648,7 +651,7 @@ func (s *Server) filterDNSRequest(d *proxy.DNSContext) (*dnsfilter.Result, error
|
||||
|
||||
// If response contains CNAME, A or AAAA records, we apply filtering to each canonical host name or IP address.
|
||||
// If this is a match, we set a new response in d.Res and return.
|
||||
func (s *Server) filterDNSResponse(d *proxy.DNSContext) (*dnsfilter.Result, error) {
|
||||
func (s *Server) filterDNSResponse(d *proxy.DNSContext, setts *dnsfilter.RequestFilteringSettings) (*dnsfilter.Result, error) {
|
||||
for _, a := range d.Res.Answer {
|
||||
host := ""
|
||||
|
||||
@@ -676,7 +679,6 @@ func (s *Server) filterDNSResponse(d *proxy.DNSContext) (*dnsfilter.Result, erro
|
||||
s.RUnlock()
|
||||
continue
|
||||
}
|
||||
setts := s.getClientRequestFilteringSettings(d)
|
||||
res, err := s.dnsFilter.CheckHostRules(host, d.Req.Question[0].Qtype, setts)
|
||||
s.RUnlock()
|
||||
|
||||
@@ -788,7 +790,8 @@ func (s *Server) genAAAAAnswer(req *dns.Msg, ip net.IP) *dns.AAAA {
|
||||
func (s *Server) genResponseWithIP(req *dns.Msg, ip net.IP) *dns.Msg {
|
||||
if req.Question[0].Qtype == dns.TypeA && ip.To4() != nil {
|
||||
return s.genARecord(req, ip.To4())
|
||||
} else if req.Question[0].Qtype == dns.TypeAAAA && ip.To4() == nil {
|
||||
} else if req.Question[0].Qtype == dns.TypeAAAA &&
|
||||
len(ip) == net.IPv6len && ip.To4() == nil {
|
||||
return s.genAAAARecord(req, ip)
|
||||
}
|
||||
|
||||
|
||||
@@ -340,6 +340,22 @@ var testIPv4 = map[string][]net.IP{
|
||||
"example.org.": {{127, 0, 0, 255}},
|
||||
}
|
||||
|
||||
func TestBlockCNAMEProtectionEnabled(t *testing.T) {
|
||||
s := createTestServer(t)
|
||||
testUpstm := &testUpstream{testCNAMEs, testIPv4, nil}
|
||||
s.conf.ProtectionEnabled = false
|
||||
err := s.startWithUpstream(testUpstm)
|
||||
assert.True(t, err == nil)
|
||||
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
|
||||
|
||||
// 'badhost' has a canonical name 'null.example.org' which is blocked by filters:
|
||||
// but protection is disabled - response is NOT blocked
|
||||
req := createTestMessage("badhost.")
|
||||
reply, err := dns.Exchange(req, addr.String())
|
||||
assert.True(t, err == nil)
|
||||
assert.True(t, reply.Rcode == dns.RcodeSuccess)
|
||||
}
|
||||
|
||||
func TestBlockCNAME(t *testing.T) {
|
||||
s := createTestServer(t)
|
||||
testUpstm := &testUpstream{testCNAMEs, testIPv4, nil}
|
||||
@@ -349,35 +365,23 @@ func TestBlockCNAME(t *testing.T) {
|
||||
|
||||
// 'badhost' has a canonical name 'null.example.org' which is blocked by filters:
|
||||
// response is blocked
|
||||
req := dns.Msg{}
|
||||
req.Id = dns.Id()
|
||||
req.Question = []dns.Question{
|
||||
{Name: "badhost.", Qtype: dns.TypeA, Qclass: dns.ClassINET},
|
||||
}
|
||||
reply, err := dns.Exchange(&req, addr.String())
|
||||
req := createTestMessage("badhost.")
|
||||
reply, err := dns.Exchange(req, addr.String())
|
||||
assert.True(t, err == nil)
|
||||
assert.True(t, reply.Rcode == dns.RcodeNameError)
|
||||
|
||||
// 'whitelist.example.org' has a canonical name 'null.example.org' which is blocked by filters
|
||||
// but 'whitelist.example.org' is in a whitelist:
|
||||
// response isn't blocked
|
||||
req = dns.Msg{}
|
||||
req.Id = dns.Id()
|
||||
req.Question = []dns.Question{
|
||||
{Name: "whitelist.example.org.", Qtype: dns.TypeA, Qclass: dns.ClassINET},
|
||||
}
|
||||
reply, err = dns.Exchange(&req, addr.String())
|
||||
req = createTestMessage("whitelist.example.org.")
|
||||
reply, err = dns.Exchange(req, addr.String())
|
||||
assert.True(t, err == nil)
|
||||
assert.True(t, reply.Rcode == dns.RcodeSuccess)
|
||||
|
||||
// 'example.org' has a canonical name 'cname1' with IP 127.0.0.255 which is blocked by filters:
|
||||
// response is blocked
|
||||
req = dns.Msg{}
|
||||
req.Id = dns.Id()
|
||||
req.Question = []dns.Question{
|
||||
{Name: "example.org.", Qtype: dns.TypeA, Qclass: dns.ClassINET},
|
||||
}
|
||||
reply, err = dns.Exchange(&req, addr.String())
|
||||
req = createTestMessage("example.org.")
|
||||
reply, err = dns.Exchange(req, addr.String())
|
||||
assert.True(t, err == nil)
|
||||
assert.True(t, reply.Rcode == dns.RcodeNameError)
|
||||
|
||||
|
||||
6
go.mod
6
go.mod
@@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/AdguardTeam/dnsproxy v0.23.5
|
||||
github.com/AdguardTeam/dnsproxy v0.23.6
|
||||
github.com/AdguardTeam/golibs v0.3.0
|
||||
github.com/AdguardTeam/urlfilter v0.7.2
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
@@ -18,8 +18,8 @@ require (
|
||||
github.com/sparrc/go-ping v0.0.0-20181106165434-ef3ab45e41b0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
go.etcd.io/bbolt v1.3.3 // indirect
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8
|
||||
gopkg.in/yaml.v2 v2.2.3
|
||||
)
|
||||
|
||||
12
go.sum
12
go.sum
@@ -1,5 +1,5 @@
|
||||
github.com/AdguardTeam/dnsproxy v0.23.5 h1:allfgFioe0e6QvSqKVeS0ZQAo9jHR+2XdNuT1isK7og=
|
||||
github.com/AdguardTeam/dnsproxy v0.23.5/go.mod h1:2qy8rpdfBzKgMPxkHmPdaNK4XZJ322v4KtVGI8s8Bn0=
|
||||
github.com/AdguardTeam/dnsproxy v0.23.6 h1:HAiY9muZyc2sNThQjR3M3rLloh1gKIhEuIAftmuae5w=
|
||||
github.com/AdguardTeam/dnsproxy v0.23.6/go.mod h1:2qy8rpdfBzKgMPxkHmPdaNK4XZJ322v4KtVGI8s8Bn0=
|
||||
github.com/AdguardTeam/golibs v0.2.4 h1:GUssokegKxKF13K67Pgl0ZGwqHjNN6X7sep5ik6ORdY=
|
||||
github.com/AdguardTeam/golibs v0.2.4/go.mod h1:R3M+mAg3nWG4X4Hsag5eef/TckHFH12ZYhK7AzJc8+U=
|
||||
github.com/AdguardTeam/golibs v0.3.0 h1:1zO8ulGEOdXDDM++Ap4sYfTsT/Z4tZBZtiWSA4ykcOU=
|
||||
@@ -145,8 +145,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191001170739-f9e2070545dc h1:KyTYo8xkh/2WdbFLUyQwBS0Jfn3qfZ9QmuPbok2oENE=
|
||||
golang.org/x/crypto v0.0.0-20191001170739-f9e2070545dc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915 h1:aJ0ex187qoXrJHPo8ZasVTASQB7llQP6YeNzgDALPRk=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190119204137-ed066c81e75e h1:MDa3fSUp6MdYHouVmCCNz/zaH2a6CRcxY3VhT/K3C5Q=
|
||||
@@ -181,8 +181,8 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY=
|
||||
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
|
||||
@@ -32,12 +32,16 @@ type Client struct {
|
||||
SafeSearchEnabled bool
|
||||
SafeBrowsingEnabled bool
|
||||
ParentalEnabled bool
|
||||
WhoisInfo [][]string // [[key,value], ...]
|
||||
|
||||
UseOwnBlockedServices bool // false: use global settings
|
||||
BlockedServices []string
|
||||
|
||||
Upstreams []string // list of upstream servers to be used for the client's requests
|
||||
// Upstream objects:
|
||||
// nil: not yet initialized
|
||||
// not nil, but empty: initialized, no good upstreams
|
||||
// not nil, not empty: Upstreams ready to be used
|
||||
upstreamObjects []upstream.Upstream
|
||||
}
|
||||
|
||||
type clientSource uint
|
||||
@@ -63,12 +67,7 @@ type clientsContainer struct {
|
||||
list map[string]*Client // name -> client
|
||||
idIndex map[string]*Client // IP -> client
|
||||
ipHost map[string]*ClientHost // IP -> Hostname
|
||||
|
||||
// cache for Upstream instances that are used in the case
|
||||
// when custom DNS servers are configured for a client
|
||||
upstreamsCache map[string][]upstream.Upstream // name -> []Upstream
|
||||
|
||||
lock sync.Mutex
|
||||
lock sync.Mutex
|
||||
|
||||
// dhcpServer is used for looking up clients IP addresses by MAC addresses
|
||||
dhcpServer *dhcpd.Server
|
||||
@@ -85,7 +84,6 @@ func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.
|
||||
clients.list = make(map[string]*Client)
|
||||
clients.idIndex = make(map[string]*Client)
|
||||
clients.ipHost = make(map[string]*ClientHost)
|
||||
clients.upstreamsCache = make(map[string][]upstream.Upstream)
|
||||
clients.dhcpServer = dhcpServer
|
||||
clients.addFromConfig(objects)
|
||||
|
||||
@@ -102,8 +100,8 @@ type clientObject struct {
|
||||
UseGlobalSettings bool `yaml:"use_global_settings"`
|
||||
FilteringEnabled bool `yaml:"filtering_enabled"`
|
||||
ParentalEnabled bool `yaml:"parental_enabled"`
|
||||
SafeSearchEnabled bool `yaml:"safebrowsing_enabled"`
|
||||
SafeBrowsingEnabled bool `yaml:"safesearch_enabled"`
|
||||
SafeSearchEnabled bool `yaml:"safesearch_enabled"`
|
||||
SafeBrowsingEnabled bool `yaml:"safebrowsing_enabled"`
|
||||
|
||||
UseGlobalBlockedServices bool `yaml:"use_global_blocked_services"`
|
||||
BlockedServices []string `yaml:"blocked_services"`
|
||||
@@ -199,6 +197,12 @@ func (clients *clientsContainer) Find(ip string) (Client, bool) {
|
||||
return clients.findByIP(ip)
|
||||
}
|
||||
|
||||
func upstreamArrayCopy(a []upstream.Upstream) []upstream.Upstream {
|
||||
a2 := make([]upstream.Upstream, len(a))
|
||||
copy(a2, a)
|
||||
return a2
|
||||
}
|
||||
|
||||
// FindUpstreams looks for upstreams configured for the client
|
||||
// If no client found for this IP, or if no custom upstreams are configured,
|
||||
// this method returns nil
|
||||
@@ -211,31 +215,22 @@ func (clients *clientsContainer) FindUpstreams(ip string) []upstream.Upstream {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(c.Upstreams) == 0 {
|
||||
if c.upstreamObjects == nil {
|
||||
c.upstreamObjects = make([]upstream.Upstream, 0)
|
||||
for _, us := range c.Upstreams {
|
||||
u, err := upstream.AddressToUpstream(us, upstream.Options{Timeout: dnsforward.DefaultTimeout})
|
||||
if err != nil {
|
||||
log.Error("upstream.AddressToUpstream: %s: %s", us, err)
|
||||
continue
|
||||
}
|
||||
c.upstreamObjects = append(c.upstreamObjects, u)
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.upstreamObjects) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
upstreams, ok := clients.upstreamsCache[c.Name]
|
||||
if ok {
|
||||
return upstreams
|
||||
}
|
||||
|
||||
for _, us := range c.Upstreams {
|
||||
u, err := upstream.AddressToUpstream(us, upstream.Options{Timeout: dnsforward.DefaultTimeout})
|
||||
if err != nil {
|
||||
log.Error("upstream.AddressToUpstream: %s: %s", us, err)
|
||||
continue
|
||||
}
|
||||
upstreams = append(upstreams, u)
|
||||
}
|
||||
|
||||
if len(upstreams) == 0 {
|
||||
clients.upstreamsCache[c.Name] = nil
|
||||
} else {
|
||||
clients.upstreamsCache[c.Name] = upstreams
|
||||
}
|
||||
|
||||
return upstreams
|
||||
return upstreamArrayCopy(c.upstreamObjects)
|
||||
}
|
||||
|
||||
// Find searches for a client by IP (and does not lock anything)
|
||||
@@ -366,17 +361,6 @@ func (clients *clientsContainer) Add(c Client) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// remove auto-clients with the same IP address, keeping WHOIS info if possible
|
||||
for _, id := range c.IDs {
|
||||
ch, ok := clients.ipHost[id]
|
||||
if ok {
|
||||
if len(c.WhoisInfo) == 0 {
|
||||
c.WhoisInfo = ch.WhoisInfo
|
||||
}
|
||||
delete(clients.ipHost, id)
|
||||
}
|
||||
}
|
||||
|
||||
// update Name index
|
||||
clients.list[c.Name] = &c
|
||||
|
||||
@@ -402,9 +386,6 @@ func (clients *clientsContainer) Del(name string) bool {
|
||||
// update Name index
|
||||
delete(clients.list, name)
|
||||
|
||||
// update upstreams cache
|
||||
delete(clients.upstreamsCache, name)
|
||||
|
||||
// update ID index
|
||||
for _, id := range c.IDs {
|
||||
delete(clients.idIndex, id)
|
||||
@@ -468,12 +449,12 @@ func (clients *clientsContainer) Update(name string, c Client) error {
|
||||
|
||||
// update Name index
|
||||
if old.Name != c.Name {
|
||||
delete(clients.list, old.Name)
|
||||
clients.list[c.Name] = old
|
||||
}
|
||||
|
||||
// update upstreams cache
|
||||
delete(clients.upstreamsCache, name)
|
||||
delete(clients.upstreamsCache, old.Name)
|
||||
c.upstreamObjects = nil
|
||||
|
||||
*old = c
|
||||
return nil
|
||||
@@ -513,12 +494,6 @@ func (clients *clientsContainer) AddHost(ip, host string, source clientSource) (
|
||||
clients.lock.Lock()
|
||||
defer clients.lock.Unlock()
|
||||
|
||||
// check existing clients first
|
||||
_, ok := clients.findByIP(ip)
|
||||
if ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check auto-clients index
|
||||
ch, ok := clients.ipHost[ip]
|
||||
if ok && ch.Source > source {
|
||||
|
||||
@@ -13,10 +13,8 @@ type clientJSON struct {
|
||||
UseGlobalSettings bool `json:"use_global_settings"`
|
||||
FilteringEnabled bool `json:"filtering_enabled"`
|
||||
ParentalEnabled bool `json:"parental_enabled"`
|
||||
SafeSearchEnabled bool `json:"safebrowsing_enabled"`
|
||||
SafeBrowsingEnabled bool `json:"safesearch_enabled"`
|
||||
|
||||
WhoisInfo map[string]interface{} `json:"whois_info"`
|
||||
SafeSearchEnabled bool `json:"safesearch_enabled"`
|
||||
SafeBrowsingEnabled bool `json:"safebrowsing_enabled"`
|
||||
|
||||
UseGlobalBlockedServices bool `json:"use_global_blocked_services"`
|
||||
BlockedServices []string `json:"blocked_services"`
|
||||
@@ -116,11 +114,6 @@ func clientToJSON(c *Client) clientJSON {
|
||||
|
||||
Upstreams: c.Upstreams,
|
||||
}
|
||||
|
||||
cj.WhoisInfo = make(map[string]interface{})
|
||||
for _, wi := range c.WhoisInfo {
|
||||
cj.WhoisInfo[wi[0]] = wi[1]
|
||||
}
|
||||
return cj
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ func TestClients(t *testing.T) {
|
||||
c = Client{}
|
||||
c, b = clients.Find("1.1.1.2")
|
||||
assert.True(t, b && c.Name == "client1-renamed" && c.IDs[0] == "1.1.1.2" && c.UseOwnSettings)
|
||||
assert.True(t, clients.list["client1"] == nil)
|
||||
|
||||
// failed remove - no such name
|
||||
if clients.Del("client3") {
|
||||
@@ -167,18 +168,18 @@ func TestClientsWhois(t *testing.T) {
|
||||
clients.SetWhoisInfo("1.1.1.1", whois)
|
||||
assert.True(t, clients.ipHost["1.1.1.1"].WhoisInfo[0][1] == "orgname-val")
|
||||
|
||||
// Check that we cannot set whois info on existing client
|
||||
// Check that we cannot set whois info on a manually-added client
|
||||
c = Client{
|
||||
IDs: []string{"1.1.1.2"},
|
||||
Name: "client1",
|
||||
}
|
||||
_, _ = clients.Add(c)
|
||||
clients.SetWhoisInfo("1.1.1.2", whois)
|
||||
assert.Nil(t, clients.idIndex["1.1.1.2"].WhoisInfo)
|
||||
assert.True(t, clients.ipHost["1.1.1.2"] == nil)
|
||||
_ = clients.Del("client1")
|
||||
}
|
||||
|
||||
func TestClientsAddExistingHost(t *testing.T) {
|
||||
func TestClientsAddExisting(t *testing.T) {
|
||||
var c Client
|
||||
clients := clientsContainer{}
|
||||
clients.testing = true
|
||||
@@ -197,9 +198,9 @@ func TestClientsAddExistingHost(t *testing.T) {
|
||||
assert.True(t, ok)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// try adding a duplicate by IP
|
||||
// add an auto-client with the same IP - it's allowed
|
||||
ok, err = clients.AddHost("1.1.1.1", "test", ClientSourceRDNS)
|
||||
assert.False(t, ok)
|
||||
assert.True(t, ok)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// now some more complicated stuff
|
||||
@@ -217,13 +218,21 @@ func TestClientsAddExistingHost(t *testing.T) {
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
// try adding a duplicate IP which for a Mac-based client
|
||||
ok, err = clients.AddHost(testIP, "test", ClientSourceRDNS)
|
||||
assert.False(t, ok)
|
||||
// add a new client with the same IP as for a client with MAC
|
||||
c = Client{
|
||||
IDs: []string{testIP},
|
||||
Name: "client2",
|
||||
}
|
||||
ok, err = clients.Add(c)
|
||||
assert.True(t, ok)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// don't allow duplicates by CIDR
|
||||
ok, err = clients.AddHost("2.2.2.2", "test", ClientSourceRDNS)
|
||||
assert.False(t, ok)
|
||||
// add a new client with the IP from the client1's IP range
|
||||
c = Client{
|
||||
IDs: []string{"2.2.2.2"},
|
||||
Name: "client3",
|
||||
}
|
||||
ok, err = clients.Add(c)
|
||||
assert.True(t, ok)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
@@ -561,7 +561,9 @@ func decode(ent *logEntry, str string) {
|
||||
}
|
||||
switch k {
|
||||
case "IP":
|
||||
ent.IP = v
|
||||
if len(ent.IP) == 0 {
|
||||
ent.IP = v
|
||||
}
|
||||
case "T":
|
||||
ent.Time, err = time.Parse(time.RFC3339, v)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user