mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +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:
@@ -4,8 +4,11 @@ package crypto // import "github.com/xtls/xray-core/common/crypto"
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
)
|
||||
|
||||
// [,)
|
||||
func RandBetween(from int64, to int64) int64 {
|
||||
if from == to {
|
||||
return from
|
||||
@@ -16,3 +19,20 @@ func RandBetween(from int64, to int64) int64 {
|
||||
bigInt, _ := rand.Int(rand.Reader, big.NewInt(to-from))
|
||||
return from + bigInt.Int64()
|
||||
}
|
||||
|
||||
// [,]
|
||||
func RandBytesBetween(b []byte, from, to byte) {
|
||||
common.Must2(rand.Read(b))
|
||||
|
||||
if from > to {
|
||||
from, to = to, from
|
||||
}
|
||||
|
||||
if to-from == 255 {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range b {
|
||||
b[i] = from + b[i]%(to-from+1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,10 +1254,11 @@ var (
|
||||
)
|
||||
|
||||
type TCPItem struct {
|
||||
Delay Int32Range `json:"delay"`
|
||||
Rand int32 `json:"rand"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
Delay Int32Range `json:"delay"`
|
||||
Rand int32 `json:"rand"`
|
||||
RandRange *Int32Range `json:"randRange"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
}
|
||||
|
||||
type HeaderCustomTCP struct {
|
||||
@@ -1289,10 +1290,18 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
}
|
||||
}
|
||||
|
||||
errInvalidRange := errors.New("invalid randRange")
|
||||
|
||||
clients := make([]*custom.TCPSequence, len(c.Clients))
|
||||
for i, value := range c.Clients {
|
||||
clients[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1301,6 +1310,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1310,6 +1321,12 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
for i, value := range c.Servers {
|
||||
servers[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1318,6 +1335,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1327,6 +1346,12 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
for i, value := range c.Errors {
|
||||
errors[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1335,6 +1360,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1433,9 +1460,10 @@ func (c *NoiseMask) Build() (proto.Message, error) {
|
||||
}
|
||||
|
||||
type UDPItem struct {
|
||||
Rand int32 `json:"rand"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
Rand int32 `json:"rand"`
|
||||
RandRange *Int32Range `json:"randRange"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
}
|
||||
|
||||
type HeaderCustomUDP struct {
|
||||
@@ -1457,25 +1485,41 @@ func (c *HeaderCustomUDP) Build() (proto.Message, error) {
|
||||
|
||||
client := make([]*custom.UDPItem, 0, len(c.Client))
|
||||
for _, item := range c.Client {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errors.New("invalid randRange")
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client = append(client, &custom.UDPItem{
|
||||
Rand: item.Rand,
|
||||
Packet: item.Packet,
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
|
||||
server := make([]*custom.UDPItem, 0, len(c.Server))
|
||||
for _, item := range c.Server {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errors.New("invalid randRange")
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
server = append(server, &custom.UDPItem{
|
||||
Rand: item.Rand,
|
||||
Packet: item.Packet,
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,11 @@ package finalmask
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
UDPSize = 4096 + 123
|
||||
)
|
||||
|
||||
type Udpmask interface {
|
||||
UDP()
|
||||
|
||||
@@ -29,27 +26,165 @@ func NewUdpmaskManager(udpmasks []Udpmask) *UdpmaskManager {
|
||||
}
|
||||
|
||||
func (m *UdpmaskManager) WrapPacketConnClient(raw net.PacketConn) (net.PacketConn, error) {
|
||||
var err error
|
||||
var sizes []int
|
||||
var conns []net.PacketConn
|
||||
for i, mask := range m.udpmasks {
|
||||
raw, err = mask.WrapPacketConnClient(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if _, ok := mask.(headerConn); ok {
|
||||
conn, err := mask.WrapPacketConnClient(nil, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sizes = append(sizes, conn.(headerSize).Size())
|
||||
conns = append(conns, conn)
|
||||
} else {
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
var err error
|
||||
raw, err = mask.WrapPacketConnClient(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func (m *UdpmaskManager) WrapPacketConnServer(raw net.PacketConn) (net.PacketConn, error) {
|
||||
var err error
|
||||
var sizes []int
|
||||
var conns []net.PacketConn
|
||||
for i, mask := range m.udpmasks {
|
||||
raw, err = mask.WrapPacketConnServer(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if _, ok := mask.(headerConn); ok {
|
||||
conn, err := mask.WrapPacketConnServer(nil, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sizes = append(sizes, conn.(headerSize).Size())
|
||||
conns = append(conns, conn)
|
||||
} else {
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
var err error
|
||||
raw, err = mask.WrapPacketConnServer(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
const (
|
||||
UDPSize = 4096
|
||||
)
|
||||
|
||||
type headerConn interface {
|
||||
HeaderConn()
|
||||
}
|
||||
|
||||
type headerSize interface {
|
||||
Size() int
|
||||
}
|
||||
|
||||
type headerManagerConn struct {
|
||||
sizes []int
|
||||
conns []net.PacketConn
|
||||
net.PacketConn
|
||||
m sync.Mutex
|
||||
writeBuf [UDPSize]byte
|
||||
}
|
||||
|
||||
func (c *headerManagerConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(buf) < UDPSize {
|
||||
buf = make([]byte, UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if n == 0 || err != nil {
|
||||
return 0, addr, err
|
||||
}
|
||||
newBuf := buf[:n]
|
||||
|
||||
sum := 0
|
||||
for _, size := range c.sizes {
|
||||
sum += size
|
||||
}
|
||||
|
||||
if n < sum {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short length")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
for i := range c.conns {
|
||||
n, _, err = c.conns[i].ReadFrom(newBuf)
|
||||
if n == 0 || err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err ", err)
|
||||
return 0, addr, nil
|
||||
}
|
||||
newBuf = newBuf[c.sizes[i] : n+c.sizes[i]]
|
||||
}
|
||||
|
||||
if len(p) < n {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[sum:sum+n])
|
||||
|
||||
return n, addr, nil
|
||||
}
|
||||
|
||||
func (c *headerManagerConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
sum := 0
|
||||
for _, size := range c.sizes {
|
||||
sum += size
|
||||
}
|
||||
|
||||
if sum+len(p) > UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
n = copy(c.writeBuf[sum:], p)
|
||||
|
||||
for i := len(c.conns) - 1; i >= 0; i-- {
|
||||
n, err = c.conns[i].WriteTo(c.writeBuf[sum-c.sizes[i]:n+sum], nil)
|
||||
if n == 0 || err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err ", err)
|
||||
return 0, nil
|
||||
}
|
||||
sum -= c.sizes[i]
|
||||
}
|
||||
|
||||
n, err = c.PacketConn.WriteTo(c.writeBuf[:n], addr)
|
||||
if n == 0 || err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
type Tcpmask interface {
|
||||
TCP()
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@ func NewConnServer(c *Config, raw net.Conn, server bool) (net.Conn, error) {
|
||||
func (c *fragmentConn) TcpMaskConn() {}
|
||||
|
||||
func (c *fragmentConn) RawConn() net.Conn {
|
||||
if c.server {
|
||||
return c
|
||||
}
|
||||
return c.Conn
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
func packDomainName(s string, msg []byte) (off1 int, err error) {
|
||||
@@ -125,52 +123,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *dnsConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *dnsConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *dnsConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package dtls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type dtls struct {
|
||||
@@ -62,52 +59,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *dtlsConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *dtlsConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *dtlsConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package srtp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type srtp struct {
|
||||
@@ -46,52 +43,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *srtpConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *srtpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *srtpConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package utp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type utp struct {
|
||||
@@ -48,52 +45,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *utpConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *utpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *utpConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package wechat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/dice"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type wechat struct {
|
||||
@@ -52,52 +49,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *wechatConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *wechatConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *wechatConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type wireguare struct{}
|
||||
@@ -39,52 +35,16 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *wireguareConn) Size() int {
|
||||
return c.header.Size()
|
||||
}
|
||||
|
||||
func (c *wireguareConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err header mismatch")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-c.header.Size() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-c.header.Size())
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[c.header.Size():n])
|
||||
|
||||
return n - c.header.Size(), addr, nil
|
||||
return len(p) - c.header.Size(), addr, nil
|
||||
}
|
||||
|
||||
func (c *wireguareConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.header.Size()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.header.Size()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.header.Size()+len(p)]
|
||||
}
|
||||
|
||||
copy(buf[c.header.Size():], p)
|
||||
c.header.Serialize(buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.header.Size()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.header.Serialize(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package aes128gcm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
@@ -33,86 +32,36 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *aes128gcmConn) Size() int {
|
||||
return c.aead.NonceSize()
|
||||
}
|
||||
|
||||
func (c *aes128gcmConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf := make([]byte, finalmask.UDPSize)
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.aead.NonceSize()+c.aead.Overhead() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead short lenth ", n)
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
nonceSize := c.aead.NonceSize()
|
||||
nonce := buf[:nonceSize]
|
||||
ciphertext := buf[nonceSize:n]
|
||||
plaintext, err := c.aead.Open(p[:0], nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead open ", err)
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(plaintext) > len(p) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", len(plaintext))
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
return n - c.aead.NonceSize() - c.aead.Overhead(), addr, nil
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(p)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.aead.NonceSize()+c.aead.Overhead() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead short lenth ", n)
|
||||
return 0, addr, nil
|
||||
if len(p) < c.aead.NonceSize()+c.aead.Overhead() {
|
||||
return 0, addr, errors.New("aead short lenth")
|
||||
}
|
||||
|
||||
nonceSize := c.aead.NonceSize()
|
||||
nonce := p[:nonceSize]
|
||||
ciphertext := p[nonceSize:n]
|
||||
ciphertext := p[nonceSize:]
|
||||
_, err = c.aead.Open(ciphertext[:0], nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead open ", err)
|
||||
return 0, addr, nil
|
||||
return 0, addr, errors.New("aead open").Base(err)
|
||||
}
|
||||
|
||||
copy(p, p[nonceSize:n-c.aead.Overhead()])
|
||||
|
||||
return n - c.aead.NonceSize() - c.aead.Overhead(), addr, nil
|
||||
return len(p) - c.aead.NonceSize() - c.aead.Overhead(), addr, nil
|
||||
}
|
||||
|
||||
func (c *aes128gcmConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.aead.NonceSize()+c.aead.Overhead()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.aead.NonceSize()+c.aead.Overhead()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.aead.NonceSize()+c.aead.Overhead()+len(p)]
|
||||
copy(buf[c.aead.NonceSize():], p)
|
||||
p = buf[c.aead.NonceSize() : c.aead.NonceSize()+len(p)]
|
||||
if c.aead.Overhead()+len(p) > finalmask.UDPSize {
|
||||
return 0, errors.New("aead short write")
|
||||
}
|
||||
|
||||
nonceSize := c.aead.NonceSize()
|
||||
nonce := buf[:nonceSize]
|
||||
nonce := p[:nonceSize]
|
||||
common.Must2(rand.Read(nonce))
|
||||
ciphertext := buf[nonceSize : c.aead.NonceSize()+c.aead.Overhead()+len(p)]
|
||||
_ = c.aead.Seal(ciphertext[:0], nonce, p, nil)
|
||||
plaintext := p[nonceSize:]
|
||||
_ = c.aead.Seal(plaintext[:0], nonce, plaintext, nil)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.aead.NonceSize()+c.aead.Overhead()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
return len(p) + c.aead.Overhead(), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package original
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"hash/fnv"
|
||||
@@ -9,7 +8,6 @@ import (
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type simple struct{}
|
||||
@@ -91,60 +89,21 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *simpleConn) Size() int {
|
||||
return c.aead.Overhead()
|
||||
}
|
||||
|
||||
func (c *simpleConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < c.aead.Overhead() {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead short lenth ", n)
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
ciphertext := buf[:n]
|
||||
opened, err := c.aead.Open(nil, nil, ciphertext, nil)
|
||||
_, err = c.aead.Open(p[:0], nil, p, nil)
|
||||
if err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err aead open ", err)
|
||||
return 0, addr, nil
|
||||
return 0, addr, errors.New("aead open").Base(err)
|
||||
}
|
||||
|
||||
if len(opened) > len(p) {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", len(opened))
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, opened)
|
||||
|
||||
return n - c.aead.Overhead(), addr, nil
|
||||
return len(p) - c.aead.Overhead(), addr, nil
|
||||
}
|
||||
|
||||
func (c *simpleConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if c.aead.Overhead()+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", c.aead.Overhead()+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:c.aead.Overhead()+len(p)]
|
||||
copy(buf[c.aead.Overhead():], p)
|
||||
p = buf[c.aead.Overhead() : c.aead.Overhead()+len(p)]
|
||||
}
|
||||
|
||||
_ = c.aead.Seal(buf[:0], nil, p, nil)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:c.aead.Overhead()+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
_ = c.aead.Seal(p[:0], nil, p[c.aead.Overhead():], nil)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,6 @@ func (c *Config) WrapPacketConnClient(raw net.PacketConn, level int, levelCount
|
||||
func (c *Config) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServer(c, raw)
|
||||
}
|
||||
|
||||
func (c *Config) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package salamander
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/transport/internet/finalmask"
|
||||
)
|
||||
|
||||
type salamanderConn struct {
|
||||
@@ -31,53 +29,18 @@ func NewConnServer(c *Config, raw net.PacketConn) (net.PacketConn, error) {
|
||||
return NewConnClient(c, raw)
|
||||
}
|
||||
|
||||
func (c *salamanderConn) Size() int {
|
||||
return smSaltLen
|
||||
}
|
||||
|
||||
func (c *salamanderConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(p) < finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
}
|
||||
c.obfs.Deobfuscate(p, p[smSaltLen:])
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if err != nil || n == 0 {
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
if n < smSaltLen {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short lenth ", n)
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
if len(p) < n-smSaltLen {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer ", len(p), " ", n-smSaltLen)
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
c.obfs.Deobfuscate(buf[:n], p)
|
||||
|
||||
return n - smSaltLen, addr, nil
|
||||
return len(p) - smSaltLen, addr, nil
|
||||
}
|
||||
|
||||
func (c *salamanderConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if smSaltLen+len(p) > finalmask.UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write ", smSaltLen+len(p), " ", finalmask.UDPSize)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if cap(p) != finalmask.UDPSize {
|
||||
buf = make([]byte, finalmask.UDPSize)
|
||||
} else {
|
||||
buf = p[:smSaltLen+len(p)]
|
||||
copy(buf[smSaltLen:], p)
|
||||
p = buf[smSaltLen:]
|
||||
}
|
||||
|
||||
c.obfs.Obfuscate(p, buf)
|
||||
|
||||
_, err = c.PacketConn.WriteTo(buf[:smSaltLen+len(p)], addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.obfs.Obfuscate(p[smSaltLen:], p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -35,10 +35,6 @@ func NewUDPConn(raw net.PacketConn, config *Config) (net.PacketConn, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *udpConn) Size() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *udpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
c.readMu.Lock()
|
||||
defer c.readMu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user