-/* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2010-2023. 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. */
#include "routing_table.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(kademlia_node, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
namespace kademlia {
static void destroy(void* message)
delete msg;
}
+/**
+ * Try to asynchronously get a new message from given mailbox. Return null if none available.
+ */
+Message* Node::receive(sg4::Mailbox* mailbox)
+{
+ if (receive_comm == nullptr)
+ receive_comm = mailbox->get_async<kademlia::Message>(&received_msg);
+ if (not receive_comm->test())
+ return nullptr;
+ receive_comm = nullptr;
+ return received_msg;
+}
+
/**
* @brief Tries to join the network
* @param known_id id of the node I know in the network.
/* First step: Send a "FIND_NODE" request to the node we know */
sendFindNode(known_id, id_);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_));
do {
- if (receive_comm == nullptr)
- receive_comm = mailbox->get_async<Message>(&received_msg);
- if (receive_comm->test()) {
+ if (Message* msg = receive(mailbox)) {
XBT_DEBUG("Received an answer from the node I know.");
got_answer = true;
// retrieve the node list and ping them.
- const Answer* node_list = received_msg->answer_.get();
- if (node_list) {
- for (auto const& contact : node_list->getNodes())
- routingTableUpdate(contact.first);
+ if (const Answer* node_list = msg->answer_.get()) {
+ for (auto const& [contact, _] : node_list->getNodes())
+ routingTableUpdate(contact);
} else {
- handleFindNode(received_msg);
+ handleFindNode(msg);
}
- delete received_msg;
- receive_comm = nullptr;
+ delete msg;
} else
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
} while (not got_answer);
/* Second step: Send a FIND_NODE to a random node in buckets */
void Node::sendFindNode(unsigned int id, unsigned int destination) const
{
/* Gets the mailbox to send to */
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id));
/* Build the task */
- auto* msg = new Message(id_, destination, simgrid::s4u::Mailbox::by_name(std::to_string(id_)),
- simgrid::s4u::Host::current()->get_cname());
+ auto* msg =
+ new Message(id_, destination, sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname());
/* Send the task */
mailbox->put_init(msg, 1)->detach(kademlia::destroy);
unsigned int i = 0;
unsigned int j = 0;
unsigned int destination = node_list->getDestinationId();
- for (auto const& node_to_query : node_list->getNodes()) {
+ for (auto const& [node_to_query, _] : node_list->getNodes()) {
/* We need to have at most "KADEMLIA_ALPHA" requests each time, according to the protocol */
/* Gets the node we want to send the query to */
- if (node_to_query.first != id_) { /* No need to query ourselves */
- sendFindNode(node_to_query.first, destination);
+ if (node_to_query != id_) { /* No need to query ourselves */
+ sendFindNode(node_to_query, destination);
j++;
}
i++;
unsigned int answers;
bool destination_found = false;
unsigned int nodes_added = 0;
- double global_timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT;
+ double global_timeout = sg4::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT;
unsigned int steps = 0;
/* First we build a list of who we already know */
answers = 0;
queries = sendFindNodeToBest(node_list.get());
nodes_added = 0;
- double timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_TIMEOUT;
+ double timeout = sg4::Engine::get_clock() + FIND_NODE_TIMEOUT;
steps++;
- double time_beginreceive = simgrid::s4u::Engine::get_clock();
+ double time_beginreceive = sg4::Engine::get_clock();
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_));
do {
- if (receive_comm == nullptr)
- receive_comm = mailbox->get_async<Message>(&received_msg);
-
- if (receive_comm->test()) {
+ if (Message* msg = receive(mailbox)) {
// Check if what we have received is what we are looking for.
- if (received_msg->answer_ && received_msg->answer_->getDestinationId() == id_to_find) {
- routingTableUpdate(received_msg->sender_id_);
+ if (msg->answer_ && msg->answer_->getDestinationId() == id_to_find) {
+ routingTableUpdate(msg->sender_id_);
// Handle the answer
- for (auto const& contact : node_list->getNodes())
- routingTableUpdate(contact.first);
+ for (auto const& [contact, _] : node_list->getNodes())
+ routingTableUpdate(contact);
answers++;
- nodes_added = node_list->merge(received_msg->answer_.get());
- XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", received_msg->answer_to_->get_cname(),
- received_msg->issuer_host_name_.c_str(), received_msg->answer_->getSize());
+ nodes_added = node_list->merge(msg->answer_.get());
+ XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", msg->answer_to_->get_cname(),
+ msg->issuer_host_name_.c_str(), msg->answer_->getSize());
} else {
- if (received_msg->answer_) {
- routingTableUpdate(received_msg->sender_id_);
+ if (msg->answer_) {
+ routingTableUpdate(msg->sender_id_);
XBT_DEBUG("Received a wrong answer for a FIND_NODE");
} else {
- handleFindNode(received_msg);
+ handleFindNode(msg);
}
// Update the timeout if we didn't have our answer
- timeout += simgrid::s4u::Engine::get_clock() - time_beginreceive;
- time_beginreceive = simgrid::s4u::Engine::get_clock();
+ timeout += sg4::Engine::get_clock() - time_beginreceive;
+ time_beginreceive = sg4::Engine::get_clock();
}
- delete received_msg;
- receive_comm = nullptr;
+ delete msg;
} else {
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
- } while (simgrid::s4u::Engine::get_clock() < timeout && answers < queries);
+ } while (sg4::Engine::get_clock() < timeout && answers < queries);
destination_found = node_list->destinationFound();
- } while (not destination_found && (nodes_added > 0 || answers == 0) &&
- simgrid::s4u::Engine::get_clock() < global_timeout && steps < MAX_STEPS);
+ } while (not destination_found && (nodes_added > 0 || answers == 0) && sg4::Engine::get_clock() < global_timeout &&
+ steps < MAX_STEPS);
if (destination_found) {
if (count_in_stats)
XBT_VERB("Received a FIND_NODE from %s (%s), he's trying to find %08x", msg->answer_to_->get_cname(),
msg->issuer_host_name_.c_str(), msg->destination_id_);
// Building the answer to the request
- auto* answer =
- new Message(id_, msg->destination_id_, findClosest(msg->destination_id_),
- simgrid::s4u::Mailbox::by_name(std::to_string(id_)), simgrid::s4u::Host::current()->get_cname());
+ auto* answer = new Message(id_, msg->destination_id_, findClosest(msg->destination_id_),
+ sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname());
// Sending the answer
msg->answer_to_->put_init(answer, 1)->detach(kademlia::destroy);
}
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;