FS-9775: Initial commit of the first portion of the DHT rewrite for peer review

Code compiles, but not yet functional, unit tests to come soon for current code
This commit is contained in:
Shane Bryldt 2016-11-30 03:47:40 +00:00 committed by Mike Jerris
parent 0c3ba1e378
commit d0791961c4
9 changed files with 539 additions and 0 deletions

View File

@ -13,6 +13,7 @@ libks_la_SOURCES += src/ks_time.c src/ks_printf.c src/ks_hash.c src/ks_q.c src/k
libks_la_SOURCES += src/ks_ssl.c src/kws.c src/ks_rng.c
libks_la_SOURCES += src/utp/utp_api.cpp src/utp/utp_callbacks.cpp src/utp/utp_hash.cpp src/utp/utp_internal.cpp
libks_la_SOURCES += src/utp/utp_packedsockaddr.cpp src/utp/utp_utils.cpp src/ks_bencode.c
libks_la_SOURCES += src/dht/ks_dht.c src/dht/ks_dht_endpoint.c src/dht/ks_dht_nodeid.c
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
#aes.h aescpp.h brg_endian.h aesopt.h aestab.h brg_types.h sha2.h twofish.h
@ -28,6 +29,7 @@ library_include_HEADERS += src/include/ks_dso.h src/include/ks_dht.h src/include
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
library_include_HEADERS += src/utp/utp_internal.h src/utp/utp.h src/utp/utp_types.h src/utp/utp_callbacks.h src/utp/utp_templates.h
library_include_HEADERS += src/utp/utp_hash.h src/utp/utp_packedsockaddr.h src/utp/utp_utils.h src/include/ks_utp.h
library_include_HEADERS += src/dht/ks_dht.h src/dht/ks_dht-int.h src/dht/ks_dht_endpoint.h src/dht/ks_dht_endpoint-int.h src/dht/ks_dht_nodeid.h
tests: libks.la
$(MAKE) -C test tests

View File

@ -0,0 +1,25 @@
#ifndef KS_DHT_INT_H
#define KS_DHT_INT_H
#include "ks.h"
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) ks_dht2_idle(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr);
KS_END_EXTERN_C
#endif /* KS_DHT_INT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

220
libs/libks/src/dht/ks_dht.c Normal file
View File

