mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-22 17:46:48 +08:00
Support VLESS Encryption (native/random) + XTLS Vision + Any Transport like XHTTP (UDS or not) + TLS/REALITY
https://github.com/XTLS/Xray-core/pull/4952#issuecomment-3200720109
This commit is contained in:
@@ -525,27 +525,37 @@ func XtlsFilterTls(buffer buf.MultiBuffer, trafficState *TrafficState, ctx conte
|
||||
}
|
||||
}
|
||||
|
||||
// UnwrapRawConn support unwrap stats, tls, utls, reality, proxyproto, uds-wrapper conn and get raw tcp/uds conn from it
|
||||
// UnwrapRawConn support unwrap encryption, stats, tls, utls, reality, proxyproto, uds-wrapper conn and get raw tcp/uds conn from it
|
||||
func UnwrapRawConn(conn net.Conn) (net.Conn, stats.Counter, stats.Counter) {
|
||||
var readCounter, writerCounter stats.Counter
|
||||
if conn != nil {
|
||||
statConn, ok := conn.(*stat.CounterConnection)
|
||||
if ok {
|
||||
isEncryption := false
|
||||
if clientConn, ok := conn.(*encryption.ClientConn); ok {
|
||||
conn = clientConn.Conn
|
||||
isEncryption = true
|
||||
}
|
||||
if serverConn, ok := conn.(*encryption.ServerConn); ok {
|
||||
conn = serverConn.Conn
|
||||
isEncryption = true
|
||||
}
|
||||
if xorConn, ok := conn.(*encryption.XorConn); ok {
|
||||
return xorConn, nil, nil // xorConn should not be penetrated
|
||||
}
|
||||
if statConn, ok := conn.(*stat.CounterConnection); ok {
|
||||
conn = statConn.Connection
|
||||
readCounter = statConn.ReadCounter
|
||||
writerCounter = statConn.WriteCounter
|
||||
}
|
||||
if _, ok := conn.(*encryption.XorConn); ok {
|
||||
return conn, readCounter, writerCounter
|
||||
}
|
||||
if xc, ok := conn.(*tls.Conn); ok {
|
||||
conn = xc.NetConn()
|
||||
} else if utlsConn, ok := conn.(*tls.UConn); ok {
|
||||
conn = utlsConn.NetConn()
|
||||
} else if realityConn, ok := conn.(*reality.Conn); ok {
|
||||
conn = realityConn.NetConn()
|
||||
} else if realityUConn, ok := conn.(*reality.UConn); ok {
|
||||
conn = realityUConn.NetConn()
|
||||
if !isEncryption { // avoids double penetration
|
||||
if xc, ok := conn.(*tls.Conn); ok {
|
||||
conn = xc.NetConn()
|
||||
} else if utlsConn, ok := conn.(*tls.UConn); ok {
|
||||
conn = utlsConn.NetConn()
|
||||
} else if realityConn, ok := conn.(*reality.Conn); ok {
|
||||
conn = realityConn.NetConn()
|
||||
} else if realityUConn, ok := conn.(*reality.UConn); ok {
|
||||
conn = realityUConn.NetConn()
|
||||
}
|
||||
}
|
||||
if pc, ok := conn.(*proxyproto.Conn); ok {
|
||||
conn = pc.Raw()
|
||||
@@ -636,7 +646,7 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net
|
||||
}
|
||||
|
||||
func readV(ctx context.Context, reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, readCounter stats.Counter) error {
|
||||
errors.LogInfo(ctx, "CopyRawConn readv")
|
||||
errors.LogInfo(ctx, "CopyRawConn (maybe) readv")
|
||||
if err := buf.Copy(reader, writer, buf.UpdateActivity(timer), buf.AddToStatCounter(readCounter)); err != nil {
|
||||
return errors.New("failed to process response").Base(err)
|
||||
}
|
||||
|
@@ -58,8 +58,8 @@ func (i *ClientInstance) Init(nfsEKeyBytes []byte, xor uint32, minutes time.Dura
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hash256 := sha3.Sum256(nfsEKeyBytes)
|
||||
copy(i.hash11[:], hash256[:])
|
||||
hash32 := sha3.Sum256(nfsEKeyBytes)
|
||||
copy(i.hash11[:], hash32[:])
|
||||
if xor > 0 {
|
||||
xorKey := sha3.Sum256(nfsEKeyBytes)
|
||||
i.xorKey = xorKey[:]
|
||||
@@ -68,7 +68,7 @@ func (i *ClientInstance) Init(nfsEKeyBytes []byte, xor uint32, minutes time.Dura
|
||||
return
|
||||
}
|
||||
|
||||
func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
func (i *ClientInstance) Handshake(conn net.Conn) (*ClientConn, error) {
|
||||
if i.nfsEKey == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
|
@@ -55,8 +55,8 @@ func (i *ServerInstance) Init(nfsDKeySeed []byte, xor uint32, minutes time.Durat
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hash256 := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||
copy(i.hash11[:], hash256[:])
|
||||
hash32 := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||
copy(i.hash11[:], hash32[:])
|
||||
if xor > 0 {
|
||||
xorKey := sha3.Sum256(i.nfsDKey.EncapsulationKey().Bytes())
|
||||
i.xorKey = xorKey[:]
|
||||
@@ -92,7 +92,7 @@ func (i *ServerInstance) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
func (i *ServerInstance) Handshake(conn net.Conn) (*ServerConn, error) {
|
||||
if i.nfsDKey == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
|
@@ -49,6 +49,7 @@ func (c *XorConn) Write(b []byte) (int, error) { // whole one/two records
|
||||
l += 10
|
||||
if t == 0 {
|
||||
c.out_after0 = true
|
||||
c.out_header = make([]byte, 0, 5) // important
|
||||
}
|
||||
}
|
||||
c.ctr.XORKeyStream(b[:l], b[:l]) // caller MUST discard b
|
||||
@@ -77,7 +78,7 @@ func (c *XorConn) Write(b []byte) (int, error) { // whole one/two records
|
||||
break
|
||||
}
|
||||
_, c.out_skip, _ = DecodeHeader(append(c.out_header, p[:need]...))
|
||||
c.out_header = make([]byte, 0, 5) // DO NOT CHANGE
|
||||
c.out_header = c.out_header[:0]
|
||||
c.ctr.XORKeyStream(p[:need], p[:need])
|
||||
p = p[need:]
|
||||
}
|
||||
@@ -116,6 +117,7 @@ func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
||||
c.isHeader = false
|
||||
if t == 0 {
|
||||
c.in_after0 = true
|
||||
c.in_header = make([]byte, 0, 5) // important
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -139,7 +141,7 @@ func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
||||
}
|
||||
c.peerCtr.XORKeyStream(p[:need], p[:need])
|
||||
_, c.in_skip, _ = DecodeHeader(append(c.in_header, p[:need]...))
|
||||
c.in_header = make([]byte, 0, 5) // DO NOT CHANGE
|
||||
c.in_header = c.in_header[:0]
|
||||
p = p[need:]
|
||||
}
|
||||
return n, err
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pires/go-proxyproto"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
"github.com/xtls/xray-core/proxy/vless"
|
||||
"github.com/xtls/xray-core/proxy/vless/encoding"
|
||||
"github.com/xtls/xray-core/proxy/vless/encryption"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
"github.com/xtls/xray-core/transport/internet/reality"
|
||||
"github.com/xtls/xray-core/transport/internet/stat"
|
||||
"github.com/xtls/xray-core/transport/internet/tls"
|
||||
@@ -208,6 +210,11 @@ func (*Handler) Network() []net.Network {
|
||||
|
||||
// Process implements proxy.Inbound.Process().
|
||||
func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
|
||||
iConn := connection
|
||||
if statConn, ok := iConn.(*stat.CounterConnection); ok {
|
||||
iConn = statConn.Connection
|
||||
}
|
||||
|
||||
if h.decryption != nil {
|
||||
var err error
|
||||
connection, err = h.decryption.Handshake(connection)
|
||||
@@ -216,11 +223,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
||||
}
|
||||
}
|
||||
|
||||
iConn := connection
|
||||
if statConn, ok := iConn.(*stat.CounterConnection); ok {
|
||||
iConn = statConn.Connection
|
||||
}
|
||||
|
||||
sessionPolicy := h.policyManager.ForLevel(0)
|
||||
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
|
||||
return errors.New("unable to set read deadline").Base(err).AtWarning()
|
||||
@@ -499,6 +501,13 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
||||
case protocol.RequestCommandTCP:
|
||||
if serverConn, ok := connection.(*encryption.ServerConn); ok {
|
||||
peerCache = &serverConn.PeerCache
|
||||
_, ok0 := serverConn.Conn.(*encryption.XorConn)
|
||||
_, ok1 := iConn.(*proxyproto.Conn)
|
||||
_, ok2 := iConn.(*net.TCPConn)
|
||||
_, ok3 := iConn.(*internet.UnixConnWrapper)
|
||||
if ok0 || (!ok1 && !ok2 && !ok3) {
|
||||
inbound.CanSpliceCopy = 3 // xorConn/non-RAW can not use Linux Splice
|
||||
}
|
||||
break
|
||||
}
|
||||
var t reflect.Type
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pires/go-proxyproto"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
@@ -103,6 +104,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
iConn := conn
|
||||
if statConn, ok := iConn.(*stat.CounterConnection); ok {
|
||||
iConn = statConn.Connection
|
||||
}
|
||||
target := ob.Target
|
||||
errors.LogInfo(ctx, "tunneling request to ", target, " via ", rec.Destination().NetAddr())
|
||||
|
||||
if h.encryption != nil {
|
||||
var err error
|
||||
conn, err = h.encryption.Handshake(conn)
|
||||
@@ -111,13 +119,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
}
|
||||
}
|
||||
|
||||
iConn := conn
|
||||
if statConn, ok := iConn.(*stat.CounterConnection); ok {
|
||||
iConn = statConn.Connection
|
||||
}
|
||||
target := ob.Target
|
||||
errors.LogInfo(ctx, "tunneling request to ", target, " via ", rec.Destination().NetAddr())
|
||||
|
||||
command := protocol.RequestCommandTCP
|
||||
if target.Network == net.Network_UDP {
|
||||
command = protocol.RequestCommandUDP
|
||||
@@ -161,6 +162,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
case protocol.RequestCommandTCP:
|
||||
if clientConn, ok := conn.(*encryption.ClientConn); ok {
|
||||
peerCache = &clientConn.PeerCache
|
||||
_, ok0 := clientConn.Conn.(*encryption.XorConn)
|
||||
_, ok1 := iConn.(*proxyproto.Conn)
|
||||
_, ok2 := iConn.(*net.TCPConn)
|
||||
_, ok3 := iConn.(*internet.UnixConnWrapper)
|
||||
if ok0 || (!ok1 && !ok2 && !ok3) {
|
||||
ob.CanSpliceCopy = 3 // xorConn/non-RAW can not use Linux Splice
|
||||
}
|
||||
break
|
||||
}
|
||||
var t reflect.Type
|
||||
|
Reference in New Issue
Block a user