summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c113
1 files changed, 107 insertions, 6 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 80a54551..5a48c7b6 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -13,9 +13,9 @@ int sendpacket(IP_Port ip_port, char * data, uint32_t length)
13//return 0 if both are same distance 13//return 0 if both are same distance
14//return 1 if client_id1 is closer. 14//return 1 if client_id1 is closer.
15//return 2 if client_id2 is closer. 15//return 2 if client_id2 is closer.
16int id_distance(char * client_id, char * client_id1, char * client_id2) 16int id_closest(char * client_id, char * client_id1, char * client_id2)
17{ 17{
18 int i; 18 uint32_t i;
19 for(i = 0; i < CLIENT_ID_SIZE; i++) 19 for(i = 0; i < CLIENT_ID_SIZE; i++)
20 { 20 {
21 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) 21 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i]))
@@ -32,11 +32,97 @@ int id_distance(char * client_id, char * client_id1, char * client_id2)
32 return 0; 32 return 0;
33} 33}
34 34
35//check if client with client_id is already in list of length length.
36//return True(1) or False(0)
37int client_in_list(Client_data * list, uint32_t length, char * client_id)
38{
39 uint32_t i, j;
40 for(i = 0; i < length; i++)
41 {
42 for(j = 0; j < CLIENT_ID_SIZE; j++)
43 {
44
45 if(list[i].client_id[j] != client_id[j])
46 {
47 break;
48 }
49 }
50 if((j - 1) == CLIENT_ID_SIZE)
51 {
52 return 1;
53 }
54 }
55 return 0;
56}
57
58//the number of seconds for a non responsive node to become bad.
59#define BAD_NODE_TIMEOUT 130
60
61//replace first bad (or empty) node with this one
62//return 0 if successfull
63//return 1 if not (list contains no bad nodes)
64int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port)
65{
66 uint32_t i;
67 for(i = 0; i < length; i++)
68 {
69 if(list[i].timestamp + BAD_NODE_TIMEOUT < unix_time())
70 {
71 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
72 list[i].ip_port = ip_port;
73 list[i].timestamp = unix_time();
74 return 0;
75 }
76 }
77 return 1;
78}
79
80//replace the first good node further to the comp_client_id than that of the client_id
81int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id)
82{
83 uint32_t i;
84 for(i = 0; i < length; i++)
85 {
86 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2)
87 {
88 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
89 list[i].ip_port = ip_port;
90 list[i].timestamp = unix_time();
91 return 0;
92 }
93 }
94 return 1;
95}
35 96
36//Attempt to add client with ip_port and client_id to the friends client list and close_clientlist 97//Attempt to add client with ip_port and client_id to the friends client list and close_clientlist
37int addto_lists(IP_Port ip_port, char * client_id) 98int addto_lists(IP_Port ip_port, char * client_id)
38{ 99{
100 uint32_t i, j;
39 101
102 //NOTE: current behaviour if there are two clients with the same id is to only keep one (the first one)
103 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id))
104 {
105
106 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
107 {
108 //if we can't replace bad nodes we try replacing good ones
109 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_client_id);
110 }
111
112 }
113 for(i = 0; i < num_friends; i++)
114 {
115 if(!client_in_list(friends_list[i].client_list, LCLIENT_LIST, client_id))
116 {
117
118 if(replace_bad(friends_list[i].client_list, LCLIENT_LIST, client_id, ip_port))
119 {
120 //if we can't replace bad nodes we try replacing good ones
121 replace_good(friends_list[i].client_list, LCLIENT_LIST, client_id, ip_port, self_client_id);
122 }
123
124 }
125 }
40 126
41 127
42} 128}
@@ -113,7 +199,7 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)
113 memcpy(&ping_id, packet + 1, 4); 199 memcpy(&ping_id, packet + 1, 4);
114 pingres(source, ping_id); 200 pingres(source, ping_id);
115 201
116 addto_lists(source, packet + 5); 202
117 203
118 return 0; 204 return 0;
119} 205}
@@ -125,7 +211,7 @@ int handle_pingres(char * packet, uint32_t length, IP_Port source)
125 return 1; 211 return 1;
126 } 212 }
127 213
128 214 addto_lists(source, packet + 5);
129} 215}
130 216
131int handle_getnodes(char * packet, uint32_t length, IP_Port source) 217int handle_getnodes(char * packet, uint32_t length, IP_Port source)
@@ -136,7 +222,7 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source)
136 } 222 }
137 223
138 224
139 addto_lists(source, packet + 5); 225
140 226
141 return 0; 227 return 0;
142} 228}
@@ -147,7 +233,7 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)
147 { 233 {
148 return 1; 234 return 1;
149 } 235 }
150 236 addto_lists(source, packet + 5);
151 237
152} 238}
153 239
@@ -212,8 +298,23 @@ void DHT_recvpacket(char * packet, uint32_t length, IP_Port source)
212 298
213} 299}
214 300
301//Ping each client in the "friends" list every 60 seconds.
302//Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list.
303void doFriends()
304{
305
306
307
308}
215 309
216 310
311void doClose()
312{
313
314
315
316}
317
217 318
218 319
219void doDHT() 320void doDHT()