chore: sync vless encryption code
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.25, macos-13) (push) Waiting to run
Test / test (1.25, macos-latest) (push) Waiting to run
Test / test (1.25, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.25, ubuntu-latest) (push) Waiting to run
Test / test (1.25, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run

This commit is contained in:
wwqgtxx 2025-09-04 22:06:47 +08:00
parent 8eba1c8afd
commit f8ee5c1e15
4 changed files with 65 additions and 26 deletions

View File

@ -100,7 +100,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
if sl.decryption != nil { if sl.decryption != nil {
defer func() { // decryption must be closed to avoid the goroutine leak defer func() { // decryption must be closed to avoid the goroutine leak
if err != nil { if err != nil {
//_ = sl.decryption.Close() _ = sl.decryption.Close()
sl.decryption = nil sl.decryption = nil
} }
}() }()
@ -210,7 +210,7 @@ func (l *Listener) Close() error {
} }
} }
if l.decryption != nil { if l.decryption != nil {
//_ = l.decryption.Close() _ = l.decryption.Close()
} }
return retErr return retErr
} }

View File

@ -26,4 +26,5 @@
// https://github.com/XTLS/Xray-core/commit/6768a22f676c9121cfc9dc4f51181a8a07837c8d // https://github.com/XTLS/Xray-core/commit/6768a22f676c9121cfc9dc4f51181a8a07837c8d
// https://github.com/XTLS/Xray-core/commit/4c6fd94d97159f5a3e740ba6dd2d9b65e3ed320c // https://github.com/XTLS/Xray-core/commit/4c6fd94d97159f5a3e740ba6dd2d9b65e3ed320c
// https://github.com/XTLS/Xray-core/commit/19f890729656bc923ae3dee8426168c93b8ee9c2 // https://github.com/XTLS/Xray-core/commit/19f890729656bc923ae3dee8426168c93b8ee9c2
// https://github.com/XTLS/Xray-core/commit/cbade89ab11af26ba1e480a3688a6c205fa3c3f8
package encryption package encryption

View File

@ -82,14 +82,14 @@ func NewServer(decryption string) (*ServerInstance, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption) return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
} }
secondsFrom := uint32(i) secondsFrom := int64(i)
var secondsTo uint32 secondsTo := int64(0)
if len(t) > 1 { if len(t) == 2 {
i, err = strconv.Atoi(t[1]) i, err = strconv.Atoi(t[1])
if err != nil { if err != nil {
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption) return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
} }
secondsTo = uint32(i) secondsTo = int64(i)
} }
var nfsSKeysBytes [][]byte var nfsSKeysBytes [][]byte
var paddings []string var paddings []string

View File

