vppn/peer/state-clientdirect.go
2025-02-25 02:43:29 +01:00

86 lines
1.6 KiB
Go

package peer
import (
"net/netip"
"time"
)
type stateClientDirect2 struct {
*peerData
lastSeen time.Time
syn packetSyn
}
func enterStateClientDirect2(data *peerData, directAddr netip.AddrPort) peerState {
data.staged.Relay = data.peer.Relay
data.staged.Direct = true
data.staged.DirectAddr = directAddr
data.publish(data.staged)
state := &stateClientDirect2{
peerData: data,
lastSeen: time.Now(),
syn: packetSyn{
TraceID: newTraceID(),
SharedKey: data.staged.DataCipher.Key(),
Direct: true,
},
}
state.Send(state.staged, state.syn)
data.pingTimer.Reset(pingInterval)
state.logf("==> ClientDirect")
return state
}
func (s *stateClientDirect2) logf(str string, args ...any) {
s.peerData.logf("CLNT | "+str, args...)
}
func (s *stateClientDirect2) OnMsg(raw any) peerState {
switch msg := raw.(type) {
case peerUpdateMsg:
return initPeerState(s.peerData, msg.Peer)
case controlMsg[packetAck]:
return s.onAck(msg)
case pingTimerMsg:
return s.onPingTimer()
case controlMsg[packetLocalDiscovery]:
return s
default:
s.logf("Ignoring message: %v", raw)
return s
}
}
func (s *stateClientDirect2) onAck(msg controlMsg[packetAck]) peerState {
if msg.Packet.TraceID != s.syn.TraceID {
return s
}
s.lastSeen = time.Now()
if !s.staged.Up {
s.staged.Up = true
s.publish(s.staged)
s.logf("Got ACK.")
}
s.pubAddrs.Store(msg.Packet.ToAddr)
return s
}
func (s *stateClientDirect2) onPingTimer() peerState {
if time.Since(s.lastSeen) > timeoutInterval {
if s.staged.Up {
s.logf("Timeout.")
}
return initPeerState(s.peerData, s.peer)
}
s.Send(s.staged, s.syn)
return s
}