node.go

 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
 5package uuid
 6
 7import (
 8	"sync"
 9)
10
11var (
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.
21func 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 "".
33func SetNodeInterface(name string) bool {
34	defer nodeMu.Unlock()
35	nodeMu.Lock()
36	return setNodeInterface(name)
37}
38
39func 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.
60func 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.
73func 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.
86func (uuid UUID) NodeID() []byte {
87	var node [6]byte
88	copy(node[:], uuid[10:])
89	return node[:]
90}