vppn/node/packets.go
2025-01-22 14:09:43 +01:00

131 lines
3.1 KiB
Go

package node
import (
"errors"
"net/netip"
)
var (
errMalformedPacket = errors.New("malformed packet")
errUnknownPacketType = errors.New("unknown packet type")
)
const (
packetTypeSyn = iota + 1
packetTypeSynAck
packetTypeAck
packetTypeProbe
packetTypeAddrDiscovery
)
// ----------------------------------------------------------------------------
type synPacket struct {
TraceID uint64 // TraceID to match response w/ request.
// TODO: SentAt int64 // Unixmilli.
SharedKey [32]byte // Our shared key.
Direct bool
PossibleAddrs [8]netip.AddrPort // Possible public addresses of the sender.
}
func (p synPacket) Marshal(buf []byte) []byte {
return newBinWriter(buf).
Byte(packetTypeSyn).
Uint64(p.TraceID).
SharedKey(p.SharedKey).
Bool(p.Direct).
AddrPort(p.PossibleAddrs[0]).
AddrPort(p.PossibleAddrs[1]).
AddrPort(p.PossibleAddrs[2]).
AddrPort(p.PossibleAddrs[3]).
AddrPort(p.PossibleAddrs[4]).
AddrPort(p.PossibleAddrs[5]).
AddrPort(p.PossibleAddrs[6]).
AddrPort(p.PossibleAddrs[7]).
Build()
}
func parseSynPacket(buf []byte) (p synPacket, err error) {
err = newBinReader(buf[1:]).
Uint64(&p.TraceID).
SharedKey(&p.SharedKey).
Bool(&p.Direct).
AddrPort(&p.PossibleAddrs[0]).
AddrPort(&p.PossibleAddrs[1]).
AddrPort(&p.PossibleAddrs[2]).
AddrPort(&p.PossibleAddrs[3]).
AddrPort(&p.PossibleAddrs[4]).
AddrPort(&p.PossibleAddrs[5]).
AddrPort(&p.PossibleAddrs[6]).
AddrPort(&p.PossibleAddrs[7]).
Error()
return
}
// ----------------------------------------------------------------------------
type ackPacket struct {
TraceID uint64
ToAddr netip.AddrPort
PossibleAddrs [8]netip.AddrPort // Possible public addresses of the sender.
}
func (p ackPacket) Marshal(buf []byte) []byte {
return newBinWriter(buf).
Byte(packetTypeAck).
Uint64(p.TraceID).
AddrPort(p.ToAddr).
AddrPort(p.PossibleAddrs[0]).
AddrPort(p.PossibleAddrs[1]).
AddrPort(p.PossibleAddrs[2]).
AddrPort(p.PossibleAddrs[3]).
AddrPort(p.PossibleAddrs[4]).
AddrPort(p.PossibleAddrs[5]).
AddrPort(p.PossibleAddrs[6]).
AddrPort(p.PossibleAddrs[7]).
Build()
}
func parseAckPacket(buf []byte) (p ackPacket, err error) {
err = newBinReader(buf[1:]).
Uint64(&p.TraceID).
AddrPort(&p.ToAddr).
AddrPort(&p.PossibleAddrs[0]).
AddrPort(&p.PossibleAddrs[1]).
AddrPort(&p.PossibleAddrs[2]).
AddrPort(&p.PossibleAddrs[3]).
AddrPort(&p.PossibleAddrs[4]).
AddrPort(&p.PossibleAddrs[5]).
AddrPort(&p.PossibleAddrs[6]).
AddrPort(&p.PossibleAddrs[7]).
Error()
return
}
// ----------------------------------------------------------------------------
// A probeReqPacket is sent from a client to a server to determine if direct
// UDP communication can be used.
type probePacket struct {
TraceID uint64
}
func (p probePacket) Marshal(buf []byte) []byte {
return newBinWriter(buf).
Byte(packetTypeProbe).
Uint64(p.TraceID).
Build()
}
func parseProbePacket(buf []byte) (p probePacket, err error) {
err = newBinReader(buf[1:]).
Uint64(&p.TraceID).
Error()
return
}
// ----------------------------------------------------------------------------
type localDiscoveryPacket struct{}