mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Add groupchat API function that returns an IP address string for a peer
This function will return an IP address string associated with a peer. If the peer is not accepting direct connections a placeholder value will be returned, indicating that their real IP address is unknown. We do not return TCP relay IP addresses because a TCP connection with a peer may use multiple relays simultaneously.
This commit is contained in:
parent
5f863a5492
commit
b2315c50e0
|
@ -9,6 +9,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "auto_test_support.h"
|
||||
#include "../toxcore/tox_private.h"
|
||||
|
||||
typedef struct State {
|
||||
size_t peer_joined_count;
|
||||
|
@ -42,6 +43,22 @@ typedef struct State {
|
|||
|
||||
#define PEER_LIMIT 20
|
||||
|
||||
static void print_ip(Tox *tox, uint32_t groupnumber, uint32_t peer_id)
|
||||
{
|
||||
Tox_Err_Group_Peer_Query err;
|
||||
size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err);
|
||||
|
||||
ck_assert_msg(err == TOX_ERR_GROUP_PEER_QUERY_OK, "failed to get ip address size: error %d", err);
|
||||
|
||||
uint8_t ip_str[TOX_GROUP_PEER_IP_STRING_MAX_LENGTH];
|
||||
tox_group_peer_get_ip_address(tox, groupnumber, peer_id, ip_str, &err);
|
||||
ip_str[length] = '\0';
|
||||
|
||||
ck_assert_msg(err == TOX_ERR_GROUP_PEER_QUERY_OK, "failed to get ip address: error %d", err);
|
||||
|
||||
fprintf(stderr, "%s\n", ip_str);
|
||||
}
|
||||
|
||||
static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, uint32_t groupnumber, size_t name_length)
|
||||
{
|
||||
for (size_t i = 0; i < tox_count; ++i) {
|
||||
|
@ -119,6 +136,9 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s joined with IP: ", peer_name);
|
||||
print_ip(tox, groupnumber, peer_id);
|
||||
|
||||
state->peer_id = peer_id;
|
||||
++state->peer_joined_count;
|
||||
}
|
||||
|
@ -178,6 +198,11 @@ static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *u
|
|||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
|
||||
ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0);
|
||||
|
||||
uint32_t peer_id = tox_group_self_get_peer_id(tox, groupnumber, nullptr);
|
||||
|
||||
fprintf(stderr, "self joined with IP: ");
|
||||
print_ip(tox, groupnumber, peer_id);
|
||||
|
||||
++state->self_joined_count;
|
||||
}
|
||||
|
||||
|
@ -341,6 +366,7 @@ static void group_announce_test(AutoTox *autotoxes)
|
|||
ck_assert(memcmp(tox0_pk_query, tox0_self_pk, TOX_GROUP_PEER_PUBLIC_KEY_SIZE) == 0);
|
||||
|
||||
fprintf(stderr, "Peer 0 disconnecting...\n");
|
||||
|
||||
// tox 0 disconnects then reconnects
|
||||
Tox_Err_Group_Disconnect d_err;
|
||||
tox_group_disconnect(tox0, groupnumber, &d_err);
|
||||
|
|
|
@ -1 +1 @@
|
|||
e0fa59db7d25204f917e4b114e1607cb3819fe9da74de5f9e807bcf76abefe42 /usr/local/bin/tox-bootstrapd
|
||||
8cb8b2f7bbc0ce71551365ed72ae468c731eafdce93e01d8c9a04ed5d904fcd9 /usr/local/bin/tox-bootstrapd
|
||||
|
|
|
@ -3517,6 +3517,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 IP_Port *ip_port, Ip_Ntoa *ip_str)
|
||||
{
|
||||
net_ip_ntoa(&ip_port->ip, ip_str);
|
||||
|
||||
if (!ip_str->ip_is_valid) {
|
||||
ip_str->buf[0] = '-';
|
||||
ip_str->buf[1] = '\0';
|
||||
ip_str->length = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id)
|
||||
{
|
||||
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||
const GC_Connection *gconn = get_gc_connection(chat, peer_number);
|
||||
|
||||
if (gconn == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;
|
||||
|
||||
Ip_Ntoa ip_str;
|
||||
get_gc_ip_ntoa(ip_port, &ip_str);
|
||||
|
||||
return ip_str.length;
|
||||
}
|
||||
|
||||
int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr)
|
||||
{
|
||||
const int peer_number = get_peer_number_of_peer_id(chat, peer_id);
|
||||
const GC_Connection *gconn = get_gc_connection(chat, peer_number);
|
||||
|
||||
if (gconn == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ip_addr == nullptr) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
const IP_Port *ip_port = peer_number == 0 ? &chat->self_ip_port : &gconn->addr.ip_port;
|
||||
|
||||
Ip_Ntoa ip_str;
|
||||
get_gc_ip_ntoa(ip_port, &ip_str);
|
||||
|
||||
assert(ip_str.length <= IP_NTOA_LEN);
|
||||
memcpy(ip_addr, ip_str.buf, ip_str.length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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`.
|
||||
*
|
||||
* If `peer_id` designates ourself, the return value indicates whether we're capable
|
||||
|
|
|
@ -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 = (uint16_t)strlen(ip_str->buf);
|
||||
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 = (uint16_t)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 = (uint16_t)strlen(ip_str->buf);
|
||||
ip_str->ip_is_valid = true;
|
||||
|
||||
return ip_str->buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
return TOX_GROUP_PEER_IP_STRING_MAX_LENGTH;
|
||||
}
|
||||
uint32_t tox_dht_node_ip_string_size(void)
|
||||
{
|
||||
return TOX_DHT_NODE_IP_STRING_SIZE;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "ccompat.h"
|
||||
#include "group_chats.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
#include "tox_struct.h"
|
||||
|
@ -166,3 +167,57 @@ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox){
|
|||
return num_cap;
|
||||
}
|
||||
|
||||
#ifndef VANILLA_NACL
|
||||
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)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
|
||||
tox_lock(tox);
|
||||
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
|
||||
|
||||
if (chat == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
|
||||
tox_unlock(tox);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int ret = gc_get_peer_ip_address_size(chat, peer_id);
|
||||
tox_unlock(tox);
|
||||
|
||||
if (ret == -1) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
|
||||
return -1;
|
||||
} else {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
|
||||
tox_lock(tox);
|
||||
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
|
||||
|
||||
if (chat == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_GROUP_NOT_FOUND);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int ret = gc_get_peer_ip_address(chat, peer_id, ip_addr);
|
||||
tox_unlock(tox);
|
||||
|
||||
if (ret == -1) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* VANILLA_NACL */
|
||||
|
|
|
@ -156,6 +156,51 @@ uint16_t tox_dht_get_num_closelist(const Tox *tox);
|
|||
*/
|
||||
uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* :: DHT groupchat queries.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user