Compare commits

...

7 Commits

Author SHA1 Message Date
风扇滑翔翼
63e8e689a8 and httpin 2025-08-20 11:39:44 +00:00
风扇滑翔翼
ff73ef5009 Socks: Fix unexpected rawConn copy 2025-08-20 11:33:34 +00:00
风扇滑翔翼
573300bc22 Issues template: Refine requirements 2025-08-19 09:27:25 +00:00
RPRX
7f300dbf0c VLESS practice: Use user-sent VLESS UUID's 7th<<8 | 8th bytes as vlessRoute instead
https://github.com/XTLS/Xray-core/pull/5009#issuecomment-3195718690

Replaces 105b306d07
2025-08-18 08:50:43 +00:00
RPRX
5464862ee6 XTLS Vision inbound: Use user-sent VLESS UUID for NewTrafficState()
Fixes https://github.com/XTLS/Xray-core/pull/5009#issuecomment-3194523018
2025-08-17 18:13:56 +00:00
yuhan6665
337b4b814e Wireguard inbound: Fix context sharing problem (#4988)
* Try fix Wireguard inbound context sharing problem

* Shallow copy inbound and content

* Fix context passing

* Add notes for source address
2025-08-17 10:56:48 -04:00
RPRX
105b306d07 VLESS practice: Use user-sent VLESS UUID's last byte as vlessRoute for routing rules
https://github.com/XTLS/Xray-core/pull/5009#issuecomment-3194262087
2025-08-17 13:55:18 +00:00
22 changed files with 263 additions and 192 deletions

View File

@@ -7,6 +7,8 @@ body:
description: |- description: |-
Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed. Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
options: options:
- label: I have read all the comments in the issue template and ensured that this issue meet the requirements.
required: true
- label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values. - label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
required: true required: true
- label: I provided the complete config and logs, rather than just providing the truncated parts based on my own judgment. - label: I provided the complete config and logs, rather than just providing the truncated parts based on my own judgment.
@@ -38,6 +40,8 @@ body:
### For config ### For config
Please provide the configuration files that can reproduce the problem, including the server and client. Please provide the configuration files that can reproduce the problem, including the server and client.
Don't just paste a big exported config file here. Eliminate useless inbound/outbound, rules, options, this can help determine the problem, if you really want to get help. Don't just paste a big exported config file here. Eliminate useless inbound/outbound, rules, options, this can help determine the problem, if you really want to get help.
After removing parts that do not affect reproduction, provide the actual running **complete** file.
meaning of complete: This config can be directly used to start the core, **not a truncated part of the config**. For fields like keys, use newly generated valid parameters that have not been actually used to fill in.
### For logs ### For logs
Please set the log level to debug and dnsLog to true first. Please set the log level to debug and dnsLog to true first.
@@ -46,42 +50,29 @@ body:
Provide the log of Xray-core, not the log output by the panel or other things. Provide the log of Xray-core, not the log output by the panel or other things.
### Finally ### Finally
After removing parts that do not affect reproduction, provide the actual running **complete** file, do not only provide inbound or outbound or a few lines of logs based on your own judgment. The specific content to be filled in each of the following text boxes needs to be placed between ```<details><pre><code>``` and ```</code></pre></details>```, like this
Put the content between the preset ```<details><pre><code>``` ```</code></pre></details>``` in the text box. ```
If the problem is very clear that only related to one end (such as core startup failure/crash after correctly writing the config according to the documents), N/A can be filled in for unnecessary areas below. <details><pre><code>
(config)
</code></pre></details>
```
- type: textarea - type: textarea
attributes: attributes:
label: Client config label: Client config
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Server config label: Server config
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Client log label: Client log
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Server log label: Server log
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true

View File

@@ -7,6 +7,8 @@ body:
description: |- description: |-
请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。 请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
options: options:
- label: 我读完了 issue 模板中的所有注释,确保填写符合要求。
required: true
- label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。 - label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
required: true required: true
- label: 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。 - label: 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。
@@ -38,6 +40,8 @@ body:
### 对于配置文件 ### 对于配置文件
请提供可以重现问题的配置文件,包括服务端和客户端。 请提供可以重现问题的配置文件,包括服务端和客户端。
不要直接在这里黏贴一大段导出的 config 文件。去掉无用的出入站、规则、选项,这可以帮助确定问题,如果你真的想得到帮助。 不要直接在这里黏贴一大段导出的 config 文件。去掉无用的出入站、规则、选项,这可以帮助确定问题,如果你真的想得到帮助。
在去掉不影响复现的部分后,提供实际运行的**完整**文件。
完整的含义:可以直接使用这个配置启动核心,**不是截取的部分配置**。对于密钥等参数使用重新生成未实际使用的有效参数填充。
### 对于日志 ### 对于日志
请先将日志等级设置为 debug, dnsLog 设置为true. 请先将日志等级设置为 debug, dnsLog 设置为true.
@@ -46,42 +50,29 @@ body:
提供 Xray-core 的日志,而不是面板或者别的东西输出的日志。 提供 Xray-core 的日志,而不是面板或者别的东西输出的日志。
### 最后 ### 最后
在去掉不影响复现的部分后,提供实际运行的**完整**文件,不要出于自己的判断只提供入站出站或者几行日志。 把下面的每格具体内容需要放在 ```<details><pre><code>``` 和 ```</code></pre></details>``` 中间,如
把内容放在文本框预置的 ```<details><pre><code>``` 和 ```</code></pre></details>``` 中间。 ```
如果问题十分明确只出现在某一端(如按文档正确编写配置后核心启动失败/崩溃)可以在下面不需要的项目填入N/A. <details><pre><code>
(config)
</code></pre></details>
```
- type: textarea - type: textarea
attributes: attributes:
label: 客户端配置 label: 客户端配置
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: 服务端配置 label: 服务端配置
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: 客户端日志 label: 客户端日志
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: 服务端日志 label: 服务端日志
value: |-
<details><pre><code>
</code></pre></details>
validations: validations:
required: true required: true

View File

@@ -44,6 +44,7 @@ type RoutingContext struct {
OutboundTag string `protobuf:"bytes,12,opt,name=OutboundTag,proto3" json:"OutboundTag,omitempty"` OutboundTag string `protobuf:"bytes,12,opt,name=OutboundTag,proto3" json:"OutboundTag,omitempty"`
LocalIPs [][]byte `protobuf:"bytes,13,rep,name=LocalIPs,proto3" json:"LocalIPs,omitempty"` LocalIPs [][]byte `protobuf:"bytes,13,rep,name=LocalIPs,proto3" json:"LocalIPs,omitempty"`
LocalPort uint32 `protobuf:"varint,14,opt,name=LocalPort,proto3" json:"LocalPort,omitempty"` LocalPort uint32 `protobuf:"varint,14,opt,name=LocalPort,proto3" json:"LocalPort,omitempty"`
VlessRoute uint32 `protobuf:"varint,15,opt,name=VlessRoute,proto3" json:"VlessRoute,omitempty"`
} }
func (x *RoutingContext) Reset() { func (x *RoutingContext) Reset() {
@@ -174,6 +175,13 @@ func (x *RoutingContext) GetLocalPort() uint32 {
return 0 return 0
} }
func (x *RoutingContext) GetVlessRoute() uint32 {
if x != nil {
return x.VlessRoute
}
return 0
}
// SubscribeRoutingStatsRequest subscribes to routing statistics channel if // SubscribeRoutingStatsRequest subscribes to routing statistics channel if
// opened by xray-core. // opened by xray-core.
// * FieldSelectors selects a subset of fields in routing statistics to return. // * FieldSelectors selects a subset of fields in routing statistics to return.
@@ -843,7 +851,7 @@ var file_app_router_command_command_proto_rawDesc = []byte{
0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, 0x65,
0x72, 0x69, 0x61, 0x6c, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75,
0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x49,
0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e, 0x0a, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e,
@@ -877,7 +885,9 @@ var file_app_router_command_command_proto_rawDesc = []byte{
0x6c, 0x49, 0x50, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x50, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x4c, 0x6f, 0x63, 0x61,
0x6c, 0x49, 0x50, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x6c, 0x49, 0x50, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72,
0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f,
0x72, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x6f, 0x75,
0x74, 0x65, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,

View File

@@ -27,6 +27,7 @@ message RoutingContext {
string OutboundTag = 12; string OutboundTag = 12;
repeated bytes LocalIPs = 13; repeated bytes LocalIPs = 13;
uint32 LocalPort = 14; uint32 LocalPort = 14;
uint32 VlessRoute = 15;
} }
// SubscribeRoutingStatsRequest subscribes to routing statistics channel if // SubscribeRoutingStatsRequest subscribes to routing statistics channel if

View File

@@ -36,6 +36,10 @@ func (c routingContext) GetLocalPort() net.Port {
return net.Port(c.RoutingContext.GetLocalPort()) return net.Port(c.RoutingContext.GetLocalPort())
} }
func (c routingContext) GetVlessRoute() net.Port {
return net.Port(c.RoutingContext.GetVlessRoute())
}
func (c routingContext) GetRuleTag() string { func (c routingContext) GetRuleTag() string {
return "" return ""
} }

View File

@@ -166,6 +166,8 @@ func (v *PortMatcher) Apply(ctx routing.Context) bool {
return v.port.Contains(ctx.GetSourcePort()) return v.port.Contains(ctx.GetSourcePort())
case "target": case "target":
return v.port.Contains(ctx.GetTargetPort()) return v.port.Contains(ctx.GetTargetPort())
case "vlessRoute":
return v.port.Contains(ctx.GetVlessRoute())
default: default:
panic("unreachable, asType should be local or source or target") panic("unreachable, asType should be local or source or target")
} }

