summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c121
-rw-r--r--core/DHT.h20
2 files changed, 124 insertions, 17 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 911e23e7..fd34db71 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -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)
86int 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.
119int 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)
90int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port) 184int 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
299int sendnodes(IP_Port ip_port, char * client_id) 395int 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
356int handle_sendnodes(char * packet, uint32_t length, IP_Port source) 450int 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 526return 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.
diff --git a/core/DHT.h b/core/DHT.h
index 7493761a..82a16cb7 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -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
53typedef struct 56typedef 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
64typedef struct
65{
66 char client_id[CLIENT_ID_SIZE];
67 IP_Port ip_port;
68}Node_format;
69
60typedef struct 70typedef 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.
156int recievepacket(IP_Port * ip_port, char * data, uint32_t * length); \ No newline at end of file 166int recievepacket(IP_Port * ip_port, char * data, uint32_t * length);
167
168#endif \ No newline at end of file