Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Match xbt_malloc with xbt_free.
[simgrid.git] / examples / c / dht-kademlia / node.c
index cf7dec0..d8204d3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2020. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -37,6 +37,19 @@ void node_free(node_t node)
   xbt_free(node);
 }
 
+/**
+  * Try to asynchronously get a new message from given mailbox. Return null if none available.
+  */
+kademlia_message_t receive(node_t node, sg_mailbox_t mailbox)
+{
+  if (node->receive_comm == NULL)
+    node->receive_comm = sg_mailbox_get_async(mailbox, &node->received_msg);
+  if (!sg_comm_test(node->receive_comm))
+    return NULL;
+  node->receive_comm = NULL;
+  return node->received_msg;
+}
+
 /**
  * @brief Tries to join the network
  * @param node node data
@@ -56,14 +69,11 @@ unsigned int join(node_t node, unsigned int id_known)
   /* First step: Send a "FIND_NODE" request to the node we know */
   send_find_node(node, id_known, node->id);
   do {
-    if (node->receive_comm == NULL)
-      node->receive_comm = sg_mailbox_get_async(mailbox, &node->received_msg);
-
-    if (sg_comm_test(node->receive_comm)) {
+    const kademlia_message_t msg = receive(node, mailbox);
+    if (msg) {
       XBT_DEBUG("Received an answer from the node I know.");
       got_answer = 1;
       // retrieve the node list and ping them.
-      const kademlia_message_t msg = (kademlia_message_t)(node->received_msg);
       const s_answer_t* node_list  = msg->answer;
       if (node_list != NULL) {
         node_contact_t contact;
@@ -73,15 +83,13 @@ unsigned int join(node_t node, unsigned int id_known)
       } else {
         handle_find_node(node, msg);
       }
-      answer_free(msg->answer);
-      free(msg);
-      node->receive_comm = NULL;
+      free_message(msg);
     } else {
       sg_actor_sleep_for(1);
     }
   } while (got_answer == 0);
 
-  /* Second step: Send a FIND_NODE to a random node in buckets */
+  /* Second step: Send a FIND_NODE to a random node in buckets */
   unsigned int bucket_id = routing_table_find_bucket(node->table, id_known)->id;
   xbt_assert(bucket_id <= IDENTIFIER_SIZE);
   for (i = 0; ((bucket_id > i) || (bucket_id + i) <= IDENTIFIER_SIZE) && i < JOIN_BUCKETS_QUERIES; i++) {
@@ -102,7 +110,7 @@ unsigned int join(node_t node, unsigned int id_known)
  * @param id node we are querying
  * @param destination node we are trying to find.
  */
-void send_find_node(node_t node, unsigned int id, unsigned int destination)
+void send_find_node(const_node_t node, unsigned int id, unsigned int destination)
 {
   /* Gets the mailbox to send to */
   sg_mailbox_t mailbox = get_node_mailbox(id);
@@ -117,7 +125,7 @@ void send_find_node(node_t node, unsigned int id, unsigned int destination)
  * Sends to the best "KADEMLIA_ALPHA" nodes in the "node_list" array a "FIND_NODE" request, to ask them for their best
  * nodes
  */
-unsigned int send_find_node_to_best(node_t node, const_answer_t node_list)
+unsigned int send_find_node_to_best(const_node_t node, const_answer_t node_list)
 {
   unsigned int i           = 0;
   unsigned int j           = 0;
@@ -170,7 +178,6 @@ void routing_table_update(const_node_t node, unsigned int id)
  */
 answer_t find_closest(const_node_t node, unsigned int destination_id)
 {
-  int i;
   answer_t answer = answer_init(destination_id);
   /* We find the corresponding bucket for the id */
   const_bucket_t bucket = routing_table_find_bucket(node->table, destination_id);
@@ -182,7 +189,7 @@ answer_t find_closest(const_node_t node, unsigned int destination_id)
   /* However, if we don't have enough elements in our bucket, we NEED to include at least "BUCKET_SIZE" elements
    * (if, of course, we know at least "BUCKET_SIZE" elements. So we're going to look unsigned into the other buckets.
    */
-  for (i = 1; answer->size < BUCKET_SIZE && ((bucket_id - i > 0) || (bucket_id + i < IDENTIFIER_SIZE)); i++) {
+  for (int i = 1; answer->size < BUCKET_SIZE && ((bucket_id - i > 0) || (bucket_id + i < IDENTIFIER_SIZE)); i++) {
     /* We check the previous buckets */
     if (bucket_id - i >= 0) {
       const_bucket_t bucket_p = &node->table->buckets[bucket_id - i];
@@ -204,7 +211,6 @@ answer_t find_closest(const_node_t node, unsigned int destination_id)
 
 unsigned int find_node(node_t node, unsigned int id_to_find, unsigned int count_in_stats)
 {
-  unsigned int i = 0;
   unsigned int queries;
   unsigned int answers;
   unsigned int destination_found = 0;
@@ -229,18 +235,15 @@ unsigned int find_node(node_t node, unsigned int id_to_find, unsigned int count_
     double time_beginreceive = simgrid_get_clock();
 
     do {
-      if (node->receive_comm == NULL)
-        node->receive_comm = sg_mailbox_get_async(mailbox, &node->received_msg);
-
-      if (sg_comm_test(node->receive_comm)) {
+      const kademlia_message_t msg = receive(node, mailbox);
+      if (msg) {
         // Figure out if we received an answer or something else
-        const kademlia_message_t msg = (kademlia_message_t)(node->received_msg);
-
         // Check if what we have received is what we are looking for.
         if (msg->answer != NULL && msg->answer->destination_id == id_to_find) {
           // Handle the answer
           routing_table_update(node, msg->sender_id);
           node_contact_t contact;
+          unsigned int i;
           xbt_dynar_foreach (node_list->nodes, i, contact)
             routing_table_update(node, contact->id);
 
@@ -260,9 +263,7 @@ unsigned int find_node(node_t node, unsigned int id_to_find, unsigned int count_
           timeout += simgrid_get_clock() - time_beginreceive;
           time_beginreceive = simgrid_get_clock();
         }
-        answer_free(msg->answer);
-        free(msg);
-        node->receive_comm = NULL;
+        free_message(msg);
       } else {
         sg_actor_sleep_for(1);
       }
@@ -298,7 +299,7 @@ void random_lookup(node_t node)
 }
 
 /** @brief Handles the answer to an incoming "find_node" message */
-void handle_find_node(node_t node, kademlia_message_t msg)
+void handle_find_node(const_node_t node, const_kademlia_message_t msg)
 {
   routing_table_update(node, msg->sender_id);
   XBT_VERB("Received a FIND_NODE from %s (%s), he's trying to find %08x", sg_mailbox_get_name(msg->answer_to),
@@ -320,7 +321,7 @@ unsigned int get_id_in_prefix(unsigned int id, unsigned int prefix)
   if (prefix == 0) {
     return 0;
   } else {
-    return (1U << ((unsigned int)(prefix - 1))) ^ id;
+    return (1U << (prefix - 1)) ^ id;
   }
 }
 
@@ -334,7 +335,7 @@ unsigned int get_node_prefix(unsigned int id, unsigned int nb_bits)
   unsigned int size = sizeof(unsigned int) * 8;
   for (unsigned int j = 0; j < size; j++) {
     if (((id >> (size - 1 - j)) & 0x1) != 0) {
-      return nb_bits - (j);
+      return nb_bits - j;
     }
   }
   return 0;