diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | core/DHT.c | 121 | ||||
-rw-r--r-- | core/DHT.h | 20 |
3 files changed, 125 insertions, 18 deletions
@@ -122,6 +122,6 @@ Proposal of a free as in freedom skype replacement: | |||
122 | Packet contents: [byte with value: 02][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][char array: requested_node_id (node_id of which we want the ip), length=32 bytes] | 122 | Packet contents: [byte with value: 02][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][char array: requested_node_id (node_id of which we want the ip), length=32 bytes] |
123 | Valid replies: a send_nodes packet | 123 | Valid replies: a send_nodes packet |
124 | 124 | ||
125 | Send_nodes (response): [byte with value: 03][random 4 byte (ping_id)][Nodes in node format, length=38 * (number of nodes (maximum of 8 nodes)) bytes] | 125 | Send_nodes (response): [byte with value: 03][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][Nodes in node format, length=38 * (number of nodes (maximum of 8 nodes)) bytes] |
126 | ex: 03[Node][Node][Node] | 126 | ex: 03[Node][Node][Node] |
127 | 127 | ||
@@ -81,8 +81,102 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id) | |||
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | 83 | ||
84 | //check if client with client_id is already in knode format list of length length. | ||
85 | //return True(1) or False(0) | ||
86 | int client_in_nodelist(Node_format * list, uint32_t length, char * client_id) | ||
87 | { | ||
88 | uint32_t i, j; | ||
89 | for(i = 0; i < length; i++) | ||
90 | { | ||
91 | for(j = 0; j < CLIENT_ID_SIZE; j++) | ||
92 | { | ||
93 | |||
94 | if(list[i].client_id[j] != client_id[j]) | ||
95 | { | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | if((j - 1) == CLIENT_ID_SIZE) | ||
100 | { | ||
101 | |||
102 | return 1; | ||
103 | } | ||
104 | } | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | |||
109 | |||
84 | //the number of seconds for a non responsive node to become bad. | 110 | //the number of seconds for a non responsive node to become bad. |
85 | #define BAD_NODE_TIMEOUT 130 | 111 | #define BAD_NODE_TIMEOUT 130 |
112 | //The max number of nodes to send with send nodes. | ||
113 | #define MAX_SENT_NODES 8 | ||
114 | |||
115 | |||
116 | //Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: | ||
117 | //put them in the nodes_list and return how many were found. | ||
118 | //TODO: Make this function much more efficient. | ||
119 | int get_close_nodes(char * client_id, Node_format * nodes_list) | ||
120 | { | ||
121 | uint32_t i, j, k; | ||
122 | int num_nodes=0; | ||
123 | uint32_t temp_time = unix_time(); | ||
124 | for(i = 0; i < LCLIENT_LIST; i++) | ||
125 | { | ||
126 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && | ||
127 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) | ||
128 | //if node is good and not already in list. | ||
129 | { | ||
130 | if(num_nodes < MAX_SENT_NODES) | ||
131 | { | ||
132 | memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | ||
133 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | ||
134 | num_nodes++; | ||
135 | } | ||
136 | else for(j = 0; j < MAX_SENT_NODES; j++) | ||
137 | { | ||
138 | if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) | ||
139 | { | ||
140 | memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | ||
141 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | |||
147 | } | ||
148 | for(i = 0; i < num_friends; i++) | ||
149 | { | ||
150 | for(j = 0; j < MAX_FRIEND_CLIENTS; j++) | ||
151 | { | ||
152 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && | ||
153 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) | ||
154 | //if node is good and not already in list. | ||
155 | { | ||
156 | if(num_nodes < MAX_SENT_NODES) | ||
157 | { | ||
158 | memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | ||
159 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | ||
160 | num_nodes++; | ||
161 | } | ||
162 | else for(k = 0; k < MAX_SENT_NODES; k++) | ||
163 | { | ||
164 | if(id_closest(client_id, nodes_list[j].client_id, friends_list[i].client_list[j].client_id) == 2) | ||
165 | { | ||
166 | memcpy(nodes_list[j].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | ||
167 | nodes_list[j].ip_port = friends_list[i].client_list[j].ip_port; | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | } | ||
174 | |||
175 | } | ||
176 | |||
177 | } | ||
178 | |||
179 | |||
86 | 180 | ||
87 | //replace first bad (or empty) node with this one | 181 | //replace first bad (or empty) node with this one |
88 | //return 0 if successfull | 182 | //return 0 if successfull |
@@ -90,13 +184,14 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id) | |||
90 | int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port) | 184 | int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port) |
91 | { | 185 | { |
92 | uint32_t i; | 186 | uint32_t i; |
187 | uint32_t temp_time = unix_time(); | ||
93 | for(i = 0; i < length; i++) | 188 | for(i = 0; i < length; i++) |
94 | { | 189 | { |
95 | if(list[i].timestamp + BAD_NODE_TIMEOUT < unix_time()) | 190 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time)//if node is bad. |
96 | { | 191 | { |
97 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 192 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
98 | list[i].ip_port = ip_port; | 193 | list[i].ip_port = ip_port; |
99 | list[i].timestamp = unix_time(); | 194 | list[i].timestamp = temp_time; |
100 | return 0; | 195 | return 0; |
101 | } | 196 | } |
102 | } | 197 | } |
@@ -138,13 +233,13 @@ int addto_lists(IP_Port ip_port, char * client_id) | |||
138 | } | 233 | } |
139 | for(i = 0; i < num_friends; i++) | 234 | for(i = 0; i < num_friends; i++) |
140 | { | 235 | { |
141 | if(!client_in_list(friends_list[i].client_list, LCLIENT_LIST, client_id)) | 236 | if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id)) |
142 | { | 237 | { |
143 | 238 | ||
144 | if(replace_bad(friends_list[i].client_list, LCLIENT_LIST, client_id, ip_port)) | 239 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
145 | { | 240 | { |
146 | //if we can't replace bad nodes we try replacing good ones | 241 | //if we can't replace bad nodes we try replacing good ones |
147 | replace_good(friends_list[i].client_list, LCLIENT_LIST, client_id, ip_port, self_client_id); | 242 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_client_id); |
148 | } | 243 | } |
149 | 244 | ||
150 | } | 245 | } |
@@ -294,11 +389,12 @@ int getnodes(IP_Port ip_port, char * client_id) | |||
294 | return sendpacket(ip_port, data, sizeof(data)); | 389 | return sendpacket(ip_port, data, sizeof(data)); |
295 | } | 390 | } |
296 | 391 | ||
392 | |||
297 | //send a send nodes response | 393 | //send a send nodes response |
298 | //Currently incomplete: missing bunch of stuff | 394 | //Currently incomplete: missing bunch of stuff |
299 | int sendnodes(IP_Port ip_port, char * client_id) | 395 | int sendnodes(IP_Port ip_port, char * client_id) |
300 | { | 396 | { |
301 | char data[5 + (CLIENT_ID_SIZE + 6)*8]; | 397 | char data[5 + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; |
302 | data[0] = 3; | 398 | data[0] = 3; |
303 | 399 | ||
304 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 400 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); |
@@ -324,9 +420,7 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source) | |||
324 | 420 | ||
325 | memcpy(&ping_id, packet + 1, 4); | 421 | memcpy(&ping_id, packet + 1, 4); |
326 | pingres(source, ping_id); | 422 | pingres(source, ping_id); |
327 | 423 | ||
328 | |||
329 | |||
330 | return 0; | 424 | return 0; |
331 | } | 425 | } |
332 | 426 | ||
@@ -346,16 +440,17 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source) | |||
346 | { | 440 | { |
347 | return 1; | 441 | return 1; |
348 | } | 442 | } |
443 | //sendnodes(IP_Port ip_port, char * client_id) | ||
349 | 444 | ||
350 | 445 | ||
351 | 446 | ||
352 | 447 | return 0; | |
353 | return 0; | ||
354 | } | 448 | } |
355 | 449 | ||
356 | int handle_sendnodes(char * packet, uint32_t length, IP_Port source) | 450 | int handle_sendnodes(char * packet, uint32_t length, IP_Port source) |
357 | { | 451 | { |
358 | if(length > 325 || (length - 5) % (CLIENT_ID_SIZE + 6) != 0) | 452 | if(length > 5 + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port)) || |
453 | (length - 5) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) | ||
359 | { | 454 | { |
360 | return 1; | 455 | return 1; |
361 | } | 456 | } |
@@ -428,7 +523,7 @@ int DHT_recvpacket(char * packet, uint32_t length, IP_Port source) | |||
428 | 523 | ||
429 | } | 524 | } |
430 | 525 | ||
431 | 526 | return 0; | |
432 | } | 527 | } |
433 | 528 | ||
434 | //Ping each client in the "friends" list every 60 seconds. | 529 | //Ping each client in the "friends" list every 60 seconds. |
@@ -1,3 +1,6 @@ | |||
1 | #ifndef DHT_H | ||
2 | #define DHT_H | ||
3 | |||
1 | #include <stdlib.h> | 4 | #include <stdlib.h> |
2 | #include <stdio.h> | 5 | #include <stdio.h> |
3 | #include <stdint.h> | 6 | #include <stdint.h> |
@@ -48,15 +51,22 @@ typedef struct | |||
48 | uint32_t timestamp; | 51 | uint32_t timestamp; |
49 | 52 | ||
50 | }Client_data; | 53 | }Client_data; |
51 | 54 | //maximum number of clients stored per friend. | |
52 | 55 | #define MAX_FRIEND_CLIENTS 8 | |
53 | typedef struct | 56 | typedef struct |
54 | { | 57 | { |
55 | char client_id[CLIENT_ID_SIZE]; | 58 | char client_id[CLIENT_ID_SIZE]; |
56 | Client_data client_list[8]; | 59 | Client_data client_list[MAX_FRIEND_CLIENTS]; |
57 | 60 | ||
58 | }Friend; | 61 | }Friend; |
59 | 62 | ||
63 | |||
64 | typedef struct | ||
65 | { | ||
66 | char client_id[CLIENT_ID_SIZE]; | ||
67 | IP_Port ip_port; | ||
68 | }Node_format; | ||
69 | |||
60 | typedef struct | 70 | typedef struct |
61 | { | 71 | { |
62 | IP_Port ip_port; | 72 | IP_Port ip_port; |
@@ -153,4 +163,6 @@ int sendpacket(IP_Port ip_port, char * data, uint32_t length); | |||
153 | //Function to recieve data, ip and port of sender is put into ip_port | 163 | //Function to recieve data, ip and port of sender is put into ip_port |
154 | //the packet data into data | 164 | //the packet data into data |
155 | //the packet length into length. | 165 | //the packet length into length. |
156 | int recievepacket(IP_Port * ip_port, char * data, uint32_t * length); \ No newline at end of file | 166 | int recievepacket(IP_Port * ip_port, char * data, uint32_t * length); |
167 | |||
168 | #endif \ No newline at end of file | ||