summaryrefslogtreecommitdiff
path: root/toxcore/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/group.c')
-rw-r--r--toxcore/group.c128
1 files changed, 91 insertions, 37 deletions
diff --git a/toxcore/group.c b/toxcore/group.c
index 50f6f2fe..b4248fd8 100644
--- a/toxcore/group.c
+++ b/toxcore/group.c
@@ -39,11 +39,13 @@ typedef enum Group_Message_Id {
39 39
40typedef enum Invite_Id { 40typedef enum Invite_Id {
41 INVITE_ID = 0, 41 INVITE_ID = 0,
42 INVITE_RESPONSE_ID = 1, 42 INVITE_ACCEPT_ID = 1,
43 INVITE_MEMBER_ID = 2,
43} Invite_Id; 44} Invite_Id;
44 45
45#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + 1 + GROUP_ID_LENGTH) 46#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + 1 + GROUP_ID_LENGTH)
46#define INVITE_RESPONSE_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH) 47#define INVITE_ACCEPT_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH)
48#define INVITE_MEMBER_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH + sizeof(uint16_t))
47 49
48#define ONLINE_PACKET_DATA_SIZE (sizeof(uint16_t) + 1 + GROUP_ID_LENGTH) 50#define ONLINE_PACKET_DATA_SIZE (sizeof(uint16_t) + 1 + GROUP_ID_LENGTH)
49 51
@@ -1512,6 +1514,9 @@ static bool try_send_rejoin(Group_Chats *g_c, Group_c *g, const uint8_t *real_pk
1512 1514
1513static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num); 1515static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
1514 1516
1517static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t friendnumber, const uint8_t *data,
1518 uint16_t length);
1519
1515/* Join a group (we need to have been invited first.) 1520/* Join a group (we need to have been invited first.)
1516 * 1521 *
1517 * expected_type is the groupchat type we expect the chat we are joining to 1522 * expected_type is the groupchat type we expect the chat we are joining to
@@ -1553,35 +1558,65 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ
1553 1558
1554 Group_c *g = &g_c->chats[groupnumber]; 1559 Group_c *g = &g_c->chats[groupnumber];
1555 1560
1556 const uint16_t group_num = net_htons(groupnumber);
1557 g->status = GROUPCHAT_STATUS_VALID; 1561 g->status = GROUPCHAT_STATUS_VALID;
1558 memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); 1562 memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE);
1559 1563
1560 uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; 1564 if (!send_invite_response(g_c, groupnumber, friendnumber, data, length)) {
1561 response[0] = INVITE_RESPONSE_ID; 1565 g->status = GROUPCHAT_STATUS_NONE;
1562 memcpy(response + 1, &group_num, sizeof(uint16_t)); 1566 return -6;
1563 memcpy(response + 1 + sizeof(uint16_t), data, sizeof(uint16_t) + 1 + GROUP_ID_LENGTH); 1567 }
1568
1569 return groupnumber;
1570}
1571
1572static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t friendnumber, const uint8_t *data,
1573 uint16_t length)
1574{
1575 Group_c *g = get_group_c(g_c, groupnumber);
1576
1577 const bool member = (g->status == GROUPCHAT_STATUS_CONNECTED);
1578
1579 VLA(uint8_t, response, member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE);
1580 response[0] = member ? INVITE_MEMBER_ID : INVITE_ACCEPT_ID;
1581 net_pack_u16(response + 1, groupnumber);
1582 memcpy(response + 1 + sizeof(uint16_t), data, length);
1583
1584 if (member) {
1585 net_pack_u16(response + 1 + sizeof(uint16_t) + length, g->peer_number);
1586 }
1587
1588 if (!send_conference_invite_packet(g_c->m, friendnumber, response, SIZEOF_VLA(response))) {
1589 return false;
1590 }
1564 1591
1565 if (send_conference_invite_packet(g_c->m, friendnumber, response, sizeof(response))) { 1592 if (!member) {
1566 uint16_t other_groupnum;
1567 memcpy(&other_groupnum, data, sizeof(other_groupnum));
1568 other_groupnum = net_ntohs(other_groupnum);
1569 g->type = data[sizeof(uint16_t)]; 1593 g->type = data[sizeof(uint16_t)];
1570 memcpy(g->id, data + sizeof(uint16_t) + 1, GROUP_ID_LENGTH); 1594 memcpy(g->id, data + sizeof(uint16_t) + 1, GROUP_ID_LENGTH);
1571 const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, 1595 }
1572 GROUPCHAT_CONNECTION_REASON_INTRODUCER, 1);
1573 1596
1574 if (connection_index != -1) { 1597 uint16_t other_groupnum;
1575 g->connections[connection_index].group_number = other_groupnum; 1598 net_unpack_u16(data, &other_groupnum);
1576 g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE;
1577 }
1578 1599
1579 send_peer_query(g_c, friendcon_id, other_groupnum); 1600 const int friendcon_id = getfriendcon_id(g_c->m, friendnumber);
1580 return groupnumber; 1601
1602 if (friendcon_id == -1) {
1603 return false;
1604 }
1605
1606 const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCER, 1);
1607
1608 if (member) {
1609 add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCING, 0);
1581 } 1610 }
1582 1611
1583 g->status = GROUPCHAT_STATUS_NONE; 1612 if (connection_index != -1) {
1584 return -6; 1613 g->connections[connection_index].group_number = other_groupnum;
1614 g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE;
1615 }
1616
1617 send_peer_query(g_c, friendcon_id, other_groupnum);
1618
1619 return true;
1585} 1620}
1586 1621
1587/* Set handlers for custom lossy packets. */ 1622/* Set handlers for custom lossy packets. */
@@ -1911,19 +1946,28 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
1911 } 1946 }
1912 1947
1913 return; 1948 return;
1949 } else {
1950 Group_c *g = get_group_c(g_c, groupnumber);
1951
1952 if (g && g->status == GROUPCHAT_STATUS_CONNECTED) {
1953 send_invite_response(g_c, groupnumber, friendnumber, invite_data, invite_length);
1954 }
1914 } 1955 }
1915 1956
1916 break; 1957 break;
1917 } 1958 }
1918 1959
1919 case INVITE_RESPONSE_ID: { 1960 case INVITE_ACCEPT_ID:
1920 if (length != INVITE_RESPONSE_PACKET_SIZE) { 1961 case INVITE_MEMBER_ID: {
1962 const bool member = (data[0] == INVITE_MEMBER_ID);
1963
1964 if (length != (member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE)) {
1921 return; 1965 return;
1922 } 1966 }
1923 1967
1924 uint16_t other_groupnum, groupnum; 1968 uint16_t other_groupnum, groupnum;
1925 memcpy(&groupnum, data + 1 + sizeof(uint16_t), sizeof(uint16_t)); 1969 net_unpack_u16(data + 1, &other_groupnum);
1926 groupnum = net_ntohs(groupnum); 1970 net_unpack_u16(data + 1 + sizeof(uint16_t), &groupnum);
1927 1971
1928 Group_c *g = get_group_c(g_c, groupnum); 1972 Group_c *g = get_group_c(g_c, groupnum);
1929 1973
@@ -1939,24 +1983,28 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
1939 return; 1983 return;
1940 } 1984 }
1941 1985
1942 /* TODO(irungentoo): what if two people enter the group at the same time and 1986 uint16_t peer_number;
1943 are given the same peer_number by different nodes? */
1944 uint16_t peer_number = random_u16();
1945 1987
1946 unsigned int tries = 0; 1988 if (member) {
1947 1989 net_unpack_u16(data + 1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH, &peer_number);
1948 while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) { 1990 } else {
1991 /* TODO(irungentoo): what if two people enter the group at the
1992 * same time and are given the same peer_number by different
1993 * nodes? */
1949 peer_number = random_u16(); 1994 peer_number = random_u16();
1950 ++tries;
1951 1995
1952 if (tries > 32) { 1996 unsigned int tries = 0;
1953 return; 1997
1998 while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) {
1999 peer_number = random_u16();
2000 ++tries;
2001
2002 if (tries > 32) {
2003 return;
2004 }
1954 } 2005 }
1955 } 2006 }
1956 2007
1957 memcpy(&other_groupnum, data + 1, sizeof(uint16_t));
1958 other_groupnum = net_ntohs(other_groupnum);
1959
1960 const int friendcon_id = getfriendcon_id(m, friendnumber); 2008 const int friendcon_id = getfriendcon_id(m, friendnumber);
1961 2009
1962 if (friendcon_id == -1) { 2010 if (friendcon_id == -1) {
@@ -1971,12 +2019,18 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
1971 const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, 2019 const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g,
1972 GROUPCHAT_CONNECTION_REASON_INTRODUCING, 1); 2020 GROUPCHAT_CONNECTION_REASON_INTRODUCING, 1);
1973 2021
2022 if (member) {
2023 add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCER, 0);
2024 send_peer_query(g_c, friendcon_id, other_groupnum);
2025 }
2026
1974 if (connection_index != -1) { 2027 if (connection_index != -1) {
1975 g->connections[connection_index].group_number = other_groupnum; 2028 g->connections[connection_index].group_number = other_groupnum;
1976 g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE; 2029 g->connections[connection_index].type = GROUPCHAT_CONNECTION_ONLINE;
1977 } 2030 }
1978 2031
1979 group_new_peer_send(g_c, groupnum, peer_number, real_pk, temp_pk); 2032 group_new_peer_send(g_c, groupnum, peer_number, real_pk, temp_pk);
2033
1980 break; 2034 break;
1981 } 2035 }
1982 2036