summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c151
1 files changed, 100 insertions, 51 deletions
diff --git a/core/DHT.c b/core/DHT.c
index c77deaad..3c17a36f 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -115,30 +115,37 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
115/*----------------------------------------------------------------------------------*/ 115/*----------------------------------------------------------------------------------*/
116 116
117/* Compares client_id1 and client_id2 with client_id 117/* Compares client_id1 and client_id2 with client_id
118 return 0 if both are same distance 118 * return 0 if both are same distance
119 return 1 if client_id1 is closer 119 * return 1 if client_id1 is closer
120 return 2 if client_id2 is closer */ 120 * return 2 if client_id2 is closer
121int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ 121 */
122int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2)
122{ 123{
123 uint32_t i; 124 uint32_t i;
125 uint8_t tmp1, tmp2;
126
124 for(i = 0; i < CLIENT_ID_SIZE; ++i) { 127 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
125 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) 128 tmp1 = abs(client_id[i] ^ client_id1[i]);
129 tmp2 = abs(client_id[i] ^ client_id2[i]);
130
131 if(tmp1 < tmp2)
126 return 1; 132 return 1;
127 else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) 133 else if(tmp1 > tmp2)
128 return 2; 134 return 2;
129 } 135 }
130 return 0; 136 return 0;
131} 137}
132 138
133/* check if client with client_id is already in list of length length. 139/* check if client with client_id is already in list of length length.
134 if it is set it's corresponding timestamp to current time. 140 * if it is then set its corresponding timestamp to current time.
135 if the id is already in the list with a different ip_port, update it. 141 * if the id is already in the list with a different ip_port, update it.
136 return True(1) or False(0) 142 * return True(1) or False(0)
137 TODO: maybe optimize this. */ 143 *
144 * TODO: maybe optimize this.
145 */
138int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) 146int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)
139{ 147{
140 uint32_t i; 148 uint32_t i, temp_time = unix_time();
141 uint32_t temp_time = unix_time();
142 149
143 for(i = 0; i < length; ++i) { 150 for(i = 0; i < length; ++i) {
144 /*If ip_port is assigned to a different client_id replace it*/ 151 /*If ip_port is assigned to a different client_id replace it*/
@@ -156,71 +163,113 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
156 } 163 }
157 } 164 }
158 return 0; 165 return 0;
159
160} 166}
161 167
162/* check if client with client_id is already in node format list of length length. 168/* check if client with client_id is already in node format list of length length.
163 return True(1) or False(0) */ 169 * return True(1) or False(0)
170 */
164int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 171int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
165{ 172{
166 uint32_t i; 173 uint32_t i;
167 for(i = 0; i < length; ++i) 174 for(i = 0; i < length; ++i) {
168 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 175 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
169 return 1; 176 return 1;
177 }
170 return 0; 178 return 0;
171} 179}
172 180
173/*Return the friend number from the client_id 181/* Returns the friend number from the client_id, or -1 if a failure occurs
174 Return -1 if failure, number of friend if success*/ 182 */
175static int friend_number(uint8_t * client_id) 183static int friend_number(uint8_t * client_id)
176{ 184{
177 uint32_t i; 185 uint32_t i;
178 for(i = 0; i < num_friends; ++i) 186 for(i = 0; i < num_friends; ++i) {
179 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 187 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
180 return i; 188 return i;
189 }
181 return -1; 190 return -1;
182} 191}
183 192
184/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 193/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
185 put them in the nodes_list and return how many were found. 194 * put them in the nodes_list and return how many were found.
186 TODO: Make this function much more efficient. */ 195 *
196 * TODO: For the love of based Allah make this function cleaner and much more efficient.
197 */
187int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 198int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
188{ 199{
189 uint32_t i, j, k; 200 uint32_t i, j, k, temp_time = unix_time();
190 int num_nodes=0; 201 int num_nodes = 0, closest, tout, inlist;
191 uint32_t temp_time = unix_time(); 202
192 for(i = 0; i < LCLIENT_LIST; ++i) 203 for (i = 0; i < LCLIENT_LIST; ++i) {
193 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 204 tout = close_clientlist[i].timestamp <= temp_time - BAD_NODE_TIMEOUT;
194 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { 205 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
195 /* if node is good and not already in list. */ 206
207 /* if node isn't good or is already in list. */
208 if(tout || inlist)
209 continue;
210
211 if(num_nodes < MAX_SENT_NODES) {
212
213 memcpy( nodes_list[num_nodes].client_id,
214 close_clientlist[i].client_id,
215 CLIENT_ID_SIZE );
216
217 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
218 num_nodes++;
219 } else {
220 for(j = 0; j < MAX_SENT_NODES; ++j) {
221 closest = id_closest( client_id,
222 nodes_list[j].client_id,
223 close_clientlist[i].client_id );
224 if(closest == 2) {
225 memcpy( nodes_list[j].client_id,
226 close_clientlist[i].client_id,
227 CLIENT_ID_SIZE);
228
229 nodes_list[j].ip_port = close_clientlist[i].ip_port;
230 break;
231 }
232 }
233 }
234 }
235
236 for(i = 0; i < num_friends; ++i) {
237 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
238 tout = friends_list[i].client_list[j].timestamp <= temp_time - BAD_NODE_TIMEOUT;
239 inlist = client_in_nodelist( nodes_list,
240 MAX_SENT_NODES,
241 friends_list[i].client_list[j].client_id);
242
243 /* if node isn't good or is already in list. */
244 if(tout || inlist)
245 continue;
246
196 if(num_nodes < MAX_SENT_NODES) { 247 if(num_nodes < MAX_SENT_NODES) {
197 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 248
198 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 249 memcpy( nodes_list[num_nodes].client_id,
250 friends_list[i].client_list[j].client_id,
251 CLIENT_ID_SIZE);
252
253 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
199 num_nodes++; 254 num_nodes++;
200 } else for(j = 0; j < MAX_SENT_NODES; ++j) 255 } else {
201 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { 256 for(k = 0; k < MAX_SENT_NODES; ++k) {
202 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 257
203 nodes_list[j].ip_port = close_clientlist[i].ip_port; 258 closest = id_closest( client_id,
259 nodes_list[k].client_id,
260 friends_list[i].client_list[j].client_id );
261 if(closest == 2) {
262 memcpy( nodes_list[k].client_id,
263 friends_list[i].client_list[j].client_id,
264 CLIENT_ID_SIZE );
265
266 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
204 break; 267 break;
205 } 268 }
206 } 269 }
207
208 for(i = 0; i < num_friends; ++i)
209 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
210 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
211 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
212 /* if node is good and not already in list. */
213 if(num_nodes < MAX_SENT_NODES) {
214 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
215 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
216 num_nodes++;
217 } else for(k = 0; k < MAX_SENT_NODES; ++k)
218 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
219 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
220 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
221 break;
222 }
223 } 270 }
271 }
272 }
224 return num_nodes; 273 return num_nodes;
225} 274}
226 275