Pull request: 3157 excessive ptrs

Merge in DNS/adguard-home from 3157-excessive-ptrs to master

Updates #3157.

Squashed commit of the following:

commit 6803988240dca2f147bb80a5b3f78d7749d2fa14
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 19 14:50:01 2022 +0300

    aghnet: and again

commit 1a7f4d1dbc8fd4d3ae620349917526a75fa71b47
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 19 14:49:20 2022 +0300

    aghnet: docs again

commit d88da1fc7135f3cd03aff10b02d9957c8ffdfd30
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 19 14:47:36 2022 +0300

    aghnet: imp docs

commit c45dbc7800e882c6c4110aab640c32b03046f89a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 19 14:41:19 2022 +0300

    aghnet: keep alphabetical order

commit b61781785d096ef43f60fb4f1905a4ed3cdf7c68
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 19 13:50:56 2022 +0300

    aghnet: imp code quality

commit 578dbd71ed2f2089c69343d7d4bf8bbc29150ace
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 12 17:02:38 2022 +0300

    aghnet: imp arp container
This commit is contained in:
Eugene Burkov 2022-04-19 15:01:49 +03:00
parent 57171f0a61
commit 12ee287d0b
8 changed files with 46 additions and 34 deletions

View File

@ -87,10 +87,15 @@ In this release, the schema version has changed from 12 to 13.
- Go 1.17 support. v0.109.0 will require at least Go 1.18 to build. - Go 1.17 support. v0.109.0 will require at least Go 1.18 to build.
### Fixed
- ARP tables refreshing process causing excessive PTR requests ([#3157]).
[#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730 [#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993 [#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057 [#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
[#3142]: https://github.com/AdguardTeam/AdGuardHome/issues/3142 [#3142]: https://github.com/AdguardTeam/AdGuardHome/issues/3142
[#3157]: https://github.com/AdguardTeam/AdGuardHome/issues/3157
[#3367]: https://github.com/AdguardTeam/AdGuardHome/issues/3367 [#3367]: https://github.com/AdguardTeam/AdGuardHome/issues/3367
[#3381]: https://github.com/AdguardTeam/AdGuardHome/issues/3381 [#3381]: https://github.com/AdguardTeam/AdGuardHome/issues/3381
[#3503]: https://github.com/AdguardTeam/AdGuardHome/issues/3503 [#3503]: https://github.com/AdguardTeam/AdGuardHome/issues/3503

View File

@ -13,19 +13,24 @@ import (
"github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/netutil"
) )
func newARPDB() *cmdARPDB { func newARPDB() (arp *cmdARPDB) {
return &cmdARPDB{ return &cmdARPDB{
parse: parseArpA, parse: parseArpA,
ns: &neighs{ ns: &neighs{
mu: &sync.RWMutex{}, mu: &sync.RWMutex{},
ns: make([]Neighbor, 0), ns: make([]Neighbor, 0),
}, },
cmd: "arp", cmd: "arp",
args: []string{"-a"}, // Use -n flag to avoid resolving the hostnames of the neighbors. By
// default ARP attempts to resolve the hostnames via DNS. See man 8
// arp.
//
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
args: []string{"-a", "-n"},
} }
} }
// parseArpA parses the output of the "arp -a" command on macOS and FreeBSD. // parseArpA parses the output of the "arp -a -n" command on macOS and FreeBSD.
// The expected input format: // The expected input format:
// //
// host.name (192.168.0.1) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet] // host.name (192.168.0.1) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet]

View File

@ -38,12 +38,17 @@ func newARPDB() (arp *arpdbs) {
fsys: rootDirFS, fsys: rootDirFS,
filename: "proc/net/arp", filename: "proc/net/arp",
}, },
// Then, try "arp -a". // Then, try "arp -a -n".
&cmdARPDB{ &cmdARPDB{
parse: parseF, parse: parseF,
ns: ns, ns: ns,
cmd: "arp", cmd: "arp",
args: []string{"-a"}, // Use -n flag to avoid resolving the hostnames of the neighbors.
// By default ARP attempts to resolve the hostnames via DNS. See
// man 8 arp.
//
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
args: []string{"-a", "-n"},
}, },
// Finally, try "ip neigh". // Finally, try "ip neigh".
&cmdARPDB{ &cmdARPDB{
@ -109,11 +114,11 @@ func (arp *fsysARPDB) Neighbors() (ns []Neighbor) {
return arp.ns.clone() return arp.ns.clone()
} }
// parseArpAWrt parses the output of the "arp -a" command on OpenWrt. The // parseArpAWrt parses the output of the "arp -a -n" command on OpenWrt. The
// expected input format: // expected input format:
// //
// IP address HW type Flags HW address Mask Device // IP address HW type Flags HW address Mask Device
// 192.168.11.98 0x1 0x2 5a:92:df:a9:7e:28 * wan // 192.168.11.98 0x1 0x2 5a:92:df:a9:7e:28 * wan
// //
func parseArpAWrt(sc *bufio.Scanner, lenHint int) (ns []Neighbor) { func parseArpAWrt(sc *bufio.Scanner, lenHint int) (ns []Neighbor) {
if !sc.Scan() { if !sc.Scan() {
@ -153,8 +158,8 @@ func parseArpAWrt(sc *bufio.Scanner, lenHint int) (ns []Neighbor) {
return ns return ns
} }
// parseArpA parses the output of the "arp -a" command on Linux. The expected // parseArpA parses the output of the "arp -a -n" command on Linux. The
// input format: // expected input format:
// //
// hostname (192.168.1.1) at ab:cd:ef:ab:cd:ef [ether] on enp0s3 // hostname (192.168.1.1) at ab:cd:ef:ab:cd:ef [ether] on enp0s3
// //

View File

@ -12,20 +12,25 @@ import (
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
) )
func newARPDB() *cmdARPDB { func newARPDB() (arp *cmdARPDB) {
return &cmdARPDB{ return &cmdARPDB{
parse: parseArpA, parse: parseArpA,
ns: &neighs{ ns: &neighs{
mu: &sync.RWMutex{}, mu: &sync.RWMutex{},
ns: make([]Neighbor, 0), ns: make([]Neighbor, 0),
}, },
cmd: "arp", cmd: "arp",
args: []string{"-a"}, // Use -n flag to avoid resolving the hostnames of the neighbors. By
// default ARP attempts to resolve the hostnames via DNS. See man 8
// arp.
//
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
args: []string{"-a", "-n"},
} }
} }
// parseArpA parses the output of the "arp -a" command on OpenBSD. The expected // parseArpA parses the output of the "arp -a -n" command on OpenBSD. The
// input format: // expected input format:
// //
// Host Ethernet Address Netif Expire Flags // Host Ethernet Address Netif Expire Flags
// 192.168.1.1 ab:cd:ef:ab:cd:ef em0 19m59s // 192.168.1.1 ab:cd:ef:ab:cd:ef em0 19m59s

View File

@ -10,7 +10,7 @@ import (
"sync" "sync"
) )
func newARPDB() *cmdARPDB { func newARPDB() (arp *cmdARPDB) {
return &cmdARPDB{ return &cmdARPDB{
parse: parseArpA, parse: parseArpA,
ns: &neighs{ ns: &neighs{

View File

@ -135,7 +135,6 @@ func (s *Server) processRecursion(dctx *dnsContext) (rc resultCode) {
pctx.Res = s.genNXDomain(pctx.Req) pctx.Res = s.genNXDomain(pctx.Req)
return resultCodeFinish return resultCodeFinish
} }
return resultCodeSuccess return resultCodeSuccess

View File

@ -83,7 +83,7 @@ func TestRecursionDetector_Suspect(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
msg dns.Msg msg dns.Msg
want bool want int
}{{ }{{
name: "simple", name: "simple",
msg: dns.Msg{ msg: dns.Msg{
@ -95,24 +95,18 @@ func TestRecursionDetector_Suspect(t *testing.T) {
Qtype: dns.TypeA, Qtype: dns.TypeA,
}}, }},
}, },
want: true, want: 1,
}, { }, {
name: "unencumbered", name: "unencumbered",
msg: dns.Msg{}, msg: dns.Msg{},
want: false, want: 0,
}} }}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Cleanup(rd.clear) t.Cleanup(rd.clear)
rd.add(tc.msg) rd.add(tc.msg)
assert.Equal(t, tc.want, rd.recentRequests.Stats().Count)
if tc.want {
assert.Equal(t, 1, rd.recentRequests.Stats().Count)
} else {
assert.Zero(t, rd.recentRequests.Stats().Count)
}
}) })
} }
} }

View File

@ -16,18 +16,17 @@ type RDNS struct {
exchanger dnsforward.RDNSExchanger exchanger dnsforward.RDNSExchanger
clients *clientsContainer clients *clientsContainer
// usePrivate is used to store the state of current private RDNS // usePrivate is used to store the state of current private RDNS resolving
// resolving settings and to react to it's changes. // settings and to react to it's changes.
usePrivate uint32 usePrivate uint32
// ipCh used to pass client's IP to rDNS workerLoop. // ipCh used to pass client's IP to rDNS workerLoop.
ipCh chan net.IP ipCh chan net.IP
// ipCache caches the IP addresses to be resolved by rDNS. The resolved // ipCache caches the IP addresses to be resolved by rDNS. The resolved
// address stays here while it's inside clients. After leaving clients // address stays here while it's inside clients. After leaving clients the
// the address will be resolved once again. If the address couldn't be // address will be resolved once again. If the address couldn't be
// resolved, cache prevents further attempts to resolve it for some // resolved, cache prevents further attempts to resolve it for some time.
// time.
ipCache cache.Cache ipCache cache.Cache
} }