Merge commit '9ddeea3d06045c8ae38cd2d6eed0fc2891c6e146'
This commit is contained in:
46
external/toxcore/c-toxcore/toxcore/BUILD.bazel
vendored
46
external/toxcore/c-toxcore/toxcore/BUILD.bazel
vendored
@ -2,10 +2,11 @@ load("@rules_cc//cc:defs.bzl", "cc_test")
|
||||
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
|
||||
load("//tools:no_undefined.bzl", "cc_library")
|
||||
|
||||
package(features = ["layering_check"])
|
||||
|
||||
exports_files(
|
||||
srcs = ["tox.h"],
|
||||
srcs = [
|
||||
"tox.h",
|
||||
"tox_private.h",
|
||||
],
|
||||
visibility = ["//c-toxcore:__pkg__"],
|
||||
)
|
||||
|
||||
@ -76,6 +77,22 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "logger",
|
||||
srcs = ["logger.c"],
|
||||
hdrs = ["logger.h"],
|
||||
visibility = [
|
||||
"//c-toxcore/auto_tests:__pkg__",
|
||||
"//c-toxcore/other:__pkg__",
|
||||
"//c-toxcore/other/bootstrap_daemon:__pkg__",
|
||||
"//c-toxcore/toxav:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "bin_pack",
|
||||
srcs = ["bin_pack.c"],
|
||||
@ -84,6 +101,7 @@ cc_library(
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":logger",
|
||||
"//c-toxcore/third_party:cmp",
|
||||
],
|
||||
)
|
||||
@ -158,22 +176,6 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "logger",
|
||||
srcs = ["logger.c"],
|
||||
hdrs = ["logger.h"],
|
||||
visibility = [
|
||||
"//c-toxcore/auto_tests:__pkg__",
|
||||
"//c-toxcore/other:__pkg__",
|
||||
"//c-toxcore/other/bootstrap_daemon:__pkg__",
|
||||
"//c-toxcore/toxav:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "state",
|
||||
srcs = ["state.c"],
|
||||
@ -339,6 +341,7 @@ cc_library(
|
||||
deps = [
|
||||
":LAN_discovery",
|
||||
":attributes",
|
||||
":bin_pack",
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":logger",
|
||||
@ -366,6 +369,7 @@ cc_test(
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "DHT_fuzz_test",
|
||||
size = "small",
|
||||
srcs = ["DHT_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"],
|
||||
deps = [
|
||||
@ -405,6 +409,7 @@ cc_library(
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "forwarding_fuzz_test",
|
||||
size = "small",
|
||||
srcs = ["forwarding_fuzz_test.cc"],
|
||||
#corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"],
|
||||
deps = [
|
||||
@ -603,6 +608,7 @@ cc_library(
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "group_announce_fuzz_test",
|
||||
size = "small",
|
||||
srcs = ["group_announce_fuzz_test.cc"],
|
||||
#corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"],
|
||||
deps = [
|
||||
@ -706,6 +712,7 @@ cc_test(
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "group_moderation_fuzz_test",
|
||||
size = "small",
|
||||
srcs = ["group_moderation_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:group_moderation_fuzz_test"],
|
||||
deps = [
|
||||
@ -862,6 +869,7 @@ cc_test(
|
||||
|
||||
cc_fuzz_test(
|
||||
name = "tox_events_fuzz_test",
|
||||
size = "small",
|
||||
srcs = ["tox_events_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"],
|
||||
deps = [
|
||||
|
119
external/toxcore/c-toxcore/toxcore/DHT.c
vendored
119
external/toxcore/c-toxcore/toxcore/DHT.c
vendored
@ -9,10 +9,12 @@
|
||||
#include "DHT.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "LAN_discovery.h"
|
||||
#include "bin_pack.h"
|
||||
#include "ccompat.h"
|
||||
#include "logger.h"
|
||||
#include "mono_time.h"
|
||||
@ -360,12 +362,32 @@ int packed_node_size(Family ip_family)
|
||||
}
|
||||
|
||||
|
||||
int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port)
|
||||
/** @brief Packs an IP structure.
|
||||
*
|
||||
* It's the caller's responsibility to make sure `is_ipv4` tells the truth. This
|
||||
* function is an implementation detail of @ref bin_pack_ip_port.
|
||||
*
|
||||
* @param is_ipv4 whether this IP is an IP4 or IP6.
|
||||
*
|
||||
* @retval true on success.
|
||||
*/
|
||||
non_null()
|
||||
static bool bin_pack_ip(Bin_Pack *bp, const IP *ip, bool is_ipv4)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
return -1;
|
||||
if (is_ipv4) {
|
||||
return bin_pack_bin_b(bp, ip->ip.v4.uint8, SIZE_IP4);
|
||||
} else {
|
||||
return bin_pack_bin_b(bp, ip->ip.v6.uint8, SIZE_IP6);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Packs an IP_Port structure.
|
||||
*
|
||||
* @retval true on success.
|
||||
*/
|
||||
non_null()
|
||||
static bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port)
|
||||
{
|
||||
bool is_ipv4;
|
||||
uint8_t family;
|
||||
|
||||
@ -387,32 +409,34 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
|
||||
// TODO(iphydf): Find out why we're trying to pack invalid IPs, stop
|
||||
// doing that, and turn this into an error.
|
||||
LOGGER_TRACE(logger, "cannot pack invalid IP: %s", net_ip_ntoa(&ip_port->ip, &ip_str));
|
||||
return false;
|
||||
}
|
||||
|
||||
return bin_pack_u08_b(bp, family)
|
||||
&& bin_pack_ip(bp, &ip_port->ip, is_ipv4)
|
||||
&& bin_pack_u16_b(bp, net_ntohs(ip_port->port));
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool bin_pack_ip_port_handler(Bin_Pack *bp, const Logger *logger, const void *obj)
|
||||
{
|
||||
return bin_pack_ip_port(bp, logger, (const IP_Port *)obj);
|
||||
}
|
||||
|
||||
int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port)
|
||||
{
|
||||
const uint32_t size = bin_pack_obj_size(bin_pack_ip_port_handler, logger, ip_port);
|
||||
|
||||
if (size > length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_ipv4) {
|
||||
const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);
|
||||
|
||||
if (size > length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = family;
|
||||
memcpy(data + 1, &ip_port->ip.ip.v4, SIZE_IP4);
|
||||
memcpy(data + 1 + SIZE_IP4, &ip_port->port, sizeof(uint16_t));
|
||||
return size;
|
||||
} else {
|
||||
const uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t);
|
||||
|
||||
if (size > length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = family;
|
||||
memcpy(data + 1, &ip_port->ip.ip.v6, SIZE_IP6);
|
||||
memcpy(data + 1 + SIZE_IP6, &ip_port->port, sizeof(uint16_t));
|
||||
return size;
|
||||
if (!bin_pack_obj(bin_pack_ip_port_handler, logger, ip_port, data, length)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(size < INT_MAX);
|
||||
return (int)size;
|
||||
}
|
||||
|
||||
int dht_create_packet(const Memory *mem, const Random *rng,
|
||||
@ -511,33 +535,25 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Pack a single node from a node array.
|
||||
*
|
||||
* @retval true on success.
|
||||
*/
|
||||
non_null()
|
||||
static bool bin_pack_node_handler(Bin_Pack *bp, const Logger *logger, const void *arr, uint32_t index)
|
||||
{
|
||||
const Node_format *nodes = (const Node_format *)arr;
|
||||
return bin_pack_ip_port(bp, logger, &nodes[index].ip_port)
|
||||
&& bin_pack_bin_b(bp, nodes[index].public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
}
|
||||
|
||||
int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number)
|
||||
{
|
||||
uint32_t packed_length = 0;
|
||||
|
||||
for (uint32_t i = 0; i < number && packed_length < length; ++i) {
|
||||
const int ipp_size = pack_ip_port(logger, data + packed_length, length - packed_length, &nodes[i].ip_port);
|
||||
|
||||
if (ipp_size == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
packed_length += ipp_size;
|
||||
|
||||
if (packed_length + CRYPTO_PUBLIC_KEY_SIZE > length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(data + packed_length, nodes[i].public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
packed_length += CRYPTO_PUBLIC_KEY_SIZE;
|
||||
|
||||
#ifndef NDEBUG
|
||||
const uint32_t increment = ipp_size + CRYPTO_PUBLIC_KEY_SIZE;
|
||||
assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
|
||||
#endif
|
||||
const uint32_t size = bin_pack_obj_array_size(bin_pack_node_handler, logger, nodes, number);
|
||||
if (!bin_pack_obj_array(bin_pack_node_handler, logger, nodes, number, data, length)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return packed_length;
|
||||
return size;
|
||||
}
|
||||
|
||||
int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
|
||||
@ -2829,8 +2845,9 @@ void dht_save(const DHT *dht, uint8_t *data)
|
||||
}
|
||||
}
|
||||
|
||||
state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num,
|
||||
clients, num), DHT_STATE_TYPE_NODES);
|
||||
state_write_section_header(
|
||||
old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, clients, num),
|
||||
DHT_STATE_TYPE_NODES);
|
||||
|
||||
mem_delete(dht->mem, clients);
|
||||
}
|
||||
|
20
external/toxcore/c-toxcore/toxcore/DHT.h
vendored
20
external/toxcore/c-toxcore/toxcore/DHT.h
vendored
@ -214,6 +214,16 @@ int packed_node_size(Family ip_family);
|
||||
non_null()
|
||||
int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port);
|
||||
|
||||
/** @brief Unpack IP_Port structure from data of max size length into ip_port.
|
||||
*
|
||||
* len_processed is the offset of data currently unpacked.
|
||||
*
|
||||
* @return size of unpacked ip_port on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled);
|
||||
|
||||
/** @brief Encrypt plain and write resulting DHT packet into packet with max size length.
|
||||
*
|
||||
* @return size of packet on success.
|
||||
@ -226,16 +236,6 @@ int dht_create_packet(const Memory *mem, const Random *rng,
|
||||
const uint8_t *plain, size_t plain_length,
|
||||
uint8_t *packet, size_t length);
|
||||
|
||||
/** @brief Unpack IP_Port structure from data of max size length into ip_port.
|
||||
*
|
||||
* len_processed is the offset of data currently unpacked.
|
||||
*
|
||||
* @return size of unpacked ip_port on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled);
|
||||
|
||||
/** @brief Pack number of nodes into data of maxlength length.
|
||||
*
|
||||
* @return length of packed nodes on success.
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "DHT.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "../testing/fuzzing/fuzz_support.h"
|
||||
@ -36,6 +38,16 @@ void TestUnpackNodes(Fuzz_Data &input)
|
||||
LOGGER_ASSERT(logger, packed_size == processed_data_len,
|
||||
"packed size (%d) != unpacked size (%d)", packed_size, processed_data_len);
|
||||
logger_kill(logger);
|
||||
|
||||
// Check that packed nodes can be unpacked again and result in the
|
||||
// original unpacked nodes.
|
||||
Node_format nodes2[node_count];
|
||||
uint16_t processed_data_len2;
|
||||
const int packed_count2 = unpack_nodes(
|
||||
nodes2, node_count, &processed_data_len2, packed.data(), packed.size(), tcp_enabled);
|
||||
assert(processed_data_len2 == processed_data_len);
|
||||
assert(packed_count2 == packed_count);
|
||||
assert(memcmp(nodes, nodes2, sizeof(Node_format) * packed_count) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
lib_LTLIBRARIES += libtoxcore.la
|
||||
|
||||
libtoxcore_la_include_HEADERS = \
|
||||
../toxcore/tox.h
|
||||
../toxcore/tox.h \
|
||||
../toxcore/tox_private.h
|
||||
|
||||
libtoxcore_la_includedir = $(includedir)/tox
|
||||
|
||||
|
40
external/toxcore/c-toxcore/toxcore/Messenger.c
vendored
40
external/toxcore/c-toxcore/toxcore/Messenger.c
vendored
@ -757,6 +757,20 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Userstatus userstatus_from_int(uint8_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case 0:
|
||||
return USERSTATUS_NONE;
|
||||
case 1:
|
||||
return USERSTATUS_AWAY;
|
||||
case 2:
|
||||
return USERSTATUS_BUSY;
|
||||
default:
|
||||
return USERSTATUS_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
int m_set_userstatus(Messenger *m, uint8_t status)
|
||||
{
|
||||
if (status >= USERSTATUS_INVALID) {
|
||||
@ -767,7 +781,7 @@ int m_set_userstatus(Messenger *m, uint8_t status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->userstatus = (Userstatus)status;
|
||||
m->userstatus = userstatus_from_int(status);
|
||||
|
||||
for (uint32_t i = 0; i < m->numfriends; ++i) {
|
||||
m->friendlist[i].userstatus_sent = false;
|
||||
@ -923,7 +937,7 @@ static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, co
|
||||
non_null()
|
||||
static void set_friend_userstatus(const Messenger *m, int32_t friendnumber, uint8_t status)
|
||||
{
|
||||
m->friendlist[friendnumber].userstatus = (Userstatus)status;
|
||||
m->friendlist[friendnumber].userstatus = userstatus_from_int(status);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -2024,7 +2038,7 @@ non_null(1, 3) nullable(5)
|
||||
static int m_handle_packet_offline(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata)
|
||||
{
|
||||
if (data_length == 0) {
|
||||
set_friend_status(m, i, FRIEND_CONFIRMED, userdata);
|
||||
set_friend_status(m, i, FRIEND_CONFIRMED, userdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2081,9 +2095,9 @@ static int m_handle_packet_userstatus(Messenger *m, const int i, const uint8_t *
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Userstatus status = (Userstatus)data[0];
|
||||
const Userstatus status = userstatus_from_int(data[0]);
|
||||
|
||||
if (status >= USERSTATUS_INVALID) {
|
||||
if (status == USERSTATUS_INVALID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2403,8 +2417,8 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
|
||||
return m_handle_packet_file_data(m, i, data, data_length, userdata);
|
||||
case PACKET_ID_MSI:
|
||||
return m_handle_packet_msi(m, i, data, data_length, userdata);
|
||||
case PACKET_ID_INVITE_GROUPCHAT:
|
||||
return m_handle_packet_invite_groupchat(m, i, data, data_length, userdata);
|
||||
case PACKET_ID_INVITE_GROUPCHAT:
|
||||
return m_handle_packet_invite_groupchat(m, i, data, data_length, userdata);
|
||||
}
|
||||
|
||||
return handle_custom_lossless_packet(object, i, temp, len, userdata);
|
||||
@ -2627,7 +2641,7 @@ void do_messenger(Messenger *m, void *userdata)
|
||||
if (m->tcp_server != nullptr) {
|
||||
/* Add self tcp server. */
|
||||
IP_Port local_ip_port;
|
||||
local_ip_port.port = m->options.tcp_server_port;
|
||||
local_ip_port.port = net_htons(m->options.tcp_server_port);
|
||||
local_ip_port.ip.family = net_family_ipv4();
|
||||
local_ip_port.ip.ip.v4 = get_ip4_loopback();
|
||||
add_tcp_relay(m->net_crypto, &local_ip_port, tcp_server_public_key(m->tcp_server));
|
||||
@ -3153,7 +3167,7 @@ static void pack_groupchats(const GC_Session *c, Bin_Pack *bp)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool pack_groupchats_handler(Bin_Pack *bp, const void *obj)
|
||||
static bool pack_groupchats_handler(Bin_Pack *bp, const Logger *log, const void *obj)
|
||||
{
|
||||
pack_groupchats((const GC_Session *)obj, bp);
|
||||
return true; // TODO(iphydf): Return bool from pack functions.
|
||||
@ -3163,7 +3177,7 @@ non_null()
|
||||
static uint32_t saved_groups_size(const Messenger *m)
|
||||
{
|
||||
GC_Session *c = m->group_handler;
|
||||
return bin_pack_obj_size(pack_groupchats_handler, c);
|
||||
return bin_pack_obj_size(pack_groupchats_handler, m->log, c);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -3185,7 +3199,7 @@ static uint8_t *groups_save(const Messenger *m, uint8_t *data)
|
||||
|
||||
data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_GROUPS);
|
||||
|
||||
if (!bin_pack_obj(pack_groupchats_handler, c, data, len)) {
|
||||
if (!bin_pack_obj(pack_groupchats_handler, m->log, c, data, len)) {
|
||||
LOGGER_FATAL(m->log, "failed to pack group chats into buffer of length %u", len);
|
||||
return data;
|
||||
}
|
||||
@ -3622,7 +3636,9 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
|
||||
m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht);
|
||||
m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht);
|
||||
m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto);
|
||||
m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
|
||||
if (m->onion_c != nullptr) {
|
||||
m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
|
||||
}
|
||||
|
||||
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
|
||||
m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) {
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define GNU_PRINTF(f, a)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(_DEBUG) && !defined(__OPTIMIZE__)
|
||||
#if defined(__GNUC__) && defined(_DEBUG)
|
||||
#define non_null(...) __attribute__((__nonnull__(__VA_ARGS__)))
|
||||
#else
|
||||
#define non_null(...)
|
||||
|
44
external/toxcore/c-toxcore/toxcore/bin_pack.c
vendored
44
external/toxcore/c-toxcore/toxcore/bin_pack.c
vendored
@ -62,21 +62,47 @@ static void bin_pack_init(Bin_Pack *bp, uint8_t *buf, uint32_t buf_size)
|
||||
cmp_init(&bp->ctx, bp, null_reader, null_skipper, buf_writer);
|
||||
}
|
||||
|
||||
bool bin_pack_obj(bin_pack_cb *callback, const void *obj, uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
Bin_Pack bp;
|
||||
bin_pack_init(&bp, buf, buf_size);
|
||||
return callback(&bp, obj);
|
||||
}
|
||||
|
||||
uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj)
|
||||
uint32_t bin_pack_obj_size(bin_pack_cb *callback, const Logger *logger, const void *obj)
|
||||
{
|
||||
Bin_Pack bp;
|
||||
bin_pack_init(&bp, nullptr, 0);
|
||||
callback(&bp, obj);
|
||||
if (!callback(&bp, logger, obj)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
return bp.bytes_pos;
|
||||
}
|
||||
|
||||
bool bin_pack_obj(bin_pack_cb *callback, const Logger *logger, const void *obj, uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
Bin_Pack bp;
|
||||
bin_pack_init(&bp, buf, buf_size);
|
||||
return callback(&bp, logger, obj);
|
||||
}
|
||||
|
||||
uint32_t bin_pack_obj_array_size(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count)
|
||||
{
|
||||
Bin_Pack bp;
|
||||
bin_pack_init(&bp, nullptr, 0);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (!callback(&bp, logger, arr, i)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
}
|
||||
return bp.bytes_pos;
|
||||
}
|
||||
|
||||
bool bin_pack_obj_array(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count, uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
Bin_Pack bp;
|
||||
bin_pack_init(&bp, buf, buf_size);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (!callback(&bp, logger, arr, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
Bin_Pack *bp = (Bin_Pack *)calloc(1, sizeof(Bin_Pack));
|
||||
|
67
external/toxcore/c-toxcore/toxcore/bin_pack.h
vendored
67
external/toxcore/c-toxcore/toxcore/bin_pack.h
vendored
@ -8,6 +8,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "logger.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -23,18 +24,29 @@ typedef struct Bin_Pack Bin_Pack;
|
||||
* This function would typically cast the `void *` to the actual object pointer type and then call
|
||||
* more appropriately typed packing functions.
|
||||
*/
|
||||
typedef bool bin_pack_cb(Bin_Pack *bp, const void *obj);
|
||||
typedef bool bin_pack_cb(Bin_Pack *bp, const Logger *logger, const void *obj);
|
||||
|
||||
/** @brief Function used to pack an array of objects.
|
||||
*
|
||||
* This function would typically cast the `void *` to the actual object pointer type and then call
|
||||
* more appropriately typed packing functions.
|
||||
*
|
||||
* @param arr is the object array as void pointer.
|
||||
* @param index is the index in the object array that is currently being packed.
|
||||
*/
|
||||
typedef bool bin_pack_array_cb(Bin_Pack *bp, const Logger *logger, const void *arr, uint32_t index);
|
||||
|
||||
/** @brief Determine the serialised size of an object.
|
||||
*
|
||||
* @param callback The function called on the created packer and packed object.
|
||||
* @param logger Optional logger object to pass to the callback.
|
||||
* @param obj The object to be packed, passed as `obj` to the callback.
|
||||
*
|
||||
* @return The packed size of the passed object according to the callback. UINT32_MAX in case of
|
||||
* errors such as buffer overflow.
|
||||
* @return The packed size of the passed object according to the callback.
|
||||
* @retval UINT32_MAX in case of errors such as buffer overflow.
|
||||
*/
|
||||
non_null(1) nullable(2)
|
||||
uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj);
|
||||
non_null(1) nullable(2, 3)
|
||||
uint32_t bin_pack_obj_size(bin_pack_cb *callback, const Logger *logger, const void *obj);
|
||||
|
||||
/** @brief Pack an object into a buffer of a given size.
|
||||
*
|
||||
@ -45,14 +57,57 @@ uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj);
|
||||
* overflows `uint32_t`, this function returns `false`.
|
||||
*
|
||||
* @param callback The function called on the created packer and packed object.
|
||||
* @param logger Optional logger object to pass to the callback.
|
||||
* @param obj The object to be packed, passed as `obj` to the callback.
|
||||
* @param buf A byte array large enough to hold the serialised representation of `obj`.
|
||||
* @param buf_size The size of the byte array. Can be `UINT32_MAX` to disable bounds checking.
|
||||
*
|
||||
* @retval false if an error occurred (e.g. buffer overflow).
|
||||
*/
|
||||
non_null(1, 4) nullable(2, 3)
|
||||
bool bin_pack_obj(bin_pack_cb *callback, const Logger *logger, const void *obj, uint8_t *buf, uint32_t buf_size);
|
||||
|
||||
/** @brief Determine the serialised size of an object array.
|
||||
*
|
||||
* Calls the callback `count` times with increasing `index` argument from 0 to
|
||||
* `count`. This function is here just so we don't need to write the same
|
||||
* trivial loop many times and so we don't need an extra struct just to contain
|
||||
* an array with size so it can be passed to `bin_pack_obj_size`.
|
||||
*
|
||||
* @param callback The function called on the created packer and each object to
|
||||
* be packed.
|
||||
* @param logger Optional logger object to pass to the callback.
|
||||
* @param arr The object array to be packed, passed as `arr` to the callback.
|
||||
* @param count The number of elements in the object array.
|
||||
*
|
||||
* @return The packed size of the passed object array according to the callback.
|
||||
* @retval UINT32_MAX in case of errors such as buffer overflow.
|
||||
*/
|
||||
non_null(1, 3) nullable(2)
|
||||
bool bin_pack_obj(bin_pack_cb *callback, const void *obj, uint8_t *buf, uint32_t buf_size);
|
||||
uint32_t bin_pack_obj_array_size(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count);
|
||||
|
||||
/** @brief Pack an object array into a buffer of a given size.
|
||||
*
|
||||
* Calls the callback `count` times with increasing `index` argument from 0 to
|
||||
* `count`. This function is here just so we don't need to write the same
|
||||
* trivial loop many times and so we don't need an extra struct just to contain
|
||||
* an array with size so it can be passed to `bin_pack_obj`.
|
||||
*
|
||||
* Similar to `bin_pack_obj` but for arrays. Does not write the array length, so
|
||||
* if you need that, write it manually using `bin_pack_array`.
|
||||
*
|
||||
* @param callback The function called on the created packer and packed object
|
||||
* array.
|
||||
* @param logger Optional logger object to pass to the callback.
|
||||
* @param arr The object array to be packed, passed as `arr` to the callback.
|
||||
* @param count The number of elements in the object array.
|
||||
* @param buf A byte array large enough to hold the serialised representation of `arr`.
|
||||
* @param buf_size The size of the byte array. Can be `UINT32_MAX` to disable bounds checking.
|
||||
*
|
||||
* @retval false if an error occurred (e.g. buffer overflow).
|
||||
*/
|
||||
non_null(1, 3, 5) nullable(2)
|
||||
bool bin_pack_obj_array(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count, uint8_t *buf, uint32_t buf_size);
|
||||
|
||||
/** @brief Allocate a new packer object.
|
||||
*
|
||||
|
@ -12,11 +12,30 @@ namespace {
|
||||
|
||||
using HmacKey = std::array<uint8_t, CRYPTO_HMAC_KEY_SIZE>;
|
||||
using Hmac = std::array<uint8_t, CRYPTO_HMAC_SIZE>;
|
||||
using PublicKey = std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
|
||||
using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
|
||||
using ExtPublicKey = std::array<uint8_t, EXT_PUBLIC_KEY_SIZE>;
|
||||
using ExtSecretKey = std::array<uint8_t, EXT_SECRET_KEY_SIZE>;
|
||||
using Signature = std::array<uint8_t, CRYPTO_SIGNATURE_SIZE>;
|
||||
using Nonce = std::array<uint8_t, CRYPTO_NONCE_SIZE>;
|
||||
|
||||
TEST(CryptoCore, EncryptLargeData)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
Nonce nonce{};
|
||||
PublicKey pk;
|
||||
SecretKey sk;
|
||||
crypto_new_keypair(rng, pk.data(), sk.data());
|
||||
|
||||
// 100 MiB of data (all zeroes, doesn't matter what's inside).
|
||||
std::vector<uint8_t> plain(100 * 1024 * 1024);
|
||||
std::vector<uint8_t> encrypted(plain.size() + CRYPTO_MAC_SIZE);
|
||||
|
||||
encrypt_data(pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
|
||||
}
|
||||
|
||||
TEST(CryptoCore, IncrementNonce)
|
||||
{
|
||||
Nonce nonce{};
|
||||
@ -60,7 +79,8 @@ TEST(CryptoCore, Signatures)
|
||||
|
||||
EXPECT_TRUE(create_extended_keypair(pk.data(), sk.data()));
|
||||
|
||||
std::vector<uint8_t> message;
|
||||
std::vector<uint8_t> message{0};
|
||||
message.clear();
|
||||
|
||||
// Try a few different sizes, including empty 0 length message.
|
||||
for (uint8_t i = 0; i < 100; ++i) {
|
||||
@ -82,7 +102,8 @@ TEST(CryptoCore, Hmac)
|
||||
HmacKey sk;
|
||||
new_hmac_key(rng, sk.data());
|
||||
|
||||
std::vector<uint8_t> message;
|
||||
std::vector<uint8_t> message{0};
|
||||
message.clear();
|
||||
|
||||
// Try a few different sizes, including empty 0 length message.
|
||||
for (uint8_t i = 0; i < 100; ++i) {
|
||||
|
@ -50,8 +50,10 @@ TEST_F(Announces, CanBeCreatedAndDeleted)
|
||||
GC_Public_Announce ann{};
|
||||
ann.chat_public_key[0] = 0x88;
|
||||
ASSERT_NE(gca_add_announce(mono_time_, gca_, &ann), nullptr);
|
||||
#ifndef _DEBUG
|
||||
ASSERT_EQ(gca_add_announce(mono_time_, gca_, nullptr), nullptr);
|
||||
ASSERT_EQ(gca_add_announce(mono_time_, nullptr, &ann), nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(Announces, AnnouncesCanTimeOut)
|
||||
@ -103,7 +105,9 @@ TEST_F(Announces, AnnouncesGetAndCleanup)
|
||||
|
||||
cleanup_gca(gca_, ann2.chat_public_key);
|
||||
ASSERT_EQ(gca_get_announces(gca_, &announces, 1, ann2.chat_public_key, empty_pk), 0);
|
||||
#ifndef _DEBUG
|
||||
ASSERT_EQ(gca_get_announces(gca_, nullptr, 1, ann2.chat_public_key, empty_pk), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct AnnouncesPack : ::testing::Test {
|
||||
@ -162,19 +166,23 @@ TEST_F(AnnouncesPack, PublicAnnounceCanBePackedAndUnpacked)
|
||||
|
||||
TEST_F(AnnouncesPack, UnpackEmptyPublicAnnounce)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
GC_Public_Announce ann{};
|
||||
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
|
||||
|
||||
EXPECT_EQ(gca_unpack_public_announce(logger_, nullptr, 0, &ann), -1);
|
||||
EXPECT_EQ(gca_unpack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(AnnouncesPack, PackEmptyPublicAnnounce)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
GC_Public_Announce ann{};
|
||||
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
|
||||
EXPECT_EQ(gca_pack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1);
|
||||
EXPECT_EQ(gca_pack_public_announce(logger_, nullptr, 0, &ann), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(AnnouncesPack, PublicAnnouncePackNull)
|
||||
@ -198,7 +206,9 @@ TEST_F(AnnouncesPack, PublicAnnouncePackNull)
|
||||
|
||||
TEST_F(AnnouncesPack, AnnouncesValidationCheck)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
EXPECT_EQ(gca_is_valid_announce(nullptr), false);
|
||||
#endif
|
||||
|
||||
GC_Announce announce = {0};
|
||||
EXPECT_EQ(gca_is_valid_announce(&announce), false);
|
||||
@ -217,8 +227,10 @@ TEST_F(AnnouncesPack, UnpackIncompleteAnnouncesList)
|
||||
|
||||
GC_Announce announce;
|
||||
EXPECT_EQ(gca_unpack_announces_list(logger_, data, sizeof(data), &announce, 1), -1);
|
||||
#ifndef _DEBUG
|
||||
EXPECT_EQ(gca_unpack_announces_list(logger_, data, sizeof(data), nullptr, 1), -1);
|
||||
EXPECT_EQ(gca_unpack_announces_list(logger_, nullptr, 0, &announce, 1), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(AnnouncesPack, PackedAnnouncesListCanBeUnpacked)
|
||||
@ -246,17 +258,21 @@ TEST_F(AnnouncesPack, PackingEmptyAnnounceFails)
|
||||
std::vector<uint8_t> packed(gca_pack_announces_list_size(1));
|
||||
EXPECT_EQ(
|
||||
gca_pack_announces_list(logger_, packed.data(), packed.size(), &announce, 1, nullptr), -1);
|
||||
#ifndef _DEBUG
|
||||
EXPECT_EQ(
|
||||
gca_pack_announces_list(logger_, packed.data(), packed.size(), nullptr, 1, nullptr), -1);
|
||||
EXPECT_EQ(gca_pack_announces_list(logger_, nullptr, 0, &announce, 1, nullptr), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(AnnouncesPack, PackAnnounceNull)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
std::vector<uint8_t> data(GCA_ANNOUNCE_MAX_SIZE);
|
||||
GC_Announce announce;
|
||||
ASSERT_EQ(gca_pack_announce(logger_, nullptr, 0, &announce), -1);
|
||||
ASSERT_EQ(gca_pack_announce(logger_, data.data(), data.size(), nullptr), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
43
external/toxcore/c-toxcore/toxcore/group_chats.c
vendored
43
external/toxcore/c-toxcore/toxcore/group_chats.c
vendored
@ -182,7 +182,7 @@ static void kill_group_friend_connection(const GC_Session *c, const GC_Chat *cha
|
||||
|
||||
uint16_t gc_get_wrapped_packet_size(uint16_t length, Net_Packet_Type packet_type)
|
||||
{
|
||||
assert(length <= MAX_GC_PACKET_CHUNK_SIZE);
|
||||
assert(length <= (packet_type == NET_PACKET_GC_LOSSY ? MAX_GC_CUSTOM_LOSSY_PACKET_SIZE : MAX_GC_PACKET_CHUNK_SIZE));
|
||||
|
||||
const uint16_t min_header_size = packet_type == NET_PACKET_GC_LOSSY
|
||||
? GC_MIN_LOSSY_PAYLOAD_SIZE
|
||||
@ -226,10 +226,20 @@ GC_Connection *get_gc_connection(const GC_Chat *chat, int peer_number)
|
||||
return &peer->gconn;
|
||||
}
|
||||
|
||||
/** Returns the amount of empty padding a packet of designated length should have. */
|
||||
static uint16_t group_packet_padding_length(uint16_t length)
|
||||
/** Returns the max packet size, not wrapped */
|
||||
static uint16_t group_packet_max_packet_size(Net_Packet_Type net_packet_type)
|
||||
{
|
||||
return (MAX_GC_PACKET_CHUNK_SIZE - length) % GC_MAX_PACKET_PADDING;
|
||||
if (net_packet_type == NET_PACKET_GC_LOSSY) {
|
||||
return MAX_GC_CUSTOM_LOSSY_PACKET_SIZE;
|
||||
} else {
|
||||
return MAX_GC_PACKET_CHUNK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the amount of empty padding a packet of designated length should have. */
|
||||
static uint16_t group_packet_padding_length(uint16_t length, uint16_t max_length)
|
||||
{
|
||||
return (max_length - length) % GC_MAX_PACKET_PADDING;
|
||||
}
|
||||
|
||||
void gc_get_self_nick(const GC_Chat *chat, uint8_t *nick)
|
||||
@ -1270,8 +1280,8 @@ static uint16_t unpack_gc_shared_state(GC_SharedState *shared_state, const uint8
|
||||
memcpy(&voice_state, data + len_processed, sizeof(uint8_t));
|
||||
len_processed += sizeof(uint8_t);
|
||||
|
||||
shared_state->voice_state = (Group_Voice_State)voice_state;
|
||||
shared_state->privacy_state = (Group_Privacy_State)privacy_state;
|
||||
shared_state->voice_state = group_voice_state_from_int(voice_state);
|
||||
shared_state->privacy_state = group_privacy_state_from_int(privacy_state);
|
||||
|
||||
return len_processed;
|
||||
}
|
||||
@ -1483,9 +1493,10 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
|
||||
int group_packet_wrap(
|
||||
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
|
||||
uint8_t gp_packet_type, uint8_t net_packet_type)
|
||||
uint8_t gp_packet_type, Net_Packet_Type net_packet_type)
|
||||
{
|
||||
const uint16_t padding_len = group_packet_padding_length(length);
|
||||
const uint16_t max_packet_size = group_packet_max_packet_size(net_packet_type);
|
||||
const uint16_t padding_len = group_packet_padding_length(length, max_packet_size);
|
||||
const uint16_t min_packet_size = net_packet_type == NET_PACKET_GC_LOSSLESS
|
||||
? length + padding_len + CRYPTO_MAC_SIZE + 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + GC_MESSAGE_ID_BYTES + 1
|
||||
: length + padding_len + CRYPTO_MAC_SIZE + 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + 1;
|
||||
@ -1495,8 +1506,8 @@ int group_packet_wrap(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length > MAX_GC_PACKET_CHUNK_SIZE) {
|
||||
LOGGER_ERROR(log, "Packet payload size (%u) exceeds maximum (%u)", length, MAX_GC_PACKET_CHUNK_SIZE);
|
||||
if (length > max_packet_size) {
|
||||
LOGGER_ERROR(log, "Packet payload size (%u) exceeds maximum (%u)", length, max_packet_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1563,7 +1574,7 @@ non_null()
|
||||
static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
|
||||
uint16_t length, uint8_t packet_type)
|
||||
{
|
||||
assert(length <= MAX_GC_PACKET_CHUNK_SIZE);
|
||||
assert(length <= MAX_GC_CUSTOM_LOSSY_PACKET_SIZE);
|
||||
|
||||
if (!gconn->handshaked || gconn->pending_delete) {
|
||||
return false;
|
||||
@ -3510,8 +3521,8 @@ unsigned int gc_get_peer_connection_status(const GC_Chat *chat, uint32_t peer_id
|
||||
{
|
||||
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||
|
||||
if (peer_number_is_self(peer_number)) { // we cannot have a connection with ourselves
|
||||
return 0;
|
||||
if (peer_number_is_self(peer_number)) {
|
||||
return chat->self_udp_status == SELF_UDP_STATUS_NONE ? 1 : 2;
|
||||
}
|
||||
|
||||
const GC_Connection *gconn = get_gc_connection(chat, peer_number);
|
||||
@ -7224,7 +7235,9 @@ static int get_new_group_index(GC_Session *c)
|
||||
|
||||
c->chats[new_index] = empty_gc_chat;
|
||||
|
||||
memset(&c->chats[new_index].saved_invites, -1, sizeof(c->chats[new_index].saved_invites));
|
||||
for (size_t i = 0; i < sizeof(c->chats[new_index].saved_invites)/sizeof(*c->chats[new_index].saved_invites); ++i) {
|
||||
c->chats[new_index].saved_invites[i] = -1;
|
||||
}
|
||||
|
||||
++c->chats_index;
|
||||
|
||||
@ -7279,7 +7292,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat)
|
||||
|
||||
/** Initializes default shared state values. */
|
||||
non_null()
|
||||
static void init_gc_shared_state(GC_Chat *chat, const Group_Privacy_State privacy_state)
|
||||
static void init_gc_shared_state(GC_Chat *chat, Group_Privacy_State privacy_state)
|
||||
{
|
||||
chat->shared_state.maxpeers = MAX_GC_PEERS_DEFAULT;
|
||||
chat->shared_state.privacy_state = privacy_state;
|
||||
|
@ -142,7 +142,7 @@ non_null(1, 2, 3, 4, 5) nullable(7)
|
||||
int group_packet_wrap(
|
||||
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
|
||||
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
|
||||
uint8_t gp_packet_type, uint8_t net_packet_type);
|
||||
uint8_t gp_packet_type, Net_Packet_Type net_packet_type);
|
||||
|
||||
/** @brief Returns the size of a wrapped/encrypted packet with a plain size of `length`.
|
||||
*
|
||||
@ -162,7 +162,7 @@ uint16_t gc_get_wrapped_packet_size(uint16_t length, Net_Packet_Type packet_type
|
||||
* Returns -4 if the sender does not have permission to speak.
|
||||
* Returns -5 if the packet fails to send.
|
||||
*/
|
||||
non_null(1, 2, 3, 4) nullable(5)
|
||||
non_null(1, 2) nullable(5)
|
||||
int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length, uint8_t type,
|
||||
uint32_t *message_id);
|
||||
|
||||
@ -391,10 +391,13 @@ non_null(1) nullable(3)
|
||||
int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uint8_t *public_key);
|
||||
|
||||
/** @brief Gets the connection status for peer associated with `peer_id`.
|
||||
*
|
||||
* If `peer_id` designates ourself, the return value indicates whether we're capable
|
||||
* of making UDP connections with other peers, or are limited to TCP connections.
|
||||
*
|
||||
* Returns 2 if we have a direct (UDP) connection with a peer.
|
||||
* Returns 1 if we have an indirect (TCP) connection with a peer.
|
||||
* Returns 0 if peer_id is invalid or corresponds to ourselves.
|
||||
* Returns 0 if peer_id is invalid.
|
||||
*
|
||||
* Note: Return values must correspond to Tox_Connection enum in API.
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@
|
||||
#define MAX_GC_MESSAGE_SIZE GROUP_MAX_MESSAGE_LENGTH
|
||||
#define MAX_GC_MESSAGE_RAW_SIZE (MAX_GC_MESSAGE_SIZE + GC_MESSAGE_PSEUDO_ID_SIZE)
|
||||
#define MAX_GC_CUSTOM_LOSSLESS_PACKET_SIZE 1373
|
||||
#define MAX_GC_CUSTOM_LOSSY_PACKET_SIZE MAX_GC_PACKET_CHUNK_SIZE
|
||||
#define MAX_GC_CUSTOM_LOSSY_PACKET_SIZE 1373
|
||||
#define MAX_GC_PASSWORD_SIZE 32
|
||||
#define MAX_GC_SAVED_INVITES 10
|
||||
#define MAX_GC_PEERS_DEFAULT 100
|
||||
@ -401,7 +401,8 @@ int unpack_gc_saved_peers(GC_Chat *chat, const uint8_t *data, uint16_t length);
|
||||
|
||||
/** @brief Packs all valid entries from saved peerlist into `data`.
|
||||
*
|
||||
* If `processed` is non-null it will be set to the length of the packed data.
|
||||
* If `processed` is non-null it will be set to the length of the packed data
|
||||
* on success, and will be untouched on error.
|
||||
*
|
||||
* Return the number of packed saved peers on success.
|
||||
* Return -1 if buffer is too small.
|
||||
|
@ -453,6 +453,7 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer
|
||||
gconn = get_gc_connection(chat, peer_number);
|
||||
|
||||
if (gconn == nullptr) {
|
||||
free(payload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
50
external/toxcore/c-toxcore/toxcore/group_pack.c
vendored
50
external/toxcore/c-toxcore/toxcore/group_pack.c
vendored
@ -9,7 +9,6 @@
|
||||
|
||||
#include "group_pack.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -19,6 +18,32 @@
|
||||
#include "ccompat.h"
|
||||
#include "util.h"
|
||||
|
||||
Group_Privacy_State group_privacy_state_from_int(uint8_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return GI_PUBLIC;
|
||||
case 1:
|
||||
return GI_PRIVATE;
|
||||
default:
|
||||
return GI_PUBLIC;
|
||||
}
|
||||
}
|
||||
|
||||
Group_Voice_State group_voice_state_from_int(uint8_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return GV_ALL;
|
||||
case 1:
|
||||
return GV_MODS;
|
||||
case 2:
|
||||
return GV_FOUNDER;
|
||||
default:
|
||||
return GV_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
non_null()
|
||||
static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu)
|
||||
{
|
||||
@ -44,8 +69,8 @@ static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu)
|
||||
}
|
||||
|
||||
chat->connection_state = manually_disconnected ? CS_DISCONNECTED : CS_CONNECTING;
|
||||
chat->shared_state.privacy_state = (Group_Privacy_State)privacy_state;
|
||||
chat->shared_state.voice_state = (Group_Voice_State)voice_state;
|
||||
chat->shared_state.privacy_state = group_privacy_state_from_int(privacy_state);
|
||||
chat->shared_state.voice_state = group_voice_state_from_int(voice_state);
|
||||
|
||||
// we always load saved groups as private in case the group became private while we were offline.
|
||||
// this will have no detrimental effect if the group is public, as the correct privacy
|
||||
@ -125,7 +150,7 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu)
|
||||
|
||||
if (chat->moderation.num_mods > MOD_MAX_NUM_MODERATORS) {
|
||||
LOGGER_ERROR(chat->log, "moderation count %u exceeds maximum %u", chat->moderation.num_mods, MOD_MAX_NUM_MODERATORS);
|
||||
return false;
|
||||
chat->moderation.num_mods = MOD_MAX_NUM_MODERATORS;
|
||||
}
|
||||
|
||||
uint8_t *packed_mod_list = (uint8_t *)malloc(chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE);
|
||||
@ -193,7 +218,10 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu)
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(self_nick_len <= MAX_GC_NICK_SIZE);
|
||||
if (self_nick_len > MAX_GC_NICK_SIZE) {
|
||||
LOGGER_ERROR(chat->log, "self_nick too big (%u bytes), truncating to %d", self_nick_len, MAX_GC_NICK_SIZE);
|
||||
self_nick_len = MAX_GC_NICK_SIZE;
|
||||
}
|
||||
|
||||
if (!bin_unpack_bin_fixed(bu, self_nick, self_nick_len)) {
|
||||
LOGGER_ERROR(chat->log, "Failed to unpack self nick bytes");
|
||||
@ -206,7 +234,10 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu)
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(chat->numpeers > 0);
|
||||
if (chat->numpeers == 0) {
|
||||
LOGGER_ERROR(chat->log, "Failed to unpack self: numpeers should be > 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
GC_Peer *self = &chat->group[0];
|
||||
|
||||
@ -369,9 +400,12 @@ static void save_pack_self_info(const GC_Chat *chat, Bin_Pack *bp)
|
||||
{
|
||||
bin_pack_array(bp, 4);
|
||||
|
||||
const GC_Peer *self = &chat->group[0];
|
||||
GC_Peer *self = &chat->group[0];
|
||||
|
||||
assert(self->nick_length <= MAX_GC_NICK_SIZE);
|
||||
if (self->nick_length > MAX_GC_NICK_SIZE) {
|
||||
LOGGER_ERROR(chat->log, "self_nick is too big (%u). Truncating to %d", self->nick_length, MAX_GC_NICK_SIZE);
|
||||
self->nick_length = MAX_GC_NICK_SIZE;
|
||||
}
|
||||
|
||||
bin_pack_u16(bp, self->nick_length); // 1
|
||||
bin_pack_u08(bp, (uint8_t)self->role); // 2
|
||||
|
@ -32,4 +32,7 @@ void gc_save_pack_group(const GC_Chat *chat, Bin_Pack *bp);
|
||||
non_null()
|
||||
bool gc_load_unpack_group(GC_Chat *chat, Bin_Unpack *bu);
|
||||
|
||||
Group_Privacy_State group_privacy_state_from_int(uint8_t value);
|
||||
Group_Voice_State group_voice_state_from_int(uint8_t value);
|
||||
|
||||
#endif // GROUP_PACK_H
|
||||
|
29
external/toxcore/c-toxcore/toxcore/mono_time.c
vendored
29
external/toxcore/c-toxcore/toxcore/mono_time.c
vendored
@ -165,7 +165,7 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t
|
||||
// Maximum reproducibility. Never return time = 0.
|
||||
mono_time->base_time = 1;
|
||||
#else
|
||||
mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL);
|
||||
mono_time->base_time = (uint64_t)time(nullptr) * 1000ULL - current_time_monotonic(mono_time);
|
||||
#endif
|
||||
|
||||
mono_time_update(mono_time);
|
||||
@ -190,14 +190,13 @@ void mono_time_free(const Memory *mem, Mono_Time *mono_time)
|
||||
|
||||
void mono_time_update(Mono_Time *mono_time)
|
||||
{
|
||||
uint64_t cur_time = 0;
|
||||
#ifdef OS_WIN32
|
||||
/* we actually want to update the overflow state of mono_time here */
|
||||
pthread_mutex_lock(&mono_time->last_clock_lock);
|
||||
mono_time->last_clock_update = true;
|
||||
#endif
|
||||
cur_time = mono_time->current_time_callback(mono_time->user_data) / 1000ULL;
|
||||
cur_time += mono_time->base_time;
|
||||
const uint64_t cur_time =
|
||||
mono_time->base_time + mono_time->current_time_callback(mono_time->user_data);
|
||||
#ifdef OS_WIN32
|
||||
pthread_mutex_unlock(&mono_time->last_clock_lock);
|
||||
#endif
|
||||
@ -211,21 +210,22 @@ void mono_time_update(Mono_Time *mono_time)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t mono_time_get(const Mono_Time *mono_time)
|
||||
uint64_t mono_time_get_ms(const Mono_Time *mono_time)
|
||||
{
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
#if !defined(ESP_PLATFORM) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
// Fuzzing is only single thread for now, no locking needed */
|
||||
return mono_time->cur_time;
|
||||
#else
|
||||
#ifndef ESP_PLATFORM
|
||||
pthread_rwlock_rdlock(mono_time->time_update_lock);
|
||||
#endif
|
||||
const uint64_t cur_time = mono_time->cur_time;
|
||||
#ifndef ESP_PLATFORM
|
||||
#if !defined(ESP_PLATFORM) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
pthread_rwlock_unlock(mono_time->time_update_lock);
|
||||
#endif
|
||||
return cur_time;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t mono_time_get(const Mono_Time *mono_time)
|
||||
{
|
||||
return mono_time_get_ms(mono_time) / 1000ULL;
|
||||
}
|
||||
|
||||
bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout)
|
||||
@ -245,9 +245,10 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current monotonic time in milliseconds (ms). The starting point is
|
||||
* unspecified.
|
||||
/** @brief Return current monotonic time in milliseconds (ms).
|
||||
*
|
||||
* The starting point is unspecified and in particular is likely not comparable
|
||||
* to the return value of `mono_time_get_ms()`.
|
||||
*/
|
||||
uint64_t current_time_monotonic(Mono_Time *mono_time)
|
||||
{
|
||||
|
19
external/toxcore/c-toxcore/toxcore/mono_time.h
vendored
19
external/toxcore/c-toxcore/toxcore/mono_time.h
vendored
@ -61,8 +61,16 @@ void mono_time_free(const Memory *mem, Mono_Time *mono_time);
|
||||
non_null()
|
||||
void mono_time_update(Mono_Time *mono_time);
|
||||
|
||||
/**
|
||||
* Return unix time since epoch in seconds.
|
||||
/** @brief Return current monotonic time in milliseconds (ms).
|
||||
*
|
||||
* The starting point is UNIX epoch as measured by `time()` in `mono_time_new()`.
|
||||
*/
|
||||
non_null()
|
||||
uint64_t mono_time_get_ms(const Mono_Time *mono_time);
|
||||
|
||||
/** @brief Return a monotonically increasing time in seconds.
|
||||
*
|
||||
* The starting point is UNIX epoch as measured by `time()` in `mono_time_new()`.
|
||||
*/
|
||||
non_null()
|
||||
uint64_t mono_time_get(const Mono_Time *mono_time);
|
||||
@ -73,9 +81,10 @@ uint64_t mono_time_get(const Mono_Time *mono_time);
|
||||
non_null()
|
||||
bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout);
|
||||
|
||||
/**
|
||||
* Return current monotonic time in milliseconds (ms). The starting point is
|
||||
* unspecified.
|
||||
/** @brief Return current monotonic time in milliseconds (ms).
|
||||
*
|
||||
* The starting point is unspecified and in particular is likely not comparable
|
||||
* to the return value of `mono_time_get_ms()`.
|
||||
*/
|
||||
non_null()
|
||||
uint64_t current_time_monotonic(Mono_Time *mono_time);
|
||||
|
4
external/toxcore/c-toxcore/toxcore/network.c
vendored
4
external/toxcore/c-toxcore/toxcore/network.c
vendored
@ -1184,11 +1184,11 @@ Networking_Core *new_networking_ex(
|
||||
int n = 1024 * 1024 * 2;
|
||||
|
||||
if (net_setsockopt(ns, temp->sock, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) != 0) {
|
||||
LOGGER_ERROR(log, "failed to set socket option %d", SO_RCVBUF);
|
||||
LOGGER_WARNING(log, "failed to set socket option %d", SO_RCVBUF);
|
||||
}
|
||||
|
||||
if (net_setsockopt(ns, temp->sock, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) != 0) {
|
||||
LOGGER_ERROR(log, "failed to set socket option %d", SO_SNDBUF);
|
||||
LOGGER_WARNING(log, "failed to set socket option %d", SO_SNDBUF);
|
||||
}
|
||||
|
||||
/* Enable broadcast on socket */
|
||||
|
5
external/toxcore/c-toxcore/toxcore/tox.h
vendored
5
external/toxcore/c-toxcore/toxcore/tox.h
vendored
@ -3307,7 +3307,7 @@ uint32_t tox_group_max_message_length(void);
|
||||
/**
|
||||
* Maximum length of a group custom lossy packet.
|
||||
*/
|
||||
#define TOX_GROUP_MAX_CUSTOM_LOSSY_PACKET_LENGTH 500
|
||||
#define TOX_GROUP_MAX_CUSTOM_LOSSY_PACKET_LENGTH 1373
|
||||
|
||||
uint32_t tox_group_max_custom_lossy_packet_length(void);
|
||||
|
||||
@ -3967,7 +3967,8 @@ Tox_Group_Role tox_group_peer_get_role(const Tox *tox, uint32_t group_number, ui
|
||||
/**
|
||||
* Return the type of connection we have established with a peer.
|
||||
*
|
||||
* This function will return an error if called on ourselves.
|
||||
* If `peer_id` designates ourself, the return value indicates whether we're capable
|
||||
* of making UDP connections with other peers, or are limited to TCP connections.
|
||||
*
|
||||
* @param group_number The group number of the group we wish to query.
|
||||
* @param peer_id The ID of the peer whose connection status we wish to query.
|
||||
|
@ -326,20 +326,20 @@ bool tox_events_unpack(Tox_Events *events, Bin_Unpack *bu)
|
||||
return true;
|
||||
}
|
||||
|
||||
non_null(1) nullable(2)
|
||||
static bool tox_events_bin_pack_handler(Bin_Pack *bp, const void *obj)
|
||||
non_null(1) nullable(2, 3)
|
||||
static bool tox_events_bin_pack_handler(Bin_Pack *bp, const Logger *logger, const void *obj)
|
||||
{
|
||||
return tox_events_pack((const Tox_Events *)obj, bp);
|
||||
}
|
||||
|
||||
uint32_t tox_events_bytes_size(const Tox_Events *events)
|
||||
{
|
||||
return bin_pack_obj_size(tox_events_bin_pack_handler, events);
|
||||
return bin_pack_obj_size(tox_events_bin_pack_handler, nullptr, events);
|
||||
}
|
||||
|
||||
void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes)
|
||||
{
|
||||
bin_pack_obj(tox_events_bin_pack_handler, events, bytes, UINT32_MAX);
|
||||
bin_pack_obj(tox_events_bin_pack_handler, nullptr, events, bytes, UINT32_MAX);
|
||||
}
|
||||
|
||||
Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size)
|
||||
|
71
external/toxcore/c-toxcore/toxcore/tox_unpack.c
vendored
71
external/toxcore/c-toxcore/toxcore/tox_unpack.c
vendored
@ -9,6 +9,17 @@
|
||||
#include "bin_unpack.h"
|
||||
#include "ccompat.h"
|
||||
|
||||
static Tox_Conference_Type tox_conference_type_from_int(uint32_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return TOX_CONFERENCE_TYPE_TEXT;
|
||||
case 1:
|
||||
return TOX_CONFERENCE_TYPE_AV;
|
||||
default:
|
||||
return TOX_CONFERENCE_TYPE_TEXT;
|
||||
}
|
||||
}
|
||||
bool tox_unpack_conference_type(Bin_Unpack *bu, Tox_Conference_Type *val)
|
||||
{
|
||||
uint32_t u32;
|
||||
@ -17,10 +28,23 @@ bool tox_unpack_conference_type(Bin_Unpack *bu, Tox_Conference_Type *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
*val = (Tox_Conference_Type)u32;
|
||||
*val = tox_conference_type_from_int(u32);
|
||||
return true;
|
||||
}
|
||||
|
||||
static Tox_Connection tox_connection_from_int(uint32_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return TOX_CONNECTION_NONE;
|
||||
case 1:
|
||||
return TOX_CONNECTION_TCP;
|
||||
case 2:
|
||||
return TOX_CONNECTION_UDP;
|
||||
default:
|
||||
return TOX_CONNECTION_NONE;
|
||||
}
|
||||
}
|
||||
bool tox_unpack_connection(Bin_Unpack *bu, Tox_Connection *val)
|
||||
{
|
||||
uint32_t u32;
|
||||
@ -29,10 +53,23 @@ bool tox_unpack_connection(Bin_Unpack *bu, Tox_Connection *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
*val = (Tox_Connection)u32;
|
||||
*val = tox_connection_from_int(u32);
|
||||
return true;
|
||||
}
|
||||
|
||||
static Tox_File_Control tox_file_control_from_int(uint32_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return TOX_FILE_CONTROL_RESUME;
|
||||
case 1:
|
||||
return TOX_FILE_CONTROL_PAUSE;
|
||||
case 2:
|
||||
return TOX_FILE_CONTROL_CANCEL;
|
||||
default:
|
||||
return TOX_FILE_CONTROL_RESUME;
|
||||
}
|
||||
}
|
||||
bool tox_unpack_file_control(Bin_Unpack *bu, Tox_File_Control *val)
|
||||
{
|
||||
uint32_t u32;
|
||||
@ -41,10 +78,21 @@ bool tox_unpack_file_control(Bin_Unpack *bu, Tox_File_Control *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
*val = (Tox_File_Control)u32;
|
||||
*val = tox_file_control_from_int(u32);
|
||||
return true;
|
||||
}
|
||||
|
||||
static Tox_Message_Type tox_message_type_from_int(uint32_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return TOX_MESSAGE_TYPE_NORMAL;
|
||||
case 1:
|
||||
return TOX_MESSAGE_TYPE_ACTION;
|
||||
default:
|
||||
return TOX_MESSAGE_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
bool tox_unpack_message_type(Bin_Unpack *bu, Tox_Message_Type *val)
|
||||
{
|
||||
uint32_t u32;
|
||||
@ -53,10 +101,23 @@ bool tox_unpack_message_type(Bin_Unpack *bu, Tox_Message_Type *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
*val = (Tox_Message_Type)u32;
|
||||
*val = tox_message_type_from_int(u32);
|
||||
return true;
|
||||
}
|
||||
|
||||
static Tox_User_Status tox_user_status_from_int(uint32_t value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0:
|
||||
return TOX_USER_STATUS_NONE;
|
||||
case 1:
|
||||
return TOX_USER_STATUS_AWAY;
|
||||
case 2:
|
||||
return TOX_USER_STATUS_BUSY;
|
||||
default:
|
||||
return TOX_USER_STATUS_NONE;
|
||||
}
|
||||
}
|
||||
bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val)
|
||||
{
|
||||
uint32_t u32;
|
||||
@ -65,7 +126,7 @@ bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
*val = (Tox_User_Status)u32;
|
||||
*val = tox_user_status_from_int(u32);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user