diff options
Diffstat (limited to 'testing/experiment/group_chats.c')
-rw-r--r-- | testing/experiment/group_chats.c | 99 |
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) | |
368 | static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) | 376 | static 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 | ||
417 | static 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 | ||
438 | uint32_t m_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length) | 478 | uint32_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 | ||
443 | void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, int, uint8_t *, uint16_t, void *), | 483 | void 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 | |||
503 | static 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 | |||
521 | void do_groupchat(Group_Chat *chat) | ||
522 | { | ||
523 | ping_close(chat); | ||
524 | } | ||
460 | 525 | ||
461 | void kill_groupchat(Group_Chat *chat) | 526 | void 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 | ||
467 | void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, int peernum) | 532 | void 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 | } |