Pull request 2200: 6312-client-ipv6-zone
Updates #6312. Squashed commit of the following: commit bd9146ee161a67fa41763070f985e1e73b85823b Merge: 58d2fd98d856cc40cf
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 24 18:09:19 2024 +0300 Merge branch 'master' into 6312-client-ipv6-zone commit 58d2fd98d3e82c84638d58dd4d74d13a9a8fbca6 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 24 18:00:56 2024 +0300 client: imp naming commit 922a14b036d829c2775feb7bb3e6beb6aa49692e Merge: 6f4d58fe160f48e2d0
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 24 14:29:00 2024 +0300 Merge branch 'master' into 6312-client-ipv6-zone commit 6f4d58fe1c42504e8345bff24dbb3f523e8c5f85 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 24 14:27:55 2024 +0300 client: imp docs commit fa292eee828cd6f27f62b782675aa1f998e44518 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Apr 22 19:20:28 2024 +0300 client: fix typo commit 599414be0ccd3f9deb044e022a8ac0006c96b467 Merge: 502571756762ef4a6d
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Apr 22 18:42:06 2024 +0300 Merge branch 'master' into 6312-client-ipv6-zone commit 502571756400a00445086b5ba412e03fca65e39f Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Apr 22 18:39:22 2024 +0300 all: imp code; add tests commit 155b2fef500a0d835f49957d9f30b0870712f6f2 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Apr 16 19:56:00 2024 +0300 all: upd chlog; imp code commit 7a4426c5d0a511cd3865884c00328b8c130746bf Merge: e9c1cbb8548c6242a7
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Apr 16 19:52:00 2024 +0300 Merge branch 'master' into 6312-client-ipv6-zone commit e9c1cbb85e4afa173969d5bedfaaaf92716b7fad Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 10 16:23:07 2024 +0300 client: client ipv6 zone
This commit is contained in:
parent
856cc40cf3
commit
c1ee2c7e5e
|
@ -34,6 +34,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Support for link-local subnets, i.e. `fe80::/16`, as client identifiers
|
||||||
|
([#6312]).
|
||||||
- Issues with QUIC and HTTP/3 upstreams on older Linux kernel versions
|
- Issues with QUIC and HTTP/3 upstreams on older Linux kernel versions
|
||||||
([#6422]).
|
([#6422]).
|
||||||
- YouTube restricted mode is not enforced by HTTPS queries on Firefox.
|
- YouTube restricted mode is not enforced by HTTPS queries on Firefox.
|
||||||
|
@ -51,6 +53,7 @@ NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
[#5345]: https://github.com/AdguardTeam/AdGuardHome/issues/5345
|
[#5345]: https://github.com/AdguardTeam/AdGuardHome/issues/5345
|
||||||
[#5812]: https://github.com/AdguardTeam/AdGuardHome/issues/5812
|
[#5812]: https://github.com/AdguardTeam/AdGuardHome/issues/5812
|
||||||
[#6192]: https://github.com/AdguardTeam/AdGuardHome/issues/6192
|
[#6192]: https://github.com/AdguardTeam/AdGuardHome/issues/6192
|
||||||
|
[#6312]: https://github.com/AdguardTeam/AdGuardHome/issues/6312
|
||||||
[#6422]: https://github.com/AdguardTeam/AdGuardHome/issues/6422
|
[#6422]: https://github.com/AdguardTeam/AdGuardHome/issues/6422
|
||||||
[#6854]: https://github.com/AdguardTeam/AdGuardHome/issues/6854
|
[#6854]: https://github.com/AdguardTeam/AdGuardHome/issues/6854
|
||||||
[#6875]: https://github.com/AdguardTeam/AdGuardHome/issues/6875
|
[#6875]: https://github.com/AdguardTeam/AdGuardHome/issues/6875
|
||||||
|
|
|
@ -197,8 +197,10 @@ func (ci *Index) findByIP(ip netip.Addr) (c *Persistent, found bool) {
|
||||||
return ci.uidToClient[uid], true
|
return ci.uidToClient[uid], true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipWithoutZone := ip.WithZone("")
|
||||||
ci.subnetToUID.Range(func(pref netip.Prefix, id UID) (cont bool) {
|
ci.subnetToUID.Range(func(pref netip.Prefix, id UID) (cont bool) {
|
||||||
if pref.Contains(ip) {
|
// Remove zone before checking because prefixes strip zones.
|
||||||
|
if pref.Contains(ipWithoutZone) {
|
||||||
uid, found = id, true
|
uid, found = id, true
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -214,6 +216,26 @@ func (ci *Index) findByIP(ip netip.Addr) (c *Persistent, found bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindByIPWithoutZone finds a persistent client by IP address without zone. It
|
||||||
|
// strips the IPv6 zone index from the stored IP addresses before comparing,
|
||||||
|
// because querylog entries don't have it. See TODO on [querylog.logEntry.IP].
|
||||||
|
//
|
||||||
|
// Note that multiple clients can have the same IP address with different zones.
|
||||||
|
// Therefore, the result of this method is indeterminate.
|
||||||
|
func (ci *Index) FindByIPWithoutZone(ip netip.Addr) (c *Persistent) {
|
||||||
|
if (ip == netip.Addr{}) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for addr, uid := range ci.ipToUID {
|
||||||
|
if addr.WithZone("") == ip {
|
||||||
|
return ci.uidToClient[uid]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// find finds persistent client by MAC.
|
// find finds persistent client by MAC.
|
||||||
func (ci *Index) findByMAC(mac net.HardwareAddr) (c *Persistent, found bool) {
|
func (ci *Index) findByMAC(mac net.HardwareAddr) (c *Persistent, found bool) {
|
||||||
k := macToKey(mac)
|
k := macToKey(mac)
|
||||||
|
|
|
@ -35,27 +35,49 @@ func TestClientIndex(t *testing.T) {
|
||||||
|
|
||||||
cliID = "client-id"
|
cliID = "client-id"
|
||||||
cliMAC = "11:11:11:11:11:11"
|
cliMAC = "11:11:11:11:11:11"
|
||||||
|
|
||||||
|
linkLocalIP = "fe80::abcd:abcd:abcd:ab%eth0"
|
||||||
|
linkLocalSubnet = "fe80::/16"
|
||||||
)
|
)
|
||||||
|
|
||||||
clients := []*Persistent{{
|
var (
|
||||||
|
clientWithBothFams = &Persistent{
|
||||||
Name: "client1",
|
Name: "client1",
|
||||||
IPs: []netip.Addr{
|
IPs: []netip.Addr{
|
||||||
netip.MustParseAddr(cliIP1),
|
netip.MustParseAddr(cliIP1),
|
||||||
netip.MustParseAddr(cliIPv6),
|
netip.MustParseAddr(cliIPv6),
|
||||||
},
|
},
|
||||||
}, {
|
}
|
||||||
|
|
||||||
|
clientWithSubnet = &Persistent{
|
||||||
Name: "client2",
|
Name: "client2",
|
||||||
IPs: []netip.Addr{netip.MustParseAddr(cliIP2)},
|
IPs: []netip.Addr{netip.MustParseAddr(cliIP2)},
|
||||||
Subnets: []netip.Prefix{netip.MustParsePrefix(cliSubnet)},
|
Subnets: []netip.Prefix{netip.MustParsePrefix(cliSubnet)},
|
||||||
}, {
|
}
|
||||||
|
|
||||||
|
clientWithMAC = &Persistent{
|
||||||
Name: "client_with_mac",
|
Name: "client_with_mac",
|
||||||
MACs: []net.HardwareAddr{mustParseMAC(cliMAC)},
|
MACs: []net.HardwareAddr{mustParseMAC(cliMAC)},
|
||||||
}, {
|
}
|
||||||
|
|
||||||
|
clientWithID = &Persistent{
|
||||||
Name: "client_with_id",
|
Name: "client_with_id",
|
||||||
ClientIDs: []string{cliID},
|
ClientIDs: []string{cliID},
|
||||||
}}
|
}
|
||||||
|
|
||||||
ci := newIDIndex(clients)
|
clientLinkLocal = &Persistent{
|
||||||
|
Name: "client_link_local",
|
||||||
|
Subnets: []netip.Prefix{netip.MustParsePrefix(linkLocalSubnet)},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ci := newIDIndex([]*Persistent{
|
||||||
|
clientWithBothFams,
|
||||||
|
clientWithSubnet,
|
||||||
|
clientWithMAC,
|
||||||
|
clientWithID,
|
||||||
|
clientLinkLocal,
|
||||||
|
})
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
want *Persistent
|
want *Persistent
|
||||||
|
@ -64,19 +86,23 @@ func TestClientIndex(t *testing.T) {
|
||||||
}{{
|
}{{
|
||||||
name: "ipv4_ipv6",
|
name: "ipv4_ipv6",
|
||||||
ids: []string{cliIP1, cliIPv6},
|
ids: []string{cliIP1, cliIPv6},
|
||||||
want: clients[0],
|
want: clientWithBothFams,
|
||||||
}, {
|
}, {
|
||||||
name: "ipv4_subnet",
|
name: "ipv4_subnet",
|
||||||
ids: []string{cliIP2, cliSubnetIP},
|
ids: []string{cliIP2, cliSubnetIP},
|
||||||
want: clients[1],
|
want: clientWithSubnet,
|
||||||
}, {
|
}, {
|
||||||
name: "mac",
|
name: "mac",
|
||||||
ids: []string{cliMAC},
|
ids: []string{cliMAC},
|
||||||
want: clients[2],
|
want: clientWithMAC,
|
||||||
}, {
|
}, {
|
||||||
name: "client_id",
|
name: "client_id",
|
||||||
ids: []string{cliID},
|
ids: []string{cliID},
|
||||||
want: clients[3],
|
want: clientWithID,
|
||||||
|
}, {
|
||||||
|
name: "client_link_local_subnet",
|
||||||
|
ids: []string{linkLocalIP},
|
||||||
|
want: clientLinkLocal,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
@ -221,3 +247,52 @@ func TestMACToKey(t *testing.T) {
|
||||||
_ = macToKey(mac)
|
_ = macToKey(mac)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIndex_FindByIPWithoutZone(t *testing.T) {
|
||||||
|
var (
|
||||||
|
ip = netip.MustParseAddr("fe80::a098:7654:32ef:ff1")
|
||||||
|
ipWithZone = netip.MustParseAddr("fe80::1ff:fe23:4567:890a%eth2")
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
clientNoZone = &Persistent{
|
||||||
|
Name: "client",
|
||||||
|
IPs: []netip.Addr{ip},
|
||||||
|
}
|
||||||
|
|
||||||
|
clientWithZone = &Persistent{
|
||||||
|
Name: "client_with_zone",
|
||||||
|
IPs: []netip.Addr{ipWithZone},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ci := newIDIndex([]*Persistent{
|
||||||
|
clientNoZone,
|
||||||
|
clientWithZone,
|
||||||
|
})
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
ip netip.Addr
|
||||||
|
want *Persistent
|
||||||
|
name string
|
||||||
|
}{{
|
||||||
|
name: "without_zone",
|
||||||
|
ip: ip,
|
||||||
|
want: clientNoZone,
|
||||||
|
}, {
|
||||||
|
name: "with_zone",
|
||||||
|
ip: ipWithZone,
|
||||||
|
want: clientWithZone,
|
||||||
|
}, {
|
||||||
|
name: "zero_address",
|
||||||
|
ip: netip.Addr{},
|
||||||
|
want: nil,
|
||||||
|
}}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
c := ci.FindByIPWithoutZone(tc.ip.WithZone(""))
|
||||||
|
require.Equal(t, tc.want, c)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -412,7 +412,11 @@ func (clients *clientsContainer) clientOrArtificial(
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cli, ok := clients.find(id)
|
cli, ok := clients.find(id)
|
||||||
if ok {
|
if !ok {
|
||||||
|
cli = clients.clientIndex.FindByIPWithoutZone(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cli != nil {
|
||||||
return &querylog.Client{
|
return &querylog.Client{
|
||||||
Name: cli.Name,
|
Name: cli.Name,
|
||||||
IgnoreQueryLog: cli.IgnoreQueryLog,
|
IgnoreQueryLog: cli.IgnoreQueryLog,
|
||||||
|
|
|
@ -31,6 +31,7 @@ type logEntry struct {
|
||||||
Answer []byte `json:",omitempty"`
|
Answer []byte `json:",omitempty"`
|
||||||
OrigAnswer []byte `json:",omitempty"`
|
OrigAnswer []byte `json:",omitempty"`
|
||||||
|
|
||||||
|
// TODO(s.chzhen): Use netip.Addr.
|
||||||
IP net.IP `json:"IP"`
|
IP net.IP `json:"IP"`
|
||||||
|
|
||||||
Result filtering.Result
|
Result filtering.Result
|
||||||
|
|
Loading…
Reference in New Issue