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 ae65b33
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 161 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
139 changes: 0 additions & 139 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "DHT.h"

#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -364,84 +363,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 +399,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
1 change: 0 additions & 1 deletion toxcore/TCP_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <stdio.h>
#include <string.h>

#include "DHT.h"
#include "TCP_common.h"
#include "ccompat.h"
#include "crypto_core.h"
Expand Down
1 change: 0 additions & 1 deletion toxcore/TCP_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <unistd.h>
#endif /* TCP_SERVER_USE_EPOLL */

#include "DHT.h"
#include "TCP_common.h"
#include "ccompat.h"
#include "crypto_core.h"
Expand Down
138 changes: 138 additions & 0 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#include <stdlib.h>
#include <string.h>

#include "bin_pack.h"
#include "ccompat.h"
#include "logger.h"
#include "mem.h"
Expand Down Expand Up @@ -1573,6 +1574,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;
}

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

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;
}

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 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
memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t));

Check warning on line 1698 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1698

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 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
memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t));

Check warning on line 1709 in toxcore/network.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxcore/network.c#L1709

MISRA 18.4 rule
return size;
}
}

const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str)
{
assert(ip_str != nullptr);
Expand Down
Loading

0 comments on commit ae65b33

Please sign in to comment.