This commit is contained in:
LjhAUMEM 2026-06-27 16:44:28 +05:00 committed by GitHub
commit c14465f7ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 233 additions and 1 deletions

View file

@ -3,6 +3,7 @@ package conf
import (
"context"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/json"
"math"
@ -22,6 +23,7 @@ import (
"github.com/xtls/xray-core/common/platform/filesystem"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/finalmask/brutal"
"github.com/xtls/xray-core/transport/internet/finalmask/fragment"
"github.com/xtls/xray-core/transport/internet/finalmask/header/custom"
"github.com/xtls/xray-core/transport/internet/finalmask/mkcp/aes128gcm"
@ -1245,6 +1247,7 @@ var (
customVarNamePattern = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
tcpmaskLoader = NewJSONConfigLoader(ConfigCreatorCache{
"force-brutal": func() interface{} { return new(Brutal) },
"header-custom": func() interface{} { return new(HeaderCustomTCP) },
"fragment": func() interface{} { return new(FragmentMask) },
"sudoku": func() interface{} { return new(Sudoku) },
@ -1262,6 +1265,34 @@ var (
}, "type", "settings")
)
type Brutal struct {
Rate uint64 `json:"rate"`
Cwnd uint32 `json:"cwnd"`
}
func (c *Brutal) Build() (proto.Message, error) {
rate := c.Rate
cwnd := c.Cwnd
if rate == 0 {
rate = 125000
}
if cwnd == 0 {
cwnd = 20
}
if rate < 62500 {
return nil, errors.New("invalid rate ", rate)
}
if cwnd < 5 || cwnd > 80 {
return nil, errors.New("invalid cwnd ", cwnd)
}
params := make([]byte, 16)
binary.NativeEndian.PutUint64(params, rate)
binary.NativeEndian.PutUint32(params[8:], cwnd)
return &brutal.Config{
Params: params,
}, nil
}
type TCPItem struct {
Delay Int32Range `json:"delay"`
Rand int32 `json:"rand"`

View file

@ -0,0 +1,13 @@
package brutal
import "net"
func (c *Config) TCP() {}
func (c *Config) WrapConnClient(raw net.Conn) (net.Conn, error) {
return NewConn(c, raw)
}
func (c *Config) WrapConnServer(raw net.Conn) (net.Conn, error) {
return NewConn(c, raw)
}

View file

@ -0,0 +1,123 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v6.33.5
// source: transport/internet/finalmask/brutal/config.proto
package brutal
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 Config struct {
state protoimpl.MessageState `protogen:"open.v1"`
Params []byte `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Config) Reset() {
*x = Config{}
mi := &file_transport_internet_finalmask_brutal_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_transport_internet_finalmask_brutal_config_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
return file_transport_internet_finalmask_brutal_config_proto_rawDescGZIP(), []int{0}
}
func (x *Config) GetParams() []byte {
if x != nil {
return x.Params
}
return nil
}
var File_transport_internet_finalmask_brutal_config_proto protoreflect.FileDescriptor
const file_transport_internet_finalmask_brutal_config_proto_rawDesc = "" +
"\n" +
"0transport/internet/finalmask/brutal/config.proto\x12(xray.transport.internet.finalmask.brutal\" \n" +
"\x06Config\x12\x16\n" +
"\x06params\x18\x01 \x01(\fR\x06paramsB\x9a\x01\n" +
",com.xray.transport.internet.finalmask.brutalP\x01Z=github.com/xtls/xray-core/transport/internet/finalmask/brutal\xaa\x02(Xray.Transport.Internet.Finalmask.Brutalb\x06proto3"
var (
file_transport_internet_finalmask_brutal_config_proto_rawDescOnce sync.Once
file_transport_internet_finalmask_brutal_config_proto_rawDescData []byte
)
func file_transport_internet_finalmask_brutal_config_proto_rawDescGZIP() []byte {
file_transport_internet_finalmask_brutal_config_proto_rawDescOnce.Do(func() {
file_transport_internet_finalmask_brutal_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_brutal_config_proto_rawDesc), len(file_transport_internet_finalmask_brutal_config_proto_rawDesc)))
})
return file_transport_internet_finalmask_brutal_config_proto_rawDescData
}
var file_transport_internet_finalmask_brutal_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_transport_internet_finalmask_brutal_config_proto_goTypes = []any{
(*Config)(nil), // 0: xray.transport.internet.finalmask.brutal.Config
}
var file_transport_internet_finalmask_brutal_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_internet_finalmask_brutal_config_proto_init() }
func file_transport_internet_finalmask_brutal_config_proto_init() {
if File_transport_internet_finalmask_brutal_config_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_brutal_config_proto_rawDesc), len(file_transport_internet_finalmask_brutal_config_proto_rawDesc)),
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_transport_internet_finalmask_brutal_config_proto_goTypes,
DependencyIndexes: file_transport_internet_finalmask_brutal_config_proto_depIdxs,
MessageInfos: file_transport_internet_finalmask_brutal_config_proto_msgTypes,
}.Build()
File_transport_internet_finalmask_brutal_config_proto = out.File
file_transport_internet_finalmask_brutal_config_proto_goTypes = nil
file_transport_internet_finalmask_brutal_config_proto_depIdxs = nil
}

View file

@ -0,0 +1,11 @@
syntax = "proto3";
package xray.transport.internet.finalmask.brutal;
option csharp_namespace = "Xray.Transport.Internet.Finalmask.Brutal";
option go_package = "github.com/xtls/xray-core/transport/internet/finalmask/brutal";
option java_package = "com.xray.transport.internet.finalmask.brutal";
option java_multiple_files = true;
message Config {
bytes params = 1;
}

View file

@ -0,0 +1,15 @@
//go:build !linux
package brutal
import (
"context"
"net"
"github.com/xtls/xray-core/common/errors"
)
func NewConn(c *Config, raw net.Conn) (net.Conn, error) {
errors.LogError(context.Background(), "unsupported system")
return raw, nil
}

View file

@ -0,0 +1,39 @@
//go:build linux
package brutal
import (
"context"
"net"
"reflect"
"github.com/pires/go-proxyproto"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"golang.org/x/sys/unix"
)
func NewConn(c *Config, raw net.Conn) (net.Conn, error) {
conn := raw
if pc, ok := conn.(*proxyproto.Conn); ok {
conn = pc.Raw()
}
if _, ok := conn.(*net.TCPConn); !ok {
errors.LogError(context.Background(), "unsupported conn ", reflect.TypeOf(conn))
}
sysConn := common.Must2(conn.(*net.TCPConn).SyscallConn())
err := sysConn.Control(func(fd uintptr) {
if err := unix.SetsockoptString(int(fd), unix.IPPROTO_TCP, unix.TCP_CONGESTION, "brutal"); err != nil {
errors.LogErrorInner(context.Background(), err, "failed to set congestion")
return
}
if err := unix.SetsockoptString(int(fd), unix.IPPROTO_TCP, 23301, string(c.Params)); err != nil {
errors.LogErrorInner(context.Background(), err, "failed to set params")
return
}
})
if err != nil {
errors.LogErrorInner(context.Background(), err, "failed to control connection")
}
return raw, nil
}

View file

@ -257,7 +257,7 @@ func (l *tcpListener) Accept() (net.Conn, error) {
newConn, err := l.m.WrapConnServer(conn)
if err != nil {
errors.LogDebugInner(context.Background(), err, "mask err")
errors.LogErrorInner(context.Background(), err, "[mask] failed to wrap connection")
_ = conn.Close()
return nil, err
}