diff --git a/go.mod b/go.mod index a46adc4ab20..f8d12e20a17 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/AdguardTeam/AdGuardHome go 1.21.8 require ( - github.com/AdguardTeam/dnsproxy v0.66.0 - github.com/AdguardTeam/golibs v0.20.2 + github.com/AdguardTeam/dnsproxy v0.67.0 + github.com/AdguardTeam/golibs v0.21.0 github.com/AdguardTeam/urlfilter v0.18.0 github.com/NYTimes/gziphandler v1.1.1 github.com/ameshkov/dnscrypt/v2 v2.2.7 diff --git a/go.sum b/go.sum index 78696a26273..a304937ec46 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -github.com/AdguardTeam/dnsproxy v0.66.0 h1:RyUbyDxRSXBFjVG1l2/4HV3I98DtfIgpnZkgXkgHKnc= -github.com/AdguardTeam/dnsproxy v0.66.0/go.mod h1:ZThEXbMUlP1RxfwtNW30ItPAHE6OF4YFygK8qjU/cvY= -github.com/AdguardTeam/golibs v0.20.2 h1:9gThBFyuELf2ohRnUNeQGQsVBYI7YslaRLUFwVaUj8E= -github.com/AdguardTeam/golibs v0.20.2/go.mod h1:/votX6WK1PdcZ3T2kBOPjPCGmfhlKixhI6ljYrFRPvI= +github.com/AdguardTeam/dnsproxy v0.67.0 h1:7oKfcA8sm9d1N4qvhsNmQWBX4+fs3sX4cAnERmBXEbw= +github.com/AdguardTeam/dnsproxy v0.67.0/go.mod h1:XLfD6IpSplUZZ+f5vhWSJW1mp4wm+KkHWiMo9w7U1Ls= +github.com/AdguardTeam/golibs v0.21.0 h1:0swWyNaHTmT7aMwffKd9d54g4wBd8Oaj0fl+5l/PRdE= +github.com/AdguardTeam/golibs v0.21.0/go.mod h1:/votX6WK1PdcZ3T2kBOPjPCGmfhlKixhI6ljYrFRPvI= github.com/AdguardTeam/urlfilter v0.18.0 h1:ZZzwODC/ADpjJSODxySrrUnt/fvOCfGFaCW6j+wsGfQ= github.com/AdguardTeam/urlfilter v0.18.0/go.mod h1:IXxBwedLiZA2viyHkaFxY/8mjub0li2PXRg8a3d9Z1s= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= diff --git a/internal/aghnet/addr.go b/internal/aghnet/addr.go index e3013125e4b..fa0bcf9c765 100644 --- a/internal/aghnet/addr.go +++ b/internal/aghnet/addr.go @@ -1,10 +1,7 @@ package aghnet import ( - "fmt" "strings" - - "github.com/AdguardTeam/golibs/stringutil" ) // NormalizeDomain returns a lowercased version of host without the final dot, @@ -19,25 +16,3 @@ func NormalizeDomain(host string) (norm string) { return strings.ToLower(strings.TrimSuffix(host, ".")) } - -// NewDomainNameSet returns nil and error, if list has duplicate or empty domain -// name. Otherwise returns a set, which contains domain names normalized using -// [NormalizeDomain]. -func NewDomainNameSet(list []string) (set *stringutil.Set, err error) { - set = stringutil.NewSet() - - for i, host := range list { - if host == "" { - return nil, fmt.Errorf("at index %d: hostname is empty", i) - } - - host = NormalizeDomain(host) - if set.Has(host) { - return nil, fmt.Errorf("duplicate hostname %q at index %d", host, i) - } - - set.Add(host) - } - - return set, nil -} diff --git a/internal/aghnet/addr_test.go b/internal/aghnet/addr_test.go deleted file mode 100644 index 2bb30e31aae..00000000000 --- a/internal/aghnet/addr_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package aghnet_test - -import ( - "testing" - - "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/golibs/testutil" - "github.com/stretchr/testify/assert" -) - -func TestNewDomainNameSet(t *testing.T) { - t.Parallel() - - testCases := []struct { - name string - wantErrMsg string - in []string - }{{ - name: "nil", - wantErrMsg: "", - in: nil, - }, { - name: "success", - wantErrMsg: "", - in: []string{ - "Domain.Example", - ".", - }, - }, { - name: "dups", - wantErrMsg: `duplicate hostname "domain.example" at index 1`, - in: []string{ - "Domain.Example", - "domain.example", - }, - }, { - name: "bad_domain", - wantErrMsg: "at index 0: hostname is empty", - in: []string{ - "", - }, - }} - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - set, err := aghnet.NewDomainNameSet(tc.in) - testutil.AssertErrorMsg(t, tc.wantErrMsg, err) - if err != nil { - return - } - - for _, host := range tc.in { - assert.Truef(t, set.Has(aghnet.NormalizeDomain(host)), "%q not matched", host) - } - }) - } -} diff --git a/internal/aghos/filewalker.go b/internal/aghos/filewalker.go index 97f966afc8a..30c2d71857e 100644 --- a/internal/aghos/filewalker.go +++ b/internal/aghos/filewalker.go @@ -5,8 +5,8 @@ import ( "io" "io/fs" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" - "github.com/AdguardTeam/golibs/stringutil" ) // FileWalker is the signature of a function called for files in the file tree. @@ -56,7 +56,7 @@ func checkFile( // srcSet. srcSet must be non-nil. func handlePatterns( fsys fs.FS, - srcSet *stringutil.Set, + srcSet *container.MapSet[string], patterns ...string, ) (sub []string, err error) { sub = make([]string, 0, len(patterns)) @@ -87,7 +87,7 @@ func handlePatterns( func (fw FileWalker) Walk(fsys fs.FS, initial ...string) (ok bool, err error) { // The slice of sources keeps the order in which the files are walked since // srcSet.Values() returns strings in undefined order. - srcSet := stringutil.NewSet() + srcSet := container.NewMapSet[string]() var src []string src, err = handlePatterns(fsys, srcSet, initial...) if err != nil { diff --git a/internal/aghos/fswatcher.go b/internal/aghos/fswatcher.go index ff40ed64a73..9f3a657046d 100644 --- a/internal/aghos/fswatcher.go +++ b/internal/aghos/fswatcher.go @@ -6,10 +6,10 @@ import ( "io/fs" "path/filepath" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/osutil" - "github.com/AdguardTeam/golibs/stringutil" "github.com/fsnotify/fsnotify" ) @@ -46,7 +46,7 @@ type osWatcher struct { events chan event // files is the set of tracked files. - files *stringutil.Set + files *container.MapSet[string] } // osWatcherPref is a prefix for logging and wrapping errors in osWathcer's @@ -67,7 +67,7 @@ func NewOSWritesWatcher() (w FSWatcher, err error) { return &osWatcher{ watcher: watcher, events: make(chan event, 1), - files: stringutil.NewSet(), + files: container.NewMapSet[string](), }, nil } diff --git a/internal/client/persistent.go b/internal/client/persistent.go index d70966d791b..06e346f4dfc 100644 --- a/internal/client/persistent.go +++ b/internal/client/persistent.go @@ -12,10 +12,10 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering/safesearch" "github.com/AdguardTeam/dnsproxy/proxy" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/netutil" - "github.com/AdguardTeam/golibs/stringutil" "github.com/google/uuid" ) @@ -98,7 +98,7 @@ type Persistent struct { } // SetTags sets the tags if they are known, otherwise logs an unknown tag. -func (c *Persistent) SetTags(tags []string, known *stringutil.Set) { +func (c *Persistent) SetTags(tags []string, known *container.MapSet[string]) { for _, t := range tags { if !known.Has(t) { log.Info("skipping unknown tag %q", t) diff --git a/internal/dnsforward/access.go b/internal/dnsforward/access.go index 21b4a758805..c4d6c5913ca 100644 --- a/internal/dnsforward/access.go +++ b/internal/dnsforward/access.go @@ -5,10 +5,12 @@ import ( "fmt" "net/http" "net/netip" + "slices" "strings" "github.com/AdguardTeam/AdGuardHome/internal/aghalg" "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/urlfilter" @@ -16,22 +18,19 @@ import ( "github.com/AdguardTeam/urlfilter/rules" ) -// unit is a convenient alias for struct{} -type unit = struct{} - // accessManager controls IP and client blocking that takes place before all // other processing. An accessManager is safe for concurrent use. type accessManager struct { - allowedIPs map[netip.Addr]unit - blockedIPs map[netip.Addr]unit + allowedIPs *container.MapSet[netip.Addr] + blockedIPs *container.MapSet[netip.Addr] - allowedClientIDs *stringutil.Set - blockedClientIDs *stringutil.Set + allowedClientIDs *container.MapSet[string] + blockedClientIDs *container.MapSet[string] // TODO(s.chzhen): Use [aghnet.IgnoreEngine]. blockedHostsEng *urlfilter.DNSEngine - // TODO(a.garipov): Create a type for a set of IP networks. + // TODO(a.garipov): Create a type for an efficient tree set of IP networks. allowedNets []netip.Prefix blockedNets []netip.Prefix } @@ -40,15 +39,15 @@ type accessManager struct { // which may be an IP address, a CIDR, or a ClientID. func processAccessClients( clientStrs []string, - ips map[netip.Addr]unit, + ips *container.MapSet[netip.Addr], nets *[]netip.Prefix, - clientIDs *stringutil.Set, + clientIDs *container.MapSet[string], ) (err error) { for i, s := range clientStrs { var ip netip.Addr var ipnet netip.Prefix if ip, err = netip.ParseAddr(s); err == nil { - ips[ip] = unit{} + ips.Add(ip) } else if ipnet, err = netip.ParsePrefix(s); err == nil { *nets = append(*nets, ipnet) } else { @@ -67,11 +66,11 @@ func processAccessClients( // newAccessCtx creates a new accessCtx. func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessManager, err error) { a = &accessManager{ - allowedIPs: map[netip.Addr]unit{}, - blockedIPs: map[netip.Addr]unit{}, + allowedIPs: container.NewMapSet[netip.Addr](), + blockedIPs: container.NewMapSet[netip.Addr](), - allowedClientIDs: stringutil.NewSet(), - blockedClientIDs: stringutil.NewSet(), + allowedClientIDs: container.NewMapSet[string](), + blockedClientIDs: container.NewMapSet[string](), } err = processAccessClients(allowed, a.allowedIPs, &a.allowedNets, a.allowedClientIDs) @@ -109,7 +108,7 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessManager, er // allowlistMode returns true if this *accessCtx is in the allowlist mode. func (a *accessManager) allowlistMode() (ok bool) { - return len(a.allowedIPs) != 0 || a.allowedClientIDs.Len() != 0 || len(a.allowedNets) != 0 + return a.allowedIPs.Len() != 0 || a.allowedClientIDs.Len() != 0 || len(a.allowedNets) != 0 } // isBlockedClientID returns true if the ClientID should be blocked. @@ -152,7 +151,7 @@ func (a *accessManager) isBlockedIP(ip netip.Addr) (blocked bool, rule string) { ipnets = a.allowedNets } - if _, ok := ips[ip]; ok { + if ips.Has(ip) { return blocked, ip.String() } @@ -176,9 +175,9 @@ func (s *Server) accessListJSON() (j accessListJSON) { defer s.serverLock.RUnlock() return accessListJSON{ - AllowedClients: stringutil.CloneSlice(s.conf.AllowedClients), - DisallowedClients: stringutil.CloneSlice(s.conf.DisallowedClients), - BlockedHosts: stringutil.CloneSlice(s.conf.BlockedHosts), + AllowedClients: slices.Clone(s.conf.AllowedClients), + DisallowedClients: slices.Clone(s.conf.DisallowedClients), + BlockedHosts: slices.Clone(s.conf.BlockedHosts), } } diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index cc75cdf795a..db2d50af20f 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -19,6 +19,7 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/netutil" @@ -461,26 +462,27 @@ func (s *Server) prepareIpsetListSettings() (err error) { // unspecPorts if its address is unspecified. func collectListenAddr( addrPort netip.AddrPort, - addrs map[netip.AddrPort]unit, - unspecPorts map[uint16]unit, + addrs *container.MapSet[netip.AddrPort], + unspecPorts *container.MapSet[uint16], ) { if addrPort == (netip.AddrPort{}) { return } - addrs[addrPort] = unit{} + addrs.Add(addrPort) if addrPort.Addr().IsUnspecified() { - unspecPorts[addrPort.Port()] = unit{} + unspecPorts.Add(addrPort.Port()) } } // collectDNSAddrs returns configured set of listening addresses. It also // returns a set of ports of each unspecified listening address. -func (conf *ServerConfig) collectDNSAddrs() (addrs mapAddrPortSet, unspecPorts map[uint16]unit) { - // TODO(e.burkov): Perhaps, we shouldn't allocate as much memory, since the - // TCP and UDP listening addresses are currently the same. - addrs = make(map[netip.AddrPort]unit, len(conf.TCPListenAddrs)+len(conf.UDPListenAddrs)) - unspecPorts = map[uint16]unit{} +func (conf *ServerConfig) collectDNSAddrs() ( + addrs *container.MapSet[netip.AddrPort], + unspecPorts *container.MapSet[uint16], +) { + addrs = container.NewMapSet[netip.AddrPort]() + unspecPorts = container.NewMapSet[uint16]() for _, laddr := range conf.TCPListenAddrs { collectListenAddr(laddr.AddrPort(), addrs, unspecPorts) @@ -511,26 +513,12 @@ type emptyAddrPortSet struct{} // Has implements the [addrPortSet] interface for [emptyAddrPortSet]. func (emptyAddrPortSet) Has(_ netip.AddrPort) (ok bool) { return false } -// mapAddrPortSet is the [addrPortSet] containing values of [netip.AddrPort] as -// keys of a map. -type mapAddrPortSet map[netip.AddrPort]unit - -// type check -var _ addrPortSet = mapAddrPortSet{} - -// Has implements the [addrPortSet] interface for [mapAddrPortSet]. -func (m mapAddrPortSet) Has(addrPort netip.AddrPort) (ok bool) { - _, ok = m[addrPort] - - return ok -} - // combinedAddrPortSet is the [addrPortSet] defined by some IP addresses along // with ports, any combination of which is considered being in the set. type combinedAddrPortSet struct { - // TODO(e.burkov): Use sorted slices in combination with binary search. - ports map[uint16]unit - addrs []netip.Addr + // TODO(e.burkov): Use container.SliceSet when available. + ports *container.MapSet[uint16] + addrs *container.MapSet[netip.Addr] } // type check @@ -538,9 +526,7 @@ var _ addrPortSet = (*combinedAddrPortSet)(nil) // Has implements the [addrPortSet] interface for [*combinedAddrPortSet]. func (m *combinedAddrPortSet) Has(addrPort netip.AddrPort) (ok bool) { - _, ok = m.ports[addrPort.Port()] - - return ok && slices.Contains(m.addrs, addrPort.Addr()) + return m.ports.Has(addrPort.Port()) && m.addrs.Has(addrPort.Addr()) } // filterOut filters out all the upstreams that match um. It returns all the @@ -578,11 +564,11 @@ func filterOutAddrs(upsConf *proxy.UpstreamConfig, set addrPortSet) (err error) func (conf *ServerConfig) ourAddrsSet() (m addrPortSet, err error) { addrs, unspecPorts := conf.collectDNSAddrs() switch { - case len(addrs) == 0: + case addrs.Len() == 0: log.Debug("dnsforward: no listen addresses") return emptyAddrPortSet{}, nil - case len(unspecPorts) == 0: + case unspecPorts.Len() == 0: log.Debug("dnsforward: filtering out addresses %s", addrs) return addrs, nil @@ -598,7 +584,7 @@ func (conf *ServerConfig) ourAddrsSet() (m addrPortSet, err error) { return &combinedAddrPortSet{ ports: unspecPorts, - addrs: ifaceAddrs, + addrs: container.NewMapSet(ifaceAddrs...), }, nil } } diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index 5c99e0ed23a..a1d1eedeb19 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -308,13 +308,13 @@ func (s *Server) WriteDiskConfig(c *Config) { sc := s.conf.Config *c = sc c.RatelimitWhitelist = slices.Clone(sc.RatelimitWhitelist) - c.BootstrapDNS = stringutil.CloneSlice(sc.BootstrapDNS) - c.FallbackDNS = stringutil.CloneSlice(sc.FallbackDNS) - c.AllowedClients = stringutil.CloneSlice(sc.AllowedClients) - c.DisallowedClients = stringutil.CloneSlice(sc.DisallowedClients) - c.BlockedHosts = stringutil.CloneSlice(sc.BlockedHosts) + c.BootstrapDNS = slices.Clone(sc.BootstrapDNS) + c.FallbackDNS = slices.Clone(sc.FallbackDNS) + c.AllowedClients = slices.Clone(sc.AllowedClients) + c.DisallowedClients = slices.Clone(sc.DisallowedClients) + c.BlockedHosts = slices.Clone(sc.BlockedHosts) c.TrustedProxies = slices.Clone(sc.TrustedProxies) - c.UpstreamDNS = stringutil.CloneSlice(sc.UpstreamDNS) + c.UpstreamDNS = slices.Clone(sc.UpstreamDNS) } // LocalPTRResolvers returns the current local PTR resolver configuration. @@ -322,7 +322,7 @@ func (s *Server) LocalPTRResolvers() (localPTRResolvers []string) { s.serverLock.RLock() defer s.serverLock.RUnlock() - return stringutil.CloneSlice(s.conf.LocalPTRResolvers) + return slices.Clone(s.conf.LocalPTRResolvers) } // AddrProcConfig returns the current address processing configuration. Only diff --git a/internal/filtering/filter.go b/internal/filtering/filter.go index e134175be56..15bc14d94c5 100644 --- a/internal/filtering/filter.go +++ b/internal/filtering/filter.go @@ -13,9 +13,9 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghrenameio" "github.com/AdguardTeam/AdGuardHome/internal/filtering/rulelist" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" - "github.com/AdguardTeam/golibs/stringutil" ) // filterDir is the subdirectory of a data directory to store downloaded @@ -234,7 +234,7 @@ func (d *DNSFilter) loadFilters(array []FilterYAML) { } func deduplicateFilters(filters []FilterYAML) (deduplicated []FilterYAML) { - urls := stringutil.NewSet() + urls := container.NewMapSet[string]() lastIdx := 0 for _, filter := range filters { diff --git a/internal/filtering/filtering.go b/internal/filtering/filtering.go index df2f4bc700b..4ea57eeabd9 100644 --- a/internal/filtering/filtering.go +++ b/internal/filtering/filtering.go @@ -20,11 +20,11 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" "github.com/AdguardTeam/AdGuardHome/internal/filtering/rulelist" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/hostsfile" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/mathutil" - "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/golibs/syncutil" "github.com/AdguardTeam/urlfilter" "github.com/AdguardTeam/urlfilter/filterlist" @@ -629,7 +629,7 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) { res.Reason = Rewritten - cnames := stringutil.NewSet() + cnames := container.NewMapSet[string]() origHost := host for matched && len(rewrites) > 0 && rewrites[0].Type == dns.TypeCNAME { rw := rewrites[0] diff --git a/internal/filtering/idgenerator.go b/internal/filtering/idgenerator.go index b7c0544b0bc..e50f86ee1db 100644 --- a/internal/filtering/idgenerator.go +++ b/internal/filtering/idgenerator.go @@ -5,6 +5,7 @@ import ( "sync/atomic" "github.com/AdguardTeam/AdGuardHome/internal/filtering/rulelist" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/log" ) @@ -41,7 +42,7 @@ func (g *idGenerator) next() (id rulelist.URLFilterID) { // fix ensures that flts all have unique IDs. func (g *idGenerator) fix(flts []FilterYAML) { - set := map[rulelist.URLFilterID]struct{}{} + set := container.NewMapSet[rulelist.URLFilterID]() for i, f := range flts { id := f.ID if id == 0 { @@ -49,14 +50,14 @@ func (g *idGenerator) fix(flts []FilterYAML) { flts[i].ID = id } - if _, ok := set[id]; !ok { - set[id] = struct{}{} + if !set.Has(id) { + set.Add(id) continue } newID := g.next() - for _, ok := set[newID]; ok; _, ok = set[newID] { + for set.Has(newID) { newID = g.next() } @@ -68,6 +69,6 @@ func (g *idGenerator) fix(flts []FilterYAML) { ) flts[i].ID = newID - set[newID] = struct{}{} + set.Add(newID) } } diff --git a/internal/filtering/rewrite/storage.go b/internal/filtering/rewrite/storage.go index cdf3e52c591..42b36273fad 100644 --- a/internal/filtering/rewrite/storage.go +++ b/internal/filtering/rewrite/storage.go @@ -7,8 +7,8 @@ import ( "strings" "sync" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/log" - "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/urlfilter" "github.com/AdguardTeam/urlfilter/filterlist" "github.com/AdguardTeam/urlfilter/rules" @@ -85,7 +85,7 @@ func (s *DefaultStorage) MatchRequest(dReq *urlfilter.DNSRequest) (rws []*rules. } // TODO(a.garipov): Check cnames for cycles on initialization. - cnames := stringutil.NewSet() + cnames := container.NewMapSet[string]() host := dReq.Hostname for len(rrules) > 0 && rrules[0].DNSRewrite != nil && rrules[0].DNSRewrite.NewCNAME != "" { rule := rrules[0] diff --git a/internal/home/clients.go b/internal/home/clients.go index fb627a2e14a..2d5b1231038 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -19,6 +19,7 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/whois" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/hostsfile" "github.com/AdguardTeam/golibs/log" @@ -54,7 +55,7 @@ type clientsContainer struct { // ipToRC maps IP addresses to runtime client information. ipToRC map[netip.Addr]*client.Runtime - allTags *stringutil.Set + allTags *container.MapSet[string] // dhcp is the DHCP service implementation. dhcp DHCP @@ -108,7 +109,7 @@ func (clients *clientsContainer) Init( clients.clientIndex = client.NewIndex() - clients.allTags = stringutil.NewSet(clientTags...) + clients.allTags = container.NewMapSet(clientTags...) // TODO(e.burkov): Use [dhcpsvc] implementation when it's ready. clients.dhcp = dhcpServer @@ -213,7 +214,7 @@ type clientObject struct { // toPersistent returns an initialized persistent client if there are no errors. func (o *clientObject) toPersistent( filteringConf *filtering.Config, - allTags *stringutil.Set, + allTags *container.MapSet[string], ) (cli *client.Persistent, err error) { cli = &client.Persistent{ Name: o.Name, @@ -307,8 +308,8 @@ func (clients *clientsContainer) forConfig() (objs []*clientObject) { BlockedServices: cli.BlockedServices.Clone(), IDs: cli.IDs(), - Tags: stringutil.CloneSlice(cli.Tags), - Upstreams: stringutil.CloneSlice(cli.Upstreams), + Tags: slices.Clone(cli.Tags), + Upstreams: slices.Clone(cli.Upstreams), UID: cli.UID, diff --git a/internal/home/i18n.go b/internal/home/i18n.go index 267205d3a83..d49ca2faf8c 100644 --- a/internal/home/i18n.go +++ b/internal/home/i18n.go @@ -5,12 +5,12 @@ import ( "net/http" "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/log" - "github.com/AdguardTeam/golibs/stringutil" ) // TODO(a.garipov): Get rid of a global or generate from .twosky.json. -var allowedLanguages = stringutil.NewSet( +var allowedLanguages = container.NewMapSet( "ar", "be", "bg", diff --git a/internal/ipset/ipset_linux.go b/internal/ipset/ipset_linux.go index 4cf1fe12736..12dcecea040 100644 --- a/internal/ipset/ipset_linux.go +++ b/internal/ipset/ipset_linux.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/AdguardTeam/golibs/container" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" "github.com/digineo/go-ipset/v2" @@ -174,18 +175,6 @@ func (p *props) parseAttrData(a netfilter.Attribute) { } } -// unit is a convenient alias for struct{}. -type unit = struct{} - -// ipsInIpset is the type of a set of IP-address-to-ipset mappings. -type ipsInIpset map[ipInIpsetEntry]unit - -// ipInIpsetEntry is the type for entries in an ipsInIpset set. -type ipInIpsetEntry struct { - ipsetName string - ipArr [net.IPv6len]byte -} - // manager is the Linux Netfilter ipset manager. type manager struct { nameToIpset map[string]props @@ -196,17 +185,24 @@ type manager struct { // mu protects all properties below. mu *sync.Mutex - // TODO(a.garipov): Currently, the ipset list is static, and we don't - // read the IPs already in sets, so we can assume that all incoming IPs - // are either added to all corresponding ipsets or not. When that stops - // being the case, for example if we add dynamic reconfiguration of - // ipsets, this map will need to become a per-ipset-name one. - addedIPs ipsInIpset + // TODO(a.garipov): Currently, the ipset list is static, and we don't read + // the IPs already in sets, so we can assume that all incoming IPs are + // either added to all corresponding ipsets or not. When that stops being + // the case, for example if we add dynamic reconfiguration of ipsets, this + // map will need to become a per-ipset-name one. + addedIPs *container.MapSet[ipInIpsetEntry] ipv4Conn ipsetConn ipv6Conn ipsetConn } +// ipInIpsetEntry is the type for entries in [manager.addIPs]. +type ipInIpsetEntry struct { + ipsetName string + // TODO(schzen): Use netip.Addr. + ipArr [net.IPv6len]byte +} + // dialNetfilter establishes connections to Linux's netfilter module. func (m *manager) dialNetfilter(conf *netlink.Config) (err error) { // The kernel API does not actually require two sockets but package @@ -372,7 +368,7 @@ func newManagerWithDialer(ipsetConf []string, dial dialer) (mgr Manager, err err dial: dial, - addedIPs: make(ipsInIpset), + addedIPs: container.NewMapSet[ipInIpsetEntry](), } err = m.dialNetfilter(&netlink.Config{}) @@ -438,7 +434,7 @@ func (m *manager) addIPs(host string, set props, ips []net.IP) (n int, err error } copy(e.ipArr[:], ip.To16()) - if _, added := m.addedIPs[e]; added { + if m.addedIPs.Has(e) { continue } @@ -471,7 +467,7 @@ func (m *manager) addIPs(host string, set props, ips []net.IP) (n int, err error for _, e := range newAddedEntries { s := m.nameToIpset[e.ipsetName] if s.isPersistent { - m.addedIPs[e] = unit{} + m.addedIPs.Add(e) } } diff --git a/internal/querylog/http.go b/internal/querylog/http.go index 3e71af5725f..1fb7cce4593 100644 --- a/internal/querylog/http.go +++ b/internal/querylog/http.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "net/url" + "slices" "strconv" "strings" "time" @@ -15,7 +16,6 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/golibs/log" - "github.com/AdguardTeam/golibs/stringutil" "github.com/AdguardTeam/golibs/timeutil" "golang.org/x/net/idna" ) @@ -308,7 +308,7 @@ func parseSearchCriterion(q url.Values, name string, ct criterionType) ( asciiVal = "" } case ctFilteringStatus: - if !stringutil.InSlice(filteringStatusValues, val) { + if !slices.Contains(filteringStatusValues, val) { return false, sc, fmt.Errorf("invalid value %s", val) } default: diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 5b811b57ffe..1ee456a08b5 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -26,7 +26,7 @@ require ( github.com/kyoh86/nolint v0.0.1 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/exp/typeparams v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/exp/typeparams v0.0.0-20240325151524-a685a6edb6d8 // indirect golang.org/x/mod v0.16.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 6b8959f4bae..be14d7adfdf 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -63,8 +63,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp/typeparams v0.0.0-20240222234643-814bf88cf225 h1:BzKNaIRXh1bD+1557OcFIHlpYBiVbK4zEyn8zBHi1SE= -golang.org/x/exp/typeparams v0.0.0-20240222234643-814bf88cf225/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20240325151524-a685a6edb6d8 h1:ShhqwXlNzuDeQzaa6htzo1S333ACXZzJZgZLpKAza8E= +golang.org/x/exp/typeparams v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= diff --git a/scripts/translations/upload.go b/scripts/translations/upload.go index b9cfd4bf796..dcad4084f6b 100644 --- a/scripts/translations/upload.go +++ b/scripts/translations/upload.go @@ -52,7 +52,7 @@ func prepareMultipartMsg( w := multipart.NewWriter(buf) var fw io.Writer - err = mapsutil.OrderedRangeError(formData, w.WriteField) + err = mapsutil.SortedRangeError(formData, w.WriteField) if err != nil { return nil, "", fmt.Errorf("writing field: %w", err) }