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:
parent
2ecf2a4c42
commit
99ec1d840c
2
go.mod
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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,
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue