lux/node/lux_node.go

99 lines
2 KiB
Go

package node
import (
"lux/crypto"
"lux/host"
"lux/net"
"lux/proto"
"sync"
)
type LuxNode struct {
router net.LuxRouter
running bool
state LuxNodeState
stateLock sync.RWMutex
}
func NewLuxNode(nodeKey crypto.LuxKey, ks crypto.LuxKeyStore) LuxNode {
return LuxNode{
router: net.NewLuxRouter(nodeKey, ks),
running: false,
state: NewNodeState(),
}
}
func (node *LuxNode) GetRouter() *net.LuxRouter {
return &node.router
}
func (node *LuxNode) GetNodeID() proto.LuxID {
return node.GetRouter().GetThisKey().Id
}
func (node *LuxNode) AddInterior(udpAddr string) error {
return node.router.CreateInboundChannel(net.LuxChannelInterior, udpAddr)
}
func (node *LuxNode) AddExterior(udpAddr string) error {
return node.router.CreateInboundChannel(net.LuxChannelExterior, udpAddr)
}
func (node *LuxNode) GetState() *LuxNodeState {
return &node.state
}
func (node *LuxNode) GetStateLock() *sync.RWMutex {
return &node.stateLock
}
func (node *LuxNode) handleHeartbeat(packet *net.LuxPacket) {
if packet.ChannelType != net.LuxChannelExterior {
log.Error("heartbeat not on exterior!")
return
}
// parse heartbeat
state := host.NewLuxState("")
if err := state.Read(&packet.Buffer); err != nil {
log.Error("failed to parse heartbeat: %v", err)
return
}
// register heartbeat
node.stateLock.Lock()
node.state.RegisterHeartbeat(packet.Target, state)
node.stateLock.Unlock()
log.Debugf("heartbeat from %s", packet.Target.String())
}
func nodeLoop(node *LuxNode) {
router := &node.router
for node.running {
packet, err := router.Recv()
if err != nil {
log.Infof("node recv err %v", err)
}
switch packet.Type {
case net.LuxPacketTypeHeartbeat:
node.handleHeartbeat(&packet)
default:
log.Warningf("unknown packet type %d on chType %d", packet.Type, packet.ChannelType)
}
}
}
func (node *LuxNode) Start() {
node.router.Start()
node.running = true
go nodeLoop(node)
}
func (node *LuxNode) Stop() {
node.running = false
node.router.Stop()
}