86 lines
1.6 KiB
Go
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
|
|
}
|