Files
vppn/peer/on_tick.go
2026-06-14 08:15:00 +02:00

81 lines
1.9 KiB
Go

package peer
import (
"log"
"net/netip"
"time"
"vppn/peer/control"
"vppn/peer/wginterface"
)
func (a *App) onTick() {
wgPeers := a.devPeers()
now := time.Now().UnixNano()
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
}
// Send pings to peers where we're the client.
if p.Role == control.Client {
a.sendPing(p, now)
}
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()
}
}