diff options
Diffstat (limited to 'testing/experiment')
-rw-r--r-- | testing/experiment/group_chats.c | 99 | ||||
-rw-r--r-- | testing/experiment/group_chats.h | 8 | ||||
-rw-r--r-- | testing/experiment/group_chats_test.c | 83 |
3 files changed, 169 insertions, 21 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 | } |
diff --git a/testing/experiment/group_chats.h b/testing/experiment/group_chats.h index 527610d8..42ea3e08 100644 --- a/testing/experiment/group_chats.h +++ b/testing/experiment/group_chats.h | |||
@@ -76,7 +76,7 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, | |||
76 | * Send a message to the group. | 76 | * Send a message to the group. |
77 | * | 77 | * |
78 | */ | 78 | */ |
79 | uint32_t m_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); | 79 | uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); |
80 | 80 | ||
81 | /* Create a new group chat. | 81 | /* Create a new group chat. |
82 | * | 82 | * |
@@ -93,6 +93,10 @@ Group_Chat *new_groupchat(Networking_Core *net); | |||
93 | */ | 93 | */ |
94 | void kill_groupchat(Group_Chat *chat); | 94 | void kill_groupchat(Group_Chat *chat); |
95 | 95 | ||
96 | /* | ||
97 | * This is the main loop. | ||
98 | */ | ||
99 | void do_groupchat(Group_Chat *chat); | ||
96 | 100 | ||
97 | /* if we receive a group chat packet we call this function so it can be handled. | 101 | /* if we receive a group chat packet we call this function so it can be handled. |
98 | return 0 if packet is handled correctly. | 102 | return 0 if packet is handled correctly. |
@@ -100,7 +104,7 @@ void kill_groupchat(Group_Chat *chat); | |||
100 | int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length); | 104 | int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length); |
101 | 105 | ||
102 | 106 | ||
103 | void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, int peernum); | 107 | void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id); |
104 | 108 | ||
105 | #ifdef __cplusplus | 109 | #ifdef __cplusplus |
106 | } | 110 | } |
diff --git a/testing/experiment/group_chats_test.c b/testing/experiment/group_chats_test.c index f08e4e15..8ef5b10e 100644 --- a/testing/experiment/group_chats_test.c +++ b/testing/experiment/group_chats_test.c | |||
@@ -1,18 +1,97 @@ | |||
1 | #include "group_chats.h" | 1 | #include "group_chats.h" |
2 | #define NUM_CHATS 8 | 2 | #define NUM_CHATS 8 |
3 | 3 | ||
4 | #ifdef WIN32 | ||
5 | #define c_sleep(x) Sleep(1*x) | ||
6 | #else | ||
7 | #define c_sleep(x) usleep(1000*x) | ||
8 | #endif | ||
9 | Group_Chat *chats[NUM_CHATS]; | ||
10 | |||
11 | void print_close(Group_Close *close) | ||
12 | { | ||
13 | uint32_t i, j; | ||
14 | IP_Port p_ip; | ||
15 | printf("___________________CLOSE________________________________\n"); | ||
16 | |||
17 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; i++) { | ||
18 | printf("ClientID: "); | ||
19 | |||
20 | for (j = 0; j < CLIENT_ID_SIZE; j++) { | ||
21 | printf("%02hhX", close[i].client_id[j]); | ||
22 | } | ||
23 | |||
24 | p_ip = close[i].ip_port; | ||
25 | printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | ||
26 | ntohs(p_ip.port)); | ||
27 | printf("\nTimestamp: %llu", (long long unsigned int) close[i].last_recv); | ||
28 | printf("\n"); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | void print_group(Group_Chat *chat) | ||
33 | { | ||
34 | uint32_t i, j; | ||
35 | printf("-----------------\nClientID: "); | ||
36 | |||
37 | for (j = 0; j < CLIENT_ID_SIZE; j++) { | ||
38 | printf("%02hhX", chat->self_public_key[j]); | ||
39 | } | ||
40 | |||
41 | printf("\n___________________GROUP________________________________\n"); | ||
42 | |||
43 | for (i = 0; i < chat->numpeers; i++) { | ||
44 | printf("ClientID: "); | ||
45 | |||
46 | for (j = 0; j < CLIENT_ID_SIZE; j++) { | ||
47 | printf("%02hhX", chat->group[i].client_id[j]); | ||
48 | } | ||
49 | |||
50 | printf("\nTimestamp: %llu", (long long unsigned int) chat->group[i].last_recv); | ||
51 | printf("\nlast_pinged: %llu", (long long unsigned int) chat->group[i].last_pinged); | ||
52 | printf("\npingid: %llu", (long long unsigned int) chat->group[i].pingid); | ||
53 | printf("\n"); | ||
54 | } | ||
55 | } | ||
56 | |||
4 | int main() | 57 | int main() |
5 | { | 58 | { |
6 | IP ip; | 59 | IP ip; |
7 | ip.uint32 = 0; | 60 | ip.uint32 = 0; |
8 | uint32_t i; | 61 | uint32_t i; |
9 | Group_Chat *chats[NUM_CHATS]; | 62 | |
10 | 63 | ||
11 | for (i = 0; i < NUM_CHATS; ++i) { | 64 | for (i = 0; i < NUM_CHATS; ++i) { |
12 | chats[i] = new_groupchat(new_networking(ip, 1234)); | 65 | chats[i] = new_groupchat(new_networking(ip, 12745)); |
13 | 66 | ||
14 | if (chats[i] == 0) | 67 | if (chats[i] == 0) |
15 | exit(1); | 68 | exit(1); |
69 | |||
70 | networking_registerhandler(chats[i]->net, 48, &handle_groupchatpacket, chats[i]); | ||
71 | } | ||
72 | |||
73 | printf("ok\n"); | ||
74 | IP_Port ip_port; | ||
75 | ip_port.ip.uint32 = 0; | ||
76 | ip_port.ip.uint8[0] = 127; | ||
77 | ip_port.ip.uint8[3] = 1; | ||
78 | ip_port.port = htons(12745); | ||
79 | |||
80 | for (i = 0; i < NUM_CHATS; ++i) { | ||
81 | chat_bootstrap(chats[i], ip_port, chats[0]->self_public_key); | ||
82 | printf("%u\n", i); | ||
83 | } | ||
84 | |||
85 | while (1) { | ||
86 | for (i = 0; i < NUM_CHATS; ++i) { | ||
87 | networking_poll(chats[i]->net); | ||
88 | do_groupchat(chats[i]); | ||
89 | printf("%u\n", chats[i]->numpeers); | ||
90 | print_close(chats[i]->close); | ||
91 | print_group(chats[i]); | ||
92 | } | ||
93 | |||
94 | c_sleep(100); | ||
16 | } | 95 | } |
17 | 96 | ||
18 | return 0; | 97 | return 0; |