Files
picomap/lib/wire/wire.go

58 lines
1.3 KiB
Go

package wire
import (
"fmt"
"github.com/theater/picomap/lib/halfsiphash"
"github.com/theater/picomap/lib/msgpack"
)
var HashKey = [8]byte{}
type ResponseBOOTSEL struct{}
type RequestBOOTSEL struct{}
type Envelope struct {
Checksum uint32
Payload []byte
}
func init() {
msgpack.RegisterExt(0, (*Envelope)(nil))
msgpack.RegisterExt(1, (*ResponseBOOTSEL)(nil))
msgpack.RegisterExt(2, (*RequestBOOTSEL)(nil))
}
func EncodeMessage(msg any) ([]byte, error) {
payload, err := msgpack.Marshal(msg)
if err != nil {
return nil, fmt.Errorf("encode inner: %w", err)
}
checksum := halfsiphash.Sum32(payload, HashKey)
env := Envelope{Checksum: checksum, Payload: payload}
data, err := msgpack.Marshal(&env)
if err != nil {
return nil, fmt.Errorf("encode envelope: %w", err)
}
return data, nil
}
func DecodeMessage(data []byte) (any, error) {
var env Envelope
if err := msgpack.Unmarshal(data, &env); err != nil {
return nil, fmt.Errorf("decode envelope: %w", err)
}
expected := halfsiphash.Sum32(env.Payload, HashKey)
if env.Checksum != expected {
return nil, fmt.Errorf("checksum mismatch: got %08x, want %08x", env.Checksum, expected)
}
var inner any
if err := msgpack.Unmarshal(env.Payload, &inner); err != nil {
return nil, fmt.Errorf("decode inner: %w", err)
}
return inner, nil
}