Skip to content

Commit

Permalink
Add groupchat API function that returns an IP address string for a peer
Browse files Browse the repository at this point in the history
This function will return an IP address string for direct/UDP connections, and nothing for
TCP connections. This is due to the fact that a TCP connection with a given peer may use
more than one TCP relay.
  • Loading branch information
JFreegman committed Dec 2, 2023
1 parent 7cfe35d commit 6b94530
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 11 deletions.
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 @@
1608abb52cd16775216d01d06569e6437d86ed11e9fc8dc6dc9c1c28668ccd8b /usr/local/bin/tox-bootstrapd
35080909d79dd4a073f4992b6b194f10ab0b4af6470aaee051c2b45721bb6049 /usr/local/bin/tox-bootstrapd
57 changes: 57 additions & 0 deletions toxcore/group_chats.c
Original file line number Diff line number Diff line change
Expand Up @@ -3506,6 +3506,63 @@ int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uin
return 0;
}

/** @brief Puts a string of the IP associated with `ip_port` in `ip_str` if the
* connection is direct, otherwise puts a placeholder in the buffer indicating that
* the IP cannot be displayed.
*/
non_null()
static void get_gc_ip_ntoa(const GC_Chat *chat, const IP_Port *ip_port, Ip_Ntoa *ip_str)

Check warning on line 3514 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3514

Added line #L3514 was not covered by tests
{
net_ip_ntoa(&ip_port->ip, ip_str);

Check warning on line 3516 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3516

Added line #L3516 was not covered by tests

if (!ip_str->ip_is_valid) {
ip_str->buf[0] = '-';
ip_str->buf[1] = '\0';
ip_str->length = 1;

Check warning on line 3521 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3518-L3521

Added lines #L3518 - L3521 were not covered by tests
}
}

int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id)

Check warning on line 3525 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3525

Added line #L3525 was not covered by tests
{
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
const GC_Connection *gconn = get_gc_connection(chat, peer_number);

Check warning on line 3528 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3527-L3528

Added lines #L3527 - L3528 were not covered by tests

if (gconn == nullptr) {
return -1;

Check warning on line 3531 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3530-L3531

Added lines #L3530 - L3531 were not covered by tests
}

const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;

Check warning on line 3534 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3534

Added line #L3534 was not covered by tests

Ip_Ntoa ip_str;
get_gc_ip_ntoa(chat, ip_port, &ip_str);

Check warning on line 3537 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3536-L3537

Added lines #L3536 - L3537 were not covered by tests

return ip_str.length;

Check warning on line 3539 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3539

Added line #L3539 was not covered by tests
}

int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr)

Check warning on line 3542 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3542

Added line #L3542 was not covered by tests
{
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
const GC_Connection *gconn = get_gc_connection(chat, peer_number);

Check warning on line 3545 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3544-L3545

Added lines #L3544 - L3545 were not covered by tests

if (gconn == nullptr) {
return -1;

Check warning on line 3548 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3547-L3548

Added lines #L3547 - L3548 were not covered by tests
}

if (ip_addr == nullptr) {
return -2;

Check warning on line 3552 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3551-L3552

Added lines #L3551 - L3552 were not covered by tests
}

const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;

Check warning on line 3555 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3555

Added line #L3555 was not covered by tests

Ip_Ntoa ip_str;
get_gc_ip_ntoa(chat, ip_port, &ip_str);

Check warning on line 3558 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3557-L3558

Added lines #L3557 - L3558 were not covered by tests

assert(ip_str.length <= IP_NTOA_LEN);
memcpy(ip_addr, ip_str.buf, ip_str.length);

Check warning on line 3561 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3560-L3561

Added lines #L3560 - L3561 were not covered by tests

return 0;

Check warning on line 3563 in toxcore/group_chats.c

View check run for this annotation

Codecov / codecov/patch

toxcore/group_chats.c#L3563

Added line #L3563 was not covered by tests
}

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);
Expand Down
23 changes: 23 additions & 0 deletions toxcore/group_chats.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,29 @@ int gc_get_peer_nick_size(const GC_Chat *chat, uint32_t peer_id);
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 Returns the length of the IP address for the peer designated by `peer_id`.
* Returns -1 if peer_id is invalid.
*/
non_null()
int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id);

