diff options
-rw-r--r-- | INSTALL.md | 19 | ||||
-rw-r--r-- | core/DHT.c | 119 | ||||
-rw-r--r-- | core/DHT.h | 24 | ||||
-rw-r--r-- | testing/DHT_test.c | 4 |
4 files changed, 162 insertions, 4 deletions
@@ -27,6 +27,23 @@ For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would r | |||
27 | make Messenger_test | 27 | make Messenger_test |
28 | ``` | 28 | ``` |
29 | 29 | ||
30 | ###OSX: | ||
31 | |||
32 | Much the same as above, remember to install the latest XCode and the developer tools (Preferences -> Downloads -> Command Line Tools). | ||
33 | Users running Mountain Lion and the latest version of XCode (4.6.3) will also need to install libtool | ||
34 | Libtool is easy enough to install, grab it from http://www.gnu.org/software/libtool/ and: | ||
35 | |||
36 | ./configure | ||
37 | make | ||
38 | sudo make install | ||
39 | |||
40 | Do not install it from macports (or any dependencies for that matter) as they get shoved in the wrong directory | ||
41 | and make your life more annoying. | ||
42 | |||
43 | Another thing you may want to install is the latest gcc, this caused me a few problems as XCode from 4.3 | ||
44 | no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at | ||
45 | http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42 | ||
46 | |||
30 | ###Windows: | 47 | ###Windows: |
31 | 48 | ||
32 | You should install: | 49 | You should install: |
@@ -49,4 +66,4 @@ mingw32-make name_of_c_file | |||
49 | For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would run: | 66 | For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would run: |
50 | ```cmd | 67 | ```cmd |
51 | mingw32-make Messenger_test | 68 | mingw32-make Messenger_test |
52 | ``` \ No newline at end of file | 69 | ``` |
@@ -34,6 +34,8 @@ typedef struct | |||
34 | IP_Port ip_port; | 34 | IP_Port ip_port; |
35 | uint32_t timestamp; | 35 | uint32_t timestamp; |
36 | uint32_t last_pinged; | 36 | uint32_t last_pinged; |
37 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend | ||
38 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ | ||
37 | }Client_data; | 39 | }Client_data; |
38 | /* maximum number of clients stored per friend. */ | 40 | /* maximum number of clients stored per friend. */ |
39 | #define MAX_FRIEND_CLIENTS 8 | 41 | #define MAX_FRIEND_CLIENTS 8 |
@@ -237,6 +239,8 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por | |||
237 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 239 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
238 | list[i].ip_port = ip_port; | 240 | list[i].ip_port = ip_port; |
239 | list[i].timestamp = temp_time; | 241 | list[i].timestamp = temp_time; |
242 | list[i].ret_ip_port.ip.i = 0; | ||
243 | list[i].ret_ip_port.port = 0; | ||
240 | return 0; | 244 | return 0; |
241 | } | 245 | } |
242 | } | 246 | } |
@@ -257,6 +261,8 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po | |||
257 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 261 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
258 | list[i].ip_port = ip_port; | 262 | list[i].ip_port = ip_port; |
259 | list[i].timestamp = temp_time; | 263 | list[i].timestamp = temp_time; |
264 | list[i].ret_ip_port.ip.i = 0; | ||
265 | list[i].ret_ip_port.port = 0; | ||
260 | return 0; | 266 | return 0; |
261 | } | 267 | } |
262 | } | 268 | } |
@@ -294,6 +300,38 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
294 | } | 300 | } |
295 | } | 301 | } |
296 | 302 | ||
303 | /* If client_id is a friend or us, update ret_ip_port | ||
304 | nodeclient_id is the id of the node that sent us this info */ | ||
305 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) | ||
306 | { | ||
307 | uint32_t i, j; | ||
308 | if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) | ||
309 | { | ||
310 | for(i = 0; i < LCLIENT_LIST; ++i) | ||
311 | { | ||
312 | if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) | ||
313 | { | ||
314 | close_clientlist[i].ret_ip_port = ip_port; | ||
315 | return; | ||
316 | } | ||
317 | } | ||
318 | } | ||
319 | else | ||
320 | for(i = 0; i < num_friends; ++i) | ||
321 | { | ||
322 | if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) | ||
323 | { | ||
324 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | ||
325 | { | ||
326 | if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) | ||
327 | { | ||
328 | friends_list[i].client_list[j].ret_ip_port = ip_port; | ||
329 | return; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | } | ||
297 | 335 | ||
298 | /* ping timeout in seconds */ | 336 | /* ping timeout in seconds */ |
299 | #define PING_TIMEOUT 5 | 337 | #define PING_TIMEOUT 5 |
@@ -725,15 +763,16 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
725 | Node_format nodes_list[MAX_SENT_NODES]; | 763 | Node_format nodes_list[MAX_SENT_NODES]; |
726 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 764 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
727 | 765 | ||
766 | addto_lists(source, packet + 1); | ||
767 | |||
728 | uint32_t i; | 768 | uint32_t i; |
729 | for(i = 0; i < num_nodes; ++i) | 769 | for(i = 0; i < num_nodes; ++i) |
730 | { | 770 | { |
731 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); | 771 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); |
772 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | ||
732 | } | 773 | } |
733 | 774 | ||
734 | addto_lists(source, packet + 1); | ||
735 | return 0; | 775 | return 0; |
736 | |||
737 | } | 776 | } |
738 | 777 | ||
739 | /* END of packet handling functions */ | 778 | /* END of packet handling functions */ |
@@ -950,6 +989,81 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) | |||
950 | } | 989 | } |
951 | 990 | ||
952 | 991 | ||
992 | |||
993 | /* send the given packet to node with client_id | ||
994 | returns -1 if failure */ | ||
995 | int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) | ||
996 | { | ||
997 | uint32_t i; | ||
998 | for(i = 0; i < LCLIENT_LIST; ++i) | ||
999 | { | ||
1000 | if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) | ||
1001 | { | ||
1002 | return sendpacket(close_clientlist[i].ip_port, packet, length); | ||
1003 | } | ||
1004 | } | ||
1005 | return -1; | ||
1006 | } | ||
1007 | |||
1008 | /* Send the following packet to everyone who tells us they are connected to friend_id | ||
1009 | returns the number of nodes it sent the packet to */ | ||
1010 | int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | ||
1011 | { | ||
1012 | uint32_t i, j; | ||
1013 | uint32_t sent = 0; | ||
1014 | uint32_t temp_time = unix_time(); | ||
1015 | for(i = 0; i < num_friends; ++i) | ||
1016 | { | ||
1017 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ | ||
1018 | { | ||
1019 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | ||
1020 | { | ||
1021 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && | ||
1022 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) | ||
1023 | /*If ip is not zero and node is good */ | ||
1024 | { | ||
1025 | if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) | ||
1026 | { | ||
1027 | ++sent; | ||
1028 | } | ||
1029 | } | ||
1030 | } | ||
1031 | return sent; | ||
1032 | } | ||
1033 | } | ||
1034 | return 0; | ||
1035 | } | ||
1036 | |||
1037 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist | ||
1038 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | ||
1039 | returns the number of ips returned | ||
1040 | returns -1 if no such friend*/ | ||
1041 | int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) | ||
1042 | { | ||
1043 | int num_ips = 0; | ||
1044 | uint32_t i, j; | ||
1045 | uint32_t temp_time = unix_time(); | ||
1046 | for(i = 0; i < num_friends; ++i) | ||
1047 | { | ||
1048 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ | ||
1049 | { | ||
1050 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | ||
1051 | { | ||
1052 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && | ||
1053 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) | ||
1054 | /*If ip is not zero and node is good */ | ||
1055 | { | ||
1056 | ip_portlist[num_ips] = friends_list[i].client_list[j].ret_ip_port; | ||
1057 | ++num_ips; | ||
1058 | } | ||
1059 | } | ||
1060 | return num_ips; | ||
1061 | } | ||
1062 | |||
1063 | } | ||
1064 | return 0; | ||
1065 | } | ||
1066 | |||
953 | /* get the size of the DHT (for saving) */ | 1067 | /* get the size of the DHT (for saving) */ |
954 | uint32_t DHT_size() | 1068 | uint32_t DHT_size() |
955 | { | 1069 | { |
@@ -1026,3 +1140,4 @@ int DHT_isconnected() | |||
1026 | } | 1140 | } |
1027 | return 0; | 1141 | return 0; |
1028 | } | 1142 | } |
1143 | |||
@@ -72,12 +72,34 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); | |||
72 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key); | 72 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key); |
73 | 73 | ||
74 | 74 | ||
75 | |||
76 | /* ROUTING FUNCTIONS */ | ||
77 | |||
78 | /* send the given packet to node with client_id | ||
79 | returns -1 if failure */ | ||
80 | int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length); | ||
81 | |||
82 | /* Send the following packet to everyone who tells us they are connected to friend_id | ||
83 | returns the number of nodes it sent the packet to */ | ||
84 | int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length); | ||
85 | |||
86 | |||
87 | |||
88 | /* NAT PUNCHING FUNCTIONS */ | ||
89 | |||
90 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist | ||
91 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | ||
92 | returns the number of ips returned | ||
93 | returns -1 if no such friend*/ | ||
94 | int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id); | ||
95 | |||
96 | |||
97 | |||
75 | /* SAVE/LOAD functions */ | 98 | /* SAVE/LOAD functions */ |
76 | 99 | ||
77 | /* get the size of the DHT (for saving) */ | 100 | /* get the size of the DHT (for saving) */ |
78 | uint32_t DHT_size(); | 101 | uint32_t DHT_size(); |
79 | 102 | ||
80 | |||
81 | /* save the DHT in data where data is an array of size DHT_size() */ | 103 | /* save the DHT in data where data is an array of size DHT_size() */ |
82 | void DHT_save(uint8_t * data); | 104 | void DHT_save(uint8_t * data); |
83 | 105 | ||
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 086cd554..5f85e934 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -44,6 +44,8 @@ void print_clientlist() | |||
44 | printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); | 44 | printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); |
45 | printf("\nTimestamp: %u", close_clientlist[i].timestamp); | 45 | printf("\nTimestamp: %u", close_clientlist[i].timestamp); |
46 | printf("\nLast pinged: %u\n", close_clientlist[i].last_pinged); | 46 | printf("\nLast pinged: %u\n", close_clientlist[i].last_pinged); |
47 | p_ip = close_clientlist[i].ret_ip_port; | ||
48 | printf("\nOUR IP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); | ||
47 | } | 49 | } |
48 | } | 50 | } |
49 | 51 | ||
@@ -78,6 +80,8 @@ void print_friendlist() | |||
78 | printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); | 80 | printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); |
79 | printf("\nTimestamp: %u", friends_list[k].client_list[i].timestamp); | 81 | printf("\nTimestamp: %u", friends_list[k].client_list[i].timestamp); |
80 | printf("\nLast pinged: %u\n", friends_list[k].client_list[i].last_pinged); | 82 | printf("\nLast pinged: %u\n", friends_list[k].client_list[i].last_pinged); |
83 | p_ip = friends_list[k].client_list[i].ret_ip_port; | ||
84 | printf("\nret IP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); | ||
81 | } | 85 | } |
82 | } | 86 | } |
83 | } | 87 | } |