gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r17012 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r17012 - gnunet/src/mesh
Date: Mon, 26 Sep 2011 14:24:41 +0200

Author: bartpolot
Date: 2011-09-26 14:24:41 +0200 (Mon, 26 Sep 2011)
New Revision: 17012

Modified:
   gnunet/src/mesh/gnunet-service-mesh.c
   gnunet/src/mesh/mesh_tunnel_tree.c
   gnunet/src/mesh/mesh_tunnel_tree.h
Log:
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


Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2011-09-26 09:14:11 UTC (rev 
17011)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2011-09-26 12:24:41 UTC (rev 
17012)
@@ -601,6 +601,32 @@
 }
 
 
+/**
+ * Function to process paths received for a new peer addition. The recorded
+ * paths form the initial tunnel, which can be optimized later.
+ * Called on each result obtained for the DHT search.
+ *
+ * @param cls closure
+ * @param exp when will this value expire
+ * @param key key of the result
+ * @param get_path NULL-terminated array of pointers
+ *                 to the peers on reverse GET path (or NULL if not recorded)
+ * @param put_path NULL-terminated array of pointers
+ *                 to the peers on the PUT path (or NULL if not recorded)
+ * @param type type of the result
+ * @param size number of bytes in data
+ * @param data pointer to the result data
+ *
+ * FIXME path
+ */
+static void
+dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
+                    const GNUNET_HashCode * key,
+                    const struct GNUNET_PeerIdentity *const *get_path,
+                    const struct GNUNET_PeerIdentity *const *put_path,
+                    enum GNUNET_BLOCK_Type type, size_t size, const void 
*data);
+
+
 
/******************************************************************************/
 /******************      GENERAL HELPER FUNCTIONS      
************************/
 
/******************************************************************************/
@@ -661,33 +687,43 @@
  * Notify a tunnel that a connection has broken that affects at least
  * some of its peers.
  *
- * @param t Tunnel affected
- * @param peer Peer that (at least) has been affected by the disconnection
- * @param p1 Peer that got disconnected from p2
- * @param p2 Peer that got disconnected from p1
+ * @param t Tunnel affected.
+ * @param peer Peer that (at least) has been affected by the disconnection.
+ * @param p1 Peer that got disconnected from p2.
+ * @param p2 Peer that got disconnected from p1.
+ *
+ * @return Short ID of the peer disconnected (either p1 or p2).
+ *         0 if the tunnel remained unaffected.
  */
-static void
+static GNUNET_PEER_Id
 tunnel_notify_connection_broken (struct MeshTunnel *t,
                                  struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
                                  GNUNET_PEER_Id p2);
 
-
 /**
  * Remove all paths that rely on a direct connection between p1 and p2
  * from the peer itself and notify all tunnels about it.
  *
- * @param pi PeerInfo of affected peer
+ * @param peer PeerInfo of affected peer.
  * @param p1 GNUNET_PEER_Id of one peer.
  * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and
  *           no longer is.
+ *
+ * TODO: optimize (see below)
  */
 static void
