diff options
author | George Hazan <ghazan@miranda.im> | 2019-06-27 15:49:50 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-06-27 15:49:50 +0300 |
commit | a9d73f89e44942f0994d73a99bc399e1f4865d12 (patch) | |
tree | f2f6430b56febcfb75f3e0ffeec7950b380fb9a6 /protocols/Tox/libtox/src | |
parent | 0af77111dfb30477ef9e722f1c77091a49a8be8f (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.c | 7 | ||||
-rw-r--r-- | protocols/Tox/libtox/src/toxcore/group.c | 122 | ||||
-rw-r--r-- | protocols/Tox/libtox/src/toxcore/group.h | 13 | ||||
-rw-r--r-- | protocols/Tox/libtox/src/toxcore/tox.api.h | 26 | ||||
-rw-r--r-- | protocols/Tox/libtox/src/toxcore/tox.c | 16 | ||||
-rw-r--r-- | protocols/Tox/libtox/src/toxcore/tox.h | 36 |
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; |