59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
package peer
|
|
|
|
import (
|
|
"net/netip"
|
|
"time"
|
|
|
|
"vppn/peer/control"
|
|
)
|
|
|
|
func (a *App) onPing(e PingEvent) {
|
|
peer, ok := a.peersByIP[e.srcVPNIP]
|
|
if !ok {
|
|
// TODO: Log here.
|
|
return
|
|
}
|
|
|
|
now := time.Now()
|
|
|
|
// If we're the server, respond - this is always necessary as it's used to
|
|
// know if peers are up or down.
|
|
if peer.Role == control.Server {
|
|
a.sendPing(peer, e.ping.PingTS)
|
|
}
|
|
|
|
// Compute RTT from server echo.
|
|
if peer.Role == control.Client {
|
|
peer.RTT = now.Sub(time.Unix(0, e.ping.PingTS))
|
|
}
|
|
|
|
// If we're public, nothing more to do.
|
|
if a.isPublic {
|
|
return
|
|
}
|
|
|
|
// We can only learn our own endpoint from directly-connected peers — Dst
|
|
// is the sender's observation of our WG handshake source.
|
|
if peer.State == StateDirect {
|
|
if dst := e.ping.Dst; dst.IsValid() {
|
|
if dst.Addr().Is4() {
|
|
a.selfV4 = dst
|
|
} else {
|
|
a.selfV6 = dst
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
a.addProbe(peer, e.ping.SrcV4, e.ping.SrcV6)
|
|
}
|
|
|
|
func (a *App) addProbe(peer *Peer, v4, v6 netip.AddrPort) {
|
|
endpoint := preferredEndpoint(v4, v6)
|
|
if !endpoint.IsValid() || endpoint == peer.PreferredEndpoint() {
|
|
return
|
|
}
|
|
peer.UpdateEndpoints(v4, v6)
|
|
a.devAddProbe(peer, endpoint)
|
|
}
|