summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--INSTALL.md2
-rw-r--r--core/CMakeLists.txt1
-rw-r--r--core/DHT.c806
-rw-r--r--core/DHT.h54
-rw-r--r--core/LAN_discovery.c79
-rw-r--r--core/LAN_discovery.h50
-rw-r--r--core/Lossless_UDP.c281
-rw-r--r--core/Lossless_UDP.h52
-rw-r--r--core/Messenger.c178
-rw-r--r--core/Messenger.h55
-rw-r--r--core/friend_requests.c87
-rw-r--r--core/friend_requests.h22
-rw-r--r--core/net_crypto.c203
-rw-r--r--core/net_crypto.h50
-rw-r--r--core/network.c83
-rw-r--r--core/network.h47
-rw-r--r--other/DHT_bootstrap.c27
-rw-r--r--other/bootstrap_serverdaemon/CMakeLists.txt1
-rw-r--r--other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c412
-rwxr-xr-xother/bootstrap_serverdaemon/DHT_bootstrap_daemon.sh109
-rw-r--r--other/bootstrap_serverdaemon/initscript.sh109
-rw-r--r--other/bootstrap_serverdaemon/server.cfg30
-rw-r--r--testing/DHT_cryptosendfiletest.c141
-rw-r--r--testing/DHT_sendfiletest.c78
-rw-r--r--testing/DHT_test.c79
-rw-r--r--testing/Lossless_UDP_testclient.c90
-rw-r--r--testing/Lossless_UDP_testserver.c66
-rw-r--r--testing/Messenger_test.c46
-rw-r--r--testing/nTox.c56
-rw-r--r--testing/nTox.h23
31 files changed, 1822 insertions, 1500 deletions
diff --git a/.travis.yml b/.travis.yml
index 0a294bf1..4d49f5fe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ compiler:
4 - clang 4 - clang
5 5
6before_script: 6before_script:
7# installing libsodium, needed for Core
7 - git clone git://github.com/jedisct1/libsodium.git 8 - git clone git://github.com/jedisct1/libsodium.git
8 - cd libsodium 9 - cd libsodium
9 - git checkout tags/0.4.2 10 - git checkout tags/0.4.2
@@ -12,6 +13,10 @@ before_script:
12 - sudo make install 13 - sudo make install
13 - sudo ldconfig 14 - sudo ldconfig
14 - cd .. 15 - cd ..
16# installing libconfig, needed for DHT_bootstrap_daemon
17 - sudo sed -i 's/precise/quantal/' /etc/apt/sources.list # needed for libconfig-dev
18 - sudo apt-get update -qq
19 - yes | sudo apt-get install libconfig-dev
15 20
16script: 21script:
17 - mkdir build && cd build 22 - mkdir build && cd build
diff --git a/INSTALL.md b/INSTALL.md
index bc027c0b..a550e47b 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -56,6 +56,8 @@ You should install:
56 - [MinGW](http://sourceforge.net/projects/mingw/)'s C compiler 56 - [MinGW](http://sourceforge.net/projects/mingw/)'s C compiler
57 - [CMake](http://www.cmake.org/cmake/resources/software.html) 57 - [CMake](http://www.cmake.org/cmake/resources/software.html)
58 58
59You have to [modify your PATH environment variable](http://www.computerhope.com/issues/ch000549.htm) so that it contains MinGW's bin folder path. With default settings, the bin folder is located at `C:\MinGW\bin`, which means that you would have to append `;C:\MinGW\bin` to the PATH variable.
60
59Then you should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere. 61Then you should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere.
60 62
61After that you should get precompiled packages of libsodium from [here](https://download.libsodium.org/libsodium/releases/) and extract the archive into this repo's root. That is, `sodium` folder should be along with `core`, `testing` and other folders. 63After that you should get precompiled packages of libsodium from [here](https://download.libsodium.org/libsodium/releases/) and extract the archive into this repo's root. That is, `sodium` folder should be along with `core`, `testing` and other folders.
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index ab4ff4bc..6ddd5b9b 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -11,6 +11,7 @@ set(core_sources
11 Lossless_UDP.c 11 Lossless_UDP.c
12 net_crypto.c 12 net_crypto.c
13 friend_requests.c 13 friend_requests.c
14 LAN_discovery.c
14 Messenger.c) 15 Messenger.c)
15 16
16add_library(core ${core_sources}) 17add_library(core ${core_sources})
diff --git a/core/DHT.c b/core/DHT.c
index 030c578e..857ac5e8 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -1,33 +1,28 @@
1/* DHT.c 1/* DHT.c
2* 2 *
3* An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24
25
26
27 23
28#include "DHT.h" 24#include "DHT.h"
29 25
30
31typedef struct 26typedef struct
32{ 27{
33 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
@@ -38,17 +33,24 @@ typedef struct
38 (for nodes in friends_list) or us (for nodes in close_clientlist) */ 33 (for nodes in friends_list) or us (for nodes in close_clientlist) */
39 uint32_t ret_timestamp; 34 uint32_t ret_timestamp;
40}Client_data; 35}Client_data;
36
41/* maximum number of clients stored per friend. */ 37/* maximum number of clients stored per friend. */
42#define MAX_FRIEND_CLIENTS 8 38#define MAX_FRIEND_CLIENTS 8
39
43typedef struct 40typedef struct
44{ 41{
45 uint8_t client_id[CLIENT_ID_SIZE]; 42 uint8_t client_id[CLIENT_ID_SIZE];
46 Client_data client_list[MAX_FRIEND_CLIENTS]; 43 Client_data client_list[MAX_FRIEND_CLIENTS];
47 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ 44 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */
48 45
46 /*Symetric NAT hole punching stuff*/
47 uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */
48 uint32_t punching_index;
49 uint32_t punching_timestamp;
50 uint64_t NATping_id;
51 uint32_t NATping_timestamp;
49}Friend; 52}Friend;
50 53
51
52typedef struct 54typedef struct
53{ 55{
54 uint8_t client_id[CLIENT_ID_SIZE]; 56 uint8_t client_id[CLIENT_ID_SIZE];
@@ -72,13 +74,11 @@ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
72#define LCLIENT_LIST 32 74#define LCLIENT_LIST 32
73static Client_data close_clientlist[LCLIENT_LIST]; 75static Client_data close_clientlist[LCLIENT_LIST];
74 76
75
76
77static Friend * friends_list; 77static Friend * friends_list;
78static uint16_t num_friends; 78static uint16_t num_friends;
79 79
80/* The list of ip ports along with the ping_id of what we sent them and a timestamp */ 80/* The list of ip ports along with the ping_id of what we sent them and a timestamp */
81#define LPING_ARRAY 128 81#define LPING_ARRAY 256
82 82
83static Pinged pings[LPING_ARRAY]; 83static Pinged pings[LPING_ARRAY];
84 84
@@ -86,7 +86,6 @@ static Pinged pings[LPING_ARRAY];
86 86
87static Pinged send_nodes[LSEND_NODES_ARRAY]; 87static Pinged send_nodes[LSEND_NODES_ARRAY];
88 88
89
90/* Compares client_id1 and client_id2 with client_id 89/* Compares client_id1 and client_id2 with client_id
91 return 0 if both are same distance 90 return 0 if both are same distance
92 return 1 if client_id1 is closer 91 return 1 if client_id1 is closer
@@ -94,17 +93,12 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
94int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ 93int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */
95{ 94{
96 uint32_t i; 95 uint32_t i;
97 for(i = 0; i < CLIENT_ID_SIZE; ++i) 96 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
98 { 97 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) {
99 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i]))
100 {
101 return 1; 98 return 1;
102 } 99 } else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) {
103 else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i]))
104 {
105 return 2; 100 return 2;
106 } 101 }
107
108 } 102 }
109 103
110 return 0; 104 return 0;
@@ -121,17 +115,14 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
121 uint32_t i; 115 uint32_t i;
122 uint32_t temp_time = unix_time(); 116 uint32_t temp_time = unix_time();
123 117
124 for(i = 0; i < length; ++i) 118 for(i = 0; i < length; ++i) {
125 {
126 /*If ip_port is assigned to a different client_id replace it*/ 119 /*If ip_port is assigned to a different client_id replace it*/
127 if(list[i].ip_port.ip.i == ip_port.ip.i && 120 if(list[i].ip_port.ip.i == ip_port.ip.i &&
128 list[i].ip_port.port == ip_port.port) 121 list[i].ip_port.port == ip_port.port) {
129 {
130 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 122 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
131 } 123 }
132 124
133 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 125 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
134 {
135 /* Refresh the client timestamp. */ 126 /* Refresh the client timestamp. */
136 list[i].timestamp = temp_time; 127 list[i].timestamp = temp_time;
137 list[i].ip_port.ip.i = ip_port.ip.i; 128 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -148,10 +139,8 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
148int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 139int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
149{ 140{
150 uint32_t i; 141 uint32_t i;
151 for(i = 0; i < length; ++i) 142 for(i = 0; i < length; ++i) {
152 { 143 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
153 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
154 {
155 144
156 return 1; 145 return 1;
157 } 146 }
@@ -160,14 +149,25 @@ int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
160 149
161} 150}
162 151
163 152/*Return the friend number from the client_id
153 Return -1 if failure, number of friend if success*/
154static int friend_number(uint8_t * client_id)
155{
156 uint32_t i;
157 for(i = 0; i < num_friends; ++i) {
158 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */
159 {
160 return i;
161 }
162 }
163 return -1;
164}
164 165
165/* the number of seconds for a non responsive node to become bad. */ 166/* the number of seconds for a non responsive node to become bad. */
166#define BAD_NODE_TIMEOUT 130 167#define BAD_NODE_TIMEOUT 70
167/* the max number of nodes to send with send nodes. */ 168/* the max number of nodes to send with send nodes. */
168#define MAX_SENT_NODES 8 169#define MAX_SENT_NODES 8
169 170
170
171/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 171/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
172 put them in the nodes_list and return how many were found. 172 put them in the nodes_list and return how many were found.
173 TODO: Make this function much more efficient. */ 173 TODO: Make this function much more efficient. */
@@ -176,48 +176,35 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
176 uint32_t i, j, k; 176 uint32_t i, j, k;
177 int num_nodes=0; 177 int num_nodes=0;
178 uint32_t temp_time = unix_time(); 178 uint32_t temp_time = unix_time();
179 for(i = 0; i < LCLIENT_LIST; ++i) 179 for(i = 0; i < LCLIENT_LIST; ++i) {
180 {
181 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 180 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
182 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) 181 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
183 /* if node is good and not already in list. */ 182 /* if node is good and not already in list. */
184 { 183 if(num_nodes < MAX_SENT_NODES) {
185 if(num_nodes < MAX_SENT_NODES)
186 {
187 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 184 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
188 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 185 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
189 num_nodes++; 186 num_nodes++;
190 } 187 }
191 else for(j = 0; j < MAX_SENT_NODES; ++j) 188 else for(j = 0; j < MAX_SENT_NODES; ++j) {
192 { 189 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
193 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2)
194 {
195 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 190 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
196 nodes_list[j].ip_port = close_clientlist[i].ip_port; 191 nodes_list[j].ip_port = close_clientlist[i].ip_port;
197 break; 192 break;
198 } 193 }
199 } 194 }
200 } 195 }
201
202 } 196 }
203 for(i = 0; i < num_friends; ++i) 197 for(i = 0; i < num_friends; ++i) {
204 { 198 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
205 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
206 {
207 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && 199 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
208 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) 200 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
209 /* if node is good and not already in list. */ 201 /* if node is good and not already in list. */
210 { 202 if(num_nodes < MAX_SENT_NODES) {
211 if(num_nodes < MAX_SENT_NODES)
212 {
213 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 203 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
214 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 204 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
215 num_nodes++; 205 num_nodes++;
216 } 206 } else for(k = 0; k < MAX_SENT_NODES; ++k) {
217 else for(k = 0; k < MAX_SENT_NODES; ++k) 207 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
218 {
219 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2)
220 {
221 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 208 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
222 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 209 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
223 break; 210 break;
@@ -227,12 +214,9 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
227 } 214 }
228 } 215 }
229 216
230 return num_nodes; 217 return num_nodes;
231
232} 218}
233 219
234
235
236/* replace first bad (or empty) node with this one 220/* replace first bad (or empty) node with this one
237 return 0 if successful 221 return 0 if successful
238 return 1 if not (list contains no bad nodes) */ 222 return 1 if not (list contains no bad nodes) */
@@ -240,10 +224,8 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
240{ 224{
241 uint32_t i; 225 uint32_t i;
242 uint32_t temp_time = unix_time(); 226 uint32_t temp_time = unix_time();
243 for(i = 0; i < length; ++i) 227 for(i = 0; i < length; ++i) {
244 { 228 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ {
245 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */
246 {
247 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 229 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
248 list[i].ip_port = ip_port; 230 list[i].ip_port = ip_port;
249 list[i].timestamp = temp_time; 231 list[i].timestamp = temp_time;
@@ -263,10 +245,8 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
263 uint32_t i; 245 uint32_t i;
264 uint32_t temp_time = unix_time(); 246 uint32_t temp_time = unix_time();
265 247
266 for(i = 0; i < length; ++i) 248 for(i = 0; i < length; ++i) {
267 { 249 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
268 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2)
269 {
270 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 250 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
271 list[i].ip_port = ip_port; 251 list[i].ip_port = ip_port;
272 list[i].timestamp = temp_time; 252 list[i].timestamp = temp_time;
@@ -286,23 +266,16 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
286 uint32_t i; 266 uint32_t i;
287 267
288 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 268 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
289 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 269 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
290 {
291 270
292 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 271 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
293 {
294 /* if we can't replace bad nodes we try replacing good ones */ 272 /* if we can't replace bad nodes we try replacing good ones */
295 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); 273 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key);
296 } 274 }
297
298 } 275 }
299 for(i = 0; i < num_friends; ++i) 276 for(i = 0; i < num_friends; ++i) {
300 { 277 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
301 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 278 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
302 {
303
304 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
305 {
306 /* if we can't replace bad nodes we try replacing good ones. */ 279 /* if we can't replace bad nodes we try replacing good ones. */
307 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 280 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
308 } 281 }
@@ -316,12 +289,9 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
316{ 289{
317 uint32_t i, j; 290 uint32_t i, j;
318 uint32_t temp_time = unix_time(); 291 uint32_t temp_time = unix_time();
319 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) 292 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
320 { 293 for(i = 0; i < LCLIENT_LIST; ++i) {
321 for(i = 0; i < LCLIENT_LIST; ++i) 294 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
322 {
323 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
324 {
325 close_clientlist[i].ret_ip_port = ip_port; 295 close_clientlist[i].ret_ip_port = ip_port;
326 close_clientlist[i].ret_timestamp = temp_time; 296 close_clientlist[i].ret_timestamp = temp_time;
327 return; 297 return;
@@ -329,14 +299,10 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
329 } 299 }
330 } 300 }
331 else 301 else
332 for(i = 0; i < num_friends; ++i) 302 for(i = 0; i < num_friends; ++i) {
333 { 303 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) {
334 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 304 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
335 { 305 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
336 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
337 {
338 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0)
339 {
340 friends_list[i].client_list[j].ret_ip_port = ip_port; 306 friends_list[i].client_list[j].ret_ip_port = ip_port;
341 friends_list[i].client_list[j].ret_timestamp = temp_time; 307 friends_list[i].client_list[j].ret_timestamp = temp_time;
342 return; 308 return;
@@ -348,6 +314,7 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
348 314
349/* ping timeout in seconds */ 315/* ping timeout in seconds */
350#define PING_TIMEOUT 5 316#define PING_TIMEOUT 5
317
351/* check if we are currently pinging an ip_port and/or a ping_id 318/* check if we are currently pinging an ip_port and/or a ping_id
352 variables with values of zero will not be checked. 319 variables with values of zero will not be checked.
353 if we are already, return 1 320 if we are already, return 1
@@ -359,28 +326,22 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
359 uint8_t pinging; 326 uint8_t pinging;
360 uint32_t temp_time = unix_time(); 327 uint32_t temp_time = unix_time();
361 328
362 for(i = 0; i < LPING_ARRAY; ++i ) 329 for(i = 0; i < LPING_ARRAY; ++i ) {
363 { 330 if((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
364 if((pings[i].timestamp + PING_TIMEOUT) > temp_time)
365 {
366 pinging = 0; 331 pinging = 0;
367 if(ip_port.ip.i != 0) 332 if(ip_port.ip.i != 0) {
368 {
369 if(pings[i].ip_port.ip.i == ip_port.ip.i && 333 if(pings[i].ip_port.ip.i == ip_port.ip.i &&
370 pings[i].ip_port.port == ip_port.port) 334 pings[i].ip_port.port == ip_port.port) {
371 {
372 ++pinging; 335 ++pinging;
373 } 336 }
374 } 337 }
375 if(ping_id != 0) 338 if(ping_id != 0) {
376 {
377 if(pings[i].ping_id == ping_id) 339 if(pings[i].ping_id == ping_id)
378 { 340 {
379 ++pinging; 341 ++pinging;
380 } 342 }
381 } 343 }
382 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 344 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
383 {
384 return 1; 345 return 1;
385 } 346 }
386 347
@@ -391,7 +352,6 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
391 352
392} 353}
393 354
394
395/* Same as last function but for get_node requests. */ 355/* Same as last function but for get_node requests. */
396int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) 356int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
397{ 357{
@@ -399,28 +359,21 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
399 uint8_t pinging; 359 uint8_t pinging;
400 uint32_t temp_time = unix_time(); 360 uint32_t temp_time = unix_time();
401 361
402 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) 362 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
403 { 363 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
404 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time)
405 {
406 pinging = 0; 364 pinging = 0;
407 if(ip_port.ip.i != 0) 365 if(ip_port.ip.i != 0) {
408 {
409 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 366 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
410 send_nodes[i].ip_port.port == ip_port.port) 367 send_nodes[i].ip_port.port == ip_port.port) {
411 {
412 ++pinging; 368 ++pinging;
413 } 369 }
414 } 370 }
415 if(ping_id != 0) 371 if(ping_id != 0) {
416 { 372 if(send_nodes[i].ping_id == ping_id) {
417 if(send_nodes[i].ping_id == ping_id)
418 {
419 ++pinging; 373 ++pinging;
420 } 374 }
421 } 375 }
422 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 376 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
423 {
424 return 1; 377 return 1;
425 } 378 }
426 379
@@ -431,7 +384,6 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
431 384
432} 385}
433 386
434
435/* Add a new ping request to the list of ping requests 387/* Add a new ping request to the list of ping requests
436 returns the ping_id to put in the ping request 388 returns the ping_id to put in the ping request
437 returns 0 if problem. 389 returns 0 if problem.
@@ -442,12 +394,9 @@ uint64_t add_pinging(IP_Port ip_port)
442 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 394 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
443 uint32_t temp_time = unix_time(); 395 uint32_t temp_time = unix_time();
444 396
445 for(i = 0; i < PING_TIMEOUT; ++i ) 397 for(i = 0; i < PING_TIMEOUT; ++i ) {
446 { 398 for(j = 0; j < LPING_ARRAY; ++j ) {
447 for(j = 0; j < LPING_ARRAY; ++j ) 399 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
448 {
449 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time)
450 {
451 pings[j].timestamp = temp_time; 400 pings[j].timestamp = temp_time;
452 pings[j].ip_port = ip_port; 401 pings[j].ip_port = ip_port;
453 pings[j].ping_id = ping_id; 402 pings[j].ping_id = ping_id;
@@ -466,12 +415,9 @@ uint64_t add_gettingnodes(IP_Port ip_port)
466 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 415 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
467 uint32_t temp_time = unix_time(); 416 uint32_t temp_time = unix_time();
468 417
469 for(i = 0; i < PING_TIMEOUT; ++i ) 418 for(i = 0; i < PING_TIMEOUT; ++i ) {
470 { 419 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
471 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 420 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
472 {
473 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time)
474 {
475 send_nodes[j].timestamp = temp_time; 421 send_nodes[j].timestamp = temp_time;
476 send_nodes[j].ip_port = ip_port; 422 send_nodes[j].ip_port = ip_port;
477 send_nodes[j].ping_id = ping_id; 423 send_nodes[j].ping_id = ping_id;
@@ -483,25 +429,20 @@ uint64_t add_gettingnodes(IP_Port ip_port)
483 429
484} 430}
485 431
486
487
488/* send a ping request 432/* send a ping request
489 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ 433 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */
490static int pingreq(IP_Port ip_port, uint8_t * public_key) 434static int pingreq(IP_Port ip_port, uint8_t * public_key)
491{ 435{
492 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 436 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
493 {
494 return 1; 437 return 1;
495 } 438 }
496 439
497 if(is_pinging(ip_port, 0)) 440 if(is_pinging(ip_port, 0)) {
498 {
499 return 1; 441 return 1;
500 } 442 }
501 443
502 uint64_t ping_id = add_pinging(ip_port); 444 uint64_t ping_id = add_pinging(ip_port);
503 if(ping_id == 0) 445 if(ping_id == 0) {
504 {
505 return 1; 446 return 1;
506 } 447 }
507 448
@@ -511,8 +452,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
511 random_nonce(nonce); 452 random_nonce(nonce);
512 453
513 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 454 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
514 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 455 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
515 {
516 return -1; 456 return -1;
517 } 457 }
518 data[0] = 0; 458 data[0] = 0;
@@ -524,12 +464,11 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
524 464
525} 465}
526 466
527
528/* send a ping response */ 467/* send a ping response */
529static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) 468static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
530{ 469{
531 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 470 /* check if packet is gonna be sent to ourself */
532 { 471 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
533 return 1; 472 return 1;
534 } 473 }
535 474
@@ -539,8 +478,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
539 random_nonce(nonce); 478 random_nonce(nonce);
540 479
541 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 480 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
542 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 481 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
543 {
544 return -1; 482 return -1;
545 } 483 }
546 data[0] = 1; 484 data[0] = 1;
@@ -555,20 +493,18 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
555/* send a getnodes request */ 493/* send a getnodes request */
556static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 494static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
557{ 495{
558 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 496 /* check if packet is gonna be sent to ourself */
559 { 497 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
560 return 1; 498 return 1;
561 } 499 }
562 500
563 if(is_gettingnodes(ip_port, 0)) 501 if(is_gettingnodes(ip_port, 0)) {
564 {
565 return 1; 502 return 1;
566 } 503 }
567 504
568 uint64_t ping_id = add_gettingnodes(ip_port); 505 uint64_t ping_id = add_gettingnodes(ip_port);
569 506
570 if(ping_id == 0) 507 if(ping_id == 0) {
571 {
572 return 1; 508 return 1;
573 } 509 }
574 510
@@ -583,8 +519,7 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
583 519
584 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 520 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
585 521
586 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 522 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
587 {
588 return -1; 523 return -1;
589 } 524 }
590 data[0] = 2; 525 data[0] = 2;
@@ -595,12 +530,10 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
595 530
596} 531}
597 532
598
599/* send a send nodes response */ 533/* send a send nodes response */
600static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 534static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
601{ 535{
602 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 536 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
603 {
604 return 1; 537 return 1;
605 } 538 }
606 539
@@ -610,8 +543,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
610 Node_format nodes_list[MAX_SENT_NODES]; 543 Node_format nodes_list[MAX_SENT_NODES];
611 int num_nodes = get_close_nodes(client_id, nodes_list); 544 int num_nodes = get_close_nodes(client_id, nodes_list);
612 545
613 if(num_nodes == 0) 546 if(num_nodes == 0) {
614 {
615 return 0; 547 return 0;
616 } 548 }
617 549
@@ -626,8 +558,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
626 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 558 int len = encrypt_data(public_key, self_secret_key, nonce, plain,
627 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 559 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
628 560
629 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 561 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) {
630 {
631 return -1; 562 return -1;
632 } 563 }
633 564
@@ -640,20 +571,17 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
640 571
641} 572}
642 573
643
644
645/* Packet handling functions 574/* Packet handling functions
646 One to handle each types of packets we receive 575 One to handle each types of packets we receive
647 return 0 if handled correctly, 1 if packet is bad. */ 576 return 0 if handled correctly, 1 if packet is bad. */
648int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) 577int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
649{ 578{
650 uint64_t ping_id; 579 uint64_t ping_id;
651 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 580 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
652 {
653 return 1; 581 return 1;
654 } 582 }
655 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 583 /* check if packet is from ourself. */
656 { 584 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
657 return 1; 585 return 1;
658 } 586 }
659 587
@@ -662,8 +590,7 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
662 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 590 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
663 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 591 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
664 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 592 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
665 if(len != sizeof(ping_id)) 593 if(len != sizeof(ping_id)) {
666 {
667 return 1; 594 return 1;
668 } 595 }
669 596
@@ -679,12 +606,10 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
679int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) 606int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
680{ 607{
681 uint64_t ping_id; 608 uint64_t ping_id;
682 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 609 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
683 {
684 return 1; 610 return 1;
685 } 611 }
686 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 612 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ {
687 {
688 return 1; 613 return 1;
689 } 614 }
690 615
@@ -693,13 +618,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
693 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 618 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
694 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 619 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
695 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 620 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
696 if(len != sizeof(ping_id)) 621 if(len != sizeof(ping_id)) {
697 {
698 return 1; 622 return 1;
699 } 623 }
700 624
701 if(is_pinging(source, ping_id)) 625 if(is_pinging(source, ping_id)) {
702 {
703 addto_lists(source, packet + 1); 626 addto_lists(source, packet + 1);
704 return 0; 627 return 0;
705 } 628 }
@@ -710,12 +633,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
710int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 633int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
711{ 634{
712 uint64_t ping_id; 635 uint64_t ping_id;
713 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 636 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
714 {
715 return 1; 637 return 1;
716 } 638 }
717 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 639 /* check if packet is from ourself. */
718 { 640 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
719 return 1; 641 return 1;
720 } 642 }
721 643
@@ -725,8 +647,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
725 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 647 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
726 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 648 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
727 649
728 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 650 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) {
729 {
730 return 1; 651 return 1;
731 } 652 }
732 653
@@ -748,8 +669,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
748 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 669 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
749 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 670 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
750 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 671 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
751 + sizeof(Node_format) + ENCRYPTION_PADDING) 672 + sizeof(Node_format) + ENCRYPTION_PADDING) {
752 {
753 return 1; 673 return 1;
754 } 674 }
755 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 675 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
@@ -762,14 +682,12 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
762 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 682 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
763 683
764 684
765 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 685 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) {
766 {
767 return 1; 686 return 1;
768 } 687 }
769 688
770 memcpy(&ping_id, plain, sizeof(ping_id)); 689 memcpy(&ping_id, plain, sizeof(ping_id));
771 if(!is_gettingnodes(source, ping_id)) 690 if(!is_gettingnodes(source, ping_id)) {
772 {
773 return 1; 691 return 1;
774 } 692 }
775 693
@@ -779,8 +697,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
779 addto_lists(source, packet + 1); 697 addto_lists(source, packet + 1);
780 698
781 uint32_t i; 699 uint32_t i;
782 for(i = 0; i < num_nodes; ++i) 700 for(i = 0; i < num_nodes; ++i) {
783 {
784 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); 701 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
785 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 702 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
786 } 703 }
@@ -793,44 +710,36 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
793int DHT_addfriend(uint8_t * client_id) 710int DHT_addfriend(uint8_t * client_id)
794{ 711{
795 Friend * temp; 712 Friend * temp;
796 if(num_friends == 0) 713 if(num_friends == 0) {
797 {
798 temp = malloc(sizeof(Friend)); 714 temp = malloc(sizeof(Friend));
799 } 715 } else {
800 else
801 {
802 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 716 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
803 } 717 }
804 if(temp == NULL) 718 if(temp == NULL) {
805 {
806 return 1; 719 return 1;
807 } 720 }
808 721
809 friends_list = temp; 722 friends_list = temp;
810 memset(&friends_list[num_friends], 0, sizeof(Friend)); 723 memset(&friends_list[num_friends], 0, sizeof(Friend));
811 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 724 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
725 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
812 ++num_friends; 726 ++num_friends;
813 return 0; 727 return 0;
814} 728}
815 729
816
817
818int DHT_delfriend(uint8_t * client_id) 730int DHT_delfriend(uint8_t * client_id)
819{ 731{
820 uint32_t i; 732 uint32_t i;
821 Friend * temp; 733 Friend * temp;
822 for(i = 0; i < num_friends; ++i) 734 for(i = 0; i < num_friends; ++i) {
823 { 735 /* Equal */
824 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 736 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0){
825 {
826 --num_friends; 737 --num_friends;
827 if(num_friends != i) 738 if(num_friends != i) {
828 {
829 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); 739 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE);
830 } 740 }
831 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 741 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
832 if(temp != NULL) 742 if(temp != NULL) {
833 {
834 friends_list = temp; 743 friends_list = temp;
835 } 744 }
836 return 0; 745 return 0;
@@ -839,61 +748,27 @@ int DHT_delfriend(uint8_t * client_id)
839 return 1; 748 return 1;
840} 749}
841 750
842
843
844
845/* TODO: Optimize this. */ 751/* TODO: Optimize this. */
846IP_Port DHT_getfriendip(uint8_t * client_id) 752IP_Port DHT_getfriendip(uint8_t * client_id)
847{ 753{
848 uint32_t i, j; 754 uint32_t i, j;
849 IP_Port empty = {{{0}}, 0}; 755 IP_Port empty = {{{0}}, 0};
850 uint32_t temp_time = unix_time(); 756 uint32_t temp_time = unix_time();
851 for(i = 0; i < num_friends; ++i) 757 for(i = 0; i < num_friends; ++i) {
852 { 758 /* Equal */
853 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 759 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
854 { 760 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
855 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
856 {
857 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 761 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
858 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 762 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) {
859 {
860 return friends_list[i].client_list[j].ip_port; 763 return friends_list[i].client_list[j].ip_port;
861 } 764 }
862 765 }
863 }
864
865 return empty; 766 return empty;
866 } 767 }
867 } 768 }
868 empty.ip.i = 1; 769 empty.ip.i = 1;
869 return empty; 770 return empty;
870 771
871}
872
873
874
875int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
876{
877 switch (packet[0]) {
878 case 0:
879 return handle_pingreq(packet, length, source);
880
881 case 1:
882 return handle_pingres(packet, length, source);
883
884 case 2:
885 return handle_getnodes(packet, length, source);
886
887 case 3:
888 return handle_sendnodes(packet, length, source);
889
890 default:
891 return 1;
892
893 }
894
895 return 0;
896
897} 772}
898 773
899/* The timeout after which a node is discarded completely. */ 774/* The timeout after which a node is discarded completely. */
@@ -907,8 +782,6 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
907 782
908/* Ping each client in the "friends" list every 60 seconds. 783/* Ping each client in the "friends" list every 60 seconds.
909 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ 784 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */
910
911
912void doDHTFriends() 785void doDHTFriends()
913{ 786{
914 uint32_t i, j; 787 uint32_t i, j;
@@ -916,27 +789,21 @@ void doDHTFriends()
916 uint32_t rand_node; 789 uint32_t rand_node;
917 uint32_t index[MAX_FRIEND_CLIENTS]; 790 uint32_t index[MAX_FRIEND_CLIENTS];
918 791
919 for(i = 0; i < num_friends; ++i) 792 for(i = 0; i < num_friends; ++i) {
920 {
921 uint32_t num_nodes = 0; 793 uint32_t num_nodes = 0;
922 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 794 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
923 { 795 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ {
924 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 796 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
925 {
926 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time)
927 {
928 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 797 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
929 friends_list[i].client_list[j].last_pinged = temp_time; 798 friends_list[i].client_list[j].last_pinged = temp_time;
930 } 799 }
931 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 800 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ {
932 {
933 index[num_nodes] = j; 801 index[num_nodes] = j;
934 ++num_nodes; 802 ++num_nodes;
935 } 803 }
936 } 804 }
937 } 805 }
938 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 806 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
939 {
940 rand_node = rand() % num_nodes; 807 rand_node = rand() % num_nodes;
941 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 808 getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
942 friends_list[i].client_list[index[rand_node]].client_id, 809 friends_list[i].client_list[index[rand_node]].client_id,
@@ -958,66 +825,77 @@ void doClose() /* tested */
958 uint32_t rand_node; 825 uint32_t rand_node;
959 uint32_t index[LCLIENT_LIST]; 826 uint32_t index[LCLIENT_LIST];
960 827
961 for(i = 0; i < LCLIENT_LIST; ++i) 828 for(i = 0; i < LCLIENT_LIST; ++i) {
962 { 829 /* if node is not dead. */
963 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 830 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
964 {
965 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) 831 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time)
966 { 832 {
967 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 833 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
968 close_clientlist[i].last_pinged = temp_time; 834 close_clientlist[i].last_pinged = temp_time;
969 } 835 }
970 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 836 /* if node is good. */
971 { 837 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
972 index[num_nodes] = i; 838 index[num_nodes] = i;
973 ++num_nodes; 839 ++num_nodes;
974 } 840 }
975 } 841 }
976 } 842 }
977 843
978 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 844 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
979 {
980 rand_node = rand() % num_nodes; 845 rand_node = rand() % num_nodes;
981 getnodes(close_clientlist[index[rand_node]].ip_port, 846 getnodes(close_clientlist[index[rand_node]].ip_port,
982 close_clientlist[index[rand_node]].client_id, 847 close_clientlist[index[rand_node]].client_id,
983 self_public_key); 848 self_public_key);
984 close_lastgetnodes = temp_time; 849 close_lastgetnodes = temp_time;
985 } 850 }
986
987}
988
989
990
991void doDHT()
992{
993 doClose();
994 doDHTFriends();
995} 851}
996 852
997
998
999void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 853void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
1000{ 854{
1001 getnodes(ip_port, public_key, self_public_key); 855 getnodes(ip_port, public_key, self_public_key);
1002} 856}
1003 857
1004
1005
1006/* send the given packet to node with client_id 858/* send the given packet to node with client_id
1007 returns -1 if failure */ 859 returns -1 if failure */
1008int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 860int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
1009{ 861{
1010 uint32_t i; 862 uint32_t i;
1011 for(i = 0; i < LCLIENT_LIST; ++i) 863 for(i = 0; i < LCLIENT_LIST; ++i) {
1012 { 864 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
1013 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
1014 {
1015 return sendpacket(close_clientlist[i].ip_port, packet, length); 865 return sendpacket(close_clientlist[i].ip_port, packet, length);
1016 } 866 }
1017 } 867 }
1018 return -1; 868 return -1;
1019} 869}
1020 870
871/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
872 ip_portlist must be at least MAX_FRIEND_CLIENTS big
873 returns the number of ips returned
874 return 0 if we are connected to friend or if no ips were found.
875 returns -1 if no such friend*/
876static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
877{
878 int num_ips = 0;
879 uint32_t i;
880 uint32_t temp_time = unix_time();
881 if(friend_num >= num_friends) {
882 return -1;
883 }
884 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
885 {
886 /*If ip is not zero and node is good */
887 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
888 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
889 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) {
890 return 0;
891 }
892 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
893 ++num_ips;
894 }
895 }
896 return num_ips;
897}
898
1021/* Send the following packet to everyone who tells us they are connected to friend_id 899/* Send the following packet to everyone who tells us they are connected to friend_id
1022 returns the number of nodes it sent the packet to */ 900 returns the number of nodes it sent the packet to */
1023int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 901int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
@@ -1025,18 +903,14 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1025 uint32_t i, j; 903 uint32_t i, j;
1026 uint32_t sent = 0; 904 uint32_t sent = 0;
1027 uint32_t temp_time = unix_time(); 905 uint32_t temp_time = unix_time();
1028 for(i = 0; i < num_friends; ++i) 906 for(i = 0; i < num_friends; ++i) {
1029 { 907 /* Equal */
1030 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 908 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
1031 { 909 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1032 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 910 /*If ip is not zero and node is good */
1033 {
1034 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 911 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
1035 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 912 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1036 /*If ip is not zero and node is good */ 913 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) {
1037 {
1038 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
1039 {
1040 ++sent; 914 ++sent;
1041 } 915 }
1042 } 916 }
@@ -1047,34 +921,255 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1047 return 0; 921 return 0;
1048} 922}
1049 923
924/* Send the following packet to one random person who tells us they are connected to friend_id
925 returns the number of nodes it sent the packet to */
926int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
927{
928 int num = friend_number(friend_id);
929 if(num == -1) {
930 return 0;
931 }
932
933 IP_Port ip_list[MAX_FRIEND_CLIENTS];
934 int n = 0;
935 uint32_t i;
936 uint32_t temp_time = unix_time();
937 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
938 /*If ip is not zero and node is good */
939 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
940 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
941 ip_list[n] = friends_list[num].client_list[i].ip_port;
942 ++n;
943 }
944 }
945 if(n < 1) {
946 return 0;
947 }
948 if(sendpacket(ip_list[rand() % n], packet, length) == length) {
949 return 1;
950 }
951 return 0;
952}
953
1050/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 954/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
1051 ip_portlist must be at least MAX_FRIEND_CLIENTS big 955 ip_portlist must be at least MAX_FRIEND_CLIENTS big
1052 returns the number of ips returned 956 returns the number of ips returned
957 return 0 if we are connected to friend or if no ips were found.
1053 returns -1 if no such friend*/ 958 returns -1 if no such friend*/
1054int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 959int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
1055{ 960{
1056 int num_ips = 0; 961
962 uint32_t i;
963 for(i = 0; i < num_friends; ++i) {
964 /* Equal */
965 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
966 return friend_iplist(ip_portlist, i);
967 }
968 }
969 return -1;
970}
971
972/*BEGINNING OF NAT PUNCHING FUNCTIONS*/
973
974int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
975{
976 uint8_t data[sizeof(uint64_t) + 1];
977 data[0] = type;
978 memcpy(data + 1, &ping_id, sizeof(uint64_t));
979
980 uint8_t packet[MAX_DATA_SIZE];
981 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
982 if(len == -1) {
983 return -1;
984 }
985 int num = 0;
986 if(type == 0) {
987 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
988 }
989 else if(type == 1) {
990 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
991 }
992 if(num == 0) {
993 return -1;
994 }
995 return num;
996}
997
998/* Handle a recieved ping request for */
999int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1000{
1001 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
1002 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) {
1003 return 1;
1004 }
1005 /* check if request is for us. */
1006 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1007 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
1008 uint8_t data[MAX_DATA_SIZE];
1009 int len = handle_request(public_key, data, packet, length);
1010 if(len != sizeof(uint64_t) + 1) {
1011 return 1;
1012 }
1013 uint64_t ping_id;
1014 memcpy(&ping_id, data + 1, sizeof(uint64_t));
1015
1016 int friendnumber = friend_number(public_key);
1017 if(friendnumber == -1) {
1018 return 1;
1019 }
1020
1021 if(data[0] == 0) {
1022 send_NATping(public_key, ping_id, 1);/*1 is reply*/
1023 return 0;
1024 } else if (data[0] == 1) {
1025 if(friends_list[friendnumber].NATping_id == ping_id)
1026 {
1027 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int();
1028 friends_list[friendnumber].hole_punching = 1;
1029 return 0;
1030 }
1031 }
1032 return 1;
1033 }
1034 /* if request is not for us, try routing it. */
1035 else {
1036 if(route_packet(packet + 1, packet, length) == length) {
1037 return 0;
1038 }
1039 }
1040 return 0;
1041}
1042
1043/*Get the most common ip in the ip_portlist
1044 Only return ip if it appears in list min_num or more
1045 len must not be bigger than MAX_FRIEND_CLIENTS
1046 return ip of 0 if failure */
1047static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
1048{
1049 IP zero = {{0}};
1050 if(len > MAX_FRIEND_CLIENTS) {
1051 return zero;
1052 }
1053
1057 uint32_t i, j; 1054 uint32_t i, j;
1055 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
1056 for(i = 0; i < len; ++i) {
1057 for(j = 0; j < len; ++j) {
1058 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) {
1059 ++numbers[i];
1060 }
1061 }
1062 if(numbers[i] >= min_num) {
1063 return ip_portlist[i].ip;
1064 }
1065 }
1066 return zero;
1067}
1068
1069/*Return all the ports for one ip in a list
1070 portlist must be at least len long
1071 where len is the length of ip_portlist
1072 returns the number of ports and puts the list of ports in portlist*/
1073static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip)
1074{
1075 uint32_t i;
1076 uint16_t num = 0;
1077 for(i = 0; i < len; ++i) {
1078 if(ip_portlist[i].ip.i == ip.i) {
1079 portlist[num] = ntohs(ip_portlist[i].port);
1080 ++num;
1081 }
1082 }
1083 return num;
1084}
1085
1086#define MAX_PUNCHING_PORTS 32
1087
1088static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num)
1089{
1090 if(numports > MAX_FRIEND_CLIENTS || numports == 0) {
1091 return;
1092 }
1093 uint32_t i;
1094 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1095 for(i = friends_list[friend_num].punching_index; i != top; i++) {
1096 /*TODO: improve port guessing algorithm*/
1097 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
1098 IP_Port pinging = {ip, htons(port)};
1099 pingreq(pinging, friends_list[friend_num].client_id);
1100 }
1101 friends_list[friend_num].punching_index = i;
1102}
1103
1104/*Interval in seconds between punching attempts*/
1105#define PUNCH_INTERVAL 10
1106
1107static void doNAT()
1108{
1109 uint32_t i;
1058 uint32_t temp_time = unix_time(); 1110 uint32_t temp_time = unix_time();
1059 for(i = 0; i < num_friends; ++i) 1111 for(i = 0; i < num_friends; ++i) {
1060 { 1112 IP_Port ip_list[MAX_FRIEND_CLIENTS];
1061 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 1113 int num = friend_iplist(ip_list, i);
1062 { 1114 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
1063 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1115 if(num < MAX_FRIEND_CLIENTS/2) {
1064 { 1116 continue;
1065 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 1117 }
1066 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 1118 if(friends_list[i].hole_punching != 1) {
1067 /*If ip is not zero and node is good */ 1119 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1068 { 1120 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1069 ip_portlist[num_ips] = friends_list[i].client_list[j].ret_ip_port; 1121 friends_list[i].NATping_timestamp = temp_time;
1070 ++num_ips;
1071 }
1072 } 1122 }
1073 return num_ips;
1074 } 1123 }
1124 else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
1125 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1126 if(ip.i == 0) {
1127 continue;
1128 }
1129 uint16_t port_list[MAX_FRIEND_CLIENTS];
1130 uint16_t numports = NAT_getports(port_list, ip_list, num, ip);
1131 punch_holes(ip, port_list, numports, i);
1132
1133 friends_list[i].punching_timestamp = temp_time;
1134 friends_list[i].hole_punching = 0;
1135 }
1136 }
1137}
1138
1139/*END OF NAT PUNCHING FUNCTIONS*/
1140
1141int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1142{
1143 switch (packet[0]) {
1144 case 0:
1145 return handle_pingreq(packet, length, source);
1146
1147 case 1:
1148 return handle_pingres(packet, length, source);
1149
1150 case 2:
1151 return handle_getnodes(packet, length, source);
1152
1153 case 3:
1154 return handle_sendnodes(packet, length, source);
1155
1156 case 254:
1157 return handle_NATping(packet, length, source);
1158
1159 default:
1160 return 1;
1075 1161
1076 } 1162 }
1163
1077 return 0; 1164 return 0;
1165
1166}
1167
1168void doDHT()
1169{
1170 doClose();
1171 doDHTFriends();
1172 doNAT();
1078} 1173}
1079 1174
1080/* get the size of the DHT (for saving) */ 1175/* get the size of the DHT (for saving) */
@@ -1095,12 +1190,10 @@ void DHT_save(uint8_t * data)
1095 return 0 if success */ 1190 return 0 if success */
1096int DHT_load(uint8_t * data, uint32_t size) 1191int DHT_load(uint8_t * data, uint32_t size)
1097{ 1192{
1098 if(size < sizeof(close_clientlist)) 1193 if(size < sizeof(close_clientlist)) {
1099 {
1100 return -1; 1194 return -1;
1101 } 1195 }
1102 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1196 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) {
1103 {
1104 return -1; 1197 return -1;
1105 } 1198 }
1106 uint32_t i, j; 1199 uint32_t i, j;
@@ -1109,17 +1202,13 @@ int DHT_load(uint8_t * data, uint32_t size)
1109 1202
1110 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1203 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1111 1204
1112 if(temp != 0) 1205 if(temp != 0) {
1113 {
1114 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1206 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1115 1207
1116 for(i = 0; i < temp; ++i) 1208 for(i = 0; i < temp; ++i) {
1117 {
1118 DHT_addfriend(tempfriends_list[i].client_id); 1209 DHT_addfriend(tempfriends_list[i].client_id);
1119 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1210 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1120 { 1211 if(tempfriends_list[i].client_list[j].timestamp != 0) {
1121 if(tempfriends_list[i].client_list[j].timestamp != 0)
1122 {
1123 getnodes(tempfriends_list[i].client_list[j].ip_port, 1212 getnodes(tempfriends_list[i].client_list[j].ip_port,
1124 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1213 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
1125 } 1214 }
@@ -1128,10 +1217,8 @@ int DHT_load(uint8_t * data, uint32_t size)
1128 } 1217 }
1129 Client_data * tempclose_clientlist = (Client_data *)data; 1218 Client_data * tempclose_clientlist = (Client_data *)data;
1130 1219
1131 for(i = 0; i < LCLIENT_LIST; ++i) 1220 for(i = 0; i < LCLIENT_LIST; ++i) {
1132 { 1221 if(tempclose_clientlist[i].timestamp != 0) {
1133 if(tempclose_clientlist[i].timestamp != 0)
1134 {
1135 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); 1222 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id);
1136 } 1223 }
1137 } 1224 }
@@ -1144,13 +1231,10 @@ int DHT_isconnected()
1144{ 1231{
1145 uint32_t i; 1232 uint32_t i;
1146 uint32_t temp_time = unix_time(); 1233 uint32_t temp_time = unix_time();
1147 for(i = 0; i < LCLIENT_LIST; ++i) 1234 for(i = 0; i < LCLIENT_LIST; ++i) {
1148 { 1235 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
1149 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1150 {
1151 return 1; 1236 return 1;
1152 } 1237 }
1153 } 1238 }
1154 return 0; 1239 return 0;
1155} 1240} \ No newline at end of file
1156
diff --git a/core/DHT.h b/core/DHT.h
index fdb89de6..966645f5 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -1,27 +1,25 @@
1/* DHT.h 1/* DHT.h
2* 2 *
3* An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24
25 23
26#ifndef DHT_H 24#ifndef DHT_H
27#define DHT_H 25#define DHT_H
@@ -38,8 +36,6 @@ extern "C" {
38/* size of the client_id in bytes */ 36/* size of the client_id in bytes */
39#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
40 38
41
42
43/* Add a new friend to the friends list 39/* Add a new friend to the friends list
44 client_id must be CLIENT_ID_SIZE bytes long. 40 client_id must be CLIENT_ID_SIZE bytes long.
45 returns 0 if success 41 returns 0 if success
@@ -52,7 +48,6 @@ int DHT_addfriend(uint8_t * client_id);
52 returns 1 if failure (client_id not in friends list) */ 48 returns 1 if failure (client_id not in friends list) */
53int DHT_delfriend(uint8_t * client_id); 49int DHT_delfriend(uint8_t * client_id);
54 50
55
56/* Get ip of friend 51/* Get ip of friend
57 client_id must be CLIENT_ID_SIZE bytes long. 52 client_id must be CLIENT_ID_SIZE bytes long.
58 ip must be 4 bytes long. 53 ip must be 4 bytes long.
@@ -62,7 +57,6 @@ int DHT_delfriend(uint8_t * client_id);
62 returns ip of 1 if friend is not in list. */ 57 returns ip of 1 if friend is not in list. */
63IP_Port DHT_getfriendip(uint8_t * client_id); 58IP_Port DHT_getfriendip(uint8_t * client_id);
64 59
65
66/* Run this function at least a couple times per second (It's the main loop) */ 60/* Run this function at least a couple times per second (It's the main loop) */
67void doDHT(); 61void doDHT();
68 62
@@ -75,8 +69,6 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
75 Sends a get nodes request to the given node with ip port and public_key */ 69 Sends a get nodes request to the given node with ip port and public_key */
76void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key); 70void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key);
77 71
78
79
80/* ROUTING FUNCTIONS */ 72/* ROUTING FUNCTIONS */
81 73
82/* send the given packet to node with client_id 74/* send the given packet to node with client_id
@@ -87,8 +79,6 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length);
87 returns the number of nodes it sent the packet to */ 79 returns the number of nodes it sent the packet to */
88int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length); 80int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length);
89 81
90
91
92/* NAT PUNCHING FUNCTIONS */ 82/* NAT PUNCHING FUNCTIONS */
93 83
94/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 84/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
@@ -97,8 +87,6 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length);
97 returns -1 if no such friend*/ 87 returns -1 if no such friend*/
98int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id); 88int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id);
99 89
100
101
102/* SAVE/LOAD functions */ 90/* SAVE/LOAD functions */
103 91
104/* get the size of the DHT (for saving) */ 92/* get the size of the DHT (for saving) */
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
new file mode 100644
index 00000000..3cfcb067
--- /dev/null
+++ b/core/LAN_discovery.c
@@ -0,0 +1,79 @@
1/* LAN_discovery.c
2 *
3 * LAN discovery implementation.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
22 */
23
24#include "LAN_discovery.h"
25
26
27/*Return the broadcast ip
28 TODO: make it return the real one, not the 255.255.255.255 one.*/
29IP broadcast_ip()
30{
31 IP ip;
32 ip.i = ~0;
33 return ip;
34}
35
36/*return 0 if ip is a LAN ip
37 return -1 if it is not */
38int LAN_ip(IP ip)
39{
40 if(ip.c[0] == 127)/* Loopback */
41 return 0;
42 if(ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */
43 return 0;
44 if(ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */
45 return 0;
46 if(ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */
47 return 0;
48 if(ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */
49 return 0;
50 return -1;
51}
52
53int handle_LANdiscovery(uint8_t * packet, uint32_t length, IP_Port source)
54{
55 if(LAN_ip(source.ip) == -1)
56 return 1;
57 if(length != crypto_box_PUBLICKEYBYTES + 1)
58 return 1;
59 DHT_bootstrap(source, packet + 1);
60 return 0;
61}
62
63
64int send_LANdiscovery(uint16_t port)
65{
66 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
67 data[0] = 32;
68 memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
69 IP_Port ip_port = {broadcast_ip(), port};
70 return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
71}
72
73
74int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
75{
76 if(packet[0] == 32)
77 return handle_LANdiscovery(packet, length, source);
78 return 1;
79}
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h
new file mode 100644
index 00000000..655830f9
--- /dev/null
+++ b/core/LAN_discovery.h
@@ -0,0 +1,50 @@
1/* LAN_discovery.h
2 *
3 * LAN discovery implementation.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
22 */
23
24
25#ifndef LAN_DISCOVERY_H
26#define LAN_DISCOVERY_H
27
28
29#include "DHT.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/*Send a LAN discovery pcaket to the broadcast address with port port*/
36int send_LANdiscovery(uint16_t port);
37
38
39/* if we receive a packet we call this function so it can be handled.
40 return 0 if packet is handled correctly.
41 return 1 if it didn't handle the packet or if the packet was shit. */
42int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
43
44
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index c4c464b6..43f61b5b 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -1,32 +1,30 @@
1/* Lossless_UDP.c 1/* Lossless_UDP.c
2* 2 *
3* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt 3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/ 23
24/* TODO: clean this file a bit. 24/* TODO: clean this file a bit.
25 There are a couple of useless variables to get rid of. */ 25 There are a couple of useless variables to get rid of. */
26#include "Lossless_UDP.h" 26#include "Lossless_UDP.h"
27 27
28
29
30/* maximum data packets in sent and receive queues. */ 28/* maximum data packets in sent and receive queues. */
31#define MAX_QUEUE_NUM 16 29#define MAX_QUEUE_NUM 16
32 30
@@ -88,7 +86,6 @@ typedef struct
88 uint8_t timeout; /* connection timeout in seconds. */ 86 uint8_t timeout; /* connection timeout in seconds. */
89}Connection; 87}Connection;
90 88
91
92#define MAX_CONNECTIONS 256 89#define MAX_CONNECTIONS 256
93 90
94static Connection connections[MAX_CONNECTIONS]; 91static Connection connections[MAX_CONNECTIONS];
@@ -104,40 +101,31 @@ int getconnection_id(IP_Port ip_port)
104{ 101{
105 uint32_t i; 102 uint32_t i;
106 for(i = 0; i < MAX_CONNECTIONS; ++i) 103 for(i = 0; i < MAX_CONNECTIONS; ++i)
107 {
108 if(connections[i].ip_port.ip.i == ip_port.ip.i && 104 if(connections[i].ip_port.ip.i == ip_port.ip.i &&
109 connections[i].ip_port.port == ip_port.port && connections[i].status > 0) 105 connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
110 {
111 return i; 106 return i;
112 }
113 }
114 return -1; 107 return -1;
115} 108}
116 109
117/* table of random numbers used below. */ 110/* table of random numbers used below. */
118static uint32_t randtable[6][256]; 111static uint32_t randtable[6][256];
119 112
120
121/* generate a handshake_id which depends on the ip_port. 113/* generate a handshake_id which depends on the ip_port.
122 this function will always give one unique handshake_id per ip_port. 114 this function will always give one unique handshake_id per ip_port.
123 TODO: make this better */ 115 TODO: make this better */
124uint32_t handshake_id(IP_Port source) 116uint32_t handshake_id(IP_Port source)
125{ 117{
126 uint32_t id = 0, i; 118 uint32_t id = 0, i;
127 for(i = 0; i < 6; ++i) 119 for(i = 0; i < 6; ++i) {
128 {
129 if(randtable[i][((uint8_t *)&source)[i]] == 0) 120 if(randtable[i][((uint8_t *)&source)[i]] == 0)
130 {
131 randtable[i][((uint8_t *)&source)[i]] = random_int(); 121 randtable[i][((uint8_t *)&source)[i]] = random_int();
132 }
133 id ^= randtable[i][((uint8_t *)&source)[i]]; 122 id ^= randtable[i][((uint8_t *)&source)[i]];
134 } 123 }
135 if(id == 0) /* id can't be zero */ 124 if(id == 0) /* id can't be zero */
136 {
137 id = 1; 125 id = 1;
138 }
139 return id; 126 return id;
140} 127}
128
141/* change the hnshake id associated with that ip_port 129/* change the hnshake id associated with that ip_port
142 TODO: make this better */ 130 TODO: make this better */
143void change_handshake(IP_Port source) 131void change_handshake(IP_Port source)
@@ -146,7 +134,6 @@ void change_handshake(IP_Port source)
146 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 134 randtable[rand][((uint8_t *)&source)[rand]] = random_int();
147} 135}
148 136
149
150/* initialize a new connection to ip_port 137/* initialize a new connection to ip_port
151 returns an integer corresponding to the connection id. 138 returns an integer corresponding to the connection id.
152 return -1 if it could not initialize the connection. 139 return -1 if it could not initialize the connection.
@@ -155,14 +142,10 @@ int new_connection(IP_Port ip_port)
155{ 142{
156 int connect = getconnection_id(ip_port); 143 int connect = getconnection_id(ip_port);
157 if(connect != -1) 144 if(connect != -1)
158 {
159 return connect; 145 return connect;
160 }
161 uint32_t i; 146 uint32_t i;
162 for(i = 0; i < MAX_CONNECTIONS; ++i) 147 for(i = 0; i < MAX_CONNECTIONS; ++i) {
163 { 148 if(connections[i].status == 0) {
164 if(connections[i].status == 0)
165 {
166 memset(&connections[i], 0, sizeof(Connection)); 149 memset(&connections[i], 0, sizeof(Connection));
167 connections[i].ip_port = ip_port; 150 connections[i].ip_port = ip_port;
168 connections[i].status = 1; 151 connections[i].status = 1;
@@ -191,14 +174,10 @@ int new_connection(IP_Port ip_port)
191int new_inconnection(IP_Port ip_port) 174int new_inconnection(IP_Port ip_port)
192{ 175{
193 if(getconnection_id(ip_port) != -1) 176 if(getconnection_id(ip_port) != -1)
194 {
195 return -1; 177 return -1;
196 }
197 uint32_t i; 178 uint32_t i;
198 for(i = 0; i < MAX_CONNECTIONS; ++i) 179 for(i = 0; i < MAX_CONNECTIONS; ++i) {
199 { 180 if(connections[i].status == 0) {
200 if(connections[i].status == 0)
201 {
202 memset(&connections[i], 0, sizeof(Connection)); 181 memset(&connections[i], 0, sizeof(Connection));
203 connections[i].ip_port = ip_port; 182 connections[i].ip_port = ip_port;
204 connections[i].status = 2; 183 connections[i].status = 2;
@@ -224,13 +203,10 @@ int incoming_connection()
224{ 203{
225 uint32_t i; 204 uint32_t i;
226 for(i = 0; i < MAX_CONNECTIONS; ++i) 205 for(i = 0; i < MAX_CONNECTIONS; ++i)
227 { 206 if(connections[i].inbound == 2) {
228 if(connections[i].inbound == 2)
229 {
230 connections[i].inbound = 1; 207 connections[i].inbound = 1;
231 return i; 208 return i;
232 } 209 }
233 }
234 return -1; 210 return -1;
235} 211}
236 212
@@ -239,14 +215,11 @@ int incoming_connection()
239int kill_connection(int connection_id) 215int kill_connection(int connection_id)
240{ 216{
241 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) 217 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
242 { 218 if(connections[connection_id].status > 0) {
243 if(connections[connection_id].status > 0)
244 {
245 connections[connection_id].status = 0; 219 connections[connection_id].status = 0;
246 change_handshake(connections[connection_id].ip_port); 220 change_handshake(connections[connection_id].ip_port);
247 return 0; 221 return 0;
248 } 222 }
249 }
250 return -1; 223 return -1;
251} 224}
252 225
@@ -256,13 +229,10 @@ int kill_connection(int connection_id)
256int kill_connection_in(int connection_id, uint32_t seconds) 229int kill_connection_in(int connection_id, uint32_t seconds)
257{ 230{
258 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) 231 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
259 { 232 if(connections[connection_id].status > 0) {
260 if(connections[connection_id].status > 0)
261 {
262 connections[connection_id].killat = current_time() + 1000000UL*seconds; 233 connections[connection_id].killat = current_time() + 1000000UL*seconds;
263 return 0; 234 return 0;
264 } 235 }
265 }
266 return -1; 236 return -1;
267} 237}
268 238
@@ -275,9 +245,7 @@ int kill_connection_in(int connection_id, uint32_t seconds)
275int is_connected(int connection_id) 245int is_connected(int connection_id)
276{ 246{
277 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) 247 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
278 {
279 return connections[connection_id].status; 248 return connections[connection_id].status;
280 }
281 return 0; 249 return 0;
282} 250}
283 251
@@ -285,9 +253,7 @@ int is_connected(int connection_id)
285IP_Port connection_ip(int connection_id) 253IP_Port connection_ip(int connection_id)
286{ 254{
287 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) 255 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
288 {
289 return connections[connection_id].ip_port; 256 return connections[connection_id].ip_port;
290 }
291 IP_Port zero = {{{0}}, 0}; 257 IP_Port zero = {{{0}}, 0};
292 return zero; 258 return zero;
293} 259}
@@ -309,17 +275,15 @@ uint32_t recvqueue(int connection_id)
309char id_packet(int connection_id) 275char id_packet(int connection_id)
310{ 276{
311 if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0) 277 if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0)
312 {
313 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; 278 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
314 }
315 return -1; 279 return -1;
316} 280}
281
317/* return 0 if there is no received data in the buffer. 282/* return 0 if there is no received data in the buffer.
318 return length of received packet if successful */ 283 return length of received packet if successful */
319int read_packet(int connection_id, uint8_t * data) 284int read_packet(int connection_id, uint8_t * data)
320{ 285{
321 if(recvqueue(connection_id) != 0) 286 if(recvqueue(connection_id) != 0) {
322 {
323 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 287 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
324 uint16_t size = connections[connection_id].recvbuffer[index].size; 288 uint16_t size = connections[connection_id].recvbuffer[index].size;
325 memcpy(data, connections[connection_id].recvbuffer[index].data, size); 289 memcpy(data, connections[connection_id].recvbuffer[index].data, size);
@@ -335,15 +299,10 @@ int read_packet(int connection_id, uint8_t * data)
335int write_packet(int connection_id, uint8_t * data, uint32_t length) 299int write_packet(int connection_id, uint8_t * data, uint32_t length)
336{ 300{
337 if(length > MAX_DATA_SIZE) 301 if(length > MAX_DATA_SIZE)
338 {
339 return 0; 302 return 0;
340 }
341 if(length == 0) 303 if(length == 0)
342 {
343 return 0; 304 return 0;
344 } 305 if(sendqueue(connection_id) < BUFFER_PACKET_NUM) {
345 if(sendqueue(connection_id) < BUFFER_PACKET_NUM)
346 {
347 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; 306 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
348 memcpy(connections[connection_id].sendbuffer[index].data, data, length); 307 memcpy(connections[connection_id].sendbuffer[index].data, data, length);
349 connections[connection_id].sendbuffer[index].size = length; 308 connections[connection_id].sendbuffer[index].size = length;
@@ -353,9 +312,6 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
353 return 0; 312 return 0;
354} 313}
355 314
356
357
358
359/* put the packet numbers the we are missing in requested and return the number */ 315/* put the packet numbers the we are missing in requested and return the number */
360uint32_t missing_packets(int connection_id, uint32_t * requested) 316uint32_t missing_packets(int connection_id, uint32_t * requested)
361{ 317{
@@ -363,59 +319,47 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
363 uint32_t i; 319 uint32_t i;
364 uint32_t temp; 320 uint32_t temp;
365 if(recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ 321 if(recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */
366 {
367 return 0; 322 return 0;
368 }
369 for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) 323 for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ )
370 { 324 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
371 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0)
372 {
373 temp = htonl(i); 325 temp = htonl(i);
374 memcpy(requested + number, &temp, 4); 326 memcpy(requested + number, &temp, 4);
375 ++number; 327 ++number;
376 } 328 }
377 }
378 if(number == 0) 329 if(number == 0)
379 {
380 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 330 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
381 }
382 return number; 331 return number;
383
384} 332}
385 333
386/* Packet sending functions 334/* Packet sending functions
387 One per packet type. 335 One per packet type.
388 see docs/Lossless_UDP.txt for more information. */ 336 see docs/Lossless_UDP.txt for more information. */
389
390
391int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) 337int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
392{ 338{
393 uint8_t packet[1 + 4 + 4]; 339 uint8_t packet[1 + 4 + 4];
394 uint32_t temp; 340 uint32_t temp;
395 341
396 packet[0] = 16; 342 packet[0] = 16;
397 temp = htonl(handshake_id1); 343 temp = htonl(handshake_id1);
398 memcpy(packet + 1, &temp, 4); 344 memcpy(packet + 1, &temp, 4);
399 temp = htonl(handshake_id2); 345 temp = htonl(handshake_id2);
400 memcpy(packet + 5, &temp, 4); 346 memcpy(packet + 5, &temp, 4);
401 return sendpacket(ip_port, packet, sizeof(packet)); 347 return sendpacket(ip_port, packet, sizeof(packet));
402
403} 348}
404 349
405
406int send_SYNC(uint32_t connection_id) 350int send_SYNC(uint32_t connection_id)
407{ 351{
408 352
409 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; 353 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)];
410 uint16_t index = 0; 354 uint16_t index = 0;
411 355
412 IP_Port ip_port = connections[connection_id].ip_port; 356 IP_Port ip_port = connections[connection_id].ip_port;
413 uint8_t counter = connections[connection_id].send_counter; 357 uint8_t counter = connections[connection_id].send_counter;
414 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); 358 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum);
415 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); 359 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum);
416 uint32_t requested[BUFFER_PACKET_NUM]; 360 uint32_t requested[BUFFER_PACKET_NUM];
417 uint32_t number = missing_packets(connection_id, requested); 361 uint32_t number = missing_packets(connection_id, requested);
418 362
419 packet[0] = 17; 363 packet[0] = 17;
420 index += 1; 364 index += 1;
421 memcpy(packet + index, &counter, 1); 365 memcpy(packet + index, &counter, 1);
@@ -427,7 +371,7 @@ int send_SYNC(uint32_t connection_id)
427 memcpy(packet + index, requested, 4 * number); 371 memcpy(packet + index, requested, 4 * number);
428 372
429 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); 373 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2));
430 374
431} 375}
432 376
433int send_data_packet(uint32_t connection_id, uint32_t packet_num) 377int send_data_packet(uint32_t connection_id, uint32_t packet_num)
@@ -449,16 +393,14 @@ int send_DATA(uint32_t connection_id)
449{ 393{
450 int ret; 394 int ret;
451 uint32_t buffer[BUFFER_PACKET_NUM]; 395 uint32_t buffer[BUFFER_PACKET_NUM];
452 if(connections[connection_id].num_req_paquets > 0) 396 if(connections[connection_id].num_req_paquets > 0) {
453 {
454 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 397 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
455 connections[connection_id].num_req_paquets--; 398 connections[connection_id].num_req_paquets--;
456 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); 399 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4);
457 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); 400 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4);
458 return ret; 401 return ret;
459 } 402 }
460 if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) 403 if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
461 {
462 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); 404 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
463 connections[connection_id].sent_packetnum++; 405 connections[connection_id].sent_packetnum++;
464 return ret; 406 return ret;
@@ -468,17 +410,13 @@ int send_DATA(uint32_t connection_id)
468 410
469/* END of packet sending functions */ 411/* END of packet sending functions */
470 412
471
472
473/* Packet handling functions 413/* Packet handling functions
474 One to handle each type of packets we receive 414 One to handle each type of packets we receive
475 return 0 if handled correctly, 1 if packet is bad. */ 415 return 0 if handled correctly, 1 if packet is bad. */
476int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) 416int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
477{ 417{
478 if(length != (1 + 4 + 4)) 418 if(length != (1 + 4 + 4))
479 {
480 return 1; 419 return 1;
481 }
482 uint32_t temp; 420 uint32_t temp;
483 uint32_t handshake_id1, handshake_id2; 421 uint32_t handshake_id1, handshake_id2;
484 int connection = getconnection_id(source); 422 int connection = getconnection_id(source);
@@ -487,17 +425,13 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
487 memcpy(&temp, packet + 5, 4); 425 memcpy(&temp, packet + 5, 4);
488 handshake_id2 = ntohl(temp); 426 handshake_id2 = ntohl(temp);
489 427
490 if(handshake_id2 == 0) 428 if(handshake_id2 == 0) {
491 {
492 send_handshake(source, handshake_id(source), handshake_id1); 429 send_handshake(source, handshake_id(source), handshake_id1);
493 return 0; 430 return 0;
494 } 431 }
495 if(is_connected(connection) != 1) 432 if(is_connected(connection) != 1)
496 {
497 return 1; 433 return 1;
498 } 434 if(handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */
499 if(handshake_id2 == connections[connection].handshake_id1) /* if handshake_id2 is what we sent previously as handshake_id1 */
500 {
501 connections[connection].status = 2; 435 connections[connection].status = 2;
502 /* NOTE: is this necessary? 436 /* NOTE: is this necessary?
503 connections[connection].handshake_id2 = handshake_id1; */ 437 connections[connection].handshake_id2 = handshake_id1; */
@@ -515,25 +449,19 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
515int SYNC_valid(uint32_t length) 449int SYNC_valid(uint32_t length)
516{ 450{
517 if(length < 4 + 4 + 2) 451 if(length < 4 + 4 + 2)
518 {
519 return 0; 452 return 0;
520 }
521 if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || 453 if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
522 ((length - 4 - 4 - 2) % 4) != 0) 454 ((length - 4 - 4 - 2) % 4) != 0)
523 {
524 return 0; 455 return 0;
525 }
526 return 1; 456 return 1;
527} 457}
528 458
529/* case 1: */ 459/* case 1: */
530int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) 460int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
531{ 461{
532 if(handshake_id(source) == recv_packetnum) 462 if(handshake_id(source) == recv_packetnum) {
533 {
534 int x = new_inconnection(source); 463 int x = new_inconnection(source);
535 if(x != -1) 464 if(x != -1) {
536 {
537 connections[x].orecv_packetnum = recv_packetnum; 465 connections[x].orecv_packetnum = recv_packetnum;
538 connections[x].sent_packetnum = recv_packetnum; 466 connections[x].sent_packetnum = recv_packetnum;
539 connections[x].sendbuff_packetnum = recv_packetnum; 467 connections[x].sendbuff_packetnum = recv_packetnum;
@@ -551,9 +479,8 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
551/* case 2: */ 479/* case 2: */
552int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 480int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
553{ 481{
554 if(recv_packetnum == connections[connection_id].orecv_packetnum) 482 if(recv_packetnum == connections[connection_id].orecv_packetnum) {
555 /* && sent_packetnum == connections[connection_id].osent_packetnum) */ 483 /* && sent_packetnum == connections[connection_id].osent_packetnum) */
556 {
557 connections[connection_id].status = 3; 484 connections[connection_id].status = 3;
558 connections[connection_id].recv_counter = counter; 485 connections[connection_id].recv_counter = counter;
559 ++connections[connection_id].send_counter; 486 ++connections[connection_id].send_counter;
@@ -572,16 +499,14 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
572 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ 499 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */
573 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); 500 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum);
574 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 501 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
575 if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) /* packet valid */ 502 if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */
576 {
577 connections[connection_id].orecv_packetnum = recv_packetnum; 503 connections[connection_id].orecv_packetnum = recv_packetnum;
578 connections[connection_id].osent_packetnum = sent_packetnum; 504 connections[connection_id].osent_packetnum = sent_packetnum;
579 connections[connection_id].successful_sent = recv_packetnum; 505 connections[connection_id].successful_sent = recv_packetnum;
580 connections[connection_id].last_recvSYNC = current_time(); 506 connections[connection_id].last_recvSYNC = current_time();
581 connections[connection_id].recv_counter = counter; 507 connections[connection_id].recv_counter = counter;
582 ++connections[connection_id].send_counter; 508 ++connections[connection_id].send_counter;
583 for(i = 0; i < number; ++i) 509 for(i = 0; i < number; ++i) {
584 {
585 temp = ntohl(req_packets[i]); 510 temp = ntohl(req_packets[i]);
586 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); 511 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number);
587 } 512 }
@@ -595,9 +520,7 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source)
595{ 520{
596 521
597 if(!SYNC_valid(length)) 522 if(!SYNC_valid(length))
598 {
599 return 1; 523 return 1;
600 }
601 int connection = getconnection_id(source); 524 int connection = getconnection_id(source);
602 uint8_t counter; 525 uint8_t counter;
603 uint32_t temp; 526 uint32_t temp;
@@ -611,21 +534,13 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source)
611 memcpy(&temp,packet + 6, 4); 534 memcpy(&temp,packet + 6, 4);
612 sent_packetnum = ntohl(temp); 535 sent_packetnum = ntohl(temp);
613 if(number != 0) 536 if(number != 0)
614 {
615 memcpy(req_packets, packet + 10, 4 * number); 537 memcpy(req_packets, packet + 10, 4 * number);
616 }
617 if(connection == -1) 538 if(connection == -1)
618 {
619 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 539 return handle_SYNC1(source, recv_packetnum, sent_packetnum);
620 }
621 if(connections[connection].status == 2) 540 if(connections[connection].status == 2)
622 {
623 return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); 541 return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum);
624 }
625 if(connections[connection].status == 3) 542 if(connections[connection].status == 3)
626 {
627 return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); 543 return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number);
628 }
629 return 0; 544 return 0;
630} 545}
631 546
@@ -634,37 +549,26 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source)
634int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) 549int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size)
635{ 550{
636 if(size > MAX_DATA_SIZE) 551 if(size > MAX_DATA_SIZE)
637 {
638 return 1; 552 return 1;
639 }
640 553
641 uint32_t i; 554 uint32_t i;
642 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; 555 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
643 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; 556 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
644 for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) 557 for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
645 { 558 if(i == data_num) {
646 if(i == data_num)
647 {
648 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); 559 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
649 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; 560 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
650 connections[connection_id].last_recvdata = current_time(); 561 connections[connection_id].last_recvdata = current_time();
651 if(sent_packet < BUFFER_PACKET_NUM) 562 if(sent_packet < BUFFER_PACKET_NUM)
652 {
653 connections[connection_id].osent_packetnum = data_num; 563 connections[connection_id].osent_packetnum = data_num;
654 }
655 break; 564 break;
656 } 565 }
657 } 566 }
658 for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) 567 for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
659 {
660 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) 568 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
661 {
662 connections[connection_id].recv_packetnum = i; 569 connections[connection_id].recv_packetnum = i;
663 }
664 else 570 else
665 {
666 break; 571 break;
667 }
668 } 572 }
669 573
670 return 0; 574 return 0;
@@ -673,54 +577,43 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size
673int handle_data(uint8_t * packet, uint32_t length, IP_Port source) 577int handle_data(uint8_t * packet, uint32_t length, IP_Port source)
674{ 578{
675 int connection = getconnection_id(source); 579 int connection = getconnection_id(source);
676 580
677 if(connection == -1) 581 if(connection == -1)
678 {
679 return 1; 582 return 1;
680 } 583
681
682 if(connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ 584 if(connections[connection].status != 3) /* Drop the data packet if connection is not connected. */
683 {
684 return 1; 585 return 1;
685 } 586
686
687 if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) 587 if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
688 {
689 return 1; 588 return 1;
690 }
691 uint32_t temp; 589 uint32_t temp;
692 uint32_t number; 590 uint32_t number;
693 uint16_t size = length - 1 - 4; 591 uint16_t size = length - 1 - 4;
694 592
695 memcpy(&temp, packet + 1, 4); 593 memcpy(&temp, packet + 1, 4);
696 number = ntohl(temp); 594 number = ntohl(temp);
697 return add_recv(connection, number, packet + 5, size); 595 return add_recv(connection, number, packet + 5, size);
698
699} 596}
700 597
701/* END of packet handling functions */ 598/* END of packet handling functions */
702 599
703
704int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) 600int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
705{ 601{
706
707 switch (packet[0]) { 602 switch (packet[0]) {
708 case 16: 603 case 16:
709 return handle_handshake(packet, length, source); 604 return handle_handshake(packet, length, source);
710 605
711 case 17: 606 case 17:
712 return handle_SYNC(packet, length, source); 607 return handle_SYNC(packet, length, source);
713 608
714 case 18: 609 case 18:
715 return handle_data(packet, length, source); 610 return handle_data(packet, length, source);
716 611
717 default: 612 default:
718 return 1; 613 return 1;
719
720 } 614 }
721 615
722 return 0; 616 return 0;
723
724} 617}
725 618
726/* Send handshake requests 619/* Send handshake requests
@@ -729,28 +622,20 @@ void doNew()
729{ 622{
730 uint32_t i; 623 uint32_t i;
731 uint64_t temp_time = current_time(); 624 uint64_t temp_time = current_time();
732 for(i = 0; i < MAX_CONNECTIONS; ++i) 625 for(i = 0; i < MAX_CONNECTIONS; ++i) {
733 {
734 if(connections[i].status == 1) 626 if(connections[i].status == 1)
735 { 627 if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
736 if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time)
737 {
738 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 628 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
739 connections[i].last_sent = temp_time; 629 connections[i].last_sent = temp_time;
740 } 630 }
741 631
742 }
743 /* kill all timed out connections */ 632 /* kill all timed out connections */
744 if( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 633 if( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
745 connections[i].status != 4) 634 connections[i].status != 4)
746 {
747 /* kill_connection(i); */ 635 /* kill_connection(i); */
748 connections[i].status = 4; 636 connections[i].status = 4;
749 }
750 if(connections[i].status > 0 && connections[i].killat < temp_time) 637 if(connections[i].status > 0 && connections[i].killat < temp_time)
751 {
752 kill_connection(i); 638 kill_connection(i);
753 }
754 } 639 }
755} 640}
756 641
@@ -758,16 +643,12 @@ void doSYNC()
758{ 643{
759 uint32_t i; 644 uint32_t i;
760 uint64_t temp_time = current_time(); 645 uint64_t temp_time = current_time();
761 for(i = 0; i < MAX_CONNECTIONS; ++i) 646 for(i = 0; i < MAX_CONNECTIONS; ++i) {
762 {
763 if(connections[i].status == 2 || connections[i].status == 3) 647 if(connections[i].status == 2 || connections[i].status == 3)
764 { 648 if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
765 if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time)
766 {
767 send_SYNC(i); 649 send_SYNC(i);
768 connections[i].last_SYNC = temp_time; 650 connections[i].last_SYNC = temp_time;
769 } 651 }
770 }
771 } 652 }
772} 653}
773 654
@@ -777,19 +658,12 @@ void doData()
777 uint64_t j; 658 uint64_t j;
778 uint64_t temp_time = current_time(); 659 uint64_t temp_time = current_time();
779 for(i = 0; i < MAX_CONNECTIONS; ++i) 660 for(i = 0; i < MAX_CONNECTIONS; ++i)
780 {
781 if(connections[i].status == 3 && sendqueue(i) != 0) 661 if(connections[i].status == 3 && sendqueue(i) != 0)
782 { 662 if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) {
783 if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time)
784 {
785 for(j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) 663 for(j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate))
786 {
787 send_DATA(i); 664 send_DATA(i);
788 }
789 connections[i].last_sent = temp_time; 665 connections[i].last_sent = temp_time;
790 } 666 }
791 }
792 }
793} 667}
794 668
795/* TODO: flow control. 669/* TODO: flow control.
@@ -801,33 +675,22 @@ void adjustRates()
801{ 675{
802 uint32_t i; 676 uint32_t i;
803 uint64_t temp_time = current_time(); 677 uint64_t temp_time = current_time();
804 for(i = 0; i < MAX_CONNECTIONS; ++i) 678 for(i = 0; i < MAX_CONNECTIONS; ++i) {
805 {
806 if(connections[i].status == 1 || connections[i].status == 2) 679 if(connections[i].status == 1 || connections[i].status == 2)
807 {
808 connections[i].SYNC_rate = MAX_SYNC_RATE; 680 connections[i].SYNC_rate = MAX_SYNC_RATE;
809 } 681 if(connections[i].status == 3) {
810 if(connections[i].status == 3) 682 if(sendqueue(i) != 0) {
811 {
812 if(sendqueue(i) != 0)
813 {
814
815 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 683 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
816
817 connections[i].SYNC_rate = MAX_SYNC_RATE; 684 connections[i].SYNC_rate = MAX_SYNC_RATE;
818
819 } 685 }
820 else if(connections[i].last_recvdata + 1000000UL > temp_time) 686 else if(connections[i].last_recvdata + 1000000UL > temp_time)
821 {
822 connections[i].SYNC_rate = MAX_SYNC_RATE; 687 connections[i].SYNC_rate = MAX_SYNC_RATE;
823 }
824 else 688 else
825 {
826 connections[i].SYNC_rate = SYNC_RATE; 689 connections[i].SYNC_rate = SYNC_RATE;
827 }
828 } 690 }
829 } 691 }
830} 692}
693
831/* Call this function a couple times per second 694/* Call this function a couple times per second
832 It's the main loop. */ 695 It's the main loop. */
833void doLossless_UDP() 696void doLossless_UDP()
@@ -836,6 +699,4 @@ void doLossless_UDP()
836 doSYNC(); 699 doSYNC();
837 doData(); 700 doData();
838 adjustRates(); 701 adjustRates();
839
840
841} 702}
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index 0f5bb119..a9f1bb15 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -1,26 +1,25 @@
1/* Lossless_UDP.h 1/* Lossless_UDP.h
2* 2 *
3* An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt 3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24 23
25#ifndef LOSSLESS_UDP_H 24#ifndef LOSSLESS_UDP_H
26#define LOSSLESS_UDP_H 25#define LOSSLESS_UDP_H
@@ -34,8 +33,6 @@ extern "C" {
34/* maximum length of the data in the data packets */ 33/* maximum length of the data in the data packets */
35#define MAX_DATA_SIZE 1024 34#define MAX_DATA_SIZE 1024
36 35
37
38
39/* Functions */ 36/* Functions */
40 37
41/* initialize a new connection to ip_port 38/* initialize a new connection to ip_port
@@ -53,7 +50,6 @@ int getconnection_id(IP_Port ip_port);
53 return -1 if there are no new incoming connections in the list. */ 50 return -1 if there are no new incoming connections in the list. */
54int incoming_connection(); 51int incoming_connection();
55 52
56
57/* return -1 if it could not kill the connection. 53/* return -1 if it could not kill the connection.
58 return 0 if killed successfully */ 54 return 0 if killed successfully */
59int kill_connection(int connection_id); 55int kill_connection(int connection_id);
@@ -75,21 +71,16 @@ char id_packet(int connection_id);
75 return length of received packet if successful */ 71 return length of received packet if successful */
76int read_packet(int connection_id, uint8_t * data); 72int read_packet(int connection_id, uint8_t * data);
77 73
78
79/* return 0 if data could not be put in packet queue 74/* return 0 if data could not be put in packet queue
80 return 1 if data was put into the queue */ 75 return 1 if data was put into the queue */
81int write_packet(int connection_id, uint8_t * data, uint32_t length); 76int write_packet(int connection_id, uint8_t * data, uint32_t length);
82 77
83
84
85/* returns the number of packets in the queue waiting to be successfully sent. */ 78/* returns the number of packets in the queue waiting to be successfully sent. */
86uint32_t sendqueue(int connection_id); 79uint32_t sendqueue(int connection_id);
87 80
88
89/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 81/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
90uint32_t recvqueue(int connection_id); 82uint32_t recvqueue(int connection_id);
91 83
92
93/* check if connection is connected 84/* check if connection is connected
94 return 0 no. 85 return 0 no.
95 return 1 if attempting handshake 86 return 1 if attempting handshake
@@ -98,7 +89,6 @@ uint32_t recvqueue(int connection_id);
98 return 4 if timed out and wating to be killed */ 89 return 4 if timed out and wating to be killed */
99int is_connected(int connection_id); 90int is_connected(int connection_id);
100 91
101
102/* Call this function a couple times per second 92/* Call this function a couple times per second
103 It's the main loop. */ 93 It's the main loop. */
104void doLossless_UDP(); 94void doLossless_UDP();
diff --git a/core/Messenger.c b/core/Messenger.c
index 043700e5..69d33172 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -1,26 +1,25 @@
1/* Messenger.c 1/* Messenger.c
2* 2 *
3* An implementation of a simple text chat only messenger on the tox network core. 3 * An implementation of a simple text chat only messenger on the tox network core.
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24 23
25#include "Messenger.h" 24#include "Messenger.h"
26#define MIN(a,b) (((a)<(b))?(a):(b)) 25#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -39,8 +38,6 @@ typedef struct
39 uint8_t userstatus_sent; 38 uint8_t userstatus_sent;
40 uint16_t info_size; /* length of the info */ 39 uint16_t info_size; /* length of the info */
41}Friend; 40}Friend;
42
43
44 41
45uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 42uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
46 43
@@ -58,26 +55,20 @@ static uint32_t numfriends;
58 0 if we are offline 55 0 if we are offline
59 static uint8_t online; */ 56 static uint8_t online; */
60 57
61
62/* return the friend id associated to that public key. 58/* return the friend id associated to that public key.
63 return -1 if no such friend */ 59 return -1 if no such friend */
64int getfriend_id(uint8_t * client_id) 60int getfriend_id(uint8_t * client_id)
65{ 61{
66 uint32_t i; 62 uint32_t i;
63
67 for(i = 0; i < numfriends; ++i) 64 for(i = 0; i < numfriends; ++i)
68 {
69 if(friendlist[i].status > 0) 65 if(friendlist[i].status > 0)
70 {
71 if(memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) 66 if(memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0)
72 {
73 return i; 67 return i;
74 } 68
75 }
76 }
77 return -1; 69 return -1;
78} 70}
79 71
80
81/* copies the public key associated to that friend id into client_id buffer. 72/* copies the public key associated to that friend id into client_id buffer.
82 make sure that client_id is of size CLIENT_ID_SIZE. 73 make sure that client_id is of size CLIENT_ID_SIZE.
83 return 0 if success 74 return 0 if success
@@ -85,19 +76,16 @@ int getfriend_id(uint8_t * client_id)
85int getclient_id(int friend_id, uint8_t * client_id) 76int getclient_id(int friend_id, uint8_t * client_id)
86{ 77{
87 if(friend_id >= numfriends || friend_id < 0) 78 if(friend_id >= numfriends || friend_id < 0)
88 {
89 return -1; 79 return -1;
90 }
91 80
92 if(friendlist[friend_id].status > 0) 81 if(friendlist[friend_id].status > 0) {
93 {
94 memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE); 82 memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE);
95 return 0; 83 return 0;
96 } 84 }
85
97 return -1; 86 return -1;
98} 87}
99 88
100
101/* add a friend 89/* add a friend
102 set the data that will be sent along with friend request 90 set the data that will be sent along with friend request
103 client_id is the client id of the friend 91 client_id is the client id of the friend
@@ -108,17 +96,11 @@ int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length)
108{ 96{
109 if(length == 0 || length >= 97 if(length == 0 || length >=
110 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) 98 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
111 {
112 return -1; 99 return -1;
113 }
114 if(memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 100 if(memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
115 {
116 return -1; 101 return -1;
117 }
118 if(getfriend_id(client_id) != -1) 102 if(getfriend_id(client_id) != -1)
119 {
120 return -1; 103 return -1;
121 }
122 uint32_t i; 104 uint32_t i;
123 for(i = 0; i <= numfriends; ++i) 105 for(i = 0; i <= numfriends; ++i)
124 { 106 {
@@ -144,9 +126,7 @@ int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length)
144int m_addfriend_norequest(uint8_t * client_id) 126int m_addfriend_norequest(uint8_t * client_id)
145{ 127{
146 if(getfriend_id(client_id) != -1) 128 if(getfriend_id(client_id) != -1)
147 {
148 return -1; 129 return -1;
149 }
150 uint32_t i; 130 uint32_t i;
151 for(i = 0; i <= numfriends; ++i) 131 for(i = 0; i <= numfriends; ++i)
152 { 132 {
@@ -172,9 +152,7 @@ int m_addfriend_norequest(uint8_t * client_id)
172int m_delfriend(int friendnumber) 152int m_delfriend(int friendnumber)
173{ 153{
174 if(friendnumber >= numfriends || friendnumber < 0) 154 if(friendnumber >= numfriends || friendnumber < 0)
175 {
176 return -1; 155 return -1;
177 }
178 156
179 DHT_delfriend(friendlist[friendnumber].client_id); 157 DHT_delfriend(friendlist[friendnumber].client_id);
180 crypto_kill(friendlist[friendnumber].crypt_connection_id); 158 crypto_kill(friendlist[friendnumber].crypt_connection_id);
@@ -182,17 +160,12 @@ int m_delfriend(int friendnumber)
182 memset(&friendlist[friendnumber], 0, sizeof(Friend)); 160 memset(&friendlist[friendnumber], 0, sizeof(Friend));
183 uint32_t i; 161 uint32_t i;
184 for(i = numfriends; i != 0; --i) 162 for(i = numfriends; i != 0; --i)
185 {
186 if(friendlist[i].status != 0) 163 if(friendlist[i].status != 0)
187 {
188 break; 164 break;
189 }
190 }
191 numfriends = i; 165 numfriends = i;
192 return 0; 166 return 0;
193} 167}
194 168
195
196/* return 4 if friend is online 169/* return 4 if friend is online
197 return 3 if friend is confirmed 170 return 3 if friend is confirmed
198 return 2 if the friend request was sent 171 return 2 if the friend request was sent
@@ -201,27 +174,20 @@ int m_delfriend(int friendnumber)
201int m_friendstatus(int friendnumber) 174int m_friendstatus(int friendnumber)
202{ 175{
203 if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 176 if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
204 {
205 return 0; 177 return 0;
206 }
207 return friendlist[friendnumber].status; 178 return friendlist[friendnumber].status;
208} 179}
209 180
210
211/* send a text chat message to an online friend 181/* send a text chat message to an online friend
212 return 1 if packet was successfully put into the send queue 182 return 1 if packet was successfully put into the send queue
213 return 0 if it was not */ 183 return 0 if it was not */
214int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length) 184int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length)
215{ 185{
216 if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 186 if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
217 {
218 return 0; 187 return 0;
219 }
220 if(length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) 188 if(length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
221 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 189 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
222 {
223 return 0; 190 return 0;
224 }
225 uint8_t temp[MAX_DATA_SIZE]; 191 uint8_t temp[MAX_DATA_SIZE];
226 temp[0] = PACKET_ID_MESSAGE; 192 temp[0] = PACKET_ID_MESSAGE;
227 memcpy(temp + 1, message, length); 193 memcpy(temp + 1, message, length);
@@ -240,18 +206,14 @@ static int m_sendname(int friendnumber, uint8_t * name)
240/* set the name of a friend 206/* set the name of a friend
241 return 0 if success 207 return 0 if success
242 return -1 if failure */ 208 return -1 if failure */
243
244static int setfriendname(int friendnumber, uint8_t * name) 209static int setfriendname(int friendnumber, uint8_t * name)
245{ 210{
246 if(friendnumber >= numfriends || friendnumber < 0) 211 if(friendnumber >= numfriends || friendnumber < 0)
247 {
248 return -1; 212 return -1;
249 }
250 memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH); 213 memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
251 return 0; 214 return 0;
252} 215}
253 216
254
255/* Set our nickname 217/* Set our nickname
256 name must be a string of maximum MAX_NAME_LENGTH length. 218 name must be a string of maximum MAX_NAME_LENGTH length.
257 return 0 if success 219 return 0 if success
@@ -259,15 +221,11 @@ static int setfriendname(int friendnumber, uint8_t * name)
259int setname(uint8_t * name, uint16_t length) 221int setname(uint8_t * name, uint16_t length)
260{ 222{
261 if(length > MAX_NAME_LENGTH) 223 if(length > MAX_NAME_LENGTH)
262 {
263 return -1; 224 return -1;
264 }
265 memcpy(self_name, name, length); 225 memcpy(self_name, name, length);
266 uint32_t i; 226 uint32_t i;
267 for(i = 0; i < numfriends; ++i) 227 for(i = 0; i < numfriends; ++i)
268 {
269 friendlist[i].name_sent = 0; 228 friendlist[i].name_sent = 0;
270 }
271 return 0; 229 return 0;
272} 230}
273 231
@@ -279,9 +237,7 @@ int setname(uint8_t * name, uint16_t length)
279int getname(int friendnumber, uint8_t * name) 237int getname(int friendnumber, uint8_t * name)
280{ 238{
281 if(friendnumber >= numfriends || friendnumber < 0) 239 if(friendnumber >= numfriends || friendnumber < 0)
282 {
283 return -1; 240 return -1;
284 }
285 memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH); 241 memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH);
286 return 0; 242 return 0;
287} 243}
@@ -289,9 +245,7 @@ int getname(int friendnumber, uint8_t * name)
289int m_set_userstatus(uint8_t *status, uint16_t length) 245int m_set_userstatus(uint8_t *status, uint16_t length)
290{ 246{
291 if(length > MAX_USERSTATUS_LENGTH) 247 if(length > MAX_USERSTATUS_LENGTH)
292 {
293 return -1; 248 return -1;
294 }
295 uint8_t *newstatus = calloc(length, 1); 249 uint8_t *newstatus = calloc(length, 1);
296 memcpy(newstatus, status, length); 250 memcpy(newstatus, status, length);
297 free(self_userstatus); 251 free(self_userstatus);
@@ -300,9 +254,7 @@ int m_set_userstatus(uint8_t *status, uint16_t length)
300 254
301 uint32_t i; 255 uint32_t i;
302 for(i = 0; i < numfriends; ++i) 256 for(i = 0; i < numfriends; ++i)
303 {
304 friendlist[i].userstatus_sent = 0; 257 friendlist[i].userstatus_sent = 0;
305 }
306 return 0; 258 return 0;
307} 259}
308 260
@@ -311,9 +263,7 @@ int m_set_userstatus(uint8_t *status, uint16_t length)
311int m_get_userstatus_size(int friendnumber) 263int m_get_userstatus_size(int friendnumber)
312{ 264{
313 if(friendnumber >= numfriends || friendnumber < 0) 265 if(friendnumber >= numfriends || friendnumber < 0)
314 {
315 return -1; 266 return -1;
316 }
317 return friendlist[friendnumber].userstatus_length; 267 return friendlist[friendnumber].userstatus_length;
318} 268}
319 269
@@ -322,9 +272,7 @@ int m_get_userstatus_size(int friendnumber)
322int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen) 272int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen)
323{ 273{
324 if(friendnumber >= numfriends || friendnumber < 0) 274 if(friendnumber >= numfriends || friendnumber < 0)
325 {
326 return -1; 275 return -1;
327 }
328 memset(buf, 0, maxlen); 276 memset(buf, 0, maxlen);
329 memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1); 277 memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1);
330 return 0; 278 return 0;
@@ -343,9 +291,7 @@ static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length)
343static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length) 291static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length)
344{ 292{
345 if(friendnumber >= numfriends || friendnumber < 0) 293 if(friendnumber >= numfriends || friendnumber < 0)
346 {
347 return -1; 294 return -1;
348 }
349 uint8_t *newstatus = calloc(length, 1); 295 uint8_t *newstatus = calloc(length, 1);
350 memcpy(newstatus, status, length); 296 memcpy(newstatus, status, length);
351 free(friendlist[friendnumber].userstatus); 297 free(friendlist[friendnumber].userstatus);
@@ -353,17 +299,15 @@ static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t le
353 friendlist[friendnumber].userstatus_length = length; 299 friendlist[friendnumber].userstatus_length = length;
354 return 0; 300 return 0;
355} 301}
356/* 302
357static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 303/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
358static uint8_t friend_request_isset = 0; 304static uint8_t friend_request_isset = 0; */
359*/
360/* set the function that will be executed when a friend request is received. */ 305/* set the function that will be executed when a friend request is received. */
361void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) 306void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
362{ 307{
363 callback_friendrequest(function); 308 callback_friendrequest(function);
364} 309}
365 310
366
367static void (*friend_message)(int, uint8_t *, uint16_t); 311static void (*friend_message)(int, uint8_t *, uint16_t);
368static uint8_t friend_message_isset = 0; 312static uint8_t friend_message_isset = 0;
369 313
@@ -374,7 +318,6 @@ void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
374 friend_message_isset = 1; 318 friend_message_isset = 1;
375} 319}
376 320
377
378static void (*friend_namechange)(int, uint8_t *, uint16_t); 321static void (*friend_namechange)(int, uint8_t *, uint16_t);
379static uint8_t friend_namechange_isset = 0; 322static uint8_t friend_namechange_isset = 0;
380void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)) 323void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t))
@@ -402,9 +345,9 @@ int initMessenger()
402 ip.i = 0; 345 ip.i = 0;
403 346
404 if(init_networking(ip,PORT) == -1) 347 if(init_networking(ip,PORT) == -1)
405 return -1; 348 return -1;
406 349
407 return 0; 350 return 0;
408} 351}
409 352
410static void doFriends() 353static void doFriends()
@@ -417,16 +360,12 @@ static void doFriends()
417 if(friendlist[i].status == 1) 360 if(friendlist[i].status == 1)
418 { 361 {
419 int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); 362 int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
420 if(fr == 0)/*TODO: This needs to be fixed so that it sends the friend requests a couple of times in case 363 if(fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case
421 of packet loss*/ 364 of packet loss */
422 {
423 friendlist[i].status = 2; 365 friendlist[i].status = 2;
424 }
425 else 366 else
426 if(fr > 0) 367 if(fr > 0)
427 {
428 friendlist[i].status = 2; 368 friendlist[i].status = 2;
429 }
430 } 369 }
431 if(friendlist[i].status == 2 || friendlist[i].status == 3) /* friend is not online */ 370 if(friendlist[i].status == 2 || friendlist[i].status == 3) /* friend is not online */
432 { 371 {
@@ -436,12 +375,10 @@ static void doFriends()
436 { 375 {
437 send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); 376 send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
438 friendlist[i].friend_request_id = unix_time(); 377 friendlist[i].friend_request_id = unix_time();
439
440 } 378 }
441 } 379 }
442 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); 380 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
443 switch(is_cryptoconnected(friendlist[i].crypt_connection_id)) 381 switch(is_cryptoconnected(friendlist[i].crypt_connection_id)) {
444 {
445 case 0: 382 case 0:
446 if (friendip.ip.i > 1) 383 if (friendip.ip.i > 1)
447 friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); 384 friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
@@ -460,19 +397,11 @@ static void doFriends()
460 while(friendlist[i].status == 4) /* friend is online */ 397 while(friendlist[i].status == 4) /* friend is online */
461 { 398 {
462 if(friendlist[i].name_sent == 0) 399 if(friendlist[i].name_sent == 0)
463 {
464 if(m_sendname(i, self_name)) 400 if(m_sendname(i, self_name))
465 {
466 friendlist[i].name_sent = 1; 401 friendlist[i].name_sent = 1;
467 }
468 }
469 if(friendlist[i].userstatus_sent == 0) 402 if(friendlist[i].userstatus_sent == 0)
470 {
471 if(send_userstatus(i, self_userstatus, self_userstatus_len)) 403 if(send_userstatus(i, self_userstatus, self_userstatus_len))
472 {
473 friendlist[i].userstatus_sent = 1; 404 friendlist[i].userstatus_sent = 1;
474 }
475 }
476 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); 405 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
477 if(len > 0) 406 if(len > 0)
478 { 407 {
@@ -500,9 +429,7 @@ static void doFriends()
500 } 429 }
501 case PACKET_ID_MESSAGE: { 430 case PACKET_ID_MESSAGE: {
502 if(friend_message_isset) 431 if(friend_message_isset)
503 {
504 (*friend_message)(i, temp + 1, len - 1); 432 (*friend_message)(i, temp + 1, len - 1);
505 }
506 break; 433 break;
507 } 434 }
508 } 435 }
@@ -521,8 +448,6 @@ static void doFriends()
521 } 448 }
522} 449}
523 450
524
525
526static void doInbound() 451static void doInbound()
527{ 452{
528 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 453 uint8_t secret_nonce[crypto_box_NONCEBYTES];
@@ -543,6 +468,22 @@ static void doInbound()
543 } 468 }
544} 469}
545 470
471/*Interval in seconds between LAN discovery packet sending*/
472#define LAN_DISCOVERY_INTERVAL 60
473
474static uint32_t last_LANdiscovery;
475
476/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
477static void LANdiscovery()
478{
479 if(last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time())
480 {
481 send_LANdiscovery(htons(PORT));
482 last_LANdiscovery = unix_time();
483 }
484}
485
486
546/* the main loop that needs to be run at least 200 times per second. */ 487/* the main loop that needs to be run at least 200 times per second. */
547void doMessenger() 488void doMessenger()
548{ 489{
@@ -554,21 +495,19 @@ void doMessenger()
554#ifdef DEBUG 495#ifdef DEBUG
555 /* if(rand() % 3 != 1) //simulate packet loss */ 496 /* if(rand() % 3 != 1) //simulate packet loss */
556 /* { */ 497 /* { */
557 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) 498 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) &&
558 { 499 friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port))
559 /* if packet is discarded */ 500 /* if packet is discarded */
560 printf("Received unhandled packet with length: %u\n", length); 501 printf("Received unhandled packet with length: %u\n", length);
561 }
562 else 502 else
563 {
564 printf("Received handled packet with length: %u\n", length); 503 printf("Received handled packet with length: %u\n", length);
565 }
566 /* } */ 504 /* } */
567 printf("Status: %u %u %u\n",friendlist[0].status ,is_cryptoconnected(friendlist[0].crypt_connection_id), friendlist[0].crypt_connection_id); 505 printf("Status: %u %u %u\n",friendlist[0].status ,is_cryptoconnected(friendlist[0].crypt_connection_id), friendlist[0].crypt_connection_id);
568#else 506#else
569 DHT_handlepacket(data, length, ip_port); 507 DHT_handlepacket(data, length, ip_port);
570 LosslessUDP_handlepacket(data, length, ip_port); 508 LosslessUDP_handlepacket(data, length, ip_port);
571 friendreq_handlepacket(data, length, ip_port); 509 friendreq_handlepacket(data, length, ip_port);
510 LANdiscovery_handlepacket(data, length, ip_port);
572#endif 511#endif
573 512
574 } 513 }
@@ -577,6 +516,7 @@ void doMessenger()
577 doNetCrypto(); 516 doNetCrypto();
578 doInbound(); 517 doInbound();
579 doFriends(); 518 doFriends();
519 LANdiscovery();
580} 520}
581 521
582/* returns the size of the messenger data (for saving) */ 522/* returns the size of the messenger data (for saving) */
@@ -606,13 +546,9 @@ void Messenger_save(uint8_t * data)
606int Messenger_load(uint8_t * data, uint32_t length) 546int Messenger_load(uint8_t * data, uint32_t length)
607{ 547{
608 if(length == ~0) 548 if(length == ~0)
609 {
610 return -1; 549 return -1;
611 }
612 if(length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2) 550 if(length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2)
613 {
614 return -1; 551 return -1;
615 }
616 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2; 552 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2;
617 load_keys(data); 553 load_keys(data);
618 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 554 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@@ -621,21 +557,15 @@ int Messenger_load(uint8_t * data, uint32_t length)
621 data += sizeof(size); 557 data += sizeof(size);
622 558
623 if(length < size) 559 if(length < size)
624 {
625 return -1; 560 return -1;
626 }
627 length -= size; 561 length -= size;
628 if(DHT_load(data, size) == -1) 562 if(DHT_load(data, size) == -1)
629 {
630 return -1; 563 return -1;
631 }
632 data += size; 564 data += size;
633 memcpy(&size, data, sizeof(size)); 565 memcpy(&size, data, sizeof(size));
634 data += sizeof(size); 566 data += sizeof(size);
635 if(length != size || length % sizeof(Friend) != 0) 567 if(length != size || length % sizeof(Friend) != 0)
636 {
637 return -1; 568 return -1;
638 }
639 569
640 Friend * temp = malloc(size); 570 Friend * temp = malloc(size);
641 memcpy(temp, data, size); 571 memcpy(temp, data, size);
diff --git a/core/Messenger.h b/core/Messenger.h
index 6afe84ac..1067d156 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -1,35 +1,35 @@
1/* Messenger.h 1/* Messenger.h
2* 2 *
3* An implementation of a simple text chat only messenger on the tox network core. 3 * An implementation of a simple text chat only messenger on the tox network core.
4* 4 *
5* NOTE: All the text in the messages must be encoded using UTF-8 5 * NOTE: All the text in the messages must be encoded using UTF-8
6 6 *
7 Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 8 *
9 This file is part of Tox. 9 * This file is part of Tox.
10 10 *
11 Tox is free software: you can redistribute it and/or modify 11 * Tox is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or 13 * the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version. 14 * (at your option) any later version.
15 15 *
16 Tox is distributed in the hope that it will be useful, 16 * Tox is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 * GNU General Public License for more details.
20 20 *
21 You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 along with Tox. If not, see <http://www.gnu.org/licenses/>. 22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 23 *
24*/ 24 */
25 25
26
27#ifndef MESSENGER_H 26#ifndef MESSENGER_H
28#define MESSENGER_H 27#define MESSENGER_H
29 28
30#include "net_crypto.h" 29#include "net_crypto.h"
31#include "DHT.h" 30#include "DHT.h"
32#include "friend_requests.h" 31#include "friend_requests.h"
32#include "LAN_discovery.h"
33 33
34#ifdef __cplusplus 34#ifdef __cplusplus
35extern "C" { 35extern "C" {
@@ -79,7 +79,6 @@ int m_delfriend(int friendnumber);
79 return 0 if there is no friend with that number */ 79 return 0 if there is no friend with that number */
80int m_friendstatus(int friendnumber); 80int m_friendstatus(int friendnumber);
81 81
82
83/* send a text chat message to an online friend 82/* send a text chat message to an online friend
84 returns 1 if packet was successfully put into the send queue 83 returns 1 if packet was successfully put into the send queue
85 return 0 if it was not */ 84 return 0 if it was not */
@@ -91,7 +90,6 @@ int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length);
91 return -1 if failure */ 90 return -1 if failure */
92int setname(uint8_t * name, uint16_t length); 91int setname(uint8_t * name, uint16_t length);
93 92
94
95/* get name of friendnumber 93/* get name of friendnumber
96 put it in name 94 put it in name
97 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 95 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
@@ -117,7 +115,6 @@ int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen);
117 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 115 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
118void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 116void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
119 117
120
121/* set the function that will be executed when a message from a friend is received. 118/* set the function that will be executed when a message from a friend is received.
122 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ 119 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
123void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); 120void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
@@ -137,11 +134,9 @@ void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t));
137 returns -1 if there are problems */ 134 returns -1 if there are problems */
138int initMessenger(); 135int initMessenger();
139 136
140
141/* the main loop that needs to be run at least 200 times per second */ 137/* the main loop that needs to be run at least 200 times per second */
142void doMessenger(); 138void doMessenger();
143 139
144
145/* SAVING AND LOADING FUNCTIONS: */ 140/* SAVING AND LOADING FUNCTIONS: */
146 141
147/* returns the size of the messenger data (for saving) */ 142/* returns the size of the messenger data (for saving) */
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 18f0866b..d1b0da57 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -2,13 +2,29 @@
2 * 2 *
3 * Handle friend requests. 3 * Handle friend requests.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
5 */ 22 */
6 23
7#include "friend_requests.h" 24#include "friend_requests.h"
8 25
9uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
10 27
11
12/* Try to send a friendrequest to peer with public_key 28/* Try to send a friendrequest to peer with public_key
13 data is the data in the request and length is the length. 29 data is the data in the request and length is the length.
14 return -1 if failure. 30 return -1 if failure.
@@ -18,33 +34,30 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
18{ 34{
19 uint8_t packet[MAX_DATA_SIZE]; 35 uint8_t packet[MAX_DATA_SIZE];
20 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ 36 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */
37
21 if(len == -1) 38 if(len == -1)
22 {
23 return -1; 39 return -1;
24 } 40
25 IP_Port ip_port = DHT_getfriendip(public_key); 41 IP_Port ip_port = DHT_getfriendip(public_key);
42
26 if(ip_port.ip.i == 1) 43 if(ip_port.ip.i == 1)
27 {
28 return -1; 44 return -1;
29 } 45
30 if(ip_port.ip.i != 0) 46 if(ip_port.ip.i != 0)
31 { 47 {
32 if(sendpacket(ip_port, packet, len) != -1) 48 if(sendpacket(ip_port, packet, len) != -1)
33 {
34 return 0; 49 return 0;
35 }
36 return -1; 50 return -1;
37 } 51 }
38 52
39 int num = route_tofriend(public_key, packet, len); 53 int num = route_tofriend(public_key, packet, len);
54
40 if(num == 0) 55 if(num == 0)
41 {
42 return -1; 56 return -1;
43 } 57
44 return num; 58 return num;
45} 59}
46 60
47
48static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t); 61static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t);
49static uint8_t handle_friendrequest_isset = 0; 62static uint8_t handle_friendrequest_isset = 0;
50 63
@@ -56,6 +69,38 @@ void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
56} 69}
57 70
58 71
72/*NOTE: the following is just a temporary fix for the multiple friend requests recieved at the same time problem
73 TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/
74
75#define MAX_RECIEVED_STORED 32
76
77static uint8_t recieved_requests[MAX_RECIEVED_STORED][crypto_box_PUBLICKEYBYTES];
78static uint16_t recieved_requests_index;
79
80/*Add to list of recieved friend requests*/
81static void addto_recievedlist(uint8_t * client_id)
82{
83 if(recieved_requests_index >= MAX_RECIEVED_STORED)
84 recieved_requests_index = 0;
85
86 memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
87 ++recieved_requests_index;
88}
89
90/* Check if a friend request was already recieved
91 return 0 if not, 1 if we did */
92static int request_recieved(uint8_t * client_id)
93{
94 uint32_t i;
95
96 for(i = 0; i < MAX_RECIEVED_STORED; ++i)
97 if(memcmp(recieved_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
98 return 1;
99
100 return 0;
101}
102
103
59int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) 104int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
60{ 105{
61 106
@@ -63,31 +108,27 @@ int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
63 { 108 {
64 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 109 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
65 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 110 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
66 {
67 return 1; 111 return 1;
68 } 112 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) /* check if request is for us. */
69 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)//check if request is for us.
70 { 113 {
71 if(handle_friendrequest_isset == 0) 114 if(handle_friendrequest_isset == 0)
72 {
73 return 1; 115 return 1;
74 } 116
75 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 117 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
76 uint8_t data[MAX_DATA_SIZE]; 118 uint8_t data[MAX_DATA_SIZE];
77 int len = handle_request(public_key, data, packet, length); 119 int len = handle_request(public_key, data, packet, length);
120
78 if(len == -1) 121 if(len == -1)
79 {
80 return 1; 122 return 1;
81 } 123 if(request_recieved(public_key))
124 return 1;
125
126 addto_recievedlist(public_key);
82 (*handle_friendrequest)(public_key, data, len); 127 (*handle_friendrequest)(public_key, data, len);
83 } 128 }
84 else//if request is not for us, try routing it. 129 else /* if request is not for us, try routing it. */
85 {
86 if(route_packet(packet + 1, packet, length) == length) 130 if(route_packet(packet + 1, packet, length) == length)
87 {
88 return 0; 131 return 0;
89 }
90 }
91 } 132 }
92 return 1; 133 return 1;
93} \ No newline at end of file 134}
diff --git a/core/friend_requests.h b/core/friend_requests.h
index de116b33..29bc2b88 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -2,13 +2,28 @@
2 * 2 *
3 * Handle friend requests. 3 * Handle friend requests.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
5 */ 22 */
6 23
7
8#ifndef FRIEND_REQUESTS_H 24#ifndef FRIEND_REQUESTS_H
9#define FRIEND_REQUESTS_H 25#define FRIEND_REQUESTS_H
10 26
11
12#include "DHT.h" 27#include "DHT.h"
13#include "net_crypto.h" 28#include "net_crypto.h"
14 29
@@ -20,7 +35,6 @@ extern "C" {
20 data is the data in the request and length is the length. */ 35 data is the data in the request and length is the length. */
21int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length); 36int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length);
22 37
23
24/* set the function that will be executed when a friend request for us is received. 38/* set the function that will be executed when a friend request for us is received.
25 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
26void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 40void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
@@ -30,8 +44,6 @@ void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
30 return 1 if it didn't handle the packet or if the packet was shit. */ 44 return 1 if it didn't handle the packet or if the packet was shit. */
31int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); 45int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
32 46
33
34
35#ifdef __cplusplus 47#ifdef __cplusplus
36} 48}
37#endif 49#endif
diff --git a/core/net_crypto.c b/core/net_crypto.c
index e01ed695..28cb83e8 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -1,38 +1,35 @@
1/* net_crypto.c 1/* net_crypto.c
2* 2 *
3* Functions for the core network crypto. 3 * Functions for the core network crypto.
4* See also: docs/Crypto.txt 4 * See also: docs/Crypto.txt
5* 5 *
6* NOTE: This code has to be perfect. We don't mess around with encryption. 6 * NOTE: This code has to be perfect. We don't mess around with encryption.
7* 7 *
8 8 * Copyright (C) 2013 Tox project All Rights Reserved.
9 Copyright (C) 2013 Tox project All Rights Reserved. 9 *
10 10 * This file is part of Tox.
11 This file is part of Tox. 11 *
12 12 * Tox is free software: you can redistribute it and/or modify
13 Tox is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by
14 it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or
15 the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version.
16 (at your option) any later version. 16 *
17 17 * Tox is distributed in the hope that it will be useful,
18 Tox is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details.
21 GNU General Public License for more details. 21 *
22 22 * You should have received a copy of the GNU General Public License
23 You should have received a copy of the GNU General Public License 23 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
24 along with Tox. If not, see <http://www.gnu.org/licenses/>. 24 *
25 25 */
26*/
27 26
28#include "net_crypto.h" 27#include "net_crypto.h"
29 28
30
31/* Our public and secret keys. */ 29/* Our public and secret keys. */
32uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 30uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
33uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 31uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
34 32
35
36typedef struct 33typedef struct
37{ 34{
38 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ 35 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
@@ -65,9 +62,7 @@ int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
65 uint8_t * plain, uint32_t length, uint8_t * encrypted) 62 uint8_t * plain, uint32_t length, uint8_t * encrypted)
66{ 63{
67 if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) 64 if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
68 {
69 return -1; 65 return -1;
70 }
71 66
72 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; 67 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
73 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; 68 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES];
@@ -79,9 +74,8 @@ int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
79 74
80 /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ 75 /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */
81 if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) 76 if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0)
82 {
83 return -1; 77 return -1;
84 } 78
85 /* unpad the encrypted message */ 79 /* unpad the encrypted message */
86 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 80 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
87 return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; 81 return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES;
@@ -95,9 +89,8 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
95 uint8_t * encrypted, uint32_t length, uint8_t * plain) 89 uint8_t * encrypted, uint32_t length, uint8_t * plain)
96{ 90{
97 if(length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) 91 if(length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
98 {
99 return -1; 92 return -1;
100 } 93
101 uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; 94 uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES];
102 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; 95 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
103 uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; 96 uint8_t zeroes[crypto_box_ZEROBYTES] = {0};
@@ -106,14 +99,12 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
106 99
107 if(crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, 100 if(crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
108 nonce, public_key, secret_key) == -1) 101 nonce, public_key, secret_key) == -1)
109 {
110 return -1; 102 return -1;
111 } 103
112 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ 104 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */
113 if(memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0) 105 if(memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0)
114 {
115 return -1; 106 return -1;
116 } 107
117 /* unpad the plain message */ 108 /* unpad the plain message */
118 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES); 109 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES);
119 return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; 110 return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES;
@@ -123,13 +114,10 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
123void increment_nonce(uint8_t * nonce) 114void increment_nonce(uint8_t * nonce)
124{ 115{
125 uint32_t i; 116 uint32_t i;
126 for(i = 0; i < crypto_box_NONCEBYTES; ++i) 117 for(i = 0; i < crypto_box_NONCEBYTES; ++i) {
127 {
128 ++nonce[i]; 118 ++nonce[i];
129 if(nonce[i] != 0) 119 if(nonce[i] != 0)
130 {
131 break; 120 break;
132 }
133 } 121 }
134} 122}
135 123
@@ -137,8 +125,7 @@ void increment_nonce(uint8_t * nonce)
137void random_nonce(uint8_t * nonce) 125void random_nonce(uint8_t * nonce)
138{ 126{
139 uint32_t i, temp; 127 uint32_t i, temp;
140 for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) 128 for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
141 {
142 temp = random_int(); 129 temp = random_int();
143 memcpy(nonce + 4 * i, &temp, 4); 130 memcpy(nonce + 4 * i, &temp, 4);
144 } 131 }
@@ -150,64 +137,44 @@ void random_nonce(uint8_t * nonce)
150int read_cryptpacket(int crypt_connection_id, uint8_t * data) 137int read_cryptpacket(int crypt_connection_id, uint8_t * data)
151{ 138{
152 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 139 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
153 {
154 return 0; 140 return 0;
155 }
156 if(crypto_connections[crypt_connection_id].status != 3) 141 if(crypto_connections[crypt_connection_id].status != 3)
157 {
158 return 0; 142 return 0;
159 }
160 uint8_t temp_data[MAX_DATA_SIZE]; 143 uint8_t temp_data[MAX_DATA_SIZE];
161 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); 144 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
162 if(length == 0) 145 if(length == 0)
163 {
164 return 0; 146 return 0;
165 }
166 if(temp_data[0] != 3) 147 if(temp_data[0] != 3)
167 {
168 return -1; 148 return -1;
169 }
170 int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, 149 int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
171 crypto_connections[crypt_connection_id].sessionsecret_key, 150 crypto_connections[crypt_connection_id].sessionsecret_key,
172 crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); 151 crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data);
173 if(len != -1) 152 if(len != -1) {
174 {
175 increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); 153 increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
176 return len; 154 return len;
177 } 155 }
178 return -1; 156 return -1;
179} 157}
180 158
181
182/* return 0 if data could not be put in packet queue 159/* return 0 if data could not be put in packet queue
183 return 1 if data was put into the queue */ 160 return 1 if data was put into the queue */
184int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length) 161int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length)
185{ 162{
186 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 163 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
187 {
188 return 0; 164 return 0;
189 }
190 if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 165 if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
191 {
192 return 0; 166 return 0;
193 }
194 if(crypto_connections[crypt_connection_id].status != 3) 167 if(crypto_connections[crypt_connection_id].status != 3)
195 {
196 return 0; 168 return 0;
197 }
198 uint8_t temp_data[MAX_DATA_SIZE]; 169 uint8_t temp_data[MAX_DATA_SIZE];
199 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, 170 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
200 crypto_connections[crypt_connection_id].sessionsecret_key, 171 crypto_connections[crypt_connection_id].sessionsecret_key,
201 crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); 172 crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1);
202 if(len == -1) 173 if(len == -1)
203 {
204 return 0; 174 return 0;
205 }
206 temp_data[0] = 3; 175 temp_data[0] = 3;
207 if(write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) 176 if(write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
208 {
209 return 0; 177 return 0;
210 }
211 increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); 178 increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
212 return 1; 179 return 1;
213} 180}
@@ -221,17 +188,13 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length)
221int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id) 188int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id)
222{ 189{
223 if(MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING) 190 if(MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING)
224 {
225 return -1; 191 return -1;
226 }
227 uint8_t nonce[crypto_box_NONCEBYTES]; 192 uint8_t nonce[crypto_box_NONCEBYTES];
228 random_nonce(nonce); 193 random_nonce(nonce);
229 int len = encrypt_data(public_key, self_secret_key, nonce, data, length, 194 int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
230 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 195 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
231 if(len == -1) 196 if(len == -1)
232 {
233 return -1; 197 return -1;
234 }
235 packet[0] = request_id; 198 packet[0] = request_id;
236 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 199 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
237 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); 200 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
@@ -257,18 +220,13 @@ int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint1
257 int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, 220 int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
258 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); 221 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data);
259 if(len1 == -1) 222 if(len1 == -1)
260 {
261 return -1; 223 return -1;
262 }
263 return len1; 224 return len1;
264 } 225 }
265 else 226 else
266 {
267 return -1; 227 return -1;
268 }
269} 228}
270 229
271
272/* Send a crypto handshake packet containing an encrypted secret nonce and session public key 230/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
273 to peer with connection_id and public_key 231 to peer with connection_id and public_key
274 the packet is encrypted with a random nonce which is sent in plain text with the packet */ 232 the packet is encrypted with a random nonce which is sent in plain text with the packet */
@@ -285,9 +243,7 @@ int send_cryptohandshake(int connection_id, uint8_t * public_key, uint8_t * secr
285 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 243 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
286 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 244 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
287 if(len == -1) 245 if(len == -1)
288 {
289 return 0; 246 return 0;
290 }
291 temp_data[0] = 2; 247 temp_data[0] = 2;
292 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 248 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
293 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 249 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
@@ -307,9 +263,7 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce,
307 return 0; 263 return 0;
308 } 264 }
309 if(data[0] != 2) 265 if(data[0] != 2)
310 {
311 return 0; 266 return 0;
312 }
313 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 267 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
314 268
315 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); 269 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
@@ -319,18 +273,13 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce,
319 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); 273 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
320 274
321 if(len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) 275 if(len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES)
322 {
323 return 0; 276 return 0;
324 }
325 277
326 memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); 278 memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
327 memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); 279 memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
328 return 1; 280 return 1;
329} 281}
330 282
331
332
333
334/* get crypto connection id from public key of peer 283/* get crypto connection id from public key of peer
335 return -1 if there are no connections like we are looking for 284 return -1 if there are no connections like we are looking for
336 return id if it found it */ 285 return id if it found it */
@@ -338,19 +287,12 @@ int getcryptconnection_id(uint8_t * public_key)
338{ 287{
339 uint32_t i; 288 uint32_t i;
340 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 289 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
341 {
342 if(crypto_connections[i].status > 0) 290 if(crypto_connections[i].status > 0)
343 {
344 if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) 291 if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
345 {
346 return i; 292 return i;
347 }
348 }
349 }
350 return -1; 293 return -1;
351} 294}
352 295
353
354/* Start a secure connection with other peer who has public_key and ip_port 296/* Start a secure connection with other peer who has public_key and ip_port
355 returns -1 if failure 297 returns -1 if failure
356 returns crypt_connection_id of the initialized connection if everything went well. */ 298 returns crypt_connection_id of the initialized connection if everything went well. */
@@ -358,23 +300,17 @@ int crypto_connect(uint8_t * public_key, IP_Port ip_port)
358{ 300{
359 uint32_t i; 301 uint32_t i;
360 int id = getcryptconnection_id(public_key); 302 int id = getcryptconnection_id(public_key);
361 if(id != -1) 303 if(id != -1) {
362 {
363 IP_Port c_ip = connection_ip(crypto_connections[id].number); 304 IP_Port c_ip = connection_ip(crypto_connections[id].number);
364 if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) 305 if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
365 {
366 return -1; 306 return -1;
367 }
368 } 307 }
369 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 308 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
370 { 309 {
371 if(crypto_connections[i].status == 0) 310 if(crypto_connections[i].status == 0) {
372 {
373 int id = new_connection(ip_port); 311 int id = new_connection(ip_port);
374 if(id == -1) 312 if(id == -1)
375 {
376 return -1; 313 return -1;
377 }
378 crypto_connections[i].number = id; 314 crypto_connections[i].number = id;
379 crypto_connections[i].status = 1; 315 crypto_connections[i].status = 1;
380 random_nonce(crypto_connections[i].recv_nonce); 316 random_nonce(crypto_connections[i].recv_nonce);
@@ -405,20 +341,16 @@ int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * sessi
405 uint32_t i; 341 uint32_t i;
406 for(i = 0; i < MAX_INCOMING; ++i) 342 for(i = 0; i < MAX_INCOMING; ++i)
407 { 343 {
408 if(incoming_connections[i] != -1) 344 if(incoming_connections[i] != -1) {
409 { 345 if(is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) {
410 if(is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0)
411 {
412 kill_connection(incoming_connections[i]); 346 kill_connection(incoming_connections[i]);
413 incoming_connections[i] = -1; 347 incoming_connections[i] = -1;
414 continue; 348 continue;
415 } 349 }
416 if(id_packet(incoming_connections[i]) == 2) 350 if(id_packet(incoming_connections[i]) == 2) {
417 {
418 uint8_t temp_data[MAX_DATA_SIZE]; 351 uint8_t temp_data[MAX_DATA_SIZE];
419 uint16_t len = read_packet(incoming_connections[i], temp_data); 352 uint16_t len = read_packet(incoming_connections[i], temp_data);
420 if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) 353 if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
421 {
422 int connection_id = incoming_connections[i]; 354 int connection_id = incoming_connections[i];
423 incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ 355 incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */
424 return connection_id; 356 return connection_id;
@@ -435,11 +367,8 @@ int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * sessi
435int crypto_kill(int crypt_connection_id) 367int crypto_kill(int crypt_connection_id)
436{ 368{
437 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 369 if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
438 {
439 return 1; 370 return 1;
440 } 371 if(crypto_connections[crypt_connection_id].status != 0) {
441 if(crypto_connections[crypt_connection_id].status != 0)
442 {
443 crypto_connections[crypt_connection_id].status = 0; 372 crypto_connections[crypt_connection_id].status = 0;
444 kill_connection(crypto_connections[crypt_connection_id].number); 373 kill_connection(crypto_connections[crypt_connection_id].number);
445 crypto_connections[crypt_connection_id].number = ~0; 374 crypto_connections[crypt_connection_id].number = ~0;
@@ -448,7 +377,6 @@ int crypto_kill(int crypt_connection_id)
448 return 1; 377 return 1;
449} 378}
450 379
451
452/* accept an incoming connection using the parameters provided by crypto_inbound 380/* accept an incoming connection using the parameters provided by crypto_inbound
453 return -1 if not successful 381 return -1 if not successful
454 returns the crypt_connection_id if successful */ 382 returns the crypt_connection_id if successful */
@@ -456,9 +384,7 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
456{ 384{
457 uint32_t i; 385 uint32_t i;
458 if(connection_id == -1) 386 if(connection_id == -1)
459 {
460 return -1; 387 return -1;
461 }
462 /* 388 /*
463 if(getcryptconnection_id(public_key) != -1) 389 if(getcryptconnection_id(public_key) != -1)
464 { 390 {
@@ -466,8 +392,7 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
466 }*/ 392 }*/
467 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 393 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
468 { 394 {
469 if(crypto_connections[i].status == 0) 395 if(crypto_connections[i].status == 0) {
470 {
471 crypto_connections[i].number = connection_id; 396 crypto_connections[i].number = connection_id;
472 crypto_connections[i].status = 2; 397 crypto_connections[i].status = 2;
473 random_nonce(crypto_connections[i].recv_nonce); 398 random_nonce(crypto_connections[i].recv_nonce);
@@ -494,19 +419,16 @@ int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * sec
494 return -1; 419 return -1;
495} 420}
496 421
497/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet 422/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet
498 (we have received a handshake but no empty data packet), 3 if the connection is established. 423 (we have received a handshake but no empty data packet), 3 if the connection is established.
499 4 if the connection is timed out and waiting to be killed */ 424 4 if the connection is timed out and waiting to be killed */
500int is_cryptoconnected(int crypt_connection_id) 425int is_cryptoconnected(int crypt_connection_id)
501{ 426{
502 if(crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) 427 if(crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
503 {
504 return crypto_connections[crypt_connection_id].status; 428 return crypto_connections[crypt_connection_id].status;
505 }
506 return 0; 429 return 0;
507} 430}
508 431
509
510/* Generate our public and private keys 432/* Generate our public and private keys
511 Only call this function the first time the program starts. */ 433 Only call this function the first time the program starts. */
512void new_keys() 434void new_keys()
@@ -537,10 +459,8 @@ void load_keys(uint8_t * keys)
537int new_incoming(int id) 459int new_incoming(int id)
538{ 460{
539 uint32_t i; 461 uint32_t i;
540 for(i = 0; i < MAX_INCOMING; ++i) 462 for(i = 0; i < MAX_INCOMING; ++i) {
541 { 463 if(incoming_connections[i] == -1) {
542 if(incoming_connections[i] == -1)
543 {
544 incoming_connections[i] = id; 464 incoming_connections[i] = id;
545 return 0; 465 return 0;
546 } 466 }
@@ -553,13 +473,10 @@ int new_incoming(int id)
553static void handle_incomings() 473static void handle_incomings()
554{ 474{
555 int income; 475 int income;
556 while(1) 476 while(1) {
557 {
558 income = incoming_connection(); 477 income = incoming_connection();
559 if(income == -1 || new_incoming(income) ) 478 if(income == -1 || new_incoming(income) )
560 {
561 break; 479 break;
562 }
563 } 480 }
564} 481}
565 482
@@ -578,17 +495,11 @@ static void receive_crypto()
578 uint16_t len; 495 uint16_t len;
579 if(id_packet(crypto_connections[i].number) == 1) 496 if(id_packet(crypto_connections[i].number) == 1)
580 /* if the packet is a friend request drop it (because we are already friends) */ 497 /* if the packet is a friend request drop it (because we are already friends) */
581 {
582 len = read_packet(crypto_connections[i].number, temp_data); 498 len = read_packet(crypto_connections[i].number, temp_data);
583 499 if(id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
584 }
585 if(id_packet(crypto_connections[i].number) == 2) /* handle handshake packet. */
586 {
587 len = read_packet(crypto_connections[i].number, temp_data); 500 len = read_packet(crypto_connections[i].number, temp_data);
588 if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) 501 if(handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
589 { 502 if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
590 if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
591 {
592 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 503 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
593 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 504 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
594 increment_nonce(crypto_connections[i].sent_nonce); 505 increment_nonce(crypto_connections[i].sent_nonce);
@@ -600,17 +511,14 @@ static void receive_crypto()
600 } 511 }
601 } 512 }
602 else if(id_packet(crypto_connections[i].number) != -1) 513 else if(id_packet(crypto_connections[i].number) != -1)
603 {
604 /* This should not happen 514 /* This should not happen
605 kill the connection if it does */ 515 kill the connection if it does */
606 crypto_kill(crypto_connections[i].number); 516 crypto_kill(crypto_connections[i].number);
607 }
608 517
609 } 518 }
610 if(crypto_connections[i].status == 2) 519 if(crypto_connections[i].status == 2)
611 { 520 {
612 if(id_packet(crypto_connections[i].number) == 3) 521 if(id_packet(crypto_connections[i].number) == 3) {
613 {
614 uint8_t temp_data[MAX_DATA_SIZE]; 522 uint8_t temp_data[MAX_DATA_SIZE];
615 uint8_t data[MAX_DATA_SIZE]; 523 uint8_t data[MAX_DATA_SIZE];
616 int length = read_packet(crypto_connections[i].number, temp_data); 524 int length = read_packet(crypto_connections[i].number, temp_data);
@@ -618,8 +526,7 @@ static void receive_crypto()
618 crypto_connections[i].sessionsecret_key, 526 crypto_connections[i].sessionsecret_key,
619 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); 527 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
620 uint32_t zero = 0; 528 uint32_t zero = 0;
621 if(len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) 529 if(len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
622 {
623 increment_nonce(crypto_connections[i].recv_nonce); 530 increment_nonce(crypto_connections[i].recv_nonce);
624 crypto_connections[i].status = 3; 531 crypto_connections[i].status = 3;
625 532
@@ -627,18 +534,14 @@ static void receive_crypto()
627 kill_connection_in(crypto_connections[i].number, 3000000); 534 kill_connection_in(crypto_connections[i].number, 3000000);
628 } 535 }
629 else 536 else
630 {
631 /* This should not happen 537 /* This should not happen
632 kill the connection if it does */ 538 kill the connection if it does */
633 crypto_kill(crypto_connections[i].number); 539 crypto_kill(crypto_connections[i].number);
634 }
635 } 540 }
636 else if(id_packet(crypto_connections[i].number) != -1) 541 else if(id_packet(crypto_connections[i].number) != -1)
637 {
638 /* This should not happen 542 /* This should not happen
639 kill the connection if it does */ 543 kill the connection if it does */
640 crypto_kill(crypto_connections[i].number); 544 crypto_kill(crypto_connections[i].number);
641 }
642 } 545 }
643 } 546 }
644} 547}
@@ -651,22 +554,16 @@ void initNetCrypto()
651 memset(incoming_connections, -1 ,sizeof(incoming_connections)); 554 memset(incoming_connections, -1 ,sizeof(incoming_connections));
652 uint32_t i; 555 uint32_t i;
653 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 556 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
654 {
655 crypto_connections[i].number = ~0; 557 crypto_connections[i].number = ~0;
656 }
657} 558}
658 559
659static void killTimedout() 560static void killTimedout()
660{ 561{
661 uint32_t i; 562 uint32_t i;
662 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 563 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
663 {
664 if(crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4) 564 if(crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4)
665 {
666 crypto_connections[i].status = 4; 565 crypto_connections[i].status = 4;
667 } 566 else if(is_connected(crypto_connections[i].number) == 4) {
668 else if(is_connected(crypto_connections[i].number) == 4)
669 {
670 kill_connection(crypto_connections[i].number); 567 kill_connection(crypto_connections[i].number);
671 crypto_connections[i].number = ~0; 568 crypto_connections[i].number = ~0;
672 } 569 }
diff --git a/core/net_crypto.h b/core/net_crypto.h
index b497f1fb..b5bab17a 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -1,26 +1,26 @@
1/* net_crypto.h 1/* net_crypto.h
2* 2 *
3* Functions for the core network crypto. 3 * Functions for the core network crypto.
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/ 23
24#ifndef NET_CRYPTO_H 24#ifndef NET_CRYPTO_H
25#define NET_CRYPTO_H 25#define NET_CRYPTO_H
26 26
@@ -55,13 +55,11 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
55/* fill the given nonce with random bytes. */ 55/* fill the given nonce with random bytes. */
56void random_nonce(uint8_t * nonce); 56void random_nonce(uint8_t * nonce);
57 57
58
59/* return 0 if there is no received data in the buffer 58/* return 0 if there is no received data in the buffer
60 return -1 if the packet was discarded. 59 return -1 if the packet was discarded.
61 return length of received data if successful */ 60 return length of received data if successful */
62int read_cryptpacket(int crypt_connection_id, uint8_t * data); 61int read_cryptpacket(int crypt_connection_id, uint8_t * data);
63 62
64
65/* return 0 if data could not be put in packet queue 63/* return 0 if data could not be put in packet queue
66 return 1 if data was put into the queue */ 64 return 1 if data was put into the queue */
67int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); 65int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length);
@@ -74,20 +72,17 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length);
74 returns the length of the created packet on success */ 72 returns the length of the created packet on success */
75int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id); 73int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id);
76 74
77
78/* puts the senders public key in the request in public_key, the data from the request 75/* puts the senders public key in the request in public_key, the data from the request
79 in data if a friend or ping request was sent to us and returns the length of the data. 76 in data if a friend or ping request was sent to us and returns the length of the data.
80 packet is the request packet and length is its length 77 packet is the request packet and length is its length
81 return -1 if not valid request. */ 78 return -1 if not valid request. */
82int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length); 79int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length);
83 80
84
85/* Start a secure connection with other peer who has public_key and ip_port 81/* Start a secure connection with other peer who has public_key and ip_port
86 returns -1 if failure 82 returns -1 if failure
87 returns crypt_connection_id of the initialized connection if everything went well. */ 83 returns crypt_connection_id of the initialized connection if everything went well. */
88int crypto_connect(uint8_t * public_key, IP_Port ip_port); 84int crypto_connect(uint8_t * public_key, IP_Port ip_port);
89 85
90
91/* kill a crypto connection 86/* kill a crypto connection
92 return 0 if killed successfully 87 return 0 if killed successfully
93 return 1 if there was a problem. */ 88 return 1 if there was a problem. */
@@ -102,7 +97,6 @@ int crypto_kill(int crypt_connection_id);
102 to refuse it just call kill_connection(...) on the connection id */ 97 to refuse it just call kill_connection(...) on the connection id */
103int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key); 98int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * session_key);
104 99
105
106/* accept an incoming connection using the parameters provided by crypto_inbound 100/* accept an incoming connection using the parameters provided by crypto_inbound
107 return -1 if not successful 101 return -1 if not successful
108 returns the crypt_connection_id if successful */ 102 returns the crypt_connection_id if successful */
diff --git a/core/network.c b/core/network.c
index d4e25c82..ec234593 100644
--- a/core/network.c
+++ b/core/network.c
@@ -1,30 +1,28 @@
1/* network.h 1/* network.h
2* 2 *
3* Functions for the core networking. 3 * Functions for the core networking.
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24 23
25#include "network.h" 24#include "network.h"
26 25
27
28/* returns current UNIX time in microseconds (us). */ 26/* returns current UNIX time in microseconds (us). */
29uint64_t current_time() 27uint64_t current_time()
30{ 28{
@@ -44,8 +42,6 @@ uint64_t current_time()
44 time = 1000000UL*a.tv_sec + a.tv_usec; 42 time = 1000000UL*a.tv_sec + a.tv_usec;
45 return time; 43 return time;
46 #endif 44 #endif
47
48
49} 45}
50 46
51/* return a random number 47/* return a random number
@@ -69,7 +65,6 @@ int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length)
69{ 65{
70 ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; 66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
71 return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); 67 return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
72
73} 68}
74 69
75/* Function to receive data, ip and port of sender is put into ip_port 70/* Function to receive data, ip and port of sender is put into ip_port
@@ -94,7 +89,6 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
94 ip_port->ip = addr.ip; 89 ip_port->ip = addr.ip;
95 ip_port->port = addr.port; 90 ip_port->port = addr.port;
96 return 0; 91 return 0;
97
98} 92}
99 93
100/* initialize networking 94/* initialize networking
@@ -103,32 +97,28 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
103 port is in host byte order (this means don't worry about it) 97 port is in host byte order (this means don't worry about it)
104 returns 0 if no problems 98 returns 0 if no problems
105 returns -1 if there are problems */ 99 returns -1 if there are problems */
106int init_networking(IP ip ,uint16_t port) 100int init_networking(IP ip, uint16_t port)
107{ 101{
108 #ifdef WIN32 102 #ifdef WIN32
109 WSADATA wsaData; 103 WSADATA wsaData;
110 if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) 104 if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
111 {
112 return -1; 105 return -1;
113 }
114
115 #else 106 #else
116 srandom((uint32_t)current_time()); 107 srandom((uint32_t)current_time());
117 #endif 108 #endif
118 srand((uint32_t)current_time()); 109 srand((uint32_t)current_time());
119 110
120 /* initialize our socket */ 111 /* initialize our socket */
121 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 112 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
122 113
123 /* Check for socket error */ 114 /* Check for socket error */
124 #ifdef WIN32 115 #ifdef WIN32
125 if (sock == INVALID_SOCKET) //MSDN recommends this 116 if (sock == INVALID_SOCKET) /* MSDN recommends this */
126 return -1; 117 return -1;
127 #else 118 #else
128 if (sock < 0) 119 if (sock < 0)
129 return -1; 120 return -1;
130 #endif 121 #endif
131
132 122
133 /* Functions to increase the size of the send and receive UDP buffers 123 /* Functions to increase the size of the send and receive UDP buffers
134 NOTE: uncomment if necessary */ 124 NOTE: uncomment if necessary */
@@ -140,10 +130,13 @@ int init_networking(IP ip ,uint16_t port)
140 } 130 }
141 131
142 if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) 132 if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1)
143 {
144 return -1; 133 return -1;
145 }*/ 134 */
146 135
136 /* Enable broadcast on socket */
137 int broadcast = 1;
138 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast));
139
147 /* Set socket nonblocking */ 140 /* Set socket nonblocking */
148 #ifdef WIN32 141 #ifdef WIN32
149 /* I think this works for windows */ 142 /* I think this works for windows */
@@ -190,11 +183,9 @@ int resolve_addr(char *address)
190 183
191 int success = getaddrinfo(address, "7", &hints, &server); 184 int success = getaddrinfo(address, "7", &hints, &server);
192 if(success != 0) 185 if(success != 0)
193 {
194 return -1; 186 return -1;
195 }
196 187
197 int resolved = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr; 188 int resolved = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr;
198 freeaddrinfo(server); 189 freeaddrinfo(server);
199 return resolved; 190 return resolved;
200} \ No newline at end of file 191}
diff --git a/core/network.h b/core/network.h
index 3b999cec..eaf12003 100644
--- a/core/network.h
+++ b/core/network.h
@@ -1,27 +1,25 @@
1/* network.h 1/* network.h
2* 2 *
3* Datatypes, functions and includes for the core networking. 3 * Datatypes, functions and includes for the core networking.
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24
25 23
26#ifndef NETWORK_H 24#ifndef NETWORK_H
27#define NETWORK_H 25#define NETWORK_H
@@ -32,8 +30,6 @@
32#include <string.h> 30#include <string.h>
33#include <time.h> 31#include <time.h>
34 32
35
36
37#ifdef WIN32 /* Put win32 includes here */ 33#ifdef WIN32 /* Put win32 includes here */
38//Windows XP 34//Windows XP
39#define WINVER 0x0501 35#define WINVER 0x0501
@@ -99,7 +95,6 @@ typedef struct
99 #endif 95 #endif
100}ADDR; 96}ADDR;
101 97
102
103/* returns current time in milleseconds since the epoch. */ 98/* returns current time in milleseconds since the epoch. */
104uint64_t current_time(); 99uint64_t current_time();
105 100
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index 0bacccd9..8942c237 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -6,6 +6,25 @@
6 * gcc -O2 -Wall -D VANILLA_NACL -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_bootstrap.c 6 * gcc -O2 -Wall -D VANILLA_NACL -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_bootstrap.c
7 * 7 *
8 * gcc -O2 -Wall -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c -lsodium DHT_bootstrap.c 8 * gcc -O2 -Wall -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c -lsodium DHT_bootstrap.c
9 *
10 *
11 * Copyright (C) 2013 Tox project All Rights Reserved.
12 *
13 * This file is part of Tox.
14 *
15 * Tox is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * Tox is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
27 *
9 */ 28 */
10 29
11#include "../core/DHT.h" 30#include "../core/DHT.h"
@@ -22,12 +41,14 @@
22 41
23#define PORT 33445 42#define PORT 33445
24 43
44//TODO: rewrite
25unsigned char * hex_string_to_bin(char hex_string[]) 45unsigned char * hex_string_to_bin(char hex_string[])
26{ 46{
27 unsigned char * val = malloc(strlen(hex_string)); 47 size_t len = strlen(hex_string);
48 unsigned char * val = malloc(len);
28 char * pos = hex_string; 49 char * pos = hex_string;
29 int i=0; 50 int i=0;
30 while(i < strlen(hex_string)) 51 while(i < len)
31 { 52 {
32 sscanf(pos,"%2hhx",&val[i]); 53 sscanf(pos,"%2hhx",&val[i]);
33 pos+=2; 54 pos+=2;
@@ -120,4 +141,4 @@ int main(int argc, char *argv[])
120 } 141 }
121 shutdown_networking(); 142 shutdown_networking();
122 return 0; 143 return 0;
123} \ No newline at end of file 144}
diff --git a/other/bootstrap_serverdaemon/CMakeLists.txt b/other/bootstrap_serverdaemon/CMakeLists.txt
index bc717d4b..6aa4dbee 100644
--- a/other/bootstrap_serverdaemon/CMakeLists.txt
+++ b/other/bootstrap_serverdaemon/CMakeLists.txt
@@ -6,4 +6,5 @@ set(exe_name DHT_bootstrap_daemon)
6add_executable(${exe_name} 6add_executable(${exe_name}
7 DHT_bootstrap_daemon.c) 7 DHT_bootstrap_daemon.c)
8 8
9target_link_libraries(${exe_name} config)
9linkCoreLibraries(${exe_name}) 10linkCoreLibraries(${exe_name})
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
index 4d79c48b..8e278b28 100644
--- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
+++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
@@ -1,50 +1,323 @@
1/* DHT boostrap 1/* DHT boostrap
2* 2 *
3* A simple DHT boostrap server for tox (daemon edition) 3 * A simple DHT boostrap server for tox - daemon edition.
4*/ 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
22 */
23
6#include <sys/types.h> /* pid_t */ 24#include <sys/types.h> /* pid_t */
7#include <sys/stat.h> /* umask */ 25#include <sys/stat.h> /* umask */
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h> /* POSIX things */ 26#include <unistd.h> /* POSIX things */
11#include <errno.h> 27#include <errno.h>
12 28
29#include <stdio.h>
30#include <stdlib.h>
31#include <libconfig.h>
32#include <arpa/inet.h> /* htons() */
33#include <string.h> /* strcpy() */
34
13#include "../../core/DHT.h" 35#include "../../core/DHT.h"
14#include "../../core/friend_requests.h" 36#include "../../core/friend_requests.h"
15 37
16 38#define DEFAULT_PORT 33445
17/* Sleep function (x = milliseconds) */ 39#define DEFAULT_PID_FILE "bootstrap_server.pid"
18#ifdef WIN32 40#define DEFAULT_KEYS_FILE "bootstrap_server.keys"
19#define c_sleep(x) Sleep(1*x) 41
20#else 42/* Server info struct */
21#include <unistd.h> 43struct server_info_s {
22#define c_sleep(x) usleep(1000*x) 44 int valid;
23#endif 45 IP_Port conn;
24 46 uint8_t bs_pk[32];
25#define PORT 33445 47};
26#define USERNAME getenv("USER") 48
27#define PIDFILE "/home/%s/.bootstrap_server.pid" /* %s represents the unser's name */ 49/* This is the struct configure_server() uses to return its data to */
28 50struct server_conf_s {
51 int err;
52 int port;
53 char pid_file[512];
54 char keys_file[512];
55 struct server_info_s info[32];
56};
57
58int b16_to_key(char b16_string[], uint8_t *bs_pubkey) {
59
60 int i;
61 unsigned int num1 = 0, num2 = 0;
62
63 for(i = 0; i < 32; ++i)
64 {
65 sscanf(&b16_string[i*2], "%1X", &num1);
66 sscanf(&b16_string[i*2+1], "%1X", &num2);
67 num1 = num1 << 4;
68 bs_pubkey[i] = bs_pubkey[i] | num1;
69 bs_pubkey[i] = bs_pubkey[i] | num2;
70 }
71 return 0;
72}
73
74/* This unction connects to all specified servers
75and connect to them.
76returns 1 if the connection to the DHT is up
77returns -1 if all attempts failed
78*/
79int connect_to_servers(struct server_info_s *info)
80{
81 int i;
82 int c;
83
84 IP_Port ip_port;
85 uint8_t data[MAX_UDP_PACKET_SIZE];
86 uint32_t length;
87
88 for(i = 0; i < 32; ++i) {
89 if(info[i].valid) {
90 /* Actual bootstrapping code goes here */
91 //puts("Calling DHT_bootstrap");
92 DHT_bootstrap(info[i].conn, info[i].bs_pk);
93 }
94 }
95
96 /* Check if we're connected to the DHT */
97 for(c = 0; c != 100; ++c) {
98 usleep(10000);
99 if(DHT_isconnected()) {
100 //puts("Connected");
101 return 1;
102 break;
103 }
104 if(DHT_isconnected() == 0 && c == 99) {
105 //puts("Not connected");
106 return -1;
107 break;
108 }
109
110 doDHT();
111
112 while(receivepacket(&ip_port, data, &length) != -1)
113 {
114 DHT_handlepacket(data, length, ip_port);
115 }
116 }
117
118 /* This probably never happens */
119 return 0;
120}
121
122void manage_keys(char *keys_file)
123{
124 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
125 uint8_t keys[KEYS_SIZE];
126
127 /* TODO: stat the file before trying to open it. We aren't cave people! */
128 FILE *keysf = fopen(keys_file, "r");
129 if (keysf != NULL) {
130 /* if file was opened successfully -- load keys */
131 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keysf);
132 if (read_size != KEYS_SIZE) {
133 printf("Error while reading the key file\nExiting.\n");
134 exit(1);
135 } else {
136 printf("Keys loaded successfully\n");
137 }
138 load_keys(keys);
139
140 } else {
141 /* otherwise save new keys */
142 /* Silly work-around to ignore any errors coming from new_keys() */
143 new_keys();
144 save_keys(keys);
145 keysf = fopen(keys_file, "w");
146 if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keysf) != KEYS_SIZE) {
147 printf("Error while writing the key file.\nExiting.\n");
148 exit(1);
149 } else {
150 printf("Keys saved successfully\n");
151 }
152 }
153
154 fclose(keysf);
155}
156
157/* This reads the configuration file, and returns a struct server_conf_s with:
158 *an error number:
159 *-1 = file wasn't read, for whatever reason
160 *-2 = no bootstrap servers found
161 *the port
162 *the location of the keys file
163 *the location of the PID file
164 *the list of bootstrap servers
165*/
166struct server_conf_s configure_server(char *cfg_file)
167{
168 config_t cfg;
169 config_setting_t *server_list;
170
171 /* This one will be strcpy'd into the pid_file array in server_conf */
172 const char *pid_file_tmp;
173 const char *keys_file_tmp;
174
175 /* Remote bootstrap server variables */
176 int bs_port;
177 const char *bs_ip;
178 const char *bs_pk;
179
180 /* The big struct */
181 static struct server_conf_s server_conf;
182
183 /* Set both to their default values. If there's an error
184 with opening/reading the config file, we return right away */
185 server_conf.port = DEFAULT_PORT;
186 strcpy(server_conf.pid_file, DEFAULT_PID_FILE);
187 strcpy(server_conf.keys_file, DEFAULT_KEYS_FILE);
188
189 config_init(&cfg);
190
191 /* Read the file. If there is an error, report it and exit. */
192 if(! config_read_file(&cfg, cfg_file))
193 {
194 fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
195 config_error_line(&cfg), config_error_text(&cfg));
196 config_destroy(&cfg);
197 server_conf.err = -1;
198 return server_conf;
199 }
200
201 /* Get the port to listen on */
202 if(config_lookup_int(&cfg, "port", &server_conf.port)) {
203 //printf("Port: %d\n", port);
204 } else {
205 fprintf(stderr, "No 'port' setting in configuration file.\n");
206 }
207
208 /* Get PID file location */
209 if(config_lookup_string(&cfg, "pid_file", &pid_file_tmp)) {
210 //printf("PID file: %s\n", pid_file_tmp);
211 strcpy(server_conf.pid_file, pid_file_tmp);
212 } else {
213 fprintf(stderr, "No 'pid_file' setting in configuration file.\n");
214 }
215
216 /* Get keys file location */
217 if(config_lookup_string(&cfg, "keys_file", &keys_file_tmp)) {
218 //printf("Keys file: %s\n", keys_file_tmp);
219 strcpy(server_conf.keys_file, keys_file_tmp);
220 } else {
221 fprintf(stderr, "No 'keys_file' setting in configuration file.\n");
222 }
223
224 /* Get all the servers in the list */
225 server_list = config_lookup(&cfg, "bootstrap_servers");
226 if(server_list != NULL) {
227 int count = config_setting_length(server_list);
228 int i;
229
230 char tmp_ip[30]; /* IP */
231 char tmp_pk[64]; /* bs_pk */
232 for(i = 0; i < count; ++i) {
233 config_setting_t *server = config_setting_get_elem(server_list, i);
234 /* Get a pointer on the key aray */
235 uint8_t *bs_pk_p = server_conf.info[i].bs_pk;
236
237 /* Only output the record if all of the expected fields are present. */
238 if(!(config_setting_lookup_string(server, "ip", &bs_ip)
239 && config_setting_lookup_int(server, "port", &bs_port)
240 && config_setting_lookup_string(server, "bs_pk", &bs_pk)))
241 continue;
242
243 /* Converting all that stuff into usable formats and storing
244 it away in the server_info struct */
245 server_conf.info[i].valid = 1;
246
247 if(resolve_addr(strcpy(tmp_ip, bs_ip)) == -1) {
248 server_conf.info[i].valid = 0;
249 printf("bootstrap_server %d: Invalid IP\n", i);
250 }
251
252 if(strlen(bs_pk) != 64) {
253 server_conf.info[i].valid = 0;
254 printf("bootstrap_server %d: Invalid public key\n", i);
255 }
256
257 if(!bs_port) {
258 server_conf.info[i].valid = 0;
259 printf("bootstrap_server %d: Invalid port\n", i);
260 }
261
262 server_conf.info[i].conn.ip.i = resolve_addr(strcpy(tmp_ip, bs_ip));
263 server_conf.info[i].conn.port = htons(bs_port);
264 b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p);
265 }
266
267 /* Check if at least one server entry is valid */
268 for(i = 0; i < 32; ++i) {
269 if(server_conf.info[i].valid)
270 break;
271 else
272 server_conf.err = -2;
273 }
274
275 } else {
276 server_conf.err = -2;
277 }
278
279 config_destroy(&cfg);
280 return server_conf;
281}
282
29int main(int argc, char *argv[]) { 283int main(int argc, char *argv[]) {
30 284
31 char pidfloc[512]; /* Location of the soon-to-be PID file */
32 pid_t pid, sid; /* Process- and Session-ID */ 285 pid_t pid, sid; /* Process- and Session-ID */
33 286 struct server_conf_s server_conf;
287
34 FILE *pidf; /* The PID file */ 288 FILE *pidf; /* The PID file */
35 289
36 /* Assemble PID file location an try to open the file */ 290 if(argc < 2) {
37 sprintf(pidfloc, PIDFILE, USERNAME); 291 printf("Please specify a configuration file.\n");
38 pidf = fopen(pidfloc, "w"); 292 exit(EXIT_FAILURE);
39 293 }
40 /* Generate new keypair */ 294
41 new_keys(); 295 /* Read the config file */
42 296 server_conf = configure_server(argv[1]);
297
298 printf("PID file: %s\n", server_conf.pid_file);
299 printf("Key file: %s\n", server_conf.keys_file);
300
301 if(server_conf.err == -1)
302 printf("Config file not read.\n");
303
304 if(server_conf.err == -2)
305 printf("No valid servers in list.\n");
306
307 /* Open PID file for writing - if an error happens,
308 it will be caught down the line */
309 pidf = fopen(server_conf.pid_file, "w");
310
311 /* Manage the keys */
312 /* for now, just ignore any errors after this call. */
313 int tmperr = errno;
314 manage_keys(server_conf.keys_file);
315 errno = tmperr;
316
43 /* Public key */ 317 /* Public key */
44 uint32_t i; 318 int i;
45
46 printf("\nPublic Key: "); 319 printf("\nPublic Key: ");
47 for(i = 0; i < 32; i++) 320 for(i = 0; i < 32; ++i)
48 { 321 {
49 uint8_t ln, hn; 322 uint8_t ln, hn;
50 ln = 0x0F & self_public_key[i]; 323 ln = 0x0F & self_public_key[i];
@@ -53,84 +326,95 @@ int main(int argc, char *argv[]) {
53 printf("%X%X", hn, ln); 326 printf("%X%X", hn, ln);
54 } 327 }
55 printf("\n"); 328 printf("\n");
56 329
57 /* initialize networking 330 /* initialize networking
58 bind to ip 0.0.0.0:PORT */ 331 bind to ip 0.0.0.0:PORT */
59 IP ip; 332 IP ip;
60 ip.i = 0; 333 ip.i = 0;
61 init_networking(ip, PORT); 334 init_networking(ip, server_conf.port);
62 335
336 /* Bootstrap the DHT
337 This one throws odd errors, too. Ignore. I assume they come
338 from somewhere in the core. */
339 tmperr = errno;
340 connect_to_servers(server_conf.info);
341 errno = tmperr;
342
343 if(!DHT_isconnected()) {
344 puts("Could not establish DHT connection. Check server settings.\n");
345 exit(EXIT_FAILURE);
346 } else {
347 printf("Connected to DHT successfully.\n");
348 }
349
63 /* If there's been an error, exit before forking off */ 350 /* If there's been an error, exit before forking off */
64 if (errno != 0) { 351 if (errno != 0) {
65 perror("Error"); 352 perror("Error");
66 printf("Error(s) occured during start-up. Exiting.\n"); 353 printf("Error(s) occured during start-up. Exiting.\n");
67 exit(EXIT_FAILURE); 354 exit(EXIT_FAILURE);
68 } 355 }
69 356
70// /* Assemble the location of the PID file */ 357 /* Things that make the daemon work come past here.
71// sprintf(pidfloc, PIDFILE, USERNAME); 358 There should be nothing here but the daemon code and
72// pidf = fopen(pidfloc, "w"); 359 the main loop. */
73// /* Check if we can actually open the file */ 360
74// if(pidf == NULL) { 361 /* Fork off from the parent process */
75// printf("Couldn't open PID-File %s for writing.\n", pidfloc);
76// exit(EXIT_FAILURE);
77// }
78
79 /* Fork off the parent process */
80 pid = fork(); 362 pid = fork();
81 if (pid < 0) { 363 if (pid < 0) {
82 printf("Forking failed.\n"); 364 printf("Forking failed.\n");
83 exit(EXIT_FAILURE); 365 exit(EXIT_FAILURE);
84 } 366 }
85 367
86 /* If we got a good PID, then 368 /* If we got a good PID, then
87 we can exit the parent process. */ 369 we can exit the parent process. */
88 if (pid > 0) { 370 if (pid > 0) {
89 printf("Forked successfully: %d\n", pid); 371 printf("Forked successfully: %d\n", pid);
90 372
91 /* Write the PID file */ 373 /* Write the PID file */
92 fprintf(pidf, "%d\n", pid); 374 fprintf(pidf, "%d\n", pid);
93 fclose(pidf); 375 fclose(pidf);
94 376
95 /* Exit parent */ 377 /* Exit parent */
96 exit(EXIT_SUCCESS); 378 exit(EXIT_SUCCESS);
97 } 379 }
98 380
99 /* Change the file mode mask */ 381 /* Change the file mode mask */
100 umask(0); 382 umask(0);
101 383
102 /* Create a new SID for the child process */ 384 /* Create a new SID for the child process */
103 sid = setsid(); 385 sid = setsid();
104 if (sid < 0) { 386 if (sid < 0) {
105 printf("SID creation failure.\n"); 387 printf("SID creation failure.\n");
106 exit(EXIT_FAILURE); 388 exit(EXIT_FAILURE);
107 } 389 }
108 390
109 /* Change the current working directory */ 391 /* Change the current working directory */
110 if ((chdir("/")) < 0) { 392 if ((chdir("/")) < 0) {
111 exit(EXIT_FAILURE); 393 exit(EXIT_FAILURE);
112 } 394 }
113 395
114 /* Go quiet */ 396 /* Go quiet */
115 close(STDIN_FILENO);
116 close(STDOUT_FILENO); 397 close(STDOUT_FILENO);
398 close(STDIN_FILENO);
117 close(STDERR_FILENO); 399 close(STDERR_FILENO);
118 400
401 /* Main loop */
119 IP_Port ip_port; 402 IP_Port ip_port;
120 uint8_t data[MAX_UDP_PACKET_SIZE]; 403 uint8_t data[MAX_UDP_PACKET_SIZE];
121 uint32_t length; 404 uint32_t length;
122 405
123 /* Main loop */ 406 while(1)
124 while(1) { 407 {
125 doDHT(); 408 doDHT();
126 while(receivepacket(&ip_port, data, &length) != -1) { 409
410 while(receivepacket(&ip_port, data, &length) != -1)
411 {
127 DHT_handlepacket(data, length, ip_port); 412 DHT_handlepacket(data, length, ip_port);
128 friendreq_handlepacket(data, length, ip_port); 413 friendreq_handlepacket(data, length, ip_port);
129 } 414 }
130 c_sleep(1); 415 usleep(10000);
131 } 416 }
132 417
133 shutdown_networking(); 418 shutdown_networking();
134 exit(EXIT_SUCCESS); 419 exit(EXIT_SUCCESS);
135} 420}
136
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.sh b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.sh
new file mode 100755
index 00000000..936bc808
--- /dev/null
+++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.sh
@@ -0,0 +1,109 @@
1#! /bin/sh
2### BEGIN INIT INFO
3# Provides: DHT_bootstrap_daemon
4# Required-Start: $remote_fs $syslog
5# Required-Stop: $remote_fs $syslog
6# Default-Start: 2 3 4 5
7# Default-Stop: 0 1 6
8# Short-Description: Start the Tox bootstrapping server
9# Description: Use this piece of junk to start the Tox
10# bootstrap server.
11### END INIT INFO
12
13# PATH should only include /usr/* if it runs after the mountnfs.sh script
14PATH=/sbin:/usr/sbin:/bin:/usr/bin
15DESC="ProjectTox bootstrap server daemon"
16NAME=DHT_bootstrap_daemon
17CFG=/home/$USER/server.cfg
18DAEMON=/home/$USER/$NAME
19DAEMON_ARGS="$CFG"
20PIDFILE=/home/$USER/.$NAME.pid
21SCRIPTNAME=/etc/init.d/$NAME
22
23# Exit if the package is not installed
24[ -x "$DAEMON" ] || exit 0
25
26# Read configuration variable file if it is present
27#[ -r /etc/default/$NAME ] && . /etc/default/$NAME
28
29# Load the VERBOSE setting and other rcS variables
30. /lib/init/vars.sh
31
32# Define LSB log_* functions.
33# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
34# and status_of_proc is working.
35. /lib/lsb/init-functions
36
37#
38# Function that starts the daemon/service
39#
40do_start()
41{
42 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
43 || return 1
44 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
45 $DAEMON_ARGS \
46 || return 2
47 sleep 1
48}
49
50#
51# Function that stops the daemon/service
52#
53do_stop()
54{
55 start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
56 RETVAL="$?"
57 [ "$RETVAL" = 2 ] && return 2
58
59 start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
60 [ "$?" = 2 ] && return 2
61 # Many daemons don't delete their pidfiles when they exit.
62 rm -f $PIDFILE
63 return "$RETVAL"
64}
65
66case "$1" in
67 start)
68 [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
69 do_start
70 case "$?" in
71 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
72 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
73 esac
74 ;;
75 stop)
76 [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
77 do_stop
78 case "$?" in
79 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
80 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
81 esac
82 ;;
83 status)
84 status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
85 ;;
86
87 restart) #|force-reload)
88 log_daemon_msg "Restarting $DESC" "$NAME"
89 do_stop
90 case "$?" in
91 0|1)
92 do_start
93 case "$?" in
94 0) log_end_msg 0 ;;
95 1) log_end_msg 1 ;; # Old process is still running
96 *) log_end_msg 1 ;; # Failed to start
97 esac
98 ;;
99 *)
100 # Failed to stop
101 log_end_msg 1
102 ;;
103 esac
104 ;;
105 *)
106 echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
107 exit 3
108 ;;
109esac
diff --git a/other/bootstrap_serverdaemon/initscript.sh b/other/bootstrap_serverdaemon/initscript.sh
deleted file mode 100644
index aa4b3e77..00000000
--- a/other/bootstrap_serverdaemon/initscript.sh
+++ /dev/null
@@ -1,109 +0,0 @@
1#! /bin/sh
2### BEGIN INIT INFO
3# Provides: bootstrap_server
4# Required-Start: $remote_fs $syslog
5# Required-Stop: $remote_fs $syslog
6# Default-Start: 2 3 4 5
7# Default-Stop: 0 1 6
8# Short-Description: Start the Tox bootstrapping server
9# Description: Use this piece of junk to start the Tox
10# bootstrap server.
11### END INIT INFO
12
13# PATH should only include /usr/* if it runs after the mountnfs.sh script
14PATH=/sbin:/usr/sbin:/bin:/usr/bin
15DESC="ProjectTox bootstrap server daemon"
16NAME=bootstrap_server
17DAEMON=/home/$USER/$NAME
18DAEMON_ARGS=""
19PIDFILE=/home/$USER/.$NAME.pid
20SCRIPTNAME=/etc/init.d/$NAME
21
22# Exit if the package is not installed
23[ -x "$DAEMON" ] || exit 0
24
25# Read configuration variable file if it is present
26[ -r /etc/default/$NAME ] && . /etc/default/$NAME
27
28# Load the VERBOSE setting and other rcS variables
29. /lib/init/vars.sh
30
31# Define LSB log_* functions.
32# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
33# and status_of_proc is working.
34. /lib/lsb/init-functions
35
36#
37# Function that starts the daemon/service
38#
39do_start()
40{
41 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
42 || return 1
43 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
44 $DAEMON_ARGS \
45 || return 2
46 sleep 1
47}
48
49#
50# Function that stops the daemon/service
51#
52do_stop()
53{
54 start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
55 RETVAL="$?"
56 [ "$RETVAL" = 2 ] && return 2
57
58 start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
59 [ "$?" = 2 ] && return 2
60 # Many daemons don't delete their pidfiles when they exit.
61 rm -f $PIDFILE
62 return "$RETVAL"
63}
64
65case "$1" in
66 start)
67 [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
68 do_start
69 case "$?" in
70 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
71 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
72 esac
73 ;;
74 stop)
75 [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
76 do_stop
77 case "$?" in
78 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
79 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
80 esac
81 ;;
82 status)
83 status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
84 ;;
85
86 restart) #|force-reload)
87 log_daemon_msg "Restarting $DESC" "$NAME"
88 do_stop
89 case "$?" in
90 0|1)
91 do_start
92 case "$?" in
93 0) log_end_msg 0 ;;
94 1) log_end_msg 1 ;; # Old process is still running
95 *) log_end_msg 1 ;; # Failed to start
96 esac
97 ;;
98 *)
99 # Failed to stop
100 log_end_msg 1
101 ;;
102 esac
103 ;;
104 *)
105 echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
106 exit 3
107 ;;
108esac
109
diff --git a/other/bootstrap_serverdaemon/server.cfg b/other/bootstrap_serverdaemon/server.cfg
new file mode 100644
index 00000000..8ef516ca
--- /dev/null
+++ b/other/bootstrap_serverdaemon/server.cfg
@@ -0,0 +1,30 @@
1// ProjectTox bootstrap server configuration file
2
3// The port used by bootstrap_server to listen on
4port = 33445;
5
6// The key file
7// make sure that the user who runs the server
8// does have permissions to read it/write to it
9keys_file = "/home/tom/.bootstrap_server.keys"
10
11// The PID file written to by bootstrap_server,
12// make sure that the user who runs the server
13// does have permissions to write to it
14pid_file = "/home/tom/.bootstrap_server.pid";
15
16// The info of the node bootstap_server will
17// bootstrap itself from.
18bootstrap_servers = (
19 { // Server 1
20 ip = "198.46.136.167";
21 port = 33445;
22 bs_pk = "728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854";
23// }
24 },
25 { // Server 2
26 ip = "192.81.133.111";
27 port = 33445;
28 bs_pk = "8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858";
29 }
30);
diff --git a/testing/DHT_cryptosendfiletest.c b/testing/DHT_cryptosendfiletest.c
index 39a928d2..5c3a0256 100644
--- a/testing/DHT_cryptosendfiletest.c
+++ b/testing/DHT_cryptosendfiletest.c
@@ -15,14 +15,33 @@
15 * Saves all received data to: received.txt 15 * Saves all received data to: received.txt
16 * 16 *
17 * EX: ./test 127.0.0.1 33445 filename.txt 17 * EX: ./test 127.0.0.1 33445 filename.txt
18 *
19 * Copyright (C) 2013 Tox project All Rights Reserved.
20 *
21 * This file is part of Tox.
22 *
23 * Tox is free software: you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation, either version 3 of the License, or
26 * (at your option) any later version.
27 *
28 * Tox is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
35 *
18 */ 36 */
37
19#include "../core/network.h" 38#include "../core/network.h"
20#include "../core/DHT.h" 39#include "../core/DHT.h"
21#include "../core/net_crypto.h" 40#include "../core/net_crypto.h"
22 41
23#include <string.h> 42#include <string.h>
24 43
25//Sleep function (x = milliseconds) 44/* Sleep function (x = milliseconds) */
26#ifdef WIN32 45#ifdef WIN32
27 46
28#define c_sleep(x) Sleep(1*x) 47#define c_sleep(x) Sleep(1*x)
@@ -41,15 +60,14 @@ void printip(IP_Port ip_port)
41 printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); 60 printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
42} 61}
43 62
44 63//TODO: rewrite
45//horrible function from one of my first C programs.
46//only here because I was too lazy to write a proper one.
47unsigned char * hex_string_to_bin(char hex_string[]) 64unsigned char * hex_string_to_bin(char hex_string[])
48{ 65{
49 unsigned char * val = malloc(strlen(hex_string)); 66 size_t len = strlen(hex_string);
67 unsigned char * val = malloc(len);
50 char * pos = hex_string; 68 char * pos = hex_string;
51 int i=0; 69 int i=0;
52 while(i < strlen(hex_string)) 70 while(i < len)
53 { 71 {
54 sscanf(pos,"%2hhx",&val[i]); 72 sscanf(pos,"%2hhx",&val[i]);
55 pos+=2; 73 pos+=2;
@@ -69,8 +87,7 @@ int main(int argc, char *argv[])
69 new_keys(); 87 new_keys();
70 printf("OUR ID: "); 88 printf("OUR ID: ");
71 uint32_t i; 89 uint32_t i;
72 for(i = 0; i < 32; i++) 90 for(i = 0; i < 32; i++) {
73 {
74 if(self_public_key[i] < 16) 91 if(self_public_key[i] < 16)
75 printf("0"); 92 printf("0");
76 printf("%hhX",self_public_key[i]); 93 printf("%hhX",self_public_key[i]);
@@ -86,8 +103,7 @@ int main(int argc, char *argv[])
86 uint8_t friend_id[32]; 103 uint8_t friend_id[32];
87 memcpy(friend_id, hex_string_to_bin(temp_id), 32); 104 memcpy(friend_id, hex_string_to_bin(temp_id), 32);
88 105
89 106 /* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */
90 //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
91 107
92 108
93 DHT_addfriend(friend_id); 109 DHT_addfriend(friend_id);
@@ -99,15 +115,13 @@ int main(int argc, char *argv[])
99 int friendrequest = -1; 115 int friendrequest = -1;
100 uint8_t request_data[512]; 116 uint8_t request_data[512];
101 117
102 //initialize networking 118 /* initialize networking
103 //bind to ip 0.0.0.0:PORT 119 * bind to ip 0.0.0.0:PORT */
104 IP ip; 120 IP ip;
105 ip.i = 0; 121 ip.i = 0;
106 init_networking(ip, PORT); 122 init_networking(ip, PORT);
107 initNetCrypto(); 123 initNetCrypto();
108 124
109
110
111 perror("Initialization"); 125 perror("Initialization");
112 IP_Port bootstrap_ip_port; 126 IP_Port bootstrap_ip_port;
113 bootstrap_ip_port.port = htons(atoi(argv[2])); 127 bootstrap_ip_port.port = htons(atoi(argv[2]));
@@ -128,125 +142,102 @@ int main(int argc, char *argv[])
128 if ( file2==NULL ){return 1;} 142 if ( file2==NULL ){return 1;}
129 read1 = fread(buffer1, 1, 128, file1); 143 read1 = fread(buffer1, 1, 128, file1);
130 144
131 while(1) 145 while(1) {
132 { 146 while(receivepacket(&ip_port, data, &length) != -1) {
133 147 if(rand() % 3 != 1) { /* simulate packet loss */
134 while(receivepacket(&ip_port, data, &length) != -1) 148 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
135 { 149 /* if packet is not recognized */
136 if(rand() % 3 != 1)//simulate packet loss
137 {
138 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port))
139 {
140 //if packet is not recognized
141 printf("Received unhandled packet with length: %u\n", length); 150 printf("Received unhandled packet with length: %u\n", length);
142 } 151 } else {
143 else
144 {
145 printf("Received handled packet with length: %u\n", length); 152 printf("Received handled packet with length: %u\n", length);
146 } 153 }
147 } 154 }
148 } 155 }
149 friend_ip = DHT_getfriendip(friend_id); 156 friend_ip = DHT_getfriendip(friend_id);
150 if(friend_ip.ip.i != 0) 157 if(friend_ip.ip.i != 0) {
151 { 158 if(connection == -1 && friendrequest == -1) {
152 if(connection == -1 && friendrequest == -1)
153 {
154 printf("Sending friend request to peer:"); 159 printf("Sending friend request to peer:");
155 printip(friend_ip); 160 printip(friend_ip);
156 friendrequest = send_friendrequest(friend_id, friend_ip,(uint8_t *) "Hello World", 12); 161 friendrequest = send_friendrequest(friend_id, friend_ip,(uint8_t *) "Hello World", 12);
157 //connection = crypto_connect((uint8_t *)friend_id, friend_ip); 162 /* connection = crypto_connect((uint8_t *)friend_id, friend_ip); */
158 //connection = new_connection(friend_ip); 163 /* connection = new_connection(friend_ip); */
159 } 164 }
160 if(check_friendrequest(friendrequest) == 1) 165 if(check_friendrequest(friendrequest) == 1) {
161 {
162 printf("Started connecting to friend:"); 166 printf("Started connecting to friend:");
163 connection = crypto_connect(friend_id, friend_ip); 167 connection = crypto_connect(friend_id, friend_ip);
164 } 168 }
165 } 169 }
166 if(inconnection == -1) 170 if(inconnection == -1) {
167 {
168 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 171 uint8_t secret_nonce[crypto_box_NONCEBYTES];
169 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 172 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
170 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 173 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
171 inconnection = crypto_inbound(public_key, secret_nonce, session_key); 174 inconnection = crypto_inbound(public_key, secret_nonce, session_key);
172 inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key); 175 inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key);
173 //inconnection = incoming_connection(); 176 /* inconnection = incoming_connection(); */
174 if(inconnection != -1) 177 if(inconnection != -1) {
175 {
176 printf("Someone connected to us:\n"); 178 printf("Someone connected to us:\n");
177 // printip(connection_ip(inconnection)); 179 /* printip(connection_ip(inconnection)); */
178 } 180 }
179 } 181 }
180 if(handle_friendrequest(acceptedfriend_public_key, request_data) > 1) 182 if(handle_friendrequest(acceptedfriend_public_key, request_data) > 1) {
181 {
182 printf("RECIEVED FRIEND REQUEST: %s\n", request_data); 183 printf("RECIEVED FRIEND REQUEST: %s\n", request_data);
183 } 184 }
184 185
185 //if someone connected to us write what he sends to a file 186 /* if someone connected to us write what he sends to a file
186 //also send him our file. 187 * also send him our file. */
187 if(inconnection != -1) 188 if(inconnection != -1) {
188 { 189 if(write_cryptpacket(inconnection, buffer1, read1)) {
189 if(write_cryptpacket(inconnection, buffer1, read1))
190 {
191 printf("Wrote data1.\n"); 190 printf("Wrote data1.\n");
192 read1 = fread(buffer1, 1, 128, file1); 191 read1 = fread(buffer1, 1, 128, file1);
193 } 192 }
194 read2 = read_cryptpacket(inconnection, buffer2); 193 read2 = read_cryptpacket(inconnection, buffer2);
195 if(read2 != 0) 194 if(read2 != 0) {
196 {
197 printf("Received data1.\n"); 195 printf("Received data1.\n");
198 if(!fwrite(buffer2, read2, 1, file2)) 196 if(!fwrite(buffer2, read2, 1, file2)) {
199 {
200 printf("file write error1\n"); 197 printf("file write error1\n");
201 } 198 }
202 if(read2 < 128) 199 if(read2 < 128) {
203 {
204 printf("Closed file1 %u\n", read2); 200 printf("Closed file1 %u\n", read2);
205 fclose(file2); 201 fclose(file2);
206 } 202 }
207 } 203 }
208 else if(is_cryptoconnected(inconnection) == 4)//if buffer is empty and the connection timed out. 204 /* if buffer is empty and the connection timed out. */
209 { 205 else if(is_cryptoconnected(inconnection) == 4) {
210 crypto_kill(inconnection); 206 crypto_kill(inconnection);
211 } 207 }
212 } 208 }
213 //if we are connected to a friend send him data from the file. 209 /* if we are connected to a friend send him data from the file.
214 //also put what he sends us in a file. 210 * also put what he sends us in a file. */
215 if(is_cryptoconnected(connection) >= 3) 211 if(is_cryptoconnected(connection) >= 3) {
216 { 212 if(write_cryptpacket(0, buffer1, read1)) {
217 if(write_cryptpacket(0, buffer1, read1))
218 {
219 printf("Wrote data2.\n"); 213 printf("Wrote data2.\n");
220 read1 = fread(buffer1, 1, 128, file1); 214 read1 = fread(buffer1, 1, 128, file1);
221 } 215 }
222 read2 = read_cryptpacket(0, buffer2); 216 read2 = read_cryptpacket(0, buffer2);
223 if(read2 != 0) 217 if(read2 != 0) {
224 {
225 printf("Received data2.\n"); 218 printf("Received data2.\n");
226 if(!fwrite(buffer2, read2, 1, file2)) 219 if(!fwrite(buffer2, read2, 1, file2)) {
227 {
228 printf("file write error2\n"); 220 printf("file write error2\n");
229 } 221 }
230 if(read2 < 128) 222 if(read2 < 128) {
231 {
232 printf("Closed file2 %u\n", read2); 223 printf("Closed file2 %u\n", read2);
233 fclose(file2); 224 fclose(file2);
234 } 225 }
235 } 226 }
236 else if(is_cryptoconnected(connection) == 4)//if buffer is empty and the connection timed out. 227 /* if buffer is empty and the connection timed out. */
237 { 228 else if(is_cryptoconnected(connection) == 4) {
238 crypto_kill(connection); 229 crypto_kill(connection);
239 } 230 }
240 } 231 }
241 doDHT(); 232 doDHT();
242 doLossless_UDP(); 233 doLossless_UDP();
243 doNetCrypto(); 234 doNetCrypto();
244 //print_clientlist(); 235 /*print_clientlist();
245 //print_friendlist(); 236 *print_friendlist();
246 //c_sleep(300); 237 *c_sleep(300); */
247 c_sleep(1); 238 c_sleep(1);
248 } 239 }
249 240
250 shutdown_networking(); 241 shutdown_networking();
251 return 0; 242 return 0;
252} \ No newline at end of file 243}
diff --git a/testing/DHT_sendfiletest.c b/testing/DHT_sendfiletest.c
index 52ee7400..5b5d6c9f 100644
--- a/testing/DHT_sendfiletest.c
+++ b/testing/DHT_sendfiletest.c
@@ -14,7 +14,26 @@
14 * Saves all received data to: received.txt 14 * Saves all received data to: received.txt
15 * 15 *
16 * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg 16 * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg
17 *
18 * Copyright (C) 2013 Tox project All Rights Reserved.
19 *
20 * This file is part of Tox.
21 *
22 * Tox is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation, either version 3 of the License, or
25 * (at your option) any later version.
26 *
27 * Tox is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
34 *
17 */ 35 */
36
18#include "../core/network.h" 37#include "../core/network.h"
19#include "../core/DHT.h" 38#include "../core/DHT.h"
20#include "../core/Lossless_UDP.h" 39#include "../core/Lossless_UDP.h"
@@ -82,68 +101,53 @@ int main(int argc, char *argv[])
82 if ( file2==NULL ){return 1;} 101 if ( file2==NULL ){return 1;}
83 read1 = fread(buffer1, 1, 128, file1); 102 read1 = fread(buffer1, 1, 128, file1);
84 103
85 while(1) 104 while(1) {
86 {
87 105
88 while(receivepacket(&ip_port, data, &length) != -1) 106 while(receivepacket(&ip_port, data, &length) != -1) {
89 { 107 if(rand() % 3 != 1) { /* simulate packet loss */
90 if(rand() % 3 != 1)//simulate packet loss 108 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
91 { 109 /* if packet is not recognized */
92 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port))
93 {
94 //if packet is not recognized
95 printf("Received unhandled packet with length: %u\n", length); 110 printf("Received unhandled packet with length: %u\n", length);
96 } 111 } else {
97 else
98 {
99 printf("Received handled packet with length: %u\n", length); 112 printf("Received handled packet with length: %u\n", length);
100 } 113 }
101 } 114 }
102 } 115 }
103 friend_ip = DHT_getfriendip((uint8_t *)argv[3]); 116 friend_ip = DHT_getfriendip((uint8_t *)argv[3]);
104 if(friend_ip.ip.i != 0) 117 if(friend_ip.ip.i != 0) {
105 { 118 if(connection == -1) {
106 if(connection == -1)
107 {
108 printf("Started connecting to friend:"); 119 printf("Started connecting to friend:");
109 printip(friend_ip); 120 printip(friend_ip);
110 connection = new_connection(friend_ip); 121 connection = new_connection(friend_ip);
111 } 122 }
112 } 123 }
113 if(inconnection == -1) 124 if(inconnection == -1) {
114 {
115 inconnection = incoming_connection(); 125 inconnection = incoming_connection();
116 if(inconnection != -1) 126 if(inconnection != -1) {
117 {
118 printf("Someone connected to us:"); 127 printf("Someone connected to us:");
119 printip(connection_ip(inconnection)); 128 printip(connection_ip(inconnection));
120 } 129 }
121 } 130 }
122 //if someone connected to us write what he sends to a file 131 /* if someone connected to us write what he sends to a file */
123 //also send him our file. 132 /* also send him our file. */
124 if(inconnection != -1) 133 if(inconnection != -1) {
125 { 134 if(write_packet(inconnection, buffer1, read1)) {
126 if(write_packet(inconnection, buffer1, read1))
127 {
128 printf("Wrote data.\n"); 135 printf("Wrote data.\n");
129 read1 = fread(buffer1, 1, 128, file1); 136 read1 = fread(buffer1, 1, 128, file1);
130 } 137 }
131 read2 = read_packet(inconnection, buffer2); 138 read2 = read_packet(inconnection, buffer2);
132 if(read2 != 0) 139 if(read2 != 0) {
133 {
134 printf("Received data.\n"); 140 printf("Received data.\n");
135 if(!fwrite(buffer2, read2, 1, file2)) 141 if(!fwrite(buffer2, read2, 1, file2)) {
136 {
137 printf("file write error\n"); 142 printf("file write error\n");
138 } 143 }
139 if(read2 < 128) 144 if(read2 < 128) {
140 {
141 fclose(file2); 145 fclose(file2);
142 } 146 }
143 } 147 }
144 } 148 }
145 //if we are connected to a friend send him data from the file. 149 /* if we are connected to a friend send him data from the file.
146 //also put what he sends us in a file. 150 * also put what he sends us in a file. */
147 if(is_connected(connection) == 3) 151 if(is_connected(connection) == 3)
148 { 152 {
149 if(write_packet(0, buffer1, read1)) 153 if(write_packet(0, buffer1, read1))
@@ -167,9 +171,9 @@ int main(int argc, char *argv[])
167 } 171 }
168 doDHT(); 172 doDHT();
169 doLossless_UDP(); 173 doLossless_UDP();
170 //print_clientlist(); 174 /* print_clientlist();
171 //print_friendlist(); 175 * print_friendlist();
172 //c_sleep(300); 176 * c_sleep(300); */
173 c_sleep(1); 177 c_sleep(1);
174 } 178 }
175 179
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index e194d06b..d14e1577 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -7,7 +7,26 @@
7 * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 7 * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
8 * 8 *
9 * The test will then ask you for the id (in hex format) of the friend you wish to add 9 * The test will then ask you for the id (in hex format) of the friend you wish to add
10 *
11 * Copyright (C) 2013 Tox project All Rights Reserved.
12 *
13 * This file is part of Tox.
14 *
15 * Tox is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * Tox is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
27 *
10 */ 28 */
29
11//#include "../core/network.h" 30//#include "../core/network.h"
12#include "../core/DHT.c" 31#include "../core/DHT.c"
13#include "../core/friend_requests.c" 32#include "../core/friend_requests.c"
@@ -28,17 +47,14 @@
28 47
29#define PORT 33445 48#define PORT 33445
30 49
31
32void print_clientlist() 50void print_clientlist()
33{ 51{
34 uint32_t i, j; 52 uint32_t i, j;
35 IP_Port p_ip; 53 IP_Port p_ip;
36 printf("___________________CLOSE________________________________\n"); 54 printf("___________________CLOSE________________________________\n");
37 for(i = 0; i < 4; i++) 55 for(i = 0; i < 4; i++) {
38 {
39 printf("ClientID: "); 56 printf("ClientID: ");
40 for(j = 0; j < 32; j++) 57 for(j = 0; j < 32; j++) {
41 {
42 printf("%c", close_clientlist[i].client_id[j]); 58 printf("%c", close_clientlist[i].client_id[j]);
43 } 59 }
44 p_ip = close_clientlist[i].ip_port; 60 p_ip = close_clientlist[i].ip_port;
@@ -56,12 +72,10 @@ void print_friendlist()
56 uint32_t i, j, k; 72 uint32_t i, j, k;
57 IP_Port p_ip; 73 IP_Port p_ip;
58 printf("_________________FRIENDS__________________________________\n"); 74 printf("_________________FRIENDS__________________________________\n");
59 for(k = 0; k < num_friends; k++) 75 for(k = 0; k < num_friends; k++) {
60 {
61 printf("FRIEND %u\n", k); 76 printf("FRIEND %u\n", k);
62 printf("ID: "); 77 printf("ID: ");
63 for(j = 0; j < 32; j++) 78 for(j = 0; j < 32; j++) {
64 {
65 printf("%c", friends_list[k].client_id[j]); 79 printf("%c", friends_list[k].client_id[j]);
66 } 80 }
67 p_ip = DHT_getfriendip(friends_list[k].client_id); 81 p_ip = DHT_getfriendip(friends_list[k].client_id);
@@ -69,11 +83,9 @@ void print_friendlist()
69 83
70 printf("\nCLIENTS IN LIST:\n\n"); 84 printf("\nCLIENTS IN LIST:\n\n");
71 85
72 for(i = 0; i < 4; i++) 86 for(i = 0; i < 4; i++) {
73 {
74 printf("ClientID: "); 87 printf("ClientID: ");
75 for(j = 0; j < 32; j++) 88 for(j = 0; j < 32; j++) {
76 {
77 if(0 <= friends_list[k].client_list[i].client_id[j] && friends_list[k].client_list[i].client_id[j] < 16) 89 if(0 <= friends_list[k].client_list[i].client_id[j] && friends_list[k].client_list[i].client_id[j] < 16)
78 printf("0"); 90 printf("0");
79 printf("%hhX", friends_list[k].client_list[i].client_id[j]); 91 printf("%hhX", friends_list[k].client_list[i].client_id[j]);
@@ -94,8 +106,7 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
94 uint32_t i; 106 uint32_t i;
95 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); 107 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
96 printf("--------------------BEGIN-----------------------------\n"); 108 printf("--------------------BEGIN-----------------------------\n");
97 for(i = 0; i < length; i++) 109 for(i = 0; i < length; i++) {
98 {
99 if(data[i] < 16) 110 if(data[i] < 16)
100 printf("0"); 111 printf("0");
101 printf("%hhX",data[i]); 112 printf("%hhX",data[i]);
@@ -103,14 +114,14 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
103 printf("\n--------------------END-----------------------------\n\n\n"); 114 printf("\n--------------------END-----------------------------\n\n\n");
104} 115}
105 116
106//horrible function from one of my first C programs. 117//TODO: rewrite
107//only here because I was too lazy to write a proper one.
108unsigned char * hex_string_to_bin(char hex_string[]) 118unsigned char * hex_string_to_bin(char hex_string[])
109{ 119{
110 unsigned char * val = malloc(strlen(hex_string)); 120 size_t len = strlen(hex_string);
121 unsigned char * val = malloc(len);
111 char * pos = hex_string; 122 char * pos = hex_string;
112 int i=0; 123 int i=0;
113 while(i < strlen(hex_string)) 124 while(i < len)
114 { 125 {
115 sscanf(pos,"%2hhx",&val[i]); 126 sscanf(pos,"%2hhx",&val[i]);
116 pos+=2; 127 pos+=2;
@@ -130,8 +141,7 @@ int main(int argc, char *argv[])
130 new_keys(); 141 new_keys();
131 printf("OUR ID: "); 142 printf("OUR ID: ");
132 uint32_t i; 143 uint32_t i;
133 for(i = 0; i < 32; i++) 144 for(i = 0; i < 32; i++) {
134 {
135 if(self_public_key[i] < 16) 145 if(self_public_key[i] < 16)
136 printf("0"); 146 printf("0");
137 printf("%hhX",self_public_key[i]); 147 printf("%hhX",self_public_key[i]);
@@ -142,8 +152,8 @@ int main(int argc, char *argv[])
142 scanf("%s", temp_id); 152 scanf("%s", temp_id);
143 DHT_addfriend(hex_string_to_bin(temp_id)); 153 DHT_addfriend(hex_string_to_bin(temp_id));
144 154
145 //initialize networking 155 /* initialize networking */
146 //bind to ip 0.0.0.0:PORT 156 /* bind to ip 0.0.0.0:PORT */
147 IP ip; 157 IP ip;
148 ip.i = 0; 158 ip.i = 0;
149 init_networking(ip, PORT); 159 init_networking(ip, PORT);
@@ -152,10 +162,10 @@ int main(int argc, char *argv[])
152 perror("Initialization"); 162 perror("Initialization");
153 IP_Port bootstrap_ip_port; 163 IP_Port bootstrap_ip_port;
154 bootstrap_ip_port.port = htons(atoi(argv[2])); 164 bootstrap_ip_port.port = htons(atoi(argv[2]));
155 //bootstrap_ip_port.ip.c[0] = 127; 165 /* bootstrap_ip_port.ip.c[0] = 127;
156 //bootstrap_ip_port.ip.c[1] = 0; 166 * bootstrap_ip_port.ip.c[1] = 0;
157 //bootstrap_ip_port.ip.c[2] = 0; 167 * bootstrap_ip_port.ip.c[2] = 0;
158 //bootstrap_ip_port.ip.c[3] = 1; 168 * bootstrap_ip_port.ip.c[3] = 1; */
159 bootstrap_ip_port.ip.i = inet_addr(argv[1]); 169 bootstrap_ip_port.ip.i = inet_addr(argv[1]);
160 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 170 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
161 171
@@ -163,20 +173,15 @@ int main(int argc, char *argv[])
163 uint8_t data[MAX_UDP_PACKET_SIZE]; 173 uint8_t data[MAX_UDP_PACKET_SIZE];
164 uint32_t length; 174 uint32_t length;
165 175
166 while(1) 176 while(1) {
167 {
168 177
169 doDHT(); 178 doDHT();
170 179
171 while(receivepacket(&ip_port, data, &length) != -1) 180 while(receivepacket(&ip_port, data, &length) != -1) {
172 { 181 if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
173 if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port))
174 {
175 //unhandled packet 182 //unhandled packet
176 printpacket(data, length, ip_port); 183 printpacket(data, length, ip_port);
177 } 184 } else {
178 else
179 {
180 printf("Received handled packet with length: %u\n", length); 185 printf("Received handled packet with length: %u\n", length);
181 } 186 }
182 } 187 }
@@ -187,4 +192,4 @@ int main(int argc, char *argv[])
187 192
188 shutdown_networking(); 193 shutdown_networking();
189 return 0; 194 return 0;
190} \ No newline at end of file 195}
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c
index 0c21867d..8f23528c 100644
--- a/testing/Lossless_UDP_testclient.c
+++ b/testing/Lossless_UDP_testclient.c
@@ -8,6 +8,24 @@
8 * 8 *
9 * Command line arguments are the ip and port to connect and send the file to. 9 * Command line arguments are the ip and port to connect and send the file to.
10 * EX: ./testclient 127.0.0.1 33445 filename.txt 10 * EX: ./testclient 127.0.0.1 33445 filename.txt
11 *
12 * Copyright (C) 2013 Tox project All Rights Reserved.
13 *
14 * This file is part of Tox.
15 *
16 * Tox is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * Tox is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
28 *
11 */ 29 */
12 30
13#include "../core/network.h" 31#include "../core/network.h"
@@ -24,7 +42,6 @@
24 42
25#endif 43#endif
26 44
27
28#define PORT 33446 45#define PORT 33446
29 46
30void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) 47void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
@@ -32,8 +49,7 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
32 uint32_t i; 49 uint32_t i;
33 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); 50 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
34 printf("--------------------BEGIN-----------------------------\n"); 51 printf("--------------------BEGIN-----------------------------\n");
35 for(i = 0; i < length; i++) 52 for(i = 0; i < length; i++) {
36 {
37 if(data[i] < 16) 53 if(data[i] < 16)
38 printf("0"); 54 printf("0");
39 printf("%hhX",data[i]); 55 printf("%hhX",data[i]);
@@ -99,39 +115,34 @@ void printconnection(int connection_id)
99 115
100} 116}
101*/ 117*/
102//recieve packets and send them to the packethandler 118
103//run doLossless_UDP(); 119/*( recieve packets and send them to the packethandler */
120/*run doLossless_UDP(); */
104void Lossless_UDP() 121void Lossless_UDP()
105{ 122{
106 IP_Port ip_port; 123 IP_Port ip_port;
107 uint8_t data[MAX_UDP_PACKET_SIZE]; 124 uint8_t data[MAX_UDP_PACKET_SIZE];
108 uint32_t length; 125 uint32_t length;
109 while(receivepacket(&ip_port, data, &length) != -1) 126 while(receivepacket(&ip_port, data, &length) != -1) {
110 {
111 printf("packet with length: %u\n", length); 127 printf("packet with length: %u\n", length);
112 //if(rand() % 3 != 1)//add packet loss 128 /* if(rand() % 3 != 1)//add packet loss
113 // { 129 { */
114 if(LosslessUDP_handlepacket(data, length, ip_port)) 130 if(LosslessUDP_handlepacket(data, length, ip_port)) {
115 {
116 printpacket(data, length, ip_port); 131 printpacket(data, length, ip_port);
117 } 132 } else {
118 else
119 {
120 //printconnection(0); 133 //printconnection(0);
121 printf("Received handled packet with length: %u\n", length); 134 printf("Received handled packet with length: %u\n", length);
122 } 135 }
123 // } 136 /* } */
124 } 137 }
125 138
126 doLossless_UDP(); 139 doLossless_UDP();
127 140
128} 141}
129 142
130
131int main(int argc, char *argv[]) 143int main(int argc, char *argv[])
132{ 144{
133 if (argc < 4) 145 if (argc < 4) {
134 {
135 printf("usage: %s ip port filename\n", argv[0]); 146 printf("usage: %s ip port filename\n", argv[0]);
136 exit(0); 147 exit(0);
137 } 148 }
@@ -143,8 +154,8 @@ int main(int argc, char *argv[])
143 if ( file==NULL ){return 1;} 154 if ( file==NULL ){return 1;}
144 155
145 156
146 //initialize networking 157 /* initialize networking */
147 //bind to ip 0.0.0.0:PORT 158 /* bind to ip 0.0.0.0:PORT */
148 IP ip; 159 IP ip;
149 ip.i = 0; 160 ip.i = 0;
150 init_networking(ip, PORT); 161 init_networking(ip, PORT);
@@ -155,17 +166,14 @@ int main(int argc, char *argv[])
155 printip(serverip); 166 printip(serverip);
156 int connection = new_connection(serverip); 167 int connection = new_connection(serverip);
157 uint64_t timer = current_time(); 168 uint64_t timer = current_time();
158 while(1) 169 while(1) {
159 { 170 /* printconnection(connection); */
160 // printconnection(connection);
161 Lossless_UDP(); 171 Lossless_UDP();
162 if(is_connected(connection) == 3) 172 if(is_connected(connection) == 3) {
163 {
164 printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer)); 173 printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
165 break; 174 break;
166 } 175 }
167 if(is_connected(connection) == 0) 176 if(is_connected(connection) == 0) {
168 {
169 printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); 177 printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
170 return 1; 178 return 1;
171 } 179 }
@@ -174,38 +182,32 @@ int main(int argc, char *argv[])
174 timer = current_time(); 182 timer = current_time();
175 183
176 184
177 //read first part of file 185 /*read first part of file */
178 read = fread(buffer, 1, 512, file); 186 read = fread(buffer, 1, 512, file);
179 187
180 while(1) 188 while(1) {
181 { 189 /* printconnection(connection); */
182 //printconnection(connection);
183 Lossless_UDP(); 190 Lossless_UDP();
184 if(is_connected(connection) == 3) 191 if(is_connected(connection) == 3) {
185 {
186 192
187 if(write_packet(connection, buffer, read)) 193 if(write_packet(connection, buffer, read)) {
188 { 194 /* printf("Wrote data.\n"); */
189 //printf("Wrote data.\n");
190 read = fread(buffer, 1, 512, file); 195 read = fread(buffer, 1, 512, file);
191 196
192 } 197 }
193 //printf("%u\n", sendqueue(connection)); 198 /* printf("%u\n", sendqueue(connection)); */
194 if(sendqueue(connection) == 0) 199 if(sendqueue(connection) == 0) {
195 { 200 if(read == 0) {
196 if(read == 0)
197 {
198 printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer)); 201 printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer));
199 break; 202 break;
200 } 203 }
201 } 204 }
202 } 205 }
203 else 206 else {
204 {
205 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); 207 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
206 return 0; 208 return 0;
207 } 209 }
208 //c_sleep(1); 210 /* c_sleep(1); */
209 } 211 }
210 212
211 return 0; 213 return 0;
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c
index 8043be25..a8097048 100644
--- a/testing/Lossless_UDP_testserver.c
+++ b/testing/Lossless_UDP_testserver.c
@@ -8,6 +8,24 @@
8 * 8 *
9 * Command line argument is the name of the file to save what we recieve to. 9 * Command line argument is the name of the file to save what we recieve to.
10 * EX: ./testserver filename1.txt 10 * EX: ./testserver filename1.txt
11 *
12 * Copyright (C) 2013 Tox project All Rights Reserved.
13 *
14 * This file is part of Tox.
15 *
16 * Tox is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * Tox is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
28 *
11 */ 29 */
12 30
13#include "../core/network.h" 31#include "../core/network.h"
@@ -25,7 +43,6 @@
25 43
26#endif 44#endif
27 45
28
29#define PORT 33445 46#define PORT 33445
30 47
31void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) 48void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
@@ -33,14 +50,14 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
33 uint32_t i; 50 uint32_t i;
34 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); 51 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
35 printf("--------------------BEGIN-----------------------------\n"); 52 printf("--------------------BEGIN-----------------------------\n");
36 for(i = 0; i < length; i++) 53 for(i = 0; i < length; i++) {
37 {
38 if(data[i] < 16) 54 if(data[i] < 16)
39 printf("0"); 55 printf("0");
40 printf("%hhX",data[i]); 56 printf("%hhX",data[i]);
41 } 57 }
42 printf("\n--------------------END-----------------------------\n\n\n"); 58 printf("\n--------------------END-----------------------------\n\n\n");
43} 59}
60
44/* 61/*
45void printpackets(Data test) 62void printpackets(Data test)
46{ 63{
@@ -95,23 +112,20 @@ void printconnection(int connection_id)
95 112
96} 113}
97*/ 114*/
98//recieve packets and send them to the packethandler 115
99//run doLossless_UDP(); 116/* recieve packets and send them to the packethandler
117 * run doLossless_UDP(); */
100void Lossless_UDP() 118void Lossless_UDP()
101{ 119{
102 IP_Port ip_port; 120 IP_Port ip_port;
103 uint8_t data[MAX_UDP_PACKET_SIZE]; 121 uint8_t data[MAX_UDP_PACKET_SIZE];
104 uint32_t length; 122 uint32_t length;
105 while(receivepacket(&ip_port, data, &length) != -1) 123 while(receivepacket(&ip_port, data, &length) != -1) {
106 {
107 //if(rand() % 3 != 1)//add packet loss 124 //if(rand() % 3 != 1)//add packet loss
108 //{ 125 //{
109 if(LosslessUDP_handlepacket(data, length, ip_port)) 126 if(LosslessUDP_handlepacket(data, length, ip_port)) {
110 {
111 printpacket(data, length, ip_port); 127 printpacket(data, length, ip_port);
112 } 128 } else {
113 else
114 {
115 //printconnection(0); 129 //printconnection(0);
116 printf("Received handled packet with length: %u\n", length); 130 printf("Received handled packet with length: %u\n", length);
117 } 131 }
@@ -119,14 +133,12 @@ void Lossless_UDP()
119 } 133 }
120 134
121 doLossless_UDP(); 135 doLossless_UDP();
122
123} 136}
124 137
125 138
126int main(int argc, char *argv[]) 139int main(int argc, char *argv[])
127{ 140{
128 if (argc < 2) 141 if (argc < 2) {
129 {
130 printf("usage: %s filename\n", argv[0]); 142 printf("usage: %s filename\n", argv[0]);
131 exit(0); 143 exit(0);
132 } 144 }
@@ -149,14 +161,11 @@ int main(int argc, char *argv[])
149 uint64_t timer = current_time(); 161 uint64_t timer = current_time();
150 162
151 163
152 while(1) 164 while(1) {
153 {
154 Lossless_UDP(); 165 Lossless_UDP();
155 connection = incoming_connection(); 166 connection = incoming_connection();
156 if(connection != -1) 167 if(connection != -1) {
157 { 168 if(is_connected(connection) == 2) {
158 if(is_connected(connection) == 2)
159 {
160 printf("Recieved the connection.\n"); 169 printf("Recieved the connection.\n");
161 170
162 } 171 }
@@ -167,25 +176,20 @@ int main(int argc, char *argv[])
167 176
168 timer = current_time(); 177 timer = current_time();
169 178
170 while(1) 179 while(1) {
171 {
172 //printconnection(0); 180 //printconnection(0);
173 Lossless_UDP(); 181 Lossless_UDP();
174 if(is_connected(connection) >= 2) 182 if(is_connected(connection) >= 2) {
175 {
176 kill_connection_in(connection, 3000000); 183 kill_connection_in(connection, 3000000);
177 read = read_packet(connection, buffer); 184 read = read_packet(connection, buffer);
178 if(read != 0) 185 if(read != 0) {
179 {
180 // printf("Recieved data.\n"); 186 // printf("Recieved data.\n");
181 if(!fwrite(buffer, read, 1, file)) 187 if(!fwrite(buffer, read, 1, file)) {
182 {
183 printf("file write error\n"); 188 printf("file write error\n");
184 } 189 }
185 } 190 }
186 } 191 }
187 if(is_connected(connection) == 4) 192 if(is_connected(connection) == 4) {
188 {
189 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); 193 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
190 fclose(file); 194 fclose(file);
191 return 1; 195 return 1;
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c
index f9215b44..f38eb962 100644
--- a/testing/Messenger_test.c
+++ b/testing/Messenger_test.c
@@ -17,7 +17,24 @@
17 * Or the argument can be the path to the save file. 17 * Or the argument can be the path to the save file.
18 * 18 *
19 * EX: ./test Save.bak 19 * EX: ./test Save.bak
20 * 20 *
21 * Copyright (C) 2013 Tox project All Rights Reserved.
22 *
23 * This file is part of Tox.
24 *
25 * Tox is free software: you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation, either version 3 of the License, or
28 * (at your option) any later version.
29 *
30 * Tox is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
37 *
21 */ 38 */
22 39
23#include "../core/Messenger.h" 40#include "../core/Messenger.h"
@@ -33,14 +50,14 @@
33 50
34#endif 51#endif
35 52
36//horrible function from one of my first C programs. 53//TODO: rewrite
37//only here because I was too lazy to write a proper one.
38unsigned char * hex_string_to_bin(char hex_string[]) 54unsigned char * hex_string_to_bin(char hex_string[])
39{ 55{
40 unsigned char * val = malloc(strlen(hex_string)); 56 size_t len = strlen(hex_string);
57 unsigned char * val = malloc(len);
41 char * pos = hex_string; 58 char * pos = hex_string;
42 int i=0; 59 int i=0;
43 while(i < strlen(hex_string)) 60 while(i < len)
44 { 61 {
45 sscanf(pos,"%2hhx",&val[i]); 62 sscanf(pos,"%2hhx",&val[i]);
46 pos+=2; 63 pos+=2;
@@ -87,15 +104,12 @@ int main(int argc, char *argv[])
87 exit(0); 104 exit(0);
88 } 105 }
89 initMessenger(); 106 initMessenger();
90 if(argc > 3) 107 if(argc > 3) {
91 {
92 IP_Port bootstrap_ip_port; 108 IP_Port bootstrap_ip_port;
93 bootstrap_ip_port.port = htons(atoi(argv[2])); 109 bootstrap_ip_port.port = htons(atoi(argv[2]));
94 bootstrap_ip_port.ip.i = inet_addr(argv[1]); 110 bootstrap_ip_port.ip.i = inet_addr(argv[1]);
95 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 111 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
96 } 112 } else {
97 else
98 {
99 FILE *file = fopen(argv[1], "rb"); 113 FILE *file = fopen(argv[1], "rb");
100 if ( file==NULL ){return 1;} 114 if ( file==NULL ){return 1;}
101 int read; 115 int read;
@@ -110,8 +124,7 @@ int main(int argc, char *argv[])
110 124
111 printf("OUR ID: "); 125 printf("OUR ID: ");
112 uint32_t i; 126 uint32_t i;
113 for(i = 0; i < 32; i++) 127 for(i = 0; i < 32; i++) {
114 {
115 if(self_public_key[i] < 16) 128 if(self_public_key[i] < 16)
116 printf("0"); 129 printf("0");
117 printf("%hhX",self_public_key[i]); 130 printf("%hhX",self_public_key[i]);
@@ -121,16 +134,14 @@ int main(int argc, char *argv[])
121 134
122 char temp_id[128]; 135 char temp_id[128];
123 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); 136 printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
124 if(scanf("%s", temp_id) != 1) 137 if(scanf("%s", temp_id) != 1) {
125 {
126 return 1; 138 return 1;
127 } 139 }
128 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 140 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
129 141
130 perror("Initialization"); 142 perror("Initialization");
131 143
132 while(1) 144 while(1) {
133 {
134 uint8_t name[128]; 145 uint8_t name[128];
135 getname(num, name); 146 getname(num, name);
136 printf("%s\n", name); 147 printf("%s\n", name);
@@ -145,6 +156,5 @@ int main(int argc, char *argv[])
145 fwrite(buffer, 1, Messenger_size(), file); 156 fwrite(buffer, 1, Messenger_size(), file);
146 free(buffer); 157 free(buffer);
147 fclose(file); 158 fclose(file);
148 } 159 }
149
150} 160}
diff --git a/testing/nTox.c b/testing/nTox.c
index 097c73af..3a5e9bb3 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -1,3 +1,26 @@
1/* nTox.c
2 *
3 * Textual frontend for Tox.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
22 */
23
1#include "nTox.h" 24#include "nTox.h"
2#include <stdio.h> 25#include <stdio.h>
3#include <time.h> 26#include <time.h>
@@ -23,12 +46,14 @@ void new_lines(char *line)
23 do_refresh(); 46 do_refresh();
24} 47}
25 48
49//TODO: rewrite
26unsigned char * hex_string_to_bin(char hex_string[]) 50unsigned char * hex_string_to_bin(char hex_string[])
27{ 51{
28 unsigned char * val = malloc(strlen(hex_string)); 52 size_t len = strlen(hex_string);
53 unsigned char * val = malloc(len);
29 char * pos = hex_string; 54 char * pos = hex_string;
30 int i=0; 55 int i=0;
31 while(i < strlen(hex_string)) 56 while(i < len)
32 { 57 {
33 sscanf(pos,"%2hhx",&val[i]); 58 sscanf(pos,"%2hhx",&val[i]);
34 pos+=2; 59 pos+=2;
@@ -58,7 +83,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
58 doMessenger(); 83 doMessenger();
59 } else if (line[1] == 'm') { //message command: /m friendnumber messsage 84 } else if (line[1] == 'm') { //message command: /m friendnumber messsage
60 int i; 85 int i;
61 int len = strlen(line); 86 size_t len = strlen(line);
62 char numstring[len-3]; 87 char numstring[len-3];
63 char message[len-3]; 88 char message[len-3];
64 for (i=0; i<len; i++) { 89 for (i=0; i<len; i++) {
@@ -77,7 +102,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
77 } else if (line[1] == 'n') { 102 } else if (line[1] == 'n') {
78 uint8_t name[MAX_NAME_LENGTH]; 103 uint8_t name[MAX_NAME_LENGTH];
79 int i = 0; 104 int i = 0;
80 for (i=3; i<strlen(line); i++) { 105 size_t len = strlen(line);
106 for (i=3; i<len; i++) {
81 if (line[i] == 0 || line[i] == '\n') break; 107 if (line[i] == 0 || line[i] == '\n') break;
82 name[i - 3] = line[i]; 108 name[i - 3] = line[i];
83 } 109 }
@@ -89,7 +115,8 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
89 } else if (line[1] == 's') { 115 } else if (line[1] == 's') {
90 uint8_t status[MAX_USERSTATUS_LENGTH]; 116 uint8_t status[MAX_USERSTATUS_LENGTH];
91 int i = 0; 117 int i = 0;
92 for (i=3; i<strlen(line); i++) { 118 size_t len = strlen(line);
119 for (i=3; i<len; i++) {
93 if (line[i] == 0 || line[i] == '\n') break; 120 if (line[i] == 0 || line[i] == '\n') break;
94 status[i - 3] = line[i]; 121 status[i - 3] = line[i];
95 } 122 }
@@ -111,7 +138,8 @@ void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
111{ 138{
112 int i = 0; 139 int i = 0;
113 strcpy(output,input); 140 strcpy(output,input);
114 for (i=line_width; i < strlen(output); i = i + line_width) { 141 size_t len = strlen(output);
142 for (i=line_width; i < len; i = i + line_width) {
115 while (output[i] != ' ' && i != 0) { 143 while (output[i] != ' ' && i != 0) {
116 i--; 144 i--;
117 } 145 }
@@ -123,7 +151,7 @@ void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
123 151
124int count_lines(char *string) 152int count_lines(char *string)
125{ 153{
126 int len = strlen(string); 154 size_t len = strlen(string);
127 int i; 155 int i;
128 int count = 1; 156 int count = 1;
129 for (i=0; i < len; i++) { 157 for (i=0; i < len; i++) {
@@ -136,7 +164,7 @@ int count_lines(char *string)
136 164
137char *appender(char *str, const char c) 165char *appender(char *str, const char c)
138{ 166{
139 int len = strlen(str); 167 size_t len = strlen(str);
140 if (len < STRING_LENGTH) { 168 if (len < STRING_LENGTH) {
141 str[len + 1] = str[len]; 169 str[len + 1] = str[len];
142 str[len] = c; 170 str[len] = c;
@@ -167,6 +195,7 @@ void do_refresh()
167 clrtoeol(); 195 clrtoeol();
168 refresh(); 196 refresh();
169} 197}
198
170void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) 199void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
171{ 200{
172 new_lines("[i] received friend request"); 201 new_lines("[i] received friend request");
@@ -182,6 +211,7 @@ void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
182 new_lines(numchar); 211 new_lines(numchar);
183 } 212 }
184} 213}
214
185void print_message(int friendnumber, uint8_t * string, uint16_t length) 215void print_message(int friendnumber, uint8_t * string, uint16_t length)
186{ 216{
187 char name[MAX_NAME_LENGTH]; 217 char name[MAX_NAME_LENGTH];
@@ -192,11 +222,12 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
192 time ( &rawtime ); 222 time ( &rawtime );
193 timeinfo = localtime ( &rawtime ); 223 timeinfo = localtime ( &rawtime );
194 char* temp = asctime(timeinfo); 224 char* temp = asctime(timeinfo);
195 int len = strlen(temp); 225 size_t len = strlen(temp);
196 temp[len-1]='\0'; 226 temp[len-1]='\0';
197 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // someone please fix this 227 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // someone please fix this
198 new_lines(msg); 228 new_lines(msg);
199} 229}
230
200void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) { 231void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) {
201 char name[MAX_NAME_LENGTH]; 232 char name[MAX_NAME_LENGTH];
202 getname(friendnumber, (uint8_t*)name); 233 getname(friendnumber, (uint8_t*)name);
@@ -204,6 +235,7 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) {
204 sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string); 235 sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string);
205 new_lines(msg); 236 new_lines(msg);
206} 237}
238
207void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) { 239void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) {
208 char name[MAX_NAME_LENGTH]; 240 char name[MAX_NAME_LENGTH];
209 getname(friendnumber, (uint8_t*)name); 241 getname(friendnumber, (uint8_t*)name);
@@ -211,6 +243,7 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) {
211 sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string); 243 sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string);
212 new_lines(msg); 244 new_lines(msg);
213} 245}
246
214void load_key(){ 247void load_key(){
215 FILE *data_file = NULL; 248 FILE *data_file = NULL;
216 if ((data_file = fopen("data","r"))) { 249 if ((data_file = fopen("data","r"))) {
@@ -237,6 +270,7 @@ void load_key(){
237 } 270 }
238 fclose(data_file); 271 fclose(data_file);
239} 272}
273
240int main(int argc, char *argv[]) 274int main(int argc, char *argv[])
241{ 275{
242 if (argc < 4) { 276 if (argc < 4) {
@@ -294,9 +328,7 @@ int main(int argc, char *argv[])
294 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); 328 DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
295 nodelay(stdscr, TRUE); 329 nodelay(stdscr, TRUE);
296 while(true) { 330 while(true) {
297 331 if (on == 0 && DHT_isconnected()) {
298 if (on == 0 && DHT_isconnected())
299 {
300 new_lines("[i] connected to DHT\n[i] define username with /n"); 332 new_lines("[i] connected to DHT\n[i] define username with /n");
301 on = 1; 333 on = 1;
302 } 334 }
diff --git a/testing/nTox.h b/testing/nTox.h
index fbc5d5c0..9b69d959 100644
--- a/testing/nTox.h
+++ b/testing/nTox.h
@@ -1,3 +1,26 @@
1/* nTox.h
2 *
3 *Textual frontend for Tox.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
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/>.
21 *
22 */
23
1#ifndef NTOX_H 24#ifndef NTOX_H
2#define NTOX_H 25#define NTOX_H
3 26