提交 3e12cca2 authored 作者: Shane Bryldt's avatar Shane Bryldt 提交者: Mike Jerris

FS-9775: Refactored sending of messages to utilize a more scalable and throttled…

FS-9775: Refactored sending of messages to utilize a more scalable and throttled queue for outgoing messages
上级 b51038f6
...@@ -8,30 +8,31 @@ KS_BEGIN_EXTERN_C ...@@ -8,30 +8,31 @@ KS_BEGIN_EXTERN_C
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_idle(ks_dht2_t *dht); KS_DECLARE(void) ks_dht2_idle(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_idle_expirations(ks_dht2_t *dht); KS_DECLARE(void) ks_dht2_idle_expirations(ks_dht2_t *dht);
KS_DECLARE(void) ks_dht2_idle_send(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr); KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht, KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht,
ks_sockaddr_t *raddr, ks_sockaddr_t *raddr,
uint8_t *transactionid, uint8_t *transactionid,
ks_size_t transactionid_length, ks_size_t transactionid_length,
long long errorcode, long long errorcode,
const char *errorstr); const char *errorstr);
KS_DECLARE(ks_status_t) ks_dht2_send_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr);
KS_DECLARE(ks_status_t) ks_dht2_send_findnode(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_nodeid_raw_t *targetid);
KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message); KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr);
KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message); KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_process_response_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message); KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_send_query_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr); KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_send_response_ping(ks_dht2_t *dht, KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_message_t *message);
ks_sockaddr_t *raddr,
uint8_t *transactionid, KS_DECLARE(ks_status_t) ks_dht2_process_response_ping(ks_dht2_t *dht, ks_dht2_message_t *message);
ks_size_t transactionid_length); KS_DECLARE(ks_status_t) ks_dht2_process_response_findnode(ks_dht2_t *dht, ks_dht2_message_t *message);
/** /**
* *
......
...@@ -79,6 +79,7 @@ KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const ks_dht2_nodeid_raw_t ...@@ -79,6 +79,7 @@ KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const ks_dht2_nodeid_raw_t
ks_hash_create(&dht->registry_query, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, dht->pool); ks_hash_create(&dht->registry_query, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, dht->pool);
ks_dht2_register_query(dht, "ping", ks_dht2_process_query_ping); ks_dht2_register_query(dht, "ping", ks_dht2_process_query_ping);
ks_dht2_register_query(dht, "find_node", ks_dht2_process_query_findnode);
ks_hash_create(&dht->registry_error, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, dht->pool); ks_hash_create(&dht->registry_error, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, dht->pool);
// @todo register 301 error for internal get/put CAS hash mismatch retry handler // @todo register 301 error for internal get/put CAS hash mismatch retry handler
...@@ -91,6 +92,8 @@ KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const ks_dht2_nodeid_raw_t ...@@ -91,6 +92,8 @@ KS_DECLARE(ks_status_t) ks_dht2_init(ks_dht2_t *dht, const ks_dht2_nodeid_raw_t
ks_hash_create(&dht->endpoints_hash, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK, dht->pool); ks_hash_create(&dht->endpoints_hash, KS_HASH_MODE_DEFAULT, KS_HASH_FLAG_RWLOCK, dht->pool);
dht->endpoints_poll = NULL; dht->endpoints_poll = NULL;
ks_q_create(&dht->send_q, dht->pool, 0);
dht->send_q_unsent = NULL;
dht->recv_buffer_length = 0; dht->recv_buffer_length = 0;
dht->transactionid_next = 1; //rand(); dht->transactionid_next = 1; //rand();
...@@ -112,6 +115,20 @@ KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht) ...@@ -112,6 +115,20 @@ KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht)
dht->transactions_hash = NULL; dht->transactions_hash = NULL;
} }
dht->recv_buffer_length = 0; dht->recv_buffer_length = 0;
if (dht->send_q) {
ks_dht2_message_t *msg;
while (ks_q_pop_timeout(dht->send_q, (void **)&msg, 1) == KS_STATUS_SUCCESS && msg) {
ks_dht2_message_deinit(msg);
ks_dht2_message_free(msg);
}
ks_q_destroy(&dht->send_q);
dht->send_q = NULL;
}
if (dht->send_q_unsent) {
ks_dht2_message_deinit(dht->send_q_unsent);
ks_dht2_message_free(dht->send_q_unsent);
dht->send_q_unsent = NULL;
}
for (int32_t i = 0; i < dht->endpoints_size; ++i) { for (int32_t i = 0; i < dht->endpoints_size; ++i) {
ks_dht2_endpoint_t *ep = dht->endpoints[i]; ks_dht2_endpoint_t *ep = dht->endpoints[i];
ks_dht2_endpoint_deinit(ep); ks_dht2_endpoint_deinit(ep);
...@@ -280,7 +297,7 @@ KS_DECLARE(ks_status_t) ks_dht2_bind(ks_dht2_t *dht, const ks_sockaddr_t *addr, ...@@ -280,7 +297,7 @@ 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_DECLARE(void) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
{ {
int32_t result; int32_t result;
...@@ -294,15 +311,7 @@ KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout) ...@@ -294,15 +311,7 @@ KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
} }
result = ks_poll(dht->endpoints_poll, dht->endpoints_size, timeout); result = ks_poll(dht->endpoints_poll, dht->endpoints_size, timeout);
if (result < 0) { 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) { for (int32_t i = 0; i < dht->endpoints_size; ++i) {
if (dht->endpoints_poll[i].revents & POLLIN) { if (dht->endpoints_poll[i].revents & POLLIN) {
ks_sockaddr_t raddr = KS_SA_INIT; ks_sockaddr_t raddr = KS_SA_INIT;
...@@ -314,10 +323,9 @@ KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout) ...@@ -314,10 +323,9 @@ KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout)
} }
} }
} }
}
ks_dht2_idle(dht); ks_dht2_idle(dht);
return KS_STATUS_SUCCESS;
} }
/** /**
...@@ -333,21 +341,19 @@ KS_DECLARE(ks_status_t) ks_dht2_maketid(ks_dht2_t *dht) ...@@ -333,21 +341,19 @@ KS_DECLARE(ks_status_t) ks_dht2_maketid(ks_dht2_t *dht)
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_idle(ks_dht2_t *dht) KS_DECLARE(void) ks_dht2_idle(ks_dht2_t *dht)
{ {
ks_assert(dht); ks_assert(dht);
if (ks_dht2_idle_expirations(dht) != KS_STATUS_SUCCESS) { ks_dht2_idle_expirations(dht);
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS; ks_dht2_idle_send(dht);
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_idle_expirations(ks_dht2_t *dht) KS_DECLARE(void) ks_dht2_idle_expirations(ks_dht2_t *dht)
{ {
ks_hash_iterator_t *it = NULL; ks_hash_iterator_t *it = NULL;
ks_time_t now = ks_time_now_sec(); ks_time_t now = ks_time_now_sec();
...@@ -375,58 +381,44 @@ KS_DECLARE(ks_status_t) ks_dht2_idle_expirations(ks_dht2_t *dht) ...@@ -375,58 +381,44 @@ KS_DECLARE(ks_status_t) ks_dht2_idle_expirations(ks_dht2_t *dht)
} }
} }
ks_hash_write_unlock(dht->transactions_hash); ks_hash_write_unlock(dht->transactions_hash);
return KS_STATUS_SUCCESS;
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr) KS_DECLARE(void) ks_dht2_idle_send(ks_dht2_t *dht)
{ {
ks_dht2_message_t message; ks_dht2_message_t *message;
ks_dht2_message_callback_t callback; ks_bool_t bail = KS_FALSE;
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_log(KS_LOG_DEBUG, "Received message from %s %d\n", raddr->host, raddr->port); while (!bail) {
if (raddr->family != AF_INET && raddr->family != AF_INET6) { message = NULL;
ks_log(KS_LOG_DEBUG, "Message from unsupported address family\n"); if (dht->send_q_unsent) {
return KS_STATUS_FAIL; message = dht->send_q_unsent;
dht->send_q_unsent = NULL;
} }
if (!message) {
// @todo blacklist check for bad actor nodes bail = ks_q_pop_timeout(dht->send_q, (void **)&message, 1) != KS_STATUS_SUCCESS || !message;
if (ks_dht2_message_prealloc(&message, dht->pool) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
} }
if (!bail) {
if (ks_dht2_message_init(&message, KS_FALSE) != KS_STATUS_SUCCESS) { bail = (ret = ks_dht2_send(dht, message)) != KS_STATUS_SUCCESS;
return KS_STATUS_FAIL; if (ret == KS_STATUS_BREAK) {
dht->send_q_unsent = message;
} else if (ret == KS_STATUS_SUCCESS) {
ks_dht2_message_deinit(message);
ks_dht2_message_free(message);
} }
if (ks_dht2_message_parse(&message, dht->recv_buffer, dht->recv_buffer_length) != KS_STATUS_SUCCESS) {
goto done;
} }
if (!(callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_type, message.type, KS_UNLOCKED))) {
ks_log(KS_LOG_DEBUG, "Message type '%s' is not registered\n", message.type);
} else {
ret = callback(dht, raddr, &message);
} }
done:
ks_dht2_message_deinit(&message);
return ret;
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
// @todo lookup standard def for IPV6 max size // @todo lookup standard def for IPV6 max size
char ip[48]; char ip[48];
...@@ -436,38 +428,32 @@ KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dh ...@@ -436,38 +428,32 @@ KS_DECLARE(ks_status_t) ks_dht2_send(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dh
ks_size_t buf_len; ks_size_t buf_len;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
ks_assert(message->data); ks_assert(message->data);
// @todo blacklist check // @todo blacklist check
ks_ip_route(ip, sizeof(ip), raddr->host); ks_ip_route(ip, sizeof(ip), message->raddr.host);
if (!(ep = ks_hash_search(dht->endpoints_hash, ip, KS_UNLOCKED)) && dht->autoroute) { if (!(ep = ks_hash_search(dht->endpoints_hash, ip, KS_UNLOCKED)) && dht->autoroute) {
ks_sockaddr_t addr; ks_sockaddr_t addr;
ks_addr_set(&addr, ip, dht->autoroute_port, raddr->family); ks_addr_set(&addr, ip, dht->autoroute_port, message->raddr.family);
if (ks_dht2_bind(dht, &addr, &ep) != KS_STATUS_SUCCESS) { if (ks_dht2_bind(dht, &addr, &ep) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL; return KS_STATUS_FAIL;
} }
} }
if (!ep) { if (!ep) {
ks_log(KS_LOG_DEBUG, "No route available to %s\n", raddr->host); ks_log(KS_LOG_DEBUG, "No route available to %s\n", message->raddr.host);
return KS_STATUS_FAIL; return KS_STATUS_FAIL;
} }
buf_len = ben_encode2(buf, sizeof(buf), message->data); buf_len = ben_encode2(buf, sizeof(buf), message->data);
ks_log(KS_LOG_DEBUG, "Sending message to %s %d\n", raddr->host, raddr->port); ks_log(KS_LOG_DEBUG, "Sending message to %s %d\n", message->raddr.host, message->raddr.port);
ks_log(KS_LOG_DEBUG, "%s\n", ben_print(message->data)); ks_log(KS_LOG_DEBUG, "%s\n", ben_print(message->data));
if (ks_socket_sendto(ep->sock, (void *)buf, &buf_len, raddr) != KS_STATUS_SUCCESS) { return ks_socket_sendto(ep->sock, (void *)buf, &buf_len, &message->raddr);
ks_log(KS_LOG_DEBUG, "Socket error\n");
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
} }
/** /**
...@@ -480,8 +466,8 @@ KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht, ...@@ -480,8 +466,8 @@ KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht,
long long errorcode, long long errorcode,
const char *errorstr) const char *errorstr)
{ {
ks_dht2_message_t error; ks_dht2_message_t *error = NULL;
struct bencode *e; struct bencode *e = NULL;
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
...@@ -489,34 +475,198 @@ KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht, ...@@ -489,34 +475,198 @@ KS_DECLARE(ks_status_t) ks_dht2_send_error(ks_dht2_t *dht,
ks_assert(transactionid); ks_assert(transactionid);
ks_assert(errorstr); ks_assert(errorstr);
if (ks_dht2_message_prealloc(&error, dht->pool) != KS_STATUS_SUCCESS) { if (ks_dht2_message_alloc(&error, dht->pool) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL; return KS_STATUS_FAIL;
} }
if (ks_dht2_message_init(&error, KS_TRUE) != KS_STATUS_SUCCESS) { if (ks_dht2_message_init(error, raddr, KS_TRUE) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL; goto done;
} }
if (ks_dht2_message_error(&error, transactionid, transactionid_length, &e) != KS_STATUS_SUCCESS) { if (ks_dht2_message_error(error, transactionid, transactionid_length, &e) != KS_STATUS_SUCCESS) {
goto done; goto done;
} }
// @note e joins response.data and will be freed with it
ben_list_append(e, ben_int(errorcode)); ben_list_append(e, ben_int(errorcode));
ben_list_append(e, ben_blob(errorstr, strlen(errorstr))); ben_list_append(e, ben_blob(errorstr, strlen(errorstr)));
ks_log(KS_LOG_DEBUG, "Sending message error %d\n", errorcode); ks_log(KS_LOG_DEBUG, "Sending message error %d\n", errorcode);
ret = ks_dht2_send(dht, raddr, &error); ks_q_push(dht->send_q, (void *)error);
ret = KS_STATUS_SUCCESS;
done: done:
ks_dht2_message_deinit(&error); if (ret != KS_STATUS_SUCCESS && error) {
ks_dht2_message_deinit(error);
ks_dht2_message_free(error);
}
return ret; return ret;
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_setup_query(ks_dht2_t *dht,
ks_sockaddr_t *raddr,
const char *query,
ks_dht2_message_callback_t callback,
ks_dht2_message_t **message,
struct bencode **args)
{
uint32_t transactionid;
ks_dht2_transaction_t *trans = NULL;
ks_dht2_message_t *msg = NULL;
ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht);
ks_assert(raddr);
ks_assert(query);
ks_assert(callback);
ks_assert(message);
*message = NULL;
// @todo atomic increment or mutex
transactionid = dht->transactionid_next++;
if (ks_dht2_transaction_alloc(&trans, dht->pool) != KS_STATUS_SUCCESS) {
goto done;
}
if (ks_dht2_transaction_init(trans, raddr, transactionid, callback) != KS_STATUS_SUCCESS) {
goto done;
}
if (ks_dht2_message_alloc(&msg, dht->pool) != KS_STATUS_SUCCESS) {
goto done;
}
if (ks_dht2_message_init(msg, raddr, KS_TRUE) != KS_STATUS_SUCCESS) {
goto done;
}
if (ks_dht2_message_query(msg, transactionid, query, args) != KS_STATUS_SUCCESS) {
goto done;
}
*message = msg;
ks_hash_insert(dht->transactions_hash, (void *)&trans->transactionid, trans);
ret = KS_STATUS_SUCCESS;
done:
if (ret != KS_STATUS_SUCCESS) {
if (trans) {
ks_dht2_transaction_deinit(trans);
ks_dht2_transaction_free(trans);
}
if (msg) {
ks_dht2_message_deinit(msg);
ks_dht2_message_free(msg);
}
*message = NULL;
}
return ret;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_send_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr)
{
ks_dht2_message_t *message = NULL;
struct bencode *a = NULL;
ks_assert(dht);
ks_assert(raddr);
if (ks_dht2_setup_query(dht, raddr, "ping", ks_dht2_process_response_ping, &message, &a) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
}
ben_dict_set(a, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
ks_log(KS_LOG_DEBUG, "Sending message query ping\n");
ks_q_push(dht->send_q, (void *)message);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_send_findnode(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_nodeid_raw_t *targetid)
{
ks_dht2_message_t *message = NULL;
struct bencode *a = NULL;
ks_assert(dht);
ks_assert(raddr);
ks_assert(targetid);
if (ks_dht2_setup_query(dht, raddr, "find_node", ks_dht2_process_response_findnode, &message, &a) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
}
ben_dict_set(a, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
ben_dict_set(a, ben_blob("target", 6), ben_blob(targetid->id, KS_DHT_NODEID_LENGTH));
ks_log(KS_LOG_DEBUG, "Sending message query find_node\n");
ks_q_push(dht->send_q, (void *)message);
//ks_dht2_send(dht, raddr, message);
return KS_STATUS_SUCCESS;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_process(ks_dht2_t *dht, ks_sockaddr_t *raddr)
{
ks_dht2_message_t message;
ks_dht2_message_callback_t callback;
ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht);
ks_assert(raddr);
ks_log(KS_LOG_DEBUG, "Received message from %s %d\n", raddr->host, raddr->port);
if (raddr->family != AF_INET && raddr->family != AF_INET6) {
ks_log(KS_LOG_DEBUG, "Message from unsupported address family\n");
return KS_STATUS_FAIL;
}
// @todo blacklist check for bad actor nodes
if (ks_dht2_message_prealloc(&message, dht->pool) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
}
if (ks_dht2_message_init(&message, raddr, KS_FALSE) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL;
}
if (ks_dht2_message_parse(&message, dht->recv_buffer, dht->recv_buffer_length) != KS_STATUS_SUCCESS) {
goto done;
}
if (!(callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_type, message.type, KS_UNLOCKED))) {
ks_log(KS_LOG_DEBUG, "Message type '%s' is not registered\n", message.type);
} else {
ret = callback(dht, &message);
}
done:
ks_dht2_message_deinit(&message);
return ret;
}
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
struct bencode *q; struct bencode *q;
struct bencode *a; struct bencode *a;
...@@ -527,7 +677,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -527,7 +677,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
// @todo start of ks_dht2_message_parse_query // @todo start of ks_dht2_message_parse_query
...@@ -560,7 +709,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -560,7 +709,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad
if (!(callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_query, query, KS_UNLOCKED))) { if (!(callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_query, query, KS_UNLOCKED))) {
ks_log(KS_LOG_DEBUG, "Message query '%s' is not registered\n", query); ks_log(KS_LOG_DEBUG, "Message query '%s' is not registered\n", query);
} else { } else {
ret = callback(dht, raddr, message); ret = callback(dht, message);
} }
return ret; return ret;
...@@ -569,7 +718,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -569,7 +718,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query(ks_dht2_t *dht, ks_sockaddr_t *rad
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
struct bencode *r; struct bencode *r;
ks_dht2_transaction_t *transaction; ks_dht2_transaction_t *transaction;
...@@ -578,7 +727,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t * ...@@ -578,7 +727,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t *
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
// @todo start of ks_dht2_message_parse_response // @todo start of ks_dht2_message_parse_response
...@@ -599,17 +747,17 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t * ...@@ -599,17 +747,17 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t *
if (!transaction) { if (!transaction) {
ks_log(KS_LOG_DEBUG, "Message response rejected with unknown transaction id %d\n", transactionid); ks_log(KS_LOG_DEBUG, "Message response rejected with unknown transaction id %d\n", transactionid);
} else if (!ks_addr_cmp(raddr, &transaction->raddr)) { } else if (!ks_addr_cmp(&message->raddr, &transaction->raddr)) {
ks_log(KS_LOG_DEBUG, ks_log(KS_LOG_DEBUG,
"Message response rejected due to spoofing from %s %d, expected %s %d\n", "Message response rejected due to spoofing from %s %d, expected %s %d\n",
raddr->host, message->raddr.host,
raddr->port, message->raddr.port,
transaction->raddr.host, transaction->raddr.host,
transaction->raddr.port); transaction->raddr.port);
} else { } else {
// @todo mark transaction for later removal // @todo mark transaction for later removal
transaction->finished = KS_TRUE; transaction->finished = KS_TRUE;
ret = transaction->callback(dht, raddr, message); ret = transaction->callback(dht, message);
} }
return ret; return ret;
...@@ -618,7 +766,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t * ...@@ -618,7 +766,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_response(ks_dht2_t *dht, ks_sockaddr_t *
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
struct bencode *e; struct bencode *e;
struct bencode *ec; struct bencode *ec;
...@@ -633,7 +781,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -633,7 +781,6 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
// @todo start of ks_dht2_message_parse_error // @todo start of ks_dht2_message_parse_error
...@@ -666,11 +813,11 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -666,11 +813,11 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad
if (!transaction) { if (!transaction) {
ks_log(KS_LOG_DEBUG, "Message error rejected with unknown transaction id %d\n", transactionid); ks_log(KS_LOG_DEBUG, "Message error rejected with unknown transaction id %d\n", transactionid);
} else if (!ks_addr_cmp(raddr, &transaction->raddr)) { } else if (!ks_addr_cmp(&message->raddr, &transaction->raddr)) {
ks_log(KS_LOG_DEBUG, ks_log(KS_LOG_DEBUG,
"Message error rejected due to spoofing from %s %d, expected %s %d\n", "Message error rejected due to spoofing from %s %d, expected %s %d\n",
raddr->host, message->raddr.host,
raddr->port, message->raddr.port,
transaction->raddr.host, transaction->raddr.host,
transaction->raddr.port); transaction->raddr.port);
} else { } else {
...@@ -679,7 +826,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -679,7 +826,7 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad
transaction->finished = KS_TRUE; transaction->finished = KS_TRUE;
if ((callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_error, error, KS_UNLOCKED))) { if ((callback = (ks_dht2_message_callback_t)(intptr_t)ks_hash_search(dht->registry_error, error, KS_UNLOCKED))) {
ret = callback(dht, raddr, message); ret = callback(dht, message);
} else { } else {
ks_log(KS_LOG_DEBUG, "Message error received for transaction id %d, error %d: %s\n", transactionid, errorcode, error); ks_log(KS_LOG_DEBUG, "Message error received for transaction id %d, error %d: %s\n", transactionid, errorcode, error);
ret = KS_STATUS_SUCCESS; ret = KS_STATUS_SUCCESS;
...@@ -692,16 +839,16 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad ...@@ -692,16 +839,16 @@ KS_DECLARE(ks_status_t) ks_dht2_process_error(ks_dht2_t *dht, ks_sockaddr_t *rad
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
struct bencode *id; struct bencode *id;
const char *idv; //const char *idv;
ks_size_t idv_len; ks_size_t idv_len;
ks_dht2_nodeid_t nid; ks_dht2_message_t *response = NULL;
struct bencode *r = NULL;
ks_status_t ret = KS_STATUS_FAIL; ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
ks_assert(message->args); ks_assert(message->args);
...@@ -711,137 +858,149 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_sockaddr_t ...@@ -711,137 +858,149 @@ KS_DECLARE(ks_status_t) ks_dht2_process_query_ping(ks_dht2_t *dht, ks_sockaddr_t
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;
} }
if (ks_dht2_nodeid_prealloc(&nid, dht->pool) != KS_STATUS_SUCCESS) { // @todo add/touch bucket entry for remote node
return KS_STATUS_FAIL;
ks_log(KS_LOG_DEBUG, "Message query ping is valid\n");
if (ks_dht2_message_alloc(&response, dht->pool) != KS_STATUS_SUCCESS) {
goto done;
} }
if (ks_dht2_nodeid_init(&nid, (const ks_dht2_nodeid_raw_t *)idv) != KS_STATUS_SUCCESS) { if (ks_dht2_message_init(response, &message->raddr, KS_TRUE) != KS_STATUS_SUCCESS) {
return KS_STATUS_FAIL; goto done;
} }
ks_log(KS_LOG_DEBUG, "Message query ping is valid\n"); if (ks_dht2_message_response(response, message->transactionid, message->transactionid_length, &r) != KS_STATUS_SUCCESS) {
goto done;
}
ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
ret = ks_dht2_send_response_ping(dht, raddr, message->transactionid, message->transactionid_length); ks_log(KS_LOG_DEBUG, "Sending message response ping\n");
ks_q_push(dht->send_q, (void *)response);
ks_dht2_nodeid_deinit(&nid); ret = KS_STATUS_SUCCESS;
done:
if (ret != KS_STATUS_SUCCESS && response) {
ks_dht2_message_deinit(response);
ks_dht2_message_free(response);
}
return ret; return ret;
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_process_response_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) KS_DECLARE(ks_status_t) ks_dht2_process_query_findnode(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
struct bencode *id;
struct bencode *target;
//const char *idv;
//const char *targetv;
ks_size_t idv_len;
ks_size_t targetv_len;
ks_dht2_message_t *response = NULL;
struct bencode *r = NULL;
ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr);
ks_assert(message); ks_assert(message);
ks_assert(message->args);
ks_log(KS_LOG_DEBUG, "Message response ping is reached\n"); id = ben_dict_get_by_str(message->args, "id");
if (!id) {
ks_log(KS_LOG_DEBUG, "Message args missing required key 'id'\n");
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS; //idv = ben_str_val(id);
} idv_len = ben_str_len(id);
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);
return KS_STATUS_FAIL;
}
/** target = ben_dict_get_by_str(message->args, "target");
* if (!target) {
*/ ks_log(KS_LOG_DEBUG, "Message args missing required key 'target'\n");
KS_DECLARE(ks_status_t) ks_dht2_send_query_ping(ks_dht2_t *dht, ks_sockaddr_t *raddr) return KS_STATUS_FAIL;
{ }
uint32_t transactionid;
ks_dht2_transaction_t *transaction = NULL;
ks_dht2_message_t query;
struct bencode *a;
ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); //targetv = ben_str_val(target);
ks_assert(raddr); targetv_len = ben_str_len(target);
if (targetv_len != KS_DHT_NODEID_LENGTH) {
ks_log(KS_LOG_DEBUG, "Message args 'target' value has an unexpected size of %d\n", targetv_len);
return KS_STATUS_FAIL;
}
// @todo atomic increment or mutex...
transactionid = dht->transactionid_next++;
if (ks_dht2_transaction_alloc(&transaction, dht->pool) != KS_STATUS_SUCCESS) { ks_log(KS_LOG_DEBUG, "Message query find_node is valid\n");
goto done;
}
if (ks_dht2_transaction_init(transaction, raddr, transactionid, ks_dht2_process_response_ping) != KS_STATUS_SUCCESS) {
goto done;
}
if (ks_dht2_message_prealloc(&query, dht->pool) != KS_STATUS_SUCCESS) { if (ks_dht2_message_alloc(&response, dht->pool) != KS_STATUS_SUCCESS) {
goto done; goto done;
} }
if (ks_dht2_message_init(&query, KS_TRUE) != KS_STATUS_SUCCESS) { if (ks_dht2_message_init(response, &message->raddr, KS_TRUE) != KS_STATUS_SUCCESS) {
goto done; goto done;
} }
if (ks_dht2_message_query(&query, transactionid, "ping", &a) != KS_STATUS_SUCCESS) { if (ks_dht2_message_response(response, message->transactionid, message->transactionid_length, &r) != KS_STATUS_SUCCESS) {
goto done; goto done;
} }
// @todo transaction expiration and raddr for validation ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH));
ks_hash_insert(dht->transactions_hash, (void *)&transaction->transactionid, transaction);
// @note a joins response.data and will be freed with it ks_log(KS_LOG_DEBUG, "Sending message response find_node\n");
ben_dict_set(a, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH)); ks_q_push(dht->send_q, (void *)response);
ks_log(KS_LOG_DEBUG, "Sending message query ping with transaction id %d\n", transactionid); ret = KS_STATUS_SUCCESS;
ret = ks_dht2_send(dht, raddr, &query);
done: done:
if (transaction && ret != KS_STATUS_SUCCESS) { if (ret != KS_STATUS_SUCCESS && response) {
ks_dht2_transaction_deinit(transaction); ks_dht2_message_deinit(response);
ks_dht2_transaction_free(transaction); ks_dht2_message_free(response);
} }
ks_dht2_message_deinit(&query);
return ret; return ret;
} }
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_send_response_ping(ks_dht2_t *dht, KS_DECLARE(ks_status_t) ks_dht2_process_response_ping(ks_dht2_t *dht, ks_dht2_message_t *message)
ks_sockaddr_t *raddr,
uint8_t *transactionid,
ks_size_t transactionid_length)
{ {
ks_dht2_message_t response;
struct bencode *r;
ks_status_t ret = KS_STATUS_FAIL;
ks_assert(dht); ks_assert(dht);
ks_assert(raddr); ks_assert(message);
ks_assert(transactionid);
if (ks_dht2_message_prealloc(&response, dht->pool) != KS_STATUS_SUCCESS) { // @todo add/touch bucket entry for remote node
return KS_STATUS_FAIL;
}
if (ks_dht2_message_init(&response, KS_TRUE) != KS_STATUS_SUCCESS) { ks_log(KS_LOG_DEBUG, "Message response ping is reached\n");
return KS_STATUS_FAIL;
}
if (ks_dht2_message_response(&response, transactionid, transactionid_length, &r) != KS_STATUS_SUCCESS) { return KS_STATUS_SUCCESS;
goto done; }
}
// @note r joins response.data and will be freed with it /**
ben_dict_set(r, ben_blob("id", 2), ben_blob(dht->nodeid.id, KS_DHT_NODEID_LENGTH)); *
*/
KS_DECLARE(ks_status_t) ks_dht2_process_response_findnode(ks_dht2_t *dht, ks_dht2_message_t *message)
{
ks_assert(dht);
ks_assert(message);
ks_log(KS_LOG_DEBUG, "Sending message response ping\n"); // @todo add/touch bucket entry for remote node and other nodes returned
ret = ks_dht2_send(dht, raddr, &response);
done: ks_log(KS_LOG_DEBUG, "Message response find_node is reached\n");
ks_dht2_message_deinit(&response);
return ret; return KS_STATUS_SUCCESS;
} }
/* For Emacs: /* For Emacs:
......
...@@ -28,7 +28,7 @@ typedef struct ks_dht2_endpoint_s ks_dht2_endpoint_t; ...@@ -28,7 +28,7 @@ typedef struct ks_dht2_endpoint_s ks_dht2_endpoint_t;
typedef struct ks_dht2_transaction_s ks_dht2_transaction_t; typedef struct ks_dht2_transaction_s ks_dht2_transaction_t;
typedef ks_status_t (*ks_dht2_message_callback_t)(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message); typedef ks_status_t (*ks_dht2_message_callback_t)(ks_dht2_t *dht, ks_dht2_message_t *message);
struct ks_dht2_nodeid_raw_s { struct ks_dht2_nodeid_raw_s {
uint8_t id[KS_DHT_NODEID_LENGTH]; uint8_t id[KS_DHT_NODEID_LENGTH];
...@@ -41,6 +41,7 @@ struct ks_dht2_nodeid_s { ...@@ -41,6 +41,7 @@ struct ks_dht2_nodeid_s {
struct ks_dht2_message_s { struct ks_dht2_message_s {
ks_pool_t *pool; ks_pool_t *pool;
ks_sockaddr_t raddr;
struct bencode *data; struct bencode *data;
uint8_t transactionid[KS_DHT_MESSAGE_TRANSACTIONID_MAX_SIZE]; uint8_t transactionid[KS_DHT_MESSAGE_TRANSACTIONID_MAX_SIZE];
ks_size_t transactionid_length; ks_size_t transactionid_length;
...@@ -85,6 +86,8 @@ struct ks_dht2_s { ...@@ -85,6 +86,8 @@ struct ks_dht2_s {
ks_hash_t *endpoints_hash; ks_hash_t *endpoints_hash;
struct pollfd *endpoints_poll; struct pollfd *endpoints_poll;
ks_q_t *send_q;
ks_dht2_message_t *send_q_unsent;
uint8_t recv_buffer[KS_DHT_RECV_BUFFER_SIZE]; uint8_t recv_buffer[KS_DHT_RECV_BUFFER_SIZE];
ks_size_t recv_buffer_length; ks_size_t recv_buffer_length;
...@@ -106,7 +109,7 @@ KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht); ...@@ -106,7 +109,7 @@ KS_DECLARE(ks_status_t) ks_dht2_deinit(ks_dht2_t *dht);
KS_DECLARE(ks_status_t) ks_dht2_autoroute(ks_dht2_t *dht, ks_bool_t autoroute, ks_port_t port); KS_DECLARE(ks_status_t) ks_dht2_autoroute(ks_dht2_t *dht, ks_bool_t autoroute, ks_port_t port);
KS_DECLARE(ks_status_t) ks_dht2_bind(ks_dht2_t *dht, const ks_sockaddr_t *addr, ks_dht2_endpoint_t **endpoint); KS_DECLARE(ks_status_t) ks_dht2_bind(ks_dht2_t *dht, const ks_sockaddr_t *addr, ks_dht2_endpoint_t **endpoint);
KS_DECLARE(ks_status_t) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout); KS_DECLARE(void) ks_dht2_pulse(ks_dht2_t *dht, int32_t timeout);
KS_DECLARE(ks_status_t) ks_dht2_register_type(ks_dht2_t *dht, const char *value, ks_dht2_message_callback_t callback); KS_DECLARE(ks_status_t) ks_dht2_register_type(ks_dht2_t *dht, const char *value, ks_dht2_message_callback_t callback);
...@@ -129,7 +132,7 @@ KS_DECLARE(ks_status_t) ks_dht2_message_alloc(ks_dht2_message_t **message, ks_po ...@@ -129,7 +132,7 @@ KS_DECLARE(ks_status_t) ks_dht2_message_alloc(ks_dht2_message_t **message, ks_po
KS_DECLARE(ks_status_t) ks_dht2_message_prealloc(ks_dht2_message_t *message, ks_pool_t *pool); KS_DECLARE(ks_status_t) ks_dht2_message_prealloc(ks_dht2_message_t *message, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_dht2_message_free(ks_dht2_message_t *message); KS_DECLARE(ks_status_t) ks_dht2_message_free(ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_message_init(ks_dht2_message_t *message, ks_bool_t alloc_data); KS_DECLARE(ks_status_t) ks_dht2_message_init(ks_dht2_message_t *message, ks_sockaddr_t *raddr, ks_bool_t alloc_data);
KS_DECLARE(ks_status_t) ks_dht2_message_deinit(ks_dht2_message_t *message); KS_DECLARE(ks_status_t) ks_dht2_message_deinit(ks_dht2_message_t *message);
KS_DECLARE(ks_status_t) ks_dht2_message_parse(ks_dht2_message_t *message, const uint8_t *buffer, ks_size_t buffer_length); KS_DECLARE(ks_status_t) ks_dht2_message_parse(ks_dht2_message_t *message, const uint8_t *buffer, ks_size_t buffer_length);
......
...@@ -47,11 +47,12 @@ KS_DECLARE(ks_status_t) ks_dht2_message_free(ks_dht2_message_t *message) ...@@ -47,11 +47,12 @@ KS_DECLARE(ks_status_t) ks_dht2_message_free(ks_dht2_message_t *message)
/** /**
* *
*/ */
KS_DECLARE(ks_status_t) ks_dht2_message_init(ks_dht2_message_t *message, ks_bool_t alloc_data) KS_DECLARE(ks_status_t) ks_dht2_message_init(ks_dht2_message_t *message, ks_sockaddr_t *raddr, ks_bool_t alloc_data)
{ {
ks_assert(message); ks_assert(message);
ks_assert(message->pool); ks_assert(message->pool);
message->raddr = *raddr;
message->data = NULL; message->data = NULL;
message->args = NULL; message->args = NULL;
message->transactionid_length = 0; message->transactionid_length = 0;
...@@ -70,6 +71,7 @@ KS_DECLARE(ks_status_t) ks_dht2_message_deinit(ks_dht2_message_t *message) ...@@ -70,6 +71,7 @@ KS_DECLARE(ks_status_t) ks_dht2_message_deinit(ks_dht2_message_t *message)
{ {
ks_assert(message); ks_assert(message);
message->raddr = (const ks_sockaddr_t){ 0 };
message->args = NULL; message->args = NULL;
message->type[0] = '\0'; message->type[0] = '\0';
message->transactionid_length = 0; message->transactionid_length = 0;
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
#define TEST_DHT1_REGISTER_TYPE_BUFFER "d1:ad2:id20:12345678901234567890e1:q4:ping1:t2:421:y1:ze" #define TEST_DHT1_REGISTER_TYPE_BUFFER "d1:ad2:id20:12345678901234567890e1:q4:ping1:t2:421:y1:ze"
#define TEST_DHT1_PROCESS_QUERY_PING_BUFFER "d1:ad2:id20:12345678901234567890e1:q4:ping1:t2:421:y1:qe" #define TEST_DHT1_PROCESS_QUERY_PING_BUFFER "d1:ad2:id20:12345678901234567890e1:q4:ping1:t2:421:y1:qe"
ks_status_t dht_z_callback(ks_dht2_t *dht, ks_sockaddr_t *raddr, ks_dht2_message_t *message) ks_status_t dht_z_callback(ks_dht2_t *dht, ks_dht2_message_t *message)
{ {
diag("dht_z_callback\n"); diag("dht_z_callback\n");
ok(message->transactionid[0] == '4' && message->transactionid[1] == '2'); ok(message->transactionid[0] == '4' && message->transactionid[1] == '2');
ks_dht2_send_error(dht, raddr, message->transactionid, message->transactionid_length, 201, "Generic test error"); ks_dht2_send_error(dht, &message->raddr, message->transactionid, message->transactionid_length, 201, "Generic test error");
return KS_STATUS_SUCCESS; return KS_STATUS_SUCCESS;
} }
...@@ -91,6 +91,8 @@ int main() { ...@@ -91,6 +91,8 @@ int main() {
ok(err == KS_STATUS_SUCCESS); ok(err == KS_STATUS_SUCCESS);
} }
diag("Custom type tests\n");
buflen = strlen(TEST_DHT1_REGISTER_TYPE_BUFFER); buflen = strlen(TEST_DHT1_REGISTER_TYPE_BUFFER);
memcpy(dht1->recv_buffer, TEST_DHT1_REGISTER_TYPE_BUFFER, buflen); memcpy(dht1->recv_buffer, TEST_DHT1_REGISTER_TYPE_BUFFER, buflen);
dht1->recv_buffer_length = buflen; dht1->recv_buffer_length = buflen;
...@@ -98,8 +100,10 @@ int main() { ...@@ -98,8 +100,10 @@ int main() {
err = ks_dht2_process(dht1, &raddr); err = ks_dht2_process(dht1, &raddr);
ok(err == KS_STATUS_SUCCESS); ok(err == KS_STATUS_SUCCESS);
err = ks_dht2_pulse(&dht2, 1000); ks_dht2_pulse(dht1, 100);
ok(err == KS_STATUS_SUCCESS);
ks_dht2_pulse(&dht2, 100);
//buflen = strlen(TEST_DHT1_PROCESS_QUERY_PING_BUFFER); //buflen = strlen(TEST_DHT1_PROCESS_QUERY_PING_BUFFER);
//memcpy(dht1->recv_buffer, TEST_DHT1_PROCESS_QUERY_PING_BUFFER, buflen); //memcpy(dht1->recv_buffer, TEST_DHT1_PROCESS_QUERY_PING_BUFFER, buflen);
...@@ -108,14 +112,17 @@ int main() { ...@@ -108,14 +112,17 @@ int main() {
//err = ks_dht2_process(dht1, &raddr); //err = ks_dht2_process(dht1, &raddr);
//ok(err == KS_STATUS_SUCCESS); //ok(err == KS_STATUS_SUCCESS);
err = ks_dht2_send_query_ping(dht1, &raddr);
ok(err == KS_STATUS_SUCCESS);
err = ks_dht2_pulse(&dht2, 1000); diag("Ping tests\n");
ok(err == KS_STATUS_SUCCESS);
ks_dht2_send_ping(dht1, &raddr);
ks_dht2_pulse(dht1, 100);
ks_dht2_pulse(&dht2, 100);
ks_dht2_pulse(dht1, 100);
err = ks_dht2_pulse(dht1, 1000);
ok(err == KS_STATUS_SUCCESS);
diag("Cleanup\n"); diag("Cleanup\n");
/* Cleanup and shutdown */ /* Cleanup and shutdown */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论