OSDN Git Service

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