inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/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 "inet.af/netstack/sync" 21 "inet.af/netstack/tcpip" 22 ) 23 24 var _ AddressableEndpoint = (*AddressableEndpointState)(nil) 25 26 // AddressableEndpointState is an implementation of an AddressableEndpoint. 27 type AddressableEndpointState struct { 28 networkEndpoint NetworkEndpoint 29 30 // Lock ordering (from outer to inner lock ordering): 31 // 32 // AddressableEndpointState.mu 33 // addressState.mu 34 mu struct { 35 sync.RWMutex 36 37 endpoints map[tcpip.Address]*addressState 38 primary []*addressState 39 } 40 } 41 42 // Init initializes the AddressableEndpointState with networkEndpoint. 43 // 44 // Must be called before calling any other function on m. 45 func (a *AddressableEndpointState) Init(networkEndpoint NetworkEndpoint) { 46 a.networkEndpoint = networkEndpoint 47 48 a.mu.Lock() 49 defer a.mu.Unlock() 50 a.mu.endpoints = make(map[tcpip.Address]*addressState) 51 } 52 53 // GetAddress returns the AddressEndpoint for the passed address. 54 // 55 // GetAddress does not increment the address's reference count or check if the 56 // address is considered bound to the endpoint. 57 // 58 // Returns nil if the passed address is not associated with the endpoint. 59 func (a *AddressableEndpointState) GetAddress(addr tcpip.Address) AddressEndpoint { 60 a.mu.RLock() 61 defer a.mu.RUnlock() 62 63 ep, ok := a.mu.endpoints[addr] 64 if !ok { 65 return nil 66 } 67 return ep 68 } 69 70 // ForEachEndpoint calls f for each address. 71 // 72 // Once f returns false, f will no longer be called. 73 func (a *AddressableEndpointState) ForEachEndpoint(f func(AddressEndpoint) bool) { 74 a.mu.RLock() 75 defer a.mu.RUnlock() 76 77 for _, ep := range a.mu.endpoints { 78 if !f(ep) { 79 return 80 } 81 } 82 } 83 84 // ForEachPrimaryEndpoint calls f for each primary address. 85 // 86 // Once f returns false, f will no longer be called. 87 func (a *AddressableEndpointState) ForEachPrimaryEndpoint(f func(AddressEndpoint) bool) { 88 a.mu.RLock() 89 defer a.mu.RUnlock() 90 91 for _, ep := range a.mu.primary { 92 if !f(ep) { 93 return 94 } 95 } 96 } 97 98 func (a *AddressableEndpointState) releaseAddressState(addrState *addressState) { 99 a.mu.Lock() 100 defer a.mu.Unlock() 101 a.releaseAddressStateLocked(addrState) 102 } 103 104 // releaseAddressState removes addrState from s's address state (primary and endpoints list). 105 // 106 // Preconditions: a.mu must be write locked. 107 func (a *AddressableEndpointState) releaseAddressStateLocked(addrState *addressState) { 108 oldPrimary := a.mu.primary 109 for i, s := range a.mu.primary { 110 if s == addrState { 111 a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...) 112 oldPrimary[len(oldPrimary)-1] = nil 113 break 114 } 115 } 116 delete(a.mu.endpoints, addrState.addr.Address) 117 } 118 119 // AddAndAcquirePermanentAddress implements AddressableEndpoint. 120 func (a *AddressableEndpointState) AddAndAcquirePermanentAddress(addr tcpip.AddressWithPrefix, properties AddressProperties) (AddressEndpoint, tcpip.Error) { 121 a.mu.Lock() 122 defer a.mu.Unlock() 123 ep, err := a.addAndAcquireAddressLocked(addr, properties, true /* permanent */) 124 // From https://golang.org/doc/faq#nil_error: 125 // 126 // Under the covers, interfaces are implemented as two elements, a type T and 127 // a value V. 128 // 129 // An interface value is nil only if the V and T are both unset, (T=nil, V is 130 // not set), In particular, a nil interface will always hold a nil type. If we 131 // store a nil pointer of type *int inside an interface value, the inner type 132 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 133 // an interface value will therefore be non-nil even when the pointer value V 134 // inside is nil. 135 // 136 // Since addAndAcquireAddressLocked returns a nil value with a non-nil type, 137 // we need to explicitly return nil below if ep is (a typed) nil. 138 if ep == nil { 139 return nil, err 140 } 141 return ep, err 142 } 143 144 // AddAndAcquireTemporaryAddress adds a temporary address. 145 // 146 // Returns *tcpip.ErrDuplicateAddress if the address exists. 147 // 148 // The temporary address's endpoint is acquired and returned. 149 func (a *AddressableEndpointState) AddAndAcquireTemporaryAddress(addr tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) (AddressEndpoint, tcpip.Error) { 150 a.mu.Lock() 151 defer a.mu.Unlock() 152 ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: peb}, false /* permanent */) 153 // From https://golang.org/doc/faq#nil_error: 154 // 155 // Under the covers, interfaces are implemented as two elements, a type T and 156 // a value V. 157 // 158 // An interface value is nil only if the V and T are both unset, (T=nil, V is 159 // not set), In particular, a nil interface will always hold a nil type. If we 160 // store a nil pointer of type *int inside an interface value, the inner type 161 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 162 // an interface value will therefore be non-nil even when the pointer value V 163 // inside is nil. 164 // 165 // Since addAndAcquireAddressLocked returns a nil value with a non-nil type, 166 // we need to explicitly return nil below if ep is (a typed) nil. 167 if ep == nil { 168 return nil, err 169 } 170 return ep, err 171 } 172 173 // addAndAcquireAddressLocked adds, acquires and returns a permanent or 174 // temporary address. 175 // 176 // If the addressable endpoint already has the address in a non-permanent state, 177 // and addAndAcquireAddressLocked is adding a permanent address, that address is 178 // promoted in place and its properties set to the properties provided. If the 179 // address already exists in any other state, then *tcpip.ErrDuplicateAddress is 180 // returned, regardless the kind of address that is being added. 181 // 182 // Precondition: a.mu must be write locked. 183 func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.AddressWithPrefix, properties AddressProperties, permanent bool) (*addressState, tcpip.Error) { 184 // attemptAddToPrimary is false when the address is already in the primary 185 // address list. 186 attemptAddToPrimary := true 187 addrState, ok := a.mu.endpoints[addr.Address] 188 if ok { 189 if !permanent { 190 // We are adding a non-permanent address but the address exists. No need 191 // to go any further since we can only promote existing temporary/expired 192 // addresses to permanent. 193 return nil, &tcpip.ErrDuplicateAddress{} 194 } 195 196 addrState.mu.Lock() 197 if addrState.mu.kind.IsPermanent() { 198 addrState.mu.Unlock() 199 // We are adding a permanent address but a permanent address already 200 // exists. 201 return nil, &tcpip.ErrDuplicateAddress{} 202 } 203 204 if addrState.mu.refs == 0 { 205 panic(fmt.Sprintf("found an address that should have been released (ref count == 0); address = %s", addrState.addr)) 206 } 207 208 // We now promote the address. 209 for i, s := range a.mu.primary { 210 if s == addrState { 211 switch properties.PEB { 212 case CanBePrimaryEndpoint: 213 // The address is already in the primary address list. 214 attemptAddToPrimary = false 215 case FirstPrimaryEndpoint: 216 if i == 0 { 217 // The address is already first in the primary address list. 218 attemptAddToPrimary = false 219 } else { 220 a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...) 221 } 222 case NeverPrimaryEndpoint: 223 a.mu.primary = append(a.mu.primary[:i], a.mu.primary[i+1:]...) 224 default: 225 panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB)) 226 } 227 break 228 } 229 } 230 } 231 232 if addrState == nil { 233 addrState = &addressState{ 234 addressableEndpointState: a, 235 addr: addr, 236 // Cache the subnet in addrState to avoid calls to addr.Subnet() as that 237 // results in allocations on every call. 238 subnet: addr.Subnet(), 239 } 240 a.mu.endpoints[addr.Address] = addrState 241 addrState.mu.Lock() 242 // We never promote an address to temporary - it can only be added as such. 243 // If we are actaully adding a permanent address, it is promoted below. 244 addrState.mu.kind = Temporary 245 } 246 247 // At this point we have an address we are either promoting from an expired or 248 // temporary address to permanent, promoting an expired address to temporary, 249 // or we are adding a new temporary or permanent address. 250 // 251 // The address MUST be write locked at this point. 252 defer addrState.mu.Unlock() // +checklocksforce 253 254 if permanent { 255 if addrState.mu.kind.IsPermanent() { 256 panic(fmt.Sprintf("only non-permanent addresses should be promoted to permanent; address = %s", addrState.addr)) 257 } 258 259 // Primary addresses are biased by 1. 260 addrState.mu.refs++ 261 addrState.mu.kind = Permanent 262 } 263 // Acquire the address before returning it. 264 addrState.mu.refs++ 265 addrState.mu.deprecated = properties.Deprecated 266 addrState.mu.configType = properties.ConfigType 267 268 if attemptAddToPrimary { 269 switch properties.PEB { 270 case NeverPrimaryEndpoint: 271 case CanBePrimaryEndpoint: 272 a.mu.primary = append(a.mu.primary, addrState) 273 case FirstPrimaryEndpoint: 274 if cap(a.mu.primary) == len(a.mu.primary) { 275 a.mu.primary = append([]*addressState{addrState}, a.mu.primary...) 276 } else { 277 // Shift all the endpoints by 1 to make room for the new address at the 278 // front. We could have just created a new slice but this saves 279 // allocations when the slice has capacity for the new address. 280 primaryCount := len(a.mu.primary) 281 a.mu.primary = append(a.mu.primary, nil) 282 if n := copy(a.mu.primary[1:], a.mu.primary); n != primaryCount { 283 panic(fmt.Sprintf("copied %d elements; expected = %d elements", n, primaryCount)) 284 } 285 a.mu.primary[0] = addrState 286 } 287 default: 288 panic(fmt.Sprintf("unrecognized primary endpoint behaviour = %d", properties.PEB)) 289 } 290 } 291 292 return addrState, nil 293 } 294 295 // RemovePermanentAddress implements AddressableEndpoint. 296 func (a *AddressableEndpointState) RemovePermanentAddress(addr tcpip.Address) tcpip.Error { 297 a.mu.Lock() 298 defer a.mu.Unlock() 299 return a.removePermanentAddressLocked(addr) 300 } 301 302 // removePermanentAddressLocked is like RemovePermanentAddress but with locking 303 // requirements. 304 // 305 // Precondition: a.mu must be write locked. 306 func (a *AddressableEndpointState) removePermanentAddressLocked(addr tcpip.Address) tcpip.Error { 307 addrState, ok := a.mu.endpoints[addr] 308 if !ok { 309 return &tcpip.ErrBadLocalAddress{} 310 } 311 312 return a.removePermanentEndpointLocked(addrState) 313 } 314 315 // RemovePermanentEndpoint removes the passed endpoint if it is associated with 316 // a and permanent. 317 func (a *AddressableEndpointState) RemovePermanentEndpoint(ep AddressEndpoint) tcpip.Error { 318 addrState, ok := ep.(*addressState) 319 if !ok || addrState.addressableEndpointState != a { 320 return &tcpip.ErrInvalidEndpointState{} 321 } 322 323 a.mu.Lock() 324 defer a.mu.Unlock() 325 return a.removePermanentEndpointLocked(addrState) 326 } 327 328 // removePermanentAddressLocked is like RemovePermanentAddress but with locking 329 // requirements. 330 // 331 // Precondition: a.mu must be write locked. 332 func (a *AddressableEndpointState) removePermanentEndpointLocked(addrState *addressState) tcpip.Error { 333 if !addrState.GetKind().IsPermanent() { 334 return &tcpip.ErrBadLocalAddress{} 335 } 336 337 addrState.SetKind(PermanentExpired) 338 a.decAddressRefLocked(addrState) 339 return nil 340 } 341 342 // decAddressRef decrements the address's reference count and releases it once 343 // the reference count hits 0. 344 func (a *AddressableEndpointState) decAddressRef(addrState *addressState) { 345 a.mu.Lock() 346 defer a.mu.Unlock() 347 a.decAddressRefLocked(addrState) 348 } 349 350 // decAddressRefLocked is like decAddressRef but with locking requirements. 351 // 352 // Precondition: a.mu must be write locked. 353 func (a *AddressableEndpointState) decAddressRefLocked(addrState *addressState) { 354 addrState.mu.Lock() 355 defer addrState.mu.Unlock() 356 357 if addrState.mu.refs == 0 { 358 panic(fmt.Sprintf("attempted to decrease ref count for AddressEndpoint w/ addr = %s when it is already released", addrState.addr)) 359 } 360 361 addrState.mu.refs-- 362 363 if addrState.mu.refs != 0 { 364 return 365 } 366 367 // A non-expired permanent address must not have its reference count dropped 368 // to 0. 369 if addrState.mu.kind.IsPermanent() { 370 panic(fmt.Sprintf("permanent addresses should be removed through the AddressableEndpoint: addr = %s, kind = %d", addrState.addr, addrState.mu.kind)) 371 } 372 373 a.releaseAddressStateLocked(addrState) 374 } 375 376 // MainAddress implements AddressableEndpoint. 377 func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix { 378 a.mu.RLock() 379 defer a.mu.RUnlock() 380 381 ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool { 382 return ep.GetKind() == Permanent 383 }) 384 if ep == nil { 385 return tcpip.AddressWithPrefix{} 386 } 387 388 addr := ep.AddressWithPrefix() 389 a.decAddressRefLocked(ep) 390 return addr 391 } 392 393 // acquirePrimaryAddressRLocked returns an acquired primary address that is 394 // valid according to isValid. 395 // 396 // Precondition: e.mu must be read locked 397 func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(isValid func(*addressState) bool) *addressState { 398 var deprecatedEndpoint *addressState 399 for _, ep := range a.mu.primary { 400 if !isValid(ep) { 401 continue 402 } 403 404 if !ep.Deprecated() { 405 if ep.IncRef() { 406 // ep is not deprecated, so return it immediately. 407 // 408 // If we kept track of a deprecated endpoint, decrement its reference 409 // count since it was incremented when we decided to keep track of it. 410 if deprecatedEndpoint != nil { 411 a.decAddressRefLocked(deprecatedEndpoint) 412 deprecatedEndpoint = nil 413 } 414 415 return ep 416 } 417 } else if deprecatedEndpoint == nil && ep.IncRef() { 418 // We prefer an endpoint that is not deprecated, but we keep track of 419 // ep in case a doesn't have any non-deprecated endpoints. 420 // 421 // If we end up finding a more preferred endpoint, ep's reference count 422 // will be decremented. 423 deprecatedEndpoint = ep 424 } 425 } 426 427 return deprecatedEndpoint 428 } 429 430 // AcquireAssignedAddressOrMatching returns an address endpoint that is 431 // considered assigned to the addressable endpoint. 432 // 433 // If the address is an exact match with an existing address, that address is 434 // returned. Otherwise, if f is provided, f is called with each address and 435 // the address that f returns true for is returned. 436 // 437 // If there is no matching address, a temporary address will be returned if 438 // allowTemp is true. 439 // 440 // Regardless how the address was obtained, it will be acquired before it is 441 // returned. 442 func (a *AddressableEndpointState) AcquireAssignedAddressOrMatching(localAddr tcpip.Address, f func(AddressEndpoint) bool, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint { 443 lookup := func() *addressState { 444 if addrState, ok := a.mu.endpoints[localAddr]; ok { 445 if !addrState.IsAssigned(allowTemp) { 446 return nil 447 } 448 449 if !addrState.IncRef() { 450 panic(fmt.Sprintf("failed to increase the reference count for address = %s", addrState.addr)) 451 } 452 453 return addrState 454 } 455 456 if f != nil { 457 for _, addrState := range a.mu.endpoints { 458 if addrState.IsAssigned(allowTemp) && f(addrState) && addrState.IncRef() { 459 return addrState 460 } 461 } 462 } 463 return nil 464 } 465 // Avoid exclusive lock on mu unless we need to add a new address. 466 a.mu.RLock() 467 ep := lookup() 468 a.mu.RUnlock() 469 470 if ep != nil { 471 return ep 472 } 473 474 if !allowTemp { 475 return nil 476 } 477 478 // Acquire state lock in exclusive mode as we need to add a new temporary 479 // endpoint. 480 a.mu.Lock() 481 defer a.mu.Unlock() 482 483 // Do the lookup again in case another goroutine added the address in the time 484 // we released and acquired the lock. 485 ep = lookup() 486 if ep != nil { 487 return ep 488 } 489 490 // Proceed to add a new temporary endpoint. 491 addr := localAddr.WithPrefix() 492 ep, err := a.addAndAcquireAddressLocked(addr, AddressProperties{PEB: tempPEB}, false /* permanent */) 493 if err != nil { 494 // addAndAcquireAddressLocked only returns an error if the address is 495 // already assigned but we just checked above if the address exists so we 496 // expect no error. 497 panic(fmt.Sprintf("a.addAndAcquireAddressLocked(%s, AddressProperties{PEB: %s}, false): %s", addr, tempPEB, err)) 498 } 499 500 // From https://golang.org/doc/faq#nil_error: 501 // 502 // Under the covers, interfaces are implemented as two elements, a type T and 503 // a value V. 504 // 505 // An interface value is nil only if the V and T are both unset, (T=nil, V is 506 // not set), In particular, a nil interface will always hold a nil type. If we 507 // store a nil pointer of type *int inside an interface value, the inner type 508 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 509 // an interface value will therefore be non-nil even when the pointer value V 510 // inside is nil. 511 // 512 // Since addAndAcquireAddressLocked returns a nil value with a non-nil type, 513 // we need to explicitly return nil below if ep is (a typed) nil. 514 if ep == nil { 515 return nil 516 } 517 return ep 518 } 519 520 // AcquireAssignedAddress implements AddressableEndpoint. 521 func (a *AddressableEndpointState) AcquireAssignedAddress(localAddr tcpip.Address, allowTemp bool, tempPEB PrimaryEndpointBehavior) AddressEndpoint { 522 return a.AcquireAssignedAddressOrMatching(localAddr, nil, allowTemp, tempPEB) 523 } 524 525 // AcquireOutgoingPrimaryAddress implements AddressableEndpoint. 526 func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allowExpired bool) AddressEndpoint { 527 a.mu.RLock() 528 defer a.mu.RUnlock() 529 530 ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool { 531 return ep.IsAssigned(allowExpired) 532 }) 533 534 // From https://golang.org/doc/faq#nil_error: 535 // 536 // Under the covers, interfaces are implemented as two elements, a type T and 537 // a value V. 538 // 539 // An interface value is nil only if the V and T are both unset, (T=nil, V is 540 // not set), In particular, a nil interface will always hold a nil type. If we 541 // store a nil pointer of type *int inside an interface value, the inner type 542 // will be *int regardless of the value of the pointer: (T=*int, V=nil). Such 543 // an interface value will therefore be non-nil even when the pointer value V 544 // inside is nil. 545 // 546 // Since acquirePrimaryAddressRLocked returns a nil value with a non-nil type, 547 // we need to explicitly return nil below if ep is (a typed) nil. 548 if ep == nil { 549 return nil 550 } 551 552 return ep 553 } 554 555 // PrimaryAddresses implements AddressableEndpoint. 556 func (a *AddressableEndpointState) PrimaryAddresses() []tcpip.AddressWithPrefix { 557 a.mu.RLock() 558 defer a.mu.RUnlock() 559 560 var addrs []tcpip.AddressWithPrefix 561 for _, ep := range a.mu.primary { 562 // Don't include tentative, expired or temporary endpoints 563 // to avoid confusion and prevent the caller from using 564 // those. 565 switch ep.GetKind() { 566 case PermanentTentative, PermanentExpired, Temporary: 567 continue 568 } 569 570 addrs = append(addrs, ep.AddressWithPrefix()) 571 } 572 573 return addrs 574 } 575 576 // PermanentAddresses implements AddressableEndpoint. 577 func (a *AddressableEndpointState) PermanentAddresses() []tcpip.AddressWithPrefix { 578 a.mu.RLock() 579 defer a.mu.RUnlock() 580 581 var addrs []tcpip.AddressWithPrefix 582 for _, ep := range a.mu.endpoints { 583 if !ep.GetKind().IsPermanent() { 584 continue 585 } 586 587 addrs = append(addrs, ep.AddressWithPrefix()) 588 } 589 590 return addrs 591 } 592 593 // Cleanup forcefully leaves all groups and removes all permanent addresses. 594 func (a *AddressableEndpointState) Cleanup() { 595 a.mu.Lock() 596 defer a.mu.Unlock() 597 598 for _, ep := range a.mu.endpoints { 599 // removePermanentEndpointLocked returns *tcpip.ErrBadLocalAddress if ep is 600 // not a permanent address. 601 switch err := a.removePermanentEndpointLocked(ep); err.(type) { 602 case nil, *tcpip.ErrBadLocalAddress: 603 default: 604 panic(fmt.Sprintf("unexpected error from removePermanentEndpointLocked(%s): %s", ep.addr, err)) 605 } 606 } 607 } 608 609 var _ AddressEndpoint = (*addressState)(nil) 610 611 // addressState holds state for an address. 612 type addressState struct { 613 addressableEndpointState *AddressableEndpointState 614 addr tcpip.AddressWithPrefix 615 subnet tcpip.Subnet 616 // Lock ordering (from outer to inner lock ordering): 617 // 618 // AddressableEndpointState.mu 619 // addressState.mu 620 mu struct { 621 sync.RWMutex 622 623 refs uint32 624 kind AddressKind 625 configType AddressConfigType 626 deprecated bool 627 } 628 } 629 630 // AddressWithPrefix implements AddressEndpoint. 631 func (a *addressState) AddressWithPrefix() tcpip.AddressWithPrefix { 632 return a.addr 633 } 634 635 // Subnet implements AddressEndpoint. 636 func (a *addressState) Subnet() tcpip.Subnet { 637 return a.subnet 638 } 639 640 // GetKind implements AddressEndpoint. 641 func (a *addressState) GetKind() AddressKind { 642 a.mu.RLock() 643 defer a.mu.RUnlock() 644 return a.mu.kind 645 } 646 647 // SetKind implements AddressEndpoint. 648 func (a *addressState) SetKind(kind AddressKind) { 649 a.mu.Lock() 650 defer a.mu.Unlock() 651 a.mu.kind = kind 652 } 653 654 // IsAssigned implements AddressEndpoint. 655 func (a *addressState) IsAssigned(allowExpired bool) bool { 656 if !a.addressableEndpointState.networkEndpoint.Enabled() { 657 return false 658 } 659 660 switch a.GetKind() { 661 case PermanentTentative: 662 return false 663 case PermanentExpired: 664 return allowExpired 665 default: 666 return true 667 } 668 } 669 670 // IncRef implements AddressEndpoint. 671 func (a *addressState) IncRef() bool { 672 a.mu.Lock() 673 defer a.mu.Unlock() 674 if a.mu.refs == 0 { 675 return false 676 } 677 678 a.mu.refs++ 679 return true 680 } 681 682 // DecRef implements AddressEndpoint. 683 func (a *addressState) DecRef() { 684 a.addressableEndpointState.decAddressRef(a) 685 } 686 687 // ConfigType implements AddressEndpoint. 688 func (a *addressState) ConfigType() AddressConfigType { 689 a.mu.RLock() 690 defer a.mu.RUnlock() 691 return a.mu.configType 692 } 693 694 // SetDeprecated implements AddressEndpoint. 695 func (a *addressState) SetDeprecated(d bool) { 696 a.mu.Lock() 697 defer a.mu.Unlock() 698 a.mu.deprecated = d 699 } 700 701 // Deprecated implements AddressEndpoint. 702 func (a *addressState) Deprecated() bool { 703 a.mu.RLock() 704 defer a.mu.RUnlock() 705 return a.mu.deprecated 706 }