[822] | 1 | // Copyright 2016 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 |
|
---|
| 5 | package uuid
|
---|
| 6 |
|
---|
| 7 | import (
|
---|
| 8 | "sync"
|
---|
| 9 | )
|
---|
| 10 |
|
---|
| 11 | var (
|
---|
| 12 | nodeMu sync.Mutex
|
---|
| 13 | ifname string // name of interface being used
|
---|
| 14 | nodeID [6]byte // hardware for version 1 UUIDs
|
---|
| 15 | zeroID [6]byte // nodeID with only 0's
|
---|
| 16 | )
|
---|
| 17 |
|
---|
| 18 | // NodeInterface returns the name of the interface from which the NodeID was
|
---|
| 19 | // derived. The interface "user" is returned if the NodeID was set by
|
---|
| 20 | // SetNodeID.
|
---|
| 21 | func NodeInterface() string {
|
---|
| 22 | defer nodeMu.Unlock()
|
---|
| 23 | nodeMu.Lock()
|
---|
| 24 | return ifname
|
---|
| 25 | }
|
---|
| 26 |
|
---|
| 27 | // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
---|
| 28 | // If name is "" then the first usable interface found will be used or a random
|
---|
| 29 | // Node ID will be generated. If a named interface cannot be found then false
|
---|
| 30 | // is returned.
|
---|
| 31 | //
|
---|
| 32 | // SetNodeInterface never fails when name is "".
|
---|
| 33 | func SetNodeInterface(name string) bool {
|
---|
| 34 | defer nodeMu.Unlock()
|
---|
| 35 | nodeMu.Lock()
|
---|
| 36 | return setNodeInterface(name)
|
---|
| 37 | }
|
---|
| 38 |
|
---|
| 39 | func setNodeInterface(name string) bool {
|
---|
| 40 | iname, addr := getHardwareInterface(name) // null implementation for js
|
---|
| 41 | if iname != "" && addr != nil {
|
---|
| 42 | ifname = iname
|
---|
| 43 | copy(nodeID[:], addr)
|
---|
| 44 | return true
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | // We found no interfaces with a valid hardware address. If name
|
---|
| 48 | // does not specify a specific interface generate a random Node ID
|
---|
| 49 | // (section 4.1.6)
|
---|
| 50 | if name == "" {
|
---|
| 51 | ifname = "random"
|
---|
| 52 | randomBits(nodeID[:])
|
---|
| 53 | return true
|
---|
| 54 | }
|
---|
| 55 | return false
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
---|
| 59 | // if not already set.
|
---|
| 60 | func NodeID() []byte {
|
---|
| 61 | defer nodeMu.Unlock()
|
---|
| 62 | nodeMu.Lock()
|
---|
| 63 | if nodeID == zeroID {
|
---|
| 64 | setNodeInterface("")
|
---|
| 65 | }
|
---|
| 66 | nid := nodeID
|
---|
| 67 | return nid[:]
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | // SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
---|
| 71 | // of id are used. If id is less than 6 bytes then false is returned and the
|
---|
| 72 | // Node ID is not set.
|
---|
| 73 | func SetNodeID(id []byte) bool {
|
---|
| 74 | if len(id) < 6 {
|
---|
| 75 | return false
|
---|
| 76 | }
|
---|
| 77 | defer nodeMu.Unlock()
|
---|
| 78 | nodeMu.Lock()
|
---|
| 79 | copy(nodeID[:], id)
|
---|
| 80 | ifname = "user"
|
---|
| 81 | return true
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
---|
| 85 | // not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
---|
| 86 | func (uuid UUID) NodeID() []byte {
|
---|
| 87 | var node [6]byte
|
---|
| 88 | copy(node[:], uuid[10:])
|
---|
| 89 | return node[:]
|
---|
| 90 | }
|
---|