IPAddressSource.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright 2014-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <glog/logging.h>
  18. #include <sys/types.h>
  19. #include <algorithm>
  20. #include <array>
  21. #include <cstring>
  22. #include <string>
  23. #include <type_traits>
  24. #include <folly/Format.h>
  25. #include <folly/detail/IPAddress.h>
  26. // BSDish platforms don't provide standard access to s6_addr16
  27. #ifndef s6_addr16
  28. #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
  29. defined(__OpenBSD__)
  30. #define s6_addr16 __u6_addr.__u6_addr16
  31. #endif
  32. #endif
  33. namespace folly {
  34. namespace detail {
  35. /**
  36. * Helper for working with unsigned char* or uint8_t* ByteArray values
  37. */
  38. struct Bytes {
  39. // mask the values from two byte arrays, returning a new byte array
  40. template <std::size_t N>
  41. static std::array<uint8_t, N> mask(
  42. const std::array<uint8_t, N>& a,
  43. const std::array<uint8_t, N>& b) {
  44. static_assert(N > 0, "Can't mask an empty ByteArray");
  45. std::size_t asize = a.size();
  46. std::array<uint8_t, N> ba{{0}};
  47. for (std::size_t i = 0; i < asize; i++) {
  48. ba[i] = uint8_t(a[i] & b[i]);
  49. }
  50. return ba;
  51. }
  52. template <std::size_t N>
  53. static std::pair<std::array<uint8_t, N>, uint8_t> longestCommonPrefix(
  54. const std::array<uint8_t, N>& one,
  55. uint8_t oneMask,
  56. const std::array<uint8_t, N>& two,
  57. uint8_t twoMask) {
  58. static constexpr auto kBitCount = N * 8;
  59. static constexpr std::array<uint8_t, 8> kMasks{{
  60. 0x80, // /1
  61. 0xc0, // /2
  62. 0xe0, // /3
  63. 0xf0, // /4
  64. 0xf8, // /5
  65. 0xfc, // /6
  66. 0xfe, // /7
  67. 0xff // /8
  68. }};
  69. if (oneMask > kBitCount || twoMask > kBitCount) {
  70. throw std::invalid_argument(sformat(
  71. "Invalid mask length: {}. Mask length must be <= {}",
  72. std::max(oneMask, twoMask),
  73. kBitCount));
  74. }
  75. auto mask = std::min(oneMask, twoMask);
  76. uint8_t byteIndex = 0;
  77. std::array<uint8_t, N> ba{{0}};
  78. // Compare a byte at a time. Note - I measured compared this with
  79. // going multiple bytes at a time (8, 4, 2 and 1). It turns out
  80. // to be 20 - 25% slower for 4 and 16 byte arrays.
  81. while (byteIndex * 8 < mask && one[byteIndex] == two[byteIndex]) {
  82. ba[byteIndex] = one[byteIndex];
  83. ++byteIndex;
  84. }
  85. auto bitIndex = std::min(mask, uint8_t(byteIndex * 8));
  86. uint8_t bI = uint8_t(bitIndex / 8);
  87. uint8_t bM = uint8_t(bitIndex % 8);
  88. // Compute the bit up to which the two byte arrays match in the
  89. // unmatched byte.
  90. // Here the check is bitIndex < mask since the 0th mask entry in
  91. // kMasks array holds the mask for masking the MSb in this byte.
  92. // We could instead make it hold so that no 0th entry masks no
  93. // bits but thats a useless iteration.
  94. while (bitIndex < mask &&
  95. ((one[bI] & kMasks[bM]) == (two[bI] & kMasks[bM]))) {
  96. ba[bI] = uint8_t(one[bI] & kMasks[bM]);
  97. ++bitIndex;
  98. bI = uint8_t(bitIndex / 8);
  99. bM = uint8_t(bitIndex % 8);
  100. }
  101. return {ba, bitIndex};
  102. }
  103. // create an in_addr from an uint8_t*
  104. static inline in_addr mkAddress4(const uint8_t* src) {
  105. union {
  106. in_addr addr;
  107. uint8_t bytes[4];
  108. } addr;
  109. std::memset(&addr, 0, 4);
  110. std::memcpy(addr.bytes, src, 4);
  111. return addr.addr;
  112. }
  113. // create an in6_addr from an uint8_t*
  114. static inline in6_addr mkAddress6(const uint8_t* src) {
  115. in6_addr addr;
  116. std::memset(&addr, 0, 16);
  117. std::memcpy(addr.s6_addr, src, 16);
  118. return addr;
  119. }
  120. // convert an uint8_t* to its hex value
  121. static std::string toHex(const uint8_t* src, std::size_t len) {
  122. static const char* const lut = "0123456789abcdef";
  123. std::string out(len * 2, 0);
  124. for (std::size_t i = 0; i < len; i++) {
  125. const unsigned char c = src[i];
  126. out[i * 2 + 0] = lut[c >> 4];
  127. out[i * 2 + 1] = lut[c & 15];
  128. }
  129. return out;
  130. }
  131. private:
  132. Bytes() = delete;
  133. ~Bytes() = delete;
  134. };
  135. //
  136. // Write a maximum amount of base-converted character digits, of a
  137. // given base, from an unsigned integral type into a byte buffer of
  138. // sufficient size.
  139. //
  140. // This function does not append null terminators.
  141. //
  142. // Output buffer size must be guaranteed by caller (indirectly
  143. // controlled by DigitCount template parameter).
  144. //
  145. // Having these parameters at compile time allows compiler to
  146. // precompute several of the values, use smaller instructions, and
  147. // better optimize surrounding code.
  148. //
  149. // IntegralType:
  150. // - Something like uint8_t, uint16_t, etc
  151. //
  152. // DigitCount is the maximum number of digits to be printed
  153. // - This is tied to IntegralType and Base. For example:
  154. // - uint8_t in base 10 will print at most 3 digits ("255")
  155. // - uint16_t in base 16 will print at most 4 hex digits ("FFFF")
  156. //
  157. // Base is the desired output base of the string
  158. // - Base 10 will print [0-9], base 16 will print [0-9a-f]
  159. //
  160. // PrintAllDigits:
  161. // - Whether or not leading zeros should be printed
  162. //
  163. template <
  164. class IntegralType,
  165. IntegralType DigitCount,
  166. IntegralType Base = IntegralType(10),
  167. bool PrintAllDigits = false,
  168. class = typename std::enable_if<
  169. std::is_integral<IntegralType>::value &&
  170. std::is_unsigned<IntegralType>::value,
  171. bool>::type>
  172. inline void writeIntegerString(IntegralType val, char** buffer) {
  173. char* buf = *buffer;
  174. if (!PrintAllDigits && val == 0) {
  175. *(buf++) = '0';
  176. *buffer = buf;
  177. return;
  178. }
  179. IntegralType powerToPrint = 1;
  180. for (IntegralType i = 1; i < DigitCount; ++i) {
  181. powerToPrint *= Base;
  182. }
  183. bool found = PrintAllDigits;
  184. while (powerToPrint) {
  185. if (found || powerToPrint <= val) {
  186. IntegralType value = IntegralType(val / powerToPrint);
  187. if (Base == 10 || value < 10) {
  188. value += '0';
  189. } else {
  190. value += ('a' - 10);
  191. }
  192. *(buf++) = char(value);
  193. val %= powerToPrint;
  194. found = true;
  195. }
  196. powerToPrint /= Base;
  197. }
  198. *buffer = buf;
  199. }
  200. inline size_t fastIpV4ToBufferUnsafe(const in_addr& inAddr, char* str) {
  201. const uint8_t* octets = reinterpret_cast<const uint8_t*>(&inAddr.s_addr);
  202. char* buf = str;
  203. writeIntegerString<uint8_t, 3>(octets[0], &buf);
  204. *(buf++) = '.';
  205. writeIntegerString<uint8_t, 3>(octets[1], &buf);
  206. *(buf++) = '.';
  207. writeIntegerString<uint8_t, 3>(octets[2], &buf);
  208. *(buf++) = '.';
  209. writeIntegerString<uint8_t, 3>(octets[3], &buf);
  210. return buf - str;
  211. }
  212. inline std::string fastIpv4ToString(const in_addr& inAddr) {
  213. char str[sizeof("255.255.255.255")];
  214. return std::string(str, fastIpV4ToBufferUnsafe(inAddr, str));
  215. }
  216. inline void fastIpv4AppendToString(const in_addr& inAddr, std::string& out) {
  217. char str[sizeof("255.255.255.255")];
  218. out.append(str, fastIpV4ToBufferUnsafe(inAddr, str));
  219. }
  220. inline size_t fastIpv6ToBufferUnsafe(const in6_addr& in6Addr, char* str) {
  221. #ifdef _MSC_VER
  222. const uint16_t* bytes = reinterpret_cast<const uint16_t*>(&in6Addr.u.Word);
  223. #else
  224. const uint16_t* bytes = reinterpret_cast<const uint16_t*>(&in6Addr.s6_addr16);
  225. #endif
  226. char* buf = str;
  227. for (int i = 0; i < 8; ++i) {
  228. writeIntegerString<
  229. uint16_t,
  230. 4, // at most 4 hex digits per ushort
  231. 16, // base 16 (hex)
  232. true>(htons(bytes[i]), &buf);
  233. if (i != 7) {
  234. *(buf++) = ':';
  235. }
  236. }
  237. return buf - str;
  238. }
  239. inline std::string fastIpv6ToString(const in6_addr& in6Addr) {
  240. char str[sizeof("2001:0db8:0000:0000:0000:ff00:0042:8329")];
  241. return std::string(str, fastIpv6ToBufferUnsafe(in6Addr, str));
  242. }
  243. inline void fastIpv6AppendToString(const in6_addr& in6Addr, std::string& out) {
  244. char str[sizeof("2001:0db8:0000:0000:0000:ff00:0042:8329")];
  245. out.append(str, fastIpv6ToBufferUnsafe(in6Addr, str));
  246. }
  247. } // namespace detail
  248. } // namespace folly