mirror of
https://github.com/net-byte/vtun
synced 2024-03-14 10:50:03 +08:00
115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package xproto
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
const ProtocolVersion = 1
|
|
|
|
type ClientSendPacketHeader struct {
|
|
ProtocolVersion uint8 //1 byte
|
|
Key *AuthKey //16 byte
|
|
Length int //2 byte, convert to [2]byte
|
|
}
|
|
|
|
func (p *ClientSendPacketHeader) Bytes() []byte {
|
|
data := make([]byte, ClientSendPacketHeaderLength)
|
|
data[0] = p.ProtocolVersion
|
|
copy(data[1:17], p.Key[:])
|
|
data[17] = byte(p.Length >> 8 & 0xff)
|
|
data[18] = byte(p.Length & 0xff)
|
|
return data
|
|
}
|
|
|
|
func ParseClientSendPacketHeader(data []byte) *ClientSendPacketHeader {
|
|
var obj = &ClientSendPacketHeader{}
|
|
var authKey AuthKey
|
|
if len(data) != ClientSendPacketHeaderLength {
|
|
return nil
|
|
}
|
|
obj.ProtocolVersion = data[0]
|
|
copy(authKey[:], data[1:17])
|
|
obj.Key = &authKey
|
|
obj.Length = ((obj.Length & 0x00) | int(data[17])) << 8
|
|
obj.Length = obj.Length | int(data[18])
|
|
return obj
|
|
}
|
|
|
|
type ServerSendPacketHeader struct {
|
|
ProtocolVersion uint8 //1 byte
|
|
Length int //2 byte, convert to [2]byte
|
|
}
|
|
|
|
func (p *ServerSendPacketHeader) Bytes() []byte {
|
|
data := make([]byte, ServerSendPacketHeaderLength)
|
|
data[0] = p.ProtocolVersion
|
|
data[1] = byte(p.Length >> 8 & 0xff)
|
|
data[2] = byte(p.Length & 0xff)
|
|
return data
|
|
}
|
|
|
|
func ParseServerSendPacketHeader(data []byte) *ServerSendPacketHeader {
|
|
var obj = &ServerSendPacketHeader{}
|
|
if len(data) != ServerSendPacketHeaderLength {
|
|
return nil
|
|
}
|
|
obj.ProtocolVersion = data[0]
|
|
obj.Length = ((obj.Length & 0x00) | int(data[1])) << 8
|
|
obj.Length = obj.Length | int(data[2])
|
|
return obj
|
|
}
|
|
|
|
const ClientSendPacketHeaderLength = 19
|
|
const ServerSendPacketHeaderLength = 3
|
|
|
|
// ConvertLength []byte length to int length
|
|
func ConvertLength(header []byte) int {
|
|
length := 0
|
|
if len(header) >= 2 {
|
|
length = ((length & 0x00) | int(header[0])) << 8
|
|
length = length | int(header[1])
|
|
}
|
|
return length
|
|
}
|
|
|
|
type AuthKey [16]byte
|
|
|
|
// Bytes returns the bytes representation of this AuthKey.
|
|
func (u *AuthKey) Bytes() []byte {
|
|
return u[:]
|
|
}
|
|
|
|
// Equals returns true if this AuthKey equals another AuthKey by value.
|
|
func (u *AuthKey) Equals(another *AuthKey) bool {
|
|
if u == nil && another == nil {
|
|
return true
|
|
}
|
|
if u == nil || another == nil {
|
|
return false
|
|
}
|
|
return bytes.Equal(u.Bytes(), another.Bytes())
|
|
}
|
|
|
|
// ParseBytes converts a AuthKey in byte form to object.
|
|
func ParseBytes(b []byte) (AuthKey, error) {
|
|
var authKey AuthKey
|
|
if len(b) != 16 {
|
|
return authKey, errors.New(fmt.Sprintf("invalid AuthKey: %v", b))
|
|
}
|
|
copy(authKey[:], b)
|
|
return authKey, nil
|
|
}
|
|
|
|
// ParseAuthKeyFromString converts a AuthKey in string form to object.
|
|
func ParseAuthKeyFromString(str string) *AuthKey {
|
|
var authKey AuthKey
|
|
m := md5.New()
|
|
m.Write([]byte(str))
|
|
r := m.Sum(nil)
|
|
copy(authKey[:], r[:16])
|
|
return &authKey
|
|
}
|