mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-21 06:43:30 +03:00
Add admin panel, manager, node_manager, bandwidth limiter, connection limiter, bonding, failover, vless encryption, mkcp transport
This commit is contained in:
202
transport/v2raykcp/header.go
Normal file
202
transport/v2raykcp/header.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package v2raykcp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// used only by KCP to add an obfuscating header before encrypted payload.
|
||||
type PacketHeader interface {
|
||||
Size() int
|
||||
Serialize([]byte)
|
||||
}
|
||||
|
||||
// NewPacketHeader creates a new PacketHeader instance for the given header type.
|
||||
// Supported values: none, srtp, utp, wechat-video,
|
||||
// dtls, wireguard. Unknown types fall back to no header.
|
||||
func NewPacketHeader(headerType string) PacketHeader {
|
||||
switch headerType {
|
||||
case "srtp":
|
||||
return newSRTPHeader()
|
||||
case "utp":
|
||||
return newUTPHeader()
|
||||
case "wechat-video":
|
||||
return newWechatVideoHeader()
|
||||
case "dtls":
|
||||
return newDTLSHeader()
|
||||
case "wireguard":
|
||||
return newWireguardHeader()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderSize returns the byte size of the header for the given type.
|
||||
func HeaderSize(headerType string) int {
|
||||
switch headerType {
|
||||
case "srtp", "utp", "wireguard":
|
||||
return 4
|
||||
case "wechat-video", "dtls":
|
||||
return 13
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// ----- SRTP -----
|
||||
|
||||
type srtpHeader struct {
|
||||
header uint16
|
||||
number uint16
|
||||
}
|
||||
|
||||
func newSRTPHeader() *srtpHeader {
|
||||
return &srtpHeader{
|
||||
header: 0xB5E8,
|
||||
number: randomUint16(),
|
||||
}
|
||||
}
|
||||
|
||||
func (*srtpHeader) Size() int {
|
||||
return 4
|
||||
}
|
||||
|
||||
func (s *srtpHeader) Serialize(b []byte) {
|
||||
s.number++
|
||||
binary.BigEndian.PutUint16(b, s.header)
|
||||
binary.BigEndian.PutUint16(b[2:], s.number)
|
||||
}
|
||||
|
||||
// ----- UTP -----
|
||||
|
||||
type utpHeader struct {
|
||||
header byte
|
||||
extension byte
|
||||
connectionID uint16
|
||||
}
|
||||
|
||||
func newUTPHeader() *utpHeader {
|
||||
return &utpHeader{
|
||||
header: 1,
|
||||
extension: 0,
|
||||
connectionID: randomUint16(),
|
||||
}
|
||||
}
|
||||
|
||||
func (*utpHeader) Size() int {
|
||||
return 4
|
||||
}
|
||||
|
||||
func (u *utpHeader) Serialize(b []byte) {
|
||||
binary.BigEndian.PutUint16(b, u.connectionID)
|
||||
b[2] = u.header
|
||||
b[3] = u.extension
|
||||
}
|
||||
|
||||
// ----- WeChat Video -----
|
||||
|
||||
type wechatVideoHeader struct {
|
||||
sn uint32
|
||||
}
|
||||
|
||||
func newWechatVideoHeader() *wechatVideoHeader {
|
||||
return &wechatVideoHeader{
|
||||
sn: randomUint32(),
|
||||
}
|
||||
}
|
||||
|
||||
func (*wechatVideoHeader) Size() int {
|
||||
return 13
|
||||
}
|
||||
|
||||
func (vc *wechatVideoHeader) Serialize(b []byte) {
|
||||
vc.sn++
|
||||
b[0] = 0xa1
|
||||
b[1] = 0x08
|
||||
binary.BigEndian.PutUint32(b[2:], vc.sn)
|
||||
b[6] = 0x00
|
||||
b[7] = 0x10
|
||||
b[8] = 0x11
|
||||
b[9] = 0x18
|
||||
b[10] = 0x30
|
||||
b[11] = 0x22
|
||||
b[12] = 0x30
|
||||
}
|
||||
|
||||
// ----- DTLS -----
|
||||
|
||||
type dtlsHeader struct {
|
||||
epoch uint16
|
||||
length uint16
|
||||
sequence uint32
|
||||
}
|
||||
|
||||
func newDTLSHeader() *dtlsHeader {
|
||||
return &dtlsHeader{
|
||||
epoch: randomUint16(),
|
||||
sequence: 0,
|
||||
length: 17,
|
||||
}
|
||||
}
|
||||
|
||||
func (*dtlsHeader) Size() int {
|
||||
return 13
|
||||
}
|
||||
|
||||
func (d *dtlsHeader) Serialize(b []byte) {
|
||||
b[0] = 23 // application data
|
||||
b[1] = 254
|
||||
b[2] = 253
|
||||
b[3] = byte(d.epoch >> 8)
|
||||
b[4] = byte(d.epoch)
|
||||
b[5] = 0
|
||||
b[6] = 0
|
||||
b[7] = byte(d.sequence >> 24)
|
||||
b[8] = byte(d.sequence >> 16)
|
||||
b[9] = byte(d.sequence >> 8)
|
||||
b[10] = byte(d.sequence)
|
||||
d.sequence++
|
||||
b[11] = byte(d.length >> 8)
|
||||
b[12] = byte(d.length)
|
||||
d.length += 17
|
||||
if d.length > 100 {
|
||||
d.length -= 50
|
||||
}
|
||||
}
|
||||
|
||||
// ----- WireGuard -----
|
||||
|
||||
type wireguardHeader struct{}
|
||||
|
||||
func newWireguardHeader() *wireguardHeader {
|
||||
return &wireguardHeader{}
|
||||
}
|
||||
|
||||
func (*wireguardHeader) Size() int {
|
||||
return 4
|
||||
}
|
||||
|
||||
func (*wireguardHeader) Serialize(b []byte) {
|
||||
b[0] = 0x04
|
||||
b[1] = 0x00
|
||||
b[2] = 0x00
|
||||
b[3] = 0x00
|
||||
}
|
||||
|
||||
// ----- helpers -----
|
||||
|
||||
func randomUint16() uint16 {
|
||||
var b [2]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return 0
|
||||
}
|
||||
return binary.BigEndian.Uint16(b[:])
|
||||
}
|
||||
|
||||
func randomUint32() uint32 {
|
||||
var b [4]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return 0
|
||||
}
|
||||
return binary.BigEndian.Uint32(b[:])
|
||||
}
|
||||
Reference in New Issue
Block a user