blob: ad56b3895b27a224fb16cee5bba0f86f7d704cac [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef VM_TOOLS_CONCIERGE_MAC_ADDRESS_GENERATOR_H_
#define VM_TOOLS_CONCIERGE_MAC_ADDRESS_GENERATOR_H_
#include <stdint.h>
#include <array>
#include <functional>
#include <unordered_set>
#include <base/macros.h>
namespace vm_tools {
namespace concierge {
using MacAddress = std::array<uint8_t, 6>;
// Generates locally managed EUI-48 MAC addresses and ensures no collisions
// with any previously generated addresses by this instance.
class MacAddressGenerator {
public:
MacAddressGenerator() = default;
~MacAddressGenerator() = default;
// Generates a new EUI-48 MAC address and ensures that there are no
// collisions with any addresses previously generated by this instance of
// the generator.
MacAddress Generate();
private:
// The standard library sadly does not provide a hash function for std::array.
// So implement one here for MacAddress based off boost::hash_combine.
struct MacAddressHasher {
size_t operator()(const MacAddress& addr) const noexcept {
std::hash<uint8_t> hasher;
size_t hash = 0;
for (uint8_t octet : addr) {
hash ^= hasher(octet) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
return hash;
}
};
// Set of all addresses generated by this instance. This doesn't _need_ to be
// an unordered_set but making it one improves the performance of the
// "Duplicates" unit test by ~33% (~150 seconds -> ~100 seconds) and it
// doesn't have a huge impact in production use so that's why we use it here.
std::unordered_set<MacAddress, MacAddressHasher> addrs_;
DISALLOW_COPY_AND_ASSIGN(MacAddressGenerator);
};
} // namespace concierge
} // namespace vm_tools
#endif // VM_TOOLS_CONCIERGE_MAC_ADDRESS_GENERATOR_H_