MCPcopy Index your code
hub / github.com/tailscale/tailscale / linkChange

Method linkChange

wgengine/userspace.go:1222–1292  ·  view source on GitHub ↗
(delta *netmon.ChangeDelta)

Source from the content-addressed store, hash-verified

1220}
1221
1222func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) {
1223
1224 up := delta.AnyInterfaceUp()
1225 if !up {
1226 e.logf("LinkChange: all links down; pausing: %v", delta.StateDesc())
1227 } else if delta.RebindLikelyRequired {
1228 e.logf("LinkChange: major, rebinding: %v", delta.StateDesc())
1229 } else {
1230 e.logf("[v1] LinkChange: minor")
1231 }
1232
1233 e.health.SetAnyInterfaceUp(up)
1234 if !up || delta.RebindLikelyRequired {
1235 if err := e.dns.FlushCaches(); err != nil {
1236 e.logf("wgengine: dns flush failed after major link change: %v", err)
1237 }
1238 }
1239
1240 // Hacky workaround for Unix DNS issue 2458: on
1241 // suspend/resume or whenever NetworkManager is started, it
1242 // nukes all systemd-resolved configs. So reapply our DNS
1243 // config on major link change.
1244 //
1245 // On Darwin (netext), we reapply the DNS config when the interface flaps
1246 // because the change in interface can potentially change the nameservers
1247 // for the forwarder. On Darwin netext clients, magicDNS is ~always the default
1248 // resolver so having no nameserver to forward queries to (or one on a network we
1249 // are not currently on) breaks DNS resolution system-wide. There are notable
1250 // timing issues here with Darwin's network stack. It is not guaranteed that
1251 // the forward resolver will be available immediately after the interface
1252 // comes up. We leave it to the network extension to also poke magicDNS directly
1253 // via [dns.Manager.RecompileDNSConfig] when it detects any change in the
1254 // nameservers.
1255 //
1256 // TODO: On Android, Darwin-tailscaled, and openbsd, why do we need this?
1257 if delta.RebindLikelyRequired && up {
1258 switch runtime.GOOS {
1259 case "linux", "android", "ios", "darwin", "openbsd":
1260 e.wgLock.Lock()
1261 dnsCfg := e.lastDNSConfig
1262 e.wgLock.Unlock()
1263 if dnsCfg.Valid() {
1264 if err := e.dns.Set(*dnsCfg.AsStruct()); err != nil {
1265 e.logf("wgengine: error setting DNS config after major link change: %v", err)
1266 } else if err := e.reconfigureVPNIfNecessary(); err != nil {
1267 e.logf("wgengine: error reconfiguring VPN after major link change: %v", err)
1268 } else {
1269 e.logf("wgengine: set DNS config again after major link change")
1270 }
1271 }
1272 }
1273 }
1274
1275 e.magicConn.SetNetworkUp(up)
1276
1277 why := "link-change-minor"
1278 if delta.RebindLikelyRequired {
1279 why = "link-change-major"

Calls 15

StateDescMethod · 0.80
SetAnyInterfaceUpMethod · 0.80
FlushCachesMethod · 0.80
SetNetworkUpMethod · 0.80
RebindMethod · 0.80
ReSTUNMethod · 0.80
LockMethod · 0.65
UnlockMethod · 0.65
ValidMethod · 0.65
SetMethod · 0.65
AsStructMethod · 0.65