Squashed 'external/toxcore/c-toxcore/' changes from e58eb27a8..1828c5356

1828c5356 fix(toxav): remove extra copy of video frame on encode
b66b8ded6 refactor: improve group stability, moderation determinism, and DHT dual-stack handling
4fbd7c10a fix(toxav): fix heap buffer overflow in RTP video packet handling
809fe8c78 refactor(tox): make the `#define` consts int literals.
50d242a37 refactor(toxav): improve MSI safety and testability
da1c13a2f fix(toxav): harden video processing and fix large frame handling
472825288 fix(toxav): fix multiple logic bugs in audio module
dc963d9a9 fix(toxav): fix multiple bugs in bandwidth controller and add tests
3bf5778ef refactor(toxav): split out RTP module and add exhaustive unit tests
b79b7d436 fix(autotools): add tox_log_level.h to public headers list
ea2e34ff2 chore: Disable cirrus. We're out of quota again.
b449ea2ed chore(ci): update azure runner image to windows-2022 windows-2019 is EOL
e115b136d refactor: Make add_to_list non-recursive.
REVERT: e58eb27a8 fix(toxav): remove extra copy of video frame on encode Tested and works, but there might be alignment issues and other stuff.

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 1828c5356b2daf1d5f680854e776d74b181d268c
This commit is contained in:
Green Sky
2026-01-01 19:15:15 +01:00
parent 596ea37298
commit e95f2cbb1c
44 changed files with 4572 additions and 1137 deletions

View File

