Skip to content

Commit

Permalink
refactor: Move pack/unpack IP_Port from DHT into network module.
Browse files Browse the repository at this point in the history
It's misplaced in DHT, since the data structures are located in network.
  • Loading branch information
iphydf committed Jan 30, 2024
1 parent a975943 commit ab4eeda
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 158 deletions.
1 change: 1 addition & 0 deletions toxcore/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ cc_library(
"//c-toxcore/toxav:__pkg__",
],
deps = [
":bin_pack",
":ccompat",
":crypto_core",
":logger",
Expand Down
138 changes: 0 additions & 138 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,84 +364,6 @@ int packed_node_size(Family ip_family)
}


/** @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 (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;

if (net_family_is_ipv4(ip_port->ip.family)) {
// TODO(irungentoo): use functions to convert endianness
is_ipv4 = true;
family = TOX_AF_INET;
} else if (net_family_is_tcp_ipv4(ip_port->ip.family)) {
is_ipv4 = true;
family = TOX_TCP_INET;
} else if (net_family_is_ipv6(ip_port->ip.family)) {
is_ipv4 = false;
family = TOX_AF_INET6;
} else if (net_family_is_tcp_ipv6(ip_port->ip.family)) {
is_ipv4 = false;
family = TOX_TCP_INET6;
} else {
Ip_Ntoa ip_str;
// 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(const void *obj, const Logger *logger, Bin_Pack *bp)
{
const IP_Port *ip_port = (const IP_Port *)obj;
return bin_pack_ip_port(bp, logger, ip_port);
}

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, ip_port, logger);

if (size > length) {
return -1;
}

if (!bin_pack_obj(bin_pack_ip_port_handler, ip_port, logger, data, length)) {
return -1;
}

assert(size < INT_MAX);
return (int)size;
}

int dht_create_packet(const Memory *mem, const Random *rng,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t *shared_key, const uint8_t type,
Expand Down Expand Up @@ -478,66 +400,6 @@ int dht_create_packet(const Memory *mem, const Random *rng,
return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length;
}

int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled)
{
if (data == nullptr) {
return -1;
}

bool is_ipv4;
Family host_family;

if (data[0] == TOX_AF_INET) {
is_ipv4 = true;
host_family = net_family_ipv4();
} else if (data[0] == TOX_TCP_INET) {
if (!tcp_enabled) {
return -1;
}

is_ipv4 = true;
host_family = net_family_tcp_ipv4();
} else if (data[0] == TOX_AF_INET6) {
is_ipv4 = false;
host_family = net_family_ipv6();
} else if (data[0] == TOX_TCP_INET6) {
if (!tcp_enabled) {
return -1;
}

is_ipv4 = false;
host_family = net_family_tcp_ipv6();
} else {
return -1;
}

ipport_reset(ip_port);

if (is_ipv4) {
const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);

if (size > length) {
return -1;
}

ip_port->ip.family = host_family;
memcpy(&ip_port->ip.ip.v4, data + 1, SIZE_IP4);
memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t));
return size;
} else {
const uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t);

if (size > length) {
return -1;
}

ip_port->ip.family = host_family;
memcpy(&ip_port->ip.ip.v6, data + 1, SIZE_IP6);
memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t));
return size;
}
}

/** @brief Pack a single node from a node array.
*
* @retval true on success.
Expand Down
20 changes: 0 additions & 20 deletions toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,26 +204,6 @@ non_null() const Client_data *dht_friend_client(const DHT_Friend *dht_friend, si
*/
int packed_node_size(Family ip_family);

/** @brief Pack an IP_Port structure into data of max size length.
*
* Packed_length is the offset of data currently packed.
*
* @return size of packed IP_Port data on success.
* @retval -1 on failure.
*/
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 Down
137 changes: 137 additions & 0 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,143 @@ void ipport_copy(IP_Port *target, const IP_Port *source)
*target = tmp;
}

/** @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 (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.
*/
bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port)
{
bool is_ipv4;
uint8_t family;

if (net_family_is_ipv4(ip_port->ip.family)) {
// TODO(irungentoo): use functions to convert endianness
is_ipv4 = true;
family = TOX_AF_INET;
} else if (net_family_is_tcp_ipv4(ip_port->ip.family)) {
is_ipv4 = true;
family = TOX_TCP_INET;
} else if (net_family_is_ipv6(ip_port->ip.family)) {
is_ipv4 = false;
family = TOX_AF_INET6;
} else if (net_family_is_tcp_ipv6(ip_port->ip.family)) {
is_ipv4 = false;
family = TOX_TCP_INET6;
} else {
Ip_Ntoa ip_str;
// 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(const void *obj, const Logger *logger, Bin_Pack *bp)
{
const IP_Port *ip_port = (const IP_Port *)obj;
return bin_pack_ip_port(bp, logger, ip_port);
}

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, ip_port, logger);

if (size > length) {
return -1;

Check warning on line 1642 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1642

Added line #L1642 was not covered by tests
}

if (!bin_pack_obj(bin_pack_ip_port_handler, ip_port, logger, data, length)) {
return -1;

Check warning on line 1646 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1646

Added line #L1646 was not covered by tests
}

assert(size < INT_MAX);
return (int)size;
}

int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled)
{
if (data == nullptr) {
return -1;

Check warning on line 1656 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1656

Added line #L1656 was not covered by tests
}

bool is_ipv4;
Family host_family;

if (data[0] == TOX_AF_INET) {
is_ipv4 = true;
host_family = net_family_ipv4();
} else if (data[0] == TOX_TCP_INET) {
if (!tcp_enabled) {
return -1;
}

is_ipv4 = true;
host_family = net_family_tcp_ipv4();
} else if (data[0] == TOX_AF_INET6) {
is_ipv4 = false;
host_family = net_family_ipv6();
} else if (data[0] == TOX_TCP_INET6) {
if (!tcp_enabled) {
return -1;
}

is_ipv4 = false;
host_family = net_family_tcp_ipv6();
} else {
return -1;
}

ipport_reset(ip_port);

if (is_ipv4) {
const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);

if (size > length) {
return -1;
}

ip_port->ip.family = host_family;
memcpy(&ip_port->ip.ip.v4, data + 1, SIZE_IP4);

Check warning on line 1696 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1696

MISRA 18.4 rule
memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t));

Check warning on line 1697 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1697

MISRA 18.4 rule
return size;
} else {
const uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t);

if (size > length) {
return -1;
}

ip_port->ip.family = host_family;
memcpy(&ip_port->ip.ip.v6, data + 1, SIZE_IP6);

Check warning on line 1707 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1707

MISRA 18.4 rule
memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t));

Check warning on line 1708 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1708

MISRA 18.4 rule
return size;
}
}

const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str)
{
assert(ip_str != nullptr);
Expand Down
24 changes: 24 additions & 0 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <stddef.h> // size_t
#include <stdint.h> // uint*_t

#include "bin_pack.h"
#include "logger.h"
#include "mem.h"

Expand Down Expand Up @@ -518,6 +519,29 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
non_null(1) nullable(2)
void net_freeipport(const Memory *mem, IP_Port *ip_ports);

non_null()
bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port);

/** @brief Pack an IP_Port structure into data of max size length.
*
* Packed_length is the offset of data currently packed.
*
* @return size of packed IP_Port data on success.
* @retval -1 on failure.
*/
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);

/**
* @return true on success, false on failure.
*/
Expand Down

0 comments on commit ab4eeda

Please sign in to comment.