@ -0,0 +1,220 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "ks_dht_endpoint-int.h"
#include "sodium.h"
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_alloc(ks_dht2_t **dht, ks_pool_t *pool)
{
ks_bool_t pool_alloc = !pool;
ks_dht2_t *d;
ks_assert(dht);
if (pool_alloc) ks_pool_open(&pool);
*dht = d = ks_pool_alloc(pool, sizeof(ks_dht2_t));
d->pool = pool;
d->pool_alloc = pool_alloc;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_free(ks_dht2_t *dht)
{
ks_pool_t *pool = dht->pool;
ks_bool_t pool_alloc = dht->pool_alloc;
ks_pool_free(pool, dht);
if (pool_alloc) {
ks_pool_close(&pool);
}
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const uint8_t *nodeid)
{
ks_assert(dht);
if (ks_dht2_nodeid_init(&dht->nodeid, nodeid) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
}
dht->bind_ipv4 = KS_FALSE;
dht->bind_ipv6 = KS_FALSE;
dht->endpoints = NULL;
dht->endpoints_size = 0;
ks_hash_create(&dht->endpoints_hash, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK, dht->pool);
dht->endpoints_poll = NULL;
dht->recv_buffer_length = 0;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht)
{
ks_assert(dht);
dht->recv_buffer_length = 0;
// @todo dht->endpoints_poll deinit
// @todo dht->endpoints deinit
ks_hash_destroy(&dht->endpoints_hash);
dht->bind_ipv4 = KS_FALSE;
dht->bind_ipv6 = KS_FALSE;
ks_dht2_nodeid_deinit(&dht->nodeid);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_bind(ks_dht2_t *dht, const ks_sockaddr_t *addr)
{
ks_dht2_endpoint_t *ep;
ks_socket_t sock;
int32_t epindex;
ks_assert(dht);
ks_assert(addr);
ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
ks_assert(addr->port);
//if (!addr->port) {
// addr->port = KS_DHT_DEFAULT_PORT;
//}
dht->bind_ipv4 |= addr->family == AF_INET;
dht->bind_ipv6 |= addr->family == AF_INET6;
// @todo start of ks_dht2_endpoint_bind
if ((sock = socket(addr->family, SOCK_DGRAM, IPPROTO_UDP)) == KS_SOCK_INVALID) {
return KS_STATUS_FAIL;
}
// @todo shouldn't ks_addr_bind take a const addr *?
if (ks_addr_bind(sock, (ks_sockaddr_t *)addr) != KS_STATUS_SUCCESS) {
ks_socket_close(&sock);
return KS_STATUS_FAIL;
}
if (ks_dht2_endpoint_alloc(&ep, dht->pool) != KS_STATUS_SUCCESS) {
ks_socket_close(&sock);
return KS_STATUS_FAIL;
}
if (ks_dht2_endpoint_init(ep, addr, sock) != KS_STATUS_SUCCESS) {
ks_dht2_endpoint_free(ep);
ks_socket_close(&sock);
return KS_STATUS_FAIL;
}
ks_socket_option(ep->sock, SO_REUSEADDR, KS_TRUE);
ks_socket_option(ep->sock, KS_SO_NONBLOCK, KS_TRUE);
// @todo end of ks_dht2_endpoint_bind
epindex = dht->endpoints_size++;
dht->endpoints = (ks_dht2_endpoint_t **)ks_pool_resize(dht->pool,
(void *)dht->endpoints,
sizeof(ks_dht2_endpoint_t *) * dht->endpoints_size);
dht->endpoints[epindex] = ep;
ks_hash_insert(dht->endpoints_hash, ep->addr.host, ep);
dht->endpoints_poll = (struct pollfd *)ks_pool_resize(dht->pool,
(void *)dht->endpoints_poll,
sizeof(struct pollfd) * dht->endpoints_size);
dht->endpoints_poll[epindex].fd = ep->sock;
dht->endpoints_poll[epindex].events = POLLIN | POLLERR;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
{
int32_t result;
ks_assert(dht);
ks_assert (timeout >= 0);
// @todo why was old DHT code checking for poll descriptor resizing here?
if (timeout == 0) {
// @todo deal with default timeout, should return quickly but not hog the CPU polling
}
result = ks_poll(dht->endpoints_poll, dht->endpoints_size, timeout);
if (result < 0) {
return KS_STATUS_FAIL;
}
if (result == 0) {
ks_dht2_idle(dht);
return KS_STATUS_TIMEOUT;
}
for (int32_t i = 0; i < dht->endpoints_size; ++i) {
if (dht->endpoints_poll[i].revents & POLLIN) {
ks_sockaddr_t raddr = KS_SA_INIT;
dht->recv_buffer_length = KS_DHT_RECV_BUFFER_SIZE;
raddr.family = dht->endpoints[i]->addr.family;
if (ks_socket_recvfrom(dht->endpoints_poll[i].fd, dht->recv_buffer, &dht->recv_buffer_length, &raddr) == KS_STATUS_SUCCESS) {
ks_dht2_process(dht, &raddr);
}
}
}
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_idle(ks_dht2_t *dht)
{
ks_assert(dht);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr)
{
ks_assert(dht);
ks_assert(raddr);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,61 @@
#ifndef KS_DHT_H
#define KS_DHT_H
#include "ks.h"
#include "ks_bencode.h"
#include "ks_dht_endpoint.h"
#include "ks_dht_nodeid.h"
KS_BEGIN_EXTERN_C
#define KS_DHT_DEFAULT_PORT 5309
#define KS_DHT_RECV_BUFFER_SIZE 0xFFFF
typedef struct ks_dht2_s ks_dht2_t;
struct ks_dht2_s {
ks_pool_t *pool;
ks_bool_t pool_alloc;
ks_dht2_nodeid_t nodeid;
ks_bool_t bind_ipv4;
ks_bool_t bind_ipv6;
ks_dht2_endpoint_t **endpoints;
int32_t endpoints_size;
ks_hash_t *endpoints_hash;
struct pollfd *endpoints_poll;
uint8_t recv_buffer[KS_DHT_RECV_BUFFER_SIZE];
ks_size_t recv_buffer_length;
};
KS_DECLARE(ks_status_t) ks_dht2_alloc(ks_dht2_t **dht, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_dht2_free(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const uint8_t *nodeid);
KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_bind(ks_dht2_t *dht, const ks_sockaddr_t *addr);
KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout);
KS_END_EXTERN_C
#endif /* KS_DHT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,28 @@
#ifndef KS_DHT_ENDPOINT_INT_H
#define KS_DHT_ENDPOINT_INT_H
#include "ks.h"
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) ks_dht2_endpoint_alloc(ks_dht2_endpoint_t **endpoint, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_dht2_endpoint_free(ks_dht2_endpoint_t *endpoint);
KS_DECLARE(ks_status_t) ks_dht2_endpoint_init(ks_dht2_endpoint_t *endpoint, const ks_sockaddr_t *addr, ks_socket_t sock);
KS_DECLARE(ks_status_t) ks_dht2_endpoint_deinit(ks_dht2_endpoint_t *endpoint);
KS_END_EXTERN_C
#endif /* KS_DHT_ENDPOINT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,68 @@
#include "ks_dht_endpoint.h"
#include "ks_dht_endpoint-int.h"
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_endpoint_alloc(ks_dht2_endpoint_t **endpoint, ks_pool_t *pool)
{
ks_dht2_endpoint_t *ep;
ks_assert(endpoint);
ks_assert(pool);
*endpoint = ep = ks_pool_alloc(pool, sizeof(ks_dht2_endpoint_t));
ep->pool = pool;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_endpoint_free(ks_dht2_endpoint_t *endpoint)
{
ks_assert(endpoint);
ks_pool_free(endpoint->pool, endpoint);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_endpoint_init(ks_dht2_endpoint_t *endpoint, const ks_sockaddr_t *addr, ks_socket_t sock)
{
ks_assert(endpoint);
ks_assert(addr);
ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
endpoint->addr = *addr;
endpoint->sock = sock;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_endpoint_deinit(ks_dht2_endpoint_t *endpoint)
{
ks_assert(endpoint);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,29 @@
#ifndef KS_DHT_ENDPOINT_H
#define KS_DHT_ENDPOINT_H
#include "ks.h"
KS_BEGIN_EXTERN_C
typedef struct ks_dht2_endpoint_s ks_dht2_endpoint_t;
struct ks_dht2_endpoint_s {
ks_pool_t *pool;
ks_sockaddr_t addr;
ks_socket_t sock;
};
KS_END_EXTERN_C
#endif /* KS_DHT_ENDPOINT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,70 @@
#include "ks_dht_nodeid.h"
#include "sodium.h"
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_nodeid_alloc(ks_dht2_nodeid_t **nodeid, ks_pool_t *pool)
{
ks_dht2_nodeid_t *nid;
ks_assert(nodeid);
ks_assert(pool);
*nodeid = nid = ks_pool_alloc(pool, sizeof(ks_dht2_nodeid_t));
nid->pool = pool;
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_nodeid_free(ks_dht2_nodeid_t *nodeid)
{
ks_assert(nodeid);
ks_pool_free(nodeid->pool, nodeid);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_nodeid_init(ks_dht2_nodeid_t *nodeid, const uint8_t *id)
{
ks_assert(nodeid);
ks_assert(id);
if (!id) {
randombytes_buf(nodeid->id, KS_DHT_NODEID_LENGTH);
} else {
memcpy(nodeid->id, id, KS_DHT_NODEID_LENGTH);
}
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_nodeid_deinit(ks_dht2_nodeid_t *nodeid)
{
ks_assert(nodeid);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,36 @@
#ifndef KS_DHT_NODEID_H
#define KS_DHT_NODEID_H
#include "ks.h"
KS_BEGIN_EXTERN_C
#define KS_DHT_NODEID_LENGTH 20
typedef struct ks_dht2_nodeid_s ks_dht2_nodeid_t;
struct ks_dht2_nodeid_s {
ks_pool_t *pool;
uint8_t id[KS_DHT_NODEID_LENGTH];
};
KS_DECLARE(ks_status_t) ks_dht2_nodeid_alloc(ks_dht2_nodeid_t **nodeid, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_dht2_nodeid_free(ks_dht2_nodeid_t *nodeid);
KS_DECLARE(ks_status_t) ks_dht2_nodeid_init(ks_dht2_nodeid_t *nodeid, const uint8_t *id);
KS_DECLARE(ks_status_t) ks_dht2_nodeid_deinit(ks_dht2_nodeid_t *nodeid);
KS_END_EXTERN_C
#endif /* KS_DHT_NODEID_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/