summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorzugz (tox) <mbays+tox@sdf.org>2020-03-01 00:00:00 +0000
committerzugz (tox) <mbays+tox@sdf.org>2020-03-18 00:00:00 +0000
commitdb07bda7f7b1ab7f5f219a9ed3d7f732b7da66b0 (patch)
treee5b4e5b43320c4073b619c006c1b32040cd06b8d /toxcore
parent84e6a8d05704d9f4db79898984af861d759c478a (diff)
Add "member" invite response
This allows invitations to work in the case that the invitee is already in the group, which can happen if the group becomes split. Such an invitation is automatically accepted, leading to the peers becoming connected in the group and sharing peer lists.
Diffstat (limited to 'toxcore')
-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