View File

@@ -45,6 +45,10 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
conds.Add(NewUserMatcher(rr.UserEmail)) conds.Add(NewUserMatcher(rr.UserEmail))
} }
if rr.VlessRouteList != nil {
conds.Add(NewPortMatcher(rr.VlessRouteList, "vlessRoute"))
}
if len(rr.InboundTag) > 0 { if len(rr.InboundTag) > 0 {
conds.Add(NewInboundTagMatcher(rr.InboundTag)) conds.Add(NewInboundTagMatcher(rr.InboundTag))
} }

View File

@@ -493,6 +493,7 @@ type RoutingRule struct {
Attributes map[string]string `protobuf:"bytes,15,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Attributes map[string]string `protobuf:"bytes,15,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
LocalGeoip []*GeoIP `protobuf:"bytes,17,rep,name=local_geoip,json=localGeoip,proto3" json:"local_geoip,omitempty"` LocalGeoip []*GeoIP `protobuf:"bytes,17,rep,name=local_geoip,json=localGeoip,proto3" json:"local_geoip,omitempty"`
LocalPortList *net.PortList `protobuf:"bytes,18,opt,name=local_port_list,json=localPortList,proto3" json:"local_port_list,omitempty"` LocalPortList *net.PortList `protobuf:"bytes,18,opt,name=local_port_list,json=localPortList,proto3" json:"local_port_list,omitempty"`
VlessRouteList *net.PortList `protobuf:"bytes,20,opt,name=vless_route_list,json=vlessRouteList,proto3" json:"vless_route_list,omitempty"`
} }
func (x *RoutingRule) Reset() { func (x *RoutingRule) Reset() {
@@ -637,6 +638,13 @@ func (x *RoutingRule) GetLocalPortList() *net.PortList {
return nil return nil
} }
func (x *RoutingRule) GetVlessRouteList() *net.PortList {
if x != nil {
return x.VlessRouteList
}
return nil
}
type isRoutingRule_TargetTag interface { type isRoutingRule_TargetTag interface {
isRoutingRule_TargetTag() isRoutingRule_TargetTag()
} }
@@ -1077,7 +1085,7 @@ var file_app_router_config_proto_rawDesc = []byte{
0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74,
0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69,
0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xa3, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xe8, 0x06, 0x0a, 0x0b, 0x52, 0x6f,
0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a,
0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c,
@@ -1123,66 +1131,71 @@ var file_app_router_config_proto_rawDesc = []byte{
0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x69, 0x73, 0x74, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69,
0x73, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x10, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x6f, 0x75, 0x74,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x6f,
0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69,
0xdc, 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69,
0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20,
0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x4d, 0x0a, 0x11, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62,
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x73, 0x74, 0x72, 0x61, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x65, 0x67, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x79, 0x12, 0x4d, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x5f, 0x73, 0x65,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78,
0x09, 0x52, 0x0b, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x67, 0x22, 0x54, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61,
0x0a, 0x0e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10,
0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x61, 0x67,
0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x54, 0x61, 0x67, 0x22, 0x54, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57,
0x61, 0x6c, 0x75, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x18,
0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a,
0x12, 0x35, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61,
0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01,
0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x17, 0x53, 0x74,
0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43,
0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02,
0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57,
0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09,
0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52,
0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78,
0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78,
0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54,
0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c,
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x9b, 0x02, 0x0a,
0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67,
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03,
0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f,
0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75,
0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c,
0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74,
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66,
0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70,
0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61,
0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79,
0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
} }
var ( var (
@@ -1235,16 +1248,17 @@ var file_app_router_config_proto_depIdxs = []int32{
14, // 12: xray.app.router.RoutingRule.attributes:type_name -> xray.app.router.RoutingRule.AttributesEntry 14, // 12: xray.app.router.RoutingRule.attributes:type_name -> xray.app.router.RoutingRule.AttributesEntry
4, // 13: xray.app.router.RoutingRule.local_geoip:type_name -> xray.app.router.GeoIP 4, // 13: xray.app.router.RoutingRule.local_geoip:type_name -> xray.app.router.GeoIP
15, // 14: xray.app.router.RoutingRule.local_port_list:type_name -> xray.common.net.PortList 15, // 14: xray.app.router.RoutingRule.local_port_list:type_name -> xray.common.net.PortList
17, // 15: xray.app.router.BalancingRule.strategy_settings:type_name -> xray.common.serial.TypedMessage 15, // 15: xray.app.router.RoutingRule.vless_route_list:type_name -> xray.common.net.PortList
10, // 16: xray.app.router.StrategyLeastLoadConfig.costs:type_name -> xray.app.router.StrategyWeight 17, // 16: xray.app.router.BalancingRule.strategy_settings:type_name -> xray.common.serial.TypedMessage
1, // 17: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy 10, // 17: xray.app.router.StrategyLeastLoadConfig.costs:type_name -> xray.app.router.StrategyWeight
8, // 18: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule 1, // 18: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy
9, // 19: xray.app.router.Config.balancing_rule:type_name -> xray.app.router.BalancingRule 8, // 19: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule
20, // [20:20] is the sub-list for method output_type 9, // 20: xray.app.router.Config.balancing_rule:type_name -> xray.app.router.BalancingRule
20, // [20:20] is the sub-list for method input_type 21, // [21:21] is the sub-list for method output_type
20, // [20:20] is the sub-list for extension type_name 21, // [21:21] is the sub-list for method input_type
20, // [20:20] is the sub-list for extension extendee 21, // [21:21] is the sub-list for extension type_name
0, // [0:20] is the sub-list for field type_name 21, // [21:21] is the sub-list for extension extendee
0, // [0:21] is the sub-list for field type_name
} }
func init() { file_app_router_config_proto_init() } func init() { file_app_router_config_proto_init() }

View File

@@ -111,6 +111,8 @@ message RoutingRule {
repeated GeoIP local_geoip = 17; repeated GeoIP local_geoip = 17;
xray.common.net.PortList local_port_list = 18; xray.common.net.PortList local_port_list = 18;
xray.common.net.PortList vless_route_list = 20;
} }
message BalancingRule { message BalancingRule {

View File

@@ -118,9 +118,7 @@ func (w *ServerWorker) handleStatusKeepAlive(meta *FrameMetadata, reader *buf.Bu
} }
func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error { func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {
// deep-clone outbounds because it is going to be mutated concurrently ctx = session.SubContextFromMuxInbound(ctx)
// (Target and OriginalTarget)
ctx = session.ContextCloneOutboundsAndContent(ctx)
errors.LogInfo(ctx, "received request for ", meta.Target) errors.LogInfo(ctx, "received request for ", meta.Target)
{ {
msg := &log.AccessMessage{ msg := &log.AccessMessage{

View File

@@ -16,15 +16,15 @@ const (
inboundSessionKey ctx.SessionKey = 1 inboundSessionKey ctx.SessionKey = 1
outboundSessionKey ctx.SessionKey = 2 outboundSessionKey ctx.SessionKey = 2
contentSessionKey ctx.SessionKey = 3 contentSessionKey ctx.SessionKey = 3
muxPreferredSessionKey ctx.SessionKey = 4 muxPreferredSessionKey ctx.SessionKey = 4 // unused
sockoptSessionKey ctx.SessionKey = 5 sockoptSessionKey ctx.SessionKey = 5 // used by dokodemo to only receive sockopt.Mark
trackedConnectionErrorKey ctx.SessionKey = 6 trackedConnectionErrorKey ctx.SessionKey = 6 // used by observer to get outbound error
dispatcherKey ctx.SessionKey = 7 dispatcherKey ctx.SessionKey = 7 // used by ss2022 inbounds to get dispatcher
timeoutOnlyKey ctx.SessionKey = 8 timeoutOnlyKey ctx.SessionKey = 8 // mux context's child contexts to only cancel when its own traffic times out
allowedNetworkKey ctx.SessionKey = 9 allowedNetworkKey ctx.SessionKey = 9 // muxcool server control incoming request tcp/udp
handlerSessionKey ctx.SessionKey = 10 handlerSessionKey ctx.SessionKey = 10 // unused
mitmAlpn11Key ctx.SessionKey = 11 mitmAlpn11Key ctx.SessionKey = 11 // used by TLS dialer
mitmServerNameKey ctx.SessionKey = 12 mitmServerNameKey ctx.SessionKey = 12 // used by TLS dialer
) )
func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context { func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context {
@@ -42,18 +42,8 @@ func ContextWithOutbounds(ctx context.Context, outbounds []*Outbound) context.Co
return context.WithValue(ctx, outboundSessionKey, outbounds) return context.WithValue(ctx, outboundSessionKey, outbounds)
} }
func ContextCloneOutboundsAndContent(ctx context.Context) context.Context { func SubContextFromMuxInbound(ctx context.Context) context.Context {
outbounds := OutboundsFromContext(ctx) newOutbounds := []*Outbound{{}}
newOutbounds := make([]*Outbound, len(outbounds))
for i, ob := range outbounds {
if ob == nil {
continue
}
// copy outbound by value
v := *ob
newOutbounds[i] = &v
}
content := ContentFromContext(ctx) content := ContentFromContext(ctx)
newContent := Content{} newContent := Content{}

View File

@@ -46,9 +46,11 @@ type Inbound struct {
Name string Name string
// User is the user that authenticates for the inbound. May be nil if the protocol allows anonymous traffic. // User is the user that authenticates for the inbound. May be nil if the protocol allows anonymous traffic.
User *protocol.MemoryUser User *protocol.MemoryUser
// Conn is actually internet.Connection. May be nil. // VlessRoute is the user-sent VLESS UUID's 7th<<8 | 8th bytes.
VlessRoute net.Port
// Used by splice copy. Conn is actually internet.Connection. May be nil.
Conn net.Conn Conn net.Conn
// Timer of the inbound buf copier. May be nil. // Used by splice copy. Timer of the inbound buf copier. May be nil.
Timer *signal.ActivityTimer Timer *signal.ActivityTimer
// CanSpliceCopy is a property for this connection // CanSpliceCopy is a property for this connection
// 1 = can, 2 = after processing protocol info should be able to, 3 = cannot // 1 = can, 2 = after processing protocol info should be able to, 3 = cannot
@@ -67,31 +69,33 @@ type Outbound struct {
Tag string Tag string
// Name of the outbound proxy that handles the connection. // Name of the outbound proxy that handles the connection.
Name string Name string
// Conn is actually internet.Connection. May be nil. It is currently nil for outbound with proxySettings // Unused. Conn is actually internet.Connection. May be nil. It is currently nil for outbound with proxySettings
Conn net.Conn Conn net.Conn
// CanSpliceCopy is a property for this connection // CanSpliceCopy is a property for this connection
// 1 = can, 2 = after processing protocol info should be able to, 3 = cannot // 1 = can, 2 = after processing protocol info should be able to, 3 = cannot
CanSpliceCopy int CanSpliceCopy int
} }
// SniffingRequest controls the behavior of content sniffing. // SniffingRequest controls the behavior of content sniffing. They are from inbound config. Read-only
type SniffingRequest struct { type SniffingRequest struct {
ExcludeForDomain []string // read-only once set ExcludeForDomain []string
OverrideDestinationForProtocol []string // read-only once set OverrideDestinationForProtocol []string
Enabled bool Enabled bool
MetadataOnly bool MetadataOnly bool
RouteOnly bool RouteOnly bool
} }
// Content is the metadata of the connection content. // Content is the metadata of the connection content. Mainly used for routing.
type Content struct { type Content struct {
// Protocol of current content. // Protocol of current content.
Protocol string Protocol string
SniffingRequest SniffingRequest SniffingRequest SniffingRequest
// HTTP traffic sniffed headers
Attributes map[string]string Attributes map[string]string
// SkipDNSResolve is set from DNS module. the DOH remote server maybe a domain name, this prevents cycle resolving dead loop
SkipDNSResolve bool SkipDNSResolve bool
} }

View File

@@ -41,6 +41,9 @@ type Context interface {
// GetUser returns the user email from the connection content, if exists. // GetUser returns the user email from the connection content, if exists.
GetUser() string GetUser() string
// GetVlessRoute returns the user-sent VLESS UUID's 7th<<8 | 8th bytes, if exists.
GetVlessRoute() net.Port
// GetAttributes returns extra attributes from the conneciont content. // GetAttributes returns extra attributes from the conneciont content.
GetAttributes() map[string]string GetAttributes() map[string]string

View File

@@ -128,6 +128,14 @@ func (ctx *Context) GetUser() string {
return ctx.Inbound.User.Email return ctx.Inbound.User.Email
} }
// GetVlessRoute implements routing.Context.
func (ctx *Context) GetVlessRoute() net.Port {
if ctx.Inbound == nil {
return 0
}
return ctx.Inbound.VlessRoute
}
// GetAttributes implements routing.Context. // GetAttributes implements routing.Context.
func (ctx *Context) GetAttributes() map[string]string { func (ctx *Context) GetAttributes() map[string]string {
if ctx.Content == nil { if ctx.Content == nil {

View File

@@ -531,6 +531,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
Source *StringList `json:"source"` Source *StringList `json:"source"`
SourcePort *PortList `json:"sourcePort"` SourcePort *PortList `json:"sourcePort"`
User *StringList `json:"user"` User *StringList `json:"user"`
VlessRoute *PortList `json:"vlessRoute"`
InboundTag *StringList `json:"inboundTag"` InboundTag *StringList `json:"inboundTag"`
Protocols *StringList `json:"protocol"` Protocols *StringList `json:"protocol"`
Attributes map[string]string `json:"attrs"` Attributes map[string]string `json:"attrs"`
@@ -628,6 +629,10 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
} }
} }
if rawFieldRule.VlessRoute != nil {
rule.VlessRouteList = rawFieldRule.VlessRoute.Build()
}
if rawFieldRule.InboundTag != nil { if rawFieldRule.InboundTag != nil {
for _, s := range *rawFieldRule.InboundTag { for _, s := range *rawFieldRule.InboundTag {
rule.InboundTag = append(rule.InboundTag, s) rule.InboundTag = append(rule.InboundTag, s)

View File

@@ -95,6 +95,9 @@ func (s *Server) ProcessWithFirstbyte(ctx context.Context, network net.Network,
inbound.User = &protocol.MemoryUser{ inbound.User = &protocol.MemoryUser{
Level: s.config.UserLevel, Level: s.config.UserLevel,
} }
if isTransportConn(conn) {
inbound.CanSpliceCopy = 3
}
var reader *bufio.Reader var reader *bufio.Reader
if len(firstbyte) > 0 { if len(firstbyte) > 0 {
readerWithoutFirstbyte := bufio.NewReaderSize(readerOnly{conn}, buf.Size) readerWithoutFirstbyte := bufio.NewReaderSize(readerOnly{conn}, buf.Size)
@@ -207,7 +210,9 @@ func (s *Server) handleConnect(ctx context.Context, _ *http.Request, reader *buf
} }
responseDone := func() error { responseDone := func() error {
inbound.CanSpliceCopy = 1 if inbound.CanSpliceCopy == 2 {
inbound.CanSpliceCopy = 1
}
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly) defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
v2writer := buf.NewWriter(conn) v2writer := buf.NewWriter(conn)
@@ -370,6 +375,20 @@ func readResponseAndHandle100Continue(r *bufio.Reader, req *http.Request, writer
return http.ReadResponse(r, req) return http.ReadResponse(r, req)
} }
// isTransportConn return false if the conn is a raw tcp conn without transport or tls, can process splice copy
func isTransportConn(conn stat.Connection) bool {
if conn != nil {
statConn, ok := conn.(*stat.CounterConnection)
if ok {
conn = statConn.Connection
}
if _, ok := conn.(*net.TCPConn); ok {
return false
}
}
return true
}
func init() { func init() {
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewServer(ctx, config.(*ServerConfig)) return NewServer(ctx, config.(*ServerConfig))

View File

@@ -75,6 +75,9 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
inbound.User = &protocol.MemoryUser{ inbound.User = &protocol.MemoryUser{
Level: s.config.UserLevel, Level: s.config.UserLevel,
} }
if isTransportConn(conn) {
inbound.CanSpliceCopy = 3
}
switch network { switch network {
case net.Network_TCP: case net.Network_TCP:
@@ -199,7 +202,9 @@ func (s *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
} }
responseDone := func() error { responseDone := func() error {
inbound.CanSpliceCopy = 1 if inbound.CanSpliceCopy == 2 {
inbound.CanSpliceCopy = 1
}
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly) defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
v2writer := buf.NewWriter(writer) v2writer := buf.NewWriter(writer)
@@ -259,7 +264,9 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn stat.Connection, dis
if inbound != nil && inbound.Source.IsValid() { if inbound != nil && inbound.Source.IsValid() {
errors.LogInfo(ctx, "client UDP connection from ", inbound.Source) errors.LogInfo(ctx, "client UDP connection from ", inbound.Source)
} }
inbound.CanSpliceCopy = 1 if inbound.CanSpliceCopy == 2 {
inbound.CanSpliceCopy = 1
}
var dest *net.Destination var dest *net.Destination
@@ -308,6 +315,20 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn stat.Connection, dis
} }
} }
// isTransportConn return false if the conn is a raw tcp conn without transport or tls, can process splice copy
func isTransportConn(conn stat.Connection) bool {
if conn != nil {
statConn, ok := conn.(*stat.CounterConnection)
if ok {
conn = statConn.Connection
}
if _, ok := conn.(*net.TCPConn); ok {
return false
}
}
return true
}
func init() { func init() {
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewServer(ctx, config.(*ServerConfig)) return NewServer(ctx, config.(*ServerConfig))

View File

@@ -62,7 +62,7 @@ func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requ
} }
// DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream. // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.
func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) { func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator vless.Validator) ([]byte, *protocol.RequestHeader, *Addons, bool, error) {
buffer := buf.StackNew() buffer := buf.StackNew()
defer buffer.Release() defer buffer.Release()
@@ -72,7 +72,7 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat
request.Version = first.Byte(0) request.Version = first.Byte(0)
} else { } else {
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
return nil, nil, false, errors.New("failed to read request version").Base(err) return nil, nil, nil, false, errors.New("failed to read request version").Base(err)
} }
request.Version = buffer.Byte(0) request.Version = buffer.Byte(0)
} }
@@ -87,13 +87,13 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat
} else { } else {
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, 16); err != nil { if _, err := buffer.ReadFullFrom(reader, 16); err != nil {
return nil, nil, false, errors.New("failed to read request user id").Base(err) return nil, nil, nil, false, errors.New("failed to read request user id").Base(err)
} }
copy(id[:], buffer.Bytes()) copy(id[:], buffer.Bytes())
} }
if request.User = validator.Get(id); request.User == nil { if request.User = validator.Get(id); request.User == nil {
return nil, nil, isfb, errors.New("invalid request user id") return nil, nil, nil, isfb, errors.New("invalid request user id")
} }
if isfb { if isfb {
@@ -102,12 +102,12 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat
requestAddons, err := DecodeHeaderAddons(&buffer, reader) requestAddons, err := DecodeHeaderAddons(&buffer, reader)
if err != nil { if err != nil {
return nil, nil, false, errors.New("failed to decode request header addons").Base(err) return nil, nil, nil, false, errors.New("failed to decode request header addons").Base(err)
} }
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
return nil, nil, false, errors.New("failed to read request command").Base(err) return nil, nil, nil, false, errors.New("failed to read request command").Base(err)
} }
request.Command = protocol.RequestCommand(buffer.Byte(0)) request.Command = protocol.RequestCommand(buffer.Byte(0))
@@ -122,11 +122,11 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat
} }
} }
if request.Address == nil { if request.Address == nil {
return nil, nil, false, errors.New("invalid request address") return nil, nil, nil, false, errors.New("invalid request address")
} }
return request, requestAddons, false, nil return id[:], request, requestAddons, false, nil
default: default:
return nil, nil, isfb, errors.New("invalid request version") return nil, nil, nil, isfb, errors.New("invalid request version")
} }
} }

