61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
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()
|
|
}
|
|
}
|