summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml9
-rw-r--r--CMakeLists.txt27
-rw-r--r--INSTALL.md39
-rw-r--r--core/CMakeLists.txt16
-rw-r--r--core/Messenger.c47
-rw-r--r--core/Messenger.h1
-rw-r--r--core/friend_requests.c93
-rw-r--r--core/friend_requests.h34
-rw-r--r--core/net_crypto.c149
-rw-r--r--core/net_crypto.h26
-rw-r--r--other/CMakeLists.txt8
-rw-r--r--other/DHT_bootstrap.c40
-rw-r--r--other/bootstrap_serverdaemon/CMakeLists.txt9
-rw-r--r--other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c5
-rw-r--r--testing/CMakeLists.txt12
-rw-r--r--testing/DHT_test.c11
-rw-r--r--testing/nTox.c53
18 files changed, 381 insertions, 200 deletions
diff --git a/.gitignore b/.gitignore
index 0b178e8e..73c7919e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ CMakeFiles
9Makefile 9Makefile
10cmake_install.cmake 10cmake_install.cmake
11install_manifest.txt 11install_manifest.txt
12
13testing/data
diff --git a/.travis.yml b/.travis.yml
index 9f62c84c..0a294bf1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,16 +8,15 @@ before_script:
8 - cd libsodium 8 - cd libsodium
9 - git checkout tags/0.4.2 9 - git checkout tags/0.4.2
10 - ./autogen.sh 10 - ./autogen.sh
11 - ./configure && make -j3 check 11 - ./configure && make check -j3
12 - sudo make install 12 - sudo make install
13 - sudo ldconfig 13 - sudo ldconfig
14 - cd .. 14 - cd ..
15 15
16script: 16script:
17 - cmake CMakeLists.txt 17 - mkdir build && cd build
18 - make DHT_bootstrap -j3 18 - cmake ..
19 - make Messenger_test -j3 19 - make -j3
20 - make nTox -j3
21 20
22notifications: 21notifications:
23 email: false 22 email: false
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 505983f2..c16ce6fe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,6 @@
1cmake_minimum_required(VERSION 2.6.0) 1cmake_minimum_required(VERSION 2.6.0)
2 2
3#MinGW prints more warnings for -Wall than gcc does, thus causing build to fail
3if(NOT WIN32) 4if(NOT WIN32)
4 if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")) 5 if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"))
5 message(STATUS "==== ${CMAKE_C_COMPILER_ID} detected - Adding compiler flags ====") 6 message(STATUS "==== ${CMAKE_C_COMPILER_ID} detected - Adding compiler flags ====")
@@ -7,31 +8,21 @@ if(NOT WIN32)
7 endif() 8 endif()
8endif() 9endif()
9 10
10if(WIN32)
11 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
12endif()
13
14set(core_sources
15 core/DHT.c
16 core/network.c
17 core/Lossless_UDP.c
18 core/net_crypto.c
19 core/Messenger.c)
20
21add_library(core ${core_sources})
22
23macro(linkCoreLibraries exe_name) 11macro(linkCoreLibraries exe_name)
12 add_dependencies(${exe_name} core)
24 if(WIN32) 13 if(WIN32)
25 target_link_libraries(${exe_name} core 14 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
26 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a 15 target_link_libraries(${exe_name} core
16 ${CMAKE_SOURCE_DIR}/sodium/lib/libsodium.a
27 ws2_32) 17 ws2_32)
28 else() 18 else()
29 target_link_libraries(${exe_name} core 19 target_link_libraries(${exe_name} core
30 sodium) 20 sodium)
31 endif() 21 endif()
32endmacro() 22endmacro()
33 23
34cmake_policy(SET CMP0011 NEW) 24cmake_policy(SET CMP0011 NEW)
35 25
36ADD_SUBDIRECTORY(testing) 26add_subdirectory(core)
37ADD_SUBDIRECTORY(other) \ No newline at end of file 27add_subdirectory(testing)
28add_subdirectory(other) \ No newline at end of file
diff --git a/INSTALL.md b/INSTALL.md
index b4e28379..bc027c0b 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -15,10 +15,11 @@ sudo ldconfig
15 15
16Then clone this repo and run: 16Then clone this repo and run:
17```bash 17```bash
18cmake CMakeLists.txt 18mkdir build && cd build
19cmake ..
19``` 20```
20 21
21Then you can build any of the [`/testing`](/testing) and [`/other`](/other) by running: 22Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
22```bash 23```bash
23make name_of_c_file 24make name_of_c_file
24``` 25```
@@ -27,6 +28,28 @@ For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would r
27make Messenger_test 28make Messenger_test
28``` 29```
29 30
31Or you could just build everything that is supported on your platform by running:
32```bash
33make
34```
35
36###OSX:
37
38Much the same as above, remember to install the latest XCode and the developer tools (Preferences -> Downloads -> Command Line Tools).
39Users running Mountain Lion and the latest version of XCode (4.6.3) will also need to install libtool
40Libtool is easy enough to install, grab it from http://www.gnu.org/software/libtool/ and:
41
42./configure
43make
44sudo make install
45
46Do not install it from macports (or any dependencies for that matter) as they get shoved in the wrong directory
47and make your life more annoying.
48
49Another thing you may want to install is the latest gcc, this caused me a few problems as XCode from 4.3
50no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at
51http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42
52
30###Windows: 53###Windows:
31 54
32You should install: 55You should install:
@@ -39,14 +62,20 @@ After that you should get precompiled packages of libsodium from [here](https://
39 62
40Navigate in `cmd` to this repo and run: 63Navigate in `cmd` to this repo and run:
41```cmd 64```cmd
42cmake -G "MinGW Makefiles" CMakeLists.txt 65mkdir build && cd build
66cmake -G "MinGW Makefiles" ..
43``` 67```
44 68
45Then you can build any of the [`/testing`](/testing) and [`/other`](/other) by running: 69Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
46```cmd 70```cmd
47mingw32-make name_of_c_file 71mingw32-make name_of_c_file
48``` 72```
49For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would run: 73For example, to build [`Messenger_test.c`](/others/Messenger_test.c) you would run:
50```cmd 74```cmd
51mingw32-make Messenger_test 75mingw32-make Messenger_test
52``` \ No newline at end of file 76```
77
78Or you could just build everything that is supported on your platform by running:
79```bash
80mingw32-make
81```
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
new file mode 100644
index 00000000..ab4ff4bc
--- /dev/null
+++ b/core/CMakeLists.txt
@@ -0,0 +1,16 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(core C)
3
4if(WIN32)
5 include_directories(${CMAKE_HOME_DIRECTORY}/sodium/include/)
6endif()
7
8set(core_sources
9 DHT.c
10 network.c
11 Lossless_UDP.c
12 net_crypto.c
13 friend_requests.c
14 Messenger.c)
15
16add_library(core ${core_sources})
diff --git a/core/Messenger.c b/core/Messenger.c
index 25ce067d..3d874837 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -353,15 +353,14 @@ static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t le
353 friendlist[friendnumber].userstatus_length = length; 353 friendlist[friendnumber].userstatus_length = length;
354 return 0; 354 return 0;
355} 355}
356 356/*
357static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 357static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
358static uint8_t friend_request_isset = 0; 358static uint8_t friend_request_isset = 0;
359 359*/
360/* set the function that will be executed when a friend request is received. */ 360/* 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)) 361void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
362{ 362{
363 friend_request = function; 363 callback_friendrequest(function);
364 friend_request_isset = 1;
365} 364}
366 365
367 366
@@ -413,19 +412,20 @@ static void doFriends()
413 { 412 {
414 if(friendlist[i].status == 1) 413 if(friendlist[i].status == 1)
415 { 414 {
416 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); 415 int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
417 int request = check_friendrequest(friendlist[i].friend_request_id); 416 if(fr == 0)/*TODO: This needs to be fixed so that it sends the friend requests a couple of times in case
418 /* printf("\n%u %u %u\n", friendip.ip.i, request, friendlist[i].friend_request_id); */ 417 of packet loss*/
419 if(friendip.ip.i > 1 && request == -1) 418 {
420 { 419 friendlist[i].status = 2;
421 friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, 420 }
422 friendip, friendlist[i].info, friendlist[i].info_size); 421 else
423 friendlist[i].status = 2; 422 if(fr > 0)
424 } 423 {
424 friendlist[i].status = 2;
425 }
425 } 426 }
426 if(friendlist[i].status == 2 || friendlist[i].status == 3) /* friend is not online */ 427 if(friendlist[i].status == 2 || friendlist[i].status == 3) /* friend is not online */
427 { 428 {
428 check_friendrequest(friendlist[i].friend_request_id); /* for now this is used to kill the friend request */
429 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); 429 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
430 switch(is_cryptoconnected(friendlist[i].crypt_connection_id)) 430 switch(is_cryptoconnected(friendlist[i].crypt_connection_id))
431 { 431 {
@@ -508,21 +508,6 @@ static void doFriends()
508 } 508 }
509} 509}
510 510
511static void doFriendRequest()
512{
513 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
514 uint8_t temp[MAX_DATA_SIZE];
515
516 int len = handle_friendrequest(public_key, temp);
517 if(len >= 0)
518 {
519 if(friend_request_isset)
520 {
521 (*friend_request)(public_key, temp, len);
522 }
523 }
524}
525
526 511
527 512
528static void doInbound() 513static void doInbound()
@@ -556,7 +541,7 @@ void doMessenger()
556#ifdef DEBUG 541#ifdef DEBUG
557 /* if(rand() % 3 != 1) //simulate packet loss */ 542 /* if(rand() % 3 != 1) //simulate packet loss */
558 /* { */ 543 /* { */
559 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) 544 if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port))
560 { 545 {
561 /* if packet is discarded */ 546 /* if packet is discarded */
562 printf("Received unhandled packet with length: %u\n", length); 547 printf("Received unhandled packet with length: %u\n", length);
@@ -570,6 +555,7 @@ void doMessenger()
570#else 555#else
571 DHT_handlepacket(data, length, ip_port); 556 DHT_handlepacket(data, length, ip_port);
572 LosslessUDP_handlepacket(data, length, ip_port); 557 LosslessUDP_handlepacket(data, length, ip_port);
558 friendreq_handlepacket(data, length, ip_port);
573#endif 559#endif
574 560
575 } 561 }
@@ -577,7 +563,6 @@ void doMessenger()
577 doLossless_UDP(); 563 doLossless_UDP();
578 doNetCrypto(); 564 doNetCrypto();
579 doInbound(); 565 doInbound();
580 doFriendRequest();
581 doFriends(); 566 doFriends();
582} 567}
583 568
diff --git a/core/Messenger.h b/core/Messenger.h
index 6fd98972..a7f114cf 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -29,6 +29,7 @@
29 29
30#include "net_crypto.h" 30#include "net_crypto.h"
31#include "DHT.h" 31#include "DHT.h"
32#include "friend_requests.h"
32 33
33#define MAX_NAME_LENGTH 128 34#define MAX_NAME_LENGTH 128
34#define MAX_USERSTATUS_LENGTH 128 35#define MAX_USERSTATUS_LENGTH 128
diff --git a/core/friend_requests.c b/core/friend_requests.c
new file mode 100644
index 00000000..18f0866b
--- /dev/null
+++ b/core/friend_requests.c
@@ -0,0 +1,93 @@
1/* friend_requests.c
2 *
3 * Handle friend requests.
4 *
5 */
6
7#include "friend_requests.h"
8
9uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
10
11
12/* Try to send a friendrequest to peer with public_key
13 data is the data in the request and length is the length.
14 return -1 if failure.
15 return 0 if it sent the friend request directly to the friend.
16 return the number of peers it was routed through if it did not send it directly.*/
17int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
18{
19 uint8_t packet[MAX_DATA_SIZE];
20 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */
21 if(len == -1)
22 {
23 return -1;
24 }
25 IP_Port ip_port = DHT_getfriendip(public_key);
26 if(ip_port.ip.i == 1)
27 {
28 return -1;
29 }
30 if(ip_port.ip.i != 0)
31 {
32 if(sendpacket(ip_port, packet, len) != -1)
33 {
34 return 0;
35 }
36 return -1;
37 }
38
39 int num = route_tofriend(public_key, packet, len);
40 if(num == 0)
41 {
42 return -1;
43 }
44 return num;
45}
46
47
48static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t);
49static uint8_t handle_friendrequest_isset = 0;
50
51/* set the function that will be executed when a friend request is received. */
52void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
53{
54 handle_friendrequest = function;
55 handle_friendrequest_isset = 1;
56}
57
58
59int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
60{
61
62 if(packet[0] == 32)
63 {
64 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
65 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
66 {
67 return 1;
68 }
69 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)//check if request is for us.
70 {
71 if(handle_friendrequest_isset == 0)
72 {
73 return 1;
74 }
75 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
76 uint8_t data[MAX_DATA_SIZE];
77 int len = handle_request(public_key, data, packet, length);
78 if(len == -1)
79 {
80 return 1;
81 }
82 (*handle_friendrequest)(public_key, data, len);
83 }
84 else//if request is not for us, try routing it.
85 {
86 if(route_packet(packet + 1, packet, length) == length)
87 {
88 return 0;
89 }
90 }
91 }
92 return 1;
93} \ No newline at end of file
diff --git a/core/friend_requests.h b/core/friend_requests.h
new file mode 100644
index 00000000..a3de46c8
--- /dev/null
+++ b/core/friend_requests.h
@@ -0,0 +1,34 @@
1/* friend_requests.h
2 *
3 * Handle friend requests.
4 *
5 */
6
7
8#ifndef FRIEND_REQUESTS_H
9#define FRIEND_REQUESTS_H
10
11
12#include "DHT.h"
13#include "net_crypto.h"
14
15
16/* Try to send a friendrequest to peer with public_key
17 data is the data in the request and length is the length. */
18int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length);
19
20
21/* set the function that will be executed when a friend request for us is received.
22 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
23void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
24
25/* if we receive a packet we call this function so it can be handled.
26 return 0 if packet is handled correctly.
27 return 1 if it didn't handle the packet or if the packet was shit. */
28int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
29
30
31
32
33
34#endif \ No newline at end of file
diff --git a/core/net_crypto.c b/core/net_crypto.c
index 270c969a..e01ed695 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -52,11 +52,6 @@ typedef struct
52 52
53static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; 53static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
54 54
55#define MAX_FRIEND_REQUESTS 32
56
57/* keeps track of the connection numbers for friends request so we can check later if they were sent */
58static int outbound_friendrequests[MAX_FRIEND_REQUESTS];
59
60#define MAX_INCOMING 64 55#define MAX_INCOMING 64
61 56
62/* keeps track of the connection numbers for friends request so we can check later if they were sent */ 57/* keeps track of the connection numbers for friends request so we can check later if they were sent */
@@ -138,14 +133,14 @@ void increment_nonce(uint8_t * nonce)
138 } 133 }
139} 134}
140 135
141/* fill the given nonce with random bytes. 136/* fill the given nonce with random bytes. */
142 TODO: make this more optimized */
143void random_nonce(uint8_t * nonce) 137void random_nonce(uint8_t * nonce)
144{ 138{
145 uint32_t i; 139 uint32_t i, temp;
146 for(i = 0; i < crypto_box_NONCEBYTES; ++i) 140 for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i)
147 { 141 {
148 nonce[i] = random_int() % 256; 142 temp = random_int();
143 memcpy(nonce + 4 * i, &temp, 4);
149 } 144 }
150} 145}
151 146
@@ -217,88 +212,63 @@ int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length)
217 return 1; 212 return 1;
218} 213}
219 214
220/* send a friend request to peer with public_key and ip_port. 215/* create a request to peer with public_key.
221 Data represents the data we send with the friends request. 216 packet must be an array of MAX_DATA_SIZE big.
217 Data represents the data we send with the request with length being the length of the data.
218 request_id is the id of the request (32 = friend request, 254 = ping request)
222 returns -1 on failure 219 returns -1 on failure
223 returns a positive friend request id that can be used later to see if it was sent correctly on success. */ 220 returns the length of the created packet on success */
224int send_friendrequest(uint8_t * public_key, IP_Port ip_port, 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)
225{ 222{
226 if(length > MAX_DATA_SIZE - 1 - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES) 223 if(MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING)
227 { 224 {
228 return -1; 225 return -1;
229 } 226 }
230 uint32_t i;
231 for(i = 0; i < MAX_FRIEND_REQUESTS; ++i)
232 {
233 if(outbound_friendrequests[i] == -1)
234 {
235 break;
236 }
237 }
238 if(i == MAX_FRIEND_REQUESTS)
239 {
240 return -1;
241 }
242 uint8_t temp_data[MAX_DATA_SIZE];
243 uint8_t nonce[crypto_box_NONCEBYTES]; 227 uint8_t nonce[crypto_box_NONCEBYTES];
244 random_nonce(nonce); 228 random_nonce(nonce);
245 int len = encrypt_data(public_key, self_secret_key, nonce, data, length, 229 int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
246 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 230 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
247 if(len == -1) 231 if(len == -1)
248 { 232 {
249 return -1; 233 return -1;
250 } 234 }
251 temp_data[0] = 1; 235 packet[0] = request_id;
252 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 236 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
253 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 237 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
254 int id = new_connection(ip_port); 238 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
255 if(id == -1) 239
256 { 240 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
257 return -1;
258 }
259 if(write_packet(id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES) == 1)
260 {
261 outbound_friendrequests[i] = id;
262 return i;
263 }
264 return -1;
265} 241}
266 242
267/* return -1 if failure 243/* puts the senders public key in the request in public_key, the data from the request
268 return 0 if connection is still trying to send the request. 244 in data if a friend or ping request was sent to us and returns the length of the data.
269 return 1 if sent correctly 245 packet is the request packet and length is its length
270 return 2 if connection timed out */ 246 return -1 if not valid request. */
271int check_friendrequest(int friend_request) 247int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length)
272{ 248{
273 if(friend_request < 0 || friend_request > MAX_FRIEND_REQUESTS) 249
250 if(length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
251 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
252 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
274 { 253 {
275 return -1; 254 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
255 uint8_t nonce[crypto_box_NONCEBYTES];
256 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
257 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);
259 if(len1 == -1)
260 {
261 return -1;
262 }
263 return len1;
276 } 264 }
277 if(outbound_friendrequests[friend_request] == -1) 265 else
278 { 266 {
279 return -1; 267 return -1;
280 } 268 }
281 if(sendqueue(outbound_friendrequests[friend_request]) == 0)
282 {
283 kill_connection(outbound_friendrequests[friend_request]);
284 outbound_friendrequests[friend_request] = -1;
285 return 1;
286 }
287 int status = is_connected(outbound_friendrequests[friend_request]);
288 if(status == 4)
289 {
290 kill_connection(outbound_friendrequests[friend_request]);
291 outbound_friendrequests[friend_request] = -1;
292 return 2;
293 }
294 if(status == 0)
295 {
296 outbound_friendrequests[friend_request] = -1;
297 return 2;
298 }
299 return 0;
300} 269}
301 270
271
302/* Send a crypto handshake packet containing an encrypted secret nonce and session public key 272/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
303 to peer with connection_id and public_key 273 to peer with connection_id and public_key
304 the packet is encrypted with a random nonce which is sent in plain text with the packet */ 274 the packet is encrypted with a random nonce which is sent in plain text with the packet */
@@ -359,43 +329,7 @@ int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce,
359} 329}
360 330
361 331
362/* puts the public key of the friend if public_key, the data from the request 332
363 in data if a friend request was sent to us and returns the length of the data.
364 return -1 if no valid friend requests. */
365int handle_friendrequest(uint8_t * public_key, uint8_t * data)
366{
367 uint32_t i;
368 for(i = 0; i < MAX_INCOMING; ++i)
369 {
370 if(incoming_connections[i] != -1)
371 {
372 if(id_packet(incoming_connections[i]) == 1)
373 {
374 uint8_t temp_data[MAX_DATA_SIZE];
375 uint16_t len = read_packet(incoming_connections[i], temp_data);
376 if(len > crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1
377 - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)
378 {
379 memcpy(public_key, temp_data + 1, crypto_box_PUBLICKEYBYTES);
380 uint8_t nonce[crypto_box_NONCEBYTES];
381 memcpy(nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_NONCEBYTES);
382 int len1 = decrypt_data(public_key, self_secret_key, nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
383 len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data);
384 if(len1 != -1)
385 {
386 kill_connection(incoming_connections[i]);
387 /* kill_connection_in(incoming_connections[i], 1); //conection is useless now, kill it in 1 seconds */
388 incoming_connections[i] = -1;
389 return len1;
390 }
391 }
392 kill_connection(incoming_connections[i]); /* conection is useless now, kill it. */
393 incoming_connections[i] = -1;
394 }
395 }
396 }
397 return -1;
398}
399 333
400/* get crypto connection id from public key of peer 334/* get crypto connection id from public key of peer
401 return -1 if there are no connections like we are looking for 335 return -1 if there are no connections like we are looking for
@@ -714,7 +648,6 @@ static void receive_crypto()
714void initNetCrypto() 648void initNetCrypto()
715{ 649{
716 memset(crypto_connections, 0 ,sizeof(crypto_connections)); 650 memset(crypto_connections, 0 ,sizeof(crypto_connections));
717 memset(outbound_friendrequests, -1 ,sizeof(outbound_friendrequests));
718 memset(incoming_connections, -1 ,sizeof(incoming_connections)); 651 memset(incoming_connections, -1 ,sizeof(incoming_connections));
719 uint32_t i; 652 uint32_t i;
720 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 653 for(i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
diff --git a/core/net_crypto.h b/core/net_crypto.h
index 0bf21f60..5a282002 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -62,24 +62,20 @@ int read_cryptpacket(int crypt_connection_id, uint8_t * data);
62 return 1 if data was put into the queue */ 62 return 1 if data was put into the queue */
63int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); 63int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length);
64 64
65/* send a friend request to peer with public_key and ip_port. 65/* create a request to peer with public_key.
66 Data represents the data we send with the friends request. 66 packet must be an array of MAX_DATA_SIZE big.
67 Data represents the data we send with the request with length being the length of the data.
68 request_id is the id of the request (32 = friend request, 254 = ping request)
67 returns -1 on failure 69 returns -1 on failure
68 returns a positive friend request id that can be used later to see if it was sent correctly on success. */ 70 returns the length of the created packet on success */
69int send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length); 71int create_request(uint8_t * packet, uint8_t * public_key, uint8_t * data, uint32_t length, uint8_t request_id);
70 72
71 73
72/* return -1 if failure 74/* puts the senders public key in the request in public_key, the data from the request
73 return 0 if connection is still trying to send the request. 75 in data if a friend or ping request was sent to us and returns the length of the data.
74 return 1 if sent correctly 76 packet is the request packet and length is its length
75 return 2 if connection timed out */ 77 return -1 if not valid request. */
76int check_friendrequest(int friend_request); 78int handle_request(uint8_t * public_key, uint8_t * data, uint8_t * packet, uint16_t length);
77
78
79/* puts the public key of the friend if public_key, the data from the request
80 in data if a friend request was sent to us and returns the length of the data.
81 return -1 if no valid friend requests. */
82int handle_friendrequest(uint8_t * public_key, uint8_t * data);
83 79
84 80
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
diff --git a/other/CMakeLists.txt b/other/CMakeLists.txt
index 22dc8e25..05b24f06 100644
--- a/other/CMakeLists.txt
+++ b/other/CMakeLists.txt
@@ -1 +1,9 @@
1cmake_minimum_required(VERSION 2.6.0)
2
3cmake_policy(SET CMP0011 NEW)
4
1include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_bootstrap.cmake) 5include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_bootstrap.cmake)
6
7if(NOT WIN32)
8 add_subdirectory(bootstrap_serverdaemon)
9endif()
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index 02d7d261..85ed679c 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -3,12 +3,13 @@
3 * A simple DHT boostrap server for tox. 3 * A simple DHT boostrap server for tox.
4 * 4 *
5 * Build commands (use one or the other): 5 * Build commands (use one or the other):
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 ../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 -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 */ 9 */
10 10
11#include "../core/DHT.h" 11#include "../core/DHT.h"
12#include "../core/friend_requests.h"
12 13
13//Sleep function (x = milliseconds) 14//Sleep function (x = milliseconds)
14#ifdef WIN32 15#ifdef WIN32
@@ -35,9 +36,41 @@ unsigned char * hex_string_to_bin(char hex_string[])
35 return val; 36 return val;
36} 37}
37 38
39void manage_keys()
40{
41 const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
42 uint8_t keys[KEYS_SIZE];
43
44 FILE *keys_file = fopen("key", "r");
45 if (keys_file != NULL) {
46 //if file was opened successfully -- load keys
47 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
48 if (read_size != KEYS_SIZE) {
49 printf("Error while reading the key file\nExiting.\n");
50 exit(1);
51 } else {
52 printf("Keys loaded successfully\n");
53 }
54 load_keys(keys);
55 } else {
56 //otherwise save new keys
57 new_keys();
58 save_keys(keys);
59 keys_file = fopen("key", "w");
60 if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) {
61 printf("Error while writing the key file.\nExiting.\n");
62 exit(1);
63 } else {
64 printf("Keys saved successfully\n");
65 }
66 }
67
68 fclose(keys_file);
69}
70
38int main(int argc, char *argv[]) 71int main(int argc, char *argv[])
39{ 72{
40 new_keys(); 73 manage_keys();
41 printf("Public key: "); 74 printf("Public key: ");
42 uint32_t i; 75 uint32_t i;
43 for(i = 0; i < 32; i++) 76 for(i = 0; i < 32; i++)
@@ -83,6 +116,7 @@ int main(int argc, char *argv[])
83 while(receivepacket(&ip_port, data, &length) != -1) 116 while(receivepacket(&ip_port, data, &length) != -1)
84 { 117 {
85 DHT_handlepacket(data, length, ip_port); 118 DHT_handlepacket(data, length, ip_port);
119 friendreq_handlepacket(data, length, ip_port);
86 } 120 }
87 c_sleep(1); 121 c_sleep(1);
88 } 122 }
diff --git a/other/bootstrap_serverdaemon/CMakeLists.txt b/other/bootstrap_serverdaemon/CMakeLists.txt
new file mode 100644
index 00000000..bc717d4b
--- /dev/null
+++ b/other/bootstrap_serverdaemon/CMakeLists.txt
@@ -0,0 +1,9 @@
1cmake_minimum_required(VERSION 2.6.0)
2project(DHT_bootstrap_daemon C)
3
4set(exe_name DHT_bootstrap_daemon)
5
6add_executable(${exe_name}
7 DHT_bootstrap_daemon.c)
8
9linkCoreLibraries(${exe_name})
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
index 276821e6..4d79c48b 100644
--- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
+++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c
@@ -10,7 +10,9 @@
10#include <unistd.h> /* POSIX things */ 10#include <unistd.h> /* POSIX things */
11#include <errno.h> 11#include <errno.h>
12 12
13#include "../core/DHT.h" 13#include "../../core/DHT.h"
14#include "../../core/friend_requests.h"
15
14 16
15/* Sleep function (x = milliseconds) */ 17/* Sleep function (x = milliseconds) */
16#ifdef WIN32 18#ifdef WIN32
@@ -123,6 +125,7 @@ int main(int argc, char *argv[]) {
123 doDHT(); 125 doDHT();
124 while(receivepacket(&ip_port, data, &length) != -1) { 126 while(receivepacket(&ip_port, data, &length) != -1) {
125 DHT_handlepacket(data, length, ip_port); 127 DHT_handlepacket(data, length, ip_port);
128 friendreq_handlepacket(data, length, ip_port);
126 } 129 }
127 c_sleep(1); 130 c_sleep(1);
128 } 131 }
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt
index bb599b86..12efc2f4 100644
--- a/testing/CMakeLists.txt
+++ b/testing/CMakeLists.txt
@@ -1,7 +1,13 @@
1include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_cryptosendfiletest.cmake) 1cmake_minimum_required(VERSION 2.6.0)
2include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_sendfiletest.cmake) 2
3cmake_policy(SET CMP0011 NEW)
4
5#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_cryptosendfiletest.cmake)
6#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_sendfiletest.cmake)
3include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_test.cmake) 7include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_test.cmake)
4include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake) 8include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake)
5include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) 9include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake)
6include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake) 10include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake)
7include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake) \ No newline at end of file 11if(NOT WIN32)
12 include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox.cmake)
13endif()
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index 5f85e934..9d599370 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -1,7 +1,7 @@
1/* DHT test 1/* DHT test
2 * A file with a main that runs our DHT for testing. 2 * A file with a main that runs our DHT for testing.
3 * 3 *
4 * Compile with: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/* DHT_test.c 4 * Compile with: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_test.c
5 * 5 *
6 * Command line arguments are the ip, port and public key of a node. 6 * Command line arguments are the ip, port and public key of a node.
7 * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 7 * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
@@ -10,6 +10,7 @@
10 */ 10 */
11//#include "../core/network.h" 11//#include "../core/network.h"
12#include "../core/DHT.c" 12#include "../core/DHT.c"
13#include "../core/friend_requests.c"
13 14
14#include <string.h> 15#include <string.h>
15 16
@@ -45,7 +46,7 @@ void print_clientlist()
45 printf("\nTimestamp: %u", close_clientlist[i].timestamp); 46 printf("\nTimestamp: %u", close_clientlist[i].timestamp);
46 printf("\nLast pinged: %u\n", close_clientlist[i].last_pinged); 47 printf("\nLast pinged: %u\n", close_clientlist[i].last_pinged);
47 p_ip = close_clientlist[i].ret_ip_port; 48 p_ip = close_clientlist[i].ret_ip_port;
48 printf("\nOUR IP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 49 printf("OUR IP: %u.%u.%u.%u Port: %u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
49 } 50 }
50} 51}
51 52
@@ -81,7 +82,7 @@ void print_friendlist()
81 printf("\nTimestamp: %u", friends_list[k].client_list[i].timestamp); 82 printf("\nTimestamp: %u", friends_list[k].client_list[i].timestamp);
82 printf("\nLast pinged: %u\n", friends_list[k].client_list[i].last_pinged); 83 printf("\nLast pinged: %u\n", friends_list[k].client_list[i].last_pinged);
83 p_ip = friends_list[k].client_list[i].ret_ip_port; 84 p_ip = friends_list[k].client_list[i].ret_ip_port;
84 printf("\nret IP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); 85 printf("ret IP: %u.%u.%u.%u:%u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port));
85 } 86 }
86 } 87 }
87} 88}
@@ -146,8 +147,6 @@ int main(int argc, char *argv[])
146 init_networking(ip, PORT); 147 init_networking(ip, PORT);
147 148
148 149
149
150
151 perror("Initialization"); 150 perror("Initialization");
152 IP_Port bootstrap_ip_port; 151 IP_Port bootstrap_ip_port;
153 bootstrap_ip_port.port = htons(atoi(argv[2])); 152 bootstrap_ip_port.port = htons(atoi(argv[2]));
@@ -169,7 +168,7 @@ int main(int argc, char *argv[])
169 168
170 while(receivepacket(&ip_port, data, &length) != -1) 169 while(receivepacket(&ip_port, data, &length) != -1)
171 { 170 {
172 if(DHT_handlepacket(data, length, ip_port)) 171 if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port))
173 { 172 {
174 //unhandled packet 173 //unhandled packet
175 printpacket(data, length, ip_port); 174 printpacket(data, length, ip_port);
diff --git a/testing/nTox.c b/testing/nTox.c
index ccb11a71..8e9a5456 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -1,5 +1,6 @@
1#include "nTox.h" 1#include "nTox.h"
2 2#include <stdio.h>
3#include <time.h>
3#ifdef WIN32 4#ifdef WIN32
4#define c_sleep(x) Sleep(1*x) 5#define c_sleep(x) Sleep(1*x)
5#else 6#else
@@ -168,12 +169,12 @@ void do_refresh()
168} 169}
169void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) 170void print_request(uint8_t * public_key, uint8_t * data, uint16_t length)
170{ 171{
171 new_lines("Friend request"); 172 new_lines("[i] received friend request");
172 do_refresh(); 173 do_refresh();
173 if(memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0 ) 174 if(memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0 )
174 //if the request contained the message of peace the person is obviously a friend so we add him. 175 //if the request contained the message of peace the person is obviously a friend so we add him.
175 { 176 {
176 new_lines("[i] friend request accepted."); 177 new_lines("[i] friend request accepted");
177 do_refresh(); 178 do_refresh();
178 int num = m_addfriend_norequest(public_key); 179 int num = m_addfriend_norequest(public_key);
179 char numchar[100]; 180 char numchar[100];
@@ -186,7 +187,14 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
186 char *name = malloc(MAX_NAME_LENGTH); 187 char *name = malloc(MAX_NAME_LENGTH);
187 getname(friendnumber, (uint8_t*)name); 188 getname(friendnumber, (uint8_t*)name);
188 char msg[100+length+strlen(name)+1]; 189 char msg[100+length+strlen(name)+1];
189 sprintf(msg, "[%d] <%s> %s", friendnumber, name, string); 190 time_t rawtime;
191 struct tm * timeinfo;
192 time ( &rawtime );
193 timeinfo = localtime ( &rawtime );
194 char* temp = asctime(timeinfo);
195 int len = strlen(temp);
196 temp[len-1]='\0';
197 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // someone please fix this
190 free(name); 198 free(name);
191 new_lines(msg); 199 new_lines(msg);
192} 200}
@@ -206,15 +214,50 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) {
206 free(name); 214 free(name);
207 new_lines(msg); 215 new_lines(msg);
208} 216}
217int load_key(){
218 FILE *data_file = NULL;
219 if ((data_file = fopen("data","r"))) {
220 //load keys
221 fseek(data_file, 0, SEEK_END);
222 int size = ftell(data_file);
223 fseek(data_file, 0, SEEK_SET);
224 uint8_t data[size];
225 if(fread(data, sizeof(uint8_t), size, data_file) != size){
226 printf("Error reading file\n");
227 exit(0);
228 }
229 Messenger_load(data, size);
230 } else {
231 //else save new keys
232 int size = Messenger_size();
233 uint8_t data[size];
234 Messenger_save(data);
235 data_file = fopen("data","w");
236 if(fwrite(data, sizeof(uint8_t), size, data_file) != size){
237 printf("Error writing file\n");
238 exit(0);
239 }
240 }
241 fclose(data_file);
242 return 0;
243}
209int main(int argc, char *argv[]) 244int main(int argc, char *argv[])
210{ 245{
211 if (argc < 4) { 246 if (argc < 4) {
212 printf("[!] Usage: %s [IP] [port] [public_key]\n", argv[0]); 247 printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
213 exit(0); 248 exit(0);
214 } 249 }
215 int c; 250 int c;
216 int on = 0; 251 int on = 0;
217 initMessenger(); 252 initMessenger();
253 //if keyfiles exist
254 if(argc > 4){
255 if(strncmp(argv[4], "nokey", 6) < 0){
256 //load_key();
257 }
258 } else {
259 load_key();
260 }
218 m_callback_friendrequest(print_request); 261 m_callback_friendrequest(print_request);
219 m_callback_friendmessage(print_message); 262 m_callback_friendmessage(print_message);
220 m_callback_namechange(print_nickchange); 263 m_callback_namechange(print_nickchange);