448 lines
18 KiB
C
448 lines
18 KiB
C
#ifndef KS_DHT_INT_H
|
|
#define KS_DHT_INT_H
|
|
|
|
#include "ks.h"
|
|
|
|
KS_BEGIN_EXTERN_C
|
|
|
|
/**
|
|
* Determines the appropriate endpoint to reach a remote address.
|
|
* If an endpoint is provided, nothing more needs to be done.
|
|
* If no endpoint is provided, first it will check for an active endpoint it can route though.
|
|
* If no active endpoint is available and autorouting is enabled it will attempt to bind a usable endpoint.
|
|
* @param dht pointer to the dht instance
|
|
* @param raddr pointer to the remote address
|
|
* @param endpoint dereferenced in/out pointer to the endpoint, if populated then returns immediately
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
|
|
* @see ks_ip_route
|
|
* @see ks_hash_read_unlock
|
|
* @see ks_addr_set
|
|
* @see ks_dht_bind
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_autoroute_check(ks_dht_t *dht, const ks_sockaddr_t *raddr, ks_dht_endpoint_t **endpoint);
|
|
|
|
/**
|
|
* Called internally to receive datagrams from endpoints.
|
|
* Handles datagrams by dispatching each through a threadpool.
|
|
* @param dht pointer to the dht instance
|
|
* @param timeout time in ms to wait for an incoming datagram on any endpoint
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_endpoints(ks_dht_t *dht, int32_t timeout);
|
|
|
|
/**
|
|
* Called internally to expire or reannounce storage item data.
|
|
* Handles reannouncing and purging of expiring storage items.
|
|
* @param dht pointer to the dht instance
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_storageitems(ks_dht_t *dht);
|
|
|
|
/**
|
|
* Called internally to process job state machine.
|
|
* Handles completing and purging of finished jobs.
|
|
* @param dht pointer to the dht instance
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_jobs(ks_dht_t *dht);
|
|
|
|
/**
|
|
* Called internally to send queued messages.
|
|
* Handles throttling of message sending to ensure system buffers are not overloaded and messages are not dropped.
|
|
* @param dht pointer to the dht instance
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_send(ks_dht_t *dht);
|
|
|
|
/**
|
|
* Called internally to expire transactions.
|
|
* Handles purging of expired and finished transactions.
|
|
* @param dht pointer to the dht instance
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_transactions(ks_dht_t *dht);
|
|
|
|
/**
|
|
* Called internally to expire and cycle tokens.
|
|
* Handles cycling new secret entropy for token generation.
|
|
* @param dht pointer to the dht instance
|
|
*/
|
|
KS_DECLARE(void) ks_dht_pulse_tokens(ks_dht_t *dht);
|
|
|
|
/**
|
|
* Converts a ks_dht_nodeid_t into it's hex string representation.
|
|
* @param id pointer to the nodeid
|
|
* @param buffer pointer to the buffer able to contain at least (KS_DHT_NODEID_SIZE * 2) + 1 characters
|
|
* @return The pointer to the front of the populated string buffer
|
|
*/
|
|
KS_DECLARE(char *) ks_dht_hex(const uint8_t *data, char *buffer, ks_size_t len);
|
|
|
|
/**
|
|
* Compacts address information as per the DHT specifications.
|
|
* @param address pointer to the address being compacted from
|
|
* @param buffer pointer to the buffer containing compacted data
|
|
* @param buffer_length pointer to the buffer length consumed
|
|
* @param buffer_size max size of the buffer
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_compact_addressinfo(const ks_sockaddr_t *address,
|
|
uint8_t *buffer,
|
|
ks_size_t *buffer_length,
|
|
ks_size_t buffer_size);
|
|
|
|
/**
|
|
* Expands address information as per the DHT specifications.
|
|
* @param buffer pointer to the buffer containing compacted data
|
|
* @param buffer_length pointer to the buffer length consumed
|
|
* @param buffer_size max size of the buffer
|
|
* @param address pointer to the address being expanded into
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
|
|
* @see ks_addr_set_raw
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_expand_addressinfo(const uint8_t *buffer,
|
|
ks_size_t *buffer_length,
|
|
ks_size_t buffer_size,
|
|
ks_sockaddr_t *address);
|
|
|
|
/**
|
|
* Compacts node information as per the DHT specifications.
|
|
* Compacts address information after the nodeid.
|
|
* @param nodeid pointer to the nodeid being compacted from
|
|
* @param address pointer to the address being compacted from
|
|
* @param buffer pointer to the buffer containing compacted data
|
|
* @param buffer_length pointer to the buffer length consumed
|
|
* @param buffer_size max size of the buffer
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
|
|
* @see ks_dht_utility_compact_addressinfo
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_compact_nodeinfo(const ks_dht_nodeid_t *nodeid,
|
|
const ks_sockaddr_t *address,
|
|
uint8_t *buffer,
|
|
ks_size_t *buffer_length,
|
|
ks_size_t buffer_size);
|
|
|
|
/**
|
|
* Expands address information as per the DHT specifications.
|
|
* Expands compacted address information after the nodeid.
|
|
* @param buffer pointer to the buffer containing compacted data
|
|
* @param buffer_length pointer to the buffer length consumed
|
|
* @param buffer_size max size of the buffer
|
|
* @param address pointer to the address being expanded into
|
|
* @param nodeid pointer to the nodeid being expanded into
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
|
|
* @see ks_dht_utility_expand_addressinfo
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_expand_nodeinfo(const uint8_t *buffer,
|
|
ks_size_t *buffer_length,
|
|
ks_size_t buffer_size,
|
|
ks_dht_nodeid_t *nodeid,
|
|
ks_sockaddr_t *address);
|
|
|
|
/**
|
|
* Extracts a ks_dht_nodeid_t from a bencode dictionary given a string key.
|
|
* @param args pointer to the bencode dictionary
|
|
* @param key string key in the bencode dictionary to extract the value from
|
|
* @param nodeid dereferenced out pointer to the nodeid
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_ARG_INVALID
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_extract_nodeid(struct bencode *args, const char *key, ks_dht_nodeid_t **nodeid);
|
|
|
|
/**
|
|
* Extracts a ks_dht_token_t from a bencode dictionary given a string key.
|
|
* @param args pointer to the bencode dictionary
|
|
* @param key string key in the bencode dictionary to extract the value from
|
|
* @param nodeid dereferenced out pointer to the token
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_ARG_INVALID
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_utility_extract_token(struct bencode *args, const char *key, ks_dht_token_t **token);
|
|
|
|
/**
|
|
* Generates an opaque write token based on a shifting secret value, the remote address and target nodeid of interest.
|
|
* This token ensures that future operations can be verified to the remote peer and target id requested.
|
|
* @param secret rotating secret portion of the token hash
|
|
* @param raddr pointer to the remote address used for the ip and port in the token hash
|
|
* @param target pointer to the nodeid of the target used for the token hash
|
|
* @param token pointer to the output token being generated
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_FAIL
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_token_generate(uint32_t secret, const ks_sockaddr_t *raddr, ks_dht_nodeid_t *target, ks_dht_token_t *token);
|
|
|
|
/**
|
|
* Verify an opaque write token matches the provided remote address and target nodeid.
|
|
* Handles checking against the last two secret values for the token hash.
|
|
* @param dht pointer to the dht instance
|
|
* @param raddr pointer to the remote address used for the ip and port in the token hash
|
|
* @param target pointer to the nodeid of the target used for the token hash
|
|
* @param token pointer to the input token being compared
|
|
* @return Either KS_TRUE if verification passes, otherwise KS_FALSE
|
|
*/
|
|
KS_DECLARE(ks_bool_t) ks_dht_token_verify(ks_dht_t *dht, const ks_sockaddr_t *raddr, ks_dht_nodeid_t *target, ks_dht_token_t *token);
|
|
|
|
/**
|
|
* Encodes a message for transmission as a UDP datagram and sends it.
|
|
* Uses the internally tracked local endpoint and remote address to route the UDP datagram.
|
|
* @param dht pointer to the dht instance
|
|
* @param message pointer to the message being sent
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
|
|
* @see ks_socket_sendto
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_send(ks_dht_t *dht, ks_dht_message_t *message);
|
|
|
|
/**
|
|
* Sets up the common parts of a query message.
|
|
* Determines the local endpoint aware of autorouting, assigns the remote address, generates a transaction, and queues a callback.
|
|
* @param dht pointer to the dht instance
|
|
* @param job pointer to the job
|
|
* @param query string value of the query type, for example "ping"
|
|
* @param callback callback to be called when response to transaction is received
|
|
* @param transaction dereferenced out pointer to the allocated transaction, may be NULL to ignore output
|
|
* @param message dereferenced out pointer to the allocated message
|
|
* @param args dereferenced out pointer to the allocated bencode args, may be NULL to ignore output
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_FAIL, ...
|
|
* @see ks_dht_autoroute_check
|
|
* @see ks_dht_transaction_alloc
|
|
* @see ks_dht_transaction_init
|
|
* @see ks_dht_message_alloc
|
|
* @see ks_dht_message_init
|
|
* @see ks_dht_message_query
|
|
* @see ks_hash_insert
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_query_setup(ks_dht_t *dht,
|
|
ks_dht_job_t *job,
|
|
const char *query,
|
|
ks_dht_job_callback_t callback,
|
|
ks_dht_transaction_t **transaction,
|
|
ks_dht_message_t **message,
|
|
struct bencode **args);
|
|
|
|
/**
|
|
* Sets up the common parts of a response message.
|
|
* Determines the local endpoint aware of autorouting, assigns the remote address, and assigns the transaction.
|
|
* @param dht pointer to the dht instance
|
|
* @param ep pointer to the endpoint, may be NULL to find an endpoint or autoroute one
|
|
* @param raddr pointer to the remote address
|
|
* @param transactionid pointer to the buffer containing the transactionid, may be of variable size depending on the querying node
|
|
* @param transactionid_length length of the transactionid buffer
|
|
* @param message dereferenced out pointer to the allocated message
|
|
* @param args dereferenced out pointer to the allocated bencode args, may be NULL to ignore output
|
|
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
|
|
* @see ks_dht_autoroute_check
|
|
* @see ks_dht_message_alloc
|
|
* @see ks_dht_message_init
|
|
* @see ks_dht_message_response
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_response_setup(ks_dht_t *dht,
|
|
ks_dht_endpoint_t *ep,
|
|
const ks_sockaddr_t *raddr,
|
|
uint8_t *transactionid,
|
|
ks_size_t transactionid_length,
|
|
ks_dht_message_t **message,
|
|
struct bencode **args);
|
|
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_error(ks_dht_t *dht,
|
|
ks_dht_endpoint_t *ep,
|
|
const ks_sockaddr_t *raddr,
|
|
uint8_t *transactionid,
|
|
ks_size_t transactionid_length,
|
|
long long errorcode,
|
|
const char *errorstr);
|
|
|
|
KS_DECLARE(void) ks_dht_pulse_jobs(ks_dht_t *dht);
|
|
KS_DECLARE(ks_status_t) ks_dht_query_ping(ks_dht_t *dht, ks_dht_job_t *job);
|
|
KS_DECLARE(ks_status_t) ks_dht_query_findnode(ks_dht_t *dht, ks_dht_job_t *job);
|
|
KS_DECLARE(ks_status_t) ks_dht_query_get(ks_dht_t *dht, ks_dht_job_t *job);
|
|
KS_DECLARE(ks_status_t) ks_dht_query_put(ks_dht_t *dht, ks_dht_job_t *job);
|
|
|
|
KS_DECLARE(void *)ks_dht_process(ks_thread_t *thread, void *data);
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_process_query(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_response(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_error(ks_dht_t *dht, ks_dht_message_t *message);
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_process_query_ping(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_response_ping(ks_dht_t *dht, ks_dht_job_t *job);
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_process_query_findnode(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_response_findnode(ks_dht_t *dht, ks_dht_job_t *job);
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_process_query_get(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_response_get(ks_dht_t *dht, ks_dht_job_t *job);
|
|
|
|
KS_DECLARE(ks_status_t) ks_dht_process_query_put(ks_dht_t *dht, ks_dht_message_t *message);
|
|
KS_DECLARE(ks_status_t) ks_dht_process_response_put(ks_dht_t *dht, ks_dht_job_t *job);
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_datagram_create(ks_dht_datagram_t **datagram,
|
|
ks_pool_t *pool,
|
|
ks_dht_t *dht,
|
|
ks_dht_endpoint_t *endpoint,
|
|
const ks_sockaddr_t *raddr);
|
|
KS_DECLARE(void) ks_dht_datagram_destroy(ks_dht_datagram_t **datagram);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_job_create(ks_dht_job_t **job,
|
|
ks_pool_t *pool,
|
|
const ks_sockaddr_t *raddr,
|
|
int32_t attempts,
|
|
void *data);
|
|
KS_DECLARE(void) ks_dht_job_build_ping(ks_dht_job_t *job, ks_dht_job_callback_t query_callback, ks_dht_job_callback_t finish_callback);
|
|
KS_DECLARE(void) ks_dht_job_build_findnode(ks_dht_job_t *job,
|
|
ks_dht_job_callback_t query_callback,
|
|
ks_dht_job_callback_t finish_callback,
|
|
ks_dht_nodeid_t *target);
|
|
KS_DECLARE(void) ks_dht_job_build_get(ks_dht_job_t *job,
|
|
ks_dht_job_callback_t query_callback,
|
|
ks_dht_job_callback_t finish_callback,
|
|
ks_dht_nodeid_t *target,
|
|
const uint8_t *salt,
|
|
ks_size_t salt_length);
|
|
KS_DECLARE(void) ks_dht_job_build_put(ks_dht_job_t *job,
|
|
ks_dht_job_callback_t query_callback,
|
|
ks_dht_job_callback_t finish_callback,
|
|
ks_dht_token_t *token,
|
|
int64_t cas,
|
|
ks_dht_storageitem_t *item);
|
|
KS_DECLARE(void) ks_dht_job_build_search(ks_dht_job_t *job,
|
|
ks_dht_job_callback_t query_callback,
|
|
ks_dht_job_callback_t finish_callback);
|
|
KS_DECLARE(void) ks_dht_job_build_search_findnode(ks_dht_job_t *job,
|
|
ks_dht_nodeid_t *target,
|
|
uint32_t family,
|
|
ks_dht_job_callback_t query_callback,
|
|
ks_dht_job_callback_t finish_callback);
|
|
KS_DECLARE(void) ks_dht_job_destroy(ks_dht_job_t **job);
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_endpoint_create(ks_dht_endpoint_t **endpoint,
|
|
ks_pool_t *pool,
|
|
const ks_sockaddr_t *addr,
|
|
ks_socket_t sock);
|
|
KS_DECLARE(void) ks_dht_endpoint_destroy(ks_dht_endpoint_t **endpoint);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_message_create(ks_dht_message_t **message,
|
|
ks_pool_t *pool,
|
|
ks_dht_endpoint_t *endpoint,
|
|
const ks_sockaddr_t *raddr,
|
|
ks_bool_t alloc_data);
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(void) ks_dht_message_destroy(ks_dht_message_t **message);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_message_parse(ks_dht_message_t *message, const uint8_t *buffer, ks_size_t buffer_length);
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_search_create(ks_dht_search_t **search,
|
|
ks_pool_t *pool,
|
|
ks_dhtrt_routetable_t *table,
|
|
const ks_dht_nodeid_t *target,
|
|
ks_dht_job_callback_t callback,
|
|
void *data);
|
|
KS_DECLARE(void) ks_dht_search_destroy(ks_dht_search_t **search);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_publish_create(ks_dht_publish_t **publish,
|
|
ks_pool_t *pool,
|
|
ks_dht_job_callback_t callback,
|
|
void *data,
|
|
int64_t cas,
|
|
ks_dht_storageitem_t *item);
|
|
KS_DECLARE(void) ks_dht_publish_destroy(ks_dht_publish_t **publish);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_distribute_create(ks_dht_distribute_t **distribute,
|
|
ks_pool_t *pool,
|
|
ks_dht_storageitem_callback_t callback,
|
|
void *data,
|
|
int64_t cas,
|
|
ks_dht_storageitem_t *item);
|
|
KS_DECLARE(void) ks_dht_distribute_destroy(ks_dht_distribute_t **distribute);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_immutable_internal(struct bencode *value, ks_dht_nodeid_t *target);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_mutable_internal(ks_dht_storageitem_pkey_t *pk, struct bencode *salt, ks_dht_nodeid_t *target);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable_internal(ks_dht_storageitem_t **item,
|
|
ks_pool_t *pool,
|
|
ks_dht_nodeid_t *target,
|
|
struct bencode *v,
|
|
ks_bool_t clone_v);
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable(ks_dht_storageitem_t **item,
|
|
ks_pool_t *pool,
|
|
ks_dht_nodeid_t *target,
|
|
const uint8_t *value,
|
|
ks_size_t value_length);
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable_internal(ks_dht_storageitem_t **item,
|
|
ks_pool_t *pool,
|
|
ks_dht_nodeid_t *target,
|
|
struct bencode *v,
|
|
ks_bool_t clone_v,
|
|
ks_dht_storageitem_pkey_t *pk,
|
|
struct bencode *salt,
|
|
ks_bool_t clone_salt,
|
|
int64_t sequence,
|
|
ks_dht_storageitem_signature_t *signature);
|
|
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable(ks_dht_storageitem_t **item,
|
|
ks_pool_t *pool,
|
|
ks_dht_nodeid_t *target,
|
|
const uint8_t *value,
|
|
ks_size_t value_length,
|
|
ks_dht_storageitem_pkey_t *pk,
|
|
const uint8_t *salt,
|
|
ks_size_t salt_length,
|
|
int64_t sequence,
|
|
ks_dht_storageitem_signature_t *signature);
|
|
KS_DECLARE(void) ks_dht_storageitem_update_mutable(ks_dht_storageitem_t *item, struct bencode *v, int64_t sequence, ks_dht_storageitem_signature_t *signature);
|
|
KS_DECLARE(void) ks_dht_storageitem_destroy(ks_dht_storageitem_t **item);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
KS_DECLARE(ks_status_t) ks_dht_transaction_create(ks_dht_transaction_t **transaction,
|
|
ks_pool_t *pool,
|
|
ks_dht_job_t *job,
|
|
uint32_t transactionid,
|
|
ks_dht_job_callback_t callback);
|
|
KS_DECLARE(void) ks_dht_transaction_destroy(ks_dht_transaction_t **transaction);
|
|
|
|
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:
|
|
*/
|