C implementation of the Kademlia-based Distributed Hash Table (DHT) used in the BitTorrent network (aka "mainline DHT")
libdht
is a C implementation of the Kademlia-based Distributed Hash Table
(DHT) used in the BitTorrent network (aka “mainline DHT”).
libdht is distributed under the MIT license (see LICENSE). The present source
also incorporates code from the following external projects:
libdht only depends on the following libraries:
It does not require any other external libraries.
So far libdht has been successfully built and tested on:
Doxygen generated documentation for the library’s API is available online at https://naturalpolice.github.io/libdht/.
Here is an example to get started operating a basic DHT node. Please refer to
the rest of the documentation for more complex scenarios.
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <dht/node.h>
static void sock_send(const unsigned char *data, size_t len,
const struct sockaddr *dest, socklen_t addrlen,
void *opaque)
{
int sock = *(int *)opaque;
if (sendto(sock, data, len, 0, dest, addrlen) < 0)
fprintf(stderr, "sendto: %s\n", strerror(errno));
}
int node_run(void)
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in sin;
struct dht_node node;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(6881);
bind(sock, (struct sockaddr *)&sin, sizeof(sin));
if (dht_node_init(&node, NULL, sock_send, &sock))
return -1;
dht_node_start(&node);
while (1) {
struct timeval tv;
fd_set rfds;
int rc;
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
dht_node_timeout(&node, &tv);
rc = select(sock + 1, &rfds, NULL, NULL, &tv);
if (rc < 0) {
fprintf(stderr, "select: %s\n", strerror(errno));
return -1;
}
if (rc && FD_ISSET(sock, &rfds)) {
unsigned char buf[2048];
struct sockaddr_storage ss;
socklen_t sl = sizeof(ss);
rc = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&ss, &sl);
if (rc < 0) {
fprintf(stderr, "recvfrom: %s\n", strerror(errno));
return -1;
}
dht_node_input(&node, buf, rc, (struct sockaddr *)&ss, sl);
}
dht_node_work(&node);
}
return 0;
}