github.com/imgk/caddy-trojan@v0.0.0-20221206043256-2631719e16c8/utils/utils.go (about)

     1  package utils
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/tls"
     6  	"net"
     7  	"reflect"
     8  	"unsafe"
     9  )
    10  
    11  // ByteSliceToString is ...
    12  func ByteSliceToString(b []byte) string {
    13  	return *(*string)(unsafe.Pointer(&b))
    14  }
    15  
    16  // StringToByteSlice is ...
    17  func StringToByteSlice(s string) []byte {
    18  	return unsafe.Slice((*byte)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&s)))), len(s))
    19  }
    20  
    21  func RewindConn(conn net.Conn, read []byte) net.Conn {
    22  	if tlsConn, ok := conn.(*tls.Conn); ok {
    23  		var (
    24  			tlsInput, _ = reflect.TypeOf(tls.Conn{}).FieldByName("input")
    25  			input       = (*bytes.Reader)(unsafe.Add(unsafe.Pointer(tlsConn), tlsInput.Offset))
    26  			remaining   = input.Len()
    27  			size        = int(input.Size())
    28  			buffered    = len(read)
    29  		)
    30  		if buffered <= size {
    31  			_, _ = input.Seek(0, 0)
    32  		} else {
    33  			buf := make([]byte, buffered+remaining)
    34  			copy(buf, read)
    35  			_, _ = input.Read(buf[buffered:])
    36  			input.Reset(buf)
    37  		}
    38  		return tlsConn
    39  	} else {
    40  		return NewRawConn(conn, read)
    41  	}
    42  }