aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-26 12:24:41 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-26 12:24:41 +0000
commit535d51c21e7ed8b8e1f9bec144c54f177de6b2f5 (patch)
treea824b52be525a48289f2191c638f4d5c9d26d138 /src/mesh
parentaa390e34b0b9e793e1c9f82a606ad0c10fcc84ca (diff)
downloadgnunet-535d51c21e7ed8b8e1f9bec144c54f177de6b2f5.tar.gz
gnunet-535d51c21e7ed8b8e1f9bec144c54f177de6b2f5.zip
Added new api in the tree module to handle core or remote disconnections
Added reconnecting mechanism to find new paths in case of peer disconnection
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/gnunet-service-mesh.c125
-rw-r--r--src/mesh/mesh_tunnel_tree.c109
-rw-r--r--src/mesh/mesh_tunnel_tree.h28
3 files changed, 242 insertions, 20 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 122280369..79f9182f0 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -601,6 +601,32 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
601} 601}
602 602
603 603
604/**
605 * Function to process paths received for a new peer addition. The recorded
606 * paths form the initial tunnel, which can be optimized later.
607 * Called on each result obtained for the DHT search.
608 *
609 * @param cls closure
610 * @param exp when will this value expire
611 * @param key key of the result
612 * @param get_path NULL-terminated array of pointers
613 * to the peers on reverse GET path (or NULL if not recorded)
614 * @param put_path NULL-terminated array of pointers
615 * to the peers on the PUT path (or NULL if not recorded)
616 * @param type type of the result
617 * @param size number of bytes in data
618 * @param data pointer to the result data
619 *
620 * FIXME path
621 */
622static void
623dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
624 const GNUNET_HashCode * key,
625 const struct GNUNET_PeerIdentity *const *get_path,
626 const struct GNUNET_PeerIdentity *const *put_path,
627 enum GNUNET_BLOCK_Type type, size_t size, const void *data);
628
629
604/******************************************************************************/ 630/******************************************************************************/
605/****************** GENERAL HELPER FUNCTIONS ************************/ 631/****************** GENERAL HELPER FUNCTIONS ************************/
606/******************************************************************************/ 632/******************************************************************************/
@@ -661,33 +687,43 @@ peer_info_destroy (struct MeshPeerInfo *pi)
661 * Notify a tunnel that a connection has broken that affects at least 687 * Notify a tunnel that a connection has broken that affects at least
662 * some of its peers. 688 * some of its peers.
663 * 689 *
664 * @param t Tunnel affected 690 * @param t Tunnel affected.
665 * @param peer Peer that (at least) has been affected by the disconnection 691 * @param peer Peer that (at least) has been affected by the disconnection.
666 * @param p1 Peer that got disconnected from p2 692 * @param p1 Peer that got disconnected from p2.
667 * @param p2 Peer that got disconnected from p1 693 * @param p2 Peer that got disconnected from p1.
694 *
695 * @return Short ID of the peer disconnected (either p1 or p2).
696 * 0 if the tunnel remained unaffected.
668 */ 697 */
669static void 698static GNUNET_PEER_Id
670tunnel_notify_connection_broken (struct MeshTunnel *t, 699tunnel_notify_connection_broken (struct MeshTunnel *t,
671 struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, 700 struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
672 GNUNET_PEER_Id p2); 701 GNUNET_PEER_Id p2);
673 702
674
675/** 703/**
676 * Remove all paths that rely on a direct connection between p1 and p2 704 * Remove all paths that rely on a direct connection between p1 and p2
677 * from the peer itself and notify all tunnels about it. 705 * from the peer itself and notify all tunnels about it.
678 * 706 *
679 * @param pi PeerInfo of affected peer 707 * @param peer PeerInfo of affected peer.
680 * @param p1 GNUNET_PEER_Id of one peer. 708 * @param p1 GNUNET_PEER_Id of one peer.
681 * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and 709 * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and
682 * no longer is. 710 * no longer is.
711 *
712 * TODO: optimize (see below)
683 */ 713 */
684static void 714static void
685path_remove_from_peer (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, 715path_remove_from_peer (struct MeshPeerInfo *peer,
716 GNUNET_PEER_Id p1,
686 GNUNET_PEER_Id p2) 717 GNUNET_PEER_Id p2)
687{ 718{
719 struct GNUNET_PeerIdentity id;
688 struct MeshPeerPath *p; 720 struct MeshPeerPath *p;
689 struct MeshPeerPath *aux; 721 struct MeshPeerPath *aux;
722 struct MeshPeerInfo *peer_d;
723 GNUNET_PEER_Id d;
690 unsigned int destroyed; 724 unsigned int destroyed;
725 unsigned int best;
726 unsigned int cost;
691 unsigned int i; 727 unsigned int i;
692 728
693 destroyed = 0; 729 destroyed = 0;
@@ -712,7 +748,56 @@ path_remove_from_peer (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
712 748
713 for (i = 0; i < peer->ntunnels; i++) 749 for (i = 0; i < peer->ntunnels; i++)
714 { 750 {
715 tunnel_notify_connection_broken (peer->tunnels[i], peer, p1, p2); 751 d = tunnel_notify_connection_broken (peer->tunnels[i], peer, p1, p2);
752 /* TODO
753 * Problem: one or more peers have been deleted from the tunnel tree.
754 * We don't know who they are to try to add them again.
755 * We need to try to find a new path for each of the disconnected peers.
756 * Some of them might already have a path to reach them that does not
757 * involve p1 and p2. Adding all anew might render in a better tree than
758 * the trivial immediate fix.
759 *
760 * Trivial immiediate fix: try to reconnect to the disconnected node. All
761 * its children will be reachable trough him.
762 */
763 GNUNET_PEER_resolve(d, &id);
764 peer_d = peer_info_get(&id);
765 best = UINT_MAX;
766 aux = NULL;
767 for (p = peer_d->path_head; NULL != p; p = p->next)
768 {
769 if ((cost = path_get_cost(peer->tunnels[i]->tree, p)) < best)
770 {
771 best = cost;
772 aux = p;
773 }
774 }
775 if (NULL != aux)
776 {
777 /* No callback, as peer will be already disconnected */
778 tree_add_path(peer->tunnels[i]->tree, aux, NULL);
779 }
780 else
781 {
782 struct MeshPathInfo *path_info;
783
784 path_info = GNUNET_malloc(sizeof(struct MeshPathInfo));
785 path_info->path = p;
786 path_info->peer = peer_d;
787 path_info->t = peer->tunnels[i];
788 peer_d->dhtget = GNUNET_DHT_get_start(dht_handle, /* handle */
789 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
790 GNUNET_BLOCK_TYPE_TEST, /* type */
791 &id.hashPubKey, /*key to search */
792 4, /* replication level */
793 GNUNET_DHT_RO_RECORD_ROUTE,
794 NULL, /* bloom filter */
795 0, /* mutator */
796 NULL, /* xquery */
797 0, /* xquery bits */
798 dht_get_id_handler,
799 (void *) path_info);
800 }
716 } 801 }
717} 802}
718 803
@@ -1051,18 +1136,24 @@ tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
1051 * Notify a tunnel that a connection has broken that affects at least 1136 * Notify a tunnel that a connection has broken that affects at least
1052 * some of its peers. 1137 * some of its peers.
1053 * 1138 *
1054 * @param t Tunnel affected 1139 * @param t Tunnel affected.
1055 * @param peer Peer that (at least) has been affected by the disconnection 1140 * @param peer Peer that (at least) has been affected by the disconnection.
1056 * @param p1 Peer that got disconnected from p2 1141 * @param p1 Peer that got disconnected from p2.
1057 * @param p2 Peer that got disconnected from p1 1142 * @param p2 Peer that got disconnected from p1.
1058 * 1143 *
1059 * FIXME path 1144 * @return Short ID of the peer disconnected (either p1 or p2).
1145 * 0 if the tunnel remained unaffected.
1146 *
1147 * FIXME working on it
1060 */ 1148 */
1061static void 1149static GNUNET_PEER_Id
1062tunnel_notify_connection_broken (struct MeshTunnel *t, 1150tunnel_notify_connection_broken (struct MeshTunnel *t,
1063 struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, 1151 struct MeshPeerInfo *peer,
1152 GNUNET_PEER_Id p1,
1064 GNUNET_PEER_Id p2) 1153 GNUNET_PEER_Id p2)
1065{ 1154{
1155 return tree_notify_connection_broken (t->tree, p1, p2,
1156 &notify_peer_disconnected);
1066} 1157}
1067 1158
1068 1159
diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c
index 748683a34..9c8d5e97d 100644
--- a/src/mesh/mesh_tunnel_tree.c
+++ b/src/mesh/mesh_tunnel_tree.c
@@ -386,9 +386,22 @@ tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
386 struct MeshTunnelTreeNode *node; 386 struct MeshTunnelTreeNode *node;
387 struct MeshTunnelTreeNode *n; 387 struct MeshTunnelTreeNode *n;
388 388
389 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree: Deleting path to %u.\n", peer_id); 389 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
390 "tree: Deleting path to %u.\n", peer_id);
390 if (peer_id == t->root->peer) 391 if (peer_id == t->root->peer)
391 return NULL; 392 return NULL;
393
394 for (n = t->disconnected_head; NULL != n; n = n->next)
395 {
396 if (n->peer == peer_id)
397 {
398 /* Was already pathless, waiting for reconnection */
399 GNUNET_CONTAINER_DLL_remove (t->disconnected_head,
400 t->disconnected_tail,
401 n);
402 return n;
403 }
404 }
392 n = tree_find_peer (t->me, peer_id); 405 n = tree_find_peer (t->me, peer_id);
393 if (NULL == n) 406 if (NULL == n)
394 return NULL; 407 return NULL;
@@ -470,8 +483,9 @@ tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer)
470 * - do not disconnect peers until new path is created & connected 483 * - do not disconnect peers until new path is created & connected
471 */ 484 */
472int 485int
473tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, 486tree_add_path (struct MeshTunnelTree *t,
474 MeshNodeDisconnectCB cb) 487 const struct MeshPeerPath *p,
488 MeshNodeDisconnectCB cb)
475{ 489{
476 struct MeshTunnelTreeNode *parent; 490 struct MeshTunnelTreeNode *parent;
477 struct MeshTunnelTreeNode *oldnode; 491 struct MeshTunnelTreeNode *oldnode;
@@ -589,6 +603,95 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
589 603
590 604
591/** 605/**
606 * Notifies a tree that a connection it might be using is broken.
607 * Marks all peers down the paths as disconnected and notifies the client.
608 *
609 * @param t Tree to use.
610 * @param p1 Short id of one of the peers (order unimportant)
611 * @param p2 Short id of one of the peers (order unimportant)
612 * @param cb Function to call for every peer that is marked as disconnected.
613 *
614 * @return Short ID of the first disconnected peer in the tree.
615 */
616GNUNET_PEER_Id
617tree_notify_connection_broken (struct MeshTunnelTree *t,
618 GNUNET_PEER_Id p1,
619 GNUNET_PEER_Id p2,
620 MeshNodeDisconnectCB cb)
621{
622 struct MeshTunnelTreeNode *n;
623 struct MeshTunnelTreeNode *c;
624
625 n = tree_find_peer(t->me, p1);
626 if (NULL == n)
627 return 0;
628 if (NULL != n->parent && n->parent->peer == p2)
629 {
630 tree_mark_peers_disconnected(t, n, cb);
631 GNUNET_CONTAINER_DLL_remove(n->parent->children_head,
632 n->parent->children_tail,
633 n);
634 GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
635 t->disconnected_tail,
636 n);
637 return p1;
638 }
639 for (c = n->children_head; NULL != c; c = c->next)
640 {
641 if (c->peer == p2)
642 {
643 tree_mark_peers_disconnected(t, c, cb);
644 GNUNET_CONTAINER_DLL_remove(n->children_head,
645 n->children_tail,
646 c);
647 GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
648 t->disconnected_tail,
649 c);
650 return p2;
651 }
652 }
653 return 0;
654}
655
656
657/**
658 * Deletes a peer from a tunnel, marking its children as disconnected.
659 *
660 * @param t Tunnel tree to use.
661 * @param peer Short ID of the peer to remove from the tunnel tree.
662 * @param cb Callback to notify client of disconnected peers.
663 *
664 * @return GNUNET_OK or GNUNET_SYSERR
665 */
666int
667tree_del_peer (struct MeshTunnelTree *t,
668 GNUNET_PEER_Id peer,
669 MeshNodeDisconnectCB cb)
670{
671 struct MeshTunnelTreeNode *n;
672 struct MeshTunnelTreeNode *c;
673 struct MeshTunnelTreeNode *aux;
674
675 n = tree_del_path(t, peer, cb);
676 c = n->children_head;
677 while (NULL != c)
678 {
679 aux = c->next;
680 GNUNET_CONTAINER_DLL_remove(n->children_head,
681 n->children_tail,
682 c);
683 GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
684 t->disconnected_tail,
685 c);
686 cb (c);
687 c = aux;
688 }
689 tree_node_destroy(n);
690 return GNUNET_OK;
691}
692
693
694/**
592 * Print the tree on stderr 695 * Print the tree on stderr
593 * 696 *
594 * @param t The tree 697 * @param t The tree
diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h
index 252929549..f187e7957 100644
--- a/src/mesh/mesh_tunnel_tree.h
+++ b/src/mesh/mesh_tunnel_tree.h
@@ -128,6 +128,16 @@ struct MeshTunnelTree
128 struct MeshTunnelTreeNode *me; 128 struct MeshTunnelTreeNode *me;
129 129
130 /** 130 /**
131 * DLL of disconneted nodes
132 */
133 struct MeshTunnelTreeNode *disconnected_head;
134
135 /**
136 * DLL of disconneted nodes
137 */
138 struct MeshTunnelTreeNode *disconnected_tail;
139
140 /**
131 * Cache of all peers and the first hop to them. 141 * Cache of all peers and the first hop to them.
132 * Indexed by PeerIdentity, contains a pointer to the PeerIdentity 142 * Indexed by PeerIdentity, contains a pointer to the PeerIdentity
133 * of 1st hop. 143 * of 1st hop.
@@ -298,6 +308,24 @@ tree_add_path (struct MeshTunnelTree *t,
298 308
299 309
300/** 310/**
311 * Notifies a tree that a connection it might be using is broken.
312 * Marks all peers down the paths as disconnected and notifies the client.
313 *
314 * @param t Tree to use.
315 * @param p1 Short id of one of the peers (order unimportant)
316 * @param p2 Short id of one of the peers (order unimportant)
317 * @param cb Function to call for every peer that is marked as disconnected.
318 *
319 * @return Short ID of the first disconnected peer in the tree.
320 */
321GNUNET_PEER_Id
322tree_notify_connection_broken (struct MeshTunnelTree *t,
323 GNUNET_PEER_Id p1,
324 GNUNET_PEER_Id p2,
325 MeshNodeDisconnectCB cb);
326
327
328/**
301 * Print the tree on stderr 329 * Print the tree on stderr
302 * 330 *
303 * @param t The tree 331 * @param t The tree