Files
vppn/peer/on_statetick.go
2026-06-15 20:15:06 +02:00

69 lines
1.7 KiB
Go

package peer
import (
"log"
"time"
"vppn/peer/wginterface"
)
func (a *App) onStateTick() {
wgPeers := a.devPeers()
for _, wgPeer := range wgPeers {
p, ok := a.peersByKey[wgPeer.PublicKey]
if !ok {
log.Printf("Wireguard peer not known. Removing: %v", wgPeer.PublicKey)
a.devRemove(&Peer{wgPeer: wgPeer})
continue
}
p.wgPeer = wgPeer
// Log endpoint changes.
if ep := p.WGEndpoint(); ep != p.EndpointWG {
log.Printf("Client %s %s endpoint: %s -> %s", p.Name, p.VPNIP, p.EndpointWG, ep)
p.EndpointWG = ep
}
switch p.State {
case StateRelayed:
if p.DirectAlive() {
// We may already have a valid direct endpoint due to wireguard
// roaming.
a.devPromote(p)
} else if ep := p.PreferredEndpoint(); ep.IsValid() {
// If we have an ep to probe, add it.
a.devAddProbe(p, ep)
}
case StateProbing:
if time.Since(p.LastHandshakeTime()) < 2*wginterface.ProbeKeepalive {
// Promote probing peers to direct once alive (direct path confirmed
// working).
a.devPromote(p)
} else if ep := p.PreferredEndpoint(); ep.IsValid() && ep != p.ProbeEndpoint {
// Re-start probing if we see a new endpoint.
a.devAddProbe(p, ep)
} else if time.Since(p.ProbeStart) > 8*wginterface.ProbeKeepalive {
// Give up probing if we haven't been able to handshake.
a.devAddRelayed(p)
}
case StateDirect:
if p.IsPublic || a.isPublic || p.Up() {
break
}
// Stale non-public direct peer: demote to relayed and wait for new IP
// information.
a.devAddRelayed(p)
}
}
// Ensure we have a live relay (if we're not public).
if !a.isPublic && (a.relay == nil || !a.relay.Up()) {
a.switchActiveRelay()
}
}