-
Notifications
You must be signed in to change notification settings - Fork 172
Running a node in your program
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).
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.
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);
}