node.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright 2011 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package uuid
  5. import (
  6. "net"
  7. "sync"
  8. )
  9. var (
  10. nodeMu sync.Mutex
  11. interfaces []net.Interface // cached list of interfaces
  12. ifname string // name of interface being used
  13. nodeID []byte // hardware for version 1 UUIDs
  14. )
  15. // NodeInterface returns the name of the interface from which the NodeID was
  16. // derived. The interface "user" is returned if the NodeID was set by
  17. // SetNodeID.
  18. func NodeInterface() string {
  19. defer nodeMu.Unlock()
  20. nodeMu.Lock()
  21. return ifname
  22. }
  23. // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
  24. // If name is "" then the first usable interface found will be used or a random
  25. // Node ID will be generated. If a named interface cannot be found then false
  26. // is returned.
  27. //
  28. // SetNodeInterface never fails when name is "".
  29. func SetNodeInterface(name string) bool {
  30. defer nodeMu.Unlock()
  31. nodeMu.Lock()
  32. return setNodeInterface(name)
  33. }
  34. func setNodeInterface(name string) bool {
  35. if interfaces == nil {
  36. var err error
  37. interfaces, err = net.Interfaces()
  38. if err != nil && name != "" {
  39. return false
  40. }
  41. }
  42. for _, ifs := range interfaces {
  43. if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
  44. if setNodeID(ifs.HardwareAddr) {
  45. ifname = ifs.Name
  46. return true
  47. }
  48. }
  49. }
  50. // We found no interfaces with a valid hardware address. If name
  51. // does not specify a specific interface generate a random Node ID
  52. // (section 4.1.6)
  53. if name == "" {
  54. if nodeID == nil {
  55. nodeID = make([]byte, 6)
  56. }
  57. randomBits(nodeID)
  58. return true
  59. }
  60. return false
  61. }
  62. // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
  63. // if not already set.
  64. func NodeID() []byte {
  65. defer nodeMu.Unlock()
  66. nodeMu.Lock()
  67. if nodeID == nil {
  68. setNodeInterface("")
  69. }
  70. nid := make([]byte, 6)
  71. copy(nid, nodeID)
  72. return nid
  73. }
  74. // SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
  75. // of id are used. If id is less than 6 bytes then false is returned and the
  76. // Node ID is not set.
  77. func SetNodeID(id []byte) bool {
  78. defer nodeMu.Unlock()
  79. nodeMu.Lock()
  80. if setNodeID(id) {
  81. ifname = "user"
  82. return true
  83. }
  84. return false
  85. }
  86. func setNodeID(id []byte) bool {
  87. if len(id) < 6 {
  88. return false
  89. }
  90. if nodeID == nil {
  91. nodeID = make([]byte, 6)
  92. }
  93. copy(nodeID, id)
  94. return true
  95. }
  96. // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
  97. // not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
  98. func (uuid UUID) NodeID() []byte {
  99. if len(uuid) != 16 {
  100. return nil
  101. }
  102. node := make([]byte, 6)
  103. copy(node, uuid[10:])
  104. return node
  105. }