diff options
-rw-r--r-- | auto_tests/network_test.c | 11 | ||||
-rw-r--r-- | docs/Hardening_docs.txt | 21 | ||||
-rw-r--r-- | docs/updates/DHT.md | 113 | ||||
-rw-r--r-- | toxcore/DHT.c | 28 | ||||
-rw-r--r-- | toxcore/Messenger.c | 9 | ||||
-rw-r--r-- | toxcore/Messenger.h | 5 | ||||
-rw-r--r-- | toxcore/assoc.c | 4 | ||||
-rw-r--r-- | toxcore/group_chats.c | 8 | ||||
-rw-r--r-- | toxcore/group_chats.h | 3 | ||||
-rw-r--r-- | toxcore/network.h | 4 | ||||
-rw-r--r-- | toxcore/tox.c | 12 | ||||
-rw-r--r-- | toxcore/tox.h | 13 |
12 files changed, 197 insertions, 34 deletions
diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c index 2383c0cb..d65b8100 100644 --- a/auto_tests/network_test.c +++ b/auto_tests/network_test.c | |||
@@ -122,6 +122,16 @@ START_TEST(test_ip_equal) | |||
122 | } | 122 | } |
123 | END_TEST | 123 | END_TEST |
124 | 124 | ||
125 | START_TEST(test_struct_sizes) | ||
126 | { | ||
127 | ck_assert_msg(sizeof(IP4) == 4, "sizeof(IP4): expected result 4, got %u.", sizeof(IP4)); | ||
128 | ck_assert_msg(sizeof(IP6) == 16, "sizeof(IP6): expected result 16, got %u.", sizeof(IP6)); | ||
129 | ck_assert_msg(sizeof(IP) == 20, "sizeof(IP): expected result 20, got %u.", sizeof(IP)); | ||
130 | ck_assert_msg(sizeof(IP_Port) == 24, "sizeof(IP_Port): expected result 24, got %u.", sizeof(IP_Port)); | ||
131 | ck_assert_msg(sizeof(IP4_Port) == 8, "sizeof(IP4_Port): expected result 8, got %u.", sizeof(IP4_Port)); | ||
132 | } | ||
133 | END_TEST | ||
134 | |||
125 | #define DEFTESTCASE(NAME) \ | 135 | #define DEFTESTCASE(NAME) \ |
126 | TCase *tc_##NAME = tcase_create(#NAME); \ | 136 | TCase *tc_##NAME = tcase_create(#NAME); \ |
127 | tcase_add_test(tc_##NAME, test_##NAME); \ | 137 | tcase_add_test(tc_##NAME, test_##NAME); \ |
@@ -133,6 +143,7 @@ Suite *network_suite(void) | |||
133 | 143 | ||
134 | DEFTESTCASE(addr_resolv_localhost); | 144 | DEFTESTCASE(addr_resolv_localhost); |
135 | DEFTESTCASE(ip_equal); | 145 | DEFTESTCASE(ip_equal); |
146 | DEFTESTCASE(struct_sizes); | ||
136 | 147 | ||
137 | return s; | 148 | return s; |
138 | } | 149 | } |
diff --git a/docs/Hardening_docs.txt b/docs/Hardening_docs.txt new file mode 100644 index 00000000..08c6ef13 --- /dev/null +++ b/docs/Hardening_docs.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | Hardening request packets are sent as crypto request packets (see crypto docs.) | ||
2 | NOTE: currently only get nodes requests are tested in the code which is why there is only one test (more will be added soon.) | ||
3 | |||
4 | All hardening requests must contain exactly 768 bytes of data. (The data sent must be padded with zeros if it is smaller than that.) | ||
5 | |||
6 | 1. Get the information (IP_port, client_id) of the node we want to test. | ||
7 | 2. Find a couple random nodes that is not that node (one for each test.) | ||
8 | 3. Send crypto request packets to each of these random nodes with the data being: | ||
9 | |||
10 | [byte with value: 02 (get nodes test request)][struct Node_format (the node to test.)][client_id(32 bytes) the id to query the node with.][padding] | ||
11 | |||
12 | 4. The random node receives a packet. | ||
13 | -The packet is a get nodes test request: | ||
14 | send a get_node request to that node with the id to query in the request. | ||
15 | when a send_node response is received, send the following response to the person who sent us the get nodes test request packet: | ||
16 | [byte with value: 03 (get nodes test response)][client_id(32 bytes): the id that the node was queried with][The list of nodes it responded with in IPv6 Node format (struct Node_Format)] | ||
17 | PROTIP: (get node requests and response contain an encrypted part that you can use to store information so that you don't | ||
18 | have to store in your memory where/if to send back the response from the send node) | ||
19 | |||
20 | 5. Receive the test responses. | ||
21 | -If the test(s) pass (the nodes behave in a satisfactory manner), make these nodes have priority over those who don't pass the test(s). | ||
diff --git a/docs/updates/DHT.md b/docs/updates/DHT.md new file mode 100644 index 00000000..79ec8c4b --- /dev/null +++ b/docs/updates/DHT.md | |||
@@ -0,0 +1,113 @@ | |||
1 | DHT protocol | ||
2 | ============ | ||
3 | |||
4 | Follows pretty much the principle of the torrent DHT: http://www.bittorrent.org/beps/bep_0005.html (READ IT) | ||
5 | |||
6 | But: | ||
7 | Vastly simplified packet format and encryption. | ||
8 | |||
9 | Boostrapping: | ||
10 | The first time you install the client we bootstrap it with a node on our servers.(bandwidth should not be a problem as the client only needs to be sent one reply.) | ||
11 | |||
12 | |||
13 | Basics | ||
14 | ------ | ||
15 | (All the numbers here are just guesses and are probably not optimal values) | ||
16 | |||
17 | client list: A list of node ids closest (mathematically see bittorrent doc) to ours matched with ip addresses + port number corresponding to that id and a timestamp containing the time or time since the client was successfully pinged. | ||
18 | |||
19 | "friends" list: A list containing the node_ids of all our "friends" or clients we want to connect to. | ||
20 | Also contains the ip addresses + port + node_ids + timestamp(of last ping like in the client list) of the 8 clients closest (mathematically see bittorrent doc) to each "friend" | ||
21 | |||
22 | One pinged lists: | ||
23 | -One for storing a list of ips along with their ping_ids and a timestamp for the ping requests | ||
24 | Entries in the pinged lists expire after 5 seconds. | ||
25 | If one of the lists becomes full, the expire rate reduces itself one second or the new ping takes the place of the oldest one. | ||
26 | |||
27 | |||
28 | Entries in client list and "friends" list expire after 300 seconds without ping response. | ||
29 | Each client stores a maximum of 32 entries in its client list. | ||
30 | Each client in the client list and "friends" list is pinged every 60 seconds. | ||
31 | Each client in the client list and "friends" list has a timestamp which denote the last time it was successfully pinged. | ||
32 | If the corresponding clients timestamp is more than 130 seconds old it is considered bad. | ||
33 | Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. | ||
34 | Send a get nodes request every 20 seconds to a random good node in the client list. | ||
35 | |||
36 | |||
37 | When a client receives any request from another | ||
38 | ----------------------------------------------- | ||
39 | -Respond to the request | ||
40 | -Ping request is replied to with with a ping response containing the same encrypted data | ||
41 | -Get nodes request is replied with a send nodes reply containing the same encrypted data and the good nodes from the client list and/or the "friends" list that are closest to the requested_node_id | ||
42 | |||
43 | -If the requesting client is not in the client list: | ||
44 | -If there are no bad clients in the list and the list is full: | ||
45 | -If the id of the other client is closer (mathematically see bittorrent doc) than at least one of the clients in the list or our "friends" list: | ||
46 | -Send a ping request to the client. | ||
47 | -if not forget about the client. | ||
48 | |||
49 | -If there are bad clients and/or the list isn't full: | ||
50 | -Send a ping request to the client | ||
51 | |||
52 | When a client receives a response | ||
53 | --------------------------------- | ||
54 | -Ping response | ||
55 | -If the node was previously pinged with a matching ping_id (check in the corresponding pinged list.) | ||
56 | -If the node is in the client list the matching client's timestamp is set to current time. | ||
57 | -If the node is in the "friends" list the matching client's timestamp is set to current time for every occurrence. | ||
58 | -If the node is not in the client list: | ||
59 | -If the list isn't full, add it to the list. | ||
60 | -If the list is full, the furthest away (mathematically see bittorrent doc) bad client is replaced by the new one. | ||
61 | -If the list is filled with good nodes replace the furthest client with it only if it is closer than the replaced node. | ||
62 | -for each friend in the "friends" list: | ||
63 | -If that friend's client list isn't full, add that client to it | ||
64 | -If that friend's client list contains bad clients, replace the furthest one with that client. | ||
65 | -If that friend's client list contains only good clients | ||
66 | -If the client is closer to the friend than one of the other clients, it replaces the farthest one | ||
67 | -If not, nothing happens. | ||
68 | |||
69 | -Send nodes | ||
70 | -If the ping_id matches what we sent previously (check in the corresponding pinged list.): | ||
71 | -Each node in the response is pinged. | ||
72 | |||
73 | |||
74 | |||
75 | |||
76 | |||
77 | Protocol | ||
78 | -------- | ||
79 | |||
80 | Node format: | ||
81 | ``` | ||
82 | [char array (node_id), length=32 bytes][ip (in network byte order), length=4 bytes][port (in network byte order), length=2 bytes][Padding , length=2 bytes] | ||
83 | ``` | ||
84 | see also: DHT.h (Node4_format struct) | ||
85 | |||
86 | IPv6 Node format: | ||
87 | see: DHT.h (Node_format struct) | ||
88 | |||
89 | Valid queries and Responses: | ||
90 | |||
91 | Ping(Request and response): | ||
92 | ``` | ||
93 | [byte with value: 00 for request, 01 for response][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender: [random 8 byte (ping_id)]] | ||
94 | ``` | ||
95 | ping_id = a random integer, the response must contain the exact same number as the request | ||
96 | |||
97 | |||
98 | Get nodes (Request): | ||
99 | Packet contents: | ||
100 | ``` | ||
101 | [byte with value: 02][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[char array: requested_node_id (node_id of which we want the ip), length=32 bytes][Encrypted data (must be sent back unmodified by in the response), length=NODES_ENCRYPTED_MESSAGE_LENGTH bytes]] | ||
102 | ``` | ||
103 | Valid replies: a send_nodes packet | ||
104 | |||
105 | Send_nodes (response (for ipv4 addresses)): | ||
106 | ``` | ||
107 | [byte with value: 03][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[Nodes in node format, length=40 * (number of nodes (maximum of 8 nodes)) bytes][Encrypted data, length=NODES_ENCRYPTED_MESSAGE_LENGTH bytes]] | ||
108 | ``` | ||
109 | |||
110 | Send_nodes_IPv6 (response (for ipv6 addresses)): | ||
111 | ``` | ||
112 | [byte with value: 04][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[Nodes in ipv6_node format, length=56 * (number of nodes (maximum of 8 nodes)) bytes][Encrypted data, length=NODES_ENCRYPTED_MESSAGE_LENGTH bytes]] | ||
113 | ``` | ||
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index fb059f5b..40ad3929 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -351,7 +351,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod | |||
351 | * | 351 | * |
352 | * want_good : do we want only good nodes as checked with the hardening returned or not? | 352 | * want_good : do we want only good nodes as checked with the hardening returned or not? |
353 | */ | 353 | */ |
354 | static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, uint8_t want_good) | 354 | static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, |
355 | uint8_t is_LAN, uint8_t want_good) | ||
355 | { | 356 | { |
356 | uint32_t num_nodes = 0, i; | 357 | uint32_t num_nodes = 0, i; |
357 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 358 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, |
@@ -365,7 +366,8 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n | |||
365 | return num_nodes; | 366 | return num_nodes; |
366 | } | 367 | } |
367 | 368 | ||
368 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, uint8_t want_good) | 369 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, |
370 | uint8_t want_good) | ||
369 | { | 371 | { |
370 | if (!dht->assoc) | 372 | if (!dht->assoc) |
371 | return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); | 373 | return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); |
@@ -492,10 +494,10 @@ static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_i | |||
492 | * return 1 if not (list contains no bad nodes). | 494 | * return 1 if not (list contains no bad nodes). |
493 | */ | 495 | */ |
494 | static int replace_possible_bad( Client_data *list, | 496 | static int replace_possible_bad( Client_data *list, |
495 | uint32_t length, | 497 | uint32_t length, |
496 | uint8_t *client_id, | 498 | uint8_t *client_id, |
497 | IP_Port ip_port, | 499 | IP_Port ip_port, |
498 | uint8_t *comp_client_id ) | 500 | uint8_t *comp_client_id ) |
499 | { | 501 | { |
500 | if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) | 502 | if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) |
501 | return 1; | 503 | return 1; |
@@ -626,10 +628,10 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
626 | if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 628 | if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
627 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 629 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
628 | if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, | 630 | if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, |
629 | dht->c->self_public_key)) { | 631 | dht->c->self_public_key)) { |
630 | /* If we can't replace bad nodes we try replacing good ones. */ | 632 | /* If we can't replace bad nodes we try replacing good ones. */ |
631 | if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, | 633 | if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, |
632 | dht->c->self_public_key)) | 634 | dht->c->self_public_key)) |
633 | used++; | 635 | used++; |
634 | } else | 636 | } else |
635 | used++; | 637 | used++; |
@@ -647,9 +649,10 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
647 | /*if (replace_possible_bad(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, | 649 | /*if (replace_possible_bad(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
648 | client_id, ip_port, dht->friends_list[i].client_id)) {*/ | 650 | client_id, ip_port, dht->friends_list[i].client_id)) {*/ |
649 | /* If we can't replace bad nodes we try replacing good ones. */ | 651 | /* If we can't replace bad nodes we try replacing good ones. */ |
650 | if (!replace_good(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, | 652 | if (!replace_good(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
651 | client_id, ip_port, dht->friends_list[i].client_id)) | 653 | client_id, ip_port, dht->friends_list[i].client_id)) |
652 | used++; | 654 | used++; |
655 | |||
653 | /*} else | 656 | /*} else |
654 | used++;*/ | 657 | used++;*/ |
655 | } else | 658 | } else |
@@ -801,7 +804,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl | |||
801 | new_nonce(nonce); | 804 | new_nonce(nonce); |
802 | 805 | ||
803 | Node4_format *nodes4_list = (Node4_format *)(plain); | 806 | Node4_format *nodes4_list = (Node4_format *)(plain); |
804 | int i, num_nodes_ok = 0; | 807 | uint32_t i, num_nodes_ok = 0; |
805 | 808 | ||
806 | for (i = 0; i < num_nodes; i++) { | 809 | for (i = 0; i < num_nodes; i++) { |
807 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); | 810 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); |
@@ -1042,6 +1045,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
1042 | 1045 | ||
1043 | memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); | 1046 | memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); |
1044 | ipport_copy(&nodes_list[i].ip_port, &ippts.ip_port); | 1047 | ipport_copy(&nodes_list[i].ip_port, &ippts.ip_port); |
1048 | |||
1045 | if (dht->assoc) | 1049 | if (dht->assoc) |
1046 | Assoc_add_entry(dht->assoc, nodes4_list[i].client_id, &ippts, NULL, used ? 1 : 0); | 1050 | Assoc_add_entry(dht->assoc, nodes4_list[i].client_id, &ippts, NULL, used ? 1 : 0); |
1047 | } | 1051 | } |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 32234784..2eebd772 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -720,6 +720,7 @@ static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber) | |||
720 | 720 | ||
721 | if (m->chats[groupnumber] == NULL) | 721 | if (m->chats[groupnumber] == NULL) |
722 | return 1; | 722 | return 1; |
723 | |||
723 | return 0; | 724 | return 0; |
724 | } | 725 | } |
725 | 726 | ||
@@ -785,7 +786,8 @@ void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, | |||
785 | * It gets called every time the name list changes(new peer/name, deleted peer) | 786 | * It gets called every time the name list changes(new peer/name, deleted peer) |
786 | * Function(Tox *tox, int groupnumber, void *userdata) | 787 | * Function(Tox *tox, int groupnumber, void *userdata) |
787 | */ | 788 | */ |
788 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), void *userdata) | 789 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), |
790 | void *userdata) | ||
789 | { | 791 | { |
790 | m->group_namelistchange = function; | 792 | m->group_namelistchange = function; |
791 | m->group_namelistchange_userdata = userdata; | 793 | m->group_namelistchange_userdata = userdata; |
@@ -794,10 +796,12 @@ void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m | |||
794 | static int get_chat_num(Messenger *m, Group_Chat *chat) | 796 | static int get_chat_num(Messenger *m, Group_Chat *chat) |
795 | { | 797 | { |
796 | uint32_t i; | 798 | uint32_t i; |
799 | |||
797 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this | 800 | for (i = 0; i < m->numchats; ++i) { //TODO: remove this |
798 | if (m->chats[i] == chat) | 801 | if (m->chats[i] == chat) |
799 | return i; | 802 | return i; |
800 | } | 803 | } |
804 | |||
801 | return -1; | 805 | return -1; |
802 | } | 806 | } |
803 | 807 | ||
@@ -805,6 +809,7 @@ static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *m | |||
805 | { | 809 | { |
806 | Messenger *m = userdata; | 810 | Messenger *m = userdata; |
807 | int i = get_chat_num(m, chat); | 811 | int i = get_chat_num(m, chat); |
812 | |||
808 | if (i == -1) | 813 | if (i == -1) |
809 | return; | 814 | return; |
810 | 815 | ||
@@ -816,6 +821,7 @@ static void group_namelistchange_function(Group_Chat *chat, int peer, uint8_t ch | |||
816 | { | 821 | { |
817 | Messenger *m = userdata; | 822 | Messenger *m = userdata; |
818 | int i = get_chat_num(m, chat); | 823 | int i = get_chat_num(m, chat); |
824 | |||
819 | if (i == -1) | 825 | if (i == -1) |
820 | return; | 826 | return; |
821 | 827 | ||
@@ -1528,6 +1534,7 @@ void kill_messenger(Messenger *m) | |||
1528 | * This requires the other modules to expose cleanup functions. | 1534 | * This requires the other modules to expose cleanup functions. |
1529 | */ | 1535 | */ |
1530 | uint32_t i, numchats = m->numchats; | 1536 | uint32_t i, numchats = m->numchats; |
1537 | |||
1531 | for (i = 0; i < numchats; ++i) | 1538 | for (i = 0; i < numchats; ++i) |
1532 | del_groupchat(m, i); | 1539 | del_groupchat(m, i); |
1533 | 1540 | ||
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 6fc23db4..579516f8 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -462,7 +462,8 @@ void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, | |||
462 | * It gets called every time the name list changes(new peer/name, deleted peer) | 462 | * It gets called every time the name list changes(new peer/name, deleted peer) |
463 | * Function(Tox *tox, int groupnumber, void *userdata) | 463 | * Function(Tox *tox, int groupnumber, void *userdata) |
464 | */ | 464 | */ |
465 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), void *userdata); | 465 | void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t, void *), |
466 | void *userdata); | ||
466 | 467 | ||
467 | /* Creates a new groupchat and puts it in the chats array. | 468 | /* Creates a new groupchat and puts it in the chats array. |
468 | * | 469 | * |
@@ -512,7 +513,7 @@ int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t | |||
512 | int group_number_peers(Messenger *m, int groupnumber); | 513 | int group_number_peers(Messenger *m, int groupnumber); |
513 | 514 | ||
514 | /* List all the peers in the group chat. | 515 | /* List all the peers in the group chat. |
515 | * | 516 | * |
516 | * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array. | 517 | * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array. |
517 | * | 518 | * |
518 | * returns the number of peers on success. | 519 | * returns the number of peers on success. |
diff --git a/toxcore/assoc.c b/toxcore/assoc.c index 4dc91671..0177ea0c 100644 --- a/toxcore/assoc.c +++ b/toxcore/assoc.c | |||
@@ -908,8 +908,8 @@ void Assoc_status(Assoc *assoc) | |||
908 | entry->used_at ? (int)(unix_time() - entry->used_at) : 0, | 908 | entry->used_at ? (int)(unix_time() - entry->used_at) : 0, |
909 | entry->seen_at ? (int)(unix_time() - entry->seen_at) : 0, | 909 | entry->seen_at ? (int)(unix_time() - entry->seen_at) : 0, |
910 | entry->seen_at ? (entry->seen_family == AF_INET ? '4' : (entry->seen_family == AF_INET6 ? '6' : '?')) : '?', | 910 | entry->seen_at ? (entry->seen_family == AF_INET ? '4' : (entry->seen_family == AF_INET6 ? '6' : '?')) : '?', |
911 | entry->heard_at ? (int)(unix_time() - entry->heard_at) : 0, | 911 | entry->heard_at ? (int)(unix_time() - entry->heard_at) : 0, |
912 | entry->heard_at ? (entry->heard_family == AF_INET ? '4' : (entry->heard_family == AF_INET6 ? '6' : '?')) : '?'); | 912 | entry->heard_at ? (entry->heard_family == AF_INET ? '4' : (entry->heard_family == AF_INET6 ? '6' : '?')) : '?'); |
913 | loglog(logbuffer); | 913 | loglog(logbuffer); |
914 | total++; | 914 | total++; |
915 | } | 915 | } |
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 16d8f344..f6574ae9 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c | |||
@@ -236,6 +236,7 @@ static int delpeer(Group_Chat *chat, int peernum) | |||
236 | return -1; | 236 | return -1; |
237 | 237 | ||
238 | uint32_t i; | 238 | uint32_t i; |
239 | |||
239 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* If peer is in close list, time it out forcefully. */ | 240 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* If peer is in close list, time it out forcefully. */ |
240 | if (id_equal(chat->close[i].client_id, chat->group[peernum].client_id)) { | 241 | if (id_equal(chat->close[i].client_id, chat->group[peernum].client_id)) { |
241 | chat->close[i].last_recv = 0; | 242 | chat->close[i].last_recv = 0; |
@@ -641,7 +642,8 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, | |||
641 | chat->group_message_userdata = userdata; | 642 | chat->group_message_userdata = userdata; |
642 | } | 643 | } |
643 | 644 | ||
644 | void callback_namelistchange(Group_Chat *chat, void (*function)(Group_Chat *chat, int peer, uint8_t change, void *), void *userdata) | 645 | void callback_namelistchange(Group_Chat *chat, void (*function)(Group_Chat *chat, int peer, uint8_t change, void *), |
646 | void *userdata) | ||
645 | { | 647 | { |
646 | chat->peer_namelistchange = function; | 648 | chat->peer_namelistchange = function; |
647 | chat->group_namelistchange_userdata = userdata; | 649 | chat->group_namelistchange_userdata = userdata; |
@@ -655,9 +657,11 @@ uint32_t group_numpeers(Group_Chat *chat) | |||
655 | uint32_t group_client_names(Group_Chat *chat, uint8_t names[][MAX_NICK_BYTES], uint16_t length) | 657 | uint32_t group_client_names(Group_Chat *chat, uint8_t names[][MAX_NICK_BYTES], uint16_t length) |
656 | { | 658 | { |
657 | uint32_t i; | 659 | uint32_t i; |
660 | |||
658 | for (i = 0; i < chat->numpeers && i < length; ++i) { | 661 | for (i = 0; i < chat->numpeers && i < length; ++i) { |
659 | group_peername(chat, i, names[i]); | 662 | group_peername(chat, i, names[i]); |
660 | } | 663 | } |
664 | |||
661 | return i; | 665 | return i; |
662 | } | 666 | } |
663 | 667 | ||
diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index 33773785..a43173ab 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h | |||
@@ -109,7 +109,8 @@ typedef enum { | |||
109 | CHAT_CHANGE_PEER_NAME, | 109 | CHAT_CHANGE_PEER_NAME, |
110 | } CHAT_CHANGE; | 110 | } CHAT_CHANGE; |
111 | 111 | ||
112 | void callback_namelistchange(Group_Chat *chat, void (*function)(Group_Chat *chat, int peer, uint8_t change, void *), void *userdata); | 112 | void callback_namelistchange(Group_Chat *chat, void (*function)(Group_Chat *chat, int peer, uint8_t change, void *), |
113 | void *userdata); | ||
113 | 114 | ||
114 | /* | 115 | /* |
115 | * Send a message to the group. | 116 | * Send a message to the group. |
diff --git a/toxcore/network.h b/toxcore/network.h index 88cfaf17..060240f4 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -129,7 +129,7 @@ typedef union { | |||
129 | } IP6; | 129 | } IP6; |
130 | 130 | ||
131 | typedef struct { | 131 | typedef struct { |
132 | sa_family_t family; | 132 | uint16_t family; |
133 | union { | 133 | union { |
134 | IP4 ip4; | 134 | IP4 ip4; |
135 | IP6 ip6; | 135 | IP6 ip6; |
@@ -238,9 +238,9 @@ typedef struct { | |||
238 | typedef struct { | 238 | typedef struct { |
239 | Packet_Handles packethandlers[256]; | 239 | Packet_Handles packethandlers[256]; |
240 | 240 | ||
241 | /* Our UDP socket. */ | ||
242 | sa_family_t family; | 241 | sa_family_t family; |
243 | uint16_t port; | 242 | uint16_t port; |
243 | /* Our UDP socket. */ | ||
244 | sock_t sock; | 244 | sock_t sock; |
245 | uint64_t send_fail_eagain; | 245 | uint64_t send_fail_eagain; |
246 | } Networking_Core; | 246 | } Networking_Core; |
diff --git a/toxcore/tox.c b/toxcore/tox.c index 487f2517..a8d41d7f 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -314,7 +314,7 @@ void tox_callback_friend_request(Tox *tox, void (*function)(uint8_t *, uint8_t * | |||
314 | * Function format is: function(int friendnumber, uint8_t * message, uint32_t length) | 314 | * Function format is: function(int friendnumber, uint8_t * message, uint32_t length) |
315 | */ | 315 | */ |
316 | void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), | 316 | void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), |
317 | void *userdata) | 317 | void *userdata) |
318 | { | 318 | { |
319 | Messenger *m = tox; | 319 | Messenger *m = tox; |
320 | m_callback_friendmessage(m, function, userdata); | 320 | m_callback_friendmessage(m, function, userdata); |
@@ -334,7 +334,7 @@ void tox_callback_action(Tox *tox, void (*function)(Messenger *tox, int, uint8_t | |||
334 | * You are not responsible for freeing newname. | 334 | * You are not responsible for freeing newname. |
335 | */ | 335 | */ |
336 | void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), | 336 | void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), |
337 | void *userdata) | 337 | void *userdata) |
338 | { | 338 | { |
339 | Messenger *m = tox; | 339 | Messenger *m = tox; |
340 | m_callback_namechange(m, function, userdata); | 340 | m_callback_namechange(m, function, userdata); |
@@ -345,7 +345,7 @@ void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int, ui | |||
345 | * You are not responsible for freeing newstatus. | 345 | * You are not responsible for freeing newstatus. |
346 | */ | 346 | */ |
347 | void tox_callback_status_message(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), | 347 | void tox_callback_status_message(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), |
348 | void *userdata) | 348 | void *userdata) |
349 | { | 349 | { |
350 | Messenger *m = tox; | 350 | Messenger *m = tox; |
351 | m_callback_statusmessage(m, function, userdata); | 351 | m_callback_statusmessage(m, function, userdata); |
@@ -542,8 +542,8 @@ uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size) | |||
542 | * Function(Tox *tox, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) | 542 | * Function(Tox *tox, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) |
543 | */ | 543 | */ |
544 | void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, uint64_t, uint8_t *, | 544 | void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, uint64_t, uint8_t *, |
545 | uint16_t, | 545 | uint16_t, |
546 | void *), void *userdata) | 546 | void *), void *userdata) |
547 | { | 547 | { |
548 | Messenger *m = tox; | 548 | Messenger *m = tox; |
549 | callback_file_sendrequest(m, function, userdata); | 549 | callback_file_sendrequest(m, function, userdata); |
@@ -589,7 +589,7 @@ int tox_new_file_sender(Tox *tox, int friendnumber, uint64_t filesize, uint8_t * | |||
589 | * return -1 on failure | 589 | * return -1 on failure |
590 | */ | 590 | */ |
591 | int tox_file_send_control(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 591 | int tox_file_send_control(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, |
592 | uint8_t *data, uint16_t length) | 592 | uint8_t *data, uint16_t length) |
593 | { | 593 | { |
594 | Messenger *m = tox; | 594 | Messenger *m = tox; |
595 | return file_control(m, friendnumber, send_receive, filenumber, message_id, data, length); | 595 | return file_control(m, friendnumber, send_receive, filenumber, message_id, data, length); |
diff --git a/toxcore/tox.h b/toxcore/tox.h index 9f84876e..d19548fb 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -298,7 +298,7 @@ void tox_callback_friend_request(Tox *tox, void (*function)(uint8_t *, uint8_t * | |||
298 | * Function format is: function(int friendnumber, uint8_t * message, uint32_t length) | 298 | * Function format is: function(int friendnumber, uint8_t * message, uint32_t length) |
299 | */ | 299 | */ |
300 | void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), | 300 | void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), |
301 | void *userdata); | 301 | void *userdata); |
302 | 302 | ||
303 | /* Set the function that will be executed when an action from a friend is received. | 303 | /* Set the function that will be executed when an action from a friend is received. |
304 | * Function format is: function(int friendnumber, uint8_t * action, uint32_t length) | 304 | * Function format is: function(int friendnumber, uint8_t * action, uint32_t length) |
@@ -310,14 +310,14 @@ void tox_callback_action(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, ui | |||
310 | * You are not responsible for freeing newname | 310 | * You are not responsible for freeing newname |
311 | */ | 311 | */ |
312 | void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), | 312 | void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), |
313 | void *userdata); | 313 | void *userdata); |
314 | 314 | ||
315 | /* Set the callback for status message changes. | 315 | /* Set the callback for status message changes. |
316 | * function(int friendnumber, uint8_t *newstatus, uint16_t length) | 316 | * function(int friendnumber, uint8_t *newstatus, uint16_t length) |
317 | * You are not responsible for freeing newstatus. | 317 | * You are not responsible for freeing newstatus. |
318 | */ | 318 | */ |
319 | void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), | 319 | void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), |
320 | void *userdata); | 320 | void *userdata); |
321 | 321 | ||
322 | /* Set the callback for status type changes. | 322 | /* Set the callback for status type changes. |
323 | * function(int friendnumber, USERSTATUS kind) | 323 | * function(int friendnumber, USERSTATUS kind) |
@@ -374,7 +374,8 @@ typedef enum { | |||
374 | TOX_CHAT_CHANGE_PEER_NAME, | 374 | TOX_CHAT_CHANGE_PEER_NAME, |
375 | } TOX_CHAT_CHANGE; | 375 | } TOX_CHAT_CHANGE; |
376 | 376 | ||
377 | void tox_callback_group_namelist_change(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t, void *), void *userdata); | 377 | void tox_callback_group_namelist_change(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t, void *), |
378 | void *userdata); | ||
378 | 379 | ||
379 | /* Creates a new groupchat and puts it in the chats array. | 380 | /* Creates a new groupchat and puts it in the chats array. |
380 | * | 381 | * |
@@ -485,7 +486,7 @@ enum { | |||
485 | * Function(Tox *tox, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) | 486 | * Function(Tox *tox, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) |
486 | */ | 487 | */ |
487 | void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int, uint8_t, uint64_t, uint8_t *, uint16_t, | 488 | void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int, uint8_t, uint64_t, uint8_t *, uint16_t, |
488 | void *), void *userdata); | 489 | void *), void *userdata); |
489 | 490 | ||
490 | /* Set the callback for file control requests. | 491 | /* Set the callback for file control requests. |
491 | * | 492 | * |
@@ -523,7 +524,7 @@ int tox_new_file_sender(Tox *tox, int friendnumber, uint64_t filesize, uint8_t * | |||
523 | * return -1 on failure | 524 | * return -1 on failure |
524 | */ | 525 | */ |
525 | int tox_file_send_control(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 526 | int tox_file_send_control(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, |
526 | uint8_t *data, uint16_t length); | 527 | uint8_t *data, uint16_t length); |
527 | 528 | ||
528 | /* Send file data. | 529 | /* Send file data. |
529 | * | 530 | * |