Feature: add xtls support for VLESS

This commit is contained in:
yaling888 2021-07-06 23:55:34 +08:00
parent 56dff65149
commit b4d93c4438
11 changed files with 567 additions and 193 deletions

View file

@ -64,6 +64,7 @@ rules:
- GEOSITE,category-ads-all,REJECT - GEOSITE,category-ads-all,REJECT
- GEOSITE,icloud@cn,DIRECT - GEOSITE,icloud@cn,DIRECT
- GEOSITE,apple@cn,DIRECT - GEOSITE,apple@cn,DIRECT
- GEOSITE,apple-cn,DIRECT
- GEOSITE,microsoft@cn,DIRECT - GEOSITE,microsoft@cn,DIRECT
- GEOSITE,facebook,PROXY - GEOSITE,facebook,PROXY
- GEOSITE,youtube,PROXY - GEOSITE,youtube,PROXY
@ -81,6 +82,67 @@ rules:
- MATCH,PROXY - MATCH,PROXY
``` ```
### Proxies configuration
Support outbound transport protocol `VLESS`
```yaml
proxies:
- name: "vless"
type: vless
server: server
port: 443
uuid: uuid
# udp: true
# skip-cert-verify: true
# servername: example.com # priority over wss host
# network: ws # not support xtls
# ws-path: /path
# ws-headers:
# Host: v2ray.com
- name: "vless-h2"
type: vless
server: server
port: 443
uuid: uuid
network: h2
# flow: xtls-rprx-direct # xtls-rprx-origin xtls-rprx-direct # enable xtls
h2-opts:
host:
- http.example.com
- http-alt.example.com
path: /
- name: "vless-http"
type: vless
server: server
port: 443
uuid: uuid
# udp: true
# network: http
# flow: xtls-rprx-direct # xtls-rprx-origin xtls-rprx-direct # enable xtls
# http-opts:
# # method: "GET"
# # path:
# # - '/'
# # - '/video'
# # headers:
# # Connection:
# # - keep-alive
- name: vless-grpc
server: server
port: 443
type: vless
uuid: uuid
network: grpc
# flow: xtls-rprx-direct # xtls-rprx-origin xtls-rprx-direct # enable xtls
servername: example.com
# skip-cert-verify: true
grpc-opts:
grpc-service-name: "example"
```
### IPTABLES auto-configuration ### IPTABLES auto-configuration
Only work on Linux OS who support `iptables`, Clash will auto-configuration iptables for tproxy listener when `tproxy-port` value isn't zero. Only work on Linux OS who support `iptables`, Clash will auto-configuration iptables for tproxy listener when `tproxy-port` value isn't zero.

View file

