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