node.go raw

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