summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-06-27 15:49:50 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-06-27 15:49:50 +0300
commita9d73f89e44942f0994d73a99bc399e1f4865d12 (patch)
treef2f6430b56febcfb75f3e0ffeec7950b380fb9a6 /protocols/Tox/libtox/src
parent0af77111dfb30477ef9e722f1c77091a49a8be8f (diff)
fixes #1995 (Update libtox to 0.2.10)
Diffstat (limited to 'protocols/Tox/libtox/src')
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.c7
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.c122
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.h13
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.api.h26
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.c16
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.h36
6 files changed, 193 insertions, 27 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c
index 6b2715ee55..79925552ac 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.c
+++ b/protocols/Tox/libtox/src/toxcore/DHT.c
@@ -1986,7 +1986,6 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
}
uint32_t sent = 0;
- uint8_t friend_sent[MAX_FRIEND_CLIENTS] = {0};
IP_Port ip_list[MAX_FRIEND_CLIENTS];
const int ip_num = friend_iplist(dht, ip_list, num);
@@ -2001,10 +2000,6 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
* is *usually* good(tm) (bites us in the behind in this case though) */
for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
- if (friend_sent[i]) {/* Send one packet per client.*/
- continue;
- }
-
const Client_data *const client = &dht_friend->client_list[i];
const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr };
@@ -2017,7 +2012,7 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
if ((unsigned int)retval == length) {
++sent;
- friend_sent[i] = 1;
+ break; /* Send one packet per client.*/
}
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c
index 101c11963d..f6f8c70431 100644
--- a/protocols/Tox/libtox/src/toxcore/group.c
+++ b/protocols/Tox/libtox/src/toxcore/group.c
@@ -118,6 +118,8 @@ static bool realloc_conferences(Group_Chats *g_c, uint16_t num)
static void setup_conference(Group_c *g)
{
memset(g, 0, sizeof(Group_c));
+
+ g->maxfrozen = MAX_FROZEN_DEFAULT;
}
/* Create a new empty groupchat connection.
@@ -539,9 +541,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
++g->numpeers;
- if (!delete_frozen(g, frozen_index)) {
- return -1;
- }
+ delete_frozen(g, frozen_index);
if (g_c->peer_list_changed_callback) {
g_c->peer_list_changed_callback(g_c->m, groupnumber, userdata);
@@ -646,8 +646,8 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
id_copy(g->group[g->numpeers].temp_pk, temp_pk);
g->group[g->numpeers].temp_pk_updated = true;
g->group[g->numpeers].peer_number = peer_number;
-
g->group[g->numpeers].last_active = mono_time_get(g_c->mono_time);
+ g->group[g->numpeers].is_friend = (getfriend_id(g_c->m, real_pk) != -1);
++g->numpeers;
add_to_closest(g_c, groupnumber, real_pk, temp_pk);
@@ -754,6 +754,56 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
return 0;
}
+static int cmp_u64(uint64_t a, uint64_t b)
+{
+ return (a > b) - (a < b);
+}
+
+/* Order peers with friends first and with more recently active earlier */
+static int cmp_frozen(const void *a, const void *b)
+{
+ const Group_Peer *pa = (const Group_Peer *) a;
+ const Group_Peer *pb = (const Group_Peer *) b;
+
+ if (pa->is_friend ^ pb->is_friend) {
+ return pa->is_friend ? -1 : 1;
+ }
+
+ return cmp_u64(pb->last_active, pa->last_active);
+}
+
+/* Delete frozen peers as necessary to ensure at most g->maxfrozen remain.
+ *
+ * return true if any frozen peers are removed.
+ */
+static bool delete_old_frozen(Group_c *g)
+{
+ if (g->numfrozen <= g->maxfrozen) {
+ return false;
+ }
+
+ if (g->maxfrozen == 0) {
+ free(g->frozen);
+ g->frozen = nullptr;
+ g->numfrozen = 0;
+ return true;
+ }
+
+ qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen);
+
+ Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * g->maxfrozen);
+
+ if (temp == nullptr) {
+ return false;
+ }
+
+ g->frozen = temp;
+
+ g->numfrozen = g->maxfrozen;
+
+ return true;
+}
+
static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk);
static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata)
@@ -764,8 +814,6 @@ static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, v
return -1;
}
- try_send_rejoin(g_c, groupnumber, g->group[peer_index].real_pk);
-
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen + 1));
if (temp == nullptr) {
@@ -774,9 +822,19 @@ static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, v
g->frozen = temp;
g->frozen[g->numfrozen] = g->group[peer_index];
+ g->frozen[g->numfrozen].object = nullptr;
+
+ if (delpeer(g_c, groupnumber, peer_index, userdata, true) != 0) {
+ return -1;
+ }
+
+ try_send_rejoin(g_c, groupnumber, g->frozen[g->numfrozen].real_pk);
+
++g->numfrozen;
- return delpeer(g_c, groupnumber, peer_index, userdata, true);
+ delete_old_frozen(g);
+
+ return 0;
}
@@ -1237,6 +1295,24 @@ int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, int p
return 0;
}
+/* Set maximum number of frozen peers.
+ *
+ * return 0 on success.
+ * return -1 if groupnumber is invalid.
+ */
+int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t maxfrozen)
+{
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ return -1;
+ }
+
+ g->maxfrozen = maxfrozen;
+ delete_old_frozen(g);
+ return 0;
+}
+
/* List all the (frozen, if frozen is true) peers in the group chat.
*
* Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array.
@@ -2831,6 +2907,12 @@ static unsigned int lossy_packet_not_received(const Group_c *g, int peer_index,
}
+/* Does this group type make use of lossy packets? */
+static bool type_uses_lossy(uint8_t type)
+{
+ return (type == GROUPCHAT_TYPE_AV);
+}
+
static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata)
{
Group_Chats *g_c = (Group_Chats *)object;
@@ -2857,6 +2939,10 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
return -1;
}
+ if (!type_uses_lossy(g->type)) {
+ return -1;
+ }
+
const int index = friend_in_close(g, friendcon_id);
if (index == -1) {
@@ -2883,6 +2969,8 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
++lossy_data;
--lossy_length;
+ send_lossy_all_close(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index);
+
if (g_c->lossy_packethandlers[message_id].function) {
if (g_c->lossy_packethandlers[message_id].function(g->object, groupnumber, peer_index, g->group[peer_index].object,
lossy_data, lossy_length) == -1) {
@@ -2892,7 +2980,6 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
return -1;
}
- send_lossy_all_close(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), index);
return 0;
}
@@ -2934,7 +3021,7 @@ int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, int peer
return 0;
}
-/* Return the object tide to the group chat previously set by group_set_object.
+/* Return the object tied to the group chat previously set by group_set_object.
*
* return NULL on failure.
* return object on success.
@@ -2950,7 +3037,7 @@ void *group_get_object(const Group_Chats *g_c, uint32_t groupnumber)
return g->object;
}
-/* Return the object tide to the group chat peer previously set by group_peer_set_object.
+/* Return the object tied to the group chat peer previously set by group_peer_set_object.
*
* return NULL on failure.
* return object on success.
@@ -3198,10 +3285,12 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data,
lendian_bytes_to_host32(&g->numfrozen, data);
data += sizeof(uint32_t);
- g->frozen = (Group_Peer *)malloc(sizeof(Group_Peer) * g->numfrozen);
+ if (g->numfrozen > 0) {
+ g->frozen = (Group_Peer *)malloc(sizeof(Group_Peer) * g->numfrozen);
- if (g->frozen == nullptr) {
- return STATE_LOAD_STATUS_ERROR;
+ if (g->frozen == nullptr) {
+ return STATE_LOAD_STATUS_ERROR;
+ }
}
g->title_len = *data;
@@ -3242,6 +3331,13 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data,
memcpy(peer->nick, data, peer->nick_len);
data += peer->nick_len;
+
+ // NOTE: this relies on friends being loaded before conferences.
+ peer->is_friend = (getfriend_id(g_c->m, peer->real_pk) != -1);
+ }
+
+ if (g->numfrozen > g->maxfrozen) {
+ g->maxfrozen = g->numfrozen;
}
g->status = GROUPCHAT_STATUS_CONNECTED;
diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h
index 83015273b3..884ac8f5d4 100644
--- a/protocols/Tox/libtox/src/toxcore/group.h
+++ b/protocols/Tox/libtox/src/toxcore/group.h
@@ -50,6 +50,7 @@ typedef struct Group_Peer {
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
bool temp_pk_updated;
+ bool is_friend;
uint64_t last_active;
@@ -106,6 +107,9 @@ typedef void peer_on_join_cb(void *object, uint32_t conference_number, uint32_t
typedef void peer_on_leave_cb(void *object, uint32_t conference_number, void *peer_object);
typedef void group_on_delete_cb(void *object, uint32_t conference_number);
+// maximum number of frozen peers to store; group_set_max_frozen() overrides.
+#define MAX_FROZEN_DEFAULT 128
+
typedef struct Group_c {
uint8_t status;
@@ -118,6 +122,8 @@ typedef struct Group_c {
Group_Peer *frozen;
uint32_t numfrozen;
+ uint32_t maxfrozen;
+
/* TODO(zugz) rename close to something more accurate - "connected"? */
Groupchat_Close close[MAX_GROUP_CONNECTIONS];
@@ -284,6 +290,13 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, int peernumber,
int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, int peernumber,
uint64_t *last_active);
+/* Set maximum number of frozen peers.
+ *
+ * return 0 on success.
+ * return -1 if groupnumber is invalid.
+ */
+int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t maxfrozen);
+
/* invite friendnumber to groupnumber
*
* return 0 on success.
diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h
index 237254de73..e73402de9c 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.api.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.api.h
@@ -182,7 +182,7 @@ const VERSION_MINOR = 2;
* The patch or revision number. Incremented when bugfixes are applied without
* changing any functionality or API or ABI.
*/
-const VERSION_PATCH = 9;
+const VERSION_PATCH = 10;
/**
* A macro to check at preprocessing time whether the client code is compatible
@@ -1377,7 +1377,7 @@ namespace friend {
* Write the status message of the friend designated by the given friend number to a byte
* array.
*
- * Call $size to determine the allocation size for the `status_name`
+ * Call $size to determine the allocation size for the `status_message`
* parameter.
*
* The data written to `status_message` is equal to the data received by the last
@@ -2294,7 +2294,10 @@ namespace conference {
/**
* Copy the name of peer_number who is in conference_number to name.
- * name must be at least $MAX_NAME_LENGTH long.
+ *
+ * Call $size to determine the allocation size for the `name` parameter.
+ *
+ * @param name A valid memory region large enough to store the peer's name.
*
* @return true on success.
*/
@@ -2339,7 +2342,10 @@ namespace conference {
/**
* Copy the name of offline_peer_number who is in conference_number to name.
- * name must be at least $MAX_NAME_LENGTH long.
+ *
+ * Call $size to determine the allocation size for the `name` parameter.
+ *
+ * @param name A valid memory region large enough to store the peer's name.
*
* @return true on success.
*/
@@ -2369,6 +2375,17 @@ namespace conference {
}
/**
+ * Set maximum number of offline peers to store, overriding the default.
+ */
+ bool set_max_offline(uint32_t conference_number, uint32_t max_offline_peers) {
+ /**
+ * The conference number passed did not designate a valid conference.
+ */
+ CONFERENCE_NOT_FOUND,
+ }
+
+
+ /**
* Invites a friend to a conference.
*
* We must be connected to the conference, meaning that the conference has not
@@ -2800,6 +2817,7 @@ typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk;
typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New;
typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete;
typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query;
+typedef TOX_ERR_CONFERENCE_SET_MAX_OFFLINE Tox_Err_Conference_Set_Max_Offline;
typedef TOX_ERR_CONFERENCE_BY_ID Tox_Err_Conference_By_Id;
typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid;
typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite;
diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c
index d59094afa3..0a575dbf1b 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.c
+++ b/protocols/Tox/libtox/src/toxcore/tox.c
@@ -1742,6 +1742,22 @@ uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t co
return last_active;
}
+bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number,
+ uint32_t max_offline_peers,
+ Tox_Err_Conference_Set_Max_Offline *error)
+{
+ const Messenger *m = tox->m;
+ const int ret = group_set_max_frozen(m->conferences_object, conference_number, max_offline_peers);
+
+ if (ret == -1) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND);
+ return false;
+ }
+
+ SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK);
+ return true;
+}
+
bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference_number,
Tox_Err_Conference_Invite *error)
{
diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h
index ba67d5ad30..af6f33608b 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.h
@@ -183,7 +183,7 @@ uint32_t tox_version_minor(void);
* The patch or revision number. Incremented when bugfixes are applied without
* changing any functionality or API or ABI.
*/
-#define TOX_VERSION_PATCH 9
+#define TOX_VERSION_PATCH 10
uint32_t tox_version_patch(void);
@@ -1556,7 +1556,7 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number
* Write the status message of the friend designated by the given friend number to a byte
* array.
*
- * Call tox_friend_get_status_message_size to determine the allocation size for the `status_name`
+ * Call tox_friend_get_status_message_size to determine the allocation size for the `status_message`
* parameter.
*
* The data written to `status_message` is equal to the data received by the last
@@ -2609,7 +2609,10 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num
/**
* Copy the name of peer_number who is in conference_number to name.
- * name must be at least TOX_MAX_NAME_LENGTH long.
+ *
+ * Call tox_conference_peer_get_name_size to determine the allocation size for the `name` parameter.
+ *
+ * @param name A valid memory region large enough to store the peer's name.
*
* @return true on success.
*/
@@ -2645,7 +2648,10 @@ size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t confer
/**
* Copy the name of offline_peer_number who is in conference_number to name.
- * name must be at least TOX_MAX_NAME_LENGTH long.
+ *
+ * Call tox_conference_offline_peer_get_name_size to determine the allocation size for the `name` parameter.
+ *
+ * @param name A valid memory region large enough to store the peer's name.
*
* @return true on success.
*/
@@ -2667,6 +2673,27 @@ bool tox_conference_offline_peer_get_public_key(const Tox *tox, uint32_t confere
uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t conference_number,
uint32_t offline_peer_number, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+typedef enum TOX_ERR_CONFERENCE_SET_MAX_OFFLINE {
+
+ /**
+ * The function returned successfully.
+ */
+ TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK,
+
+ /**
+ * The conference number passed did not designate a valid conference.
+ */
+ TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND,
+
+} TOX_ERR_CONFERENCE_SET_MAX_OFFLINE;
+
+
+/**
+ * Set maximum number of offline peers to store, overriding the default.
+ */
+bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number, uint32_t max_offline_peers,
+ TOX_ERR_CONFERENCE_SET_MAX_OFFLINE *error);
+
typedef enum TOX_ERR_CONFERENCE_INVITE {
/**
@@ -3185,6 +3212,7 @@ typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk;
typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New;
typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete;
typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query;
+typedef TOX_ERR_CONFERENCE_SET_MAX_OFFLINE Tox_Err_Conference_Set_Max_Offline;
typedef TOX_ERR_CONFERENCE_BY_ID Tox_Err_Conference_By_Id;
typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid;
typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite;