address.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2023-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package zerotier
  14. import (
  15. "encoding/json"
  16. "fmt"
  17. "strconv"
  18. )
  19. // Address represents a 40-bit short ZeroTier address
  20. type Address uint64
  21. // NewAddressFromString parses a 10-digit ZeroTier address
  22. func NewAddressFromString(s string) (Address, error) {
  23. if len(s) != 10 {
  24. return Address(0), ErrInvalidZeroTierAddress
  25. }
  26. a, err := strconv.ParseUint(s, 16, 64)
  27. return Address(a & 0xffffffffff), err
  28. }
  29. // NewAddressFromBytes reads a 5-byte 40-bit address.
  30. func NewAddressFromBytes(b []byte) (Address, error) {
  31. if len(b) < 5 {
  32. return Address(0), ErrInvalidZeroTierAddress
  33. }
  34. return Address((uint64(b[0]) << 32) | (uint64(b[1]) << 24) | (uint64(b[2]) << 16) | (uint64(b[3]) << 8) | uint64(b[4])), nil
  35. }
  36. // IsReserved returns true if this address is reserved and therefore is not valid for a real node.
  37. func (a Address) IsReserved() bool { return a == 0 || (a>>32) == 0xff }
  38. // String returns this address's 10-digit hex identifier
  39. func (a Address) String() string {
  40. return fmt.Sprintf("%.10x", uint64(a))
  41. }
  42. // MarshalJSON marshals this Address as a string
  43. func (a Address) MarshalJSON() ([]byte, error) {
  44. return []byte(fmt.Sprintf("\"%.10x\"", uint64(a))), nil
  45. }
  46. // UnmarshalJSON unmarshals this Address from a string
  47. func (a *Address) UnmarshalJSON(j []byte) error {
  48. var s string
  49. err := json.Unmarshal(j, &s)
  50. if err != nil {
  51. return err
  52. }
  53. tmp, err := NewAddressFromString(s)
  54. *a = tmp
  55. return err
  56. }