164 lines
3.4 KiB
Go
164 lines
3.4 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
|
|
packetTypeAddrReq
|
|
packetTypeAddrResp
|
|
)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
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)
|
|
case packetTypeAddrReq:
|
|
p.Payload, err = parseAddrReqPacket(buf)
|
|
case packetTypeAddrResp:
|
|
p.Payload, err = parseAddrRespPacket(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
|
|
RecvAddr netip.AddrPort
|
|
}
|
|
|
|
func (p synAckPacket) Marshal(buf []byte) []byte {
|
|
return newBinWriter(buf).
|
|
Byte(packetTypeSynAck).
|
|
Uint64(p.TraceID).
|
|
AddrPort(p.RecvAddr).
|
|
Build()
|
|
}
|
|
|
|
func parseSynAckPacket(buf []byte) (p synAckPacket, err error) {
|
|
err = newBinReader(buf[1:]).
|
|
Uint64(&p.TraceID).
|
|
AddrPort(&p.RecvAddr).
|
|
Error()
|
|
return
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type ackPacket struct {
|
|
TraceID uint64
|
|
SendAddr netip.AddrPort // Address of the sender.
|
|
RecvAddr netip.AddrPort // Address of the recipient as seen by sender.
|
|
}
|
|
|
|
func (p ackPacket) Marshal(buf []byte) []byte {
|
|
return newBinWriter(buf).
|
|
Byte(packetTypeAck).
|
|
Uint64(p.TraceID).
|
|
AddrPort(p.SendAddr).
|
|
AddrPort(p.RecvAddr).
|
|
Build()
|
|
}
|
|
|
|
func parseAckPacket(buf []byte) (p ackPacket, err error) {
|
|
err = newBinReader(buf[1:]).
|
|
Uint64(&p.TraceID).
|
|
AddrPort(&p.SendAddr).
|
|
AddrPort(&p.RecvAddr).
|
|
Error()
|
|
return
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type addrReqPacket struct {
|
|
TraceID uint64
|
|
}
|
|
|
|
func (p addrReqPacket) Marshal(buf []byte) []byte {
|
|
return newBinWriter(buf).
|
|
Byte(packetTypeAddrReq).
|
|
Uint64(p.TraceID).
|
|
Build()
|
|
}
|
|
|
|
func parseAddrReqPacket(buf []byte) (p addrReqPacket, err error) {
|
|
err = newBinReader(buf[1:]).
|
|
Uint64(&p.TraceID).
|
|
Error()
|
|
return
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type addrRespPacket struct {
|
|
TraceID uint64
|
|
Addr netip.AddrPort
|
|
}
|
|
|
|
func (p addrRespPacket) Marshal(buf []byte) []byte {
|
|
return newBinWriter(buf).
|
|
Byte(packetTypeAddrResp).
|
|
Uint64(p.TraceID).
|
|
AddrPort(p.Addr).
|
|
Build()
|
|
}
|
|
|
|
func parseAddrRespPacket(buf []byte) (p addrRespPacket, err error) {
|
|
err = newBinReader(buf[1:]).
|
|
Uint64(&p.TraceID).
|
|
AddrPort(&p.Addr).
|
|
Error()
|
|
return
|
|
}
|