@@ -42,6 +42,7 @@ typedef enum Group_Message_Id {
42
42
GROUP_MESSAGE_PING_ID = 0 ,
43
43
GROUP_MESSAGE_NEW_PEER_ID = 16 ,
44
44
GROUP_MESSAGE_KILL_PEER_ID = 17 ,
45
+ GROUP_MESSAGE_FREEZE_PEER_ID = 18 ,
45
46
GROUP_MESSAGE_NAME_ID = 48 ,
46
47
GROUP_MESSAGE_TITLE_ID = 49 ,
47
48
} Group_Message_Id ;
@@ -201,6 +202,17 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *real_pk)
201
202
return -1 ;
202
203
}
203
204
205
+ static 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
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
469
return -1 ;
458
470
}
459
471
472
+ static 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
500
/* Update last_active timestamp on peer, and thaw the peer if it is frozen.
461
501
*
462
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
541
++ g -> numpeers ;
502
542
503
- -- g -> numfrozen ;
504
-
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 ;
543
+ if (!delete_frozen (g , frozen_index )) {
544
+ return -1 ;
520
545
}
521
546
522
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
557
return g -> numpeers - 1 ;
533
558
}
534
559
560
+ static int delpeer (Group_Chats * g_c , uint32_t groupnumber , int peer_index , void * userdata , bool keep_connection );
561
+
562
+ static 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
583
/* Add a peer to the group chat, or update an existing peer.
536
584
*
537
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
637
Group_Peer * temp = (Group_Peer * )realloc (g -> group , sizeof (Group_Peer ) * (g -> numpeers + 1 ));
588
638
589
639
if (temp == nullptr ) {
@@ -1034,7 +1084,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
1034
1084
return groupnumber ;
1035
1085
}
1036
1086
1037
- static int group_leave (const Group_Chats * g_c , uint32_t groupnumber );
1087
+ static bool group_leave (const Group_Chats * g_c , uint32_t groupnumber , bool permanent );
1038
1088
1039
1089
/* Delete a groupchat from the chats array, informing the group first as
1040
1090
* appropriate.
@@ -1050,9 +1100,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently
1050
1100
return -1 ;
1051
1101
}
1052
1102
1053
- if (leave_permanently ) {
1054
- group_leave (g_c , groupnumber );
1055
- }
1103
+ group_leave (g_c , groupnumber , leave_permanently );
1056
1104
1057
1105
for (uint32_t i = 0 ; i < MAX_GROUP_CONNECTIONS ; ++ i ) {
1058
1106
if (g -> close [i ].type == GROUPCHAT_CLOSE_NONE ) {
@@ -1606,21 +1654,37 @@ static int group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uin
1606
1654
}
1607
1655
1608
1656
/* send a kill_peer message
1609
- * return 0 on success
1610
- * return -1 on failure
1657
+ * return true on success
1611
1658
*/
1612
- static int group_kill_peer_send (const Group_Chats * g_c , uint32_t groupnumber , uint16_t peer_num )
1659
+ static bool group_kill_peer_send (const Group_Chats * g_c , uint32_t groupnumber , uint16_t peer_num )
1613
1660
{
1614
1661
uint8_t packet [GROUP_MESSAGE_KILL_PEER_LENGTH ];
1615
1662
1616
1663
peer_num = net_htons (peer_num );
1617
1664
memcpy (packet , & peer_num , sizeof (uint16_t ));
1618
1665
1619
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
+ */
1676
+ static 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
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
1707
/* send message to announce leaving group
1644
- * return 0 on success
1645
- * return -1 on failure
1708
+ * return true on success
1646
1709
*/
1647
- static int group_leave (const Group_Chats * g_c , uint32_t groupnumber )
1710
+ static bool group_leave (const Group_Chats * g_c , uint32_t groupnumber , bool permanent )
1648
1711
{
1649
1712
Group_c * g = get_group_c (g_c , groupnumber );
1650
1713
1651
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
1811
return true;
1745
1812
}
1746
1813
1747
- for ( uint32_t i = 0 ; i < g -> numfrozen ; ++ i ) {
1748
- if ( id_equal ( g -> frozen [ i ]. real_pk , real_pk )) {
1749
- * peer_number = g -> frozen [ i ]. peer_number ;
1750
- return true ;
1751
- }
1814
+ const int frozen_index = frozen_in_chat ( g , real_pk );
1815
+
1816
+ if ( frozen_index >= 0 ) {
1817
+ * peer_number = g -> frozen [ frozen_index ]. peer_number ;
1818
+ return true;
1752
1819
}
1753
1820
1754
1821
return false;
@@ -2497,9 +2564,24 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2497
2564
memcpy (& peer_number , data , sizeof (uint16_t ));
2498
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
2580
if (index == -1 ) {
2581
+ if (ignore_frozen ) {
2582
+ return ;
2583
+ }
2584
+
2503
2585
/* If we don't know the peer this packet came from, then we query the
2504
2586
* list of peers from the relaying peer.
2505
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
2611
if (!check_message_info (message_number , message_id , & g -> group [index ])) {
2538
2612
return ;
2539
2613
}
@@ -2555,7 +2629,8 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2555
2629
}
2556
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
2634
if (msg_data_len != GROUP_MESSAGE_KILL_PEER_LENGTH ) {
2560
2635
return ;
2561
2636
}
@@ -2565,7 +2640,11 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
2565
2640
kill_peer_number = net_ntohs (kill_peer_number );
2566
2641
2567
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
2648
} else {
2570
2649
return ;
2571
2650
// TODO(irungentoo):
@@ -3011,7 +3090,7 @@ static uint8_t *save_conf(const Group_c *g, uint8_t *data)
3011
3090
host_to_lendian_bytes16 (data , g -> peer_number );
3012
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
3094
data += sizeof (uint32_t );
3016
3095
3017
3096
* data = g -> title_len ;
@@ -3020,24 +3099,20 @@ static uint8_t *save_conf(const Group_c *g, uint8_t *data)
3020
3099
memcpy (data , g -> title , g -> title_len );
3021
3100
data += g -> title_len ;
3022
3101
3023
- #ifndef NDEBUG
3024
- bool found_self = false;
3025
- #endif
3102
+ uint32_t numsaved = 0 ;
3026
3103
3027
3104
for (uint32_t j = 0 ; j < g -> numpeers + g -> numfrozen ; ++ j ) {
3028
3105
const Group_Peer * peer = (j < g -> numpeers ) ? & g -> group [j ] : & g -> frozen [j - g -> numpeers ];
3029
3106
3030
3107
if (id_equal (peer -> real_pk , g -> real_pk )) {
3031
- #ifndef NDEBUG
3032
- found_self = true;
3033
- #endif
3034
3108
continue ;
3035
3109
}
3036
3110
3037
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
3117
return data ;
3043
3118
}
0 commit comments