123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- //go:build go1.25 && badlinkname
- 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)
- }
|