diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/group.c | 129 | ||||
-rw-r--r-- | toxcore/group.h | 6 |
2 files changed, 131 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 | */ | ||
792 | static 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 | */ | ||
1377 | static 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 | */ | ||
1641 | static 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 | |||
1583 | static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length) | 1691 | static 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 | ||
diff --git a/toxcore/group.h b/toxcore/group.h index 74abfa66..5adde463 100644 --- a/toxcore/group.h +++ b/toxcore/group.h | |||
@@ -33,6 +33,8 @@ enum { | |||
33 | GROUPCHAT_STATUS_CONNECTED | 33 | GROUPCHAT_STATUS_CONNECTED |
34 | }; | 34 | }; |
35 | 35 | ||
36 | #define MAX_LOSSY_COUNT 256 | ||
37 | |||
36 | typedef struct { | 38 | typedef struct { |
37 | uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; | 39 | uint8_t real_pk[crypto_box_PUBLICKEYBYTES]; |
38 | uint8_t temp_pk[crypto_box_PUBLICKEYBYTES]; | 40 | uint8_t temp_pk[crypto_box_PUBLICKEYBYTES]; |
@@ -44,6 +46,9 @@ typedef struct { | |||
44 | uint8_t nick_len; | 46 | uint8_t nick_len; |
45 | 47 | ||
46 | uint16_t peer_number; | 48 | uint16_t peer_number; |
49 | |||
50 | uint8_t recv_lossy[MAX_LOSSY_COUNT]; | ||
51 | uint16_t bottom_lossy_number, top_lossy_number; | ||
47 | } Group_Peer; | 52 | } Group_Peer; |
48 | 53 | ||
49 | #define DESIRED_CLOSE_CONNECTIONS 4 | 54 | #define DESIRED_CLOSE_CONNECTIONS 4 |
@@ -80,6 +85,7 @@ typedef struct { | |||
80 | uint8_t identifier[GROUP_IDENTIFIER_LENGTH]; | 85 | uint8_t identifier[GROUP_IDENTIFIER_LENGTH]; |
81 | 86 | ||
82 | uint32_t message_number; | 87 | uint32_t message_number; |
88 | uint16_t lossy_message_number; | ||
83 | uint16_t peer_number; | 89 | uint16_t peer_number; |
84 | 90 | ||
85 | uint64_t last_sent_ping; | 91 | uint64_t last_sent_ping; |