@ -34,6 +34,8 @@ type VlessOption struct {
Server string `proxy:"server"` Server string `proxy:"server"`
Port int `proxy:"port"` Port int `proxy:"port"`
UUID string `proxy:"uuid"` UUID string `proxy:"uuid"`
Flow string `proxy:"flow,omitempty"`
FlowShow bool `proxy:"flow_show,omitempty"`
TLS bool `proxy:"tls,omitempty"` TLS bool `proxy:"tls,omitempty"`
UDP bool `proxy:"udp,omitempty"` UDP bool `proxy:"udp,omitempty"`
Network string `proxy:"network,omitempty"` Network string `proxy:"network,omitempty"`
@ -73,21 +75,9 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c, err = vmess.StreamWebsocketConn(c, wsOpts) c, err = vmess.StreamWebsocketConn(c, wsOpts)
case "http": case "http":
// readability first, so just copy default TLS logic // readability first, so just copy default TLS logic
if v.option.TLS { c, err = v.streamTLSOrXTLSConn(c, false)
host, _, _ := net.SplitHostPort(v.addr) if err != nil {
tlsOpts := &vmess.TLSConfig{ return nil, err
Host: host,
SkipCertVerify: v.option.SkipCertVerify,
}
if v.option.ServerName != "" {
tlsOpts.Host = v.option.ServerName
}
c, err = vmess.StreamTLSConn(c, tlsOpts)
if err != nil {
return nil, err
}
} }
host, _, _ := net.SplitHostPort(v.addr) host, _, _ := net.SplitHostPort(v.addr)
@ -100,18 +90,7 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c = vmess.StreamHTTPConn(c, httpOpts) c = vmess.StreamHTTPConn(c, httpOpts)
case "h2": case "h2":
host, _, _ := net.SplitHostPort(v.addr) c, err = v.streamTLSOrXTLSConn(c, true)
tlsOpts := vmess.TLSConfig{
Host: host,
SkipCertVerify: v.option.SkipCertVerify,
NextProtos: []string{"h2"},
}
if v.option.ServerName != "" {
tlsOpts.Host = v.option.ServerName
}
c, err = vmess.StreamTLSConn(c, &tlsOpts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -123,23 +102,14 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c, err = vmess.StreamH2Conn(c, h2Opts) c, err = vmess.StreamH2Conn(c, h2Opts)
case "grpc": case "grpc":
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig) if v.isXTLSEnabled() {
default: c, err = gun.StreamGunWithXTLSConn(c, v.gunTLSConfig, v.gunConfig)
// handle TLS } else {
if v.option.TLS { c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig)
host, _, _ := net.SplitHostPort(v.addr)
tlsOpts := &vmess.TLSConfig{
Host: host,
SkipCertVerify: v.option.SkipCertVerify,
NextProtos: []string{"h2"},
}
if v.option.ServerName != "" {
tlsOpts.Host = v.option.ServerName
}
c, err = vmess.StreamTLSConn(c, tlsOpts)
} }
default:
// handle TLS And XTLS
c, err = v.streamTLSOrXTLSConn(c, true)
} }
if err != nil { if err != nil {
@ -149,6 +119,49 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
return v.client.StreamConn(c, parseVlessAddr(metadata)) return v.client.StreamConn(c, parseVlessAddr(metadata))
} }
func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error) {
host, _, _ := net.SplitHostPort(v.addr)
if v.isXTLSEnabled() {
xtlsOpts := vless.XTLSConfig{
Host: host,
SkipCertVerify: v.option.SkipCertVerify,
}
if isH2 {
xtlsOpts.NextProtos = []string{"h2"}
}
if v.option.ServerName != "" {
xtlsOpts.Host = v.option.ServerName
}
return vless.StreamXTLSConn(conn, &xtlsOpts)
} else if v.option.TLS {
tlsOpts := vmess.TLSConfig{
Host: host,
SkipCertVerify: v.option.SkipCertVerify,
}
if isH2 {
tlsOpts.NextProtos = []string{"h2"}
}
if v.option.ServerName != "" {
tlsOpts.Host = v.option.ServerName
}
return vmess.StreamTLSConn(conn, &tlsOpts)
}
return conn, nil
}
func (v *Vless) isXTLSEnabled() bool {
return v.client.Addons != nil
}
// DialContext implements C.ProxyAdapter // DialContext implements C.ProxyAdapter
func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) { func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
// gun transport // gun transport
@ -262,14 +275,24 @@ func (uc *vlessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
} }
func NewVless(option VlessOption) (*Vless, error) { func NewVless(option VlessOption) (*Vless, error) {
client, err := vless.NewClient(option.UUID) var addons *vless.Addons
if err != nil { if option.Network != "ws" && len(option.Flow) >= 16 {
return nil, err option.Flow = option.Flow[:16]
switch option.Flow {
case vless.XRO, vless.XRD, vless.XRS:
addons = &vless.Addons{
Flow: option.Flow,
}
default:
return nil, fmt.Errorf("unsupported vless flow type: %s", option.Flow)
}
} }
if option.Network != "ws" { option.TLS = true
option.TLS = true
option.SkipCertVerify = false client, err := vless.NewClient(option.UUID, addons, option.FlowShow)
if err != nil {
return nil, err
} }
v := &Vless{ v := &Vless{
@ -315,7 +338,11 @@ func NewVless(option VlessOption) (*Vless, error) {
v.gunTLSConfig = tlsConfig v.gunTLSConfig = tlsConfig
v.gunConfig = gunConfig v.gunConfig = gunConfig
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig) if v.isXTLSEnabled() {
v.transport = gun.NewHTTP2XTLSClient(dialFn, tlsConfig)
} else {
v.transport = gun.NewHTTP2Client(dialFn, tlsConfig)
}
} }
return v, nil return v, nil

1
go.mod
View file

@ -13,6 +13,7 @@ require (
github.com/miekg/dns v1.1.43 github.com/miekg/dns v1.1.43
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
go.uber.org/atomic v1.8.0 go.uber.org/atomic v1.8.0
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
golang.org/x/net v0.0.0-20210614182718-04defd469f4e golang.org/x/net v0.0.0-20210614182718-04defd469f4e

2
go.sum
View file

@ -286,6 +286,8 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 h1:QHESTXtfgc1ABV+ArlbPVqUx9Ht5I0dDkYhxYoXFxNo=
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499/go.mod h1:5TB2+k58gx4A4g2Nf5miSHNDF6CuAzHKpWBooLAshTs=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

View file

@ -1,8 +1,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.26.0 // protoc-gen-go v1.27.1
// protoc v3.15.8 // protoc v3.17.3
// source: config.proto // source: rule/geodata/router/config.proto
package router package router
@ -61,11 +61,11 @@ func (x Domain_Type) String() string {
} }
func (Domain_Type) Descriptor() protoreflect.EnumDescriptor { func (Domain_Type) Descriptor() protoreflect.EnumDescriptor {
return file_config_proto_enumTypes[0].Descriptor() return file_rule_geodata_router_config_proto_enumTypes[0].Descriptor()
} }
func (Domain_Type) Type() protoreflect.EnumType { func (Domain_Type) Type() protoreflect.EnumType {
return &file_config_proto_enumTypes[0] return &file_rule_geodata_router_config_proto_enumTypes[0]
} }
func (x Domain_Type) Number() protoreflect.EnumNumber { func (x Domain_Type) Number() protoreflect.EnumNumber {
@ -74,7 +74,7 @@ func (x Domain_Type) Number() protoreflect.EnumNumber {
// Deprecated: Use Domain_Type.Descriptor instead. // Deprecated: Use Domain_Type.Descriptor instead.
func (Domain_Type) EnumDescriptor() ([]byte, []int) { func (Domain_Type) EnumDescriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{0, 0} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{0, 0}
} }
// Domain for routing decision. // Domain for routing decision.
@ -94,7 +94,7 @@ type Domain struct {
func (x *Domain) Reset() { func (x *Domain) Reset() {
*x = Domain{} *x = Domain{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[0] mi := &file_rule_geodata_router_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -107,7 +107,7 @@ func (x *Domain) String() string {
func (*Domain) ProtoMessage() {} func (*Domain) ProtoMessage() {}
func (x *Domain) ProtoReflect() protoreflect.Message { func (x *Domain) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[0] mi := &file_rule_geodata_router_config_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -120,7 +120,7 @@ func (x *Domain) ProtoReflect() protoreflect.Message {
// Deprecated: Use Domain.ProtoReflect.Descriptor instead. // Deprecated: Use Domain.ProtoReflect.Descriptor instead.
func (*Domain) Descriptor() ([]byte, []int) { func (*Domain) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{0} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{0}
} }
func (x *Domain) GetType() Domain_Type { func (x *Domain) GetType() Domain_Type {
@ -159,7 +159,7 @@ type CIDR struct {
func (x *CIDR) Reset() { func (x *CIDR) Reset() {
*x = CIDR{} *x = CIDR{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[1] mi := &file_rule_geodata_router_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -172,7 +172,7 @@ func (x *CIDR) String() string {
func (*CIDR) ProtoMessage() {} func (*CIDR) ProtoMessage() {}
func (x *CIDR) ProtoReflect() protoreflect.Message { func (x *CIDR) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[1] mi := &file_rule_geodata_router_config_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -185,7 +185,7 @@ func (x *CIDR) ProtoReflect() protoreflect.Message {
// Deprecated: Use CIDR.ProtoReflect.Descriptor instead. // Deprecated: Use CIDR.ProtoReflect.Descriptor instead.
func (*CIDR) Descriptor() ([]byte, []int) { func (*CIDR) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{1} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{1}
} }
func (x *CIDR) GetIp() []byte { func (x *CIDR) GetIp() []byte {
@ -215,7 +215,7 @@ type GeoIP struct {
func (x *GeoIP) Reset() { func (x *GeoIP) Reset() {
*x = GeoIP{} *x = GeoIP{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[2] mi := &file_rule_geodata_router_config_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -228,7 +228,7 @@ func (x *GeoIP) String() string {
func (*GeoIP) ProtoMessage() {} func (*GeoIP) ProtoMessage() {}
func (x *GeoIP) ProtoReflect() protoreflect.Message { func (x *GeoIP) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[2] mi := &file_rule_geodata_router_config_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -241,7 +241,7 @@ func (x *GeoIP) ProtoReflect() protoreflect.Message {
// Deprecated: Use GeoIP.ProtoReflect.Descriptor instead. // Deprecated: Use GeoIP.ProtoReflect.Descriptor instead.
func (*GeoIP) Descriptor() ([]byte, []int) { func (*GeoIP) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{2} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{2}
} }
func (x *GeoIP) GetCountryCode() string { func (x *GeoIP) GetCountryCode() string {
@ -276,7 +276,7 @@ type GeoIPList struct {
func (x *GeoIPList) Reset() { func (x *GeoIPList) Reset() {
*x = GeoIPList{} *x = GeoIPList{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[3] mi := &file_rule_geodata_router_config_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -289,7 +289,7 @@ func (x *GeoIPList) String() string {
func (*GeoIPList) ProtoMessage() {} func (*GeoIPList) ProtoMessage() {}
func (x *GeoIPList) ProtoReflect() protoreflect.Message { func (x *GeoIPList) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[3] mi := &file_rule_geodata_router_config_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -302,7 +302,7 @@ func (x *GeoIPList) ProtoReflect() protoreflect.Message {
// Deprecated: Use GeoIPList.ProtoReflect.Descriptor instead. // Deprecated: Use GeoIPList.ProtoReflect.Descriptor instead.
func (*GeoIPList) Descriptor() ([]byte, []int) { func (*GeoIPList) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{3} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{3}
} }
func (x *GeoIPList) GetEntry() []*GeoIP { func (x *GeoIPList) GetEntry() []*GeoIP {
@ -324,7 +324,7 @@ type GeoSite struct {
func (x *GeoSite) Reset() { func (x *GeoSite) Reset() {
*x = GeoSite{} *x = GeoSite{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[4] mi := &file_rule_geodata_router_config_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -337,7 +337,7 @@ func (x *GeoSite) String() string {
func (*GeoSite) ProtoMessage() {} func (*GeoSite) ProtoMessage() {}
func (x *GeoSite) ProtoReflect() protoreflect.Message { func (x *GeoSite) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[4] mi := &file_rule_geodata_router_config_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -350,7 +350,7 @@ func (x *GeoSite) ProtoReflect() protoreflect.Message {
// Deprecated: Use GeoSite.ProtoReflect.Descriptor instead. // Deprecated: Use GeoSite.ProtoReflect.Descriptor instead.
func (*GeoSite) Descriptor() ([]byte, []int) { func (*GeoSite) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{4} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{4}
} }
func (x *GeoSite) GetCountryCode() string { func (x *GeoSite) GetCountryCode() string {
@ -378,7 +378,7 @@ type GeoSiteList struct {
func (x *GeoSiteList) Reset() { func (x *GeoSiteList) Reset() {
*x = GeoSiteList{} *x = GeoSiteList{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[5] mi := &file_rule_geodata_router_config_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -391,7 +391,7 @@ func (x *GeoSiteList) String() string {
func (*GeoSiteList) ProtoMessage() {} func (*GeoSiteList) ProtoMessage() {}
func (x *GeoSiteList) ProtoReflect() protoreflect.Message { func (x *GeoSiteList) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[5] mi := &file_rule_geodata_router_config_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -404,7 +404,7 @@ func (x *GeoSiteList) ProtoReflect() protoreflect.Message {
// Deprecated: Use GeoSiteList.ProtoReflect.Descriptor instead. // Deprecated: Use GeoSiteList.ProtoReflect.Descriptor instead.
func (*GeoSiteList) Descriptor() ([]byte, []int) { func (*GeoSiteList) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{5} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{5}
} }
func (x *GeoSiteList) GetEntry() []*GeoSite { func (x *GeoSiteList) GetEntry() []*GeoSite {
@ -429,7 +429,7 @@ type Domain_Attribute struct {
func (x *Domain_Attribute) Reset() { func (x *Domain_Attribute) Reset() {
*x = Domain_Attribute{} *x = Domain_Attribute{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_config_proto_msgTypes[6] mi := &file_rule_geodata_router_config_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -442,7 +442,7 @@ func (x *Domain_Attribute) String() string {
func (*Domain_Attribute) ProtoMessage() {} func (*Domain_Attribute) ProtoMessage() {}
func (x *Domain_Attribute) ProtoReflect() protoreflect.Message { func (x *Domain_Attribute) ProtoReflect() protoreflect.Message {
mi := &file_config_proto_msgTypes[6] mi := &file_rule_geodata_router_config_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -455,7 +455,7 @@ func (x *Domain_Attribute) ProtoReflect() protoreflect.Message {
// Deprecated: Use Domain_Attribute.ProtoReflect.Descriptor instead. // Deprecated: Use Domain_Attribute.ProtoReflect.Descriptor instead.
func (*Domain_Attribute) Descriptor() ([]byte, []int) { func (*Domain_Attribute) Descriptor() ([]byte, []int) {
return file_config_proto_rawDescGZIP(), []int{0, 0} return file_rule_geodata_router_config_proto_rawDescGZIP(), []int{0, 0}
} }
func (x *Domain_Attribute) GetKey() string { func (x *Domain_Attribute) GetKey() string {
@ -502,84 +502,85 @@ func (*Domain_Attribute_BoolValue) isDomain_Attribute_TypedValue() {}
func (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {} func (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {}
var File_config_proto protoreflect.FileDescriptor var File_rule_geodata_router_config_proto protoreflect.FileDescriptor
var file_config_proto_rawDesc = []byte{ var file_rule_geodata_router_config_proto_rawDesc = []byte{
0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x0a, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72,
0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x06, 0x44, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67,
0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x22, 0xc7, 0x02,
0x28, 0x0e, 0x32, 0x26, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6c, 0x61, 0x73,
0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x74, 0x74,
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
0x65, 0x1a, 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,
0x32, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x6c, 0x61, 0x69, 0x6e,
0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x01, 0x12, 0x0a, 0x0a,
0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c,
0x6c, 0x10, 0x03, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70,
0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65,
0x66, 0x69, 0x78, 0x22, 0x84, 0x01, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a,
0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65,
0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f,
0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64,
0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52,
0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65,
0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65,
0x76, 0x65, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x43, 0x0a, 0x09, 0x47, 0x65,
0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72,
0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,
0x67, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x09, 0x61, 0x74,
0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x39, 0x0a, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e,
0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61,
0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x47, 0x0a, 0x0b, 0x47, 0x65, 0x6f, 0x53, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72,
0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x69, 0x62, 0x75, 0x74, 0x65, 0x1a, 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c,
0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c,
0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56,
0x65, 0x72, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61,
0x2f, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50,
0x2f, 0x72, 0x75, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x6f, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10,
0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x19, 0x43, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x52, 0x75, 0x6c, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a,
0x65, 0x2e, 0x47, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x03, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12,
0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x84, 0x01, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49,
0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79,
0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e,
0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43,
0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x76,
0x65, 0x72, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x43,
0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65,
0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e,
0x74, 0x72, 0x79, 0x22, 0x67, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21,
0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64,
0x65, 0x12, 0x39, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67,
0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f,
0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x47, 0x0a, 0x0b,
0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x05, 0x65,
0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05,
0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x2f, 0x63,
0x6c, 0x61, 0x73, 0x68, 0x2f, 0x72, 0x75, 0x6c, 0x65, 0x2f, 0x67, 0x65, 0x6f, 0x64, 0x61, 0x74,
0x61, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x19, 0x43, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f,
0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
file_config_proto_rawDescOnce sync.Once file_rule_geodata_router_config_proto_rawDescOnce sync.Once
file_config_proto_rawDescData = file_config_proto_rawDesc file_rule_geodata_router_config_proto_rawDescData = file_rule_geodata_router_config_proto_rawDesc
) )
func file_config_proto_rawDescGZIP() []byte { func file_rule_geodata_router_config_proto_rawDescGZIP() []byte {
file_config_proto_rawDescOnce.Do(func() { file_rule_geodata_router_config_proto_rawDescOnce.Do(func() {
file_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_proto_rawDescData) file_rule_geodata_router_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_rule_geodata_router_config_proto_rawDescData)
}) })
return file_config_proto_rawDescData return file_rule_geodata_router_config_proto_rawDescData
} }
var file_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_rule_geodata_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_rule_geodata_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_config_proto_goTypes = []interface{}{ var file_rule_geodata_router_config_proto_goTypes = []interface{}{
(Domain_Type)(0), // 0: clash.rule.geodata.router.Domain.Type (Domain_Type)(0), // 0: clash.rule.geodata.router.Domain.Type
(*Domain)(nil), // 1: clash.rule.geodata.router.Domain (*Domain)(nil), // 1: clash.rule.geodata.router.Domain
(*CIDR)(nil), // 2: clash.rule.geodata.router.CIDR (*CIDR)(nil), // 2: clash.rule.geodata.router.CIDR
@ -589,7 +590,7 @@ var file_config_proto_goTypes = []interface{}{
(*GeoSiteList)(nil), // 6: clash.rule.geodata.router.GeoSiteList (*GeoSiteList)(nil), // 6: clash.rule.geodata.router.GeoSiteList
(*Domain_Attribute)(nil), // 7: clash.rule.geodata.router.Domain.Attribute (*Domain_Attribute)(nil), // 7: clash.rule.geodata.router.Domain.Attribute
} }
var file_config_proto_depIdxs = []int32{ var file_rule_geodata_router_config_proto_depIdxs = []int32{
0, // 0: clash.rule.geodata.router.Domain.type:type_name -> clash.rule.geodata.router.Domain.Type 0, // 0: clash.rule.geodata.router.Domain.type:type_name -> clash.rule.geodata.router.Domain.Type
7, // 1: clash.rule.geodata.router.Domain.attribute:type_name -> clash.rule.geodata.router.Domain.Attribute 7, // 1: clash.rule.geodata.router.Domain.attribute:type_name -> clash.rule.geodata.router.Domain.Attribute
2, // 2: clash.rule.geodata.router.GeoIP.cidr:type_name -> clash.rule.geodata.router.CIDR 2, // 2: clash.rule.geodata.router.GeoIP.cidr:type_name -> clash.rule.geodata.router.CIDR
@ -603,13 +604,13 @@ var file_config_proto_depIdxs = []int32{
0, // [0:6] is the sub-list for field type_name 0, // [0:6] is the sub-list for field type_name
} }
func init() { file_config_proto_init() } func init() { file_rule_geodata_router_config_proto_init() }
func file_config_proto_init() { func file_rule_geodata_router_config_proto_init() {
if File_config_proto != nil { if File_rule_geodata_router_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Domain); i { switch v := v.(*Domain); i {
case 0: case 0:
return &v.state return &v.state
@ -621,7 +622,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CIDR); i { switch v := v.(*CIDR); i {
case 0: case 0:
return &v.state return &v.state
@ -633,7 +634,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GeoIP); i { switch v := v.(*GeoIP); i {
case 0: case 0:
return &v.state return &v.state
@ -645,7 +646,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GeoIPList); i { switch v := v.(*GeoIPList); i {
case 0: case 0:
return &v.state return &v.state
@ -657,7 +658,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GeoSite); i { switch v := v.(*GeoSite); i {
case 0: case 0:
return &v.state return &v.state
@ -669,7 +670,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GeoSiteList); i { switch v := v.(*GeoSiteList); i {
case 0: case 0:
return &v.state return &v.state
@ -681,7 +682,7 @@ func file_config_proto_init() {
return nil return nil
} }
} }
file_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { file_rule_geodata_router_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Domain_Attribute); i { switch v := v.(*Domain_Attribute); i {
case 0: case 0:
return &v.state return &v.state
@ -694,7 +695,7 @@ func file_config_proto_init() {
} }
} }
} }
file_config_proto_msgTypes[6].OneofWrappers = []interface{}{ file_rule_geodata_router_config_proto_msgTypes[6].OneofWrappers = []interface{}{
(*Domain_Attribute_BoolValue)(nil), (*Domain_Attribute_BoolValue)(nil),
(*Domain_Attribute_IntValue)(nil), (*Domain_Attribute_IntValue)(nil),
} }
@ -702,19 +703,19 @@ func file_config_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_config_proto_rawDesc, RawDescriptor: file_rule_geodata_router_config_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 7, NumMessages: 7,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_config_proto_goTypes, GoTypes: file_rule_geodata_router_config_proto_goTypes,
DependencyIndexes: file_config_proto_depIdxs, DependencyIndexes: file_rule_geodata_router_config_proto_depIdxs,
EnumInfos: file_config_proto_enumTypes, EnumInfos: file_rule_geodata_router_config_proto_enumTypes,
MessageInfos: file_config_proto_msgTypes, MessageInfos: file_rule_geodata_router_config_proto_msgTypes,
}.Build() }.Build()
File_config_proto = out.File File_rule_geodata_router_config_proto = out.File
file_config_proto_rawDesc = nil file_rule_geodata_router_config_proto_rawDesc = nil
file_config_proto_goTypes = nil file_rule_geodata_router_config_proto_goTypes = nil
file_config_proto_depIdxs = nil file_rule_geodata_router_config_proto_depIdxs = nil
} }

56
transport/gun/gun_xtls.go Normal file
View file

@ -0,0 +1,56 @@
// Modified from: https://github.com/Qv2ray/gun-lite
// License: MIT
package gun
import (
"crypto/tls"
"fmt"
"net"
xtls "github.com/xtls/go"
"golang.org/x/net/http2"
)
func NewHTTP2XTLSClient(dialFn DialFn, tlsConfig *tls.Config) *http2.Transport {
dialFunc := func(network, addr string, cfg *tls.Config) (net.Conn, error) {
pconn, err := dialFn(network, addr)
if err != nil {
return nil, err
}
xtlsConfig := &xtls.Config{
InsecureSkipVerify: cfg.InsecureSkipVerify,
ServerName: cfg.ServerName,
}
cn := xtls.Client(pconn, xtlsConfig)
if err := cn.Handshake(); err != nil {
pconn.Close()
return nil, err
}
state := cn.ConnectionState()
if p := state.NegotiatedProtocol; p != http2.NextProtoTLS {
cn.Close()
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http2.NextProtoTLS)
}
return cn, nil
}
return &http2.Transport{
DialTLS: dialFunc,
TLSClientConfig: tlsConfig,
AllowHTTP: false,
DisableCompression: true,
PingTimeout: 0,
}
}
func StreamGunWithXTLSConn(conn net.Conn, tlsConfig *tls.Config, cfg *Config) (net.Conn, error) {
dialFn := func(network, addr string) (net.Conn, error) {
return conn, nil
}
transport := NewHTTP2XTLSClient(dialFn, tlsConfig)
return StreamGunWithTransport(transport, cfg)
}

View file

@ -0,0 +1,158 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.17.3
// source: transport/vless/config.proto
package vless
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Addons struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Flow string `protobuf:"bytes,1,opt,name=Flow,proto3" json:"Flow,omitempty"`
Seed []byte `protobuf:"bytes,2,opt,name=Seed,proto3" json:"Seed,omitempty"`
}
func (x *Addons) Reset() {
*x = Addons{}
if protoimpl.UnsafeEnabled {
mi := &file_transport_vless_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Addons) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Addons) ProtoMessage() {}
func (x *Addons) ProtoReflect() protoreflect.Message {
mi := &file_transport_vless_config_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Addons.ProtoReflect.Descriptor instead.
func (*Addons) Descriptor() ([]byte, []int) {
return file_transport_vless_config_proto_rawDescGZIP(), []int{0}
}
func (x *Addons) GetFlow() string {
if x != nil {
return x.Flow
}
return ""
}
func (x *Addons) GetSeed() []byte {
if x != nil {
return x.Seed
}
return nil
}
var File_transport_vless_config_proto protoreflect.FileDescriptor
var file_transport_vless_config_proto_rawDesc = []byte{
0x0a, 0x1c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x76, 0x6c, 0x65, 0x73,
0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15,
0x63, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e,
0x76, 0x6c, 0x65, 0x73, 0x73, 0x22, 0x30, 0x0a, 0x06, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x12,
0x12, 0x0a, 0x04, 0x46, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46,
0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x65, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x04, 0x53, 0x65, 0x65, 0x64, 0x42, 0x61, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x63,
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76,
0x6c, 0x65, 0x73, 0x73, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x2f, 0x63, 0x6c, 0x61,
0x73, 0x68, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x76, 0x6c, 0x65,
0x73, 0x73, 0xaa, 0x02, 0x15, 0x43, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x70, 0x6f, 0x72, 0x74, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_transport_vless_config_proto_rawDescOnce sync.Once
file_transport_vless_config_proto_rawDescData = file_transport_vless_config_proto_rawDesc
)
func file_transport_vless_config_proto_rawDescGZIP() []byte {
file_transport_vless_config_proto_rawDescOnce.Do(func() {
file_transport_vless_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_transport_vless_config_proto_rawDescData)
})
return file_transport_vless_config_proto_rawDescData
}
var file_transport_vless_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_transport_vless_config_proto_goTypes = []interface{}{
(*Addons)(nil), // 0: clash.transport.vless.Addons
}
var file_transport_vless_config_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_transport_vless_config_proto_init() }
func file_transport_vless_config_proto_init() {
if File_transport_vless_config_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_transport_vless_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Addons); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_transport_vless_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_transport_vless_config_proto_goTypes,
DependencyIndexes: file_transport_vless_config_proto_depIdxs,
MessageInfos: file_transport_vless_config_proto_msgTypes,
}.Build()
File_transport_vless_config_proto = out.File
file_transport_vless_config_proto_rawDesc = nil
file_transport_vless_config_proto_goTypes = nil
file_transport_vless_config_proto_depIdxs = nil
}

View file

@ -0,0 +1,12 @@
syntax = "proto3";
package clash.transport.vless;
option csharp_namespace = "Clash.Transport.Vless";
option go_package = "github.com/Dreamacro/clash/transport/vless";
option java_package = "com.clash.transport.vless";
option java_multiple_files = true;
message Addons {
string Flow = 1;
bytes Seed = 2;
}

View file

@ -4,29 +4,21 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net" "net"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
xtls "github.com/xtls/go"
"google.golang.org/protobuf/proto"
) )
/*var (
//proto.Marshal(addons) bytes for Flow: "xtls-rprx-direct"
addOnBytes, _ = hex.DecodeString("120a1078746c732d727072782d646972656374")
addOnBytesLen = len(addOnBytes)
//proto.Marshal(addons) bytes for Flow: ""
//addOnEmptyBytes, _ = hex.DecodeString("00")
//addOnEmptyBytesLen = len(addOnEmptyBytes)
)*/
type Conn struct { type Conn struct {
net.Conn net.Conn
dst *DstAddr dst *DstAddr
id *uuid.UUID id *uuid.UUID
addons *Addons
received bool received bool
} }
@ -48,16 +40,22 @@ func (vc *Conn) sendRequest() error {
buf.WriteByte(Version) // protocol version buf.WriteByte(Version) // protocol version
buf.Write(vc.id.Bytes()) // 16 bytes of uuid buf.Write(vc.id.Bytes()) // 16 bytes of uuid
// command if vc.addons != nil {
if vc.dst.UDP { bytes, err := proto.Marshal(vc.addons)
buf.WriteByte(0) // addon data length. 0 means no addon data if err != nil {
//buf.WriteByte(byte(addOnEmptyBytesLen)) return err
//buf.Write(addOnEmptyBytes) }
buf.WriteByte(CommandUDP)
buf.WriteByte(byte(len(bytes)))
buf.Write(bytes)
} else { } else {
buf.WriteByte(0) // addon data length. 0 means no addon data buf.WriteByte(0) // addon data length. 0 means no addon data
//buf.WriteByte(byte(addOnBytesLen)) }
//buf.Write(addOnBytes)
// command
if vc.dst.UDP {
buf.WriteByte(CommandUDP)
} else {
buf.WriteByte(CommandTCP) buf.WriteByte(CommandTCP)
} }
@ -96,12 +94,34 @@ func (vc *Conn) recvResponse() error {
} }
// newConn return a Conn instance // newConn return a Conn instance
func newConn(conn net.Conn, id *uuid.UUID, dst *DstAddr) (*Conn, error) { func newConn(conn net.Conn, client *Client, dst *DstAddr) (*Conn, error) {
c := &Conn{ c := &Conn{
Conn: conn, Conn: conn,
id: id, id: client.uuid,
dst: dst, dst: dst,
} }
if !dst.UDP && client.Addons != nil {
switch client.Addons.Flow {
case XRO, XRD, XRS:
if xtlsConn, ok := conn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = client.XTLSShow
xtlsConn.MARK = "XTLS"
if client.Addons.Flow == XRS {
client.Addons.Flow = XRD
}
if client.Addons.Flow == XRD {
xtlsConn.DirectMode = true
}
c.addons = client.Addons
} else {
return nil, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", client.Addons.Flow)
}
}
}
if err := c.sendRequest(); err != nil { if err := c.sendRequest(); err != nil {
return nil, err return nil, err
} }

View file

@ -6,7 +6,13 @@ import (
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
) )
const Version byte = 0 // protocol version. preview version is 0 const (
XRO = "xtls-rprx-origin"
XRD = "xtls-rprx-direct"
XRS = "xtls-rprx-splice"
Version byte = 0 // protocol version. preview version is 0
)
// Command types // Command types
const ( const (
@ -40,22 +46,26 @@ type Config struct {
// Client is vless connection generator // Client is vless connection generator
type Client struct { type Client struct {
uuid *uuid.UUID uuid *uuid.UUID
Addons *Addons
XTLSShow bool
} }
// StreamConn return a Conn with net.Conn and DstAddr // StreamConn return a Conn with net.Conn and DstAddr
func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) {
return newConn(conn, c.uuid, dst) return newConn(conn, c, dst)
} }
// NewClient return Client instance // NewClient return Client instance
func NewClient(uuidStr string) (*Client, error) { func NewClient(uuidStr string, addons *Addons, xtlsShow bool) (*Client, error) {
uid, err := uuid.FromString(uuidStr) uid, err := uuid.FromString(uuidStr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Client{ return &Client{
uuid: &uid, uuid: &uid,
Addons: addons,
XTLSShow: xtlsShow,
}, nil }, nil
} }

25
transport/vless/xtls.go Normal file
View file

@ -0,0 +1,25 @@
package vless
import (
"net"
xtls "github.com/xtls/go"
)
type XTLSConfig struct {
Host string
SkipCertVerify bool
NextProtos []string
}
func StreamXTLSConn(conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
xtlsConfig := &xtls.Config{
ServerName: cfg.Host,
InsecureSkipVerify: cfg.SkipCertVerify,
NextProtos: cfg.NextProtos,
}
xtlsConn := xtls.Client(conn, xtlsConfig)
err := xtlsConn.Handshake()
return xtlsConn, err
}