Skip to content

Commit

Permalink
Pull request 2200: 6312-client-ipv6-zone
Browse files Browse the repository at this point in the history
Updates AdguardTeam#6312.

Squashed commit of the following:

commit bd9146e
Merge: 58d2fd9 856cc40
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 58d2fd9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 24 18:00:56 2024 +0300

    client: imp naming

commit 922a14b
Merge: 6f4d58f 60f48e2
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 6f4d58f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 24 14:27:55 2024 +0300

    client: imp docs

commit fa292ee
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 22 19:20:28 2024 +0300

    client: fix typo

commit 599414b
Merge: 5025717 762ef4a
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 5025717
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 22 18:39:22 2024 +0300

    all: imp code; add tests

commit 155b2fe
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 16 19:56:00 2024 +0300

    all: upd chlog; imp code

commit 7a4426c
Merge: e9c1cbb 48c6242
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 e9c1cbb
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 10 16:23:07 2024 +0300

    client: client ipv6 zone
  • Loading branch information
schzhn committed Apr 24, 2024
1 parent 856cc40 commit c1ee2c7
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 24 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ NOTE: Add new changes BELOW THIS COMMENT.

### 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
([#6422]).
- YouTube restricted mode is not enforced by HTTPS queries on Firefox.
Expand All @@ -51,6 +53,7 @@ NOTE: Add new changes BELOW THIS COMMENT.
[#5345]: https://github.com/AdguardTeam/AdGuardHome/issues/5345
[#5812]: https://github.com/AdguardTeam/AdGuardHome/issues/5812
[#6192]: https://github.com/AdguardTeam/AdGuardHome/issues/6192
[#6312]: https://github.com/AdguardTeam/AdGuardHome/issues/6312
[#6422]: https://github.com/AdguardTeam/AdGuardHome/issues/6422
[#6854]: https://github.com/AdguardTeam/AdGuardHome/issues/6854
[#6875]: https://github.com/AdguardTeam/AdGuardHome/issues/6875
Expand Down
24 changes: 23 additions & 1 deletion internal/client/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,10 @@ func (ci *Index) findByIP(ip netip.Addr) (c *Persistent, found bool) {
return ci.uidToClient[uid], true
}

ipWithoutZone := ip.WithZone("")
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

return false
Expand All @@ -214,6 +216,26 @@ func (ci *Index) findByIP(ip netip.Addr) (c *Persistent, found bool) {
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.
func (ci *Index) findByMAC(mac net.HardwareAddr) (c *Persistent, found bool) {
k := macToKey(mac)
Expand Down
119 changes: 97 additions & 22 deletions internal/client/index_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,49 @@ func TestClientIndex(t *testing.T) {

cliID = "client-id"
cliMAC = "11:11:11:11:11:11"

linkLocalIP = "fe80::abcd:abcd:abcd:ab%eth0"
linkLocalSubnet = "fe80::/16"
)

clients := []*Persistent{{
Name: "client1",
IPs: []netip.Addr{
netip.MustParseAddr(cliIP1),
netip.MustParseAddr(cliIPv6),
},
}, {
Name: "client2",
IPs: []netip.Addr{netip.MustParseAddr(cliIP2)},
Subnets: []netip.Prefix{netip.MustParsePrefix(cliSubnet)},
}, {
Name: "client_with_mac",
MACs: []net.HardwareAddr{mustParseMAC(cliMAC)},
}, {
Name: "client_with_id",
ClientIDs: []string{cliID},
}}
var (
clientWithBothFams = &Persistent{
Name: "client1",
IPs: []netip.Addr{
netip.MustParseAddr(cliIP1),
netip.MustParseAddr(cliIPv6),
},
}

ci := newIDIndex(clients)
clientWithSubnet = &Persistent{
Name: "client2",
IPs: []netip.Addr{netip.MustParseAddr(cliIP2)},
Subnets: []netip.Prefix{netip.MustParsePrefix(cliSubnet)},
}

clientWithMAC = &Persistent{
Name: "client_with_mac",
MACs: []net.HardwareAddr{mustParseMAC(cliMAC)},
}

clientWithID = &Persistent{
Name: "client_with_id",
ClientIDs: []string{cliID},
}

clientLinkLocal = &Persistent{
Name: "client_link_local",
Subnets: []netip.Prefix{netip.MustParsePrefix(linkLocalSubnet)},
}
)

ci := newIDIndex([]*Persistent{
clientWithBothFams,
clientWithSubnet,
clientWithMAC,
clientWithID,
clientLinkLocal,
})

testCases := []struct {
want *Persistent
Expand All @@ -64,19 +86,23 @@ func TestClientIndex(t *testing.T) {
}{{
name: "ipv4_ipv6",
ids: []string{cliIP1, cliIPv6},
want: clients[0],
want: clientWithBothFams,
}, {
name: "ipv4_subnet",
ids: []string{cliIP2, cliSubnetIP},
want: clients[1],
want: clientWithSubnet,
}, {
name: "mac",
ids: []string{cliMAC},
want: clients[2],
want: clientWithMAC,
}, {
name: "client_id",
ids: []string{cliID},
want: clients[3],
want: clientWithID,
}, {
name: "client_link_local_subnet",
ids: []string{linkLocalIP},
want: clientLinkLocal,
}}

for _, tc := range testCases {
Expand Down Expand Up @@ -221,3 +247,52 @@ func TestMACToKey(t *testing.T) {
_ = 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)
})
}
}
6 changes: 5 additions & 1 deletion internal/home/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,11 @@ func (clients *clientsContainer) clientOrArtificial(
}()

cli, ok := clients.find(id)
if ok {
if !ok {
cli = clients.clientIndex.FindByIPWithoutZone(ip)
}

if cli != nil {
return &querylog.Client{
Name: cli.Name,
IgnoreQueryLog: cli.IgnoreQueryLog,
Expand Down
1 change: 1 addition & 0 deletions internal/querylog/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type logEntry struct {
Answer []byte `json:",omitempty"`
OrigAnswer []byte `json:",omitempty"`

// TODO(s.chzhen): Use netip.Addr.
IP net.IP `json:"IP"`

Result filtering.Result
Expand Down

0 comments on commit c1ee2c7

Please sign in to comment.