package node import ( "errors" "net/netip" "time" "unsafe" ) var errMalformedPacket = errors.New("malformed packet") const ( packetTypePing = iota + 1 packetTypePong ) // ---------------------------------------------------------------------------- type controlPacket struct { SrcIP byte RemoteAddr netip.AddrPort Payload any } // ---------------------------------------------------------------------------- // A pingPacket is sent from a node acting as a client, to a node acting // as a server. It always contains the shared key the client is expecting // to use for data encryption with the server. type pingPacket struct { SentAt int64 // UnixMilli. SharedKey [32]byte } func newPingPacket(sharedKey []byte) (pp pingPacket) { pp.SentAt = time.Now().UnixMilli() copy(pp.SharedKey[:], sharedKey) return } func (p pingPacket) Marshal(buf []byte) []byte { buf = buf[:41] buf[0] = packetTypePing *(*uint64)(unsafe.Pointer(&buf[1])) = uint64(p.SentAt) copy(buf[9:41], p.SharedKey[:]) return buf } func parsePingPacket(buf []byte) (p pingPacket, err error) { if len(buf) != 41 { return p, errMalformedPacket } p.SentAt = *(*int64)(unsafe.Pointer(&buf[1])) copy(p.SharedKey[:], buf[9:41]) return } // ---------------------------------------------------------------------------- // A pongPacket is sent by a node in a server role in response to a pingPacket. type pongPacket struct { SentAt int64 // UnixMilli. RecvdAt int64 // UnixMilli. } func newPongPacket(sentAt int64) (pp pongPacket) { pp.SentAt = sentAt pp.RecvdAt = time.Now().UnixMilli() return } func (p pongPacket) Marshal(buf []byte) []byte { buf = buf[:17] buf[0] = packetTypePong *(*uint64)(unsafe.Pointer(&buf[1])) = uint64(p.SentAt) *(*uint64)(unsafe.Pointer(&buf[9])) = uint64(p.RecvdAt) return buf } func parsePongPacket(buf []byte) (p pongPacket, err error) { if len(buf) != 17 { return p, errMalformedPacket } p.SentAt = *(*int64)(unsafe.Pointer(&buf[1])) p.RecvdAt = *(*int64)(unsafe.Pointer(&buf[9])) return }