summaryrefslogtreecommitdiff
path: root/toxcore/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/group.c')
-rw-r--r--toxcore/group.c129
1 files changed, 125 insertions, 4 deletions
diff --git a/toxcore/group.c b/toxcore/group.c
index 636803fb..19d7ffa5 100644
--- a/toxcore/group.c
+++ b/toxcore/group.c
@@ -784,6 +784,26 @@ static unsigned int send_packet_group_peer(Friend_Connections *fr_c, int friendc
784 sizeof(packet), 0) != -1; 784 sizeof(packet), 0) != -1;
785} 785}
786 786
787/* Send a group lossy packet to friendcon_id.
788 *
789 * return 1 on success
790 * return 0 on failure
791 */
792static unsigned int send_lossy_group_peer(Friend_Connections *fr_c, int friendcon_id, uint8_t packet_id,
793 uint16_t group_num, const uint8_t *data, uint16_t length)
794{
795 if (1 + sizeof(uint16_t) + length > MAX_CRYPTO_DATA_SIZE)
796 return 0;
797
798 group_num = htons(group_num);
799 uint8_t packet[1 + sizeof(uint16_t) + length];
800 packet[0] = packet_id;
801 memcpy(packet + 1, &group_num, sizeof(uint16_t));
802 memcpy(packet + 1 + sizeof(uint16_t), data, length);
803 return send_lossy_cryptpacket(fr_c->net_crypto, friend_connection_crypt_connection_id(fr_c, friendcon_id), packet,
804 sizeof(packet)) != -1;
805}
806
787#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH) 807#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH)
788#define INVITE_ID 0 808#define INVITE_ID 0
789 809
@@ -1349,6 +1369,36 @@ static unsigned int send_message_all_close(const Group_Chats *g_c, int groupnumb
1349 return sent; 1369 return sent;
1350} 1370}
1351 1371
1372/* Send lossy message to all close except receiver (if receiver isn't -1)
1373 * NOTE: this function appends the group chat number to the data passed to it.
1374 *
1375 * return number of messages sent.
1376 */
1377static unsigned int send_lossy_all_close(const Group_Chats *g_c, int groupnumber, const uint8_t *data, uint16_t length,
1378 int receiver)
1379{
1380 Group_c *g = get_group_c(g_c, groupnumber);
1381
1382 if (!g)
1383 return 0;
1384
1385 uint16_t i, sent = 0;
1386
1387 for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
1388 if (g->close[i].type != GROUPCHAT_CLOSE_ONLINE)
1389 continue;
1390
1391 if ((int)i == receiver)
1392 continue;
1393
1394 if (send_lossy_group_peer(g_c->fr_c, g->close[i].number, PACKET_ID_LOSSY_GROUPCHAT, g->close[i].group_number, data,
1395 length))
1396 ++sent;
1397 }
1398
1399 return sent;
1400}
1401
1352#define MAX_GROUP_MESSAGE_DATA_LEN (MAX_CRYPTO_DATA_SIZE - (1 + MIN_MESSAGE_PACKET_LEN)) 1402#define MAX_GROUP_MESSAGE_DATA_LEN (MAX_CRYPTO_DATA_SIZE - (1 + MIN_MESSAGE_PACKET_LEN))
1353 1403
1354/* Send data of len with message_id to groupnumber. 1404/* Send data of len with message_id to groupnumber.
@@ -1580,21 +1630,81 @@ static int handle_packet(void *object, int friendcon_id, uint8_t *data, uint16_t
1580 return 0; 1630 return 0;
1581} 1631}
1582 1632
1633/* Did we already receive the lossy packet or not.
1634 *
1635 * return -1 on failure.
1636 * return 0 if packet was not received.
1637 * return 1 if packet was received.
1638 *
1639 * TODO: test this
1640 */
1641static unsigned int lossy_packet_not_received(Group_c *g, int peer_index, uint16_t message_number)
1642{
1643 if (peer_index == -1)
1644 return -1;
1645
1646 if (g->group[peer_index].bottom_lossy_number == g->group[peer_index].top_lossy_number) {
1647 g->group[peer_index].top_lossy_number = message_number;
1648 g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1;
1649 g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1;
1650 return 0;
1651 }
1652
1653 if (message_number - g->group[peer_index].bottom_lossy_number <= MAX_LOSSY_COUNT) {
1654 if (g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT])
1655 return 1;
1656
1657 g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1;
1658 return 0;
1659 }
1660
1661 if (message_number - g->group[peer_index].bottom_lossy_number > (1 << 15))
1662 return -1;
1663
1664 uint16_t top_distance = message_number - g->group[peer_index].top_lossy_number;
1665
1666 if (top_distance >= MAX_LOSSY_COUNT) {
1667 memset(g->group[peer_index].recv_lossy, 0, sizeof(g->group[peer_index].recv_lossy));
1668 g->group[peer_index].top_lossy_number = message_number;
1669 g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1;
1670 g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1;
1671 return 0;
1672 }
1673
1674 if (top_distance < MAX_LOSSY_COUNT) {
1675 unsigned int i;
1676
1677 for (i = g->group[peer_index].bottom_lossy_number; i != (g->group[peer_index].bottom_lossy_number + top_distance);
1678 ++i) {
1679 g->group[peer_index].recv_lossy[i % MAX_LOSSY_COUNT] = 0;
1680 }
1681
1682 g->group[peer_index].top_lossy_number = message_number;
1683 g->group[peer_index].bottom_lossy_number = (message_number - MAX_LOSSY_COUNT) + 1;
1684 g->group[peer_index].recv_lossy[message_number % MAX_LOSSY_COUNT] = 1;
1685 return 0;
1686 }
1687
1688 return -1;
1689}
1690
1583static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length) 1691static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length)
1584{ 1692{
1585 Group_Chats *g_c = object; 1693 Group_Chats *g_c = object;
1586 1694
1587 if (length < 1 + sizeof(uint16_t) + sizeof(uint16_t) + 1) 1695 if (length < 1 + sizeof(uint16_t) * 3 + 1)
1588 return -1; 1696 return -1;
1589 1697
1590 if (data[0] != PACKET_ID_LOSSY_GROUPCHAT) 1698 if (data[0] != PACKET_ID_LOSSY_GROUPCHAT)
1591 return -1; 1699 return -1;
1592 1700
1593 uint16_t groupnumber, peer_number; 1701 uint16_t groupnumber, peer_number, message_number;
1594 memcpy(&groupnumber, data + 1, sizeof(uint16_t)); 1702 memcpy(&groupnumber, data + 1, sizeof(uint16_t));
1595 memcpy(&peer_number, data + 1 + sizeof(uint16_t), sizeof(uint16_t)); 1703 memcpy(&peer_number, data + 1 + sizeof(uint16_t), sizeof(uint16_t));
1704 memcpy(&message_number, data + 1 + sizeof(uint16_t) * 2, sizeof(uint16_t));
1596 groupnumber = ntohs(groupnumber); 1705 groupnumber = ntohs(groupnumber);
1597 peer_number = ntohs(peer_number); 1706 peer_number = ntohs(peer_number);
1707 message_number = ntohs(message_number);
1598 1708
1599 Group_c *g = get_group_c(g_c, groupnumber); 1709 Group_c *g = get_group_c(g_c, groupnumber);
1600 1710
@@ -1611,11 +1721,22 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
1611 if (peer_index == -1) 1721 if (peer_index == -1)
1612 return -1; 1722 return -1;
1613 1723
1614 const uint8_t *lossy_data = data + 1 + sizeof(uint16_t) * 2; 1724 if (lossy_packet_not_received(g, peer_index, message_number))
1615 uint16_t lossy_length = length - (1 + sizeof(uint16_t) * 2); 1725 return -1;
1726
1727 const uint8_t *lossy_data = data + 1 + sizeof(uint16_t) * 3;
1728 uint16_t lossy_length = length - (1 + sizeof(uint16_t) * 3);
1616 uint8_t message_id = lossy_data[0]; 1729 uint8_t message_id = lossy_data[0];
1617 ++lossy_data; 1730 ++lossy_data;
1618 --lossy_length; 1731 --lossy_length;
1732
1733 switch (message_id) {
1734
1735
1736 }
1737
1738 send_lossy_all_close(g_c, groupnumber, data + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)),
1739 -1/*TODO close_index*/);
1619 return 0; 1740 return 0;
1620} 1741}
1621 1742