gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r22871 - gnunet/src/mesh
Date: Tue, 24 Jul 2012 15:58:38 +0200

Author: bartpolot
Date: 2012-07-24 15:58:38 +0200 (Tue, 24 Jul 2012)
New Revision: 22871

Modified:
   gnunet/src/mesh/gnunet-service-mesh.c
Log:
- collect children information for ack

Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2012-07-24 13:46:12 UTC (rev 
22870)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2012-07-24 13:58:38 UTC (rev 
22871)
@@ -298,6 +298,16 @@
   uint32_t skip;
 
     /**
+     * MeshTunnelChildInfo of all children, indexed by GNUNET_PEER_Id.
+     */
+  struct GNUNET_CONTAINER_MultiHashMap *children_fc;
+
+    /**
+     * Maximum child ACK.
+     */
+  uint32_t max_child_ack;
+
+    /**
      * How many messages are in the queue.
      */
   unsigned int queue_n;
@@ -421,6 +431,32 @@
 
 
 /**
+ * Info about a child node in a tunnel, needed to perform flow control.
+ */
+struct MeshTunnelChildInfo
+{
+    /**
+     * ID of the child node.
+     */
+  GNUNET_PEER_Id id;
+
+    /**
+     * SKIP value
+     */
+  uint32_t skip;
+
+    /**
+     * Last sent PID.
+     */
+  uint32_t pid;
+
+    /**
+     * Maximum PID allowed.
+     */
+  uint32_t max_pid;
+};
+
+/**
  * Info needed to work with tunnel paths and peers
  */
 struct MeshPathInfo
@@ -2697,6 +2733,25 @@
 
 
 /**
+ * Iterator to free MeshTunnelChildInfo of tunnel children.
+ *
+ * @param cls Closure (tunnel info).
+ * @param key Hash of GNUNET_PEER_Id (unused).
+ * @param value MeshTunnelChildInfo of the child.
+ *
+ * @return always GNUNET_YES, to keep iterating
+ */
+static int
+tunnel_destroy_child (void *cls,
+                      const struct GNUNET_HashCode * key,
+                      void *value)
+{
+  GNUNET_free (value);
+  return GNUNET_YES;
+}
+
+
+/**
  * Callback used to notify a client owner of a tunnel that a peer has
  * disconnected, most likely because of a path change.
  *
@@ -2961,6 +3016,71 @@
 
 
 /**
+ * Iterator to get the appropiate ACK value from all children nodes
+ */
+static void
+tunnel_get_child_ack (void *cls,
+                      GNUNET_PEER_Id id)
+{
+  struct GNUNET_PeerIdentity peer_id;
+  struct MeshTunnelChildInfo *cinfo;
+  struct MeshTunnel *t = cls;
+  uint32_t ack;
+
+  GNUNET_PEER_resolve (id, &peer_id);
+  cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
+                                             &peer_id.hashPubKey);
+  if (NULL == cinfo)
+  {
+    cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo));
+    cinfo->id = id;
+    cinfo->pid = t->pid;
+    cinfo->skip = t->pid;
+    cinfo->max_pid = ack =  t->pid + 1;
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CONTAINER_multihashmap_put(t->children_fc,
+                                                     &peer_id.hashPubKey,
+                                                     cinfo,
+                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
+  }
+  else
+  {
+    ack = cinfo->max_pid;
+  }
+
+  if (0 == t->max_child_ack)
+    t->max_child_ack = ack;
+
+  if (GNUNET_YES == t->speed_min)
+  {
+    t->max_child_ack = t->max_child_ack > ack ? ack : t->max_child_ack;
+  }
+  else
+  {
+    t->max_child_ack = t->max_child_ack > ack ? t->max_child_ack : ack;
+  }
+
+}
+
+
+/**
+ * Get the maximum PID allowed to transmit to any
+ * tunnel child of the local peer.
+ *
+ * @param t Tunnel.
+ *
+ * @return Maximum PID allowed.
+ */
+static uint32_t
+tunnel_get_children_ack (struct MeshTunnel *t)
+{
+  t->max_child_ack = 0;
+  tree_iterate_children (t->tree, tunnel_get_child_ack, t);
+  return t->max_child_ack;
+}
+
+
+/**
  * Send an ACK informing the predecessor about the available buffer space.
  * 
  * @param t Tunnel on which to send the ACK.
@@ -2972,6 +3092,8 @@
   struct GNUNET_PeerIdentity id;
   uint32_t count;
   uint32_t buffer_free;
+  uint32_t child_ack;
+  uint32_t ack;
 
   if (t->queue_max > t->queue_n * 2)
     return;
@@ -2982,8 +3104,19 @@
   GNUNET_PEER_resolve(t->id.oid, &msg.oid);
   count = t->pid - t->skip;
   buffer_free = t->queue_max - t->queue_n;
-  msg.pid = htonl (count + buffer_free);
+  ack = count + buffer_free;
+  child_ack = tunnel_get_children_ack (t);
 
+  if (GNUNET_YES == t->speed_min)
+  {
+    ack = child_ack > ack ? ack : child_ack;
+  }
+  else
+  {
+    ack = child_ack > ack ? child_ack : ack;
+  }
+  msg.pid = htonl (ack);
+
   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
 
   send_message (&msg.header, &id, t);
@@ -3121,6 +3254,11 @@
     GNUNET_CONTAINER_multihashmap_destroy (t->peers);
   }
 
+  GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
+                                         &tunnel_destroy_child,
+                                         t);
+  GNUNET_CONTAINER_multihashmap_destroy (t->children_fc);
+
   tree_destroy (t->tree);
 
   if (NULL != t->regex_ctx)
@@ -3162,6 +3300,7 @@
   t->tree = tree_new (owner);
   t->owner = client;
   t->local_tid = local;
+  t->children_fc = GNUNET_CONTAINER_multihashmap_create (8);
 
   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
   if (GNUNET_OK !=




reply via email to

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