Skip to content

Commit cc31ff0

Browse files
committed
feat: Add support for custom random number generator.
This can be used by fuzzers to make RNG-driven code deterministic (i.e. based on the fuzzer input).
1 parent 660e346 commit cc31ff0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+587
-458
lines changed

auto_tests/TCP_test.c

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,17 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
4646
static void test_basic(void)
4747
{
4848
Mono_Time *mono_time = mono_time_new();
49+
const Random *rng = system_random();
50+
ck_assert(rng != nullptr);
4951
Logger *logger = logger_new();
5052
logger_callback_log(logger, (logger_cb *)print_debug_log, nullptr, nullptr);
5153

5254
// Attempt to create a new TCP_Server instance.
5355
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
5456
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
55-
crypto_new_keypair(self_public_key, self_secret_key);
57+
crypto_new_keypair(rng, self_public_key, self_secret_key);
5658
const Network *ns = system_network();
57-
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
59+
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
5860
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
5961
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS,
6062
"Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS);
@@ -81,19 +83,19 @@ static void test_basic(void)
8183
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
8284
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
8385
uint8_t f_nonce[CRYPTO_NONCE_SIZE];
84-
crypto_new_keypair(f_public_key, f_secret_key);
85-
random_nonce(f_nonce);
86+
crypto_new_keypair(rng, f_public_key, f_secret_key);
87+
random_nonce(rng, f_nonce);
8688

8789
// Generation of the initial handshake.
8890
uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE];
8991
uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE);
9092
ck_assert(handshake_plain != nullptr);
91-
crypto_new_keypair(handshake_plain, t_secret_key);
93+
crypto_new_keypair(rng, handshake_plain, t_secret_key);
9294
memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE);
9395
uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE);
9496
ck_assert(handshake != nullptr);
9597
memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE);
96-
random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE);
98+
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
9799

98100
// Encrypting handshake
99101
int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
@@ -194,7 +196,7 @@ struct sec_TCP_con {
194196
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
195197
};
196198

197-
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
199+
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
198200
{
199201
struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
200202
ck_assert(sec_c != nullptr);
@@ -203,22 +205,22 @@ static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Network *ns,
203205

204206
IP_Port localhost;
205207
localhost.ip = get_loopback();
206-
localhost.port = net_htons(ports[random_u32() % NUM_PORTS]);
208+
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
207209

208210
bool ok = net_connect(logger, sock, &localhost);
209211
ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
210212

211213
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
212-
crypto_new_keypair(sec_c->public_key, f_secret_key);
213-
random_nonce(sec_c->sent_nonce);
214+
crypto_new_keypair(rng, sec_c->public_key, f_secret_key);
215+
random_nonce(rng, sec_c->sent_nonce);
214216

215217
uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE];
216218
uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE];
217-
crypto_new_keypair(handshake_plain, t_secret_key);
219+
crypto_new_keypair(rng, handshake_plain, t_secret_key);
218220
memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, sec_c->sent_nonce, CRYPTO_NONCE_SIZE);
219221
uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE];
220222
memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
221-
random_nonce(handshake + CRYPTO_PUBLIC_KEY_SIZE);
223+
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
222224

223225
int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
224226
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@@ -296,19 +298,21 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui
296298
static void test_some(void)
297299
{
298300
Mono_Time *mono_time = mono_time_new();
301+
const Random *rng = system_random();
302+
ck_assert(rng != nullptr);
299303
Logger *logger = logger_new();
300304
const Network *ns = system_network();
301305

302306
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
303307
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
304-
crypto_new_keypair(self_public_key, self_secret_key);
305-
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
308+
crypto_new_keypair(rng, self_public_key, self_secret_key);
309+
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
306310
ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server");
307311
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports.");
308312

309-
struct sec_TCP_con *con1 = new_TCP_con(logger, ns, tcp_s, mono_time);
310-
struct sec_TCP_con *con2 = new_TCP_con(logger, ns, tcp_s, mono_time);
311-
struct sec_TCP_con *con3 = new_TCP_con(logger, ns, tcp_s, mono_time);
313+
struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
314+
struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
315+
struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time);
312316

313317
uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE];
314318
requ_p[0] = TCP_PACKET_ROUTING_REQUEST;
@@ -484,26 +488,28 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
484488