View File

@@ -45,7 +45,7 @@ func TestRequestSerialization(t *testing.T) {
Validator := new(vless.MemoryValidator) Validator := new(vless.MemoryValidator)
Validator.Add(user) Validator.Add(user)
actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) _, actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)
common.Must(err) common.Must(err)
if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" {
@@ -86,7 +86,7 @@ func TestInvalidRequest(t *testing.T) {
Validator := new(vless.MemoryValidator) Validator := new(vless.MemoryValidator)
Validator.Add(user) Validator.Add(user)
_, _, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) _, _, _, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)
if err == nil { if err == nil {
t.Error("nil error") t.Error("nil error")
} }
@@ -117,7 +117,7 @@ func TestMuxRequest(t *testing.T) {
Validator := new(vless.MemoryValidator) Validator := new(vless.MemoryValidator)
Validator.Add(user) Validator.Add(user)
actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) _, actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)
common.Must(err) common.Must(err)
if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" {

View File

@@ -217,6 +217,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
Buffer: buf.MultiBuffer{first}, Buffer: buf.MultiBuffer{first},
} }
var userSentID []byte // not MemoryAccount.ID
var request *protocol.RequestHeader var request *protocol.RequestHeader
var requestAddons *encoding.Addons var requestAddons *encoding.Addons
var err error var err error
@@ -227,7 +228,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
if isfb && firstLen < 18 { if isfb && firstLen < 18 {
err = errors.New("fallback directly") err = errors.New("fallback directly")
} else { } else {
request, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator) userSentID, request, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator)
} }
if err != nil { if err != nil {
@@ -455,6 +456,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
} }
inbound.Name = "vless" inbound.Name = "vless"
inbound.User = request.User inbound.User = request.User
inbound.VlessRoute = net.PortFromBytes(userSentID[6:8])
account := request.User.Account.(*vless.MemoryAccount) account := request.User.Account.(*vless.MemoryAccount)
@@ -530,7 +532,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
serverReader := link.Reader // .(*pipe.Reader) serverReader := link.Reader // .(*pipe.Reader)
serverWriter := link.Writer // .(*pipe.Writer) serverWriter := link.Writer // .(*pipe.Writer)
trafficState := proxy.NewTrafficState(account.ID.Bytes()) trafficState := proxy.NewTrafficState(userSentID)
postRequest := func() error { postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)

