raw_half_conn.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //go:build go1.25 && badlinkname
  2. package badtls
  3. import (
  4. "hash"
  5. "reflect"
  6. "sync"
  7. "unsafe"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. )
  10. type RawHalfConn struct {
  11. pointer unsafe.Pointer
  12. methods *Methods
  13. *sync.Mutex
  14. Err *error
  15. Version *uint16
  16. Cipher *any
  17. Seq *[8]byte
  18. ScratchBuf *[13]byte
  19. TrafficSecret *[]byte
  20. Mac *hash.Hash
  21. RawKey *[]byte
  22. RawIV *[]byte
  23. RawMac *[]byte
  24. }
  25. func NewRawHalfConn(rawHalfConn reflect.Value, methods *Methods) (*RawHalfConn, error) {
  26. halfConn := &RawHalfConn{
  27. pointer: (unsafe.Pointer)(rawHalfConn.UnsafeAddr()),
  28. methods: methods,
  29. }
  30. rawMutex := rawHalfConn.FieldByName("Mutex")
  31. if !rawMutex.IsValid() || rawMutex.Kind() != reflect.Struct {
  32. return nil, E.New("badtls: invalid halfConn.Mutex")
  33. }
  34. halfConn.Mutex = (*sync.Mutex)(unsafe.Pointer(rawMutex.UnsafeAddr()))
  35. rawErr := rawHalfConn.FieldByName("err")
  36. if !rawErr.IsValid() || rawErr.Kind() != reflect.Interface {
  37. return nil, E.New("badtls: invalid halfConn.err")
  38. }
  39. halfConn.Err = (*error)(unsafe.Pointer(rawErr.UnsafeAddr()))
  40. rawVersion := rawHalfConn.FieldByName("version")
  41. if !rawVersion.IsValid() || rawVersion.Kind() != reflect.Uint16 {
  42. return nil, E.New("badtls: invalid halfConn.version")
  43. }
  44. halfConn.Version = (*uint16)(unsafe.Pointer(rawVersion.UnsafeAddr()))
  45. rawCipher := rawHalfConn.FieldByName("cipher")
  46. if !rawCipher.IsValid() || rawCipher.Kind() != reflect.Interface {
  47. return nil, E.New("badtls: invalid halfConn.cipher")
  48. }
  49. halfConn.Cipher = (*any)(unsafe.Pointer(rawCipher.UnsafeAddr()))
  50. rawSeq := rawHalfConn.FieldByName("seq")
  51. if !rawSeq.IsValid() || rawSeq.Kind() != reflect.Array || rawSeq.Len() != 8 || rawSeq.Type().Elem().Kind() != reflect.Uint8 {
  52. return nil, E.New("badtls: invalid halfConn.seq")
  53. }
  54. halfConn.Seq = (*[8]byte)(unsafe.Pointer(rawSeq.UnsafeAddr()))
  55. rawScratchBuf := rawHalfConn.FieldByName("scratchBuf")
  56. if !rawScratchBuf.IsValid() || rawScratchBuf.Kind() != reflect.Array || rawScratchBuf.Len() != 13 || rawScratchBuf.Type().Elem().Kind() != reflect.Uint8 {
  57. return nil, E.New("badtls: invalid halfConn.scratchBuf")
  58. }
  59. halfConn.ScratchBuf = (*[13]byte)(unsafe.Pointer(rawScratchBuf.UnsafeAddr()))
  60. rawTrafficSecret := rawHalfConn.FieldByName("trafficSecret")
  61. if !rawTrafficSecret.IsValid() || rawTrafficSecret.Kind() != reflect.Slice || rawTrafficSecret.Type().Elem().Kind() != reflect.Uint8 {
  62. return nil, E.New("badtls: invalid halfConn.trafficSecret")
  63. }
  64. halfConn.TrafficSecret = (*[]byte)(unsafe.Pointer(rawTrafficSecret.UnsafeAddr()))
  65. rawMac := rawHalfConn.FieldByName("mac")
  66. if !rawMac.IsValid() || rawMac.Kind() != reflect.Interface {
  67. return nil, E.New("badtls: invalid halfConn.mac")
  68. }
  69. halfConn.Mac = (*hash.Hash)(unsafe.Pointer(rawMac.UnsafeAddr()))
  70. rawKey := rawHalfConn.FieldByName("rawKey")
  71. if rawKey.IsValid() {
  72. if /*!rawKey.IsValid() || */ rawKey.Kind() != reflect.Slice || rawKey.Type().Elem().Kind() != reflect.Uint8 {
  73. return nil, E.New("badtls: invalid halfConn.rawKey")
  74. }
  75. halfConn.RawKey = (*[]byte)(unsafe.Pointer(rawKey.UnsafeAddr()))
  76. rawIV := rawHalfConn.FieldByName("rawIV")
  77. if !rawIV.IsValid() || rawIV.Kind() != reflect.Slice || rawIV.Type().Elem().Kind() != reflect.Uint8 {
  78. return nil, E.New("badtls: invalid halfConn.rawIV")
  79. }
  80. halfConn.RawIV = (*[]byte)(unsafe.Pointer(rawIV.UnsafeAddr()))
  81. rawMAC := rawHalfConn.FieldByName("rawMac")
  82. if !rawMAC.IsValid() || rawMAC.Kind() != reflect.Slice || rawMAC.Type().Elem().Kind() != reflect.Uint8 {
  83. return nil, E.New("badtls: invalid halfConn.rawMac")
  84. }
  85. halfConn.RawMac = (*[]byte)(unsafe.Pointer(rawMAC.UnsafeAddr()))
  86. }
  87. return halfConn, nil
  88. }
  89. func (hc *RawHalfConn) Decrypt(record []byte) ([]byte, uint8, error) {
  90. return hc.methods.decrypt(hc.pointer, record)
  91. }
  92. func (hc *RawHalfConn) SetErrorLocked(err error) error {
  93. return hc.methods.setErrorLocked(hc.pointer, err)
  94. }
  95. func (hc *RawHalfConn) SetTrafficSecret(suite unsafe.Pointer, level int, secret []byte) {
  96. hc.methods.setTrafficSecret(hc.pointer, suite, level, secret)
  97. }
  98. func (hc *RawHalfConn) ExplicitNonceLen() int {
  99. return hc.methods.explicitNonceLen(hc.pointer)
  100. }