mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-07 14:25:17 +03:00
95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
package tunnel
|
|
|
|
import "encoding/binary"
|
|
|
|
const (
|
|
MsgConnect byte = 0x01
|
|
MsgConnectOK byte = 0x02
|
|
MsgConnectErr byte = 0x03
|
|
MsgData byte = 0x04
|
|
MsgClose byte = 0x05
|
|
MsgUDP byte = 0x06
|
|
MsgUDPReply byte = 0x07
|
|
MsgConfig byte = 0x08
|
|
MsgConfigAck byte = 0x09
|
|
)
|
|
|
|
const ControlConnID uint32 = 0
|
|
|
|
type DataTunnel interface {
|
|
SendData(data []byte)
|
|
SetOnData(fn func([]byte))
|
|
SetOnClose(fn func())
|
|
Reconfigure(fps, batch int)
|
|
}
|
|
|
|
func EncodeVP8Config(fps, batch, trackCount int) []byte {
|
|
if fps < 1 {
|
|
fps = 1
|
|
}
|
|
if batch < 1 {
|
|
batch = 1
|
|
}
|
|
if trackCount < 1 {
|
|
trackCount = 1
|
|
}
|
|
if fps > 0xFFFF {
|
|
fps = 0xFFFF
|
|
}
|
|
if batch > 0xFFFF {
|
|
batch = 0xFFFF
|
|
}
|
|
if trackCount > 0xFFFF {
|
|
trackCount = 0xFFFF
|
|
}
|
|
var payload [6]byte
|
|
binary.BigEndian.PutUint16(payload[0:2], uint16(fps))
|
|
binary.BigEndian.PutUint16(payload[2:4], uint16(batch))
|
|
binary.BigEndian.PutUint16(payload[4:6], uint16(trackCount))
|
|
return EncodeFrame(ControlConnID, MsgConfig, payload[:])
|
|
}
|
|
|
|
func DecodeVP8Config(payload []byte) (fps, batch, trackCount int, ok bool) {
|
|
if len(payload) < 4 {
|
|
return 0, 0, 0, false
|
|
}
|
|
fps = int(binary.BigEndian.Uint16(payload[0:2]))
|
|
batch = int(binary.BigEndian.Uint16(payload[2:4]))
|
|
trackCount = 1
|
|
if len(payload) >= 6 {
|
|
trackCount = int(binary.BigEndian.Uint16(payload[4:6]))
|
|
}
|
|
return fps, batch, trackCount, true
|
|
}
|
|
|
|
func EncodeFrame(connID uint32, msgType byte, payload []byte) []byte {
|
|
buf := make([]byte, 4+5+len(payload))
|
|
binary.BigEndian.PutUint32(buf[0:4], uint32(5+len(payload)))
|
|
binary.BigEndian.PutUint32(buf[4:8], connID)
|
|
buf[8] = msgType
|
|
copy(buf[9:], payload)
|
|
return buf
|
|
}
|
|
|
|
func LooksLikeRelayFrame(payload []byte) bool {
|
|
if len(payload) < 9 {
|
|
return false
|
|
}
|
|
frameLen := binary.BigEndian.Uint32(payload[0:4])
|
|
return frameLen >= 5 && int(frameLen)+4 <= len(payload)
|
|
}
|
|
|
|
func DecodeFrames(data []byte, cb func(connID uint32, msgType byte, payload []byte)) {
|
|
for len(data) >= 4 {
|
|
frameLen := int(binary.BigEndian.Uint32(data[0:4]))
|
|
if frameLen < 5 || 4+frameLen > len(data) {
|
|
return
|
|
}
|
|
connID := binary.BigEndian.Uint32(data[4:8])
|
|
msgType := data[8]
|
|
payload := data[9 : 4+frameLen]
|
|
cb(connID, msgType, payload)
|
|
data = data[4+frameLen:]
|
|
}
|
|
}
|