VLESS Reverse Proxy: Add "sniffing" to outbound's "reverse" (which is actually an inbound) (#5837)

Closes https://github.com/XTLS/Xray-core/issues/5662

---------

Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
This commit is contained in:
Copilot
2026-03-23 09:49:32 +00:00
committed by GitHub
parent d8a8629a14
commit 755f0a1d12
5 changed files with 84 additions and 27 deletions

View File

@@ -7,6 +7,7 @@
package vless
import (
proxyman "github.com/xtls/xray-core/app/proxyman"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@@ -22,8 +23,9 @@ const (
)
type Reverse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
Sniffing *proxyman.SniffingConfig `protobuf:"bytes,2,opt,name=sniffing,proto3" json:"sniffing,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -65,6 +67,13 @@ func (x *Reverse) GetTag() string {
return ""
}
func (x *Reverse) GetSniffing() *proxyman.SniffingConfig {
if x != nil {
return x.Sniffing
}
return nil
}
type Account struct {
state protoimpl.MessageState `protogen:"open.v1"`
// ID of the account, in the form of a UUID, e.g., "66ad4540-b58c-4ad2-9926-ea63445a9b57".
@@ -179,9 +188,10 @@ var File_proxy_vless_account_proto protoreflect.FileDescriptor
const file_proxy_vless_account_proto_rawDesc = "" +
"\n" +
"\x19proxy/vless/account.proto\x12\x10xray.proxy.vless\"\x1b\n" +
"\x19proxy/vless/account.proto\x12\x10xray.proxy.vless\x1a\x19app/proxyman/config.proto\"Z\n" +
"\aReverse\x12\x10\n" +
"\x03tag\x18\x01 \x01(\tR\x03tag\"\x86\x02\n" +
"\x03tag\x18\x01 \x01(\tR\x03tag\x12=\n" +
"\bsniffing\x18\x02 \x01(\v2!.xray.app.proxyman.SniffingConfigR\bsniffing\"\x86\x02\n" +
"\aAccount\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
"\x04flow\x18\x02 \x01(\tR\x04flow\x12\x1e\n" +
@@ -210,16 +220,18 @@ func file_proxy_vless_account_proto_rawDescGZIP() []byte {
var file_proxy_vless_account_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proxy_vless_account_proto_goTypes = []any{
(*Reverse)(nil), // 0: xray.proxy.vless.Reverse
(*Account)(nil), // 1: xray.proxy.vless.Account
(*Reverse)(nil), // 0: xray.proxy.vless.Reverse
(*Account)(nil), // 1: xray.proxy.vless.Account
(*proxyman.SniffingConfig)(nil), // 2: xray.app.proxyman.SniffingConfig
}
var file_proxy_vless_account_proto_depIdxs = []int32{
0, // 0: xray.proxy.vless.Account.reverse:type_name -> xray.proxy.vless.Reverse
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
2, // 0: xray.proxy.vless.Reverse.sniffing:type_name -> xray.app.proxyman.SniffingConfig
0, // 1: xray.proxy.vless.Account.reverse:type_name -> xray.proxy.vless.Reverse
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proxy_vless_account_proto_init() }

View File

@@ -6,8 +6,11 @@ option go_package = "github.com/xtls/xray-core/proxy/vless";
option java_package = "com.xray.proxy.vless";
option java_multiple_files = true;
import "app/proxyman/config.proto";
message Reverse {
string tag = 1;
xray.app.proxyman.SniffingConfig sniffing = 2;
}
message Account {

View File

@@ -97,14 +97,26 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
}
if a.Reverse != nil {
rvsCtx := session.ContextWithInbound(ctx, &session.Inbound{
Tag: a.Reverse.Tag,
User: handler.server.User, // TODO: email
})
if sc := a.Reverse.Sniffing; sc != nil && sc.Enabled {
rvsCtx = session.ContextWithContent(rvsCtx, &session.Content{
SniffingRequest: session.SniffingRequest{
Enabled: sc.Enabled,
OverrideDestinationForProtocol: sc.DestinationOverride,
ExcludeForDomain: sc.DomainsExcluded,
MetadataOnly: sc.MetadataOnly,
RouteOnly: sc.RouteOnly,
},
})
}
handler.reverse = &Reverse{
tag: a.Reverse.Tag,
dispatcher: v.GetFeature(routing.DispatcherType()).(routing.Dispatcher),
ctx: session.ContextWithInbound(ctx, &session.Inbound{
Tag: a.Reverse.Tag,
User: handler.server.User, // TODO: email
}),
handler: handler,
ctx: rvsCtx,
handler: handler,
}
handler.reverse.monitorTask = &task.Periodic{
Execute: handler.reverse.monitor,