mirror of
https://github.com/bolucat/Archive.git
synced 2025-09-26 20:21:35 +08:00
Update On Thu Aug 28 20:40:12 CEST 2025
This commit is contained in:
@@ -31,7 +31,7 @@ require (
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.6
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
|
||||
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250828081059-57e77685eef9
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||
github.com/metacubex/tfo-go v0.0.0-20250827083229-aa432b865617
|
||||
|
@@ -131,8 +131,8 @@ github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MY
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f h1:1MV/pFn2vjnyvH/0u6sJST0kmaoZXgbUytCCfuelhl8=
|
||||
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f/go.mod h1:FQ9zXA+kVhdzqgFqeJdi/AUhJgUgw+SUXqrR++GvbnM=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0 h1:WZepq4TOZa6WewB8tGAZrrL+bL2R2ivoBzuEgAeolWc=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250828081059-57e77685eef9 h1:VP7rBmRJUqBpP8uJQpzEqCgnbAYWbz2QtWqoBdNrmwU=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250828081059-57e77685eef9/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113awp7P6odM2okB5s60HUyF0FMqKmo=
|
||||
|
@@ -65,7 +65,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
|
||||
if i.NfsPKeys == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
c := &CommonConn{Conn: conn}
|
||||
c := NewCommonConn(conn)
|
||||
|
||||
ivAndRealysLength := 16 + i.RelaysLength
|
||||
pfsKeyExchangeLength := 18 + 1184 + 32 + 16
|
||||
|
@@ -4,16 +4,16 @@ import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/pool"
|
||||
|
||||
"github.com/metacubex/blake3"
|
||||
"github.com/metacubex/randv2"
|
||||
)
|
||||
|
||||
type CommonConn struct {
|
||||
@@ -23,36 +23,44 @@ type CommonConn struct {
|
||||
PreWrite []byte
|
||||
GCM *GCM
|
||||
PeerPadding []byte
|
||||
rawInput bytes.Buffer // PeerInBytes
|
||||
PeerGCM *GCM
|
||||
input bytes.Reader // PeerCache
|
||||
}
|
||||
|
||||
func NewCommonConn(conn net.Conn) *CommonConn {
|
||||
return &CommonConn{
|
||||
Conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonConn) Write(b []byte) (int, error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var data []byte
|
||||
outBytes := pool.Get(5 + 8192 + 16)
|
||||
defer pool.Put(outBytes)
|
||||
for n := 0; n < len(b); {
|
||||
b := b[n:]
|
||||
if len(b) > 8192 {
|
||||
b = b[:8192] // for avoiding another copy() in peer's Read()
|
||||
}
|
||||
n += len(b)
|
||||
data = make([]byte, 5+len(b)+16)
|
||||
EncodeHeader(data, len(b)+16)
|
||||
headerAndData := outBytes[:5+len(b)+16]
|
||||
EncodeHeader(headerAndData, len(b)+16)
|
||||
max := false
|
||||
if bytes.Equal(c.GCM.Nonce[:], MaxNonce) {
|
||||
max = true
|
||||
}
|
||||
c.GCM.Seal(data[:5], nil, b, data[:5])
|
||||
c.GCM.Seal(headerAndData[:5], nil, b, headerAndData[:5])
|
||||
if max {
|
||||
c.GCM = NewGCM(data[5:], c.UnitedKey)
|
||||
c.GCM = NewGCM(headerAndData, c.UnitedKey)
|
||||
}
|
||||
if c.PreWrite != nil {
|
||||
data = append(c.PreWrite, data...)
|
||||
headerAndData = append(c.PreWrite, headerAndData...)
|
||||
c.PreWrite = nil
|
||||
}
|
||||
if _, err := c.Conn.Write(data); err != nil {
|
||||
if _, err := c.Conn.Write(headerAndData); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
@@ -85,9 +93,13 @@ func (c *CommonConn) Read(b []byte) (int, error) {
|
||||
if c.input.Len() > 0 {
|
||||
return c.input.Read(b)
|
||||
}
|
||||
h, l, err := ReadAndDecodeHeader(c.Conn) // l: 17~17000
|
||||
peerHeader := make([]byte, 5)
|
||||
if _, err := io.ReadFull(c.Conn, peerHeader); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l, err := DecodeHeader(peerHeader) // l: 17~17000
|
||||
if err != nil {
|
||||
if c.Client != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // client's 0-RTT
|
||||
if c.Client != nil && errors.Is(err, ErrInvalidHeader) { // client's 0-RTT
|
||||
c.Client.RWLock.Lock()
|
||||
if bytes.HasPrefix(c.UnitedKey, c.Client.PfsKey) {
|
||||
c.Client.Expire = time.Now() // expired
|
||||
@@ -98,7 +110,8 @@ func (c *CommonConn) Read(b []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
c.Client = nil
|
||||
peerData := make([]byte, l)
|
||||
c.rawInput.Grow(l)
|
||||
peerData := c.rawInput.Bytes()[:l]
|
||||
if _, err := io.ReadFull(c.Conn, peerData); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -108,9 +121,9 @@ func (c *CommonConn) Read(b []byte) (int, error) {
|
||||
}
|
||||
var newGCM *GCM
|
||||
if bytes.Equal(c.PeerGCM.Nonce[:], MaxNonce) {
|
||||
newGCM = NewGCM(peerData, c.UnitedKey)
|
||||
newGCM = NewGCM(append(peerHeader, peerData...), c.UnitedKey)
|
||||
}
|
||||
_, err = c.PeerGCM.Open(dst[:0], nil, peerData, h)
|
||||
_, err = c.PeerGCM.Open(dst[:0], nil, peerData, peerHeader)
|
||||
if newGCM != nil {
|
||||
c.PeerGCM = newGCM
|
||||
}
|
||||
@@ -180,41 +193,22 @@ func EncodeHeader(h []byte, l int) {
|
||||
h[4] = byte(l)
|
||||
}
|
||||
|
||||
var ErrInvalidHeader = errors.New("invalid header")
|
||||
|
||||
func DecodeHeader(h []byte) (l int, err error) {
|
||||
l = int(h[3])<<8 | int(h[4])
|
||||
if h[0] != 23 || h[1] != 3 || h[2] != 3 {
|
||||
l = 0
|
||||
}
|
||||
if l < 17 || l > 17000 { // TODO: TLSv1.3 max length
|
||||
err = fmt.Errorf("invalid header: %v", h[:5]) // DO NOT CHANGE: relied by client's Read()
|
||||
err = fmt.Errorf("%w: %v", ErrInvalidHeader, h[:5]) // DO NOT CHANGE: relied by client's Read()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ReadAndDecodeHeader(conn net.Conn) (h []byte, l int, err error) {
|
||||
h = make([]byte, 5)
|
||||
if _, err = io.ReadFull(conn, h); err != nil {
|
||||
return
|
||||
}
|
||||
l, err = DecodeHeader(h)
|
||||
return
|
||||
}
|
||||
|
||||
func ReadAndDiscardPaddings(conn net.Conn) (h []byte, l int, err error) {
|
||||
for {
|
||||
if h, l, err = ReadAndDecodeHeader(conn); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = io.ReadFull(conn, make([]byte, l)); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func randBetween(from int64, to int64) int64 {
|
||||
if from == to {
|
||||
return from
|
||||
}
|
||||
bigInt, _ := rand.Int(rand.Reader, big.NewInt(to-from))
|
||||
return from + bigInt.Int64()
|
||||
return from + randv2.Int64N(to-from)
|
||||
}
|
||||
|
@@ -20,4 +20,5 @@
|
||||
// https://github.com/XTLS/Xray-core/commit/ad7140641c44239c9dcdc3d7215ea639b1f0841c
|
||||
// https://github.com/XTLS/Xray-core/commit/0199dea39988a1a1b846d0bf8598631bade40902
|
||||
// https://github.com/XTLS/Xray-core/commit/fce1195b60f48ca18a953dbd5c7d991869de9a5e
|
||||
// https://github.com/XTLS/Xray-core/commit/b0b220985c9c1bc832665458d5fd6e0c287b67ae
|
||||
package encryption
|
||||
|
@@ -101,7 +101,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*CommonConn, error) {
|
||||
if i.NfsSKeys == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
c := &CommonConn{Conn: conn}
|
||||
c := NewCommonConn(conn)
|
||||
|
||||
ivAndRelays := make([]byte, 16+i.RelaysLength)
|
||||
if _, err := io.ReadFull(conn, ivAndRelays); err != nil {
|
||||
|
@@ -125,6 +125,7 @@ func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error {
|
||||
}
|
||||
if vc.input.Len() == 0 {
|
||||
needReturn = true
|
||||
*vc.input = bytes.Reader{} // full reset
|
||||
vc.input = nil
|
||||
} else { // buffer is full
|
||||
return nil
|
||||
@@ -139,6 +140,7 @@ func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error {
|
||||
}
|
||||
needReturn = true
|
||||
if vc.rawInput.Len() == 0 {
|
||||
*vc.rawInput = bytes.Buffer{} // full reset
|
||||
vc.rawInput = nil
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user