Pull request: use mathutil

Merge in DNS/adguard-home from use-mathutil to master

Squashed commit of the following:

commit cfe2c02a7bb727e81fcd91674aa777df37413a8e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jan 24 18:12:32 2023 +0300

    all: use mathutil
This commit is contained in:
Eugene Burkov 2023-01-24 19:50:19 +03:00
parent 2ecf2a4c42
commit 99ec1d840c
10 changed files with 29 additions and 55 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.18
require ( require (
github.com/AdguardTeam/dnsproxy v0.46.5 github.com/AdguardTeam/dnsproxy v0.46.5
github.com/AdguardTeam/golibs v0.11.3 github.com/AdguardTeam/golibs v0.11.4
github.com/AdguardTeam/urlfilter v0.16.0 github.com/AdguardTeam/urlfilter v0.16.0
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.5 github.com/ameshkov/dnscrypt/v2 v2.2.5

4
go.sum
View File

@ -2,8 +2,8 @@ github.com/AdguardTeam/dnsproxy v0.46.5 h1:TiJZhwaIDDaKkqEfJ9AD9aroFjcHN8oEbKB8W
github.com/AdguardTeam/dnsproxy v0.46.5/go.mod h1:yKBVgFlE6CqTQtye++3e7SATaMPc4Ixij+KkHsM6HhM= github.com/AdguardTeam/dnsproxy v0.46.5/go.mod h1:yKBVgFlE6CqTQtye++3e7SATaMPc4Ixij+KkHsM6HhM=
github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw= github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.11.3 h1:Oif+REq2WLycQ2Xm3ZPmJdfftptss0HbGWbxdFaC310= github.com/AdguardTeam/golibs v0.11.4 h1:IltyvxwCTN+xxJF5sh6VadF8Zfbf8elgCm9dgijSVzM=
github.com/AdguardTeam/golibs v0.11.3/go.mod h1:87bN2x4VsTritptE3XZg9l8T6gznWsIxHBcQ1DeRIXA= github.com/AdguardTeam/golibs v0.11.4/go.mod h1:87bN2x4VsTritptE3XZg9l8T6gznWsIxHBcQ1DeRIXA=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU= github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.16.0 h1:IO29m+ZyQuuOnPLTzHuXj35V1DZOp1Dcryl576P2syg= github.com/AdguardTeam/urlfilter v0.16.0 h1:IO29m+ZyQuuOnPLTzHuXj35V1DZOp1Dcryl576P2syg=
github.com/AdguardTeam/urlfilter v0.16.0/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI= github.com/AdguardTeam/urlfilter v0.16.0/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=

View File

@ -4,6 +4,8 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/AdguardTeam/golibs/mathutil"
) )
// NullBool is a nullable boolean. Use these in JSON requests and responses // NullBool is a nullable boolean. Use these in JSON requests and responses
@ -33,11 +35,7 @@ func (nb NullBool) String() (s string) {
// BoolToNullBool converts a bool into a NullBool. // BoolToNullBool converts a bool into a NullBool.
func BoolToNullBool(cond bool) (nb NullBool) { func BoolToNullBool(cond bool) (nb NullBool) {
if cond { return NBFalse - mathutil.BoolToNumber[NullBool](cond)
return NBTrue
}
return NBFalse
} }
// type check // type check

View File

@ -4,6 +4,9 @@ package aghio
import ( import (
"fmt" "fmt"
"io" "io"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/mathutil"
) )
// LimitReachedError records the limit and the operation that caused it. // LimitReachedError records the limit and the operation that caused it.
@ -11,22 +14,22 @@ type LimitReachedError struct {
Limit int64 Limit int64
} }
// Error implements the error interface for LimitReachedError. // Error implements the [error] interface for *LimitReachedError.
// //
// TODO(a.garipov): Think about error string format. // TODO(a.garipov): Think about error string format.
func (lre *LimitReachedError) Error() string { func (lre *LimitReachedError) Error() string {
return fmt.Sprintf("attempted to read more than %d bytes", lre.Limit) return fmt.Sprintf("attempted to read more than %d bytes", lre.Limit)
} }
// limitedReader is a wrapper for io.Reader with limited reader and dealing with // limitedReader is a wrapper for [io.Reader] limiting the input and dealing
// errors package. // with errors package.
type limitedReader struct { type limitedReader struct {
r io.Reader r io.Reader
limit int64 limit int64
n int64 n int64
} }
// Read implements Reader interface. // Read implements the [io.Reader] interface.
func (lr *limitedReader) Read(p []byte) (n int, err error) { func (lr *limitedReader) Read(p []byte) (n int, err error) {
if lr.n == 0 { if lr.n == 0 {
return 0, &LimitReachedError{ return 0, &LimitReachedError{
@ -34,9 +37,7 @@ func (lr *limitedReader) Read(p []byte) (n int, err error) {
} }
} }
if int64(len(p)) > lr.n { p = p[:mathutil.Min(lr.n, int64(len(p)))]
p = p[:lr.n]
}
n, err = lr.r.Read(p) n, err = lr.r.Read(p)
lr.n -= int64(n) lr.n -= int64(n)
@ -48,7 +49,7 @@ func (lr *limitedReader) Read(p []byte) (n int, err error) {
// n bytes read. // n bytes read.
func LimitReader(r io.Reader, n int64) (limited io.Reader, err error) { func LimitReader(r io.Reader, n int64) (limited io.Reader, err error) {
if n < 0 { if n < 0 {
return nil, fmt.Errorf("aghio: invalid n in LimitReader: %d", n) return nil, errors.Error("limit must be non-negative")
} }
return &limitedReader{ return &limitedReader{

View File

@ -24,7 +24,7 @@ func TestLimitReader(t *testing.T) {
name: "zero", name: "zero",
n: 0, n: 0,
}, { }, {
wantErrMsg: "aghio: invalid n in LimitReader: -1", wantErrMsg: "limit must be non-negative",
name: "negative", name: "negative",
n: -1, n: -1,
}} }}

View File

@ -56,7 +56,7 @@ func (rm *requestMatcher) MatchRequest(
) (res *urlfilter.DNSResult, ok bool) { ) (res *urlfilter.DNSResult, ok bool) {
switch req.DNSType { switch req.DNSType {
case dns.TypeA, dns.TypeAAAA, dns.TypePTR: case dns.TypeA, dns.TypeAAAA, dns.TypePTR:
log.Debug("%s: handling the request", hostsContainerPref) log.Debug("%s: handling the request for %s", hostsContainerPref, req.Hostname)
default: default:
return nil, false return nil, false
} }
@ -481,9 +481,6 @@ func (hc *HostsContainer) refresh() (err error) {
} }
// hc.last is nil on the first refresh, so let that one through. // hc.last is nil on the first refresh, so let that one through.
//
// TODO(a.garipov): Once https://github.com/golang/go/issues/56621 is
// resolved, remove the first condition.
if hc.last != nil && maps.EqualFunc(hp.table, hc.last, (*HostsRecord).equal) { if hc.last != nil && maps.EqualFunc(hp.table, hc.last, (*HostsRecord).equal) {
log.Debug("%s: no changes detected", hostsContainerPref) log.Debug("%s: no changes detected", hostsContainerPref)

View File

@ -17,6 +17,8 @@ import (
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/mathutil"
"golang.org/x/exp/slices"
) )
// UnsupportedError is returned by functions and methods when a particular // UnsupportedError is returned by functions and methods when a particular
@ -60,9 +62,8 @@ const MaxCmdOutputSize = 64 * 1024
func RunCommand(command string, arguments ...string) (code int, output []byte, err error) { func RunCommand(command string, arguments ...string) (code int, output []byte, err error) {
cmd := exec.Command(command, arguments...) cmd := exec.Command(command, arguments...)
out, err := cmd.Output() out, err := cmd.Output()
if len(out) > MaxCmdOutputSize {
out = out[:MaxCmdOutputSize] out = out[:mathutil.Min(len(out), MaxCmdOutputSize)]
}
if err != nil { if err != nil {
if eerr := new(exec.ExitError); errors.As(err, &eerr) { if eerr := new(exec.ExitError); errors.As(err, &eerr) {
@ -136,14 +137,12 @@ func parsePSOutput(r io.Reader, cmdName string, ignore []int) (largest, instNum
} }
cur, aerr := strconv.Atoi(fields[0]) cur, aerr := strconv.Atoi(fields[0])
if aerr != nil || cur < 0 || intIn(cur, ignore) { if aerr != nil || cur < 0 || slices.Contains(ignore, cur) {
continue continue
} }
instNum++ instNum++
if cur > largest { largest = mathutil.Max(largest, cur)
largest = cur
}
} }
if err = s.Err(); err != nil { if err = s.Err(); err != nil {
return 0, 0, fmt.Errorf("scanning stdout: %w", err) return 0, 0, fmt.Errorf("scanning stdout: %w", err)
@ -152,17 +151,6 @@ func parsePSOutput(r io.Reader, cmdName string, ignore []int) (largest, instNum
return largest, instNum, nil return largest, instNum, nil
} }
// intIn returns true if nums contains n.
func intIn(n int, nums []int) (ok bool) {
for _, nn := range nums {
if n == nn {
return true
}
}
return false
}
// IsOpenWrt returns true if host OS is OpenWrt. // IsOpenWrt returns true if host OS is OpenWrt.
func IsOpenWrt() (ok bool) { func IsOpenWrt() (ok bool) {
return isOpenWrt() return isOpenWrt()

View File

@ -7,6 +7,7 @@ import (
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/mathutil"
"github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/netutil"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
@ -335,15 +336,10 @@ func (s *Server) synthRR(rr dns.RR, soaTTL uint32) (result dns.RR) {
Name: aResp.Hdr.Name, Name: aResp.Hdr.Name,
Rrtype: dns.TypeAAAA, Rrtype: dns.TypeAAAA,
Class: aResp.Hdr.Class, Class: aResp.Hdr.Class,
Ttl: mathutil.Min(aResp.Hdr.Ttl, soaTTL),
}, },
AAAA: s.mapDNS64(addr), AAAA: s.mapDNS64(addr),
} }
if rrTTL := aResp.Hdr.Ttl; rrTTL < soaTTL {
aaaa.Hdr.Ttl = rrTTL
} else {
aaaa.Hdr.Ttl = soaTTL
}
return aaaa return aaaa
} }

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/mathutil"
"github.com/miekg/dns" "github.com/miekg/dns"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -201,7 +202,7 @@ func findRewrites(
if isWildcard(r.Domain) { if isWildcard(r.Domain) {
// Don't use rewrites[:0], because we need to return at least one // Don't use rewrites[:0], because we need to return at least one
// item here. // item here.
rewrites = rewrites[:max(1, i)] rewrites = rewrites[:mathutil.Max(1, i)]
break break
} }
@ -209,11 +210,3 @@ func findRewrites(
return rewrites, matched return rewrites, matched
} }
func max(a, b int) int {
if a > b {
return a
}
return b
}

View File

@ -66,11 +66,12 @@ func (ab *authRateLimiter) check(usrID string) (left time.Duration) {
defer ab.failedAuthsLock.Unlock() defer ab.failedAuthsLock.Unlock()
ab.cleanupLocked(now) ab.cleanupLocked(now)
return ab.checkLocked(usrID, now) return ab.checkLocked(usrID, now)
} }
// incLocked increments the number of unsuccessful attempts for attempter with // incLocked increments the number of unsuccessful attempts for attempter with
// ip and updates it's blocking moment if needed. For internal use only. // usrID and updates it's blocking moment if needed. For internal use only.
func (ab *authRateLimiter) incLocked(usrID string, now time.Time) { func (ab *authRateLimiter) incLocked(usrID string, now time.Time) {
until := now.Add(failedAuthTTL) until := now.Add(failedAuthTTL)
var attNum uint = 1 var attNum uint = 1