summaryrefslogtreecommitdiff
path: root/testing/experiment/group_chats.c
diff options
context:
space:
mode:
Diffstat (limited to 'testing/experiment/group_chats.c')
-rw-r--r--testing/experiment/group_chats.c99
1 files changed, 82 insertions, 17 deletions
diff --git a/testing/experiment/group_chats.c b/testing/experiment/group_chats.c
index 665707b2..faf274d5 100644
--- a/testing/experiment/group_chats.c
+++ b/testing/experiment/group_chats.c
@@ -111,8 +111,10 @@ static int peer_okping(Group_Chat *chat, uint8_t *client_id)
111 uint64_t temp_time = unix_time(); 111 uint64_t temp_time = unix_time();
112 112
113 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 113 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
114 if (chat->close[i].last_recv < temp_time + BAD_NODE_TIMEOUT) 114 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) {
115 ++j;
115 continue; 116 continue;
117 }
116 118
117 /* Equal */ 119 /* Equal */
118 if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) 120 if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0)
@@ -147,7 +149,7 @@ static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
147 } 149 }
148 150
149 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */ 151 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */
150 if (chat->close[i].last_recv < temp_time + BAD_NODE_TIMEOUT) { 152 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) {
151 memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES); 153 memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES);
152 chat->close[i].ip_port = ip_port; 154 chat->close[i].ip_port = ip_port;
153 chat->close[i].last_recv = temp_time; 155 chat->close[i].last_recv = temp_time;
@@ -224,6 +226,7 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id)
224 226
225 Group_Peer *temp; 227 Group_Peer *temp;
226 temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers + 1)); 228 temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers + 1));
229 memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer));
227 230
228 if (temp == NULL) 231 if (temp == NULL)
229 return -1; 232 return -1;
@@ -301,14 +304,11 @@ static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64
301 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 304 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
302 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { 305 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) {
303 memcpy(contents.nodes[j].client_id, chat->close[i].client_id, crypto_box_PUBLICKEYBYTES); 306 memcpy(contents.nodes[j].client_id, chat->close[i].client_id, crypto_box_PUBLICKEYBYTES);
304 contents.nodes[j].ip_port = ip_port; 307 contents.nodes[j].ip_port = chat->close[i].ip_port;
305 ++j; 308 ++j;
306 } 309 }
307 } 310 }
308 311
309 if (j == 0)
310 return -1;
311
312 return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, 312 return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents,
313 sizeof(contents.pingid) + sizeof(groupchat_nodes) * j, 49); 313 sizeof(contents.pingid) + sizeof(groupchat_nodes) * j, 49);
314} 314}
@@ -324,6 +324,10 @@ static int handle_getnodes(Group_Chat *chat, IP_Port source, int peernum, uint8_
324 getnodes_data contents; 324 getnodes_data contents;
325 memcpy(&contents, data, sizeof(contents)); 325 memcpy(&contents, data, sizeof(contents));
326 send_sendnodes(chat, source, peernum, contents.pingid); 326 send_sendnodes(chat, source, peernum, contents.pingid);
327
328 if (peer_okping(chat, chat->group[peernum].client_id) > 0)
329 send_getnodes(chat, source, peernum);
330
327 return 0; 331 return 0;
328} 332}
329 333
@@ -332,7 +336,7 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
332 if (peernum < 0 || peernum >= chat->numpeers) 336 if (peernum < 0 || peernum >= chat->numpeers)
333 return 1; 337 return 1;
334 338
335 if (len > sizeof(sendnodes_data) || len < (sizeof(uint64_t) + sizeof(groupchat_nodes))) 339 if (len > sizeof(sendnodes_data) || len < sizeof(uint64_t))
336 return 1; 340 return 1;
337 341
338 if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0) 342 if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0)
@@ -354,6 +358,10 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
354 if (peer_okping(chat, contents.nodes[i].client_id) > 0) { 358 if (peer_okping(chat, contents.nodes[i].client_id) > 0) {
355 int peern = peer_in_chat(chat, contents.nodes[i].client_id); 359 int peern = peer_in_chat(chat, contents.nodes[i].client_id);
356 360
361 if (peern == -1) { /*NOTE: This is just for testing and will be removed later.*/
362 peern = addpeer(chat, contents.nodes[i].client_id);
363 }
364
357 if (peern == -1) 365 if (peern == -1)
358 continue; 366 continue;
359 367
@@ -364,17 +372,37 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
364 add_closepeer(chat, chat->group[peernum].client_id, source); 372 add_closepeer(chat, chat->group[peernum].client_id, source);
365 return 0; 373 return 0;
366} 374}
367 375#define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1)
368static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) 376static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
369{ 377{
370 if (len < 2) 378 if (len < GROUP_DATA_MIN_SIZE)
371 return 1; 379 return 1;
372 380
381//TODO:
382 int peernum = peer_in_chat(chat, data);
383
384 if (peernum == -1) { /*NOTE: This is just for testing and will be removed later.*/
385 peernum = addpeer(chat, data);
386 }
387
388 if (peernum == -1)
389 return 1;
390
391 uint32_t message_num;
392 memcpy(&message_num, data + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
393 message_num = ntohl(message_num);
394
395 if (message_num - chat->group[peernum].last_message_number > 64 ||
396 message_num == chat->group[peernum].last_message_number)
397 return 1;
398
399 chat->group[peernum].last_message_number = message_num;
400
373 int handled = 0; 401 int handled = 0;
374 402
375 if (data[0] == 64 && chat->group_message != NULL) { 403 if (data[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] == 64
376//TODO 404 && chat->group_message != NULL) { /* If message is chat message */
377 (*chat->group_message)(chat, 0, data + 1, len - 1, chat->group_message_userdata); 405 (*chat->group_message)(chat, peernum, data + GROUP_DATA_MIN_SIZE, len - 1, chat->group_message_userdata);
378 handled = 1; 406 handled = 1;
379 } 407 }
380 408
@@ -386,6 +414,19 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
386 return 1; 414 return 1;
387} 415}
388 416
417static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id)
418{
419 if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/
420 return 1;
421
422 uint8_t packet[MAX_DATA_SIZE];
423 uint32_t message_num = htonl(chat->message_number);
424//TODO
425 memcpy(packet, chat->self_public_key, crypto_box_PUBLICKEYBYTES);
426 memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num));
427 packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id;
428 return sendto_allpeers(chat, packet, len + GROUP_DATA_MIN_SIZE, 50);
429}
389/* 430/*
390 * Handle get nodes group packet. 431 * Handle get nodes group packet.
391 * 432 *
@@ -417,7 +458,6 @@ int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, ui
417 if (peernum == -1) 458 if (peernum == -1)
418 return 1; 459 return 1;
419 460
420
421 switch (number) { 461 switch (number) {
422 case 48: 462 case 48:
423 return handle_getnodes(chat, source, peernum, data, len); 463 return handle_getnodes(chat, source, peernum, data, len);
@@ -435,9 +475,9 @@ int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, ui
435 return 1; 475 return 1;
436} 476}
437 477
438uint32_t m_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length) 478uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length)
439{ 479{
440 480 return send_data(chat, message, length, 64); //TODO: better return values?
441} 481}
442 482
443void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, int, uint8_t *, uint16_t, void *), 483void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, int, uint8_t *, uint16_t, void *),
@@ -454,9 +494,34 @@ Group_Chat *new_groupchat(Networking_Core *net)
454 494
455 Group_Chat *chat = calloc(1, sizeof(Group_Chat)); 495 Group_Chat *chat = calloc(1, sizeof(Group_Chat));
456 chat->net = net; 496 chat->net = net;
497 crypto_box_keypair(chat->self_public_key, chat->self_secret_key);
457 return chat; 498 return chat;
458} 499}
459 500
501#define NODE_PING_INTERVAL 10
502
503static void ping_close(Group_Chat *chat)
504{
505 uint32_t i;
506 uint64_t temp_time = unix_time();
507
508 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
509 if (chat->close[i].last_recv < temp_time + BAD_NODE_TIMEOUT) {
510 int peernum = peer_in_chat(chat, chat->close[i].client_id);
511
512 if (peernum == -1)
513 continue;
514
515 if (chat->group[peernum].last_pinged + NODE_PING_INTERVAL < temp_time)
516 send_getnodes(chat, chat->close[i].ip_port, peernum);
517 }
518 }
519}
520
521void do_groupchat(Group_Chat *chat)
522{
523 ping_close(chat);
524}
460 525
461void kill_groupchat(Group_Chat *chat) 526void kill_groupchat(Group_Chat *chat)
462{ 527{
@@ -464,7 +529,7 @@ void kill_groupchat(Group_Chat *chat)
464 free(chat); 529 free(chat);
465} 530}
466 531
467void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, int peernum) 532void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id)
468{ 533{
469 send_getnodes(chat, ip_port, peernum); 534 send_getnodes(chat, ip_port, addpeer(chat, client_id));
470} 535}