diff options
-rw-r--r-- | auto_tests/CMakeLists.txt | 4 | ||||
-rw-r--r-- | auto_tests/cmake/crypto_test.cmake | 10 | ||||
-rw-r--r-- | auto_tests/crypto_test.c | 230 | ||||
-rwxr-xr-x | auto_tests/run_tests | 2 | ||||
-rw-r--r-- | core/DHT.c | 35 | ||||
-rw-r--r-- | core/DHT.h | 8 | ||||
-rw-r--r-- | core/LAN_discovery.c | 10 | ||||
-rw-r--r-- | core/LAN_discovery.h | 6 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 26 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 6 | ||||
-rw-r--r-- | core/Messenger.c | 38 | ||||
-rw-r--r-- | core/friend_requests.c | 7 | ||||
-rw-r--r-- | core/friend_requests.h | 6 | ||||
-rw-r--r-- | core/net_crypto.c | 106 | ||||
-rw-r--r-- | core/net_crypto.h | 16 | ||||
-rw-r--r-- | core/network.c | 24 | ||||
-rw-r--r-- | core/network.h | 14 | ||||
-rw-r--r-- | core/ping.c | 4 | ||||
-rw-r--r-- | core/ping.h | 4 | ||||
-rw-r--r-- | other/CMakeLists.txt | 2 | ||||
-rw-r--r-- | other/DHT_bootstrap.c | 12 | ||||
-rw-r--r-- | other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | 20 | ||||
-rw-r--r-- | testing/CMakeLists.txt | 1 | ||||
-rw-r--r-- | testing/DHT_test.c | 11 | ||||
-rw-r--r-- | testing/Lossless_UDP_testclient.c | 12 | ||||
-rw-r--r-- | testing/Lossless_UDP_testserver.c | 23 | ||||
-rw-r--r-- | testing/cmake/crypto_speed_test.cmake | 9 | ||||
-rw-r--r-- | testing/crypto_speed_test.c | 130 | ||||
-rw-r--r-- | testing/toxic/prompt.c | 48 |
29 files changed, 644 insertions, 180 deletions
diff --git a/auto_tests/CMakeLists.txt b/auto_tests/CMakeLists.txt index fbbcb7d7..c0b6aee4 100644 --- a/auto_tests/CMakeLists.txt +++ b/auto_tests/CMakeLists.txt | |||
@@ -5,16 +5,18 @@ include_directories(${CHECK_INCLUDE_DIRS}) | |||
5 | 5 | ||
6 | find_package(Check REQUIRED) | 6 | find_package(Check REQUIRED) |
7 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/messenger_test.cmake) | 7 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/messenger_test.cmake) |
8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_test.cmake) | ||
8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/friends_test.cmake) | 9 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/friends_test.cmake) |
9 | 10 | ||
10 | include( CTest ) | 11 | include( CTest ) |
11 | enable_testing() | 12 | enable_testing() |
12 | 13 | ||
13 | add_test(messenger messenger_test) | 14 | add_test(messenger messenger_test) |
15 | add_test(crypto crypto_test) | ||
14 | # TODO enable once test is fixed | 16 | # TODO enable once test is fixed |
15 | #add_test(friends friends_test) | 17 | #add_test(friends friends_test) |
16 | 18 | ||
17 | add_custom_target( | 19 | add_custom_target( |
18 | test COMMAND ${CMAKE_CTEST_COMMAND} -V | 20 | test COMMAND ${CMAKE_CTEST_COMMAND} -V |
19 | DEPENDS messenger_test | 21 | DEPENDS messenger_test crypto_test |
20 | ) | 22 | ) |
diff --git a/auto_tests/cmake/crypto_test.cmake b/auto_tests/cmake/crypto_test.cmake new file mode 100644 index 00000000..9ca9a331 --- /dev/null +++ b/auto_tests/cmake/crypto_test.cmake | |||
@@ -0,0 +1,10 @@ | |||
1 | cmake_minimum_required(VERSION 2.6.0) | ||
2 | project(crypto_test C) | ||
3 | set(exe_name crypto_test) | ||
4 | |||
5 | add_executable(${exe_name} | ||
6 | crypto_test.c) | ||
7 | |||
8 | linkCoreLibraries(${exe_name}) | ||
9 | add_dependencies(${exe_name} Check) | ||
10 | target_link_libraries(${exe_name} check) | ||
diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c new file mode 100644 index 00000000..9ac81349 --- /dev/null +++ b/auto_tests/crypto_test.c | |||
@@ -0,0 +1,230 @@ | |||
1 | #include "../core/net_crypto.h" | ||
2 | #include <sys/types.h> | ||
3 | #include <stdint.h> | ||
4 | #include <string.h> | ||
5 | #include <check.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <time.h> | ||
8 | #include <sodium.h> | ||
9 | |||
10 | void rand_bytes(uint8_t *b, size_t blen) | ||
11 | { | ||
12 | size_t i; | ||
13 | for (i = 0; i < blen; i++) | ||
14 | { | ||
15 | b[i] = rand(); | ||
16 | } | ||
17 | } | ||
18 | |||
19 | // These test vectors are from libsodium's test suite | ||
20 | |||
21 | unsigned char alicesk[32] = { | ||
22 | 0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d, | ||
23 | 0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45, | ||
24 | 0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a, | ||
25 | 0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a | ||
26 | }; | ||
27 | |||
28 | unsigned char bobpk[32] = { | ||
29 | 0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4, | ||
30 | 0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37, | ||
31 | 0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d, | ||
32 | 0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f | ||
33 | }; | ||
34 | |||
35 | unsigned char nonce[24] = { | ||
36 | 0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73, | ||
37 | 0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6, | ||
38 | 0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37 | ||
39 | }; | ||
40 | |||
41 | unsigned char test_m[131] = { | ||
42 | 0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, | ||
43 | 0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b, | ||
44 | 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, | ||
45 | 0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc, | ||
46 | 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, | ||
47 | 0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29, | ||
48 | 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, | ||
49 | 0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31, | ||
50 | 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, | ||
51 | 0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57, | ||
52 | 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, | ||
53 | 0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde, | ||
54 | 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, | ||
55 | 0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52, | ||
56 | 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, | ||
57 | 0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64, | ||
58 | 0x5e,0x07,0x05 | ||
59 | }; | ||
60 | |||
61 | unsigned char test_c[147] = { | ||
62 | 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5, | ||
63 | 0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9, | ||
64 | 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73, | ||
65 | 0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, | ||
66 | 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4, | ||
67 | 0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, | ||
68 | 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b, | ||
69 | 0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, | ||
70 | 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2, | ||
71 | 0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, | ||
72 | 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a, | ||
73 | 0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, | ||
74 | 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea, | ||
75 | 0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, | ||
76 | 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde, | ||
77 | 0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, | ||
78 | 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6, | ||
79 | 0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, | ||
80 | 0xe3,0x55,0xa5 | ||
81 | }; | ||
82 | |||
83 | START_TEST(test_known) | ||
84 | { | ||
85 | unsigned char c[147]; | ||
86 | unsigned char m[131]; | ||
87 | int clen, mlen; | ||
88 | |||
89 | ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); | ||
90 | ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); | ||
91 | ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); | ||
92 | |||
93 | clen = encrypt_data(bobpk, alicesk, nonce, test_m, sizeof(test_m)/sizeof(unsigned char), c); | ||
94 | |||
95 | ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); | ||
96 | ck_assert_msg(clen == sizeof(c)/sizeof(unsigned char), "wrong ciphertext length"); | ||
97 | |||
98 | mlen = decrypt_data(bobpk, alicesk, nonce, test_c, sizeof(test_c)/sizeof(unsigned char), m); | ||
99 | |||
100 | ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); | ||
101 | ck_assert_msg(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length"); | ||
102 | } | ||
103 | END_TEST | ||
104 | |||
105 | START_TEST(test_fast_known) | ||
106 | { | ||
107 | unsigned char k[crypto_box_BEFORENMBYTES]; | ||
108 | unsigned char c[147]; | ||
109 | unsigned char m[131]; | ||
110 | int clen, mlen; | ||
111 | |||
112 | encrypt_precompute(bobpk, alicesk, k); | ||
113 | |||
114 | ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); | ||
115 | ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); | ||
116 | ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); | ||
117 | |||
118 | clen = encrypt_data_fast(k, nonce, test_m, sizeof(test_m)/sizeof(unsigned char), c); | ||
119 | |||
120 | ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); | ||
121 | ck_assert_msg(clen == sizeof(c)/sizeof(unsigned char), "wrong ciphertext length"); | ||
122 | |||
123 | mlen = decrypt_data_fast(k, nonce, test_c, sizeof(test_c)/sizeof(unsigned char), m); | ||
124 | |||
125 | ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); | ||
126 | ck_assert_msg(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length"); | ||
127 | |||
128 | } | ||
129 | END_TEST | ||
130 | |||
131 | START_TEST(test_endtoend) | ||
132 | { | ||
133 | unsigned char pk1[crypto_box_PUBLICKEYBYTES]; | ||
134 | unsigned char sk1[crypto_box_SECRETKEYBYTES]; | ||
135 | unsigned char pk2[crypto_box_PUBLICKEYBYTES]; | ||
136 | unsigned char sk2[crypto_box_SECRETKEYBYTES]; | ||
137 | unsigned char k1[crypto_box_BEFORENMBYTES]; | ||
138 | unsigned char k2[crypto_box_BEFORENMBYTES]; | ||
139 | |||
140 | unsigned char n[crypto_box_NONCEBYTES]; | ||
141 | |||
142 | unsigned char m[500]; | ||
143 | unsigned char c1[sizeof(m) + ENCRYPTION_PADDING]; | ||
144 | unsigned char c2[sizeof(m) + ENCRYPTION_PADDING]; | ||
145 | unsigned char c3[sizeof(m) + ENCRYPTION_PADDING]; | ||
146 | unsigned char c4[sizeof(m) + ENCRYPTION_PADDING]; | ||
147 | unsigned char m1[sizeof(m)]; | ||
148 | unsigned char m2[sizeof(m)]; | ||
149 | unsigned char m3[sizeof(m)]; | ||
150 | unsigned char m4[sizeof(m)]; | ||
151 | |||
152 | int mlen; | ||
153 | int c1len, c2len, c3len, c4len; | ||
154 | int m1len, m2len, m3len, m4len; | ||
155 | |||
156 | int testno; | ||
157 | |||
158 | // Test 100 random messages and keypairs | ||
159 | for (testno = 0; testno < 100; testno++) | ||
160 | { | ||
161 | //Generate random message (random length from 100 to 500) | ||
162 | mlen = (rand() % 400) + 100; | ||
163 | rand_bytes(m, mlen); | ||
164 | rand_bytes(n, crypto_box_NONCEBYTES); | ||
165 | |||
166 | //Generate keypairs | ||
167 | crypto_box_keypair(pk1,sk1); | ||
168 | crypto_box_keypair(pk2,sk2); | ||
169 | |||
170 | //Precompute shared keys | ||
171 | encrypt_precompute(pk2, sk1, k1); | ||
172 | encrypt_precompute(pk1, sk2, k2); | ||
173 | |||
174 | ck_assert_msg(memcmp(k1, k2, crypto_box_BEFORENMBYTES) == 0, "encrypt_precompute: bad"); | ||
175 | |||
176 | //Encrypt all four ways | ||
177 | c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); | ||
178 | c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); | ||
179 | c3len = encrypt_data_fast(k1, n, m, mlen, c3); | ||
180 | c4len = encrypt_data_fast(k2, n, m, mlen, c4); | ||
181 | |||
182 | ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); | ||
183 | ck_assert_msg(c1len == mlen + ENCRYPTION_PADDING, "wrong cyphertext length"); | ||
184 | ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); | ||
185 | |||
186 | //Decrypt all four ways | ||
187 | m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); | ||
188 | m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); | ||
189 | m3len = decrypt_data_fast(k1, n, c1, c1len, m3); | ||
190 | m4len = decrypt_data_fast(k2, n, c1, c1len, m4); | ||
191 | |||
192 | ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); | ||
193 | ck_assert_msg(m1len == mlen, "wrong decrypted text length"); | ||
194 | ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); | ||
195 | ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); | ||
196 | } | ||
197 | } | ||
198 | END_TEST | ||
199 | |||
200 | #define DEFTESTCASE(NAME) \ | ||
201 | TCase *NAME = tcase_create(#NAME); \ | ||
202 | tcase_add_test(NAME, test_##NAME); \ | ||
203 | suite_add_tcase(s, NAME); | ||
204 | |||
205 | Suite* crypto_suite(void) | ||
206 | { | ||
207 | Suite *s = suite_create("Crypto"); | ||
208 | |||
209 | DEFTESTCASE(known); | ||
210 | DEFTESTCASE(fast_known); | ||
211 | DEFTESTCASE(endtoend); | ||
212 | |||
213 | return s; | ||
214 | } | ||
215 | |||
216 | int main(int argc, char* argv[]) | ||
217 | { | ||
218 | srand((unsigned int) time(NULL)); | ||
219 | |||
220 | Suite *crypto = crypto_suite(); | ||
221 | SRunner *test_runner = srunner_create(crypto); | ||
222 | int number_failed = 0; | ||
223 | |||
224 | srunner_run_all(test_runner, CK_NORMAL); | ||
225 | number_failed = srunner_ntests_failed(test_runner); | ||
226 | |||
227 | srunner_free(test_runner); | ||
228 | |||
229 | return number_failed; | ||
230 | } | ||
diff --git a/auto_tests/run_tests b/auto_tests/run_tests index 4448b2e2..1899f354 100755 --- a/auto_tests/run_tests +++ b/auto_tests/run_tests | |||
@@ -2,4 +2,4 @@ | |||
2 | # run_tests - run the current tests for tox core | 2 | # run_tests - run the current tests for tox core |
3 | set -e | 3 | set -e |
4 | 4 | ||
5 | ./messenger_test && ./friends_test | 5 | ./messenger_test && ./friends_test && ./crypto_test |
@@ -554,7 +554,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, | |||
554 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 554 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
555 | } | 555 | } |
556 | 556 | ||
557 | static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 557 | static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length) |
558 | { | 558 | { |
559 | uint64_t ping_id; | 559 | uint64_t ping_id; |
560 | 560 | ||
@@ -586,7 +586,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
586 | return 0; | 586 | return 0; |
587 | } | 587 | } |
588 | 588 | ||
589 | static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | 589 | static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length) |
590 | { | 590 | { |
591 | uint64_t ping_id; | 591 | uint64_t ping_id; |
592 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 592 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
@@ -930,7 +930,7 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
930 | } | 930 | } |
931 | 931 | ||
932 | /* Handle a received ping request for */ | 932 | /* Handle a received ping request for */ |
933 | static int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | 933 | static int handle_NATping(IP_Port source, uint8_t * packet, uint32_t length) |
934 | { | 934 | { |
935 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING | 935 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING |
936 | || length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 936 | || length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
@@ -1074,30 +1074,13 @@ static void doNAT(void) | |||
1074 | /*----------------------------------------------------------------------------------*/ | 1074 | /*----------------------------------------------------------------------------------*/ |
1075 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ | 1075 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ |
1076 | 1076 | ||
1077 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 1077 | void DHT_init(void) |
1078 | { | 1078 | { |
1079 | switch (packet[0]) { | 1079 | networking_registerhandler(0, &handle_ping_request); |
1080 | case 0: | 1080 | networking_registerhandler(1, &handle_ping_response); |
1081 | return handle_ping_request(packet, length, source); | 1081 | networking_registerhandler(2, &handle_getnodes); |
1082 | 1082 | networking_registerhandler(3, &handle_sendnodes); | |
1083 | case 1: | 1083 | networking_registerhandler(254, &handle_NATping); |
1084 | return handle_ping_response(packet, length, source); | ||
1085 | |||
1086 | case 2: | ||
1087 | return handle_getnodes(packet, length, source); | ||
1088 | |||
1089 | case 3: | ||
1090 | return handle_sendnodes(packet, length, source); | ||
1091 | |||
1092 | case 254: | ||
1093 | return handle_NATping(packet, length, source); | ||
1094 | |||
1095 | default: | ||
1096 | return 1; | ||
1097 | |||
1098 | } | ||
1099 | |||
1100 | return 0; | ||
1101 | } | 1084 | } |
1102 | 1085 | ||
1103 | void doDHT(void) | 1086 | void doDHT(void) |
@@ -58,11 +58,6 @@ IP_Port DHT_getfriendip(uint8_t *client_id); | |||
58 | /* Run this function at least a couple times per second (It's the main loop) */ | 58 | /* Run this function at least a couple times per second (It's the main loop) */ |
59 | void doDHT(void); | 59 | void doDHT(void); |
60 | 60 | ||
61 | /* if we receive a DHT packet we call this function so it can be handled. | ||
62 | return 0 if packet is handled correctly. | ||
63 | return 1 if it didn't handle the packet or if the packet was shit. */ | ||
64 | int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | ||
65 | |||
66 | /* Use this function to bootstrap the client | 61 | /* Use this function to bootstrap the client |
67 | Sends a get nodes request to the given node with ip port and public_key */ | 62 | Sends a get nodes request to the given node with ip port and public_key */ |
68 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | 63 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); |
@@ -93,6 +88,9 @@ uint32_t DHT_size(void); | |||
93 | /* save the DHT in data where data is an array of size DHT_size() */ | 88 | /* save the DHT in data where data is an array of size DHT_size() */ |
94 | void DHT_save(uint8_t *data); | 89 | void DHT_save(uint8_t *data); |
95 | 90 | ||
91 | /* init DHT */ | ||
92 | void DHT_init(void); | ||
93 | |||
96 | /* load the DHT from data of size size; | 94 | /* load the DHT from data of size size; |
97 | return -1 if failure | 95 | return -1 if failure |
98 | return 0 if success */ | 96 | return 0 if success */ |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 26b3930c..67dc656b 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -111,7 +111,7 @@ static int LAN_ip(IP ip) | |||
111 | return -1; | 111 | return -1; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int handle_LANdiscovery(uint8_t *packet, uint32_t length, IP_Port source) | 114 | static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length) |
115 | { | 115 | { |
116 | if (LAN_ip(source.ip) == -1) | 116 | if (LAN_ip(source.ip) == -1) |
117 | return 1; | 117 | return 1; |
@@ -125,16 +125,14 @@ static int handle_LANdiscovery(uint8_t *packet, uint32_t length, IP_Port source) | |||
125 | int send_LANdiscovery(uint16_t port) | 125 | int send_LANdiscovery(uint16_t port) |
126 | { | 126 | { |
127 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; | 127 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; |
128 | data[0] = 32; | 128 | data[0] = 33; |
129 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 129 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); |
130 | IP_Port ip_port = {broadcast_ip(), port}; | 130 | IP_Port ip_port = {broadcast_ip(), port}; |
131 | return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); | 131 | return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); |
132 | } | 132 | } |
133 | 133 | ||
134 | 134 | ||
135 | int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | 135 | void LANdiscovery_init(void) |
136 | { | 136 | { |
137 | if (packet[0] == 32) | 137 | networking_registerhandler(33, &handle_LANdiscovery); |
138 | return handle_LANdiscovery(packet, length, source); | ||
139 | return 1; | ||
140 | } | 138 | } |
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h index 96a6e6ad..6b5b8c75 100644 --- a/core/LAN_discovery.h +++ b/core/LAN_discovery.h | |||
@@ -43,10 +43,8 @@ extern "C" { | |||
43 | int send_LANdiscovery(uint16_t port); | 43 | int send_LANdiscovery(uint16_t port); |
44 | 44 | ||
45 | 45 | ||
46 | /* if we receive a packet we call this function so it can be handled. | 46 | /* sets up packet handlers */ |
47 | return 0 if packet is handled correctly. | 47 | void LANdiscovery_init(void); |
48 | return 1 if it didn't handle the packet or if the packet was shit. */ | ||
49 | int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | ||
50 | 48 | ||
51 | 49 | ||
52 | 50 | ||
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 3a289735..002e2cf8 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -555,7 +555,7 @@ static int send_DATA(uint32_t connection_id) | |||
555 | 555 | ||
556 | 556 | ||
557 | /* Return 0 if handled correctly, 1 if packet is bad. */ | 557 | /* Return 0 if handled correctly, 1 if packet is bad. */ |
558 | static int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 558 | static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length) |
559 | { | 559 | { |
560 | if (length != (1 + 4 + 4)) | 560 | if (length != (1 + 4 + 4)) |
561 | return 1; | 561 | return 1; |
@@ -669,7 +669,7 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet | |||
669 | return 1; | 669 | return 1; |
670 | } | 670 | } |
671 | 671 | ||
672 | static int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | 672 | static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) |
673 | { | 673 | { |
674 | 674 | ||
675 | if (!SYNC_valid(length)) | 675 | if (!SYNC_valid(length)) |
@@ -742,7 +742,7 @@ static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_ | |||
742 | return 0; | 742 | return 0; |
743 | } | 743 | } |
744 | 744 | ||
745 | static int handle_data(uint8_t *packet, uint32_t length, IP_Port source) | 745 | static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) |
746 | { | 746 | { |
747 | int connection = getconnection_id(source); | 747 | int connection = getconnection_id(source); |
748 | 748 | ||
@@ -770,23 +770,11 @@ static int handle_data(uint8_t *packet, uint32_t length, IP_Port source) | |||
770 | * END of packet handling functions | 770 | * END of packet handling functions |
771 | */ | 771 | */ |
772 | 772 | ||
773 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | 773 | void LosslessUDP_init(void) |
774 | { | 774 | { |
775 | switch (packet[0]) { | 775 | networking_registerhandler(16, &handle_handshake); |
776 | case 16: | 776 | networking_registerhandler(17, &handle_SYNC); |
777 | return handle_handshake(packet, length, source); | 777 | networking_registerhandler(18, &handle_data); |
778 | |||
779 | case 17: | ||
780 | return handle_SYNC(packet, length, source); | ||
781 | |||
782 | case 18: | ||
783 | return handle_data(packet, length, source); | ||
784 | |||
785 | default: | ||
786 | return 1; | ||
787 | } | ||
788 | |||
789 | return 0; | ||
790 | } | 778 | } |
791 | 779 | ||
792 | /* | 780 | /* |
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index b4cb186a..53afe606 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -113,11 +113,9 @@ int is_connected(int connection_id); | |||
113 | void doLossless_UDP(void); | 113 | void doLossless_UDP(void); |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * If we receive a Lossless_UDP packet, call this function so it can be handled. | 116 | * This function sets up LosslessUDP packet handling. |
117 | * Return 0 if packet is handled correctly. | ||
118 | * Return 1 if it didn't handle the packet or if the packet was shit. | ||
119 | */ | 117 | */ |
120 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 118 | void LosslessUDP_init(void); |
121 | 119 | ||
122 | #ifdef __cplusplus | 120 | #ifdef __cplusplus |
123 | } | 121 | } |
diff --git a/core/Messenger.c b/core/Messenger.c index dd651107..d26bba56 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -138,7 +138,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
138 | for (i = 0; i <= numfriends; ++i) { | 138 | for (i = 0; i <= numfriends; ++i) { |
139 | if (friendlist[i].status == NOFRIEND) { | 139 | if (friendlist[i].status == NOFRIEND) { |
140 | DHT_addfriend(client_id); | 140 | DHT_addfriend(client_id); |
141 | set_friend_status(i, FRIEND_ADDED); | 141 | friendlist[i].status = FRIEND_ADDED; |
142 | friendlist[i].crypt_connection_id = -1; | 142 | friendlist[i].crypt_connection_id = -1; |
143 | friendlist[i].friend_request_id = -1; | 143 | friendlist[i].friend_request_id = -1; |
144 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 144 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
@@ -231,7 +231,11 @@ uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | |||
231 | uint32_t msgid = ++friendlist[friendnumber].message_id; | 231 | uint32_t msgid = ++friendlist[friendnumber].message_id; |
232 | if (msgid == 0) | 232 | if (msgid == 0) |
233 | msgid = 1; /* otherwise, false error */ | 233 | msgid = 1; /* otherwise, false error */ |
234 | return m_sendmessage_withid(friendnumber, msgid, message, length); | 234 | if(m_sendmessage_withid(friendnumber, msgid, message, length)) { |
235 | return msgid; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
235 | } | 239 | } |
236 | 240 | ||
237 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) | 241 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) |
@@ -518,6 +522,11 @@ int initMessenger(void) | |||
518 | if(init_networking(ip,PORT) == -1) | 522 | if(init_networking(ip,PORT) == -1) |
519 | return -1; | 523 | return -1; |
520 | 524 | ||
525 | DHT_init(); | ||
526 | LosslessUDP_init(); | ||
527 | friendreq_init(); | ||
528 | LANdiscovery_init(); | ||
529 | |||
521 | return 0; | 530 | return 0; |
522 | } | 531 | } |
523 | 532 | ||
@@ -684,29 +693,8 @@ static void LANdiscovery(void) | |||
684 | /* the main loop that needs to be run at least 200 times per second. */ | 693 | /* the main loop that needs to be run at least 200 times per second. */ |
685 | void doMessenger(void) | 694 | void doMessenger(void) |
686 | { | 695 | { |
687 | IP_Port ip_port; | 696 | networking_poll(); |
688 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 697 | |
689 | uint32_t length; | ||
690 | while (receivepacket(&ip_port, data, &length) != -1) { | ||
691 | #ifdef DEBUG | ||
692 | /* if(rand() % 3 != 1) //simulate packet loss */ | ||
693 | /* { */ | ||
694 | if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && | ||
695 | friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) | ||
696 | /* if packet is discarded */ | ||
697 | printf("Received unhandled packet with length: %u\n", length); | ||
698 | else | ||
699 | printf("Received handled packet with length: %u\n", length); | ||
700 | /* } */ | ||
701 | printf("Status: %u %u %u\n",friendlist[0].status ,is_cryptoconnected(friendlist[0].crypt_connection_id), friendlist[0].crypt_connection_id); | ||
702 | #else | ||
703 | DHT_handlepacket(data, length, ip_port); | ||
704 | LosslessUDP_handlepacket(data, length, ip_port); | ||
705 | friendreq_handlepacket(data, length, ip_port); | ||
706 | LANdiscovery_handlepacket(data, length, ip_port); | ||
707 | #endif | ||
708 | |||
709 | } | ||
710 | doDHT(); | 698 | doDHT(); |
711 | doLossless_UDP(); | 699 | doLossless_UDP(); |
712 | doNetCrypto(); | 700 | doNetCrypto(); |
diff --git a/core/friend_requests.c b/core/friend_requests.c index b8dab87e..422cc028 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -101,7 +101,7 @@ static int request_received(uint8_t * client_id) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | 103 | ||
104 | int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 104 | static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t length) |
105 | { | 105 | { |
106 | if (packet[0] == 32) { | 106 | if (packet[0] == 32) { |
107 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 107 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || |
@@ -129,3 +129,8 @@ int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | |||
129 | } | 129 | } |
130 | return 1; | 130 | return 1; |
131 | } | 131 | } |
132 | |||
133 | void friendreq_init(void) | ||
134 | { | ||
135 | networking_registerhandler(32, &friendreq_handlepacket); | ||
136 | } | ||
diff --git a/core/friend_requests.h b/core/friend_requests.h index 4dfc5130..708d8f66 100644 --- a/core/friend_requests.h +++ b/core/friend_requests.h | |||
@@ -39,10 +39,8 @@ int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length); | |||
39 | 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) */ |
40 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); | 40 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); |
41 | 41 | ||
42 | /* if we receive a packet we call this function so it can be handled. | 42 | /* sets up friendreq packet handlers */ |
43 | return 0 if packet is handled correctly. | 43 | void friendreq_init(void); |
44 | return 1 if it didn't handle the packet or if the packet was shit. */ | ||
45 | int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | ||
46 | 44 | ||
47 | #ifdef __cplusplus | 45 | #ifdef __cplusplus |
48 | } | 46 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index 1c56b95a..07c43c40 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -37,6 +37,7 @@ typedef struct { | |||
37 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | 37 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ |
38 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ | 38 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ |
39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | 39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ |
40 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */ | ||
40 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 41 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
41 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 42 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
42 | 4 if the connection is timed out. */ | 43 | 4 if the connection is timed out. */ |
@@ -59,6 +60,17 @@ static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | |||
59 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | 60 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ |
60 | static int incoming_connections[MAX_INCOMING]; | 61 | static int incoming_connections[MAX_INCOMING]; |
61 | 62 | ||
63 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ | ||
64 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | ||
65 | { | ||
66 | uint8_t check = 0; | ||
67 | uint32_t i; | ||
68 | for (i = 0; i < length; ++i) { | ||
69 | check |= mem[i]; | ||
70 | } | ||
71 | return check; // We return zero if mem is made out of zeroes. | ||
72 | } | ||
73 | |||
62 | /* encrypts plain of length length to encrypted of length + 16 using the | 74 | /* encrypts plain of length length to encrypted of length + 16 using the |
63 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 75 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
64 | return -1 if there was a problem. | 76 | return -1 if there was a problem. |
@@ -78,12 +90,38 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
78 | 90 | ||
79 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero | 91 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero |
80 | apparently memcmp should not be used so we do this instead:*/ | 92 | apparently memcmp should not be used so we do this instead:*/ |
81 | uint32_t i; | 93 | if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) |
82 | uint32_t check = 0; | 94 | return -1; |
83 | for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { | 95 | |
84 | check |= temp_encrypted[i] ^ 0; | 96 | /* unpad the encrypted message */ |
85 | } | 97 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); |
86 | if(check != 0) | 98 | return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; |
99 | } | ||
100 | |||
101 | /* Precomputes the shared key from their public_key and our secret_key. | ||
102 | This way we can avoid an expensive elliptic curve scalar multiply for each | ||
103 | encrypt/decrypt operation. | ||
104 | enc_key has to be crypto_box_BEFORENMBYTES bytes long. */ | ||
105 | void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) | ||
106 | { | ||
107 | crypto_box_beforenm(enc_key, public_key, secret_key); | ||
108 | } | ||
109 | |||
110 | /* Fast encrypt. Depends on enc_key from encrypt_precompute. */ | ||
111 | int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | ||
112 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | ||
113 | { | ||
114 | if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) | ||
115 | return -1; | ||
116 | |||
117 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0}; | ||
118 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; | ||
119 | |||
120 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ | ||
121 | |||
122 | crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); | ||
123 | |||
124 | if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) | ||
87 | return -1; | 125 | return -1; |
88 | 126 | ||
89 | /* unpad the encrypted message */ | 127 | /* unpad the encrypted message */ |
@@ -112,12 +150,33 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
112 | 150 | ||
113 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero | 151 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero |
114 | apparently memcmp should not be used so we do this instead:*/ | 152 | apparently memcmp should not be used so we do this instead:*/ |
115 | uint32_t i; | 153 | if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) |
116 | uint32_t check = 0; | 154 | return -1; |
117 | for(i = 0; i < crypto_box_ZEROBYTES; ++i) { | 155 | |
118 | check |= temp_plain[i] ^ 0; | 156 | /* unpad the plain message */ |
119 | } | 157 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); |
120 | if(check != 0) | 158 | return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; |
159 | } | ||
160 | |||
161 | /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ | ||
162 | int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | ||
163 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | ||
164 | { | ||
165 | if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) | ||
166 | return -1; | ||
167 | |||
168 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; | ||
169 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0}; | ||
170 | |||
171 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ | ||
172 | |||
173 | if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, | ||
174 | nonce, enc_key) == -1) | ||
175 | return -1; | ||
176 | |||
177 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero | ||
178 | apparently memcmp should not be used so we do this instead:*/ | ||
179 | if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) | ||
121 | return -1; | 180 | return -1; |
122 | 181 | ||
123 | /* unpad the plain message */ | 182 | /* unpad the plain message */ |
@@ -161,9 +220,9 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
161 | return 0; | 220 | return 0; |
162 | if (temp_data[0] != 3) | 221 | if (temp_data[0] != 3) |
163 | return -1; | 222 | return -1; |
164 | int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, | 223 | int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, |
165 | crypto_connections[crypt_connection_id].sessionsecret_key, | 224 | crypto_connections[crypt_connection_id].recv_nonce, |
166 | crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); | 225 | temp_data + 1, length - 1, data); |
167 | if (len != -1) { | 226 | if (len != -1) { |
168 | increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); | 227 | increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); |
169 | return len; | 228 | return len; |
@@ -182,9 +241,9 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
182 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) | 241 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
183 | return 0; | 242 | return 0; |
184 | uint8_t temp_data[MAX_DATA_SIZE]; | 243 | uint8_t temp_data[MAX_DATA_SIZE]; |
185 | int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, | 244 | int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, |
186 | crypto_connections[crypt_connection_id].sessionsecret_key, | 245 | crypto_connections[crypt_connection_id].sent_nonce, |
187 | crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); | 246 | data, length, temp_data + 1); |
188 | if (len == -1) | 247 | if (len == -1) |
189 | return 0; | 248 | return 0; |
190 | temp_data[0] = 3; | 249 | temp_data[0] = 3; |
@@ -417,6 +476,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
417 | crypto_connections[i].sessionpublic_key) == 1) { | 476 | crypto_connections[i].sessionpublic_key) == 1) { |
418 | increment_nonce(crypto_connections[i].recv_nonce); | 477 | increment_nonce(crypto_connections[i].recv_nonce); |
419 | uint32_t zero = 0; | 478 | uint32_t zero = 0; |
479 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | ||
480 | crypto_connections[i].sessionsecret_key, | ||
481 | crypto_connections[i].shared_key); | ||
420 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 482 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
421 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 483 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); |
422 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 484 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
@@ -511,6 +573,9 @@ static void receive_crypto(void) | |||
511 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 573 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
512 | increment_nonce(crypto_connections[i].sent_nonce); | 574 | increment_nonce(crypto_connections[i].sent_nonce); |
513 | uint32_t zero = 0; | 575 | uint32_t zero = 0; |
576 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | ||
577 | crypto_connections[i].sessionsecret_key, | ||
578 | crypto_connections[i].shared_key); | ||
514 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 579 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
515 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 580 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); |
516 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 581 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
@@ -521,7 +586,7 @@ static void receive_crypto(void) | |||
521 | 586 | ||
522 | } | 587 | } |
523 | if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { | 588 | if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { |
524 | if (id_packet(crypto_connections[i].number) == CONN_ESTABLISHED) { | 589 | if (id_packet(crypto_connections[i].number) == 3) { |
525 | uint8_t temp_data[MAX_DATA_SIZE]; | 590 | uint8_t temp_data[MAX_DATA_SIZE]; |
526 | uint8_t data[MAX_DATA_SIZE]; | 591 | uint8_t data[MAX_DATA_SIZE]; |
527 | int length = read_packet(crypto_connections[i].number, temp_data); | 592 | int length = read_packet(crypto_connections[i].number, temp_data); |
@@ -531,6 +596,9 @@ static void receive_crypto(void) | |||
531 | uint32_t zero = 0; | 596 | uint32_t zero = 0; |
532 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 597 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { |
533 | increment_nonce(crypto_connections[i].recv_nonce); | 598 | increment_nonce(crypto_connections[i].recv_nonce); |
599 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | ||
600 | crypto_connections[i].sessionsecret_key, | ||
601 | crypto_connections[i].shared_key); | ||
534 | crypto_connections[i].status = CONN_ESTABLISHED; | 602 | crypto_connections[i].status = CONN_ESTABLISHED; |
535 | 603 | ||
536 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | 604 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 66634d45..135e099d 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -36,6 +36,9 @@ extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |||
36 | 36 | ||
37 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | 37 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) |
38 | 38 | ||
39 | /* returns zero if the buffer contains only zeros */ | ||
40 | uint8_t crypto_iszero(uint8_t* buffer, uint32_t blen); | ||
41 | |||
39 | /* encrypts plain of length length to encrypted of length + 16 using the | 42 | /* encrypts plain of length length to encrypted of length + 16 using the |
40 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 43 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
41 | return -1 if there was a problem. | 44 | return -1 if there was a problem. |
@@ -51,6 +54,19 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
51 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 54 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, |
52 | uint8_t *encrypted, uint32_t length, uint8_t *plain); | 55 | uint8_t *encrypted, uint32_t length, uint8_t *plain); |
53 | 56 | ||
57 | /* Fast encrypt/decrypt operations. Use if this is not a one-time communication. | ||
58 | encrypt_precompute does the shared-key generation once so it does not have | ||
59 | to be preformed on every encrypt/decrypt. */ | ||
60 | void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key); | ||
61 | |||
62 | /* Fast encrypt. Depends on enc_key from encrypt_precompute. */ | ||
63 | int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | ||
64 | uint8_t *plain, uint32_t length, uint8_t *encrypted); | ||
65 | |||
66 | /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ | ||
67 | int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | ||
68 | uint8_t *encrypted, uint32_t length, uint8_t *plain); | ||
69 | |||
54 | 70 | ||
55 | /* fill the given nonce with random bytes. */ | 71 | /* fill the given nonce with random bytes. */ |
56 | void random_nonce(uint8_t *nonce); | 72 | void random_nonce(uint8_t *nonce); |
diff --git a/core/network.c b/core/network.c index 8c6fa7b6..7e3b344a 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -71,7 +71,7 @@ int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) | |||
71 | the packet data into data | 71 | the packet data into data |
72 | the packet length into length. | 72 | the packet length into length. |
73 | dump all empty packets. */ | 73 | dump all empty packets. */ |
74 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | 74 | static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) |
75 | { | 75 | { |
76 | ADDR addr; | 76 | ADDR addr; |
77 | #ifdef WIN32 | 77 | #ifdef WIN32 |
@@ -88,6 +88,27 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | |||
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | 90 | ||
91 | static packet_handler_callback packethandlers[256] = {0}; | ||
92 | |||
93 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb) | ||
94 | { | ||
95 | packethandlers[byte] = cb; | ||
96 | } | ||
97 | |||
98 | void networking_poll() | ||
99 | { | ||
100 | IP_Port ip_port; | ||
101 | uint8_t data[MAX_UDP_PACKET_SIZE]; | ||
102 | uint32_t length; | ||
103 | |||
104 | while (receivepacket(&ip_port, data, &length) != -1) | ||
105 | { | ||
106 | if (length < 1) continue; | ||
107 | if (!packethandlers[data[0]]) continue; | ||
108 | packethandlers[data[0]](ip_port, data, length); | ||
109 | } | ||
110 | } | ||
111 | |||
91 | /* initialize networking | 112 | /* initialize networking |
92 | bind to ip and port | 113 | bind to ip and port |
93 | ip must be in network order EX: 127.0.0.1 = (7F000001) | 114 | ip must be in network order EX: 127.0.0.1 = (7F000001) |
@@ -149,7 +170,6 @@ int init_networking(IP ip, uint16_t port) | |||
149 | bind(sock, (struct sockaddr*)&addr, sizeof(addr)); | 170 | bind(sock, (struct sockaddr*)&addr, sizeof(addr)); |
150 | 171 | ||
151 | return 0; | 172 | return 0; |
152 | |||
153 | } | 173 | } |
154 | 174 | ||
155 | /* function to cleanup networking stuff */ | 175 | /* function to cleanup networking stuff */ |
diff --git a/core/network.h b/core/network.h index d3c39333..7c95d84d 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -94,6 +94,11 @@ typedef struct { | |||
94 | #endif | 94 | #endif |
95 | } ADDR; | 95 | } ADDR; |
96 | 96 | ||
97 | /* Function to receive data, ip and port of sender is put into ip_port | ||
98 | the packet data into data | ||
99 | the packet length into length. */ | ||
100 | typedef int (*packet_handler_callback)(IP_Port ip_port, uint8_t *data, uint32_t len); | ||
101 | |||
97 | /* returns current time in milleseconds since the epoch. */ | 102 | /* returns current time in milleseconds since the epoch. */ |
98 | uint64_t current_time(void); | 103 | uint64_t current_time(void); |
99 | 104 | ||
@@ -106,10 +111,11 @@ uint32_t random_int(void); | |||
106 | /* Function to send packet(data) of length length to ip_port */ | 111 | /* Function to send packet(data) of length length to ip_port */ |
107 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); | 112 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); |
108 | 113 | ||
109 | /* Function to receive data, ip and port of sender is put into ip_port | 114 | /* Function to call when packet beginning with byte is received */ |
110 | the packet data into data | 115 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb); |
111 | the packet length into length. */ | 116 | |
112 | int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length); | 117 | /* call this several times a second */ |
118 | void networking_poll(); | ||
113 | 119 | ||
114 | /* initialize networking | 120 | /* initialize networking |
115 | bind to ip and port | 121 | bind to ip and port |
diff --git a/core/ping.c b/core/ping.c index 6a1fbb7e..24ece06a 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -163,7 +163,7 @@ int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) | |||
163 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | 163 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); |
164 | } | 164 | } |
165 | 165 | ||
166 | int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source) | 166 | int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length) |
167 | { | 167 | { |
168 | pingreq_t* p = (pingreq_t*) packet; | 168 | pingreq_t* p = (pingreq_t*) packet; |
169 | int rc; | 169 | int rc; |
@@ -190,7 +190,7 @@ int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source) | |||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source) | 193 | int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length) |
194 | { | 194 | { |
195 | pingres_t* p = (pingres_t*) packet; | 195 | pingres_t* p = (pingres_t*) packet; |
196 | int rc; | 196 | int rc; |
diff --git a/core/ping.h b/core/ping.h index 2cab7d59..1ccfabac 100644 --- a/core/ping.h +++ b/core/ping.h | |||
@@ -12,5 +12,5 @@ uint64_t add_ping(IP_Port ipp); | |||
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | 12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); |
13 | int send_ping_request(IP_Port ipp, clientid_t* client_id); | 13 | int send_ping_request(IP_Port ipp, clientid_t* client_id); |
14 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); | 14 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); |
15 | int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source); | 15 | int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length); |
16 | int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source); | 16 | int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length); |
diff --git a/other/CMakeLists.txt b/other/CMakeLists.txt index 05b24f06..db742e3e 100644 --- a/other/CMakeLists.txt +++ b/other/CMakeLists.txt | |||
@@ -4,6 +4,6 @@ cmake_policy(SET CMP0011 NEW) | |||
4 | 4 | ||
5 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_bootstrap.cmake) | 5 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_bootstrap.cmake) |
6 | 6 | ||
7 | if(NOT WIN32) | 7 | if(LINUX) |
8 | add_subdirectory(bootstrap_serverdaemon) | 8 | add_subdirectory(bootstrap_serverdaemon) |
9 | endif() | 9 | endif() |
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index befe2225..4b0adeff 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c | |||
@@ -113,9 +113,8 @@ int main(int argc, char *argv[]) | |||
113 | free(bootstrap_key); | 113 | free(bootstrap_key); |
114 | } | 114 | } |
115 | 115 | ||
116 | IP_Port ip_port; | 116 | DHT_init(); |
117 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 117 | friendreq_init(); |
118 | uint32_t length; | ||
119 | 118 | ||
120 | int is_waiting_for_dht_connection = 1; | 119 | int is_waiting_for_dht_connection = 1; |
121 | while(1) | 120 | while(1) |
@@ -127,11 +126,8 @@ int main(int argc, char *argv[]) | |||
127 | } | 126 | } |
128 | doDHT(); | 127 | doDHT(); |
129 | 128 | ||
130 | while(receivepacket(&ip_port, data, &length) != -1) | 129 | networking_poll(); |
131 | { | 130 | |
132 | DHT_handlepacket(data, length, ip_port); | ||
133 | friendreq_handlepacket(data, length, ip_port); | ||
134 | } | ||
135 | c_sleep(1); | 131 | c_sleep(1); |
136 | } | 132 | } |
137 | shutdown_networking(); | 133 | shutdown_networking(); |
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c index 48152744..6ce542c1 100644 --- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c +++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | |||
@@ -81,10 +81,6 @@ int connect_to_servers(struct server_info_s *info) | |||
81 | int i; | 81 | int i; |
82 | int c; | 82 | int c; |
83 | 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) { | 84 | for(i = 0; i < 32; ++i) { |
89 | if(info[i].valid) { | 85 | if(info[i].valid) { |
90 | /* Actual bootstrapping code goes here */ | 86 | /* Actual bootstrapping code goes here */ |
@@ -109,10 +105,7 @@ int connect_to_servers(struct server_info_s *info) | |||
109 | 105 | ||
110 | doDHT(); | 106 | doDHT(); |
111 | 107 | ||
112 | while(receivepacket(&ip_port, data, &length) != -1) | 108 | networking_poll(); |
113 | { | ||
114 | DHT_handlepacket(data, length, ip_port); | ||
115 | } | ||
116 | } | 109 | } |
117 | 110 | ||
118 | /* This probably never happens */ | 111 | /* This probably never happens */ |
@@ -337,6 +330,7 @@ int main(int argc, char *argv[]) { | |||
337 | /* Bootstrap the DHT | 330 | /* Bootstrap the DHT |
338 | This one throws odd errors, too. Ignore. I assume they come | 331 | This one throws odd errors, too. Ignore. I assume they come |
339 | from somewhere in the core. */ | 332 | from somewhere in the core. */ |
333 | DHT_init(); | ||
340 | tmperr = errno; | 334 | tmperr = errno; |
341 | connect_to_servers(server_conf.info); | 335 | connect_to_servers(server_conf.info); |
342 | errno = tmperr; | 336 | errno = tmperr; |
@@ -400,19 +394,13 @@ int main(int argc, char *argv[]) { | |||
400 | close(STDERR_FILENO); | 394 | close(STDERR_FILENO); |
401 | 395 | ||
402 | /* Main loop */ | 396 | /* Main loop */ |
403 | IP_Port ip_port; | 397 | friendreq_init(); |
404 | uint8_t data[MAX_UDP_PACKET_SIZE]; | ||
405 | uint32_t length; | ||
406 | 398 | ||
407 | while(1) | 399 | while(1) |
408 | { | 400 | { |
409 | doDHT(); | 401 | doDHT(); |
410 | 402 | ||
411 | while(receivepacket(&ip_port, data, &length) != -1) | 403 | networking_poll(); |
412 | { | ||
413 | DHT_handlepacket(data, length, ip_port); | ||
414 | friendreq_handlepacket(data, length, ip_port); | ||
415 | } | ||
416 | usleep(10000); | 404 | usleep(10000); |
417 | } | 405 | } |
418 | 406 | ||
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index f2a2e95e..7322509a 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt | |||
@@ -8,6 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DHT_test.cmake) | |||
8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake) | 8 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake) |
9 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) | 9 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) |
10 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake) | 10 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake) |
11 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_speed_test.cmake) | ||
11 | 12 | ||
12 | if(WIN32) | 13 | if(WIN32) |
13 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) | 14 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) |
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index c8feaf4b..350093fd 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -156,14 +156,20 @@ int main(int argc, char *argv[]) | |||
156 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | 156 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); |
157 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); | 157 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); |
158 | 158 | ||
159 | /* | ||
159 | IP_Port ip_port; | 160 | IP_Port ip_port; |
160 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 161 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
161 | uint32_t length; | 162 | uint32_t length; |
163 | */ | ||
164 | |||
165 | DHT_init(); | ||
166 | friendreq_init(); | ||
162 | 167 | ||
163 | while(1) { | 168 | while(1) { |
164 | 169 | ||
165 | doDHT(); | 170 | doDHT(); |
166 | 171 | ||
172 | /* slvrTODO: | ||
167 | while(receivepacket(&ip_port, data, &length) != -1) { | 173 | while(receivepacket(&ip_port, data, &length) != -1) { |
168 | if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) { | 174 | if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) { |
169 | //unhandled packet | 175 | //unhandled packet |
@@ -172,11 +178,14 @@ int main(int argc, char *argv[]) | |||
172 | printf("Received handled packet with length: %u\n", length); | 178 | printf("Received handled packet with length: %u\n", length); |
173 | } | 179 | } |
174 | } | 180 | } |
181 | */ | ||
182 | networking_poll(); | ||
183 | |||
175 | print_clientlist(); | 184 | print_clientlist(); |
176 | print_friendlist(); | 185 | print_friendlist(); |
177 | c_sleep(300); | 186 | c_sleep(300); |
178 | } | 187 | } |
179 | 188 | ||
180 | shutdown_networking(); | 189 | shutdown_networking(); |
181 | return 0; | 190 | return 0; |
182 | } | 191 | } |
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 78aff1a3..7efafa4f 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c | |||
@@ -120,20 +120,23 @@ void printconnection(int connection_id) | |||
120 | /*run doLossless_UDP(); */ | 120 | /*run doLossless_UDP(); */ |
121 | void Lossless_UDP() | 121 | void Lossless_UDP() |
122 | { | 122 | { |
123 | IP_Port ip_port; | 123 | /* IP_Port ip_port; |
124 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 124 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
125 | uint32_t length; | 125 | uint32_t length; |
126 | while (receivepacket(&ip_port, data, &length) != -1) { | 126 | while (receivepacket(&ip_port, data, &length) != -1) { |
127 | printf("packet with length: %u\n", length); | 127 | printf("packet with length: %u\n", length); */ |
128 | /* if(rand() % 3 != 1)//add packet loss | 128 | /* if(rand() % 3 != 1)//add packet loss |
129 | { */ | 129 | { */ |
130 | /* | ||
130 | if (LosslessUDP_handlepacket(data, length, ip_port)) | 131 | if (LosslessUDP_handlepacket(data, length, ip_port)) |
131 | printpacket(data, length, ip_port); | 132 | printpacket(data, length, ip_port); |
132 | else | 133 | else |
133 | printf("Received handled packet with length: %u\n", length); //printconnection(0); | 134 | printf("Received handled packet with length: %u\n", length); //printconnection(0); */ |
134 | 135 | ||
135 | /* } */ | 136 | /* } */ |
136 | } | 137 | /* }*/ |
138 | |||
139 | networking_poll(); | ||
137 | 140 | ||
138 | doLossless_UDP(); | 141 | doLossless_UDP(); |
139 | 142 | ||
@@ -181,6 +184,7 @@ int main(int argc, char *argv[]) | |||
181 | } | 184 | } |
182 | timer = current_time(); | 185 | timer = current_time(); |
183 | 186 | ||
187 | LosslessUDP_init(); | ||
184 | 188 | ||
185 | /*read first part of file */ | 189 | /*read first part of file */ |
186 | read = fread(buffer, 1, 512, file); | 190 | read = fread(buffer, 1, 512, file); |
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index f4b144b4..bc4fed7a 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c | |||
@@ -117,20 +117,22 @@ void printconnection(int connection_id) | |||
117 | * run doLossless_UDP(); */ | 117 | * run doLossless_UDP(); */ |
118 | void Lossless_UDP() | 118 | void Lossless_UDP() |
119 | { | 119 | { |
120 | IP_Port ip_port; | 120 | // IP_Port ip_port; |
121 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 121 | // uint8_t data[MAX_UDP_PACKET_SIZE]; |
122 | uint32_t length; | 122 | // uint32_t length; |
123 | while (receivepacket(&ip_port, data, &length) != -1) { | 123 | // while (receivepacket(&ip_port, data, &length) != -1) { |
124 | //if(rand() % 3 != 1)//add packet loss | 124 | //if(rand() % 3 != 1)//add packet loss |
125 | //{ | 125 | //{ |
126 | if (LosslessUDP_handlepacket(data, length, ip_port)) { | 126 | // if (LosslessUDP_handlepacket(data, length, ip_port)) { |
127 | printpacket(data, length, ip_port); | 127 | // printpacket(data, length, ip_port); |
128 | } else { | 128 | // } else { |
129 | //printconnection(0); | 129 | //printconnection(0); |
130 | printf("Received handled packet with length: %u\n", length); | 130 | // printf("Received handled packet with length: %u\n", length); |
131 | } | 131 | // } |
132 | //} | 132 | //} |
133 | } | 133 | // } |
134 | |||
135 | networking_poll(); | ||
134 | 136 | ||
135 | doLossless_UDP(); | 137 | doLossless_UDP(); |
136 | } | 138 | } |
@@ -161,6 +163,7 @@ int main(int argc, char *argv[]) | |||
161 | int connection; | 163 | int connection; |
162 | uint64_t timer = current_time(); | 164 | uint64_t timer = current_time(); |
163 | 165 | ||
166 | LosslessUDP_init(); | ||
164 | 167 | ||
165 | while (1) { | 168 | while (1) { |
166 | Lossless_UDP(); | 169 | Lossless_UDP(); |
diff --git a/testing/cmake/crypto_speed_test.cmake b/testing/cmake/crypto_speed_test.cmake new file mode 100644 index 00000000..c269af5b --- /dev/null +++ b/testing/cmake/crypto_speed_test.cmake | |||
@@ -0,0 +1,9 @@ | |||
1 | cmake_minimum_required(VERSION 2.6.0) | ||
2 | project(crypto_speed_test C) | ||
3 | |||
4 | set(exe_name crypto_speed_test) | ||
5 | |||
6 | add_executable(${exe_name} | ||
7 | crypto_speed_test.c) | ||
8 | |||
9 | linkCoreLibraries(${exe_name}) | ||
diff --git a/testing/crypto_speed_test.c b/testing/crypto_speed_test.c new file mode 100644 index 00000000..81be92c6 --- /dev/null +++ b/testing/crypto_speed_test.c | |||
@@ -0,0 +1,130 @@ | |||
1 | // Hi-resolution timer | ||
2 | #ifdef WIN32 | ||
3 | |||
4 | #include <windows.h> | ||
5 | double get_time() | ||
6 | { | ||
7 | LARGE_INTEGER t, f; | ||
8 | QueryPerformanceCounter(&t); | ||
9 | QueryPerformanceFrequency(&f); | ||
10 | return (double)t.QuadPart/(double)f.QuadPart; | ||
11 | } | ||
12 | |||
13 | #else | ||
14 | |||
15 | #include <sys/time.h> | ||
16 | #include <sys/resource.h> | ||
17 | |||
18 | double get_time() | ||
19 | { | ||
20 | struct timeval t; | ||
21 | struct timezone tzp; | ||
22 | gettimeofday(&t, &tzp); | ||
23 | return t.tv_sec + t.tv_usec*1e-6; | ||
24 | } | ||
25 | |||
26 | #endif | ||
27 | |||
28 | #include "../core/net_crypto.h" | ||
29 | #include <stdlib.h> | ||
30 | #include <time.h> | ||
31 | |||
32 | void rand_bytes(uint8_t *b, size_t blen) | ||
33 | { | ||
34 | size_t i; | ||
35 | for (i = 0; i < blen; i++) | ||
36 | { | ||
37 | b[i] = rand(); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | int main(int argc, char* argv[]) | ||
42 | { | ||
43 | const int numtrials = 10000; | ||
44 | |||
45 | unsigned char pk1[crypto_box_PUBLICKEYBYTES]; | ||
46 | unsigned char sk1[crypto_box_SECRETKEYBYTES]; | ||
47 | unsigned char pk2[crypto_box_PUBLICKEYBYTES]; | ||
48 | unsigned char sk2[crypto_box_SECRETKEYBYTES]; | ||
49 | unsigned char k1[crypto_box_BEFORENMBYTES]; | ||
50 | unsigned char k2[crypto_box_BEFORENMBYTES]; | ||
51 | |||
52 | unsigned char n[crypto_box_NONCEBYTES]; | ||
53 | |||
54 | unsigned char m[500]; | ||
55 | unsigned char c[sizeof(m) + ENCRYPTION_PADDING]; | ||
56 | |||
57 | unsigned char k[crypto_box_BEFORENMBYTES]; | ||
58 | |||
59 | int trialno; | ||
60 | |||
61 | double starttime; | ||
62 | double endtime; | ||
63 | double slow_time; | ||
64 | double fast_time; | ||
65 | double keygen_time; | ||
66 | double precompute_time; | ||
67 | |||
68 | // Pregenerate | ||
69 | crypto_box_keypair(pk1, sk1); | ||
70 | crypto_box_keypair(pk2, sk2); | ||
71 | encrypt_precompute(pk1, sk2, k1); | ||
72 | encrypt_precompute(pk2, sk1, k2); | ||
73 | rand_bytes(m, sizeof(m)); | ||
74 | rand_bytes(n, sizeof(n)); | ||
75 | |||
76 | printf("starting slow...\n"); | ||
77 | starttime = get_time(); | ||
78 | for (trialno = 0; trialno < numtrials; trialno++) | ||
79 | { | ||
80 | encrypt_data(pk1, sk2, n, m, sizeof(m), c); | ||
81 | decrypt_data(pk2, sk1, n, c, sizeof(c), m); | ||
82 | } | ||
83 | endtime = get_time(); | ||
84 | slow_time = endtime-starttime; | ||
85 | |||
86 | printf("starting fast...\n"); | ||
87 | starttime = get_time(); | ||
88 | for (trialno = 0; trialno < numtrials; trialno++) | ||
89 | { | ||
90 | encrypt_data_fast(k1, n, m, sizeof(m), c); | ||
91 | decrypt_data_fast(k2, n, c, sizeof(c), m); | ||
92 | } | ||
93 | endtime = get_time(); | ||
94 | fast_time = endtime-starttime; | ||
95 | |||
96 | printf("starting keygen...\n"); | ||
97 | starttime = get_time(); | ||
98 | for (trialno = 0; trialno < numtrials; trialno++) | ||
99 | { | ||
100 | crypto_box_keypair(pk1, sk1); | ||
101 | crypto_box_keypair(pk2, sk2); | ||
102 | } | ||
103 | endtime = get_time(); | ||
104 | keygen_time = endtime-starttime; | ||
105 | |||
106 | printf("starting precompute...\n"); | ||
107 | starttime = get_time(); | ||
108 | for (trialno = 0; trialno < numtrials; trialno++) | ||
109 | { | ||
110 | encrypt_precompute(pk1, sk2, k); | ||
111 | encrypt_precompute(pk2, sk1, k); | ||
112 | } | ||
113 | endtime = get_time(); | ||
114 | precompute_time = endtime-starttime; | ||
115 | |||
116 | printf("\n"); | ||
117 | printf("trials: %i\n", 2*numtrials); | ||
118 | printf("\n"); | ||
119 | printf("slow time: %f sec\n", slow_time); | ||
120 | printf("fast time: %f sec\n", fast_time); | ||
121 | printf("keygen time: %f sec\n", keygen_time); | ||
122 | printf("precompute time: %f sec\n", precompute_time); | ||
123 | printf("\n"); | ||
124 | printf("Speed boost: %.1f%%\n", slow_time * 100 / fast_time); | ||
125 | printf("\n"); | ||
126 | printf("slow: %.1f per second\n", 2*numtrials/slow_time); | ||
127 | printf("fast: %.1f per second\n", 2*numtrials/fast_time); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index e4eb259b..ab44e960 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c | |||
@@ -40,7 +40,7 @@ static struct { | |||
40 | void (*func)(ToxWindow *, char **); | 40 | void (*func)(ToxWindow *, char **); |
41 | } commands[] = { | 41 | } commands[] = { |
42 | { "accept", 1, cmd_accept }, | 42 | { "accept", 1, cmd_accept }, |
43 | { "add", 2, cmd_add }, | 43 | { "add", 1, cmd_add }, |
44 | { "clear", 0, cmd_clear }, | 44 | { "clear", 0, cmd_clear }, |
45 | { "connect", 3, cmd_connect }, | 45 | { "connect", 3, cmd_connect }, |
46 | { "exit", 0, cmd_quit }, | 46 | { "exit", 0, cmd_quit }, |
@@ -300,36 +300,54 @@ static void execute(ToxWindow *self, char *u_cmd) | |||
300 | break; | 300 | break; |
301 | cmd[cmd_end + 1] = '\0'; | 301 | cmd[cmd_end + 1] = '\0'; |
302 | 302 | ||
303 | char *args[4]; | 303 | /* insert \0 at argument boundaries */ |
304 | args[0] = strtok(cmd, " "); | 304 | int numargs = 0; |
305 | for (i = 0; i < MAX_STR_SIZE; i++) { | ||
306 | if (cmd[i] == '\"') | ||
307 | while (cmd[++i] != '\"'); /* skip over strings */ | ||
308 | if (cmd[i] == ' ') { | ||
309 | cmd[i] = '\0'; | ||
310 | numargs++; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /* excessive arguments */ | ||
315 | if (numargs > 3) { | ||
316 | wprintw(self->window, "Invalid command: too many arguments.\n"); | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | /* read arguments into array */ | ||
321 | char *cmdargs[5]; | ||
322 | int pos = 0; | ||
323 | for (i = 0; i < 5; i++) { | ||
324 | cmdargs[i] = cmd + pos; | ||
325 | pos += strlen(cmdargs[i]) + 1; | ||
326 | } | ||
305 | 327 | ||
306 | /* no input */ | 328 | /* no input */ |
307 | if (!args[0]) | 329 | if (strlen(cmdargs[0]) == 0) |
308 | return; | 330 | return; |
309 | 331 | ||
310 | /* match input to command list */ | 332 | /* match input to command list */ |
311 | for (i = 0; i < NUM_COMMANDS; i++) { | 333 | for (i = 0; i < NUM_COMMANDS; i++) { |
312 | if (!strcmp(args[0], commands[i].name)) { | 334 | if (!strcmp(cmdargs[0], commands[i].name)) { |
313 | /* read in arguments */ | 335 | /* check for missing arguments */ |
314 | int j; | 336 | int j; |
315 | for (j = 1; j <= commands[i].numargs; j++) { | 337 | for (j = 0; j <= commands[i].numargs; j++) { |
316 | args[j] = strtok(NULL, " "); | 338 | if (strlen(cmdargs[j]) == 0) { |
317 | /* check for missing arguments */ | ||
318 | /* add is special because it can take either 1 or 2 arguments */ | ||
319 | if (strcmp(args[0], "add") != 0 && args[j] == NULL) { | ||
320 | wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n", | 339 | wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n", |
321 | commands[i].name, commands[i].numargs, j - 1); | 340 | commands[i].name, commands[i].numargs, j - 1); |
322 | return; | 341 | return; |
323 | } | 342 | } |
324 | } | 343 | } |
325 | /* check for excess arguments */ | 344 | /* check for excess arguments */ |
326 | /* add is special because the add message may contain spaces */ | 345 | if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) { |
327 | if (strcmp(args[0], "add") != 0 && strtok(NULL, " ") != NULL) { | ||
328 | wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name); | 346 | wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name); |
329 | return; | 347 | return; |
330 | } | 348 | } |
331 | /* pass arguments to command function */ | 349 | /* pass arguments to command function */ |
332 | (commands[i].func)(self, args); | 350 | (commands[i].func)(self, cmdargs); |
333 | return; | 351 | return; |
334 | } | 352 | } |
335 | } | 353 | } |