/** @brief Copies peer_id's IP address to `ip_addr`.
*
* If the peer is forcing TCP connections this will be a placeholder value indicating
* that their real IP address is unknown to us.
*
* If `peer_id` designates ourself, it will write either our own IP address or a
* placeholder value, depending on whether or not we're forcing TCP connections.
*
* `ip_addr` should have room for at least IP_NTOA_LEN bytes.
*
* Returns 0 on success.
* Returns -1 if peer_id is invalid or doesn't correspond to a valid peer connection.
* Returns -2 if `ip_addr` is null.
*/
non_null(1) nullable(3)
int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr);

/** @brief Gets the connection status for peer associated with `peer_id`.
*
* Returns 2 if we have a direct (UDP) connection with a peer.
Expand Down
15 changes: 7 additions & 8 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,30 +1514,29 @@ void ipport_copy(IP_Port *target, const IP_Port *source)
*target = *source;
}

/** @brief Converts IP into a string.
*
* Writes error message into the buffer on error.
*
* @param ip_str contains a buffer of the required size.
*
* @return Pointer to the buffer inside `ip_str` containing the IP string.
*/
const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str)
{
assert(ip_str != nullptr);

ip_str->ip_is_valid = false;

if (ip == nullptr) {
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid: NULL)");
ip_str->length = strlen(ip_str->buf);

Check warning on line 1525 in toxcore/network.c

View check run for this annotation

Codecov / codecov/patch

toxcore/network.c#L1525

Added line #L1525 was not covered by tests
return ip_str->buf;
}

if (!ip_parse_addr(ip, ip_str->buf, sizeof(ip_str->buf))) {
snprintf(ip_str->buf, sizeof(ip_str->buf), "(IP invalid, family %u)", ip->family.value);
ip_str->length = strlen(ip_str->buf);
return ip_str->buf;
}

/* brute force protection against lacking termination */
ip_str->buf[sizeof(ip_str->buf) - 1] = '\0';
ip_str->length = strlen(ip_str->buf);
ip_str->ip_is_valid = true;

return ip_str->buf;
}

Expand Down
7 changes: 5 additions & 2 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,14 @@ bool ipv6_ipv4_in_v6(const IP6 *a);
/** this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
#define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?

/** Contains a null terminated string of an IP address. */
typedef struct Ip_Ntoa {
char buf[IP_NTOA_LEN];
char buf[IP_NTOA_LEN]; // a string formatted IP address or an error message.
uint16_t length; // the length of the string (not including the null byte).
bool ip_is_valid; // if this is false `buf` will contain an error message.
} Ip_Ntoa;