485489
static void test_client(void)
486490
{
491+
const Random *rng = system_random();
492+
ck_assert(rng != nullptr);
487493
Mono_Time *mono_time = mono_time_new();
488494
Logger *logger = logger_new();
489495

490496
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
491497
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
492-
crypto_new_keypair(self_public_key, self_secret_key);
498+
crypto_new_keypair(rng, self_public_key, self_secret_key);
493499
const Network *ns = system_network();
494-
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
500+
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
495501
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
496502
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports.");
497503

498504
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
499505
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
500-
crypto_new_keypair(f_public_key, f_secret_key);
506+
crypto_new_keypair(rng, f_public_key, f_secret_key);
501507
IP_Port ip_port_tcp_s;
502508

503-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
509+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
504510
ip_port_tcp_s.ip = get_loopback();
505511

506-
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f_public_key,
512+
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key,
507513
f_secret_key, nullptr);
508514
do_TCP_connection(logger, mono_time, conn, nullptr);
509515
c_sleep(50);
@@ -536,9 +542,9 @@ static void test_client(void)
536542

537543
uint8_t f2_public_key[CRYPTO_PUBLIC_KEY_SIZE];
538544
uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE];
539-
crypto_new_keypair(f2_public_key, f2_secret_key);
540-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
541-
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
545+
crypto_new_keypair(rng, f2_public_key, f2_secret_key);
546+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
547+
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
542548
f2_secret_key, nullptr);
543549

544550
// The client should call this function (defined earlier) during the routing process.
@@ -613,22 +619,24 @@ static void test_client(void)
613619
// Test how the client handles servers that don't respond.
614620
static void test_client_invalid(void)
615621
{
622+
const Random *rng = system_random();
623+
ck_assert(rng != nullptr);
616624
Mono_Time *mono_time = mono_time_new();
617625
Logger *logger = logger_new();
618626
const Network *ns = system_network();
619627

620628
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
621629
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
622-
crypto_new_keypair(self_public_key, self_secret_key);
630+
crypto_new_keypair(rng, self_public_key, self_secret_key);
623631

624632
uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE];
625633
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
626-
crypto_new_keypair(f_public_key, f_secret_key);
634+
crypto_new_keypair(rng, f_public_key, f_secret_key);
627635
IP_Port ip_port_tcp_s;
628636

629-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
637+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
630638
ip_port_tcp_s.ip = get_loopback();
631-
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, ns, &ip_port_tcp_s,
639+
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s,
632640
self_public_key, f_public_key, f_secret_key, nullptr);
633641

634642
// Run the client's main loop but not the server.
@@ -688,36 +696,38 @@ static void test_tcp_connection(void)
688696
{
689697
Mono_Time *mono_time = mono_time_new();
690698
Logger *logger = logger_new();
699+
const Random *rng = system_random();
700+
ck_assert(rng != nullptr);
691701
const Network *ns = system_network();
692702

693703
tcp_data_callback_called = 0;
694704
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
695705
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
696-
crypto_new_keypair(self_public_key, self_secret_key);
697-
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
706+
crypto_new_keypair(rng, self_public_key, self_secret_key);
707+
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
698708
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
699709

700710
TCP_Proxy_Info proxy_info;
701711
proxy_info.proxy_type = TCP_PROXY_NONE;
702-
crypto_new_keypair(self_public_key, self_secret_key);
703-
TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
712+
crypto_new_keypair(rng, self_public_key, self_secret_key);
713+
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
704714
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
705715

706-
crypto_new_keypair(self_public_key, self_secret_key);
707-
TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
716+
crypto_new_keypair(rng, self_public_key, self_secret_key);
717+
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
708718
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
709719

710720
IP_Port ip_port_tcp_s;
711721

712-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
722+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
713723
ip_port_tcp_s.ip = get_loopback();
714724

715725
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);
716726
ck_assert_msg(connection == 0, "Connection id wrong");
717727
ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0,
718728
"Could not add tcp relay to connection\n");
719729

