diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2e5b75545..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "[Bug]" -labels: '' -assignees: '' - ---- - - - ------------------------------------------------------------------- - - - -### Clash config - -
- config.yaml - -```yaml -…… -``` - -
- -### Clash log - -``` -…… -``` - -### 环境 Environment - -* 操作系统 (the OS that the Clash core is running on) -…… -* 网路环境或拓扑 (network conditions/topology) -…… -* iptables,如果适用 (if applicable) -…… -* ISP 有没有进行 DNS 污染 (is your ISP performing DNS pollution?) -…… -* 其他 (any other information that would be useful) -…… - -### 说明 Description - - - -### 重现问题的具体布骤 Steps to Reproduce - -1. [First Step] -2. [Second Step] -3. …… - -**我预期会发生……?** - - -**实际上发生了什么?** - - -### 可能的解决方案 Possible Solution - - - - -### 更多信息 More Information diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..b56b98651 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,76 @@ +name: Bug report +description: Create a report to help us improve +title: "[Bug] " +body: + - type: checkboxes + id: ensure + attributes: + label: Verify steps + description: " +在提交之前,请确认 +Please verify that you've followed these steps +" + options: + - label: " +如果你可以自己 debug 并解决的话,提交 PR 吧 +Is this something you can **debug and fix**? Send a pull request! Bug fixes and documentation fixes are welcome. +" + required: true + - label: " +我已经在 [Issue Tracker](……/) 中找过我要提出的问题 +I have searched on the [issue tracker](……/) for a related issue. +" + required: true + - label: " +我已经使用 dev 分支版本测试过,问题依旧存在 +I have tested using the dev branch, and the issue still exists. +" + required: true + - label: " +我已经仔细看过 [Documentation](https://github.com/Dreamacro/clash/wiki/) 并无法自行解决问题 +I have read the [documentation](https://github.com/Dreamacro/clash/wiki/) and was unable to solve the issue. +" + required: true + - label: " +这是 Clash 核心的问题,并非我所使用的 Clash 衍生版本(如 OpenClash、KoolClash 等)的特定问题 +This is an issue of the Clash core *per se*, not to the derivatives of Clash, like OpenClash or KoolClash. +" + required: true + - type: input + attributes: + label: Clash version + validations: + required: true + - type: dropdown + id: os + attributes: + label: What OS are you seeing the problem on? + multiple: true + options: + - macOS + - Windows + - Linux + - OpenBSD/FreeBSD + - type: textarea + attributes: + render: yaml + label: "Clash config" + description: " +在下方附上 Clash core 脱敏后配置文件的内容 +Paste the Clash core configuration below. +" + validations: + required: true + - type: textarea + attributes: + render: shell + label: Clash log + description: " +在下方附上 Clash Core 的日志,log level 使用 DEBUG +Paste the Clash core log below with the log level set to `DEBUG`. +" + - type: textarea + attributes: + label: Description + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..7404fe27c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: false + +contact_links: + - name: Get help in GitHub Discussions + url: https://github.com/Dreamacro/clash/discussions + about: Have a question? Not sure if your issue affects everyone reproducibly? The quickest way to get help is on Clash's GitHub Discussions! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index d5ddc956a..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "[Feature]" -labels: '' -assignees: '' - ---- - - -感谢你向 Clash Core 提交 Feature Request! -在提交之前,请确认: - -- [ ] 我已经在 [Issue Tracker](……/) 中找过我要提出的请求 - -请注意,如果你并没有遵照这个 issue template 填写内容,我们将直接关闭这个 issue。 - - - -我都确认过了,我要继续提交。 - ------------------------------------------------------------------- - -请附上任何可以帮助我们解决这个问题的信息,如果我们收到的信息不足,我们将对这个 issue 加上 *Needs more information* 标记并在收到更多资讯之前关闭 issue。 - - -### Clash core config - -``` -…… -``` - -### Clash log - -``` -…… -``` - -### 环境 Environment - -* Clash Core 的操作系统 (the OS that the Clash core is running on) -…… -* 使用者的操作系统 (the OS running on the client) -…… -* 网路环境或拓扑 (network conditions/topology) -…… -* iptables,如果适用 (if applicable) -…… -* ISP 有没有进行 DNS 污染 (is your ISP performing DNS pollution?) -…… -* 其他 -…… - -### 说明 Description - - - -### 可能的解决方案 Possible Solution - - - - -### 更多信息 More Information diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..34668d1ab --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,36 @@ +name: Feature request +description: Suggest an idea for this project +title: "[Feature] " +body: + - type: checkboxes + id: ensure + attributes: + label: Verify steps + description: " +在提交之前,请确认 +Please verify that you've followed these steps +" + options: + - label: " +我已经在 [Issue Tracker](……/) 中找过我要提出的请求 +I have searched on the [issue tracker](……/) for a related feature request. +" + required: true + - label: " +我已经仔细看过 [Documentation](https://github.com/Dreamacro/clash/wiki/) 并无法自行解决问题 +I have read the [documentation](https://github.com/Dreamacro/clash/wiki/) and was unable to solve the issue. +" + required: true + - type: textarea + attributes: + label: Description + description: 请详细、清晰地表达你要提出的论述,例如这个问题如何影响到你?你想实现什么功能?目前 Clash Core 的行为是什麽? + validations: + required: true + - type: textarea + attributes: + label: Possible Solution + description: " +此项非必须,但是如果你有想法的话欢迎提出。 +Not obligatory, but suggest a fix/reason for the bug, or ideas how to implement the addition or change +" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 385d232ea..ce85a4ca9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -52,7 +52,7 @@ jobs: - name: Get all docker tags if: startsWith(github.ref, 'refs/tags/') - uses: actions/github-script@v3 + uses: actions/github-script@v4 id: tags with: script: | diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f819a4765..6b996084b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -9,7 +9,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: 1.16 + go-version: 1.17 - name: Check out code into the Go module directory uses: actions/checkout@v2 @@ -51,8 +51,6 @@ jobs: - name: Upload Release uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: bin/* draft: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 68629f7a4..9978d235f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -12,9 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 + - uses: actions/stale@v4 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days' days-before-stale: 60 days-before-close: 5 diff --git a/Makefile b/Makefile index 8c2de5f25..413963ea1 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ PLATFORM_LIST = \ WINDOWS_ARCH_LIST = \ windows-386 \ windows-amd64 \ + windows-arm64 \ windows-arm32v7 all: linux-amd64 darwin-amd64 windows-amd64 # Most used @@ -92,6 +93,9 @@ windows-386: windows-amd64: GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe +windows-arm64: + GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe + windows-arm32v7: GOARCH=arm GOOS=windows GOARM=7 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 187ccf744..4d7843df8 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -42,6 +42,7 @@ type VlessOption struct { HTTPOpts HTTPOptions `proxy:"http-opts,omitempty"` HTTP2Opts HTTP2Options `proxy:"h2-opts,omitempty"` GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"` + WSOpts WSOptions `proxy:"ws-opts,omitempty"` WSPath string `proxy:"ws-path,omitempty"` WSHeaders map[string]string `proxy:"ws-headers,omitempty"` SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` @@ -52,11 +53,20 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { var err error switch v.option.Network { case "ws": + if v.option.WSOpts.Path == "" { + v.option.WSOpts.Path = v.option.WSPath + } + if len(v.option.WSOpts.Headers) == 0 { + v.option.WSOpts.Headers = v.option.WSHeaders + } + host, port, _ := net.SplitHostPort(v.addr) wsOpts := &vmess.WebsocketConfig{ - Host: host, - Port: port, - Path: v.option.WSPath, + Host: host, + Port: port, + Path: v.option.WSPath, + MaxEarlyData: v.option.WSOpts.MaxEarlyData, + EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName, } if len(v.option.WSHeaders) != 0 { diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index 5ee4abbc3..445b1ef47 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -43,6 +43,7 @@ type VmessOption struct { HTTPOpts HTTPOptions `proxy:"http-opts,omitempty"` HTTP2Opts HTTP2Options `proxy:"h2-opts,omitempty"` GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"` + WSOpts WSOptions `proxy:"ws-opts,omitempty"` WSPath string `proxy:"ws-path,omitempty"` WSHeaders map[string]string `proxy:"ws-headers,omitempty"` SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` @@ -64,19 +65,35 @@ type GrpcOptions struct { GrpcServiceName string `proxy:"grpc-service-name,omitempty"` } +type WSOptions struct { + Path string `proxy:"path,omitempty"` + Headers map[string]string `proxy:"headers,omitempty"` + MaxEarlyData int `proxy:"max-early-data,omitempty"` + EarlyDataHeaderName string `proxy:"early-data-header-name,omitempty"` +} + // StreamConn implements C.ProxyAdapter func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { var err error switch v.option.Network { case "ws": - host, port, _ := net.SplitHostPort(v.addr) - wsOpts := &vmess.WebsocketConfig{ - Host: host, - Port: port, - Path: v.option.WSPath, + if v.option.WSOpts.Path == "" { + v.option.WSOpts.Path = v.option.WSPath + } + if len(v.option.WSOpts.Headers) == 0 { + v.option.WSOpts.Headers = v.option.WSHeaders } - if len(v.option.WSHeaders) != 0 { + host, port, _ := net.SplitHostPort(v.addr) + wsOpts := &vmess.WebsocketConfig{ + Host: host, + Port: port, + Path: v.option.WSOpts.Path, + MaxEarlyData: v.option.WSOpts.MaxEarlyData, + EarlyDataHeaderName: v.option.WSOpts.EarlyDataHeaderName, + } + + if len(v.option.WSOpts.Headers) != 0 { header := http.Header{} for key, value := range v.option.WSHeaders { header.Add(key, value) diff --git a/common/sockopt/reuseaddr_other.go b/common/sockopt/reuseaddr_other.go index 2b1369508..c07083de0 100644 --- a/common/sockopt/reuseaddr_other.go +++ b/common/sockopt/reuseaddr_other.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package sockopt diff --git a/component/dialer/bind_others.go b/component/dialer/bind_others.go index be30bae84..e09b5ff84 100644 --- a/component/dialer/bind_others.go +++ b/component/dialer/bind_others.go @@ -1,3 +1,4 @@ +//go:build !linux && !darwin // +build !linux,!darwin package dialer diff --git a/component/process/process_other.go b/component/process/process_other.go index 1e0bd4478..f8a6ebbb4 100644 --- a/component/process/process_other.go +++ b/component/process/process_other.go @@ -1,4 +1,7 @@ -// +build !darwin,!linux,!windows +//go:build !darwin && !linux && !windows && (!freebsd || !amd64) +// +build !darwin +// +build !linux +// +build !windows // +build !freebsd !amd64 package process diff --git a/config/config.go b/config/config.go index 2ce038710..d4b120b26 100644 --- a/config/config.go +++ b/config/config.go @@ -73,9 +73,10 @@ type DNS struct { // FallbackFilter config type FallbackFilter struct { - GeoIP bool `yaml:"geoip"` - IPCIDR []*net.IPNet `yaml:"ipcidr"` - Domain []string `yaml:"domain"` + GeoIP bool `yaml:"geoip"` + GeoIPCode string `yaml:"geoip-code"` + IPCIDR []*net.IPNet `yaml:"ipcidr"` + Domain []string `yaml:"domain"` } // Profile config @@ -124,9 +125,10 @@ type RawDNS struct { } type RawFallbackFilter struct { - GeoIP bool `yaml:"geoip"` - IPCIDR []string `yaml:"ipcidr"` - Domain []string `yaml:"domain"` + GeoIP bool `yaml:"geoip"` + GeoIPCode string `yaml:"geoip-code"` + IPCIDR []string `yaml:"ipcidr"` + Domain []string `yaml:"domain"` } type RawConfig struct { @@ -190,8 +192,9 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { UseHosts: true, FakeIPRange: "198.18.0.1/16", FallbackFilter: RawFallbackFilter{ - GeoIP: true, - IPCIDR: []string{}, + GeoIP: true, + GeoIPCode: "CN", + IPCIDR: []string{}, }, DefaultNameserver: []string{ "114.114.114.114", @@ -621,6 +624,7 @@ func parseDNS(cfg RawDNS, hosts *trie.DomainTrie) (*DNS, error) { } dnsCfg.FallbackFilter.GeoIP = cfg.FallbackFilter.GeoIP + dnsCfg.FallbackFilter.GeoIPCode = cfg.FallbackFilter.GeoIPCode if fallbackip, err := parseFallbackIPCIDR(cfg.FallbackFilter.IPCIDR); err == nil { dnsCfg.FallbackFilter.IPCIDR = fallbackip } diff --git a/dns/filters.go b/dns/filters.go index 3cf70ba4d..88ee36e6b 100644 --- a/dns/filters.go +++ b/dns/filters.go @@ -16,11 +16,13 @@ type fallbackIPFilter interface { Match(net.IP) bool } -type geoipFilter struct{} +type geoipFilter struct { + code string +} func (gf *geoipFilter) Match(ip net.IP) bool { if multiGeoIPMatcher == nil { - countryCodeCN := "cn" + countryCodeCN := gf.code countryCodePrivate := "private" geoLoader, err := geodata.GetGeoDataLoader("standard") if err != nil { diff --git a/dns/resolver.go b/dns/resolver.go index 1ca0293ea..56b5e3268 100644 --- a/dns/resolver.go +++ b/dns/resolver.go @@ -302,9 +302,10 @@ type NameServer struct { } type FallbackFilter struct { - GeoIP bool - IPCIDR []*net.IPNet - Domain []string + GeoIP bool + GeoIPCode string + IPCIDR []*net.IPNet + Domain []string } type Config struct { @@ -344,7 +345,9 @@ func NewResolver(config Config) *Resolver { fallbackIPFilters := []fallbackIPFilter{} if config.FallbackFilter.GeoIP { - fallbackIPFilters = append(fallbackIPFilters, &geoipFilter{}) + fallbackIPFilters = append(fallbackIPFilters, &geoipFilter{ + code: config.FallbackFilter.GeoIPCode, + }) } for _, ipnet := range config.FallbackFilter.IPCIDR { fallbackIPFilters = append(fallbackIPFilters, &ipnetFilter{ipnet: ipnet}) diff --git a/go.mod b/go.mod index c12533baf..b5f9ba6de 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/Dreamacro/clash -go 1.16 +go 1.17 require ( github.com/Dreamacro/go-shadowsocks2 v0.1.7 @@ -14,12 +14,21 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 - go.uber.org/atomic v1.8.0 - golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e - golang.org/x/net v0.0.0-20210614182718-04defd469f4e + go.uber.org/atomic v1.9.0 + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 + golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c + golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 google.golang.org/protobuf v1.27.1 gopkg.in/yaml.v2 v2.4.0 gvisor.dev/gvisor v0.0.0-20210519191755-bd7eb2c99ba9 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/btree v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/go.sum b/go.sum index 29e5acf7d..3e3099aa6 100644 --- a/go.sum +++ b/go.sum @@ -299,8 +299,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.8.0 h1:CUhrE4N1rqSE6FM9ecihEjRkLQu8cDfgDyoOs83mEY4= -go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -310,8 +310,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -377,8 +377,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -446,8 +446,8 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 9c11a2eba..46a6dec67 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -131,9 +131,10 @@ func updateDNS(c *config.DNS, general *config.General) { Pool: c.FakeIPRange, Hosts: c.Hosts, FallbackFilter: dns.FallbackFilter{ - GeoIP: c.FallbackFilter.GeoIP, - IPCIDR: c.FallbackFilter.IPCIDR, - Domain: c.FallbackFilter.Domain, + GeoIP: c.FallbackFilter.GeoIP, + GeoIPCode: c.FallbackFilter.GeoIPCode, + IPCIDR: c.FallbackFilter.IPCIDR, + Domain: c.FallbackFilter.Domain, }, Default: c.DefaultNameserver, Policy: c.NameServerPolicy, diff --git a/listener/http/hack.go b/listener/http/hack.go index 14a725383..c33eb6f1b 100644 --- a/listener/http/hack.go +++ b/listener/http/hack.go @@ -7,4 +7,4 @@ import ( ) //go:linkname ReadRequest net/http.readRequest -func ReadRequest(b *bufio.Reader, deleteHostHeader bool) (req *http.Request, err error) +func ReadRequest(b *bufio.Reader) (req *http.Request, err error) diff --git a/listener/http/proxy.go b/listener/http/proxy.go index 9ac95cb49..449658cac 100644 --- a/listener/http/proxy.go +++ b/listener/http/proxy.go @@ -24,7 +24,7 @@ func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache) { trusted := cache == nil // disable authenticate if cache is nil for keepAlive { - request, err := ReadRequest(conn.Reader(), false) + request, err := ReadRequest(conn.Reader()) if err != nil { break } diff --git a/listener/redir/tcp_linux_other.go b/listener/redir/tcp_linux_other.go index 95472823c..3299843d0 100644 --- a/listener/redir/tcp_linux_other.go +++ b/listener/redir/tcp_linux_other.go @@ -1,3 +1,4 @@ +//go:build linux && !386 // +build linux,!386 package redir diff --git a/listener/redir/tcp_other.go b/listener/redir/tcp_other.go index 50968e9ab..592e9584f 100644 --- a/listener/redir/tcp_other.go +++ b/listener/redir/tcp_other.go @@ -1,3 +1,4 @@ +//go:build !darwin && !linux && !freebsd // +build !darwin,!linux,!freebsd package redir diff --git a/listener/tproxy/setsockopt_linux.go b/listener/tproxy/setsockopt_linux.go index a70223f7f..1e92db128 100644 --- a/listener/tproxy/setsockopt_linux.go +++ b/listener/tproxy/setsockopt_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package tproxy diff --git a/listener/tproxy/setsockopt_other.go b/listener/tproxy/setsockopt_other.go index 059477284..24fb7c7b4 100644 --- a/listener/tproxy/setsockopt_other.go +++ b/listener/tproxy/setsockopt_other.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package tproxy diff --git a/listener/tproxy/udp_linux.go b/listener/tproxy/udp_linux.go index 40c177e7e..f68ce8f1f 100644 --- a/listener/tproxy/udp_linux.go +++ b/listener/tproxy/udp_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package tproxy diff --git a/listener/tproxy/udp_other.go b/listener/tproxy/udp_other.go index a4531b5d0..f899fc3d2 100644 --- a/listener/tproxy/udp_other.go +++ b/listener/tproxy/udp_other.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package tproxy diff --git a/rule/geoip.go b/rule/geoip.go index 50c9b9277..f7c5f4300 100644 --- a/rule/geoip.go +++ b/rule/geoip.go @@ -28,6 +28,10 @@ func (g *GEOIP) Match(metadata *C.Metadata) bool { if ip == nil { return false } + + if strings.EqualFold(g.country, "LAN") { + return ip.IsPrivate() + } return g.geoIPMatcher.Match(ip) } diff --git a/test/config/vmess-grpc.json b/test/config/vmess-grpc.json index 1b3a8e9a7..22e117634 100644 --- a/test/config/vmess-grpc.json +++ b/test/config/vmess-grpc.json @@ -24,7 +24,7 @@ ] }, "grpcSettings": { - "serviceName": "example" + "serviceName": "example!" } } } diff --git a/test/config/vmess-ws-0rtt.json b/test/config/vmess-ws-0rtt.json new file mode 100644 index 000000000..7e2876d0c --- /dev/null +++ b/test/config/vmess-ws-0rtt.json @@ -0,0 +1,30 @@ +{ + "inbounds": [ + { + "port": 10002, + "listen": "0.0.0.0", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "b831381d-6324-4d53-ad4f-8cda48b30811", + "alterId": 32 + } + ] + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "maxEarlyData": 128, + "earlyDataHeaderName": "Sec-WebSocket-Protocol" + } + } + } + ], + "outbounds": [ + { + "protocol": "freedom" + } + ] +} \ No newline at end of file diff --git a/test/go.mod b/test/go.mod index 88db62292..5d86eda93 100644 --- a/test/go.mod +++ b/test/go.mod @@ -1,19 +1,46 @@ module clash-test -go 1.16 +go 1.17 require ( - github.com/Dreamacro/clash v1.6.5 - github.com/Microsoft/go-winio v0.5.0 // indirect - github.com/containerd/containerd v1.5.3 // indirect - github.com/docker/docker v20.10.7+incompatible + github.com/Dreamacro/clash v1.6.6-0.20210821162529-0267b2efad9a + github.com/docker/docker v20.10.8+incompatible github.com/docker/go-connections v0.4.0 - github.com/gorilla/mux v1.8.0 // indirect github.com/miekg/dns v1.1.43 + github.com/stretchr/testify v1.7.0 + golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d +) + +require ( + github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/containerd/containerd v1.5.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/gofrs/uuid v4.0.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/stretchr/testify v1.7.0 - golang.org/x/net v0.0.0-20210614182718-04defd469f4e - golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect - google.golang.org/grpc v1.39.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect + github.com/oschwald/geoip2-golang v1.5.0 // indirect + github.com/oschwald/maxminddb-golang v1.8.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect + google.golang.org/grpc v1.40.0 // indirect + google.golang.org/protobuf v1.26.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/test/go.sum b/test/go.sum index 0b460241b..e83047937 100644 --- a/test/go.sum +++ b/test/go.sum @@ -38,8 +38,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Dreamacro/clash v1.6.5 h1:bO8MJpfDOqZsgiK32x2xe9fjniujqVabQOWEYAg5Rac= -github.com/Dreamacro/clash v1.6.5/go.mod h1:AqwqYq0ibcW8j14Re3/uY0bido9PzAuME7Dj+7zst/o= +github.com/Dreamacro/clash v1.6.6-0.20210821162529-0267b2efad9a h1:Y+EWU18ZaK9ZxcZGv2O3nUzGk3XYLZe2r5i8FMku7wA= +github.com/Dreamacro/clash v1.6.6-0.20210821162529-0267b2efad9a/go.mod h1:eN07P85tFwbnkHnEQPYlFsyTc8spXBNa4fOFUea6F58= github.com/Dreamacro/go-shadowsocks2 v0.1.7 h1:8CtbE1HoPPMfrQZGXmlluq6dO2lL31W6WRRE8fabc4Q= github.com/Dreamacro/go-shadowsocks2 v0.1.7/go.mod h1:8p5G4cAj5ZlXwUR+Ww63gfSikr8kvw8uw3TDwLAJpUc= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -82,6 +82,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= @@ -94,6 +95,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -101,6 +103,7 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -138,8 +141,8 @@ github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.5.3 h1:mfKOepNDIJ3EiBTEyHFpEqB6YSOSkGcjPDIu7cD+YzY= -github.com/containerd/containerd v1.5.3/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw= +github.com/containerd/containerd v1.5.5 h1:q1gxsZsGZ8ddVe98yO6pR21b5xQSMiR61lD0W96pgQo= +github.com/containerd/containerd v1.5.5/go.mod h1:oSTh0QpT1w6jYcGmbiSbxv9OSQYaa88mPyWIuU79zyo= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -201,6 +204,7 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 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= @@ -224,8 +228,8 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.8+incompatible h1:RVqD337BgQicVCzYrrlhLDWhq6OAD2PJDUg2LsEUvKM= +github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -283,6 +287,7 @@ github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= 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/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= @@ -318,8 +323,9 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -329,8 +335,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -472,14 +479,17 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/oschwald/geoip2-golang v1.5.0 h1:igg2yQIrrcRccB1ytFXqBfOHCjXWIoMv85lVJ1ONZzw= github.com/oschwald/geoip2-golang v1.5.0/go.mod h1:xdvYt5xQzB8ORWFqPnqMwZpCpgNagttWdoZLlJQzg7s= github.com/oschwald/maxminddb-golang v1.8.0 h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk= @@ -612,8 +622,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.8.0 h1:CUhrE4N1rqSE6FM9ecihEjRkLQu8cDfgDyoOs83mEY4= -go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -630,8 +640,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -697,8 +707,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -777,10 +787,11 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -795,8 +806,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 h1:Vv0JUPWTyeqUq42B2WJ1FeIDjjvGKoA2Ss+Ts0lAVbs= -golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -896,8 +907,8 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -907,8 +918,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/vmess_test.go b/test/vmess_test.go index de3b2ba6a..b696fcea7 100644 --- a/test/vmess_test.go +++ b/test/vmess_test.go @@ -335,7 +335,88 @@ func TestClash_VmessGrpc(t *testing.T) { UDP: true, ServerName: "example.org", GrpcOpts: outbound.GrpcOptions{ - GrpcServiceName: "example", + GrpcServiceName: "example!", + }, + }) + if err != nil { + assert.FailNow(t, err.Error()) + } + + time.Sleep(waitTime) + testSuit(t, proxy) +} + +func TestClash_VmessWebsocket0RTT(t *testing.T) { + cfg := &container.Config{ + Image: ImageVmess, + ExposedPorts: defaultExposedPorts, + } + hostCfg := &container.HostConfig{ + PortBindings: defaultPortBindings, + Binds: []string{ + fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-ws-0rtt.json")), + }, + } + + id, err := startContainer(cfg, hostCfg, "vmess-ws-0rtt") + if err != nil { + assert.FailNow(t, err.Error()) + } + defer cleanContainer(id) + + proxy, err := outbound.NewVmess(outbound.VmessOption{ + Name: "vmess", + Server: localIP.String(), + Port: 10002, + UUID: "b831381d-6324-4d53-ad4f-8cda48b30811", + Cipher: "auto", + AlterID: 32, + Network: "ws", + UDP: true, + ServerName: "example.org", + WSOpts: outbound.WSOptions{ + MaxEarlyData: 2048, + EarlyDataHeaderName: "Sec-WebSocket-Protocol", + }, + }) + if err != nil { + assert.FailNow(t, err.Error()) + } + + time.Sleep(waitTime) + testSuit(t, proxy) +} + +func TestClash_VmessWebsocketXray0RTT(t *testing.T) { + cfg := &container.Config{ + Image: ImageXray, + ExposedPorts: defaultExposedPorts, + } + hostCfg := &container.HostConfig{ + PortBindings: defaultPortBindings, + Binds: []string{ + fmt.Sprintf("%s:/etc/xray/config.json", C.Path.Resolve("vmess-ws-0rtt.json")), + }, + } + + id, err := startContainer(cfg, hostCfg, "vmess-xray-ws-0rtt") + if err != nil { + assert.FailNow(t, err.Error()) + } + defer cleanContainer(id) + + proxy, err := outbound.NewVmess(outbound.VmessOption{ + Name: "vmess", + Server: localIP.String(), + Port: 10002, + UUID: "b831381d-6324-4d53-ad4f-8cda48b30811", + Cipher: "auto", + AlterID: 32, + Network: "ws", + UDP: true, + ServerName: "example.org", + WSOpts: outbound.WSOptions{ + Path: "/?ed=2048", }, }) if err != nil { diff --git a/transport/gun/gun.go b/transport/gun/gun.go index f19006adf..3f97121f8 100644 --- a/transport/gun/gun.go +++ b/transport/gun/gun.go @@ -211,6 +211,8 @@ func StreamGunWithTransport(transport *http2.Transport, cfg *Config) (net.Conn, Scheme: "https", Host: cfg.Host, Path: fmt.Sprintf("/%s/Tun", serviceName), + // for unescape path + Opaque: fmt.Sprintf("//%s/%s/Tun", cfg.Host, serviceName), }, Proto: "HTTP/2", ProtoMajor: 2, diff --git a/transport/ssr/protocol/auth_aes128_sha1.go b/transport/ssr/protocol/auth_aes128_sha1.go index 65bcd7416..fab9d0081 100644 --- a/transport/ssr/protocol/auth_aes128_sha1.go +++ b/transport/ssr/protocol/auth_aes128_sha1.go @@ -152,7 +152,7 @@ func (a *authAES128) Encode(buf *bytes.Buffer, b []byte) error { } func (a *authAES128) DecodePacket(b []byte) ([]byte, error) { - if !bytes.Equal(a.hmac(a.Key, b[:len(b)-4])[:4], b[len(b)-4:]) { + if !bytes.Equal(a.hmac(a.userKey, b[:len(b)-4])[:4], b[len(b)-4:]) { return nil, errAuthAES128ChksumError } return b[:len(b)-4], nil diff --git a/transport/vmess/conn.go b/transport/vmess/conn.go index e6e57be61..cc3155ee4 100644 --- a/transport/vmess/conn.go +++ b/transport/vmess/conn.go @@ -59,12 +59,12 @@ func (vc *Conn) Read(b []byte) (int, error) { func (vc *Conn) sendRequest() error { timestamp := time.Now() + mbuf := &bytes.Buffer{} + if !vc.isAead { h := hmac.New(md5.New, vc.id.UUID.Bytes()) binary.Write(h, binary.BigEndian, uint64(timestamp.Unix())) - if _, err := vc.Conn.Write(h.Sum(nil)); err != nil { - return err - } + mbuf.Write(h.Sum(nil)) } buf := &bytes.Buffer{} @@ -110,7 +110,8 @@ func (vc *Conn) sendRequest() error { stream := cipher.NewCFBEncrypter(block, hashTimestamp(timestamp)) stream.XORKeyStream(buf.Bytes(), buf.Bytes()) - _, err = vc.Conn.Write(buf.Bytes()) + mbuf.Write(buf.Bytes()) + _, err = vc.Conn.Write(mbuf.Bytes()) return err } diff --git a/transport/vmess/websocket.go b/transport/vmess/websocket.go index 6ed353e76..f00e4c4bf 100644 --- a/transport/vmess/websocket.go +++ b/transport/vmess/websocket.go @@ -1,12 +1,17 @@ package vmess import ( + "bytes" + "context" "crypto/tls" + "encoding/base64" + "errors" "fmt" "io" "net" "net/http" "net/url" + "strconv" "strings" "sync" "time" @@ -23,15 +28,26 @@ type websocketConn struct { rMux sync.Mutex wMux sync.Mutex } +type websocketWithEarlyDataConn struct { + net.Conn + underlay net.Conn + closed bool + dialed chan bool + cancel context.CancelFunc + ctx context.Context + config *WebsocketConfig +} type WebsocketConfig struct { - Host string - Port string - Path string - Headers http.Header - TLS bool - SkipCertVerify bool - ServerName string + Host string + Port string + Path string + Headers http.Header + TLS bool + SkipCertVerify bool + ServerName string + MaxEarlyData int + EarlyDataHeaderName string } // Read implements net.Conn.Read() @@ -113,7 +129,118 @@ func (wsc *websocketConn) SetWriteDeadline(t time.Time) error { return wsc.conn.SetWriteDeadline(t) } -func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { +func (wsedc *websocketWithEarlyDataConn) Dial(earlyData []byte) error { + base64DataBuf := &bytes.Buffer{} + base64EarlyDataEncoder := base64.NewEncoder(base64.RawURLEncoding, base64DataBuf) + + earlyDataBuf := bytes.NewBuffer(earlyData) + if _, err := base64EarlyDataEncoder.Write(earlyDataBuf.Next(wsedc.config.MaxEarlyData)); err != nil { + return errors.New("failed to encode early data: " + err.Error()) + } + + if errc := base64EarlyDataEncoder.Close(); errc != nil { + return errors.New("failed to encode early data tail: " + errc.Error()) + } + + var err error + if wsedc.Conn, err = streamWebsocketConn(wsedc.underlay, wsedc.config, base64DataBuf); err != nil { + wsedc.Close() + return errors.New("failed to dial WebSocket: " + err.Error()) + } + + wsedc.dialed <- true + if earlyDataBuf.Len() != 0 { + _, err = wsedc.Conn.Write(earlyDataBuf.Bytes()) + } + + return err +} + +func (wsedc *websocketWithEarlyDataConn) Write(b []byte) (int, error) { + if wsedc.closed { + return 0, io.ErrClosedPipe + } + if wsedc.Conn == nil { + if err := wsedc.Dial(b); err != nil { + return 0, err + } + return len(b), nil + } + + return wsedc.Conn.Write(b) +} + +func (wsedc *websocketWithEarlyDataConn) Read(b []byte) (int, error) { + if wsedc.closed { + return 0, io.ErrClosedPipe + } + if wsedc.Conn == nil { + select { + case <-wsedc.ctx.Done(): + return 0, io.ErrUnexpectedEOF + case <-wsedc.dialed: + } + } + return wsedc.Conn.Read(b) +} + +func (wsedc *websocketWithEarlyDataConn) Close() error { + wsedc.closed = true + wsedc.cancel() + if wsedc.Conn == nil { + return nil + } + return wsedc.Conn.Close() +} + +func (wsedc *websocketWithEarlyDataConn) LocalAddr() net.Addr { + if wsedc.Conn == nil { + return wsedc.underlay.LocalAddr() + } + return wsedc.Conn.LocalAddr() +} + +func (wsedc *websocketWithEarlyDataConn) RemoteAddr() net.Addr { + if wsedc.Conn == nil { + return wsedc.underlay.RemoteAddr() + } + return wsedc.Conn.RemoteAddr() +} + +func (wsedc *websocketWithEarlyDataConn) SetDeadline(t time.Time) error { + if err := wsedc.SetReadDeadline(t); err != nil { + return err + } + return wsedc.SetWriteDeadline(t) +} + +func (wsedc *websocketWithEarlyDataConn) SetReadDeadline(t time.Time) error { + if wsedc.Conn == nil { + return nil + } + return wsedc.Conn.SetReadDeadline(t) +} + +func (wsedc *websocketWithEarlyDataConn) SetWriteDeadline(t time.Time) error { + if wsedc.Conn == nil { + return nil + } + return wsedc.Conn.SetWriteDeadline(t) +} + +func streamWebsocketWithEarlyDataConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { + ctx, cancel := context.WithCancel(context.Background()) + conn = &websocketWithEarlyDataConn{ + dialed: make(chan bool, 1), + cancel: cancel, + ctx: ctx, + underlay: conn, + config: c, + } + return conn, nil +} + +func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buffer) (net.Conn, error) { dialer := &websocket.Dialer{ NetDial: func(network, addr string) (net.Conn, error) { return conn, nil @@ -152,6 +279,14 @@ func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { } } + if earlyData != nil { + if c.EarlyDataHeaderName == "" { + uri.Path += earlyData.String() + } else { + headers.Set(c.EarlyDataHeaderName, earlyData.String()) + } + } + wsConn, resp, err := dialer.Dial(uri.String(), headers) if err != nil { reason := err.Error() @@ -166,3 +301,23 @@ func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { remoteAddr: conn.RemoteAddr(), }, nil } + +func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { + if u, err := url.Parse(c.Path); err == nil { + if q := u.Query(); q.Get("ed") != "" { + if ed, err := strconv.Atoi(q.Get("ed")); err == nil { + c.MaxEarlyData = ed + c.EarlyDataHeaderName = "Sec-WebSocket-Protocol" + q.Del("ed") + u.RawQuery = q.Encode() + c.Path = u.String() + } + } + } + + if c.MaxEarlyData > 0 { + return streamWebsocketWithEarlyDataConn(conn, c) + } + + return streamWebsocketConn(conn, c, nil) +}