lux/node/lux_node_sync.go
2025-01-18 16:06:45 +02:00

81 lines
1.5 KiB
Go

package node
import (
"fmt"
"lux/proto"
"net/netip"
ipnet "net"
)
type LuxNodeSync struct {
Synced map[proto.LuxID]struct{}
Neighbors map[proto.LuxID]*ipnet.UDPAddr
SyncState LuxNodeState
}
func NewLuxNodeSync() LuxNodeSync {
return LuxNodeSync{
Synced: make(map[proto.LuxID]struct{}),
Neighbors: make(map[proto.LuxID]*ipnet.UDPAddr),
SyncState: LuxNodeState{},
}
}
func (sync *LuxNodeSync) Read(rd *proto.LuxBuffer) error {
// read synced list
syncNum, err := rd.ReadUint16()
if err != nil {
return err
}
for i := 0; i < int(syncNum); i++ {
id := proto.LuxID{}
if err := id.Read(rd); err != nil {
return err
}
sync.Synced[id] = struct{}{}
}
// read neighbors
neighborNum, err := rd.ReadUint16()
if err != nil {
return err
}
for i := 0; i < int(neighborNum); i++ {
id := proto.LuxID{}
if err := id.Read(rd); err != nil {
return err
}
ipOctets, err := rd.ReadVarBlock()
if err != nil {
return err
}
portNum, err := rd.ReadUint16()
if err != nil {
return err
}
// TODO: move this to proto
var addrPort netip.AddrPort
switch len(ipOctets) {
case ipnet.IPv4len:
addrPort = netip.AddrPortFrom(netip.AddrFrom4([4]byte(ipOctets)), portNum)
case ipnet.IPv6len:
addrPort = netip.AddrPortFrom(netip.AddrFrom16([16]byte(ipOctets)), portNum)
default:
return fmt.Errorf("received wrong sized neighbor ip len %d", len(ipOctets))
}
sync.Neighbors[id] = ipnet.UDPAddrFromAddrPort(addrPort)
}
// read sync state
err = sync.SyncState.Read(rd)
if err != nil {
return err
}
return nil
}