Pull request 2021: upd golibs
Merge in DNS/adguard-home from upd-golibs to master
Squashed commit of the following:
commit 266b002c5450329761dee21d918c80d08e5d8ab9
Merge: 99eb7745d e305bd8e4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Oct 5 14:21:51 2023 +0300
Merge branch 'master' into upd-golibs
commit 99eb7745d0bee190399f9b16cb7151f34a591b54
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Oct 5 14:14:28 2023 +0300
home: imp alignment
commit 556cde56720ce449aec17b500825681fc8c084bf
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Oct 5 13:35:35 2023 +0300
dnsforward: imp naming, docs
commit 1ee99655a3318263db1edbcb9e4eeb33bfe441c8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Oct 5 13:28:39 2023 +0300
home: make ports uint16
commit b228032ea1f5902ab9bac7b5d55d84aaf6354616
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Wed Oct 4 18:56:59 2023 +0300
all: rm system resolvers
commit 4b5becbed5890db80612e53861f000aaf4c869ff
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Wed Oct 4 17:30:16 2023 +0300
all: upd golibs
This commit is contained in:
parent
e305bd8e40
commit
5f61b550fa
14
go.mod
14
go.mod
|
@ -3,8 +3,8 @@ module github.com/AdguardTeam/AdGuardHome
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/AdguardTeam/dnsproxy v0.54.0
|
github.com/AdguardTeam/dnsproxy v0.56.0
|
||||||
github.com/AdguardTeam/golibs v0.15.0
|
github.com/AdguardTeam/golibs v0.17.0
|
||||||
github.com/AdguardTeam/urlfilter v0.17.0
|
github.com/AdguardTeam/urlfilter v0.17.0
|
||||||
github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/ameshkov/dnscrypt/v2 v2.2.7
|
github.com/ameshkov/dnscrypt/v2 v2.2.7
|
||||||
|
@ -26,8 +26,8 @@ require (
|
||||||
// TODO(a.garipov): This package is deprecated; find a new one or use our
|
// TODO(a.garipov): This package is deprecated; find a new one or use our
|
||||||
// own code for that. Perhaps, use gopacket.
|
// own code for that. Perhaps, use gopacket.
|
||||||
github.com/mdlayher/raw v0.1.0
|
github.com/mdlayher/raw v0.1.0
|
||||||
github.com/miekg/dns v1.1.55
|
github.com/miekg/dns v1.1.56
|
||||||
github.com/quic-go/quic-go v0.38.1
|
github.com/quic-go/quic-go v0.39.0
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/ti-mo/netfilter v0.5.0
|
github.com/ti-mo/netfilter v0.5.0
|
||||||
go.etcd.io/bbolt v1.3.7
|
go.etcd.io/bbolt v1.3.7
|
||||||
|
@ -47,10 +47,9 @@ require (
|
||||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
|
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 // indirect
|
||||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb // indirect
|
|
||||||
github.com/mdlayher/socket v0.5.0 // indirect
|
github.com/mdlayher/socket v0.5.0 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.12.1 // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
@ -58,6 +57,7 @@ require (
|
||||||
github.com/quic-go/qpack v0.4.0 // indirect
|
github.com/quic-go/qpack v0.4.0 // indirect
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
|
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
|
||||||
|
go.uber.org/mock v0.3.0 // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
golang.org/x/text v0.13.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
|
|
37
go.sum
37
go.sum
|
@ -1,7 +1,7 @@
|
||||||
github.com/AdguardTeam/dnsproxy v0.54.0 h1:OgSitM/EKrMMOi+guWZNwaU1cqRqJKWgR3l3fPWWayI=
|
github.com/AdguardTeam/dnsproxy v0.56.0 h1:kAg88woRTWTgqVEB2i2Uhze8Lv0JF1zTIAGhe0prjKM=
|
||||||
github.com/AdguardTeam/dnsproxy v0.54.0/go.mod h1:tG/treaQekcKnugYoKOfm8vt3JGi6CliWta0MkQr15U=
|
github.com/AdguardTeam/dnsproxy v0.56.0/go.mod h1:fqmehcE3cHFNqKbWQpIjGk7GqBy7ur1v5At499lFjRc=
|
||||||
github.com/AdguardTeam/golibs v0.15.0 h1:yOv/fdVkJIOWKr0NlUXAE9RA0DK9GKiBbiGzq47vY7o=
|
github.com/AdguardTeam/golibs v0.17.0 h1:oPp2+2kV41qH45AIFbAlHFTPQOQ6JbF+JemjeECFn1g=
|
||||||
github.com/AdguardTeam/golibs v0.15.0/go.mod h1:66ZLs8P7nk/3IfKroQ1rqtieLk+5eXYXMBKXlVL7KeI=
|
github.com/AdguardTeam/golibs v0.17.0/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
|
||||||
github.com/AdguardTeam/urlfilter v0.17.0 h1:tUzhtR9wMx704GIP3cibsDQJrixlMHfwoQbYJfPdFow=
|
github.com/AdguardTeam/urlfilter v0.17.0 h1:tUzhtR9wMx704GIP3cibsDQJrixlMHfwoQbYJfPdFow=
|
||||||
github.com/AdguardTeam/urlfilter v0.17.0/go.mod h1:bbuZjPUzm/Ip+nz5qPPbwIP+9rZyQbQad8Lt/0fCulU=
|
github.com/AdguardTeam/urlfilter v0.17.0/go.mod h1:bbuZjPUzm/Ip+nz5qPPbwIP+9rZyQbQad8Lt/0fCulU=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
|
@ -33,8 +33,6 @@ github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
|
||||||
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
|
||||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
@ -43,8 +41,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb h1:LCMfzVg3sflxTs4UvuP4D8CkoZnfHLe2qzqgDn/4OHs=
|
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 h1:gpptm606MZYGaMHMsB4Srmb6EbW/IVHnt04rcMXnkBQ=
|
||||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||||
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
@ -75,11 +73,11 @@ github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5
|
||||||
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
||||||
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
|
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
|
||||||
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
|
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
|
||||||
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
|
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
||||||
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA=
|
||||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
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/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
|
@ -96,8 +94,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
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/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.39.0 h1:AgP40iThFMY0bj8jGxROhw3S0FMGa8ryqsmi9tBH3So=
|
||||||
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
|
github.com/quic-go/quic-go v0.39.0/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
|
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
@ -113,10 +111,11 @@ github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+Kd
|
||||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
|
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
|
||||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||||
|
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||||
|
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||||
|
@ -125,7 +124,6 @@ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjs
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
@ -134,7 +132,6 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -148,8 +145,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
@ -163,15 +158,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
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/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
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.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
|
|
|
@ -12,12 +12,12 @@ import (
|
||||||
// listenPacketReusable announces on the local network address additionally
|
// listenPacketReusable announces on the local network address additionally
|
||||||
// configuring the socket to have a reusable binding.
|
// configuring the socket to have a reusable binding.
|
||||||
func listenPacketReusable(ifaceName, network, address string) (c net.PacketConn, err error) {
|
func listenPacketReusable(ifaceName, network, address string) (c net.PacketConn, err error) {
|
||||||
var port int
|
var port uint16
|
||||||
_, port, err = netutil.SplitHostPort(address)
|
_, port, err = netutil.SplitHostPort(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(e.burkov): Inspect nclient4.NewRawUDPConn and implement here.
|
// TODO(e.burkov): Inspect nclient4.NewRawUDPConn and implement here.
|
||||||
return nclient4.NewRawUDPConn(ifaceName, port)
|
return nclient4.NewRawUDPConn(ifaceName, int(port))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package aghnet_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -64,7 +65,7 @@ ParseAddr("256.256.256.256"): IPv4 field has value >255`,
|
||||||
want: netip.AddrPort{},
|
want: netip.AddrPort{},
|
||||||
}, {
|
}, {
|
||||||
name: "error_invalid_port",
|
name: "error_invalid_port",
|
||||||
input: netutil.JoinHostPort(v4addr.String(), -5),
|
input: net.JoinHostPort(v4addr.String(), "-5"),
|
||||||
wantErrMsg: `invalid port "-5" parsing "1.2.3.4:-5"
|
wantErrMsg: `invalid port "-5" parsing "1.2.3.4:-5"
|
||||||
ParseAddr("1.2.3.4:-5"): unexpected character (at ":-5")`,
|
ParseAddr("1.2.3.4:-5"): unexpected character (at ":-5")`,
|
||||||
want: netip.AddrPort{},
|
want: netip.AddrPort{},
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package aghnet
|
|
||||||
|
|
||||||
// DefaultRefreshIvl is the default period of time between refreshing cached
|
|
||||||
// addresses.
|
|
||||||
// const DefaultRefreshIvl = 5 * time.Minute
|
|
||||||
|
|
||||||
// HostGenFunc is the signature for functions generating fake hostnames. The
|
|
||||||
// implementation must be safe for concurrent use.
|
|
||||||
type HostGenFunc func() (host string)
|
|
||||||
|
|
||||||
// SystemResolvers helps to work with local resolvers' addresses provided by OS.
|
|
||||||
type SystemResolvers interface {
|
|
||||||
// Get returns the slice of local resolvers' addresses. It must be safe for
|
|
||||||
// concurrent use.
|
|
||||||
Get() (rs []string)
|
|
||||||
// refresh refreshes the local resolvers' addresses cache. It must be safe
|
|
||||||
// for concurrent use.
|
|
||||||
refresh() (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSystemResolvers returns a SystemResolvers with the cache refresh rate
|
|
||||||
// defined by refreshIvl. It disables auto-refreshing if refreshIvl is 0. If
|
|
||||||
// nil is passed for hostGenFunc, the default generator will be used.
|
|
||||||
func NewSystemResolvers(
|
|
||||||
hostGenFunc HostGenFunc,
|
|
||||||
) (sr SystemResolvers, err error) {
|
|
||||||
sr = newSystemResolvers(hostGenFunc)
|
|
||||||
|
|
||||||
// Fill cache.
|
|
||||||
err = sr.refresh()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sr, nil
|
|
||||||
}
|
|
|
@ -1,146 +0,0 @@
|
||||||
//go:build !windows
|
|
||||||
|
|
||||||
package aghnet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// defaultHostGen is the default method of generating host for Refresh.
|
|
||||||
func defaultHostGen() (host string) {
|
|
||||||
// TODO(e.burkov): Use strings.Builder.
|
|
||||||
return fmt.Sprintf("test%d.org", time.Now().UnixNano())
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemResolvers is a default implementation of SystemResolvers interface.
|
|
||||||
type systemResolvers struct {
|
|
||||||
// addrsLock protects addrs.
|
|
||||||
addrsLock sync.RWMutex
|
|
||||||
// addrs is the set that contains cached local resolvers' addresses.
|
|
||||||
addrs *stringutil.Set
|
|
||||||
|
|
||||||
// resolver is used to fetch the resolvers' addresses.
|
|
||||||
resolver *net.Resolver
|
|
||||||
// hostGenFunc generates hosts to resolve.
|
|
||||||
hostGenFunc HostGenFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// errBadAddrPassed is returned when dialFunc can't parse an IP address.
|
|
||||||
errBadAddrPassed errors.Error = "the passed string is not a valid IP address"
|
|
||||||
|
|
||||||
// errFakeDial is an error which dialFunc is expected to return.
|
|
||||||
errFakeDial errors.Error = "this error signals the successful dialFunc work"
|
|
||||||
|
|
||||||
// errUnexpectedHostFormat is returned by validateDialedHost when the host has
|
|
||||||
// more than one percent sign.
|
|
||||||
errUnexpectedHostFormat errors.Error = "unexpected host format"
|
|
||||||
)
|
|
||||||
|
|
||||||
// refresh implements the SystemResolvers interface for *systemResolvers.
|
|
||||||
func (sr *systemResolvers) refresh() (err error) {
|
|
||||||
defer func() { err = errors.Annotate(err, "systemResolvers: %w") }()
|
|
||||||
|
|
||||||
_, err = sr.resolver.LookupHost(context.Background(), sr.hostGenFunc())
|
|
||||||
dnserr := &net.DNSError{}
|
|
||||||
if errors.As(err, &dnserr) && dnserr.Err == errFakeDial.Error() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSystemResolvers(hostGenFunc HostGenFunc) (sr SystemResolvers) {
|
|
||||||
if hostGenFunc == nil {
|
|
||||||
hostGenFunc = defaultHostGen
|
|
||||||
}
|
|
||||||
s := &systemResolvers{
|
|
||||||
resolver: &net.Resolver{
|
|
||||||
PreferGo: true,
|
|
||||||
},
|
|
||||||
hostGenFunc: hostGenFunc,
|
|
||||||
addrs: stringutil.NewSet(),
|
|
||||||
}
|
|
||||||
s.resolver.Dial = s.dialFunc
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateDialedHost validated the host used by resolvers in dialFunc.
|
|
||||||
func validateDialedHost(host string) (err error) {
|
|
||||||
defer func() { err = errors.Annotate(err, "parsing %q: %w", host) }()
|
|
||||||
|
|
||||||
parts := strings.Split(host, "%")
|
|
||||||
switch len(parts) {
|
|
||||||
case 1:
|
|
||||||
// host
|
|
||||||
case 2:
|
|
||||||
// Remove the zone and check the IP address part.
|
|
||||||
host = parts[0]
|
|
||||||
default:
|
|
||||||
return errUnexpectedHostFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = netutil.ParseIP(host); err != nil {
|
|
||||||
return errBadAddrPassed
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// dockerEmbeddedDNS is the address of Docker's embedded DNS server.
|
|
||||||
//
|
|
||||||
// See
|
|
||||||
// https://github.com/moby/moby/blob/v1.12.0/docs/userguide/networking/dockernetworks.md.
|
|
||||||
const dockerEmbeddedDNS = "127.0.0.11"
|
|
||||||
|
|
||||||
// dialFunc gets the resolver's address and puts it into internal cache.
|
|
||||||
func (sr *systemResolvers) dialFunc(_ context.Context, _, address string) (_ net.Conn, err error) {
|
|
||||||
// Just validate the passed address is a valid IP.
|
|
||||||
var host string
|
|
||||||
host, err = netutil.SplitHost(address)
|
|
||||||
if err != nil {
|
|
||||||
// TODO(e.burkov): Maybe use a structured errBadAddrPassed to
|
|
||||||
// allow unwrapping of the real error.
|
|
||||||
return nil, fmt.Errorf("%s: %w", err, errBadAddrPassed)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exclude Docker's embedded DNS server, as it may cause recursion if
|
|
||||||
// the container is set as the host system's default DNS server.
|
|
||||||
//
|
|
||||||
// See https://github.com/AdguardTeam/AdGuardHome/issues/3064.
|
|
||||||
//
|
|
||||||
// TODO(a.garipov): Perhaps only do this when we are in the container?
|
|
||||||
// Maybe use an environment variable?
|
|
||||||
if host == dockerEmbeddedDNS {
|
|
||||||
return nil, errFakeDial
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validateDialedHost(host)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("validating dialed host: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sr.addrsLock.Lock()
|
|
||||||
defer sr.addrsLock.Unlock()
|
|
||||||
|
|
||||||
sr.addrs.Add(host)
|
|
||||||
|
|
||||||
return nil, errFakeDial
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *systemResolvers) Get() (rs []string) {
|
|
||||||
sr.addrsLock.RLock()
|
|
||||||
defer sr.addrsLock.RUnlock()
|
|
||||||
|
|
||||||
return sr.addrs.Values()
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
//go:build !windows
|
|
||||||
|
|
||||||
package aghnet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/testutil"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func createTestSystemResolversImpl(
|
|
||||||
t *testing.T,
|
|
||||||
hostGenFunc HostGenFunc,
|
|
||||||
) (imp *systemResolvers) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
sr := createTestSystemResolvers(t, hostGenFunc)
|
|
||||||
|
|
||||||
return testutil.RequireTypeAssert[*systemResolvers](t, sr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemResolvers_Refresh(t *testing.T) {
|
|
||||||
t.Run("expected_error", func(t *testing.T) {
|
|
||||||
sr := createTestSystemResolvers(t, nil)
|
|
||||||
|
|
||||||
assert.NoError(t, sr.refresh())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unexpected_error", func(t *testing.T) {
|
|
||||||
_, err := NewSystemResolvers(func() string {
|
|
||||||
return "127.0.0.1::123"
|
|
||||||
})
|
|
||||||
assert.Error(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemResolvers_DialFunc(t *testing.T) {
|
|
||||||
imp := createTestSystemResolversImpl(t, nil)
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
want error
|
|
||||||
name string
|
|
||||||
address string
|
|
||||||
}{{
|
|
||||||
want: errFakeDial,
|
|
||||||
name: "valid_ipv4",
|
|
||||||
address: "127.0.0.1",
|
|
||||||
}, {
|
|
||||||
want: errFakeDial,
|
|
||||||
name: "valid_ipv6_port",
|
|
||||||
address: "[::1]:53",
|
|
||||||
}, {
|
|
||||||
want: errFakeDial,
|
|
||||||
name: "valid_ipv6_zone_port",
|
|
||||||
address: "[::1%lo0]:53",
|
|
||||||
}, {
|
|
||||||
want: errBadAddrPassed,
|
|
||||||
name: "invalid_split_host",
|
|
||||||
address: "127.0.0.1::123",
|
|
||||||
}, {
|
|
||||||
want: errUnexpectedHostFormat,
|
|
||||||
name: "invalid_ipv6_zone_port",
|
|
||||||
address: "[::1%%lo0]:53",
|
|
||||||
}, {
|
|
||||||
want: errBadAddrPassed,
|
|
||||||
name: "invalid_parse_ip",
|
|
||||||
address: "not-ip",
|
|
||||||
}}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
conn, err := imp.dialFunc(context.Background(), "", tc.address)
|
|
||||||
require.Nil(t, conn)
|
|
||||||
|
|
||||||
assert.ErrorIs(t, err, tc.want)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package aghnet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func createTestSystemResolvers(
|
|
||||||
t *testing.T,
|
|
||||||
hostGenFunc HostGenFunc,
|
|
||||||
) (sr SystemResolvers) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
sr, err = NewSystemResolvers(hostGenFunc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, sr)
|
|
||||||
|
|
||||||
return sr
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSystemResolvers_Get(t *testing.T) {
|
|
||||||
sr := createTestSystemResolvers(t, nil)
|
|
||||||
|
|
||||||
var rs []string
|
|
||||||
require.NotPanics(t, func() {
|
|
||||||
rs = sr.Get()
|
|
||||||
})
|
|
||||||
|
|
||||||
assert.NotEmpty(t, rs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(e.burkov): Write tests for refreshWithTicker.
|
|
||||||
//
|
|
||||||
// See https://github.com/AdguardTeam/AdGuardHome/issues/2846.
|
|
|
@ -1,163 +0,0 @@
|
||||||
//go:build windows
|
|
||||||
|
|
||||||
package aghnet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// systemResolvers implementation differs for Windows since Go's resolver
|
|
||||||
// doesn't work there.
|
|
||||||
//
|
|
||||||
// See https://github.com/golang/go/issues/33097.
|
|
||||||
type systemResolvers struct {
|
|
||||||
// addrs is the slice of cached local resolvers' addresses.
|
|
||||||
addrs []string
|
|
||||||
addrsLock sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSystemResolvers(_ HostGenFunc) (sr SystemResolvers) {
|
|
||||||
return &systemResolvers{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *systemResolvers) Get() (rs []string) {
|
|
||||||
sr.addrsLock.RLock()
|
|
||||||
defer sr.addrsLock.RUnlock()
|
|
||||||
|
|
||||||
addrs := sr.addrs
|
|
||||||
rs = make([]string, len(addrs))
|
|
||||||
copy(rs, addrs)
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeExit writes "exit" to w and closes it. It is supposed to be run in
|
|
||||||
// a goroutine.
|
|
||||||
func writeExit(w io.WriteCloser) {
|
|
||||||
defer log.OnPanic("systemResolvers: writeExit")
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
derr := w.Close()
|
|
||||||
if derr != nil {
|
|
||||||
log.Error("systemResolvers: writeExit: closing: %s", derr)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
_, err := io.WriteString(w, "exit")
|
|
||||||
if err != nil {
|
|
||||||
log.Error("systemResolvers: writeExit: writing: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// scanAddrs scans the DNS addresses from nslookup's output. The expected
|
|
||||||
// output of nslookup looks like this:
|
|
||||||
//
|
|
||||||
// Default Server: 192-168-1-1.qualified.domain.ru
|
|
||||||
// Address: 192.168.1.1
|
|
||||||
func scanAddrs(s *bufio.Scanner) (addrs []string) {
|
|
||||||
for s.Scan() {
|
|
||||||
line := strings.TrimSpace(s.Text())
|
|
||||||
fields := strings.Fields(line)
|
|
||||||
if len(fields) != 2 || fields[0] != "Address:" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the address contains port then it is separated with '#'.
|
|
||||||
ipPort := strings.Split(fields[1], "#")
|
|
||||||
if len(ipPort) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
addr := ipPort[0]
|
|
||||||
if net.ParseIP(addr) == nil {
|
|
||||||
log.Debug("systemResolvers: %q is not a valid ip", addr)
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return addrs
|
|
||||||
}
|
|
||||||
|
|
||||||
// getAddrs gets local resolvers' addresses from OS in a special Windows way.
|
|
||||||
//
|
|
||||||
// TODO(e.burkov): This whole function needs more detailed research on getting
|
|
||||||
// local resolvers addresses on Windows. We execute the external command for
|
|
||||||
// now that is not the most accurate way.
|
|
||||||
func (sr *systemResolvers) getAddrs() (addrs []string, err error) {
|
|
||||||
var cmdPath string
|
|
||||||
cmdPath, err = exec.LookPath("nslookup.exe")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("looking up cmd path: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command(cmdPath)
|
|
||||||
|
|
||||||
var stdin io.WriteCloser
|
|
||||||
stdin, err = cmd.StdinPipe()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("getting the command's stdin pipe: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var stdout io.ReadCloser
|
|
||||||
stdout, err = cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("getting the command's stdout pipe: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go writeExit(stdin)
|
|
||||||
|
|
||||||
err = cmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("start command executing: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s := bufio.NewScanner(stdout)
|
|
||||||
addrs = scanAddrs(s)
|
|
||||||
|
|
||||||
err = cmd.Wait()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("executing the command: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.Err()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("scanning output: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't close StdoutPipe since Wait do it for us in ¿most? cases.
|
|
||||||
//
|
|
||||||
// See [exec.Cmd.StdoutPipe].
|
|
||||||
|
|
||||||
return addrs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sr *systemResolvers) refresh() (err error) {
|
|
||||||
defer func() { err = errors.Annotate(err, "systemResolvers: %w") }()
|
|
||||||
|
|
||||||
got, err := sr.getAddrs()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't get addresses: %w", err)
|
|
||||||
}
|
|
||||||
if len(got) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sr.addrsLock.Lock()
|
|
||||||
defer sr.addrsLock.Unlock()
|
|
||||||
|
|
||||||
sr.addrs = got
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
//go:build windows
|
|
||||||
|
|
||||||
package aghnet
|
|
||||||
|
|
||||||
// TODO(e.burkov): Write tests for Windows implementation.
|
|
||||||
//
|
|
||||||
// See https://github.com/AdguardTeam/AdGuardHome/issues/2846.
|
|
|
@ -436,18 +436,18 @@ func (conf *ServerConfig) collectDNSAddrs() (
|
||||||
// defaultPlainDNSPort is the default port for plain DNS.
|
// defaultPlainDNSPort is the default port for plain DNS.
|
||||||
const defaultPlainDNSPort uint16 = 53
|
const defaultPlainDNSPort uint16 = 53
|
||||||
|
|
||||||
// upstreamMatcher is a function that matches address of an upstream.
|
// addrPortMatcher is a function that matches an IP address with port.
|
||||||
type upstreamMatcher func(addr netip.AddrPort) (ok bool)
|
type addrPortMatcher func(addr netip.AddrPort) (ok bool)
|
||||||
|
|
||||||
// filterOut filters out all the upstreams that match um. It returns all the
|
// filterOut filters out all the upstreams that match um. It returns all the
|
||||||
// closing errors joined.
|
// closing errors joined.
|
||||||
func (um upstreamMatcher) filterOut(upsConf *proxy.UpstreamConfig) (err error) {
|
func (m addrPortMatcher) filterOut(upsConf *proxy.UpstreamConfig) (err error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
delFunc := func(u upstream.Upstream) (ok bool) {
|
delFunc := func(u upstream.Upstream) (ok bool) {
|
||||||
// TODO(e.burkov): We should probably consider the protocol of u to
|
// TODO(e.burkov): We should probably consider the protocol of u to
|
||||||
// only filter out the listening addresses of the same protocol.
|
// only filter out the listening addresses of the same protocol.
|
||||||
addr, parseErr := aghnet.ParseAddrPort(u.Address(), defaultPlainDNSPort)
|
addr, parseErr := aghnet.ParseAddrPort(u.Address(), defaultPlainDNSPort)
|
||||||
if parseErr != nil || !um(addr) {
|
if parseErr != nil || !m(addr) {
|
||||||
// Don't filter out the upstream if it either cannot be parsed, or
|
// Don't filter out the upstream if it either cannot be parsed, or
|
||||||
// does not match um.
|
// does not match um.
|
||||||
return false
|
return false
|
||||||
|
@ -469,23 +469,21 @@ func (um upstreamMatcher) filterOut(upsConf *proxy.UpstreamConfig) (err error) {
|
||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterOurAddrs filters out all the upstreams that pointing to the local
|
// ourAddrsMatcher returns a matcher that matches all the configured listening
|
||||||
// listening addresses to avoid recursive queries. upsConf may appear empty
|
// addresses.
|
||||||
// after the filtering. All the filtered upstreams are closed and these
|
func (conf *ServerConfig) ourAddrsMatcher() (m addrPortMatcher, err error) {
|
||||||
// closings errors are joined.
|
|
||||||
func (conf *ServerConfig) filterOurAddrs(upsConf *proxy.UpstreamConfig) (err error) {
|
|
||||||
addrs, unspecPorts := conf.collectDNSAddrs()
|
addrs, unspecPorts := conf.collectDNSAddrs()
|
||||||
if len(addrs) == 0 {
|
if len(addrs) == 0 {
|
||||||
log.Debug("dnsforward: no listen addresses")
|
log.Debug("dnsforward: no listen addresses")
|
||||||
|
|
||||||
return nil
|
// Match no addresses.
|
||||||
|
return func(_ netip.AddrPort) (ok bool) { return false }, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var matcher upstreamMatcher
|
|
||||||
if len(unspecPorts) == 0 {
|
if len(unspecPorts) == 0 {
|
||||||
log.Debug("dnsforward: filtering out addresses %s", addrs)
|
log.Debug("dnsforward: filtering out addresses %s", addrs)
|
||||||
|
|
||||||
matcher = func(a netip.AddrPort) (ok bool) {
|
m = func(a netip.AddrPort) (ok bool) {
|
||||||
_, ok = addrs[a]
|
_, ok = addrs[a]
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
@ -495,12 +493,12 @@ func (conf *ServerConfig) filterOurAddrs(upsConf *proxy.UpstreamConfig) (err err
|
||||||
ifaceAddrs, err = aghnet.CollectAllIfacesAddrs()
|
ifaceAddrs, err = aghnet.CollectAllIfacesAddrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Don't wrap the error since it's informative enough as is.
|
// Don't wrap the error since it's informative enough as is.
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("dnsforward: filtering out addresses %s on ports %d", ifaceAddrs, unspecPorts)
|
log.Debug("dnsforward: filtering out addresses %s on ports %d", ifaceAddrs, unspecPorts)
|
||||||
|
|
||||||
matcher = func(a netip.AddrPort) (ok bool) {
|
m = func(a netip.AddrPort) (ok bool) {
|
||||||
if _, ok = unspecPorts[a.Port()]; ok {
|
if _, ok = unspecPorts[a.Port()]; ok {
|
||||||
return slices.Contains(ifaceAddrs, a.Addr())
|
return slices.Contains(ifaceAddrs, a.Addr())
|
||||||
}
|
}
|
||||||
|
@ -509,7 +507,7 @@ func (conf *ServerConfig) filterOurAddrs(upsConf *proxy.UpstreamConfig) (err err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return matcher.filterOut(upsConf)
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepareTLS - prepares TLS configuration for the DNS proxy
|
// prepareTLS - prepares TLS configuration for the DNS proxy
|
||||||
|
|
|
@ -25,8 +25,10 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
|
"github.com/AdguardTeam/golibs/netutil/sysresolv"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultTimeout is the default upstream timeout
|
// DefaultTimeout is the default upstream timeout
|
||||||
|
@ -72,6 +74,11 @@ type DHCP interface {
|
||||||
Enabled() (ok bool)
|
Enabled() (ok bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SystemResolvers interface {
|
||||||
|
// Addrs returns the list of system resolvers' addresses.
|
||||||
|
Addrs() (addrs []netip.AddrPort)
|
||||||
|
}
|
||||||
|
|
||||||
// Server is the main way to start a DNS server.
|
// Server is the main way to start a DNS server.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
|
@ -126,7 +133,7 @@ type Server struct {
|
||||||
|
|
||||||
// sysResolvers used to fetch system resolvers to use by default for private
|
// sysResolvers used to fetch system resolvers to use by default for private
|
||||||
// PTR resolving.
|
// PTR resolving.
|
||||||
sysResolvers aghnet.SystemResolvers
|
sysResolvers SystemResolvers
|
||||||
|
|
||||||
// recDetector is a cache for recursive requests. It is used to detect
|
// recDetector is a cache for recursive requests. It is used to detect
|
||||||
// and prevent recursive requests only for private upstreams.
|
// and prevent recursive requests only for private upstreams.
|
||||||
|
@ -225,9 +232,7 @@ func NewServer(p DNSCreateParams) (s *Server, err error) {
|
||||||
anonymizer: p.Anonymizer,
|
anonymizer: p.Anonymizer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(e.burkov): Enable the refresher after the actual implementation
|
s.sysResolvers, err = sysresolv.NewSystemResolvers(nil, defaultPlainDNSPort)
|
||||||
// passes the public testing.
|
|
||||||
s.sysResolvers, err = aghnet.NewSystemResolvers(nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("initializing system resolvers: %w", err)
|
return nil, fmt.Errorf("initializing system resolvers: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -442,19 +447,30 @@ const defaultLocalTimeout = 1 * time.Second
|
||||||
// setupLocalResolvers initializes the resolvers for local addresses. For
|
// setupLocalResolvers initializes the resolvers for local addresses. For
|
||||||
// internal use only.
|
// internal use only.
|
||||||
func (s *Server) setupLocalResolvers() (err error) {
|
func (s *Server) setupLocalResolvers() (err error) {
|
||||||
|
matcher, err := s.conf.ourAddrsMatcher()
|
||||||
|
if err != nil {
|
||||||
|
// Don't wrap the error because it's informative enough as is.
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
bootstraps := s.conf.BootstrapDNS
|
bootstraps := s.conf.BootstrapDNS
|
||||||
resolvers := s.conf.LocalPTRResolvers
|
resolvers := s.conf.LocalPTRResolvers
|
||||||
|
filterConfig := false
|
||||||
|
|
||||||
if len(resolvers) == 0 {
|
if len(resolvers) == 0 {
|
||||||
resolvers = s.sysResolvers.Get()
|
sysResolvers := slices.DeleteFunc(s.sysResolvers.Addrs(), matcher)
|
||||||
bootstraps = nil
|
resolvers = make([]string, 0, len(sysResolvers))
|
||||||
|
for _, r := range sysResolvers {
|
||||||
|
resolvers = append(resolvers, r.String())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
resolvers = stringutil.FilterOut(resolvers, IsCommentOrEmpty)
|
resolvers = stringutil.FilterOut(resolvers, IsCommentOrEmpty)
|
||||||
|
filterConfig = true
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("dnsforward: upstreams to resolve ptr for local addresses: %v", resolvers)
|
log.Debug("dnsforward: upstreams to resolve ptr for local addresses: %v", resolvers)
|
||||||
|
|
||||||
uc, err := s.prepareLocalUpstreamConfig(resolvers, nil, &upstream.Options{
|
uc, err := s.prepareUpstreamConfig(resolvers, nil, &upstream.Options{
|
||||||
Bootstrap: bootstraps,
|
Bootstrap: bootstraps,
|
||||||
Timeout: defaultLocalTimeout,
|
Timeout: defaultLocalTimeout,
|
||||||
// TODO(e.burkov): Should we verify server's certificates?
|
// TODO(e.burkov): Should we verify server's certificates?
|
||||||
|
@ -464,6 +480,12 @@ func (s *Server) setupLocalResolvers() (err error) {
|
||||||
return fmt.Errorf("preparing private upstreams: %w", err)
|
return fmt.Errorf("preparing private upstreams: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if filterConfig {
|
||||||
|
if err = matcher.filterOut(uc); err != nil {
|
||||||
|
return fmt.Errorf("filtering private upstreams: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.localResolvers = &proxy.Proxy{
|
s.localResolvers = &proxy.Proxy{
|
||||||
Config: proxy.Config{
|
Config: proxy.Config{
|
||||||
UpstreamConfig: uc,
|
UpstreamConfig: uc,
|
||||||
|
|
|
@ -179,17 +179,16 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
|
||||||
// defaultLocalPTRUpstreams returns the list of default local PTR resolvers
|
// defaultLocalPTRUpstreams returns the list of default local PTR resolvers
|
||||||
// filtered of AdGuard Home's own DNS server addresses. It may appear empty.
|
// filtered of AdGuard Home's own DNS server addresses. It may appear empty.
|
||||||
func (s *Server) defaultLocalPTRUpstreams() (ups []string, err error) {
|
func (s *Server) defaultLocalPTRUpstreams() (ups []string, err error) {
|
||||||
s.serverLock.RLock()
|
matcher, err := s.conf.ourAddrsMatcher()
|
||||||
defer s.serverLock.RUnlock()
|
|
||||||
|
|
||||||
uc, err := s.prepareLocalUpstreamConfig(s.sysResolvers.Get(), nil, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting system upstream config: %w", err)
|
// Don't wrap the error because it's informative enough as is.
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() { err = errors.Join(err, uc.Close()) }()
|
|
||||||
|
|
||||||
for _, u := range uc.Upstreams {
|
sysResolvers := slices.DeleteFunc(s.sysResolvers.Addrs(), matcher)
|
||||||
ups = append(ups, u.Address())
|
ups = make([]string, 0, len(sysResolvers))
|
||||||
|
for _, r := range sysResolvers {
|
||||||
|
ups = append(ups, r.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return ups, nil
|
return ups, nil
|
||||||
|
@ -228,7 +227,7 @@ func (req *jsonDNSConfig) checkBootstrap() (err error) {
|
||||||
return errors.Error("empty")
|
return errors.Error("empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = upstream.NewResolver(b, nil); err != nil {
|
if _, err = upstream.NewUpstreamResolver(b, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,12 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fakeSystemResolvers is a mock aghnet.SystemResolvers implementation for
|
// emptySysResolvers is an empty [SystemResolvers] implementation that always
|
||||||
// tests.
|
// returns nil.
|
||||||
type fakeSystemResolvers struct {
|
type emptySysResolvers struct{}
|
||||||
// SystemResolvers is embedded here simply to make *fakeSystemResolvers
|
|
||||||
// an aghnet.SystemResolvers without actually implementing all methods.
|
|
||||||
aghnet.SystemResolvers
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get implements the aghnet.SystemResolvers interface for *fakeSystemResolvers.
|
// Addrs implements the aghnet.SystemResolvers interface for emptySysResolvers.
|
||||||
// It always returns nil.
|
func (emptySysResolvers) Addrs() (addrs []netip.AddrPort) {
|
||||||
func (fsr *fakeSystemResolvers) Get() (rs []string) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +74,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
|
||||||
ConfigModified: func() {},
|
ConfigModified: func() {},
|
||||||
}
|
}
|
||||||
s := createTestServer(t, filterConf, forwardConf, nil)
|
s := createTestServer(t, filterConf, forwardConf, nil)
|
||||||
s.sysResolvers = &fakeSystemResolvers{}
|
s.sysResolvers = &emptySysResolvers{}
|
||||||
|
|
||||||
require.NoError(t, s.Start())
|
require.NoError(t, s.Start())
|
||||||
testutil.CleanupAndRequireSuccess(t, s.Stop)
|
testutil.CleanupAndRequireSuccess(t, s.Stop)
|
||||||
|
@ -156,7 +151,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
|
||||||
ConfigModified: func() {},
|
ConfigModified: func() {},
|
||||||
}
|
}
|
||||||
s := createTestServer(t, filterConf, forwardConf, nil)
|
s := createTestServer(t, filterConf, forwardConf, nil)
|
||||||
s.sysResolvers = &fakeSystemResolvers{}
|
s.sysResolvers = &emptySysResolvers{}
|
||||||
|
|
||||||
defaultConf := s.conf
|
defaultConf := s.conf
|
||||||
|
|
||||||
|
@ -485,7 +480,7 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
|
||||||
hostsListener := newLocalUpstreamListener(t, 0, goodHandler)
|
hostsListener := newLocalUpstreamListener(t, 0, goodHandler)
|
||||||
hostsUps := (&url.URL{
|
hostsUps := (&url.URL{
|
||||||
Scheme: "tcp",
|
Scheme: "tcp",
|
||||||
Host: netutil.JoinHostPort(upstreamHost, int(hostsListener.Port())),
|
Host: netutil.JoinHostPort(upstreamHost, hostsListener.Port()),
|
||||||
}).String()
|
}).String()
|
||||||
|
|
||||||
hc, err := aghnet.NewHostsContainer(
|
hc, err := aghnet.NewHostsContainer(
|
||||||
|
|
|
@ -103,27 +103,6 @@ func (s *Server) prepareUpstreamConfig(
|
||||||
return uc, nil
|
return uc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepareLocalUpstreamConfig returns the upstream configuration for private
|
|
||||||
// upstreams based on upstreams and configuration of s. It also filters out
|
|
||||||
// the own listening addresses from the upstreams, so it may appear empty.
|
|
||||||
func (s *Server) prepareLocalUpstreamConfig(
|
|
||||||
upstreams []string,
|
|
||||||
defaultUpstreams []string,
|
|
||||||
opts *upstream.Options,
|
|
||||||
) (uc *proxy.UpstreamConfig, err error) {
|
|
||||||
uc, err = s.prepareUpstreamConfig(upstreams, defaultUpstreams, opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("preparing private upstreams: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.conf.filterOurAddrs(uc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("filtering private upstreams: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return uc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// replaceUpstreamsWithHosts replaces unique upstreams with their resolved
|
// replaceUpstreamsWithHosts replaces unique upstreams with their resolved
|
||||||
// versions based on the system hosts file.
|
// versions based on the system hosts file.
|
||||||
//
|
//
|
||||||
|
|
|
@ -182,7 +182,7 @@ type httpPprofConfig struct {
|
||||||
// not absolutely necessary.
|
// not absolutely necessary.
|
||||||
type dnsConfig struct {
|
type dnsConfig struct {
|
||||||
BindHosts []netip.Addr `yaml:"bind_hosts"`
|
BindHosts []netip.Addr `yaml:"bind_hosts"`
|
||||||
Port int `yaml:"port"`
|
Port uint16 `yaml:"port"`
|
||||||
|
|
||||||
// AnonymizeClientIP defines if clients' IP addresses should be anonymized
|
// AnonymizeClientIP defines if clients' IP addresses should be anonymized
|
||||||
// in query log and statistics.
|
// in query log and statistics.
|
||||||
|
@ -232,13 +232,13 @@ type tlsConfigSettings struct {
|
||||||
Enabled bool `yaml:"enabled" json:"enabled"` // Enabled is the encryption (DoT/DoH/HTTPS) status
|
Enabled bool `yaml:"enabled" json:"enabled"` // Enabled is the encryption (DoT/DoH/HTTPS) status
|
||||||
ServerName string `yaml:"server_name" json:"server_name,omitempty"` // ServerName is the hostname of your HTTPS/TLS server
|
ServerName string `yaml:"server_name" json:"server_name,omitempty"` // ServerName is the hostname of your HTTPS/TLS server
|
||||||
ForceHTTPS bool `yaml:"force_https" json:"force_https"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
ForceHTTPS bool `yaml:"force_https" json:"force_https"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
||||||
PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
PortHTTPS uint16 `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
||||||
PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DoT will be disabled
|
PortDNSOverTLS uint16 `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DoT will be disabled
|
||||||
PortDNSOverQUIC int `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"` // DNS-over-QUIC port. If 0, DoQ will be disabled
|
PortDNSOverQUIC uint16 `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"` // DNS-over-QUIC port. If 0, DoQ will be disabled
|
||||||
|
|
||||||
// PortDNSCrypt is the port for DNSCrypt requests. If it's zero,
|
// PortDNSCrypt is the port for DNSCrypt requests. If it's zero,
|
||||||
// DNSCrypt is disabled.
|
// DNSCrypt is disabled.
|
||||||
PortDNSCrypt int `yaml:"port_dnscrypt" json:"port_dnscrypt"`
|
PortDNSCrypt uint16 `yaml:"port_dnscrypt" json:"port_dnscrypt"`
|
||||||
// DNSCryptConfigFile is the path to the DNSCrypt config file. Must be
|
// DNSCryptConfigFile is the path to the DNSCrypt config file. Must be
|
||||||
// set if PortDNSCrypt is not zero.
|
// set if PortDNSCrypt is not zero.
|
||||||
//
|
//
|
||||||
|
@ -554,10 +554,10 @@ func validateConfig() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// udpPort is the port number for UDP protocol.
|
// udpPort is the port number for UDP protocol.
|
||||||
type udpPort int
|
type udpPort uint16
|
||||||
|
|
||||||
// tcpPort is the port number for TCP protocol.
|
// tcpPort is the port number for TCP protocol.
|
||||||
type tcpPort int
|
type tcpPort uint16
|
||||||
|
|
||||||
// addPorts is a helper for ports validation that skips zero ports.
|
// addPorts is a helper for ports validation that skips zero ports.
|
||||||
func addPorts[T tcpPort | udpPort](uc aghalg.UniqChecker[T], ports ...T) {
|
func addPorts[T tcpPort | udpPort](uc aghalg.UniqChecker[T], ports ...T) {
|
||||||
|
|
|
@ -24,11 +24,9 @@ import (
|
||||||
// addresses to a slice of strings.
|
// addresses to a slice of strings.
|
||||||
func appendDNSAddrs(dst []string, addrs ...netip.Addr) (res []string) {
|
func appendDNSAddrs(dst []string, addrs ...netip.Addr) (res []string) {
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
var hostport string
|
hostport := addr.String()
|
||||||
if config.DNS.Port != defaultPortDNS {
|
if p := config.DNS.Port; p != defaultPortDNS {
|
||||||
hostport = netip.AddrPortFrom(addr, uint16(config.DNS.Port)).String()
|
hostport = netutil.JoinHostPort(hostport, p)
|
||||||
} else {
|
|
||||||
hostport = addr.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dst = append(dst, hostport)
|
dst = append(dst, hostport)
|
||||||
|
@ -102,7 +100,7 @@ type statusResponse struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Language string `json:"language"`
|
Language string `json:"language"`
|
||||||
DNSAddrs []string `json:"dns_addresses"`
|
DNSAddrs []string `json:"dns_addresses"`
|
||||||
DNSPort int `json:"dns_port"`
|
DNSPort uint16 `json:"dns_port"`
|
||||||
HTTPPort uint16 `json:"http_port"`
|
HTTPPort uint16 `json:"http_port"`
|
||||||
|
|
||||||
// ProtectionDisabledDuration is the duration of the protection pause in
|
// ProtectionDisabledDuration is the duration of the protection pause in
|
||||||
|
@ -340,7 +338,7 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool)
|
||||||
var (
|
var (
|
||||||
forceHTTPS bool
|
forceHTTPS bool
|
||||||
serveHTTP3 bool
|
serveHTTP3 bool
|
||||||
portHTTPS int
|
portHTTPS uint16
|
||||||
)
|
)
|
||||||
func() {
|
func() {
|
||||||
config.RLock()
|
config.RLock()
|
||||||
|
@ -394,7 +392,7 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool)
|
||||||
|
|
||||||
// httpsURL returns a copy of u for redirection to the HTTPS version, taking the
|
// httpsURL returns a copy of u for redirection to the HTTPS version, taking the
|
||||||
// hostname and the HTTPS port into account.
|
// hostname and the HTTPS port into account.
|
||||||
func httpsURL(u *url.URL, host string, portHTTPS int) (redirectURL *url.URL) {
|
func httpsURL(u *url.URL, host string, portHTTPS uint16) (redirectURL *url.URL) {
|
||||||
hostPort := host
|
hostPort := host
|
||||||
if portHTTPS != defaultPortHTTPS {
|
if portHTTPS != defaultPortHTTPS {
|
||||||
hostPort = netutil.JoinHostPort(host, portHTTPS)
|
hostPort = netutil.JoinHostPort(host, portHTTPS)
|
||||||
|
|
|
@ -43,8 +43,8 @@ func (web *webAPI) handleInstallGetAddresses(w http.ResponseWriter, r *http.Requ
|
||||||
data := getAddrsResponse{
|
data := getAddrsResponse{
|
||||||
Version: version.Version(),
|
Version: version.Version(),
|
||||||
|
|
||||||
WebPort: defaultPortHTTP,
|
WebPort: int(defaultPortHTTP),
|
||||||
DNSPort: defaultPortDNS,
|
DNSPort: int(defaultPortDNS),
|
||||||
}
|
}
|
||||||
|
|
||||||
ifaces, err := aghnet.GetValidNetInterfacesForWeb()
|
ifaces, err := aghnet.GetValidNetInterfacesForWeb()
|
||||||
|
@ -64,7 +64,7 @@ func (web *webAPI) handleInstallGetAddresses(w http.ResponseWriter, r *http.Requ
|
||||||
|
|
||||||
type checkConfReqEnt struct {
|
type checkConfReqEnt struct {
|
||||||
IP netip.Addr `json:"ip"`
|
IP netip.Addr `json:"ip"`
|
||||||
Port int `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
Autofix bool `json:"autofix"`
|
Autofix bool `json:"autofix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func (req *checkConfReq) validateWeb(tcpPorts aghalg.UniqChecker[tcpPort]) (err
|
||||||
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
||||||
|
|
||||||
// TODO(a.garipov): Declare all port variables anywhere as uint16.
|
// TODO(a.garipov): Declare all port variables anywhere as uint16.
|
||||||
reqPort := uint16(req.Web.Port)
|
reqPort := req.Web.Port
|
||||||
port := tcpPort(reqPort)
|
port := tcpPort(reqPort)
|
||||||
addPorts(tcpPorts, port)
|
addPorts(tcpPorts, port)
|
||||||
if err = tcpPorts.Validate(); err != nil {
|
if err = tcpPorts.Validate(); err != nil {
|
||||||
|
@ -128,7 +128,7 @@ func (req *checkConfReq) validateDNS(
|
||||||
) (canAutofix bool, err error) {
|
) (canAutofix bool, err error) {
|
||||||
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
||||||
|
|
||||||
port := uint16(req.DNS.Port)
|
port := req.DNS.Port
|
||||||
switch port {
|
switch port {
|
||||||
case 0:
|
case 0:
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -142,13 +142,13 @@ func (req *checkConfReq) validateDNS(
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||||
if !aghnet.IsAddrInUse(err) {
|
if !aghnet.IsAddrInUse(err) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func (req *checkConfReq) validateDNS(
|
||||||
log.Error("disabling DNSStubListener: %s", err)
|
log.Error("disabling DNSStubListener: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||||
canAutofix = false
|
canAutofix = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ func disableDNSStubListener() error {
|
||||||
|
|
||||||
type applyConfigReqEnt struct {
|
type applyConfigReqEnt struct {
|
||||||
IP netip.Addr `json:"ip"`
|
IP netip.Addr `json:"ip"`
|
||||||
Port int `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type applyConfigReq struct {
|
type applyConfigReq struct {
|
||||||
|
@ -395,14 +395,14 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(req.DNS.Port)))
|
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, req.DNS.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, uint16(req.DNS.Port)))
|
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, req.DNS.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||||
copyInstallSettings(curConfig, config)
|
copyInstallSettings(curConfig, config)
|
||||||
|
|
||||||
Context.firstRun = false
|
Context.firstRun = false
|
||||||
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port))
|
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
|
||||||
config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
|
config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
|
||||||
config.DNS.Port = req.DNS.Port
|
config.DNS.Port = req.DNS.Port
|
||||||
|
|
||||||
|
@ -445,8 +445,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
web.conf.firstRun = false
|
web.conf.firstRun = false
|
||||||
web.conf.BindHost = req.Web.IP
|
web.conf.BindAddr = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
|
||||||
web.conf.BindPort = req.Web.Port
|
|
||||||
|
|
||||||
registerControlHandlers(web)
|
registerControlHandlers(web)
|
||||||
|
|
||||||
|
@ -487,9 +486,9 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
|
||||||
}
|
}
|
||||||
|
|
||||||
addrPort := config.HTTPConfig.Address
|
addrPort := config.HTTPConfig.Address
|
||||||
restartHTTP = addrPort.Addr() != req.Web.IP || int(addrPort.Port()) != req.Web.Port
|
restartHTTP = addrPort.Addr() != req.Web.IP || addrPort.Port() != req.Web.Port
|
||||||
if restartHTTP {
|
if restartHTTP {
|
||||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port)))
|
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, req.Web.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf(
|
return nil, false, fmt.Errorf(
|
||||||
"checking address %s:%d: %w",
|
"checking address %s:%d: %w",
|
||||||
|
|
|
@ -27,11 +27,11 @@ import (
|
||||||
|
|
||||||
// Default listening ports.
|
// Default listening ports.
|
||||||
const (
|
const (
|
||||||
defaultPortDNS = 53
|
defaultPortDNS uint16 = 53
|
||||||
defaultPortHTTP = 80
|
defaultPortHTTP uint16 = 80
|
||||||
defaultPortHTTPS = 443
|
defaultPortHTTPS uint16 = 443
|
||||||
defaultPortQUIC = 853
|
defaultPortQUIC uint16 = 853
|
||||||
defaultPortTLS = 853
|
defaultPortTLS uint16 = 853
|
||||||
)
|
)
|
||||||
|
|
||||||
// Called by other modules when configuration is changed
|
// Called by other modules when configuration is changed
|
||||||
|
@ -196,27 +196,27 @@ func isRunning() bool {
|
||||||
return Context.dnsServer != nil && Context.dnsServer.IsRunning()
|
return Context.dnsServer != nil && Context.dnsServer.IsRunning()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ipsToTCPAddrs(ips []netip.Addr, port int) (tcpAddrs []*net.TCPAddr) {
|
func ipsToTCPAddrs(ips []netip.Addr, port uint16) (tcpAddrs []*net.TCPAddr) {
|
||||||
if ips == nil {
|
if ips == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpAddrs = make([]*net.TCPAddr, 0, len(ips))
|
tcpAddrs = make([]*net.TCPAddr, 0, len(ips))
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
tcpAddrs = append(tcpAddrs, net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, uint16(port))))
|
tcpAddrs = append(tcpAddrs, net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, port)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return tcpAddrs
|
return tcpAddrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func ipsToUDPAddrs(ips []netip.Addr, port int) (udpAddrs []*net.UDPAddr) {
|
func ipsToUDPAddrs(ips []netip.Addr, port uint16) (udpAddrs []*net.UDPAddr) {
|
||||||
if ips == nil {
|
if ips == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
udpAddrs = make([]*net.UDPAddr, 0, len(ips))
|
udpAddrs = make([]*net.UDPAddr, 0, len(ips))
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
udpAddrs = append(udpAddrs, net.UDPAddrFromAddrPort(netip.AddrPortFrom(ip, uint16(port))))
|
udpAddrs = append(udpAddrs, net.UDPAddrFromAddrPort(netip.AddrPortFrom(ip, port)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return udpAddrs
|
return udpAddrs
|
||||||
|
@ -346,8 +346,8 @@ func getDNSEncryption() (de dnsEncryption) {
|
||||||
hostname := tlsConf.ServerName
|
hostname := tlsConf.ServerName
|
||||||
if tlsConf.PortHTTPS != 0 {
|
if tlsConf.PortHTTPS != 0 {
|
||||||
addr := hostname
|
addr := hostname
|
||||||
if tlsConf.PortHTTPS != defaultPortHTTPS {
|
if p := tlsConf.PortHTTPS; p != defaultPortHTTPS {
|
||||||
addr = netutil.JoinHostPort(addr, tlsConf.PortHTTPS)
|
addr = netutil.JoinHostPort(addr, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
de.https = (&url.URL{
|
de.https = (&url.URL{
|
||||||
|
@ -357,17 +357,17 @@ func getDNSEncryption() (de dnsEncryption) {
|
||||||
}).String()
|
}).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsConf.PortDNSOverTLS != 0 {
|
if p := tlsConf.PortDNSOverTLS; p != 0 {
|
||||||
de.tls = (&url.URL{
|
de.tls = (&url.URL{
|
||||||
Scheme: "tls",
|
Scheme: "tls",
|
||||||
Host: netutil.JoinHostPort(hostname, tlsConf.PortDNSOverTLS),
|
Host: netutil.JoinHostPort(hostname, p),
|
||||||
}).String()
|
}).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsConf.PortDNSOverQUIC != 0 {
|
if p := tlsConf.PortDNSOverQUIC; p != 0 {
|
||||||
de.quic = (&url.URL{
|
de.quic = (&url.URL{
|
||||||
Scheme: "quic",
|
Scheme: "quic",
|
||||||
Host: netutil.JoinHostPort(hostname, tlsConf.PortDNSOverQUIC),
|
Host: netutil.JoinHostPort(hostname, p),
|
||||||
}).String()
|
}).String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,7 +329,7 @@ func setupBindOpts(opts options) (err error) {
|
||||||
if opts.bindPort != 0 {
|
if opts.bindPort != 0 {
|
||||||
config.HTTPConfig.Address = netip.AddrPortFrom(
|
config.HTTPConfig.Address = netip.AddrPortFrom(
|
||||||
config.HTTPConfig.Address.Addr(),
|
config.HTTPConfig.Address.Addr(),
|
||||||
uint16(opts.bindPort),
|
opts.bindPort,
|
||||||
)
|
)
|
||||||
|
|
||||||
err = checkPorts()
|
err = checkPorts()
|
||||||
|
@ -497,8 +497,7 @@ func initWeb(opts options, clientBuildFS fs.FS, upd *updater.Updater) (web *webA
|
||||||
|
|
||||||
clientFS: clientFS,
|
clientFS: clientFS,
|
||||||
|
|
||||||
BindHost: config.HTTPConfig.Address.Addr(),
|
BindAddr: config.HTTPConfig.Address,
|
||||||
BindPort: int(config.HTTPConfig.Address.Port()),
|
|
||||||
|
|
||||||
ReadTimeout: readTimeout,
|
ReadTimeout: readTimeout,
|
||||||
ReadHeaderTimeout: readHdrTimeout,
|
ReadHeaderTimeout: readHdrTimeout,
|
||||||
|
@ -853,7 +852,7 @@ func loadCmdLineOpts() (opts options) {
|
||||||
// example:
|
// example:
|
||||||
//
|
//
|
||||||
// go to http://127.0.0.1:80
|
// go to http://127.0.0.1:80
|
||||||
func printWebAddrs(proto, addr string, port int) {
|
func printWebAddrs(proto, addr string, port uint16) {
|
||||||
log.Printf("go to %s://%s", proto, netutil.JoinHostPort(addr, port))
|
log.Printf("go to %s://%s", proto, netutil.JoinHostPort(addr, port))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +864,7 @@ func printHTTPAddresses(proto string) {
|
||||||
Context.tls.WriteDiskConfig(&tlsConf)
|
Context.tls.WriteDiskConfig(&tlsConf)
|
||||||
}
|
}
|
||||||
|
|
||||||
port := int(config.HTTPConfig.Address.Port())
|
port := config.HTTPConfig.Address.Port()
|
||||||
if proto == aghhttp.SchemeHTTPS {
|
if proto == aghhttp.SchemeHTTPS {
|
||||||
port = tlsConf.PortHTTPS
|
port = tlsConf.PortHTTPS
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ type options struct {
|
||||||
// bindPort is the port on which to serve the HTTP UI.
|
// bindPort is the port on which to serve the HTTP UI.
|
||||||
//
|
//
|
||||||
// Deprecated: Use bindAddr.
|
// Deprecated: Use bindAddr.
|
||||||
bindPort int
|
bindPort uint16
|
||||||
|
|
||||||
// bindAddr is the address to serve the web UI on.
|
// bindAddr is the address to serve the web UI on.
|
||||||
bindAddr netip.AddrPort
|
bindAddr netip.AddrPort
|
||||||
|
@ -160,15 +160,11 @@ var cmdLineOpts = []cmdLineOpt{{
|
||||||
shortName: "h",
|
shortName: "h",
|
||||||
}, {
|
}, {
|
||||||
updateWithValue: func(o options, v string) (options, error) {
|
updateWithValue: func(o options, v string) (options, error) {
|
||||||
var err error
|
p, err := strconv.ParseUint(v, 10, 16)
|
||||||
var p int
|
if err != nil {
|
||||||
minPort, maxPort := 0, 1<<16-1
|
err = fmt.Errorf("parsing port: %w", err)
|
||||||
if p, err = strconv.Atoi(v); err != nil {
|
|
||||||
err = fmt.Errorf("port %q is not a number", v)
|
|
||||||
} else if p < minPort || p > maxPort {
|
|
||||||
err = fmt.Errorf("port %d not in range %d - %d", p, minPort, maxPort)
|
|
||||||
} else {
|
} else {
|
||||||
o.bindPort = p
|
o.bindPort = uint16(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return o, err
|
return o, err
|
||||||
|
@ -180,7 +176,7 @@ var cmdLineOpts = []cmdLineOpt{{
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
return strconv.Itoa(o.bindPort), true
|
return strconv.Itoa(int(o.bindPort)), true
|
||||||
},
|
},
|
||||||
description: "Deprecated. Port to serve HTTP pages on. Use --web-addr.",
|
description: "Deprecated. Port to serve HTTP pages on. Use --web-addr.",
|
||||||
longName: "port",
|
longName: "port",
|
||||||
|
|
|
@ -67,11 +67,11 @@ func TestParseBindHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseBindPort(t *testing.T) {
|
func TestParseBindPort(t *testing.T) {
|
||||||
assert.Equal(t, 0, testParseOK(t).bindPort, "empty is port 0")
|
assert.Equal(t, uint16(0), testParseOK(t).bindPort, "empty is port 0")
|
||||||
assert.Equal(t, 65535, testParseOK(t, "-p", "65535").bindPort, "-p is port")
|
assert.Equal(t, uint16(65535), testParseOK(t, "-p", "65535").bindPort, "-p is port")
|
||||||
testParseParamMissing(t, "-p")
|
testParseParamMissing(t, "-p")
|
||||||
|
|
||||||
assert.Equal(t, 65535, testParseOK(t, "--port", "65535").bindPort, "--port is port")
|
assert.Equal(t, uint16(65535), testParseOK(t, "--port", "65535").bindPort, "--port is port")
|
||||||
testParseParamMissing(t, "--port")
|
testParseParamMissing(t, "--port")
|
||||||
|
|
||||||
testParseErr(t, "not an int", "-p", "x")
|
testParseErr(t, "not an int", "-p", "x")
|
||||||
|
|
|
@ -39,8 +39,8 @@ type webConfig struct {
|
||||||
|
|
||||||
clientFS fs.FS
|
clientFS fs.FS
|
||||||
|
|
||||||
BindHost netip.Addr
|
// BindAddr is the binding address with port for plain HTTP web interface.
|
||||||
BindPort int
|
BindAddr netip.AddrPort
|
||||||
|
|
||||||
// ReadTimeout is an option to pass to http.Server for setting an
|
// ReadTimeout is an option to pass to http.Server for setting an
|
||||||
// appropriate field.
|
// appropriate field.
|
||||||
|
@ -125,12 +125,12 @@ func newWebAPI(conf *webConfig) (w *webAPI) {
|
||||||
// available, unless the HTTPS server isn't active.
|
// available, unless the HTTPS server isn't active.
|
||||||
//
|
//
|
||||||
// TODO(a.garipov): Adapt for HTTP/3.
|
// TODO(a.garipov): Adapt for HTTP/3.
|
||||||
func webCheckPortAvailable(port int) (ok bool) {
|
func webCheckPortAvailable(port uint16) (ok bool) {
|
||||||
if Context.web.httpsServer.server != nil {
|
if Context.web.httpsServer.server != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
addrPort := netip.AddrPortFrom(config.HTTPConfig.Address.Addr(), uint16(port))
|
addrPort := netip.AddrPortFrom(config.HTTPConfig.Address.Addr(), port)
|
||||||
|
|
||||||
return aghnet.CheckPort("tcp", addrPort) == nil
|
return aghnet.CheckPort("tcp", addrPort) == nil
|
||||||
}
|
}
|
||||||
|
@ -185,10 +185,9 @@ func (web *webAPI) start() {
|
||||||
hdlr := h2c.NewHandler(withMiddlewares(Context.mux, limitRequestBody), &http2.Server{})
|
hdlr := h2c.NewHandler(withMiddlewares(Context.mux, limitRequestBody), &http2.Server{})
|
||||||
|
|
||||||
// Create a new instance, because the Web is not usable after Shutdown.
|
// Create a new instance, because the Web is not usable after Shutdown.
|
||||||
hostStr := web.conf.BindHost.String()
|
|
||||||
web.httpServer = &http.Server{
|
web.httpServer = &http.Server{
|
||||||
ErrorLog: log.StdLog("web: plain", log.DEBUG),
|
ErrorLog: log.StdLog("web: plain", log.DEBUG),
|
||||||
Addr: netutil.JoinHostPort(hostStr, web.conf.BindPort),
|
Addr: web.conf.BindAddr.String(),
|
||||||
Handler: hdlr,
|
Handler: hdlr,
|
||||||
ReadTimeout: web.conf.ReadTimeout,
|
ReadTimeout: web.conf.ReadTimeout,
|
||||||
ReadHeaderTimeout: web.conf.ReadHeaderTimeout,
|
ReadHeaderTimeout: web.conf.ReadHeaderTimeout,
|
||||||
|
@ -249,7 +248,7 @@ func (web *webAPI) tlsServerLoop() {
|
||||||
|
|
||||||
web.httpsServer.cond.L.Unlock()
|
web.httpsServer.cond.L.Unlock()
|
||||||
|
|
||||||
var portHTTPS int
|
var portHTTPS uint16
|
||||||
func() {
|
func() {
|
||||||
config.RLock()
|
config.RLock()
|
||||||
defer config.RUnlock()
|
defer config.RUnlock()
|
||||||
|
@ -257,7 +256,7 @@ func (web *webAPI) tlsServerLoop() {
|
||||||
portHTTPS = config.TLS.PortHTTPS
|
portHTTPS = config.TLS.PortHTTPS
|
||||||
}()
|
}()
|
||||||
|
|
||||||
addr := netutil.JoinHostPort(web.conf.BindHost.String(), portHTTPS)
|
addr := netip.AddrPortFrom(web.conf.BindAddr.Addr(), portHTTPS).String()
|
||||||
web.httpsServer.server = &http.Server{
|
web.httpsServer.server = &http.Server{
|
||||||
ErrorLog: log.StdLog("web: https", log.DEBUG),
|
ErrorLog: log.StdLog("web: https", log.DEBUG),
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
|
|
Loading…
Reference in New Issue