mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-16 08:49:01 +00:00
FS-9775: Added preliminary support for processing find_nodes query, including calls to compact addresses and node info
This commit is contained in:
parent
3e12cca293
commit
d034968774
@ -5,6 +5,19 @@
|
|||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
KS_DECLARE(ks_status_t) ks_dht2_utility_compact_address(ks_sockaddr_t *address,
|
||||||
|
uint8_t *buffer,
|
||||||
|
ks_size_t *buffer_length,
|
||||||
|
ks_size_t buffer_size);
|
||||||
|
KS_DECLARE(ks_status_t) ks_dht2_utility_compact_node(ks_dht2_nodeid_raw_t *nodeid,
|
||||||
|
ks_sockaddr_t *address,
|
||||||
|
uint8_t *buffer,
|
||||||
|
ks_size_t *buffer_length,
|
||||||
|
ks_size_t buffer_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -180,8 +180,8 @@ KS_DECLARE(ks_status_t) ks_dht2_autoroute(ks_dht2_t *dht, ks_bool_t autoroute, k
|
|||||||
|
|
||||||
if (!autoroute) {
|
if (!autoroute) {
|
||||||
port = 0;
|
port = 0;
|
||||||
} else if (port == 0) {
|
} else if (port <= 0) {
|
||||||
return KS_STATUS_FAIL;
|
port = KS_DHT_DEFAULT_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
dht->autoroute = autoroute;
|
dht->autoroute = autoroute;
|
||||||
@ -331,13 +331,81 @@ KS_DECLARE(void) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
KS_DECLARE(ks_status_t) ks_dht2_maketid(ks_dht2_t *dht)
|
KS_DECLARE(ks_status_t) ks_dht2_utility_compact_address(ks_sockaddr_t *address,
|
||||||
|
uint8_t *buffer,
|
||||||
|
ks_size_t *buffer_length,
|
||||||
|
ks_size_t buffer_size)
|
||||||
{
|
{
|
||||||
ks_assert(dht);
|
ks_size_t required = sizeof(uint16_t);
|
||||||
|
uint16_t port = 0;
|
||||||
|
|
||||||
|
ks_assert(address);
|
||||||
|
ks_assert(buffer);
|
||||||
|
ks_assert(buffer_length);
|
||||||
|
ks_assert(buffer_size);
|
||||||
|
ks_assert(address->family == AF_INET || address->family == AF_INET6);
|
||||||
|
|
||||||
|
if (address->family == AF_INET) {
|
||||||
|
required += sizeof(uint32_t);
|
||||||
|
} else {
|
||||||
|
required += 8 * sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*buffer_length + required > buffer_size) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Insufficient space remaining for compacting\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address->family == AF_INET) {
|
||||||
|
uint32_t *paddr = (uint32_t *)&address->v.v4.sin_addr;
|
||||||
|
uint32_t addr = htonl(*paddr);
|
||||||
|
port = htons(address->v.v4.sin_port);
|
||||||
|
|
||||||
|
memcpy(buffer + (*buffer_length), (void *)&addr, sizeof(uint32_t));
|
||||||
|
*buffer_length += sizeof(uint32_t);
|
||||||
|
} else {
|
||||||
|
uint16_t *paddr = (uint16_t *)&address->v.v6.sin6_addr;
|
||||||
|
port = htons(address->v.v6.sin6_port);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 8; ++i) {
|
||||||
|
uint16_t addr = htons(paddr[i]);
|
||||||
|
memcpy(buffer + (*buffer_length), (void *)&addr, sizeof(uint16_t));
|
||||||
|
*buffer_length += sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer + (*buffer_length), (void *)&port, sizeof(uint16_t));
|
||||||
|
*buffer_length += sizeof(uint16_t);
|
||||||
|
|
||||||
return KS_STATUS_SUCCESS;
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
KS_DECLARE(ks_status_t) ks_dht2_utility_compact_node(ks_dht2_nodeid_raw_t *nodeid,
|
||||||
|
ks_sockaddr_t *address,
|
||||||
|
uint8_t *buffer,
|
||||||
|
ks_size_t *buffer_length,
|
||||||
|
ks_size_t buffer_size)
|
||||||
|
{
|
||||||
|
ks_assert(address);
|
||||||
|
ks_assert(buffer);
|
||||||
|
ks_assert(buffer_length);
|
||||||
|
ks_assert(buffer_size);
|
||||||
|
ks_assert(address->family == AF_INET || address->family == AF_INET6);
|
||||||
|
|
||||||
|
if (*buffer_length + KS_DHT_NODEID_LENGTH > buffer_size) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Insufficient space remaining for compacting\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer + (*buffer_length), (void *)nodeid, KS_DHT_NODEID_LENGTH);
|
||||||
|
*buffer_length += KS_DHT_NODEID_LENGTH;
|
||||||
|
|
||||||
|
return ks_dht2_utility_compact_address(address, buffer, buffer_length, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -904,31 +972,38 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
|
|||||||
{
|
{
|
||||||
struct bencode *id;
|
struct bencode *id;
|
||||||
struct bencode *target;
|
struct bencode *target;
|
||||||
//const char *idv;
|
struct bencode *want;
|
||||||
|
const char *idv;
|
||||||
//const char *targetv;
|
//const char *targetv;
|
||||||
ks_size_t idv_len;
|
ks_size_t idv_len;
|
||||||
ks_size_t targetv_len;
|
ks_size_t targetv_len;
|
||||||
|
ks_bool_t want4 = KS_FALSE;
|
||||||
|
ks_bool_t want6 = KS_FALSE;
|
||||||
ks_dht2_message_t *response = NULL;
|
ks_dht2_message_t *response = NULL;
|
||||||
struct bencode *r = NULL;
|
struct bencode *r = NULL;
|
||||||
|
uint8_t buffer[1000];
|
||||||
|
ks_size_t buffer_length = 0;
|
||||||
ks_status_t ret = KS_STATUS_FAIL;
|
ks_status_t ret = KS_STATUS_FAIL;
|
||||||
|
|
||||||
ks_assert(dht);
|
ks_assert(dht);
|
||||||
ks_assert(message);
|
ks_assert(message);
|
||||||
ks_assert(message->args);
|
ks_assert(message->args);
|
||||||
|
|
||||||
|
|
||||||
id = ben_dict_get_by_str(message->args, "id");
|
id = ben_dict_get_by_str(message->args, "id");
|
||||||
if (!id) {
|
if (!id) {
|
||||||
ks_log(KS_LOG_DEBUG, "Message args missing required key 'id'\n");
|
ks_log(KS_LOG_DEBUG, "Message args missing required key 'id'\n");
|
||||||
return KS_STATUS_FAIL;
|
return KS_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//idv = ben_str_val(id);
|
idv = ben_str_val(id);
|
||||||
idv_len = ben_str_len(id);
|
idv_len = ben_str_len(id);
|
||||||
if (idv_len != KS_DHT_NODEID_LENGTH) {
|
if (idv_len != KS_DHT_NODEID_LENGTH) {
|
||||||
ks_log(KS_LOG_DEBUG, "Message args 'id' value has an unexpected size of %d\n", idv_len);
|
ks_log(KS_LOG_DEBUG, "Message args 'id' value has an unexpected size of %d\n", idv_len);
|
||||||
return KS_STATUS_FAIL;
|
return KS_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
target = ben_dict_get_by_str(message->args, "target");
|
target = ben_dict_get_by_str(message->args, "target");
|
||||||
if (!target) {
|
if (!target) {
|
||||||
ks_log(KS_LOG_DEBUG, "Message args missing required key 'target'\n");
|
ks_log(KS_LOG_DEBUG, "Message args missing required key 'target'\n");
|
||||||
@ -943,8 +1018,36 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
want = ben_dict_get_by_str(message->args, "want");
|
||||||
|
if (want) {
|
||||||
|
size_t want_len = ben_list_len(want);
|
||||||
|
for (size_t i = 0; i < want_len; ++i) {
|
||||||
|
struct bencode *iv = ben_list_get(want, i);
|
||||||
|
if (!ben_cmp_with_str(iv, "n4")) {
|
||||||
|
want4 = KS_TRUE;
|
||||||
|
}
|
||||||
|
if (!ben_cmp_with_str(iv, "n6")) {
|
||||||
|
want6 = KS_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!want4 && !want6) {
|
||||||
|
want4 = message->raddr.family == AF_INET;
|
||||||
|
want6 = message->raddr.family == AF_INET6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo add/touch bucket entry for remote node
|
||||||
|
|
||||||
ks_log(KS_LOG_DEBUG, "Message query find_node is valid\n");
|
ks_log(KS_LOG_DEBUG, "Message query find_node is valid\n");
|
||||||
|
|
||||||
|
// @todo get closest nodes to target from route table
|
||||||
|
|
||||||
|
// @todo compact into buffer
|
||||||
|
if (ks_dht2_utility_compact_node((ks_dht2_nodeid_raw_t *)idv, &message->raddr, buffer, &buffer_length, sizeof(buffer)) != KS_STATUS_SUCCESS) {
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ks_dht2_message_alloc(&response, dht->pool) != KS_STATUS_SUCCESS) {
|
if (ks_dht2_message_alloc(&response, dht->pool) != KS_STATUS_SUCCESS) {
|
||||||
goto done;
|
goto done;
|
||||||
@ -959,6 +1062,8 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_m
|
|||||||
}
|
}
|
||||||
|
|
||||||
ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
|
ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
|
||||||
|
// @todo populate nodes/nodes6
|
||||||
|
ben_dict_set(r, ben_blob("nodes", 5), ben_blob(buffer, buffer_length));
|
||||||
|
|
||||||
ks_log(KS_LOG_DEBUG, "Sending message response find_node\n");
|
ks_log(KS_LOG_DEBUG, "Sending message response find_node\n");
|
||||||
ks_q_push(dht->send_q, (void *)response);
|
ks_q_push(dht->send_q, (void *)response);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user