mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-15 09:28:45 +00:00
Finalmask: Add header-custom (TCP & UDP), fragment (TCP), noise (UDP); Support dialer-proxy, XHTTP/3; Fix XDNS, XICMP potential panic (#5657)
https://github.com/XTLS/Xray-core/pull/5657#issuecomment-4016609446
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package noise
|
||||
|
||||
import "net"
|
||||
|
||||
func (c *Config) UDP() {
|
||||
}
|
||||
|
||||
func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v6.33.5
|
||||
// source: transport/internet/finalmask/noise/config.proto
|
||||
|
||||
package noise
|
||||
|
||||
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 Item struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
RandMin int64 `protobuf:"varint,1,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
|
||||
RandMax int64 `protobuf:"varint,2,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,3,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
DelayMin int64 `protobuf:"varint,4,opt,name=delay_min,json=delayMin,proto3" json:"delay_min,omitempty"`
|
||||
DelayMax int64 `protobuf:"varint,5,opt,name=delay_max,json=delayMax,proto3" json:"delay_max,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Item) Reset() {
|
||||
*x = Item{}
|
||||
mi := &file_transport_internet_finalmask_noise_config_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Item) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Item) ProtoMessage() {}
|
||||
|
||||
func (x *Item) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_transport_internet_finalmask_noise_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 Item.ProtoReflect.Descriptor instead.
|
||||
func (*Item) Descriptor() ([]byte, []int) {
|
||||
return file_transport_internet_finalmask_noise_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Item) GetRandMin() int64 {
|
||||
if x != nil {
|
||||
return x.RandMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Item) GetRandMax() int64 {
|
||||
if x != nil {
|
||||
return x.RandMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Item) GetPacket() []byte {
|
||||
if x != nil {
|
||||
return x.Packet
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Item) GetDelayMin() int64 {
|
||||
if x != nil {
|
||||
return x.DelayMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Item) GetDelayMax() int64 {
|
||||
if x != nil {
|
||||
return x.DelayMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ResetMin int64 `protobuf:"varint,1,opt,name=reset_min,json=resetMin,proto3" json:"reset_min,omitempty"`
|
||||
ResetMax int64 `protobuf:"varint,2,opt,name=reset_max,json=resetMax,proto3" json:"reset_max,omitempty"`
|
||||
Items []*Item `protobuf:"bytes,3,rep,name=items,proto3" json:"items,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
*x = Config{}
|
||||
mi := &file_transport_internet_finalmask_noise_config_proto_msgTypes[1]
|
||||
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_noise_config_proto_msgTypes[1]
|
||||
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_noise_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Config) GetResetMin() int64 {
|
||||
if x != nil {
|
||||
return x.ResetMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetResetMax() int64 {
|
||||
if x != nil {
|
||||
return x.ResetMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetItems() []*Item {
|
||||
if x != nil {
|
||||
return x.Items
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_transport_internet_finalmask_noise_config_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_transport_internet_finalmask_noise_config_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"/transport/internet/finalmask/noise/config.proto\x12'xray.transport.internet.finalmask.noise\"\x8e\x01\n" +
|
||||
"\x04Item\x12\x19\n" +
|
||||
"\brand_min\x18\x01 \x01(\x03R\arandMin\x12\x19\n" +
|
||||
"\brand_max\x18\x02 \x01(\x03R\arandMax\x12\x16\n" +
|
||||
"\x06packet\x18\x03 \x01(\fR\x06packet\x12\x1b\n" +
|
||||
"\tdelay_min\x18\x04 \x01(\x03R\bdelayMin\x12\x1b\n" +
|
||||
"\tdelay_max\x18\x05 \x01(\x03R\bdelayMax\"\x87\x01\n" +
|
||||
"\x06Config\x12\x1b\n" +
|
||||
"\treset_min\x18\x01 \x01(\x03R\bresetMin\x12\x1b\n" +
|
||||
"\treset_max\x18\x02 \x01(\x03R\bresetMax\x12C\n" +
|
||||
"\x05items\x18\x03 \x03(\v2-.xray.transport.internet.finalmask.noise.ItemR\x05itemsB\x97\x01\n" +
|
||||
"+com.xray.transport.internet.finalmask.noiseP\x01Z<github.com/xtls/xray-core/transport/internet/finalmask/noise\xaa\x02'Xray.Transport.Internet.Finalmask.Noiseb\x06proto3"
|
||||
|
||||
var (
|
||||
file_transport_internet_finalmask_noise_config_proto_rawDescOnce sync.Once
|
||||
file_transport_internet_finalmask_noise_config_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_transport_internet_finalmask_noise_config_proto_rawDescGZIP() []byte {
|
||||
file_transport_internet_finalmask_noise_config_proto_rawDescOnce.Do(func() {
|
||||
file_transport_internet_finalmask_noise_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_noise_config_proto_rawDesc), len(file_transport_internet_finalmask_noise_config_proto_rawDesc)))
|
||||
})
|
||||
return file_transport_internet_finalmask_noise_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_transport_internet_finalmask_noise_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_transport_internet_finalmask_noise_config_proto_goTypes = []any{
|
||||
(*Item)(nil), // 0: xray.transport.internet.finalmask.noise.Item
|
||||
(*Config)(nil), // 1: xray.transport.internet.finalmask.noise.Config
|
||||
}
|
||||
var file_transport_internet_finalmask_noise_config_proto_depIdxs = []int32{
|
||||
0, // 0: xray.transport.internet.finalmask.noise.Config.items:type_name -> xray.transport.internet.finalmask.noise.Item
|
||||
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
|
||||
}
|
||||
|
||||
func init() { file_transport_internet_finalmask_noise_config_proto_init() }
|
||||
func file_transport_internet_finalmask_noise_config_proto_init() {
|
||||
if File_transport_internet_finalmask_noise_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_noise_config_proto_rawDesc), len(file_transport_internet_finalmask_noise_config_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_transport_internet_finalmask_noise_config_proto_goTypes,
|
||||
DependencyIndexes: file_transport_internet_finalmask_noise_config_proto_depIdxs,
|
||||
MessageInfos: file_transport_internet_finalmask_noise_config_proto_msgTypes,
|
||||
}.Build()
|
||||
File_transport_internet_finalmask_noise_config_proto = out.File
|
||||
file_transport_internet_finalmask_noise_config_proto_goTypes = nil
|
||||
file_transport_internet_finalmask_noise_config_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package xray.transport.internet.finalmask.noise;
|
||||
option csharp_namespace = "Xray.Transport.Internet.Finalmask.Noise";
|
||||
option go_package = "github.com/xtls/xray-core/transport/internet/finalmask/noise";
|
||||
option java_package = "com.xray.transport.internet.finalmask.noise";
|
||||
option java_multiple_files = true;
|
||||
|
||||
message Item {
|
||||
int64 rand_min = 1;
|
||||
int64 rand_max = 2;
|
||||
bytes packet = 3;
|
||||
int64 delay_min = 4;
|
||||
int64 delay_max = 5;
|
||||
}
|
||||
|
||||
message Config {
|
||||
int64 reset_min = 1;
|
||||
int64 reset_max = 2;
|
||||
repeated Item items = 3;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package noise
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/crypto"
|
||||
)
|
||||
|
||||
type noiseConn struct {
|
||||
net.PacketConn
|
||||
config *Config
|
||||
m map[string]time.Time
|
||||
stop chan struct{}
|
||||
once sync.Once
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewConnClient(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
conn := &noiseConn{
|
||||
PacketConn: raw,
|
||||
config: c,
|
||||
m: make(map[string]time.Time),
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
|
||||
if conn.config.ResetMax > 0 {
|
||||
go conn.reset()
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *noiseConn) reset() {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
c.mutex.RLock()
|
||||
now := time.Now()
|
||||
timeOut := make([]string, 0, len(c.m))
|
||||
for key, last := range c.m {
|
||||
if now.After(last) {
|
||||
timeOut = append(timeOut, key)
|
||||
}
|
||||
}
|
||||
c.mutex.RUnlock()
|
||||
|
||||
for _, key := range timeOut {
|
||||
c.mutex.Lock()
|
||||
delete(c.m, key)
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
case <-c.stop:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *noiseConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
c.mutex.RLock()
|
||||
_, ready := c.m[addr.String()]
|
||||
c.mutex.RUnlock()
|
||||
|
||||
if !ready {
|
||||
c.mutex.Lock()
|
||||
_, ready = c.m[addr.String()]
|
||||
if !ready {
|
||||
for _, item := range c.config.Items {
|
||||
if item.RandMax > 0 {
|
||||
item.Packet = make([]byte, crypto.RandBetween(item.RandMin, item.RandMax))
|
||||
common.Must2(rand.Read(item.Packet))
|
||||
}
|
||||
c.PacketConn.WriteTo(item.Packet, addr)
|
||||
time.Sleep(time.Duration(crypto.RandBetween(item.DelayMin, item.DelayMax)) * time.Millisecond)
|
||||
}
|
||||
c.m[addr.String()] = time.Now().Add(time.Duration(crypto.RandBetween(c.config.ResetMin, c.config.ResetMax)) * time.Second)
|
||||
}
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
return c.PacketConn.WriteTo(p, addr)
|
||||
}
|
||||
|
||||
func (c *noiseConn) Close() error {
|
||||
c.once.Do(func() {
|
||||
close(c.stop)
|
||||
})
|
||||
return c.PacketConn.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user