mirror of
https://github.com/fosrl/olm.git
synced 2026-07-17 03:19:55 +00:00
Rapid test the local endpoints as well
This commit is contained in:
@@ -196,7 +196,7 @@ func (pm *PeerManager) AddPeer(siteConfig SiteConfig) error {
|
||||
|
||||
// Perform rapid initial holepunch test (outside of lock to avoid blocking)
|
||||
// This quickly determines if holepunch is viable and triggers relay if not
|
||||
go pm.performRapidInitialTest(siteConfig.SiteId, siteConfig.Endpoint)
|
||||
go pm.performRapidInitialTest(siteConfig.SiteId, siteConfig.Endpoint, siteConfig.LocalEndpoints)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -868,15 +868,43 @@ endpoint=%s:%d`, util.FixKey(peer.PublicKey), formattedEndpoint, relayPort)
|
||||
}
|
||||
|
||||
// performRapidInitialTest performs a rapid holepunch test for a newly added peer.
|
||||
// If the test fails, it immediately requests relay to minimize connection delay.
|
||||
// This runs in a goroutine to avoid blocking AddPeer.
|
||||
func (pm *PeerManager) performRapidInitialTest(siteId int, endpoint string) {
|
||||
// It races a test of the public endpoint against a test of the local candidate endpoints
|
||||
// (if any) and waits for both to finish before acting, so we never request relay only to
|
||||
// have it immediately superseded by a local connection (or vice versa). Local wins if it's
|
||||
// viable at all; otherwise relay is requested only if the public endpoint isn't viable.
|
||||
// This runs in a goroutine to avoid blocking AddPeer - the peer already starts out pointed
|
||||
// at the public endpoint (set synchronously in AddPeer), so this just settles the peer onto
|
||||
// its steady-state connection within ~1-2 seconds.
|
||||
func (pm *PeerManager) performRapidInitialTest(siteId int, endpoint string, localEndpoints []string) {
|
||||
if pm.peerMonitor == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Perform rapid test - this takes ~1-2 seconds max
|
||||
holepunchViable := pm.peerMonitor.RapidTestPeer(siteId, endpoint)
|
||||
var wg sync.WaitGroup
|
||||
var localWinner string
|
||||
var holepunchViable bool
|
||||
|
||||
if len(localEndpoints) > 0 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
localWinner = pm.peerMonitor.RapidTestLocalEndpoints(siteId, localEndpoints)
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
holepunchViable = pm.peerMonitor.RapidTestPeer(siteId, endpoint)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if localWinner != "" {
|
||||
logger.Info("Rapid test: local connection viable for site %d, switching to %s", siteId, localWinner)
|
||||
pm.LocalPeer(siteId, localWinner)
|
||||
return
|
||||
}
|
||||
|
||||
if !holepunchViable {
|
||||
// Holepunch failed rapid test, request relay immediately
|
||||
|
||||
@@ -370,6 +370,49 @@ func (pm *PeerMonitor) RapidTestPeer(siteID int, endpoint string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RapidTestLocalEndpoints performs a rapid connectivity test of local candidate endpoints
|
||||
// for a newly added peer, so local viability is known within the same ~1-2 second window as
|
||||
// RapidTestPeer's public-endpoint test (rather than waiting for the next backoff-loop tick,
|
||||
// which could be tens of seconds away). Candidates are tried in order (best-to-worst) and
|
||||
// the first reachable one wins. Returns the winning endpoint, or "" if none are reachable.
|
||||
func (pm *PeerMonitor) RapidTestLocalEndpoints(siteID int, endpoints []string) string {
|
||||
if pm.holepunchTester == nil || len(endpoints) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
pm.mutex.Lock()
|
||||
timeout := pm.rapidTestTimeout
|
||||
pm.mutex.Unlock()
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
result := pm.holepunchTester.TestEndpoint(endpoint, timeout)
|
||||
if !result.Success {
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Info("Rapid test: local endpoint %s for site %d SUCCEEDED (RTT: %v)", endpoint, siteID, result.RTT)
|
||||
|
||||
pm.mutex.Lock()
|
||||
// Peer may have been removed while we were testing.
|
||||
stillTracked := false
|
||||
if _, tracked := pm.localEndpoints[siteID]; tracked {
|
||||
stillTracked = true
|
||||
pm.localActiveEndpoint[siteID] = endpoint
|
||||
pm.localFailures[siteID] = 0
|
||||
}
|
||||
pm.mutex.Unlock()
|
||||
|
||||
if stillTracked {
|
||||
pm.sendLocal(siteID, endpoint)
|
||||
}
|
||||
|
||||
return endpoint
|
||||
}
|
||||
|
||||
logger.Info("Rapid test: no local endpoint reachable for site %d", siteID)
|
||||
return ""
|
||||
}
|
||||
|
||||
// UpdatePeerEndpoint updates the monitor endpoint for a peer
|
||||
func (pm *PeerMonitor) UpdatePeerEndpoint(siteID int, monitorPeer string) {
|
||||
pm.mutex.Lock()
|
||||
|
||||
Reference in New Issue
Block a user