summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src/toxcore/net_crypto.c
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-07-24 16:44:24 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-07-24 16:44:24 +0300
commite55d071e5485a937efd427d159b76c208cccdcce (patch)
tree48d09dc5cf1df2581fd6471b5ccf1560015fa3a4 /protocols/Tox/libtox/src/toxcore/net_crypto.c
parentf36629f67153bc500c828cf51de31988122a1024 (diff)
fixes #3118 (Update toxcore to 0.2.18)
Diffstat (limited to 'protocols/Tox/libtox/src/toxcore/net_crypto.c')
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.c784
1 files changed, 459 insertions, 325 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c
index 77ba2294ce..c34a45734c 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.c
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
+#include "ccompat.h"
#include "list.h"
#include "mono_time.h"
#include "util.h"
@@ -112,7 +113,7 @@ typedef struct Crypto_Connection {
/* TCP_connection connection_number */
unsigned int connection_number_tcp;
- uint8_t maximum_speed_reached;
+ bool maximum_speed_reached;
/* Must be a pointer, because the struct is moved in memory */
pthread_mutex_t *mutex;
@@ -122,9 +123,13 @@ typedef struct Crypto_Connection {
uint32_t dht_pk_callback_number;
} Crypto_Connection;
+static const Crypto_Connection empty_crypto_connection = {{0}};
+
struct Net_Crypto {
const Logger *log;
+ const Random *rng;
Mono_Time *mono_time;
+ const Network *ns;
DHT *dht;
TCP_Connections *tcp_c;
@@ -173,6 +178,7 @@ DHT *nc_get_dht(const Net_Crypto *c)
return c->dht;
}
+non_null()
static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connection_id)
{
if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) {
@@ -185,11 +191,7 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti
const Crypto_Conn_State status = c->crypto_connections[crypt_connection_id].status;
- if (status == CRYPTO_CONN_NO_CONNECTION || status == CRYPTO_CONN_FREE) {
- return false;
- }
-
- return true;
+ return status != CRYPTO_CONN_NO_CONNECTION && status != CRYPTO_CONN_FREE;
}
/** cookie timeout in seconds */
@@ -202,14 +204,16 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti
#define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE)
#define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE)
-/** Create a cookie request packet and put it in packet.
+/** @brief Create a cookie request packet and put it in packet.
+ *
* dht_public_key is the dht public key of the other
*
* packet must be of size COOKIE_REQUEST_LENGTH or bigger.
*
- * return -1 on failure.
- * return COOKIE_REQUEST_LENGTH on success.
+ * @retval -1 on failure.
+ * @retval COOKIE_REQUEST_LENGTH on success.
*/
+non_null()
static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key,
uint64_t number, uint8_t *shared_key)
{
@@ -222,34 +226,35 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
dht_get_shared_key_sent(c->dht, shared_key, dht_public_key);
uint8_t nonce[CRYPTO_NONCE_SIZE];
- random_nonce(nonce);
+ random_nonce(c->rng, nonce);
packet[0] = NET_PACKET_COOKIE_REQUEST;
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
- int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
+ const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) {
return -1;
}
- return (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len);
+ return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len;
}
-/** Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
+/** @brief Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
-static int create_cookie(const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
+non_null()
+static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
const uint64_t temp_time = mono_time_get(mono_time);
memcpy(contents, &temp_time, sizeof(temp_time));
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
- random_nonce(cookie);
- int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
+ random_nonce(rng, cookie);
+ const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) {
return -1;
@@ -258,11 +263,12 @@ static int create_cookie(const Mono_Time *mono_time, uint8_t *cookie, const uint
return 0;
}
-/** Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
+/** @brief Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
const uint8_t *encryption_key)
{
@@ -287,13 +293,14 @@ static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t
}
-/** Create a cookie response packet and put it in packet.
- * request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes.
- * packet must be of size COOKIE_RESPONSE_LENGTH or bigger.
+/** @brief Create a cookie response packet and put it in packet.
+ * @param request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes.
+ * @param packet must be of size COOKIE_RESPONSE_LENGTH or bigger.
*
- * return -1 on failure.
- * return COOKIE_RESPONSE_LENGTH on success.
+ * @retval -1 on failure.
+ * @retval COOKIE_RESPONSE_LENGTH on success.
*/
+non_null()
static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain,
const uint8_t *shared_key, const uint8_t *dht_public_key)
{
@@ -302,14 +309,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
- if (create_cookie(c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
+ if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
packet[0] = NET_PACKET_COOKIE_RESPONSE;
- random_nonce(packet + 1);
- int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
+ random_nonce(c->rng, packet + 1);
+ const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) {
return -1;
@@ -318,13 +325,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
return COOKIE_RESPONSE_LENGTH;
}
-/** Handle the cookie request packet of length length.
+/** @brief Handle the cookie request packet of length length.
* Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH)
* Put the key used to decrypt the request into shared_key (of size CRYPTO_SHARED_KEY_SIZE) for use in the response.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key,
uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
{
@@ -334,7 +342,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE);
dht_get_shared_key_sent(c->dht, shared_key, dht_public_key);
- int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
+ const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE,
request_plain);
@@ -345,8 +353,8 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
return 0;
}
-/** Handle the cookie request packet (for raw UDP)
- */
+/** Handle the cookie request packet (for raw UDP) */
+non_null(1, 2, 3) nullable(5)
static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
@@ -372,8 +380,8 @@ static int udp_handle_cookie_request(void *object, const IP_Port *source, const
return 0;
}
-/** Handle the cookie request packet (for TCP)
- */
+/** Handle the cookie request packet (for TCP) */
+non_null()
static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number, const uint8_t *packet,
uint16_t length)
{
@@ -391,12 +399,12 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number
return -1;
}
- int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data));
+ const int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data));
return ret;
}
-/** Handle the cookie request packet (for TCP oob packets)
- */
+/** Handle the cookie request packet (for TCP oob packets) */
+non_null()
static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number,
const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
{
@@ -408,7 +416,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
return -1;
}
- if (public_key_cmp(dht_public_key, dht_public_key_temp) != 0) {
+ if (!pk_equal(dht_public_key, dht_public_key_temp)) {
return -1;
}
@@ -418,18 +426,19 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
return -1;
}
- int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data));
+ const int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data));
return ret;
}
-/** Handle a cookie response packet of length encrypted with shared_key.
+/** @brief Handle a cookie response packet of length encrypted with shared_key.
* put the cookie in the response in cookie
*
- * cookie must be of length COOKIE_LENGTH.
+ * @param cookie must be of length COOKIE_LENGTH.
*
- * return -1 on failure.
- * return COOKIE_LENGTH on success.
+ * @retval -1 on failure.
+ * @retval COOKIE_LENGTH on success.
*/
+non_null()
static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
const uint8_t *packet, uint16_t length,
const uint8_t *shared_key)
@@ -453,13 +462,14 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE)
-/** Create a handshake packet and put it in packet.
- * cookie must be COOKIE_LENGTH bytes.
- * packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
+/** @brief Create a handshake packet and put it in packet.
+ * @param cookie must be COOKIE_LENGTH bytes.
+ * @param packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
*
- * return -1 on failure.
- * return HANDSHAKE_PACKET_LENGTH on success.
+ * @retval -1 on failure.
+ * @retval HANDSHAKE_PACKET_LENGTH on success.
*/
+non_null()
static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce,
const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey)
{
@@ -471,13 +481,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
- if (create_cookie(c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
+ if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
- random_nonce(packet + 1 + COOKIE_LENGTH);
- int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
+ random_nonce(c->rng, packet + 1 + COOKIE_LENGTH);
+ const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE);
if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) {
@@ -490,7 +500,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
return HANDSHAKE_PACKET_LENGTH;
}
-/** Handle a crypto handshake packet of length.
+/** @brief Handle a crypto handshake packet of length.
* put the nonce contained in the packet in nonce,
* the session public key in session_pk
* the real public key of the peer in peer_real_pk
@@ -505,40 +515,41 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
* peer_real_pk must be at least CRYPTO_PUBLIC_KEY_SIZE
* cookie must be at least COOKIE_LENGTH
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval false on failure.
+ * @retval true on success.
*/
-static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
- uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk)
+non_null(1, 2, 3, 4, 5, 6, 7) nullable(9)
+static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
+ uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint16_t length, const uint8_t *expected_real_pk)
{
if (length != HANDSHAKE_PACKET_LENGTH) {
- return -1;
+ return false;
}
uint8_t cookie_plain[COOKIE_DATA_LENGTH];
if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
- return -1;
+ return false;
}
- if (expected_real_pk && public_key_cmp(cookie_plain, expected_real_pk) != 0) {
- return -1;
+ if (expected_real_pk != nullptr && !pk_equal(cookie_plain, expected_real_pk)) {
+ return false;
}
uint8_t cookie_hash[CRYPTO_SHA512_SIZE];
crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH];
- int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
+ const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE,
HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain);
if (len != sizeof(plain)) {
- return -1;
+ return false;
}
- if (crypto_sha512_cmp(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE) != 0) {
- return -1;
+ if (!crypto_sha512_eq(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE)) {
+ return false;
}
memcpy(nonce, plain, CRYPTO_NONCE_SIZE);
@@ -546,10 +557,11 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
memcpy(cookie, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, COOKIE_LENGTH);
memcpy(peer_real_pk, cookie_plain, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
- return 0;
+ return true;
}
+non_null()
static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id)
{
if (!crypt_connection_id_is_valid(c, crypt_connection_id)) {
@@ -560,11 +572,12 @@ static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_c
}
-/** Associate an ip_port to a connection.
+/** @brief Associate an ip_port to a connection.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -598,14 +611,15 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, const
return -1;
}
-/** Return the IP_Port that should be used to send packets to the other peer.
+/** @brief Return the IP_Port that should be used to send packets to the other peer.
*
- * return IP_Port with family 0 on failure.
- * return IP_Port on success.
+ * @retval IP_Port with family 0 on failure.
+ * @return IP_Port on success.
*/
+non_null()
static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connection_id)
{
- const IP_Port empty = {0};
+ const IP_Port empty = {{{0}}};
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -614,15 +628,15 @@ static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connecti
}
const uint64_t current_time = mono_time_get(c->mono_time);
- bool v6 = 0;
- bool v4 = 0;
+ bool v6 = false;
+ bool v4 = false;
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
- v4 = 1;
+ v4 = true;
}
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
- v6 = 1;
+ v6 = true;
}
/* Prefer IP_Ports which haven't timed out to those which have.
@@ -655,11 +669,12 @@ static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connecti
return empty;
}
-/** Sends a packet to the peer using the fastest route.
+/** @brief Sends a packet to the peer using the fastest route.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
// TODO(irungentoo): TCP, etc...
@@ -669,14 +684,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
return -1;
}
- int direct_send_attempt = 0;
+ bool direct_send_attempt = false;
pthread_mutex_lock(conn->mutex);
IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
// TODO(irungentoo): on bad networks, direct connections might not last indefinitely.
if (!net_family_is_unspec(ip_port.ip.family)) {
- bool direct_connected = 0;
+ bool direct_connected = false;
// FIXME(sudden6): handle return value
crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr);
@@ -688,6 +703,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
}
pthread_mutex_unlock(conn->mutex);
+ LOGGER_WARNING(c->log, "sending packet of length %d failed", length);
return -1;
}
@@ -697,7 +713,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
if ((((UDP_DIRECT_TIMEOUT / 2) + conn->direct_send_attempt_time) < current_time && length < 96)
|| data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
- direct_send_attempt = 1;
+ direct_send_attempt = true;
conn->direct_send_attempt_time = mono_time_get(c->mono_time);
}
}
@@ -705,7 +721,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
pthread_mutex_unlock(conn->mutex);
pthread_mutex_lock(&c->tcp_mutex);
- int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
+ const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
pthread_mutex_unlock(&c->tcp_mutex);
pthread_mutex_lock(conn->mutex);
@@ -716,38 +732,40 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
pthread_mutex_unlock(conn->mutex);
- if (ret == 0 || direct_send_attempt) {
+ if (direct_send_attempt) {
return 0;
}
- return -1;
+ return ret;
}
/*** START: Array Related functions */
-/** Return number of packets in array
+/** @brief Return number of packets in array
* Note that holes are counted too.
*/
+non_null()
static uint32_t num_packets_array(const Packets_Array *array)
{
return array->buffer_end - array->buffer_start;
}
-/** Add data with packet number to array.
+/** @brief Add data with packet number to array.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data)
{
if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) {
return -1;
}
- uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
- if (array->buffer[num]) {
+ if (array->buffer[num] != nullptr) {
return -1;
}
@@ -767,12 +785,13 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe
return 0;
}
-/** Get pointer of data with packet number.
+/** @brief Get pointer of data with packet number.
*
- * return -1 on failure.
- * return 0 if data at number is empty.
- * return 1 if data pointer was put in data.
+ * @retval -1 on failure.
+ * @retval 0 if data at number is empty.
+ * @retval 1 if data pointer was put in data.
*/
+non_null()
static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint32_t number)
{
const uint32_t num_spots = num_packets_array(array);
@@ -781,9 +800,9 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint
return -1;
}
- uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
- if (!array->buffer[num]) {
+ if (array->buffer[num] == nullptr) {
return 0;
}
@@ -791,37 +810,41 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint
return 1;
}
-/** Add data to end of array.
+/** @brief Add data to end of array.
*
- * return -1 on failure.
- * return packet number on success.
+ * @retval -1 on failure.
+ * @return packet number on success.
*/
-static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *data)
+non_null()
+static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array, const Packet_Data *data)
{
const uint32_t num_spots = num_packets_array(array);
if (num_spots >= CRYPTO_PACKET_BUFFER_SIZE) {
+ LOGGER_WARNING(logger, "crypto packet buffer size exceeded; rejecting packet of length %d", data->length);
return -1;
}
Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data));
if (new_d == nullptr) {
+ LOGGER_ERROR(logger, "packet data allocation failed");
return -1;
}
*new_d = *data;
- uint32_t id = array->buffer_end;
+ const uint32_t id = array->buffer_end;
array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d;
++array->buffer_end;
return id;
}
-/** Read data from beginning of array.
+/** @brief Read data from beginning of array.
*
- * return -1 on failure.
- * return packet number on success.
+ * @retval -1 on failure.
+ * @return packet number on success.
*/
+non_null()
static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
{
if (array->buffer_end == array->buffer_start) {
@@ -830,23 +853,24 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
const uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE;
- if (!array->buffer[num]) {
+ if (array->buffer[num] == nullptr) {
return -1;
}
*data = *array->buffer[num];
- uint32_t id = array->buffer_start;
+ const uint32_t id = array->buffer_start;
++array->buffer_start;
free(array->buffer[num]);
array->buffer[num] = nullptr;
return id;
}
-/** Delete all packets in array before number (but not number)
+/** @brief Delete all packets in array before number (but not number)
*
- * return -1 on failure.
- * return 0 on success
+ * @retval -1 on failure.
+ * @retval 0 on success
*/
+non_null()
static int clear_buffer_until(Packets_Array *array, uint32_t number)
{
const uint32_t num_spots = num_packets_array(array);
@@ -858,9 +882,9 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
uint32_t i;
for (i = array->buffer_start; i != number; ++i) {
- uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
- if (array->buffer[num]) {
+ if (array->buffer[num] != nullptr) {
free(array->buffer[num]);
array->buffer[num] = nullptr;
}
@@ -870,14 +894,15 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
return 0;
}
+non_null()
static int clear_buffer(Packets_Array *array)
{
uint32_t i;
for (i = array->buffer_start; i != array->buffer_end; ++i) {
- uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
- if (array->buffer[num]) {
+ if (array->buffer[num] != nullptr) {
free(array->buffer[num]);
array->buffer[num] = nullptr;
}
@@ -887,11 +912,12 @@ static int clear_buffer(Packets_Array *array)
return 0;
}
-/** Set array buffer end to number.
+/** @brief Set array buffer end to number.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int set_buffer_end(Packets_Array *array, uint32_t number)
{
if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) {
@@ -906,12 +932,14 @@ static int set_buffer_end(Packets_Array *array, uint32_t number)
return 0;
}
-/** Create a packet request packet from recv_array and send_buffer_end into
- * data of length.
+/**
+ * @brief Create a packet request packet from recv_array and send_buffer_end into
+ * data of length.
*
- * return -1 on failure.
- * return length of packet on success.
+ * @retval -1 on failure.
+ * @return length of packet on success.
*/
+non_null()
static int generate_request_packet(uint8_t *data, uint16_t length, const Packets_Array *recv_array)
{
if (length == 0) {
@@ -933,9 +961,9 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets
uint32_t n = 1;
for (uint32_t i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) {
- uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
- if (!recv_array->buffer[num]) {
+ if (recv_array->buffer[num] == nullptr) {
data[cur_len] = n;
n = 0;
++cur_len;
@@ -959,12 +987,13 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets
return cur_len;
}
-/** Handle a request data packet.
+/** @brief Handle a request data packet.
* Remove all the packets the other received from the array.
*
- * return -1 on failure.
- * return number of requested packets on success.
+ * @retval -1 on failure.
+ * @return number of requested packets on success.
*/
+non_null()
static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array,
const uint8_t *data, uint16_t length,
uint64_t *latest_send_time, uint64_t rtt_time)
@@ -988,18 +1017,18 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array
uint32_t requested = 0;
const uint64_t temp_time = current_time_monotonic(mono_time);
- uint64_t l_sent_time = -1;
+ uint64_t l_sent_time = 0;
for (uint32_t i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
if (length == 0) {
break;
}
- uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
+ const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
if (n == data[0]) {
- if (send_array->buffer[num]) {
- uint64_t sent_time = send_array->buffer[num]->sent_time;
+ if (send_array->buffer[num] != nullptr) {
+ const uint64_t sent_time = send_array->buffer[num]->sent_time;
if ((sent_time + rtt_time) < temp_time) {
send_array->buffer[num]->sent_time = 0;
@@ -1011,7 +1040,7 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array
n = 0;
++requested;
} else {
- if (send_array->buffer[num]) {
+ if (send_array->buffer[num] != nullptr) {
l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time);
free(send_array->buffer[num]);
@@ -1042,32 +1071,37 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array
#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE))
-/** Creates and sends a data packet to the peer using the fastest route.
+/** @brief Creates and sends a data packet to the peer using the fastest route.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE);
if (length == 0 || length > max_length) {
+ LOGGER_ERROR(c->log, "zero-length or too large data packet: %d (max: %d)", length, max_length);
return -1;
}
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
+ LOGGER_ERROR(c->log, "connection id %d not found", crypt_connection_id);
return -1;
}
pthread_mutex_lock(conn->mutex);
- VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
+ const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
+ VLA(uint8_t, packet, packet_size);
packet[0] = NET_PACKET_CRYPTO_DATA;
memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t));
const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
- if (len + 1 + sizeof(uint16_t) != SIZEOF_VLA(packet)) {
+ if (len + 1 + sizeof(uint16_t) != packet_size) {
+ LOGGER_ERROR(c->log, "encryption failed: %d", len);
pthread_mutex_unlock(conn->mutex);
return -1;
}
@@ -1078,21 +1112,23 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet));
}
-/** Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
+/** @brief Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
const uint8_t *data, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
+ LOGGER_ERROR(c->log, "zero-length or too large data packet: %d (max: %d)", length, MAX_CRYPTO_PACKET_SIZE);
return -1;
}
num = net_htonl(num);
buffer_start = net_htonl(buffer_start);
- uint16_t padding_length = (MAX_CRYPTO_DATA_SIZE - length) % CRYPTO_MAX_PADDING;
+ const uint16_t padding_length = (MAX_CRYPTO_DATA_SIZE - length) % CRYPTO_MAX_PADDING;
VLA(uint8_t, packet, sizeof(uint32_t) + sizeof(uint32_t) + padding_length + length);
memcpy(packet, &buffer_start, sizeof(uint32_t));
memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t));
@@ -1102,6 +1138,7 @@ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint3
return send_data_packet(c, crypt_connection_id, packet, SIZEOF_VLA(packet));
}
+non_null()
static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1126,19 +1163,23 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
dt->sent_time = current_time_monotonic(c->mono_time);
}
- conn->maximum_speed_reached = 0;
+ conn->maximum_speed_reached = false;
}
return 0;
}
-/** return -1 if data could not be put in packet queue.
- * return positive packet number if data was put into the queue.
+/**
+ * @retval -1 if data could not be put in packet queue.
+ * @return positive packet number if data was put into the queue.
*/
+non_null()
static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
- uint8_t congestion_control)
+ bool congestion_control)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
+ LOGGER_ERROR(c->log, "rejecting too large (or empty) packet of size %d on crypt connection %d", length,
+ crypt_connection_id);
return -1;
}
@@ -1153,6 +1194,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
reset_max_speed_reached(c, crypt_connection_id);
if (conn->maximum_speed_reached && congestion_control) {
+ LOGGER_INFO(c->log, "congestion control: maximum speed reached on crypt connection %d", crypt_connection_id);
return -1;
}
@@ -1161,7 +1203,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt.length = length;
memcpy(dt.data, data, length);
pthread_mutex_lock(conn->mutex);
- int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
+ const int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt);
pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) {
@@ -1179,16 +1221,18 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt1->sent_time = current_time_monotonic(c->mono_time);
}
} else {
- conn->maximum_speed_reached = 1;
- LOGGER_DEBUG(c->log, "send_data_packet failed");
+ conn->maximum_speed_reached = true;
+ LOGGER_DEBUG(c->log, "send_data_packet failed (packet_num = %ld)", (long)packet_num);
}
return packet_num;
}
-/** Get the lowest 2 bytes from the nonce and convert
- * them to host byte format before returning them.
+/**
+ * @brief Get the lowest 2 bytes from the nonce and convert
+ * them to host byte format before returning them.
*/
+non_null()
static uint16_t get_nonce_uint16(const uint8_t *nonce)
{
uint16_t num;
@@ -1198,13 +1242,14 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce)
#define DATA_NUM_THRESHOLD 21845
-/** Handle a data packet.
+/** @brief Handle a data packet.
* Decrypt packet of length and put it into data.
* data must be at least MAX_DATA_DATA_PACKET_SIZE big.
*
- * return -1 on failure.
- * return length of data on success.
+ * @retval -1 on failure.
+ * @return length of data on success.
*/
+non_null()
static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet,
uint16_t length)
{
@@ -1222,12 +1267,12 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
uint8_t nonce[CRYPTO_NONCE_SIZE];
memcpy(nonce, conn->recv_nonce, CRYPTO_NONCE_SIZE);
- uint16_t num_cur_nonce = get_nonce_uint16(nonce);
+ const uint16_t num_cur_nonce = get_nonce_uint16(nonce);
uint16_t num;
net_unpack_u16(packet + 1, &num);
- uint16_t diff = num - num_cur_nonce;
+ const uint16_t diff = num - num_cur_nonce;
increment_nonce_number(nonce, diff);
- int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
+ const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
length - (1 + sizeof(uint16_t)), data);
if ((unsigned int)len != length - crypto_packet_overhead) {
@@ -1241,11 +1286,12 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
return len;
}
-/** Send a request packet.
+/** @brief Send a request packet.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1255,7 +1301,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
}
uint8_t data[MAX_CRYPTO_DATA_SIZE];
- int len = generate_request_packet(data, sizeof(data), &conn->recv_array);
+ const int len = generate_request_packet(data, sizeof(data), &conn->recv_array);
if (len == -1) {
return -1;
@@ -1265,11 +1311,12 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
len);
}
-/** Send up to max num previously requested data packets.
+/** @brief Send up to max num previously requested data packets.
*
- * return -1 on failure.
- * return number of packets sent on success.
+ * @retval -1 on failure.
+ * @return number of packets sent on success.
*/
+non_null()
static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32_t max_num)
{
if (max_num == 0) {
@@ -1299,7 +1346,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
continue;
}
- if (dt->sent_time) {
+ if (dt->sent_time != 0) {
continue;
}
@@ -1318,11 +1365,12 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
}
-/** Add a new temp packet to send repeatedly.
+/** @brief Add a new temp packet to send repeatedly.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) {
@@ -1341,7 +1389,7 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u
return -1;
}
- if (conn->temp_packet) {
+ if (conn->temp_packet != nullptr) {
free(conn->temp_packet);
}
@@ -1353,11 +1401,12 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u
return 0;
}
-/** Clear the temp packet.
+/** @brief Clear the temp packet.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1366,7 +1415,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
return -1;
}
- if (conn->temp_packet) {
+ if (conn->temp_packet != nullptr) {
free(conn->temp_packet);
}
@@ -1378,11 +1427,12 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
}
-/** Send the temp packet.
+/** @brief Send the temp packet.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1391,7 +1441,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
return -1;
}
- if (!conn->temp_packet) {
+ if (conn->temp_packet == nullptr) {
return -1;
}
@@ -1404,12 +1454,13 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
return 0;
}
-/** Create a handshake packet and set it as a temp packet.
- * cookie must be COOKIE_LENGTH.
+/** @brief Create a handshake packet and set it as a temp packet.
+ * @param cookie must be COOKIE_LENGTH.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
const uint8_t *dht_public_key)
{
@@ -1434,11 +1485,12 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u
return 0;
}
-/** Send a kill packet.
+/** @brief Send a kill packet.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1452,6 +1504,7 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
&kill_packet, sizeof(kill_packet));
}
+non_null(1) nullable(3)
static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userdata)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1460,15 +1513,15 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda
return;
}
- if (conn->connection_status_callback) {
- conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0,
- userdata);
+ if (conn->connection_status_callback != nullptr) {
+ conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id,
+ false, userdata);
}
- while (1) { /* TODO(irungentoo): is this really the best way to do this? */
+ while (true) { /* TODO(irungentoo): is this really the best way to do this? */
pthread_mutex_lock(&c->connections_mutex);
- if (!c->connection_use_counter) {
+ if (c->connection_use_counter == 0) {
break;
}
@@ -1479,11 +1532,12 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda
pthread_mutex_unlock(&c->connections_mutex);
}
-/** Handle a received data packet.
+/** @brief Handle a received data packet.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null(1, 3) nullable(6)
static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
bool udp, void *userdata)
{
@@ -1498,7 +1552,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
}
uint8_t data[MAX_DATA_DATA_PACKET_SIZE];
- int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
+ const int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
if (len <= (int)(sizeof(uint32_t) * 2)) {
return -1;
@@ -1546,9 +1600,9 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
clear_temp_packet(c, crypt_connection_id);
conn->status = CRYPTO_CONN_ESTABLISHED;
- if (conn->connection_status_callback) {
- conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1,
- userdata);
+ if (conn->connection_status_callback != nullptr) {
+ conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id,
+ true, userdata);
}
}
@@ -1561,7 +1615,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
rtt_time = DEFAULT_TCP_PING_CONNECTION;
}
- int requested = handle_request_packet(c->mono_time, &conn->send_array,
+ const int requested = handle_request_packet(c->mono_time, &conn->send_array,
real_data, real_length,
&rtt_calc_time, rtt_time);
@@ -1579,7 +1633,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
return -1;
}
- while (1) {
+ while (true) {
pthread_mutex_lock(conn->mutex);
const int ret = read_data_beg_buffer(&conn->recv_array, &dt);
pthread_mutex_unlock(conn->mutex);
@@ -1588,7 +1642,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
break;
}
- if (conn->connection_data_callback) {
+ if (conn->connection_data_callback != nullptr) {
conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data,
dt.length, userdata);
}
@@ -1607,7 +1661,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
set_buffer_end(&conn->recv_array, num);
- if (conn->connection_lossy_data_callback) {
+ if (conn->connection_lossy_data_callback != nullptr) {
conn->connection_lossy_data_callback(conn->connection_lossy_data_callback_object,
conn->connection_lossy_data_callback_id, real_data, real_length, userdata);
}
@@ -1626,6 +1680,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
return 0;
}
+non_null()
static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1657,6 +1712,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id,
return 0;
}
+non_null(1, 3) nullable(5)
static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
void *userdata)
{
@@ -1676,12 +1732,12 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const
uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t cookie[COOKIE_LENGTH];
- if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
- packet, length, conn->public_key) != 0) {
+ if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
+ packet, length, conn->public_key)) {
return -1;
}
- if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
+ if (pk_equal(dht_public_key, conn->dht_public_key)) {
encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
@@ -1692,7 +1748,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
} else {
- if (conn->dht_pk_callback) {
+ if (conn->dht_pk_callback != nullptr) {
conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata);
}
}
@@ -1700,6 +1756,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const
return 0;
}
+non_null(1, 3) nullable(6)
static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
bool udp, void *userdata)
{
@@ -1716,11 +1773,12 @@ static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, con
return handle_data_packet_core(c, crypt_connection_id, packet, length, udp, userdata);
}
-/** Handle a packet that was received for the connection.
+/** @brief Handle a packet that was received for the connection.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null(1, 3) nullable(6)
static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
bool udp, void *userdata)
{
@@ -1743,11 +1801,12 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
}
}
-/** Set the size of the friend list to numfriends.
+/** @brief Set the size of the friend list to numfriends.
*
- * return -1 if realloc fails.
- * return 0 if it succeeds.
+ * @retval -1 if realloc fails.
+ * @retval 0 if it succeeds.
*/
+non_null()
static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
{
if (num == 0) {
@@ -1768,17 +1827,18 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
}
-/** Create a new empty crypto connection.
+/** @brief Create a new empty crypto connection.
*
- * return -1 on failure.
- * return connection id on success.
+ * @retval -1 on failure.
+ * @return connection id on success.
*/
+non_null()
static int create_crypto_connection(Net_Crypto *c)
{
- while (1) { /* TODO(irungentoo): is this really the best way to do this? */
+ while (true) { /* TODO(irungentoo): is this really the best way to do this? */
pthread_mutex_lock(&c->connections_mutex);
- if (!c->connection_use_counter) {
+ if (c->connection_use_counter == 0) {
break;
}
@@ -1798,7 +1858,7 @@ static int create_crypto_connection(Net_Crypto *c)
if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) {
id = c->crypto_connections_length;
++c->crypto_connections_length;
- memset(&c->crypto_connections[id], 0, sizeof(Crypto_Connection));
+ c->crypto_connections[id] = empty_crypto_connection;
}
}
@@ -1829,11 +1889,12 @@ static int create_crypto_connection(Net_Crypto *c)
return id;
}
-/** Wipe a crypto connection.
+/** @brief Wipe a crypto connection.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null()
static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
{
if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) {
@@ -1871,11 +1932,12 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
return 0;
}
-/** Get crypto connection id from public key of peer.
+/** @brief Get crypto connection id from public key of peer.
*
- * return -1 if there are no connections like we are looking for.
- * return id if it found it.
+ * @retval -1 if there are no connections like we are looking for.
+ * @return id if it found it.
*/
+non_null()
static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
{
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
@@ -1883,7 +1945,7 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
continue;
}
- if (public_key_cmp(public_key, c->crypto_connections[i].public_key) == 0) {
+ if (pk_equal(public_key, c->crypto_connections[i].public_key)) {
return i;
}
}
@@ -1891,13 +1953,14 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
return -1;
}
-/** Add a source to the crypto connection.
+/** @brief Add a source to the crypto connection.
* This is to be used only when we have received a packet from that source.
*
- * return -1 on failure.
- * return positive number on success.
- * 0 if source was a direct UDP connection.
+ * @retval -1 on failure.
+ * @retval 0 if source was a direct UDP connection.
+ * @return positive number on success.
*/
+non_null()
static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, const IP_Port *source)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1920,8 +1983,10 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
return 0;
}
- if (net_family_is_tcp_family(source->ip.family)) {
- if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source->ip.ip.v6.uint32[0]) == 0) {
+ unsigned int tcp_connections_number;
+
+ if (ip_port_to_tcp_connections_number(source, &tcp_connections_number)) {
+ if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, tcp_connections_number) == 0) {
return 1;
}
}
@@ -1930,7 +1995,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
}
-/** Set function to be called when someone requests a new connection to us.
+/** @brief Set function to be called when someone requests a new connection to us.
*
* The set function should return -1 on failure and 0 on success.
*
@@ -1942,12 +2007,13 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal
c->new_connection_callback_object = object;
}
-/** Handle a handshake packet by someone who wants to initiate a new connection with us.
- * This calls the callback set by new_connection_handler() if the handshake is ok.
+/** @brief Handle a handshake packet by someone who wants to initiate a new connection with us.
+ * This calls the callback set by `new_connection_handler()` if the handshake is ok.
*
- * return -1 on failure.
- * return 0 on success.
+ * @retval -1 on failure.
+ * @retval 0 on success.
*/
+non_null(1, 2, 3) nullable(5)
static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length,
void *userdata)
{
@@ -1961,8 +2027,8 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
n_c.source = *source;
n_c.cookie_length = COOKIE_LENGTH;
- if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
- n_c.cookie, data, length, nullptr) != 0) {
+ if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
+ n_c.cookie, data, length, nullptr)) {
free(n_c.cookie);
return -1;
}
@@ -1976,7 +2042,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
return -1;
}
- if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) {
+ if (!pk_equal(n_c.dht_public_key, conn->dht_public_key)) {
connection_kill(c, crypt_connection_id, userdata);
} else {
if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) {
@@ -2001,12 +2067,12 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
}
}
- int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
+ const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
free(n_c.cookie);
return ret;
}
-/** Accept a crypto connection.
+/** @brief Accept a crypto connection.
*
* return -1 on failure.
* return connection id on success.
@@ -2044,8 +2110,8 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
memcpy(conn->public_key, n_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(conn->recv_nonce, n_c->recv_nonce, CRYPTO_NONCE_SIZE);
memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, CRYPTO_PUBLIC_KEY_SIZE);
- random_nonce(conn->sent_nonce);
- crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
+ random_nonce(c->rng, conn->sent_nonce);
+ crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key);
encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
@@ -2066,7 +2132,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
return crypt_connection_id;
}
-/** Create a crypto connection.
+/** @brief Create a crypto connection.
* If one to that real public key already exists, return it.
*
* return -1 on failure.
@@ -2099,8 +2165,8 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
conn->connection_number_tcp = connection_number_tcp;
memcpy(conn->public_key, real_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- random_nonce(conn->sent_nonce);
- crypto_new_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
+ random_nonce(c->rng, conn->sent_nonce);
+ crypto_new_keypair(c->rng, conn->sessionpublic_key, conn->sessionsecret_key);
conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE;
@@ -2108,7 +2174,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
conn->rtt_time = DEFAULT_PING_CONNECTION;
memcpy(conn->dht_public_key, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- conn->cookie_request_number = random_u64();
+ conn->cookie_request_number = random_u64(c->rng);
uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
@@ -2124,7 +2190,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
return crypt_connection_id;
}
-/** Set the direct ip of the crypto connection.
+/** @brief Set the direct ip of the crypto connection.
*
* Connected is 0 if we are not sure we are connected to that person, 1 if we are sure.
*
@@ -2155,6 +2221,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
}
+non_null(1, 3) nullable(5)
static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_t *data, uint16_t length,
void *userdata)
{
@@ -2177,7 +2244,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_
// This unlocks the mutex that at this point is locked by do_tcp before
// calling do_tcp_connections.
pthread_mutex_unlock(&c->tcp_mutex);
- int ret = handle_packet_connection(c, crypt_connection_id, data, length, 0, userdata);
+ const int ret = handle_packet_connection(c, crypt_connection_id, data, length, false, userdata);
pthread_mutex_lock(&c->tcp_mutex);
if (ret != 0) {
@@ -2188,6 +2255,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_
return 0;
}
+non_null(1, 2, 4) nullable(6)
static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
const uint8_t *data, uint16_t length, void *userdata)
{
@@ -2202,10 +2270,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in
}
if (data[0] == NET_PACKET_CRYPTO_HS) {
- IP_Port source;
- source.port = 0;
- source.ip.family = net_family_tcp_family;
- source.ip.ip.v6.uint32[0] = tcp_connections_number;
+ IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number);
if (handle_new_connection_handshake(c, &source, data, length, userdata) != 0) {
return -1;
@@ -2217,7 +2282,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in
return -1;
}
-/** Add a tcp relay, associating it to a crypt_connection_id.
+/** @brief Add a tcp relay, associating it to a crypt_connection_id.
*
* return 0 if it was added.
* return -1 if it wasn't.
@@ -2231,12 +2296,12 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
}
pthread_mutex_lock(&c->tcp_mutex);
- int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
+ const int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
pthread_mutex_unlock(&c->tcp_mutex);
return ret;
}
-/** Add a tcp relay to the array.
+/** @brief Add a tcp relay to the array.
*
* return 0 if it was added.
* return -1 if it wasn't.
@@ -2244,12 +2309,12 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key)
{
pthread_mutex_lock(&c->tcp_mutex);
- int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
+ const int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
pthread_mutex_unlock(&c->tcp_mutex);
return ret;
}
-/** Return a random TCP connection number for use in send_tcp_onion_request.
+/** @brief Return a random TCP connection number for use in send_tcp_onion_request.
*
* TODO(irungentoo): This number is just the index of an array that the elements can
* change without warning.
@@ -2260,13 +2325,27 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k
int get_random_tcp_con_number(Net_Crypto *c)
{
pthread_mutex_lock(&c->tcp_mutex);
- int ret = get_random_tcp_onion_conn_number(c->tcp_c);
+ const int ret = get_random_tcp_onion_conn_number(c->tcp_c);
pthread_mutex_unlock(&c->tcp_mutex);
return ret;
}
-/** Send an onion packet via the TCP relay corresponding to tcp_connections_number.
+/** @brief Put IP_Port of a random onion TCP connection in ip_port.
+ *
+ * return true on success.
+ * return false on failure.
+ */
+bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port)
+{
+ pthread_mutex_lock(&c->tcp_mutex);
+ const bool ret = tcp_get_random_conn_ip_port(c->tcp_c, ip_port);
+ pthread_mutex_unlock(&c->tcp_mutex);
+
+ return ret;
+}
+
+/** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
@@ -2274,13 +2353,34 @@ int get_random_tcp_con_number(Net_Crypto *c)
int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
{
pthread_mutex_lock(&c->tcp_mutex);
- int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
+ const int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
+ pthread_mutex_unlock(&c->tcp_mutex);
+
+ return ret;
+}
+
+/**
+ * Send a forward request to the TCP relay with IP_Port tcp_forwarder,
+ * requesting to forward data via a chain of dht nodes starting with dht_node.
+ * A chain_length of 0 means that dht_node is the final destination of data.
+ *
+ * return 0 on success.
+ * return -1 on failure.
+ */
+int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port *tcp_forwarder, const IP_Port *dht_node,
+ const uint8_t *chain_keys, uint16_t chain_length,
+ const uint8_t *data, uint16_t data_length)
+{
+ pthread_mutex_lock(&c->tcp_mutex);
+ const int ret = tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node,
+ chain_keys, chain_length, data, data_length);
pthread_mutex_unlock(&c->tcp_mutex);
return ret;
}
-/** Copy a maximum of num TCP relays we are connected to to tcp_relays.
+/** @brief Copy a maximum of num random TCP relays we are connected to to tcp_relays.
+ *
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
@@ -2293,12 +2393,26 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u
}
pthread_mutex_lock(&c->tcp_mutex);
- unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
+ const unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
pthread_mutex_unlock(&c->tcp_mutex);
return ret;
}
+uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx)
+{
+ if (num == 0) {
+ return 0;
+ }
+
+ pthread_mutex_lock(&c->tcp_mutex);
+ const uint32_t ret = tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx);
+ pthread_mutex_unlock(&c->tcp_mutex);
+
+ return ret;
+}
+
+non_null()
static void do_tcp(Net_Crypto *c, void *userdata)
{
pthread_mutex_lock(&c->tcp_mutex);
@@ -2328,7 +2442,7 @@ static void do_tcp(Net_Crypto *c, void *userdata)
}
}
-/** Set function to be called when connection with crypt_connection_id goes connects/disconnects.
+/** @brief Set function to be called when connection with crypt_connection_id goes connects/disconnects.
*
* The set function should return -1 on failure and 0 on success.
* Note that if this function is set, the connection will clear itself on disconnect.
@@ -2353,7 +2467,7 @@ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
return 0;
}
-/** Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
+/** @brief Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -2376,7 +2490,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id,
return 0;
}
-/** Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
+/** @brief Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -2401,7 +2515,7 @@ int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id,
}
-/** Set the function for this friend that will be callbacked with object and number if
+/** @brief Set the function for this friend that will be callbacked with object and number if
* the friend sends us a different dht public key than we have associated to him.
*
* If this function is called, the connection should be recreated with the new public key.
@@ -2425,11 +2539,12 @@ int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb *
return 0;
}
-/** Get the crypto connection id from the ip_port.
+/** @brief Get the crypto connection id from the ip_port.
*
* return -1 on failure.
* return connection id on success.
*/
+non_null()
static int crypto_id_ip_port(const Net_Crypto *c, const IP_Port *ip_port)
{
return bs_list_find(&c->ip_port_list, (const uint8_t *)ip_port);
@@ -2437,7 +2552,7 @@ static int crypto_id_ip_port(const Net_Crypto *c, const IP_Port *ip_port)
#define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)
-/** Handle raw UDP packets coming directly from the socket.
+/** @brief Handle raw UDP packets coming directly from the socket.
*
* Handles:
* Cookie response packets.
@@ -2445,6 +2560,7 @@ static int crypto_id_ip_port(const Net_Crypto *c, const IP_Port *ip_port)
* Crypto data packets.
*
*/
+non_null(1, 2, 3) nullable(5)
static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
@@ -2468,7 +2584,7 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t
return 0;
}
- if (handle_packet_connection(c, crypt_connection_id, packet, length, 1, userdata) != 0) {
+ if (handle_packet_connection(c, crypt_connection_id, packet, length, true, userdata) != 0) {
return 1;
}
@@ -2490,24 +2606,27 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t
return 0;
}
-/** The dT for the average packet receiving rate calculations.
- * Also used as the */
+/** @brief The dT for the average packet receiving rate calculations.
+ * Also used as the
+ */
#define PACKET_COUNTER_AVERAGE_INTERVAL 50
-/** Ratio of recv queue size / recv packet rate (in seconds) times
+/** @brief Ratio of recv queue size / recv packet rate (in seconds) times
* the number of ms between request packets to send at that ratio
*/
#define REQUEST_PACKETS_COMPARE_CONSTANT (0.125 * 100.0)
-/** Timeout for increasing speed after congestion event (in ms). */
+/** @brief Timeout for increasing speed after congestion event (in ms). */
#define CONGESTION_EVENT_TIMEOUT 1000
-/** If the send queue is SEND_QUEUE_RATIO times larger than the
+/**
+ * If the send queue is SEND_QUEUE_RATIO times larger than the
* calculated link speed the packet send speed will be reduced
* by a value depending on this number.
*/
#define SEND_QUEUE_RATIO 2.0
+non_null()
static void send_crypto_packets(Net_Crypto *c)
{
const uint64_t temp_time = current_time_monotonic(c->mono_time);
@@ -2537,7 +2656,7 @@ static void send_crypto_packets(Net_Crypto *c)
double request_packet_interval = REQUEST_PACKETS_COMPARE_CONSTANT / ((num_packets_array(
&conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0));
- double request_packet_interval2 = ((CRYPTO_PACKET_MIN_RATE / conn->packet_recv_rate) *
+ const double request_packet_interval2 = ((CRYPTO_PACKET_MIN_RATE / conn->packet_recv_rate) *
(double)CRYPTO_SEND_PACKET_INTERVAL) + (double)PACKET_COUNTER_AVERAGE_INTERVAL;
if (request_packet_interval2 < request_packet_interval) {
@@ -2564,37 +2683,37 @@ static void send_crypto_packets(Net_Crypto *c)
}
if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) {
- const double dt = temp_time - conn->packet_counter_set;
+ const double dt = (double)(temp_time - conn->packet_counter_set);
conn->packet_recv_rate = (double)conn->packet_counter / (dt / 1000.0);
conn->packet_counter = 0;
conn->packet_counter_set = temp_time;
- uint32_t packets_sent = conn->packets_sent;
+ const uint32_t packets_sent = conn->packets_sent;
conn->packets_sent = 0;
- uint32_t packets_resent = conn->packets_resent;
+ const uint32_t packets_resent = conn->packets_resent;
conn->packets_resent = 0;
/* conjestion control
* calculate a new value of conn->packet_send_rate based on some data
*/
- unsigned int pos = conn->last_sendqueue_counter % CONGESTION_QUEUE_ARRAY_SIZE;
+ const unsigned int pos = conn->last_sendqueue_counter % CONGESTION_QUEUE_ARRAY_SIZE;
conn->last_sendqueue_size[pos] = num_packets_array(&conn->send_array);
long signed int sum = 0;
sum = (long signed int)conn->last_sendqueue_size[pos] -
(long signed int)conn->last_sendqueue_size[(pos + 1) % CONGESTION_QUEUE_ARRAY_SIZE];
- unsigned int n_p_pos = conn->last_sendqueue_counter % CONGESTION_LAST_SENT_ARRAY_SIZE;
+ const unsigned int n_p_pos = conn->last_sendqueue_counter % CONGESTION_LAST_SENT_ARRAY_SIZE;
conn->last_num_packets_sent[n_p_pos] = packets_sent;
conn->last_num_packets_resent[n_p_pos] = packets_resent;
conn->last_sendqueue_counter = (conn->last_sendqueue_counter + 1) %
(CONGESTION_QUEUE_ARRAY_SIZE * CONGESTION_LAST_SENT_ARRAY_SIZE);
- bool direct_connected = 0;
+ bool direct_connected = false;
/* return value can be ignored since the `if` above ensures the connection is established */
crypto_connection_status(c, i, &direct_connected, nullptr);
@@ -2605,14 +2724,14 @@ static void send_crypto_packets(Net_Crypto *c)
// TODO(irungentoo): use real delay
unsigned int delay = (unsigned int)(((double)conn->rtt_time / PACKET_COUNTER_AVERAGE_INTERVAL) + 0.5);
- unsigned int packets_set_rem_array = CONGESTION_LAST_SENT_ARRAY_SIZE - CONGESTION_QUEUE_ARRAY_SIZE;
+ const unsigned int packets_set_rem_array = CONGESTION_LAST_SENT_ARRAY_SIZE - CONGESTION_QUEUE_ARRAY_SIZE;
if (delay > packets_set_rem_array) {
delay = packets_set_rem_array;
}
for (unsigned j = 0; j < CONGESTION_QUEUE_ARRAY_SIZE; ++j) {
- unsigned int ind = (j + (packets_set_rem_array - delay) + n_p_pos) % CONGESTION_LAST_SENT_ARRAY_SIZE;
+ const unsigned int ind = (j + (packets_set_rem_array - delay) + n_p_pos) % CONGESTION_LAST_SENT_ARRAY_SIZE;
total_sent += conn->last_num_packets_sent[ind];
total_resent += conn->last_num_packets_resent[ind];
}
@@ -2626,18 +2745,18 @@ static void send_crypto_packets(Net_Crypto *c)
}
/* if queue is too big only allow resending packets. */
- uint32_t npackets = num_packets_array(&conn->send_array);
+ const uint32_t npackets = num_packets_array(&conn->send_array);
double min_speed = 1000.0 * (((double)total_sent) / ((double)CONGESTION_QUEUE_ARRAY_SIZE *
PACKET_COUNTER_AVERAGE_INTERVAL));
- double min_speed_request = 1000.0 * (((double)(total_sent + total_resent)) / (
+ const double min_speed_request = 1000.0 * (((double)(total_sent + total_resent)) / (
(double)CONGESTION_QUEUE_ARRAY_SIZE * PACKET_COUNTER_AVERAGE_INTERVAL));
if (min_speed < CRYPTO_PACKET_MIN_RATE) {
min_speed = CRYPTO_PACKET_MIN_RATE;
}
- double send_array_ratio = (double)npackets / min_speed;
+ const double send_array_ratio = (double)npackets / min_speed;
// TODO(irungentoo): Improve formula?
if (send_array_ratio > SEND_QUEUE_RATIO && CRYPTO_MIN_QUEUE_LENGTH < npackets) {
@@ -2670,8 +2789,8 @@ static void send_crypto_packets(Net_Crypto *c)
double n_packets = conn->packet_send_rate * (((double)(temp_time - conn->last_packets_left_set)) / 1000.0);
n_packets += conn->last_packets_left_rem;
- uint32_t num_packets = n_packets;
- double rem = n_packets - (double)num_packets;
+ const uint32_t num_packets = n_packets;
+ const double rem = n_packets - (double)num_packets;
if (conn->packets_left > num_packets * 4 + CRYPTO_MIN_QUEUE_LENGTH) {
conn->packets_left = num_packets * 4 + CRYPTO_MIN_QUEUE_LENGTH;
@@ -2702,7 +2821,7 @@ static void send_crypto_packets(Net_Crypto *c)
}
}
- int ret = send_requested_packets(c, i, conn->packets_left_requested);
+ const int ret = send_requested_packets(c, i, conn->packets_left_requested);
if (ret != -1) {
conn->packets_left_requested -= ret;
@@ -2730,7 +2849,7 @@ static void send_crypto_packets(Net_Crypto *c)
}
if (total_send_rate > CRYPTO_PACKET_MIN_RATE) {
- sleep_time = (1000.0 / total_send_rate);
+ sleep_time = 1000.0 / total_send_rate;
if (c->current_sleep_time > sleep_time) {
c->current_sleep_time = sleep_time + 1;
@@ -2744,16 +2863,18 @@ static void send_crypto_packets(Net_Crypto *c)
}
}
-/** Return 1 if max speed was reached for this connection (no more data can be physically through the pipe).
- * Return 0 if it wasn't reached.
+/**
+ * @retval 1 if max speed was reached for this connection (no more data can be physically through the pipe).
+ * @retval 0 if it wasn't reached.
*/
bool max_speed_reached(Net_Crypto *c, int crypt_connection_id)
{
return reset_max_speed_reached(c, crypt_connection_id) != 0;
}
-/** returns the number of packet slots left in the sendbuffer.
- * return 0 if failure.
+/**
+ * @return the number of packet slots left in the sendbuffer.
+ * @retval 0 if failure.
*/
uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id)
{
@@ -2763,7 +2884,7 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
return 0;
}
- uint32_t max_packets = CRYPTO_PACKET_BUFFER_SIZE - num_packets_array(&conn->send_array);
+ const uint32_t max_packets = CRYPTO_PACKET_BUFFER_SIZE - num_packets_array(&conn->send_array);
if (conn->packets_left < max_packets) {
return conn->packets_left;
@@ -2772,7 +2893,7 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
return max_packets;
}
-/** Sends a lossless cryptopacket.
+/** @brief Sends a lossless cryptopacket.
*
* return -1 if data could not be put in packet queue.
* return positive packet number if data was put into the queue.
@@ -2782,31 +2903,38 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
* congestion_control: should congestion control apply to this packet?
*/
int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
- uint8_t congestion_control)
+ bool congestion_control)
{
if (length == 0) {
+ // We need at least a packet id.
+ LOGGER_ERROR(c->log, "rejecting empty packet for crypto connection %d", crypt_connection_id);
return -1;
}
if (data[0] < PACKET_ID_RANGE_LOSSLESS_START || data[0] > PACKET_ID_RANGE_LOSSLESS_END) {
+ LOGGER_ERROR(c->log, "rejecting lossless packet with out-of-range id %d", data[0]);
return -1;
}
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
+ LOGGER_WARNING(c->log, "invalid crypt connection id %d", crypt_connection_id);
return -1;
}
if (conn->status != CRYPTO_CONN_ESTABLISHED) {
+ LOGGER_WARNING(c->log, "attempted to send packet to non-established connection %d", crypt_connection_id);
return -1;
}
if (congestion_control && conn->packets_left == 0) {
+ LOGGER_ERROR(c->log, "congestion control: rejecting packet of length %d on crypt connection %d", length,
+ crypt_connection_id);
return -1;
}
- int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length, congestion_control);
+ const int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length, congestion_control);
if (ret == -1) {
return -1;
@@ -2821,7 +2949,7 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
return ret;
}
-/** Check if packet_number was received by the other side.
+/** @brief Check if packet_number was received by the other side.
*
* packet_number must be a valid packet number of a packet sent on this connection.
*
@@ -2843,8 +2971,8 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t
return -1;
}
- uint32_t num = num_packets_array(&conn->send_array);
- uint32_t num1 = packet_number - conn->send_array.buffer_start;
+ const uint32_t num = num_packets_array(&conn->send_array);
+ const uint32_t num1 = packet_number - conn->send_array.buffer_start;
if (num >= num1) {
return -1;
@@ -2853,7 +2981,7 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t
return 0;
}
-/** Sends a lossy cryptopacket.
+/** @brief Sends a lossy cryptopacket.
*
* return -1 on failure.
* return 0 on success.
@@ -2878,10 +3006,10 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
int ret = -1;
- if (conn) {
+ if (conn != nullptr) {
pthread_mutex_lock(conn->mutex);
- uint32_t buffer_start = conn->recv_array.buffer_start;
- uint32_t buffer_end = conn->send_array.buffer_end;
+ const uint32_t buffer_start = conn->recv_array.buffer_start;
+ const uint32_t buffer_end = conn->send_array.buffer_end;
pthread_mutex_unlock(conn->mutex);
ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length);
}
@@ -2893,7 +3021,7 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
return ret;
}
-/** Kill a crypto connection.
+/** @brief Kill a crypto connection.
*
* return -1 on failure.
* return 0 on success.
@@ -2904,7 +3032,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
int ret = -1;
- if (conn) {
+ if (conn != nullptr) {
if (conn->status == CRYPTO_CONN_ESTABLISHED) {
send_kill_packet(c, crypt_connection_id);
}
@@ -2925,7 +3053,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
}
bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected,
- unsigned int *online_tcp_relays)
+ uint32_t *online_tcp_relays)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -2933,19 +3061,19 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool
return false;
}
- if (direct_connected) {
- *direct_connected = 0;
+ if (direct_connected != nullptr) {
+ *direct_connected = false;
const uint64_t current_time = mono_time_get(c->mono_time);
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
- *direct_connected = 1;
+ *direct_connected = true;
} else if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
- *direct_connected = 1;
+ *direct_connected = true;
}
}
- if (online_tcp_relays) {
+ if (online_tcp_relays != nullptr) {
*online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp);
}
@@ -2954,11 +3082,11 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool
void new_keys(Net_Crypto *c)
{
- crypto_new_keypair(c->self_public_key, c->self_secret_key);
+ crypto_new_keypair(c->rng, c->self_public_key, c->self_secret_key);
}
-/** Save the public and private keys to the keys array.
- * Length must be CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE.
+/** @brief Save the public and private keys to the keys array.
+ * Length must be CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE.
*
* TODO(irungentoo): Save only secret key.
*/
@@ -2968,7 +3096,7 @@ void save_keys(const Net_Crypto *c, uint8_t *keys)
memcpy(keys + CRYPTO_PUBLIC_KEY_SIZE, c->self_secret_key, CRYPTO_SECRET_KEY_SIZE);
}
-/** Load the secret key.
+/** @brief Load the secret key.
* Length must be CRYPTO_SECRET_KEY_SIZE.
*/
void load_secret_key(Net_Crypto *c, const uint8_t *sk)
@@ -2977,10 +3105,10 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
crypto_derive_public_key(c->self_public_key, c->self_secret_key);
}
-/** Create new instance of Net_Crypto.
- * Sets all the global connection variables to their default values.
+/** @brief Create new instance of Net_Crypto.
+ * Sets all the global connection variables to their default values.
*/
-Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
+Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
{
if (dht == nullptr) {
return nullptr;
@@ -2993,9 +3121,11 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, co
}
temp->log = log;
+ temp->rng = rng;
temp->mono_time = mono_time;
+ temp->ns = ns;
- temp->tcp_c = new_tcp_connections(log, mono_time, dht_get_self_secret_key(dht), proxy_info);
+ temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
if (temp->tcp_c == nullptr) {
free(temp);
@@ -3015,7 +3145,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, co
temp->dht = dht;
new_keys(temp);
- new_symmetric_key(temp->secret_symmetric_key);
+ new_symmetric_key(rng, temp->secret_symmetric_key);
temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL;
@@ -3029,6 +3159,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, co
return temp;
}
+non_null(1) nullable(2)
static void kill_timedout(Net_Crypto *c, void *userdata)
{
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
@@ -3051,15 +3182,14 @@ static void kill_timedout(Net_Crypto *c, void *userdata)
if (conn->status == CRYPTO_CONN_ESTABLISHED) {
// TODO(irungentoo): add a timeout here?
- do_timeout_here();
+ /* do_timeout_here(); */
}
#endif
}
}
-/** return the optimal interval in ms for running do_net_crypto.
- */
+/** return the optimal interval in ms for running do_net_crypto. */
uint32_t crypto_run_interval(const Net_Crypto *c)
{
return c->current_sleep_time;
@@ -3075,6 +3205,10 @@ void do_net_crypto(Net_Crypto *c, void *userdata)
void kill_net_crypto(Net_Crypto *c)
{
+ if (c == nullptr) {
+ return;
+ }
+
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
crypto_kill(c, i);
}