Compare commits

...

3 Commits

Author SHA1 Message Date
RPRX
d2758a023c v26.3.27
Some checks failed
Build and Release for Windows 7 / check-assets (push) Has been cancelled
Build and Release / check-assets (push) Has been cancelled
Scheduled assets update / geodat (push) Has been cancelled
Scheduled assets update / wintun (push) Has been cancelled
Test / check-assets (push) Has been cancelled
Test / check-proto (push) Has been cancelled
Build and Release for Windows 7 / build (win7-32, 386, windows) (push) Has been cancelled
Build and Release for Windows 7 / build (win7-64, amd64, windows) (push) Has been cancelled
Build and Release / build (386, freebsd, ) (push) Has been cancelled
Build and Release / build (386, linux, ) (push) Has been cancelled
Build and Release / build (386, openbsd, ) (push) Has been cancelled
Build and Release / build (386, windows, ) (push) Has been cancelled
Build and Release / build (amd64, android, android-amd64) (push) Has been cancelled
Build and Release / build (amd64, darwin, ) (push) Has been cancelled
Build and Release / build (amd64, freebsd, ) (push) Has been cancelled
Build and Release / build (amd64, linux, ) (push) Has been cancelled
Build and Release / build (amd64, openbsd, ) (push) Has been cancelled
Build and Release / build (amd64, windows, ) (push) Has been cancelled
Build and Release / build (arm, 5, linux) (push) Has been cancelled
Build and Release / build (arm, 6, linux) (push) Has been cancelled
Build and Release / build (arm, 7, freebsd) (push) Has been cancelled
Build and Release / build (arm, 7, linux) (push) Has been cancelled
Build and Release / build (arm, 7, openbsd) (push) Has been cancelled
Build and Release / build (arm64, android) (push) Has been cancelled
Build and Release / build (arm64, darwin) (push) Has been cancelled
Build and Release / build (arm64, freebsd) (push) Has been cancelled
Build and Release / build (arm64, linux) (push) Has been cancelled
Build and Release / build (arm64, openbsd) (push) Has been cancelled
Build and Release / build (arm64, windows) (push) Has been cancelled
Build and Release / build (loong64, linux) (push) Has been cancelled
Build and Release / build (mips, linux) (push) Has been cancelled
Build and Release / build (mips64, linux) (push) Has been cancelled
Build and Release / build (mips64le, linux) (push) Has been cancelled
Build and Release / build (mipsle, linux) (push) Has been cancelled
Build and Release / build (ppc64, linux) (push) Has been cancelled
Build and Release / build (ppc64le, linux) (push) Has been cancelled
Build and Release / build (riscv64, linux) (push) Has been cancelled
Build and Release / build (s390x, linux) (push) Has been cancelled
Test / test (macos-latest) (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
Test / test (windows-latest) (push) Has been cancelled
Announcement of NFTs by Project X: https://github.com/XTLS/Xray-core/discussions/3633
Project X NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/1

VLESS Post-Quantum Encryption: https://github.com/XTLS/Xray-core/pull/5067
VLESS NFT: https://opensea.io/collection/vless

XHTTP: Beyond REALITY: https://github.com/XTLS/Xray-core/discussions/4113
REALITY NFT: https://opensea.io/assets/ethereum/0x5ee362866001613093361eb8569d59c4141b76d1/2
2026-03-27 17:45:40 +00:00
LjhAUMEM
8aacdbd71b WireGuard inbound: Fix multi-peer; Fix potential routing issue (#5843)
Fixes https://github.com/XTLS/Xray-core/pull/5554

Fixes https://github.com/XTLS/Xray-core/issues/4760
2026-03-27 17:30:21 +00:00
LjhAUMEM
14524cc3b7 Finalmask: Add randRange to "noise" (UDP), as the same as "header-custom"'s (TCP & UDP) (#5850)
https://github.com/XTLS/Xray-core/pull/5812
2026-03-27 17:20:43 +00:00
10 changed files with 119 additions and 105 deletions

View File

@@ -36,7 +36,7 @@ type serverityLogger struct {
func NewLogger(logWriterCreator WriterCreator) Handler {
return &generalLogger{
creator: logWriterCreator,
buffer: make(chan Message, 16),
buffer: make(chan Message, 128),
access: semaphore.New(1),
done: done.New(),
}
@@ -46,7 +46,7 @@ func ReplaceWithSeverityLogger(serverity Severity) {
w := CreateStdoutLogWriter()
g := &generalLogger{
creator: w,
buffer: make(chan Message, 16),
buffer: make(chan Message, 128),
access: semaphore.New(1),
done: done.New(),
}

View File

@@ -20,7 +20,7 @@ import (
var (
Version_x byte = 26
Version_y byte = 3
Version_z byte = 23
Version_z byte = 27
)
var (

View File

@@ -1425,10 +1425,11 @@ func (c *FragmentMask) Build() (proto.Message, error) {
}
type NoiseItem struct {
Rand Int32Range `json:"rand"`
Type string `json:"type"`
Packet json.RawMessage `json:"packet"`
Delay Int32Range `json:"delay"`
Rand Int32Range `json:"rand"`
RandRange *Int32Range `json:"randRange"`
Type string `json:"type"`
Packet json.RawMessage `json:"packet"`
Delay Int32Range `json:"delay"`
}
type NoiseMask struct {
@@ -1445,16 +1446,24 @@ func (c *NoiseMask) Build() (proto.Message, error) {
noiseSlice := make([]*noise.Item, 0, len(c.Noise))
for _, item := range c.Noise {
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
}
noiseSlice = append(noiseSlice, &noise.Item{
RandMin: int64(item.Rand.From),
RandMax: int64(item.Rand.To),
Packet: item.Packet,
DelayMin: int64(item.Delay.From),
DelayMax: int64(item.Delay.To),
RandMin: int64(item.Rand.From),
RandMax: int64(item.Rand.To),
RandRangeMin: item.RandRange.From,
RandRangeMax: item.RandRange.To,
Packet: item.Packet,
DelayMin: int64(item.Delay.From),
DelayMax: int64(item.Delay.To),
})
}

View File

@@ -2,27 +2,23 @@ package wireguard
import (
"context"
"errors"
gonet "net"
"net/netip"
"runtime"
"strconv"
"sync"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/transport/internet"
)
type netReadInfo struct {
// status
waiter sync.WaitGroup
// param
buff []byte
// result
bytes int
buff []byte
endpoint conn.Endpoint
err error
}
// reduce duplicated code
@@ -32,6 +28,7 @@ type netBind struct {
workers int
readQueue chan *netReadInfo
closedCh chan struct{}
}
// SetMark implements conn.Bind
@@ -79,27 +76,23 @@ func (bind *netBind) BatchSize() int {
// Open implements conn.Bind
func (bind *netBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error) {
bind.readQueue = make(chan *netReadInfo)
bind.closedCh = make(chan struct{})
errors.LogDebug(context.Background(), "bind opened")
fun := func(bufs [][]byte, sizes []int, eps []conn.Endpoint) (n int, err error) {
defer func() {
if r := recover(); r != nil {
n = 0
err = errors.New("channel closed")
}
}()
r, ok := <-bind.readQueue
if !ok {
return 0, errors.New("channel closed")
select {
case r := <-bind.readQueue:
sizes[0], eps[0] = copy(bufs[0], r.buff), r.endpoint
return 1, nil
case <-bind.closedCh:
errors.LogDebug(context.Background(), "recv func closed")
return 0, gonet.ErrClosed
}
copy(bufs[0], r.buff[:r.bytes])
sizes[0], eps[0] = r.bytes, r.endpoint
r.waiter.Done()
return 1, r.err
}
workers := bind.workers
if workers <= 0 {
workers = runtime.NumCPU()
}
if workers <= 0 {
workers = 1
}
@@ -113,8 +106,9 @@ func (bind *netBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error) {
// Close implements conn.Bind
func (bind *netBind) Close() error {
if bind.readQueue != nil {
close(bind.readQueue)
errors.LogDebug(context.Background(), "bind closed")
if bind.closedCh != nil {
close(bind.closedCh)
}
return nil
}
@@ -134,35 +128,35 @@ func (bind *netBindClient) connectTo(endpoint *netEndpoint) error {
}
endpoint.conn = c
go func(readQueue chan<- *netReadInfo, endpoint *netEndpoint) {
defer func() {
_ = recover() // handle send on closed channel
}()
go func() {
for {
buff := make([]byte, 1700)
i, err := c.Read(buff)
buff := make([]byte, device.MaxMessageSize)
n, err := c.Read(buff)
if i > 3 {
if err != nil {
endpoint.conn = nil
c.Close()
return
}
if n > 3 {
buff[1] = 0
buff[2] = 0
buff[3] = 0
}
r := &netReadInfo{
buff: buff,
bytes: i,
select {
case bind.readQueue <- &netReadInfo{
buff: buff[:n],
endpoint: endpoint,
err: err,
}
r.waiter.Add(1)
readQueue <- r
r.waiter.Wait()
if err != nil {
}:
case <-bind.closedCh:
endpoint.conn = nil
c.Close()
return
}
}
}(bind.readQueue, endpoint)
}()
return nil
}
@@ -206,7 +200,8 @@ func (bind *netBindServer) Send(buff [][]byte, endpoint conn.Endpoint) error {
}
if nend.conn == nil {
return errors.New("connection not open yet")
errors.LogDebug(context.Background(), nend.dst.NetAddr(), " send on closed peer")
return errors.New("peer closed")
}
for _, buff := range buff {

View File

@@ -121,7 +121,8 @@ func (h *Handler) processWireGuard(ctx context.Context, dialer internet.Dialer)
IPv4Enable: h.hasIPv4,
IPv6Enable: h.hasIPv6,
},
workers: int(h.conf.NumWorkers),
workers: int(h.conf.NumWorkers),
readQueue: make(chan *netReadInfo),
},
ctx: ctx,
dialer: dialer,

View File

@@ -2,8 +2,6 @@ package wireguard
import (
"context"
goerrors "errors"
"io"
"github.com/xtls/xray-core/common/buf"
c "github.com/xtls/xray-core/common/ctx"
@@ -51,6 +49,8 @@ func NewServer(ctx context.Context, conf *DeviceConfig) (*Server, error) {
IPv4Enable: hasIPv4,
IPv6Enable: hasIPv6,
},
workers: int(conf.NumWorkers),
readQueue: make(chan *netReadInfo),
},
},
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
@@ -93,25 +93,31 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
reader := buf.NewPacketReader(conn)
for {
mpayload, err := reader.ReadMultiBuffer()
mb, err := reader.ReadMultiBuffer()
if err != nil {
nep.conn = nil
buf.ReleaseMulti(mb)
return err
}
for _, payload := range mpayload {
v, ok := <-s.bindServer.readQueue
if !ok {
return nil
}
i, err := payload.Read(v.buff)
for i, b := range mb {
buff := b.Bytes()
v.bytes = i
v.endpoint = nep
v.err = err
v.waiter.Done()
if err != nil && goerrors.Is(err, io.EOF) {
if b.Len() > 3 {
buff[1] = 0
buff[2] = 0
buff[3] = 0
}
select {
case s.bindServer.readQueue <- &netReadInfo{
buff: buff,
endpoint: nep,
}:
case <-s.bindServer.closedCh:
nep.conn = nil
return nil
buf.ReleaseMulti(mb[i:])
return errors.New("bind closed")
}
}
}
@@ -138,9 +144,11 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) {
// Currently we have no way to link to the original source address
inbound.Source = net.DestinationFromAddr(conn.RemoteAddr())
ctx = session.ContextWithInbound(ctx, &inbound)
content := new(session.Content)
if s.info.contentTag != nil {
ctx = session.ContextWithContent(ctx, s.info.contentTag)
content.SniffingRequest = s.info.contentTag.SniffingRequest
}
ctx = session.ContextWithContent(ctx, content)
ctx = session.SubContextFromMuxInbound(ctx)
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{

View File

@@ -8,25 +8,8 @@ import (
"strings"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/log"
"golang.zx2c4.com/wireguard/device"
)
var wgLogger = &device.Logger{
Verbosef: func(format string, args ...any) {
log.Record(&log.GeneralMessage{
Severity: log.Severity_Debug,
Content: fmt.Sprintf(format, args...),
})
},
Errorf: func(format string, args ...any) {
log.Record(&log.GeneralMessage{
Severity: log.Severity_Error,
Content: fmt.Sprintf(format, args...),
})
},
}
func init() {
common.Must(common.RegisterConfig((*DeviceConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
deviceConfig := config.(*DeviceConfig)

View File

@@ -25,9 +25,11 @@ type Item struct {
state protoimpl.MessageState `protogen:"open.v1"`
RandMin int64 `protobuf:"varint,1,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
RandMax int64 `protobuf:"varint,2,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
Packet []byte `protobuf:"bytes,3,opt,name=packet,proto3" json:"packet,omitempty"`
DelayMin int64 `protobuf:"varint,4,opt,name=delay_min,json=delayMin,proto3" json:"delay_min,omitempty"`
DelayMax int64 `protobuf:"varint,5,opt,name=delay_max,json=delayMax,proto3" json:"delay_max,omitempty"`
RandRangeMin int32 `protobuf:"varint,3,opt,name=rand_range_min,json=randRangeMin,proto3" json:"rand_range_min,omitempty"`
RandRangeMax int32 `protobuf:"varint,4,opt,name=rand_range_max,json=randRangeMax,proto3" json:"rand_range_max,omitempty"`
Packet []byte `protobuf:"bytes,5,opt,name=packet,proto3" json:"packet,omitempty"`
DelayMin int64 `protobuf:"varint,6,opt,name=delay_min,json=delayMin,proto3" json:"delay_min,omitempty"`
DelayMax int64 `protobuf:"varint,7,opt,name=delay_max,json=delayMax,proto3" json:"delay_max,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -76,6 +78,20 @@ func (x *Item) GetRandMax() int64 {
return 0
}
func (x *Item) GetRandRangeMin() int32 {
if x != nil {
return x.RandRangeMin
}
return 0
}
func (x *Item) GetRandRangeMax() int32 {
if x != nil {
return x.RandRangeMax
}
return 0
}
func (x *Item) GetPacket() []byte {
if x != nil {
return x.Packet
@@ -161,13 +177,15 @@ var File_transport_internet_finalmask_noise_config_proto protoreflect.FileDescri
const file_transport_internet_finalmask_noise_config_proto_rawDesc = "" +
"\n" +
"/transport/internet/finalmask/noise/config.proto\x12'xray.transport.internet.finalmask.noise\"\x8e\x01\n" +
"/transport/internet/finalmask/noise/config.proto\x12'xray.transport.internet.finalmask.noise\"\xda\x01\n" +
"\x04Item\x12\x19\n" +
"\brand_min\x18\x01 \x01(\x03R\arandMin\x12\x19\n" +
"\brand_max\x18\x02 \x01(\x03R\arandMax\x12\x16\n" +
"\x06packet\x18\x03 \x01(\fR\x06packet\x12\x1b\n" +
"\tdelay_min\x18\x04 \x01(\x03R\bdelayMin\x12\x1b\n" +
"\tdelay_max\x18\x05 \x01(\x03R\bdelayMax\"\x87\x01\n" +
"\brand_max\x18\x02 \x01(\x03R\arandMax\x12$\n" +
"\x0erand_range_min\x18\x03 \x01(\x05R\frandRangeMin\x12$\n" +
"\x0erand_range_max\x18\x04 \x01(\x05R\frandRangeMax\x12\x16\n" +
"\x06packet\x18\x05 \x01(\fR\x06packet\x12\x1b\n" +
"\tdelay_min\x18\x06 \x01(\x03R\bdelayMin\x12\x1b\n" +
"\tdelay_max\x18\a \x01(\x03R\bdelayMax\"\x87\x01\n" +
"\x06Config\x12\x1b\n" +
"\treset_min\x18\x01 \x01(\x03R\bresetMin\x12\x1b\n" +
"\treset_max\x18\x02 \x01(\x03R\bresetMax\x12C\n" +

View File

@@ -9,9 +9,11 @@ option java_multiple_files = true;
message Item {
int64 rand_min = 1;
int64 rand_max = 2;
bytes packet = 3;
int64 delay_min = 4;
int64 delay_max = 5;
int32 rand_range_min = 3;
int32 rand_range_max = 4;
bytes packet = 5;
int64 delay_min = 6;
int64 delay_max = 7;
}
message Config {

View File

@@ -1,12 +1,10 @@
package noise
import (
"crypto/rand"
"net"
"sync"
"time"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/crypto"
)
@@ -77,7 +75,7 @@ func (c *noiseConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
for _, item := range c.config.Items {
if item.RandMax > 0 {
item.Packet = make([]byte, crypto.RandBetween(item.RandMin, item.RandMax))
common.Must2(rand.Read(item.Packet))
crypto.RandBytesBetween(item.Packet, byte(item.RandRangeMin), byte(item.RandRangeMax))
}
c.PacketConn.WriteTo(item.Packet, addr)
time.Sleep(time.Duration(crypto.RandBetween(item.DelayMin, item.DelayMax)) * time.Millisecond)