diff --git a/common/crypto/crypto.go b/common/crypto/crypto.go index efc33a11..49ce164b 100644 --- a/common/crypto/crypto.go +++ b/common/crypto/crypto.go @@ -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) + } +} diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index cdd6157b..c65c175c 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -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, }) } diff --git a/transport/internet/finalmask/finalmask.go b/transport/internet/finalmask/finalmask.go index 3eee635a..a98aa3fc 100644 --- a/transport/internet/finalmask/finalmask.go +++ b/transport/internet/finalmask/finalmask.go @@ -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() diff --git a/transport/internet/finalmask/fragment/conn.go b/transport/internet/finalmask/fragment/conn.go index 1cadf5f0..91822ace 100644 --- a/transport/internet/finalmask/fragment/conn.go +++ b/transport/internet/finalmask/fragment/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/custom/config.go b/transport/internet/finalmask/header/custom/config.go index 1d72e336..be094f21 100644 --- a/transport/internet/finalmask/header/custom/config.go +++ b/transport/internet/finalmask/header/custom/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/custom/config.pb.go b/transport/internet/finalmask/header/custom/config.pb.go index ff06eb29..c8db3e1a 100644 --- a/transport/internet/finalmask/header/custom/config.pb.go +++ b/transport/internet/finalmask/header/custom/config.pb.go @@ -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" + diff --git a/transport/internet/finalmask/header/custom/config.proto b/transport/internet/finalmask/header/custom/config.proto index 34314dee..cbf498ef 100644 --- a/transport/internet/finalmask/header/custom/config.proto +++ b/transport/internet/finalmask/header/custom/config.proto @@ -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 { diff --git a/transport/internet/finalmask/header/custom/tcp.go b/transport/internet/finalmask/header/custom/tcp.go index 9f3e893a..ef631984 100644 --- a/transport/internet/finalmask/header/custom/tcp.go +++ b/transport/internet/finalmask/header/custom/tcp.go @@ -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...) diff --git a/transport/internet/finalmask/header/custom/udp.go b/transport/internet/finalmask/header/custom/udp.go index efecf90b..033351e1 100644 --- a/transport/internet/finalmask/header/custom/udp.go +++ b/transport/internet/finalmask/header/custom/udp.go @@ -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 } diff --git a/transport/internet/finalmask/header/dns/config.go b/transport/internet/finalmask/header/dns/config.go index 7be9eb9a..48ede126 100644 --- a/transport/internet/finalmask/header/dns/config.go +++ b/transport/internet/finalmask/header/dns/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/dns/conn.go b/transport/internet/finalmask/header/dns/conn.go index a60aa2e4..263ca7ef 100644 --- a/transport/internet/finalmask/header/dns/conn.go +++ b/transport/internet/finalmask/header/dns/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/dtls/config.go b/transport/internet/finalmask/header/dtls/config.go index 02d102d0..decb69e3 100644 --- a/transport/internet/finalmask/header/dtls/config.go +++ b/transport/internet/finalmask/header/dtls/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/dtls/conn.go b/transport/internet/finalmask/header/dtls/conn.go index 0f7c16e8..3f875c2e 100644 --- a/transport/internet/finalmask/header/dtls/conn.go +++ b/transport/internet/finalmask/header/dtls/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/srtp/config.go b/transport/internet/finalmask/header/srtp/config.go index 875bf899..006964d9 100644 --- a/transport/internet/finalmask/header/srtp/config.go +++ b/transport/internet/finalmask/header/srtp/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/srtp/conn.go b/transport/internet/finalmask/header/srtp/conn.go index 8dabcd5f..94de0f9f 100644 --- a/transport/internet/finalmask/header/srtp/conn.go +++ b/transport/internet/finalmask/header/srtp/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/utp/config.go b/transport/internet/finalmask/header/utp/config.go index 804f462a..45d9a20c 100644 --- a/transport/internet/finalmask/header/utp/config.go +++ b/transport/internet/finalmask/header/utp/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/utp/conn.go b/transport/internet/finalmask/header/utp/conn.go index 7647e049..59005325 100644 --- a/transport/internet/finalmask/header/utp/conn.go +++ b/transport/internet/finalmask/header/utp/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/wechat/config.go b/transport/internet/finalmask/header/wechat/config.go index 8cd6ad3f..a433318e 100644 --- a/transport/internet/finalmask/header/wechat/config.go +++ b/transport/internet/finalmask/header/wechat/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/wechat/conn.go b/transport/internet/finalmask/header/wechat/conn.go index 157c1947..cb1fff62 100644 --- a/transport/internet/finalmask/header/wechat/conn.go +++ b/transport/internet/finalmask/header/wechat/conn.go @@ -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 } diff --git a/transport/internet/finalmask/header/wireguard/config.go b/transport/internet/finalmask/header/wireguard/config.go index b159f438..dd3609d8 100644 --- a/transport/internet/finalmask/header/wireguard/config.go +++ b/transport/internet/finalmask/header/wireguard/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/header/wireguard/conn.go b/transport/internet/finalmask/header/wireguard/conn.go index 2d310d28..4a38969f 100644 --- a/transport/internet/finalmask/header/wireguard/conn.go +++ b/transport/internet/finalmask/header/wireguard/conn.go @@ -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 } diff --git a/transport/internet/finalmask/mkcp/aes128gcm/config.go b/transport/internet/finalmask/mkcp/aes128gcm/config.go index da3459c6..a7160e2b 100644 --- a/transport/internet/finalmask/mkcp/aes128gcm/config.go +++ b/transport/internet/finalmask/mkcp/aes128gcm/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/mkcp/aes128gcm/conn.go b/transport/internet/finalmask/mkcp/aes128gcm/conn.go index 89fd9031..055803af 100644 --- a/transport/internet/finalmask/mkcp/aes128gcm/conn.go +++ b/transport/internet/finalmask/mkcp/aes128gcm/conn.go @@ -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 } diff --git a/transport/internet/finalmask/mkcp/original/config.go b/transport/internet/finalmask/mkcp/original/config.go index 19db4138..d18b1391 100644 --- a/transport/internet/finalmask/mkcp/original/config.go +++ b/transport/internet/finalmask/mkcp/original/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/mkcp/original/conn.go b/transport/internet/finalmask/mkcp/original/conn.go index 898541bd..15abe99b 100644 --- a/transport/internet/finalmask/mkcp/original/conn.go +++ b/transport/internet/finalmask/mkcp/original/conn.go @@ -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 } diff --git a/transport/internet/finalmask/salamander/config.go b/transport/internet/finalmask/salamander/config.go index 371b528c..8df1285d 100644 --- a/transport/internet/finalmask/salamander/config.go +++ b/transport/internet/finalmask/salamander/config.go @@ -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() { +} diff --git a/transport/internet/finalmask/salamander/conn.go b/transport/internet/finalmask/salamander/conn.go index f693ef07..bfb4934a 100644 --- a/transport/internet/finalmask/salamander/conn.go +++ b/transport/internet/finalmask/salamander/conn.go @@ -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 } diff --git a/transport/internet/finalmask/sudoku/conn_udp.go b/transport/internet/finalmask/sudoku/conn_udp.go index 0a774682..c2b2f4dd 100644 --- a/transport/internet/finalmask/sudoku/conn_udp.go +++ b/transport/internet/finalmask/sudoku/conn_udp.go @@ -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()