gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r26400 - gnunet/src/dv


From: gnunet
Subject: [GNUnet-SVN] r26400 - gnunet/src/dv
Date: Wed, 13 Mar 2013 16:00:38 +0100

Author: grothoff
Date: 2013-03-13 16:00:37 +0100 (Wed, 13 Mar 2013)
New Revision: 26400

Modified:
   gnunet/src/dv/dv.h
   gnunet/src/dv/gnunet-service-dv.c
Log:
-more dv bookkeeping work

Modified: gnunet/src/dv/dv.h
===================================================================
--- gnunet/src/dv/dv.h  2013-03-13 14:23:23 UTC (rev 26399)
+++ gnunet/src/dv/dv.h  2013-03-13 15:00:37 UTC (rev 26400)
@@ -69,9 +69,9 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * The distance to the peer that we used to have
+   * Always zero.
    */
-  uint32_t distance GNUNET_PACKED;
+  uint32_t reserved GNUNET_PACKED;
 
   /**
    * The peer that is no longer available.

Modified: gnunet/src/dv/gnunet-service-dv.c
===================================================================
--- gnunet/src/dv/gnunet-service-dv.c   2013-03-13 14:23:23 UTC (rev 26399)
+++ gnunet/src/dv/gnunet-service-dv.c   2013-03-13 15:00:37 UTC (rev 26400)
@@ -249,12 +249,11 @@
 {
 
   /**
-   * Array of targets in the set, may include NULL 
-   * entries if a neighbor has disconnected; the
-   * targets are allocated with the respective
-   * 'struct Route', not here.
+   * Array of targets in the set, may include NULL entries if a
+   * neighbor has disconnected; the targets are allocated with the
+   * respective container (i.e. 'struct RoutingNeighbor'), not here.
    */
-  struct Target **targets;
+  struct Route **targets;
 
   /**
    * Size of the 'targets' array.
@@ -461,38 +460,30 @@
 
 
 /**
- * Give an ACK message to the plugin, we transmitted a message for it.
+ * Forward a control message to the plugin.
  *
- * @param target peer that received the message
- * @param uid plugin-chosen UID for the message
+ * @param message the message to send to the plugin
+ * @param distant_neighbor the original sender of the message
+ * @param distnace distance to the original sender of the message
  */
 static void
