mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-22 01:06:30 -05:00
Merge branch 'master' into v5
This commit is contained in:
commit
c6c0030b89
2
.github/ISSUE_TEMPLATE/bug_cn.md
vendored
2
.github/ISSUE_TEMPLATE/bug_cn.md
vendored
@ -4,7 +4,7 @@ about: "提交一个 V2Ray 的程序问题报告。"
|
|||||||
---
|
---
|
||||||
|
|
||||||
除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。
|
除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。
|
||||||
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。
|
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/v2ray-core/discussions)进行讨论。
|
||||||
|
|
||||||
1) 你正在使用哪个版本的 V2Ray?(如果服务器和客户端使用了不同版本,请注明)
|
1) 你正在使用哪个版本的 V2Ray?(如果服务器和客户端使用了不同版本,请注明)
|
||||||
|
|
||||||
|
2
.github/ISSUE_TEMPLATE/bug_en.md
vendored
2
.github/ISSUE_TEMPLATE/bug_en.md
vendored
@ -4,7 +4,7 @@ about: "Create a bug report to help us improve"
|
|||||||
---
|
---
|
||||||
|
|
||||||
Please answer all the questions with enough information. All issues not following this template will be closed immediately.
|
Please answer all the questions with enough information. All issues not following this template will be closed immediately.
|
||||||
If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.
|
If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/v2ray-core/discussions) first.
|
||||||
|
|
||||||
1) What version of V2Ray are you using (If you deploy different version on server and client, please explicitly point out)?
|
1) What version of V2Ray are you using (If you deploy different version on server and client, please explicitly point out)?
|
||||||
|
|
||||||
|
6
.github/ISSUE_TEMPLATE/other_en.md
vendored
6
.github/ISSUE_TEMPLATE/other_en.md
vendored
@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
name: Other
|
name: Other
|
||||||
about: "其它问题请使用 https://github.com/v2fly/discussion/issues 进行讨论 / Please discuss other issues at https://github.com/v2fly/discussion/issues"
|
about: "其它问题请使用 https://github.com/v2fly/v2ray-core/discussions 进行讨论 / Please discuss other issues at https://github.com/v2fly/v2ray-core/discussions"
|
||||||
---
|
---
|
||||||
|
|
||||||
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。
|
如果你遇到的问题不是 V2Ray 的 bug,比如你不清楚要如何配置,请使用[Discussion](https://github.com/v2fly/v2ray-core/discussions)进行讨论。
|
||||||
|
|
||||||
此 Issue 会被立即关闭。
|
此 Issue 会被立即关闭。
|
||||||
|
|
||||||
If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.
|
If you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/v2ray-core/discussions) first.
|
||||||
|
|
||||||
This issue will be closed immediately.
|
This issue will be closed immediately.
|
||||||
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -66,6 +66,10 @@ jobs:
|
|||||||
- goos: linux
|
- goos: linux
|
||||||
goarch: mips
|
goarch: mips
|
||||||
# END MIPS
|
# END MIPS
|
||||||
|
# BEGIN Android
|
||||||
|
- goos: android
|
||||||
|
goarch: arm64
|
||||||
|
# END Android
|
||||||
# END Other architectures
|
# END Other architectures
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.25.0
|
// protoc-gen-go v1.25.0
|
||||||
// protoc v3.13.0
|
// protoc v3.14.0
|
||||||
// source: app/dns/config.proto
|
// source: app/dns/config.proto
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
@ -85,6 +85,7 @@ type NameServer struct {
|
|||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
||||||
|
ClientIp []byte `protobuf:"bytes,5,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"`
|
||||||
PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
|
PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
|
||||||
Geoip []*router.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"`
|
Geoip []*router.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"`
|
||||||
OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"`
|
OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"`
|
||||||
@ -129,6 +130,13 @@ func (x *NameServer) GetAddress() *net.Endpoint {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *NameServer) GetClientIp() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.ClientIp
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain {
|
func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.PrioritizedDomain
|
return x.PrioritizedDomain
|
||||||
@ -446,82 +454,84 @@ var file_app_dns_config_proto_rawDesc = []byte{
|
|||||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74,
|
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74,
|
||||||
0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
|
0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63,
|
0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63,
|
||||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcb, 0x03, 0x0a, 0x0a,
|
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x03, 0x0a, 0x0a,
|
||||||
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64,
|
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64,
|
||||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32,
|
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32,
|
||||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
||||||
0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64,
|
0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64,
|
||||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
|
0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f,
|
||||||
0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
|
0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||||
0x0b, 0x32, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61,
|
0x49, 0x70, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65,
|
||||||
0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65,
|
0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
|
||||||
0x72, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
|
||||||
0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d,
|
0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50,
|
||||||
0x61, 0x69, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03,
|
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70,
|
||||||
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
||||||
0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50,
|
0x12, 0x32, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||||
0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69,
|
0x1c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
|
||||||
0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67,
|
||||||
0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
|
0x65, 0x6f, 0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
|
||||||
0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e,
|
0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76,
|
||||||
0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72,
|
0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e,
|
||||||
0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0e, 0x50,
|
0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69,
|
||||||
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a,
|
0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69,
|
||||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32,
|
0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f,
|
||||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
|
0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79,
|
||||||
0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54,
|
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
|
||||||
0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
|
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f,
|
||||||
0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
|
0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65,
|
||||||
0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c,
|
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
||||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36,
|
||||||
0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20,
|
0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12,
|
||||||
0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xc3, 0x04, 0x0a, 0x06, 0x43, 0x6f,
|
0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75,
|
||||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76,
|
0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
|
||||||
0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61,
|
0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xc3, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
|
0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,
|
||||||
0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b,
|
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
||||||
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e,
|
0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45,
|
||||||
0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
|
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d,
|
||||||
0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
|
0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
|
||||||
0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05,
|
0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64,
|
||||||
0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32,
|
0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e,
|
||||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
|
0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05, 0x48, 0x6f, 0x73,
|
||||||
0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74,
|
0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
|
||||||
0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a,
|
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f,
|
||||||
0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
|
0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42,
|
||||||
0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x49, 0x0a, 0x0c, 0x73, 0x74,
|
0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c,
|
||||||
0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
|
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63,
|
||||||
0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x49, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69,
|
||||||
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73,
|
0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e,
|
||||||
0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63,
|
0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64,
|
||||||
0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01,
|
0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61,
|
||||||
0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x1a, 0x5b, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73,
|
0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73,
|
||||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
0x03, 0x74, 0x61, 0x67, 0x1a, 0x5b, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74,
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49,
|
0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
|
||||||
0x3a, 0x02, 0x38, 0x01, 0x1a, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70,
|
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72,
|
||||||
0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
|
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||||
0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
0x01, 0x1a, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
|
||||||
0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61,
|
0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||||
0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
|
0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
|
||||||
0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68,
|
||||||
0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03,
|
0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a,
|
||||||
0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78,
|
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64,
|
||||||
0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||||
0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2a,
|
0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64,
|
||||||
0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e,
|
0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70,
|
||||||
0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12,
|
0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2a, 0x45, 0x0a, 0x12,
|
||||||
0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b,
|
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79,
|
||||||
0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52,
|
0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09,
|
||||||
0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x42, 0x47, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32,
|
0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b,
|
||||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
|
0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65,
|
||||||
0x50, 0x01, 0x5a, 0x16, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
|
0x78, 0x10, 0x03, 0x42, 0x47, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
|
||||||
0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52,
|
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a,
|
||||||
0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62,
|
0x16, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f,
|
||||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e,
|
||||||
|
0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72,
|
||||||
|
0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -12,6 +12,7 @@ import "app/router/config.proto";
|
|||||||
|
|
||||||
message NameServer {
|
message NameServer {
|
||||||
v2ray.core.common.net.Endpoint address = 1;
|
v2ray.core.common.net.Endpoint address = 1;
|
||||||
|
bytes client_ip = 5;
|
||||||
|
|
||||||
message PriorityDomain {
|
message PriorityDomain {
|
||||||
DomainMatchingType type = 1;
|
DomainMatchingType type = 1;
|
||||||
|
@ -42,6 +42,9 @@ type DoHNameServer struct {
|
|||||||
// NewDoHNameServer creates DOH client object for remote resolving
|
// NewDoHNameServer creates DOH client object for remote resolving
|
||||||
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.IP) (*DoHNameServer, error) {
|
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.IP) (*DoHNameServer, error) {
|
||||||
newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog()
|
newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog()
|
||||||
|
if clientIP != nil {
|
||||||
|
newError("DNS: Remote DOH client ", url.String(), " uses clientip ", clientIP.String()).AtInfo().WriteToLog()
|
||||||
|
}
|
||||||
s := baseDOHNameServer(url, "DOH", clientIP)
|
s := baseDOHNameServer(url, "DOH", clientIP)
|
||||||
|
|
||||||
// Dispatched connection will be closed (interrupted) after each request
|
// Dispatched connection will be closed (interrupted) after each request
|
||||||
@ -105,6 +108,9 @@ func NewDoHLocalNameServer(url *url.URL, clientIP net.IP) *DoHNameServer {
|
|||||||
Transport: tr,
|
Transport: tr,
|
||||||
}
|
}
|
||||||
newError("DNS: created Local DOH client for ", url.String()).AtInfo().WriteToLog()
|
newError("DNS: created Local DOH client for ", url.String()).AtInfo().WriteToLog()
|
||||||
|
if clientIP != nil {
|
||||||
|
newError("DNS: Local DOH client ", url.String(), " uses clientip ", clientIP.String()).AtInfo().WriteToLog()
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +96,13 @@ func New(ctx context.Context, config *Config) (*Server, error) {
|
|||||||
endpoint := ns.Address
|
endpoint := ns.Address
|
||||||
address := endpoint.Address.AsAddress()
|
address := endpoint.Address.AsAddress()
|
||||||
|
|
||||||
|
var myClientIP net.IP
|
||||||
|
if len(ns.ClientIp) == net.IPv4len || len(ns.ClientIp) == net.IPv6len {
|
||||||
|
myClientIP = net.IP(ns.ClientIp)
|
||||||
|
} else {
|
||||||
|
myClientIP = server.clientIP
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case address.Family().IsDomain() && address.Domain() == "localhost":
|
case address.Family().IsDomain() && address.Domain() == "localhost":
|
||||||
server.clients = append(server.clients, NewLocalNameServer())
|
server.clients = append(server.clients, NewLocalNameServer())
|
||||||
@ -123,7 +130,7 @@ func New(ctx context.Context, config *Config) (*Server, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(newError("DNS config error").Base(err))
|
log.Fatalln(newError("DNS config error").Base(err))
|
||||||
}
|
}
|
||||||
server.clients = append(server.clients, NewDoHLocalNameServer(u, server.clientIP))
|
server.clients = append(server.clients, NewDoHLocalNameServer(u, myClientIP))
|
||||||
|
|
||||||
case address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https://"):
|
case address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https://"):
|
||||||
// DOH Remote mode
|
// DOH Remote mode
|
||||||
@ -136,7 +143,7 @@ func New(ctx context.Context, config *Config) (*Server, error) {
|
|||||||
|
|
||||||
// need the core dispatcher, register DOHClient at callback
|
// need the core dispatcher, register DOHClient at callback
|
||||||
common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
|
common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
|
||||||
c, err := NewDoHNameServer(u, d, server.clientIP)
|
c, err := NewDoHNameServer(u, d, myClientIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(newError("DNS config error").Base(err))
|
log.Fatalln(newError("DNS config error").Base(err))
|
||||||
}
|
}
|
||||||
@ -154,7 +161,7 @@ func New(ctx context.Context, config *Config) (*Server, error) {
|
|||||||
server.clients = append(server.clients, nil)
|
server.clients = append(server.clients, nil)
|
||||||
|
|
||||||
common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
|
common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
|
||||||
server.clients[idx] = NewClassicNameServer(dest, d, server.clientIP)
|
server.clients[idx] = NewClassicNameServer(dest, d, myClientIP)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,10 @@ func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher
|
|||||||
Execute: s.Cleanup,
|
Execute: s.Cleanup,
|
||||||
}
|
}
|
||||||
s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
|
s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
|
||||||
newError("DNS: created udp client inited for ", address.NetAddr()).AtInfo().WriteToLog()
|
newError("DNS: created UDP client inited for ", address.NetAddr()).AtInfo().WriteToLog()
|
||||||
|
if clientIP != nil {
|
||||||
|
newError("DNS: UDP client ", address.NetAddr(), " uses clientip ", clientIP.String()).AtInfo().WriteToLog()
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
go.mod
4
go.mod
@ -10,7 +10,7 @@ require (
|
|||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/lucas-clemente/quic-go v0.19.3
|
github.com/lucas-clemente/quic-go v0.19.3
|
||||||
github.com/miekg/dns v1.1.35
|
github.com/miekg/dns v1.1.35
|
||||||
github.com/pires/go-proxyproto v0.3.2
|
github.com/pires/go-proxyproto v0.3.3
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab
|
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848
|
github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848
|
||||||
@ -22,5 +22,5 @@ require (
|
|||||||
google.golang.org/grpc v1.34.0
|
google.golang.org/grpc v1.34.0
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.25.0
|
||||||
gopkg.in/yaml.v2 v2.3.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
h12.io/socks v1.0.1
|
h12.io/socks v1.0.2
|
||||||
)
|
)
|
||||||
|
8
go.sum
8
go.sum
@ -125,8 +125,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
|||||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
|
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
|
||||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||||
github.com/pires/go-proxyproto v0.3.2 h1:E5ig1h9SFGne7IWVY6yRu3UCzyAFkQIukXHMkdFUOCA=
|
github.com/pires/go-proxyproto v0.3.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q=
|
||||||
github.com/pires/go-proxyproto v0.3.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
|
github.com/pires/go-proxyproto v0.3.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@ -314,8 +314,8 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||||
h12.io/socks v1.0.1 h1:bXESSI/+hbdrp+22vcc7/JiXjmLH4UWktKdYgGr3ShA=
|
h12.io/socks v1.0.2 h1:cZhhbV8+DE0Y1kotwhr1a3RC3kFO7AtuZ4GLr3qKSc8=
|
||||||
h12.io/socks v1.0.1/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
|
h12.io/socks v1.0.2/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
type NameServerConfig struct {
|
type NameServerConfig struct {
|
||||||
Address *Address
|
Address *Address
|
||||||
|
ClientIP *Address
|
||||||
Port uint16
|
Port uint16
|
||||||
Domains []string
|
Domains []string
|
||||||
ExpectIPs StringList
|
ExpectIPs StringList
|
||||||
@ -26,12 +27,14 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
var advanced struct {
|
var advanced struct {
|
||||||
Address *Address `json:"address"`
|
Address *Address `json:"address"`
|
||||||
|
ClientIP *Address `json:"clientIp"`
|
||||||
Port uint16 `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
Domains []string `json:"domains"`
|
Domains []string `json:"domains"`
|
||||||
ExpectIPs StringList `json:"expectIps"`
|
ExpectIPs StringList `json:"expectIps"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, &advanced); err == nil {
|
if err := json.Unmarshal(data, &advanced); err == nil {
|
||||||
c.Address = advanced.Address
|
c.Address = advanced.Address
|
||||||
|
c.ClientIP = advanced.ClientIP
|
||||||
c.Port = advanced.Port
|
c.Port = advanced.Port
|
||||||
c.Domains = advanced.Domains
|
c.Domains = advanced.Domains
|
||||||
c.ExpectIPs = advanced.ExpectIPs
|
c.ExpectIPs = advanced.ExpectIPs
|
||||||
@ -87,12 +90,21 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
|
|||||||
return nil, newError("invalid ip rule: ", c.ExpectIPs).Base(err)
|
return nil, newError("invalid ip rule: ", c.ExpectIPs).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var myClientIP []byte
|
||||||
|
if c.ClientIP != nil {
|
||||||
|
if !c.ClientIP.Family().IsIP() {
|
||||||
|
return nil, newError("not an IP address:", c.ClientIP.String())
|
||||||
|
}
|
||||||
|
myClientIP = []byte(c.ClientIP.IP())
|
||||||
|
}
|
||||||
|
|
||||||
return &dns.NameServer{
|
return &dns.NameServer{
|
||||||
Address: &net.Endpoint{
|
Address: &net.Endpoint{
|
||||||
Network: net.Network_UDP,
|
Network: net.Network_UDP,
|
||||||
Address: c.Address.Build(),
|
Address: c.Address.Build(),
|
||||||
Port: uint32(c.Port),
|
Port: uint32(c.Port),
|
||||||
},
|
},
|
||||||
|
ClientIp: myClientIP,
|
||||||
PrioritizedDomain: domains,
|
PrioritizedDomain: domains,
|
||||||
Geoip: geoipList,
|
Geoip: geoipList,
|
||||||
OriginalRules: originalRules,
|
OriginalRules: originalRules,
|
||||||
|
@ -45,6 +45,7 @@ func init() {
|
|||||||
common.Must(err)
|
common.Must(err)
|
||||||
common.Must2(geositeFile.Write(listBytes))
|
common.Must2(geositeFile.Write(listBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDNSConfigParsing(t *testing.T) {
|
func TestDNSConfigParsing(t *testing.T) {
|
||||||
geositePath := platform.GetAssetLocation("geosite.dat")
|
geositePath := platform.GetAssetLocation("geosite.dat")
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -67,6 +68,7 @@ func TestDNSConfigParsing(t *testing.T) {
|
|||||||
Input: `{
|
Input: `{
|
||||||
"servers": [{
|
"servers": [{
|
||||||
"address": "8.8.8.8",
|
"address": "8.8.8.8",
|
||||||
|
"clientIp": "10.0.0.1",
|
||||||
"port": 5353,
|
"port": 5353,
|
||||||
"domains": ["domain:v2ray.com"]
|
"domains": ["domain:v2ray.com"]
|
||||||
}],
|
}],
|
||||||
@ -92,6 +94,7 @@ func TestDNSConfigParsing(t *testing.T) {
|
|||||||
Network: net.Network_UDP,
|
Network: net.Network_UDP,
|
||||||
Port: 5353,
|
Port: 5353,
|
||||||
},
|
},
|
||||||
|
ClientIp: []byte{10, 0, 0, 1},
|
||||||
PrioritizedDomain: []*dns.NameServer_PriorityDomain{
|
PrioritizedDomain: []*dns.NameServer_PriorityDomain{
|
||||||
{
|
{
|
||||||
Type: dns.DomainMatchingType_Subdomain,
|
Type: dns.DomainMatchingType_Subdomain,
|
||||||
|
@ -396,6 +396,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
|||||||
type RawFieldRule struct {
|
type RawFieldRule struct {
|
||||||
RouterRule
|
RouterRule
|
||||||
Domain *StringList `json:"domain"`
|
Domain *StringList `json:"domain"`
|
||||||
|
Domains *StringList `json:"domains"`
|
||||||
IP *StringList `json:"ip"`
|
IP *StringList `json:"ip"`
|
||||||
Port *PortList `json:"port"`
|
Port *PortList `json:"port"`
|
||||||
Network *NetworkList `json:"network"`
|
Network *NetworkList `json:"network"`
|
||||||
@ -436,6 +437,16 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rawFieldRule.Domains != nil {
|
||||||
|
for _, domain := range *rawFieldRule.Domains {
|
||||||
|
rules, err := parseDomainRule(domain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newError("failed to parse domain rule: ", domain).Base(err)
|
||||||
|
}
|
||||||
|
rule.Domain = append(rule.Domain, rules...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if rawFieldRule.IP != nil {
|
if rawFieldRule.IP != nil {
|
||||||
geoipList, err := toCidrList(*rawFieldRule.IP)
|
geoipList, err := toCidrList(*rawFieldRule.IP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -37,6 +37,14 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
],
|
],
|
||||||
"outboundTag": "direct"
|
"outboundTag": "direct"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"domains": [
|
||||||
|
"v2fly.org",
|
||||||
|
"github.com"
|
||||||
|
],
|
||||||
|
"outboundTag": "direct"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "field",
|
"type": "field",
|
||||||
"ip": [
|
"ip": [
|
||||||
@ -87,6 +95,21 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
Tag: "direct",
|
Tag: "direct",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Domain: []*router.Domain{
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "v2fly.org",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "github.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TargetTag: &router.RoutingRule_Tag{
|
||||||
|
Tag: "direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Geoip: []*router.GeoIP{
|
Geoip: []*router.GeoIP{
|
||||||
{
|
{
|
||||||
@ -145,6 +168,14 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
],
|
],
|
||||||
"outboundTag": "direct"
|
"outboundTag": "direct"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"domains": [
|
||||||
|
"v2fly.org",
|
||||||
|
"github.com"
|
||||||
|
],
|
||||||
|
"outboundTag": "direct"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "field",
|
"type": "field",
|
||||||
"ip": [
|
"ip": [
|
||||||
@ -175,6 +206,21 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
Tag: "direct",
|
Tag: "direct",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Domain: []*router.Domain{
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "v2fly.org",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "github.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TargetTag: &router.RoutingRule_Tag{
|
||||||
|
Tag: "direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Geoip: []*router.GeoIP{
|
Geoip: []*router.GeoIP{
|
||||||
{
|
{
|
||||||
@ -209,6 +255,14 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
],
|
],
|
||||||
"outboundTag": "direct"
|
"outboundTag": "direct"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"domains": [
|
||||||
|
"v2fly.org",
|
||||||
|
"github.com"
|
||||||
|
],
|
||||||
|
"outboundTag": "direct"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "field",
|
"type": "field",
|
||||||
"ip": [
|
"ip": [
|
||||||
@ -238,6 +292,21 @@ func TestRouterConfig(t *testing.T) {
|
|||||||
Tag: "direct",
|
Tag: "direct",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Domain: []*router.Domain{
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "v2fly.org",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: router.Domain_Plain,
|
||||||
|
Value: "github.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TargetTag: &router.RoutingRule_Tag{
|
||||||
|
Tag: "direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Geoip: []*router.GeoIP{
|
Geoip: []*router.GeoIP{
|
||||||
{
|
{
|
||||||
|
@ -51,14 +51,19 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
if outbound == nil || !outbound.Target.IsValid() {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("target not specified.")
|
return newError("target not specified.")
|
||||||
}
|
}
|
||||||
|
// Destination of the inner request.
|
||||||
destination := outbound.Target
|
destination := outbound.Target
|
||||||
|
|
||||||
|
// Outbound server.
|
||||||
var server *protocol.ServerSpec
|
var server *protocol.ServerSpec
|
||||||
|
// Outbound server's destination.
|
||||||
|
var dest net.Destination
|
||||||
|
// Connection to the outbound server.
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
|
||||||
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
server = c.serverPicker.PickServer()
|
server = c.serverPicker.PickServer()
|
||||||
dest := server.Destination()
|
dest = server.Destination()
|
||||||
rawConn, err := dialer.Dial(ctx, dest)
|
rawConn, err := dialer.Dial(ctx, dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -101,6 +106,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("failed to establish connection to server").AtWarning().Base(err)
|
return newError("failed to establish connection to server").AtWarning().Base(err)
|
||||||
}
|
}
|
||||||
|
if udpRequest != nil {
|
||||||
|
if udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 {
|
||||||
|
udpRequest.Address = dest.Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := conn.SetDeadline(time.Time{}); err != nil {
|
if err := conn.SetDeadline(time.Time{}); err != nil {
|
||||||
newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
|
@ -16,7 +16,7 @@ const (
|
|||||||
|
|
||||||
cmdTCPConnect = 0x01
|
cmdTCPConnect = 0x01
|
||||||
cmdTCPBind = 0x02
|
cmdTCPBind = 0x02
|
||||||
cmdUDPPort = 0x03
|
cmdUDPAssociate = 0x03
|
||||||
cmdTorResolve = 0xF0
|
cmdTorResolve = 0xF0
|
||||||
cmdTorResolvePTR = 0xF1
|
cmdTorResolvePTR = 0xF1
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri
|
|||||||
case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
|
case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
|
||||||
// We don't have a solution for Tor case now. Simply treat it as connect command.
|
// We don't have a solution for Tor case now. Simply treat it as connect command.
|
||||||
request.Command = protocol.RequestCommandTCP
|
request.Command = protocol.RequestCommandTCP
|
||||||
case cmdUDPPort:
|
case cmdUDPAssociate:
|
||||||
if !s.config.UdpEnabled {
|
if !s.config.UdpEnabled {
|
||||||
writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
|
writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
|
||||||
return nil, newError("UDP is not enabled.")
|
return nil, newError("UDP is not enabled.")
|
||||||
@ -446,7 +446,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
|
|||||||
|
|
||||||
command := byte(cmdTCPConnect)
|
command := byte(cmdTCPConnect)
|
||||||
if request.Command == protocol.RequestCommandUDP {
|
if request.Command == protocol.RequestCommandUDP {
|
||||||
command = byte(cmdUDPPort)
|
command = byte(cmdUDPAssociate)
|
||||||
}
|
}
|
||||||
common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))
|
common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))
|
||||||
if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {
|
if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -18,5 +18,6 @@
|
|||||||
"openbsd-amd64": { "friendlyName": "openbsd-64" },
|
"openbsd-amd64": { "friendlyName": "openbsd-64" },
|
||||||
"windows-amd64": { "friendlyName": "windows-64" },
|
"windows-amd64": { "friendlyName": "windows-64" },
|
||||||
"windows-386": { "friendlyName": "windows-32" },
|
"windows-386": { "friendlyName": "windows-32" },
|
||||||
"windows-arm7": { "friendlyName": "windows-arm32-v7a" }
|
"windows-arm7": { "friendlyName": "windows-arm32-v7a" },
|
||||||
|
"android-arm64": { "friendlyName": "android-arm64-v8a" }
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSe
|
|||||||
Net: "unix",
|
Net: "unix",
|
||||||
}, streamSettings.SocketSettings)
|
}, streamSettings.SocketSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to listen Unix Doman Socket on ", address).Base(err)
|
return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err)
|
||||||
}
|
}
|
||||||
newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx))
|
newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx))
|
||||||
locker := ctx.Value(address.Domain())
|
locker := ctx.Value(address.Domain())
|
||||||
|
Loading…
Reference in New Issue
Block a user