diff --git a/peer/on_statetick.go b/peer/on_statetick.go index a35f19c..c996346 100644 --- a/peer/on_statetick.go +++ b/peer/on_statetick.go @@ -28,8 +28,12 @@ func (a *App) onStateTick() { switch p.State { case StateRelayed: - // If we have an ep to probe, add it. - if ep := p.PreferredEndpoint(); ep.IsValid() { + 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) } diff --git a/peer/remote.go b/peer/remote.go index 22ccb5f..de90464 100644 --- a/peer/remote.go +++ b/peer/remote.go @@ -7,6 +7,7 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "vppn/peer/control" + "vppn/peer/wginterface" ) type PeerState string @@ -61,6 +62,11 @@ func (p *Peer) Up() bool { return time.Since(p.LastPing) < 3*PingInterval } +func (p *Peer) DirectAlive() bool { + return p.WGEndpoint().IsValid() && + time.Since(p.LastHandshakeTime()) < 2*wginterface.ProbeKeepalive +} + func (p *Peer) CanRelay() bool { return p.IsRelay && p.Up() }