From 62ca625aaf9e7822ba0968dff72dca645cc7d883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= Date: Sun, 6 Aug 2023 22:35:23 +0800 Subject: [PATCH] feat: add meek (#258) Co-authored-by: mzz <2017@duck.com> Co-authored-by: dae-bot[bot] <136105375+dae-bot[bot]@users.noreply.github.com> --- component/outbound/dialer/v2ray/v2ray.go | 29 ++++++++++++++++++++++++ control/control_plane.go | 4 +++- docs/en/proxy-protocols.md | 1 + docs/zh/proxy-protocols.md | 1 + go.mod | 4 ++-- go.sum | 8 +++---- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/component/outbound/dialer/v2ray/v2ray.go b/component/outbound/dialer/v2ray/v2ray.go index 3863ec2..ee1295c 100644 --- a/component/outbound/dialer/v2ray/v2ray.go +++ b/component/outbound/dialer/v2ray/v2ray.go @@ -17,6 +17,7 @@ import ( "github.com/daeuniverse/softwind/protocol/direct" "github.com/daeuniverse/softwind/protocol/http" "github.com/daeuniverse/softwind/transport/grpc" + "github.com/daeuniverse/softwind/transport/meek" jsoniter "github.com/json-iterator/go" ) @@ -166,6 +167,26 @@ func (s *V2Ray) Dialer(option *dialer.GlobalOption, nextDialer netproxy.Dialer) if err != nil { return nil, nil, err } + case "meek": + if strings.HasPrefix(s.Path, "https://") && s.TLS != "tls" && s.TLS != "utls" { + return nil, nil, fmt.Errorf("%w: meek: tls should be enabled", dialer.InvalidParameterErr) + } + + u := url.URL{ + Scheme: "meek", + Host: net.JoinHostPort(s.Add, s.Port), + RawQuery: url.Values{ + "url": []string{s.Path}, + "alpn": []string{s.Alpn}, + "serverName": []string{s.SNI}, + "skipCertVerify": []string{common.BoolToString(s.AllowInsecure || option.AllowInsecure)}, + }.Encode(), + } + + d, err = meek.NewDialer(u.String(), d) + if err != nil { + return nil, nil, err + } default: return nil, nil, fmt.Errorf("%w: network: %v", dialer.UnexpectedFieldErr, s.Net) } @@ -213,6 +234,11 @@ func ParseVlessURL(vless string) (data *V2Ray, err error) { if data.Net == "grpc" { data.Path = u.Query().Get("serviceName") } + + if data.Net == "meek" { + data.Path = u.Query().Get("url") + } + if data.Type == "" { data.Type = "none" } @@ -327,7 +353,10 @@ func (s *V2Ray) ExportToURL() string { common.SetValue(&query, "path", s.Path) case "grpc": common.SetValue(&query, "serviceName", s.Path) + case "meek": + common.SetValue(&query, "url", s.Host) } + //TODO: QUIC if s.TLS != "none" { common.SetValue(&query, "sni", s.Host) // FIXME: it may be different from ws's host diff --git a/control/control_plane.go b/control/control_plane.go index 32a177a..32886dc 100644 --- a/control/control_plane.go +++ b/control/control_plane.go @@ -8,6 +8,7 @@ package control import ( "context" "fmt" + "github.com/daeuniverse/softwind/transport/meek" "net" "net/netip" "os" @@ -276,8 +277,9 @@ func NewControlPlane( } // Filter out groups. - // FIXME: Ugly code here: reset grpc clients manually. + // FIXME: Ugly code here: reset grpc and meek clients manually. grpc.CleanGlobalClientConnectionCache() + meek.CleanGlobalRoundTripperCache() dialerSet := outbound.NewDialerSetFromLinks(option, tagToNodeList) deferFuncs = append(deferFuncs, dialerSet.Close) for _, group := range groups { diff --git a/docs/en/proxy-protocols.md b/docs/en/proxy-protocols.md index 00bed32..8eabee8 100644 --- a/docs/en/proxy-protocols.md +++ b/docs/en/proxy-protocols.md @@ -13,6 +13,7 @@ - [x] TLS - [x] gRPC - [x] h2 + - [x] Meek - [x] Shadowsocks - [x] AEAD Ciphers - [x] Stream Ciphers diff --git a/docs/zh/proxy-protocols.md b/docs/zh/proxy-protocols.md index 20d03a5..33f951a 100644 --- a/docs/zh/proxy-protocols.md +++ b/docs/zh/proxy-protocols.md @@ -12,6 +12,7 @@ - [x] WS - [x] TLS - [x] gRPC + - [x] Meek - [x] Shadowsocks - [x] AEAD Ciphers - [x] Stream Ciphers diff --git a/go.mod b/go.mod index 6372918..f275e0e 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/bits-and-blooms/bloom/v3 v3.5.0 github.com/cilium/ebpf v0.11.0 github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d - github.com/daeuniverse/softwind v0.0.0-20230805041143-2db4e28c8922 + github.com/daeuniverse/softwind v0.0.0-20230806140139-8dd211d63c60 github.com/gorilla/websocket v1.5.0 github.com/json-iterator/go v1.1.12 github.com/miekg/dns v1.1.55 @@ -34,7 +34,7 @@ require ( github.com/golang/mock v1.6.0 // indirect github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/klauspost/compress v1.16.7 // indirect - github.com/mzz2017/quic-go v0.0.0-20230805032040-5e9a02f54eac // indirect + github.com/mzz2017/quic-go v0.0.0-20230806040851-f9ecab3bb42a // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/quic-go/qtls-go1-20 v0.3.1 // indirect golang.org/x/mod v0.12.0 // indirect diff --git a/go.sum b/go.sum index 116f7e8..88c474f 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUg github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d h1:hnC39MjR7xt5kZjrKlef7DXKFDkiX8MIcDXYC/6Jf9Q= github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d/go.mod h1:VGWGgv7pCP5WGyHGUyb9+nq/gW0yBm+i/GfCNATOJ1M= -github.com/daeuniverse/softwind v0.0.0-20230805041143-2db4e28c8922 h1:TQkiCTLMY82prw7vfGqOtSCWOuX9MvnCa3g6ufvPgxg= -github.com/daeuniverse/softwind v0.0.0-20230805041143-2db4e28c8922/go.mod h1:hL69hHFjobbgKxTJ5cknnuZT1DCglxdl30uJ3dS8nco= +github.com/daeuniverse/softwind v0.0.0-20230806140139-8dd211d63c60 h1:3h6gBNiPvaEINMKJWwjAz6TojZ4MpSj+fLWj/uvqrRs= +github.com/daeuniverse/softwind v0.0.0-20230806140139-8dd211d63c60/go.mod h1:SXBNF3LXl1cfYKxoRJO/aK5ycoTNdou280mM9cGZYr4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -91,8 +91,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mzz2017/disk-bloom v1.0.1 h1:rEF9MiXd9qMW3ibRpqcerLXULoTgRlM21yqqJl1B90M= github.com/mzz2017/disk-bloom v1.0.1/go.mod h1:JLHETtUu44Z6iBmsqzkOtFlRvXSlKnxjwiBRDapizDI= -github.com/mzz2017/quic-go v0.0.0-20230805032040-5e9a02f54eac h1:luSUVeRYonUjk7Pxx8zViDj9Vpf42DZmfR/CbQcXKt0= -github.com/mzz2017/quic-go v0.0.0-20230805032040-5e9a02f54eac/go.mod h1:DBA25b2LoPhrfSzOPE8KcDOicysx00qvvnqe0BpA8DQ= +github.com/mzz2017/quic-go v0.0.0-20230806040851-f9ecab3bb42a h1:clBJMmZdRtli4Tko2ZdQ+3n1cA4Es/0ao3tB5vXvctY= +github.com/mzz2017/quic-go v0.0.0-20230806040851-f9ecab3bb42a/go.mod h1:DBA25b2LoPhrfSzOPE8KcDOicysx00qvvnqe0BpA8DQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=