mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-09-08 10:18:49 +08:00
122 lines
4.1 KiB
Go
122 lines
4.1 KiB
Go
//go:build go1.25 && !without_badtls
|
|
|
|
package badtls
|
|
|
|
import (
|
|
"hash"
|
|
"reflect"
|
|
"sync"
|
|
"unsafe"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
)
|
|
|
|
type RawHalfConn struct {
|
|
pointer unsafe.Pointer
|
|
methods *Methods
|
|
*sync.Mutex
|
|
Err *error
|
|
Version *uint16
|
|
Cipher *any
|
|
Seq *[8]byte
|
|
ScratchBuf *[13]byte
|
|
TrafficSecret *[]byte
|
|
Mac *hash.Hash
|
|
RawKey *[]byte
|
|
RawIV *[]byte
|
|
RawMac *[]byte
|
|
}
|
|
|
|
func NewRawHalfConn(rawHalfConn reflect.Value, methods *Methods) (*RawHalfConn, error) {
|
|
halfConn := &RawHalfConn{
|
|
pointer: (unsafe.Pointer)(rawHalfConn.UnsafeAddr()),
|
|
methods: methods,
|
|
}
|
|
|
|
rawMutex := rawHalfConn.FieldByName("Mutex")
|
|
if !rawMutex.IsValid() || rawMutex.Kind() != reflect.Struct {
|
|
return nil, E.New("badtls: invalid halfConn.Mutex")
|
|
}
|
|
halfConn.Mutex = (*sync.Mutex)(unsafe.Pointer(rawMutex.UnsafeAddr()))
|
|
|
|
rawErr := rawHalfConn.FieldByName("err")
|
|
if !rawErr.IsValid() || rawErr.Kind() != reflect.Interface {
|
|
return nil, E.New("badtls: invalid halfConn.err")
|
|
}
|
|
halfConn.Err = (*error)(unsafe.Pointer(rawErr.UnsafeAddr()))
|
|
|
|
rawVersion := rawHalfConn.FieldByName("version")
|
|
if !rawVersion.IsValid() || rawVersion.Kind() != reflect.Uint16 {
|
|
return nil, E.New("badtls: invalid halfConn.version")
|
|
}
|
|
halfConn.Version = (*uint16)(unsafe.Pointer(rawVersion.UnsafeAddr()))
|
|
|
|
rawCipher := rawHalfConn.FieldByName("cipher")
|
|
if !rawCipher.IsValid() || rawCipher.Kind() != reflect.Interface {
|
|
return nil, E.New("badtls: invalid halfConn.cipher")
|
|
}
|
|
halfConn.Cipher = (*any)(unsafe.Pointer(rawCipher.UnsafeAddr()))
|
|
|
|
rawSeq := rawHalfConn.FieldByName("seq")
|
|
if !rawSeq.IsValid() || rawSeq.Kind() != reflect.Array || rawSeq.Len() != 8 || rawSeq.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.seq")
|
|
}
|
|
halfConn.Seq = (*[8]byte)(unsafe.Pointer(rawSeq.UnsafeAddr()))
|
|
|
|
rawScratchBuf := rawHalfConn.FieldByName("scratchBuf")
|
|
if !rawScratchBuf.IsValid() || rawScratchBuf.Kind() != reflect.Array || rawScratchBuf.Len() != 13 || rawScratchBuf.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.scratchBuf")
|
|
}
|
|
halfConn.ScratchBuf = (*[13]byte)(unsafe.Pointer(rawScratchBuf.UnsafeAddr()))
|
|
|
|
rawTrafficSecret := rawHalfConn.FieldByName("trafficSecret")
|
|
if !rawTrafficSecret.IsValid() || rawTrafficSecret.Kind() != reflect.Slice || rawTrafficSecret.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.trafficSecret")
|
|
}
|
|
halfConn.TrafficSecret = (*[]byte)(unsafe.Pointer(rawTrafficSecret.UnsafeAddr()))
|
|
|
|
rawMac := rawHalfConn.FieldByName("mac")
|
|
if !rawMac.IsValid() || rawMac.Kind() != reflect.Interface {
|
|
return nil, E.New("badtls: invalid halfConn.mac")
|
|
}
|
|
halfConn.Mac = (*hash.Hash)(unsafe.Pointer(rawMac.UnsafeAddr()))
|
|
|
|
rawKey := rawHalfConn.FieldByName("rawKey")
|
|
if rawKey.IsValid() {
|
|
if /*!rawKey.IsValid() || */ rawKey.Kind() != reflect.Slice || rawKey.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.rawKey")
|
|
}
|
|
halfConn.RawKey = (*[]byte)(unsafe.Pointer(rawKey.UnsafeAddr()))
|
|
|
|
rawIV := rawHalfConn.FieldByName("rawIV")
|
|
if !rawIV.IsValid() || rawIV.Kind() != reflect.Slice || rawIV.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.rawIV")
|
|
}
|
|
halfConn.RawIV = (*[]byte)(unsafe.Pointer(rawIV.UnsafeAddr()))
|
|
|
|
rawMAC := rawHalfConn.FieldByName("rawMac")
|
|
if !rawMAC.IsValid() || rawMAC.Kind() != reflect.Slice || rawMAC.Type().Elem().Kind() != reflect.Uint8 {
|
|
return nil, E.New("badtls: invalid halfConn.rawMac")
|
|
}
|
|
halfConn.RawMac = (*[]byte)(unsafe.Pointer(rawMAC.UnsafeAddr()))
|
|
}
|
|
|
|
return halfConn, nil
|
|
}
|
|
|
|
func (hc *RawHalfConn) Decrypt(record []byte) ([]byte, uint8, error) {
|
|
return hc.methods.decrypt(hc.pointer, record)
|
|
}
|
|
|
|
func (hc *RawHalfConn) SetErrorLocked(err error) error {
|
|
return hc.methods.setErrorLocked(hc.pointer, err)
|
|
}
|
|
|
|
func (hc *RawHalfConn) SetTrafficSecret(suite unsafe.Pointer, level int, secret []byte) {
|
|
hc.methods.setTrafficSecret(hc.pointer, suite, level, secret)
|
|
}
|
|
|
|
func (hc *RawHalfConn) ExplicitNonceLen() int {
|
|
return hc.methods.explicitNonceLen(hc.pointer)
|
|
}
|