diff --git a/Makefile b/Makefile index c179dca5cffc4f7a53c29ced9d05d23e1ced9274..2edd4c1e5ba1c576ec6aa4c0644e1438eba29ead 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ DIST_DIR = build GOAMD64 = v1 GOPROXY = https://proxy.golang.org|direct GOTELEMETRY = off -GOTOOLCHAIN = go1.24.2 +GOTOOLCHAIN = go1.24.3 OUT = dnsproxy RACE = 0 REVISION = $${REVISION:-$$(git rev-parse --short HEAD)} diff --git a/go.mod b/go.mod index 42337a30f06c7e752d1fd642815562eb4d9f652e..4c62051a8749076be4d6cd2290a247b71a6e4be4 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,50 @@ module github.com/AdguardTeam/dnsproxy -go 1.24.2 +go 1.24.3 require ( - github.com/AdguardTeam/golibs v0.32.9 + github.com/AdguardTeam/golibs v0.32.11 github.com/ameshkov/dnscrypt/v2 v2.4.0 github.com/ameshkov/dnsstamps v1.0.3 github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 github.com/bluele/gcache v0.0.2 - github.com/miekg/dns v1.1.65 + github.com/miekg/dns v1.1.66 github.com/patrickmn/go-cache v2.1.0+incompatible // TODO(s.chzhen): Update after investigation of the 0-RTT bug/behavior // when TestUpstreamDoH_serverRestart/http3/second_try keeps failing. - github.com/quic-go/quic-go v0.48.2 + github.com/quic-go/quic-go v0.52.0 github.com/stretchr/testify v1.10.0 - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect - golang.org/x/net v0.39.0 + golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect + golang.org/x/net v0.40.0 golang.org/x/sys v0.33.0 gonum.org/v1/gonum v0.16.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.120.0 // indirect - cloud.google.com/go/ai v0.10.1 // indirect - cloud.google.com/go/auth v0.15.0 // indirect + cloud.google.com/go v0.121.2 // indirect + cloud.google.com/go/ai v0.12.1 // indirect + cloud.google.com/go/auth v0.16.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/longrunning v0.6.6 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + cloud.google.com/go/longrunning v0.6.7 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/ccojocar/zxcvbn-go v1.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/golangci/misspell v0.6.0 // indirect - github.com/google/generative-ai-go v0.19.0 // indirect + github.com/golangci/misspell v0.7.0 // indirect + github.com/google/generative-ai-go v0.20.1 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20250501235452-c0086092b71a // indirect + github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e // indirect github.com/google/renameio/v2 v2.0.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.14.1 // indirect + github.com/googleapis/gax-go/v2 v2.14.2 // indirect github.com/gookit/color v1.5.4 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/jstemmer/go-junit-report/v2 v2.1.0 // indirect @@ -54,32 +54,32 @@ require ( github.com/quic-go/qpack v0.5.1 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/securego/gosec/v2 v2.22.3 // indirect + github.com/securego/gosec/v2 v2.22.4 // indirect github.com/uudashr/gocognit v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.2 // indirect - golang.org/x/crypto v0.37.0 // indirect - golang.org/x/exp/typeparams v0.0.0-20250408133849-7e4ce0ab07d0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/oauth2 v0.29.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/telemetry v0.0.0-20250406004356-f593adaf3fc1 // indirect - golang.org/x/term v0.31.0 // indirect - golang.org/x/text v0.24.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.32.0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20250531010427-b6e5de432a8b // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.15.0 // indirect + golang.org/x/telemetry v0.0.0-20250605140807-cd7dbf5ade20 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.26.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/tools v0.33.0 // indirect golang.org/x/vuln v1.1.4 // indirect - google.golang.org/api v0.228.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect - google.golang.org/grpc v1.71.1 // indirect + google.golang.org/api v0.236.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/grpc v1.73.0 // indirect google.golang.org/protobuf v1.36.6 // indirect honnef.co/go/tools v0.6.1 // indirect mvdan.cc/editorconfig v0.3.0 // indirect diff --git a/go.sum b/go.sum index d185e08804e42e581b8bc99e234529a2be2e5153..3c26e1425181507674e137558d17783a3f714d8f 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,17 @@ -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/ai v0.10.1 h1:EU93KqYmMeOKgaBXAz2DshH2C/BzAT1P+iJORksLIic= -cloud.google.com/go/ai v0.10.1/go.mod h1:sWWHZvmJ83BjuxAQtYEiA0SFTpijtbH+SXWFO14ri5A= -cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= +cloud.google.com/go v0.121.2 h1:v2qQpN6Dx9x2NmwrqlesOt3Ys4ol5/lFZ6Mg1B7OJCg= +cloud.google.com/go v0.121.2/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= +cloud.google.com/go/ai v0.12.1 h1:m1n/VjUuHS+pEO/2R4/VbuuEIkgk0w67fDQvFaMngM0= +cloud.google.com/go/ai v0.12.1/go.mod h1:5vIPNe1ZQsVZqCliXIPL4QnhObQQY4d9hAGHdVc4iw4= +cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4= +cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR65Rbw= -cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= -github.com/AdguardTeam/golibs v0.32.9 h1:/6luT0aMOn05/s9eh1yA4lbcHgl0d1iEEvEBbIMMUk0= -github.com/AdguardTeam/golibs v0.32.9/go.mod h1:McV1QFFlKLElKa306V4OL/T2kr7564PhsayfvTWYBVs= +cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +github.com/AdguardTeam/golibs v0.32.11 h1:75EquS8SWvzsM3JFJY0359ZBw66jDjAegteHzh9nSw8= +github.com/AdguardTeam/golibs v0.32.11/go.mod h1:LXr0gqqZuVpt+L+bP3Nnr0/CecLmm3rxkdgyyW5JXXM= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/ameshkov/dnscrypt/v2 v2.4.0 h1:if6ZG2cuQmcP2TwSY+D0+8+xbPfoatufGlOQTMNkI9o= @@ -31,8 +31,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= @@ -41,17 +41,17 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= -github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= -github.com/google/generative-ai-go v0.19.0 h1:R71szggh8wHMCUlEMsW2A/3T+5LdEIkiaHSYgSpUgdg= -github.com/google/generative-ai-go v0.19.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E= +github.com/golangci/misspell v0.7.0 h1:4GOHr/T1lTW0hhR4tgaaV1WS/lJ+ncvYCoFKmqJsj0c= +github.com/golangci/misspell v0.7.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg= +github.com/google/generative-ai-go v0.20.1 h1:6dEIujpgN2V0PgLhr6c/M1ynRdc7ARtiIDPFzj45uNQ= +github.com/google/generative-ai-go v0.20.1/go.mod h1:TjOnZJmZKzarWbjUJgy+r3Ee7HGBRVLhOIgupnwR4Bg= github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU= github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/pprof v0.0.0-20250501235452-c0086092b71a h1:rDA3FfmxwXR+BVKKdz55WwMJ1pD2hJQNW31d+l3mPk4= -github.com/google/pprof v0.0.0-20250501235452-c0086092b71a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= +github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e h1:FJta/0WsADCe1r9vQjdHbd3KuiLPu7Y9WlyLGwMUNyE= +github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= @@ -62,8 +62,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0= +github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= @@ -76,12 +76,12 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= -github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= -github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= -github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= +github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -90,14 +90,14 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= -github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA= +github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/securego/gosec/v2 v2.22.3 h1:mRrCNmRF2NgZp4RJ8oJ6yPJ7G4x6OCiAXHd8x4trLRc= -github.com/securego/gosec/v2 v2.22.3/go.mod h1:42M9Xs0v1WseinaB/BmNGO8AVqG8vRfhC2686ACY48k= +github.com/securego/gosec/v2 v2.22.4 h1:21VdNGcKicFSv6rUDBc0cEtEl7lWyCKZxKIm0iwvrIM= +github.com/securego/gosec/v2 v2.22.4/go.mod h1:ww5Yie7KJ3AH8XZQTletkW5zOmIse6FACs/Ys8VR3qE= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -109,46 +109,46 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= -golang.org/x/exp/typeparams v0.0.0-20250408133849-7e4ce0ab07d0 h1:oMe07YcizemJ09rs2kRkFYAp0pt4e1lYLwPWiEGMpXE= -golang.org/x/exp/typeparams v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b h1:QoALfVG9rhQ/M7vYDScfPdWjGL9dlsVVM5VGh7aKoAA= +golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp/typeparams v0.0.0-20250531010427-b6e5de432a8b h1:BYXmVbbiQZNvDQnJIC37pAGLxabO8CGWgWEZrCtjXbk= +golang.org/x/exp/typeparams v0.0.0-20250531010427-b6e5de432a8b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -156,22 +156,22 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/telemetry v0.0.0-20250406004356-f593adaf3fc1 h1:LxyDqgHX2VuimV2UQSNFpQxz+NRUUsh8ulNcP3WvNG0= -golang.org/x/telemetry v0.0.0-20250406004356-f593adaf3fc1/go.mod h1:RoaXAWDwS90j6FxVKwJdBV+0HCU+llrKUGgJaxiKl6M= +golang.org/x/telemetry v0.0.0-20250605140807-cd7dbf5ade20 h1:76h5FVhq9x1b/mxY9tfFIY66XtbIeUx1af9FJOQ/R10= +golang.org/x/telemetry v0.0.0-20250605140807-cd7dbf5ade20/go.mod h1:mUcjA5g0luJpMYCLjhH91f4t4RAUNp+zq9ZmUoqPD7M= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= -golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= -golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I= golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -179,14 +179,16 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs= -google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4= -google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= -google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= -google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/api v0.236.0 h1:CAiEiDVtO4D/Qja2IA9VzlFrgPnK3XVMmRoJZlSWbc0= +google.golang.org/api v0.236.0/go.mod h1:X1WF9CU2oTc+Jml1tiIxGmWFK/UZezdqEu09gcxZAj4= +google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78= +google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= +google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= +google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/proxy/config.go b/proxy/config.go index 2f4947b055c43ec9332dd37a241e6243a83aee39..65065c8682d1061ef218812cb1d7c7959ea46117 100644 --- a/proxy/config.go +++ b/proxy/config.go @@ -86,7 +86,10 @@ type Config struct { PrivateRDNSUpstreamConfig *UpstreamConfig // Fallbacks is a list of fallback resolvers. Those will be used if the - // general set fails responding. + // general set fails responding. It isn't allowed to be empty, but can be + // nil, which means not to use fallbacks. + // + // TODO(e.burkov): Add explicit boolean for disabling fallbacks. Fallbacks *UpstreamConfig // Userinfo is the sole permitted userinfo for the DoH basic authentication. @@ -266,35 +269,42 @@ type PendingRequestsConfig struct { func (p *Proxy) validateConfig() (err error) { err = p.UpstreamConfig.validate() if err != nil { - return fmt.Errorf("validating general upstreams: %w", err) + return fmt.Errorf("general upstreams: %w", err) } err = ValidatePrivateConfig(p.PrivateRDNSUpstreamConfig, p.privateNets) if err != nil { if p.UsePrivateRDNS || errors.Is(err, upstream.ErrNoUpstreams) { - return fmt.Errorf("validating private RDNS upstreams: %w", err) + return fmt.Errorf("private rdns upstreams: %w", err) } } + err = p.Fallbacks.validate() // Allow [Proxy.Fallbacks] to be nil, but not empty. nil means not to use // fallbacks at all. - err = p.Fallbacks.validate() if errors.Is(err, upstream.ErrNoUpstreams) { - return fmt.Errorf("validating fallbacks: %w", err) + return fmt.Errorf("fallbacks: %w", err) } err = p.validateRatelimit() if err != nil { - return fmt.Errorf("validating ratelimit: %w", err) + return fmt.Errorf("ratelimit: %w", err) } switch p.UpstreamMode { - case "": - // Go on. - case UpstreamModeFastestAddr, UpstreamModeLoadBalance, UpstreamModeParallel: + case + "", + UpstreamModeFastestAddr, + UpstreamModeLoadBalance, + UpstreamModeParallel: // Go on. default: - return fmt.Errorf("bad upstream mode: %q", p.UpstreamMode) + return fmt.Errorf("upstream mode: %w: %q", errors.ErrBadEnumValue, p.UpstreamMode) + } + + err = p.validateBasicAuth() + if err != nil { + return fmt.Errorf("basic auth: %w", err) } p.logConfigInfo() @@ -368,9 +378,11 @@ func (p *Proxy) logConfigInfo() { // validateListenAddrs returns an error if the addresses are not configured // properly. +// +// TODO(e.burkov): Move to configuration validation. func (p *Proxy) validateListenAddrs() (err error) { if !p.hasListenAddrs() { - return errors.Error("no listen address specified") + return fmt.Errorf("listen addresses: %w", errors.ErrNoValue) } err = p.validateTLSConfig() diff --git a/proxy/dns64.go b/proxy/dns64.go index 8738eae89fc748bfbf3b8f7bdbd954d99aca8746..2779ee117e0c4b5df53eed29d2820a4833e21dfb 100644 --- a/proxy/dns64.go +++ b/proxy/dns64.go @@ -37,6 +37,8 @@ const ( // is specified explicitly. Each prefix also validated to be a valid IPv6 CIDR // with a maximum length of 96 bits. The first specified prefix is then used to // synthesize AAAA records. +// +// TODO(e.burkov): Split validation and initialization. func (p *Proxy) setupDNS64() (err error) { if !p.Config.UseDNS64 { return nil diff --git a/proxy/proxy.go b/proxy/proxy.go index befed45af8c270310c72f0a423e4fa1949cc2592..054cfff8fe2776c8310b55f13a21ed740688485f 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -27,6 +27,7 @@ import ( "github.com/AdguardTeam/golibs/service" "github.com/AdguardTeam/golibs/syncutil" "github.com/AdguardTeam/golibs/timeutil" + "github.com/AdguardTeam/golibs/validate" "github.com/ameshkov/dnscrypt/v2" "github.com/miekg/dns" gocache "github.com/patrickmn/go-cache" @@ -183,9 +184,9 @@ type Proxy struct { // udpOOBSize is the size of the out-of-band data for UDP connections. udpOOBSize int - // bindRetryNum is the number of retries for binding to an address for + // bindRetryCount is the number of retries for binding to an address for // listening. Zero means one attempt and no retries. - bindRetryNum uint + bindRetryCount uint // bindRetryIvl is the interval between attempts to bind to an address for // listening. @@ -215,6 +216,8 @@ type Proxy struct { // New creates a new Proxy with the specified configuration. c must not be nil. // // TODO(e.burkov): Cover with tests. +// +// TODO(e.burkov): Add context. func New(c *Config) (p *Proxy, err error) { p = &Proxy{ Config: *c, @@ -256,12 +259,6 @@ func New(c *Config) (p *Proxy, err error) { return nil, err } - // TODO(s.chzhen): Consider moving to [Proxy.validateConfig]. - err = p.validateBasicAuth() - if err != nil { - return nil, fmt.Errorf("basic auth: %w", err) - } - p.initCache() if p.MaxGoroutines > 0 { @@ -281,7 +278,7 @@ func New(c *Config) (p *Proxy, err error) { } if bindRetries := c.BindRetryConfig; bindRetries != nil && bindRetries.Enabled { - p.bindRetryNum = bindRetries.Count + p.bindRetryCount = bindRetries.Count p.bindRetryIvl = bindRetries.Interval } @@ -290,6 +287,7 @@ func New(c *Config) (p *Proxy, err error) { return nil, fmt.Errorf("setting up DNS64: %w", err) } + // TODO(e.burkov): Clone all mutable fields of Config. p.RatelimitWhitelist = slices.Clone(p.RatelimitWhitelist) slices.SortFunc(p.RatelimitWhitelist, netip.Addr.Compare) @@ -324,11 +322,7 @@ func (p *Proxy) validateBasicAuth() (err error) { return nil } - if len(conf.HTTPSListenAddr) == 0 { - return errors.Error("no https addrs") - } - - return nil + return validate.NotEmptySlice("HTTPSListenAddr", conf.HTTPSListenAddr) } // Returns true if proxy is started. It is safe for concurrent use. @@ -359,12 +353,15 @@ func (p *Proxy) Start(ctx context.Context) (err error) { return err } - err = p.configureListeners(ctx) + err = p.startListeners(ctx) if err != nil { - return fmt.Errorf("configuring listeners: %w", err) + closeErr := errors.Join(p.closeListeners(nil)...) + + return fmt.Errorf("configuring listeners: %w", errors.WithDeferred(err, closeErr)) } - p.startListeners() + p.serveListeners() + p.started = true return nil @@ -390,7 +387,8 @@ func closeAll[C io.Closer](errs []error, closers ...C) (appended []error) { return errs } -// Shutdown implements the [service.Interface] for *Proxy. +// Shutdown implements the [service.Interface] for *Proxy. It also closes the +// configured upstream configurations. func (p *Proxy) Shutdown(ctx context.Context) (err error) { p.logger.InfoContext(ctx, "stopping server") @@ -404,17 +402,47 @@ func (p *Proxy) Shutdown(ctx context.Context) (err error) { return nil } - errs := closeAll(nil, p.tcpListen...) + errs := p.closeListeners(nil) + + for _, u := range []*UpstreamConfig{ + p.UpstreamConfig, + p.PrivateRDNSUpstreamConfig, + p.Fallbacks, + } { + if u != nil { + errs = closeAll(errs, u) + } + } + + p.started = false + + p.logger.InfoContext(ctx, "stopped dns proxy server") + + err = errors.Join(errs...) + if err != nil { + return fmt.Errorf("stopping dns proxy server: %w", err) + } + + return nil +} + +// closeListeners closes all acrive listeners and returns the occurred errors. +// +// TODO(e.burkov): Remove the argument if it remains unused. +func (p *Proxy) closeListeners(errs []error) (res []error) { + res = errs + + res = closeAll(res, p.tcpListen...) p.tcpListen = nil - errs = closeAll(errs, p.udpListen...) + res = closeAll(res, p.udpListen...) p.udpListen = nil - errs = closeAll(errs, p.tlsListen...) + res = closeAll(res, p.tlsListen...) p.tlsListen = nil if p.httpsServer != nil { - errs = closeAll(errs, p.httpsServer) + res = closeAll(res, p.httpsServer) p.httpsServer = nil // No need to close these since they're closed by httpsServer.Close(). @@ -422,47 +450,29 @@ func (p *Proxy) Shutdown(ctx context.Context) (err error) { } if p.h3Server != nil { - errs = closeAll(errs, p.h3Server) + res = closeAll(res, p.h3Server) p.h3Server = nil } - errs = closeAll(errs, p.h3Listen...) + res = closeAll(res, p.h3Listen...) p.h3Listen = nil - errs = closeAll(errs, p.quicListen...) + res = closeAll(res, p.quicListen...) p.quicListen = nil - errs = closeAll(errs, p.quicTransports...) + res = closeAll(res, p.quicTransports...) p.quicTransports = nil - errs = closeAll(errs, p.quicConns...) + res = closeAll(res, p.quicConns...) p.quicConns = nil - errs = closeAll(errs, p.dnsCryptUDPListen...) + res = closeAll(res, p.dnsCryptUDPListen...) p.dnsCryptUDPListen = nil - errs = closeAll(errs, p.dnsCryptTCPListen...) + res = closeAll(res, p.dnsCryptTCPListen...) p.dnsCryptTCPListen = nil - for _, u := range []*UpstreamConfig{ - p.UpstreamConfig, - p.PrivateRDNSUpstreamConfig, - p.Fallbacks, - } { - if u != nil { - errs = closeAll(errs, u) - } - } - - p.started = false - - p.logger.InfoContext(ctx, "stopped dns proxy server") - - if len(errs) > 0 { - return fmt.Errorf("stopping dns proxy server: %w", errors.Join(errs...)) - } - - return nil + return res } // addrFunc provides the address from the given A. diff --git a/proxy/proxy_test.go b/proxy/proxy_test.go index 47a0882efa89bfd649e4e82e9b931806afa2638f..d6930d47c2b9f741b5755f2224efbec42cf538f6 100644 --- a/proxy/proxy_test.go +++ b/proxy/proxy_test.go @@ -4,6 +4,7 @@ import ( "net" "testing" + "github.com/AdguardTeam/dnsproxy/internal/bootstrap" "github.com/AdguardTeam/dnsproxy/internal/dnsproxytest" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" @@ -143,3 +144,52 @@ func TestProxy_Resolve_cache(t *testing.T) { }) } } + +func TestProxy_Start_closeOnFail(t *testing.T) { + t.Parallel() + + l, err := net.ListenTCP(bootstrap.NetworkTCP, net.TCPAddrFromAddrPort(localhostAnyPort)) + require.NoError(t, err) + + tcpAddr := testutil.RequireTypeAssert[*net.TCPAddr](t, l.Addr()) + + ups := &dnsproxytest.FakeUpstream{ + OnExchange: func(_ *dns.Msg) (_ *dns.Msg, _ error) { panic("not implemented") }, + OnAddress: func() (_ string) { panic("not implemented") }, + OnClose: func() (_ error) { panic("not implemented") }, + } + + p, err := proxy.New(&proxy.Config{ + // Add a free address. + UDPListenAddr: []*net.UDPAddr{net.UDPAddrFromAddrPort(localhostAnyPort)}, + // Add a bound address. + TCPListenAddr: []*net.TCPAddr{tcpAddr}, + UpstreamConfig: &proxy.UpstreamConfig{Upstreams: []upstream.Upstream{ups}}, + }) + require.NoError(t, err) + + require.True(t, t.Run("start_fail", func(t *testing.T) { + ctx := testutil.ContextWithTimeout(t, testTimeout) + err = p.Start(ctx) + + var netErr net.Error + require.ErrorAs(t, err, &netErr) + })) + + // Don't panic anymore. + ups.OnClose = func() (err error) { return nil } + + require.True(t, t.Run("restart_success", func(t *testing.T) { + require.NoError(t, l.Close()) + + ctx := testutil.ContextWithTimeout(t, testTimeout) + err = p.Start(ctx) + require.NoError(t, err) + + testutil.CleanupAndRequireSuccess(t, func() (err error) { + ctx = testutil.ContextWithTimeout(t, testTimeout) + + return p.Shutdown(ctx) + }) + })) +} diff --git a/proxy/retry.go b/proxy/retry.go index 64a81e8dbca9fb95e5ff4cc4effb5a699038e636..1b2d5f370a4858dc36b3cdd8bf371b8602418c1b 100644 --- a/proxy/retry.go +++ b/proxy/retry.go @@ -32,7 +32,7 @@ func (p *Proxy) bindWithRetry(ctx context.Context, bindFunc func() (err error)) p.logger.WarnContext(ctx, "binding", "attempt", 1, slogutil.KeyError, err) - for attempt := uint(1); attempt <= p.bindRetryNum; attempt++ { + for attempt := uint(1); attempt <= p.bindRetryCount; attempt++ { time.Sleep(p.bindRetryIvl) retryErr := bindFunc() diff --git a/proxy/retry_internal_test.go b/proxy/retry_internal_test.go index 23ec9c234091eeddabe101fd0ce069a1e1b19c8a..3b81d988850034913a21da5e8bb0764ba3c315c1 100644 --- a/proxy/retry_internal_test.go +++ b/proxy/retry_internal_test.go @@ -76,9 +76,9 @@ func TestWithRetry(t *testing.T) { }} p := &Proxy{ - logger: slogutil.NewDiscardLogger(), - bindRetryNum: 1, - bindRetryIvl: 0, + logger: slogutil.NewDiscardLogger(), + bindRetryCount: 1, + bindRetryIvl: 0, } for _, tc := range testCases { diff --git a/proxy/server.go b/proxy/server.go index 646c52383319a7a0559b194c09b1bc984f6f3125..2734a00cb0624258b546d965fd848105ca0dae52 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -15,8 +15,9 @@ import ( "github.com/quic-go/quic-go" ) -// configureListeners configures listeners. -func (p *Proxy) configureListeners(ctx context.Context) (err error) { +// startListeners configures listeners and starts listening each configured +// address. If it returns an error, all listeners should be closed manually. +func (p *Proxy) startListeners(ctx context.Context) (err error) { err = p.initUDPListeners(ctx) if err != nil { return err @@ -50,8 +51,8 @@ func (p *Proxy) configureListeners(ctx context.Context) (err error) { return nil } -// startListeners starts listener loops. -func (p *Proxy) startListeners() { +// serveListeners starts serving the configured listeners. +func (p *Proxy) serveListeners() { for _, l := range p.udpListen { go p.udpPacketLoop(l, p.requestsSema) } diff --git a/proxy/upstreams.go b/proxy/upstreams.go index c618e7de75794a3cb492be66dc54425c822a5b5d..df90395c22b51d3fde6b1fa7c19d15cf6c68be3f 100644 --- a/proxy/upstreams.go +++ b/proxy/upstreams.go @@ -327,20 +327,15 @@ func (p *configParser) includeToReserved(dnsUpstream upstream.Upstream, domains // considered valid if it contains at least a single default upstream. Empty c // causes [upstream.ErrNoUpstreams]. func (uc *UpstreamConfig) validate() (err error) { - const ( - errNilConf errors.Error = "upstream config is nil" - errNoDefault errors.Error = "no default upstreams specified" - ) - switch { case uc == nil: - return errNilConf + return errors.ErrNoValue case len(uc.Upstreams) > 0: return nil case len(uc.DomainReservedUpstreams) == 0 && len(uc.SpecifiedDomainUpstreams) == 0: return upstream.ErrNoUpstreams default: - return errNoDefault + return fmt.Errorf("default upstreams: %w", errors.ErrNoValue) } } diff --git a/proxy/upstreams_internal_test.go b/proxy/upstreams_internal_test.go index a8df057e89fcbc4aa329c0f3a3922cdc2f8fc4ab..8952658fa476f6d4ffea0bca4705aa0c25f3a2d7 100644 --- a/proxy/upstreams_internal_test.go +++ b/proxy/upstreams_internal_test.go @@ -188,7 +188,7 @@ func TestUpstreamConfig_Validate(t *testing.T) { }, }, { name: "no_default", - wantErr: errors.Error("no default upstreams specified"), + wantErr: errors.ErrNoValue, in: []string{ "[/domain.example/]udp://upstream.example:53", "[/another.domain.example/]#", @@ -205,7 +205,9 @@ func TestUpstreamConfig_Validate(t *testing.T) { } t.Run("actual_nil", func(t *testing.T) { - assert.ErrorIs(t, (*UpstreamConfig)(nil).validate(), errors.Error("upstream config is nil")) + var c *UpstreamConfig + + assert.Equal(t, c.validate(), errors.ErrNoValue) }) } diff --git a/upstream/parallel.go b/upstream/parallel.go index 5bc5a5eb09fd9cf0c498a1747c90999f447cfab3..a2c3c495a0a6bbf30fa0315d562be6fe87bfddae 100644 --- a/upstream/parallel.go +++ b/upstream/parallel.go @@ -8,6 +8,8 @@ import ( "github.com/miekg/dns" ) +// TODO(e.burkov): Consider using wrapped [errors.ErrNoValue] and +// [errors.ErrEmptyValue] instead. const ( // ErrNoUpstreams is returned from the methods that expect at least a single // upstream to work with when no upstreams specified.