summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--auto_tests/Makefile.inc5
-rw-r--r--auto_tests/conference_double_invite_test.c4
-rw-r--r--auto_tests/conference_invite_merge_test.c244
-rw-r--r--toxcore/group.c128
5 files changed, 344 insertions, 38 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 81a41e7f..355fd103 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -397,6 +397,7 @@ auto_test(TCP)
397auto_test(bootstrap) 397auto_test(bootstrap)
398auto_test(conference) 398auto_test(conference)
399auto_test(conference_double_invite) 399auto_test(conference_double_invite)
400auto_test(conference_invite_merge)
400auto_test(conference_peer_nick) 401auto_test(conference_peer_nick)
401auto_test(conference_simple) 402auto_test(conference_simple)
402auto_test(conference_two) 403auto_test(conference_two)
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc
index fcaeff5b..983c83d3 100644
--- a/auto_tests/Makefile.inc
+++ b/auto_tests/Makefile.inc
@@ -3,6 +3,7 @@ if BUILD_TESTS
3TESTS = \ 3TESTS = \
4 bootstrap_test \ 4 bootstrap_test \
5 conference_double_invite_test \ 5 conference_double_invite_test \
6 conference_invite_merge_test \
6 conference_peer_nick_test \ 7 conference_peer_nick_test \
7 conference_simple_test \ 8 conference_simple_test \
8 conference_test \ 9 conference_test \
@@ -73,6 +74,10 @@ conference_double_invite_test_SOURCES = ../auto_tests/conference_double_invite_t
73conference_double_invite_test_CFLAGS = $(AUTOTEST_CFLAGS) 74conference_double_invite_test_CFLAGS = $(AUTOTEST_CFLAGS)
74conference_double_invite_test_LDADD = $(AUTOTEST_LDADD) 75conference_double_invite_test_LDADD = $(AUTOTEST_LDADD)
75 76
77conference_invite_merge_test_SOURCES = ../auto_tests/conference_invite_merge_test.c
78conference_invite_merge_test_CFLAGS = $(AUTOTEST_CFLAGS)
79conference_invite_merge_test_LDADD = $(AUTOTEST_LDADD)
80
76conference_peer_nick_test_SOURCES = ../auto_tests/conference_peer_nick_test.c 81conference_peer_nick_test_SOURCES = ../auto_tests/conference_peer_nick_test.c
77conference_peer_nick_test_CFLAGS = $(AUTOTEST_CFLAGS) 82conference_peer_nick_test_CFLAGS = $(AUTOTEST_CFLAGS)
78conference_peer_nick_test_LDADD = $(AUTOTEST_LDADD) 83conference_peer_nick_test_LDADD = $(AUTOTEST_LDADD)
diff --git a/auto_tests/conference_double_invite_test.c b/auto_tests/conference_double_invite_test.c
index 17124f1c..c9e64e5b 100644
--- a/auto_tests/conference_double_invite_test.c
+++ b/auto_tests/conference_double_invite_test.c
@@ -28,6 +28,8 @@ static void handle_conference_invite(
28 state->index, friend_number, type, (unsigned)length); 28 state->index, friend_number, type, (unsigned)length);
29 fprintf(stderr, "tox%u joining conference\n", state->index); 29 fprintf(stderr, "tox%u joining conference\n", state->index);
30 30
31 ck_assert_msg(!state->joined, "invitation callback generated for already joined conference");
32
31 if (friend_number != -1) { 33 if (friend_number != -1) {
32 Tox_Err_Conference_Join err; 34 Tox_Err_Conference_Join err;
33 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); 35 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
@@ -71,7 +73,7 @@ static void conference_double_invite_test(Tox **toxes, State *state)
71 73
72 fprintf(stderr, "Invitations accepted\n"); 74 fprintf(stderr, "Invitations accepted\n");
73 75
74 // Invite one more time, resulting in friend -1 inviting tox1 (toxes[1]). 76 fprintf(stderr, "Sending second invitation; should be ignored\n");
75 tox_conference_invite(toxes[0], 0, state[0].conference, nullptr); 77 tox_conference_invite(toxes[0], 0, state[0].conference, nullptr);
76 78
77 iterate_all_wait(2, toxes, state, ITERATION_INTERVAL); 79 iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
diff --git a/auto_tests/conference_invite_merge_test.c b/auto_tests/conference_invite_merge_test.c
new file mode 100644
index 00000000..e7ec499c
--- /dev/null
+++ b/auto_tests/conference_invite_merge_test.c
@@ -0,0 +1,244 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <stdbool.h>
6#include <stdint.h>
7#include <stdlib.h>
8
9typedef struct State {
10 uint32_t index;
11 uint64_t clock;
12
13 size_t save_size;
14 uint8_t *save_state;
15 bool alive;
16
17 bool connected;
18 uint32_t conference;
19} State;
20
21#define NUM_INVITE_MERGE_TOX 5
22
23#include "run_auto_test.h"
24
25static void handle_conference_invite(
26 Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
27 const uint8_t *cookie, size_t length, void *user_data)
28{
29 State *state = (State *)user_data;
30
31 if (friend_number != -1) {
32 Tox_Err_Conference_Join err;
33 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
34 ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
35 "attempting to join the conference returned with an error: %d", err);
36 fprintf(stderr, "#%u accepted invite to conference %u\n", state->index, state->conference);
37 }
38}
39
40static void handle_conference_connected(
41 Tox *tox, uint32_t conference_number, void *user_data)
42{
43 State *state = (State *)user_data;
44 fprintf(stderr, "#%u connected to conference %u\n", state->index, state->conference);
45 state->connected = true;
46}
47
48static void iterate_alive(Tox **toxes, State *state)
49{
50 for (uint32_t i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
51 if (!state[i].alive) {
52 continue;
53 }
54
55 tox_iterate(toxes[i], &state[i]);
56 state[i].clock += ITERATION_INTERVAL;
57 }
58
59 c_sleep(20);
60}
61
62static void save(Tox **toxes, State *state, uint32_t n)
63{
64 fprintf(stderr, "Saving #%u\n", state[n].index);
65
66 if (state[n].save_state != nullptr) {
67 free(state[n].save_state);
68 }
69
70 state[n].save_size = tox_get_savedata_size(toxes[n]);
71 state[n].save_state = (uint8_t *)malloc(state[n].save_size);
72 ck_assert_msg(state[n].save_state != nullptr, "malloc failed");
73 tox_get_savedata(toxes[n], state[n].save_state);
74}
75
76static void kill(Tox **toxes, State *state, uint32_t n)
77{
78 fprintf(stderr, "Killing #%u\n", state[n].index);
79 state[n].alive = false;
80 tox_kill(toxes[n]);
81}
82
83static void reload(Tox **toxes, State *state, uint32_t n)
84{
85 if (state[n].alive) {
86 state[n].alive = false;
87 tox_kill(toxes[n]);
88 }
89
90 fprintf(stderr, "Reloading #%u\n", state[n].index);
91 ck_assert(state[n].save_state != nullptr);
92
93 struct Tox_Options *const options = tox_options_new(nullptr);
94 tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
95 tox_options_set_savedata_data(options, state[n].save_state, state[n].save_size);
96 toxes[n] = tox_new_log(options, nullptr, &state[n].index);
97 tox_options_free(options);
98
99 set_mono_time_callback(toxes[n], &state[n]);
100 state[n].alive = true;
101}
102
103static void wait_connected(Tox **toxes, State *state, uint32_t n, uint32_t friendnumber)
104{
105 do {
106 iterate_alive(toxes, state);
107 } while (tox_friend_get_connection_status(toxes[n], friendnumber, nullptr) == TOX_CONNECTION_NONE);
108}
109
110static void do_invite(Tox **toxes, State *state, uint32_t inviter, uint32_t invitee, uint32_t friendnum)
111{
112 fprintf(stderr, "#%u inviting #%u\n", state[inviter].index, state[invitee].index);
113
114 Tox_Err_Conference_Invite err;
115 tox_conference_invite(toxes[inviter], friendnum, state[inviter].conference, &err);
116 ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
117 "#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", state[inviter].index, state[invitee].index,
118 friendnum, err);
119
120 do {
121 iterate_alive(toxes, state);
122 } while (!state[invitee].connected);
123}
124
125static bool group_complete(Tox **toxes, State *state)
126{
127 int c = -1, size = 0;
128
129 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
130 if (!state[i].alive) {
131 continue;
132 }
133
134 const int ct = tox_conference_peer_count(toxes[i], state[i].conference, nullptr);
135
136 if (c == -1) {
137 c = ct;
138 } else if (c != ct) {
139 return false;
140 }
141
142 ++size;
143 }
144
145 return (c == size);
146}
147
148static void wait_group_complete(Tox **toxes, State *state)
149{
150 do {
151 iterate_alive(toxes, state);
152 } while (!group_complete(toxes, state));
153}
154
155static void conference_invite_merge_test(Tox **toxes, State *state)
156{
157 // Test that an explicit invite between peers in different connected
158 // components will cause a split group to merge
159
160 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
161 tox_callback_conference_invite(toxes[i], handle_conference_invite);
162 tox_callback_conference_connected(toxes[i], &handle_conference_connected);
163 state[i].alive = true;
164 state[i].save_state = nullptr;
165 }
166
167 {
168 // Create new conference, tox 2 is the founder.
169 Tox_Err_Conference_New err;
170 state[2].conference = tox_conference_new(toxes[2], &err);
171 state[2].connected = true;
172 ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
173 "attempting to create a new conference returned with an error: %d", err);
174 fprintf(stderr, "Created conference: index=%u\n", state[2].conference);
175 }
176
177 save(toxes, state, 2);
178
179 do_invite(toxes, state, 2, 1, 0);
180 do_invite(toxes, state, 1, 0, 0);
181
182 save(toxes, state, 1);
183 kill(toxes, state, 1);
184
185 do {
186 iterate_alive(toxes, state);
187 } while (tox_conference_peer_count(toxes[2], state[2].conference, nullptr) != 1);
188
189 do_invite(toxes, state, 2, 3, 1);
190 do_invite(toxes, state, 3, 4, 1);
191
192 kill(toxes, state, 2);
193
194 reload(toxes, state, 1);
195
196 uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
197 tox_self_get_public_key(toxes[1], public_key);
198 tox_friend_add_norequest(toxes[3], public_key, nullptr);
199 tox_self_get_public_key(toxes[3], public_key);
200 tox_friend_add_norequest(toxes[1], public_key, nullptr);
201 wait_connected(toxes, state, 1, 2);
202
203 do_invite(toxes, state, 1, 3, 2);
204
205 fprintf(stderr, "Waiting for group to merge\n");
206
207 wait_group_complete(toxes, state);
208
209 fprintf(stderr, "Group merged\n");
210
211 reload(toxes, state, 2);
212 wait_connected(toxes, state, 2, 0);
213 do_invite(toxes, state, 2, 1, 0);
214
215 fprintf(stderr, "Waiting for #2 to rejoin\n");
216
217 wait_group_complete(toxes, state);
218
219 kill(toxes, state, 2);
220 wait_group_complete(toxes, state);
221 reload(toxes, state, 2);
222 wait_connected(toxes, state, 2, 0);
223 wait_connected(toxes, state, 1, 1);
224
225 do_invite(toxes, state, 1, 2, 1);
226
227 fprintf(stderr, "Waiting for #2 to rejoin\n");
228
229 wait_group_complete(toxes, state);
230
231 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
232 if (state[i].save_state != nullptr) {
233 free(state[i].save_state);
234 }
235 }
236}
237
238int main(void)
239{
240 setvbuf(stdout, nullptr, _IONBF, 0);
241
242 run_auto_test(NUM_INVITE_MERGE_TOX, conference_invite_merge_test, true);
243 return 0;
244}
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