@ -2030,14 +2030,21 @@ func mutationsAreWorthyOfTellingIPNBus(muts []netmap.NodeMutation) bool {
return false
return false
}
}
// setExitNodeID updates prefs to either use the suggestedExitNodeID if AutoExitNode is enabled,
// resolveAutoExitNodeLocked computes a suggested exit node and updates prefs
// or resolve ExitNodeIP to an ID and use that. It returns whether prefs was mutated.
// to use it if AutoExitNode is enabled, and reports whether prefs was mutated.
func setExitNodeID ( prefs * ipn . Prefs , suggestedExitNodeID tailcfg . StableNodeID , nm * netmap . NetworkMap ) ( prefsChanged bool ) {
//
if prefs . AutoExitNode . IsSet ( ) {
// b.mu must be held.
func ( b * LocalBackend ) resolveAutoExitNodeLocked ( prefs * ipn . Prefs ) ( prefsChanged bool ) {
if ! prefs . AutoExitNode . IsSet ( ) {
return false
}
if _ , err := b . suggestExitNodeLocked ( ) ; err != nil && ! errors . Is ( err , ErrNoPreferredDERP ) {
b . logf ( "failed to select auto exit node: %v" , err ) // non-fatal, see below
}
var newExitNodeID tailcfg . StableNodeID
var newExitNodeID tailcfg . StableNodeID
if ! suggestedExitNodeID . IsZero ( ) {
if ! b. la stS uggestedExitNode. IsZero ( ) {
// If we have a suggested exit node, use it.
// If we have a suggested exit node, use it.
newExitNodeID = suggestedExitNodeID
newExitNodeID = b. la stS uggestedExitNode
} else if isAllowedAutoExitNodeID ( prefs . ExitNodeID ) {
} else if isAllowedAutoExitNodeID ( prefs . ExitNodeID ) {
// If we don't have a suggested exit node, but the prefs already
// If we don't have a suggested exit node, but the prefs already
// specify an allowed auto exit node ID, retain it.
// specify an allowed auto exit node ID, retain it.
@ -2057,20 +2064,14 @@ func setExitNodeID(prefs *ipn.Prefs, suggestedExitNodeID tailcfg.StableNodeID, n
prefsChanged = true
prefsChanged = true
}
}
return prefsChanged
return prefsChanged
}
return resolveExitNodeIP ( prefs , nm )
}
}
// resolveExitNodeIP updates prefs to reference an exit node by ID, rather
// resolveExitNodeIP Locked updates prefs to reference an exit node by ID, rather
// than by IP. It returns whether prefs was mutated.
// than by IP. It returns whether prefs was mutated.
func resolveExitNodeIP ( prefs * ipn . Prefs , nm * netmap . NetworkMap ) ( prefsChanged bool ) {
//
if nm == nil {
// b.mu must be held.
// No netmap, can't resolve anything.
func ( b * LocalBackend ) resolveExitNodeIPLocked ( prefs * ipn . Prefs ) ( prefsChanged bool ) {
return false
// If we have a desired IP on file, try to find the corresponding node.
}
// If we have a desired IP on file, try to find the corresponding
// node.
if ! prefs . ExitNodeIP . IsValid ( ) {
if ! prefs . ExitNodeIP . IsValid ( ) {
return false
return false
}
}
@ -2081,20 +2082,19 @@ func resolveExitNodeIP(prefs *ipn.Prefs, nm *netmap.NetworkMap) (prefsChanged bo
prefsChanged = true
prefsChanged = true
}
}
oldExitNodeID := prefs . ExitNodeID
cn := b . currentNode ( )
for _ , peer := range nm . Peers {
if nid , ok := cn . NodeByAddr ( prefs . ExitNodeIP ) ; ok {
for _ , addr := range peer . Addresses ( ) . All ( ) {
if node , ok := cn . NodeByID ( nid ) ; ok {
if ! addr . IsSingleIP ( ) || addr . Addr ( ) != prefs . ExitNodeIP {
continue
}
// Found the node being referenced, upgrade prefs to
// Found the node being referenced, upgrade prefs to
// reference it directly for next time.
// reference it directly for next time.
prefs . ExitNodeID = peer . StableID ( )
prefs . ExitNodeID = node . StableID ( )
prefs . ExitNodeIP = netip . Addr { }
prefs . ExitNodeIP = netip . Addr { }
return prefsChanged || oldExitNodeID != prefs . ExitNodeID
// Cleared ExitNodeIP, so prefs changed
// even if the ID stayed the same.
prefsChanged = true
}
}
}
}
return prefsChanged
return prefsChanged
}
}
@ -6042,17 +6042,13 @@ func (b *LocalBackend) reconcilePrefsLocked(prefs *ipn.Prefs) (changed bool) {
//
//
// b.mu must be held.
// b.mu must be held.
func ( b * LocalBackend ) resolveExitNodeInPrefsLocked ( prefs * ipn . Prefs ) ( changed bool ) {
func ( b * LocalBackend ) resolveExitNodeInPrefsLocked ( prefs * ipn . Prefs ) ( changed bool ) {
if prefs . AutoExitNode . IsSet ( ) {
if b . resolveAutoExitNodeLocked ( prefs ) {
_ , err := b . suggestExitNodeLocked ( )
changed = true
if err != nil && ! errors . Is ( err , ErrNoPreferredDERP ) {
b . logf ( "failed to select auto exit node: %v" , err )
}
}
}
if setExitNodeID ( prefs , b . lastSuggestedExitNode , b . currentNode ( ) . NetMap ( ) ) {
if b . resolveExitNodeIPLocked ( prefs ) {
b . logf ( "exit node resolved: %v" , prefs . ExitNodeID )
changed = true
return true
}
}
return false
return changed
}
}
// setNetMapLocked updates the LocalBackend state to reflect the newly
// setNetMapLocked updates the LocalBackend state to reflect the newly