diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 113 | ||||
-rw-r--r-- | core/DHT.h | 2 |
2 files changed, 108 insertions, 7 deletions
@@ -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. |
16 | int id_distance(char * client_id, char * client_id1, char * client_id2) | 16 | int 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) | ||
37 | int 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) | ||
64 | int 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 | ||
81 | int 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 |
37 | int addto_lists(IP_Port ip_port, char * client_id) | 98 | int 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 | ||
131 | int handle_getnodes(char * packet, uint32_t length, IP_Port source) | 217 | int 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. | ||
303 | void doFriends() | ||
304 | { | ||
305 | |||
306 | |||
307 | |||
308 | } | ||
215 | 309 | ||
216 | 310 | ||
311 | void doClose() | ||
312 | { | ||
313 | |||
314 | |||
315 | |||
316 | } | ||
317 | |||
217 | 318 | ||
218 | 319 | ||
219 | void doDHT() | 320 | void doDHT() |
@@ -92,7 +92,7 @@ char delfriend(char * client_id); | |||
92 | //ip must be 4 bytes long. | 92 | //ip must be 4 bytes long. |
93 | //port must be 2 bytes long. | 93 | //port must be 2 bytes long. |
94 | //returns ip if success | 94 | //returns ip if success |
95 | //returns ip of 0 if failure (This means the friend is either offline of we have not found him yet.) | 95 | //returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) |
96 | IP_Port getfriendip(char * client_id); | 96 | IP_Port getfriendip(char * client_id); |
97 | 97 | ||
98 | 98 | ||