package peer import ( "log" "time" "vppn/peer/control" ) 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 in index, removing: %v", wgPeer) a.devRemove(&Peer{wgPeer: wgPeer}) continue } p.wgPeer = wgPeer // Send pings to peers where we're the client. if p.Role == control.Client { a.sendPing(p, now) } switch p.State { case StateProbing: if p.Up() { // Direct handshake succeeded; WG entry already correct. p.State = StateDirect } else if time.Now().After(p.probeDeadline) { // Probe timed out — revert to relay. if a.relay != nil { a.devAddRelayed(p, a.relay.VPNIP) } else { a.devAddPeer(p) } } case StateDirect: // Demotion skips StateProbing — only probe when there is positive // evidence of a direct path (ping or multicast beacon). if !p.IsPublic && !p.Up() { if a.relay != nil { a.devAddRelayed(p, a.relay.VPNIP) } else { a.devAddPeer(p) } } } } // Ensure we have a live relay. if a.relay == nil || !a.relay.Up() { a.switchActiveRelay() } }