@@ -591,9 +591,18 @@ static bool client_or_ip_port_in_list(const Logger *_Nonnull log, const Mono_Tim
LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv%d)", index, ip_version);
/* kill the other address, if it was set */
const IPPTsPng empty_ipptspng = {{{{0}}}};
*assoc = empty_ipptspng;
/* kill the other address, if it was set.
* We just updated `assoc` (which is either assoc4 or assoc6) with the new public_key.
* If there was an association for the other IP version, it's now invalid for this new identity.
*/
if (ip_version == 4) {
const IPPTsPng empty_ipptspng = {{{{0}}}};
list[index].assoc6 = empty_ipptspng;
} else {
const IPPTsPng empty_ipptspng = {{{{0}}}};
list[index].assoc4 = empty_ipptspng;
}
return true;
}
@@ -601,27 +610,30 @@ bool add_to_list(
Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE],
const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE])
{
uint8_t pk_cur[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_cur, pk, CRYPTO_PUBLIC_KEY_SIZE);
IP_Port ip_port_cur = *ip_port;
bool inserted = false;
for (uint32_t i = 0; i < length; ++i) {
Node_format *node = &nodes_list[i];
if (id_closest(cmp_pk, node->public_key, pk) == 2) {
if (id_closest(cmp_pk, node->public_key, pk_cur) == 2) {
uint8_t pk_bak[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_bak, node->public_key, CRYPTO_PUBLIC_KEY_SIZE);
const IP_Port ip_port_bak = node->ip_port;
memcpy(node->public_key, pk, CRYPTO_PUBLIC_KEY_SIZE);
node->ip_port = *ip_port;
memcpy(node->public_key, pk_cur, CRYPTO_PUBLIC_KEY_SIZE);
node->ip_port = ip_port_cur;
if (i != length - 1) {
add_to_list(nodes_list, length, pk_bak, &ip_port_bak, cmp_pk);
}
return true;
memcpy(pk_cur, pk_bak, CRYPTO_PUBLIC_KEY_SIZE);
ip_port_cur = ip_port_bak;
inserted = true;
}
}
return false;
return inserted;
}
/**
@@ -638,12 +650,6 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *_Nonnull pub
for (uint32_t i = 0; i < client_list_length; ++i) {
const Client_data *const client = &client_list[i];
/* node already in list? */
if (index_of_node_pk(nodes_list, MAX_SENT_NODES, client->public_key) != UINT32_MAX) {
continue;
}
const IPPTsPng *ipptp;
if (net_family_is_ipv4(sa_family)) {
@@ -674,6 +680,11 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *_Nonnull pub
#endif /* CHECK_ANNOUNCE_NODE */
/* node already in list? */
if (index_of_node_pk(nodes_list, num_nodes, client->public_key) != UINT32_MAX) {
continue;
}
if (num_nodes < MAX_SENT_NODES) {
memcpy(nodes_list[num_nodes].public_key, client->public_key, CRYPTO_PUBLIC_KEY_SIZE);
nodes_list[num_nodes].ip_port = ipptp->ip_port;
@@ -2009,7 +2020,7 @@ static uint32_t foreach_ip_port(const DHT *_Nonnull dht, const DHT_Friend *_Nonn
static bool send_packet_to_friend(const DHT *_Nonnull dht, const IP_Port *_Nonnull ip_port, uint32_t *_Nonnull n, void *_Nonnull userdata)
{
const Packet *packet = (const Packet *)userdata;
const int retval = send_packet(dht->net, ip_port, *packet);
const int retval = net_send_packet(dht->net, ip_port, *packet);
if ((uint32_t)retval == packet->length) {
++*n;
@@ -2078,7 +2089,7 @@ static uint32_t routeone_to_friend(const DHT *_Nonnull dht, const uint8_t *_Nonn
}
const uint32_t rand_idx = random_range_u32(dht->rng, n);
const int retval = send_packet(dht->net, &ip_list[rand_idx], *packet);
const int retval = net_send_packet(dht->net, &ip_list[rand_idx], *packet);
if ((unsigned int)retval == packet->length) {
return 1;

View File

@@ -2,6 +2,7 @@ lib_LTLIBRARIES += libtoxcore.la
libtoxcore_la_include_HEADERS = \
../toxcore/tox.h \
../toxcore/tox_log_level.h \
../toxcore/tox_options.h
libtoxcore_la_includedir = $(includedir)/tox

View File

@@ -142,12 +142,7 @@ bool crypto_memunlock(void *data, size_t length)
bool pk_equal(const uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE])
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Hope that this is better for the fuzzer
return memcmp(pk1, pk2, CRYPTO_PUBLIC_KEY_SIZE) == 0;
#else
return crypto_verify_32(pk1, pk2) == 0;
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
void pk_copy(uint8_t dest[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t src[CRYPTO_PUBLIC_KEY_SIZE])
@@ -167,12 +162,7 @@ bool crypto_sha512_eq(const uint8_t cksum1[CRYPTO_SHA512_SIZE], const uint8_t ck
bool crypto_sha256_eq(const uint8_t cksum1[CRYPTO_SHA256_SIZE], const uint8_t cksum2[CRYPTO_SHA256_SIZE])
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Hope that this is better for the fuzzer
return memcmp(cksum1, cksum2, CRYPTO_SHA256_SIZE) == 0;
#else
return crypto_verify_32(cksum1, cksum2) == 0;
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
uint8_t random_u08(const Random *rng)

View File

@@ -3717,6 +3717,10 @@ Group_Chats *new_groupchats(const Mono_Time *mono_time, const Memory *mem, Messe
/** main groupchats loop. */
void do_groupchats(Group_Chats *g_c, void *userdata)
{
if (g_c == nullptr) {
return;
}
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
Group_c *g = get_group_c(g_c, i);

View File

@@ -1759,11 +1759,6 @@ static bool unpack_gc_sync_announce(GC_Chat *_Nonnull chat, const uint8_t *_Nonn
static int handle_gc_sync_response(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nullable data,
uint16_t length, void *_Nullable userdata)
{
if (chat->connection_state == CS_CONNECTED && get_gc_confirmed_numpeers(chat) >= chat->shared_state.maxpeers
&& !peer_is_founder(chat, peer_number)) {
return -1;
}
if (length > 0) {
if (!unpack_gc_sync_announce(chat, data, length)) {
return -1;
@@ -1778,6 +1773,14 @@ static int handle_gc_sync_response(const GC_Session *_Nonnull c, GC_Chat *_Nonnu
return -2;
}
/* If the group is full, we only allow already confirmed peers to sync.
* This prevents disconnecting existing peers during re-syncing.
*/
if (!gconn->confirmed && get_gc_confirmed_numpeers(chat) >= chat->shared_state.maxpeers
&& !peer_is_founder(chat, peer_number)) {
return -1;
}
if (!send_gc_peer_exchange(chat, gconn)) {
LOGGER_WARNING(chat->log, "Failed to send peer exchange on sync response");
}
@@ -2200,7 +2203,7 @@ static int handle_gc_invite_request(GC_Chat *_Nonnull chat, uint32_t peer_number
uint8_t invite_error;
if (get_gc_confirmed_numpeers(chat) >= chat->shared_state.maxpeers && !peer_is_founder(chat, peer_number)) {
if (!gconn->confirmed && get_gc_confirmed_numpeers(chat) >= chat->shared_state.maxpeers && !peer_is_founder(chat, peer_number)) {
invite_error = GJ_GROUP_FULL;
goto FAILED_INVITE;
}
@@ -3828,12 +3831,6 @@ static bool handle_gc_topic_validate(const GC_Chat *_Nonnull chat, const GC_Peer
return true;
}
if (chat->topic_prev_checksum == topic_info->checksum &&
!mono_time_is_timeout(chat->mono_time, chat->topic_time_set, GC_CONFIRMED_PEER_TIMEOUT)) {
LOGGER_DEBUG(chat->log, "Topic reversion (probable sync error)");
return false;
}
return true;
}
@@ -3893,11 +3890,17 @@ static int handle_gc_topic(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat,
chat->topic_info = topic_info;
memcpy(chat->topic_sig, signature, SIGNATURE_SIZE);
if (!skip_callback && chat->connection_state == CS_CONNECTED && c->topic_change != nullptr) {
const int setter_peer_number = get_peer_number_of_sig_pk(chat, topic_info.public_sig_key);
const GC_Peer_Id peer_id = setter_peer_number >= 0 ? chat->group[setter_peer_number].peer_id : gc_unknown_peer_id();
if (!skip_callback && chat->connection_state == CS_CONNECTED) {
if (gc_get_self_role(chat) == GR_FOUNDER) {
broadcast_gc_topic(chat);
}
c->topic_change(c->messenger, chat->group_number, peer_id, topic_info.topic, topic_info.length, userdata);
if (c->topic_change != nullptr) {
const int setter_peer_number = get_peer_number_of_sig_pk(chat, topic_info.public_sig_key);
const GC_Peer_Id peer_id = setter_peer_number >= 0 ? chat->group[setter_peer_number].peer_id : gc_unknown_peer_id();
c->topic_change(c->messenger, chat->group_number, peer_id, topic_info.topic, topic_info.length, userdata);
}
}
return 0;
@@ -5530,7 +5533,9 @@ static bool send_gc_handshake_packet(const GC_Chat *_Nonnull chat, GC_Connection
}
if (ret != length && gconn->tcp_relays_count == 0) {
LOGGER_WARNING(chat->log, "UDP handshake failed and no TCP relays to fall back on");
Ip_Ntoa ip_str;
LOGGER_WARNING(chat->log, "UDP handshake failed and no TCP relays to fall back on. ret: %d, target: %s:%u",
ret, net_ip_ntoa(&gconn->addr.ip_port.ip, &ip_str), net_ntohs(gconn->addr.ip_port.port));
return false;
}
@@ -5588,7 +5593,8 @@ static bool send_gc_oob_handshake_request(const GC_Chat *chat, const GC_Connecti
* Returns peer_number of new connected peer on success.
* Returns -1 on failure.
*/
static int handle_gc_handshake_response(const GC_Chat *_Nonnull chat, const uint8_t *_Nonnull sender_pk, const uint8_t *_Nonnull data, uint16_t length)
static int handle_gc_handshake_response(const GC_Chat *_Nonnull chat, const IP_Port *_Nullable ipp,
const uint8_t *_Nonnull sender_pk, const uint8_t *_Nonnull data, uint16_t length)
{
// this should be checked at lower level; this is a redundant defense check. Ideally we should
// guarantee that this can never happen in the future.
@@ -5609,6 +5615,11 @@ static int handle_gc_handshake_response(const GC_Chat *_Nonnull chat, const uint
return -1;
}
if (ipp != nullptr) {
gcc_set_ip_port(gconn, ipp);
gconn->last_received_direct_time = mono_time_get(chat->mono_time);
}
const uint8_t *sender_session_pk = data;
gcc_make_session_shared_key(gconn, sender_session_pk);
@@ -5666,7 +5677,7 @@ static bool send_gc_handshake_response(const GC_Chat *_Nonnull chat, GC_Connecti
* Return new peer's peer_number on success.
* Return -1 on failure.
*/
#define GC_NEW_PEER_CONNECTION_LIMIT 10
#define GC_NEW_PEER_CONNECTION_LIMIT 32
static int handle_gc_handshake_request(GC_Chat *_Nonnull chat, const IP_Port *_Nullable ipp, const uint8_t *_Nonnull sender_pk,
const uint8_t *_Nonnull data, uint16_t length)
{
@@ -5682,14 +5693,6 @@ static int handle_gc_handshake_request(GC_Chat *_Nonnull chat, const IP_Port *_N
return -1;
}
if (chat->connection_o_metre >= GC_NEW_PEER_CONNECTION_LIMIT) {
chat->block_handshakes = true;
LOGGER_DEBUG(chat->log, "Handshake overflow. Blocking handshakes.");
return -1;
}
++chat->connection_o_metre;
const uint8_t *public_sig_key = data + ENC_PUBLIC_KEY_SIZE;
const uint8_t request_type = data[ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE];
@@ -5715,18 +5718,18 @@ static int handle_gc_handshake_request(GC_Chat *_Nonnull chat, const IP_Port *_N
if (gconn->handshaked) {
gconn->handshaked = false;
LOGGER_DEBUG(chat->log, "Handshaked peer sent a handshake request");
return -1;
}
// peers sent handshake request at same time so the closer peer becomes the requestor
// and ignores the request packet while further peer continues on with the response
if (gconn->self_is_closer) {
LOGGER_DEBUG(chat->log, "Simultaneous handshake requests; other peer is closer");
return 0;
LOGGER_DEBUG(chat->log, "Handshaked peer %d sent a handshake request; re-handshaking", peer_number);
}
}
if (chat->connection_o_metre >= GC_NEW_PEER_CONNECTION_LIMIT) {
chat->block_handshakes = true;
LOGGER_DEBUG(chat->log, "Handshake overflow. Blocking handshakes.");
return -1;
}
++chat->connection_o_metre;
GC_Connection *gconn = get_gc_connection(chat, peer_number);
if (gconn == nullptr) {
@@ -5734,7 +5737,10 @@ static int handle_gc_handshake_request(GC_Chat *_Nonnull chat, const IP_Port *_N
return -1;
}
gcc_set_ip_port(gconn, ipp);
if (ipp != nullptr) {
gcc_set_ip_port(gconn, ipp);
gconn->last_received_direct_time = mono_time_get(chat->mono_time);
}
Node_format node[GCA_MAX_ANNOUNCED_TCP_RELAYS];
const int processed = ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE + 1 + 1;
@@ -5824,7 +5830,7 @@ static int handle_gc_handshake_packet(GC_Chat *_Nonnull chat, const uint8_t *_No
if (handshake_type == GH_REQUEST) {
peer_number = handle_gc_handshake_request(chat, ipp, sender_pk, real_data, real_len);
} else if (handshake_type == GH_RESPONSE) {
peer_number = handle_gc_handshake_response(chat, sender_pk, real_data, real_len);
peer_number = handle_gc_handshake_response(chat, ipp, sender_pk, real_data, real_len);
} else {
mem_delete(chat->mem, data);
return -1;
@@ -5832,16 +5838,6 @@ static int handle_gc_handshake_packet(GC_Chat *_Nonnull chat, const uint8_t *_No
mem_delete(chat->mem, data);
GC_Connection *gconn = get_gc_connection(chat, peer_number);
if (gconn == nullptr) {
return -1;
}
if (direct_conn) {
gconn->last_received_direct_time = mono_time_get(chat->mono_time);
}
return peer_number;
}
@@ -6718,6 +6714,7 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key)
gconn->last_received_packet_time = tm;
gconn->last_key_rotation = tm;
gconn->tcp_connection_num = tcp_connection_num;
gconn->friend_number = -1;
gconn->last_sent_ip_time = tm;
gconn->last_sent_ping_time = tm - (GC_PING_TIMEOUT / 2) + (peer_number % (GC_PING_TIMEOUT / 2));
gconn->self_is_closer = id_closest(get_chat_id(&chat->chat_public_key),
@@ -6820,13 +6817,26 @@ static void do_peer_connections(const GC_Session *_Nonnull c, GC_Chat *_Nonnull
* load peers from our saved peers list and initiate handshake requests with them.
*/
#define LOAD_PEERS_TIMEOUT (GC_UNCONFIRMED_PEER_TIMEOUT + 10)
static void do_handshakes(GC_Chat *_Nonnull chat)
static bool copy_friend_ip_port_to_gconn(const Messenger *_Nonnull m, int friend_number, GC_Connection *_Nonnull gconn);
static void do_handshakes(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat)
{
for (uint32_t i = 1; i < chat->numpeers; ++i) {
GC_Connection *gconn = get_gc_connection(chat, i);
assert(gconn != nullptr);
if (gconn->handshaked || gconn->pending_delete) {
if (gconn->pending_delete) {
continue;
}
/* If we don't have an IP/port for this peer yet, try to get it from the messenger friend connection.
* This might happen if the friend's DHT IP/port was not yet known when we handled the invite.
*/
if (!gconn->handshaked && !gcc_ip_port_is_set(gconn) && gconn->friend_number != -1) {
copy_friend_ip_port_to_gconn(c->messenger, gconn->friend_number, gconn);
}
if (gconn->handshaked) {
continue;
}
@@ -7028,10 +7038,12 @@ static void do_gc_tcp(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, void
set_tcp_connection_to_status(chat->tcp_conn, gconn->tcp_connection_num, tcp_set);
}
const uint32_t main_tcp_connected_count = tcp_connected_relays_count(nc_get_tcp_c(c->messenger->net_crypto));
if (mono_time_is_timeout(chat->mono_time, chat->last_checked_tcp_relays, TCP_RELAYS_CHECK_INTERVAL)
&& tcp_connected_relays_count(chat->tcp_conn) != chat->connected_tcp_relays) {
&& main_tcp_connected_count != chat->connected_tcp_relays) {
add_tcp_relays_to_chat(c, chat);
chat->connected_tcp_relays = tcp_connected_relays_count(chat->tcp_conn);
chat->connected_tcp_relays = main_tcp_connected_count;
chat->last_checked_tcp_relays = mono_time_get(chat->mono_time);
}
}
@@ -7130,7 +7142,7 @@ void do_gc(GC_Session *c, void *userdata)
if (state != CS_DISCONNECTED) {
do_peer_connections(c, chat, userdata);
do_gc_tcp(c, chat, userdata);
do_handshakes(chat);
do_handshakes(c, chat);
do_self_connection(c, chat);
}
@@ -7298,6 +7310,7 @@ static int create_new_group(const Memory *_Nonnull mem, GC_Session *_Nonnull c,
const int group_number = get_new_group_index(mem, c);
if (group_number == -1) {
LOGGER_DEBUG(c->messenger->log, "get_new_group_index failed");
return -1;
}
@@ -7328,16 +7341,19 @@ static int create_new_group(const Memory *_Nonnull mem, GC_Session *_Nonnull c,
init_gc_moderation(chat);
if (!init_gc_tcp_connection(c, chat)) {
LOGGER_DEBUG(chat->log, "init_gc_tcp_connection failed");
group_delete(c, chat);
return -1;
}
if (peer_add(chat, nullptr, chat->self_public_key.enc) != 0) { /* you are always peer_number/index 0 */
LOGGER_DEBUG(chat->log, "peer_add failed");
group_delete(c, chat);
return -1;
}
if (!self_gc_set_nick(chat, nick, (uint16_t)nick_length)) {
LOGGER_DEBUG(chat->log, "self_gc_set_nick failed");
group_delete(c, chat);
return -1;
}
@@ -7517,7 +7533,12 @@ int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state,
crypto_memlock(&chat->chat_secret_key, sizeof(chat->chat_secret_key));
create_extended_keypair(&chat->chat_public_key, &chat->chat_secret_key, chat->rng);
/* Ensure we have a valid keypair for the group. */
if (!create_extended_keypair(&chat->chat_public_key, &chat->chat_secret_key, chat->rng)) {
crypto_memunlock(&chat->chat_secret_key, sizeof(chat->chat_secret_key));
group_delete(c, chat);
return -3;
}
if (!init_gc_shared_state_founder(chat, privacy_state, group_name, group_name_length)) {
group_delete(c, chat);
@@ -7893,7 +7914,11 @@ int handle_gc_invite_confirmed_packet(const GC_Session *c, int friend_number, co
nullptr, data + ENC_PUBLIC_KEY_SIZE + CHAT_ID_SIZE,
length - GC_JOIN_DATA_LENGTH, true);
const bool copy_ip_port_result = copy_friend_ip_port_to_gconn(c->messenger, friend_number, gconn);
bool has_ip_port = gcc_ip_port_is_set(gconn);
if (!has_ip_port) {
has_ip_port = copy_friend_ip_port_to_gconn(c->messenger, friend_number, gconn);
}
gconn->friend_number = friend_number;
uint32_t tcp_relays_added = 0;
@@ -7903,7 +7928,7 @@ int handle_gc_invite_confirmed_packet(const GC_Session *c, int friend_number, co
LOGGER_WARNING(chat->log, "Invite confirm packet did not contain any TCP relays");
}
if (tcp_relays_added == 0 && !copy_ip_port_result) {
if (tcp_relays_added == 0 && !has_ip_port) {
LOGGER_ERROR(chat->log, "Got invalid connection info from peer");
return -5;
}
@@ -7957,11 +7982,15 @@ bool handle_gc_invite_accepted_packet(const GC_Session *c, int friend_number, co
}
Node_format tcp_relays[GCC_MAX_TCP_SHARED_RELAYS];
const uint32_t num_tcp_relays = tcp_copy_connected_relays(chat->tcp_conn, tcp_relays, GCC_MAX_TCP_SHARED_RELAYS);
const uint32_t num_tcp_relays = tcp_copy_connected_relays(nc_get_tcp_c(m->net_crypto), tcp_relays, GCC_MAX_TCP_SHARED_RELAYS);
const bool copy_ip_port_result = copy_friend_ip_port_to_gconn(m, friend_number, gconn);
bool has_ip_port = gcc_ip_port_is_set(gconn);
if (!has_ip_port) {
has_ip_port = copy_friend_ip_port_to_gconn(m, friend_number, gconn);
}
gconn->friend_number = friend_number;
if (num_tcp_relays == 0 && !copy_ip_port_result) {
if (num_tcp_relays == 0 && !has_ip_port) {
return false;
}
@@ -7974,7 +8003,7 @@ bool handle_gc_invite_accepted_packet(const GC_Session *c, int friend_number, co
if (num_tcp_relays > 0) {
const uint32_t tcp_relays_added = add_gc_tcp_relays(chat, gconn, tcp_relays, num_tcp_relays);
if (tcp_relays_added == 0 && !copy_ip_port_result) {
if (tcp_relays_added == 0 && !has_ip_port) {
LOGGER_ERROR(chat->log, "Got invalid connection info from peer");
return false;
}
@@ -7982,7 +8011,7 @@ bool handle_gc_invite_accepted_packet(const GC_Session *c, int friend_number, co
const int nodes_len = pack_nodes(chat->log, out_data + len, sizeof(out_data) - len, tcp_relays,
(uint16_t)num_tcp_relays);
if (nodes_len <= 0 && !copy_ip_port_result) {
if (nodes_len <= 0 && !has_ip_port) {
return false;
}

View File

@@ -112,6 +112,7 @@ typedef struct GC_Connection {
uint8_t session_shared_key[CRYPTO_SHARED_KEY_SIZE]; /* made with our session sk and peer's session pk */
int tcp_connection_num;
int32_t friend_number; /* The messenger friend number associated with this group connection. Used to discover the peer's IP/port if it wasn't available during the initial invite. */
uint64_t last_sent_tcp_relays_time; /* the last time we attempted to send this peer our tcp relays */
uint16_t tcp_relay_share_index;
uint64_t last_received_direct_time; /* the last time we received a direct UDP packet from this connection */

View File

@@ -556,7 +556,7 @@ void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn)
const uint16_t start = gconn->send_array_start;
const uint16_t end = gconn->send_message_id % GCC_BUFFER_SIZE;
GC_Message_Array_Entry *array_entry = &gconn->send_array[start];
const GC_Message_Array_Entry *array_entry = &gconn->send_array[start];
if (array_entry_is_empty(array_entry)) {
return;
@@ -569,23 +569,23 @@ void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn)
}
for (uint16_t i = start; i != end; i = (i + 1) % GCC_BUFFER_SIZE) {
array_entry = &gconn->send_array[i];
GC_Message_Array_Entry *const array_entry_loop = &gconn->send_array[i];
if (array_entry_is_empty(array_entry)) {
if (array_entry_is_empty(array_entry_loop)) {
continue;
}
if (tm == array_entry->last_send_try) {
if (tm == array_entry_loop->last_send_try) {
continue;
}
const uint64_t delta = array_entry->last_send_try - array_entry->time_added;
array_entry->last_send_try = tm;
const uint64_t delta = array_entry_loop->last_send_try - array_entry_loop->time_added;
array_entry_loop->last_send_try = tm;
/* if this occurrs less than once per second this won't be reliable */
if (delta > 1 && is_power_of_2(delta)) {
gcc_encrypt_and_send_lossless_packet(chat, gconn, array_entry->data, array_entry->data_length,
array_entry->message_id, array_entry->packet_type);
gcc_encrypt_and_send_lossless_packet(chat, gconn, array_entry_loop->data, array_entry_loop->data_length,
array_entry_loop->message_id, array_entry_loop->packet_type);
}
}
}

View File

@@ -10,6 +10,7 @@
#include "group_moderation.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -23,6 +24,30 @@
#include "network.h"
#include "util.h"
static int compare_signatures(const void *a, const void *b)
{
return memcmp(a, b, SIGNATURE_SIZE);
}
static int compare_sig_pks(const void *a, const void *b)
{
return memcmp(a, b, SIG_PUBLIC_KEY_SIZE);
}
static int compare_sanctions(const void *a, const void *b)
{
const Mod_Sanction *sa = (const Mod_Sanction *)a;
const Mod_Sanction *sb = (const Mod_Sanction *)b;
return memcmp(sa->signature, sb->signature, SIGNATURE_SIZE);
}
static int compare_mod_pointers(const void *a, const void *b)
{
const uint8_t *const *mod_a = (const uint8_t *const *)a;
const uint8_t *const *mod_b = (const uint8_t *const *)b;
return memcmp(*mod_a, *mod_b, SIG_PUBLIC_KEY_SIZE);
}
static_assert(MOD_SANCTIONS_CREDS_SIZE <= MAX_PACKET_SIZE_NO_HEADERS,
"MOD_SANCTIONS_CREDS_SIZE must be <= the maximum allowed payload size");
static_assert(MOD_MAX_NUM_SANCTIONS * MOD_SANCTION_PACKED_SIZE + MOD_SANCTIONS_CREDS_SIZE <= MAX_PACKET_SIZE_NO_HEADERS,
@@ -34,6 +59,7 @@ static_assert(MOD_MAX_NUM_MODERATORS <= MOD_MAX_NUM_MODERATORS_LIMIT,
static_assert(MOD_MAX_NUM_SANCTIONS <= MOD_MAX_NUM_SANCTIONS_LIMIT,
"MOD_MAX_NUM_SANCTIONS must be <= MOD_MAX_NUM_SANCTIONS_LIMIT");
/** @brief Returns the size in bytes of the packed moderation list. */
uint16_t mod_list_packed_size(const Moderation *_Nonnull moderation)
{
return moderation->num_mods * MOD_LIST_ENTRY_SIZE;
@@ -76,6 +102,8 @@ int mod_list_unpack(Moderation *_Nonnull moderation, const uint8_t *_Nonnull dat
moderation->mod_list = tmp_list;
moderation->num_mods = num_mods;
qsort(moderation->mod_list, moderation->num_mods, sizeof(uint8_t *), compare_mod_pointers);
return unpacked_len;
}
@@ -110,6 +138,8 @@ bool mod_list_make_hash(const Moderation *_Nonnull moderation, uint8_t *_Nonnull
mod_list_pack(moderation, data);
qsort(data, moderation->num_mods, SIG_PUBLIC_KEY_SIZE, compare_sig_pks);
mod_list_get_data_hash(hash, data, data_buf_size);
mem_delete(moderation->mem, data);
@@ -176,6 +206,8 @@ bool mod_list_remove_index(Moderation *_Nonnull moderation, uint16_t index)
moderation->mod_list = tmp_list;
qsort(moderation->mod_list, moderation->num_mods, sizeof(uint8_t *), compare_mod_pointers);
return true;
}
@@ -221,6 +253,8 @@ bool mod_list_add_entry(Moderation *_Nonnull moderation, const uint8_t *_Nonnull
tmp_list[moderation->num_mods] = entry;
++moderation->num_mods;
qsort(moderation->mod_list, moderation->num_mods, sizeof(uint8_t *), compare_mod_pointers);
return true;
}
@@ -430,6 +464,8 @@ static bool sanctions_list_make_hash(const Memory *_Nonnull mem, const Mod_Sanct
memcpy(&data[i * SIGNATURE_SIZE], sanctions[i].signature, SIGNATURE_SIZE);
}
qsort(data, num_sanctions, SIGNATURE_SIZE, compare_signatures);
memcpy(&data[sig_data_size], &new_version, sizeof(uint32_t));
crypto_sha256(hash, data, data_buf_size);
@@ -594,6 +630,8 @@ static bool sanctions_apply_new(Moderation *_Nonnull moderation, Mod_Sanction *_
moderation->sanctions_creds = *new_creds;
}
qsort(new_sanctions, num_sanctions, sizeof(Mod_Sanction), compare_sanctions);
sanctions_list_cleanup(moderation);
moderation->sanctions = new_sanctions;
moderation->num_sanctions = num_sanctions;
@@ -805,7 +843,8 @@ bool sanctions_list_make_entry(Moderation *_Nonnull moderation, const uint8_t *_
memcpy(sanction->setter_public_sig_key, moderation->self_public_sig_key, SIG_PUBLIC_KEY_SIZE);
sanction->time_set = (uint64_t)time(nullptr);
/* Use a stable non-zero value to ensure deterministic signatures and hashes. */
sanction->time_set = 1;
sanction->type = type;
if (!sanctions_list_sign_entry(moderation, sanction)) {

View File

@@ -85,12 +85,12 @@ typedef enum Packet_Id {
#define CRYPTO_MIN_QUEUE_LENGTH 64
/** Maximum total size of packets that net_crypto sends. */
#define MAX_CRYPTO_PACKET_SIZE (uint16_t)1400
#define MAX_CRYPTO_PACKET_SIZE 1400
#define CRYPTO_DATA_PACKET_MIN_SIZE (uint16_t)(1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + CRYPTO_MAC_SIZE)
#define CRYPTO_DATA_PACKET_MIN_SIZE (1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + CRYPTO_MAC_SIZE)
/** Max size of data in packets */
#define MAX_CRYPTO_DATA_SIZE (uint16_t)(MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
/** Interval in ms between sending cookie request/handshake packets. */
#define CRYPTO_SEND_PACKET_INTERVAL 1000

View File

@@ -838,7 +838,7 @@ uint16_t net_port(const Networking_Core *net)
/* Basic network functions:
*/
int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packet)
int net_send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packet)
{
IP_Port ipp_copy = *ip_port;
@@ -919,12 +919,12 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe
/**
* Function to send packet(data) of length length to ip_port.
*
* @deprecated Use send_packet instead.
* @deprecated Use net_send_packet instead.
*/
int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t *data, uint16_t length)
{
const Packet packet = {data, length};
return send_packet(net, ip_port, packet);
return net_send_packet(net, ip_port, packet);
}
/** @brief Function to receive data

View File

@@ -448,7 +448,7 @@ bool set_socket_dualstack(const Network *_Nonnull ns, Socket sock);
/**
* An outgoing network packet.
*
* Use `send_packet` to send it to an IP/port endpoint.
* Use `net_send_packet` to send it to an IP/port endpoint.
*/
typedef struct Packet {
const uint8_t *_Nonnull data;
@@ -458,12 +458,12 @@ typedef struct Packet {
/**
* Function to send a network packet to a given IP/port.
*/
int send_packet(const Networking_Core *_Nonnull net, const IP_Port *_Nonnull ip_port, Packet packet);
int net_send_packet(const Networking_Core *_Nonnull net, const IP_Port *_Nonnull ip_port, Packet packet);
/**
* Function to send packet(data) of length length to ip_port.
*
* @deprecated Use send_packet instead.
* @deprecated Use net_send_packet instead.
*/
int sendpacket(const Networking_Core *_Nonnull net, const IP_Port *_Nonnull ip_port, const uint8_t *_Nonnull data, uint16_t length);

View File

@@ -239,7 +239,7 @@ uint32_t tox_conference_id_size(void);
/**
* @brief The size of the nospam in bytes when written in a Tox address.
*/
#define TOX_NOSPAM_SIZE (sizeof(uint32_t))
#define TOX_NOSPAM_SIZE 4
uint32_t tox_nospam_size(void);
@@ -253,7 +253,7 @@ uint32_t tox_nospam_size(void);
* byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
* XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam.
*/
#define TOX_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + TOX_NOSPAM_SIZE + sizeof(uint16_t))
#define TOX_ADDRESS_SIZE 38
uint32_t tox_address_size(void);