- Network: Layer 3 IP tunnel over QUIC with TUN interfaces and IP pool - FileMask: new noise/obfuscation layer masking traffic as encrypted file downloads - Hysteria outbound: chain Hysteria servers via pluggable outbound
73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package network
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
|
|
"github.com/apernet/quic-go"
|
|
)
|
|
|
|
type FrameType byte
|
|
|
|
const (
|
|
FrameAuth FrameType = 0x01
|
|
FrameAuthOK FrameType = 0x02
|
|
FrameAuthErr FrameType = 0x03
|
|
FrameData FrameType = 0x04
|
|
FrameKeepalive FrameType = 0x05
|
|
)
|
|
|
|
type Frame struct {
|
|
Type FrameType
|
|
Payload []byte
|
|
}
|
|
|
|
func SendFrame(stream *quic.Stream, f *Frame) error {
|
|
buf := make([]byte, 4+1+len(f.Payload))
|
|
binary.BigEndian.PutUint32(buf[:4], uint32(1+len(f.Payload)))
|
|
buf[4] = byte(f.Type)
|
|
copy(buf[5:], f.Payload)
|
|
_, err := stream.Write(buf)
|
|
return err
|
|
}
|
|
|
|
func ReceiveFrame(stream *quic.Stream) (*Frame, error) {
|
|
var lenBuf [4]byte
|
|
if _, err := io.ReadFull(stream, lenBuf[:]); err != nil {
|
|
return nil, err
|
|
}
|
|
frameLen := binary.BigEndian.Uint32(lenBuf[:])
|
|
if frameLen < 1 || frameLen > 65535 {
|
|
return nil, fmt.Errorf("invalid frame length: %d", frameLen)
|
|
}
|
|
frameData := make([]byte, frameLen)
|
|
if _, err := io.ReadFull(stream, frameData); err != nil {
|
|
return nil, err
|
|
}
|
|
return &Frame{
|
|
Type: FrameType(frameData[0]),
|
|
Payload: frameData[1:],
|
|
}, nil
|
|
}
|
|
|
|
func SendAuth(stream *quic.Stream, token string) error {
|
|
return SendFrame(stream, &Frame{Type: FrameAuth, Payload: []byte(token)})
|
|
}
|
|
|
|
func SendAuthOK(stream *quic.Stream, assignedIP net.IP) error {
|
|
return SendFrame(stream, &Frame{Type: FrameAuthOK, Payload: assignedIP.To4()})
|
|
}
|
|
|
|
func SendAuthErr(stream *quic.Stream, reason string) error {
|
|
return SendFrame(stream, &Frame{Type: FrameAuthErr, Payload: []byte(reason)})
|
|
}
|
|
|
|
func SendData(stream *quic.Stream, pkt []byte) error {
|
|
return SendFrame(stream, &Frame{Type: FrameData, Payload: pkt})
|
|
}
|
|
|
|
func SendKeepalive(stream *quic.Stream) error {
|
|
return SendFrame(stream, &Frame{Type: FrameKeepalive})
|
|
}
|