vppn/peer/state-clientinit.go
2025-02-25 08:56:49 +01:00

86 lines
1.8 KiB
Go

package peer
import (
"net/netip"
"time"
)
type stateClientInit2 struct {
*peerData
startedAt time.Time
traceID uint64
}
func enterStateClientInit2(data *peerData) peerState {
ip, ipValid := netip.AddrFromSlice(data.peer.PublicIP)
data.staged.Up = false
data.staged.Relay = false
data.staged.Direct = ipValid
data.staged.DirectAddr = netip.AddrPortFrom(ip, data.peer.Port)
data.staged.PubSignKey = data.peer.PubSignKey
data.staged.ControlCipher = newControlCipher(data.privKey, data.peer.PubKey)
data.staged.DataCipher = newDataCipher()
data.publish(data.staged)
state := &stateClientInit2{
peerData: data,
startedAt: time.Now(),
traceID: newTraceID(),
}
state.sendInit()
data.pingTimer.Reset(pingInterval)
state.logf("==> ClientInit")
return state
}
func (s *stateClientInit2) logf(str string, args ...any) {
s.peerData.logf("INIT | "+str, args...)
}
func (s *stateClientInit2) OnMsg(raw any) peerState {
switch msg := raw.(type) {
case peerUpdateMsg:
return initPeerState(s.peerData, msg.Peer)
case controlMsg[packetInit]:
return s.onInit(msg)
case pingTimerMsg:
return s.onPing()
default:
s.logf("Ignoring message: %v", raw)
return s
}
}
func (s *stateClientInit2) onInit(msg controlMsg[packetInit]) peerState {
if msg.Packet.TraceID != s.traceID {
s.logf("Invalid trace ID on INIT.")
return s
}
s.logf("Got INIT version %d.", msg.Packet.Version)
return enterStateClient(s.peerData)
}
func (s *stateClientInit2) onPing() peerState {
if time.Since(s.startedAt) > timeoutInterval {
s.logf("Init timeout. Assuming version 1.")
return enterStateClient(s.peerData)
}
s.sendInit()
return s
}
func (s *stateClientInit2) sendInit() {
s.traceID = newTraceID()
init := packetInit{
TraceID: s.traceID,
Direct: s.staged.Direct,
Version: version,
}
s.Send(s.staged, init)
}