/** @brief Converts IP into a string.
/** @brief Converts IP into a null terminated string.
*
* Writes error message into the buffer on error.
*
Expand Down
54 changes: 54 additions & 0 deletions toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ static_assert(FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
"FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE");
static_assert(TOX_DHT_NODE_IP_STRING_SIZE == IP_NTOA_LEN,
"TOX_DHT_NODE_IP_STRING_SIZE is assumed to be equal to IP_NTOA_LEN");
static_assert(TOX_GROUP_PEER_IP_STRING_MAX_LENGTH == IP_NTOA_LEN,
"TOX_GROUP_PEER_IP_STRING_MAX_LENGTH is assumed to be equal to IP_NTOA_LEN");
static_assert(TOX_DHT_NODE_PUBLIC_KEY_SIZE == CRYPTO_PUBLIC_KEY_SIZE,
"TOX_DHT_NODE_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE");
static_assert(TOX_FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
Expand Down Expand Up @@ -3515,6 +3517,58 @@ bool tox_group_peer_get_public_key(const Tox *tox, uint32_t group_number, uint32
return true;
}

size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id,

Check warning on line 3520 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3520

Added line #L3520 was not covered by tests
Tox_Err_Group_Peer_Query *error)
{
assert(tox != nullptr);

Check warning on line 3523 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3523

Added line #L3523 was not covered by tests

tox_lock(tox);
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);

Check warning on line 3526 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3525-L3526

Added lines #L3525 - L3526 were not covered by tests

if (chat == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return -1;

Check warning on line 3531 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3528-L3531

Added lines #L3528 - L3531 were not covered by tests
}

const int ret = gc_get_peer_ip_address_size(chat, peer_id);
tox_unlock(tox);

Check warning on line 3535 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3534-L3535

Added lines #L3534 - L3535 were not covered by tests

if (ret == -1) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
return -1;

Check warning on line 3539 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3537-L3539

Added lines #L3537 - L3539 were not covered by tests
} else {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
return ret;

Check warning on line 3542 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3541-L3542

Added lines #L3541 - L3542 were not covered by tests
}
}

bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32_t peer_id, uint8_t *ip_addr,

Check warning on line 3546 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3546

Added line #L3546 was not covered by tests
Tox_Err_Group_Peer_Query *error)
{
assert(tox != nullptr);

Check warning on line 3549 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3549

Added line #L3549 was not covered by tests

tox_lock(tox);
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);

Check warning on line 3552 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3551-L3552

Added lines #L3551 - L3552 were not covered by tests

if (chat == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;

Check warning on line 3557 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3554-L3557

Added lines #L3554 - L3557 were not covered by tests
}

const int ret = gc_get_peer_ip_address(chat, peer_id, ip_addr);
tox_unlock(tox);

Check warning on line 3561 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3560-L3561

Added lines #L3560 - L3561 were not covered by tests

if (ret == -1) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
return false;

Check warning on line 3565 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3563-L3565

Added lines #L3563 - L3565 were not covered by tests
}

SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
return true;

Check warning on line 3569 in toxcore/tox.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox.c#L3568-L3569

Added lines #L3568 - L3569 were not covered by tests
}

Tox_Connection tox_group_peer_get_connection_status(const Tox *tox, uint32_t group_number, uint32_t peer_id,
Tox_Err_Group_Peer_Query *error)
{
Expand Down
37 changes: 37 additions & 0 deletions toxcore/tox.h
Original file line number Diff line number Diff line change
Expand Up @@ -3346,6 +3346,12 @@ uint32_t tox_group_chat_id_size(void);

uint32_t tox_group_peer_public_key_size(void);

/**
* Maximum size of a peer IP address string.
*/
#define TOX_GROUP_PEER_IP_STRING_MAX_LENGTH 96

uint32_t tox_group_peer_ip_string_max_length(void);

/*******************************************************************************
*
Expand Down Expand Up @@ -4027,6 +4033,37 @@ typedef void tox_group_peer_status_cb(Tox *tox, uint32_t group_number, uint32_t
*/
void tox_callback_group_peer_status(Tox *tox, tox_group_peer_status_cb *callback);

/**
* Return the length of the peer's IP address in string form. If the group number or ID
* is invalid, the return value is unspecified.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose IP address length we want to retrieve.
*/
size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id,
Tox_Err_Group_Peer_Query *error);
/**
* Write the IP address associated with the designated peer_id for the designated group number
* to ip_addr.
*
* If the peer is forcing TCP connections a placeholder value will be written instead,
* indicating that their real IP address is unknown to us.
*
* If `peer_id` designates ourself, it will write either our own IP address or a placeholder value,
* depending on whether or not we're forcing TCP connections.
*
* Call tox_group_peer_get_ip_address_size to determine the allocation size for the `ip_addr` parameter.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose public key we wish to retrieve.
* @param ip_addr A valid memory region large enough to store the IP address string.
* If this parameter is NULL, this function call has no effect.
*
* @return true on success.
*/
bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32_t peer_id, uint8_t *ip_addr,
Tox_Err_Group_Peer_Query *error);


/*******************************************************************************
*
Expand Down
4 changes: 4 additions & 0 deletions toxcore/tox_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ uint32_t tox_group_peer_public_key_size(void)
{
return TOX_GROUP_PEER_PUBLIC_KEY_SIZE;
}
uint32_t tox_group_peer_ip_string_max_length(void)

Check warning on line 127 in toxcore/tox_api.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox_api.c#L127

Added line #L127 was not covered by tests
{
return TOX_GROUP_PEER_IP_STRING_MAX_LENGTH;

Check warning on line 129 in toxcore/tox_api.c

View check run for this annotation

Codecov / codecov/patch

toxcore/tox_api.c#L129

Added line #L129 was not covered by tests
}
uint32_t tox_dht_node_ip_string_size(void)
{
return TOX_DHT_NODE_IP_STRING_SIZE;
Expand Down

0 comments on commit 6b94530

Please sign in to comment.