diff --git a/auto_tests/monolith_test.cc b/auto_tests/monolith_test.cc index 7511decf..53b4982e 100644 --- a/auto_tests/monolith_test.cc +++ b/auto_tests/monolith_test.cc @@ -164,7 +164,7 @@ int main(int argc, char *argv[]) { #if defined(__x86_64__) && defined(__LP64__) // toxcore/DHT CHECK_SIZE(Client_data, 496); - CHECK_SIZE(Cryptopacket_Handles, 16); + CHECK_SIZE(Cryptopacket_Handler, 16); CHECK_SIZE(DHT, 676528); CHECK_SIZE(DHT_Friend, 5104); CHECK_SIZE(Hardening, 144); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 2572b28a..3fd3829e 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -61,7 +61,11 @@ /* Number of get node requests to send to quickly find close nodes. */ #define MAX_BOOTSTRAP_TIMES 5 -#define ARRAY_SIZE(ARR) (sizeof (ARR) / sizeof (ARR)[0]) +typedef struct DHT_Friend_Callback { + dht_ip_cb *ip_callback; + void *data; + int32_t number; +} DHT_Friend_Callback; struct DHT_Friend { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -76,16 +80,17 @@ struct DHT_Friend { NAT nat; uint16_t lock_count; - struct { - void (*ip_callback)(void *, int32_t, IP_Port); - void *data; - int32_t number; - } callbacks[DHT_FRIEND_MAX_LOCKS]; + DHT_Friend_Callback callbacks[DHT_FRIEND_MAX_LOCKS]; Node_format to_bootstrap[MAX_SENT_NODES]; unsigned int num_to_bootstrap; }; +typedef struct Cryptopacket_Handler { + cryptopacket_handler_cb *function; + void *object; +} Cryptopacket_Handler; + struct DHT { const Logger *log; Networking_Core *net; @@ -115,7 +120,7 @@ struct DHT { Ping_Array *dht_harden_ping_array; uint64_t last_run; - Cryptopacket_Handles cryptopackethandlers[256]; + Cryptopacket_Handler cryptopackethandlers[256]; Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES]; unsigned int num_to_bootstrap; @@ -618,28 +623,30 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed * * return index or UINT32_MAX if not found. */ -#define INDEX_OF_PK \ - for (uint32_t i = 0; i < size; i++) { \ - if (id_equal(array[i].public_key, pk)) { \ - return i; \ - } \ - } \ - \ - return UINT32_MAX; +#define INDEX_OF_PK(array, size, pk) \ + do { \ + for (uint32_t i = 0; i < size; ++i) { \ + if (id_equal(array[i].public_key, pk)) { \ + return i; \ + } \ + } \ + \ + return UINT32_MAX; \ + } while (0) static uint32_t index_of_client_pk(const Client_data *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } static uint32_t index_of_friend_pk(const DHT_Friend *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const uint8_t *pk) { - INDEX_OF_PK + INDEX_OF_PK(array, size, pk); } /* Find index of Client_data with ip_port equal to param ip_port. @@ -796,7 +803,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ uint32_t num_nodes = *num_nodes_ptr; - for (uint32_t i = 0; i < client_list_length; i++) { + for (uint32_t i = 0; i < client_list_length; ++i) { const Client_data *const client = &client_list[i]; /* node already in list? */ @@ -834,7 +841,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_ if (num_nodes < MAX_SENT_NODES) { memcpy(nodes_list[num_nodes].public_key, client->public_key, CRYPTO_PUBLIC_KEY_SIZE); nodes_list[num_nodes].ip_port = ipptp->ip_port; - num_nodes++; + ++num_nodes; } else { add_to_list(nodes_list, MAX_SENT_NODES, client->public_key, ipptp->ip_port, public_key); } @@ -885,11 +892,21 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good); } -typedef struct { +typedef struct DHT_Cmp_data { const uint8_t *base_public_key; Client_data entry; } DHT_Cmp_data; +static bool assoc_timeout(const IPPTsPng *assoc) +{ + return is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT); +} + +static bool incorrect_hardening(const IPPTsPng *assoc) +{ + return hardening_correct(&assoc->hardening) != HARDENING_ALL_OK; +} + static int cmp_dht_entry(const void *a, const void *b) { DHT_Cmp_data cmp1, cmp2; @@ -899,10 +916,8 @@ static int cmp_dht_entry(const void *a, const void *b) const Client_data entry2 = cmp2.entry; const uint8_t *cmp_public_key = cmp1.base_public_key; -#define ASSOC_TIMEOUT(assoc) is_timeout((assoc).timestamp, BAD_NODE_TIMEOUT) - - bool t1 = ASSOC_TIMEOUT(entry1.assoc4) && ASSOC_TIMEOUT(entry1.assoc6); - bool t2 = ASSOC_TIMEOUT(entry2.assoc4) && ASSOC_TIMEOUT(entry2.assoc6); + bool t1 = assoc_timeout(&entry1.assoc4) && assoc_timeout(&entry1.assoc6); + bool t2 = assoc_timeout(&entry2.assoc4) && assoc_timeout(&entry2.assoc6); if (t1 && t2) { return 0; @@ -916,10 +931,8 @@ static int cmp_dht_entry(const void *a, const void *b) return 1; } -#define INCORRECT_HARDENING(assoc) hardening_correct(&(assoc).hardening) != HARDENING_ALL_OK - - t1 = INCORRECT_HARDENING(entry1.assoc4) && INCORRECT_HARDENING(entry1.assoc6); - t2 = INCORRECT_HARDENING(entry2.assoc4) && INCORRECT_HARDENING(entry2.assoc6); + t1 = incorrect_hardening(&entry1.assoc4) && incorrect_hardening(&entry1.assoc6); + t2 = incorrect_hardening(&entry2.assoc4) && incorrect_hardening(&entry2.assoc6); if (t1 && !t2) { return -1; @@ -960,14 +973,14 @@ static void sort_client_list(Client_data *list, unsigned int length, const uint8 // comparison function can use it as the base of comparison. VLA(DHT_Cmp_data, cmp_list, length); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { cmp_list[i].base_public_key = comp_public_key; cmp_list[i].entry = list[i]; } qsort(cmp_list, length, sizeof(DHT_Cmp_data), cmp_dht_entry); - for (uint32_t i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; ++i) { list[i] = cmp_list[i].entry; } } @@ -1192,7 +1205,7 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) /* add_to_close should be called only if !in_list (don't extract to variable) */ if (in_close_list || add_to_close(dht, public_key, ip_port, 0)) { - used++; + ++used; } DHT_Friend *friend_foundip = nullptr; @@ -1210,7 +1223,7 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key) friend_foundip = dht_friend; } - used++; + ++used; } } @@ -1527,7 +1540,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa return 0; } - for (uint32_t i = 0; i < num_nodes; i++) { + for (uint32_t i = 0; i < num_nodes; ++i) { if (ipport_isset(&plain_nodes[i].ip_port)) { ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, plain_nodes[i].ip_port); returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1); @@ -1540,7 +1553,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa /*----------------------------------------------------------------------------------*/ /*------------------------END of packet handling functions--------------------------*/ -int dht_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port), +int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, void *data, int32_t number, uint16_t *lock_count) { const uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key); @@ -1578,7 +1591,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void memset(dht_friend, 0, sizeof(DHT_Friend)); memcpy(dht_friend->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); - dht_friend->nat.NATping_id = random_u64(); + dht_friend->nat.nat_ping_id = random_u64(); ++dht->num_friends; lock_num = dht_friend->lock_count; @@ -1660,10 +1673,10 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port) } const Client_data *const client = &frnd->client_list[client_index]; - const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t i = 0; i < ARRAY_SIZE(assocs); i++) { - const IPPTsPng *const assoc = assocs[i]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { *ip_port = assoc->ip_port; @@ -1687,18 +1700,20 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co unsigned int sort = 0; bool sort_ok = false; - for (uint32_t i = 0; i < list_count; i++) { + for (uint32_t i = 0; i < list_count; ++i) { /* If node is not dead. */ Client_data *client = &list[i]; - IPPTsPng *assocs[] = { &client->assoc6, &client->assoc4 }; + IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - IPPTsPng *assoc = assocs[j]; + uint32_t j = 0; + + for (IPPTsPng * const *it = assocs; *it; ++it, ++j) { + IPPTsPng *const assoc = *it; if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { sort = 0; - not_kill++; + ++not_kill; if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr); @@ -1790,13 +1805,13 @@ static void do_Close(DHT *dht) * KILL_NODE_TIMEOUT, so we at least keep trying pings */ const uint64_t badonly = unix_time() - BAD_NODE_TIMEOUT; - for (size_t i = 0; i < LCLIENT_LIST; i++) { + for (size_t i = 0; i < LCLIENT_LIST; ++i) { Client_data *const client = &dht->close_clientlist[i]; - IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - IPPTsPng *const assoc = assocs[j]; + for (IPPTsPng * const *it = assocs; *it; ++it) { + IPPTsPng *const assoc = *it; if (assoc->timestamp) { assoc->timestamp = badonly; @@ -1853,10 +1868,10 @@ int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packe for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { if (id_equal(public_key, dht->close_clientlist[i].public_key)) { const Client_data *const client = &dht->close_clientlist[i]; - const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4 }; + const IPPTsPng *const assocs[] = { &client->assoc6, &client->assoc4, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *const assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; if (ip_isset(&assoc->ip_port.ip)) { return sendpacket(dht->net, assoc->ip_port, packet, length); @@ -1978,10 +1993,10 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack } const Client_data *const client = &dht_friend->client_list[i]; - const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6 }; + const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *const assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -2020,10 +2035,10 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t * for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) { const Client_data *const client = &dht_friend->client_list[i]; - const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6 }; + const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr }; - for (size_t j = 0; j < ARRAY_SIZE(assocs); j++) { - const IPPTsPng *assoc = assocs[j]; + for (const IPPTsPng * const *it = assocs; *it; ++it) { + const IPPTsPng *const assoc = *it; /* If ip is not zero and node is good. */ if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { @@ -2103,13 +2118,13 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu if (packet[0] == NAT_PING_REQUEST) { /* 1 is reply */ send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE); - dht_friend->nat.recvNATping_timestamp = unix_time(); + dht_friend->nat.recv_nat_ping_timestamp = unix_time(); return 0; } if (packet[0] == NAT_PING_RESPONSE) { - if (dht_friend->nat.NATping_id == ping_id) { - dht_friend->nat.NATping_id = random_u64(); + if (dht_friend->nat.nat_ping_id == ping_id) { + dht_friend->nat.nat_ping_id = random_u64(); dht_friend->nat.hole_punching = 1; return 0; } @@ -2124,7 +2139,7 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu * * return ip of 0 if failure. */ -static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) +static IP nat_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) { IP zero; ip_reset(&zero); @@ -2156,7 +2171,7 @@ static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) * * return number of ports and puts the list of ports in portlist. */ -static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) +static uint16_t nat_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) { uint16_t num = 0; @@ -2241,16 +2256,16 @@ static void do_NAT(DHT *dht) continue; } - if (dht->friends_list[i].nat.NATping_timestamp + PUNCH_INTERVAL < temp_time) { - send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.NATping_id, NAT_PING_REQUEST); - dht->friends_list[i].nat.NATping_timestamp = temp_time; + if (dht->friends_list[i].nat.nat_ping_timestamp + PUNCH_INTERVAL < temp_time) { + send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST); + dht->friends_list[i].nat.nat_ping_timestamp = temp_time; } if (dht->friends_list[i].nat.hole_punching == 1 && dht->friends_list[i].nat.punching_timestamp + PUNCH_INTERVAL < temp_time && - dht->friends_list[i].nat.recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { + dht->friends_list[i].nat.recv_nat_ping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { - const IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); + const IP ip = nat_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); if (!ip_isset(&ip)) { continue; @@ -2263,7 +2278,7 @@ static void do_NAT(DHT *dht) } uint16_t port_list[MAX_FRIEND_CLIENTS]; - const uint16_t numports = NAT_getports(port_list, ip_list, num, ip); + const uint16_t numports = nat_getports(port_list, ip_list, num, ip); punch_holes(dht, ip, port_list, numports, i); dht->friends_list[i].nat.punching_timestamp = temp_time; @@ -2276,16 +2291,16 @@ static void do_NAT(DHT *dht) /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ #define DHT_HARDENING 0 -#define HARDREQ_DATA_SIZE 384 /* Attempt to prevent amplification/other attacks*/ +#define HARDREQ_DATA_SIZE 384 // Attempt to prevent amplification/other attacks -enum { +typedef enum Check_Type { CHECK_TYPE_ROUTE_REQ = 0, CHECK_TYPE_ROUTE_RES = 1, CHECK_TYPE_GETNODE_REQ = 2, CHECK_TYPE_GETNODE_RES = 3, CHECK_TYPE_TEST_REQ = 4, CHECK_TYPE_TEST_RES = 5, -}; +} Check_Type; #if DHT_HARDENING static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length) @@ -2625,7 +2640,7 @@ static void do_hardening(DHT *dht) /*----------------------------------------------------------------------------------*/ -void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object) +void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object) { dht->cryptopackethandlers[byte].function = cb; dht->cryptopackethandlers[byte].object = object; diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 15ff44e5..0852827c 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -64,10 +64,10 @@ #define MAX_CRYPTO_REQUEST_SIZE 1024 -#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ -#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ +#define CRYPTO_PACKET_FRIEND_REQ 32 // Friend request crypto packet ID. +#define CRYPTO_PACKET_HARDENING 48 // Hardening crypto packet ID. #define CRYPTO_PACKET_DHTPK 156 -#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ +#define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID. /* Create a request to peer. * send_public_key and send_secret_key are the pub/secret keys of the sender. @@ -89,12 +89,12 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, uint8_t *request_id, const uint8_t *packet, uint16_t length); -typedef struct { +typedef struct IPPTs { IP_Port ip_port; uint64_t timestamp; } IPPTs; -typedef struct { +typedef struct Hardening { /* Node routes request correctly (true (1) or false/didn't check (0)) */ uint8_t routes_requests_ok; /* Time which we last checked this.*/ @@ -112,7 +112,7 @@ typedef struct { uint8_t testing_pingedid[CRYPTO_PUBLIC_KEY_SIZE]; } Hardening; -typedef struct { +typedef struct IPPTsPng { IP_Port ip_port; uint64_t timestamp; uint64_t last_pinged; @@ -123,7 +123,7 @@ typedef struct { uint64_t ret_timestamp; } IPPTsPng; -typedef struct { +typedef struct Client_data { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IPPTsPng assoc4; IPPTsPng assoc6; @@ -131,7 +131,7 @@ typedef struct { /*----------------------------------------------------------------------------------*/ -typedef struct { +typedef struct NAT { /* 1 if currently hole punching, otherwise 0 */ uint8_t hole_punching; uint32_t punching_index; @@ -139,18 +139,17 @@ typedef struct { uint32_t punching_index2; uint64_t punching_timestamp; - uint64_t recvNATping_timestamp; - uint64_t NATping_id; - uint64_t NATping_timestamp; + uint64_t recv_nat_ping_timestamp; + uint64_t nat_ping_id; + uint64_t nat_ping_timestamp; } NAT; #define DHT_FRIEND_MAX_LOCKS 32 -typedef struct { +typedef struct Node_format { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; IP_Port ip_port; -} -Node_format; +} Node_format; typedef struct DHT_Friend DHT_Friend; @@ -199,7 +198,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed #define MAX_KEYS_PER_SLOT 4 #define KEYS_TIMEOUT 600 -typedef struct { +typedef struct Shared_Key { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint32_t times_requested; @@ -207,19 +206,14 @@ typedef struct { uint64_t time_last_requested; } Shared_Key; -typedef struct { +typedef struct Shared_Keys { Shared_Key keys[256 * MAX_KEYS_PER_SLOT]; } Shared_Keys; /*----------------------------------------------------------------------------------*/ -typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, const uint8_t *source_pubkey, - const uint8_t *data, uint16_t len, void *userdata); - -typedef struct { - cryptopacket_handler_callback function; - void *object; -} Cryptopacket_Handles; +typedef int cryptopacket_handler_cb(void *object, IP_Port ip_port, const uint8_t *source_pubkey, + const uint8_t *data, uint16_t len, void *userdata); #define DHT_DEFINED typedef struct DHT DHT; @@ -261,6 +255,8 @@ void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *publi void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id); +typedef void dht_ip_cb(void *object, int32_t number, IP_Port ip_port); + /* Add a new friend to the friends list. * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. * @@ -273,7 +269,7 @@ void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, con * return 0 if success. * return -1 if failure (friends list is full). */ -int dht_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void *data, int32_t number, IP_Port), +int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, void *data, int32_t number, uint16_t *lock_count); /* Delete a friend from the friends list. @@ -387,7 +383,7 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack /* Function to handle crypto packets. */ -void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object); +void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object); /* SAVE/LOAD functions */