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 | }
|
---|