Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Use Bin_Pack for packing Node_format. #2220

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion other/bootstrap_daemon/docker/tox-bootstrapd.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
036adfc1e993624ae0bf49f08c2890bb44e6d4224a07a8c7fd2e2b5a8be6bf4c /usr/local/bin/tox-bootstrapd
60712ccabce7ff7ae3a3125ad37c2b3b30cd5bde59efeb5a83fb5a2a7998459c /usr/local/bin/tox-bootstrapd
34 changes: 18 additions & 16 deletions toxcore/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,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"],
Expand All @@ -84,6 +100,7 @@ cc_library(
deps = [
":attributes",
":ccompat",
":logger",
"//c-toxcore/third_party:cmp",
],
)
Expand Down Expand Up @@ -158,22 +175,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"],
Expand Down Expand Up @@ -339,6 +340,7 @@ cc_library(
deps = [
":LAN_discovery",
":attributes",
":bin_pack",
":ccompat",
":crypto_core",
":logger",
Expand Down
118 changes: 70 additions & 48 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;

Expand All @@ -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 -1;
return false;
}

if (is_ipv4) {
const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);
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));
}

if (size > length) {
return -1;
}
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);
}

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);
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 (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,
Expand Down Expand Up @@ -511,33 +535,30 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
}
}

int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number)
/** @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)
{
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;
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);
}

#ifndef NDEBUG
const uint32_t increment = ipp_size + CRYPTO_PUBLIC_KEY_SIZE;
#endif
assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
/** @brief Pack number of nodes into data of maxlength length.
*
* @return length of packed nodes on success.
* @retval -1 on failure.
*/
int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number)
{
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,
Expand Down Expand Up @@ -2829,8 +2850,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);
}
Expand Down
20 changes: 10 additions & 10 deletions toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions toxcore/DHT_fuzz_test.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "DHT.h"

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <vector>

#include "../testing/fuzzing/fuzz_support.h"
Expand Down Expand Up @@ -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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -3153,7 +3153,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.
Expand All @@ -3163,7 +3163,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()
Expand All @@ -3185,7 +3185,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;
}
Expand Down
34 changes: 30 additions & 4 deletions toxcore/bin_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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);
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, obj);
return callback(&bp, logger, obj);
}

uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *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);
callback(&bp, obj);
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));
Expand Down
Loading
Loading