0d84b07f68
CI / docker (push) Successful in 1m58s
Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package protocol
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
const (
|
|
MsgRegister byte = 1
|
|
MsgRegisterAck byte = 2
|
|
MsgPing byte = 3
|
|
MsgPong byte = 4
|
|
MsgOpenStream byte = 5
|
|
MsgStreamReady byte = 6
|
|
MsgClose byte = 7
|
|
)
|
|
|
|
const (
|
|
ConnTypeTCP = "tcp"
|
|
ConnTypeUDP = "udp"
|
|
ConnTypeHTTP = "http"
|
|
)
|
|
|
|
type RegisterPayload struct {
|
|
VerifyKey string `json:"verify_key"`
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
type RegisterAckPayload struct {
|
|
ClientID uint `json:"client_id"`
|
|
Message string `json:"message"`
|
|
OK bool `json:"ok"`
|
|
}
|
|
|
|
type LinkMeta struct {
|
|
ConnType string `json:"conn_type"`
|
|
Target string `json:"target"`
|
|
RemoteAddr string `json:"remote_addr"`
|
|
StreamID uint32 `json:"stream_id"`
|
|
}
|
|
|
|
func WriteMessage(w io.Writer, msgType byte, payload interface{}) error {
|
|
var body []byte
|
|
var err error
|
|
if payload != nil {
|
|
body, err = json.Marshal(payload)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
header := make([]byte, 5)
|
|
header[0] = msgType
|
|
binary.BigEndian.PutUint32(header[1:], uint32(len(body)))
|
|
if _, err := w.Write(header); err != nil {
|
|
return err
|
|
}
|
|
if len(body) > 0 {
|
|
_, err = w.Write(body)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func ReadMessage(r io.Reader) (byte, []byte, error) {
|
|
header := make([]byte, 5)
|
|
if _, err := io.ReadFull(r, header); err != nil {
|
|
return 0, nil, err
|
|
}
|
|
msgType := header[0]
|
|
length := binary.BigEndian.Uint32(header[1:])
|
|
if length == 0 {
|
|
return msgType, nil, nil
|
|
}
|
|
if length > 1<<20 {
|
|
return 0, nil, fmt.Errorf("message too large: %d", length)
|
|
}
|
|
body := make([]byte, length)
|
|
if _, err := io.ReadFull(r, body); err != nil {
|
|
return 0, nil, err
|
|
}
|
|
return msgType, body, nil
|
|
}
|
|
|
|
func ParseRegister(body []byte) (*RegisterPayload, error) {
|
|
var p RegisterPayload
|
|
if err := json.Unmarshal(body, &p); err != nil {
|
|
return nil, err
|
|
}
|
|
return &p, nil
|
|
}
|
|
|
|
func ParseLinkMeta(body []byte) (*LinkMeta, error) {
|
|
var p LinkMeta
|
|
if err := json.Unmarshal(body, &p); err != nil {
|
|
return nil, err
|
|
}
|
|
return &p, nil
|
|
}
|