package node import ( "errors" "net/netip" ) var ( errMalformedPacket = errors.New("malformed packet") errUnknownPacketType = errors.New("unknown packet type") ) const ( packetTypeSyn = iota + 1 packetTypeSynAck packetTypeAck packetTypePing packetTypePong packetTypeRelayed ) // ---------------------------------------------------------------------------- type controlPacket struct { SrcIP byte RemoteAddr netip.AddrPort Payload any } func (p *controlPacket) ParsePayload(buf []byte) (err error) { switch buf[0] { case packetTypeSyn: p.Payload, err = parseSynPacket(buf) case packetTypeSynAck: p.Payload, err = parseSynAckPacket(buf) case packetTypeAck: p.Payload, err = parseAckPacket(buf) default: return errUnknownPacketType } return err } // ---------------------------------------------------------------------------- type synPacket struct { TraceID uint64 // TraceID to match response w/ request. SharedKey [32]byte // Our shared key. RelayIP byte } func (p synPacket) Marshal(buf []byte) []byte { return newBinWriter(buf). Byte(packetTypeSyn). Uint64(p.TraceID). SharedKey(p.SharedKey). Byte(p.RelayIP). Build() } func parseSynPacket(buf []byte) (p synPacket, err error) { err = newBinReader(buf[1:]). Uint64(&p.TraceID). SharedKey(&p.SharedKey). Byte(&p.RelayIP). Error() return } // ---------------------------------------------------------------------------- type synAckPacket struct { TraceID uint64 } func newSynAckPacket(traceID uint64) synAckPacket { return synAckPacket{traceID} } func (p synAckPacket) Marshal(buf []byte) []byte { return newBinWriter(buf). Byte(packetTypeSynAck). Uint64(p.TraceID). Build() } func parseSynAckPacket(buf []byte) (p synAckPacket, err error) { err = newBinReader(buf[1:]). Uint64(&p.TraceID). Error() return } // ---------------------------------------------------------------------------- type ackPacket struct { TraceID uint64 } func (p ackPacket) Marshal(buf []byte) []byte { return newBinWriter(buf). Byte(packetTypeAck). Uint64(p.TraceID). Build() } func parseAckPacket(buf []byte) (p ackPacket, err error) { err = newBinReader(buf[1:]). Uint64(&p.TraceID). Error() return }