720-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
730+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
721731
connection = new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123);
722732
ck_assert_msg(connection == 0, "Connection id wrong");
723733
ck_assert_msg(add_tcp_relay_connection(tc_2, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0,
@@ -795,30 +805,32 @@ static void test_tcp_connection2(void)
795805
{
796806
Mono_Time *mono_time = mono_time_new();
797807
Logger *logger = logger_new();
808+
const Random *rng = system_random();
809+
ck_assert(rng != nullptr);
798810
const Network *ns = system_network();
799811

800812
tcp_oobdata_callback_called = 0;
801813
tcp_data_callback_called = 0;
802814

803815
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
804816
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
805-
crypto_new_keypair(self_public_key, self_secret_key);
806-
TCP_Server *tcp_s = new_TCP_server(logger, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
817+
crypto_new_keypair(rng, self_public_key, self_secret_key);
818+
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr);
807819
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
808820

809821
TCP_Proxy_Info proxy_info;
810822
proxy_info.proxy_type = TCP_PROXY_NONE;
811-
crypto_new_keypair(self_public_key, self_secret_key);
812-
TCP_Connections *tc_1 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
823+
crypto_new_keypair(rng, self_public_key, self_secret_key);
824+
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
813825
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
814826

815-
crypto_new_keypair(self_public_key, self_secret_key);
816-
TCP_Connections *tc_2 = new_tcp_connections(logger, mono_time, ns, self_secret_key, &proxy_info);
827+
crypto_new_keypair(rng, self_public_key, self_secret_key);
828+
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info);
817829
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
818830

819831
IP_Port ip_port_tcp_s;
820832

821-
ip_port_tcp_s.port = net_htons(ports[random_u32() % NUM_PORTS]);
833+
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
822834
ip_port_tcp_s.ip = get_loopback();
823835

824836
int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123);

auto_tests/conference_av_test.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
165165
* returns a random index at which a list of booleans is false
166166
* (some such index is required to exist)
167167
*/
168-
static uint32_t random_false_index(bool *list, const uint32_t length)
168+
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
169169
{
170170
uint32_t index;
171171

172172
do {
173-
index = random_u32() % length;
173+
index = random_u32(rng) % length;
174174
} while (list[index]);
175175

176176
return index;
@@ -287,6 +287,8 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations)
287287

288288
static void run_conference_tests(AutoTox *autotoxes)
289289
{
290+
const Random *rng = system_random();
291+
ck_assert(rng != nullptr);
290292
bool disabled[NUM_AV_GROUP_TOX] = {0};
291293

292294
test_audio(autotoxes, disabled, false);
@@ -302,7 +304,7 @@ static void run_conference_tests(AutoTox *autotoxes)
302304
ck_assert(NUM_AV_DISCONNECT < NUM_AV_GROUP_TOX);
303305

304306
for (uint32_t i = 0; i < NUM_AV_DISCONNECT; ++i) {
305-
uint32_t disconnect = random_false_index(disconnected, NUM_AV_GROUP_TOX);
307+
uint32_t disconnect = random_false_index(rng, disconnected, NUM_AV_GROUP_TOX);
306308
disconnected[disconnect] = true;
307309

308310
if (i < NUM_AV_DISCONNECT / 2) {
@@ -358,7 +360,7 @@ static void run_conference_tests(AutoTox *autotoxes)
358360
ck_assert(NUM_AV_DISABLE < NUM_AV_GROUP_TOX);
359361

360362
for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) {
361-
uint32_t disable = random_false_index(disabled, NUM_AV_GROUP_TOX);
363+
uint32_t disable = random_false_index(rng, disabled, NUM_AV_GROUP_TOX);
362364
disabled[disable] = true;
363365
printf("Disabling #%u\n", autotoxes[disable].index);
364366
ck_assert_msg(toxav_groupchat_enable_av(autotoxes[disable].tox, 0, audio_callback, &autotoxes[disable]) != 0,

auto_tests/conference_test.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,21 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes)
179179
* returns a random index at which a list of booleans is false
180180
* (some such index is required to exist)
181181
*/
182-
static uint32_t random_false_index(bool *list, const uint32_t length)
182+
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
183183
{
184184
uint32_t index;
185185

186186
do {
187-
index = random_u32() % length;
187+
index = random_u32(rng) % length;
188188
} while (list[index]);
189189

190190
return index;
191191
}
192192

193193
static void run_conference_tests(AutoTox *autotoxes)
194194
{
195+
const Random *rng = system_random();
196+
ck_assert(rng != nullptr);
195197
/* disabling name change propagation check for now, as it occasionally
196198
* fails due to disconnections too short to trigger freezing */
197199
const bool check_name_change_propagation = false;
@@ -215,7 +217,7 @@ static void run_conference_tests(AutoTox *autotoxes)
215217
ck_assert(NUM_DISCONNECT < NUM_GROUP_TOX);
216218

217219
for (uint32_t i = 0; i < NUM_DISCONNECT; ++i) {
218-
uint32_t disconnect = random_false_index(disconnected, NUM_GROUP_TOX);
220+
uint32_t disconnect = random_false_index(rng, disconnected, NUM_GROUP_TOX);
219221
disconnected[disconnect] = true;
220222

221223
if (i < NUM_DISCONNECT / 2) {
@@ -292,7 +294,7 @@ static void run_conference_tests(AutoTox *autotoxes)
292294
Tox_Err_Conference_Send_Message err;
293295
ck_assert_msg(
294296
tox_conference_send_message(
295-
autotoxes[random_u32() % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
297+
autotoxes[random_u32(rng) % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
296298
sizeof(GROUP_MESSAGE) - 1, &err) != 0, "failed to send group message");
297299
ck_assert_msg(
298300
err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "failed to send group message");

0 commit comments

Comments
 (0)