Make Ping_Array a module-private type.

This commit is contained in:
iphydf 2018-01-13 16:50:32 +00:00
parent 1e1efec34a
commit e775b5533b
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
9 changed files with 189 additions and 98 deletions

View File

@ -228,6 +228,7 @@ endif()
# LAYER 3: Distributed Hash Table
# -------------------------------
apidsl(toxcore/ping_array.api.h)
add_submodule(toxcore toxdht
toxcore/DHT.c
toxcore/DHT.h

View File

@ -1179,9 +1179,9 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
if (sendback_node != NULL) {
memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format));
ping_id = ping_array_add(&dht->dht_harden_ping_array, plain_message, sizeof(plain_message));
ping_id = ping_array_add(dht->dht_harden_ping_array, plain_message, sizeof(plain_message));
} else {
ping_id = ping_array_add(&dht->dht_ping_array, plain_message, sizeof(receiver));
ping_id = ping_array_add(dht->dht_ping_array, plain_message, sizeof(receiver));
}
if (ping_id == 0) {
@ -1296,9 +1296,9 @@ static uint8_t sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port
{
uint8_t data[sizeof(Node_format) * 2];
if (ping_array_check(data, sizeof(data), &dht->dht_ping_array, ping_id) == sizeof(Node_format)) {
if (ping_array_check(dht->dht_ping_array, data, sizeof(data), ping_id) == sizeof(Node_format)) {
memset(sendback_node, 0, sizeof(Node_format));
} else if (ping_array_check(data, sizeof(data), &dht->dht_harden_ping_array, ping_id) == sizeof(data)) {
} else if (ping_array_check(dht->dht_harden_ping_array, data, sizeof(data), ping_id) == sizeof(data)) {
memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format));
} else {
return 0;
@ -2578,8 +2578,8 @@ DHT *new_DHT(Logger *log, Networking_Core *net, bool holepunching_enabled)
new_symmetric_key(dht->secret_symmetric_key);
crypto_new_keypair(dht->self_public_key, dht->self_secret_key);
ping_array_init(&dht->dht_ping_array, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
ping_array_init(&dht->dht_harden_ping_array, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
dht->dht_harden_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
for (uint32_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
uint8_t random_key_bytes[CRYPTO_PUBLIC_KEY_SIZE];
@ -2622,8 +2622,8 @@ void kill_DHT(DHT *dht)
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL);
ping_array_free_all(&dht->dht_ping_array);
ping_array_free_all(&dht->dht_harden_ping_array);
ping_array_kill(dht->dht_ping_array);
ping_array_kill(dht->dht_harden_ping_array);
kill_ping(dht->ping);
free(dht->friends_list);
free(dht->loaded_nodes_list);

View File

@ -252,8 +252,8 @@ typedef struct {
Shared_Keys shared_keys_sent;
struct PING *ping;
Ping_Array dht_ping_array;
Ping_Array dht_harden_ping_array;
Ping_Array *dht_ping_array;
Ping_Array *dht_harden_ping_array;
uint64_t last_run;
Cryptopacket_Handles cryptopackethandlers[256];

View File

@ -397,7 +397,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port));
memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
*sendback = ping_array_add(&onion_c->announce_ping_array, data, sizeof(data));
*sendback = ping_array_add(onion_c->announce_ping_array, data, sizeof(data));
if (*sendback == 0) {
return -1;
@ -423,7 +423,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
memcpy(&sback, sendback, sizeof(uint64_t));
uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
if (ping_array_check(data, sizeof(data), &onion_c->announce_ping_array, sback) != sizeof(data)) {
if (ping_array_check(onion_c->announce_ping_array, data, sizeof(data), sback) != sizeof(data)) {
return ~0;
}
@ -1733,7 +1733,9 @@ Onion_Client *new_onion_client(Net_Crypto *c)
return NULL;
}
if (ping_array_init(&onion_c->announce_ping_array, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT) != 0) {
onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
if (onion_c->announce_ping_array == NULL) {
free(onion_c);
return NULL;
}
@ -1758,7 +1760,7 @@ void kill_onion_client(Onion_Client *onion_c)
return;
}
ping_array_free_all(&onion_c->announce_ping_array);
ping_array_kill(onion_c->announce_ping_array);
realloc_onion_friends(onion_c, 0);
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);

View File

@ -162,7 +162,7 @@ typedef struct {
Node_format path_nodes_bs[MAX_PATH_NODES];
uint16_t path_nodes_index_bs;
Ping_Array announce_ping_array;
Ping_Array *announce_ping_array;
uint8_t last_pinged_index;
struct {
oniondata_handler_callback function;

View File

@ -48,7 +48,7 @@
struct PING {
DHT *dht;
Ping_Array ping_array;
Ping_Array *ping_array;
Node_format to_ping[MAX_TO_PING];
uint64_t last_to_ping;
};
@ -76,7 +76,7 @@ int send_ping_request(PING *ping, IP_Port ipp, const uint8_t *public_key)
uint8_t data[PING_DATA_SIZE];
id_copy(data, public_key);
memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, &ipp, sizeof(IP_Port));
ping_id = ping_array_add(&ping->ping_array, data, sizeof(data));
ping_id = ping_array_add(ping->ping_array, data, sizeof(data));
if (ping_id == 0) {
return 1;
@ -217,7 +217,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
uint8_t data[PING_DATA_SIZE];
if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data)) {
if (ping_array_check(ping->ping_array, data, sizeof(data), ping_id) != sizeof(data)) {
return 1;
}
@ -359,7 +359,9 @@ PING *new_ping(DHT *dht)
return NULL;
}
if (ping_array_init(&ping->ping_array, PING_NUM_MAX, PING_TIMEOUT) != 0) {
ping->ping_array = ping_array_new(PING_NUM_MAX, PING_TIMEOUT);
if (ping->ping_array == NULL) {
free(ping);
return NULL;
}
@ -375,7 +377,7 @@ void kill_ping(PING *ping)
{
networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
ping_array_free_all(&ping->ping_array);
ping_array_kill(ping->ping_array);
free(ping);
}

72
toxcore/ping_array.api.h Normal file
View File

@ -0,0 +1,72 @@
%{
/*
* Implementation of an efficient array to store that we pinged something.
*/
/*
* Copyright © 2016-2017 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
*
* Tox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PING_ARRAY_H
#define PING_ARRAY_H
#include "network.h"
%}
class ping_Array {
struct this;
/**
* Initialize a Ping_Array.
* size represents the total size of the array and should be a power of 2.
* timeout represents the maximum timeout in seconds for the entry.
*
* return 0 on success.
* return -1 on failure.
*/
static this new(uint32_t size, uint32_t timeout);
/**
* Free all the allocated memory in a Ping_Array.
*/
void kill();
/**
* Add a data with length to the Ping_Array list and return a ping_id.
*
* return ping_id on success.
* return 0 on failure.
*/
uint64_t add(const uint8_t *data, uint32_t length);
/**
* Check if ping_id is valid and not timed out.
*
* On success, copies the data into data of length,
*
* return length of data copied on success.
* return -1 on failure.
*/
int32_t check(uint8_t[length] data, uint64_t ping_id);
}
%{
#endif
%}

View File

@ -30,6 +30,55 @@
#include "crypto_core.h"
#include "util.h"
typedef struct {
void *data;
uint32_t length;
uint64_t time;
uint64_t ping_id;
} Ping_Array_Entry;
struct Ping_Array {
Ping_Array_Entry *entries;
uint32_t last_deleted; /* number representing the next entry to be deleted. */
uint32_t last_added; /* number representing the last entry to be added. */
uint32_t total_size; /* The length of entries */
uint32_t timeout; /* The timeout after which entries are cleared. */
};
/* Initialize a Ping_Array.
* size represents the total size of the array and should be a power of 2.
* timeout represents the maximum timeout in seconds for the entry.
*
* return 0 on success.
* return -1 on failure.
*/
Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
{
if (size == 0 || timeout == 0) {
return NULL;
}
Ping_Array *empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array));
if (empty_array == NULL) {
return NULL;
}
empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry));
if (empty_array->entries == NULL) {
free(empty_array);
return NULL;
}
empty_array->last_deleted = empty_array->last_added = 0;
empty_array->total_size = size;
empty_array->timeout = timeout;
return empty_array;
}
static void clear_entry(Ping_Array *array, uint32_t index)
{
free(array->entries[index].data);
@ -39,6 +88,20 @@ static void clear_entry(Ping_Array *array, uint32_t index)
array->entries[index].ping_id = 0;
}
/* Free all the allocated memory in a Ping_Array.
*/
void ping_array_kill(Ping_Array *array)
{
while (array->last_deleted != array->last_added) {
uint32_t index = array->last_deleted % array->total_size;
clear_entry(array, index);
++array->last_deleted;
}
free(array->entries);
free(array);
}
/* Clear timed out entries.
*/
static void ping_array_clear_timedout(Ping_Array *array)
@ -101,7 +164,7 @@ uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length)
* return length of data copied on success.
* return -1 on failure.
*/
int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id)
int32_t ping_array_check(Ping_Array *array, uint8_t *data, size_t length, uint64_t ping_id)
{
if (ping_id == 0) {
return -1;
@ -130,43 +193,3 @@ int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t
clear_entry(array, index);
return len;
}
/* Initialize a Ping_Array.
* size represents the total size of the array and should be a power of 2.
* timeout represents the maximum timeout in seconds for the entry.
*
* return 0 on success.
* return -1 on failure.
*/
int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout)
{
if (size == 0 || timeout == 0 || empty_array == NULL) {
return -1;
}
empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry));
if (empty_array->entries == NULL) {
return -1;
}
empty_array->last_deleted = empty_array->last_added = 0;
empty_array->total_size = size;
empty_array->timeout = timeout;
return 0;
}
/* Free all the allocated memory in a Ping_Array.
*/
void ping_array_free_all(Ping_Array *array)
{
while (array->last_deleted != array->last_added) {
uint32_t index = array->last_deleted % array->total_size;
clear_entry(array, index);
++array->last_deleted;
}
free(array->entries);
array->entries = NULL;
}

