diff options
Diffstat (limited to 'core/DHT.c')
-rw-r--r-- | core/DHT.c | 551 |
1 files changed, 239 insertions, 312 deletions
@@ -23,7 +23,8 @@ | |||
23 | 23 | ||
24 | #include "DHT.h" | 24 | #include "DHT.h" |
25 | 25 | ||
26 | typedef struct { | 26 | typedef struct |
27 | { | ||
27 | uint8_t client_id[CLIENT_ID_SIZE]; | 28 | uint8_t client_id[CLIENT_ID_SIZE]; |
28 | IP_Port ip_port; | 29 | IP_Port ip_port; |
29 | uint32_t timestamp; | 30 | uint32_t timestamp; |
@@ -31,12 +32,13 @@ typedef struct { | |||
31 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend | 32 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend |
32 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ | 33 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ |
33 | uint32_t ret_timestamp; | 34 | uint32_t ret_timestamp; |
34 | } Client_data; | 35 | }Client_data; |
35 | 36 | ||
36 | /* maximum number of clients stored per friend. */ | 37 | /* maximum number of clients stored per friend. */ |
37 | #define MAX_FRIEND_CLIENTS 8 | 38 | #define MAX_FRIEND_CLIENTS 8 |
38 | 39 | ||
39 | typedef struct { | 40 | typedef struct |
41 | { | ||
40 | uint8_t client_id[CLIENT_ID_SIZE]; | 42 | uint8_t client_id[CLIENT_ID_SIZE]; |
41 | Client_data client_list[MAX_FRIEND_CLIENTS]; | 43 | Client_data client_list[MAX_FRIEND_CLIENTS]; |
42 | uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ | 44 | uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ |
@@ -47,19 +49,21 @@ typedef struct { | |||
47 | uint32_t punching_timestamp; | 49 | uint32_t punching_timestamp; |
48 | uint64_t NATping_id; | 50 | uint64_t NATping_id; |
49 | uint32_t NATping_timestamp; | 51 | uint32_t NATping_timestamp; |
50 | } Friend; | 52 | }Friend; |
51 | 53 | ||
52 | typedef struct { | 54 | typedef struct |
55 | { | ||
53 | uint8_t client_id[CLIENT_ID_SIZE]; | 56 | uint8_t client_id[CLIENT_ID_SIZE]; |
54 | IP_Port ip_port; | 57 | IP_Port ip_port; |
55 | } Node_format; | 58 | }Node_format; |
56 | 59 | ||
57 | typedef struct { | 60 | typedef struct |
61 | { | ||
58 | IP_Port ip_port; | 62 | IP_Port ip_port; |
59 | uint64_t ping_id; | 63 | uint64_t ping_id; |
60 | uint32_t timestamp; | 64 | uint32_t timestamp; |
61 | 65 | ||
62 | } Pinged; | 66 | }Pinged; |
63 | 67 | ||
64 | /* Our client id/public key */ | 68 | /* Our client id/public key */ |
65 | uint8_t self_public_key[CLIENT_ID_SIZE]; | 69 | uint8_t self_public_key[CLIENT_ID_SIZE]; |
@@ -70,7 +74,7 @@ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |||
70 | #define LCLIENT_LIST 32 | 74 | #define LCLIENT_LIST 32 |
71 | static Client_data close_clientlist[LCLIENT_LIST]; | 75 | static Client_data close_clientlist[LCLIENT_LIST]; |
72 | 76 | ||
73 | static Friend *friends_list; | 77 | static Friend * friends_list; |
74 | static uint16_t num_friends; | 78 | static uint16_t num_friends; |
75 | 79 | ||
76 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | 80 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ |
@@ -86,10 +90,10 @@ static Pinged send_nodes[LSEND_NODES_ARRAY]; | |||
86 | return 0 if both are same distance | 90 | return 0 if both are same distance |
87 | return 1 if client_id1 is closer | 91 | return 1 if client_id1 is closer |
88 | return 2 if client_id2 is closer */ | 92 | return 2 if client_id2 is closer */ |
89 | int id_closest(uint8_t *client_id, uint8_t *client_id1, uint8_t *client_id2) /* tested */ | 93 | int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ |
90 | { | 94 | { |
91 | uint32_t i; | 95 | uint32_t i; |
92 | for (i = 0; i < CLIENT_ID_SIZE; ++i) { | 96 | for(i = 0; i < CLIENT_ID_SIZE; ++i) { |
93 | if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) | 97 | if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) |
94 | return 1; | 98 | return 1; |
95 | else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) | 99 | else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) |
@@ -103,19 +107,18 @@ int id_closest(uint8_t *client_id, uint8_t *client_id1, uint8_t *client_id2) /* | |||
103 | if the id is already in the list with a different ip_port, update it. | 107 | if the id is already in the list with a different ip_port, update it. |
104 | return True(1) or False(0) | 108 | return True(1) or False(0) |
105 | TODO: maybe optimize this. */ | 109 | TODO: maybe optimize this. */ |
106 | int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port) | 110 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) |
107 | { | 111 | { |
108 | uint32_t i; | 112 | uint32_t i; |
109 | uint32_t temp_time = unix_time(); | 113 | uint32_t temp_time = unix_time(); |
110 | 114 | ||
111 | for (i = 0; i < length; ++i) { | 115 | for(i = 0; i < length; ++i) { |
112 | /*If ip_port is assigned to a different client_id replace it*/ | 116 | /*If ip_port is assigned to a different client_id replace it*/ |
113 | if(list[i].ip_port.ip.i == ip_port.ip.i && | 117 | if(list[i].ip_port.ip.i == ip_port.ip.i && |
114 | list[i].ip_port.port == ip_port.port) | 118 | list[i].ip_port.port == ip_port.port) { |
115 | { | ||
116 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 119 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
117 | } | 120 | } |
118 | 121 | ||
119 | if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 122 | if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
120 | /* Refresh the client timestamp. */ | 123 | /* Refresh the client timestamp. */ |
121 | list[i].timestamp = temp_time; | 124 | list[i].timestamp = temp_time; |
@@ -125,31 +128,28 @@ int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Po | |||
125 | } | 128 | } |
126 | } | 129 | } |
127 | return 0; | 130 | return 0; |
128 | 131 | ||
129 | } | 132 | } |
130 | 133 | ||
131 | /* check if client with client_id is already in node format list of length length. | 134 | /* check if client with client_id is already in node format list of length length. |
132 | return True(1) or False(0) */ | 135 | return True(1) or False(0) */ |
133 | int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) | 136 | int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) |
134 | { | 137 | { |
135 | uint32_t i; | 138 | uint32_t i; |
136 | for (i = 0; i < length; ++i) { | 139 | for(i = 0; i < length; ++i) |
137 | if (memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) | 140 | if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) |
138 | return 1; | 141 | return 1; |
139 | } | ||
140 | return 0; | 142 | return 0; |
141 | |||
142 | } | 143 | } |
143 | 144 | ||
144 | /*Return the friend number from the client_id | 145 | /*Return the friend number from the client_id |
145 | Return -1 if failure, number of friend if success*/ | 146 | Return -1 if failure, number of friend if success*/ |
146 | static int friend_number(uint8_t *client_id) | 147 | static int friend_number(uint8_t * client_id) |
147 | { | 148 | { |
148 | uint32_t i; | 149 | uint32_t i; |
149 | for (i = 0; i < num_friends; ++i) { | 150 | for(i = 0; i < num_friends; ++i) |
150 | if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ | 151 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ |
151 | return i; | 152 | return i; |
152 | } | ||
153 | return -1; | 153 | return -1; |
154 | } | 154 | } |
155 | 155 | ||
@@ -161,62 +161,56 @@ static int friend_number(uint8_t *client_id) | |||
161 | /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: | 161 | /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: |
162 | put them in the nodes_list and return how many were found. | 162 | put them in the nodes_list and return how many were found. |
163 | TODO: Make this function much more efficient. */ | 163 | TODO: Make this function much more efficient. */ |
164 | int get_close_nodes(uint8_t *client_id, Node_format * nodes_list) | 164 | int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) |
165 | { | 165 | { |
166 | uint32_t i, j, k; | 166 | uint32_t i, j, k; |
167 | int num_nodes=0; | 167 | int num_nodes=0; |
168 | uint32_t temp_time = unix_time(); | 168 | uint32_t temp_time = unix_time(); |
169 | for (i = 0; i < LCLIENT_LIST; ++i) { | 169 | for(i = 0; i < LCLIENT_LIST; ++i) |
170 | if (close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && | 170 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && |
171 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) | 171 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { |
172 | { | ||
173 | /* if node is good and not already in list. */ | 172 | /* if node is good and not already in list. */ |
174 | if(num_nodes < MAX_SENT_NODES) { | 173 | if(num_nodes < MAX_SENT_NODES) { |
175 | memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | 174 | memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); |
176 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | 175 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; |
177 | num_nodes++; | 176 | num_nodes++; |
178 | } | 177 | } |
179 | else for(j = 0; j < MAX_SENT_NODES; ++j) { | 178 | else for(j = 0; j < MAX_SENT_NODES; ++j) |
180 | if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { | 179 | if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { |
181 | memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | 180 | memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); |
182 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | 181 | nodes_list[j].ip_port = close_clientlist[i].ip_port; |
183 | break; | 182 | break; |
184 | } | 183 | } |
185 | } | 184 | } |
186 | } | 185 | |
187 | } | 186 | for(i = 0; i < num_friends; ++i) |
188 | for (i = 0; i < num_friends; ++i) { | 187 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
189 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 188 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && |
190 | if (friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && | ||
191 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) { | 189 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) { |
192 | /* if node is good and not already in list. */ | 190 | /* if node is good and not already in list. */ |
193 | if (num_nodes < MAX_SENT_NODES) { | 191 | if(num_nodes < MAX_SENT_NODES) { |
194 | memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | 192 | memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); |
195 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | 193 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; |
196 | num_nodes++; | 194 | num_nodes++; |
197 | } else for(k = 0; k < MAX_SENT_NODES; ++k) { | 195 | } else for(k = 0; k < MAX_SENT_NODES; ++k) |
198 | if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) { | 196 | if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) { |
199 | memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | 197 | memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); |
200 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; | 198 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; |
201 | break; | 199 | break; |
202 | } | 200 | } |
203 | } | ||
204 | } | 201 | } |
205 | } | ||
206 | } | ||
207 | |||
208 | return num_nodes; | 202 | return num_nodes; |
209 | } | 203 | } |
210 | 204 | ||
211 | /* replace first bad (or empty) node with this one | 205 | /* replace first bad (or empty) node with this one |
212 | return 0 if successful | 206 | return 0 if successful |
213 | return 1 if not (list contains no bad nodes) */ | 207 | return 1 if not (list contains no bad nodes) */ |
214 | int replace_bad(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port) /* tested */ | 208 | int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ |
215 | { | 209 | { |
216 | uint32_t i; | 210 | uint32_t i; |
217 | uint32_t temp_time = unix_time(); | 211 | uint32_t temp_time = unix_time(); |
218 | for (i = 0; i < length; ++i) { | 212 | for(i = 0; i < length; ++i) |
219 | if (list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ { | 213 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ { |
220 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 214 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
221 | list[i].ip_port = ip_port; | 215 | list[i].ip_port = ip_port; |
222 | list[i].timestamp = temp_time; | 216 | list[i].timestamp = temp_time; |
@@ -225,19 +219,18 @@ int replace_bad(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port | |||
225 | list[i].ret_timestamp = 0; | 219 | list[i].ret_timestamp = 0; |
226 | return 0; | 220 | return 0; |
227 | } | 221 | } |
228 | } | 222 | |
229 | return 1; | 223 | return 1; |
230 | |||
231 | } | 224 | } |
232 | 225 | ||
233 | /* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ | 226 | /* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ |
234 | int replace_good(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port, uint8_t *comp_client_id) | 227 | int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) |
235 | { | 228 | { |
236 | uint32_t i; | 229 | uint32_t i; |
237 | uint32_t temp_time = unix_time(); | 230 | uint32_t temp_time = unix_time(); |
238 | 231 | ||
239 | for (i = 0; i < length; ++i) { | 232 | for(i = 0; i < length; ++i) |
240 | if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) { | 233 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { |
241 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 234 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
242 | list[i].ip_port = ip_port; | 235 | list[i].ip_port = ip_port; |
243 | list[i].timestamp = temp_time; | 236 | list[i].timestamp = temp_time; |
@@ -246,59 +239,50 @@ int replace_good(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port | |||
246 | list[i].ret_timestamp = 0; | 239 | list[i].ret_timestamp = 0; |
247 | return 0; | 240 | return 0; |
248 | } | 241 | } |
249 | } | 242 | |
250 | return 1; | 243 | return 1; |
251 | |||
252 | } | 244 | } |
253 | 245 | ||
254 | /* Attempt to add client with ip_port and client_id to the friends client list and close_clientlist */ | 246 | /* Attempt to add client with ip_port and client_id to the friends client list and close_clientlist */ |
255 | void addto_lists(IP_Port ip_port, uint8_t *client_id) | 247 | void addto_lists(IP_Port ip_port, uint8_t * client_id) |
256 | { | 248 | { |
257 | uint32_t i; | 249 | uint32_t i; |
258 | 250 | ||
259 | /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ | 251 | /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ |
260 | if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 252 | if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
261 | if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 253 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
262 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); /* if we can't replace bad nodes we try replacing good ones */ | 254 | /* if we can't replace bad nodes we try replacing good ones */ |
263 | } | 255 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); |
264 | for(i = 0; i < num_friends; ++i) { | 256 | |
265 | if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) { | 257 | for(i = 0; i < num_friends; ++i) |
266 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) { | 258 | if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
259 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) | ||
267 | /* if we can't replace bad nodes we try replacing good ones. */ | 260 | /* if we can't replace bad nodes we try replacing good ones. */ |
268 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); | 261 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); |
269 | } | ||
270 | } | ||
271 | } | ||
272 | } | 262 | } |
273 | 263 | ||
274 | /* If client_id is a friend or us, update ret_ip_port | 264 | /* If client_id is a friend or us, update ret_ip_port |
275 | nodeclient_id is the id of the node that sent us this info */ | 265 | nodeclient_id is the id of the node that sent us this info */ |
276 | void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 266 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) |
277 | { | 267 | { |
278 | uint32_t i, j; | 268 | uint32_t i, j; |
279 | uint32_t temp_time = unix_time(); | 269 | uint32_t temp_time = unix_time(); |
280 | if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { | 270 | if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { |
281 | for (i = 0; i < LCLIENT_LIST; ++i) { | 271 | for(i = 0; i < LCLIENT_LIST; ++i) |
282 | if (memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { | 272 | if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { |
283 | close_clientlist[i].ret_ip_port = ip_port; | 273 | close_clientlist[i].ret_ip_port = ip_port; |
284 | close_clientlist[i].ret_timestamp = temp_time; | 274 | close_clientlist[i].ret_timestamp = temp_time; |
285 | return; | 275 | return; |
286 | } | 276 | } |
287 | } | 277 | } else |
288 | } | 278 | for(i = 0; i < num_friends; ++i) |
289 | else { | 279 | if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) |
290 | for (i = 0; i < num_friends; ++i) { | 280 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
291 | if (memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) { | 281 | if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { |
292 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 282 | friends_list[i].client_list[j].ret_ip_port = ip_port; |
293 | if (memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { | 283 | friends_list[i].client_list[j].ret_timestamp = temp_time; |
294 | friends_list[i].client_list[j].ret_ip_port = ip_port; | 284 | return; |
295 | friends_list[i].client_list[j].ret_timestamp = temp_time; | 285 | } |
296 | return; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | } | 286 | } |
303 | 287 | ||
304 | /* ping timeout in seconds */ | 288 | /* ping timeout in seconds */ |
@@ -315,28 +299,21 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id) | |||
315 | uint8_t pinging; | 299 | uint8_t pinging; |
316 | uint32_t temp_time = unix_time(); | 300 | uint32_t temp_time = unix_time(); |
317 | 301 | ||
318 | for (i = 0; i < LPING_ARRAY; ++i ) { | 302 | for(i = 0; i < LPING_ARRAY; ++i ) |
319 | if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) { | 303 | if((pings[i].timestamp + PING_TIMEOUT) > temp_time) { |
320 | pinging = 0; | 304 | pinging = 0; |
321 | if (ip_port.ip.i != 0) { | 305 | if(ip_port.ip.i != 0) |
322 | if(pings[i].ip_port.ip.i == ip_port.ip.i && | 306 | if(pings[i].ip_port.ip.i == ip_port.ip.i && |
323 | pings[i].ip_port.port == ip_port.port) | 307 | pings[i].ip_port.port == ip_port.port) |
324 | { | ||
325 | ++pinging; | 308 | ++pinging; |
326 | } | 309 | if(ping_id != 0) |
327 | } | ||
328 | if (ping_id != 0) { | ||
329 | if(pings[i].ping_id == ping_id) | 310 | if(pings[i].ping_id == ping_id) |
330 | ++pinging; | 311 | ++pinging; |
331 | |||
332 | } | ||
333 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 312 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
334 | return 1; | 313 | return 1; |
335 | } | 314 | } |
336 | } | ||
337 | 315 | ||
338 | return 0; | 316 | return 0; |
339 | |||
340 | } | 317 | } |
341 | 318 | ||
342 | /* Same as last function but for get_node requests. */ | 319 | /* Same as last function but for get_node requests. */ |
@@ -346,26 +323,22 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
346 | uint8_t pinging; | 323 | uint8_t pinging; |
347 | uint32_t temp_time = unix_time(); | 324 | uint32_t temp_time = unix_time(); |
348 | 325 | ||
349 | for(i = 0; i < LSEND_NODES_ARRAY; ++i) { | 326 | for(i = 0; i < LSEND_NODES_ARRAY; ++i ) |
350 | if ((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { | 327 | if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { |
351 | pinging = 0; | 328 | pinging = 0; |
352 | if (ip_port.ip.i != 0) { | 329 | if(ip_port.ip.i != 0) |
353 | if (send_nodes[i].ip_port.ip.i == ip_port.ip.i && | 330 | if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && |
354 | send_nodes[i].ip_port.port == ip_port.port) { | 331 | send_nodes[i].ip_port.port == ip_port.port) |
355 | ++pinging; | 332 | ++pinging; |
356 | } | 333 | if(ping_id != 0) |
357 | } | 334 | if(send_nodes[i].ping_id == ping_id) |
358 | if (ping_id != 0) { | 335 | ++pinging; |
359 | if (send_nodes[i].ping_id == ping_id) | ||
360 | ++pinging; | ||
361 | } | ||
362 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 336 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
363 | return 1; | 337 | return 1; |
338 | |||
364 | } | 339 | } |
365 | } | ||
366 | 340 | ||
367 | return 0; | 341 | return 0; |
368 | |||
369 | } | 342 | } |
370 | 343 | ||
371 | /* Add a new ping request to the list of ping requests | 344 | /* Add a new ping request to the list of ping requests |
@@ -377,19 +350,17 @@ uint64_t add_pinging(IP_Port ip_port) | |||
377 | uint32_t i, j; | 350 | uint32_t i, j; |
378 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 351 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
379 | uint32_t temp_time = unix_time(); | 352 | uint32_t temp_time = unix_time(); |
380 | 353 | ||
381 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 354 | for(i = 0; i < PING_TIMEOUT; ++i ) |
382 | for (j = 0; j < LPING_ARRAY; ++j ) { | 355 | for(j = 0; j < LPING_ARRAY; ++j ) |
383 | if ((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { | 356 | if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { |
384 | pings[j].timestamp = temp_time; | 357 | pings[j].timestamp = temp_time; |
385 | pings[j].ip_port = ip_port; | 358 | pings[j].ip_port = ip_port; |
386 | pings[j].ping_id = ping_id; | 359 | pings[j].ping_id = ping_id; |
387 | return ping_id; | 360 | return ping_id; |
388 | } | 361 | } |
389 | } | 362 | |
390 | } | ||
391 | return 0; | 363 | return 0; |
392 | |||
393 | } | 364 | } |
394 | 365 | ||
395 | /* Same but for get node requests */ | 366 | /* Same but for get node requests */ |
@@ -398,40 +369,38 @@ uint64_t add_gettingnodes(IP_Port ip_port) | |||
398 | uint32_t i, j; | 369 | uint32_t i, j; |
399 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 370 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
400 | uint32_t temp_time = unix_time(); | 371 | uint32_t temp_time = unix_time(); |
401 | 372 | ||
402 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 373 | for(i = 0; i < PING_TIMEOUT; ++i ) |
403 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { | 374 | for(j = 0; j < LSEND_NODES_ARRAY; ++j ) |
404 | if ((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { | 375 | if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { |
405 | send_nodes[j].timestamp = temp_time; | 376 | send_nodes[j].timestamp = temp_time; |
406 | send_nodes[j].ip_port = ip_port; | 377 | send_nodes[j].ip_port = ip_port; |
407 | send_nodes[j].ping_id = ping_id; | 378 | send_nodes[j].ping_id = ping_id; |
408 | return ping_id; | 379 | return ping_id; |
409 | } | 380 | } |
410 | } | 381 | |
411 | } | ||
412 | return 0; | 382 | return 0; |
413 | |||
414 | } | 383 | } |
415 | 384 | ||
416 | /* send a ping request | 385 | /* send a ping request |
417 | Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ | 386 | Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ |
418 | static int pingreq(IP_Port ip_port, uint8_t *public_key) | 387 | static int pingreq(IP_Port ip_port, uint8_t * public_key) |
419 | { | 388 | { |
420 | if (memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ | 389 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ |
421 | return 1; | 390 | return 1; |
422 | 391 | ||
423 | if (is_pinging(ip_port, 0)) | 392 | if(is_pinging(ip_port, 0)) |
424 | return 1; | 393 | return 1; |
425 | 394 | ||
426 | uint64_t ping_id = add_pinging(ip_port); | 395 | uint64_t ping_id = add_pinging(ip_port); |
427 | if (ping_id == 0) | 396 | if(ping_id == 0) |
428 | return 1; | 397 | return 1; |
429 | 398 | ||
430 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; | 399 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
431 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | 400 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; |
432 | uint8_t nonce[crypto_box_NONCEBYTES]; | 401 | uint8_t nonce[crypto_box_NONCEBYTES]; |
433 | random_nonce(nonce); | 402 | random_nonce(nonce); |
434 | 403 | ||
435 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | 404 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); |
436 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | 405 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) |
437 | return -1; | 406 | return -1; |
@@ -439,25 +408,24 @@ static int pingreq(IP_Port ip_port, uint8_t *public_key) | |||
439 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 408 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
440 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 409 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
441 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 410 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
442 | 411 | ||
443 | return sendpacket(ip_port, data, sizeof(data)); | 412 | return sendpacket(ip_port, data, sizeof(data)); |
444 | |||
445 | } | 413 | } |
446 | 414 | ||
447 | /* send a ping response */ | 415 | /* send a ping response */ |
448 | static int pingres(IP_Port ip_port, uint8_t *public_key, uint64_t ping_id) | 416 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) |
449 | { | 417 | { |
450 | /* check if packet is gonna be sent to ourself */ | 418 | /* check if packet is gonna be sent to ourself */ |
451 | if (memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) | 419 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) |
452 | return 1; | 420 | return 1; |
453 | 421 | ||
454 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; | 422 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
455 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | 423 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; |
456 | uint8_t nonce[crypto_box_NONCEBYTES]; | 424 | uint8_t nonce[crypto_box_NONCEBYTES]; |
457 | random_nonce(nonce); | 425 | random_nonce(nonce); |
458 | 426 | ||
459 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | 427 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); |
460 | if (len != sizeof(ping_id) + ENCRYPTION_PADDING) | 428 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) |
461 | return -1; | 429 | return -1; |
462 | data[0] = 1; | 430 | data[0] = 1; |
463 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 431 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
@@ -465,21 +433,21 @@ static int pingres(IP_Port ip_port, uint8_t *public_key, uint64_t ping_id) | |||
465 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 433 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
466 | 434 | ||
467 | return sendpacket(ip_port, data, sizeof(data)); | 435 | return sendpacket(ip_port, data, sizeof(data)); |
468 | |||
469 | } | 436 | } |
470 | 437 | ||
471 | /* send a getnodes request */ | 438 | /* send a getnodes request */ |
472 | static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 439 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) |
473 | { | 440 | { |
474 | /* check if packet is gonna be sent to ourself */ | 441 | /* check if packet is gonna be sent to ourself */ |
475 | if (memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) | 442 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) |
476 | return 1; | 443 | return 1; |
477 | if (is_gettingnodes(ip_port, 0)) | 444 | |
445 | if(is_gettingnodes(ip_port, 0)) | ||
478 | return 1; | 446 | return 1; |
479 | 447 | ||
480 | uint64_t ping_id = add_gettingnodes(ip_port); | 448 | uint64_t ping_id = add_gettingnodes(ip_port); |
481 | 449 | ||
482 | if (ping_id == 0) | 450 | if(ping_id == 0) |
483 | return 1; | 451 | return 1; |
484 | 452 | ||
485 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; | 453 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; |
@@ -493,31 +461,30 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
493 | 461 | ||
494 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); | 462 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); |
495 | 463 | ||
496 | if (len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | 464 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) |
497 | return -1; | 465 | return -1; |
498 | data[0] = 2; | 466 | data[0] = 2; |
499 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 467 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
500 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 468 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
501 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 469 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
502 | return sendpacket(ip_port, data, sizeof(data)); | 470 | return sendpacket(ip_port, data, sizeof(data)); |
503 | |||
504 | } | 471 | } |
505 | 472 | ||
506 | /* send a send nodes response */ | 473 | /* send a send nodes response */ |
507 | static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | 474 | static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) |
508 | { | 475 | { |
509 | if (memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ | 476 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ |
510 | return 1; | 477 | return 1; |
511 | 478 | ||
512 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 479 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
513 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 480 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
514 | 481 | ||
515 | Node_format nodes_list[MAX_SENT_NODES]; | 482 | Node_format nodes_list[MAX_SENT_NODES]; |
516 | int num_nodes = get_close_nodes(client_id, nodes_list); | 483 | int num_nodes = get_close_nodes(client_id, nodes_list); |
517 | 484 | ||
518 | if (num_nodes == 0) | 485 | if(num_nodes == 0) |
519 | return 0; | 486 | return 0; |
520 | 487 | ||
521 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | 488 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; |
522 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 489 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
523 | uint8_t nonce[crypto_box_NONCEBYTES]; | 490 | uint8_t nonce[crypto_box_NONCEBYTES]; |
@@ -529,58 +496,57 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
529 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, | 496 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, |
530 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); | 497 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); |
531 | 498 | ||
532 | if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) | 499 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) |
533 | return -1; | 500 | return -1; |
534 | 501 | ||
535 | data[0] = 3; | 502 | data[0] = 3; |
536 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 503 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
537 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 504 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
538 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 505 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
539 | 506 | ||
540 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 507 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
541 | |||
542 | } | 508 | } |
543 | 509 | ||
544 | /* Packet handling functions | 510 | /* Packet handling functions |
545 | One to handle each types of packets we receive | 511 | One to handle each types of packets we receive |
546 | return 0 if handled correctly, 1 if packet is bad. */ | 512 | return 0 if handled correctly, 1 if packet is bad. */ |
547 | int handle_pingreq(uint8_t *packet, uint32_t length, IP_Port source) | 513 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) |
548 | { | 514 | { |
549 | uint64_t ping_id; | 515 | uint64_t ping_id; |
550 | if (length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | 516 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) |
551 | return 1; | 517 | return 1; |
552 | /* check if packet is from ourself. */ | 518 | /* check if packet is from ourself. */ |
553 | if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) | 519 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) |
554 | return 1; | 520 | return 1; |
521 | |||
555 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 522 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
556 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 523 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
557 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | 524 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); |
558 | if (len != sizeof(ping_id)) | 525 | if(len != sizeof(ping_id)) |
559 | return 1; | 526 | return 1; |
560 | 527 | ||
561 | pingres(source, packet + 1, ping_id); | 528 | pingres(source, packet + 1, ping_id); |
562 | 529 | ||
563 | pingreq(source, packet + 1); /* TODO: make this smarter? */ | 530 | pingreq(source, packet + 1); /* TODO: make this smarter? */ |
564 | 531 | ||
565 | return 0; | 532 | return 0; |
566 | |||
567 | } | 533 | } |
568 | 534 | ||
569 | int handle_pingres(uint8_t *packet, uint32_t length, IP_Port source) | 535 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) |
570 | { | 536 | { |
571 | uint64_t ping_id; | 537 | uint64_t ping_id; |
572 | if (length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | 538 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) |
573 | return 1; | 539 | return 1; |
574 | if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ | 540 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ |
575 | return 1; | 541 | return 1; |
576 | 542 | ||
577 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 543 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
578 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 544 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
579 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | 545 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); |
580 | if (len != sizeof(ping_id)) | 546 | if(len != sizeof(ping_id)) |
581 | return 1; | 547 | return 1; |
582 | 548 | ||
583 | if (is_pinging(source, ping_id)) { | 549 | if(is_pinging(source, ping_id)) { |
584 | addto_lists(source, packet + 1); | 550 | addto_lists(source, packet + 1); |
585 | return 0; | 551 | return 0; |
586 | } | 552 | } |
@@ -588,29 +554,29 @@ int handle_pingres(uint8_t *packet, uint32_t length, IP_Port source) | |||
588 | 554 | ||
589 | } | 555 | } |
590 | 556 | ||
591 | int handle_getnodes(uint8_t *packet, uint32_t length, IP_Port source) | 557 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
592 | { | 558 | { |
593 | uint64_t ping_id; | 559 | uint64_t ping_id; |
594 | if (length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | 560 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) |
595 | return 1; | 561 | return 1; |
596 | /* check if packet is from ourself. */ | 562 | /* check if packet is from ourself. */ |
597 | if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) | 563 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) |
598 | return 1; | 564 | return 1; |
599 | 565 | ||
600 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 566 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
601 | 567 | ||
602 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 568 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
603 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 569 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
604 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); | 570 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); |
605 | 571 | ||
606 | if (len != sizeof(ping_id) + CLIENT_ID_SIZE) | 572 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE) |
607 | return 1; | 573 | return 1; |
608 | 574 | ||
609 | memcpy(&ping_id, plain, sizeof(ping_id)); | 575 | memcpy(&ping_id, plain, sizeof(ping_id)); |
610 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | 576 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); |
611 | 577 | ||
612 | pingreq(source, packet + 1); /* TODO: make this smarter? */ | 578 | pingreq(source, packet + 1); /* TODO: make this smarter? */ |
613 | 579 | ||
614 | return 0; | 580 | return 0; |
615 | 581 | ||
616 | } | 582 | } |
@@ -618,55 +584,57 @@ int handle_getnodes(uint8_t *packet, uint32_t length, IP_Port source) | |||
618 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | 584 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) |
619 | { | 585 | { |
620 | uint64_t ping_id; | 586 | uint64_t ping_id; |
621 | if (length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) //TODO: rewrite this monstrosity | 587 | /* TODO: make this more readable */ |
588 | if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
622 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || | 589 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || |
623 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 590 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
624 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || | 591 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || |
625 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 592 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
626 | + sizeof(Node_format) + ENCRYPTION_PADDING) { | 593 | + sizeof(Node_format) + ENCRYPTION_PADDING) { |
627 | return 1; | 594 | return 1; |
628 | } | 595 | } |
629 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 596 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
630 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); | 597 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); |
631 | 598 | ||
632 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | 599 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; |
633 | 600 | ||
634 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 601 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
635 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 602 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
636 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); | 603 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); |
637 | 604 | ||
638 | 605 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) | |
639 | if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) | ||
640 | return 1; | 606 | return 1; |
607 | |||
641 | memcpy(&ping_id, plain, sizeof(ping_id)); | 608 | memcpy(&ping_id, plain, sizeof(ping_id)); |
642 | if(!is_gettingnodes(source, ping_id)) | 609 | if(!is_gettingnodes(source, ping_id)) |
643 | return 1; | 610 | return 1; |
644 | 611 | ||
645 | Node_format nodes_list[MAX_SENT_NODES]; | 612 | Node_format nodes_list[MAX_SENT_NODES]; |
646 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 613 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
647 | 614 | ||
648 | addto_lists(source, packet + 1); | 615 | addto_lists(source, packet + 1); |
649 | 616 | ||
650 | uint32_t i; | 617 | uint32_t i; |
651 | for (i = 0; i < num_nodes; ++i) | 618 | for(i = 0; i < num_nodes; ++i) { |
652 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); | 619 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); |
653 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 620 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
654 | 621 | } | |
622 | |||
655 | return 0; | 623 | return 0; |
656 | } | 624 | } |
657 | 625 | ||
658 | /* END of packet handling functions */ | 626 | /* END of packet handling functions */ |
659 | 627 | ||
660 | int DHT_addfriend(uint8_t *client_id) | 628 | int DHT_addfriend(uint8_t * client_id) |
661 | { | 629 | { |
662 | Friend * temp; | 630 | Friend * temp; |
663 | if (num_friends == 0) | 631 | if(num_friends == 0) |
664 | temp = malloc(sizeof(Friend)); | 632 | temp = malloc(sizeof(Friend)); |
665 | else | 633 | else |
666 | temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); | 634 | temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); |
667 | if (temp == NULL) | 635 | if(temp == NULL) |
668 | return 1; | 636 | return 1; |
669 | 637 | ||
670 | friends_list = temp; | 638 | friends_list = temp; |
671 | memset(&friends_list[num_friends], 0, sizeof(Friend)); | 639 | memset(&friends_list[num_friends], 0, sizeof(Friend)); |
672 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); | 640 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); |
@@ -675,43 +643,41 @@ int DHT_addfriend(uint8_t *client_id) | |||
675 | return 0; | 643 | return 0; |
676 | } | 644 | } |
677 | 645 | ||
678 | int DHT_delfriend(uint8_t *client_id) | 646 | int DHT_delfriend(uint8_t * client_id) |
679 | { | 647 | { |
680 | uint32_t i; | 648 | uint32_t i; |
681 | Friend * temp; | 649 | Friend * temp; |
682 | for (i = 0; i < num_friends; ++i) { | 650 | for(i = 0; i < num_friends; ++i) |
683 | /* Equal */ | 651 | /* Equal */ |
684 | if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0){ | 652 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
685 | --num_friends; | 653 | --num_friends; |
686 | if (num_friends != i) | 654 | if(num_friends != i) |
687 | memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); | 655 | memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); |
688 | temp = realloc(friends_list, sizeof(Friend) * (num_friends)); | 656 | temp = realloc(friends_list, sizeof(Friend) * (num_friends)); |
689 | if (temp != NULL) | 657 | if(temp != NULL) |
690 | friends_list = temp; | 658 | friends_list = temp; |
691 | return 0; | 659 | return 0; |
692 | } | 660 | } |
693 | } | 661 | |
694 | return 1; | 662 | return 1; |
695 | } | 663 | } |
696 | 664 | ||
697 | /* TODO: Optimize this. */ | 665 | /* TODO: Optimize this. */ |
698 | IP_Port DHT_getfriendip(uint8_t *client_id) | 666 | IP_Port DHT_getfriendip(uint8_t * client_id) |
699 | { | 667 | { |
700 | uint32_t i, j; | 668 | uint32_t i, j; |
701 | IP_Port empty = {{{0}}, 0}; | 669 | IP_Port empty = {{{0}}, 0}; |
702 | uint32_t temp_time = unix_time(); | 670 | uint32_t temp_time = unix_time(); |
703 | for (i = 0; i < num_friends; ++i) { | 671 | for(i = 0; i < num_friends; ++i) |
704 | /* Equal */ | 672 | /* Equal */ |
705 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 673 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
706 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 674 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
707 | if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && | 675 | if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && |
708 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { | 676 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) |
709 | return friends_list[i].client_list[j].ip_port; | 677 | return friends_list[i].client_list[j].ip_port; |
710 | } | 678 | |
711 | } | ||
712 | return empty; | 679 | return empty; |
713 | } | 680 | } |
714 | } | ||
715 | empty.ip.i = 1; | 681 | empty.ip.i = 1; |
716 | return empty; | 682 | return empty; |
717 | 683 | ||
@@ -735,21 +701,20 @@ void doDHTFriends() | |||
735 | uint32_t rand_node; | 701 | uint32_t rand_node; |
736 | uint32_t index[MAX_FRIEND_CLIENTS]; | 702 | uint32_t index[MAX_FRIEND_CLIENTS]; |
737 | 703 | ||
738 | for (i = 0; i < num_friends; ++i) { | 704 | for(i = 0; i < num_friends; ++i) { |
739 | uint32_t num_nodes = 0; | 705 | uint32_t num_nodes = 0; |
740 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 706 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
741 | if (friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ { | 707 | if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ { |
742 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 708 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
743 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); | 709 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); |
744 | friends_list[i].client_list[j].last_pinged = temp_time; | 710 | friends_list[i].client_list[j].last_pinged = temp_time; |
745 | } | 711 | } |
746 | if (friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ { | 712 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ { |
747 | index[num_nodes] = j; | 713 | index[num_nodes] = j; |
748 | ++num_nodes; | 714 | ++num_nodes; |
749 | } | 715 | } |
750 | } | 716 | } |
751 | } | 717 | if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
752 | if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | ||
753 | rand_node = rand() % num_nodes; | 718 | rand_node = rand() % num_nodes; |
754 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, | 719 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, |
755 | friends_list[i].client_list[index[rand_node]].client_id, | 720 | friends_list[i].client_list[index[rand_node]].client_id, |
@@ -771,23 +736,21 @@ void doClose() /* tested */ | |||
771 | uint32_t rand_node; | 736 | uint32_t rand_node; |
772 | uint32_t index[LCLIENT_LIST]; | 737 | uint32_t index[LCLIENT_LIST]; |
773 | 738 | ||
774 | for (i = 0; i < LCLIENT_LIST; ++i) { | 739 | for(i = 0; i < LCLIENT_LIST; ++i) |
775 | /* if node is not dead. */ | 740 | /* if node is not dead. */ |
776 | if (close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { | 741 | if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { |
777 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) | 742 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
778 | { | ||
779 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); | 743 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); |
780 | close_clientlist[i].last_pinged = temp_time; | 744 | close_clientlist[i].last_pinged = temp_time; |
781 | } | 745 | } |
782 | /* if node is good. */ | 746 | /* if node is good. */ |
783 | if (close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { | 747 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { |
784 | index[num_nodes] = i; | 748 | index[num_nodes] = i; |
785 | ++num_nodes; | 749 | ++num_nodes; |
786 | } | 750 | } |
787 | } | 751 | } |
788 | } | ||
789 | 752 | ||
790 | if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 753 | if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
791 | rand_node = rand() % num_nodes; | 754 | rand_node = rand() % num_nodes; |
792 | getnodes(close_clientlist[index[rand_node]].ip_port, | 755 | getnodes(close_clientlist[index[rand_node]].ip_port, |
793 | close_clientlist[index[rand_node]].client_id, | 756 | close_clientlist[index[rand_node]].client_id, |
@@ -796,21 +759,19 @@ void doClose() /* tested */ | |||
796 | } | 759 | } |
797 | } | 760 | } |
798 | 761 | ||
799 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key) | 762 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) |
800 | { | 763 | { |
801 | getnodes(ip_port, public_key, self_public_key); | 764 | getnodes(ip_port, public_key, self_public_key); |
802 | } | 765 | } |
803 | 766 | ||
804 | /* send the given packet to node with client_id | 767 | /* send the given packet to node with client_id |
805 | returns -1 if failure */ | 768 | returns -1 if failure */ |
806 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | 769 | int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) |
807 | { | 770 | { |
808 | uint32_t i; | 771 | uint32_t i; |
809 | for (i = 0; i < LCLIENT_LIST; ++i) { | 772 | for(i = 0; i < LCLIENT_LIST; ++i) |
810 | if (memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { | 773 | if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) |
811 | return sendpacket(close_clientlist[i].ip_port, packet, length); | 774 | return sendpacket(close_clientlist[i].ip_port, packet, length); |
812 | } | ||
813 | } | ||
814 | return -1; | 775 | return -1; |
815 | } | 776 | } |
816 | 777 | ||
@@ -819,48 +780,43 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
819 | returns the number of ips returned | 780 | returns the number of ips returned |
820 | return 0 if we are connected to friend or if no ips were found. | 781 | return 0 if we are connected to friend or if no ips were found. |
821 | returns -1 if no such friend*/ | 782 | returns -1 if no such friend*/ |
822 | static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | 783 | static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) |
823 | { | 784 | { |
824 | int num_ips = 0; | 785 | int num_ips = 0; |
825 | uint32_t i; | 786 | uint32_t i; |
826 | uint32_t temp_time = unix_time(); | 787 | uint32_t temp_time = unix_time(); |
827 | if (friend_num >= num_friends) | 788 | if(friend_num >= num_friends) |
828 | return -1; | 789 | return -1; |
829 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 790 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
830 | /*If ip is not zero and node is good */ | 791 | /*If ip is not zero and node is good */ |
831 | if (friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && | 792 | if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && |
832 | friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) | 793 | friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { |
833 | { | 794 | if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) |
834 | if (memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0) | ||
835 | return 0; | 795 | return 0; |
836 | ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; | 796 | ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; |
837 | ++num_ips; | 797 | ++num_ips; |
838 | } | 798 | } |
839 | } | ||
840 | return num_ips; | 799 | return num_ips; |
841 | } | 800 | } |
842 | 801 | ||
843 | /* Send the following packet to everyone who tells us they are connected to friend_id | 802 | /* Send the following packet to everyone who tells us they are connected to friend_id |
844 | returns the number of nodes it sent the packet to */ | 803 | returns the number of nodes it sent the packet to */ |
845 | int route_tofriend(uint8_t * friend_id, uint8_t *packet, uint32_t length) | 804 | int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) |
846 | { | 805 | { |
847 | uint32_t i, j; | 806 | uint32_t i, j; |
848 | uint32_t sent = 0; | 807 | uint32_t sent = 0; |
849 | uint32_t temp_time = unix_time(); | 808 | uint32_t temp_time = unix_time(); |
850 | for (i = 0; i < num_friends; ++i) { | 809 | for(i = 0; i < num_friends; ++i) |
851 | /* Equal */ | 810 | /* Equal */ |
852 | if (memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { | 811 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { |
853 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 812 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
854 | /*If ip is not zero and node is good */ | 813 | /*If ip is not zero and node is good */ |
855 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && | 814 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && |
856 | friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { | 815 | friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) |
857 | if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) | 816 | if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) |
858 | ++sent; | 817 | ++sent; |
859 | } | ||
860 | } | ||
861 | return sent; | 818 | return sent; |
862 | } | 819 | } |
863 | } | ||
864 | return 0; | 820 | return 0; |
865 | } | 821 | } |
866 | 822 | ||
@@ -869,28 +825,24 @@ int route_tofriend(uint8_t * friend_id, uint8_t *packet, uint32_t length) | |||
869 | int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | 825 | int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) |
870 | { | 826 | { |
871 | int num = friend_number(friend_id); | 827 | int num = friend_number(friend_id); |
872 | if(num == -1) { | 828 | if(num == -1) |
873 | return 0; | 829 | return 0; |
874 | } | ||
875 | 830 | ||
876 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 831 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
877 | int n = 0; | 832 | int n = 0; |
878 | uint32_t i; | 833 | uint32_t i; |
879 | uint32_t temp_time = unix_time(); | 834 | uint32_t temp_time = unix_time(); |
880 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 835 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
881 | /*If ip is not zero and node is good */ | 836 | /*If ip is not zero and node is good */ |
882 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && | 837 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && |
883 | friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { | 838 | friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { |
884 | ip_list[n] = friends_list[num].client_list[i].ip_port; | 839 | ip_list[n] = friends_list[num].client_list[i].ip_port; |
885 | ++n; | 840 | ++n; |
886 | } | 841 | } |
887 | } | 842 | if(n < 1) |
888 | if(n < 1) { | ||
889 | return 0; | 843 | return 0; |
890 | } | 844 | if(sendpacket(ip_list[rand() % n], packet, length) == length) |
891 | if(sendpacket(ip_list[rand() % n], packet, length) == length) { | ||
892 | return 1; | 845 | return 1; |
893 | } | ||
894 | return 0; | 846 | return 0; |
895 | } | 847 | } |
896 | 848 | ||
@@ -903,12 +855,10 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) | |||
903 | { | 855 | { |
904 | 856 | ||
905 | uint32_t i; | 857 | uint32_t i; |
906 | for(i = 0; i < num_friends; ++i) { | 858 | for(i = 0; i < num_friends; ++i) |
907 | /* Equal */ | 859 | /* Equal */ |
908 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { | 860 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) |
909 | return friend_iplist(ip_portlist, i); | 861 | return friend_iplist(ip_portlist, i); |
910 | } | ||
911 | } | ||
912 | return -1; | 862 | return -1; |
913 | } | 863 | } |
914 | 864 | ||
@@ -922,19 +872,17 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
922 | 872 | ||
923 | uint8_t packet[MAX_DATA_SIZE]; | 873 | uint8_t packet[MAX_DATA_SIZE]; |
924 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ | 874 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ |
925 | if(len == -1) { | 875 | if(len == -1) |
926 | return -1; | 876 | return -1; |
927 | } | 877 | |
928 | int num = 0; | 878 | int num = 0; |
929 | if(type == 0) { | 879 | |
880 | if(type == 0) | ||
930 | num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/ | 881 | num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/ |
931 | } | 882 | else if(type == 1) |
932 | else if(type == 1) { | ||
933 | num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/ | 883 | num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/ |
934 | } | 884 | if(num == 0) |
935 | if(num == 0) { | ||
936 | return -1; | 885 | return -1; |
937 | } | ||
938 | return num; | 886 | return num; |
939 | } | 887 | } |
940 | 888 | ||
@@ -942,44 +890,37 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
942 | int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | 890 | int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) |
943 | { | 891 | { |
944 | if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 892 | if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
945 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) { | 893 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
946 | return 1; | 894 | return 1; |
947 | } | ||
948 | /* check if request is for us. */ | 895 | /* check if request is for us. */ |
949 | if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 896 | if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
950 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 897 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
951 | uint8_t data[MAX_DATA_SIZE]; | 898 | uint8_t data[MAX_DATA_SIZE]; |
952 | int len = handle_request(public_key, data, packet, length); | 899 | int len = handle_request(public_key, data, packet, length); |
953 | if(len != sizeof(uint64_t) + 1) { | 900 | if(len != sizeof(uint64_t) + 1) |
954 | return 1; | 901 | return 1; |
955 | } | ||
956 | uint64_t ping_id; | 902 | uint64_t ping_id; |
957 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); | 903 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); |
958 | 904 | ||
959 | int friendnumber = friend_number(public_key); | 905 | int friendnumber = friend_number(public_key); |
960 | if(friendnumber == -1) { | 906 | if(friendnumber == -1) |
961 | return 1; | 907 | return 1; |
962 | } | ||
963 | 908 | ||
964 | if(data[0] == 0) { | 909 | if(data[0] == 0) { |
965 | send_NATping(public_key, ping_id, 1);/*1 is reply*/ | 910 | send_NATping(public_key, ping_id, 1); /*1 is reply*/ |
966 | return 0; | 911 | return 0; |
967 | } else if (data[0] == 1) { | 912 | } else if (data[0] == 1) |
968 | if(friends_list[friendnumber].NATping_id == ping_id) | 913 | if(friends_list[friendnumber].NATping_id == ping_id) { |
969 | { | ||
970 | friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int(); | 914 | friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int(); |
971 | friends_list[friendnumber].hole_punching = 1; | 915 | friends_list[friendnumber].hole_punching = 1; |
972 | return 0; | 916 | return 0; |
973 | } | 917 | } |
974 | } | ||
975 | return 1; | 918 | return 1; |
976 | } | 919 | } |
977 | /* if request is not for us, try routing it. */ | 920 | /* if request is not for us, try routing it. */ |
978 | else { | 921 | else |
979 | if(route_packet(packet + 1, packet, length) == length) { | 922 | if(route_packet(packet + 1, packet, length) == length) |
980 | return 0; | 923 | return 0; |
981 | } | ||
982 | } | ||
983 | return 0; | 924 | return 0; |
984 | } | 925 | } |
985 | 926 | ||
@@ -990,21 +931,17 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | |||
990 | static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) | 931 | static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) |
991 | { | 932 | { |
992 | IP zero = {{0}}; | 933 | IP zero = {{0}}; |
993 | if(len > MAX_FRIEND_CLIENTS) { | 934 | if(len > MAX_FRIEND_CLIENTS) |
994 | return zero; | 935 | return zero; |
995 | } | ||
996 | 936 | ||
997 | uint32_t i, j; | 937 | uint32_t i, j; |
998 | uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; | 938 | uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; |
999 | for(i = 0; i < len; ++i) { | 939 | for(i = 0; i < len; ++i) { |
1000 | for(j = 0; j < len; ++j) { | 940 | for(j = 0; j < len; ++j) |
1001 | if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) { | 941 | if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) |
1002 | ++numbers[i]; | 942 | ++numbers[i]; |
1003 | } | 943 | if(numbers[i] >= min_num) |
1004 | } | ||
1005 | if(numbers[i] >= min_num) { | ||
1006 | return ip_portlist[i].ip; | 944 | return ip_portlist[i].ip; |
1007 | } | ||
1008 | } | 945 | } |
1009 | return zero; | 946 | return zero; |
1010 | } | 947 | } |
@@ -1017,12 +954,11 @@ static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_ | |||
1017 | { | 954 | { |
1018 | uint32_t i; | 955 | uint32_t i; |
1019 | uint16_t num = 0; | 956 | uint16_t num = 0; |
1020 | for(i = 0; i < len; ++i) { | 957 | for(i = 0; i < len; ++i) |
1021 | if(ip_portlist[i].ip.i == ip.i) { | 958 | if(ip_portlist[i].ip.i == ip.i) { |
1022 | portlist[num] = ntohs(ip_portlist[i].port); | 959 | portlist[num] = ntohs(ip_portlist[i].port); |
1023 | ++num; | 960 | ++num; |
1024 | } | 961 | } |
1025 | } | ||
1026 | return num; | 962 | return num; |
1027 | } | 963 | } |
1028 | 964 | ||
@@ -1030,9 +966,8 @@ static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_ | |||
1030 | 966 | ||
1031 | static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) | 967 | static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) |
1032 | { | 968 | { |
1033 | if(numports > MAX_FRIEND_CLIENTS || numports == 0) { | 969 | if(numports > MAX_FRIEND_CLIENTS || numports == 0) |
1034 | return; | 970 | return; |
1035 | } | ||
1036 | uint32_t i; | 971 | uint32_t i; |
1037 | uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; | 972 | uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; |
1038 | for(i = friends_list[friend_num].punching_index; i != top; i++) { | 973 | for(i = friends_list[friend_num].punching_index; i != top; i++) { |
@@ -1055,9 +990,9 @@ static void doNAT() | |||
1055 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 990 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
1056 | int num = friend_iplist(ip_list, i); | 991 | int num = friend_iplist(ip_list, i); |
1057 | /*If we are connected to friend or if friend is not online don't try to hole punch with him*/ | 992 | /*If we are connected to friend or if friend is not online don't try to hole punch with him*/ |
1058 | if(num < MAX_FRIEND_CLIENTS/2) { | 993 | if(num < MAX_FRIEND_CLIENTS/2) |
1059 | continue; | 994 | continue; |
1060 | } | 995 | |
1061 | if(friends_list[i].hole_punching != 1) { | 996 | if(friends_list[i].hole_punching != 1) { |
1062 | if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { | 997 | if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { |
1063 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ | 998 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ |
@@ -1066,9 +1001,9 @@ static void doNAT() | |||
1066 | } | 1001 | } |
1067 | else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) { | 1002 | else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) { |
1068 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); | 1003 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); |
1069 | if(ip.i == 0) { | 1004 | if(ip.i == 0) |
1070 | continue; | 1005 | continue; |
1071 | } | 1006 | |
1072 | uint16_t port_list[MAX_FRIEND_CLIENTS]; | 1007 | uint16_t port_list[MAX_FRIEND_CLIENTS]; |
1073 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); | 1008 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); |
1074 | punch_holes(ip, port_list, numports, i); | 1009 | punch_holes(ip, port_list, numports, i); |
@@ -1105,7 +1040,6 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | |||
1105 | } | 1040 | } |
1106 | 1041 | ||
1107 | return 0; | 1042 | return 0; |
1108 | |||
1109 | } | 1043 | } |
1110 | 1044 | ||
1111 | void doDHT() | 1045 | void doDHT() |
@@ -1133,12 +1067,10 @@ void DHT_save(uint8_t * data) | |||
1133 | return 0 if success */ | 1067 | return 0 if success */ |
1134 | int DHT_load(uint8_t * data, uint32_t size) | 1068 | int DHT_load(uint8_t * data, uint32_t size) |
1135 | { | 1069 | { |
1136 | if(size < sizeof(close_clientlist)) { | 1070 | if(size < sizeof(close_clientlist)) |
1137 | return -1; | 1071 | return -1; |
1138 | } | 1072 | if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) |
1139 | if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) { | ||
1140 | return -1; | 1073 | return -1; |
1141 | } | ||
1142 | uint32_t i, j; | 1074 | uint32_t i, j; |
1143 | /* uint32_t temp_time = unix_time(); */ | 1075 | /* uint32_t temp_time = unix_time(); */ |
1144 | uint16_t temp; | 1076 | uint16_t temp; |
@@ -1150,21 +1082,18 @@ int DHT_load(uint8_t * data, uint32_t size) | |||
1150 | 1082 | ||
1151 | for(i = 0; i < temp; ++i) { | 1083 | for(i = 0; i < temp; ++i) { |
1152 | DHT_addfriend(tempfriends_list[i].client_id); | 1084 | DHT_addfriend(tempfriends_list[i].client_id); |
1153 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 1085 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
1154 | if(tempfriends_list[i].client_list[j].timestamp != 0) { | 1086 | if(tempfriends_list[i].client_list[j].timestamp != 0) { |
1155 | getnodes(tempfriends_list[i].client_list[j].ip_port, | 1087 | getnodes(tempfriends_list[i].client_list[j].ip_port, |
1156 | tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); | 1088 | tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); |
1157 | } | 1089 | } |
1158 | } | ||
1159 | } | 1090 | } |
1160 | } | 1091 | } |
1161 | Client_data * tempclose_clientlist = (Client_data *)data; | 1092 | Client_data * tempclose_clientlist = (Client_data *)data; |
1162 | 1093 | ||
1163 | for(i = 0; i < LCLIENT_LIST; ++i) { | 1094 | for(i = 0; i < LCLIENT_LIST; ++i) |
1164 | if(tempclose_clientlist[i].timestamp != 0) { | 1095 | if(tempclose_clientlist[i].timestamp != 0) |
1165 | DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); | 1096 | DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); |
1166 | } | ||
1167 | } | ||
1168 | return 0; | 1097 | return 0; |
1169 | } | 1098 | } |
1170 | 1099 | ||
@@ -1174,10 +1103,8 @@ int DHT_isconnected() | |||
1174 | { | 1103 | { |
1175 | uint32_t i; | 1104 | uint32_t i; |
1176 | uint32_t temp_time = unix_time(); | 1105 | uint32_t temp_time = unix_time(); |
1177 | for(i = 0; i < LCLIENT_LIST; ++i) { | 1106 | for(i = 0; i < LCLIENT_LIST; ++i) |
1178 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { | 1107 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) |
1179 | return 1; | 1108 | return 1; |
1180 | } | ||
1181 | } | ||
1182 | return 0; | 1109 | return 0; |
1183 | } \ No newline at end of file | 1110 | } |