mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-01 20:41:28 +02:00
[relay] Release home relay lock before the connection race
OpenConn held relayClientMu for the whole call, including the network-bound FallbackOpener.Run, which blocked onServerDisconnected/storeClient from taking the write lock and delayed reconnect by up to the race timeout. Snapshot the home relay client under the read lock, release it, and run the foreign check and the race on the snapshot. isForeignServer now takes the client so it uses the snapshot instead of re-reading the field after the lock is dropped.
This commit is contained in:
@@ -144,22 +144,23 @@ func (m *Manager) Serve() error {
|
||||
|
||||
func (m *Manager) OpenConn(ctx context.Context, remoteRelayServer RelayServer, peerKey string, preferForeign bool) (net.Conn, error) {
|
||||
m.relayClientMu.RLock()
|
||||
defer m.relayClientMu.RUnlock()
|
||||
relayClient := m.relayClient
|
||||
m.relayClientMu.RUnlock()
|
||||
|
||||
if m.relayClient == nil {
|
||||
if relayClient == nil {
|
||||
return nil, ErrRelayClientNotConnected
|
||||
}
|
||||
|
||||
foreign, err := m.isForeignServer(remoteRelayServer.Addr)
|
||||
foreign, err := m.isForeignServer(relayClient, remoteRelayServer.Addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !foreign {
|
||||
return m.relayClient.OpenConn(ctx, peerKey)
|
||||
return relayClient.OpenConn(ctx, peerKey)
|
||||
}
|
||||
|
||||
opener := NewFallbackOpener(m.relayClient, m.foreign)
|
||||
opener := NewFallbackOpener(relayClient, m.foreign)
|
||||
return opener.Run(ctx, peerKey, remoteRelayServer, preferForeign)
|
||||
}
|
||||
|
||||
@@ -191,7 +192,7 @@ func (m *Manager) AddCloseListener(serverAddress string, onClosedListener OnServ
|
||||
return ErrRelayClientNotConnected
|
||||
}
|
||||
|
||||
foreign, err := m.isForeignServer(serverAddress)
|
||||
foreign, err := m.isForeignServer(m.relayClient, serverAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -329,8 +330,8 @@ func (m *Manager) storeClient(client *Client) {
|
||||
m.relayClient.SetOnDisconnectListener(m.onServerDisconnected)
|
||||
}
|
||||
|
||||
func (m *Manager) isForeignServer(address string) (bool, error) {
|
||||
rAddr, err := m.relayClient.ServerInstanceURL()
|
||||
func (m *Manager) isForeignServer(relayClient *Client, address string) (bool, error) {
|
||||
rAddr, err := relayClient.ServerInstanceURL()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("relay client not connected")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user