mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-22 16:28:30 +02:00
refactor(agent/stream): rename payload.go to header.go and update protocol header format
- Rename payload.go to header.go for clarity - Add HostLength and PortLength fields to avoid NUL-terminated string scanning - Add padding bytes to make struct size match headerSize - Remove unused StreamRequestPayload struct and WriteTo method - Add runtime size validation in init() - Update PROTOCOL.md documentation
This commit is contained in:
@@ -7,15 +7,18 @@ This package implements a small header-based handshake that allows an authentica
|
|||||||
The on-wire header is a fixed-size binary blob:
|
The on-wire header is a fixed-size binary blob:
|
||||||
|
|
||||||
- `Version` (8 bytes)
|
- `Version` (8 bytes)
|
||||||
|
- `HostLength` (1 byte)
|
||||||
- `Host` (255 bytes, NUL padded)
|
- `Host` (255 bytes, NUL padded)
|
||||||
|
- `PortLength` (1 byte)
|
||||||
- `Port` (5 bytes, NUL padded)
|
- `Port` (5 bytes, NUL padded)
|
||||||
- `Checksum` (4 bytes, big-endian CRC32)
|
- `Checksum` (4 bytes, big-endian CRC32)
|
||||||
|
- `Padding` (14 bytes)
|
||||||
|
|
||||||
Total: `headerSize = 8 + 255 + 5 + 4 = 272` bytes.
|
Total: `headerSize = 8 + 1 + 255 + 1 + 5 + 4 + 14 = 288` bytes.
|
||||||
|
|
||||||
Checksum is `crc32.ChecksumIEEE(header[0:headerSize-4])`.
|
Checksum is `crc32.ChecksumIEEE(header[0:headerSize-4])`.
|
||||||
|
|
||||||
See [`StreamRequestHeader`](payload.go:26).
|
See [`StreamRequestHeader`](header.go:10).
|
||||||
|
|
||||||
## TCP behavior
|
## TCP behavior
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
package stream
|
package stream
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"io"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,7 +15,7 @@ const (
|
|||||||
portSize = 5
|
portSize = 5
|
||||||
checksumSize = 4 // crc32 checksum
|
checksumSize = 4 // crc32 checksum
|
||||||
|
|
||||||
headerSize = versionSize + hostSize + portSize + checksumSize
|
headerSize = 288
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = [versionSize]byte{'0', '.', '1', '.', '0', 0, 0, 0}
|
var version = [versionSize]byte{'0', '.', '1', '.', '0', 0, 0, 0}
|
||||||
@@ -24,15 +23,23 @@ var version = [versionSize]byte{'0', '.', '1', '.', '0', 0, 0, 0}
|
|||||||
var ErrInvalidHeader = errors.New("invalid header")
|
var ErrInvalidHeader = errors.New("invalid header")
|
||||||
|
|
||||||
type StreamRequestHeader struct {
|
type StreamRequestHeader struct {
|
||||||
Version [versionSize]byte
|
Version [versionSize]byte
|
||||||
Host [hostSize]byte
|
|
||||||
Port [portSize]byte
|
HostLength uint8
|
||||||
|
Host [hostSize]byte
|
||||||
|
|
||||||
|
PortLength uint8
|
||||||
|
Port [portSize]byte
|
||||||
|
|
||||||
Checksum [checksumSize]byte
|
Checksum [checksumSize]byte
|
||||||
|
|
||||||
|
_ [14]byte // padding to make the header size match the size of the struct
|
||||||
}
|
}
|
||||||
|
|
||||||
type StreamRequestPayload struct {
|
func init() {
|
||||||
StreamRequestHeader
|
if headerSize != reflect.TypeFor[StreamRequestHeader]().Size() {
|
||||||
Data []byte
|
panic("headerSize does not match the size of StreamRequestHeader")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStreamRequestHeader(host, port string) (*StreamRequestHeader, error) {
|
func NewStreamRequestHeader(host, port string) (*StreamRequestHeader, error) {
|
||||||
@@ -44,7 +51,9 @@ func NewStreamRequestHeader(host, port string) (*StreamRequestHeader, error) {
|
|||||||
}
|
}
|
||||||
header := &StreamRequestHeader{}
|
header := &StreamRequestHeader{}
|
||||||
copy(header.Version[:], version[:])
|
copy(header.Version[:], version[:])
|
||||||
|
header.HostLength = uint8(len(host))
|
||||||
copy(header.Host[:], host)
|
copy(header.Host[:], host)
|
||||||
|
header.PortLength = uint8(len(port))
|
||||||
copy(header.Port[:], port)
|
copy(header.Port[:], port)
|
||||||
header.updateChecksum()
|
header.updateChecksum()
|
||||||
return header, nil
|
return header, nil
|
||||||
@@ -54,39 +63,20 @@ func ToHeader(buf [headerSize]byte) *StreamRequestHeader {
|
|||||||
return (*StreamRequestHeader)(unsafe.Pointer(&buf[0]))
|
return (*StreamRequestHeader)(unsafe.Pointer(&buf[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteTo implements the io.WriterTo interface.
|
|
||||||
func (p *StreamRequestPayload) WriteTo(w io.Writer) (n int64, err error) {
|
|
||||||
n1, err := w.Write(p.StreamRequestHeader.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(p.Data) == 0 {
|
|
||||||
return int64(n1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
n2, err := w.Write(p.Data)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return int64(n1) + int64(n2), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StreamRequestHeader) GetHostPort() (string, string) {
|
func (h *StreamRequestHeader) GetHostPort() (string, string) {
|
||||||
hostEnd := bytes.IndexByte(h.Host[:], 0)
|
return string(h.Host[:h.HostLength]), string(h.Port[:h.PortLength])
|
||||||
portEnd := bytes.IndexByte(h.Port[:], 0)
|
|
||||||
if hostEnd == -1 {
|
|
||||||
hostEnd = hostSize
|
|
||||||
}
|
|
||||||
if portEnd == -1 {
|
|
||||||
portEnd = portSize
|
|
||||||
}
|
|
||||||
return string(h.Host[:hostEnd]), string(h.Port[:portEnd])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StreamRequestHeader) Validate() bool {
|
func (h *StreamRequestHeader) Validate() bool {
|
||||||
if h.Version != version {
|
if h.Version != version {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if h.HostLength > hostSize {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if h.PortLength > portSize {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return h.validateChecksum()
|
return h.validateChecksum()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,9 +91,9 @@ func (h *StreamRequestHeader) validateChecksum() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *StreamRequestHeader) BytesWithoutChecksum() []byte {
|
func (h *StreamRequestHeader) BytesWithoutChecksum() []byte {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(h)), headerSize-checksumSize)
|
return (*[headerSize - checksumSize]byte)(unsafe.Pointer(h))[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StreamRequestHeader) Bytes() []byte {
|
func (h *StreamRequestHeader) Bytes() []byte {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(h)), headerSize)
|
return (*[headerSize]byte)(unsafe.Pointer(h))[:]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user