summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorzugz (tox) <mbays+tox@sdf.org>2018-11-17 21:33:46 +0100
committeriphydf <iphydf@users.noreply.github.com>2019-01-06 19:37:33 +0000
commite5561ad2b0db69cc58ce6d858bd6aca1928b0d8f (patch)
tree1cb55c7639edebb4f2d8c877eb898be81534592b /toxcore
parente08f631547612a807922adc50f12ed8d2231a955 (diff)
Improve handling of peers entering and leaving conferences
* send freeze packet on quit * delete existing peers with same real_pk on adding a peer * record actual number of conference peers saved
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/group.c185
1 files changed, 130 insertions, 55 deletions
diff --git a/toxcore/group.c b/toxcore/group.c
index b345a01c..dfa821a4 100644
--- a/toxcore/group.c
+++ b/toxcore/group.c
@@ -42,6 +42,7 @@ typedef enum Group_Message_Id {
42 GROUP_MESSAGE_PING_ID = 0, 42 GROUP_MESSAGE_PING_ID = 0,
43 GROUP_MESSAGE_NEW_PEER_ID = 16, 43 GROUP_MESSAGE_NEW_PEER_ID = 16,
44 GROUP_MESSAGE_KILL_PEER_ID = 17, 44 GROUP_MESSAGE_KILL_PEER_ID = 17,
45 GROUP_MESSAGE_FREEZE_PEER_ID = 18,
45 GROUP_MESSAGE_NAME_ID = 48, 46 GROUP_MESSAGE_NAME_ID = 48,
46 GROUP_MESSAGE_TITLE_ID = 49, 47 GROUP_MESSAGE_TITLE_ID = 49,
47} Group_Message_Id; 48} Group_Message_Id;
@@ -201,6 +202,17 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk)
201 return -1; 202 return -1;
202} 203}
203 204
205static int frozen_in_chat(const Group_c *chat, const uint8_t *real_pk)
206{
207 for (uint32_t i = 0; i < chat->numfrozen; ++i) {
208 if (id_equal(chat->frozen[i].real_pk, real_pk)) {
209 return i;
210 }
211 }
212
213 return -1;
214}
215
204/* 216/*
205 * check if group with the given type and id is in group array. 217 * check if group with the given type and id is in group array.
206 * 218 *
@@ -457,6 +469,34 @@ static int get_frozen_index(Group_c *g, uint16_t peer_number)
457 return -1; 469 return -1;
458} 470}
459 471
472static bool delete_frozen(Group_c *g, uint32_t frozen_index)
473{
474 if (frozen_index >= g->numfrozen) {
475 return false;
476 }
477
478 --g->numfrozen;
479
480 if (g->numfrozen == 0) {
481 free(g->frozen);
482 g->frozen = nullptr;
483 } else {
484 if (g->numfrozen != frozen_index) {
485 g->frozen[frozen_index] = g->frozen[g->numfrozen];
486 }
487
488 Group_Peer *frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen));
489
490 if (frozen_temp == nullptr) {
491 return false;
492 }
493
494 g->frozen = frozen_temp;
495 }
496
497 return true;
498}
499
460/* Update last_active timestamp on peer, and thaw the peer if it is frozen. 500/* Update last_active timestamp on peer, and thaw the peer if it is frozen.
461 * 501 *
462 * return peer index if peer is in the conference. 502 * return peer index if peer is in the conference.
@@ -500,23 +540,8 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
500 540
501 ++g->numpeers; 541 ++g->numpeers;
502 542
503 --g->numfrozen; 543 if (!delete_frozen(g, frozen_index)) {
504 544 return -1;
505 if (g->numfrozen == 0) {
506 free(g->frozen);
507 g->frozen = nullptr;
508 } else {
509 if (g->numfrozen != (uint32_t)frozen_index) {
510 g->frozen[frozen_index] = g->frozen[g->numfrozen];
511 }
512
513 Group_Peer *frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen));
514
515 if (frozen_temp == nullptr) {
516 return -1;
517 }
518
519 g->frozen = frozen_temp;
520 } 545 }
521 546
522 if (g_c->peer_list_changed_callback) { 547 if (g_c->peer_list_changed_callback) {
@@ -532,6 +557,29 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
532 return g->numpeers - 1; 557 return g->numpeers - 1;
533} 558}
534 559
560static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata, bool keep_connection);
561
562static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk, void *userdata)
563{
564 Group_c *g = get_group_c(g_c, groupnumber);
565
566 if (!g) {
567 return;
568 }
569
570 int prev_peer_index = peer_in_chat(g, real_pk);
571
572 if (prev_peer_index >= 0) {
573 delpeer(g_c, groupnumber, prev_peer_index, userdata, false);
574 }
575
576 int prev_frozen_index = frozen_in_chat(g, real_pk);
577
578 if (prev_frozen_index >= 0) {
579 delete_frozen(g, prev_frozen_index);
580 }
581}
582
535/* Add a peer to the group chat, or update an existing peer. 583/* Add a peer to the group chat, or update an existing peer.
536 * 584 *
537 * fresh indicates whether we should consider this information on the peer to 585 * fresh indicates whether we should consider this information on the peer to
@@ -584,6 +632,8 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
584 } 632 }
585 } 633 }
586 634
635 delete_any_peer_with_pk(g_c, groupnumber, real_pk, userdata);
636
587 Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1)); 637 Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1));
588 638
589 if (temp == nullptr) { 639 if (temp == nullptr) {
@@ -1034,7 +1084,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
1034 return groupnumber; 1084 return groupnumber;
1035} 1085}
1036 1086
1037static int group_leave(const Group_Chats *g_c, uint32_t groupnumber); 1087static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool permanent);
1038 1088
1039/* Delete a groupchat from the chats array, informing the group first as 1089/* Delete a groupchat from the chats array, informing the group first as
1040 * appropriate. 1090 * appropriate.
@@ -1050,9 +1100,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently
1050 return -1; 1100 return -1;
1051 } 1101 }
1052 1102
1053 if (leave_permanently) { 1103 group_leave(g_c, groupnumber, leave_permanently);
1054 group_leave(g_c, groupnumber);
1055 }
1056 1104
1057 for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { 1105 for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
1058 if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { 1106 if (g->close[i].type == GROUPCHAT_CLOSE_NONE) {
@@ -1606,10 +1654,9 @@ static int group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uin
1606} 1654}
1607 1655
1608/* send a kill_peer message 1656/* send a kill_peer message
1609 * return 0 on success 1657 * return true on success
1610 * return -1 on failure
1611 */ 1658 */
1612static int group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num) 1659static bool group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num)
1613{ 1660{
1614 uint8_t packet[GROUP_MESSAGE_KILL_PEER_LENGTH]; 1661 uint8_t packet[GROUP_MESSAGE_KILL_PEER_LENGTH];
1615 1662
@@ -1617,10 +1664,27 @@ static int group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, ui
1617 memcpy(packet, &peer_num, sizeof(uint16_t)); 1664 memcpy(packet, &peer_num, sizeof(uint16_t));
1618 1665
1619 if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_KILL_PEER_ID, packet, sizeof(packet)) > 0) { 1666 if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_KILL_PEER_ID, packet, sizeof(packet)) > 0) {
1620 return 0; 1667 return true;
1621 } 1668 }
1622 1669
1623 return -1; 1670 return false;
1671}
1672
1673/* send a freeze_peer message
1674 * return true on success
1675 */
1676static bool group_freeze_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num)
1677{
1678 uint8_t packet[GROUP_MESSAGE_KILL_PEER_LENGTH];
1679
1680 peer_num = net_htons(peer_num);
1681 memcpy(packet, &peer_num, sizeof(uint16_t));
1682
1683 if (send_message_group(g_c, groupnumber, GROUP_MESSAGE_FREEZE_PEER_ID, packet, sizeof(packet)) > 0) {
1684 return true;
1685 }
1686
1687 return false;
1624} 1688}
1625 1689
1626/* send a name message 1690/* send a name message
@@ -1641,18 +1705,21 @@ static int group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const u
1641} 1705}
1642 1706
1643/* send message to announce leaving group 1707/* send message to announce leaving group
1644 * return 0 on success 1708 * return true on success
1645 * return -1 on failure
1646 */ 1709 */
1647static int group_leave(const Group_Chats *g_c, uint32_t groupnumber) 1710static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool permanent)
1648{ 1711{
1649 Group_c *g = get_group_c(g_c, groupnumber); 1712 Group_c *g = get_group_c(g_c, groupnumber);
1650 1713
1651 if (!g) { 1714 if (!g) {
1652 return -1; 1715 return false;
1653 } 1716 }
1654 1717
1655 return group_kill_peer_send(g_c, groupnumber, g->peer_number); 1718 if (permanent) {
1719 return group_kill_peer_send(g_c, groupnumber, g->peer_number);
1720 } else {
1721 return group_freeze_peer_send(g_c, groupnumber, g->peer_number);
1722 }
1656} 1723}
1657 1724
1658 1725
@@ -1744,11 +1811,11 @@ static bool get_peer_number(const Group_c *g, const uint8_t *real_pk, uint16_t *
1744 return true; 1811 return true;
1745 } 1812 }
1746 1813
1747 for (uint32_t i = 0; i < g->numfrozen; ++i) { 1814 const int frozen_index = frozen_in_chat(g, real_pk);
1748 if (id_equal(g->frozen[i].real_pk, real_pk)) { 1815
1749 *peer_number = g->frozen[i].peer_number; 1816 if (frozen_index >= 0) {
1750 return true; 1817 *peer_number = g->frozen[frozen_index].peer_number;
1751 } 1818 return true;
1752 } 1819 }
1753 1820
1754 return false; 1821 return false;
@@ -2497,9 +2564,24 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2497 memcpy(&peer_number, data, sizeof(uint16_t)); 2564 memcpy(&peer_number, data, sizeof(uint16_t));
2498 peer_number = net_ntohs(peer_number); 2565 peer_number = net_ntohs(peer_number);
2499 2566
2500 const int index = note_peer_active(g_c, groupnumber, peer_number, userdata); 2567 uint32_t message_number;
2568 memcpy(&message_number, data + sizeof(uint16_t), sizeof(message_number));
2569 message_number = net_ntohl(message_number);
2570
2571 const uint8_t message_id = data[sizeof(uint16_t) + sizeof(message_number)];
2572 const uint8_t *msg_data = data + sizeof(uint16_t) + sizeof(message_number) + 1;
2573 const uint16_t msg_data_len = length - (sizeof(uint16_t) + sizeof(message_number) + 1);
2574
2575 const bool ignore_frozen = message_id == GROUP_MESSAGE_FREEZE_PEER_ID;
2576
2577 const int index = ignore_frozen ? get_peer_index(g, peer_number)
2578 : note_peer_active(g_c, groupnumber, peer_number, userdata);
2501 2579
2502 if (index == -1) { 2580 if (index == -1) {
2581 if (ignore_frozen) {
2582 return;
2583 }
2584
2503 /* If we don't know the peer this packet came from, then we query the 2585 /* If we don't know the peer this packet came from, then we query the
2504 * list of peers from the relaying peer. 2586 * list of peers from the relaying peer.
2505 * (They would not have relayed it if they didn't know the peer.) */ 2587 * (They would not have relayed it if they didn't know the peer.) */
@@ -2526,14 +2608,6 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2526 } 2608 }
2527 } 2609 }
2528 2610
2529 uint32_t message_number;
2530 memcpy(&message_number, data + sizeof(uint16_t), sizeof(message_number));
2531 message_number = net_ntohl(message_number);
2532
2533 const uint8_t message_id = data[sizeof(uint16_t) + sizeof(message_number)];
2534 const uint8_t *msg_data = data + sizeof(uint16_t) + sizeof(message_number) + 1;
2535 const uint16_t msg_data_len = length - (sizeof(uint16_t) + sizeof(message_number) + 1);
2536
2537 if (!check_message_info(message_number, message_id, &g->group[index])) { 2611 if (!check_message_info(message_number, message_id, &g->group[index])) {
2538 return; 2612 return;
2539 } 2613 }
@@ -2555,7 +2629,8 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2555 } 2629 }
2556 break; 2630 break;
2557 2631
2558 case GROUP_MESSAGE_KILL_PEER_ID: { 2632 case GROUP_MESSAGE_KILL_PEER_ID:
2633 case GROUP_MESSAGE_FREEZE_PEER_ID: {
2559 if (msg_data_len != GROUP_MESSAGE_KILL_PEER_LENGTH) { 2634 if (msg_data_len != GROUP_MESSAGE_KILL_PEER_LENGTH) {
2560 return; 2635 return;
2561 } 2636 }
@@ -2565,7 +2640,11 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2565 kill_peer_number = net_ntohs(kill_peer_number); 2640 kill_peer_number = net_ntohs(kill_peer_number);
2566 2641
2567 if (peer_number == kill_peer_number) { 2642 if (peer_number == kill_peer_number) {
2568 delpeer(g_c, groupnumber, index, userdata, false); 2643 if (message_id == GROUP_MESSAGE_KILL_PEER_ID) {
2644 delpeer(g_c, groupnumber, index, userdata, false);
2645 } else {
2646 freeze_peer(g_c, groupnumber, index, userdata);
2647 }
2569 } else { 2648 } else {
2570 return; 2649 return;
2571 // TODO(irungentoo): 2650 // TODO(irungentoo):
@@ -3011,7 +3090,7 @@ static uint8_t *save_conf(const Group_c *g, uint8_t *data)
3011 host_to_lendian_bytes16(data, g->peer_number); 3090 host_to_lendian_bytes16(data, g->peer_number);
3012 data += sizeof(uint16_t); 3091 data += sizeof(uint16_t);
3013 3092
3014 host_to_lendian_bytes32(data, g->numpeers - 1 + g->numfrozen); 3093 uint8_t *numsaved_location = data;
3015 data += sizeof(uint32_t); 3094 data += sizeof(uint32_t);
3016 3095
3017 *data = g->title_len; 3096 *data = g->title_len;
@@ -3020,24 +3099,20 @@ static uint8_t *save_conf(const Group_c *g, uint8_t *data)
3020 memcpy(data, g->title, g->title_len); 3099 memcpy(data, g->title, g->title_len);
3021 data += g->title_len; 3100 data += g->title_len;
3022 3101
3023#ifndef NDEBUG 3102 uint32_t numsaved = 0;
3024 bool found_self = false;
3025#endif
3026 3103
3027 for (uint32_t j = 0; j < g->numpeers + g->numfrozen; ++j) { 3104 for (uint32_t j = 0; j < g->numpeers + g->numfrozen; ++j) {
3028 const Group_Peer *peer = (j < g->numpeers) ? &g->group[j] : &g->frozen[j - g->numpeers]; 3105 const Group_Peer *peer = (j < g->numpeers) ? &g->group[j] : &g->frozen[j - g->numpeers];
3029 3106
3030 if (id_equal(peer->real_pk, g->real_pk)) { 3107 if (id_equal(peer->real_pk, g->real_pk)) {
3031#ifndef NDEBUG
3032 found_self = true;
3033#endif
3034 continue; 3108 continue;
3035 } 3109 }
3036 3110
3037 data = save_peer(peer, data); 3111 data = save_peer(peer, data);
3112 ++numsaved;
3038 } 3113 }
3039 3114
3040 assert(found_self); 3115 host_to_lendian_bytes32(numsaved_location, numsaved);
3041 3116
3042 return data; 3117 return data;
3043} 3118}