-send_ack_to_plugin (struct GNUNET_PeerIdentity *target, 
-                   uint32_t uid)
+send_control_to_plugin (const struct GNUNET_MessageHeader *message)
 {
-  struct GNUNET_DV_AckMessage *ack_msg;
   struct PendingMessage *pending_message;
   size_t size;
 
   if (NULL == client_handle)
   {
     GNUNET_STATISTICS_update (stats,
-                             "# acks discarded (no plugin)",
+                             "# control messages discarded (no plugin)",
                              1, GNUNET_NO);
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 _("Refusing to queue messages, DV plugin not active.\n"));
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Delivering ACK for message to peer `%s'\n",
-              GNUNET_i2s (target));
-  size = sizeof (struct GNUNET_DV_AckMessage);
+  size = ntohs (message->size);
   pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size);
-  ack_msg = (struct GNUNET_DV_AckMessage *) &pending_message[1];
-  ack_msg->header.size = htons (size);
-  ack_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND_ACK);
-  ack_msg->uid = htonl (uid);
-  ack_msg->target = *target;
+  memcpy (&pending_message[1], message, size);
   GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head, 
                                    plugin_pending_tail,
                                    pending_message);  
@@ -505,6 +496,77 @@
 
 
 /**
+ * Give an ACK message to the plugin, we transmitted a message for it.
+ *
+ * @param target peer that received the message
+ * @param uid plugin-chosen UID for the message
+ */
+static void
+send_ack_to_plugin (struct GNUNET_PeerIdentity *target, 
+                   uint32_t uid)
+{
+  struct GNUNET_DV_AckMessage ack_msg;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Delivering ACK for message to peer `%s'\n",
+              GNUNET_i2s (target));
+  ack_msg.header.size = htons (sizeof (ack_msg));
+  ack_msg.header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND_ACK);
+  ack_msg.uid = htonl (uid);
+  ack_msg.target = *target;
+  send_control_to_plugin (&ack_msg.header);
+}
+
+
+/**
+ * Give a CONNECT message to the plugin.
+ *
+ * @param target peer that connected
+ * @param distance distance to the target
+ */
+static void
+send_connect_to_plugin (const struct GNUNET_PeerIdentity *target, 
+                       uint32_t distance)
+{
+  struct GNUNET_DV_ConnectMessage cm;
+
+  if (NULL == client_handle)
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Delivering CONNECT about peer `%s'\n",
+              GNUNET_i2s (target));
+  cm.header.size = htons (sizeof (cm));
+  cm.header.type = htons (GNUNET_MESSAGE_TYPE_DV_CONNECT);
+  cm.distance = htonl (distance);
+  cm.peer = *target;
+  send_control_to_plugin (&cm.header);
+}
+
+
+/**
+ * Give a DISCONNECT message to the plugin.
+ *
+ * @param target peer that disconnected
+ */
+static void
+send_disconnect_to_plugin (const struct GNUNET_PeerIdentity *target)
+{
+  struct GNUNET_DV_DisconnectMessage dm;
+
+  if (NULL == client_handle)
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Delivering DISCONNECT about peer `%s'\n",
+              GNUNET_i2s (target));
+  dm.header.size = htons (sizeof (dm));
+  dm.header.type = htons (GNUNET_MESSAGE_TYPE_DV_DISCONNECT);
+  dm.reserved = htonl (0);
+  dm.peer = *target;
+  send_control_to_plugin (&dm.header);
+}
+
+
+/**
  * Function called to transfer a message to another peer
  * via core.
  *
@@ -557,6 +619,108 @@
 
 
 /**
+ * Begin exchanging routing information with 'rn', updating
+ * our respective neighbor table in the process.
+ *
+ * @param rn neighbor with whom we should exchange the information
+ */
+static void
+exchange_routing_information (struct RoutingNeighbor *rn)
+{
+  GNUNET_break (0);
+  // FIXME
+}
+
+
+/**
+ * Find a free slot for storing a 'route' in the 'consensi'
+ * set at the given distance.
+ *
+ * @param distance distance to use for the set slot
+ */
+static unsigned int
+get_consensus_slot (uint32_t distance)
+{
+  struct ConsensusSet *cs;
+  unsigned int i;
+
+  cs = &consensi[distance];
+  i = 0;
+  while ( (i < cs->array_length) &&
+         (NULL != cs->targets[i]) ) i++;
+  if (i == cs->array_length)
+    GNUNET_array_grow (cs->targets,
+                      cs->array_length,
+                      cs->array_length * 2 + 2);
+  return i;
+}
+
+
+/**
+ * Setup an entry in the 'routing neighbor' table and begin the
+ * exchange with the new routing neighbor.  Note that a routing
+ * neighbor can be a direct neighbor at the same time, in which case
+ * the peer identity of 'target' and 'next_hop->peer' will be the same
+ * (and the distance will be 1).
+ *
+ * If a routing neighbor already exists, ignore the update if
+ * the distance is not smaller; otherwise if the distance
+ * is smaller, replace the existing entry with the new route.
+ *
+ * @param next_hop first routing hop towards the routing neighbor
+ * @param target peer identity of the routing neighbor
+ * @param distance number of hops to the routing neighbor
+ */
+static void
+create_routing_neighbor (struct DirectNeighbor *next_hop,
+                        const struct GNUNET_PeerIdentity *target,
+                        uint32_t distance)
+{
+  struct RoutingNeighbor *rn;
+  unsigned int i;
+
+  rn = GNUNET_CONTAINER_multihashmap_get (routing_neighbors, 
+                                         &target->hashPubKey);
+  if (NULL != rn)
+  {
+    /* update the entry, instead of creating a new one */
+    if (distance >= rn->route.target.distance)
+      return; /* ignore, distance is not better */
+    rn->route.next_hop = next_hop;
+    if (distance < rn->route.target.distance)
+    { 
+      /* move to alternative consensi slot */
+      consensi[rn->route.target.distance].targets[rn->route.set_offset] = NULL;
+      rn->route.target.distance = distance;
+      i = get_consensus_slot (distance);
+      rn->route.set_offset = i;
+      consensi[distance].targets[i] = &rn->route;      
+    }
+    if (DIRECT_NEIGHBOR_COST == distance)
+    {
+      /* we're now a direct neighbor, remove from set reachable via DV! */
+      send_disconnect_to_plugin (target);
+    }
+    return;
+  }
+  GNUNET_assert (distance < DEFAULT_FISHEYE_DEPTH - 1);
+  i = get_consensus_slot (distance);
+  rn = GNUNET_malloc (sizeof (struct RoutingNeighbor));
+  rn->route.next_hop = next_hop;
+  rn->route.target.peer = *target;
+  rn->route.target.distance = distance;
+  rn->route.set_offset = i;
+  consensi[distance].targets[i] = &rn->route;
+  exchange_routing_information (rn);
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_put (direct_neighbors,
+                                                   &target->hashPubKey,
+                                                   rn,
+                                                   
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+}
+
+
+/**
  * Method called whenever a peer connects.
  *
  * @param cls closure
@@ -570,6 +734,7 @@
                      unsigned int atsi_count)
 {
   struct DirectNeighbor *neighbor;
+  struct RoutingNeighbor *rn;
   uint32_t distance;
 
   /* Check for connect to self message */
@@ -585,14 +750,20 @@
   }
   if (DIRECT_NEIGHBOR_COST != distance) 
     return; /* is a DV-neighbor */
-
-  GNUNET_break (0); // FIXME...
+  neighbor = GNUNET_malloc (sizeof (struct DirectNeighbor));
+  neighbor->peer = *peer;
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_put (direct_neighbors,
+                                                   &peer->hashPubKey,
+                                                   neighbor,
+                                                   
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+  create_routing_neighbor (neighbor, peer, DIRECT_NEIGHBOR_COST);
 }
 
 
 
 /**
- * Core handler for dv data messages.  Whatever this message
+ * Core handler for DV data messages.  Whatever this message
  * contains all we really have to do is rip it out of its
  * DV layering and give it to our pal the DV plugin to report
  * in with.
@@ -816,6 +987,8 @@
   GNUNET_CONTAINER_multihashmap_destroy (all_routes);
   GNUNET_CORE_disconnect (core_api);
   core_api = NULL;
+  GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
+  stats = NULL;
   while (NULL != (pending = plugin_pending_head))
   {
     GNUNET_CONTAINER_DLL_remove (plugin_pending_head,
@@ -911,7 +1084,7 @@
 
   if (NULL == core_api)
     return;
-  // FIXME: stats
+  stats = GNUNET_STATISTICS_create ("dv", cfg);
   GNUNET_SERVER_add_handlers (server, plugin_handlers);
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                &shutdown_task, NULL);
@@ -932,3 +1105,5 @@
           GNUNET_SERVICE_run (argc, argv, "dv", GNUNET_SERVICE_OPTION_NONE,
                               &run, NULL)) ? 0 : 1;
 }
+
+/* end of gnunet-service-dv.c */




reply via email to

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