130 lines
3.1 KiB
Go
130 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.
|
|
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{}
|