github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/tcpip/stack/addressable_endpoint_state.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package stack 16 17 import ( 18 "fmt" 19 20 "github.com/sagernet/gvisor/pkg/tcpip" 21 "github.com/sagernet/gvisor/pkg/tcpip/header" 22 ) 23 24 func (lifetimes *AddressLifetimes) sanitize() { 25 if lifetimes.Deprecated { 26 lifetimes.PreferredUntil = tcpip.MonotonicTime{} 27 } 28 } 29 30 var _ AddressableEndpoint = (*AddressableEndpointState)(nil) 31 32 // AddressableEndpointState is an implementation of an AddressableEndpoint. 33 type AddressableEndpointState struct { 34 networkEndpoint NetworkEndpoint 35 options AddressableEndpointStateOptions 36 37 // Lock ordering (from outer to inner lock ordering): 38 // 39 // AddressableEndpointState.mu 40 // addressState.mu 41 mu addressableEndpointStateRWMutex 42 // +checklocks:mu 43 endpoints map[tcpip.Address]*addressState 44 // +checklocks:mu 45 primary []*addressState 46 } 47 48 // AddressableEndpointStateOptions contains options used to configure an 49 // AddressableEndpointState. 50 type AddressableEndpointStateOptions struct { 51 // HiddenWhileDisabled determines whether addresses should be returned to 52 // callers while the NetworkEndpoint this AddressableEndpointState belongs 53 // to is disabled. 54 HiddenWhileDisabled bool 55 } 56 57 // Init initializes the AddressableEndpointState with networkEndpoint. 58 // 59 // Must be called before calling any other function on m. 60 func (a *AddressableEndpointState) Init(networkEndpoint NetworkEndpoint, options AddressableEndpointStateOptions) { 61 a.networkEndpoint = networkEndpoint 62 a.options = options 63 64 a.mu.Lock() 65 defer a.mu.Unlock() 66 a.endpoints = make(map[tcpip.Address]*addressState) 67 } 68 69 // OnNetworkEndpointEnabledChanged must be called every time the 70 // NetworkEndpoint this AddressableEndpointState belongs to is enabled or 71 // disabled so that any AddressDispatchers can be notified of the NIC enabled 72 // change. 73 func (a *AddressableEndpointState) OnNetworkEndpointEnabledChanged() { 74 a.mu.RLock() 75 defer a.mu.RUnlock() 76 77 for _, ep := range a.endpoints { 78 ep.mu.Lock() 79 ep.notifyChangedLocked() 80 ep.mu.Unlock() 81 } 82 } 83 84 // GetAddress returns the AddressEndpoint for the passed address. 85 // 86 // GetAddress does not increment the address's reference count or check if the 87 // address is considered bound to the endpoint. 88 // 89 // Returns nil if the passed address is not associated with the endpoint. 90 func (a *AddressableEndpointState) GetAddress(addr tcpip.Address) AddressEndpoint { 91 a.mu.RLock() 92 defer a.mu.RUnlock() 93 94 ep, ok := a.endpoints[addr] 95 if !ok { 96 return nil 97 } 98 return ep 99 } 100 101 // ForEachEndpoint calls f for each address. 102 // 103 // Once f returns false, f will no longer be called. 104 func (a *AddressableEndpointState) ForEachEndpoint(f func(AddressEndpoint) bool) { 105 a.mu.RLock() 106 defer a.mu.RUnlock() 107 108 for _, ep := range a.endpoints { 109 if !f(ep) { 110 return 111 } 112 } 113 } 114 115 // ForEachPrimaryEndpoint calls f for each primary address. 116 // 117 // Once f returns false, f will no longer be called. 118 func (a *AddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint) bool) { 119 a.mu.RLock() 120 defer a.mu.RUnlock() 121 122 for _, ep := range a.primary { 123 if !f(ep) { 124 return 125 } 126 } 127 } 128 129 func (a *AddressableEndpointState) releaseAddressState(addrState *addressState) { 130 a.mu.Lock() 131 defer a.mu.Unlock() 132 a.releaseAddressStateLocked(addrState) 133 } 134 135 // releaseAddressStateLocked removes addrState from a's address state 136 // (primary and endpoints list). 137 // 138 // +checklocks:a.mu 139 func (a *AddressableEndpointState) releaseAddressStateLocked(addrState *addressState) { 140 oldPrimary := a.primary 141 for i, s := range a.primary { 142 if s == addrState { 143 a.primary = append(a.primary[:i], a.primary[i+1:]...) 144 oldPrimary[len(oldPrimary)-1] = nil 145 break 146 } 147 } 148 delete(a.endpoints, addrState.addr.Address) 149 } 150 151 // AddAndAcquirePermanentAddress implements AddressableEndpoint. 152 func (a *AddressableEndpointState) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, properties AddressProperties) (AddressEndpoint, tcpip.Error) { 153 return a.AddAndAcquireAddress(addr, properties, Permanent) 154 } 155 156 // AddAndAcquireTemporaryAddress adds a temporary address. 157 // 158 // Returns *tcpip.ErrDuplicateAddress if the address exists. 159 // 160 // The temporary address's endpoint is acquired and returned. 161 func (a *AddressableEndpointState) AddAndAcquireTemporaryAddress(addr tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) (AddressEndpoint, tcpip.Error) { 162 return a.AddAndAcquireAddress(addr, AddressProperties{PEB: peb}, Temporary) 163 } 164 165 // AddAndAcquireAddress adds an address with the specified kind. 166 // 167 // Returns *tcpip.ErrDuplicateAddress if the address exists. 168 func (a *AddressableEndpointState) AddAndAcquireAddress(addr tcpip.AddressWithPrefix, properties AddressProperties, kind AddressKind) (AddressEndpoint, tcpip.Error) { 169 a.mu.Lock() 170 defer a.mu.Unlock() 171 ep, err := a.addAndAcquireAddressLocked(addr, properties, kind) 172 // From https://golang.org/doc/faq#nil_error: 173 // 174 // Under the covers, interfaces are implemented as two elements, a type T and 175 // a value V. 176 // 177 // An interface value is nil only if the V and T are both unset, (T=nil, V is 178 // not set), In particular, a nil interface will always hold a nil type. If we 179 // store a nil pointer of type *int inside an interface value, the inner type 180 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 181 // an interface value will therefore be non-nil even when the pointer value V 182 // inside is nil. 183 // 184 // Since addAndAcquireAddressLocked returns a nil value with a non-nil type, 185 // we need to explicitly return nil below if ep is (a typed) nil. 186 if ep == nil { 187 return nil, err 188 } 189 return ep, err 190 } 191 192 // addAndAcquireAddressLocked adds, acquires and returns a permanent or 193 // temporary address. 194 // 195 // If the addressable endpoint already has the address in a non-permanent state, 196 // and addAndAcquireAddressLocked is adding a permanent address, that address is 197 // promoted in place and its properties set to the properties provided. If the 198 // address already exists in any other state, then *tcpip.ErrDuplicateAddress is 199 // returned, regardless the kind of address that is being added. 200 // 201 // +checklocks:a.mu 202 func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.AddressWithPrefix, properties AddressProperties, kind AddressKind) (*addressState, tcpip.Error) { 203 var permanent bool 204 switch kind { 205 case PermanentExpired: 206 panic(fmt.Sprintf("cannot add address %s in PermanentExpired state", addr)) 207 case Permanent, PermanentTentative: 208 permanent = true 209 case Temporary: 210 default: 211 panic(fmt.Sprintf("unknown address kind: %d", kind)) 212 } 213 // attemptAddToPrimary is false when the address is already in the primary 214 // address list. 215 attemptAddToPrimary := true 216 addrState, ok := a.endpoints[addr.Address] 217 if ok { 218 if !permanent { 219 // We are adding a non-permanent address but the address exists. No need 220 // to go any further since we can only promote existing temporary/expired 221 // addresses to permanent. 222 return nil, &tcpip.ErrDuplicateAddress{} 223 } 224 225 addrState.mu.RLock() 226 if addrState.refs.ReadRefs() == 0 { 227 panic(fmt.Sprintf("found an address that should have been released (ref count == 0); address = %s", addrState.addr)) 228 } 229 isPermanent := addrState.kind.IsPermanent() 230 addrState.mu.RUnlock() 231 232 if isPermanent { 233 // We are adding a permanent address but a permanent address already 234 // exists. 235 return nil, &tcpip.ErrDuplicateAddress{} 236 } 237 238 // We now promote the address. 239 for i, s := range a.primary { 240 if s == addrState { 241 switch properties.PEB { 242 case CanBePrimaryEndpoint: 243 // The address is already in the primary address list. 244 attemptAddToPrimary = false 245 case FirstPrimaryEndpoint: 246 if i == 0 { 247 // The address is already first in the primary address list. 248 attemptAddToPrimary = false 249 } else { 250 a.primary = append(a.primary[:i], a.primary[i+1:]...) 251 } 252 case NeverPrimaryEndpoint: 253 a.primary = append(a.primary[:i], a.primary[i+1:]...) 254 default: 255 panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB)) 256 } 257 break 258 } 259 } 260 addrState.refs.IncRef() 261 } else { 262 addrState = &addressState{ 263 addressableEndpointState: a, 264 addr: addr, 265 temporary: properties.Temporary, 266 // Cache the subnet in addrState to avoid calls to addr.Subnet() as that 267 // results in allocations on every call. 268 subnet: addr.Subnet(), 269 } 270 addrState.refs.InitRefs() 271 a.endpoints[addr.Address] = addrState 272 // We never promote an address to temporary - it can only be added as such. 273 // If we are actually adding a permanent address, it is promoted below. 274 addrState.kind = Temporary 275 } 276 277 // At this point we have an address we are either promoting from an expired or 278 // temporary address to permanent, promoting an expired address to temporary, 279 // or we are adding a new temporary or permanent address. 280 // 281 // The address MUST be write locked at this point. 282 addrState.mu.Lock() 283 defer addrState.mu.Unlock() 284 285 if permanent { 286 if addrState.kind.IsPermanent() { 287 panic(fmt.Sprintf("only non-permanent addresses should be promoted to permanent; address = %s", addrState.addr)) 288 } 289 290 // Primary addresses are biased by 1. 291 addrState.refs.IncRef() 292 addrState.kind = kind 293 } 294 addrState.configType = properties.ConfigType 295 lifetimes := properties.Lifetimes 296 lifetimes.sanitize() 297 addrState.lifetimes = lifetimes 298 addrState.disp = properties.Disp 299 300 if attemptAddToPrimary { 301 switch properties.PEB { 302 case NeverPrimaryEndpoint: 303 case CanBePrimaryEndpoint: 304 a.primary = append(a.primary, addrState) 305 case FirstPrimaryEndpoint: 306 if cap(a.primary) == len(a.primary) { 307 a.primary = append([]*addressState{addrState}, a.primary...) 308 } else { 309 // Shift all the endpoints by 1 to make room for the new address at the 310 // front. We could have just created a new slice but this saves 311 // allocations when the slice has capacity for the new address. 312 primaryCount := len(a.primary) 313 a.primary = append(a.primary, nil) 314 if n := copy(a.primary[1:], a.primary); n != primaryCount { 315 panic(fmt.Sprintf("copied %d elements; expected = %d elements", n, primaryCount)) 316 } 317 a.primary[0] = addrState 318 } 319 default: 320 panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB)) 321 } 322 } 323 324 addrState.notifyChangedLocked() 325 return addrState, nil 326 } 327 328 // RemovePermanentAddress implements AddressableEndpoint. 329 func (a *AddressableEndpointState) RemovePermanentAddress(addr tcpip.Address) tcpip.Error { 330 a.mu.Lock() 331 defer a.mu.Unlock() 332 return a.removePermanentAddressLocked(addr) 333 } 334 335 // removePermanentAddressLocked is like RemovePermanentAddress but with locking 336 // requirements. 337 // 338 // +checklocks:a.mu 339 func (a *AddressableEndpointState) removePermanentAddressLocked(addr tcpip.Address) tcpip.Error { 340 addrState, ok := a.endpoints[addr] 341 if !ok { 342 return &tcpip.ErrBadLocalAddress{} 343 } 344 345 return a.removePermanentEndpointLocked(addrState, AddressRemovalManualAction) 346 } 347 348 // RemovePermanentEndpoint removes the passed endpoint if it is associated with 349 // a and permanent. 350 func (a *AddressableEndpointState) RemovePermanentEndpoint(ep AddressEndpoint, reason AddressRemovalReason) tcpip.Error { 351 addrState, ok := ep.(*addressState) 352 if !ok || addrState.addressableEndpointState != a { 353 return &tcpip.ErrInvalidEndpointState{} 354 } 355 356 a.mu.Lock() 357 defer a.mu.Unlock() 358 return a.removePermanentEndpointLocked(addrState, reason) 359 } 360 361 // removePermanentAddressLocked is like RemovePermanentAddress but with locking 362 // requirements. 363 // 364 // +checklocks:a.mu 365 func (a *AddressableEndpointState) removePermanentEndpointLocked(addrState *addressState, reason AddressRemovalReason) tcpip.Error { 366 if !addrState.GetKind().IsPermanent() { 367 return &tcpip.ErrBadLocalAddress{} 368 } 369 370 addrState.remove(reason) 371 a.decAddressRefLocked(addrState) 372 return nil 373 } 374 375 // decAddressRef decrements the address's reference count and releases it once 376 // the reference count hits 0. 377 func (a *AddressableEndpointState) decAddressRef(addrState *addressState) { 378 a.mu.Lock() 379 defer a.mu.Unlock() 380 a.decAddressRefLocked(addrState) 381 } 382 383 // decAddressRefLocked is like decAddressRef but with locking requirements. 384 // 385 // +checklocks:a.mu 386 func (a *AddressableEndpointState) decAddressRefLocked(addrState *addressState) { 387 destroy := false 388 addrState.refs.DecRef(func() { 389 destroy = true 390 }) 391 392 if !destroy { 393 return 394 } 395 addrState.mu.Lock() 396 defer addrState.mu.Unlock() 397 // A non-expired permanent address must not have its reference count dropped 398 // to 0. 399 if addrState.kind.IsPermanent() { 400 panic(fmt.Sprintf("permanent addresses should be removed through the AddressableEndpoint: addr = %s, kind = %d", addrState.addr, addrState.kind)) 401 } 402 403 a.releaseAddressStateLocked(addrState) 404 } 405 406 // SetDeprecated implements stack.AddressableEndpoint. 407 func (a *AddressableEndpointState) SetDeprecated(addr tcpip.Address, deprecated bool) tcpip.Error { 408 a.mu.RLock() 409 defer a.mu.RUnlock() 410 411 addrState, ok := a.endpoints[addr] 412 if !ok { 413 return &tcpip.ErrBadLocalAddress{} 414 } 415 addrState.SetDeprecated(deprecated) 416 return nil 417 } 418 419 // SetLifetimes implements stack.AddressableEndpoint. 420 func (a *AddressableEndpointState) SetLifetimes(addr tcpip.Address, lifetimes AddressLifetimes) tcpip.Error { 421 a.mu.RLock() 422 defer a.mu.RUnlock() 423 424 addrState, ok := a.endpoints[addr] 425 if !ok { 426 return &tcpip.ErrBadLocalAddress{} 427 } 428 addrState.SetLifetimes(lifetimes) 429 return nil 430 } 431 432 // MainAddress implements AddressableEndpoint. 433 func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix { 434 a.mu.RLock() 435 defer a.mu.RUnlock() 436 437 ep := a.acquirePrimaryAddressRLocked(tcpip.Address{}, tcpip.Address{} /* srcHint */, func(ep *addressState) bool { 438 switch kind := ep.GetKind(); kind { 439 case Permanent: 440 return a.networkEndpoint.Enabled() || !a.options.HiddenWhileDisabled 441 case PermanentTentative, PermanentExpired, Temporary: 442 return false 443 default: 444 panic(fmt.Sprintf("unknown address kind: %d", kind)) 445 } 446 }) 447 if ep == nil { 448 return tcpip.AddressWithPrefix{} 449 } 450 addr := ep.AddressWithPrefix() 451 // Note that when ep must have a ref count >=2, because its ref count 452 // must be >=1 in order to be found and the ref count was incremented 453 // when a reference was acquired. The only way for the ref count to 454 // drop below 2 is for the endpoint to be removed, which requires a 455 // write lock; so we're guaranteed to be able to decrement the ref 456 // count and not need to remove the endpoint from a.primary. 457 ep.decRefMustNotFree() 458 return addr 459 } 460 461 // acquirePrimaryAddressRLocked returns an acquired primary address that is 462 // valid according to isValid. 463 // 464 // +checklocksread:a.mu 465 func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(remoteAddr, srcHint tcpip.Address, isValid func(*addressState) bool) *addressState { 466 // TODO: Move this out into IPv4-specific code. 467 // IPv6 handles source IP selection elsewhere. We have to do source 468 // selection only for IPv4, in which case ep is never deprecated. Thus 469 // we don't have to worry about refcounts. 470 if remoteAddr.Len() == header.IPv4AddressSize && remoteAddr != (tcpip.Address{}) { 471 var best *addressState 472 var bestLen uint8 473 for _, state := range a.primary { 474 if !isValid(state) { 475 continue 476 } 477 // Source hint takes precedent over prefix matching. 478 if state.addr.Address == srcHint && srcHint != (tcpip.Address{}) { 479 best = state 480 break 481 } 482 stateLen := state.addr.Address.MatchingPrefix(remoteAddr) 483 if best == nil || bestLen < stateLen { 484 best = state 485 bestLen = stateLen 486 } 487 } 488 if best != nil && best.TryIncRef() { 489 return best 490 } 491 } 492 493 var deprecatedEndpoint *addressState 494 for _, ep := range a.primary { 495 if !isValid(ep) { 496 continue 497 } 498 499 if !ep.Deprecated() { 500 if ep.TryIncRef() { 501 // ep is not deprecated, so return it immediately. 502 // 503 // If we kept track of a deprecated endpoint, decrement its reference 504 // count since it was incremented when we decided to keep track of it. 505 if deprecatedEndpoint != nil { 506 // Note that when deprecatedEndpoint was found, its ref count 507 // must have necessarily been >=1, and after incrementing it 508 // must be >=2. The only way for the ref count to drop below 2 is 509 // for the endpoint to be removed, which requires a write lock; 510 // so we're guaranteed to be able to decrement the ref count 511 // and not need to remove the endpoint from a.primary. 512 deprecatedEndpoint.decRefMustNotFree() 513 } 514 515 return ep 516 } 517 } else if deprecatedEndpoint == nil && ep.TryIncRef() { 518 // We prefer an endpoint that is not deprecated, but we keep track of 519 // ep in case a doesn't have any non-deprecated endpoints. 520 // 521 // If we end up finding a more preferred endpoint, ep's reference count 522 // will be decremented. 523 deprecatedEndpoint = ep 524 } 525 } 526 527 return deprecatedEndpoint 528 } 529 530 // AcquireAssignedAddressOrMatching returns an address endpoint that is 531 // considered assigned to the addressable endpoint. 532 // 533 // If the address is an exact match with an existing address, that address is 534 // returned. Otherwise, if f is provided, f is called with each address and 535 // the address that f returns true for is returned. 536 // 537 // If there is no matching address, a temporary address will be returned if 538 // allowTemp is true. 539 // 540 // If readOnly is true, the address will be returned without an extra reference. 541 // In this case it is not safe to modify the endpoint, only read attributes like 542 // subnet. 543 // 544 // Regardless how the address was obtained, it will be acquired before it is 545 // returned. 546 func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior, readOnly bool) AddressEndpoint { 547 lookup := func() *addressState { 548 if addrState, ok := a.endpoints[localAddr]; ok { 549 if !addrState.IsAssigned(allowTemp) { 550 return nil 551 } 552 553 if !readOnly && !addrState.TryIncRef() { 554 panic(fmt.Sprintf("failed to increase the reference count for address = %s", addrState.addr)) 555 } 556 557 return addrState 558 } 559 560 if f != nil { 561 for _, addrState := range a.endpoints { 562 if addrState.IsAssigned(allowTemp) && f(addrState) { 563 if !readOnly && !addrState.TryIncRef() { 564 continue 565 } 566 return addrState 567 } 568 } 569 } 570 return nil 571 } 572 // Avoid exclusive lock on mu unless we need to add a new address. 573 a.mu.RLock() 574 ep := lookup() 575 a.mu.RUnlock() 576 577 if ep != nil { 578 return ep 579 } 580 581 if !allowTemp { 582 return nil 583 } 584 585 // Acquire state lock in exclusive mode as we need to add a new temporary 586 // endpoint. 587 a.mu.Lock() 588 defer a.mu.Unlock() 589 590 // Do the lookup again in case another goroutine added the address in the time 591 // we released and acquired the lock. 592 ep = lookup() 593 if ep != nil { 594 return ep 595 } 596 597 // Proceed to add a new temporary endpoint. 598 addr := localAddr.WithPrefix() 599 ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, Temporary) 600 if err != nil { 601 // addAndAcquireAddressLocked only returns an error if the address is 602 // already assigned but we just checked above if the address exists so we 603 // expect no error. 604 panic(fmt.Sprintf("a.addAndAcquireAddressLocked(%s, AddressProperties{PEB: %s}, false): %s", addr, tempPEB, err)) 605 } 606 607 // From https://golang.org/doc/faq#nil_error: 608 // 609 // Under the covers, interfaces are implemented as two elements, a type T and 610 // a value V. 611 // 612 // An interface value is nil only if the V and T are both unset, (T=nil, V is 613 // not set), In particular, a nil interface will always hold a nil type. If we 614 // store a nil pointer of type *int inside an interface value, the inner type 615 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 616 // an interface value will therefore be non-nil even when the pointer value V 617 // inside is nil. 618 // 619 // Since addAndAcquireAddressLocked returns a nil value with a non-nil type, 620 // we need to explicitly return nil below if ep is (a typed) nil. 621 if ep == nil { 622 return nil 623 } 624 if readOnly { 625 if ep.addressableEndpointState == a { 626 // Checklocks doesn't understand that we are logically guaranteed to have 627 // ep.mu locked already. We need to use checklocksignore to appease the 628 // analyzer. 629 ep.addressableEndpointState.decAddressRefLocked(ep) // +checklocksignore 630 } else { 631 ep.DecRef() 632 } 633 } 634 return ep 635 } 636 637 // AcquireAssignedAddress implements AddressableEndpoint. 638 func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior, readOnly bool) AddressEndpoint { 639 return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB, readOnly) 640 } 641 642 // AcquireOutgoingPrimaryAddress implements AddressableEndpoint. 643 func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, srcHint tcpip.Address, allowExpired bool) AddressEndpoint { 644 a.mu.Lock() 645 defer a.mu.Unlock() 646 647 ep := a.acquirePrimaryAddressRLocked(remoteAddr, srcHint, func(ep *addressState) bool { 648 return ep.IsAssigned(allowExpired) 649 }) 650 651 // From https://golang.org/doc/faq#nil_error: 652 // 653 // Under the covers, interfaces are implemented as two elements, a type T and 654 // a value V. 655 // 656 // An interface value is nil only if the V and T are both unset, (T=nil, V is 657 // not set), In particular, a nil interface will always hold a nil type. If we 658 // store a nil pointer of type *int inside an interface value, the inner type 659 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 660 // an interface value will therefore be non-nil even when the pointer value V 661 // inside is nil. 662 // 663 // Since acquirePrimaryAddressLocked returns a nil value with a non-nil type, 664 // we need to explicitly return nil below if ep is (a typed) nil. 665 if ep == nil { 666 return nil 667 } 668 669 return ep 670 } 671 672 // PrimaryAddresses implements AddressableEndpoint. 673 func (a *AddressableEndpointState) PrimaryAddresses() []tcpip.AddressWithPrefix { 674 a.mu.RLock() 675 defer a.mu.RUnlock() 676 677 var addrs []tcpip.AddressWithPrefix 678 if a.options.HiddenWhileDisabled && !a.networkEndpoint.Enabled() { 679 return addrs 680 } 681 for _, ep := range a.primary { 682 switch kind := ep.GetKind(); kind { 683 // Don't include tentative, expired or temporary endpoints 684 // to avoid confusion and prevent the caller from using 685 // those. 686 case PermanentTentative, PermanentExpired, Temporary: 687 continue 688 case Permanent: 689 default: 690 panic(fmt.Sprintf("address %s has unknown kind %d", ep.AddressWithPrefix(), kind)) 691 } 692 693 addrs = append(addrs, ep.AddressWithPrefix()) 694 } 695 696 return addrs 697 } 698 699 // PermanentAddresses implements AddressableEndpoint. 700 func (a *AddressableEndpointState) PermanentAddresses() []tcpip.AddressWithPrefix { 701 a.mu.RLock() 702 defer a.mu.RUnlock() 703 704 var addrs []tcpip.AddressWithPrefix 705 for _, ep := range a.endpoints { 706 if !ep.GetKind().IsPermanent() { 707 continue 708 } 709 710 addrs = append(addrs, ep.AddressWithPrefix()) 711 } 712 713 return addrs 714 } 715 716 // Cleanup forcefully leaves all groups and removes all permanent addresses. 717 func (a *AddressableEndpointState) Cleanup() { 718 a.mu.Lock() 719 defer a.mu.Unlock() 720 721 for _, ep := range a.endpoints { 722 // removePermanentEndpointLocked returns *tcpip.ErrBadLocalAddress if ep is 723 // not a permanent address. 724 switch err := a.removePermanentEndpointLocked(ep, AddressRemovalInterfaceRemoved); err.(type) { 725 case nil, *tcpip.ErrBadLocalAddress: 726 default: 727 panic(fmt.Sprintf("unexpected error from removePermanentEndpointLocked(%s): %s", ep.addr, err)) 728 } 729 } 730 } 731 732 var _ AddressEndpoint = (*addressState)(nil) 733 734 // addressState holds state for an address. 735 type addressState struct { 736 addressableEndpointState *AddressableEndpointState 737 addr tcpip.AddressWithPrefix 738 subnet tcpip.Subnet 739 temporary bool 740 741 // Lock ordering (from outer to inner lock ordering): 742 // 743 // AddressableEndpointState.mu 744 // addressState.mu 745 mu addressStateRWMutex 746 refs addressStateRefs 747 // checklocks:mu 748 kind AddressKind 749 // checklocks:mu 750 configType AddressConfigType 751 // lifetimes holds this address' lifetimes. 752 // 753 // Invariant: if lifetimes.deprecated is true, then lifetimes.PreferredUntil 754 // must be the zero value. Note that the converse does not need to be 755 // upheld! 756 // 757 // checklocks:mu 758 lifetimes AddressLifetimes 759 // The enclosing mutex must be write-locked before calling methods on the 760 // dispatcher. 761 // 762 // checklocks:mu 763 disp AddressDispatcher 764 } 765 766 // AddressWithPrefix implements AddressEndpoint. 767 func (a *addressState) AddressWithPrefix() tcpip.AddressWithPrefix { 768 return a.addr 769 } 770 771 // Subnet implements AddressEndpoint. 772 func (a *addressState) Subnet() tcpip.Subnet { 773 return a.subnet 774 } 775 776 // GetKind implements AddressEndpoint. 777 func (a *addressState) GetKind() AddressKind { 778 a.mu.RLock() 779 defer a.mu.RUnlock() 780 return a.kind 781 } 782 783 // SetKind implements AddressEndpoint. 784 func (a *addressState) SetKind(kind AddressKind) { 785 a.mu.Lock() 786 defer a.mu.Unlock() 787 788 prevKind := a.kind 789 a.kind = kind 790 if kind == PermanentExpired { 791 a.notifyRemovedLocked(AddressRemovalManualAction) 792 } else if prevKind != kind && a.addressableEndpointState.networkEndpoint.Enabled() { 793 a.notifyChangedLocked() 794 } 795 } 796 797 // notifyRemovedLocked notifies integrators of address removal. 798 // 799 // +checklocks:a.mu 800 func (a *addressState) notifyRemovedLocked(reason AddressRemovalReason) { 801 if disp := a.disp; disp != nil { 802 a.disp.OnRemoved(reason) 803 a.disp = nil 804 } 805 } 806 807 func (a *addressState) remove(reason AddressRemovalReason) { 808 a.mu.Lock() 809 defer a.mu.Unlock() 810 811 a.kind = PermanentExpired 812 a.notifyRemovedLocked(reason) 813 } 814 815 // IsAssigned implements AddressEndpoint. 816 func (a *addressState) IsAssigned(allowExpired bool) bool { 817 switch kind := a.GetKind(); kind { 818 case PermanentTentative: 819 return false 820 case PermanentExpired: 821 return allowExpired 822 case Permanent, Temporary: 823 return true 824 default: 825 panic(fmt.Sprintf("address %s has unknown kind %d", a.AddressWithPrefix(), kind)) 826 } 827 } 828 829 // IncRef implements AddressEndpoint. 830 func (a *addressState) TryIncRef() bool { 831 return a.refs.TryIncRef() 832 } 833 834 // DecRef implements AddressEndpoint. 835 func (a *addressState) DecRef() { 836 a.addressableEndpointState.decAddressRef(a) 837 } 838 839 // decRefMustNotFree decreases the reference count with the guarantee that the 840 // reference count will be greater than 0 after the decrement. 841 // 842 // Panics if the ref count is less than 2 after acquiring the lock in this 843 // function. 844 func (a *addressState) decRefMustNotFree() { 845 a.refs.DecRef(func() { 846 panic(fmt.Sprintf("cannot decrease addressState %s without freeing the endpoint", a.addr)) 847 }) 848 } 849 850 // ConfigType implements AddressEndpoint. 851 func (a *addressState) ConfigType() AddressConfigType { 852 a.mu.RLock() 853 defer a.mu.RUnlock() 854 return a.configType 855 } 856 857 // notifyChangedLocked notifies integrators of address property changes. 858 // 859 // +checklocks:a.mu 860 func (a *addressState) notifyChangedLocked() { 861 if a.disp == nil { 862 return 863 } 864 865 state := AddressDisabled 866 if a.addressableEndpointState.networkEndpoint.Enabled() { 867 switch a.kind { 868 case Permanent: 869 state = AddressAssigned 870 case PermanentTentative: 871 state = AddressTentative 872 case Temporary, PermanentExpired: 873 return 874 default: 875 panic(fmt.Sprintf("unrecognized address kind = %d", a.kind)) 876 } 877 } 878 879 a.disp.OnChanged(a.lifetimes, state) 880 } 881 882 // SetDeprecated implements AddressEndpoint. 883 func (a *addressState) SetDeprecated(d bool) { 884 a.mu.Lock() 885 defer a.mu.Unlock() 886 887 var changed bool 888 if a.lifetimes.Deprecated != d { 889 a.lifetimes.Deprecated = d 890 changed = true 891 } 892 if d { 893 a.lifetimes.PreferredUntil = tcpip.MonotonicTime{} 894 } 895 if changed { 896 a.notifyChangedLocked() 897 } 898 } 899 900 // Deprecated implements AddressEndpoint. 901 func (a *addressState) Deprecated() bool { 902 a.mu.RLock() 903 defer a.mu.RUnlock() 904 return a.lifetimes.Deprecated 905 } 906 907 // SetLifetimes implements AddressEndpoint. 908 func (a *addressState) SetLifetimes(lifetimes AddressLifetimes) { 909 a.mu.Lock() 910 defer a.mu.Unlock() 911 912 lifetimes.sanitize() 913 914 var changed bool 915 if a.lifetimes != lifetimes { 916 changed = true 917 } 918 a.lifetimes = lifetimes 919 if changed { 920 a.notifyChangedLocked() 921 } 922 } 923 924 // Lifetimes implements AddressEndpoint. 925 func (a *addressState) Lifetimes() AddressLifetimes { 926 a.mu.RLock() 927 defer a.mu.RUnlock() 928 return a.lifetimes 929 } 930 931 // Temporary implements AddressEndpoint. 932 func (a *addressState) Temporary() bool { 933 return a.temporary 934 } 935 936 // RegisterDispatcher implements AddressEndpoint. 937 func (a *addressState) RegisterDispatcher(disp AddressDispatcher) { 938 a.mu.Lock() 939 defer a.mu.Unlock() 940 if disp != nil { 941 a.disp = disp 942 a.notifyChangedLocked() 943 } 944 }