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{}