View File

@ -26,51 +26,42 @@
#include "network.h"
typedef struct {
void *data;
uint32_t length;
uint64_t time;
uint64_t ping_id;
} Ping_Array_Entry;
#ifndef PING_ARRAY_DEFINED
#define PING_ARRAY_DEFINED
typedef struct Ping_Array Ping_Array;
#endif /* PING_ARRAY_DEFINED */
typedef struct {
Ping_Array_Entry *entries;
uint32_t last_deleted; /* number representing the next entry to be deleted. */
uint32_t last_added; /* number representing the last entry to be added. */
uint32_t total_size; /* The length of entries */
uint32_t timeout; /* The timeout after which entries are cleared. */
} Ping_Array;
/* Add a data with length to the Ping_Array list and return a ping_id.
*
* return ping_id on success.
* return 0 on failure.
*/
uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length);
/* Check if ping_id is valid and not timed out.
*
* On success, copies the data into data of length,
*
* return length of data copied on success.
* return -1 on failure.
*/
int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id);
/* Initialize a Ping_Array.
/**
* Initialize a Ping_Array.
* size represents the total size of the array and should be a power of 2.
* timeout represents the maximum timeout in seconds for the entry.
*
* return 0 on success.
* return -1 on failure.
*/
int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout);
struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout);
/* Free all the allocated memory in a Ping_Array.
/**
* Free all the allocated memory in a Ping_Array.
*/
void ping_array_free_all(Ping_Array *array);
void ping_array_kill(struct Ping_Array *_array);
/**
* Add a data with length to the Ping_Array list and return a ping_id.
*
* return ping_id on success.
* return 0 on failure.
*/
uint64_t ping_array_add(struct Ping_Array *_array, const uint8_t *data, uint32_t length);
/**
* Check if ping_id is valid and not timed out.
*
* On success, copies the data into data of length,
*
* return length of data copied on success.
* return -1 on failure.
*/
int32_t ping_array_check(struct Ping_Array *_array, uint8_t *data, size_t length, uint64_t ping_id);
#endif