summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt4
-rw-r--r--INSTALL.md22
-rw-r--r--core/DHT.c826
-rw-r--r--core/DHT.h2
-rw-r--r--core/Lossless_UDP.c14
-rw-r--r--core/Messenger.c4
-rw-r--r--core/net_crypto.c14
-rw-r--r--testing/DHT_test.c12
-rw-r--r--testing/nTox.c104
-rw-r--r--testing/nTox_win32.c279
-rw-r--r--testing/nTox_win32.h7
-rw-r--r--testing/toxic/prompt.c1
12 files changed, 808 insertions, 481 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bf709e72..ed934c01 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 2.6.0)
2 2
3set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 3set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
4 4
5if(UNIX)
6 find_package(Curses REQUIRED)
7endif()
8
5if(NOT WIN32) 9if(NOT WIN32)
6 option(USE_NACL "Use NaCl library instead of libsodium") 10 option(USE_NACL "Use NaCl library instead of libsodium")
7endif() 11endif()
diff --git a/INSTALL.md b/INSTALL.md
index d6a5b3f9..625a9c6d 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -18,6 +18,14 @@ Build dependencies:
18```bash 18```bash
19apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall 19apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall
20``` 20```
21
22On Fedora:
23
24```bash
25yum groupinstall "Development Tools"
26yum install libtool autoconf automake libconfig-devel ncurses-devel cmake
27```
28
21Note that `libconfig-dev` should be >= 1.4. 29Note that `libconfig-dev` should be >= 1.4.
22 30
23You should get and install [libsodium](https://github.com/jedisct1/libsodium): 31You should get and install [libsodium](https://github.com/jedisct1/libsodium):
@@ -31,6 +39,20 @@ sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
31sudo ldconfig 39sudo ldconfig
32``` 40```
33 41
42Or if checkinstall is not easily available for your distribution (e.g. Fedora),
43this will install the libs to /usr/local/lib and the headers to /usr/local/include:
44
45```bash
46git clone git://github.com/jedisct1/libsodium.git
47cd libsodium
48git checkout tags/0.4.2
49./autogen.sh
50./configure
51make check
52sudo make install
53```
54
55
34Then clone this repo and generate makefile: 56Then clone this repo and generate makefile:
35```bash 57```bash
36git clone git://github.com/irungentoo/ProjectTox-Core.git 58git clone git://github.com/irungentoo/ProjectTox-Core.git
diff --git a/core/DHT.c b/core/DHT.c
index 272641ee..6972fdeb 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -64,12 +64,12 @@
64typedef struct { 64typedef struct {
65 uint8_t client_id[CLIENT_ID_SIZE]; 65 uint8_t client_id[CLIENT_ID_SIZE];
66 IP_Port ip_port; 66 IP_Port ip_port;
67 uint32_t timestamp; 67 uint64_t timestamp;
68 uint32_t last_pinged; 68 uint64_t last_pinged;
69 69
70 /* Returned by this node. Either our friend or us */ 70 /* Returned by this node. Either our friend or us */
71 IP_Port ret_ip_port; 71 IP_Port ret_ip_port;
72 uint32_t ret_timestamp; 72 uint64_t ret_timestamp;
73} Client_data; 73} Client_data;
74 74
75typedef struct { 75typedef struct {
@@ -77,17 +77,17 @@ typedef struct {
77 Client_data client_list[MAX_FRIEND_CLIENTS]; 77 Client_data client_list[MAX_FRIEND_CLIENTS];
78 78
79 /* time at which the last get_nodes request was sent. */ 79 /* time at which the last get_nodes request was sent. */
80 uint32_t lastgetnode; 80 uint64_t lastgetnode;
81 81
82 /* Symetric NAT hole punching stuff */ 82 /* Symetric NAT hole punching stuff */
83 83
84 /* 1 if currently hole punching, otherwise 0 */ 84 /* 1 if currently hole punching, otherwise 0 */
85 uint8_t hole_punching; 85 uint8_t hole_punching;
86 uint32_t punching_index; 86 uint32_t punching_index;
87 uint32_t punching_timestamp; 87 uint64_t punching_timestamp;
88 int64_t recvNATping_timestamp; 88 uint64_t recvNATping_timestamp;
89 uint64_t NATping_id; 89 uint64_t NATping_id;
90 uint32_t NATping_timestamp; 90 uint64_t NATping_timestamp;
91} Friend; 91} Friend;
92 92
93typedef struct { 93typedef struct {
@@ -98,7 +98,7 @@ typedef struct {
98typedef struct { 98typedef struct {
99 IP_Port ip_port; 99 IP_Port ip_port;
100 uint64_t ping_id; 100 uint64_t ping_id;
101 int64_t timestamp; 101 uint64_t timestamp;
102} Pinged; 102} Pinged;
103 103
104/*----------------------------------------------------------------------------------*/ 104/*----------------------------------------------------------------------------------*/
@@ -115,30 +115,38 @@ 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;
141 int64_t temp_time = unix_time(); 149 uint64_t temp_time = unix_time();
142 150
143 for(i = 0; i < length; ++i) { 151 for(i = 0; i < length; ++i) {
144 /*If ip_port is assigned to a different client_id replace it*/ 152 /*If ip_port is assigned to a different client_id replace it*/
@@ -156,83 +164,131 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
156 } 164 }
157 } 165 }
158 return 0; 166 return 0;
159
160} 167}
161 168
162/* check if client with client_id is already in node format list of length length. 169/* check if client with client_id is already in node format list of length length.
163 return True(1) or False(0) */ 170 * return True(1) or False(0)
171 */
164int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 172int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
165{ 173{
166 uint32_t i; 174 uint32_t i;
167 for(i = 0; i < length; ++i) 175 for(i = 0; i < length; ++i) {
168 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 176 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
169 return 1; 177 return 1;
178 }
170 return 0; 179 return 0;
171} 180}
172 181
173/*Return the friend number from the client_id 182/* Returns the friend number from the client_id, or -1 if a failure occurs
174 Return -1 if failure, number of friend if success*/ 183 */
175static int friend_number(uint8_t * client_id) 184static int friend_number(uint8_t * client_id)
176{ 185{
177 uint32_t i; 186 uint32_t i;
178 for(i = 0; i < num_friends; ++i) 187 for(i = 0; i < num_friends; ++i) {
179 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 188 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
180 return i; 189 return i;
190 }
181 return -1; 191 return -1;
182} 192}
183 193
184/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 194/* 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. 195 * put them in the nodes_list and return how many were found.
186 TODO: Make this function much more efficient. */ 196 *
197 * TODO: For the love of based Allah make this function cleaner and much more efficient.
198 */
187int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 199int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
188{ 200{
189 uint32_t i, j, k; 201 uint32_t i, j, k;
190 int num_nodes=0; 202 uint64_t temp_time = unix_time();
191 int64_t temp_time = unix_time(); 203 int num_nodes = 0, closest, tout, inlist;
192 for(i = 0; i < LCLIENT_LIST; ++i) 204
193 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 205 for (i = 0; i < LCLIENT_LIST; ++i) {
194 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { 206 tout = close_clientlist[i].timestamp <= temp_time - BAD_NODE_TIMEOUT;
195 /* if node is good and not already in list. */ 207 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
208
209 /* if node isn't good or is already in list. */
210 if(tout || inlist)
211 continue;
212
213 if(num_nodes < MAX_SENT_NODES) {
214
215 memcpy( nodes_list[num_nodes].client_id,
216 close_clientlist[i].client_id,
217 CLIENT_ID_SIZE );
218
219 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
220 num_nodes++;
221 } else {
222 for(j = 0; j < MAX_SENT_NODES; ++j) {
223 closest = id_closest( client_id,
224 nodes_list[j].client_id,
225 close_clientlist[i].client_id );
226 if(closest == 2) {
227 memcpy( nodes_list[j].client_id,
228 close_clientlist[i].client_id,
229 CLIENT_ID_SIZE);
230
231 nodes_list[j].ip_port = close_clientlist[i].ip_port;
232 break;
233 }
234 }
235 }
236 }
237
238 for(i = 0; i < num_friends; ++i) {
239 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
240 tout = friends_list[i].client_list[j].timestamp <= temp_time - BAD_NODE_TIMEOUT;
241 inlist = client_in_nodelist( nodes_list,
242 MAX_SENT_NODES,
243 friends_list[i].client_list[j].client_id);
244
245 /* if node isn't good or is already in list. */
246 if(tout || inlist)
247 continue;
248
196 if(num_nodes < MAX_SENT_NODES) { 249 if(num_nodes < MAX_SENT_NODES) {
197 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 250
198 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 251 memcpy( nodes_list[num_nodes].client_id,
252 friends_list[i].client_list[j].client_id,
253 CLIENT_ID_SIZE);
254
255 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
199 num_nodes++; 256 num_nodes++;
200 } else for(j = 0; j < MAX_SENT_NODES; ++j) 257 } else {
201 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { 258 for(k = 0; k < MAX_SENT_NODES; ++k) {
202 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 259
203 nodes_list[j].ip_port = close_clientlist[i].ip_port; 260 closest = id_closest( client_id,
261 nodes_list[k].client_id,
262 friends_list[i].client_list[j].client_id );
263 if(closest == 2) {
264 memcpy( nodes_list[k].client_id,
265 friends_list[i].client_list[j].client_id,
266 CLIENT_ID_SIZE );
267
268 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
204 break; 269 break;
205 } 270 }
206 } 271 }
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 } 272 }
273 }
274 }
224 return num_nodes; 275 return num_nodes;
225} 276}
226 277
227/* replace first bad (or empty) node with this one 278/* replace first bad (or empty) node with this one
228 return 0 if successful 279 * return 0 if successful
229 return 1 if not (list contains no bad nodes) */ 280 * return 1 if not (list contains no bad nodes)
230int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ 281 */
282int replace_bad( Client_data * list,
283 uint32_t length,
284 uint8_t * client_id,
285 IP_Port ip_port )
231{ 286{
232 uint32_t i; 287 uint32_t i;
233 int64_t temp_time = unix_time(); 288 uint64_t temp_time = unix_time();
234 for(i = 0; i < length; ++i) 289 for(i = 0; i < length; ++i) {
235 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */ 290 /* if node is bad */
291 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) {
236 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 292 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
237 list[i].ip_port = ip_port; 293 list[i].ip_port = ip_port;
238 list[i].timestamp = temp_time; 294 list[i].timestamp = temp_time;
@@ -241,15 +297,20 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
241 list[i].ret_timestamp = 0; 297 list[i].ret_timestamp = 0;
242 return 0; 298 return 0;
243 } 299 }
300 }
244 301
245 return 1; 302 return 1;
246} 303}
247 304
248/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ 305/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */
249int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) 306int replace_good( Client_data * list,
307 uint32_t length,
308 uint8_t * client_id,
309 IP_Port ip_port,
310 uint8_t * comp_client_id )
250{ 311{
251 uint32_t i; 312 uint32_t i;
252 int64_t temp_time = unix_time(); 313 uint64_t temp_time = unix_time();
253 314
254 for(i = 0; i < length; ++i) 315 for(i = 0; i < length; ++i)
255 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { 316 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
@@ -265,72 +326,111 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
265 return 1; 326 return 1;
266} 327}
267 328
268/* Attempt to add client with ip_port and client_id to the friends client list and close_clientlist */ 329/* Attempt to add client with ip_port and client_id to the friends client list
330 * and close_clientlist
331 */
269void addto_lists(IP_Port ip_port, uint8_t * client_id) 332void addto_lists(IP_Port ip_port, uint8_t * client_id)
270{ 333{
271 uint32_t i; 334 uint32_t i;
272 335
273 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 336 /* NOTE: current behavior if there are two clients with the same id is
274 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 337 * to replace the first ip by the second.
275 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 338 */
339 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
340 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
276 /* if we can't replace bad nodes we try replacing good ones */ 341 /* if we can't replace bad nodes we try replacing good ones */
277 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); 342 replace_good( close_clientlist,
343 LCLIENT_LIST,
344 client_id,
345 ip_port,
346 self_public_key );
347 }
348 }
349
350 for (i = 0; i < num_friends; ++i) {
351 if (!client_in_list( friends_list[i].client_list,
352 MAX_FRIEND_CLIENTS,
353 client_id,
354 ip_port )) {
278 355
279 for(i = 0; i < num_friends; ++i) 356 if (replace_bad( friends_list[i].client_list,
280 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 357 MAX_FRIEND_CLIENTS,
281 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 358 client_id,
359 ip_port )) {
282 /* if we can't replace bad nodes we try replacing good ones. */ 360 /* if we can't replace bad nodes we try replacing good ones. */
283 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 361 replace_good( friends_list[i].client_list,
362 MAX_FRIEND_CLIENTS,
363 client_id,
364 ip_port,
365 friends_list[i].client_id );
366 }
367 }
368 }
284} 369}
285 370
286/* If client_id is a friend or us, update ret_ip_port 371/* If client_id is a friend or us, update ret_ip_port
287 nodeclient_id is the id of the node that sent us this info */ 372 * nodeclient_id is the id of the node that sent us this info
373 */
288void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 374void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
289{ 375{
290 uint32_t i, j; 376 uint32_t i, j;
291 int64_t temp_time = unix_time(); 377 uint64_t temp_time = unix_time();
292 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { 378
293 for(i = 0; i < LCLIENT_LIST; ++i) 379 if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
294 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { 380 for (i = 0; i < LCLIENT_LIST; ++i) {
381
382 if (memcmp( nodeclient_id,
383 close_clientlist[i].client_id,
384 CLIENT_ID_SIZE ) == 0) {
295 close_clientlist[i].ret_ip_port = ip_port; 385 close_clientlist[i].ret_ip_port = ip_port;
296 close_clientlist[i].ret_timestamp = temp_time; 386 close_clientlist[i].ret_timestamp = temp_time;
297 return; 387 return;
298 } 388 }
299 } else 389 }
300 for(i = 0; i < num_friends; ++i) 390 } else {
301 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 391 for (i = 0; i < num_friends; ++i) {
302 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 392 if (memcmp( client_id,
303 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { 393 friends_list[i].client_id,
394 CLIENT_ID_SIZE ) == 0) {
395 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
396
397 if (memcmp( nodeclient_id,
398 friends_list[i].client_list[j].client_id,
399 CLIENT_ID_SIZE ) == 0) {
304 friends_list[i].client_list[j].ret_ip_port = ip_port; 400 friends_list[i].client_list[j].ret_ip_port = ip_port;
305 friends_list[i].client_list[j].ret_timestamp = temp_time; 401 friends_list[i].client_list[j].ret_timestamp = temp_time;
306 return; 402 return;
307 } 403 }
404 }
405 }
406 }
407 }
308} 408}
309 409
310/* check if we are currently pinging an ip_port and/or a ping_id 410/* check if we are currently pinging an ip_port and/or a ping_id variables with
311 variables with values of zero will not be checked. 411 * values of zero will not be checked. If we are already, return 1 else return 0
312 if we are already, return 1 412 *
313 else return 0 413 * TODO: optimize this
314TODO: optimize this */ 414 */
315int is_pinging(IP_Port ip_port, uint64_t ping_id) 415int is_pinging(IP_Port ip_port, uint64_t ping_id)
316{ 416{
317 uint32_t i; 417 uint32_t i;
318 uint8_t pinging; 418 uint8_t pinging;
319 int64_t temp_time = unix_time(); 419 uint64_t temp_time = unix_time();
320 420
321 for(i = 0; i < LPING_ARRAY; ++i ) 421 for (i = 0; i < LPING_ARRAY; ++i ) {
322 if((pings[i].timestamp + PING_TIMEOUT) > temp_time) { 422 if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
323 pinging = 0; 423 pinging = 0;
324 if(ip_port.ip.i != 0) 424 if (ip_port.ip.i != 0 &&
325 if(pings[i].ip_port.ip.i == ip_port.ip.i && 425 pings[i].ip_port.ip.i == ip_port.ip.i &&
326 pings[i].ip_port.port == ip_port.port) 426 pings[i].ip_port.port == ip_port.port)
327 ++pinging;
328 if(ping_id != 0)
329 if(pings[i].ping_id == ping_id)
330 ++pinging; 427 ++pinging;
331 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 428 if (ping_id != 0 && pings[i].ping_id == ping_id)
429 ++pinging;
430 if (pinging == ((ping_id != 0) + (ip_port.ip.i != 0)))
332 return 1; 431 return 1;
333 } 432 }
433 }
334 434
335 return 0; 435 return 0;
336} 436}
@@ -340,44 +440,48 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
340{ 440{
341 uint32_t i; 441 uint32_t i;
342 uint8_t pinging; 442 uint8_t pinging;
343 int64_t temp_time = unix_time(); 443 uint64_t temp_time = unix_time();
344 444
345 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) 445 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
346 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { 446 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
347 pinging = 0; 447 pinging = 0;
348 if(ip_port.ip.i != 0) 448 if(ip_port.ip.i != 0 &&
349 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 449 send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
350 send_nodes[i].ip_port.port == ip_port.port) 450 send_nodes[i].ip_port.port == ip_port.port)
351 ++pinging; 451 ++pinging;
352 if(ping_id != 0) 452 if(ping_id != 0 && send_nodes[i].ping_id == ping_id)
353 if(send_nodes[i].ping_id == ping_id)
354 ++pinging; 453 ++pinging;
355 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 454 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
356 return 1; 455 return 1;
357
358 } 456 }
457 }
359 458
360 return 0; 459 return 0;
361} 460}
362 461
363/* Add a new ping request to the list of ping requests 462/* Add a new ping request to the list of ping requests
364 returns the ping_id to put in the ping request 463 * returns the ping_id to put in the ping request
365 returns 0 if problem. 464 * returns 0 if problem.
366 TODO: optimize this */ 465 *
466 * TODO: optimize this
467 */
367uint64_t add_pinging(IP_Port ip_port) 468uint64_t add_pinging(IP_Port ip_port)
368{ 469{
369 uint32_t i, j; 470 uint32_t i, j;
370 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 471 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
371 int64_t temp_time = unix_time(); 472 uint64_t temp_time = unix_time();
372 473
373 for(i = 0; i < PING_TIMEOUT; ++i ) 474
374 for(j = 0; j < LPING_ARRAY; ++j ) 475 for(i = 0; i < PING_TIMEOUT; ++i ) {
476 for(j = 0; j < LPING_ARRAY; ++j ) {
375 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { 477 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
376 pings[j].timestamp = temp_time; 478 pings[j].timestamp = temp_time;
377 pings[j].ip_port = ip_port; 479 pings[j].ip_port = ip_port;
378 pings[j].ping_id = ping_id; 480 pings[j].ping_id = ping_id;
379 return ping_id; 481 return ping_id;
380 } 482 }
483 }
484 }
381 485
382 return 0; 486 return 0;
383} 487}
@@ -387,28 +491,30 @@ uint64_t add_gettingnodes(IP_Port ip_port)
387{ 491{
388 uint32_t i, j; 492 uint32_t i, j;
389 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 493 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
390 int64_t temp_time = unix_time(); 494 uint64_t temp_time = unix_time();
391 495
392 for(i = 0; i < PING_TIMEOUT; ++i ) 496 for(i = 0; i < PING_TIMEOUT; ++i ) {
393 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 497 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
394 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { 498 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
395 send_nodes[j].timestamp = temp_time; 499 send_nodes[j].timestamp = temp_time;
396 send_nodes[j].ip_port = ip_port; 500 send_nodes[j].ip_port = ip_port;
397 send_nodes[j].ping_id = ping_id; 501 send_nodes[j].ping_id = ping_id;
398 return ping_id; 502 return ping_id;
399 } 503 }
504 }
505 }
400 506
401 return 0; 507 return 0;
402} 508}
403 509
404/* send a ping request 510/* send a ping request, only works if none has been sent to that ip/port
405 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ 511 * in the last 5 seconds.
512 */
406static int pingreq(IP_Port ip_port, uint8_t * public_key) 513static int pingreq(IP_Port ip_port, uint8_t * public_key)
407{ 514{
408 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 515 /* check if packet is gonna be sent to ourself */
409 return 1; 516 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0
410 517 || is_pinging(ip_port, 0))
411 if(is_pinging(ip_port, 0))
412 return 1; 518 return 1;
413 519
414 uint64_t ping_id = add_pinging(ip_port); 520 uint64_t ping_id = add_pinging(ip_port);
@@ -420,9 +526,16 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
420 uint8_t nonce[crypto_box_NONCEBYTES]; 526 uint8_t nonce[crypto_box_NONCEBYTES];
421 random_nonce(nonce); 527 random_nonce(nonce);
422 528
423 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 529 int len = encrypt_data( public_key,
530 self_secret_key,
531 nonce,
532 (uint8_t *)&ping_id,
533 sizeof(ping_id),
534 encrypt );
535
424 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 536 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
425 return -1; 537 return -1;
538
426 data[0] = 0; 539 data[0] = 0;
427 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 540 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
428 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 541 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
@@ -443,9 +556,15 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
443 uint8_t nonce[crypto_box_NONCEBYTES]; 556 uint8_t nonce[crypto_box_NONCEBYTES];
444 random_nonce(nonce); 557 random_nonce(nonce);
445 558
446 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 559 int len = encrypt_data( public_key,
560 self_secret_key, nonce,
561 (uint8_t *)&ping_id,
562 sizeof(ping_id),
563 encrypt );
564
447 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 565 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
448 return -1; 566 return -1;
567
449 data[0] = 1; 568 data[0] = 1;
450 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 569 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
451 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 570 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
@@ -458,10 +577,8 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
458static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 577static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
459{ 578{
460 /* check if packet is gonna be sent to ourself */ 579 /* check if packet is gonna be sent to ourself */
461 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 580 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0
462 return 1; 581 || is_gettingnodes(ip_port, 0))
463
464 if(is_gettingnodes(ip_port, 0))
465 return 1; 582 return 1;
466 583
467 uint64_t ping_id = add_gettingnodes(ip_port); 584 uint64_t ping_id = add_gettingnodes(ip_port);
@@ -478,21 +595,29 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
478 memcpy(plain, &ping_id, sizeof(ping_id)); 595 memcpy(plain, &ping_id, sizeof(ping_id));
479 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 596 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
480 597
481 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 598 int len = encrypt_data( public_key,
599 self_secret_key,
600 nonce,
601 plain,
602 sizeof(ping_id) + CLIENT_ID_SIZE,
603 encrypt );
482 604
483 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 605 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
484 return -1; 606 return -1;
607
485 data[0] = 2; 608 data[0] = 2;
486 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 609 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
487 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 610 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
488 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 611 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
612
489 return sendpacket(ip_port, data, sizeof(data)); 613 return sendpacket(ip_port, data, sizeof(data));
490} 614}
491 615
492/* send a send nodes response */ 616/* send a send nodes response */
493static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 617static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
494{ 618{
495 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 619 /* check if packet is gonna be sent to ourself */
620 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
496 return 1; 621 return 1;
497 622
498 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 623 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
@@ -512,8 +637,12 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
512 memcpy(plain, &ping_id, sizeof(ping_id)); 637 memcpy(plain, &ping_id, sizeof(ping_id));
513 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 638 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
514 639
515 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 640 int len = encrypt_data( public_key,
516 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 641 self_secret_key,
642 nonce,
643 plain,
644 sizeof(ping_id) + num_nodes * sizeof(Node_format),
645 encrypt );
517 646
518 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 647 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
519 return -1; 648 return -1;
@@ -526,26 +655,30 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
526 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 655 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
527} 656}
528 657
529/* Packet handling functions 658/* Packet handling functions, one to handle each types of packets we receive
530 One to handle each types of packets we receive 659 * Returns 0 if handled correctly, 1 if packet is bad.
531 return 0 if handled correctly, 1 if packet is bad. */ 660 */
532int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) 661int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
533{ 662{
534 uint64_t ping_id; 663 uint64_t ping_id;
535 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 664 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
536 return 1; 665 return 1;
666
537 /* check if packet is from ourself. */ 667 /* check if packet is from ourself. */
538 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 668 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
539 return 1; 669 return 1;
540 670
541 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 671 int len = decrypt_data( packet + 1,
542 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 672 self_secret_key,
543 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 673 packet + 1 + CLIENT_ID_SIZE,
674 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
675 sizeof(ping_id) + ENCRYPTION_PADDING,
676 (uint8_t *)&ping_id );
677
544 if(len != sizeof(ping_id)) 678 if(len != sizeof(ping_id))
545 return 1; 679 return 1;
546 680
547 pingres(source, packet + 1, ping_id); 681 pingres(source, packet + 1, ping_id);
548
549 pingreq(source, packet + 1); /* TODO: make this smarter? */ 682 pingreq(source, packet + 1); /* TODO: make this smarter? */
550 683
551 return 0; 684 return 0;
@@ -556,12 +689,18 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
556 uint64_t ping_id; 689 uint64_t ping_id;
557 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 690 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
558 return 1; 691 return 1;
559 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 692
693 /* check if packet is from ourself. */
694 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
560 return 1; 695 return 1;
561 696
562 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 697 int len = decrypt_data( packet + 1,
563 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 698 self_secret_key,
564 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 699 packet + 1 + CLIENT_ID_SIZE,
700 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
701 sizeof(ping_id) + ENCRYPTION_PADDING,
702 (uint8_t *)&ping_id );
703
565 if(len != sizeof(ping_id)) 704 if(len != sizeof(ping_id))
566 return 1; 705 return 1;
567 706
@@ -570,25 +709,30 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
570 return 0; 709 return 0;
571 } 710 }
572 return 1; 711 return 1;
573
574} 712}
575 713
576int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 714int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
577{ 715{
578 uint64_t ping_id; 716 uint64_t ping_id;
579 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 717
718 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
719 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING ))
580 return 1; 720 return 1;
721
581 /* check if packet is from ourself. */ 722 /* check if packet is from ourself. */
582 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 723 if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
583 return 1; 724 return 1;
584 725
585 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 726 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
586 727
587 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 728 int len = decrypt_data( packet + 1,
588 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 729 self_secret_key,
589 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 730 packet + 1 + CLIENT_ID_SIZE,
731 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
732 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING,
733 plain );
590 734
591 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 735 if (len != sizeof(ping_id) + CLIENT_ID_SIZE)
592 return 1; 736 return 1;
593 737
594 memcpy(&ping_id, plain, sizeof(ping_id)); 738 memcpy(&ping_id, plain, sizeof(ping_id));
@@ -597,29 +741,28 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
597 pingreq(source, packet + 1); /* TODO: make this smarter? */ 741 pingreq(source, packet + 1); /* TODO: make this smarter? */
598 742
599 return 0; 743 return 0;
600
601} 744}
602 745
603int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) 746int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
604{ 747{
605 uint64_t ping_id; 748 uint64_t ping_id;
606 /* TODO: make this more readable */ 749 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
607 if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 750 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
608 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || 751
609 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 752 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) ||
610 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 753 ((length - cid_size) % sizeof(Node_format)) != 0 ||
611 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 754 (length < cid_size + sizeof(Node_format)))
612 + sizeof(Node_format) + ENCRYPTION_PADDING) {
613 return 1; 755 return 1;
614 }
615 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
616 + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
617 756
757 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format);
618 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 758 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
619 759
620 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 760 int len = decrypt_data(
621 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 761 packet + 1,
622 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 762 self_secret_key,
763 packet + 1 + CLIENT_ID_SIZE,
764 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
765 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain );
623 766
624 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 767 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
625 return 1; 768 return 1;
@@ -649,12 +792,13 @@ int DHT_addfriend(uint8_t * client_id)
649{ 792{
650 Friend * temp; 793 Friend * temp;
651 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 794 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
652 if(temp == NULL) 795 if (temp == NULL)
653 return 1; 796 return 1;
654 797
655 friends_list = temp; 798 friends_list = temp;
656 memset(&friends_list[num_friends], 0, sizeof(Friend)); 799 memset(&friends_list[num_friends], 0, sizeof(Friend));
657 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 800 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
801
658 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 802 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
659 ++num_friends; 803 ++num_friends;
660 return 0; 804 return 0;
@@ -664,17 +808,21 @@ int DHT_delfriend(uint8_t * client_id)
664{ 808{
665 uint32_t i; 809 uint32_t i;
666 Friend * temp; 810 Friend * temp;
667 for(i = 0; i < num_friends; ++i) 811 for (i = 0; i < num_friends; ++i) {
668 /* Equal */ 812 /* Equal */
669 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 813 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
670 --num_friends; 814 --num_friends;
671 if(num_friends != i) 815 if (num_friends != i) {
672 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); 816 memcpy( friends_list[i].client_id,
817 friends_list[num_friends].client_id,
818 CLIENT_ID_SIZE );
819 }
673 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 820 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
674 if(temp != NULL) 821 if (temp != NULL)
675 friends_list = temp; 822 friends_list = temp;
676 return 0; 823 return 0;
677 } 824 }
825 }
678 826
679 return 1; 827 return 1;
680} 828}
@@ -683,86 +831,97 @@ int DHT_delfriend(uint8_t * client_id)
683IP_Port DHT_getfriendip(uint8_t * client_id) 831IP_Port DHT_getfriendip(uint8_t * client_id)
684{ 832{
685 uint32_t i, j; 833 uint32_t i, j;
834 uint64_t temp_time = unix_time();
686 IP_Port empty = {{{0}}, 0}; 835 IP_Port empty = {{{0}}, 0};
687 int64_t temp_time = unix_time(); 836
688 for(i = 0; i < num_friends; ++i) 837 for (i = 0; i < num_friends; ++i) {
689 /* Equal */ 838 /* Equal */
690 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 839 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
691 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 840 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
692 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 841 if (memcmp( friends_list[i].client_list[j].client_id,
842 client_id,
843 CLIENT_ID_SIZE ) == 0 &&
693 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 844 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
694 return friends_list[i].client_list[j].ip_port; 845 return friends_list[i].client_list[j].ip_port;
695 846 }
696 return empty; 847 return empty;
697 } 848 }
849 }
698 empty.ip.i = 1; 850 empty.ip.i = 1;
699 return empty; 851 return empty;
700
701} 852}
702 853
703/* Ping each client in the "friends" list every 60 seconds. 854/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request
704 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ 855 * every 20 seconds to a random good node for each "friend" in our "friends" list.
856 */
705void doDHTFriends() 857void doDHTFriends()
706{ 858{
707 uint32_t i, j; 859 uint32_t i, j;
708 int64_t temp_time = unix_time(); 860 uint64_t temp_time = unix_time();
709 uint32_t rand_node; 861 uint32_t rand_node;
710 uint32_t index[MAX_FRIEND_CLIENTS]; 862 uint32_t index[MAX_FRIEND_CLIENTS];
711 863
712 for(i = 0; i < num_friends; ++i) { 864 for (i = 0; i < num_friends; ++i) {
713 uint32_t num_nodes = 0; 865 uint32_t num_nodes = 0;
714 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 866 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
715 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */ 867 /* if node is not dead. */
716 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 868 if (friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) {
717 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 869 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
870 pingreq( friends_list[i].client_list[j].ip_port,
871 friends_list[i].client_list[j].client_id );
718 friends_list[i].client_list[j].last_pinged = temp_time; 872 friends_list[i].client_list[j].last_pinged = temp_time;
719 } 873 }
720 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */ 874 /* if node is good. */
875 if (friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) {
721 index[num_nodes] = j; 876 index[num_nodes] = j;
722 ++num_nodes; 877 ++num_nodes;
723 } 878 }
724 } 879 }
880 }
725 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 881 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
726 rand_node = rand() % num_nodes; 882 rand_node = rand() % num_nodes;
727 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 883 getnodes( friends_list[i].client_list[index[rand_node]].ip_port,
728 friends_list[i].client_list[index[rand_node]].client_id, 884 friends_list[i].client_list[index[rand_node]].client_id,
729 friends_list[i].client_id); 885 friends_list[i].client_id );
730 friends_list[i].lastgetnode = temp_time; 886 friends_list[i].lastgetnode = temp_time;
731 } 887 }
732 } 888 }
733} 889}
734 890
735static uint32_t close_lastgetnodes; 891static uint64_t close_lastgetnodes;
736 892
737/* Ping each client in the close nodes list every 60 seconds. 893/* Ping each client in the close nodes list every 60 seconds.
738 Send a get nodes request every 20 seconds to a random good node in the list. */ 894 * Send a get nodes request every 20 seconds to a random good node in the list.
739void doClose() /* tested */ 895 */
896void doClose()
740{ 897{
741 uint32_t i; 898 uint32_t i;
742 int64_t temp_time = unix_time(); 899 uint64_t temp_time = unix_time();
743 uint32_t num_nodes = 0; 900 uint32_t num_nodes = 0;
744 uint32_t rand_node; 901 uint32_t rand_node;
745 uint32_t index[LCLIENT_LIST]; 902 uint32_t index[LCLIENT_LIST];
746 903
747 for(i = 0; i < LCLIENT_LIST; ++i) 904 for (i = 0; i < LCLIENT_LIST; ++i) {
748 /* if node is not dead. */ 905 /* if node is not dead. */
749 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { 906 if (close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
750 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 907 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
751 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 908 pingreq( close_clientlist[i].ip_port,
909 close_clientlist[i].client_id );
752 close_clientlist[i].last_pinged = temp_time; 910 close_clientlist[i].last_pinged = temp_time;
753 } 911 }
754 /* if node is good. */ 912 /* if node is good. */
755 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { 913 if (close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
756 index[num_nodes] = i; 914 index[num_nodes] = i;
757 ++num_nodes; 915 ++num_nodes;
758 } 916 }
759 } 917 }
918 }
760 919
761 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 920 if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
762 rand_node = rand() % num_nodes; 921 rand_node = rand() % num_nodes;
763 getnodes(close_clientlist[index[rand_node]].ip_port, 922 getnodes( close_clientlist[index[rand_node]].ip_port,
764 close_clientlist[index[rand_node]].client_id, 923 close_clientlist[index[rand_node]].client_id,
765 self_public_key); 924 self_public_key );
766 close_lastgetnodes = temp_time; 925 close_lastgetnodes = temp_time;
767 } 926 }
768} 927}
@@ -773,100 +932,129 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
773} 932}
774 933
775/* send the given packet to node with client_id 934/* send the given packet to node with client_id
776 returns -1 if failure */ 935 * returns -1 if failure
936 */
777int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 937int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
778{ 938{
779 uint32_t i; 939 uint32_t i;
780 for(i = 0; i < LCLIENT_LIST; ++i) 940 for (i = 0; i < LCLIENT_LIST; ++i) {
781 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) 941 if (memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
782 return sendpacket(close_clientlist[i].ip_port, packet, length); 942 return sendpacket(close_clientlist[i].ip_port, packet, length);
943 }
783 return -1; 944 return -1;
784} 945}
785 946
786/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist 947/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
787 ip_portlist must be at least MAX_FRIEND_CLIENTS big 948 * ip_portlist must be at least MAX_FRIEND_CLIENTS big
788 returns the number of ips returned 949 * returns the number of ips returned
789 return 0 if we are connected to friend or if no ips were found. 950 * return 0 if we are connected to friend or if no ips were found.
790 returns -1 if no such friend*/ 951 * returns -1 if no such friend
952 */
791static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) 953static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
792{ 954{
793 int num_ips = 0; 955 int num_ips = 0;
794 uint32_t i; 956 uint32_t i;
795 int64_t temp_time = unix_time(); 957 uint64_t temp_time = unix_time();
796 if(friend_num >= num_friends) 958
959 if (friend_num >= num_friends)
797 return -1; 960 return -1;
798 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 961
962 Friend * friend = &friends_list[friend_num];
963 Client_data * client;
964
965 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
966 client = &friend->client_list[i];
967
799 /*If ip is not zero and node is good */ 968 /*If ip is not zero and node is good */
800 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && 969 if (client->ret_ip_port.ip.i != 0 &&
801 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 970 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
802 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) 971
972 if (memcmp(client->client_id, friend->client_id, CLIENT_ID_SIZE) == 0)
803 return 0; 973 return 0;
804 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; 974
975 ip_portlist[num_ips] = client->ret_ip_port;
805 ++num_ips; 976 ++num_ips;
806 } 977 }
978 }
807 return num_ips; 979 return num_ips;
808} 980}
809 981
810/* Send the following packet to everyone who tells us they are connected to friend_id 982/* Send the following packet to everyone who tells us they are connected to friend_id
811 returns the number of nodes it sent the packet to */ 983 * returns the number of nodes it sent the packet to
984 */
812int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 985int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
813{ 986{
814 uint32_t i, j; 987 int num = friend_number(friend_id);
815 uint32_t sent = 0; 988 if (num == -1)
816 int64_t temp_time = unix_time(); 989 return 0;
817 for(i = 0; i < num_friends; ++i) 990
818 /* Equal */ 991 uint32_t i, sent = 0;
819 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { 992 uint64_t temp_time = unix_time();
820 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 993 Friend * friend = &friends_list[num];
821 /*If ip is not zero and node is good */ 994 Client_data * client;
822 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 995
823 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 996 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
824 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) 997 client = &friend->client_list[i];
825 ++sent; 998
826 return sent; 999 /*If ip is not zero and node is good */
1000 if (client->ret_ip_port.ip.i != 0 &&
1001 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1002
1003 if (sendpacket(client->ip_port, packet, length) == length)
1004 ++sent;
827 } 1005 }
828 return 0; 1006 }
1007 return sent;
829} 1008}
830 1009
831/* Send the following packet to one random person who tells us they are connected to friend_id 1010/* Send the following packet to one random person who tells us they are connected to friend_id
832 returns the number of nodes it sent the packet to */ 1011* returns the number of nodes it sent the packet to
1012*/
833int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 1013int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
834{ 1014{
835 int num = friend_number(friend_id); 1015 int num = friend_number(friend_id);
836 if(num == -1) 1016 if (num == -1)
837 return 0; 1017 return 0;
838 1018
1019 Friend * friend = &friends_list[num];
1020 Client_data * client;
1021
839 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1022 IP_Port ip_list[MAX_FRIEND_CLIENTS];
840 int n = 0; 1023 int n = 0;
841 uint32_t i; 1024 uint32_t i;
842 int64_t temp_time = unix_time(); 1025 uint64_t temp_time = unix_time();
843 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 1026
1027 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1028 client = &friend->client_list[i];
1029
844 /*If ip is not zero and node is good */ 1030 /*If ip is not zero and node is good */
845 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && 1031 if(client->ret_ip_port.ip.i != 0 &&
846 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 1032 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
847 ip_list[n] = friends_list[num].client_list[i].ip_port; 1033 ip_list[n] = client->ip_port;
848 ++n; 1034 ++n;
849 } 1035 }
850 if(n < 1) 1036 }
1037 if (n < 1)
851 return 0; 1038 return 0;
852 if(sendpacket(ip_list[rand() % n], packet, length) == length) 1039 if (sendpacket(ip_list[rand() % n], packet, length) == length)
853 return 1; 1040 return 1;
854 return 0; 1041 return 0;
855} 1042}
856 1043
857/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 1044/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
858 ip_portlist must be at least MAX_FRIEND_CLIENTS big 1045 * ip_portlist must be at least MAX_FRIEND_CLIENTS big
859 returns the number of ips returned 1046 * returns the number of ips returned
860 return 0 if we are connected to friend or if no ips were found. 1047 * return 0 if we are connected to friend or if no ips were found.
861 returns -1 if no such friend*/ 1048 * returns -1 if no such friend
1049 */
862int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 1050int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
863{ 1051{
864
865 uint32_t i; 1052 uint32_t i;
866 for(i = 0; i < num_friends; ++i) 1053 for (i = 0; i < num_friends; ++i) {
867 /* Equal */ 1054 /* Equal */
868 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) 1055 if (memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0)
869 return friend_iplist(ip_portlist, i); 1056 return friend_iplist(ip_portlist, i);
1057 }
870 return -1; 1058 return -1;
871} 1059}
872 1060
@@ -876,21 +1064,24 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
876int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) 1064int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
877{ 1065{
878 uint8_t data[sizeof(uint64_t) + 1]; 1066 uint8_t data[sizeof(uint64_t) + 1];
1067 uint8_t packet[MAX_DATA_SIZE];
1068
1069 int num = 0;
1070
879 data[0] = type; 1071 data[0] = type;
880 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 1072 memcpy(data + 1, &ping_id, sizeof(uint64_t));
1073 /* 254 is NAT ping request packet id */
1074 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254);
881 1075
882 uint8_t packet[MAX_DATA_SIZE]; 1076 if (len == -1)
883 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
884 if(len == -1)
885 return -1; 1077 return -1;
886 1078
887 int num = 0; 1079 if (type == 0) /*If packet is request use many people to route it*/
1080 num = route_tofriend(public_key, packet, len);
1081 else if (type == 1) /*If packet is response use only one person to route it*/
1082 num = routeone_tofriend(public_key, packet, len);
888 1083
889 if(type == 0) 1084 if (num == 0)
890 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
891 else if(type == 1)
892 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
893 if(num == 0)
894 return -1; 1085 return -1;
895 return num; 1086 return num;
896} 1087}
@@ -898,45 +1089,54 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
898/* Handle a recieved ping request for */ 1089/* Handle a recieved ping request for */
899int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) 1090int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
900{ 1091{
901 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 1092 if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING
902 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 1093 && length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
903 return 1; 1094 return 1;
1095
904 /* check if request is for us. */ 1096 /* check if request is for us. */
905 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 1097 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
906 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 1098 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
907 uint8_t data[MAX_DATA_SIZE]; 1099 uint8_t data[MAX_DATA_SIZE];
1100
908 int len = handle_request(public_key, data, packet, length); 1101 int len = handle_request(public_key, data, packet, length);
909 if(len != sizeof(uint64_t) + 1) 1102 if (len != sizeof(uint64_t) + 1)
910 return 1; 1103 return 1;
1104
911 uint64_t ping_id; 1105 uint64_t ping_id;
912 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 1106 memcpy(&ping_id, data + 1, sizeof(uint64_t));
913 1107
914 int friendnumber = friend_number(public_key); 1108 int friendnumber = friend_number(public_key);
915 if(friendnumber == -1) 1109 if (friendnumber == -1)
916 return 1; 1110 return 1;
917 1111
918 if(data[0] == 0) { 1112 Friend * friend = &friends_list[friendnumber];
919 send_NATping(public_key, ping_id, 1); /*1 is reply*/ 1113
920 friends_list[friendnumber].recvNATping_timestamp = unix_time(); 1114 if (data[0] == 0) {
1115 /* 1 is reply */
1116 send_NATping(public_key, ping_id, 1);
1117 friend->recvNATping_timestamp = unix_time();
921 return 0; 1118 return 0;
922 } else if (data[0] == 1) 1119 } else if (data[0] == 1) {
923 if(friends_list[friendnumber].NATping_id == ping_id) { 1120 if (friend->NATping_id == ping_id) {
924 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 1121 friend->NATping_id = ((uint64_t)random_int() << 32) + random_int();
925 friends_list[friendnumber].hole_punching = 1; 1122 friend->hole_punching = 1;
926 return 0; 1123 return 0;
927 } 1124 }
1125 }
928 return 1; 1126 return 1;
929 } 1127 }
1128
930 /* if request is not for us, try routing it. */ 1129 /* if request is not for us, try routing it. */
931 else if(route_packet(packet + 1, packet, length) == length) 1130 route_packet(packet + 1, packet, length);
932 return 0; 1131
933 return 0; 1132 return 0;
934} 1133}
935 1134
936/*Get the most common ip in the ip_portlist 1135/* Get the most common ip in the ip_portlist
937 Only return ip if it appears in list min_num or more 1136 * Only return ip if it appears in list min_num or more
938 len must not be bigger than MAX_FRIEND_CLIENTS 1137 * len must not be bigger than MAX_FRIEND_CLIENTS
939 return ip of 0 if failure */ 1138 * return ip of 0 if failure
1139 */
940static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) 1140static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
941{ 1141{
942 IP zero = {{0}}; 1142 IP zero = {{0}};
@@ -945,29 +1145,34 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
945 1145
946 uint32_t i, j; 1146 uint32_t i, j;
947 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 1147 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
1148
948 for(i = 0; i < len; ++i) { 1149 for(i = 0; i < len; ++i) {
949 for(j = 0; j < len; ++j) 1150 for(j = 0; j < len; ++j) {
950 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) 1151 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i)
951 ++numbers[i]; 1152 ++numbers[i];
1153 }
952 if(numbers[i] >= min_num) 1154 if(numbers[i] >= min_num)
953 return ip_portlist[i].ip; 1155 return ip_portlist[i].ip;
954 } 1156 }
955 return zero; 1157 return zero;
956} 1158}
957 1159
958/*Return all the ports for one ip in a list 1160/* Return all the ports for one ip in a list
959 portlist must be at least len long 1161 * portlist must be at least len long
960 where len is the length of ip_portlist 1162 * where len is the length of ip_portlist
961 returns the number of ports and puts the list of ports in portlist*/ 1163 * returns the number of ports and puts the list of ports in portlist
1164 */
962static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip) 1165static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip)
963{ 1166{
964 uint32_t i; 1167 uint32_t i;
965 uint16_t num = 0; 1168 uint16_t num = 0;
966 for(i = 0; i < len; ++i) 1169
1170 for(i = 0; i < len; ++i) {
967 if(ip_portlist[i].ip.i == ip.i) { 1171 if(ip_portlist[i].ip.i == ip.i) {
968 portlist[num] = ntohs(ip_portlist[i].port); 1172 portlist[num] = ntohs(ip_portlist[i].port);
969 ++num; 1173 ++num;
970 } 1174 }
1175 }
971 return num; 1176 return num;
972} 1177}
973 1178
@@ -975,8 +1180,10 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
975{ 1180{
976 if(numports > MAX_FRIEND_CLIENTS || numports == 0) 1181 if(numports > MAX_FRIEND_CLIENTS || numports == 0)
977 return; 1182 return;
1183
978 uint32_t i; 1184 uint32_t i;
979 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1185 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1186
980 for(i = friends_list[friend_num].punching_index; i != top; i++) { 1187 for(i = friends_list[friend_num].punching_index; i != top; i++) {
981 /*TODO: improve port guessing algorithm*/ 1188 /*TODO: improve port guessing algorithm*/
982 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1189 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
@@ -989,24 +1196,26 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
989static void doNAT() 1196static void doNAT()
990{ 1197{
991 uint32_t i; 1198 uint32_t i;
992 int64_t temp_time = unix_time(); 1199 uint64_t temp_time = unix_time();
993 for(i = 0; i < num_friends; ++i) { 1200
1201 for (i = 0; i < num_friends; ++i) {
994 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1202 IP_Port ip_list[MAX_FRIEND_CLIENTS];
995 int num = friend_iplist(ip_list, i); 1203 int num = friend_iplist(ip_list, i);
996 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
997 if(num < MAX_FRIEND_CLIENTS/2)
998 continue;
999 1204
1205 /*If already connected or friend is not online don't try to hole punch*/
1206 if (num < MAX_FRIEND_CLIENTS/2)
1207 continue;
1000 1208
1001 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1209 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1002 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1210 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1003 friends_list[i].NATping_timestamp = temp_time; 1211 friends_list[i].NATping_timestamp = temp_time;
1004 } 1212 }
1005 if(friends_list[i].hole_punching == 1 && 1213 if (friends_list[i].hole_punching == 1 &&
1006 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1214 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
1007 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) { 1215 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) {
1216
1008 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); 1217 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1009 if(ip.i == 0) 1218 if (ip.i == 0)
1010 continue; 1219 continue;
1011 1220
1012 uint16_t port_list[MAX_FRIEND_CLIENTS]; 1221 uint16_t port_list[MAX_FRIEND_CLIENTS];
@@ -1069,17 +1278,22 @@ void DHT_save(uint8_t * data)
1069} 1278}
1070 1279
1071/* load the DHT from data of size size; 1280/* load the DHT from data of size size;
1072 return -1 if failure 1281 * return -1 if failure
1073 return 0 if success */ 1282 * return 0 if success
1283 */
1074int DHT_load(uint8_t * data, uint32_t size) 1284int DHT_load(uint8_t * data, uint32_t size)
1075{ 1285{
1076 if(size < sizeof(close_clientlist)) 1286 if(size < sizeof(close_clientlist))
1077 return -1; 1287 return -1;
1288
1078 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1289 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0)
1079 return -1; 1290 return -1;
1291
1080 uint32_t i, j; 1292 uint32_t i, j;
1081 /* int64_t temp_time = unix_time(); */
1082 uint16_t temp; 1293 uint16_t temp;
1294 /* uint64_t temp_time = unix_time(); */
1295
1296 Client_data * client;
1083 1297
1084 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1298 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1085 1299
@@ -1088,29 +1302,35 @@ int DHT_load(uint8_t * data, uint32_t size)
1088 1302
1089 for(i = 0; i < temp; ++i) { 1303 for(i = 0; i < temp; ++i) {
1090 DHT_addfriend(tempfriends_list[i].client_id); 1304 DHT_addfriend(tempfriends_list[i].client_id);
1091 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1305
1092 if(tempfriends_list[i].client_list[j].timestamp != 0) { 1306 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1093 getnodes(tempfriends_list[i].client_list[j].ip_port, 1307 client = &tempfriends_list[i].client_list[j];
1094 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1308 if(client->timestamp != 0)
1095 } 1309 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id);
1310 }
1096 } 1311 }
1097 } 1312 }
1098 Client_data * tempclose_clientlist = (Client_data *)data; 1313 Client_data * tempclose_clientlist = (Client_data *)data;
1099 1314
1100 for(i = 0; i < LCLIENT_LIST; ++i) 1315 for(i = 0; i < LCLIENT_LIST; ++i) {
1101 if(tempclose_clientlist[i].timestamp != 0) 1316 if(tempclose_clientlist[i].timestamp != 0)
1102 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); 1317 DHT_bootstrap( tempclose_clientlist[i].ip_port,
1318 tempclose_clientlist[i].client_id );
1319 }
1103 return 0; 1320 return 0;
1104} 1321}
1105 1322
1106/* returns 0 if we are not connected to the DHT 1323/* returns 0 if we are not connected to the DHT
1107 returns 1 if we are */ 1324 * returns 1 if we are
1325 */
1108int DHT_isconnected() 1326int DHT_isconnected()
1109{ 1327{
1110 uint32_t i; 1328 uint32_t i;
1111 int64_t temp_time = unix_time(); 1329 uint64_t temp_time = unix_time();
1112 for(i = 0; i < LCLIENT_LIST; ++i) 1330
1331 for(i = 0; i < LCLIENT_LIST; ++i) {
1113 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) 1332 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1114 return 1; 1333 return 1;
1334 }
1115 return 0; 1335 return 0;
1116} 1336}
diff --git a/core/DHT.h b/core/DHT.h
index 5e1fd0a5..ffa02087 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -31,7 +31,7 @@ extern "C" {
31#endif 31#endif
32 32
33/* Current time, unix format */ 33/* Current time, unix format */
34#define unix_time() ((int64_t)time(NULL)) 34#define unix_time() ((uint64_t)time(NULL))
35 35
36/* size of the client_id in bytes */ 36/* size of the client_id in bytes */
37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 4affc38f..33b8eb19 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -202,15 +202,16 @@ int new_connection(IP_Port ip_port)
202 for (i = 0; i < MAX_CONNECTIONS; ++i) { 202 for (i = 0; i < MAX_CONNECTIONS; ++i) {
203 if(connections[i].status == 0) { 203 if(connections[i].status == 0) {
204 memset(&connections[i], 0, sizeof(Connection)); 204 memset(&connections[i], 0, sizeof(Connection));
205 uint32_t handshake_id1 = handshake_id(ip_port);
205 206
206 connections[i] = (Connection) { 207 connections[i] = (Connection) {
207 .ip_port = ip_port, 208 .ip_port = ip_port,
208 .status = 1, 209 .status = 1,
209 .inbound = 0, 210 .inbound = 0,
210 .handshake_id1 = handshake_id(ip_port), 211 .handshake_id1 = handshake_id1,
211 .sent_packetnum = connections[i].handshake_id1, 212 .sent_packetnum = handshake_id1,
212 .sendbuff_packetnum = connections[i].handshake_id1, 213 .sendbuff_packetnum = handshake_id1,
213 .successful_sent = connections[i].handshake_id1, 214 .successful_sent = handshake_id1,
214 .SYNC_rate = SYNC_RATE, 215 .SYNC_rate = SYNC_RATE,
215 .data_rate = DATA_SYNC_RATE, 216 .data_rate = DATA_SYNC_RATE,
216 .last_recvSYNC = current_time(), 217 .last_recvSYNC = current_time(),
@@ -254,6 +255,7 @@ int new_inconnection(IP_Port ip_port)
254 for (i = 0; i < MAX_CONNECTIONS; ++i) { 255 for (i = 0; i < MAX_CONNECTIONS; ++i) {
255 if (connections[i].status == 0) { 256 if (connections[i].status == 0) {
256 memset(&connections[i], 0, sizeof(Connection)); 257 memset(&connections[i], 0, sizeof(Connection));
258 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
257 259
258 connections[i] = (Connection){ 260 connections[i] = (Connection){
259 .ip_port = ip_port, 261 .ip_port = ip_port,
@@ -266,10 +268,10 @@ int new_inconnection(IP_Port ip_port)
266 .send_counter = 127, 268 .send_counter = 127,
267 269
268 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 270 /* add randomness to timeout to prevent connections getting stuck in a loop. */
269 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT, 271 .timeout = timeout,
270 272
271 /* if this connection isn't handled within the timeout kill it. */ 273 /* if this connection isn't handled within the timeout kill it. */
272 .killat = current_time() + 1000000UL*connections[i].timeout 274 .killat = current_time() + 1000000UL*timeout
273 }; 275 };
274 ++connections_number; 276 ++connections_number;
275 return i; 277 return i;
diff --git a/core/Messenger.c b/core/Messenger.c
index 3ffbe6ab..c768633e 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -27,7 +27,7 @@
27typedef struct { 27typedef struct {
28 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
29 int crypt_connection_id; 29 int crypt_connection_id;
30 int64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ 30 uint64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
31 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */ 31 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */
32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ 32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
33 uint8_t name[MAX_NAME_LENGTH]; 33 uint8_t name[MAX_NAME_LENGTH];
@@ -485,7 +485,7 @@ static void doInbound()
485/*Interval in seconds between LAN discovery packet sending*/ 485/*Interval in seconds between LAN discovery packet sending*/
486#define LAN_DISCOVERY_INTERVAL 60 486#define LAN_DISCOVERY_INTERVAL 60
487 487
488static int64_t last_LANdiscovery; 488static uint64_t last_LANdiscovery;
489 489
490/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 490/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
491static void LANdiscovery() 491static void LANdiscovery()
diff --git a/core/net_crypto.c b/core/net_crypto.c
index 31fb24be..3b5b67f4 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -66,11 +66,11 @@ static int incoming_connections[MAX_INCOMING];
66int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 66int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
67 uint8_t *plain, uint32_t length, uint8_t *encrypted) 67 uint8_t *plain, uint32_t length, uint8_t *encrypted)
68{ 68{
69 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) 69 if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0)
70 return -1; 70 return -1;
71 71
72 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; 72 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0};
73 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; 73 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES];
74 74
75 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ 75 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */
76 76
@@ -87,7 +87,7 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
87 return -1; 87 return -1;
88 88
89 /* unpad the encrypted message */ 89 /* unpad the encrypted message */
90 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 90 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
91 return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; 91 return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES;
92} 92}
93 93
@@ -101,8 +101,8 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
101 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) 101 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
102 return -1; 102 return -1;
103 103
104 uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; 104 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES];
105 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; 105 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0};
106 106
107 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ 107 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */
108 108
@@ -121,7 +121,7 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
121 return -1; 121 return -1;
122 122
123 /* unpad the plain message */ 123 /* unpad the plain message */
124 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES); 124 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
125 return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; 125 return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES;
126} 126}
127 127
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index 588450e2..f1940614 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -60,11 +60,11 @@ void print_clientlist()
60 } 60 }
61 p_ip = close_clientlist[i].ip_port; 61 p_ip = close_clientlist[i].ip_port;
62 printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 62 printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
63 printf("\nTimestamp: %u", close_clientlist[i].timestamp); 63 printf("\nTimestamp: %llu",(long long unsigned int) close_clientlist[i].timestamp);
64 printf("\nLast pinged: %u\n", close_clientlist[i].last_pinged); 64 printf("\nLast pinged: %llu\n",(long long unsigned int) close_clientlist[i].last_pinged);
65 p_ip = close_clientlist[i].ret_ip_port; 65 p_ip = close_clientlist[i].ret_ip_port;
66 printf("OUR IP: %u.%u.%u.%u Port: %u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 66 printf("OUR IP: %u.%u.%u.%u Port: %u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
67 printf("Timestamp: %u\n", close_clientlist[i].ret_timestamp); 67 printf("Timestamp: %llu\n",(long long unsigned int) close_clientlist[i].ret_timestamp);
68 } 68 }
69} 69}
70 70
@@ -93,11 +93,11 @@ void print_friendlist()
93 } 93 }
94 p_ip = friends_list[k].client_list[i].ip_port; 94 p_ip = friends_list[k].client_list[i].ip_port;
95 printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 95 printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
96 printf("\nTimestamp: %u", friends_list[k].client_list[i].timestamp); 96 printf("\nTimestamp: %llu",(long long unsigned int) friends_list[k].client_list[i].timestamp);
97 printf("\nLast pinged: %u\n", friends_list[k].client_list[i].last_pinged); 97 printf("\nLast pinged: %llu\n",(long long unsigned int) friends_list[k].client_list[i].last_pinged);
98 p_ip = friends_list[k].client_list[i].ret_ip_port; 98 p_ip = friends_list[k].client_list[i].ret_ip_port;
99 printf("ret IP: %u.%u.%u.%u:%u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 99 printf("ret IP: %u.%u.%u.%u:%u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
100 printf("Timestamp: %u\n", friends_list[k].client_list[i].ret_timestamp); 100 printf("Timestamp: %llu\n", (long long unsigned int)friends_list[k].client_list[i].ret_timestamp);
101 } 101 }
102 } 102 }
103} 103}
diff --git a/testing/nTox.c b/testing/nTox.c
index 81cac0b6..13db58d7 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23#include "nTox.h" 23#include "nTox.h"
24#include "misc_tools.h" 24#include "misc_tools.h"
@@ -44,13 +44,37 @@ int x, y;
44uint8_t pending_requests[256][CLIENT_ID_SIZE]; 44uint8_t pending_requests[256][CLIENT_ID_SIZE];
45uint8_t num_requests = 0; 45uint8_t num_requests = 0;
46 46
47void get_id(char *data)
48{
49 char idstring0[200];
50 char idstring1[PUB_KEY_BYTES][5];
51 char idstring2[PUB_KEY_BYTES][5];
52 int i = 0;
53 for(i = 0; i < PUB_KEY_BYTES; i++)
54 {
55 if (self_public_key[i] < (PUB_KEY_BYTES / 2))
56 strcpy(idstring1[i],"0");
57 else
58 strcpy(idstring1[i], "");
59 sprintf(idstring2[i], "%hhX",self_public_key[i]);
60 }
61 strcpy(idstring0,"[i] ID: ");
62 int j = 0;
63 for (j = 0; j < PUB_KEY_BYTES; j++) {
64 strcat(idstring0,idstring1[j]);
65 strcat(idstring0,idstring2[j]);
66 }
67
68 memcpy(data, idstring0, strlen(idstring0));
69}
70
47void new_lines(char *line) 71void new_lines(char *line)
48{ 72{
49 int i; 73 int i = 0;
50 for (i = HISTORY-1; i > 0; i--) 74 for (i = HISTORY-1; i > 0; i--)
51 strcpy(lines[i], lines[i-1]); 75 strncpy(lines[i], lines[i-1], STRING_LENGTH - 1);
52 76
53 strcpy(lines[0], line); 77 strncpy(lines[0], line, STRING_LENGTH - 1);
54 do_refresh(); 78 do_refresh();
55} 79}
56 80
@@ -109,7 +133,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
109 if (inpt_command == 'f') { // add friend command: /f ID 133 if (inpt_command == 'f') { // add friend command: /f ID
110 int i; 134 int i;
111 char temp_id[128]; 135 char temp_id[128];
112 for (i = 0; i < 128; i++) 136 for (i = 0; i < 128; i++)
113 temp_id[i] = line[i+prompt_offset]; 137 temp_id[i] = line[i+prompt_offset];
114 138
115 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 139 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
@@ -142,8 +166,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
142 } 166 }
143 else if (inpt_command == 'm') { //message command: /m friendnumber messsage 167 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
144 size_t len = strlen(line); 168 size_t len = strlen(line);
145 if(len < 3) 169 if(len < 3)
146 return; 170 return;
147 171
148 char numstring[len-3]; 172 char numstring[len-3];
149 char message[len-3]; 173 char message[len-3];
@@ -216,32 +240,15 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
216 new_lines("[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)"); 240 new_lines("[i] /l list (list friends), /h for help, /i for info, /n nick (to change nickname), /q (to quit)");
217 } 241 }
218 else if (inpt_command == 'i') { //info 242 else if (inpt_command == 'i') { //info
219 char idstring0[200]; 243 char idstring[200];
220 char idstring1[PUB_KEY_BYTES][5]; 244 get_id(idstring);
221 char idstring2[PUB_KEY_BYTES][5]; 245 new_lines(idstring);
222 int i;
223 for (i = 0; i < PUB_KEY_BYTES; i++)
224 {
225 if (self_public_key[i] < (PUB_KEY_BYTES/2))
226 strcpy(idstring1[i],"0");
227 else
228 strcpy(idstring1[i], "");
229 sprintf(idstring2[i], "%hhX", self_public_key[i]);
230 }
231 //
232 strcpy(idstring0,"[i] ID: ");
233 int j;
234 for (j = 0; j < PUB_KEY_BYTES; j++) {
235 strcat(idstring0,idstring1[j]);
236 strcat(idstring0,idstring2[j]);
237 }
238 new_lines(idstring0);
239 } 246 }
240 247
241 else if (inpt_command == 'q') { //exit 248 else if (inpt_command == 'q') { //exit
242 endwin(); 249 endwin();
243 exit(EXIT_SUCCESS); 250 exit(EXIT_SUCCESS);
244 } else { 251 } else {
245 new_lines("[i] invalid command"); 252 new_lines("[i] invalid command");
246 } 253 }
247 } else { 254 } else {
@@ -328,7 +335,7 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
328 new_lines(format_message((char*)string, friendnumber)); 335 new_lines(format_message((char*)string, friendnumber));
329} 336}
330 337
331void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) 338void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
332{ 339{
333 char name[MAX_NAME_LENGTH]; 340 char name[MAX_NAME_LENGTH];
334 getname(friendnumber, (uint8_t*)name); 341 getname(friendnumber, (uint8_t*)name);
@@ -337,7 +344,7 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length)
337 new_lines(msg); 344 new_lines(msg);
338} 345}
339 346
340void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) 347void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
341{ 348{
342 char name[MAX_NAME_LENGTH]; 349 char name[MAX_NAME_LENGTH];
343 getname(friendnumber, (uint8_t*)name); 350 getname(friendnumber, (uint8_t*)name);
@@ -346,7 +353,7 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length)
346 new_lines(msg); 353 new_lines(msg);
347} 354}
348 355
349void load_key() 356void load_key()
350{ 357{
351 FILE *data_file = NULL; 358 FILE *data_file = NULL;
352 data_file = fopen("data","r"); 359 data_file = fopen("data","r");
@@ -361,7 +368,7 @@ void load_key()
361 exit(1); 368 exit(1);
362 } 369 }
363 Messenger_load(data, size); 370 Messenger_load(data, size);
364 } else { 371 } else {
365 //else save new keys 372 //else save new keys
366 int size = Messenger_size(); 373 int size = Messenger_size();
367 uint8_t data[size]; 374 uint8_t data[size];
@@ -396,29 +403,14 @@ int main(int argc, char *argv[])
396 m_callback_friendmessage(print_message); 403 m_callback_friendmessage(print_message);
397 m_callback_namechange(print_nickchange); 404 m_callback_namechange(print_nickchange);
398 m_callback_userstatus(print_statuschange); 405 m_callback_userstatus(print_statuschange);
399 char idstring0[200]; 406
400 char idstring1[PUB_KEY_BYTES][5]; 407 char idstring[200];
401 char idstring2[PUB_KEY_BYTES][5]; 408 get_id(idstring);
402 int i;
403 for(i = 0; i < PUB_KEY_BYTES; i++)
404 {
405 if (self_public_key[i] < (PUB_KEY_BYTES / 2))
406 strcpy(idstring1[i],"0");
407 else
408 strcpy(idstring1[i], "");
409 sprintf(idstring2[i], "%hhX",self_public_key[i]);
410 }
411 strcpy(idstring0,"[i] your ID: ");
412 int j;
413 for (j = 0; j < PUB_KEY_BYTES; j++) {
414 strcat(idstring0,idstring1[j]);
415 strcat(idstring0,idstring2[j]);
416 }
417 initscr(); 409 initscr();
418 noecho(); 410 noecho();
419 raw(); 411 raw();
420 getmaxyx(stdscr, y, x); 412 getmaxyx(stdscr, y, x);
421 new_lines(idstring0); 413 new_lines(idstring);
422 new_lines(help); 414 new_lines(help);
423 strcpy(line, ""); 415 strcpy(line, "");
424 IP_Port bootstrap_ip_port; 416 IP_Port bootstrap_ip_port;
@@ -426,9 +418,9 @@ int main(int argc, char *argv[])
426 int resolved_address = resolve_addr(argv[1]); 418 int resolved_address = resolve_addr(argv[1]);
427 if (resolved_address != 0) 419 if (resolved_address != 0)
428 bootstrap_ip_port.ip.i = resolved_address; 420 bootstrap_ip_port.ip.i = resolved_address;
429 else 421 else
430 exit(1); 422 exit(1);
431 423
432 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 424 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
433 nodelay(stdscr, TRUE); 425 nodelay(stdscr, TRUE);
434 while(true) { 426 while(true) {
@@ -449,7 +441,7 @@ int main(int argc, char *argv[])
449 if (c == '\n') { 441 if (c == '\n') {
450 line_eval(lines, line); 442 line_eval(lines, line);
451 strcpy(line, ""); 443 strcpy(line, "");
452 } else if (c == 127) { 444 } else if (c == 8 || c == 127) {
453 line[strlen(line)-1] = '\0'; 445 line[strlen(line)-1] = '\0';
454 } else if (isalnum(c) || ispunct(c) || c == ' ') { 446 } else if (isalnum(c) || ispunct(c) || c == ' ') {
455 strcpy(line, appender(line, (char) c)); 447 strcpy(line, appender(line, (char) c));
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
index 27fc6ff3..3b6fb043 100644
--- a/testing/nTox_win32.c
+++ b/testing/nTox_win32.c
@@ -28,6 +28,7 @@
28 28
29uint8_t pending_requests[256][CLIENT_ID_SIZE]; 29uint8_t pending_requests[256][CLIENT_ID_SIZE];
30uint8_t num_requests = 0; 30uint8_t num_requests = 0;
31uint32_t maxnumfriends;
31 32
32char line[STRING_LENGTH]; 33char line[STRING_LENGTH];
33char users_id[200]; 34char users_id[200];
@@ -105,6 +106,7 @@ void load_key()
105 int size = Messenger_size(); 106 int size = Messenger_size();
106 uint8_t data[size]; 107 uint8_t data[size];
107 Messenger_save(data); 108 Messenger_save(data);
109 fclose(data_file);
108 data_file = fopen("data", "w"); 110 data_file = fopen("data", "w");
109 111
110 if (fwrite(data, sizeof(uint8_t), size, data_file) != size) { 112 if (fwrite(data, sizeof(uint8_t), size, data_file) != size) {
@@ -115,32 +117,178 @@ void load_key()
115 fclose(data_file); 117 fclose(data_file);
116} 118}
117 119
120void add_friend()
121{
122 int i;
123 char temp_id[128];
124
125 for (i = 0; i < 128; i++)
126 temp_id[i] = line[i+3];
127
128 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
129
130 if (num >= 0) {
131 char numstring[100];
132 sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
133 printf(numstring);
134 ++maxnumfriends;
135 }
136 else if (num == -1)
137 printf("\n[i] Message is too long.\n\n");
138
139 else if (num == -2)
140 printf("\n[i] Please add a message to your friend request.\n\n");
141
142 else if (num == -3)
143 printf("\n[i] That appears to be your own ID.\n\n");
144
145 else if (num == -4)
146 printf("\n[i] Friend request already sent.\n\n");
147
148 else if (num == -5)
149 printf("\n[i] Undefined error when adding friend\n\n");
150}
151
152void list_friends()
153{
154 int activefriends = 0;
155 int i;
156
157 for (i = 0; i <= maxnumfriends; i++) {
158 if (m_friendstatus(i) == 4)
159 activefriends++;
160 }
161
162 printf("\n[i] Friend List | Total: %d\n\n", activefriends);
163
164 for (i = 0; i <= 256; i++) {/* TODO: fix this properly*/
165 char name[MAX_NAME_LENGTH];
166 getname(i, (uint8_t*)name);
167
168 if (m_friendstatus(i) == 4)
169 printf("[%d] %s\n\n", i, (uint8_t*)name);
170 }
171}
172
173void delete_friend()
174{
175 size_t len = strlen(line);
176 char numstring[len-3];
177 int i;
178
179 for (i = 0; i < len; i++) {
180 if (line[i+3] != ' ')
181 numstring[i] = line[i+3];
182 }
183
184 int num = atoi(numstring);
185 m_delfriend(num);
186 --maxnumfriends;
187 printf("\n\n");
188}
189
190void message_friend()
191{
192 size_t len = strlen(line);
193 char numstring[len-3];
194 char message[len-3];
195 int i;
196
197 for (i = 0; i < len; i++) {
198
199 if (line[i+3] != ' ')
200 numstring[i] = line[i+3];
201
202 else {
203 int j;
204
205 for (j = (i+1); j < len; j++)
206 message[j-i-1] = line[j+3];
207
208 break;
209 }
210 }
211
212 int num = atoi(numstring);
213
214 if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1)
215 printf("\n[i] could not send message (they may be offline): %s\n", message);
216
217 else
218 printf("\n");
219}
220
221void change_nickname()
222{
223 uint8_t name[MAX_NAME_LENGTH];
224 int i = 0;
225 size_t len = strlen(line);
226
227 for (i = 3; i < len; i++) {
228
229 if (line[i] == 0 || line[i] == '\n')
230 break;
231
232 name[i-3] = line[i];
233 }
234
235 name[i-3] = 0;
236 setname(name, i);
237 char numstring[100];
238 sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name);
239 printf(numstring);
240
241 FILE *name_file = NULL;
242 name_file = fopen("namefile.txt", "w");
243 fprintf(name_file, "%s", (char*)name);
244 fclose(name_file);
245}
246
247void change_status()
248{
249 uint8_t status[MAX_USERSTATUS_LENGTH];
250 int i = 0;
251 size_t len = strlen(line);
252
253 for (i = 3; i < len; i++) {
254 if (line[i] == 0 || line[i] == '\n')
255 break;
256
257 status[i-3] = line[i];
258 }
259
260 status[i-3] = 0;
261 m_set_userstatus(status, strlen((char*)status));
262 char numstring[100];
263 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status);
264 printf(numstring);
265
266 FILE* status_file = NULL;
267 status_file = fopen("statusfile.txt", "w");
268 fprintf(status_file, "%s", (char*)status);
269 fclose(status_file);
270}
271
272void accept_friend_request()
273{
274 uint8_t numf = atoi(line + 3);
275 char numchar[100];
276 sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf);
277 printf(numchar);
278 int num = m_addfriend_norequest(pending_requests[numf]);
279 sprintf(numchar, "\n[i] added friendnumber %d\n\n", num);
280 printf(numchar);
281 ++maxnumfriends;
282}
283
118void line_eval(char* line) 284void line_eval(char* line)
119{ 285{
120 if(line[0] == '/') { 286 if(line[0] == '/') {
287
121 char inpt_command = line[1]; 288 char inpt_command = line[1];
122 /* Add friend */ 289
123 if(inpt_command == 'f') { 290 if(inpt_command == 'f') {
124 int i; 291 add_friend(line);
125 char temp_id[128];
126 for (i = 0; i < 128; i++)
127 temp_id[i] = line[i+3];
128 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
129 if (num >= 0) {
130 char numstring[100];
131 sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
132 printf(numstring);
133 }
134 else if (num == -1)
135 printf("\n[i] Message is too long.\n\n");
136 else if (num == -2)
137 printf("\n[i] Please add a message to your friend request.\n\n");
138 else if (num == -3)
139 printf("\n[i] That appears to be your own ID.\n\n");
140 else if (num == -4)
141 printf("\n[i] Friend request already sent.\n\n");
142 else if (num == -5)
143 printf("\n[i] Undefined error when adding friend\n\n");
144 } 292 }
145 293
146 else if (inpt_command == 'r') { 294 else if (inpt_command == 'r') {
@@ -149,96 +297,27 @@ void line_eval(char* line)
149 } 297 }
150 298
151 else if (inpt_command == 'l') { 299 else if (inpt_command == 'l') {
152 int activefriends = 0; 300 list_friends(line);
153 int i;
154 } 301 }
155 302
156 else if (inpt_command == 'd') { 303 else if (inpt_command == 'd') {
157 size_t len = strlen(line); 304 delete_friend(line);
158 char numstring[len-3];
159 int i;
160 for (i = 0; i < len; i++) {
161 if (line[i+3] != ' ') {
162 numstring[i] = line[i+3];
163 }
164 }
165 int num = atoi(numstring);
166 m_delfriend(num);
167 printf("\n\n");
168 } 305 }
169 /* Send message to friend */ 306 /* Send message to friend */
170 else if (inpt_command == 'm') { 307 else if (inpt_command == 'm') {
171 size_t len = strlen(line); 308 message_friend(line);
172 char numstring[len-3];
173 char message[len-3];
174 int i;
175 for (i = 0; i < len; i++) {
176 if (line[i+3] != ' ') {
177 numstring[i] = line[i+3];
178 } else {
179 int j;
180 for (j = (i+1); j < len; j++)
181 message[j-i-1] = line[j+3];
182 break;
183 }
184 }
185 int num = atoi(numstring);
186 if(m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) {
187 printf("\n[i] could not send message (they may be offline): %s\n", message);
188 } else {
189 //simply for aesthetics
190 printf("\n");
191 }
192 } 309 }
193 310
194 else if (inpt_command == 'n') { 311 else if (inpt_command == 'n') {
195 uint8_t name[MAX_NAME_LENGTH]; 312 change_nickname(line);
196 int i = 0;
197 size_t len = strlen(line);
198 for (i = 3; i < len; i++) {
199 if (line[i] == 0 || line[i] == '\n') break;
200 name[i-3] = line[i];
201 }
202 name[i-3] = 0;
203 setname(name, i);
204 char numstring[100];
205 sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name);
206 printf(numstring);
207
208 FILE *name_file = NULL;
209 name_file = fopen("namefile.txt", "w");
210 fprintf(name_file, "%s", (char*)name);
211 fclose(name_file);
212 } 313 }
213 314
214 else if (inpt_command == 's') { 315 else if (inpt_command == 's') {
215 uint8_t status[MAX_USERSTATUS_LENGTH]; 316 change_status(line);
216 int i = 0;
217 size_t len = strlen(line);
218 for (i = 3; i < len; i++) {
219 if (line[i] == 0 || line[i] == '\n') break;
220 status[i-3] = line[i];
221 }
222 status[i-3] = 0;
223 m_set_userstatus(status, strlen((char*)status));
224 char numstring[100];
225 sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status);
226 printf(numstring);
227
228 FILE* status_file = NULL;
229 status_file = fopen("statusfile.txt", "w");
230 fprintf(status_file, "%s", (char*)status);
231 fclose(status_file);
232 } 317 }
233 318
234 else if (inpt_command == 'a') { 319 else if (inpt_command == 'a') {
235 uint8_t numf = atoi(line + 3); 320 accept_friend_request(line);
236 char numchar[100];
237 sprintf(numchar, "\n[i] friend request %u accepted\n\n", numf);
238 printf(numchar);
239 int num = m_addfriend_norequest(pending_requests[numf]);
240 sprintf(numchar, "\n[i] added friendnumber %d\n\n", num);
241 printf(numchar);
242 } 321 }
243 /* EXIT */ 322 /* EXIT */
244 else if (inpt_command == 'q') { 323 else if (inpt_command == 'q') {
@@ -246,8 +325,6 @@ void line_eval(char* line)
246 m_set_userstatus(status, strlen((char*)status)); 325 m_set_userstatus(status, strlen((char*)status));
247 exit(EXIT_SUCCESS); 326 exit(EXIT_SUCCESS);
248 } 327 }
249 } else {
250 //nothing atm
251 } 328 }
252} 329}
253 330
@@ -290,8 +367,9 @@ int main(int argc, char *argv[])
290 setname(name, strlen((char*)name)+1); 367 setname(name, strlen((char*)name)+1);
291 nameloaded = 1; 368 nameloaded = 1;
292 printf("%s\n", name); 369 printf("%s\n", name);
370 fclose(name_file);
293 } 371 }
294 fclose(name_file); 372
295 373
296 FILE* status_file = NULL; 374 FILE* status_file = NULL;
297 status_file = fopen("statusfile.txt", "r"); 375 status_file = fopen("statusfile.txt", "r");
@@ -303,8 +381,9 @@ int main(int argc, char *argv[])
303 m_set_userstatus(status, strlen((char*)status)+1); 381 m_set_userstatus(status, strlen((char*)status)+1);
304 statusloaded = 1; 382 statusloaded = 1;
305 printf("%s\n", status); 383 printf("%s\n", status);
384 fclose(status_file);
306 } 385 }
307 fclose(status_file); 386
308 387
309 m_callback_friendrequest(print_request); 388 m_callback_friendrequest(print_request);
310 m_callback_friendmessage(print_message); 389 m_callback_friendmessage(print_message);
diff --git a/testing/nTox_win32.h b/testing/nTox_win32.h
index 374348a4..211ac95f 100644
--- a/testing/nTox_win32.h
+++ b/testing/nTox_win32.h
@@ -34,6 +34,13 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length);
34void print_nickchange(int friendnumber, uint8_t *string, uint16_t length); 34void print_nickchange(int friendnumber, uint8_t *string, uint16_t length);
35void print_statuschange(int friendnumber, uint8_t *string, uint16_t length); 35void print_statuschange(int friendnumber, uint8_t *string, uint16_t length);
36void load_key(); 36void load_key();
37void add_friend();
38void list_friends();
39void delete_friend();
40void message_friend();
41void change_nickname();
42void change_status();
43void accept_friend_request();
37void line_eval(char* line); 44void line_eval(char* line);
38void get_input(); 45void get_input();
39 46
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 484f5906..1db60883 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -140,6 +140,7 @@ static void execute(ToxWindow* self, char* cmd) {
140 break; 140 break;
141 case -2: 141 case -2:
142 wprintw(self->window, "Please add a message to your request.\n"); 142 wprintw(self->window, "Please add a message to your request.\n");
143 break;
143 case -3: 144 case -3:
144 wprintw(self->window, "That appears to be your own ID.\n"); 145 wprintw(self->window, "That appears to be your own ID.\n");
145 break; 146 break;