cloudflared-mirror/vendor/github.com/marten-seemann/qtls-go1-15/unsafe.go

90 lines
2.2 KiB
Go

package qtls
import (
"crypto/tls"
"reflect"
"unsafe"
)
func init() {
if !structsEqual(&tls.ConnectionState{}, &connectionState{}) {
panic("qtls.ConnectionState doesn't match")
}
if !structsEqual(&tls.ClientSessionState{}, &clientSessionState{}) {
panic("qtls.ClientSessionState doesn't match")
}
if !structsEqual(&tls.Config{}, &config{}) {
panic("qtls.Config doesn't match")
}
if !structsEqual(&tls.ClientHelloInfo{}, &clientHelloInfo{}) {
panic("qtls.ClientHelloInfo doesn't match")
}
}
func toConnectionState(c connectionState) ConnectionState {
return *(*ConnectionState)(unsafe.Pointer(&c))
}
func toClientSessionState(s *clientSessionState) *ClientSessionState {
return (*ClientSessionState)(unsafe.Pointer(s))
}
func fromClientSessionState(s *ClientSessionState) *clientSessionState {
return (*clientSessionState)(unsafe.Pointer(s))
}
func toConfig(c *config) *Config {
return (*Config)(unsafe.Pointer(c))
}
func fromConfig(c *Config) *config {
return (*config)(unsafe.Pointer(c))
}
func toClientHelloInfo(chi *clientHelloInfo) *ClientHelloInfo {
return (*ClientHelloInfo)(unsafe.Pointer(chi))
}
func structsEqual(a, b interface{}) bool {
return compare(reflect.ValueOf(a), reflect.ValueOf(b))
}
func compare(a, b reflect.Value) bool {
sa := a.Elem()
sb := b.Elem()
if sa.NumField() != sb.NumField() {
return false
}
for i := 0; i < sa.NumField(); i++ {
fa := sa.Type().Field(i)
fb := sb.Type().Field(i)
if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) {
if fa.Type.Kind() != fb.Type.Kind() {
return false
}
if fa.Type.Kind() == reflect.Slice {
if !compareStruct(fa.Type.Elem(), fb.Type.Elem()) {
return false
}
continue
}
return false
}
}
return true
}
func compareStruct(a, b reflect.Type) bool {
if a.NumField() != b.NumField() {
return false
}
for i := 0; i < a.NumField(); i++ {
fa := a.Field(i)
fb := b.Field(i)
if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) {
return false
}
}
return true
}