diff --git a/.github/workflows/build-master.yml b/.github/workflows/build-master.yml index af0a870..e49b09c 100644 --- a/.github/workflows/build-master.yml +++ b/.github/workflows/build-master.yml @@ -31,7 +31,7 @@ jobs: GOFLAGS: "-tags=gpl" with: xgo_version: latest - go_version: 1.18 + go_version: 1.19 dest: dist prefix: hysteria targets: linux/amd64,linux/386,linux/arm-5,linux/arm-7,linux/arm64,linux/s390x,linux/mipsle,darwin-10.12/amd64,darwin-10.12/arm64,windows-6.0/amd64,windows-6.0/386 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 187f955..1e5f557 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: id: current-time - name: Build - uses: tobyxdd/go-cross-build@6f4e7852e615d5499d1e223cd5e6e7569915b023 + uses: tobyxdd/go-cross-build@d00fc41eb205f57dd90f6e5af4613e21c7ebe73f env: TIME: "${{ steps.current-time.outputs.time }}" GOFLAGS: "-tags=gpl" diff --git a/Dockerfile b/Dockerfile index 250b002..41d3a94 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine AS builder +FROM golang:1.19-alpine AS builder LABEL maintainer="mritd " diff --git a/cmd/client.go b/cmd/client.go index 5cc6fe3..89f2924 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -33,7 +33,12 @@ func client(config *clientConfig) { logrus.WithField("config", config.String()).Info("Client configuration loaded") // Resolver if len(config.Resolver) > 0 { - setResolver(config.Resolver) + err := setResolver(config.Resolver) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed to set resolver") + } } // TLS tlsConfig := &tls.Config{ @@ -98,15 +103,13 @@ func client(config *clientConfig) { } // Resolve preference if len(config.ResolvePreference) > 0 { - pref, excl, err := transport.ResolvePreferenceFromString(config.ResolvePreference) + pref, err := transport.ResolvePreferenceFromString(config.ResolvePreference) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, }).Fatal("Failed to parse the resolve preference") } - transport.DefaultClientTransport.PrefEnabled = true - transport.DefaultClientTransport.PrefIPv6 = pref - transport.DefaultClientTransport.PrefExclusive = excl + transport.DefaultClientTransport.ResolvePreference = pref } // ACL var aclEngine *acl.Engine diff --git a/cmd/resolver.go b/cmd/resolver.go index f60442d..aefe81f 100644 --- a/cmd/resolver.go +++ b/cmd/resolver.go @@ -1,21 +1,88 @@ package main import ( - "context" + "errors" + rdns "github.com/folbricht/routedns" "github.com/tobyxdd/hysteria/pkg/utils" "net" + "strings" ) -func setResolver(dns string) { - if _, _, err := utils.SplitHostPort(dns); err != nil { - // Append the default DNS port - dns = net.JoinHostPort(dns, "53") +var errInvalidSyntax = errors.New("invalid syntax") + +func setResolver(dns string) error { + if net.ParseIP(dns) != nil { + // Just an IP address, treat as UDP 53 + dns = "udp://" + net.JoinHostPort(dns, "53") } - dialer := net.Dialer{} - net.DefaultResolver = &net.Resolver{ - PreferGo: true, - Dial: func(ctx context.Context, network, address string) (net.Conn, error) { - return dialer.DialContext(ctx, network, dns) - }, + var r rdns.Resolver + if strings.HasPrefix(dns, "udp://") { + // Standard UDP DNS resolver + dns = strings.TrimPrefix(dns, "udp://") + if dns == "" { + return errInvalidSyntax + } + if _, _, err := utils.SplitHostPort(dns); err != nil { + // Append the default DNS port + dns = net.JoinHostPort(dns, "53") + } + client, err := rdns.NewDNSClient("dns-udp", dns, "udp", rdns.DNSClientOptions{}) + if err != nil { + return err + } + r = client + } else if strings.HasPrefix(dns, "tcp://") { + // Standard TCP DNS resolver + dns = strings.TrimPrefix(dns, "tcp://") + if dns == "" { + return errInvalidSyntax + } + if _, _, err := utils.SplitHostPort(dns); err != nil { + // Append the default DNS port + dns = net.JoinHostPort(dns, "53") + } + client, err := rdns.NewDNSClient("dns-tcp", dns, "tcp", rdns.DNSClientOptions{}) + if err != nil { + return err + } + r = client + } else if strings.HasPrefix(dns, "https://") { + // DoH resolver + client, err := rdns.NewDoHClient("doh", dns, rdns.DoHClientOptions{}) + if err != nil { + return err + } + r = client + } else if strings.HasPrefix(dns, "tls://") { + // DoT resolver + dns = strings.TrimPrefix(dns, "tls://") + if dns == "" { + return errInvalidSyntax + } + if _, _, err := utils.SplitHostPort(dns); err != nil { + // Append the default DoT port + dns = net.JoinHostPort(dns, "853") + } + client, err := rdns.NewDoTClient("dot", dns, rdns.DoTClientOptions{}) + if err != nil { + return err + } + r = client + } else if strings.HasPrefix(dns, "quic://") { + // DoQ resolver + dns = strings.TrimPrefix(dns, "quic://") + if dns == "" { + return errInvalidSyntax + } + client, err := rdns.NewDoQClient("doq", dns, rdns.DoQClientOptions{}) + if err != nil { + return err + } + r = client + } else { + return errInvalidSyntax } + cache := rdns.NewCache("cache", r, rdns.CacheOptions{}) + net.DefaultResolver = rdns.NewNetResolver(cache) + return nil } diff --git a/cmd/server.go b/cmd/server.go index d4d033e..3a83a3e 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -28,7 +28,12 @@ func server(config *serverConfig) { logrus.WithField("config", config.String()).Info("Server configuration loaded") // Resolver if len(config.Resolver) > 0 { - setResolver(config.Resolver) + err := setResolver(config.Resolver) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed to set resolver") + } } // Load TLS config var tlsConfig *tls.Config @@ -143,15 +148,13 @@ func server(config *serverConfig) { } // Resolve preference if len(config.ResolvePreference) > 0 { - pref, excl, err := transport.ResolvePreferenceFromString(config.ResolvePreference) + pref, err := transport.ResolvePreferenceFromString(config.ResolvePreference) if err != nil { logrus.WithFields(logrus.Fields{ "error": err, }).Fatal("Failed to parse the resolve preference") } - transport.DefaultServerTransport.PrefEnabled = true - transport.DefaultServerTransport.PrefIPv6 = pref - transport.DefaultServerTransport.PrefExclusive = excl + transport.DefaultServerTransport.ResolvePreference = pref } // SOCKS5 outbound if config.SOCKS5Outbound.Server != "" { diff --git a/go.mod b/go.mod index fbef75c..00c04e4 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,11 @@ require ( github.com/coreos/go-iptables v0.6.0 github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac + github.com/folbricht/routedns v0.1.6-0.20220806202012-361f5b35b4c3 github.com/fsnotify/fsnotify v1.5.4 github.com/google/gopacket v1.1.19 github.com/hashicorp/golang-lru v0.5.4 - github.com/lucas-clemente/quic-go v0.27.2 + github.com/lucas-clemente/quic-go v0.28.1 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/oschwald/geoip2-golang v1.7.0 github.com/prometheus/client_golang v1.12.2 @@ -23,9 +24,11 @@ require ( github.com/xjasonlyu/tun2socks/v2 v2.4.1 github.com/yosuke-furukawa/json5 v0.1.1 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 + gvisor.dev/gvisor v0.0.0-20220405222207-795f4f0139bb ) require ( + github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect @@ -34,16 +37,18 @@ require ( github.com/google/btree v1.0.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jtacoma/uritemplates v1.0.0 // indirect github.com/klauspost/cpuid/v2 v2.0.11 // indirect github.com/libdns/libdns v0.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/marten-seemann/qpack v0.2.1 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mholt/acmez v1.0.4 // indirect - github.com/miekg/dns v1.1.46 // indirect + github.com/miekg/dns v1.1.48 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/onsi/ginkgo v1.16.4 // indirect @@ -51,6 +56,11 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pion/dtls/v2 v2.1.3 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/transport v0.13.0 // indirect + github.com/pion/udp v0.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect @@ -79,7 +89,6 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect - gvisor.dev/gvisor v0.0.0-20220405222207-795f4f0139bb // indirect ) -replace github.com/lucas-clemente/quic-go => github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599 +replace github.com/lucas-clemente/quic-go => github.com/tobyxdd/quic-go v0.28.2-0.20220806194731-5be744e08984 diff --git a/go.sum b/go.sum index f9c0d2f..c40f6b3 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Dreamacro/go-shadowsocks2 v0.1.7/go.mod h1:8p5G4cAj5ZlXwUR+Ww63gfSikr8kvw8uw3TDwLAJpUc= @@ -82,6 +83,8 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91 h1:vX+gnvBc56EbWYrmlhYbFYRaeikAke1GL84N4BEYOFE= +github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91/go.mod h1:cDLGBht23g0XQdLjzn6xOGXDkLK182YfINAaZEQLCHQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -166,6 +169,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -200,6 +204,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/folbricht/routedns v0.1.6-0.20220806202012-361f5b35b4c3 h1:5SBA5PxbbVW2CnI5eZ3E0MDnCLiik4em0LfxtkN9gsU= +github.com/folbricht/routedns v0.1.6-0.20220806202012-361f5b35b4c3/go.mod h1:K34wIQLA7ouMpm4H5xs5BLzWYq4vtwrwoH4nU0GlAsw= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= @@ -232,6 +238,7 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -379,6 +386,7 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/heimdalr/dag v1.0.1/go.mod h1:t+ZkR+sjKL4xhlE1B9rwpvwfo+x+2R0363efS+Oghns= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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= @@ -397,6 +405,8 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtacoma/uritemplates v1.0.0 h1:xwx5sBF7pPAb0Uj8lDC1Q/aBPpOFyQza7OC705ZlLCo= +github.com/jtacoma/uritemplates v1.0.0/go.mod h1:IhIICdE9OcvgUnGwTtJxgBQ+VrTrti5PcbLVSJianO8= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -431,6 +441,7 @@ github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamh github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= @@ -459,8 +470,9 @@ github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DA github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.46 h1:uzwpxRtSVxtcIZmz/4Uz6/Rn7G11DvsaslXoy5LxQio= github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -521,6 +533,15 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pion/dtls/v2 v2.1.3 h1:3UF7udADqous+M2R5Uo2q/YaP4EzUoWKdfX2oscCUio= +github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q= +github.com/pion/transport v0.13.0 h1:KWTA5ZrQogizzYwPEciGtHPLwpAjE91FgXnyu+Hv2uY= +github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g= +github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o= +github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -624,6 +645,7 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -652,8 +674,8 @@ github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599 h1:We+z04jRpTGxFggeGWf+GbinhlIk1I1kMMEgujhUfiA= -github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= +github.com/tobyxdd/quic-go v0.28.2-0.20220806194731-5be744e08984 h1:2gxxS9orZKoGr6MvZmda0VTft8LcZopG4bi+qCGl49w= +github.com/tobyxdd/quic-go v0.28.2-0.20220806194731-5be744e08984/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf h1:7PflaKRtU4np/epFxRXlFhlzLXZzKFrH5/I4so5Ove0= @@ -725,6 +747,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -809,6 +832,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -822,6 +846,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= diff --git a/pkg/transport/client.go b/pkg/transport/client.go index 9dae83f..4ee1722 100644 --- a/pkg/transport/client.go +++ b/pkg/transport/client.go @@ -13,17 +13,15 @@ import ( ) type ClientTransport struct { - Dialer *net.Dialer - PrefEnabled bool - PrefIPv6 bool - PrefExclusive bool + Dialer *net.Dialer + ResolvePreference ResolvePreference } var DefaultClientTransport = &ClientTransport{ Dialer: &net.Dialer{ Timeout: 8 * time.Second, }, - PrefEnabled: false, + ResolvePreference: ResolvePreferenceDefault, } func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfs.Obfuscator) (net.PacketConn, error) { @@ -84,11 +82,7 @@ func (ct *ClientTransport) QUICDial(proto string, server string, tlsConfig *tls. } func (ct *ClientTransport) ResolveIPAddr(address string) (*net.IPAddr, error) { - if ct.PrefEnabled { - return resolveIPAddrWithPreference(address, ct.PrefIPv6, ct.PrefExclusive) - } else { - return net.ResolveIPAddr("ip", address) - } + return resolveIPAddrWithPreference(address, ct.ResolvePreference) } func (ct *ClientTransport) DialTCP(raddr *net.TCPAddr) (*net.TCPConn, error) { diff --git a/pkg/transport/resolve.go b/pkg/transport/resolve.go index 2bed90e..3a28c3b 100644 --- a/pkg/transport/resolve.go +++ b/pkg/transport/resolve.go @@ -1,58 +1,93 @@ package transport import ( + "context" "errors" "fmt" "net" + "time" +) + +type ResolvePreference int + +const ( + ResolvePreferenceDefault = ResolvePreference(iota) + ResolvePreferenceIPv4 + ResolvePreferenceIPv6 + ResolvePreferenceIPv4OrIPv6 + ResolvePreferenceIPv6OrIPv4 + + ResolveTimeout = 8 * time.Second ) var ( errNoIPv4Addr = errors.New("no IPv4 address") errNoIPv6Addr = errors.New("no IPv6 address") + errNoAddr = errors.New("no address") ) -func resolveIPAddrWithPreference(address string, preferIPv6 bool, exclusive bool) (*net.IPAddr, error) { - ips, err := net.LookupIP(address) +func resolveIPAddrWithPreference(host string, pref ResolvePreference) (*net.IPAddr, error) { + if pref == ResolvePreferenceDefault { + return net.ResolveIPAddr("ip", host) + } + ctx, cancel := context.WithTimeout(context.Background(), ResolveTimeout) + ips, err := net.DefaultResolver.LookupIPAddr(ctx, host) + cancel() if err != nil { return nil, err } - if preferIPv6 { - for _, ip := range ips { - if ip.To4() == nil { - return &net.IPAddr{IP: ip}, nil - } - } - if exclusive { - return nil, errNoIPv6Addr + var ip4, ip6 *net.IPAddr + for _, ip := range ips { + if ip.IP.To4() != nil { + ip4 = &ip } else { - return &net.IPAddr{IP: ips[0]}, nil - } - } else { - // prefer IPv4 - for _, ip := range ips { - if ip.To4() != nil { - return &net.IPAddr{IP: ip}, nil - } - } - if exclusive { - return nil, errNoIPv4Addr - } else { - return &net.IPAddr{IP: ips[0]}, nil + ip6 = &ip } } + switch pref { + case ResolvePreferenceIPv4: + if ip4 == nil { + return nil, errNoIPv4Addr + } + return ip4, nil + case ResolvePreferenceIPv6: + if ip6 == nil { + return nil, errNoIPv6Addr + } + return ip6, nil + case ResolvePreferenceIPv4OrIPv6: + if ip4 == nil { + if ip6 == nil { + return nil, errNoAddr + } else { + return ip6, nil + } + } + return ip4, nil + case ResolvePreferenceIPv6OrIPv4: + if ip6 == nil { + if ip4 == nil { + return nil, errNoAddr + } else { + return ip4, nil + } + } + return ip6, nil + } + return nil, errNoAddr } -func ResolvePreferenceFromString(preference string) (bool, bool, error) { +func ResolvePreferenceFromString(preference string) (ResolvePreference, error) { switch preference { case "4": - return false, true, nil + return ResolvePreferenceIPv4, nil case "6": - return true, true, nil + return ResolvePreferenceIPv6, nil case "46": - return false, false, nil + return ResolvePreferenceIPv4OrIPv6, nil case "64": - return true, false, nil + return ResolvePreferenceIPv6OrIPv4, nil default: - return false, false, fmt.Errorf("%s is not a valid preference", preference) + return ResolvePreferenceDefault, fmt.Errorf("invalid preference: %s", preference) } } diff --git a/pkg/transport/server.go b/pkg/transport/server.go index 0805f1a..9890ab3 100644 --- a/pkg/transport/server.go +++ b/pkg/transport/server.go @@ -16,13 +16,11 @@ import ( ) type ServerTransport struct { - Dialer *net.Dialer - SOCKS5Client *SOCKS5Client - PrefEnabled bool - PrefIPv6 bool - PrefExclusive bool - LocalUDPAddr *net.UDPAddr - LocalUDPIntf *net.Interface + Dialer *net.Dialer + SOCKS5Client *SOCKS5Client + ResolvePreference ResolvePreference + LocalUDPAddr *net.UDPAddr + LocalUDPIntf *net.Interface } // AddrEx is like net.TCPAddr or net.UDPAddr, but with additional domain information for SOCKS5. @@ -74,7 +72,7 @@ var DefaultServerTransport = &ServerTransport{ Dialer: &net.Dialer{ Timeout: 8 * time.Second, }, - PrefEnabled: false, + ResolvePreference: ResolvePreferenceDefault, } func (st *ServerTransport) quicPacketConn(proto string, laddr string, obfs obfs.Obfuscator) (net.PacketConn, error) { @@ -142,13 +140,8 @@ func (st *ServerTransport) ResolveIPAddr(address string) (*net.IPAddr, bool, err if ip != nil { return &net.IPAddr{IP: ip, Zone: zone}, false, nil } - if st.PrefEnabled { - ipAddr, err := resolveIPAddrWithPreference(address, st.PrefIPv6, st.PrefExclusive) - return ipAddr, true, err - } else { - ipAddr, err := net.ResolveIPAddr("ip", address) - return ipAddr, true, err - } + ipAddr, err := resolveIPAddrWithPreference(address, st.ResolvePreference) + return ipAddr, true, err } func (st *ServerTransport) DialTCP(raddr *AddrEx) (*net.TCPConn, error) {