diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 151 |
1 files changed, 100 insertions, 51 deletions
@@ -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 |
121 | int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ | 121 | */ |
122 | int 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 | */ | ||
138 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) | 146 | int 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 | */ | ||
164 | int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) | 171 | int 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 | */ |
175 | static int friend_number(uint8_t * client_id) | 183 | static 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 | */ | ||
187 | int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) | 198 | int 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 | ||