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

73 lines
1.8 KiB
Go

package peer
import (
"log"
"net/netip"
"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 we have an ep to probe, add it.
if ep := p.PreferredEndpoint(); ep.IsValid() {
p.ProbeStart = time.Now()
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.WGEndpoint() {
// Update the probe address if it's changed.
a.devAddProbe(p, ep)
} else if time.Since(p.ProbeStart) > 8*wginterface.ProbeKeepalive {
// Give up probing if we haven't been able to handshake.
p.EndpointV4 = netip.AddrPort{}
p.EndpointV6 = netip.AddrPort{}
p.EndpointLAN = netip.AddrPort{}
a.devAddPeer(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.
p.EndpointV4 = netip.AddrPort{}
p.EndpointV6 = netip.AddrPort{}
p.EndpointLAN = netip.AddrPort{}
a.devAddPeer(p)
}
}
// Ensure we have a live relay (if we're not public).
if !a.isPublic && (a.relay == nil || !a.relay.Up()) {
a.switchActiveRelay()
}
}