mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-02 17:58:46 +00:00
Finalmask: Refactor header conns to avoid multiple-copy; Add randRange to "header-custom" (TCP & UDP) (#5812)
https://github.com/XTLS/Xray-core/pull/5657#issuecomment-4016760602 https://github.com/XTLS/Xray-core/pull/5657#issuecomment-4052921628
This commit is contained in:
@@ -25,3 +25,6 @@ func (c *UDPConfig) WrapPacketConnClient(raw net.PacketConn, level int, levelCou
|
||||
func (c *UDPConfig) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServerUDP(c, raw)
|
||||
}
|
||||
|
||||
func (c *UDPConfig) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ type TCPItem struct {
|
||||
DelayMin int64 `protobuf:"varint,1,opt,name=delay_min,json=delayMin,proto3" json:"delay_min,omitempty"`
|
||||
DelayMax int64 `protobuf:"varint,2,opt,name=delay_max,json=delayMax,proto3" json:"delay_max,omitempty"`
|
||||
Rand int32 `protobuf:"varint,3,opt,name=rand,proto3" json:"rand,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,4,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
RandMin int32 `protobuf:"varint,4,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
|
||||
RandMax int32 `protobuf:"varint,5,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,6,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -82,6 +84,20 @@ func (x *TCPItem) GetRand() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetRandMin() int32 {
|
||||
if x != nil {
|
||||
return x.RandMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetRandMax() int32 {
|
||||
if x != nil {
|
||||
return x.RandMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetPacket() []byte {
|
||||
if x != nil {
|
||||
return x.Packet
|
||||
@@ -196,7 +212,9 @@ func (x *TCPConfig) GetErrors() []*TCPSequence {
|
||||
type UDPItem struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Rand int32 `protobuf:"varint,1,opt,name=rand,proto3" json:"rand,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,2,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
RandMin int32 `protobuf:"varint,2,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
|
||||
RandMax int32 `protobuf:"varint,3,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,4,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -238,6 +256,20 @@ func (x *UDPItem) GetRand() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetRandMin() int32 {
|
||||
if x != nil {
|
||||
return x.RandMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetRandMax() int32 {
|
||||
if x != nil {
|
||||
return x.RandMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetPacket() []byte {
|
||||
if x != nil {
|
||||
return x.Packet
|
||||
@@ -301,21 +333,25 @@ var File_transport_internet_finalmask_header_custom_config_proto protoreflect.Fi
|
||||
|
||||
const file_transport_internet_finalmask_header_custom_config_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"7transport/internet/finalmask/header/custom/config.proto\x12/xray.transport.internet.finalmask.header.custom\"o\n" +
|
||||
"7transport/internet/finalmask/header/custom/config.proto\x12/xray.transport.internet.finalmask.header.custom\"\xa5\x01\n" +
|
||||
"\aTCPItem\x12\x1b\n" +
|
||||
"\tdelay_min\x18\x01 \x01(\x03R\bdelayMin\x12\x1b\n" +
|
||||
"\tdelay_max\x18\x02 \x01(\x03R\bdelayMax\x12\x12\n" +
|
||||
"\x04rand\x18\x03 \x01(\x05R\x04rand\x12\x16\n" +
|
||||
"\x06packet\x18\x04 \x01(\fR\x06packet\"c\n" +
|
||||
"\x04rand\x18\x03 \x01(\x05R\x04rand\x12\x19\n" +
|
||||
"\brand_min\x18\x04 \x01(\x05R\arandMin\x12\x19\n" +
|
||||
"\brand_max\x18\x05 \x01(\x05R\arandMax\x12\x16\n" +
|
||||
"\x06packet\x18\x06 \x01(\fR\x06packet\"c\n" +
|
||||
"\vTCPSequence\x12T\n" +
|
||||
"\bsequence\x18\x01 \x03(\v28.xray.transport.internet.finalmask.header.custom.TCPItemR\bsequence\"\x91\x02\n" +
|
||||
"\tTCPConfig\x12V\n" +
|
||||
"\aclients\x18\x01 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\aclients\x12V\n" +
|
||||
"\aservers\x18\x02 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\aservers\x12T\n" +
|
||||
"\x06errors\x18\x03 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\x06errors\"5\n" +
|
||||
"\x06errors\x18\x03 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\x06errors\"k\n" +
|
||||
"\aUDPItem\x12\x12\n" +
|
||||
"\x04rand\x18\x01 \x01(\x05R\x04rand\x12\x16\n" +
|
||||
"\x06packet\x18\x02 \x01(\fR\x06packet\"\xaf\x01\n" +
|
||||
"\x04rand\x18\x01 \x01(\x05R\x04rand\x12\x19\n" +
|
||||
"\brand_min\x18\x02 \x01(\x05R\arandMin\x12\x19\n" +
|
||||
"\brand_max\x18\x03 \x01(\x05R\arandMax\x12\x16\n" +
|
||||
"\x06packet\x18\x04 \x01(\fR\x06packet\"\xaf\x01\n" +
|
||||
"\tUDPConfig\x12P\n" +
|
||||
"\x06client\x18\x01 \x03(\v28.xray.transport.internet.finalmask.header.custom.UDPItemR\x06client\x12P\n" +
|
||||
"\x06server\x18\x02 \x03(\v28.xray.transport.internet.finalmask.header.custom.UDPItemR\x06serverB\xaf\x01\n" +
|
||||
|
||||
@@ -10,7 +10,9 @@ message TCPItem {
|
||||
int64 delay_min = 1;
|
||||
int64 delay_max = 2;
|
||||
int32 rand = 3;
|
||||
bytes packet = 4;
|
||||
int32 rand_min = 4;
|
||||
int32 rand_max = 5;
|
||||
bytes packet = 6;
|
||||
}
|
||||
|
||||
message TCPSequence {
|
||||
@@ -25,7 +27,9 @@ message TCPConfig {
|
||||
|
||||
message UDPItem {
|
||||
int32 rand = 1;
|
||||
bytes packet = 2;
|
||||
int32 rand_min = 2;
|
||||
int32 rand_max = 3;
|
||||
bytes packet = 4;
|
||||
}
|
||||
|
||||
message UDPConfig {
|
||||
|
||||
@@ -2,13 +2,11 @@ package custom
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/crypto"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
@@ -231,7 +229,7 @@ func writeSequence(w io.Writer, sequence *TCPSequence) bool {
|
||||
}
|
||||
if item.Rand > 0 {
|
||||
buf := make([]byte, item.Rand)
|
||||
common.Must2(rand.Read(buf))
|
||||
crypto.RandBytesBetween(buf, byte(item.RandMin), byte(item.RandMax))
|
||||
merged = append(merged, buf...)
|
||||
} else {
|
||||
merged = append(merged, item.Packet...)
|
||||
|
||||
@@ -2,13 +2,10 @@ package custom
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/crypto"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type udpCustomClient struct {
|
||||
@@ -21,7 +18,7 @@ func (h *udpCustomClient) Serialize(b []byte) {
|
||||
index := 0
|
||||
for _, item := range h.client {
|
||||
if item.Rand > 0 {
|
||||
common.Must2(rand.Read(h.merged[index : index+int(item.Rand)]))
|
||||
crypto.RandBytesBetween(h.merged[index:index+int(item.Rand)], byte(item.RandMin), byte(item.RandMax))
|
||||
index += int(item.Rand)
|
||||
} else {
|
||||
index += len(item.Packet)
|
||||
@@ -80,52 +77,20 @@ func NewConnClientUDP(c *UDPConfig, raw net.PacketConn) (net.PacketConn, error)
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (c *udpCustomClientConn) Size() int {
|
||||
return len(c.header.merged)
|
||||
}
|
||||
|
||||
func (c *udpCustomClientConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
if !c.header.Match(p) {
|
||||
return 0, addr, errors.New("header mismatch")
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if !c.header.Match(buf[:n]) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-len(c.header.merged) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-len(c.header.merged))
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[len(c.header.merged):n])
|
||||
|
||||
return n - len(c.header.merged), addr, nil
|
||||
return len(p) - len(c.header.merged), addr, nil
|
||||
}
|
||||
|
||||
func (c *udpCustomClientConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if len(c.header.merged)+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", len(c.header.merged)+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:len(c.header.merged)+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[len(c.header.merged):], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:len(c.header.merged)+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
@@ -140,7 +105,7 @@ func (h *udpCustomServer) Serialize(b []byte) {
|
||||
index := 0
|
||||
for _, item := range h.server {
|
||||
if item.Rand > 0 {
|
||||
common.Must2(rand.Read(h.merged[index : index+int(item.Rand)]))
|
||||
crypto.RandBytesBetween(h.merged[index:index+int(item.Rand)], byte(item.RandMin), byte(item.RandMax))
|
||||
index += int(item.Rand)
|
||||
} else {
|
||||
index += len(item.Packet)
|
||||
@@ -199,52 +164,20 @@ func NewConnServerUDP(c *UDPConfig, raw net.PacketConn) (net.PacketConn, error)
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (c *udpCustomServerConn) Size() int {
|
||||
return len(c.header.merged)
|
||||
}
|
||||
|
||||
func (c *udpCustomServerConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
if !c.header.Match(p) {
|
||||
return 0, addr, errors.New("header mismatch")
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if !c.header.Match(buf[:n]) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-len(c.header.merged) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-len(c.header.merged))
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[len(c.header.merged):n])
|
||||
|
||||
return n - len(c.header.merged), addr, nil
|
||||
return len(p) - len(c.header.merged), addr, nil
|
||||
}
|
||||
|
||||
func (c *udpCustomServerConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if len(c.header.merged)+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", len(c.header.merged)+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:len(c.header.merged)+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[len(c.header.merged):], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:len(c.header.merged)+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user