130 lines
3.5 KiB
Go
130 lines
3.5 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"sirherobrine23.com.br/go-bds/go-playit/api"
|
|
"sirherobrine23.com.br/go-bds/go-playit/proto"
|
|
"sirherobrine23.com.br/go-bds/go-playit/xcode"
|
|
)
|
|
|
|
type AgentSettings struct {
|
|
Api *api.ApiClient
|
|
}
|
|
|
|
type PlayitAgent struct {
|
|
Config *AgentSettings // Agent config
|
|
keepRunning bool // Keep running new connections from Controller
|
|
clientAcceptTcp chan *proto.NewClient // TCP Clients
|
|
UdpRxPacket chan *proto.UdpChannelDetails // UDP Packets
|
|
|
|
AgentInfo *api.AgentRunData // Agent run data
|
|
ForceUpdateAgentInfo bool // Force agent get new data from API
|
|
|
|
// Connected
|
|
|
|
ControlAddr netip.AddrPort // Current Controller address
|
|
PacketIo *net.UDPConn // Local listen UDP
|
|
PongLatest proto.Pong // Last Pong return from controller
|
|
|
|
// Estabilished
|
|
|
|
PongAtAuth proto.Pong // Pong on authenticate
|
|
Registered *proto.AgentRegistered // Agent register from controller
|
|
CurrentPing xcode.Option[uint32] // Current ping
|
|
ClockOffset int64 // Clock offset
|
|
ForceExpired bool // Force expire auth
|
|
|
|
// Maintened
|
|
|
|
LastControlTargets []netip.AddrPort // Last controller addresses
|
|
LastKeepAlive time.Time // Last keep alive from agent
|
|
LastPing time.Time // Last ping to controller
|
|
LastPong time.Time // Last pong return from controller
|
|
LastUdpAuth time.Time // Last send auth to controller
|
|
}
|
|
|
|
func NewPlayitAgent(config *AgentSettings) (*PlayitAgent, error) {
|
|
agent := &PlayitAgent{
|
|
keepRunning: true,
|
|
clientAcceptTcp: make(chan *proto.NewClient),
|
|
UdpRxPacket: make(chan *proto.UdpChannelDetails),
|
|
Config: config,
|
|
}
|
|
|
|
if err := connectToFirst(agent); err != nil {
|
|
close(agent.clientAcceptTcp)
|
|
close(agent.UdpRxPacket)
|
|
return nil, fmt.Errorf("cannot connect to first address: %w", err)
|
|
}
|
|
|
|
if err := agent.setupConnection(); err != nil {
|
|
close(agent.clientAcceptTcp)
|
|
close(agent.UdpRxPacket)
|
|
return nil, fmt.Errorf("cannot setup connection: %w", err)
|
|
}
|
|
|
|
// Start agent packet process
|
|
go agent.run()
|
|
|
|
return agent, nil
|
|
}
|
|
|
|
func (agent *PlayitAgent) Close() (err error) {
|
|
defer func() { recover() }()
|
|
if err = agent.PacketIo.Close(); err != nil {
|
|
return
|
|
}
|
|
|
|
if agent.clientAcceptTcp != nil {
|
|
close(agent.clientAcceptTcp)
|
|
agent.clientAcceptTcp = nil
|
|
}
|
|
if agent.UdpRxPacket != nil {
|
|
close(agent.UdpRxPacket)
|
|
agent.UdpRxPacket = nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Process controller packets
|
|
func (agent *PlayitAgent) run() {
|
|
lastRunData := time.Now()
|
|
lastControlAddr := lastRunData
|
|
|
|
for agent.keepRunning {
|
|
if agent.AgentInfo == nil || len(agent.AgentInfo.Tunnels) == 0 || agent.ForceUpdateAgentInfo || lastRunData.Add(time.Minute).Compare(time.Now()) < 0 {
|
|
agent.AgentInfo, _ = agent.Config.Api.AgentInfo()
|
|
lastRunData = time.Now()
|
|
agent.ForceUpdateAgentInfo = false
|
|
}
|
|
|
|
if lastControlAddr.Add(time.Millisecond*30_000).Compare(time.Now()) < 0 {
|
|
lastControlAddr = time.Now()
|
|
agent.reloadControlAddrs()
|
|
// if err := ; err != nil {
|
|
// fmt.Fprintf(os.Stderr, "cannot reload control addresses: %s\n", err)
|
|
// }
|
|
}
|
|
|
|
// Update PacketIo
|
|
event, err := agent.update()
|
|
if err != nil {
|
|
// fmt.Fprintf(os.Stderr, "cannot update agent: %s\n", err)
|
|
continue
|
|
} else if event == nil {
|
|
continue
|
|
}
|
|
|
|
switch {
|
|
case event.NewClientTcp != nil:
|
|
agent.clientAcceptTcp <- event.NewClientTcp
|
|
case event.UdpRxPacket != nil:
|
|
agent.UdpRxPacket <- event.UdpRxPacket
|
|
}
|
|
}
|
|
}
|