Running a node in your program - savoirfairelinux/opendht GitHub Wiki
A DHT node can be implemented in C++ as an instance of the dht::Dht
class standalone, integrated into your program's main loop, or by using the helper class dht::DhtRunner
(recommended).
dht::DhtRunner
Running a node with The class dht::DhtRunner
provides thread-safe access to the running DHT instance and also manages network sockets.
DhtRunner
runs an instance of dht::SecureDht
so that cryptographic operations are made available. An identity (RSA key pair) can be optionally provided to sign/encrypt values (see DhtRunner::run
).
dht::DhtRunner node;
// Launch a dht node on a new thread, using a
// generated RSA key pair, and listen on port 4222.
node.run(4222, dht::crypto::generateIdentity(), true);
// use the node...
// stop the node
node.join();
// node.run() can be called again
The run
method is defined as:
void run(in_port_t port, const crypto::Identity identity, bool threaded = true, StatusCallback status_cb = nullptr);
port
is the UDP port to bind.identity
is the RSA keypair to use for the crypto layer. A new key pair can be generated withdht::crypto::generateIdentity()
.threaded
defines if a new thread will be launched to run the DHT. Iftrue
, no further action is required to have a working DHT. If false (default),DhtRunner::loop()
has to be called regularly.status_cb
is a status callback informing about the connection state of the DHT (connecting, connected..) for both IPv4 and IPv6.
Calling run
while the instance is already running has no effect.
Joining an existing network
On a local network, the simplest way to initiate or join a network is to use Peer Discovery. This will use IP multicast to find and add DHT peers.
A node can join an existing OpenDHT network through any connected node. The recommended method to join a network is to use one of:
void bootstrap(const char* host, const char* service);
void bootstrap(const std::vector<std::pair<sockaddr_storage, socklen_t>>& nodes);
void bootstrap(const std::vector<Dht::NodeExport>& nodes);
The first two will ping specified IP addresses. The first version will resolve a string representation to an actual IP address, the second method takes raw sockaddr
structures.
The third method is recommended when joining a known network. It will add previously known nodes to the routing table and only try to contact them if necessary. It takes a list of the Dht::NodeExport
structure, obtained during previous runs using exportNodes()
.
Dht::NodeExport
is msgpack-serializable so that the result of exportNodes()
can be easily serialized/unserialized as in this example:
dht::DhtRunner node;
// Export nodes to binary file
std::ofstream myfile("dhtNodeExport.bin", std::ios::binary);
msgpack::pack(myfile, node.exportNodes());
// Import nodes from binary file
msgpack::unpacker pac;
{
// Read whole file
std::ifstream myfile("dhtNodeExport.bin", std::ios::binary|std::ios::ate);
auto size = myfile.tellg();
myfile.seekg (0, std::ios::beg);
pac.reserve_buffer(size);
myfile.read (pac.buffer(), size);
pac.buffer_consumed(size);
}
// Import nodes
msgpack::object_handle oh;
while (pac.next(oh)) {
auto imported_nodes = oh.get().as<std::vector<dht::NodeExport>>();
std::cout << "Importing : " << imported_nodes.size() << " nodes" << std::endl;
node.bootstrap(imported_nodes);
}