Unverified Commit 07dcccfb authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #1499

Remove ripemd160
parents d121310b ee80d379
...@@ -111,9 +111,7 @@ caf_add_component( ...@@ -111,9 +111,7 @@ caf_add_component(
caf/detail/behavior_stack.cpp caf/detail/behavior_stack.cpp
caf/detail/blocking_behavior.cpp caf/detail/blocking_behavior.cpp
caf/detail/config_consumer.cpp caf/detail/config_consumer.cpp
caf/detail/get_mac_addresses.cpp
caf/detail/get_process_id.cpp caf/detail/get_process_id.cpp
caf/detail/get_root_uuid.cpp
caf/detail/glob_match.cpp caf/detail/glob_match.cpp
caf/detail/group_tunnel.cpp caf/detail/group_tunnel.cpp
caf/detail/invoke_result_visitor.cpp caf/detail/invoke_result_visitor.cpp
...@@ -133,7 +131,6 @@ caf_add_component( ...@@ -133,7 +131,6 @@ caf_add_component(
caf/detail/private_thread_pool.cpp caf/detail/private_thread_pool.cpp
caf/detail/rfc3629.cpp caf/detail/rfc3629.cpp
caf/detail/rfc3629.test.cpp caf/detail/rfc3629.test.cpp
caf/detail/ripemd_160.cpp
caf/detail/set_thread_name.cpp caf/detail/set_thread_name.cpp
caf/detail/stream_bridge.cpp caf/detail/stream_bridge.cpp
caf/detail/stringification_inspector.cpp caf/detail/stringification_inspector.cpp
...@@ -277,7 +274,6 @@ caf_add_component( ...@@ -277,7 +274,6 @@ caf_add_component(
detail.parser.read_unsigned_integer detail.parser.read_unsigned_integer
detail.private_thread_pool detail.private_thread_pool
detail.ringbuffer detail.ringbuffer
detail.ripemd_160
detail.type_id_list_builder detail.type_id_list_builder
detail.unique_function detail.unique_function
dictionary dictionary
......
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/config.hpp"
#include "caf/detail/scope_guard.hpp"
#if defined(CAF_MACOS) || defined(CAF_BSD) || defined(CAF_IOS)
# include <arpa/inet.h>
# include <cerrno>
# include <cstdio>
# include <cstdlib>
# include <memory>
# include <net/if.h>
# include <net/if_dl.h>
# include <netinet/in.h>
# include <sstream>
# include <sys/ioctl.h>
# include <sys/socket.h>
# include <sys/sysctl.h>
# include <sys/types.h>
# include <iostream>
namespace caf {
namespace detail {
std::vector<iface_info> get_mac_addresses() {
int mib[6];
std::vector<iface_info> result;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
auto indices = if_nameindex();
std::vector<char> buf;
for (auto i = indices; !(i->if_index == 0 && i->if_name == nullptr); ++i) {
mib[5] = static_cast<int>(i->if_index);
size_t len;
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
perror("sysctl 1 error");
exit(3);
}
if (buf.size() < len)
buf.resize(len);
CAF_ASSERT(len > 0);
if (sysctl(mib, 6, buf.data(), &len, nullptr, 0) < 0) {
perror("sysctl 2 error");
exit(5);
}
auto ifm = reinterpret_cast<if_msghdr*>(buf.data());
auto sdl = reinterpret_cast<sockaddr_dl*>(ifm + 1);
constexpr auto mac_addr_len = 6;
if (sdl->sdl_alen != mac_addr_len)
continue;
auto ptr = reinterpret_cast<unsigned char*>(LLADDR(sdl));
auto uctoi = [](unsigned char c) -> unsigned {
return static_cast<unsigned char>(c);
};
std::ostringstream oss;
oss << std::hex;
oss.fill('0');
oss.width(2);
oss << uctoi(*ptr++);
for (auto j = 0; j < mac_addr_len - 1; ++j) {
oss << ":";
oss.width(2);
oss << uctoi(*ptr++);
}
auto addr = oss.str();
if (addr != "00:00:00:00:00:00") {
result.emplace_back(i->if_name, std::move(addr));
}
}
if_freenameindex(indices);
return result;
}
} // namespace detail
} // namespace caf
#elif defined(CAF_LINUX) || defined(CAF_ANDROID) || defined(CAF_CYGWIN)
# include <algorithm>
# include <cctype>
# include <cstring>
# include <fstream>
# include <iostream>
# include <iterator>
# include <net/if.h>
# include <sstream>
# include <stdio.h>
# include <string>
# include <sys/ioctl.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <unistd.h>
# include <vector>
namespace caf::detail {
std::vector<iface_info> get_mac_addresses() {
// get a socket handle
int socktype = SOCK_DGRAM;
# ifdef SOCK_CLOEXEC
socktype |= SOCK_CLOEXEC;
# endif
int sck = socket(AF_INET, socktype, 0);
if (sck < 0) {
perror("socket");
return {};
}
auto g = make_scope_guard([&] { close(sck); });
// query available interfaces
char buf[1024] = {0};
ifconf ifc;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
perror("ioctl(SIOCGIFCONF)");
return {};
}
std::vector<iface_info> result;
auto ctoi = [](char c) -> unsigned { return static_cast<unsigned char>(c); };
// iterate through interfaces
auto ifr = ifc.ifc_req;
auto num_ifaces = static_cast<size_t>(ifc.ifc_len) / sizeof(ifreq);
for (size_t i = 0; i < num_ifaces; ++i) {
auto item = &ifr[i];
// get mac address
if (ioctl(sck, SIOCGIFHWADDR, item) < 0) {
perror("ioctl(SIOCGIFHWADDR)");
return {};
}
std::ostringstream oss;
oss << std::hex;
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[0]);
for (size_t j = 1; j < 6; ++j) {
oss << ":";
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[j]);
}
auto addr = oss.str();
if (addr != "00:00:00:00:00:00") {
result.push_back({item->ifr_name, std::move(addr)});
}
}
return result;
}
} // namespace caf::detail
#else
// windows
// clang-format off
# include <ws2tcpip.h>
# include <winsock2.h>
# include <iphlpapi.h>
// clang-format on
# include <algorithm>
# include <cctype>
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <fstream>
# include <iostream>
# include <iterator>
# include <memory>
# include <sstream>
# include <string>
# include <vector>
namespace {
constexpr size_t working_buffer_size = 15 * 1024; // 15kb by default
constexpr size_t max_iterations = 3;
struct c_free {
template <class T>
void operator()(T* ptr) const {
free(ptr);
}
};
} // namespace
namespace caf {
namespace detail {
std::vector<iface_info> get_mac_addresses() {
// result vector
std::vector<iface_info> result;
// flags to pass to GetAdaptersAddresses
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
// default to unspecified address family (both)
ULONG family = AF_UNSPEC;
// buffer
std::unique_ptr<IP_ADAPTER_ADDRESSES, c_free> addresses;
// init buf size to default, adjusted by GetAdaptersAddresses if needed
ULONG addresses_len = working_buffer_size;
// stores result of latest system call
DWORD res = 0;
// break condition
size_t iterations = 0;
do {
addresses.reset((IP_ADAPTER_ADDRESSES*) malloc(addresses_len));
if (!addresses) {
perror("Memory allocation failed for IP_ADAPTER_ADDRESSES struct");
exit(1);
}
res = GetAdaptersAddresses(family, flags, nullptr, addresses.get(),
&addresses_len);
} while ((res == ERROR_BUFFER_OVERFLOW) && (++iterations < max_iterations));
if (res == NO_ERROR) {
// read hardware addresses from the output we've received
for (auto addr = addresses.get(); addr != nullptr; addr = addr->Next) {
if (addr->PhysicalAddressLength > 0) {
std::ostringstream oss;
oss << std::hex;
oss.width(2);
oss << static_cast<int>(addr->PhysicalAddress[0]);
for (DWORD i = 1; i < addr->PhysicalAddressLength; ++i) {
oss << ":";
oss.width(2);
oss << static_cast<int>(addr->PhysicalAddress[i]);
}
auto hw_addr = oss.str();
if (hw_addr != "00:00:00:00:00:00") {
result.push_back({addr->AdapterName, std::move(hw_addr)});
}
}
}
} else {
if (res == ERROR_NO_DATA) {
perror("No addresses were found for the requested parameters");
} else {
perror("Call to GetAdaptersAddresses failed with error");
}
}
return result;
}
} // namespace detail
} // namespace caf
#endif
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include <string>
#include <utility>
#include <vector>
#include "caf/detail/core_export.hpp"
namespace caf::detail {
using iface_info = std::pair<std::string /* interface name */,
std::string /* interface address */>;
CAF_CORE_EXPORT std::vector<iface_info> get_mac_addresses();
} // namespace caf::detail
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/detail/get_root_uuid.hpp"
#include "caf/config.hpp"
#ifndef CAF_MACOS // not needed on Mac OS X
namespace {
constexpr char uuid_format[] = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";
} // namespace
#endif // CAF_MACOS
#if defined(CAF_MACOS)
namespace {
inline void erase_trailing_newline(std::string& str) {
while (!str.empty() && (*str.rbegin()) == '\n') {
str.resize(str.size() - 1);
}
}
constexpr const char* s_get_uuid = "/usr/sbin/diskutil info / | "
"/usr/bin/awk '$0 ~ /UUID/ { print $3 }'";
} // namespace
namespace caf {
namespace detail {
std::string get_root_uuid() {
char cbuf[100];
// fetch hd serial
std::string uuid;
FILE* get_uuid_cmd = popen(s_get_uuid, "r");
while (fgets(cbuf, 100, get_uuid_cmd) != nullptr) {
uuid += cbuf;
}
pclose(get_uuid_cmd);
erase_trailing_newline(uuid);
return uuid;
}
} // namespace detail
} // namespace caf
#elif defined(CAF_IOS) || defined(CAF_ANDROID) || defined(CAF_NET_BSD)
// Return a randomly-generated UUID on mobile devices or NetBSD (requires root
// access to get UUID from disk).
# include <random>
namespace caf {
namespace detail {
std::string get_root_uuid() {
std::random_device rd;
std::uniform_int_distribution<int> dist(0, 15);
std::string uuid = uuid_format;
for (auto& c : uuid) {
if (c != '-') {
auto n = dist(rd);
c = static_cast<char>((n < 10) ? n + '0' : (n - 10) + 'A');
}
}
return uuid;
}
} // namespace detail
} // namespace caf
#elif defined(CAF_LINUX) || defined(CAF_BSD) || defined(CAF_CYGWIN)
# include <algorithm>
# include <fstream>
# include <iostream>
# include <iterator>
# include <sstream>
# include <string>
# include <vector>
# include "caf/string_algorithms.hpp"
using std::ifstream;
using std::string;
using std::vector;
namespace caf::detail {
namespace {
struct columns_iterator {
using iterator_category = std::forward_iterator_tag;
using value_type = std::vector<string>;
using difference_type = ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
columns_iterator(ifstream* s = nullptr) : fs(s) {
// nop
}
vector<string>& operator*() {
return cols;
}
columns_iterator& operator++() {
string line;
if (!std::getline(*fs, line)) {
fs = nullptr;
} else {
split(cols, line, is_any_of(" "), token_compress_on);
}
return *this;
}
ifstream* fs;
vector<string> cols;
};
bool operator==(const columns_iterator& lhs, const columns_iterator& rhs) {
return lhs.fs == rhs.fs;
}
bool operator!=(const columns_iterator& lhs, const columns_iterator& rhs) {
return !(lhs == rhs);
}
} // namespace
std::string get_root_uuid() {
string uuid;
ifstream fs;
fs.open("/etc/fstab", std::ios_base::in);
columns_iterator end;
auto i = std::find_if(columns_iterator{&fs}, end,
[](const vector<string>& cols) {
return cols.size() == 6 && cols[1] == "/";
});
if (i != end) {
uuid = std::move((*i)[0]);
const char cstr[] = {"UUID="};
auto slen = sizeof(cstr) - 1;
if (uuid.compare(0, slen, cstr) == 0) {
uuid.erase(0, slen);
}
// UUIDs are formatted as 8-4-4-4-12 hex digits groups
auto cpy = uuid;
std::replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
// discard invalid UUID
if (cpy != uuid_format) {
uuid.clear();
}
// "\\?\Volume{5ec70abf-058c-11e1-bdda-806e6f6e6963}\"
}
return uuid;
}
} // namespace caf::detail
#elif defined(CAF_WINDOWS)
# include <algorithm>
# include <iostream>
# include <string>
# include <tchar.h>
# include <windows.h>
namespace caf {
namespace detail {
namespace {
constexpr size_t max_drive_name = MAX_PATH;
}
// if TCHAR is indeed a char, we can simply move rhs
void mv(std::string& lhs, std::string&& rhs) {
lhs = std::move(rhs);
}
// if TCHAR is defined as WCHAR, we have to do unicode conversion
void mv(std::string& lhs, const std::basic_string<WCHAR>& rhs) {
auto size_needed = WideCharToMultiByte(CP_UTF8, 0, rhs.c_str(),
static_cast<int>(rhs.size()), nullptr,
0, nullptr, nullptr);
lhs.resize(size_needed);
WideCharToMultiByte(CP_UTF8, 0, rhs.c_str(), static_cast<int>(rhs.size()),
&lhs[0], size_needed, nullptr, nullptr);
}
std::string get_root_uuid() {
using tchar_str = std::basic_string<TCHAR>;
std::string uuid;
TCHAR buf[max_drive_name]; // temporary buffer for volume name
tchar_str drive = TEXT("c:\\"); // string "template" for drive specifier
// walk through legal drive letters, skipping floppies
for (TCHAR i = TEXT('c'); i < TEXT('z'); i++) {
// Stamp the drive for the appropriate letter.
drive[0] = i;
if (GetVolumeNameForVolumeMountPoint(drive.c_str(), buf, max_drive_name)) {
tchar_str drive_name = buf;
auto first = drive_name.find(TEXT("Volume{"));
if (first != std::string::npos) {
first += 7;
auto last = drive_name.find(TEXT("}"), first);
if (last != std::string::npos && last > first) {
mv(uuid, drive_name.substr(first, last - first));
// UUIDs are formatted as 8-4-4-4-12 hex digits groups
auto cpy = uuid;
std::replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
// discard invalid UUID
if (cpy != uuid_format) {
uuid.clear();
} else {
return uuid; // return first valid UUID we get
}
}
}
}
}
return uuid;
}
} // namespace detail
} // namespace caf
#endif // CAF_WINDOWS
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include <string>
#include "caf/detail/core_export.hpp"
namespace caf::detail {
CAF_CORE_EXPORT std::string get_root_uuid();
} // namespace caf::detail
This diff is collapsed.
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
// Based on http://homes.esat.kuleuven.be/~cosicart/ps/AB-9601/rmd160.h;
// original header:
//
// AUTHOR: Antoon Bosselaers, ESAT-COSIC
// DATE: 1 March 1996
// VERSION: 1.0
//
// Copyright (c) Katholieke Universiteit Leuven
// 1996, All Rights Reserved
//
// Conditions for use of the RIPEMD-160 Software
//
// The RIPEMD-160 software is freely available for use under the terms and
// conditions described hereunder, which shall be deemed to be accepted by
// any user of the software and applicable on any use of the software:
//
// 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
// all purposes be considered the owner of the RIPEMD-160 software and of
// all copyright, trade secret, patent or other intellectual property
// rights therein.
// 2. The RIPEMD-160 software is provided on an "as is" basis without
// warranty of any sort, express or implied. K.U.Leuven makes no
// representation that the use of the software will not infringe any
// patent or proprietary right of third parties. User will indemnify
// K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
// which may arise as a result of its use of the software. In no
// circumstances K.U.Leuven R&D will be held liable for any deficiency,
// fault or other mishappening with regard to the use or performance of
// the software.
// 3. User agrees to give due credit to K.U.Leuven in scientific publications
// or communications in relation with the use of the RIPEMD-160 software
// as follows: RIPEMD-160 software written by Antoon Bosselaers,
// available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
#pragma once
#include <array>
#include <cstdint>
#include <string>
#include "caf/detail/core_export.hpp"
namespace caf::detail {
/// Creates a hash from `data` using the RIPEMD-160 algorithm.
CAF_CORE_EXPORT void ripemd_160(std::array<uint8_t, 20>& storage,
const std::string& data);
} // namespace caf::detail
...@@ -17,12 +17,9 @@ ...@@ -17,12 +17,9 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/deserializer.hpp" #include "caf/deserializer.hpp"
#include "caf/detail/append_hex.hpp" #include "caf/detail/append_hex.hpp"
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/get_process_id.hpp" #include "caf/detail/get_process_id.hpp"
#include "caf/detail/get_root_uuid.hpp"
#include "caf/detail/parse.hpp" #include "caf/detail/parse.hpp"
#include "caf/detail/parser/ascii_to_int.hpp" #include "caf/detail/parser/ascii_to_int.hpp"
#include "caf/detail/ripemd_160.hpp"
#include "caf/expected.hpp" #include "caf/expected.hpp"
#include "caf/logger.hpp" #include "caf/logger.hpp"
#include "caf/make_counted.hpp" #include "caf/make_counted.hpp"
...@@ -95,29 +92,18 @@ bool hashed_node_id::can_parse(std::string_view str) noexcept { ...@@ -95,29 +92,18 @@ bool hashed_node_id::can_parse(std::string_view str) noexcept {
node_id hashed_node_id::local(const actor_system_config&) { node_id hashed_node_id::local(const actor_system_config&) {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
auto ifs = detail::get_mac_addresses(); // We add an global incrementing counter to make sure two actor systems in the
std::vector<std::string> macs; // same process won't have the same node ID - even if the user manipulates the
macs.reserve(ifs.size()); // system to always produce the same seed for its randomness.
for (auto& i : ifs) auto sys_seed = static_cast<uint8_t>(system_id.fetch_add(1));
macs.emplace_back(std::move(i.second));
auto seeded_hd_serial_and_mac_addr = join(macs, "") + detail::get_root_uuid();
// By adding 8 random ASCII characters, we make sure to assign a new (random)
// ID to a node every time we start it. Otherwise, we might run into issues
// where a restarted node produces identical actor IDs than the node it
// replaces. Especially when running nodes in a container, because then the
// process ID is most likely the same.
std::random_device rd; std::random_device rd;
std::minstd_rand gen{rd()}; std::minstd_rand gen{rd() + sys_seed};
std::uniform_int_distribution<> dis(33, 126); // uniform_int_distribution doesn't accept uint8_t as template parameter
for (int i = 0; i < 8; ++i) std::uniform_int_distribution<> dis(std::numeric_limits<uint8_t>::min(),
seeded_hd_serial_and_mac_addr += static_cast<char>(dis(gen)); std::numeric_limits<uint8_t>::max());
// One final tweak: we add another character that makes sure two actor systems
// in the same process won't have the same node ID - even if the user
// manipulates the system to always produce the same seed for its randomness.
auto sys_seed = static_cast<char>(system_id.fetch_add(1) + 33);
seeded_hd_serial_and_mac_addr += sys_seed;
host_id_type hid; host_id_type hid;
detail::ripemd_160(hid, seeded_hd_serial_and_mac_addr); for (auto& x : hid)
x = static_cast<uint8_t>(dis(gen));
return make_node_id(detail::get_process_id(), hid); return make_node_id(detail::get_process_id(), hid);
} }
......
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE detail.ripemd_160
#include "caf/detail/ripemd_160.hpp"
#include "core-test.hpp"
#include <iomanip>
#include <iostream>
using caf::detail::ripemd_160;
namespace {
std::string str_hash(const std::string& what) {
std::array<uint8_t, 20> hash;
ripemd_160(hash, what);
std::ostringstream oss;
oss << std::setfill('0') << std::hex;
for (auto i : hash) {
oss << std::setw(2) << static_cast<int>(i);
}
return oss.str();
}
} // namespace
// verify ripemd implementation with example hash results from
// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
CAF_TEST(hash_results) {
CHECK_EQ("9c1185a5c5e9fc54612808977ee8f548b2258d31", str_hash(""));
CHECK_EQ("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", str_hash("a"));
CHECK_EQ("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", str_hash("abc"));
CHECK_EQ("5d0689ef49d2fae572b881b123a85ffa21595f36",
str_hash("message digest"));
CHECK_EQ("f71c27109c692c1b56bbdceb5b9d2865b3708dbc",
str_hash("abcdefghijklmnopqrstuvwxyz"));
CHECK_EQ("12a053384a9c0c88e405a06c27dcf49ada62eb2b",
str_hash("abcdbcdecdefdefgefghfghighij"
"hijkijkljklmklmnlmnomnopnopq"));
CHECK_EQ("b0e20b6e3116640286ed3a87a5713079b21f5189",
str_hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
"fghijklmnopqrstuvwxyz0123456789"));
CHECK_EQ("9b752e45573d4b39f4dbd3323cab82bf63326bfb",
str_hash("1234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890"));
}
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "caf/binary_serializer.hpp" #include "caf/binary_serializer.hpp"
#include "caf/byte_buffer.hpp" #include "caf/byte_buffer.hpp"
#include "caf/deserializer.hpp" #include "caf/deserializer.hpp"
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/ieee_754.hpp" #include "caf/detail/ieee_754.hpp"
#include "caf/detail/int_list.hpp" #include "caf/detail/int_list.hpp"
#include "caf/detail/stringification_inspector.hpp" #include "caf/detail/stringification_inspector.hpp"
......
...@@ -18,11 +18,8 @@ ...@@ -18,11 +18,8 @@
#include "caf/after.hpp" #include "caf/after.hpp"
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/defaults.hpp" #include "caf/defaults.hpp"
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/get_root_uuid.hpp"
#include "caf/detail/latch.hpp" #include "caf/detail/latch.hpp"
#include "caf/detail/prometheus_broker.hpp" #include "caf/detail/prometheus_broker.hpp"
#include "caf/detail/ripemd_160.hpp"
#include "caf/detail/set_thread_name.hpp" #include "caf/detail/set_thread_name.hpp"
#include "caf/event_based_actor.hpp" #include "caf/event_based_actor.hpp"
#include "caf/function_view.hpp" #include "caf/function_view.hpp"
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "caf/detail/get_mac_addresses.hpp"
#include "caf/detail/print.hpp" #include "caf/detail/print.hpp"
#include "caf/io/network/ip_endpoint.hpp" #include "caf/io/network/ip_endpoint.hpp"
#include "caf/raise_error.hpp" #include "caf/raise_error.hpp"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment