cadet_tunnel_tree.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file cadet/cadet_tunnel_tree.c
  19. * @brief Tunnel tree handling functions
  20. * @author Bartlomiej Polot
  21. */
  22. #include "cadet.h"
  23. #include "cadet_tunnel_tree.h"
  24. #define CADET_TREE_DEBUG GNUNET_YES
  25. /**
  26. * Node of path tree for a tunnel
  27. */
  28. struct CadetTunnelTreeNode
  29. {
  30. /**
  31. * Peer this node describes
  32. */
  33. GNUNET_PEER_Id peer;
  34. /**
  35. * Parent node in the tree
  36. */
  37. struct CadetTunnelTreeNode *parent;
  38. /**
  39. * DLL of siblings
  40. */
  41. struct CadetTunnelTreeNode *next;
  42. /**
  43. * DLL of siblings
  44. */
  45. struct CadetTunnelTreeNode *prev;
  46. /**
  47. * DLL of children
  48. */
  49. struct CadetTunnelTreeNode *children_head;
  50. /**
  51. * DLL of children
  52. */
  53. struct CadetTunnelTreeNode *children_tail;
  54. /**
  55. * Status of the peer in the tunnel
  56. */
  57. enum CadetPeerState status;
  58. };
  59. /**
  60. * Tree to reach all peers in the tunnel
  61. */
  62. struct CadetTunnelTree
  63. {
  64. /**
  65. * Root node of peer tree
  66. */
  67. struct CadetTunnelTreeNode *root;
  68. /**
  69. * Node that represents our position in the tree (for non local tunnels)
  70. */
  71. struct CadetTunnelTreeNode *me;
  72. /**
  73. * DLL of disconneted nodes
  74. */
  75. struct CadetTunnelTreeNode *disconnected_head;
  76. /**
  77. * DLL of disconneted nodes
  78. */
  79. struct CadetTunnelTreeNode *disconnected_tail;
  80. /**
  81. * Cache of all peers and the first hop to them.
  82. * Indexed by PeerIdentity, contains a pointer to the PeerIdentity
  83. * of 1st hop.
  84. */
  85. struct GNUNET_CONTAINER_MultiHashMap *first_hops;
  86. };
  87. /**
  88. * Create a new path
  89. *
  90. * @param length How many hops will the path have.
  91. *
  92. * @return A newly allocated path with a peer array of the specified length.
  93. */
  94. struct CadetPeerPath *
  95. path_new (unsigned int length)
  96. {
  97. struct CadetPeerPath *p;
  98. p = GNUNET_new (struct CadetPeerPath);
  99. if (length > 0)
  100. {
  101. p->length = length;
  102. p->peers = GNUNET_malloc (length * sizeof (GNUNET_PEER_Id));
  103. }
  104. return p;
  105. }
  106. /**
  107. * Invert the path
  108. *
  109. * @param path the path to invert
  110. */
  111. void
  112. path_invert (struct CadetPeerPath *path)
  113. {
  114. GNUNET_PEER_Id aux;
  115. unsigned int i;
  116. for (i = 0; i < path->length / 2; i++)
  117. {
  118. aux = path->peers[i];
  119. path->peers[i] = path->peers[path->length - i - 1];
  120. path->peers[path->length - i - 1] = aux;
  121. }
  122. }
  123. /**
  124. * Duplicate a path, incrementing short peer's rc.
  125. *
  126. * @param path The path to duplicate.
  127. */
  128. struct CadetPeerPath *
  129. path_duplicate (struct CadetPeerPath *path)
  130. {
  131. struct CadetPeerPath *aux;
  132. unsigned int i;
  133. aux = path_new (path->length);
  134. memcpy (aux->peers, path->peers, path->length * sizeof (GNUNET_PEER_Id));
  135. for (i = 0; i < path->length; i++)
  136. GNUNET_PEER_change_rc (path->peers[i], 1);
  137. return aux;
  138. }
  139. /**
  140. * Recusively update the info about what is the first hop to reach the node
  141. *
  142. * @param tree Tree this nodes belongs to.
  143. * @param parent The node form which to start updating.
  144. * @param hop If known, ID of the first hop.
  145. * If not known, NULL to find out and pass on children.
  146. */
  147. static void
  148. tree_node_update_first_hops (struct CadetTunnelTree *tree,
  149. struct CadetTunnelTreeNode *parent,
  150. struct GNUNET_PeerIdentity *hop);
  151. /**
  152. * Get the length of a path.
  153. *
  154. * @param path The path to measure, with the local peer at any point of it.
  155. *
  156. * @return Number of hops to reach destination.
  157. * UINT_MAX in case the peer is not in the path.
  158. */
  159. unsigned int
  160. path_get_length (struct CadetPeerPath *path)
  161. {
  162. if (NULL == path)
  163. return UINT_MAX;
  164. return path->length;
  165. }
  166. /**
  167. * Destroy the path and free any allocated resources linked to it
  168. *
  169. * @param p the path to destroy
  170. *
  171. * @return GNUNET_OK on success
  172. */
  173. int
  174. path_destroy (struct CadetPeerPath *p)
  175. {
  176. if (NULL == p)
  177. return GNUNET_OK;
  178. GNUNET_PEER_decrement_rcs (p->peers, p->length);
  179. GNUNET_free_non_null (p->peers);
  180. GNUNET_free (p);
  181. return GNUNET_OK;
  182. }
  183. /**
  184. * Allocates and initializes a new node.
  185. * Sets ID and parent of the new node and inserts it in the DLL of the parent
  186. *
  187. * @param parent Node that will be the parent from the new node, NULL for root
  188. * @param peer Short Id of the new node
  189. *
  190. * @return Newly allocated node
  191. */
  192. static struct CadetTunnelTreeNode *
  193. tree_node_new (struct CadetTunnelTreeNode *parent, GNUNET_PEER_Id peer)
  194. {
  195. struct CadetTunnelTreeNode *node;
  196. node = GNUNET_new (struct CadetTunnelTreeNode);
  197. node->peer = peer;
  198. GNUNET_PEER_change_rc (peer, 1);
  199. node->parent = parent;
  200. if (NULL != parent)
  201. GNUNET_CONTAINER_DLL_insert (parent->children_head, parent->children_tail,
  202. node);
  203. return node;
  204. }
  205. /**
  206. * Recursively find the given peer.
  207. *
  208. * @param parent Node where to start looking.
  209. * @param peer_id Short ID of the peer to find.
  210. *
  211. * @return Pointer to the node of the peer. NULL if not found.
  212. */
  213. static struct CadetTunnelTreeNode *
  214. tree_node_find_peer (struct CadetTunnelTreeNode *parent, GNUNET_PEER_Id peer_id)
  215. {
  216. struct CadetTunnelTreeNode *n;
  217. struct CadetTunnelTreeNode *r;
  218. if (parent->peer == peer_id)
  219. return parent;
  220. for (n = parent->children_head; NULL != n; n = n->next)
  221. {
  222. r = tree_node_find_peer (n, peer_id);
  223. if (NULL != r)
  224. return r;
  225. }
  226. return NULL;
  227. }
  228. /**
  229. * Recusively update the info about what is the first hop to reach the node
  230. *
  231. * @param tree Tree this nodes belongs to.
  232. * @param parent ID from node form which to start updating.
  233. * @param hop If known, ID of the first hop.
  234. * If not known, NULL to find out and pass on children.
  235. */
  236. static void
  237. tree_node_update_first_hops (struct CadetTunnelTree *tree,
  238. struct CadetTunnelTreeNode *parent,
  239. struct GNUNET_PeerIdentity *hop)
  240. {
  241. struct GNUNET_PeerIdentity pi;
  242. struct GNUNET_PeerIdentity *copy;
  243. struct GNUNET_PeerIdentity id;
  244. struct CadetTunnelTreeNode *n;
  245. #if CADET_TREE_DEBUG
  246. GNUNET_PEER_resolve (parent->peer, &id);
  247. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Finding first hop for %s.\n",
  248. GNUNET_i2s (&id));
  249. #endif
  250. if (NULL == hop)
  251. {
  252. struct CadetTunnelTreeNode *aux;
  253. struct CadetTunnelTreeNode *old;
  254. aux = old = parent;
  255. while (aux != tree->me)
  256. {
  257. #if CADET_TREE_DEBUG
  258. GNUNET_PEER_resolve (aux->peer, &id);
  259. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: ... checking %s.\n",
  260. GNUNET_i2s (&id));
  261. #endif
  262. old = aux;
  263. aux = aux->parent;
  264. GNUNET_assert (NULL != aux);
  265. }
  266. #if CADET_TREE_DEBUG
  267. GNUNET_PEER_resolve (old->peer, &id);
  268. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: It's %s!\n",
  269. GNUNET_i2s (&id));
  270. #endif
  271. hop = &pi;
  272. GNUNET_PEER_resolve (old->peer, hop);
  273. }
  274. GNUNET_PEER_resolve (parent->peer, &id);
  275. copy = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey);
  276. if (NULL == copy)
  277. copy = GNUNET_new (struct GNUNET_PeerIdentity);
  278. *copy = *hop;
  279. (void) GNUNET_CONTAINER_multihashmap_put (tree->first_hops, &id.hashPubKey,
  280. copy,
  281. GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
  282. for (n = parent->children_head; NULL != n; n = n->next)
  283. {
  284. tree_node_update_first_hops (tree, n, hop);
  285. }
  286. }
  287. static void
  288. tree_node_debug (struct CadetTunnelTreeNode *n, uint16_t level)
  289. {
  290. struct CadetTunnelTreeNode *c;
  291. struct GNUNET_PeerIdentity id;;
  292. uint16_t i;
  293. for (i = 0; i < level; i++)
  294. FPRINTF (stderr, "%s", " ");
  295. if (n->status == CADET_PEER_READY)
  296. FPRINTF (stderr, "%s", "#");
  297. if (n->status == CADET_PEER_SEARCHING)
  298. FPRINTF (stderr, "%s", "+");
  299. if (n->status == CADET_PEER_RELAY)
  300. FPRINTF (stderr, "%s", "-");
  301. if (n->status == CADET_PEER_RECONNECTING)
  302. FPRINTF (stderr, "%s", "*");
  303. GNUNET_PEER_resolve (n->peer, &id);
  304. FPRINTF (stderr, "%s, [%u, %p] ", GNUNET_i2s (&id), n->peer, n);
  305. if (NULL != n->parent)
  306. {
  307. GNUNET_PEER_resolve (n->parent->peer, &id);
  308. FPRINTF (stderr, "(-> %s [%u])\n", GNUNET_i2s (&id), n->parent->peer);
  309. }
  310. else
  311. FPRINTF (stderr, "%s", "(root)\n");
  312. for (c = n->children_head; NULL != c; c = c->next)
  313. tree_node_debug (c, level + 1);
  314. }
  315. /**
  316. * Destroys and frees the node and all children
  317. *
  318. * @param parent Parent node to be destroyed
  319. */
  320. static void
  321. tree_node_destroy (struct CadetTunnelTreeNode *parent)
  322. {
  323. struct CadetTunnelTreeNode *n;
  324. struct CadetTunnelTreeNode *next;
  325. if (NULL == parent)
  326. return;
  327. #if CADET_TREE_DEBUG
  328. struct GNUNET_PeerIdentity id;
  329. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying node %u\n",
  330. parent->peer);
  331. GNUNET_PEER_resolve (parent->peer, &id);
  332. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: (%s)\n", GNUNET_i2s (&id));
  333. #endif
  334. n = parent->children_head;
  335. while (NULL != n)
  336. {
  337. next = n->next;
  338. tree_node_destroy (n);
  339. n = next;
  340. }
  341. GNUNET_PEER_change_rc (parent->peer, -1);
  342. if (NULL != parent->parent)
  343. GNUNET_CONTAINER_DLL_remove (parent->parent->children_head,
  344. parent->parent->children_tail, parent);
  345. GNUNET_free (parent);
  346. }
  347. /**
  348. * Create a new tree.
  349. *
  350. * @param peer A short peer id of the root of the tree.
  351. *
  352. * @return A newly allocated and initialized tunnel tree.
  353. */
  354. struct CadetTunnelTree *
  355. tree_new (GNUNET_PEER_Id peer)
  356. {
  357. struct CadetTunnelTree *tree;
  358. tree = GNUNET_new (struct CadetTunnelTree);
  359. tree->first_hops = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
  360. tree->root = tree_node_new (NULL, peer);
  361. tree->root->status = CADET_PEER_ROOT;
  362. if (1 == peer)
  363. {
  364. tree->me = tree->root;
  365. }
  366. return tree;
  367. }
  368. /**
  369. * Set the status of a node.
  370. *
  371. * @param tree Tree.
  372. * @param peer A short peer id of the node.
  373. * @param status New status to set.
  374. */
  375. void
  376. tree_set_status (struct CadetTunnelTree *tree, GNUNET_PEER_Id peer,
  377. enum CadetPeerState status)
  378. {
  379. struct CadetTunnelTreeNode *n;
  380. n = tree_find_peer (tree, peer);
  381. if (NULL == n)
  382. return;
  383. n->status = status;
  384. }
  385. /**
  386. * Get the status of a node.
  387. *
  388. * @param tree Tree whose node's status we want to now.
  389. * @param peer A short peer id of the node.
  390. *
  391. * @return Status of the peer.
  392. */
  393. enum CadetPeerState
  394. tree_get_status (struct CadetTunnelTree *tree, GNUNET_PEER_Id peer)
  395. {
  396. struct CadetTunnelTreeNode *n;
  397. n = tree_find_peer (tree, peer);
  398. if (NULL == n)
  399. return CADET_PEER_INVALID;
  400. return n->status;
  401. }
  402. /**
  403. * Get the id of the predecessor of the local node.
  404. *
  405. * @param tree Tree whose local id we want to now.
  406. *
  407. * @return Short peer id of local peer.
  408. */
  409. GNUNET_PEER_Id
  410. tree_get_predecessor (struct CadetTunnelTree *tree)
  411. {
  412. if (NULL != tree->me && NULL != tree->me->parent)
  413. return tree->me->parent->peer;
  414. else
  415. return (GNUNET_PEER_Id) 0;
  416. }
  417. /**
  418. * Find the first peer whom to send a packet to go down this path
  419. *
  420. * @param t The tunnel tree to use
  421. * @param peer The peerinfo of the peer we are trying to reach
  422. *
  423. * @return peerinfo of the peer who is the first hop in the tunnel
  424. * NULL on error
  425. *
  426. * FIXME use PEER_Id
  427. */
  428. struct GNUNET_PeerIdentity *
  429. tree_get_first_hop (struct CadetTunnelTree *t, GNUNET_PEER_Id peer)
  430. {
  431. struct GNUNET_PeerIdentity id;
  432. struct GNUNET_PeerIdentity *r;
  433. GNUNET_PEER_resolve (peer, &id);
  434. r = GNUNET_CONTAINER_multihashmap_get (t->first_hops, &id.hashPubKey);
  435. if (NULL == r)
  436. {
  437. struct CadetTunnelTreeNode *n;
  438. n = tree_find_peer (t, peer);
  439. if (NULL != t->me && NULL != n)
  440. {
  441. tree_node_update_first_hops (t, n, NULL);
  442. r = GNUNET_CONTAINER_multihashmap_get (t->first_hops, &id.hashPubKey);
  443. GNUNET_assert (NULL != r);
  444. }
  445. else
  446. {
  447. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  448. "Tree structure inconsistent! me: %p, n: %p", t->me, n);
  449. GNUNET_break (0);
  450. }
  451. }
  452. return r;
  453. }
  454. /**
  455. * Find the given peer in the tree.
  456. *
  457. * @param tree Tree where to look for the peer.
  458. * @param peer_id Short ID of the peer to find.
  459. *
  460. * @return Pointer to the node of the peer. NULL if not found.
  461. */
  462. struct CadetTunnelTreeNode *
  463. tree_find_peer (struct CadetTunnelTree *tree, GNUNET_PEER_Id peer_id)
  464. {
  465. return tree_node_find_peer (tree->root, peer_id);
  466. }
  467. /**
  468. * Recusively mark peer and children as disconnected, notify client
  469. *
  470. * @param tree Tree this node belongs to
  471. * @param parent Node to be clean, potentially with children
  472. * @param cb Callback to use to notify about disconnected peers.
  473. * @param cbcls Closure for cb.
  474. */
  475. static void
  476. tree_mark_peers_disconnected (struct CadetTunnelTree *tree,
  477. struct CadetTunnelTreeNode *parent,
  478. CadetTreeCallback cb, void *cbcls)
  479. {
  480. struct GNUNET_PeerIdentity *pi;
  481. struct GNUNET_PeerIdentity id;
  482. struct CadetTunnelTreeNode *n;
  483. for (n = parent->children_head; NULL != n; n = n->next)
  484. {
  485. tree_mark_peers_disconnected (tree, n, cb, cbcls);
  486. }
  487. if (CADET_PEER_READY == parent->status)
  488. {
  489. if (NULL != cb)
  490. cb (cbcls, parent->peer);
  491. parent->status = CADET_PEER_RECONNECTING;
  492. }
  493. /* Remove and free info about first hop */
  494. GNUNET_PEER_resolve (parent->peer, &id);
  495. pi = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey);
  496. GNUNET_CONTAINER_multihashmap_remove_all (tree->first_hops, &id.hashPubKey);
  497. if (NULL != pi)
  498. GNUNET_free (pi);
  499. }
  500. /**
  501. * Iterate over all children of the local node.
  502. *
  503. * @param tree Tree to use. Must have "me" set.
  504. * @param cb Callback to call over each child.
  505. * @param cb_cls Closure for @c cb.
  506. */
  507. void
  508. tree_iterate_children (struct CadetTunnelTree *tree, CadetTreeCallback cb,
  509. void *cb_cls)
  510. {
  511. struct CadetTunnelTreeNode *n;
  512. if (NULL == tree->me)
  513. return;
  514. for (n = tree->me->children_head; NULL != n; n = n->next)
  515. {
  516. cb (cb_cls, n->peer);
  517. }
  518. }
  519. /**
  520. * Struct to contain a list of pending nodes when iterating a tree.
  521. */
  522. struct CadetTreePendingNode {
  523. /**
  524. * DLL next.
  525. */
  526. struct CadetTreePendingNode *next;
  527. /**
  528. * DLL prev.
  529. */
  530. struct CadetTreePendingNode *prev;
  531. /**
  532. * Pending node.
  533. */
  534. struct CadetTunnelTreeNode *node;
  535. };
  536. /**
  537. * Iterate over all nodes in the tree.
  538. *
  539. * @param tree Tree to use..
  540. * @param cb Callback to call over each child.
  541. * @param cb_cls Closure for @c cb.
  542. *
  543. * TODO: recursive implementation? (s/heap/stack/g)
  544. */
  545. void
  546. tree_iterate_all (struct CadetTunnelTree *tree,
  547. CadetWholeTreeCallback cb,
  548. void *cb_cls)
  549. {
  550. struct CadetTunnelTreeNode *parent;
  551. struct CadetTunnelTreeNode *n;
  552. struct CadetTreePendingNode *head;
  553. struct CadetTreePendingNode *tail;
  554. struct CadetTreePendingNode *pending;
  555. cb (cb_cls, tree->root->peer, 0);
  556. pending = GNUNET_new (struct CadetTreePendingNode);
  557. pending->node = tree->root;
  558. head = tail = NULL;
  559. GNUNET_CONTAINER_DLL_insert (head, tail, pending);
  560. while (NULL != head)
  561. {
  562. pending = head;
  563. parent = pending->node;
  564. GNUNET_CONTAINER_DLL_remove (head, tail, pending);
  565. GNUNET_free (pending);
  566. for (n = parent->children_head; NULL != n; n = n->next)
  567. {
  568. cb (cb_cls, n->peer, parent->peer);
  569. pending = GNUNET_new (struct CadetTreePendingNode);
  570. pending->node = n;
  571. /* Insert_tail: breadth first, Insert: depth first */
  572. GNUNET_CONTAINER_DLL_insert (head, tail, pending);
  573. }
  574. }
  575. }
  576. /**
  577. * Iterator to count the children in a tree.
  578. */
  579. static void
  580. count_children_cb (void *cls, GNUNET_PEER_Id peer)
  581. {
  582. unsigned int *i = cls;
  583. (*i)++;
  584. }
  585. /**
  586. * Count how many children does the local node have in the tree.
  587. *
  588. * @param tree Tree to use. Must have "me" set.
  589. */
  590. unsigned int
  591. tree_count_children (struct CadetTunnelTree *tree)
  592. {
  593. unsigned int i;
  594. i = 0;
  595. tree_iterate_children(tree, &count_children_cb, &i);
  596. return i;
  597. }
  598. /**
  599. * Recusively update the info about what is the first hop to reach the node
  600. *
  601. * @param tree Tree this nodes belongs to.
  602. * @param parent_id Short ID from node form which to start updating.
  603. * @param hop If known, ID of the first hop.
  604. * If not known, NULL to find out and pass on children.
  605. */
  606. void
  607. tree_update_first_hops (struct CadetTunnelTree *tree, GNUNET_PEER_Id parent_id,
  608. struct GNUNET_PeerIdentity *hop)
  609. {
  610. tree_node_update_first_hops (tree, tree_find_peer (tree, parent_id), hop);
  611. }
  612. /**
  613. * Delete the current path to the peer, including all now unused relays.
  614. * The destination peer is NOT destroyed, it is returned in order to either set
  615. * a new path to it or destroy it explicitly, taking care of it's child nodes.
  616. *
  617. * @param t Tunnel tree where to delete the path from.
  618. * @param peer_id Short ID of the destination peer whose path we want to remove.
  619. * @param cb Callback to use to notify about disconnected peers.
  620. * @param cbcls Closure for cb.
  621. *
  622. * @return pointer to the pathless node.
  623. * NULL when not found
  624. */
  625. struct CadetTunnelTreeNode *
  626. tree_del_path (struct CadetTunnelTree *t, GNUNET_PEER_Id peer_id,
  627. CadetTreeCallback cb, void *cbcls)
  628. {
  629. struct CadetTunnelTreeNode *parent;
  630. struct CadetTunnelTreeNode *node;
  631. struct CadetTunnelTreeNode *n;
  632. #if CADET_TREE_DEBUG
  633. struct GNUNET_PeerIdentity id;
  634. GNUNET_PEER_resolve (peer_id, &id);
  635. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Deleting path to %s.\n",
  636. GNUNET_i2s (&id));
  637. #endif
  638. if (NULL == t->root || peer_id == t->root->peer)
  639. return NULL;
  640. for (n = t->disconnected_head; NULL != n; n = n->next)
  641. {
  642. if (n->peer == peer_id)
  643. {
  644. /* Was already pathless, waiting for reconnection */
  645. GNUNET_CONTAINER_DLL_remove (t->disconnected_head, t->disconnected_tail,
  646. n);
  647. return n;
  648. }
  649. }
  650. n = tree_find_peer (t, peer_id);
  651. if (NULL == n)
  652. return NULL;
  653. node = n;
  654. parent = n->parent;
  655. GNUNET_CONTAINER_DLL_remove (parent->children_head, parent->children_tail, n);
  656. n->parent = NULL;
  657. while (CADET_PEER_RELAY == parent->status &&
  658. NULL == parent->children_head)
  659. {
  660. #if CADET_TREE_DEBUG
  661. GNUNET_PEER_resolve (parent->peer, &id);
  662. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Deleting node %s.\n",
  663. GNUNET_i2s (&id));
  664. #endif
  665. n = parent->parent;
  666. if (parent == t->me)
  667. t->me = NULL;
  668. tree_node_destroy (parent);
  669. parent = n;
  670. }
  671. #if CADET_TREE_DEBUG
  672. GNUNET_PEER_resolve (parent->peer, &id);
  673. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Not deleted peer %s.\n",
  674. GNUNET_i2s (&id));
  675. #endif
  676. tree_mark_peers_disconnected (t, node, cb, cbcls);
  677. return node;
  678. }
  679. /**
  680. * Return a newly allocated individual path to reach a peer from the local peer,
  681. * according to the path tree of some tunnel.
  682. *
  683. * @param t Tunnel from which to read the path tree.
  684. * @param peer Short ID of the destination peer to whom we want a path.
  685. *
  686. * @return A newly allocated individual path to reach the destination peer.
  687. * Path must be destroyed afterwards.
  688. */
  689. struct CadetPeerPath *
  690. tree_get_path_to_peer (struct CadetTunnelTree *t, GNUNET_PEER_Id peer)
  691. {
  692. struct CadetTunnelTreeNode *n;
  693. struct CadetPeerPath *p;
  694. n = tree_find_peer (t, peer);
  695. if (NULL == n)
  696. {
  697. GNUNET_break (0);
  698. return NULL;
  699. }
  700. p = path_new (0);
  701. /* Building the path (inverted!) */
  702. while (n->peer != 1)
  703. {
  704. GNUNET_array_append (p->peers, p->length, n->peer);
  705. GNUNET_PEER_change_rc (n->peer, 1);
  706. n = n->parent;
  707. if (NULL == n)
  708. {
  709. GNUNET_break (0);
  710. path_destroy (p);
  711. return NULL;
  712. }
  713. }
  714. GNUNET_array_append (p->peers, p->length, 1);
  715. GNUNET_PEER_change_rc (1, 1);
  716. path_invert (p);
  717. return p;
  718. }
  719. /**
  720. * Integrate a stand alone path into the tunnel tree.
  721. * If the peer toward which the new path is already in the tree, the peer
  722. * and its children will be maked as disconnected and the callback
  723. * will be called on each one of them. They will be maked as online only after
  724. * receiving a PATH ACK for the new path for each one of them, so the caller
  725. * should take care of sending a new CREATE PATH message for each disconnected
  726. * peer.
  727. *
  728. * @param t Tunnel where to add the new path.
  729. * @param p Path to be integrated.
  730. * @param cb Callback to use to notify about peers temporarily disconnecting.
  731. * @param cbcls Closure for cb.
  732. *
  733. * @return GNUNET_OK in case of success.
  734. * GNUNET_SYSERR in case of error.
  735. *
  736. * TODO: optimize
  737. * - go backwards on path looking for each peer in the present tree
  738. * - do not disconnect peers until new path is created & connected
  739. */
  740. int
  741. tree_add_path (struct CadetTunnelTree *t, const struct CadetPeerPath *p,
  742. CadetTreeCallback cb, void *cbcls)
  743. {
  744. struct CadetTunnelTreeNode *parent;
  745. struct CadetTunnelTreeNode *oldnode;
  746. struct CadetTunnelTreeNode *n;
  747. struct CadetTunnelTreeNode *c;
  748. struct GNUNET_PeerIdentity id;
  749. int me;
  750. unsigned int i;
  751. #if CADET_TREE_DEBUG
  752. GNUNET_PEER_resolve (p->peers[p->length - 1], &id);
  753. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  754. "tree: Adding path [%u] towards peer %s.\n", p->length,
  755. GNUNET_i2s (&id));
  756. #endif
  757. GNUNET_assert (0 != p->length);
  758. parent = n = t->root;
  759. if (n->peer != p->peers[0])
  760. {
  761. GNUNET_break (0);
  762. return GNUNET_SYSERR;
  763. }
  764. if (1 == p->length)
  765. return GNUNET_OK;
  766. oldnode = tree_del_path (t, p->peers[p->length - 1], cb, cbcls);
  767. /* Look for the first node that is not already present in the tree
  768. *
  769. * Assuming that the tree is somewhat balanced, O(log n * log N).
  770. * - Length of the path is expected to be log N (size of whole network).
  771. * - Each level of the tree is expected to have log n children (size of tree).
  772. */
  773. me = t->root->peer == 1 ? 0 : -1;
  774. for (i = 1; i < p->length; i++)
  775. {
  776. #if CADET_TREE_DEBUG
  777. GNUNET_PEER_resolve (p->peers[i], &id);
  778. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Looking for peer %s.\n",
  779. GNUNET_i2s (&id));
  780. #endif
  781. parent = n;
  782. if (p->peers[i] == 1)
  783. me = i;
  784. for (c = n->children_head; NULL != c; c = c->next)
  785. {
  786. if (c->peer == p->peers[i])
  787. {
  788. #if CADET_TREE_DEBUG
  789. GNUNET_PEER_resolve (parent->peer, &id);
  790. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  791. "tree: Found in children of %s.\n", GNUNET_i2s (&id));
  792. #endif
  793. n = c;
  794. break;
  795. }
  796. }
  797. /* If we couldn't find a child equal to path[i], we have reached the end
  798. * of the common path. */
  799. if (parent == n)
  800. break;
  801. }
  802. #if CADET_TREE_DEBUG
  803. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: All childen visited.\n");
  804. #endif
  805. /* Add the rest of the path as a branch from parent. */
  806. while (i < p->length)
  807. {
  808. #if CADET_TREE_DEBUG
  809. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Adding peer %u to %u.\n",
  810. p->peers[i], parent->peer);
  811. GNUNET_PEER_resolve (p->peers[i], &id);
  812. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Adding peer %s.\n",
  813. GNUNET_i2s (&id));
  814. GNUNET_PEER_resolve (parent->peer, &id);
  815. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: to %s.\n",
  816. GNUNET_i2s (&id));
  817. #endif
  818. if (i == p->length - 1 && NULL != oldnode)
  819. {
  820. #if CADET_TREE_DEBUG
  821. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  822. "tree: Putting old node into place.\n");
  823. #endif
  824. oldnode->parent = parent;
  825. GNUNET_CONTAINER_DLL_insert (parent->children_head, parent->children_tail,
  826. oldnode);
  827. tree_node_update_first_hops (t, oldnode, NULL);
  828. n = oldnode;
  829. }
  830. else
  831. {
  832. #if CADET_TREE_DEBUG
  833. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Creating new node.\n");
  834. #endif
  835. n = tree_node_new (parent, p->peers[i]);
  836. n->status = CADET_PEER_RELAY;
  837. }
  838. if (n->peer == 1)
  839. {
  840. t->me = n;
  841. me = i;
  842. }
  843. i++;
  844. parent = n;
  845. }
  846. n->status = CADET_PEER_SEARCHING;
  847. GNUNET_break (-1 != me);
  848. /* Add info about first hop into hashmap. */
  849. if (-1 != me && me < p->length - 1)
  850. {
  851. #if CADET_TREE_DEBUG
  852. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  853. "CADET: finding first hop (own pos %d/%u)\n", me,
  854. p->length - 1);
  855. #endif
  856. GNUNET_PEER_resolve (p->peers[me + 1], &id);
  857. tree_update_first_hops (t, p->peers[me + 1], &id);
  858. }
  859. #if CADET_TREE_DEBUG
  860. else
  861. {
  862. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  863. "CADET: was last in path, not updating first hops (%d/%u)\n",
  864. me, p->length - 1);
  865. }
  866. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: New node added.\n");
  867. #endif
  868. if (NULL == t->me)
  869. t->me = tree_find_peer (t, 1);
  870. return GNUNET_OK;
  871. }
  872. /**
  873. * Notifies a tree that a connection it might be using is broken.
  874. * Marks all peers down the paths as disconnected and notifies the client.
  875. *
  876. * @param t Tree to use.
  877. * @param p1 Short id of one of the peers (order unimportant)
  878. * @param p2 Short id of one of the peers (order unimportant)
  879. * @param cb Function to call for every peer that is marked as disconnected.
  880. * @param cbcls Closure for cb.
  881. *
  882. * @return Short ID of the first disconnected peer in the tree.
  883. */
  884. GNUNET_PEER_Id
  885. tree_notify_connection_broken (struct CadetTunnelTree *t, GNUNET_PEER_Id p1,
  886. GNUNET_PEER_Id p2, CadetTreeCallback cb,
  887. void *cbcls)
  888. {
  889. struct CadetTunnelTreeNode *n;
  890. struct CadetTunnelTreeNode *c;
  891. n = tree_find_peer (t, p1);
  892. if (NULL == n)
  893. return 0;
  894. if (NULL != n->parent && n->parent->peer == p2)
  895. {
  896. tree_mark_peers_disconnected (t, n, cb, cbcls);
  897. GNUNET_CONTAINER_DLL_remove (n->parent->children_head,
  898. n->parent->children_tail, n);
  899. GNUNET_CONTAINER_DLL_insert (t->disconnected_head, t->disconnected_tail, n);
  900. return p1;
  901. }
  902. for (c = n->children_head; NULL != c; c = c->next)
  903. {
  904. if (c->peer == p2)
  905. {
  906. tree_mark_peers_disconnected (t, c, cb, cbcls);
  907. GNUNET_CONTAINER_DLL_remove (n->children_head, n->children_tail, c);
  908. GNUNET_CONTAINER_DLL_insert (t->disconnected_head, t->disconnected_tail,
  909. c);
  910. return p2;
  911. }
  912. }
  913. return 0;
  914. }
  915. /**
  916. * Deletes a peer from a tunnel, liberating all unused resources on the path to
  917. * it. It shouldn't have children, if it has they will be destroyed as well.
  918. * If the tree is not local and no longer has any paths, the root node will be
  919. * destroyed and marked as NULL.
  920. *
  921. * @param t Tunnel tree to use.
  922. * @param peer Short ID of the peer to remove from the tunnel tree.
  923. * @param cb Callback to notify client of disconnected peers.
  924. * @param cbcls Closure for cb.
  925. *
  926. * @return GNUNET_OK or GNUNET_SYSERR
  927. */
  928. int
  929. tree_del_peer (struct CadetTunnelTree *t, GNUNET_PEER_Id peer,
  930. CadetTreeCallback cb, void *cbcls)
  931. {
  932. struct CadetTunnelTreeNode *n;
  933. n = tree_del_path (t, peer, cb, cbcls);
  934. if (NULL == n)
  935. {
  936. GNUNET_break (0);
  937. return GNUNET_YES;
  938. }
  939. tree_node_destroy (n);
  940. if (NULL == t->root->children_head && t->me != t->root)
  941. {
  942. tree_node_destroy (t->root);
  943. t->root = NULL;
  944. return GNUNET_NO;
  945. }
  946. return GNUNET_YES;
  947. }
  948. /**
  949. * Get the cost of the path relative to the already built tunnel tree.
  950. *
  951. * @param t The tunnel tree to which compare.
  952. * @param path The individual path to reach a peer. It has to start at the
  953. * root of the tree to be comparable.
  954. *
  955. * @return Number of hops to reach destination, UINT_MAX in case the peer is not
  956. * in the path.
  957. *
  958. * TODO: adapt to allow any start / root combination
  959. * TODO: take in account state of the nodes
  960. */
  961. unsigned int
  962. tree_get_path_cost (struct CadetTunnelTree *t, struct CadetPeerPath *path)
  963. {
  964. struct CadetTunnelTreeNode *n;
  965. struct CadetTunnelTreeNode *p;
  966. unsigned int i;
  967. unsigned int l;
  968. l = path_get_length (path);
  969. p = t->root;
  970. if (t->root->peer != path->peers[0])
  971. {
  972. GNUNET_break (0);
  973. return UINT_MAX;
  974. }
  975. for (i = 1; i < l; i++)
  976. {
  977. for (n = p->children_head; NULL != n; n = n->next)
  978. {
  979. if (path->peers[i] == n->peer)
  980. {
  981. break;
  982. }
  983. }
  984. if (NULL == n)
  985. return l - i;
  986. p = n;
  987. }
  988. return l - i;
  989. }
  990. /**
  991. * Print the tree on stderr
  992. *
  993. * @param t The tree
  994. */
  995. void
  996. tree_debug (struct CadetTunnelTree *t)
  997. {
  998. tree_node_debug (t->root, 0);
  999. FPRINTF (stderr, "root: %p\n", t->root);
  1000. FPRINTF (stderr, "me: %p\n", t->me);
  1001. }
  1002. /**
  1003. * Iterator over hash map peer entries and frees all data in it.
  1004. * Used prior to destroying a hashmap. Makes you miss anonymous functions in C.
  1005. *
  1006. * @param cls closure
  1007. * @param key current key code (will no longer contain valid data!!)
  1008. * @param value value in the hash map (treated as void *)
  1009. * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not.
  1010. */
  1011. static int
  1012. iterate_free (void *cls, const struct GNUNET_HashCode * key, void *value)
  1013. {
  1014. GNUNET_free (value);
  1015. return GNUNET_YES;
  1016. }
  1017. /**
  1018. * Destroy the whole tree and free all used memory and Peer_Ids
  1019. *
  1020. * @param t Tree to be destroyed
  1021. */
  1022. void
  1023. tree_destroy (struct CadetTunnelTree *t)
  1024. {
  1025. #if CADET_TREE_DEBUG
  1026. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying tree\n");
  1027. #endif
  1028. tree_node_destroy (t->root);
  1029. GNUNET_CONTAINER_multihashmap_iterate (t->first_hops, &iterate_free, NULL);
  1030. GNUNET_CONTAINER_multihashmap_destroy (t->first_hops);
  1031. GNUNET_free (t);
  1032. }