View File

@@ -18,6 +18,12 @@ type Validator interface {
GetCount() int64 GetCount() int64
} }
func ProcessUUID(id [16]byte) [16]byte {
id[6] = 0
id[7] = 0
return id
}
// MemoryValidator stores valid VLESS users. // MemoryValidator stores valid VLESS users.
type MemoryValidator struct { type MemoryValidator struct {
// Considering email's usage here, map + sync.Mutex/RWMutex may have better performance. // Considering email's usage here, map + sync.Mutex/RWMutex may have better performance.
@@ -33,7 +39,7 @@ func (v *MemoryValidator) Add(u *protocol.MemoryUser) error {
return errors.New("User ", u.Email, " already exists.") return errors.New("User ", u.Email, " already exists.")
} }
} }
v.users.Store(u.Account.(*MemoryAccount).ID.UUID(), u) v.users.Store(ProcessUUID(u.Account.(*MemoryAccount).ID.UUID()), u)
return nil return nil
} }
@@ -48,13 +54,13 @@ func (v *MemoryValidator) Del(e string) error {
return errors.New("User ", e, " not found.") return errors.New("User ", e, " not found.")
} }
v.email.Delete(le) v.email.Delete(le)
v.users.Delete(u.(*protocol.MemoryUser).Account.(*MemoryAccount).ID.UUID()) v.users.Delete(ProcessUUID(u.(*protocol.MemoryUser).Account.(*MemoryAccount).ID.UUID()))
return nil return nil
} }
// Get a VLESS user with UUID, nil if user doesn't exist. // Get a VLESS user with UUID, nil if user doesn't exist.
func (v *MemoryValidator) Get(id uuid.UUID) *protocol.MemoryUser { func (v *MemoryValidator) Get(id uuid.UUID) *protocol.MemoryUser {
u, _ := v.users.Load(id) u, _ := v.users.Load(ProcessUUID(id))
if u != nil { if u != nil {
return u.(*protocol.MemoryUser) return u.(*protocol.MemoryUser)
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
c "github.com/xtls/xray-core/common/ctx"
"github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
@@ -33,7 +34,6 @@ type routingInfo struct {
ctx context.Context ctx context.Context
dispatcher routing.Dispatcher dispatcher routing.Dispatcher
inboundTag *session.Inbound inboundTag *session.Inbound
outboundTag *session.Outbound
contentTag *session.Content contentTag *session.Content
} }
@@ -78,18 +78,11 @@ func (*Server) Network() []net.Network {
// Process implements proxy.Inbound. // Process implements proxy.Inbound.
func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error { func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error {
inbound := session.InboundFromContext(ctx)
inbound.Name = "wireguard"
inbound.CanSpliceCopy = 3
outbounds := session.OutboundsFromContext(ctx)
ob := outbounds[len(outbounds)-1]
s.info = routingInfo{ s.info = routingInfo{
ctx: core.ToBackgroundDetachedContext(ctx), ctx: ctx,
dispatcher: dispatcher, dispatcher: dispatcher,
inboundTag: session.InboundFromContext(ctx), inboundTag: session.InboundFromContext(ctx),
outboundTag: ob, contentTag: session.ContentFromContext(ctx),
contentTag: session.ContentFromContext(ctx),
} }
ep, err := s.bindServer.ParseEndpoint(conn.RemoteAddr().String()) ep, err := s.bindServer.ParseEndpoint(conn.RemoteAddr().String())
@@ -134,6 +127,25 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) {
defer conn.Close() defer conn.Close()
ctx, cancel := context.WithCancel(core.ToBackgroundDetachedContext(s.info.ctx)) ctx, cancel := context.WithCancel(core.ToBackgroundDetachedContext(s.info.ctx))
sid := session.NewID()
ctx = c.ContextWithID(ctx, sid)
inbound := session.Inbound{} // since promiscuousModeHandler mixed-up context, we shallow copy inbound (tag) and content (configs)
if s.info.inboundTag != nil {
inbound = *s.info.inboundTag
}
inbound.Name = "wireguard"
inbound.CanSpliceCopy = 3
// overwrite the source to use the tun address for each sub context.
// Since gvisor.ForwarderRequest doesn't provide any info to associate the sub-context with the Parent context
// Currently we have no way to link to the original source address
inbound.Source = net.DestinationFromAddr(conn.RemoteAddr())
ctx = session.ContextWithInbound(ctx, &inbound)
if s.info.contentTag != nil {
ctx = session.ContextWithContent(ctx, s.info.contentTag)
}
ctx = session.SubContextFromMuxInbound(ctx)
plcy := s.policyManager.ForLevel(0) plcy := s.policyManager.ForLevel(0)
timer := signal.CancelAfterInactivity(ctx, cancel, plcy.Timeouts.ConnectionIdle) timer := signal.CancelAfterInactivity(ctx, cancel, plcy.Timeouts.ConnectionIdle)
@@ -144,25 +156,9 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) {
Reason: "", Reason: "",
}) })
if s.info.inboundTag != nil {
ctx = session.ContextWithInbound(ctx, s.info.inboundTag)
}
// what's this?
// Session information should not be shared between different connections
// why reuse them in server level? This will cause incorrect destoverride and unexpected routing behavior.
// Disable it temporarily. Maybe s.info should be removed.
// if s.info.outboundTag != nil {
// ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{s.info.outboundTag})
// }
// if s.info.contentTag != nil {
// ctx = session.ContextWithContent(ctx, s.info.contentTag)
// }
link, err := s.info.dispatcher.Dispatch(ctx, dest) link, err := s.info.dispatcher.Dispatch(ctx, dest)
if err != nil { if err != nil {
errors.LogErrorInner(s.info.ctx, err, "dispatch connection") errors.LogErrorInner(ctx, err, "dispatch connection")
} }
defer cancel() defer cancel()
@@ -188,7 +184,7 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) {
if err := task.Run(ctx, requestDonePost, responseDone); err != nil { if err := task.Run(ctx, requestDonePost, responseDone); err != nil {
common.Interrupt(link.Reader) common.Interrupt(link.Reader)
common.Interrupt(link.Writer) common.Interrupt(link.Writer)
errors.LogDebugInner(s.info.ctx, err, "connection ends") errors.LogDebugInner(ctx, err, "connection ends")
return return
} }
} }