-path_remove_from_peer (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
+path_remove_from_peer (struct MeshPeerInfo *peer,
+                       GNUNET_PEER_Id p1,
                        GNUNET_PEER_Id p2)
 {
+  struct GNUNET_PeerIdentity id;
   struct MeshPeerPath *p;
   struct MeshPeerPath *aux;
+  struct MeshPeerInfo *peer_d;
+  GNUNET_PEER_Id d;
   unsigned int destroyed;
+  unsigned int best;
+  unsigned int cost;
   unsigned int i;
 
   destroyed = 0;
@@ -712,7 +748,56 @@
 
   for (i = 0; i < peer->ntunnels; i++)
   {
-    tunnel_notify_connection_broken (peer->tunnels[i], peer, p1, p2);
+    d = tunnel_notify_connection_broken (peer->tunnels[i], peer, p1, p2);
+    /* TODO
+     * Problem: one or more peers have been deleted from the tunnel tree.
+     * We don't know who they are to try to add them again.
+     * We need to try to find a new path for each of the disconnected peers.
+     * Some of them might already have a path to reach them that does not
+     * involve p1 and p2. Adding all anew might render in a better tree than
+     * the trivial immediate fix.
+     * 
+     * Trivial immiediate fix: try to reconnect to the disconnected node. All
+     * its children will be reachable trough him.
+     */
+    GNUNET_PEER_resolve(d, &id);
+    peer_d = peer_info_get(&id);
+    best = UINT_MAX;
+    aux = NULL;
+    for (p = peer_d->path_head; NULL != p; p = p->next)
+    {
+      if ((cost = path_get_cost(peer->tunnels[i]->tree, p)) < best)
+      {
+        best = cost;
+        aux = p;
+      }
+    }
+    if (NULL != aux)
+    {
+      /* No callback, as peer will be already disconnected */
+      tree_add_path(peer->tunnels[i]->tree, aux, NULL);
+    }
+    else
+    {
+      struct MeshPathInfo *path_info;
+
+      path_info = GNUNET_malloc(sizeof(struct MeshPathInfo));
+      path_info->path = p;
+      path_info->peer = peer_d;
+      path_info->t = peer->tunnels[i];
+      peer_d->dhtget = GNUNET_DHT_get_start(dht_handle,       /* handle */
+                                            GNUNET_TIME_UNIT_FOREVER_REL,     
/* timeout */
+                                            GNUNET_BLOCK_TYPE_TEST,   /* type 
*/
+                                            &id.hashPubKey,   /*key to search 
*/
+                                            4,        /* replication level */
+                                            GNUNET_DHT_RO_RECORD_ROUTE,
+                                            NULL,     /* bloom filter */
+                                            0,        /* mutator */
+                                            NULL,     /* xquery */
+                                            0,        /* xquery bits */
+                                            dht_get_id_handler,
+                                            (void *) path_info);
+    }
   }
 }
 
@@ -1051,18 +1136,24 @@
  * Notify a tunnel that a connection has broken that affects at least
  * some of its peers.
  *
- * @param t Tunnel affected
- * @param peer Peer that (at least) has been affected by the disconnection
- * @param p1 Peer that got disconnected from p2
- * @param p2 Peer that got disconnected from p1
- * 
- * FIXME path
+ * @param t Tunnel affected.
+ * @param peer Peer that (at least) has been affected by the disconnection.
+ * @param p1 Peer that got disconnected from p2.
+ * @param p2 Peer that got disconnected from p1.
+ *
+ * @return Short ID of the peer disconnected (either p1 or p2).
+ *         0 if the tunnel remained unaffected.
+ *
+ * FIXME working on it
  */
-static void
+static GNUNET_PEER_Id
 tunnel_notify_connection_broken (struct MeshTunnel *t,
-                                 struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
+                                 struct MeshPeerInfo *peer,
+                                 GNUNET_PEER_Id p1,
                                  GNUNET_PEER_Id p2)
 {
+  return tree_notify_connection_broken (t->tree, p1, p2,
+                                        &notify_peer_disconnected);
 }
 
 

Modified: gnunet/src/mesh/mesh_tunnel_tree.c
===================================================================
--- gnunet/src/mesh/mesh_tunnel_tree.c  2011-09-26 09:14:11 UTC (rev 17011)
+++ gnunet/src/mesh/mesh_tunnel_tree.c  2011-09-26 12:24:41 UTC (rev 17012)
@@ -386,9 +386,22 @@
   struct MeshTunnelTreeNode *node;
   struct MeshTunnelTreeNode *n;
 
-  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tree:   Deleting path to %u.\n", 
peer_id);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+             "tree:   Deleting path to %u.\n", peer_id);
   if (peer_id == t->root->peer)
     return NULL;
+
+  for (n = t->disconnected_head; NULL != n; n = n->next)
+  {
+    if (n->peer == peer_id)
+    {
+      /* Was already pathless, waiting for reconnection */
+      GNUNET_CONTAINER_DLL_remove (t->disconnected_head,
+                                   t->disconnected_tail,
+                                   n);
+      return n;
+    }
+  }
   n = tree_find_peer (t->me, peer_id);
   if (NULL == n)
     return NULL;
@@ -470,8 +483,9 @@
  * - do not disconnect peers until new path is created & connected
  */
 int
-tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p,
-                 MeshNodeDisconnectCB cb)
+tree_add_path (struct MeshTunnelTree *t,
+               const struct MeshPeerPath *p,
+               MeshNodeDisconnectCB cb)
 {
   struct MeshTunnelTreeNode *parent;
   struct MeshTunnelTreeNode *oldnode;
@@ -589,6 +603,95 @@
 
 
 /**
+ * Notifies a tree that a connection it might be using is broken.
+ * Marks all peers down the paths as disconnected and notifies the client.
+ *
+ * @param t Tree to use.
+ * @param p1 Short id of one of the peers (order unimportant)
+ * @param p2 Short id of one of the peers (order unimportant)
+ * @param cb Function to call for every peer that is marked as disconnected.
+ *
+ * @return Short ID of the first disconnected peer in the tree.
+ */
+GNUNET_PEER_Id
+tree_notify_connection_broken (struct MeshTunnelTree *t,
+                               GNUNET_PEER_Id p1,
+                               GNUNET_PEER_Id p2,
+                               MeshNodeDisconnectCB cb)
+{
+  struct MeshTunnelTreeNode *n;
+  struct MeshTunnelTreeNode *c;
+
+  n = tree_find_peer(t->me, p1);
+  if (NULL == n)
+    return 0;
+  if (NULL != n->parent && n->parent->peer == p2)
+  {
+    tree_mark_peers_disconnected(t, n, cb);
+    GNUNET_CONTAINER_DLL_remove(n->parent->children_head,
+                                n->parent->children_tail,
+                                n);
+    GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
+                                t->disconnected_tail,
+                                n);
+    return p1;
+  }
+  for (c = n->children_head; NULL != c; c = c->next)
+  {
+    if (c->peer == p2)
+    {
+      tree_mark_peers_disconnected(t, c, cb);
+      GNUNET_CONTAINER_DLL_remove(n->children_head,
+                                  n->children_tail,
+                                  c);
+      GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
+                                  t->disconnected_tail,
+                                  c);
+      return p2;
+    }
+  }
+  return 0;
+}
+
+
+/**
+ * Deletes a peer from a tunnel, marking its children as disconnected.
+ *
+ * @param t Tunnel tree to use.
+ * @param peer Short ID of the peer to remove from the tunnel tree.
+ * @param cb Callback to notify client of disconnected peers.
+ *
+ * @return GNUNET_OK or GNUNET_SYSERR
+ */
+int
+tree_del_peer (struct MeshTunnelTree *t,
+               GNUNET_PEER_Id peer,
+               MeshNodeDisconnectCB cb)
+{
+  struct MeshTunnelTreeNode *n;
+  struct MeshTunnelTreeNode *c;
+  struct MeshTunnelTreeNode *aux;
+
+  n = tree_del_path(t, peer, cb);
+  c = n->children_head;
+  while (NULL != c)
+  {
+    aux = c->next;
+    GNUNET_CONTAINER_DLL_remove(n->children_head,
+                                n->children_tail,
+                                c);
+    GNUNET_CONTAINER_DLL_insert(t->disconnected_head,
+                                t->disconnected_tail,
+                                c);
+    cb (c);
+    c = aux;
+  }
+  tree_node_destroy(n);
+  return GNUNET_OK;
+}
+
+
+/**
  * Print the tree on stderr
  *
  * @param t The tree

Modified: gnunet/src/mesh/mesh_tunnel_tree.h
===================================================================
--- gnunet/src/mesh/mesh_tunnel_tree.h  2011-09-26 09:14:11 UTC (rev 17011)
+++ gnunet/src/mesh/mesh_tunnel_tree.h  2011-09-26 12:24:41 UTC (rev 17012)
@@ -128,6 +128,16 @@
   struct MeshTunnelTreeNode *me;
 
   /**
+   * DLL of disconneted nodes
+   */
+  struct MeshTunnelTreeNode *disconnected_head;
+
+  /**
+   * DLL of disconneted nodes
+   */
+  struct MeshTunnelTreeNode *disconnected_tail;
+
+  /**
    * Cache of all peers and the first hop to them.
    * Indexed by PeerIdentity, contains a pointer to the PeerIdentity
    * of 1st hop.
@@ -298,6 +308,24 @@
 
 
 /**
+ * Notifies a tree that a connection it might be using is broken.
+ * Marks all peers down the paths as disconnected and notifies the client.
+ *
+ * @param t Tree to use.
+ * @param p1 Short id of one of the peers (order unimportant)
+ * @param p2 Short id of one of the peers (order unimportant)
+ * @param cb Function to call for every peer that is marked as disconnected.
+ *
+ * @return Short ID of the first disconnected peer in the tree.
+ */
+GNUNET_PEER_Id
+tree_notify_connection_broken (struct MeshTunnelTree *t,
+                               GNUNET_PEER_Id p1,
+                               GNUNET_PEER_Id p2,
+                               MeshNodeDisconnectCB cb);
+
+
+/**
  * Print the tree on stderr
  *
  * @param t The tree




reply via email to

[Prev in Thread] Current Thread [Next in Thread]