NodeStore.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "crypto/AddressCalc.h"
  16. #include "dht/Address.h"
  17. #include "dht/CJDHTConstants.h"
  18. #include "dht/dhtcore/DistanceNodeCollector.h"
  19. #include "dht/dhtcore/LinkStateNodeCollector.h"
  20. #include "dht/dhtcore/Node.h"
  21. #include "dht/dhtcore/NodeHeader.h"
  22. #include "dht/dhtcore/NodeStore_pvt.h"
  23. #include "dht/dhtcore/NodeCollector.h"
  24. #include "dht/dhtcore/NodeList.h"
  25. #include "util/Assert.h"
  26. #include "util/Bits.h"
  27. #include "util/log/Log.h"
  28. #include "util/version/Version.h"
  29. #include "switch/NumberCompress.h"
  30. #include "switch/LabelSplicer.h"
  31. #include <stdbool.h>
  32. #include <inttypes.h>
  33. /** See: NodeStore.h */
  34. struct NodeStore* NodeStore_new(struct Address* myAddress,
  35. const uint32_t capacity,
  36. struct Allocator* allocator,
  37. struct Log* logger,
  38. struct Random* rand)
  39. {
  40. struct NodeStore_pvt* out = Allocator_malloc(allocator, sizeof(struct NodeStore_pvt));
  41. out->pub.selfAddress = myAddress;
  42. out->headers = Allocator_calloc(allocator, sizeof(struct NodeHeader), capacity);
  43. out->nodes = Allocator_calloc(allocator, sizeof(struct Node), capacity);
  44. out->capacity = capacity;
  45. out->logger = logger;
  46. out->pub.size = 0;
  47. out->labelSum = 0;
  48. out->rand = rand;
  49. Identity_set(out);
  50. return &out->pub;
  51. }
  52. static struct Node* nodeForIndex(struct NodeStore_pvt* store, uint32_t index)
  53. {
  54. struct Node* out = &store->nodes[index];
  55. out->reach = store->headers[index].reach;
  56. out->version = store->headers[index].version;
  57. return out;
  58. }
  59. /** See: NodeStore.h */
  60. struct Node* NodeStore_getNode(struct NodeStore* nodeStore, struct Address* addr)
  61. {
  62. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  63. uint32_t pfx = Address_getPrefix(addr);
  64. // If multiple nodes with the same address, get the one with the best reach.
  65. int32_t bestIndex = -1;
  66. uint32_t bestReach = 0;
  67. for (int32_t i = 0; i < (int32_t) store->pub.size; i++) {
  68. if (pfx == store->headers[i].addressPrefix
  69. && Bits_memcmp(addr->key, store->nodes[i].address.key, Address_KEY_SIZE) == 0
  70. && store->headers[i].reach >= bestReach)
  71. {
  72. bestIndex = i;
  73. bestReach = store->headers[i].reach;
  74. }
  75. }
  76. if (bestIndex == -1) {
  77. return NULL;
  78. }
  79. // Synchronize the reach values.
  80. return nodeForIndex(store, bestIndex);
  81. }
  82. /**
  83. * Dump the table, one node at a time.
  84. */
  85. struct Node* NodeStore_dumpTable(struct NodeStore* store, uint32_t index)
  86. {
  87. struct NodeStore_pvt* s = Identity_cast((struct NodeStore_pvt*)store);
  88. if (index >= (uint32_t)store->size) {
  89. return NULL;
  90. }
  91. return nodeForIndex(s, index);
  92. }
  93. static inline uint32_t getSwitchIndex(struct Address* addr)
  94. {
  95. uint32_t bits = NumberCompress_bitsUsedForLabel(addr->path);
  96. return NumberCompress_getDecompressed(addr->path, bits);
  97. }
  98. static inline void replaceNode(struct Node* nodeToReplace,
  99. struct NodeHeader* headerToReplace,
  100. struct Address* addr,
  101. struct NodeStore_pvt* store)
  102. {
  103. headerToReplace->addressPrefix = Address_getPrefix(addr);
  104. headerToReplace->reach = 0;
  105. headerToReplace->version = 0;
  106. headerToReplace->switchIndex = getSwitchIndex(addr);
  107. store->labelSum -= Bits_log2x64(nodeToReplace->address.path);
  108. store->labelSum += Bits_log2x64(addr->path);
  109. Assert_true(store->labelSum > 0);
  110. Bits_memcpyConst(&nodeToReplace->address, addr, sizeof(struct Address));
  111. }
  112. #ifdef Log_DEBUG
  113. static void logNodeZeroed(struct Log* logger, struct Node* node)
  114. {
  115. uint8_t ip6[40];
  116. AddrTools_printIp(ip6, node->address.ip6.bytes);
  117. Log_debug(logger, "Zeroing reach for node [%s]", ip6);
  118. }
  119. #else
  120. #define logNodeZeroed(x, y)
  121. #endif
  122. static struct Node* nodeForHeader(struct NodeHeader* header, struct NodeStore_pvt* store)
  123. {
  124. return nodeForIndex(store, header - store->headers);
  125. }
  126. static inline void adjustReach(struct NodeHeader* header,
  127. const int64_t reachDiff,
  128. struct NodeStore_pvt* store)
  129. {
  130. if (reachDiff == 0) {
  131. return;
  132. }
  133. int64_t newReach = reachDiff + header->reach;
  134. if (newReach <= 0) {
  135. header->reach = 0;
  136. logNodeZeroed(store->logger, nodeForHeader(header, store));
  137. } else if (newReach > INT32_MAX) {
  138. header->reach = INT32_MAX;
  139. } else {
  140. header->reach = (uint32_t) newReach;
  141. }
  142. }
  143. static void removeNode(struct Node* node, struct NodeStore_pvt* store)
  144. {
  145. Assert_true(node >= store->nodes && node < store->nodes + store->pub.size);
  146. #ifdef Log_DEBUG
  147. uint8_t addr[60];
  148. Address_print(addr, &node->address);
  149. Log_debug(store->logger, "Removing route to %s\n", addr);
  150. #endif
  151. store->pub.size--;
  152. if (node != &store->nodes[store->pub.size]) {
  153. Bits_memcpyConst(node, &store->nodes[store->pub.size], sizeof(struct Node));
  154. struct NodeHeader* header = &store->headers[node - store->nodes];
  155. Bits_memcpyConst(header, &store->headers[store->pub.size], sizeof(struct NodeHeader));
  156. }
  157. // This is needed because otherwise replaceNode will cause the labelSum to skew.
  158. store->nodes[store->pub.size].address.path = 0;
  159. }
  160. struct Node* NodeStore_addNode(struct NodeStore* nodeStore,
  161. struct Address* addr,
  162. int64_t reachDifference,
  163. uint32_t version)
  164. {
  165. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  166. if (!Version_isCompatible(Version_CURRENT_PROTOCOL, version)) {
  167. Log_debug(store->logger, "node with incompatable version");
  168. return NULL;
  169. }
  170. uint32_t pfx = Address_getPrefix(addr);
  171. if (Bits_memcmp(addr->ip6.bytes, store->pub.selfAddress, 16) == 0) {
  172. Log_debug(store->logger, "got introduced to ourselves");
  173. return NULL;
  174. }
  175. if (!AddressCalc_validAddress(addr->ip6.bytes)) {
  176. uint8_t address[60];
  177. Address_print(address, addr);
  178. Log_critical(store->logger,
  179. "tried to insert address %s which does not begin with 0xFC.\n",
  180. address);
  181. Assert_true(false);
  182. }
  183. // Keep track of the node with the longest label so if the store is full, it can be replaced.
  184. int worstNode = -1;
  185. uint64_t worstPath = 0;
  186. // becomes true when the direct peer behind this path is found.
  187. int foundPeer = LabelSplicer_isOneHop(addr->path);
  188. for (int i = 0; i < store->pub.size; i++) {
  189. if (LabelSplicer_isOneHop(store->nodes[i].address.path)
  190. && LabelSplicer_routesThrough(addr->path, store->nodes[i].address.path))
  191. {
  192. foundPeer = 1;
  193. }
  194. if (store->pub.size >= store->capacity && store->nodes[i].address.path > worstPath) {
  195. worstPath = store->nodes[i].address.path;
  196. worstNode = i;
  197. }
  198. if (store->headers[i].addressPrefix == pfx
  199. && Address_isSameIp(&store->nodes[i].address, addr))
  200. {
  201. // same address
  202. #ifdef PARANOIA
  203. uint8_t realAddr[16];
  204. AddressCalc_addressForPublicKey(realAddr, addr->key);
  205. Assert_true(!Bits_memcmp(realAddr, addr->ip6.bytes, 16));
  206. #endif
  207. if (store->nodes[i].address.path == addr->path) {
  208. // same node
  209. } else if (LabelSplicer_routesThrough(store->nodes[i].address.path, addr->path)) {
  210. #ifdef Log_DEBUG
  211. uint8_t nodeAddr[60];
  212. Address_print(nodeAddr, &store->nodes[i].address);
  213. uint8_t newAddr[20];
  214. AddrTools_printPath(newAddr, addr->path);
  215. Log_debug(store->logger,
  216. "Found a better route to %s via %s\n",
  217. nodeAddr,
  218. newAddr);
  219. #endif
  220. // We can take the reach of the existing node with us because this path is a
  221. // subpath of the one we were using so it's functionality implies this path's
  222. // functionality.
  223. reachDifference += store->headers[i].reach;
  224. // Remove the node and continue on to add this one.
  225. // If we just change the path, we get duplicates.
  226. removeNode(&store->nodes[i], store);
  227. i--;
  228. continue;
  229. } else if (!LabelSplicer_routesThrough(addr->path, store->nodes[i].address.path)) {
  230. // Completely different routes, store seperately.
  231. continue;
  232. }
  233. // either same node or discovered a redundant route to the same node.
  234. adjustReach(&store->headers[i], reachDifference, store);
  235. store->headers[i].version = version;
  236. return nodeForIndex(store, i);
  237. } else if (store->nodes[i].address.path == addr->path) {
  238. // same path different addr.
  239. // When a node restarts, it's switch renumbers meaning that the paths to other nodes
  240. // change. This causes a previously valid path to A to now point to B. The problem
  241. // is that there is a real node at the end of the path to B and worse, there are real
  242. // nodes behind that one. Those nodes may respond properly to *switch* pings but not
  243. // to router pings or searches because their addresses are different so the keys don't
  244. // match.
  245. //
  246. // This will allow incoming packets from B to clear A out of the table and replace
  247. // them with B while preventing another node's memory of B from causing A to be
  248. // replaced. Being *told* about a node implies reachDifference == 0, having first hand
  249. // experience of it's existance implies reachDifference > 0.
  250. if (reachDifference > 0) {
  251. // Removing and adding back because of the creepy above comment about duplicates.
  252. removeNode(&store->nodes[i], store);
  253. i--;
  254. continue;
  255. } else {
  256. // TODO:
  257. // We were told about another node, it might be B and it might be A (invalid).
  258. // the only way to know for sure it to queue a ping to that node and wait for it
  259. // to respond. We need a system for queueing pings so we don't send out a flood.
  260. return NULL;
  261. }
  262. }
  263. }
  264. #ifdef Log_DEBUG
  265. uint8_t nodeAddr[60];
  266. Address_print(nodeAddr, addr);
  267. Log_debug(store->logger,
  268. "Discovered node: %s reach %" PRIu64,
  269. nodeAddr,
  270. reachDifference);
  271. #endif
  272. if (!foundPeer) {
  273. Log_debug(store->logger, "Dropping discovered node because there is no peer behind it");
  274. return NULL;
  275. }
  276. #ifdef PARANOIA
  277. for (int i = 0; i < store->pub.size; i++) {
  278. Assert_true(store->headers[i].addressPrefix ==
  279. Address_getPrefix(&store->nodes[i].address));
  280. Assert_true(!(!Bits_memcmp(&store->nodes[i].address.ip6, &addr->ip6, 16)
  281. && store->nodes[i].address.path == addr->path));
  282. }
  283. Assert_true(store->pub.size < store->capacity || worstNode != -1);
  284. #endif
  285. int insertionIndex = (store->pub.size >= store->capacity) ? worstNode : store->pub.size++;
  286. replaceNode(&store->nodes[insertionIndex], &store->headers[insertionIndex], addr, store);
  287. adjustReach(&store->headers[insertionIndex], reachDifference, store);
  288. store->headers[insertionIndex].version = version;
  289. return nodeForIndex(store, insertionIndex);
  290. }
  291. struct Node* NodeStore_getBest(struct Address* targetAddress, struct NodeStore* nodeStore)
  292. {
  293. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  294. struct NodeCollector_Element element = {
  295. .value = 0,
  296. .distance = UINT32_MAX,
  297. .node = NULL
  298. };
  299. struct NodeCollector collector = {
  300. .capacity = 1,
  301. .targetPrefix = Address_getPrefix(targetAddress),
  302. .targetAddress = targetAddress,
  303. .nodes = &element,
  304. .logger = store->logger
  305. };
  306. collector.thisNodeDistance =
  307. Address_getPrefix(store->pub.selfAddress) ^ collector.targetPrefix;
  308. for (int i = 0; i < store->pub.size; i++) {
  309. if (store->headers[i].reach != 0) {
  310. LinkStateNodeCollector_addNode(store->headers + i, store->nodes + i, &collector);
  311. }
  312. }
  313. return element.node ? nodeForHeader(element.node, store) : NULL;
  314. }
  315. struct NodeList* NodeStore_getNodesByAddr(struct Address* address,
  316. const uint32_t max,
  317. struct Allocator* allocator,
  318. struct NodeStore* nodeStore)
  319. {
  320. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  321. struct NodeCollector* collector = NodeCollector_new(address,
  322. max,
  323. store->pub.selfAddress,
  324. true,
  325. store->logger,
  326. allocator);
  327. for (int i = 0; i < store->pub.size; i++) {
  328. DistanceNodeCollector_addNode(store->headers + i, store->nodes + i, collector);
  329. }
  330. struct NodeList* out = Allocator_malloc(allocator, sizeof(struct NodeList));
  331. out->nodes = Allocator_malloc(allocator, max * sizeof(char*));
  332. uint32_t outIndex = 0;
  333. for (uint32_t i = 0; i < max; i++) {
  334. if (collector->nodes[i].node != NULL
  335. && !Bits_memcmp(collector->nodes[i].body->address.ip6.bytes, address->ip6.bytes, 16))
  336. {
  337. out->nodes[outIndex] = collector->nodes[i].body;
  338. outIndex++;
  339. }
  340. }
  341. out->size = outIndex;
  342. return out;
  343. }
  344. struct NodeList* NodeStore_getPeers(uint64_t label,
  345. const uint32_t max,
  346. struct Allocator* allocator,
  347. struct NodeStore* nodeStore)
  348. {
  349. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  350. // truncate the label to the part which this node uses...
  351. label &= (((uint64_t)1) << NumberCompress_bitsUsedForLabel(label)) - 1;
  352. struct NodeList* out = Allocator_malloc(allocator, sizeof(struct NodeList));
  353. out->nodes = Allocator_calloc(allocator, sizeof(char*), max);
  354. for (int i = 0; i < store->pub.size; i++) {
  355. uint64_t p = store->nodes[i].address.path;
  356. if (LabelSplicer_isOneHop(p)) {
  357. int j;
  358. for (j = 0; j < (int)max; j++) {
  359. if (out->nodes[j] && (out->nodes[j]->address.path ^ label) < (p ^ label)) {
  360. break;
  361. }
  362. }
  363. switch (j) {
  364. default: Bits_memmove(out->nodes, &out->nodes[1], (j - 1) * sizeof(char*));
  365. case 1: out->nodes[j - 1] = &store->nodes[i];
  366. case 0:;
  367. }
  368. }
  369. }
  370. out->size = 0;
  371. for (int i = 0; i < (int)max; i++) {
  372. if (out->nodes[i]) {
  373. out->nodes = &out->nodes[i];
  374. out->size = max - i;
  375. break;
  376. }
  377. }
  378. return out;
  379. }
  380. /** See: NodeStore.h */
  381. struct NodeList* NodeStore_getClosestNodes(struct NodeStore* nodeStore,
  382. struct Address* targetAddress,
  383. struct Address* requestorsAddress,
  384. const uint32_t count,
  385. uint32_t versionOfRequestingNode,
  386. struct Allocator* allocator)
  387. {
  388. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  389. // LinkStateNodeCollector strictly requires that allowNodesFartherThanUs be true.
  390. struct NodeCollector* collector = NodeCollector_new(targetAddress,
  391. count,
  392. store->pub.selfAddress,
  393. true,
  394. store->logger,
  395. allocator);
  396. // Don't send nodes which route back to the node which asked us.
  397. uint32_t index = (requestorsAddress) ? getSwitchIndex(requestorsAddress) : 0;
  398. // naive implementation, todo make this faster
  399. for (int i = 0; i < store->pub.size; i++) {
  400. if (requestorsAddress && store->headers[i].switchIndex == index) {
  401. // Nodes which are down the same interface as the node who asked.
  402. continue;
  403. }
  404. if (!Version_isCompatible(store->headers[i].version, versionOfRequestingNode)) {
  405. // Known not to be compatable.
  406. continue;
  407. }
  408. LinkStateNodeCollector_addNode(store->headers + i, store->nodes + i, collector);
  409. }
  410. struct NodeList* out = Allocator_malloc(allocator, sizeof(struct NodeList));
  411. out->nodes = Allocator_malloc(allocator, count * sizeof(char*));
  412. uint32_t outIndex = 0;
  413. for (uint32_t i = 0; i < count; i++) {
  414. if (collector->nodes[i].node != NULL) {
  415. out->nodes[outIndex] = nodeForHeader(collector->nodes[i].node, store);
  416. outIndex++;
  417. }
  418. }
  419. out->size = outIndex;
  420. return out;
  421. }
  422. /** See: NodeStore.h */
  423. void NodeStore_updateReach(const struct Node* const node,
  424. const struct NodeStore* const nodeStore)
  425. {
  426. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  427. store->headers[node - store->nodes].reach = node->reach;
  428. uint64_t path = node->address.path;
  429. for (int i = 0; i < store->pub.size; i++) {
  430. uint64_t dest = store->nodes[i].address.path;
  431. if (LabelSplicer_routesThrough(dest, path)
  432. && store->headers[i].reach > node->reach)
  433. {
  434. store->headers[i].reach = node->reach;
  435. if (node->reach == 0) {
  436. logNodeZeroed(store->logger, &store->nodes[i]);
  437. }
  438. } else if (LabelSplicer_routesThrough(path, dest)
  439. && store->headers[i].reach < node->reach)
  440. {
  441. store->headers[i].reach = node->reach;
  442. }
  443. }
  444. }
  445. int NodeStore_nonZeroNodes(struct NodeStore* nodeStore)
  446. {
  447. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  448. int nonZeroNodes = 0;
  449. for (int i = 0; i < store->pub.size; i++) {
  450. nonZeroNodes += (store->headers[i].reach > 0);
  451. }
  452. return nonZeroNodes;
  453. }
  454. /** see: NodeStore.h */
  455. struct Node* NodeStore_getNodeByNetworkAddr(uint64_t path, struct NodeStore* nodeStore)
  456. {
  457. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  458. if (path == 0) {
  459. return (store->pub.size > 0)
  460. ? &store->nodes[Random_uint32(store->rand) % store->pub.size] : NULL;
  461. }
  462. for (int i = 0; i < store->pub.size; i++) {
  463. if (path == store->nodes[i].address.path) {
  464. return nodeForIndex(store, i);
  465. }
  466. }
  467. return NULL;
  468. }
  469. int NodeStore_brokenPath(uint64_t path, struct NodeStore* nodeStore)
  470. {
  471. struct NodeStore_pvt* store = Identity_cast((struct NodeStore_pvt*)nodeStore);
  472. int out = 0;
  473. for (int32_t i = (int32_t) store->pub.size - 1; i >= 0; i--) {
  474. if (LabelSplicer_routesThrough(store->nodes[i].address.path, path)) {
  475. if (LabelSplicer_isOneHop(store->nodes[i].address.path)) {
  476. Assert_true(store->nodes[i].address.path == path);
  477. }
  478. removeNode(&store->nodes[i], store);
  479. out++;
  480. }
  481. }
  482. return out;
  483. }