@ -27,16 +27,19 @@ type ServerInstance struct {
Hash32s [][32]byte Hash32s [][32]byte
RelaysLength int RelaysLength int
XorMode uint32 XorMode uint32
SecondsFrom uint32 SecondsFrom int64
SecondsTo uint32 SecondsTo int64
PaddingLens [][3]int PaddingLens [][3]int
PaddingGaps [][3]int PaddingGaps [][3]int
RWLock sync.RWMutex RWLock sync.RWMutex
Closed bool
Lasts map[int64][16]byte
Tickets [][16]byte
Sessions map[[16]byte]*ServerSession Sessions map[[16]byte]*ServerSession
} }
func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode, secondsFrom, secondsTo uint32, padding string) (err error) { func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode uint32, secondsFrom, secondsTo int64, padding string) (err error) {
if i.NfsSKeys != nil { if i.NfsSKeys != nil {
return errors.New("already initialized") return errors.New("already initialized")
} }
@ -67,8 +70,47 @@ func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode, secondsFrom, seco
i.XorMode = xorMode i.XorMode = xorMode
i.SecondsFrom = secondsFrom i.SecondsFrom = secondsFrom
i.SecondsTo = secondsTo i.SecondsTo = secondsTo
i.Sessions = make(map[[16]byte]*ServerSession) err = ParsePadding(padding, &i.PaddingLens, &i.PaddingGaps)
return ParsePadding(padding, &i.PaddingLens, &i.PaddingGaps) if err != nil {
return
}
if i.SecondsFrom > 0 || i.SecondsTo > 0 {
i.Lasts = make(map[int64][16]byte)
i.Tickets = make([][16]byte, 0, 1024)
i.Sessions = make(map[[16]byte]*ServerSession)
go func() {
for {
time.Sleep(time.Minute)
i.RWLock.Lock()
if i.Closed {
i.RWLock.Unlock()
return
}
minute := time.Now().Unix() / 60
last := i.Lasts[minute]
delete(i.Lasts, minute)
delete(i.Lasts, minute-1) // for insurance
if last != [16]byte{} {
for j, ticket := range i.Tickets {
delete(i.Sessions, ticket)
if ticket == last {
i.Tickets = i.Tickets[j+1:]
break
}
}
}
i.RWLock.Unlock()
}
}()
}
return
}
func (i *ServerInstance) Close() (err error) {
i.RWLock.Lock()
i.Closed = true
i.RWLock.Unlock()
return
} }
func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn, error) { func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn, error) {
@ -223,25 +265,21 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
c.AEAD = NewAEAD(pfsPublicKey, c.UnitedKey, c.UseAES) c.AEAD = NewAEAD(pfsPublicKey, c.UnitedKey, c.UseAES)
c.PeerAEAD = NewAEAD(encryptedPfsPublicKey[:1184+32], c.UnitedKey, c.UseAES) c.PeerAEAD = NewAEAD(encryptedPfsPublicKey[:1184+32], c.UnitedKey, c.UseAES)
ticket := make([]byte, 16) ticket := [16]byte{}
rand.Read(ticket) rand.Read(ticket[:])
seconds := 0 var seconds int64
if i.SecondsTo == 0 { if i.SecondsTo == 0 {
seconds = int(i.SecondsFrom) * int(randBetween(50, 100)) / 100 seconds = i.SecondsFrom * randBetween(50, 100) / 100
} else { } else {
seconds = int(randBetween(int64(i.SecondsFrom), int64(i.SecondsTo))) seconds = randBetween(i.SecondsFrom, i.SecondsTo)
} }
copy(ticket, EncodeLength(int(seconds))) copy(ticket[:], EncodeLength(int(seconds)))
if seconds > 0 { if seconds > 0 {
i.RWLock.Lock() i.RWLock.Lock()
i.Sessions[[16]byte(ticket)] = &ServerSession{PfsKey: pfsKey} i.Lasts[(time.Now().Unix()+max(i.SecondsFrom, i.SecondsTo))/60+2] = ticket
i.Tickets = append(i.Tickets, ticket)
i.Sessions[ticket] = &ServerSession{PfsKey: pfsKey}
i.RWLock.Unlock() i.RWLock.Unlock()
go func() {
time.Sleep(time.Duration(seconds)*time.Second + time.Minute)
i.RWLock.Lock()
delete(i.Sessions, [16]byte(ticket))
i.RWLock.Unlock()
}()
} }
pfsKeyExchangeLength := 1088 + 32 + 16 pfsKeyExchangeLength := 1088 + 32 + 16
@ -249,7 +287,7 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
paddingLength, paddingLens, paddingGaps := CreatPadding(i.PaddingLens, i.PaddingGaps) paddingLength, paddingLens, paddingGaps := CreatPadding(i.PaddingLens, i.PaddingGaps)
serverHello := make([]byte, pfsKeyExchangeLength+encryptedTicketLength+paddingLength) serverHello := make([]byte, pfsKeyExchangeLength+encryptedTicketLength+paddingLength)
nfsAEAD.Seal(serverHello[:0], MaxNonce, pfsPublicKey, nil) nfsAEAD.Seal(serverHello[:0], MaxNonce, pfsPublicKey, nil)
c.AEAD.Seal(serverHello[:pfsKeyExchangeLength], nil, ticket, nil) c.AEAD.Seal(serverHello[:pfsKeyExchangeLength], nil, ticket[:], nil)
padding := serverHello[pfsKeyExchangeLength+encryptedTicketLength:] padding := serverHello[pfsKeyExchangeLength+encryptedTicketLength:]
c.AEAD.Seal(padding[:0], nil, EncodeLength(paddingLength-18), nil) c.AEAD.Seal(padding[:0], nil, EncodeLength(paddingLength-18), nil)
c.AEAD.Seal(padding[:18], nil, padding[18:paddingLength-16], nil) c.AEAD.Seal(padding[:18], nil, padding[18:paddingLength-16], nil)
@ -283,7 +321,7 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn
} }
if i.XorMode == 2 { if i.XorMode == 2 {
c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, ticket), NewCTR(c.UnitedKey, iv), 0, 0) c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, ticket[:]), NewCTR(c.UnitedKey, iv), 0, 0)
} }
return c, nil return c, nil
} }