diff --git a/mosdns/Makefile b/mosdns/Makefile index 5b00978..a37fa7c 100644 --- a/mosdns/Makefile +++ b/mosdns/Makefile @@ -19,9 +19,10 @@ PKG_MAINTAINER:=Tianling Shen PKG_BUILD_DEPENDS:=golang/host PKG_BUILD_PARALLEL:=1 PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 GO_PKG:=github.com/IrineSistiana/mosdns -GO_PKG_LDFLAGS_X:=main.version=v$(PKG_VERSION) +GO_PKG_LDFLAGS_X:=main.version=v$(PKG_VERSION)-$(PKG_RELEASE) include $(INCLUDE_DIR)/package.mk include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk diff --git a/mosdns/patches/100-update-deps.patch b/mosdns/patches/100-update-dependencies.patch similarity index 85% rename from mosdns/patches/100-update-deps.patch rename to mosdns/patches/100-update-dependencies.patch index dfdfedf..1e6267d 100644 --- a/mosdns/patches/100-update-deps.patch +++ b/mosdns/patches/100-update-dependencies.patch @@ -1,21 +1,25 @@ -From 1a5d1bbc33a20856d20b3935338c279ee9aae584 Mon Sep 17 00:00:00 2001 +From 5bb7b776f8b5aba1b23ee5337e2ed3b8a1a79ccd Mon Sep 17 00:00:00 2001 From: sbwml Date: Fri, 25 Aug 2023 09:19:37 +0800 -Subject: [PATCH] update dependencies & quic-go v0.38.1 +Subject: [PATCH 01/10] update dependencies --- - go.mod | 66 +++++++------ - go.sum | 149 ++++++++++++++--------------- - pkg/server/http_handler/handler.go | 1 + - pkg/upstream/upstream.go | 23 +++-- - 4 files changed, 119 insertions(+), 120 deletions(-) + go.mod | 70 +++++++++--------- + go.sum | 156 ++++++++++++++++++++------------------- + pkg/upstream/upstream.go | 23 +++--- + 3 files changed, 128 insertions(+), 121 deletions(-) diff --git a/go.mod b/go.mod -index 2212cd3..1a1dd43 100644 +index 2212cd3..b56078b 100644 --- a/go.mod +++ b/go.mod -@@ -3,26 +3,26 @@ module github.com/IrineSistiana/mosdns/v5 - go 1.19 +@@ -1,28 +1,30 @@ + module github.com/IrineSistiana/mosdns/v5 + +-go 1.19 ++go 1.21 ++ ++toolchain go1.21.1 require ( - github.com/go-chi/chi/v5 v5.0.8 @@ -25,7 +29,7 @@ index 2212cd3..1a1dd43 100644 - github.com/klauspost/compress v1.16.3 - github.com/miekg/dns v1.1.52 + github.com/klauspost/compress v1.16.7 -+ github.com/miekg/dns v1.1.55 ++ github.com/miekg/dns v1.1.56 github.com/mitchellh/mapstructure v1.5.0 github.com/nadoo/ipset v0.5.0 - github.com/prometheus/client_golang v1.14.0 @@ -46,17 +50,17 @@ index 2212cd3..1a1dd43 100644 - golang.org/x/sync v0.1.0 - golang.org/x/sys v0.6.0 - google.golang.org/protobuf v1.29.1 -+ go.uber.org/zap v1.25.0 ++ go.uber.org/zap v1.26.0 + go4.org/netipx v0.0.0-20230824141953-6213f710f925 -+ golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 -+ golang.org/x/net v0.14.0 ++ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 ++ golang.org/x/net v0.15.0 + golang.org/x/sync v0.3.0 -+ golang.org/x/sys v0.11.0 ++ golang.org/x/sys v0.12.0 + google.golang.org/protobuf v1.31.0 ) replace github.com/nadoo/ipset v0.5.0 => github.com/IrineSistiana/ipset v0.5.1-0.20220703061533-6e0fc3b04c0a -@@ -32,39 +32,37 @@ require ( +@@ -32,39 +34,37 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -66,7 +70,7 @@ index 2212cd3..1a1dd43 100644 github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect -+ github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect ++ github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect @@ -77,9 +81,9 @@ index 2212cd3..1a1dd43 100644 - github.com/onsi/ginkgo/v2 v2.9.1 // indirect - github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/mdlayher/netlink v1.7.2 // indirect -+ github.com/mdlayher/socket v0.4.1 // indirect ++ github.com/mdlayher/socket v0.5.0 // indirect + github.com/onsi/ginkgo/v2 v2.12.0 // indirect -+ github.com/pelletier/go-toml/v2 v2.0.9 // indirect ++ github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect @@ -90,7 +94,7 @@ index 2212cd3..1a1dd43 100644 github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.1 // indirect - github.com/quic-go/qtls-go1-20 v0.1.1 // indirect -+ github.com/quic-go/qtls-go1-20 v0.3.3 // indirect ++ github.com/quic-go/qtls-go1-20 v0.3.4 // indirect github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cast v1.5.1 // indirect @@ -106,32 +110,32 @@ index 2212cd3..1a1dd43 100644 - golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.7.0 // indirect + go.uber.org/multierr v1.11.0 // indirect -+ golang.org/x/crypto v0.12.0 // indirect ++ golang.org/x/crypto v0.13.0 // indirect + golang.org/x/mod v0.12.0 // indirect -+ golang.org/x/text v0.12.0 // indirect -+ golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect ++ golang.org/x/text v0.13.0 // indirect ++ golang.org/x/tools v0.13.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum -index 960ad98..59c420f 100644 +index 960ad98..633f864 100644 --- a/go.sum +++ b/go.sum -@@ -40,7 +40,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 +@@ -40,7 +40,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/IrineSistiana/ipset v0.5.1-0.20220703061533-6e0fc3b04c0a h1:GQdh/h0q0ni3L//CXusyk+7QdhBL289vdNaes1WKkHI= github.com/IrineSistiana/ipset v0.5.1-0.20220703061533-6e0fc3b04c0a/go.mod h1:rYF5DQLRGGoQ8ZSWeK+6eX5amAuPqwFkWjhQlEITGJQ= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -+github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -@@ -63,17 +63,17 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m +@@ -63,17 +62,19 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= ++github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= @@ -145,23 +149,24 @@ index 960ad98..59c420f 100644 -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= ++github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -@@ -133,8 +133,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf +@@ -133,8 +134,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ= -github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= -+github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -+github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= ++github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 h1:gpptm606MZYGaMHMsB4Srmb6EbW/IVHnt04rcMXnkBQ= ++github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -@@ -146,7 +146,6 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +@@ -146,7 +147,6 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -169,7 +174,7 @@ index 960ad98..59c420f 100644 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= -@@ -156,11 +155,11 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X +@@ -156,81 +156,83 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -181,10 +186,12 @@ index 960ad98..59c420f 100644 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= ++github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -@@ -168,69 +167,67 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V ++github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= + github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -196,10 +203,10 @@ index 960ad98..59c420f 100644 -github.com/miekg/dns v1.1.52/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= +github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= -+github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= -+github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= -+github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -+github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= ++github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= ++github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= ++github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= ++github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= @@ -211,8 +218,9 @@ index 960ad98..59c420f 100644 +github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= +github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -+github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -+github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= ++github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= ++github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= ++github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -242,13 +250,14 @@ index 960ad98..59c420f 100644 -github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= -github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= -+github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -+github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= ++github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= ++github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= ++github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= @@ -289,7 +298,7 @@ index 960ad98..59c420f 100644 github.com/vishvananda/netlink v1.2.1-beta.2.0.20221107222636-d3c0a2caa559 h1:NwQroOyW+fpfiUroBzAMqFc6NRwBmvJevoVtEK6gsFE= github.com/vishvananda/netlink v1.2.1-beta.2.0.20221107222636-d3c0a2caa559/go.mod h1:cAAsePK2e15YDAMJNyOpGYEWNe4sIghTY7gpz4cX/Ik= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -@@ -247,15 +244,13 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +@@ -247,15 +249,14 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= @@ -303,38 +312,39 @@ index 960ad98..59c420f 100644 -go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo= -go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= ++go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -+go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -+go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= ++go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= ++go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ= +go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -@@ -263,8 +258,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U +@@ -263,8 +264,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= ++golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= ++golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -@@ -275,8 +270,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 +@@ -275,8 +276,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230314191032-db074128a8ec h1:pAv+d8BM2JNnNctsLJ6nnZ6NqXT8N4+eauvZSb3P0I0= -golang.org/x/exp v0.0.0-20230314191032-db074128a8ec/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= ++golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= ++golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -@@ -301,8 +296,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +@@ -301,8 +302,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -345,18 +355,18 @@ index 960ad98..59c420f 100644 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -@@ -336,8 +331,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v +@@ -336,8 +337,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= ++golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= ++golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -@@ -358,8 +353,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ +@@ -358,8 +359,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -367,40 +377,40 @@ index 960ad98..59c420f 100644 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -@@ -401,8 +396,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc +@@ -401,8 +402,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= ++golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= ++golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -@@ -412,8 +407,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +@@ -412,8 +413,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -+golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= ++golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= ++golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -@@ -465,8 +460,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f +@@ -465,8 +466,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -+golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -+golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= ++golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= ++golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -@@ -561,8 +556,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj +@@ -561,11 +562,12 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -411,18 +421,10 @@ index 960ad98..59c420f 100644 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -diff --git a/pkg/server/http_handler/handler.go b/pkg/server/http_handler/handler.go -index 3e800f9..25f52e1 100644 ---- a/pkg/server/http_handler/handler.go -+++ b/pkg/server/http_handler/handler.go -@@ -96,6 +96,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - if err != nil { - h.warnErr(req, "invalid request", err) - w.WriteHeader(http.StatusBadRequest) -+ w.Write([]byte("Bad Request")) - return - } - ++gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= + gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= + gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= + gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/pkg/upstream/upstream.go b/pkg/upstream/upstream.go index d0fdc74..8486563 100644 --- a/pkg/upstream/upstream.go diff --git a/mosdns/patches/101-fix-nftset-mask.patch b/mosdns/patches/101-fix-nftset-mask-667.patch similarity index 91% rename from mosdns/patches/101-fix-nftset-mask.patch rename to mosdns/patches/101-fix-nftset-mask-667.patch index f4afce1..6f1cfcd 100644 --- a/mosdns/patches/101-fix-nftset-mask.patch +++ b/mosdns/patches/101-fix-nftset-mask-667.patch @@ -1,14 +1,14 @@ -From 0cb2257a6cbb63e0717f2324bb7563c32714934f Mon Sep 17 00:00:00 2001 +From 854b3e77c36acfe8032e71306d617d40fce19591 Mon Sep 17 00:00:00 2001 From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> Date: Fri, 16 Jun 2023 14:56:30 +0800 -Subject: [PATCH] fix #667 +Subject: [PATCH 02/10] fix #667 --- pkg/nftset_utils/handler.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/pkg/nftset_utils/handler.go b/pkg/nftset_utils/handler.go -index 7403f390a..3b79afb42 100644 +index 7403f39..3b79afb 100644 --- a/pkg/nftset_utils/handler.go +++ b/pkg/nftset_utils/handler.go @@ -24,11 +24,12 @@ package nftset_utils @@ -55,3 +55,6 @@ index 7403f390a..3b79afb42 100644 } else { elems = append(elems, nftables.SetElement{Key: e.Addr().AsSlice()}) } +-- +2.34.8 + diff --git a/mosdns/patches/102-server-simplify-udp-oob-handling.patch b/mosdns/patches/102-server-simplify-udp-oob-handling.patch new file mode 100644 index 0000000..cbbc6bc --- /dev/null +++ b/mosdns/patches/102-server-simplify-udp-oob-handling.patch @@ -0,0 +1,350 @@ +From f0274e3664a690d8ef1dd05ba7dc68869df7806f Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Thu, 31 Aug 2023 18:09:09 +0800 +Subject: [PATCH 03/10] server: simplify udp oob handling + +--- + pkg/server/udp.go | 71 +++++++--------- + pkg/server/udp_linux.go | 112 +++++++++++-------------- + pkg/server/udp_others.go | 4 +- + plugin/server/udp_server/udp_server.go | 5 +- + 4 files changed, 86 insertions(+), 106 deletions(-) + +diff --git a/pkg/server/udp.go b/pkg/server/udp.go +index 45d689c..8980a08 100644 +--- a/pkg/server/udp.go ++++ b/pkg/server/udp.go +@@ -22,14 +22,14 @@ package server + import ( + "context" + "fmt" ++ "net" ++ + "github.com/IrineSistiana/mosdns/v5/mlog" + "github.com/IrineSistiana/mosdns/v5/pkg/pool" + "github.com/IrineSistiana/mosdns/v5/pkg/query_context" + "github.com/IrineSistiana/mosdns/v5/pkg/server/dns_handler" +- "github.com/IrineSistiana/mosdns/v5/pkg/utils" + "github.com/miekg/dns" + "go.uber.org/zap" +- "net" + ) + + type UDPServer struct { +@@ -53,39 +53,31 @@ func (opts *UDPServerOpts) init() { + return + } + +-// cmcUDPConn can read and write cmsg. +-type cmcUDPConn interface { +- readFrom(b []byte) (n int, dst net.IP, IfIndex int, src net.Addr, err error) +- writeTo(b []byte, src net.IP, IfIndex int, dst net.Addr) (n int, err error) +-} +- + // ServeUDP starts a server at c. It returns if c had a read error. + // It always returns a non-nil error. +-func (s *UDPServer) ServeUDP(c net.PacketConn) error { ++func (s *UDPServer) ServeUDP(c *net.UDPConn) error { + listenerCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + + rb := pool.GetBuf(dns.MaxMsgSize) + defer pool.ReleaseBuf(rb) + +- var cmc cmcUDPConn +- var err error +- uc, ok := c.(*net.UDPConn) +- if ok && uc.LocalAddr().(*net.UDPAddr).IP.IsUnspecified() { +- cmc, err = newCmc(uc) +- if err != nil { +- return fmt.Errorf("failed to control socket cmsg, %w", err) +- } +- } else { +- cmc = newDummyCmc(c) ++ oobReader, oobWriter, err := initOobHandler(c) ++ if err != nil { ++ return fmt.Errorf("failed to init oob handler, %w", err) ++ } ++ var ob []byte ++ if oobReader != nil { ++ ob := pool.GetBuf(1024) ++ defer pool.ReleaseBuf(ob) + } + + for { +- n, localAddr, ifIndex, remoteAddr, err := cmc.readFrom(rb) ++ n, oobn, _, remoteAddr, err := c.ReadMsgUDPAddrPort(rb, ob) + if err != nil { + return fmt.Errorf("unexpected read err: %w", err) + } +- clientAddr := utils.GetAddrFromAddr(remoteAddr) ++ clientAddr := remoteAddr.Addr() + + q := new(dns.Msg) + if err := q.Unpack(rb[:n]); err != nil { +@@ -93,6 +85,15 @@ func (s *UDPServer) ServeUDP(c net.PacketConn) error { + continue + } + ++ var dstIpFromCm net.IP ++ if oobReader != nil { ++ var err error ++ dstIpFromCm, err = oobReader(ob[:oobn]) ++ if err != nil { ++ s.opts.Logger.Error("failed to get dst address from oob", zap.Error(err)) ++ } ++ } ++ + // handle query + go func() { + qCtx := query_context.NewContext(q) +@@ -110,7 +111,12 @@ func (s *UDPServer) ServeUDP(c net.PacketConn) error { + return + } + defer pool.ReleaseBuf(buf) +- if _, err := cmc.writeTo(b, localAddr, ifIndex, remoteAddr); err != nil { ++ var oob []byte ++ ++ if oobWriter != nil && dstIpFromCm != nil { ++ oob = oobWriter(dstIpFromCm) ++ } ++ if _, _, err := c.WriteMsgUDPAddrPort(b, oob, remoteAddr); err != nil { + s.opts.Logger.Warn("failed to write response", zap.Stringer("client", remoteAddr), zap.Error(err)) + } + } +@@ -129,22 +135,5 @@ func getUDPSize(m *dns.Msg) int { + return int(s) + } + +-// newDummyCmc returns a dummyCmcWrapper. +-func newDummyCmc(c net.PacketConn) cmcUDPConn { +- return dummyCmcWrapper{c: c} +-} +- +-// dummyCmcWrapper is just a wrapper that implements cmcUDPConn but does not +-// write or read any control msg. +-type dummyCmcWrapper struct { +- c net.PacketConn +-} +- +-func (w dummyCmcWrapper) readFrom(b []byte) (n int, dst net.IP, IfIndex int, src net.Addr, err error) { +- n, src, err = w.c.ReadFrom(b) +- return +-} +- +-func (w dummyCmcWrapper) writeTo(b []byte, src net.IP, IfIndex int, dst net.Addr) (n int, err error) { +- return w.c.WriteTo(b, dst) +-} ++type getSrcAddrFromOOB func(oob []byte) (net.IP, error) ++type writeSrcAddrToOOB func(a net.IP) []byte +diff --git a/pkg/server/udp_linux.go b/pkg/server/udp_linux.go +index 4eb466d..9728a39 100644 +--- a/pkg/server/udp_linux.go ++++ b/pkg/server/udp_linux.go +@@ -22,84 +22,71 @@ + package server + + import ( ++ "errors" + "fmt" ++ "net" ++ "os" ++ + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" + "golang.org/x/sys/unix" +- "net" +- "os" + ) + +-type ipv4cmc struct { +- c *ipv4.PacketConn +-} +- +-func newIpv4cmc(c *ipv4.PacketConn) *ipv4cmc { +- return &ipv4cmc{c: c} +-} ++var ( ++ errCmNoDstAddr = errors.New("control msg does not have dst address") ++) + +-func (i *ipv4cmc) readFrom(b []byte) (n int, dst net.IP, IfIndex int, src net.Addr, err error) { +- n, cm, src, err := i.c.ReadFrom(b) +- if cm != nil { +- dst, IfIndex = cm.Dst, cm.IfIndex ++func getOOBFromCM4(oob []byte) (net.IP, error) { ++ var cm ipv4.ControlMessage ++ if err := cm.Parse(oob); err != nil { ++ return nil, err + } +- return +-} +- +-func (i *ipv4cmc) writeTo(b []byte, src net.IP, IfIndex int, dst net.Addr) (n int, err error) { +- cm := &ipv4.ControlMessage{ +- Src: src, +- IfIndex: IfIndex, ++ if cm.Dst == nil { ++ return nil, errCmNoDstAddr + } +- return i.c.WriteTo(b, cm, dst) ++ return cm.Dst, nil + } + +-type ipv6cmc struct { +- c4 *ipv4.PacketConn // ipv4 entrypoint for sending ipv4 packages. +- c6 *ipv6.PacketConn ++func getOOBFromCM6(oob []byte) (net.IP, error) { ++ var cm ipv6.ControlMessage ++ if err := cm.Parse(oob); err != nil { ++ return nil, err ++ } ++ if cm.Dst == nil { ++ return nil, errCmNoDstAddr ++ } ++ return cm.Dst, nil + } + +-func newIpv6PacketConn(c4 *ipv4.PacketConn, c6 *ipv6.PacketConn) *ipv6cmc { +- return &ipv6cmc{c4: c4, c6: c6} +-} ++func srcIP2Cm(ip net.IP) []byte { ++ if ip4 := ip.To4(); ip4 != nil { ++ return (&ipv4.ControlMessage{ ++ Src: ip, ++ }).Marshal() ++ } + +-func (i *ipv6cmc) readFrom(b []byte) (n int, dst net.IP, IfIndex int, src net.Addr, err error) { +- n, cm, src, err := i.c6.ReadFrom(b) +- if cm != nil { +- dst, IfIndex = cm.Dst, cm.IfIndex ++ if ip6 := ip.To16(); ip6 != nil { ++ return (&ipv6.ControlMessage{ ++ Src: ip, ++ }).Marshal() + } +- return ++ ++ return nil + } + +-func (i *ipv6cmc) writeTo(b []byte, src net.IP, IfIndex int, dst net.Addr) (n int, err error) { +- if src != nil { +- // If src is ipv4, use IP_PKTINFO instead of IPV6_PKTINFO. +- // Otherwise, sendmsg will raise "invalid argument" error. +- // No official doc found. +- if src4 := src.To4(); src4 != nil { +- cm4 := &ipv4.ControlMessage{ +- Src: src4, +- IfIndex: IfIndex, +- } +- return i.c4.WriteTo(b, cm4, dst) +- } +- } +- cm6 := &ipv6.ControlMessage{ +- Src: src, +- IfIndex: IfIndex, ++func initOobHandler(c *net.UDPConn) (getSrcAddrFromOOB, writeSrcAddrToOOB, error) { ++ if !c.LocalAddr().(*net.UDPAddr).IP.IsUnspecified() { ++ return nil, nil, nil + } +- return i.c6.WriteTo(b, cm6, dst) +-} + +-func newCmc(c *net.UDPConn) (cmcUDPConn, error) { + sc, err := c.SyscallConn() + if err != nil { +- return nil, err ++ return nil, nil, err + } + ++ var getter getSrcAddrFromOOB ++ var setter writeSrcAddrToOOB + var controlErr error +- var cmc cmcUDPConn +- + if err := sc.Control(func(fd uintptr) { + v, err := unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_DOMAIN) + if err != nil { +@@ -109,27 +96,30 @@ func newCmc(c *net.UDPConn) (cmcUDPConn, error) { + switch v { + case unix.AF_INET: + c4 := ipv4.NewPacketConn(c) +- if err := c4.SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true); err != nil { ++ if err := c4.SetControlMessage(ipv4.FlagDst, true); err != nil { + controlErr = fmt.Errorf("failed to set ipv4 cmsg flags, %w", err) + } +- cmc = newIpv4cmc(c4) ++ ++ getter = getOOBFromCM4 ++ setter = srcIP2Cm + return + case unix.AF_INET6: + c6 := ipv6.NewPacketConn(c) +- if err := c6.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true); err != nil { ++ if err := c6.SetControlMessage(ipv6.FlagDst, true); err != nil { + controlErr = fmt.Errorf("failed to set ipv6 cmsg flags, %w", err) + } +- cmc = newIpv6PacketConn(ipv4.NewPacketConn(c), c6) ++ getter = getOOBFromCM6 ++ setter = srcIP2Cm + return + default: + controlErr = fmt.Errorf("socket protocol %d is not supported", v) + } + }); err != nil { +- return nil, fmt.Errorf("control fd err, %w", controlErr) ++ return nil, nil, fmt.Errorf("control fd err, %w", controlErr) + } + + if controlErr != nil { +- return nil, fmt.Errorf("failed to set up socket, %w", controlErr) ++ return nil, nil, fmt.Errorf("failed to set up socket, %w", controlErr) + } +- return cmc, nil ++ return getter, setter, nil + } +diff --git a/pkg/server/udp_others.go b/pkg/server/udp_others.go +index 8ce6280..1e42651 100644 +--- a/pkg/server/udp_others.go ++++ b/pkg/server/udp_others.go +@@ -23,6 +23,6 @@ package server + + import "net" + +-func newCmc(c *net.UDPConn) (cmcUDPConn, error) { +- return newDummyCmc(c), nil ++func initOobHandler(c *net.UDPConn) (getSrcAddrFromOOB, writeSrcAddrToOOB, error) { ++ return nil, nil, nil + } +diff --git a/plugin/server/udp_server/udp_server.go b/plugin/server/udp_server/udp_server.go +index 9ed94f5..293f720 100644 +--- a/plugin/server/udp_server/udp_server.go ++++ b/plugin/server/udp_server/udp_server.go +@@ -21,11 +21,12 @@ package udp_server + + import ( + "fmt" ++ "net" ++ + "github.com/IrineSistiana/mosdns/v5/coremain" + "github.com/IrineSistiana/mosdns/v5/pkg/server" + "github.com/IrineSistiana/mosdns/v5/pkg/utils" + "github.com/IrineSistiana/mosdns/v5/plugin/server/server_utils" +- "net" + ) + + const PluginType = "udp_server" +@@ -71,7 +72,7 @@ func StartServer(bp *coremain.BP, args *Args) (*UdpServer, error) { + } + go func() { + defer c.Close() +- err := s.ServeUDP(c) ++ err := s.ServeUDP(c.(*net.UDPConn)) + bp.M().GetSafeClose().SendCloseSignal(err) + }() + return &UdpServer{ +-- +2.34.8 + diff --git a/mosdns/patches/103-use-go-bytes-pool.patch b/mosdns/patches/103-use-go-bytes-pool.patch new file mode 100644 index 0000000..b5ba5df --- /dev/null +++ b/mosdns/patches/103-use-go-bytes-pool.patch @@ -0,0 +1,475 @@ +From 9bb813bf50ba0eed3a35acc8f41764613c11687d Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Sun, 17 Sep 2023 08:29:31 +0800 +Subject: [PATCH 04/10] use go-bytes-pool + +--- + go.mod | 1 + + go.sum | 2 + + pkg/dnsutils/net_io.go | 45 +++++---- + pkg/pool/allocator.go | 78 +--------------- + pkg/pool/allocator_test.go | 119 ------------------------ + pkg/pool/msg_buf.go | 4 +- + pkg/pool/msg_buf_test.go | 4 +- + pkg/server/udp.go | 6 +- + pkg/upstream/transport/dns_conn_test.go | 4 +- + plugin/executable/cache/cache.go | 8 +- + 10 files changed, 43 insertions(+), 228 deletions(-) + delete mode 100644 pkg/pool/allocator_test.go + +diff --git a/go.mod b/go.mod +index b56078b..2c359e3 100644 +--- a/go.mod ++++ b/go.mod +@@ -5,6 +5,7 @@ go 1.21 + toolchain go1.21.1 + + require ( ++ github.com/IrineSistiana/go-bytes-pool v0.0.0-20230419012903-2f1f26674686 + github.com/go-chi/chi/v5 v5.0.10 + github.com/google/nftables v0.1.0 + github.com/kardianos/service v1.2.2 +diff --git a/go.sum b/go.sum +index 633f864..d4bbaa2 100644 +--- a/go.sum ++++ b/go.sum +@@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f + dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= + github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= + github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= ++github.com/IrineSistiana/go-bytes-pool v0.0.0-20230419012903-2f1f26674686 h1:5R32cCep3VUDTKf3aurFKfgbvg+RScuBmZsw/DyyXco= ++github.com/IrineSistiana/go-bytes-pool v0.0.0-20230419012903-2f1f26674686/go.mod h1:pQ/FSsWSNYmNdgIKmulKlmVC/R2PEpq2vIEi3J9IijI= + github.com/IrineSistiana/ipset v0.5.1-0.20220703061533-6e0fc3b04c0a h1:GQdh/h0q0ni3L//CXusyk+7QdhBL289vdNaes1WKkHI= + github.com/IrineSistiana/ipset v0.5.1-0.20220703061533-6e0fc3b04c0a/go.mod h1:rYF5DQLRGGoQ8ZSWeK+6eX5amAuPqwFkWjhQlEITGJQ= + github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +diff --git a/pkg/dnsutils/net_io.go b/pkg/dnsutils/net_io.go +index 1b8a7b1..8fc769b 100644 +--- a/pkg/dnsutils/net_io.go ++++ b/pkg/dnsutils/net_io.go +@@ -23,9 +23,10 @@ import ( + "encoding/binary" + "errors" + "fmt" ++ "io" ++ + "github.com/IrineSistiana/mosdns/v5/pkg/pool" + "github.com/miekg/dns" +- "io" + ) + + var ( +@@ -35,45 +36,43 @@ var ( + // ReadRawMsgFromTCP reads msg from c in RFC 1035 format (msg is prefixed + // with a two byte length field). + // n represents how many bytes are read from c. +-// The returned the []byte should be released by pool.ReleaseBuf. +-func ReadRawMsgFromTCP(c io.Reader) ([]byte, int, error) { +- n := 0 ++// The returned the *[]byte should be released by pool.ReleaseBuf. ++func ReadRawMsgFromTCP(c io.Reader) (*[]byte, error) { + h := pool.GetBuf(2) + defer pool.ReleaseBuf(h) +- nh, err := io.ReadFull(c, h) +- n += nh ++ _, err := io.ReadFull(c, *h) ++ + if err != nil { +- return nil, n, err ++ return nil, err + } + + // dns length +- length := binary.BigEndian.Uint16(h) ++ length := binary.BigEndian.Uint16(*h) + if length == 0 { +- return nil, 0, errZeroLenMsg ++ return nil, errZeroLenMsg + } + +- buf := pool.GetBuf(int(length)) +- nm, err := io.ReadFull(c, buf) +- n += nm ++ b := pool.GetBuf(int(length)) ++ _, err = io.ReadFull(c, *b) + if err != nil { +- pool.ReleaseBuf(buf) +- return nil, n, err ++ pool.ReleaseBuf(b) ++ return nil, err + } +- return buf, n, nil ++ return b, nil + } + + // ReadMsgFromTCP reads msg from c in RFC 1035 format (msg is prefixed + // with a two byte length field). + // n represents how many bytes are read from c. + func ReadMsgFromTCP(c io.Reader) (*dns.Msg, int, error) { +- b, n, err := ReadRawMsgFromTCP(c) ++ b, err := ReadRawMsgFromTCP(c) + if err != nil { + return nil, 0, err + } + defer pool.ReleaseBuf(b) + +- m, err := unpackMsgWithDetailedErr(b) +- return m, n, err ++ m, err := unpackMsgWithDetailedErr(*b) ++ return m, len(*b) + 2, err + } + + // WriteMsgToTCP packs and writes m to c in RFC 1035 format. +@@ -96,9 +95,9 @@ func WriteRawMsgToTCP(c io.Writer, b []byte) (n int, err error) { + buf := pool.GetBuf(len(b) + 2) + defer pool.ReleaseBuf(buf) + +- binary.BigEndian.PutUint16(buf[:2], uint16(len(b))) +- copy(buf[2:], b) +- return c.Write(buf) ++ binary.BigEndian.PutUint16((*buf)[:2], uint16(len(b))) ++ copy((*buf)[2:], b) ++ return c.Write((*buf)) + } + + func WriteMsgToUDP(c io.Writer, m *dns.Msg) (int, error) { +@@ -118,12 +117,12 @@ func ReadMsgFromUDP(c io.Reader, bufSize int) (*dns.Msg, int, error) { + + b := pool.GetBuf(bufSize) + defer pool.ReleaseBuf(b) +- n, err := c.Read(b) ++ n, err := c.Read(*b) + if err != nil { + return nil, n, err + } + +- m, err := unpackMsgWithDetailedErr(b[:n]) ++ m, err := unpackMsgWithDetailedErr((*b)[:n]) + return m, n, err + } + +diff --git a/pkg/pool/allocator.go b/pkg/pool/allocator.go +index 0bfc0bc..d8ac4ef 100644 +--- a/pkg/pool/allocator.go ++++ b/pkg/pool/allocator.go +@@ -20,79 +20,11 @@ + package pool + + import ( +- "fmt" +- "math" +- "math/bits" +- "sync" ++ bytesPool "github.com/IrineSistiana/go-bytes-pool" + ) + + // defaultBufPool is an Allocator that has a maximum capacity. +-var defaultBufPool = NewAllocator() +- +-// GetBuf returns a []byte from pool with most appropriate cap. +-// It panics if size < 0. +-func GetBuf(size int) []byte { +- return defaultBufPool.Get(size) +-} +- +-// ReleaseBuf puts the buf to the pool. +-func ReleaseBuf(b []byte) { +- defaultBufPool.Release(b) +-} +- +-type Allocator struct { +- buffers []sync.Pool +-} +- +-// NewAllocator initiates a []byte Allocator. +-// The waste(memory fragmentation) of space allocation is guaranteed to be +-// no more than 50%. +-func NewAllocator() *Allocator { +- alloc := &Allocator{ +- buffers: make([]sync.Pool, bits.UintSize+1), +- } +- +- for i := range alloc.buffers { +- var bufSize uint +- if i == bits.UintSize { +- bufSize = math.MaxUint +- } else { +- bufSize = 1 << i +- } +- alloc.buffers[i].New = func() any { +- b := make([]byte, bufSize) +- return &b +- } +- } +- return alloc +-} +- +-// Get returns a []byte from pool with most appropriate cap +-func (alloc *Allocator) Get(size int) []byte { +- if size < 0 { +- panic(fmt.Sprintf("invalid slice size %d", size)) +- } +- +- i := shard(size) +- v := alloc.buffers[i].Get() +- buf := v.(*[]byte) +- return (*buf)[0:size] +-} +- +-// Release releases the buf to the allocatorL. +-func (alloc *Allocator) Release(buf []byte) { +- c := cap(buf) +- i := shard(c) +- if c == 0 || c != 1<. +- */ +- +-package pool +- +-import ( +- "fmt" +- "strconv" +- "testing" +-) +- +-func TestAllocator_Get(t *testing.T) { +- alloc := NewAllocator() +- tests := []struct { +- size int +- wantCap int +- wantPanic bool +- }{ +- {-1, 0, true}, // invalid +- {0, 1, false}, +- {1, 1, false}, +- {2, 2, false}, +- {12, 16, false}, +- {256, 256, false}, +- {257, 512, false}, +- } +- for _, tt := range tests { +- t.Run(strconv.Itoa(tt.size), func(t *testing.T) { +- if tt.wantPanic { +- defer func() { +- msg := recover() +- if msg == nil { +- t.Error("no panic") +- } +- }() +- } +- +- for i := 0; i < 5; i++ { +- b := alloc.Get(tt.size) +- if len(b) != tt.size { +- t.Fatalf("buffer size, want %d, got %d", tt.size, len(b)) +- } +- if cap(b) != tt.wantCap { +- t.Fatalf("buffer cap, want %d, got %d", tt.wantCap, cap(b)) +- } +- alloc.Release(b) +- } +- }) +- } +-} +- +-func Test_shard(t *testing.T) { +- tests := []struct { +- size int +- want int +- }{ +- {-1, 0}, +- {0, 0}, +- {1, 0}, +- {2, 1}, +- {3, 2}, +- {4, 2}, +- {5, 3}, +- {8, 3}, +- {1023, 10}, +- {1024, 10}, +- {1025, 11}, +- } +- for _, tt := range tests { +- t.Run(strconv.Itoa(tt.size), func(t *testing.T) { +- if got := shard(tt.size); got != tt.want { +- t.Errorf("shard() = %v, want %v", got, tt.want) +- } +- }) +- } +-} +- +-func Benchmark_Allocator(b *testing.B) { +- allocator := NewAllocator() +- +- for l := 0; l <= 16; l += 4 { +- bufLen := 1 << l +- b.Run(fmt.Sprintf("length %d", bufLen), func(b *testing.B) { +- b.ReportAllocs() +- for i := 0; i < b.N; i++ { +- buf := allocator.Get(bufLen) +- allocator.Release(buf) +- } +- }) +- } +-} +- +-func Benchmark_MakeByteSlice(b *testing.B) { +- for l := 0; l <= 8; l++ { +- bufLen := 1 << l +- b.Run(fmt.Sprintf("length %d", bufLen), func(b *testing.B) { +- b.ReportAllocs() +- for i := 0; i < b.N; i++ { +- _ = make([]byte, bufLen) +- } +- }) +- } +-} +diff --git a/pkg/pool/msg_buf.go b/pkg/pool/msg_buf.go +index 83eea80..980a08b 100644 +--- a/pkg/pool/msg_buf.go ++++ b/pkg/pool/msg_buf.go +@@ -31,9 +31,9 @@ const packBufSize = 4096 + // PackBuffer packs the dns msg m to wire format. + // Callers should release the buf by calling ReleaseBuf after they have done + // with the wire []byte. +-func PackBuffer(m *dns.Msg) (wire, buf []byte, err error) { ++func PackBuffer(m *dns.Msg) (wire []byte, buf *[]byte, err error) { + buf = GetBuf(packBufSize) +- wire, err = m.PackBuffer(buf) ++ wire, err = m.PackBuffer(*buf) + if err != nil { + ReleaseBuf(buf) + return nil, nil, err +diff --git a/pkg/pool/msg_buf_test.go b/pkg/pool/msg_buf_test.go +index 0685864..02d7348 100644 +--- a/pkg/pool/msg_buf_test.go ++++ b/pkg/pool/msg_buf_test.go +@@ -32,7 +32,7 @@ func TestPackBuffer_No_Allocation(t *testing.T) { + t.Fatal(err) + } + +- if cap(wire) != cap(buf) { +- t.Fatalf("wire and buf have different cap, wire %d, buf %d", cap(wire), cap(buf)) ++ if cap(wire) != cap(*buf) { ++ t.Fatalf("wire and buf have different cap, wire %d, buf %d", cap(wire), cap(*buf)) + } + } +diff --git a/pkg/server/udp.go b/pkg/server/udp.go +index 8980a08..c1c9aa9 100644 +--- a/pkg/server/udp.go ++++ b/pkg/server/udp.go +@@ -73,15 +73,15 @@ func (s *UDPServer) ServeUDP(c *net.UDPConn) error { + } + + for { +- n, oobn, _, remoteAddr, err := c.ReadMsgUDPAddrPort(rb, ob) ++ n, oobn, _, remoteAddr, err := c.ReadMsgUDPAddrPort(*rb, ob) + if err != nil { + return fmt.Errorf("unexpected read err: %w", err) + } + clientAddr := remoteAddr.Addr() + + q := new(dns.Msg) +- if err := q.Unpack(rb[:n]); err != nil { +- s.opts.Logger.Warn("invalid msg", zap.Error(err), zap.Binary("msg", rb[:n]), zap.Stringer("from", remoteAddr)) ++ if err := q.Unpack((*rb)[:n]); err != nil { ++ s.opts.Logger.Warn("invalid msg", zap.Error(err), zap.Binary("msg", (*rb)[:n]), zap.Stringer("from", remoteAddr)) + continue + } + +diff --git a/pkg/upstream/transport/dns_conn_test.go b/pkg/upstream/transport/dns_conn_test.go +index 8c49131..c677797 100644 +--- a/pkg/upstream/transport/dns_conn_test.go ++++ b/pkg/upstream/transport/dns_conn_test.go +@@ -40,13 +40,13 @@ var ( + c1, c2 := net.Pipe() + go func() { + for { +- m, _, readErr := dnsutils.ReadRawMsgFromTCP(c2) ++ m, readErr := dnsutils.ReadRawMsgFromTCP(c2) + if m != nil { + go func() { + defer pool.ReleaseBuf(m) + latency := time.Millisecond * time.Duration(rand.Intn(20)) + time.Sleep(latency) +- _, _ = dnsutils.WriteRawMsgToTCP(c2, m) ++ _, _ = dnsutils.WriteRawMsgToTCP(c2, *m) + }() + } + if readErr != nil { +diff --git a/plugin/executable/cache/cache.go b/plugin/executable/cache/cache.go +index f67d740..4091b50 100644 +--- a/plugin/executable/cache/cache.go ++++ b/plugin/executable/cache/cache.go +@@ -420,27 +420,27 @@ func (c *Cache) readDump(r io.Reader) (int, error) { + readBlock := func() error { + h := pool.GetBuf(8) + defer pool.ReleaseBuf(h) +- _, err := io.ReadFull(gr, h) ++ _, err := io.ReadFull(gr, *h) + if err != nil { + if errors.Is(err, io.EOF) { + return errReadHeaderEOF + } + return fmt.Errorf("failed to read block header, %w", err) + } +- u := binary.BigEndian.Uint64(h) ++ u := binary.BigEndian.Uint64(*h) + if u > dumpMaximumBlockLength { + return fmt.Errorf("invalid header, block length is big, %d", u) + } + + b := pool.GetBuf(int(u)) + defer pool.ReleaseBuf(b) +- _, err = io.ReadFull(gr, b) ++ _, err = io.ReadFull(gr, *b) + if err != nil { + return fmt.Errorf("failed to read block data, %w", err) + } + + block := new(CacheDumpBlock) +- if err := proto.Unmarshal(b, block); err != nil { ++ if err := proto.Unmarshal(*b, block); err != nil { + return fmt.Errorf("failed to decode block data, %w", err) + } + +-- +2.34.8 + diff --git a/mosdns/patches/210-fixed-712.patch b/mosdns/patches/104-fixed-712.patch similarity index 91% rename from mosdns/patches/210-fixed-712.patch rename to mosdns/patches/104-fixed-712.patch index 9c05938..581f775 100644 --- a/mosdns/patches/210-fixed-712.patch +++ b/mosdns/patches/104-fixed-712.patch @@ -1,7 +1,7 @@ -From 208abee452a28674e521bc317fb901c4e7c2a7a9 Mon Sep 17 00:00:00 2001 +From 757ccd6692c93fd7071a9e8011beea3d792dfb9d Mon Sep 17 00:00:00 2001 From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> Date: Sun, 17 Sep 2023 19:52:38 +0800 -Subject: [PATCH] fixed #712 +Subject: [PATCH 05/10] fixed #712 --- plugin/executable/nftset/nftset_linux.go | 11 ++++++++--- diff --git a/mosdns/patches/105-fixed-udp-oob-buf.patch b/mosdns/patches/105-fixed-udp-oob-buf.patch new file mode 100644 index 0000000..f39add5 --- /dev/null +++ b/mosdns/patches/105-fixed-udp-oob-buf.patch @@ -0,0 +1,43 @@ +From 9c235f5aa42fe0dcf410486b199b30dc9e40c998 Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Mon, 18 Sep 2023 09:50:44 +0800 +Subject: [PATCH 06/10] fixed udp oob buf + +--- + pkg/server/udp.go | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/pkg/server/udp.go b/pkg/server/udp.go +index c1c9aa9..a1e478b 100644 +--- a/pkg/server/udp.go ++++ b/pkg/server/udp.go +@@ -66,14 +66,14 @@ func (s *UDPServer) ServeUDP(c *net.UDPConn) error { + if err != nil { + return fmt.Errorf("failed to init oob handler, %w", err) + } +- var ob []byte ++ var ob *[]byte + if oobReader != nil { +- ob := pool.GetBuf(1024) ++ ob = pool.GetBuf(1024) + defer pool.ReleaseBuf(ob) + } + + for { +- n, oobn, _, remoteAddr, err := c.ReadMsgUDPAddrPort(*rb, ob) ++ n, oobn, _, remoteAddr, err := c.ReadMsgUDPAddrPort(*rb, *ob) + if err != nil { + return fmt.Errorf("unexpected read err: %w", err) + } +@@ -88,7 +88,7 @@ func (s *UDPServer) ServeUDP(c *net.UDPConn) error { + var dstIpFromCm net.IP + if oobReader != nil { + var err error +- dstIpFromCm, err = oobReader(ob[:oobn]) ++ dstIpFromCm, err = oobReader((*ob)[:oobn]) + if err != nil { + s.opts.Logger.Error("failed to get dst address from oob", zap.Error(err)) + } +-- +2.34.8 + diff --git a/mosdns/patches/106-fixed-707.patch b/mosdns/patches/106-fixed-707.patch new file mode 100644 index 0000000..e8635b1 --- /dev/null +++ b/mosdns/patches/106-fixed-707.patch @@ -0,0 +1,151 @@ +From edd39f198bc34ba443983a277e40e6f87ca38da6 Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Mon, 18 Sep 2023 10:36:43 +0800 +Subject: [PATCH 07/10] fixed #707 + +--- + plugin/executable/cache/cache.go | 19 ++++++++++--------- + plugin/executable/cache/dump.pb.go | 18 +++++++++--------- + plugin/executable/cache/dump.proto | 2 +- + 3 files changed, 20 insertions(+), 19 deletions(-) + +diff --git a/plugin/executable/cache/cache.go b/plugin/executable/cache/cache.go +index 4091b50..58162ee 100644 +--- a/plugin/executable/cache/cache.go ++++ b/plugin/executable/cache/cache.go +@@ -24,6 +24,14 @@ import ( + "encoding/binary" + "errors" + "fmt" ++ "io" ++ "net/http" ++ "os" ++ "strconv" ++ "sync" ++ "sync/atomic" ++ "time" ++ + "github.com/IrineSistiana/mosdns/v5/coremain" + "github.com/IrineSistiana/mosdns/v5/pkg/cache" + "github.com/IrineSistiana/mosdns/v5/pkg/pool" +@@ -37,13 +45,6 @@ import ( + "go.uber.org/zap" + "golang.org/x/sync/singleflight" + "google.golang.org/protobuf/proto" +- "io" +- "net/http" +- "os" +- "strconv" +- "sync" +- "sync/atomic" +- "time" + ) + + const ( +@@ -60,7 +61,7 @@ const ( + expiredMsgTtl = 5 + + minimumChangesToDump = 1024 +- dumpHeader = "mosdns_cache_v1" ++ dumpHeader = "mosdns_cache_v2" + dumpBlockSize = 128 + dumpMaximumBlockLength = 1 << 20 // 1M block. 8kb pre entry. Should be enough. + ) +@@ -379,7 +380,7 @@ func (c *Cache) writeDump(w io.Writer) (int, error) { + return fmt.Errorf("failed to pack msg, %w", err) + } + e := &CachedEntry{ +- Key: string(k), ++ Key: []byte(k), + CacheExpirationTime: cacheExpirationTime.Unix(), + MsgExpirationTime: v.expirationTime.Unix(), + Msg: msg, +diff --git a/plugin/executable/cache/dump.pb.go b/plugin/executable/cache/dump.pb.go +index ba40b95..58a7f15 100644 +--- a/plugin/executable/cache/dump.pb.go ++++ b/plugin/executable/cache/dump.pb.go +@@ -1,7 +1,7 @@ + // Code generated by protoc-gen-go. DO NOT EDIT. + // versions: +-// protoc-gen-go v1.28.1 +-// protoc v3.21.7 ++// protoc-gen-go v1.31.0 ++// protoc v4.24.3 + // source: plugin/executable/cache/dump.proto + + package cache +@@ -25,7 +25,7 @@ type CachedEntry struct { + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + +- Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` ++ Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Msg []byte `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + CacheExpirationTime int64 `protobuf:"varint,3,opt,name=cache_expiration_time,json=cacheExpirationTime,proto3" json:"cache_expiration_time,omitempty"` + MsgExpirationTime int64 `protobuf:"varint,4,opt,name=msg_expiration_time,json=msgExpirationTime,proto3" json:"msg_expiration_time,omitempty"` +@@ -64,11 +64,11 @@ func (*CachedEntry) Descriptor() ([]byte, []int) { + return file_plugin_executable_cache_dump_proto_rawDescGZIP(), []int{0} + } + +-func (x *CachedEntry) GetKey() string { ++func (x *CachedEntry) GetKey() []byte { + if x != nil { + return x.Key + } +- return "" ++ return nil + } + + func (x *CachedEntry) GetMsg() []byte { +@@ -153,7 +153,7 @@ var file_plugin_executable_cache_dump_proto_rawDesc = []byte{ + 0x62, 0x6c, 0x65, 0x2f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x22, 0xbd, 0x01, 0x0a, 0x0b, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, +- 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, ++ 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, + 0x32, 0x0a, 0x15, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, +@@ -185,7 +185,7 @@ func file_plugin_executable_cache_dump_proto_rawDescGZIP() []byte { + } + + var file_plugin_executable_cache_dump_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +-var file_plugin_executable_cache_dump_proto_goTypes = []any{ ++var file_plugin_executable_cache_dump_proto_goTypes = []interface{}{ + (*CachedEntry)(nil), // 0: cache.CachedEntry + (*CacheDumpBlock)(nil), // 1: cache.CacheDumpBlock + } +@@ -204,7 +204,7 @@ func file_plugin_executable_cache_dump_proto_init() { + return + } + if !protoimpl.UnsafeEnabled { +- file_plugin_executable_cache_dump_proto_msgTypes[0].Exporter = func(v any, i int) any { ++ file_plugin_executable_cache_dump_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CachedEntry); i { + case 0: + return &v.state +@@ -216,7 +216,7 @@ func file_plugin_executable_cache_dump_proto_init() { + return nil + } + } +- file_plugin_executable_cache_dump_proto_msgTypes[1].Exporter = func(v any, i int) any { ++ file_plugin_executable_cache_dump_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CacheDumpBlock); i { + case 0: + return &v.state +diff --git a/plugin/executable/cache/dump.proto b/plugin/executable/cache/dump.proto +index 756e034..93f1106 100644 +--- a/plugin/executable/cache/dump.proto ++++ b/plugin/executable/cache/dump.proto +@@ -5,7 +5,7 @@ package cache; + option go_package = "plugin/executable/cache"; + + message CachedEntry { +- string key = 1; ++ bytes key = 1; + bytes msg = 2; + int64 cache_expiration_time = 3; + int64 msg_expiration_time = 4; +-- +2.34.8 + diff --git a/mosdns/patches/107-add-doq-upstream.patch b/mosdns/patches/107-add-doq-upstream.patch new file mode 100644 index 0000000..c8f94e9 --- /dev/null +++ b/mosdns/patches/107-add-doq-upstream.patch @@ -0,0 +1,426 @@ +From e30a4d5d8a8e8bd591daa574dd1ff3fd787184d4 Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Sun, 17 Sep 2023 19:06:53 +0800 +Subject: [PATCH 08/10] add doq upstream + +--- + pkg/pool/msg_buf.go | 30 ++++ + pkg/pool/msg_buf_test.go | 3 +- + pkg/upstream/doq/upstream.go | 283 +++++++++++++++++++++++++++++++++++ + pkg/upstream/upstream.go | 36 ++++- + 4 files changed, 347 insertions(+), 5 deletions(-) + create mode 100644 pkg/upstream/doq/upstream.go + +diff --git a/pkg/pool/msg_buf.go b/pkg/pool/msg_buf.go +index 980a08b..f132cc2 100644 +--- a/pkg/pool/msg_buf.go ++++ b/pkg/pool/msg_buf.go +@@ -20,6 +20,9 @@ + package pool + + import ( ++ "encoding/binary" ++ "fmt" ++ + "github.com/miekg/dns" + ) + +@@ -40,3 +43,30 @@ func PackBuffer(m *dns.Msg) (wire []byte, buf *[]byte, err error) { + } + return wire, buf, nil + } ++ ++// PackBuffer packs the dns msg m to wire format, with to bytes length header. ++// Callers should release the buf by calling ReleaseBuf. ++func PackTCPBuffer(m *dns.Msg) (buf *[]byte, err error) { ++ b := GetBuf(packBufSize) ++ wire, err := m.PackBuffer((*b)[2:]) ++ if err != nil { ++ ReleaseBuf(b) ++ return nil, err ++ } ++ ++ l := len(wire) ++ if l > dns.MaxMsgSize { ++ ReleaseBuf(b) ++ return nil, fmt.Errorf("dns payload size %d is too large", l) ++ } ++ ++ if &((*b)[0]) != &wire[0] { // reallocated ++ ReleaseBuf(b) ++ b = GetBuf(l + 2) ++ binary.BigEndian.PutUint16((*b)[:2], uint16(l)) ++ copy((*b)[2:], wire) ++ return b, nil ++ } ++ *b = (*b)[:2+l] ++ return b, nil ++} +diff --git a/pkg/pool/msg_buf_test.go b/pkg/pool/msg_buf_test.go +index 02d7348..97d9a76 100644 +--- a/pkg/pool/msg_buf_test.go ++++ b/pkg/pool/msg_buf_test.go +@@ -20,8 +20,9 @@ + package pool + + import ( +- "github.com/miekg/dns" + "testing" ++ ++ "github.com/miekg/dns" + ) + + func TestPackBuffer_No_Allocation(t *testing.T) { +diff --git a/pkg/upstream/doq/upstream.go b/pkg/upstream/doq/upstream.go +new file mode 100644 +index 0000000..43241f4 +--- /dev/null ++++ b/pkg/upstream/doq/upstream.go +@@ -0,0 +1,283 @@ ++/* ++ * Copyright (C) 2020-2022, IrineSistiana ++ * ++ * This file is part of mosdns. ++ * ++ * mosdns is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * mosdns is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++package doq ++ ++import ( ++ "context" ++ "crypto/rand" ++ "crypto/tls" ++ "errors" ++ "net" ++ "sync" ++ "sync/atomic" ++ "time" ++ ++ "github.com/IrineSistiana/mosdns/v5/pkg/dnsutils" ++ "github.com/IrineSistiana/mosdns/v5/pkg/pool" ++ "github.com/miekg/dns" ++ "github.com/quic-go/quic-go" ++) ++ ++const ( ++ defaultDoQTimeout = time.Second * 5 ++ dialTimeout = time.Second * 3 ++ connectionLostThreshold = time.Second * 5 ++) ++ ++var ( ++ doqAlpn = []string{"doq"} ++) ++ ++type Upstream struct { ++ t *quic.Transport ++ addr string ++ tlsConfig *tls.Config ++ quicConfig *quic.Config ++ ++ cm sync.Mutex ++ lc *lazyConn ++} ++ ++// tlsConfig cannot be nil, it should have Servername or InsecureSkipVerify. ++func NewUpstream(addr string, lc *net.UDPConn, tlsConfig *tls.Config, quicConfig *quic.Config) (*Upstream, error) { ++ srk, err := initSrk() ++ if err != nil { ++ return nil, err ++ } ++ if tlsConfig == nil { ++ return nil, errors.New("nil tls config") ++ } ++ ++ tlsConfig = tlsConfig.Clone() ++ tlsConfig.NextProtos = doqAlpn ++ ++ return &Upstream{ ++ t: &quic.Transport{ ++ Conn: lc, ++ StatelessResetKey: (*quic.StatelessResetKey)(srk), ++ }, ++ addr: addr, ++ tlsConfig: tlsConfig, ++ quicConfig: quicConfig, ++ }, nil ++} ++ ++func initSrk() (*[32]byte, error) { ++ var b [32]byte ++ _, err := rand.Read(b[:]) ++ if err != nil { ++ return nil, err ++ } ++ return &b, nil ++} ++ ++func (u *Upstream) Close() error { ++ return u.t.Close() ++} ++ ++func (u *Upstream) newStream(ctx context.Context) (quic.Stream, *lazyConn, error) { ++ var lc *lazyConn ++ u.cm.Lock() ++ if u.lc == nil { // First dial. ++ u.lc = u.asyncDialConn() ++ } else { ++ select { ++ case <-u.lc.dialFinished: ++ if u.lc.err != nil { // previous dial failed ++ u.lc = u.asyncDialConn() ++ } else { ++ err := u.lc.c.Context().Err() ++ if err != nil { // previous connection is dead or closed ++ u.lc = u.asyncDialConn() ++ } ++ // previous connection looks good ++ } ++ default: ++ // still dialing ++ } ++ } ++ lc = u.lc ++ u.cm.Unlock() ++ ++ select { ++ case <-lc.dialFinished: ++ if lc.c == nil { ++ return nil, nil, lc.err ++ } ++ s, err := lc.c.OpenStream() ++ if err != nil { ++ lc.queryFailedAndCloseIfConnLost(time.Now()) ++ return nil, nil, err ++ } ++ return s, lc, nil ++ case <-ctx.Done(): ++ return nil, nil, ctx.Err() ++ } ++} ++ ++type lazyConn struct { ++ cancelDial func() ++ ++ m sync.Mutex ++ closed bool ++ dialFinished chan struct{} ++ c quic.Connection ++ err error ++ ++ latestRecvMs atomic.Int64 ++} ++ ++func (u *Upstream) asyncDialConn() *lazyConn { ++ ctx, cancel := context.WithTimeout(context.Background(), dialTimeout) ++ lc := &lazyConn{ ++ cancelDial: cancel, ++ dialFinished: make(chan struct{}), ++ } ++ ++ go func() { ++ defer cancel() ++ ++ ua, err := net.ResolveUDPAddr("udp", u.addr) // TODO: Support bootstrap. ++ if err != nil { ++ lc.err = err ++ return ++ } ++ ++ c, err := u.t.Dial(ctx, ua, u.tlsConfig, u.quicConfig) ++ ++ var closeC bool ++ lc.m.Lock() ++ if lc.closed { ++ closeC = true // lc was closed, nothing to do ++ } else { ++ if err != nil { ++ lc.err = err ++ } else { ++ lc.c = c ++ lc.saveLatestRespRecvTime(time.Now()) ++ } ++ close(lc.dialFinished) ++ } ++ lc.m.Unlock() ++ ++ if closeC && c != nil { // lc was closed while dialing. ++ c.CloseWithError(0, "") ++ } ++ }() ++ return lc ++} ++ ++func (lc *lazyConn) close() { ++ lc.m.Lock() ++ defer lc.m.Unlock() ++ ++ if lc.closed { ++ return ++ } ++ lc.closed = true ++ ++ select { ++ case <-lc.dialFinished: ++ if lc.c != nil { ++ lc.c.CloseWithError(0, "") ++ } ++ default: ++ lc.cancelDial() ++ lc.err = net.ErrClosed ++ close(lc.dialFinished) ++ } ++} ++ ++func (lc *lazyConn) saveLatestRespRecvTime(t time.Time) { ++ lc.latestRecvMs.Store(t.UnixMilli()) ++} ++ ++func (lc *lazyConn) latestRespRecvTime() time.Time { ++ return time.UnixMilli(lc.latestRecvMs.Load()) ++} ++ ++func (lc *lazyConn) queryFailedAndCloseIfConnLost(t time.Time) { ++ // No msg received for a quit long time. This connection may be lost. ++ if time.Since(lc.latestRespRecvTime()) > connectionLostThreshold { ++ lc.close() ++ } ++} ++ ++func (u *Upstream) ExchangeContext(ctx context.Context, q *dns.Msg) (*dns.Msg, error) { ++ payload, err := pool.PackTCPBuffer(q) ++ if err != nil { ++ return nil, err ++ } ++ // 4.2.1. DNS Message IDs ++ // When sending queries over a QUIC connection, the DNS Message ID MUST ++ // be set to 0. The stream mapping for DoQ allows for unambiguous ++ // correlation of queries and responses, so the Message ID field is not ++ // required. ++ (*payload)[2], (*payload)[3] = 0, 0 ++ ++ s, lc, err := u.newStream(ctx) ++ if err != nil { ++ return nil, err ++ } ++ ++ type res struct { ++ resp *dns.Msg ++ err error ++ } ++ rc := make(chan res, 1) ++ go func() { ++ defer pool.ReleaseBuf(payload) ++ defer s.Close() ++ r, err := u.exchange(s, *payload) ++ rc <- res{resp: r, err: err} ++ if err != nil { ++ lc.queryFailedAndCloseIfConnLost(time.Now()) ++ } else { ++ lc.saveLatestRespRecvTime(time.Now()) ++ } ++ }() ++ ++ select { ++ case <-ctx.Done(): ++ return nil, context.Cause(ctx) ++ case r := <-rc: ++ resp := r.resp ++ err := r.err ++ if resp != nil { ++ resp.Id = q.Id ++ } ++ return resp, err ++ } ++} ++ ++func (u *Upstream) exchange(s quic.Stream, payload []byte) (*dns.Msg, error) { ++ s.SetDeadline(time.Now().Add(defaultDoQTimeout)) ++ ++ _, err := s.Write(payload) ++ if err != nil { ++ return nil, err ++ } ++ ++ resp, _, err := dnsutils.ReadMsgFromTCP(s) ++ if err != nil { ++ return nil, err ++ } ++ return resp, nil ++} +diff --git a/pkg/upstream/upstream.go b/pkg/upstream/upstream.go +index 8486563..1bc80a2 100644 +--- a/pkg/upstream/upstream.go ++++ b/pkg/upstream/upstream.go +@@ -35,6 +35,7 @@ import ( + "github.com/IrineSistiana/mosdns/v5/pkg/dnsutils" + "github.com/IrineSistiana/mosdns/v5/pkg/upstream/bootstrap" + "github.com/IrineSistiana/mosdns/v5/pkg/upstream/doh" ++ "github.com/IrineSistiana/mosdns/v5/pkg/upstream/doq" + "github.com/IrineSistiana/mosdns/v5/pkg/upstream/transport" + "github.com/miekg/dns" + "github.com/quic-go/quic-go" +@@ -181,10 +182,8 @@ func NewUpstream(addr string, opt Opt) (Upstream, error) { + } + return transport.NewReuseConnTransport(transport.ReuseConnOpts{IOOpts: to}), nil + case "tls": +- var tlsConfig *tls.Config +- if opt.TLSConfig != nil { +- tlsConfig = opt.TLSConfig.Clone() +- } else { ++ tlsConfig := opt.TLSConfig.Clone() ++ if tlsConfig == nil { + tlsConfig = new(tls.Config) + } + if len(tlsConfig.ServerName) == 0 { +@@ -287,6 +286,35 @@ func NewUpstream(addr string, opt Opt) (Upstream, error) { + Client: &http.Client{Transport: t}, + AddOnCloser: addonCloser, + }, nil ++ case "quic", "doq": ++ tlsConfig := opt.TLSConfig.Clone() ++ if tlsConfig == nil { ++ tlsConfig = new(tls.Config) ++ } ++ if len(tlsConfig.ServerName) == 0 { ++ tlsConfig.ServerName = tryRemovePort(addrURL.Host) ++ } ++ ++ quicConfig := &quic.Config{ ++ TokenStore: quic.NewLRUTokenStore(4, 8), ++ InitialStreamReceiveWindow: 4 * 1024, ++ MaxStreamReceiveWindow: 4 * 1024, ++ InitialConnectionReceiveWindow: 8 * 1024, ++ MaxConnectionReceiveWindow: 64 * 1024, ++ } ++ ++ lc := net.ListenConfig{Control: getSocketControlFunc(socketOpts{so_mark: opt.SoMark, bind_to_device: opt.BindToDevice})} ++ uc, err := lc.ListenPacket(context.Background(), "udp", "") ++ if err != nil { ++ return nil, fmt.Errorf("failed to init udp socket for quic") ++ } ++ ++ dialAddr := getDialAddrWithPort(addrURL.Host, opt.DialAddr, 853) ++ u, err := doq.NewUpstream(dialAddr, uc.(*net.UDPConn), tlsConfig, quicConfig) ++ if err != nil { ++ return nil, fmt.Errorf("failed to setup doq upstream, %w", err) ++ } ++ return u, nil + default: + return nil, fmt.Errorf("unsupported protocol [%s]", addrURL.Scheme) + } +-- +2.34.8 + diff --git a/mosdns/patches/108-workaround-recover-from-0rtt-rejected.patch b/mosdns/patches/108-workaround-recover-from-0rtt-rejected.patch new file mode 100644 index 0000000..96c93db --- /dev/null +++ b/mosdns/patches/108-workaround-recover-from-0rtt-rejected.patch @@ -0,0 +1,47 @@ +From bc22fe05350994d031a1d915b8b1650d23062a52 Mon Sep 17 00:00:00 2001 +From: Irine Sistiana <49315432+IrineSistiana@users.noreply.github.com> +Date: Sun, 17 Sep 2023 22:38:11 +0800 +Subject: [PATCH 09/10] workaround: recover from "0rtt rejected" + +--- + pkg/upstream/doq/upstream.go | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/pkg/upstream/doq/upstream.go b/pkg/upstream/doq/upstream.go +index 43241f4..7b2d4e7 100644 +--- a/pkg/upstream/doq/upstream.go ++++ b/pkg/upstream/doq/upstream.go +@@ -39,6 +39,7 @@ const ( + defaultDoQTimeout = time.Second * 5 + dialTimeout = time.Second * 3 + connectionLostThreshold = time.Second * 5 ++ handshakeTimeout = time.Second * 3 + ) + + var ( +@@ -160,7 +161,21 @@ func (u *Upstream) asyncDialConn() *lazyConn { + return + } + +- c, err := u.t.Dial(ctx, ua, u.tlsConfig, u.quicConfig) ++ var c quic.Connection ++ ec, err := u.t.DialEarly(ctx, ua, u.tlsConfig, u.quicConfig) ++ if ec != nil { ++ // This is a workaround to ++ // 1. recover from strange 0rtt rejected err. ++ // 2. avoid NextConnection might block forever. ++ // TODO: Remove this workaround. ++ select { ++ case <-ctx.Done(): ++ err = context.Cause(ctx) ++ ec.CloseWithError(0, "") ++ case <-ec.HandshakeComplete(): ++ c = ec.NextConnection() ++ } ++ } + + var closeC bool + lc.m.Lock() +-- +2.34.8 + diff --git a/mosdns/patches/200-add-debug-log-again.patch b/mosdns/patches/200-add-debug-log-again.patch index 88061c2..624e94a 100644 --- a/mosdns/patches/200-add-debug-log-again.patch +++ b/mosdns/patches/200-add-debug-log-again.patch @@ -1,12 +1,13 @@ -From 90530ab71c101e8aa620a8d7669ffd7f59dfebf4 Mon Sep 17 00:00:00 2001 +From 3f57bcbf18fc5a537a4365ce1e5f5798db3a9dc6 Mon Sep 17 00:00:00 2001 From: sbwml Date: Sun, 25 Jun 2023 06:50:27 +0800 -Subject: [PATCH] add debug log again +Subject: [PATCH 10/10] add debug log again --- pkg/server/dns_handler/entry_handler.go | 4 +++- + pkg/server/http_handler/handler.go | 1 + plugin/executable/cache/cache.go | 3 +++ - 2 files changed, 6 insertions(+), 1 deletion(-) + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/server/dns_handler/entry_handler.go b/pkg/server/dns_handler/entry_handler.go index 4737811..cec4123 100644 @@ -23,11 +24,23 @@ index 4737811..cec4123 100644 } if err == nil && respMsg == nil { +diff --git a/pkg/server/http_handler/handler.go b/pkg/server/http_handler/handler.go +index 3e800f9..25f52e1 100644 +--- a/pkg/server/http_handler/handler.go ++++ b/pkg/server/http_handler/handler.go +@@ -96,6 +96,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if err != nil { + h.warnErr(req, "invalid request", err) + w.WriteHeader(http.StatusBadRequest) ++ w.Write([]byte("Bad Request")) + return + } + diff --git a/plugin/executable/cache/cache.go b/plugin/executable/cache/cache.go -index f67d740..c590a01 100644 +index 58162ee..dd833dc 100644 --- a/plugin/executable/cache/cache.go +++ b/plugin/executable/cache/cache.go -@@ -203,7 +203,10 @@ func (c *Cache) Exec(ctx context.Context, qCtx *query_context.Context, next sequ +@@ -204,7 +204,10 @@ func (c *Cache) Exec(ctx context.Context, qCtx *query_context.Context, next sequ c.hitTotal.Inc() cachedResp.Id = q.Id // change msg id shuffleIP(cachedResp)