/src/Fast-DDS/src/cpp/utils/Host.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima). |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef UTILS_HOST_HPP_ |
16 | | #define UTILS_HOST_HPP_ |
17 | | |
18 | | #include <fastcdr/cdr/fixed_size_string.hpp> |
19 | | |
20 | | #include <fastdds/dds/log/Log.hpp> |
21 | | #include <fastdds/rtps/common/LocatorList.hpp> |
22 | | #include <fastdds/utils/IPFinder.hpp> |
23 | | #include <fastdds/utils/md5.hpp> |
24 | | |
25 | | |
26 | | namespace eprosima { |
27 | | |
28 | | |
29 | | /** |
30 | | * This singleton generates a host_id based on system interfaces |
31 | | * ip addresses, mac addresses or the machine UUID. |
32 | | */ |
33 | | class Host |
34 | | { |
35 | | public: |
36 | | |
37 | | static const size_t mac_id_length = 6; |
38 | | struct uint48 |
39 | | { |
40 | | unsigned char value[mac_id_length]; |
41 | | |
42 | | uint48() |
43 | 0 | { |
44 | 0 | memset(value, 0, mac_id_length); |
45 | 0 | } |
46 | | |
47 | | }; |
48 | | |
49 | | inline uint16_t id() const |
50 | 0 | { |
51 | 0 | return id_; |
52 | 0 | } |
53 | | |
54 | | inline uint48 mac_id() const |
55 | 0 | { |
56 | 0 | return mac_id_; |
57 | 0 | } |
58 | | |
59 | | inline fastcdr::string_255 machine_id() const |
60 | 0 | { |
61 | 0 | return machine_id_; |
62 | 0 | } |
63 | | |
64 | | static Host& instance() |
65 | 0 | { |
66 | 0 | static Host singleton; |
67 | 0 | return singleton; |
68 | 0 | } |
69 | | |
70 | | static inline uint16_t compute_id( |
71 | | const fastdds::rtps::LocatorList& loc) |
72 | 0 | { |
73 | 0 | uint16_t ret_val = 0; |
74 | |
|
75 | 0 | if (loc.size() > 0) |
76 | 0 | { |
77 | 0 | fastdds::MD5 md5; |
78 | 0 | for (auto& l : loc) |
79 | 0 | { |
80 | 0 | md5.update(l.address, sizeof(l.address)); |
81 | 0 | } |
82 | 0 | md5.finalize(); |
83 | | |
84 | | // Hash the 16-bytes md5.digest into a uint16_t |
85 | 0 | ret_val = 0; |
86 | 0 | for (size_t i = 0; i < sizeof(md5.digest); i += 2) |
87 | 0 | { |
88 | | // Treat the next two bytes as a big-endian uint16_t and |
89 | | // hash them into ret_val. |
90 | 0 | uint16_t tmp = static_cast<uint16_t>(md5.digest[i]); |
91 | 0 | tmp = (tmp << 8) | static_cast<uint16_t>(md5.digest[i + 1]); |
92 | 0 | ret_val ^= tmp; |
93 | 0 | } |
94 | 0 | } |
95 | 0 | else |
96 | 0 | { |
97 | 0 | reinterpret_cast<uint8_t*>(&ret_val)[0] = 127; |
98 | 0 | reinterpret_cast<uint8_t*>(&ret_val)[1] = 1; |
99 | 0 | } |
100 | |
|
101 | 0 | return ret_val; |
102 | 0 | } |
103 | | |
104 | | private: |
105 | | |
106 | | Host() |
107 | 0 | { |
108 | | // Compute the host id |
109 | 0 | fastdds::rtps::LocatorList loc; |
110 | 0 | fastdds::rtps::IPFinder::getIP4Address(&loc); |
111 | 0 | id_ = compute_id(loc); |
112 | | |
113 | | // Compute the MAC id |
114 | 0 | std::vector<fastdds::rtps::IPFinder::info_MAC> macs; |
115 | 0 | if (fastdds::rtps::IPFinder::getAllMACAddress(&macs) && |
116 | 0 | macs.size() > 0) |
117 | 0 | { |
118 | 0 | fastdds::MD5 md5; |
119 | 0 | for (auto& m : macs) |
120 | 0 | { |
121 | 0 | md5.update(m.address, sizeof(m.address)); |
122 | 0 | } |
123 | 0 | md5.finalize(); |
124 | 0 | for (size_t i = 0, j = 0; i < sizeof(md5.digest); ++i, ++j) |
125 | 0 | { |
126 | 0 | if (j >= mac_id_length) |
127 | 0 | { |
128 | 0 | j = 0; |
129 | 0 | } |
130 | 0 | mac_id_.value[j] ^= md5.digest[i]; |
131 | 0 | } |
132 | 0 | } |
133 | 0 | else |
134 | 0 | { |
135 | 0 | EPROSIMA_LOG_WARNING(UTILS, "Cannot get MAC addresses. Failing back to IP based ID"); |
136 | 0 | for (size_t i = 0; i < mac_id_length; i += 2) |
137 | 0 | { |
138 | 0 | mac_id_.value[i] = (id_ >> 8); |
139 | 0 | mac_id_.value[i + 1] = (id_ & 0xFF); |
140 | 0 | } |
141 | 0 | } |
142 | | |
143 | | // Compute the machine id hash |
144 | 0 | machine_id_ = compute_machine_id(); |
145 | 0 | if (machine_id_ == "") |
146 | 0 | { |
147 | 0 | EPROSIMA_LOG_WARNING(UTILS, "Cannot get machine id. Failing back to IP based ID"); |
148 | 0 | } |
149 | 0 | } |
150 | | |
151 | | static fastcdr::string_255 compute_machine_id(); |
152 | | |
153 | | uint16_t id_; |
154 | | uint48 mac_id_; |
155 | | fastcdr::string_255 machine_id_; |
156 | | }; |
157 | | |
158 | | } // eprosima |
159 | | |
160 | | #endif // UTILS_HOST_HPP_ |