package peer import ( "log" "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. // // We make sure we don't set a private address as our public address since we // may be connected via LAN to some peers. if peer.State == StateDirect { if dst := e.ping.Dst; addrIsRoutable(e.ping.Dst) { if dst.Addr().Is4() { if dst != a.selfV4 { log.Printf("Local IPv4 updated: %s -> %s", a.selfV4, dst) a.selfV4 = dst } } else { if dst != a.selfV6 { log.Printf("Local IPv6 updated: %s -> %s", a.selfV6, dst) a.selfV6 = dst } } } return } peer.UpdateEndpoints(e.ping.SrcV4, e.ping.SrcV6) } func addrIsRoutable(addrPort netip.AddrPort) bool { if addrPort.Port() == 0 { return false } addr := addrPort.Addr() return addr.IsGlobalUnicast() && !addr.IsPrivate() }