summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-09-05 17:00:41 -0400
committerirungentoo <irungentoo@gmail.com>2013-09-05 17:00:41 -0400
commitcc8a536cb07484396354c4880f3631666a1cf874 (patch)
tree708f598799ebef55e2b3f261b96472b7099e99e8
parentc59975dd7ecdabe864f341b699f986e5e474acb6 (diff)
Base of group chats seems to be working now.
-rw-r--r--testing/experiment/group_chats.c99
-rw-r--r--testing/experiment/group_chats.h8
-rw-r--r--testing/experiment/group_chats_test.c83
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)
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}
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 */
79uint32_t m_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); 79uint32_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 */
94void kill_groupchat(Group_Chat *chat); 94void kill_groupchat(Group_Chat *chat);
95 95
96/*
97 * This is the main loop.
98 */
99void 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);
100int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length); 104int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length);
101 105
102 106
103void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, int peernum); 107void 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
9Group_Chat *chats[NUM_CHATS];
10
11void 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
32void 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
4int main() 57int 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;