ffi-tox 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/ProjectTox-Core/AUTHORS +0 -0
  3. data/ProjectTox-Core/ChangeLog +0 -0
  4. data/ProjectTox-Core/INSTALL +370 -0
  5. data/ProjectTox-Core/INSTALL.md +455 -56
  6. data/ProjectTox-Core/Makefile.am +35 -0
  7. data/ProjectTox-Core/NEWS +0 -0
  8. data/ProjectTox-Core/README +43 -0
  9. data/ProjectTox-Core/README.md +34 -44
  10. data/ProjectTox-Core/auto_tests/Makefile.inc +110 -0
  11. data/ProjectTox-Core/auto_tests/TCP_test.c +519 -0
  12. data/ProjectTox-Core/auto_tests/assoc_test.c +160 -0
  13. data/ProjectTox-Core/auto_tests/crypto_test.c +302 -0
  14. data/ProjectTox-Core/auto_tests/dht_test.c +362 -0
  15. data/ProjectTox-Core/auto_tests/encryptsave_test.c +104 -0
  16. data/ProjectTox-Core/auto_tests/friends_test.c +238 -0
  17. data/ProjectTox-Core/auto_tests/helpers.h +15 -0
  18. data/ProjectTox-Core/auto_tests/messenger_test.c +365 -0
  19. data/ProjectTox-Core/auto_tests/network_test.c +171 -0
  20. data/ProjectTox-Core/auto_tests/onion_test.c +363 -0
  21. data/ProjectTox-Core/auto_tests/skeleton_test.c +49 -0
  22. data/ProjectTox-Core/auto_tests/tox_test.c +454 -0
  23. data/ProjectTox-Core/auto_tests/toxav_basic_test.c +597 -0
  24. data/ProjectTox-Core/auto_tests/toxav_many_test.c +402 -0
  25. data/ProjectTox-Core/autogen.sh +6 -0
  26. data/ProjectTox-Core/build/Makefile.am +14 -0
  27. data/ProjectTox-Core/configure.ac +694 -0
  28. data/ProjectTox-Core/dist-build/android-arm.sh +3 -0
  29. data/ProjectTox-Core/dist-build/android-armv7.sh +3 -0
  30. data/ProjectTox-Core/dist-build/android-build.sh +59 -0
  31. data/ProjectTox-Core/dist-build/android-mips.sh +3 -0
  32. data/ProjectTox-Core/dist-build/android-x86.sh +3 -0
  33. data/ProjectTox-Core/docs/Group-Chats.md +71 -0
  34. data/ProjectTox-Core/docs/Hardening.txt +60 -0
  35. data/ProjectTox-Core/docs/Hardening_docs.txt +30 -0
  36. data/ProjectTox-Core/docs/Prevent_Tracking.txt +160 -0
  37. data/ProjectTox-Core/docs/TCP_Network.txt +154 -0
  38. data/ProjectTox-Core/docs/TODO +62 -0
  39. data/ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt +120 -0
  40. data/ProjectTox-Core/docs/av_api.md +194 -0
  41. data/ProjectTox-Core/libtoxav.pc.in +11 -0
  42. data/ProjectTox-Core/libtoxcore.pc.in +11 -0
  43. data/ProjectTox-Core/m4/ax_have_epoll.m4 +104 -0
  44. data/ProjectTox-Core/m4/ax_pthread.m4 +317 -0
  45. data/ProjectTox-Core/m4/pkg.m4 +199 -0
  46. data/ProjectTox-Core/other/DHT_bootstrap.c +121 -58
  47. data/ProjectTox-Core/other/DHTnodes +3 -0
  48. data/ProjectTox-Core/other/Makefile.inc +20 -0
  49. data/ProjectTox-Core/other/bootstrap_node_packets.c +65 -0
  50. data/ProjectTox-Core/other/tox.png +0 -0
  51. data/ProjectTox-Core/testing/DHT_test.c +170 -98
  52. data/ProjectTox-Core/testing/Makefile.inc +112 -0
  53. data/ProjectTox-Core/testing/Messenger_test.c +133 -69
  54. data/ProjectTox-Core/testing/dns3_test.c +115 -0
  55. data/ProjectTox-Core/testing/misc_tools.c +59 -13
  56. data/ProjectTox-Core/testing/nTox.c +1127 -264
  57. data/ProjectTox-Core/testing/nTox.h +10 -19
  58. data/ProjectTox-Core/testing/tox_shell.c +159 -0
  59. data/ProjectTox-Core/testing/tox_sync.c +299 -0
  60. data/ProjectTox-Core/tools/README +11 -0
  61. data/ProjectTox-Core/tools/astylerc +11 -0
  62. data/ProjectTox-Core/tools/pre-commit +17 -0
  63. data/ProjectTox-Core/toxav/Makefile.inc +36 -0
  64. data/ProjectTox-Core/toxav/codec.c +357 -0
  65. data/ProjectTox-Core/toxav/codec.h +116 -0
  66. data/ProjectTox-Core/toxav/msi.c +1949 -0
  67. data/ProjectTox-Core/toxav/msi.h +267 -0
  68. data/ProjectTox-Core/toxav/rtp.c +600 -0
  69. data/ProjectTox-Core/toxav/rtp.h +196 -0
  70. data/ProjectTox-Core/toxav/toxav.c +1148 -0
  71. data/ProjectTox-Core/toxav/toxav.h +389 -0
  72. data/ProjectTox-Core/toxcore/DHT.c +2521 -0
  73. data/ProjectTox-Core/toxcore/DHT.h +412 -0
  74. data/ProjectTox-Core/toxcore/LAN_discovery.c +322 -0
  75. data/ProjectTox-Core/{core → toxcore}/LAN_discovery.h +17 -12
  76. data/ProjectTox-Core/toxcore/Makefile.inc +67 -0
  77. data/ProjectTox-Core/toxcore/Messenger.c +3006 -0
  78. data/ProjectTox-Core/toxcore/Messenger.h +818 -0
  79. data/ProjectTox-Core/toxcore/TCP_client.c +858 -0
  80. data/ProjectTox-Core/toxcore/TCP_client.h +156 -0
  81. data/ProjectTox-Core/toxcore/TCP_server.c +1332 -0
  82. data/ProjectTox-Core/toxcore/TCP_server.h +181 -0
  83. data/ProjectTox-Core/toxcore/assoc.c +1033 -0
  84. data/ProjectTox-Core/toxcore/assoc.h +104 -0
  85. data/ProjectTox-Core/toxcore/crypto_core.c +278 -0
  86. data/ProjectTox-Core/toxcore/crypto_core.h +151 -0
  87. data/ProjectTox-Core/toxcore/friend_requests.c +175 -0
  88. data/ProjectTox-Core/toxcore/friend_requests.h +83 -0
  89. data/ProjectTox-Core/toxcore/group_chats.c +837 -0
  90. data/ProjectTox-Core/toxcore/group_chats.h +199 -0
  91. data/ProjectTox-Core/toxcore/list.c +256 -0
  92. data/ProjectTox-Core/toxcore/list.h +85 -0
  93. data/ProjectTox-Core/toxcore/logger.c +153 -0
  94. data/ProjectTox-Core/toxcore/logger.h +84 -0
  95. data/ProjectTox-Core/toxcore/misc_tools.h +70 -0
  96. data/ProjectTox-Core/toxcore/net_crypto.c +2753 -0
  97. data/ProjectTox-Core/toxcore/net_crypto.h +410 -0
  98. data/ProjectTox-Core/toxcore/network.c +979 -0
  99. data/ProjectTox-Core/toxcore/network.h +367 -0
  100. data/ProjectTox-Core/toxcore/onion.c +540 -0
  101. data/ProjectTox-Core/toxcore/onion.h +150 -0
  102. data/ProjectTox-Core/toxcore/onion_announce.c +433 -0
  103. data/ProjectTox-Core/toxcore/onion_announce.h +139 -0
  104. data/ProjectTox-Core/toxcore/onion_client.c +1347 -0
  105. data/ProjectTox-Core/toxcore/onion_client.h +253 -0
  106. data/ProjectTox-Core/toxcore/ping.c +346 -0
  107. data/ProjectTox-Core/toxcore/ping.h +47 -0
  108. data/ProjectTox-Core/toxcore/ping_array.c +162 -0
  109. data/ProjectTox-Core/toxcore/ping_array.h +75 -0
  110. data/ProjectTox-Core/toxcore/tox.c +940 -0
  111. data/ProjectTox-Core/toxcore/tox.h +734 -0
  112. data/ProjectTox-Core/toxcore/util.c +193 -0
  113. data/ProjectTox-Core/toxcore/util.h +63 -0
  114. data/ProjectTox-Core/toxdns/Makefile.inc +29 -0
  115. data/ProjectTox-Core/toxdns/toxdns.c +238 -0
  116. data/ProjectTox-Core/toxdns/toxdns.h +88 -0
  117. data/ProjectTox-Core/toxencryptsave/Makefile.inc +45 -0
  118. data/ProjectTox-Core/toxencryptsave/toxencryptsave.c +179 -0
  119. data/ProjectTox-Core/toxencryptsave/toxencryptsave.h +74 -0
  120. data/interfaces/libtox.i +2 -6
  121. data/lib/ffi-tox/libtox.rb +406 -28
  122. metadata +124 -46
  123. data/ProjectTox-Core/CMakeLists.txt +0 -50
  124. data/ProjectTox-Core/cmake/FindLIBCONFIG.cmake +0 -15
  125. data/ProjectTox-Core/cmake/FindNaCl.cmake +0 -17
  126. data/ProjectTox-Core/cmake/FindSODIUM.cmake +0 -15
  127. data/ProjectTox-Core/core/CMakeLists.txt +0 -19
  128. data/ProjectTox-Core/core/DHT.c +0 -1104
  129. data/ProjectTox-Core/core/DHT.h +0 -111
  130. data/ProjectTox-Core/core/LAN_discovery.c +0 -79
  131. data/ProjectTox-Core/core/Lossless_UDP.c +0 -755
  132. data/ProjectTox-Core/core/Lossless_UDP.h +0 -106
  133. data/ProjectTox-Core/core/Messenger.c +0 -596
  134. data/ProjectTox-Core/core/Messenger.h +0 -165
  135. data/ProjectTox-Core/core/friend_requests.c +0 -131
  136. data/ProjectTox-Core/core/friend_requests.h +0 -51
  137. data/ProjectTox-Core/core/net_crypto.c +0 -575
  138. data/ProjectTox-Core/core/net_crypto.h +0 -134
  139. data/ProjectTox-Core/core/network.c +0 -205
  140. data/ProjectTox-Core/core/network.h +0 -134
  141. data/ProjectTox-Core/docs/commands.md +0 -25
  142. data/ProjectTox-Core/docs/start_guide.de.md +0 -40
  143. data/ProjectTox-Core/docs/start_guide.md +0 -38
  144. data/ProjectTox-Core/other/CMakeLists.txt +0 -9
  145. data/ProjectTox-Core/testing/CMakeLists.txt +0 -18
  146. data/ProjectTox-Core/testing/DHT_cryptosendfiletest.c +0 -228
  147. data/ProjectTox-Core/testing/DHT_sendfiletest.c +0 -176
  148. data/ProjectTox-Core/testing/Lossless_UDP_testclient.c +0 -214
  149. data/ProjectTox-Core/testing/Lossless_UDP_testserver.c +0 -201
  150. data/ProjectTox-Core/testing/misc_tools.h +0 -29
  151. data/ProjectTox-Core/testing/nTox_win32.c +0 -387
  152. data/ProjectTox-Core/testing/nTox_win32.h +0 -40
  153. data/ProjectTox-Core/testing/rect.py +0 -45
@@ -0,0 +1,85 @@
1
+ /* list.h
2
+ *
3
+ * Simple struct with functions to create a list which associates ids with data
4
+ * -Allows for finding ids associated with data such as IPs or public keys in a short time
5
+ * -Should only be used if there are relatively few add/remove calls to the list
6
+ *
7
+ * Copyright (C) 2014 Tox project All Rights Reserved.
8
+ *
9
+ * This file is part of Tox.
10
+ *
11
+ * Tox is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * Tox is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23
+ *
24
+ */
25
+
26
+ #ifndef LIST_H
27
+ #define LIST_H
28
+
29
+ #include <stdlib.h>
30
+ #include <stdint.h>
31
+ #include <string.h>
32
+
33
+ typedef struct {
34
+ uint32_t n; //number of elements
35
+ uint32_t capacity; //number of elements memory is allocated for
36
+ uint32_t element_size; //size of the elements
37
+ void *data; //array of elements
38
+ int *ids; //array of element ids
39
+ } BS_LIST;
40
+
41
+ /* Initialize a list, element_size is the size of the elements in the list and
42
+ * initial_capacity is the number of elements the memory will be initially allocated for
43
+ *
44
+ * return value:
45
+ * 1 : success
46
+ * 0 : failure
47
+ */
48
+ int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity);
49
+
50
+ /* Free a list initiated with list_init */
51
+ void bs_list_free(BS_LIST *list);
52
+
53
+ /* Retrieve the id of an element in the list
54
+ *
55
+ * return value:
56
+ * >= 0 : id associated with data
57
+ * -1 : failure
58
+ */
59
+ int bs_list_find(const BS_LIST *list, const void *data);
60
+
61
+ /* Add an element with associated id to the list
62
+ *
63
+ * return value:
64
+ * 1 : success
65
+ * 0 : failure (data already in list)
66
+ */
67
+ int bs_list_add(BS_LIST *list, const void *data, int id);
68
+
69
+ /* Remove element from the list
70
+ *
71
+ * return value:
72
+ * 1 : success
73
+ * 0 : failure (element not found or id does not match)
74
+ */
75
+ int bs_list_remove(BS_LIST *list, const void *data, int id);
76
+
77
+ /* Removes the memory overhead
78
+ *
79
+ * return value:
80
+ * 1 : success
81
+ * 0 : failure
82
+ */
83
+ int bs_list_trim(BS_LIST *list);
84
+
85
+ #endif
@@ -0,0 +1,153 @@
1
+ /* logger.c
2
+ *
3
+ * Wrapping logger functions in nice macros
4
+ *
5
+ * Copyright (C) 2013 Tox project All Rights Reserved.
6
+ *
7
+ * This file is part of Tox.
8
+ *
9
+ * Tox is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * Tox is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
+ *
22
+ */
23
+
24
+ #ifdef HAVE_CONFIG_H
25
+ #include "config.h"
26
+ #endif /* HAVE_CONFIG_H */
27
+
28
+ #include "logger.h"
29
+
30
+ #ifdef LOGGING
31
+
32
+ #include "network.h" /* for time */
33
+
34
+ #include <stdio.h>
35
+ #include <errno.h>
36
+ #include <stdlib.h>
37
+ #include <stdarg.h>
38
+ #include <inttypes.h>
39
+ #include <time.h>
40
+
41
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
42
+ #define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
43
+ #endif
44
+
45
+ static struct logger_config {
46
+ FILE *log_file;
47
+ LoggerLevel level;
48
+ uint64_t start_time; /* Time when lib loaded */
49
+ }
50
+ logger = {
51
+ NULL,
52
+ DEBUG,
53
+ 0
54
+ };
55
+
56
+ void __attribute__((destructor)) terminate_logger()
57
+ {
58
+ if ( !logger.log_file ) return;
59
+
60
+ time_t tim = time(NULL);
61
+
62
+ logger_write(ERROR, "\n============== Closing logger [%u] ==============\n"
63
+ "Time: %s", logger_get_pid(), asctime(localtime(&tim)));
64
+
65
+ fclose(logger.log_file);
66
+ }
67
+
68
+ unsigned logger_get_pid()
69
+ {
70
+ return
71
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
72
+ GetCurrentProcessId();
73
+ #else
74
+ getpid();
75
+ #endif
76
+ }
77
+
78
+ const char *logger_stringify_level(LoggerLevel level)
79
+ {
80
+ static const char *strings [] = {
81
+ "INFO",
82
+ "DEBUG",
83
+ "WARNING",
84
+ "ERROR"
85
+ };
86
+
87
+ return strings[level];
88
+ }
89
+
90
+
91
+ int logger_init(const char *file_name, LoggerLevel level)
92
+ {
93
+ char *final_l = calloc(sizeof(char), strlen(file_name) + 32);
94
+ sprintf(final_l, "%s"/*.%u"*/, file_name/*, logger_get_pid()*/);
95
+
96
+ if ( logger.log_file ) {
97
+ fprintf(stderr, "Error opening logger name: %s with level %d: file already opened!\n", final_l, level);
98
+ free (final_l);
99
+ return -1;
100
+ }
101
+
102
+ logger.log_file = fopen(final_l, "ab");
103
+
104
+ if ( logger.log_file == NULL ) {
105
+ fprintf(stderr, "Error opening logger file: %s; info: %s\n", final_l, strerror(errno));
106
+
107
+ free (final_l);
108
+ return -1;
109
+ }
110
+
111
+
112
+ logger.level = level;
113
+ logger.start_time = current_time_monotonic();
114
+
115
+
116
+ time_t tim = time(NULL);
117
+ logger_write(ERROR, "\n============== Starting logger [%u] ==============\n"
118
+ "Time: %s", logger_get_pid(), asctime(localtime(&tim)));
119
+
120
+
121
+
122
+ free (final_l);
123
+ return 0;
124
+ }
125
+
126
+
127
+ void logger_write (LoggerLevel level, const char *format, ...)
128
+ {
129
+ if (logger.log_file == NULL) {
130
+ /*fprintf(stderr, "Logger file is NULL!\n");*/
131
+ return;
132
+ }
133
+
134
+ if (logger.level > level) return; /* Don't print some levels xuh */
135
+
136
+ va_list _arg;
137
+ va_start (_arg, format);
138
+ vfprintf (logger.log_file, format, _arg);
139
+ va_end (_arg);
140
+
141
+ fflush(logger.log_file);
142
+ }
143
+
144
+ char *logger_timestr(char *dest, size_t max_size)
145
+ {
146
+ uint64_t diff = (current_time_monotonic() - logger.start_time); /* ms */
147
+ snprintf(dest, max_size, "%"PRIu64"", diff);
148
+
149
+ return dest;
150
+ }
151
+
152
+
153
+ #endif /* LOGGING */
@@ -0,0 +1,84 @@
1
+ /* logger.h
2
+ *
3
+ * Wrapping logger functions in nice macros
4
+ *
5
+ * Copyright (C) 2013 Tox project All Rights Reserved.
6
+ *
7
+ * This file is part of Tox.
8
+ *
9
+ * Tox is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * Tox is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
+ *
22
+ */
23
+
24
+
25
+ #ifndef __TOXLOGGER
26
+ #define __TOXLOGGER
27
+
28
+ #include <string.h>
29
+
30
+ #ifdef LOGGING
31
+
32
+ typedef enum _LoggerLevel {
33
+ INFO,
34
+ DEBUG,
35
+ WARNING,
36
+ ERROR
37
+ } LoggerLevel;
38
+
39
+ /*
40
+ * Set 'level' as the lowest printable level
41
+ */
42
+ int logger_init(const char *file_name, LoggerLevel level);
43
+ const char *logger_stringify_level(LoggerLevel level);
44
+ unsigned logger_get_pid();
45
+ void logger_write (LoggerLevel level, const char *format, ...);
46
+ char *logger_timestr (char *dest, size_t max_size);
47
+
48
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
49
+ #define _SFILE (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
50
+ #else
51
+ #define _SFILE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
52
+ #endif
53
+
54
+ #define WRITE_FORMAT(__LEVEL__, format) char __time__[20]; char* the_str = calloc(sizeof(char), strlen(format)+ 500); sprintf(the_str, "\n[%u] [%s] [%s] [%s:%d %s()] %s", \
55
+ logger_get_pid(), logger_stringify_level(__LEVEL__), logger_timestr(__time__, 20), _SFILE, __LINE__, __func__, format)
56
+
57
+ /* Use these macros */
58
+
59
+ #define LOGGER_INIT(name, level) logger_init(name, level);
60
+ #define LOGGER_INFO(format, ...) do { WRITE_FORMAT(INFO, format); logger_write( INFO, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
61
+ #define LOGGER_DEBUG(format, ...) do { WRITE_FORMAT(DEBUG, format); logger_write( DEBUG, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
62
+ #define LOGGER_WARNING(format, ...) do { WRITE_FORMAT(WARNING, format); logger_write( WARNING, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
63
+ #define LOGGER_ERROR(format, ...) do { WRITE_FORMAT(ERROR, format); logger_write( ERROR, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
64
+
65
+ /* To do some checks or similar only when logging use this */
66
+ #define LOGGER_SCOPE(__SCOPE_DO__) do { __SCOPE_DO__ } while(0)
67
+
68
+ #else
69
+
70
+
71
+ #define LOGGER_INIT(name, level) do {} while(0)
72
+ #define LOGGER_INFO(format, ...) do {} while(0)
73
+ #define LOGGER_DEBUG(format, ...) do {} while(0)
74
+ #define LOGGER_WARNING(format, ...) do {} while(0)
75
+ #define LOGGER_ERROR(format, ...) do {} while(0)
76
+
77
+ #define LOGGER_SCOPE(__SCOPE_DO__) do {} while(0)
78
+
79
+ #endif /* LOGGING */
80
+
81
+
82
+
83
+
84
+ #endif /* __TOXLOGGER */
@@ -0,0 +1,70 @@
1
+ /* misc_tools.h
2
+ *
3
+ * Miscellaneous functions and data structures for doing random things.
4
+ *
5
+ * Copyright (C) 2013 Tox project All Rights Reserved.
6
+ *
7
+ * This file is part of Tox.
8
+ *
9
+ * Tox is free software: you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation, either version 3 of the License, or
12
+ * (at your option) any later version.
13
+ *
14
+ * Tox is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21
+ *
22
+ */
23
+
24
+ #ifndef MISC_TOOLS_H
25
+ #define MISC_TOOLS_H
26
+
27
+ /****************************Algorithms***************************
28
+ * Macro/generic definitions for useful algorithms
29
+ *****************************************************************/
30
+
31
+ /* Creates a new quick_sort implementation for arrays of the specified type.
32
+ * For a type T (eg: int, char), creates a function named T_quick_sort.
33
+ *
34
+ * Quick Sort: Complexity O(nlogn)
35
+ * arr - the array to sort
36
+ * n - the sort index (should be called with n = length(arr))
37
+ * cmpfn - a function that compares two values of type type.
38
+ * Must return -1, 0, 1 for a < b, a == b, and a > b respectively.
39
+ */
40
+ /* Must be called in the header file. */
41
+ #define declare_quick_sort(type) \
42
+ void type##_quick_sort(type *arr, int n, int (*cmpfn)(type, type));
43
+
44
+ /* Must be called in the C file. */
45
+ #define make_quick_sort(type) \
46
+ void type##_quick_sort(type *arr, int n, int (*cmpfn)(type, type)) \
47
+ { \
48
+ if ((n) < 2) \
49
+ return; \
50
+ type _p_ = (arr)[(n) / 2]; \
51
+ type *_l_ = (arr); \
52
+ type *_r_ = (arr) + n - 1; \
53
+ while (_l_ <= _r_) { \
54
+ if (cmpfn(*_l_, _p_) == -1) { \
55
+ ++_l_; \
56
+ continue; \
57
+ } \
58
+ if (cmpfn(*_r_, _p_) == 1) { \
59
+ --_r_; \
60
+ continue; \
61
+ } \
62
+ type _t_ = *_l_; \
63
+ *_l_++ = *_r_; \
64
+ *_r_-- = _t_; \
65
+ } \
66
+ type##_quick_sort((arr), _r_ - (arr) + 1, cmpfn); \
67
+ type##_quick_sort(_l_, (arr) + n - _l_, cmpfn); \
68
+ }
69
+
70
+ #endif // MISC_TOOLS_H
@@ -0,0 +1,2753 @@
1
+ /* net_crypto.c
2
+ *
3
+ * Functions for the core network crypto.
4
+ * See also: http://wiki.tox.im/index.php/DHT
5
+ *
6
+ * NOTE: This code has to be perfect. We don't mess around with encryption.
7
+ *
8
+ * Copyright (C) 2013 Tox project All Rights Reserved.
9
+ *
10
+ * This file is part of Tox.
11
+ *
12
+ * Tox is free software: you can redistribute it and/or modify
13
+ * it under the terms of the GNU General Public License as published by
14
+ * the Free Software Foundation, either version 3 of the License, or
15
+ * (at your option) any later version.
16
+ *
17
+ * Tox is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
24
+ *
25
+ */
26
+
27
+ #ifdef HAVE_CONFIG_H
28
+ #include "config.h"
29
+ #endif
30
+
31
+ #include "net_crypto.h"
32
+ #include "util.h"
33
+ #include "math.h"
34
+ #include "logger.h"
35
+
36
+ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id)
37
+ {
38
+ return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
39
+ }
40
+
41
+ /* cookie timeout in seconds */
42
+ #define COOKIE_TIMEOUT 10
43
+ #define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2)
44
+ #define COOKIE_CONTENTS_LENGTH (sizeof(uint64_t) + COOKIE_DATA_LENGTH)
45
+ #define COOKIE_LENGTH (crypto_box_NONCEBYTES + COOKIE_CONTENTS_LENGTH + crypto_box_MACBYTES)
46
+
47
+ #define COOKIE_REQUEST_PLAIN_LENGTH (COOKIE_DATA_LENGTH + sizeof(uint64_t))
48
+ #define COOKIE_REQUEST_LENGTH (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES)
49
+ #define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + sizeof(uint64_t) + crypto_box_MACBYTES)
50
+
51
+ /* Create a cookie request packet and put it in packet.
52
+ * dht_public_key is the dht public key of the other
53
+ *
54
+ * packet must be of size COOKIE_REQUEST_LENGTH or bigger.
55
+ *
56
+ * return -1 on failure.
57
+ * return COOKIE_REQUEST_LENGTH on success.
58
+ */
59
+ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number,
60
+ uint8_t *shared_key)
61
+ {
62
+ uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH];
63
+ uint8_t padding[crypto_box_PUBLICKEYBYTES] = {0};
64
+
65
+ memcpy(plain, c->self_public_key, crypto_box_PUBLICKEYBYTES);
66
+ memcpy(plain + crypto_box_PUBLICKEYBYTES, padding, crypto_box_PUBLICKEYBYTES);
67
+ memcpy(plain + (crypto_box_PUBLICKEYBYTES * 2), &number, sizeof(uint64_t));
68
+
69
+ DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key);
70
+ uint8_t nonce[crypto_box_NONCEBYTES];
71
+ new_nonce(nonce);
72
+ packet[0] = NET_PACKET_COOKIE_REQUEST;
73
+ memcpy(packet + 1, c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
74
+ memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
75
+ int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
76
+ packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
77
+
78
+ if (len != COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES)
79
+ return -1;
80
+
81
+ return (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + len);
82
+ }
83
+
84
+ /* Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
85
+ *
86
+ * return -1 on failure.
87
+ * return 0 on success.
88
+ */
89
+ static int create_cookie(uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key)
90
+ {
91
+ uint8_t contents[COOKIE_CONTENTS_LENGTH];
92
+ uint64_t temp_time = unix_time();
93
+ memcpy(contents, &temp_time, sizeof(temp_time));
94
+ memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
95
+ new_nonce(cookie);
96
+ int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + crypto_box_NONCEBYTES);
97
+
98
+ if (len != COOKIE_LENGTH - crypto_box_NONCEBYTES)
99
+ return -1;
100
+
101
+ return 0;
102
+ }
103
+
104
+ /* Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
105
+ *
106
+ * return -1 on failure.
107
+ * return 0 on success.
108
+ */
109
+ static int open_cookie(uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key)
110
+ {
111
+ uint8_t contents[COOKIE_CONTENTS_LENGTH];
112
+ int len = decrypt_data_symmetric(encryption_key, cookie, cookie + crypto_box_NONCEBYTES,
113
+ COOKIE_LENGTH - crypto_box_NONCEBYTES, contents);
114
+
115
+ if (len != sizeof(contents))
116
+ return -1;
117
+
118
+ uint64_t cookie_time;
119
+ memcpy(&cookie_time, contents, sizeof(cookie_time));
120
+ uint64_t temp_time = unix_time();
121
+
122
+ if (cookie_time + COOKIE_TIMEOUT < temp_time || temp_time < cookie_time)
123
+ return -1;
124
+
125
+ memcpy(bytes, contents + sizeof(cookie_time), COOKIE_DATA_LENGTH);
126
+ return 0;
127
+ }
128
+
129
+
130
+ /* Create a cookie response packet and put it in packet.
131
+ * request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes.
132
+ * packet must be of size COOKIE_RESPONSE_LENGTH or bigger.
133
+ *
134
+ * return -1 on failure.
135
+ * return COOKIE_RESPONSE_LENGTH on success.
136
+ */
137
+ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain,
138
+ const uint8_t *shared_key, const uint8_t *dht_public_key)
139
+ {
140
+ uint8_t cookie_plain[COOKIE_DATA_LENGTH];
141
+ memcpy(cookie_plain, request_plain, crypto_box_PUBLICKEYBYTES);
142
+ memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, dht_public_key, crypto_box_PUBLICKEYBYTES);
143
+ uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
144
+
145
+ if (create_cookie(plain, cookie_plain, c->secret_symmetric_key) != 0)
146
+ return -1;
147
+
148
+ memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
149
+ packet[0] = NET_PACKET_COOKIE_RESPONSE;
150
+ new_nonce(packet + 1);
151
+ int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + crypto_box_NONCEBYTES);
152
+
153
+ if (len != COOKIE_RESPONSE_LENGTH - (1 + crypto_box_NONCEBYTES))
154
+ return -1;
155
+
156
+ return COOKIE_RESPONSE_LENGTH;
157
+ }
158
+
159
+ /* Handle the cookie request packet of length length.
160
+ * Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH)
161
+ * Put the key used to decrypt the request into shared_key (of size crypto_box_BEFORENMBYTES) for use in the response.
162
+ *
163
+ * return -1 on failure.
164
+ * return 0 on success.
165
+ */
166
+ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key,
167
+ uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
168
+ {
169
+ if (length != COOKIE_REQUEST_LENGTH)
170
+ return -1;
171
+
172
+ memcpy(dht_public_key, packet + 1, crypto_box_PUBLICKEYBYTES);
173
+ DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key);
174
+ int len = decrypt_data_symmetric(shared_key, packet + 1 + crypto_box_PUBLICKEYBYTES,
175
+ packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES,
176
+ request_plain);
177
+
178
+ if (len != COOKIE_REQUEST_PLAIN_LENGTH)
179
+ return -1;
180
+
181
+ return 0;
182
+ }
183
+
184
+ /* Handle the cookie request packet (for raw UDP)
185
+ */
186
+ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
187
+ {
188
+ Net_Crypto *c = object;
189
+ uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
190
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
191
+ uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
192
+
193
+ if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0)
194
+ return 1;
195
+
196
+ uint8_t data[COOKIE_RESPONSE_LENGTH];
197
+
198
+ if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
199
+ return 1;
200
+
201
+ if ((uint32_t)sendpacket(c->dht->net, source, data, sizeof(data)) != sizeof(data))
202
+ return 1;
203
+
204
+ return 0;
205
+ }
206
+
207
+ /* Handle the cookie request packet (for TCP)
208
+ */
209
+ static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id,
210
+ const uint8_t *packet, uint32_t length)
211
+ {
212
+ uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
213
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
214
+ uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
215
+
216
+ if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0)
217
+ return -1;
218
+
219
+ uint8_t data[COOKIE_RESPONSE_LENGTH];
220
+
221
+ if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
222
+ return -1;
223
+
224
+ if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
225
+ return -1;
226
+
227
+ return 0;
228
+ }
229
+
230
+ /* Handle the cookie request packet (for TCP oob packets)
231
+ */
232
+ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con,
233
+ const uint8_t *dht_public_key, const uint8_t *packet, uint32_t length)
234
+ {
235
+ uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
236
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
237
+ uint8_t dht_public_key_temp[crypto_box_PUBLICKEYBYTES];
238
+
239
+ if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0)
240
+ return -1;
241
+
242
+ if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0)
243
+ return -1;
244
+
245
+ uint8_t data[COOKIE_RESPONSE_LENGTH];
246
+
247
+ if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
248
+ return -1;
249
+
250
+ if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1)
251
+ return -1;
252
+
253
+ return 0;
254
+ }
255
+
256
+ /* Handle a cookie response packet of length encrypted with shared_key.
257
+ * put the cookie in the response in cookie
258
+ *
259
+ * cookie must be of length COOKIE_LENGTH.
260
+ *
261
+ * return -1 on failure.
262
+ * return COOKIE_LENGTH on success.
263
+ */
264
+ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint32_t length,
265
+ const uint8_t *shared_key)
266
+ {
267
+ if (length != COOKIE_RESPONSE_LENGTH)
268
+ return -1;
269
+
270
+ uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
271
+ int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
272
+ length - (1 + crypto_box_NONCEBYTES), plain);
273
+
274
+ if (len != sizeof(plain))
275
+ return -1;
276
+
277
+ memcpy(cookie, plain, COOKIE_LENGTH);
278
+ memcpy(number, plain + COOKIE_LENGTH, sizeof(uint64_t));
279
+ return COOKIE_LENGTH;
280
+ }
281
+
282
+ #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH + crypto_box_MACBYTES)
283
+
284
+ /* Create a handshake packet and put it in packet.
285
+ * cookie must be COOKIE_LENGTH bytes.
286
+ * packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
287
+ *
288
+ * return -1 on failure.
289
+ * return HANDSHAKE_PACKET_LENGTH on success.
290
+ */
291
+ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce,
292
+ const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey)
293
+ {
294
+ uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
295
+ memcpy(plain, nonce, crypto_box_NONCEBYTES);
296
+ memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES);
297
+ crypto_hash_sha512(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, cookie, COOKIE_LENGTH);
298
+ uint8_t cookie_plain[COOKIE_DATA_LENGTH];
299
+ memcpy(cookie_plain, peer_real_pk, crypto_box_PUBLICKEYBYTES);
300
+ memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, peer_dht_pubkey, crypto_box_PUBLICKEYBYTES);
301
+
302
+ if (create_cookie(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, cookie_plain,
303
+ c->secret_symmetric_key) != 0)
304
+ return -1;
305
+
306
+ new_nonce(packet + 1 + COOKIE_LENGTH);
307
+ int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
308
+ packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES);
309
+
310
+ if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES))
311
+ return -1;
312
+
313
+ packet[0] = NET_PACKET_CRYPTO_HS;
314
+ memcpy(packet + 1, cookie, COOKIE_LENGTH);
315
+
316
+ return HANDSHAKE_PACKET_LENGTH;
317
+ }
318
+
319
+ /* Handle a crypto handshake packet of length.
320
+ * put the nonce contained in the packet in nonce,
321
+ * the session public key in session_pk
322
+ * the real public key of the peer in peer_real_pk
323
+ * the dht public key of the peer in dht_public_key and
324
+ * the cookie inside the encrypted part of the packet in cookie.
325
+ *
326
+ * if expected_real_pk isn't NULL it denotes the real public key
327
+ * the packet should be from.
328
+ *
329
+ * nonce must be at least crypto_box_NONCEBYTES
330
+ * session_pk must be at least crypto_box_PUBLICKEYBYTES
331
+ * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES
332
+ * cookie must be at least COOKIE_LENGTH
333
+ *
334
+ * return -1 on failure.
335
+ * return 0 on success.
336
+ */
337
+ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
338
+ uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint32_t length, const uint8_t *expected_real_pk)
339
+ {
340
+ if (length != HANDSHAKE_PACKET_LENGTH)
341
+ return -1;
342
+
343
+ uint8_t cookie_plain[COOKIE_DATA_LENGTH];
344
+
345
+ if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0)
346
+ return -1;
347
+
348
+ if (expected_real_pk)
349
+ if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0)
350
+ return -1;
351
+
352
+ uint8_t cookie_hash[crypto_hash_sha512_BYTES];
353
+ crypto_hash_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
354
+
355
+ uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
356
+ int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
357
+ packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
358
+ HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
359
+
360
+ if (len != sizeof(plain))
361
+ return -1;
362
+
363
+ if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0)
364
+ return -1;
365
+
366
+ memcpy(nonce, plain, crypto_box_NONCEBYTES);
367
+ memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
368
+ memcpy(cookie, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, COOKIE_LENGTH);
369
+ memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES);
370
+ memcpy(dht_public_key, cookie_plain + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
371
+ return 0;
372
+ }
373
+
374
+
375
+ static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id)
376
+ {
377
+ if (crypt_connection_id_not_valid(c, crypt_connection_id))
378
+ return 0;
379
+
380
+ return &c->crypto_connections[crypt_connection_id];
381
+ }
382
+
383
+
384
+ /* Sends a packet to the peer using the fastest route.
385
+ *
386
+ * return -1 on failure.
387
+ * return 0 on success.
388
+ */
389
+ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
390
+ {
391
+ //TODO TCP, etc...
392
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
393
+
394
+ if (conn == 0)
395
+ return -1;
396
+
397
+ int direct_send_attempt = 0;
398
+
399
+ //TODO: on bad networks, direct connections might not last indefinitely.
400
+ if (conn->ip_port.ip.family != 0) {
401
+ uint8_t direct_connected = 0;
402
+ crypto_connection_status(c, crypt_connection_id, &direct_connected);
403
+
404
+ if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
405
+ return 0;
406
+
407
+ //TODO: a better way of sending packets directly to confirm the others ip.
408
+ if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
409
+ if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
410
+ direct_send_attempt = 1;
411
+ }
412
+
413
+ }
414
+
415
+ //TODO: detect and kill bad relays.
416
+ uint32_t i;
417
+
418
+ unsigned int r = crypt_connection_id;
419
+
420
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
421
+ pthread_mutex_lock(&c->tcp_mutex);
422
+
423
+ int ret = 0;
424
+
425
+ if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
426
+ ret = send_data(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->con_number_tcp[(i + r) % MAX_TCP_CONNECTIONS],
427
+ data, length);
428
+ }
429
+
430
+ pthread_mutex_unlock(&c->tcp_mutex);
431
+
432
+ if (ret == 1) {
433
+ return 0;
434
+ }
435
+ }
436
+
437
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
438
+ pthread_mutex_lock(&c->tcp_mutex);
439
+
440
+ int ret = 0;
441
+
442
+ if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_INVISIBLE) {
443
+ ret = send_oob_packet(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->dht_public_key, data, length);
444
+ }
445
+
446
+ pthread_mutex_unlock(&c->tcp_mutex);
447
+
448
+ if (ret == 1) {
449
+ return 0;
450
+ }
451
+ }
452
+
453
+ if (direct_send_attempt) {
454
+ return 0;
455
+ }
456
+
457
+ return -1;
458
+ }
459
+
460
+ /** START: Array Related functions **/
461
+
462
+
463
+ /* Return number of packets in array
464
+ * Note that holes are counted too.
465
+ */
466
+ static uint32_t num_packets_array(const Packets_Array *array)
467
+ {
468
+ return array->buffer_end - array->buffer_start;
469
+ }
470
+
471
+ /* Add data with packet number to array.
472
+ *
473
+ * return -1 on failure.
474
+ * return 0 on success.
475
+ */
476
+ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data)
477
+ {
478
+ if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE)
479
+ return -1;
480
+
481
+ uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
482
+
483
+ if (array->buffer[num])
484
+ return -1;
485
+
486
+ Packet_Data *new_d = malloc(sizeof(Packet_Data));
487
+
488
+ if (new_d == NULL)
489
+ return -1;
490
+
491
+ memcpy(new_d, data, sizeof(Packet_Data));
492
+ array->buffer[num] = new_d;
493
+
494
+ if ((number - array->buffer_start) >= (array->buffer_end - array->buffer_start))
495
+ array->buffer_end = number + 1;
496
+
497
+ return 0;
498
+ }
499
+
500
+ /* Get pointer of data with packet number.
501
+ *
502
+ * return -1 on failure.
503
+ * return 0 if data at number is empty.
504
+ * return 1 if data pointer was put in data.
505
+ */
506
+ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint32_t number)
507
+ {
508
+ uint32_t num_spots = array->buffer_end - array->buffer_start;
509
+
510
+ if (array->buffer_end - number > num_spots || number - array->buffer_start >= num_spots)
511
+ return -1;
512
+
513
+ uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
514
+
515
+ if (!array->buffer[num])
516
+ return 0;
517
+
518
+ *data = array->buffer[num];
519
+ return 1;
520
+ }
521
+
522
+ /* Add data to end of array.
523
+ *
524
+ * return -1 on failure.
525
+ * return packet number on success.
526
+ */
527
+ static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *data)
528
+ {
529
+ if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE)
530
+ return -1;
531
+
532
+ Packet_Data *new_d = malloc(sizeof(Packet_Data));
533
+
534
+ if (new_d == NULL)
535
+ return -1;
536
+
537
+ memcpy(new_d, data, sizeof(Packet_Data));
538
+ uint32_t id = array->buffer_end;
539
+ array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d;
540
+ ++array->buffer_end;
541
+ return id;
542
+ }
543
+
544
+ /* Read data from begginning of array.
545
+ *
546
+ * return -1 on failure.
547
+ * return packet number on success.
548
+ */
549
+ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
550
+ {
551
+ if (array->buffer_end == array->buffer_start)
552
+ return -1;
553
+
554
+ uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE;
555
+
556
+ if (!array->buffer[num])
557
+ return -1;
558
+
559
+ memcpy(data, array->buffer[num], sizeof(Packet_Data));
560
+ uint32_t id = array->buffer_start;
561
+ ++array->buffer_start;
562
+ free(array->buffer[num]);
563
+ array->buffer[num] = NULL;
564
+ return id;
565
+ }
566
+
567
+ /* Delete all packets in array before number (but not number)
568
+ *
569
+ * return -1 on failure.
570
+ * return 0 on success
571
+ */
572
+ static int clear_buffer_until(Packets_Array *array, uint32_t number)
573
+ {
574
+ uint32_t num_spots = array->buffer_end - array->buffer_start;
575
+
576
+ if (array->buffer_end - number >= num_spots || number - array->buffer_start > num_spots)
577
+ return -1;
578
+
579
+ uint32_t i;
580
+
581
+ for (i = array->buffer_start; i != number; ++i) {
582
+ uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
583
+
584
+ if (array->buffer[num]) {
585
+ free(array->buffer[num]);
586
+ array->buffer[num] = NULL;
587
+ }
588
+ }
589
+
590
+ array->buffer_start = i;
591
+ return 0;
592
+ }
593
+
594
+ /* Set array buffer end to number.
595
+ *
596
+ * return -1 on failure.
597
+ * return 0 on success.
598
+ */
599
+ static int set_buffer_end(Packets_Array *array, uint32_t number)
600
+ {
601
+ if ((number - array->buffer_start) > CRYPTO_PACKET_BUFFER_SIZE)
602
+ return -1;
603
+
604
+ if ((number - array->buffer_end) > CRYPTO_PACKET_BUFFER_SIZE)
605
+ return -1;
606
+
607
+ array->buffer_end = number;
608
+ return 0;
609
+ }
610
+
611
+ /* Create a packet request packet from recv_array and send_buffer_end into
612
+ * data of length.
613
+ *
614
+ * return -1 on failure.
615
+ * return length of packet on success.
616
+ */
617
+ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets_Array *recv_array)
618
+ {
619
+ if (length == 0)
620
+ return -1;
621
+
622
+ data[0] = PACKET_ID_REQUEST;
623
+
624
+ uint16_t cur_len = 1;
625
+
626
+ if (recv_array->buffer_start == recv_array->buffer_end)
627
+ return cur_len;
628
+
629
+ if (length <= cur_len)
630
+ return cur_len;
631
+
632
+ uint32_t i, n = 1;
633
+
634
+ for (i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) {
635
+ uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
636
+
637
+ if (!recv_array->buffer[num]) {
638
+ data[cur_len] = n;
639
+ n = 0;
640
+ ++cur_len;
641
+
642
+ if (length <= cur_len)
643
+ return cur_len;
644
+
645
+ } else if (n == 255) {
646
+ data[cur_len] = 0;
647
+ n = 0;
648
+ ++cur_len;
649
+
650
+ if (length <= cur_len)
651
+ return cur_len;
652
+ }
653
+
654
+ ++n;
655
+ }
656
+
657
+ return cur_len;
658
+ }
659
+
660
+ /* Handle a request data packet.
661
+ * Remove all the packets the other received from the array.
662
+ *
663
+ * return -1 on failure.
664
+ * return number of requested packets on success.
665
+ */
666
+ static int handle_request_packet(Packets_Array *send_array, const uint8_t *data, uint16_t length)
667
+ {
668
+ if (length < 1)
669
+ return -1;
670
+
671
+ if (data[0] != PACKET_ID_REQUEST)
672
+ return -1;
673
+
674
+ if (length == 1)
675
+ return 0;
676
+
677
+ ++data;
678
+ --length;
679
+
680
+ uint32_t i, n = 1;
681
+ uint32_t requested = 0;
682
+
683
+ for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
684
+ if (length == 0)
685
+ break;
686
+
687
+ uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
688
+
689
+ if (n == data[0]) {
690
+ if (send_array->buffer[num]) {
691
+ send_array->buffer[num]->time = 0;
692
+ }
693
+
694
+ ++data;
695
+ --length;
696
+ n = 0;
697
+ ++requested;
698
+ } else {
699
+ free(send_array->buffer[num]);
700
+ send_array->buffer[num] = NULL;
701
+ }
702
+
703
+ if (n == 255) {
704
+ n = 1;
705
+
706
+ if (data[0] != 0)
707
+ return -1;
708
+
709
+ ++data;
710
+ --length;
711
+ } else {
712
+ ++n;
713
+ }
714
+ }
715
+
716
+ return requested;
717
+ }
718
+
719
+ /** END: Array Related functions **/
720
+
721
+ #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
722
+
723
+ /* Creates and sends a data packet to the peer using the fastest route.
724
+ *
725
+ * return -1 on failure.
726
+ * return 0 on success.
727
+ */
728
+ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
729
+ {
730
+ if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE)
731
+ return -1;
732
+
733
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
734
+
735
+ if (conn == 0)
736
+ return -1;
737
+
738
+ pthread_mutex_lock(&conn->mutex);
739
+ uint8_t packet[1 + sizeof(uint16_t) + length + crypto_box_MACBYTES];
740
+ packet[0] = NET_PACKET_CRYPTO_DATA;
741
+ memcpy(packet + 1, conn->sent_nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t));
742
+ int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
743
+
744
+ if (len + 1 + sizeof(uint16_t) != sizeof(packet)) {
745
+ pthread_mutex_unlock(&conn->mutex);
746
+ return -1;
747
+ }
748
+
749
+ increment_nonce(conn->sent_nonce);
750
+ int ret = send_packet_to(c, crypt_connection_id, packet, sizeof(packet));
751
+ pthread_mutex_unlock(&conn->mutex);
752
+ return ret;
753
+ }
754
+
755
+ /* Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
756
+ *
757
+ * return -1 on failure.
758
+ * return 0 on success.
759
+ */
760
+ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
761
+ const uint8_t *data, uint32_t length)
762
+ {
763
+ if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
764
+ return -1;
765
+
766
+ num = htonl(num);
767
+ buffer_start = htonl(buffer_start);
768
+ uint16_t padding_length = (MAX_CRYPTO_DATA_SIZE - length) % CRYPTO_MAX_PADDING;
769
+ uint8_t packet[sizeof(uint32_t) + sizeof(uint32_t) + padding_length + length];
770
+ memcpy(packet, &buffer_start, sizeof(uint32_t));
771
+ memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t));
772
+ memset(packet + (sizeof(uint32_t) * 2), 0, padding_length);
773
+ memcpy(packet + (sizeof(uint32_t) * 2) + padding_length, data, length);
774
+
775
+ return send_data_packet(c, crypt_connection_id, packet, sizeof(packet));
776
+ }
777
+
778
+ /* return -1 if data could not be put in packet queue.
779
+ * return positive packet number if data was put into the queue.
780
+ */
781
+ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length,
782
+ uint8_t congestion_control)
783
+ {
784
+ if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
785
+ return -1;
786
+
787
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
788
+
789
+ if (conn == 0)
790
+ return -1;
791
+
792
+ uint64_t temp_time = current_time_monotonic();
793
+
794
+ /* If last packet send failed, try to send packet again.
795
+ If sending it fails we won't be able to send the new packet. */
796
+ if (conn->maximum_speed_reached) {
797
+ Packet_Data *dt = NULL;
798
+ uint32_t packet_num = conn->send_array.buffer_end - 1;
799
+ int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
800
+
801
+ uint8_t send_failed = 0;
802
+
803
+ if (ret == 1) {
804
+ if (!dt->time) {
805
+ if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
806
+ dt->length) != 0) {
807
+ if (congestion_control) {
808
+ return -1;
809
+ } else {
810
+ send_failed = 1;
811
+ }
812
+ } else {
813
+ dt->time = temp_time;
814
+ }
815
+ }
816
+ }
817
+
818
+ if (!send_failed) {
819
+ conn->maximum_speed_reached = 0;
820
+ }
821
+ }
822
+
823
+ Packet_Data dt;
824
+ dt.time = 0;
825
+ dt.length = length;
826
+ memcpy(dt.data, data, length);
827
+ int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
828
+
829
+ if (packet_num == -1)
830
+ return -1;
831
+
832
+ if (!congestion_control && conn->maximum_speed_reached) {
833
+ return packet_num;
834
+ }
835
+
836
+ if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) == 0) {
837
+ Packet_Data *dt1 = NULL;
838
+ get_data_pointer(&conn->send_array, &dt1, packet_num);
839
+ dt1->time = temp_time;
840
+ } else {
841
+ conn->maximum_speed_reached = 1;
842
+ LOGGER_ERROR("send_data_packet failed\n");
843
+ }
844
+
845
+ return packet_num;
846
+ }
847
+
848
+ /* Get the lowest 2 bytes from the nonce and convert
849
+ * them to host byte format before returning them.
850
+ */
851
+ static uint16_t get_nonce_uint16(const uint8_t *nonce)
852
+ {
853
+ uint16_t num;
854
+ memcpy(&num, nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t));
855
+ return ntohs(num);
856
+ }
857
+
858
+ #define DATA_NUM_THRESHOLD 21845
859
+
860
+ /* Handle a data packet.
861
+ * Decrypt packet of length and put it into data.
862
+ * data must be at least MAX_DATA_DATA_PACKET_SIZE big.
863
+ *
864
+ * return -1 on failure.
865
+ * return length of data on success.
866
+ */
867
+ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet,
868
+ uint16_t length)
869
+ {
870
+ if (length <= (1 + sizeof(uint16_t) + crypto_box_MACBYTES) || length > MAX_CRYPTO_PACKET_SIZE)
871
+ return -1;
872
+
873
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
874
+
875
+ if (conn == 0)
876
+ return -1;
877
+
878
+ uint8_t nonce[crypto_box_NONCEBYTES];
879
+ memcpy(nonce, conn->recv_nonce, crypto_box_NONCEBYTES);
880
+ uint16_t num_cur_nonce = get_nonce_uint16(nonce);
881
+ uint16_t num;
882
+ memcpy(&num, packet + 1, sizeof(uint16_t));
883
+ num = ntohs(num);
884
+ uint16_t diff = num - num_cur_nonce;
885
+ increment_nonce_number(nonce, diff);
886
+ int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
887
+ length - (1 + sizeof(uint16_t)), data);
888
+
889
+ if ((unsigned int)len != length - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
890
+ return -1;
891
+
892
+ if (diff > DATA_NUM_THRESHOLD * 2) {
893
+ increment_nonce_number(conn->recv_nonce, DATA_NUM_THRESHOLD);
894
+ }
895
+
896
+ return len;
897
+ }
898
+
899
+ /* Send a request packet.
900
+ *
901
+ * return -1 on failure.
902
+ * return 0 on success.
903
+ */
904
+ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
905
+ {
906
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
907
+
908
+ if (conn == 0)
909
+ return -1;
910
+
911
+ uint8_t data[MAX_CRYPTO_DATA_SIZE];
912
+ int len = generate_request_packet(data, sizeof(data), &conn->recv_array);
913
+
914
+ if (len == -1)
915
+ return -1;
916
+
917
+ return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, data,
918
+ len);
919
+ }
920
+
921
+ /* Send up to max num previously requested data packets.
922
+ *
923
+ * return -1 on failure.
924
+ * return number of packets sent on success.
925
+ */
926
+ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num)
927
+ {
928
+ if (max_num == 0)
929
+ return -1;
930
+
931
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
932
+
933
+ if (conn == 0)
934
+ return -1;
935
+
936
+ uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array);
937
+
938
+ for (i = 0; i < array_size; ++i) {
939
+ Packet_Data *dt;
940
+ uint32_t packet_num = (i + conn->send_array.buffer_start);
941
+ int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
942
+
943
+ if (ret == -1) {
944
+ return -1;
945
+ } else if (ret == 0) {
946
+ continue;
947
+ }
948
+
949
+ if (dt->time != 0) {
950
+ continue;
951
+ }
952
+
953
+ dt->time = current_time_monotonic();
954
+
955
+ if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
956
+ dt->length) == 0)
957
+ ++num_sent;
958
+
959
+ if (num_sent >= max_num)
960
+ break;
961
+ }
962
+
963
+ return num_sent;
964
+ }
965
+
966
+
967
+ /* Add a new temp packet to send repeatedly.
968
+ *
969
+ * return -1 on failure.
970
+ * return 0 on success.
971
+ */
972
+ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
973
+ {
974
+ if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
975
+ return -1;
976
+
977
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
978
+
979
+ if (conn == 0)
980
+ return -1;
981
+
982
+ uint8_t *temp_packet = malloc(length);
983
+
984
+ if (temp_packet == 0)
985
+ return -1;
986
+
987
+ if (conn->temp_packet)
988
+ free(conn->temp_packet);
989
+
990
+ memcpy(temp_packet, packet, length);
991
+ conn->temp_packet = temp_packet;
992
+ conn->temp_packet_length = length;
993
+ conn->temp_packet_sent_time = 0;
994
+ conn->temp_packet_num_sent = 0;
995
+ return 0;
996
+ }
997
+
998
+ /* Clear the temp packet.
999
+ *
1000
+ * return -1 on failure.
1001
+ * return 0 on success.
1002
+ */
1003
+ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
1004
+ {
1005
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1006
+
1007
+ if (conn == 0)
1008
+ return -1;
1009
+
1010
+ if (conn->temp_packet)
1011
+ free(conn->temp_packet);
1012
+
1013
+ conn->temp_packet = 0;
1014
+ conn->temp_packet_length = 0;
1015
+ conn->temp_packet_sent_time = 0;
1016
+ conn->temp_packet_num_sent = 0;
1017
+ return 0;
1018
+ }
1019
+
1020
+
1021
+ /* Send the temp packet.
1022
+ *
1023
+ * return -1 on failure.
1024
+ * return 0 on success.
1025
+ */
1026
+ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
1027
+ {
1028
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1029
+
1030
+ if (conn == 0)
1031
+ return -1;
1032
+
1033
+ if (!conn->temp_packet)
1034
+ return -1;
1035
+
1036
+ if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0)
1037
+ return -1;
1038
+
1039
+ conn->temp_packet_sent_time = current_time_monotonic();
1040
+ ++conn->temp_packet_num_sent;
1041
+ return 0;
1042
+ }
1043
+
1044
+ /* Create a handshake packet and set it as a temp packet.
1045
+ * cookie must be COOKIE_LENGTH.
1046
+ *
1047
+ * return -1 on failure.
1048
+ * return 0 on success.
1049
+ */
1050
+ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
1051
+ const uint8_t *dht_public_key)
1052
+ {
1053
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1054
+
1055
+ if (conn == 0)
1056
+ return -1;
1057
+
1058
+ uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH];
1059
+
1060
+ if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key,
1061
+ conn->public_key, dht_public_key) != sizeof(handshake_packet))
1062
+ return -1;
1063
+
1064
+ if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0)
1065
+ return -1;
1066
+
1067
+ send_temp_packet(c, crypt_connection_id);
1068
+ return 0;
1069
+ }
1070
+
1071
+ /* Send a kill packet.
1072
+ *
1073
+ * return -1 on failure.
1074
+ * return 0 on success.
1075
+ */
1076
+ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
1077
+ {
1078
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1079
+
1080
+ if (conn == 0)
1081
+ return -1;
1082
+
1083
+ uint8_t kill_packet = PACKET_ID_KILL;
1084
+ return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end,
1085
+ &kill_packet, sizeof(kill_packet));
1086
+ }
1087
+
1088
+ /* Handle a received data packet.
1089
+ *
1090
+ * return -1 on failure.
1091
+ * return 0 on success.
1092
+ */
1093
+ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet,
1094
+ uint16_t length)
1095
+ {
1096
+ if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1097
+ return -1;
1098
+
1099
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1100
+
1101
+ if (conn == 0)
1102
+ return -1;
1103
+
1104
+ uint8_t data[MAX_DATA_DATA_PACKET_SIZE];
1105
+ int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
1106
+
1107
+ if (len <= (int)(sizeof(uint32_t) * 2))
1108
+ return -1;
1109
+
1110
+ uint32_t buffer_start, num;
1111
+ memcpy(&buffer_start, data, sizeof(uint32_t));
1112
+ memcpy(&num, data + sizeof(uint32_t), sizeof(uint32_t));
1113
+ buffer_start = ntohl(buffer_start);
1114
+ num = ntohl(num);
1115
+
1116
+ if (buffer_start != conn->send_array.buffer_start && clear_buffer_until(&conn->send_array, buffer_start) != 0)
1117
+ return -1;
1118
+
1119
+ uint8_t *real_data = data + (sizeof(uint32_t) * 2);
1120
+ uint16_t real_length = len - (sizeof(uint32_t) * 2);
1121
+
1122
+ while (real_data[0] == 0) { /* Remove Padding */
1123
+ ++real_data;
1124
+ --real_length;
1125
+
1126
+ if (real_length == 0)
1127
+ return -1;
1128
+ }
1129
+
1130
+ if (real_data[0] == PACKET_ID_KILL) {
1131
+ conn->killed = 1;
1132
+ return 0;
1133
+ }
1134
+
1135
+ if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
1136
+ clear_temp_packet(c, crypt_connection_id);
1137
+ conn->status = CRYPTO_CONN_ESTABLISHED;
1138
+
1139
+ if (conn->connection_status_callback)
1140
+ conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
1141
+ }
1142
+
1143
+ if (real_data[0] == PACKET_ID_REQUEST) {
1144
+ int requested = handle_request_packet(&conn->send_array, real_data, real_length);
1145
+
1146
+ if (requested == -1) {
1147
+ return -1;
1148
+ } else {
1149
+ //TODO?
1150
+ }
1151
+
1152
+ set_buffer_end(&conn->recv_array, num);
1153
+ } else if (real_data[0] >= CRYPTO_RESERVED_PACKETS && real_data[0] < PACKET_ID_LOSSY_RANGE_START) {
1154
+ Packet_Data dt;
1155
+ dt.time = current_time_monotonic();
1156
+ dt.length = real_length;
1157
+ memcpy(dt.data, real_data, real_length);
1158
+
1159
+ if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0)
1160
+ return -1;
1161
+
1162
+ while (read_data_beg_buffer(&conn->recv_array, &dt) != -1) {
1163
+ if (conn->connection_data_callback)
1164
+ conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data,
1165
+ dt.length);
1166
+ }
1167
+
1168
+ /* Packet counter. */
1169
+ ++conn->packet_counter;
1170
+ } else if (real_data[0] >= PACKET_ID_LOSSY_RANGE_START &&
1171
+ real_data[0] < (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE)) {
1172
+
1173
+ if (conn->connection_lossy_data_callback)
1174
+ conn->connection_lossy_data_callback(conn->connection_lossy_data_callback_object,
1175
+ conn->connection_lossy_data_callback_id, real_data, real_length);
1176
+
1177
+ set_buffer_end(&conn->recv_array, num);
1178
+ } else {
1179
+ return -1;
1180
+ }
1181
+
1182
+ return 0;
1183
+ }
1184
+
1185
+ /* Handle a packet that was received for the connection.
1186
+ *
1187
+ * return -1 on failure.
1188
+ * return 0 on success.
1189
+ */
1190
+ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
1191
+ {
1192
+ if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1193
+ return -1;
1194
+
1195
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1196
+
1197
+ if (conn == 0)
1198
+ return -1;
1199
+
1200
+ switch (packet[0]) {
1201
+ case NET_PACKET_COOKIE_RESPONSE: {
1202
+ if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING)
1203
+ return -1;
1204
+
1205
+ uint8_t cookie[COOKIE_LENGTH];
1206
+ uint64_t number;
1207
+
1208
+ if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie))
1209
+ return -1;
1210
+
1211
+ if (number != conn->cookie_request_number)
1212
+ return -1;
1213
+
1214
+ if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0)
1215
+ return -1;
1216
+
1217
+ conn->status = CRYPTO_CONN_HANDSHAKE_SENT;
1218
+ return 0;
1219
+ }
1220
+
1221
+ case NET_PACKET_CRYPTO_HS: {
1222
+ if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
1223
+ || conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
1224
+ uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES];
1225
+ uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
1226
+ uint8_t cookie[COOKIE_LENGTH];
1227
+
1228
+ if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
1229
+ packet, length, conn->public_key) != 0)
1230
+ return -1;
1231
+
1232
+ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1233
+
1234
+ if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1235
+ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1236
+ return -1;
1237
+ }
1238
+
1239
+ conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1240
+ /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1241
+ set_connection_dht_public_key(c, crypt_connection_id, dht_public_key, current_time_monotonic());
1242
+ } else {
1243
+ return -1;
1244
+ }
1245
+
1246
+ return 0;
1247
+ }
1248
+
1249
+ case NET_PACKET_CRYPTO_DATA: {
1250
+ if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) {
1251
+ return handle_data_packet_helper(c, crypt_connection_id, packet, length);
1252
+ } else {
1253
+ return -1;
1254
+ }
1255
+
1256
+ return 0;
1257
+ }
1258
+
1259
+ default: {
1260
+ return -1;
1261
+ }
1262
+ }
1263
+
1264
+ return 0;
1265
+ }
1266
+
1267
+ /* Set the size of the friend list to numfriends.
1268
+ *
1269
+ * return -1 if realloc fails.
1270
+ * return 0 if it succeeds.
1271
+ */
1272
+ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
1273
+ {
1274
+ if (num == 0) {
1275
+ free(c->crypto_connections);
1276
+ c->crypto_connections = NULL;
1277
+ return 0;
1278
+ }
1279
+
1280
+ Crypto_Connection *newcrypto_connections = realloc(c->crypto_connections, num * sizeof(Crypto_Connection));
1281
+
1282
+ if (newcrypto_connections == NULL)
1283
+ return -1;
1284
+
1285
+ c->crypto_connections = newcrypto_connections;
1286
+ return 0;
1287
+ }
1288
+
1289
+
1290
+ /* Create a new empty crypto connection.
1291
+ *
1292
+ * return -1 on failure.
1293
+ * return connection id on success.
1294
+ */
1295
+ static int create_crypto_connection(Net_Crypto *c)
1296
+ {
1297
+ uint32_t i;
1298
+
1299
+ for (i = 0; i < c->crypto_connections_length; ++i) {
1300
+ if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION)
1301
+ return i;
1302
+ }
1303
+
1304
+ while (1) { /* TODO: is this really the best way to do this? */
1305
+ pthread_mutex_lock(&c->connections_mutex);
1306
+
1307
+ if (!c->connection_use_counter) {
1308
+ break;
1309
+ }
1310
+
1311
+ pthread_mutex_unlock(&c->connections_mutex);
1312
+ }
1313
+
1314
+ int id = -1;
1315
+
1316
+ if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == 0) {
1317
+ memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
1318
+ id = c->crypto_connections_length;
1319
+ pthread_mutex_init(&c->crypto_connections[id].mutex, NULL);
1320
+ ++c->crypto_connections_length;
1321
+ }
1322
+
1323
+ pthread_mutex_unlock(&c->connections_mutex);
1324
+ return id;
1325
+ }
1326
+
1327
+ /* Wipe a crypto connection.
1328
+ *
1329
+ * return -1 on failure.
1330
+ * return 0 on success.
1331
+ */
1332
+ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
1333
+ {
1334
+ if (crypt_connection_id_not_valid(c, crypt_connection_id))
1335
+ return -1;
1336
+
1337
+ uint32_t i;
1338
+ pthread_mutex_destroy(&c->crypto_connections[crypt_connection_id].mutex);
1339
+ memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
1340
+
1341
+ for (i = c->crypto_connections_length; i != 0; --i) {
1342
+ if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION)
1343
+ break;
1344
+ }
1345
+
1346
+ if (c->crypto_connections_length != i) {
1347
+ c->crypto_connections_length = i;
1348
+ realloc_cryptoconnection(c, c->crypto_connections_length);
1349
+ }
1350
+
1351
+ return 0;
1352
+ }
1353
+
1354
+ /* Get crypto connection id from public key of peer.
1355
+ *
1356
+ * return -1 if there are no connections like we are looking for.
1357
+ * return id if it found it.
1358
+ */
1359
+ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
1360
+ {
1361
+ uint32_t i;
1362
+
1363
+ for (i = 0; i < c->crypto_connections_length; ++i) {
1364
+ if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION)
1365
+ if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
1366
+ return i;
1367
+ }
1368
+
1369
+ return -1;
1370
+ }
1371
+
1372
+ /* Get crypto connection id from public key of peer.
1373
+ *
1374
+ * return -1 if there are no connections like we are looking for.
1375
+ * return id if it found it.
1376
+ */
1377
+ static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key)
1378
+ {
1379
+ uint32_t i;
1380
+
1381
+ for (i = 0; i < c->crypto_connections_length; ++i) {
1382
+ if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1383
+ if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1384
+ return i;
1385
+ }
1386
+
1387
+ return -1;
1388
+ }
1389
+
1390
+ /* Add a source to the crypto connection.
1391
+ * This is to be used only when we have received a packet from that source.
1392
+ *
1393
+ * return -1 on failure.
1394
+ * return positive number on success.
1395
+ * 0 if source was a direct UDP connection.
1396
+ * TODO
1397
+ */
1398
+ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
1399
+ {
1400
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1401
+
1402
+ if (conn == 0)
1403
+ return -1;
1404
+
1405
+ if (source.ip.family == AF_INET || source.ip.family == AF_INET6) {
1406
+ if (!ipport_equal(&source, &conn->ip_port)) {
1407
+ if (!bs_list_add(&c->ip_port_list, &source, crypt_connection_id))
1408
+ return -1;
1409
+
1410
+ bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
1411
+ conn->ip_port = source;
1412
+ }
1413
+
1414
+ conn->direct_lastrecv_time = current_time_monotonic();
1415
+ return 0;
1416
+ }
1417
+
1418
+ return -1;
1419
+ }
1420
+
1421
+
1422
+ /* Set function to be called when someone requests a new connection to us.
1423
+ *
1424
+ * The set function should return -1 on failure and 0 on success.
1425
+ *
1426
+ * n_c is only valid for the duration of the function call.
1427
+ */
1428
+ void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
1429
+ void *object)
1430
+ {
1431
+ c->new_connection_callback = new_connection_callback;
1432
+ c->new_connection_callback_object = object;
1433
+ }
1434
+
1435
+ /* Handle a handshake packet by someone who wants to initiate a new connection with us.
1436
+ * This calls the callback set by new_connection_handler() if the handshake is ok.
1437
+ *
1438
+ * return -1 on failure.
1439
+ * return 0 on success.
1440
+ */
1441
+ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const uint8_t *data, uint16_t length)
1442
+ {
1443
+ New_Connection n_c;
1444
+ n_c.cookie = malloc(COOKIE_LENGTH);
1445
+
1446
+ if (n_c.cookie == NULL)
1447
+ return -1;
1448
+
1449
+ n_c.source = source;
1450
+ n_c.cookie_length = COOKIE_LENGTH;
1451
+
1452
+ if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
1453
+ n_c.cookie, data, length, 0) != 0) {
1454
+ free(n_c.cookie);
1455
+ return -1;
1456
+ }
1457
+
1458
+ int crypt_connection_id = getcryptconnection_id(c, n_c.public_key);
1459
+
1460
+ if (crypt_connection_id != -1) {
1461
+ int ret = -1;
1462
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1463
+
1464
+ if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) {
1465
+ memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES);
1466
+ memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1467
+ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1468
+
1469
+ crypto_connection_add_source(c, crypt_connection_id, source);
1470
+
1471
+ if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1472
+ conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1473
+ /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1474
+ set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key, current_time_monotonic());
1475
+ ret = 0;
1476
+ }
1477
+ }
1478
+
1479
+ free(n_c.cookie);
1480
+ return ret;
1481
+ }
1482
+
1483
+ int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
1484
+ free(n_c.cookie);
1485
+ return ret;
1486
+ }
1487
+
1488
+ /* Accept a crypto connection.
1489
+ *
1490
+ * return -1 on failure.
1491
+ * return connection id on success.
1492
+ */
1493
+ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1494
+ {
1495
+ if (getcryptconnection_id(c, n_c->public_key) != -1)
1496
+ return -1;
1497
+
1498
+ int crypt_connection_id = create_crypto_connection(c);
1499
+
1500
+ if (crypt_connection_id == -1)
1501
+ return -1;
1502
+
1503
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1504
+
1505
+ if (conn == 0)
1506
+ return -1;
1507
+
1508
+ memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
1509
+ memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES);
1510
+ memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1511
+ random_nonce(conn->sent_nonce);
1512
+ crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1513
+ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1514
+
1515
+ if (n_c->cookie_length != COOKIE_LENGTH)
1516
+ return -1;
1517
+
1518
+ if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0)
1519
+ return -1;
1520
+
1521
+ conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1522
+ /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1523
+ set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
1524
+ conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1525
+ conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1526
+ crypto_connection_add_source(c, crypt_connection_id, n_c->source);
1527
+ return crypt_connection_id;
1528
+ }
1529
+
1530
+ /* Create a crypto connection.
1531
+ * If one to that real public key already exists, return it.
1532
+ *
1533
+ * return -1 on failure.
1534
+ * return connection id on success.
1535
+ */
1536
+ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1537
+ {
1538
+ int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1539
+
1540
+ if (crypt_connection_id != -1)
1541
+ return crypt_connection_id;
1542
+
1543
+ crypt_connection_id = create_crypto_connection(c);
1544
+
1545
+ if (crypt_connection_id == -1)
1546
+ return -1;
1547
+
1548
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1549
+
1550
+ if (conn == 0)
1551
+ return -1;
1552
+
1553
+ memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1554
+ random_nonce(conn->sent_nonce);
1555
+ crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1556
+ conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1557
+ conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1558
+ conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1559
+ return crypt_connection_id;
1560
+ }
1561
+
1562
+ /* Disconnect peer from all associated TCP connections.
1563
+ *
1564
+ * return -1 on failure.
1565
+ * return 0 on success.
1566
+ */
1567
+ static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1568
+ {
1569
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1570
+
1571
+ if (conn == 0)
1572
+ return -1;
1573
+
1574
+ uint32_t i;
1575
+
1576
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1577
+ if (conn->status_tcp[i] != STATUS_TCP_NULL) {
1578
+ pthread_mutex_lock(&c->tcp_mutex);
1579
+ send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1580
+ conn->status_tcp[i] = STATUS_TCP_NULL;
1581
+ conn->con_number_tcp[i] = 0;
1582
+ pthread_mutex_unlock(&c->tcp_mutex);
1583
+ }
1584
+ }
1585
+
1586
+ return 0;
1587
+ }
1588
+
1589
+ /* Connect peer to all associated TCP connections.
1590
+ *
1591
+ * return -1 on failure.
1592
+ * return 0 on success.
1593
+ */
1594
+ static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1595
+ {
1596
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1597
+
1598
+ if (conn == 0)
1599
+ return -1;
1600
+
1601
+ uint32_t i;
1602
+
1603
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1604
+ if (c->tcp_connections[i] == NULL)
1605
+ continue;
1606
+
1607
+ pthread_mutex_lock(&c->tcp_mutex);
1608
+ //TODO check function return?
1609
+ send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1610
+ pthread_mutex_unlock(&c->tcp_mutex);
1611
+ }
1612
+
1613
+ return 0;
1614
+ }
1615
+
1616
+ /* Copy friends DHT public key into dht_key.
1617
+ *
1618
+ * return 0 on failure (no key copied).
1619
+ * return timestamp on success (key copied).
1620
+ */
1621
+ uint64_t get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1622
+ {
1623
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1624
+
1625
+ if (conn == 0)
1626
+ return 0;
1627
+
1628
+ if (conn->dht_public_key_set == 0)
1629
+ return 0;
1630
+
1631
+ memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES);
1632
+ return conn->dht_public_key_timestamp;
1633
+ }
1634
+
1635
+
1636
+ /* Set the DHT public key of the crypto connection.
1637
+ * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
1638
+ * the other peer.
1639
+ *
1640
+ * return -1 on failure.
1641
+ * return 0 on success.
1642
+ */
1643
+ int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key,
1644
+ uint64_t timestamp)
1645
+ {
1646
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1647
+
1648
+ if (conn == 0)
1649
+ return -1;
1650
+
1651
+ if (timestamp <= conn->dht_public_key_timestamp)
1652
+ return -1;
1653
+
1654
+ if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1655
+ return -1;
1656
+
1657
+ if (conn->dht_public_key_set == 1) {
1658
+ disconnect_peer_tcp(c, crypt_connection_id);
1659
+ }
1660
+
1661
+ memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1662
+ conn->dht_public_key_set = 1;
1663
+ conn->dht_public_key_timestamp = timestamp;
1664
+
1665
+ if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1666
+ conn->cookie_request_number = random_64b();
1667
+ uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1668
+
1669
+ if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1670
+ conn->shared_key) != sizeof(cookie_request))
1671
+ return -1;
1672
+
1673
+ if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
1674
+ return -1;
1675
+ }//TODO
1676
+
1677
+ connect_peer_tcp(c, crypt_connection_id);
1678
+ return 0;
1679
+ }
1680
+
1681
+ /* Set the direct ip of the crypto connection.
1682
+ *
1683
+ * return -1 on failure.
1684
+ * return 0 on success.
1685
+ */
1686
+ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1687
+ {
1688
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1689
+
1690
+ if (conn == 0)
1691
+ return -1;
1692
+
1693
+ if (!ipport_equal(&ip_port, &conn->ip_port)) {
1694
+ if (bs_list_add(&c->ip_port_list, &ip_port, crypt_connection_id)) {
1695
+ bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
1696
+ conn->ip_port = ip_port;
1697
+ conn->direct_lastrecv_time = 0;
1698
+ return 0;
1699
+ }
1700
+ }
1701
+
1702
+ return -1;
1703
+ }
1704
+
1705
+ static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
1706
+ {
1707
+ TCP_Client_Connection *TCP_con = object;
1708
+ Net_Crypto *c = TCP_con->net_crypto_pointer;
1709
+
1710
+ int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1711
+
1712
+ if (crypt_connection_id == -1)
1713
+ return -1;
1714
+
1715
+ set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1716
+
1717
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1718
+
1719
+ if (conn == 0)
1720
+ return -1;
1721
+
1722
+ uint32_t location = TCP_con->net_crypto_location;
1723
+
1724
+ if (location >= MAX_TCP_CONNECTIONS)
1725
+ return -1;
1726
+
1727
+ if (c->tcp_connections[location] != TCP_con)
1728
+ return -1;
1729
+
1730
+ conn->con_number_tcp[location] = connection_id;
1731
+ uint32_t i;
1732
+
1733
+ for (i = 0; i < conn->num_tcp_relays; ++i) {
1734
+ if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
1735
+ conn->status_tcp[location] = STATUS_TCP_INVISIBLE;
1736
+ return 0;
1737
+ }
1738
+ }
1739
+
1740
+ conn->status_tcp[location] = STATUS_TCP_OFFLINE;
1741
+ return 0;
1742
+ }
1743
+
1744
+ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1745
+ {
1746
+ TCP_Client_Connection *TCP_con = object;
1747
+ Net_Crypto *c = TCP_con->net_crypto_pointer;
1748
+
1749
+ Crypto_Connection *conn = get_crypto_connection(c, number);
1750
+
1751
+ if (conn == 0)
1752
+ return -1;
1753
+
1754
+ uint32_t location = TCP_con->net_crypto_location;
1755
+
1756
+ if (location >= MAX_TCP_CONNECTIONS)
1757
+ return -1;
1758
+
1759
+ if (c->tcp_connections[location] != TCP_con)
1760
+ return -1;
1761
+
1762
+ if (status == 1) {
1763
+ conn->status_tcp[location] = STATUS_TCP_OFFLINE;
1764
+ } else if (status == 2) {
1765
+ conn->status_tcp[location] = STATUS_TCP_ONLINE;
1766
+ }
1767
+
1768
+ conn->con_number_tcp[location] = connection_id;
1769
+ return 0;
1770
+ }
1771
+
1772
+ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length)
1773
+ {
1774
+
1775
+ if (length == 0)
1776
+ return -1;
1777
+
1778
+ TCP_Client_Connection *TCP_con = object;
1779
+ Net_Crypto *c = TCP_con->net_crypto_pointer;
1780
+
1781
+ if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1782
+ return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length);
1783
+ }
1784
+
1785
+ Crypto_Connection *conn = get_crypto_connection(c, number);
1786
+
1787
+ if (conn == 0)
1788
+ return -1;
1789
+
1790
+ if (handle_packet_connection(c, number, data, length) != 0)
1791
+ return -1;
1792
+
1793
+ //TODO detect and kill bad TCP connections.
1794
+ return 0;
1795
+ }
1796
+
1797
+ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length)
1798
+ {
1799
+ if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1800
+ return -1;
1801
+
1802
+ TCP_Client_Connection *TCP_con = object;
1803
+ Net_Crypto *c = TCP_con->net_crypto_pointer;
1804
+ uint32_t location = TCP_con->net_crypto_location;
1805
+
1806
+ if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1807
+ return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length);
1808
+ }
1809
+
1810
+ int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1811
+
1812
+ if (crypt_connection_id == -1) {
1813
+ IP_Port source;
1814
+ source.ip.family = TCP_FAMILY;
1815
+ source.ip.ip6.uint32[0] = location;
1816
+
1817
+ if (data[0] != NET_PACKET_CRYPTO_HS) {
1818
+ LOGGER_DEBUG("tcp snhappen %u\n", data[0]);
1819
+ return -1;
1820
+ }
1821
+
1822
+ if (handle_new_connection_handshake(c, source, data, length) != 0)
1823
+ return -1;
1824
+
1825
+ return 0;
1826
+ }
1827
+
1828
+ if (handle_packet_connection(c, crypt_connection_id, data, length) != 0)
1829
+ return -1;
1830
+
1831
+ return 0;
1832
+ }
1833
+
1834
+ static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length)
1835
+ {
1836
+ Net_Crypto *c = object;
1837
+
1838
+ if (c->tcp_onion_callback)
1839
+ return c->tcp_onion_callback(c->tcp_onion_callback_object, data, length);
1840
+
1841
+ return 1;
1842
+ }
1843
+
1844
+
1845
+ /* Check if tcp connection to public key can be created.
1846
+ *
1847
+ * return -1 if it can't.
1848
+ * return 0 if it can.
1849
+ */
1850
+ static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key)
1851
+ {
1852
+ uint32_t i;
1853
+
1854
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1855
+ if (c->tcp_connections_new[i] == NULL)
1856
+ continue;
1857
+
1858
+ if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1859
+ return -1;
1860
+ }
1861
+
1862
+ uint32_t num = 0;
1863
+
1864
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1865
+ if (c->tcp_connections[i] == NULL)
1866
+ continue;
1867
+
1868
+ if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1869
+ return -1;
1870
+
1871
+ ++num;
1872
+ }
1873
+
1874
+ if (num == MAX_TCP_CONNECTIONS)
1875
+ return -1;
1876
+
1877
+ return 0;
1878
+ }
1879
+
1880
+ /* Add a tcp relay, associating it to a crypt_connection_id.
1881
+ *
1882
+ * return 0 if it was added.
1883
+ * return -1 if it wasn't.
1884
+ */
1885
+ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, const uint8_t *public_key)
1886
+ {
1887
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1888
+
1889
+ if (conn == 0)
1890
+ return -1;
1891
+
1892
+ if (ip_port.ip.family == TCP_INET) {
1893
+ ip_port.ip.family = AF_INET;
1894
+ } else if (ip_port.ip.family == TCP_INET6) {
1895
+ ip_port.ip.family = AF_INET6;
1896
+ }
1897
+
1898
+ if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
1899
+ return -1;
1900
+
1901
+ uint32_t i;
1902
+
1903
+ for (i = 0; i < conn->num_tcp_relays; ++i) {
1904
+ if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1905
+ conn->tcp_relays[i].ip_port = ip_port;
1906
+ return 0;
1907
+ }
1908
+ }
1909
+
1910
+ if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) {
1911
+ uint16_t index = rand() % MAX_TCP_RELAYS_PEER;
1912
+ conn->tcp_relays[index].ip_port = ip_port;
1913
+ memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES);
1914
+ } else {
1915
+ conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port;
1916
+ memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES);
1917
+ ++conn->num_tcp_relays;
1918
+ }
1919
+
1920
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1921
+ if (c->tcp_connections[i] == NULL)
1922
+ continue;
1923
+
1924
+ if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1925
+ if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
1926
+ conn->status_tcp[i] = STATUS_TCP_INVISIBLE;
1927
+ }
1928
+ }
1929
+
1930
+ return add_tcp_relay(c, ip_port, public_key);
1931
+ }
1932
+
1933
+ /* Add a tcp relay to the array.
1934
+ *
1935
+ * return 0 if it was added.
1936
+ * return -1 if it wasn't.
1937
+ */
1938
+ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
1939
+ {
1940
+ if (ip_port.ip.family == TCP_INET) {
1941
+ ip_port.ip.family = AF_INET;
1942
+ } else if (ip_port.ip.family == TCP_INET6) {
1943
+ ip_port.ip.family = AF_INET6;
1944
+ }
1945
+
1946
+ if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
1947
+ return -1;
1948
+
1949
+ if (tcp_connection_check(c, public_key) != 0)
1950
+ return -1;
1951
+
1952
+ uint32_t i;
1953
+
1954
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1955
+ if (c->tcp_connections_new[i] == NULL) {
1956
+ if (c->proxy_set) {
1957
+ c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
1958
+ &c->proxy_info);
1959
+ } else {
1960
+ c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
1961
+ 0);
1962
+ }
1963
+
1964
+ return 0;
1965
+ }
1966
+ }
1967
+
1968
+ return -1;
1969
+ }
1970
+
1971
+ /* Send an onion packet via a random connected TCP relay.
1972
+ *
1973
+ * return 0 on success.
1974
+ * return -1 on failure.
1975
+ */
1976
+ int send_tcp_onion_request(Net_Crypto *c, const uint8_t *data, uint16_t length)
1977
+ {
1978
+ unsigned int i, r = rand();
1979
+
1980
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1981
+ if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) {
1982
+ pthread_mutex_lock(&c->tcp_mutex);
1983
+ int ret = send_onion_request(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], data, length);
1984
+ pthread_mutex_unlock(&c->tcp_mutex);
1985
+
1986
+ if (ret == 1)
1987
+ return 0;
1988
+ }
1989
+ }
1990
+
1991
+ return -1;
1992
+ }
1993
+
1994
+ /* Set the function to be called when an onion response packet is received by one of the TCP connections.
1995
+ */
1996
+ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
1997
+ uint16_t length), void *object)
1998
+ {
1999
+ c->tcp_onion_callback = tcp_onion_callback;
2000
+ c->tcp_onion_callback_object = object;
2001
+ }
2002
+
2003
+ /* Copy a maximum of num TCP relays we are connected to to tcp_relays.
2004
+ * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
2005
+ *
2006
+ * return number of relays copied to tcp_relays on success.
2007
+ * return 0 on failure.
2008
+ */
2009
+ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
2010
+ {
2011
+ if (num == 0)
2012
+ return 0;
2013
+
2014
+ uint32_t i;
2015
+ uint16_t copied = 0;
2016
+
2017
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2018
+ if (c->tcp_connections[i] != NULL) {
2019
+ memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
2020
+ tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
2021
+
2022
+ if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
2023
+ tcp_relays[copied].ip_port.ip.family = TCP_INET;
2024
+ } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
2025
+ tcp_relays[copied].ip_port.ip.family = TCP_INET6;
2026
+ }
2027
+
2028
+ ++copied;
2029
+
2030
+ if (copied == num)
2031
+ return copied;
2032
+ }
2033
+ }
2034
+
2035
+ return copied;
2036
+ }
2037
+
2038
+ /* Add a connected tcp connection to the tcp_connections array.
2039
+ *
2040
+ * return 0 if it was added.
2041
+ * return -1 if it wasn't.
2042
+ */
2043
+ static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
2044
+ {
2045
+ uint32_t i;
2046
+
2047
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2048
+ if (c->tcp_connections[i] == NULL)
2049
+ break;
2050
+ }
2051
+
2052
+ if (i == MAX_TCP_CONNECTIONS)
2053
+ return -1;
2054
+
2055
+ uint32_t tcp_num = i;
2056
+
2057
+ for (i = 0; i < c->crypto_connections_length; ++i) {
2058
+ Crypto_Connection *conn = get_crypto_connection(c, i);
2059
+
2060
+ if (conn == 0)
2061
+ return -1;
2062
+
2063
+ if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2064
+ continue;
2065
+
2066
+ if (conn->status == CRYPTO_CONN_TIMED_OUT)
2067
+ continue;
2068
+
2069
+ if (conn->dht_public_key_set)
2070
+ if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
2071
+ return -1;
2072
+
2073
+ }
2074
+
2075
+ tcp_con->net_crypto_pointer = c;
2076
+ tcp_con->net_crypto_location = tcp_num;
2077
+ routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
2078
+ routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
2079
+ routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
2080
+ oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
2081
+ onion_response_handler(tcp_con, tcp_onion_callback, c);
2082
+ c->tcp_connections[tcp_num] = tcp_con;
2083
+ return 0;
2084
+ }
2085
+
2086
+ static void do_tcp(Net_Crypto *c)
2087
+ {
2088
+ uint32_t i;
2089
+
2090
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2091
+ if (c->tcp_connections_new[i] == NULL)
2092
+ continue;
2093
+
2094
+ do_TCP_connection(c->tcp_connections_new[i]);
2095
+
2096
+ if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) {
2097
+ pthread_mutex_lock(&c->tcp_mutex);
2098
+ int ret = add_tcp_connected(c, c->tcp_connections_new[i]);
2099
+ pthread_mutex_unlock(&c->tcp_mutex);
2100
+
2101
+ if (ret == 0) {
2102
+ c->tcp_connections_new[i] = NULL;
2103
+ } else {
2104
+ kill_TCP_connection(c->tcp_connections_new[i]);
2105
+ c->tcp_connections_new[i] = NULL;
2106
+ }
2107
+ }
2108
+ }
2109
+
2110
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2111
+ if (c->tcp_connections[i] == NULL)
2112
+ continue;
2113
+
2114
+ pthread_mutex_lock(&c->tcp_mutex);
2115
+ do_TCP_connection(c->tcp_connections[i]);
2116
+ pthread_mutex_unlock(&c->tcp_mutex);
2117
+ }
2118
+ }
2119
+
2120
+ static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
2121
+ {
2122
+ if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2123
+ return;
2124
+
2125
+ if (number >= MAX_TCP_CONNECTIONS)
2126
+ return;
2127
+
2128
+ conn->status_tcp[number] = STATUS_TCP_NULL;
2129
+ conn->con_number_tcp[number] = 0;
2130
+ }
2131
+
2132
+ static void clear_disconnected_tcp(Net_Crypto *c)
2133
+ {
2134
+ uint32_t i, j;
2135
+
2136
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2137
+ if (c->tcp_connections_new[i] == NULL)
2138
+ continue;
2139
+
2140
+ if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
2141
+ continue;
2142
+
2143
+ kill_TCP_connection(c->tcp_connections_new[i]);
2144
+ c->tcp_connections_new[i] = NULL;
2145
+ }
2146
+
2147
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2148
+ if (c->tcp_connections[i] == NULL)
2149
+ continue;
2150
+
2151
+ TCP_Client_Connection *tcp_con = c->tcp_connections[i];
2152
+
2153
+ if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
2154
+ continue;
2155
+
2156
+ /* Try reconnecting to relay on disconnect. */
2157
+ add_tcp_relay(c, tcp_con->ip_port, tcp_con->public_key);
2158
+
2159
+ pthread_mutex_lock(&c->tcp_mutex);
2160
+ c->tcp_connections[i] = NULL;
2161
+ kill_TCP_connection(tcp_con);
2162
+
2163
+ for (j = 0; j < c->crypto_connections_length; ++j) {
2164
+ Crypto_Connection *conn = get_crypto_connection(c, j);
2165
+
2166
+ if (conn == 0)
2167
+ continue;
2168
+
2169
+ clear_disconnected_tcp_peer(conn, i);
2170
+ }
2171
+
2172
+ pthread_mutex_unlock(&c->tcp_mutex);
2173
+ }
2174
+ }
2175
+
2176
+ /* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
2177
+ *
2178
+ * The set function should return -1 on failure and 0 on success.
2179
+ * Note that if this function is set, the connection will clear itself on disconnect.
2180
+ * Object and id will be passed to this function untouched.
2181
+ * status is 1 if the connection is going online, 0 if it is going offline.
2182
+ *
2183
+ * return -1 on failure.
2184
+ * return 0 on success.
2185
+ */
2186
+ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
2187
+ int (*connection_status_callback)(void *object, int id, uint8_t status), void *object, int id)
2188
+ {
2189
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2190
+
2191
+ if (conn == 0)
2192
+ return -1;
2193
+
2194
+ conn->connection_status_callback = connection_status_callback;
2195
+ conn->connection_status_callback_object = object;
2196
+ conn->connection_status_callback_id = id;
2197
+ return 0;
2198
+ }
2199
+
2200
+ /* Set function to be called when connection with crypt_connection_id receives a data packet of length.
2201
+ *
2202
+ * The set function should return -1 on failure and 0 on success.
2203
+ * Object and id will be passed to this function untouched.
2204
+ *
2205
+ * return -1 on failure.
2206
+ * return 0 on success.
2207
+ */
2208
+ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
2209
+ int id, uint8_t *data, uint16_t length), void *object, int id)
2210
+ {
2211
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2212
+
2213
+ if (conn == 0)
2214
+ return -1;
2215
+
2216
+ conn->connection_data_callback = connection_data_callback;
2217
+ conn->connection_data_callback_object = object;
2218
+ conn->connection_data_callback_id = id;
2219
+ return 0;
2220
+ }
2221
+
2222
+ /* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
2223
+ *
2224
+ * The set function should return -1 on failure and 0 on success.
2225
+ * Object and id will be passed to this function untouched.
2226
+ *
2227
+ * return -1 on failure.
2228
+ * return 0 on success.
2229
+ */
2230
+ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2231
+ int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, int id)
2232
+ {
2233
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2234
+
2235
+ if (conn == 0)
2236
+ return -1;
2237
+
2238
+ conn->connection_lossy_data_callback = connection_lossy_data_callback;
2239
+ conn->connection_lossy_data_callback_object = object;
2240
+ conn->connection_lossy_data_callback_id = id;
2241
+ return 0;
2242
+ }
2243
+
2244
+ /* Get the crypto connection id from the ip_port.
2245
+ *
2246
+ * return -1 on failure.
2247
+ * return connection id on success.
2248
+ */
2249
+ static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port)
2250
+ {
2251
+ return bs_list_find(&c->ip_port_list, &ip_port);
2252
+ }
2253
+
2254
+ #define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + crypto_box_MACBYTES)
2255
+
2256
+ /* Handle raw UDP packets coming directly from the socket.
2257
+ *
2258
+ * Handles:
2259
+ * Cookie response packets.
2260
+ * Crypto handshake packets.
2261
+ * Crypto data packets.
2262
+ *
2263
+ */
2264
+ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
2265
+ {
2266
+ if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE)
2267
+ return 1;
2268
+
2269
+ Net_Crypto *c = object;
2270
+ int crypt_connection_id = crypto_id_ip_port(c, source);
2271
+
2272
+ if (crypt_connection_id == -1) {
2273
+ if (packet[0] != NET_PACKET_CRYPTO_HS)
2274
+ return 1;
2275
+
2276
+ if (handle_new_connection_handshake(c, source, packet, length) != 0)
2277
+ return 1;
2278
+
2279
+ return 0;
2280
+ }
2281
+
2282
+ if (handle_packet_connection(c, crypt_connection_id, packet, length) != 0)
2283
+ return 1;
2284
+
2285
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2286
+
2287
+ if (conn == 0)
2288
+ return -1;
2289
+
2290
+ conn->direct_lastrecv_time = current_time_monotonic();
2291
+ return 0;
2292
+ }
2293
+
2294
+ /* The dT for the average packet receiving rate calculations.
2295
+ Also used as the */
2296
+ #define PACKET_COUNTER_AVERAGE_INTERVAL 100
2297
+
2298
+ /* Ratio of recv queue size / recv packet rate (in seconds) times
2299
+ * the number of ms between request packets to send at that ratio
2300
+ */
2301
+ #define REQUEST_PACKETS_COMPARE_CONSTANT (0.5 * 100.0)
2302
+ static void send_crypto_packets(Net_Crypto *c)
2303
+ {
2304
+ uint32_t i;
2305
+ uint64_t temp_time = current_time_monotonic();
2306
+ double total_send_rate = 0;
2307
+ uint32_t peak_request_packet_interval = ~0;
2308
+
2309
+ for (i = 0; i < c->crypto_connections_length; ++i) {
2310
+ Crypto_Connection *conn = get_crypto_connection(c, i);
2311
+
2312
+ if (conn == 0)
2313
+ return;
2314
+
2315
+ if (CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time < temp_time) {
2316
+ send_temp_packet(c, i);
2317
+ }
2318
+
2319
+ if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED)
2320
+ && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_request_packet_sent) < temp_time) {
2321
+ if (send_request_packet(c, i) == 0) {
2322
+ conn->last_request_packet_sent = temp_time;
2323
+ }
2324
+
2325
+ }
2326
+
2327
+ if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2328
+ if (conn->packet_recv_rate > CRYPTO_PACKET_MIN_RATE) {
2329
+ double request_packet_interval = (REQUEST_PACKETS_COMPARE_CONSTANT / (((double)num_packets_array(
2330
+ &conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0)));
2331
+
2332
+ if (temp_time - conn->last_request_packet_sent > (uint64_t)request_packet_interval) {
2333
+ if (send_request_packet(c, i) == 0) {
2334
+ conn->last_request_packet_sent = temp_time;
2335
+ }
2336
+ }
2337
+
2338
+ if (request_packet_interval < peak_request_packet_interval) {
2339
+ peak_request_packet_interval = request_packet_interval;
2340
+ }
2341
+ }
2342
+
2343
+ if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) {
2344
+
2345
+ double dt = temp_time - conn->packet_counter_set;
2346
+
2347
+ conn->packet_recv_rate = (double)conn->packet_counter / (dt / 1000.0);
2348
+ conn->packet_counter = 0;
2349
+ conn->packet_counter_set = temp_time;
2350
+
2351
+ uint32_t packets_sent = conn->packets_sent;
2352
+ conn->packets_sent = 0;
2353
+
2354
+ /* conjestion control
2355
+ calculate a new value of conn->packet_send_rate based on some data
2356
+ */
2357
+
2358
+ unsigned int pos = conn->last_sendqueue_counter % CONGESTION_QUEUE_ARRAY_SIZE;
2359
+ conn->last_sendqueue_size[pos] = num_packets_array(&conn->send_array);
2360
+ ++conn->last_sendqueue_counter;
2361
+
2362
+ unsigned int j;
2363
+ long signed int sum = 0;
2364
+ sum = (long signed int)conn->last_sendqueue_size[(pos) % CONGESTION_QUEUE_ARRAY_SIZE] -
2365
+ (long signed int)conn->last_sendqueue_size[(pos - (CONGESTION_QUEUE_ARRAY_SIZE - 1)) % CONGESTION_QUEUE_ARRAY_SIZE];
2366
+
2367
+ conn->last_num_packets_sent[pos] = packets_sent;
2368
+ long signed int total_sent = 0;
2369
+
2370
+ for (j = 0; j < CONGESTION_QUEUE_ARRAY_SIZE; ++j) {
2371
+ total_sent += conn->last_num_packets_sent[j];
2372
+ }
2373
+
2374
+ total_sent -= sum;
2375
+
2376
+ double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) *
2377
+ PACKET_COUNTER_AVERAGE_INTERVAL));
2378
+
2379
+ conn->packet_send_rate = min_speed * 1.3;
2380
+
2381
+ if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) {
2382
+ conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
2383
+ }
2384
+
2385
+ }
2386
+
2387
+ if (conn->last_packets_left_set == 0) {
2388
+ conn->last_packets_left_set = temp_time;
2389
+ conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
2390
+ } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) {
2391
+ uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0) + 0.5;
2392
+
2393
+ if (conn->packets_left > num_packets * 4 + CRYPTO_MIN_QUEUE_LENGTH) {
2394
+ conn->packets_left = num_packets * 4 + CRYPTO_MIN_QUEUE_LENGTH;
2395
+ } else {
2396
+ conn->packets_left += num_packets;
2397
+ }
2398
+
2399
+ conn->last_packets_left_set = temp_time;
2400
+ }
2401
+
2402
+ int ret = send_requested_packets(c, i, conn->packets_left);
2403
+
2404
+ if (ret != -1) {
2405
+ conn->packets_left -= ret;
2406
+ }
2407
+
2408
+ if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) {
2409
+ total_send_rate += conn->packet_send_rate;
2410
+ }
2411
+ }
2412
+ }
2413
+
2414
+ c->current_sleep_time = ~0;
2415
+ uint32_t sleep_time = peak_request_packet_interval;
2416
+
2417
+ if (c->current_sleep_time > sleep_time) {
2418
+ c->current_sleep_time = sleep_time;
2419
+ }
2420
+
2421
+ if (total_send_rate > CRYPTO_PACKET_MIN_RATE) {
2422
+ sleep_time = (1000.0 / total_send_rate);
2423
+
2424
+ if (c->current_sleep_time > sleep_time) {
2425
+ c->current_sleep_time = sleep_time + 1;
2426
+ }
2427
+ }
2428
+
2429
+ sleep_time = CRYPTO_SEND_PACKET_INTERVAL;
2430
+
2431
+ if (c->current_sleep_time > sleep_time) {
2432
+ c->current_sleep_time = sleep_time;
2433
+ }
2434
+ }
2435
+
2436
+
2437
+ /* returns the number of packet slots left in the sendbuffer.
2438
+ * return 0 if failure.
2439
+ */
2440
+ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id)
2441
+ {
2442
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2443
+
2444
+ if (conn == 0)
2445
+ return 0;
2446
+
2447
+ return conn->packets_left;
2448
+ }
2449
+
2450
+ /* Sends a lossless cryptopacket.
2451
+ *
2452
+ * return -1 if data could not be put in packet queue.
2453
+ * return positive packet number if data was put into the queue.
2454
+ *
2455
+ * congestion_control: should congestion control apply to this packet?
2456
+ */
2457
+ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length,
2458
+ uint8_t congestion_control)
2459
+ {
2460
+ if (length == 0)
2461
+ return -1;
2462
+
2463
+ if (data[0] < CRYPTO_RESERVED_PACKETS)
2464
+ return -1;
2465
+
2466
+ if (data[0] >= PACKET_ID_LOSSY_RANGE_START)
2467
+ return -1;
2468
+
2469
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2470
+
2471
+ if (conn == 0)
2472
+ return -1;
2473
+
2474
+ if (conn->status != CRYPTO_CONN_ESTABLISHED)
2475
+ return -1;
2476
+
2477
+ if (congestion_control && conn->packets_left == 0)
2478
+ return -1;
2479
+
2480
+ int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length, congestion_control);
2481
+
2482
+ if (ret == -1)
2483
+ return -1;
2484
+
2485
+ if (congestion_control) {
2486
+ --conn->packets_left;
2487
+ conn->packets_sent++;
2488
+ }
2489
+
2490
+ return ret;
2491
+ }
2492
+
2493
+ /* Check if packet_number was received by the other side.
2494
+ *
2495
+ * packet_number must be a valid packet number of a packet sent on this connection.
2496
+ *
2497
+ * return -1 on failure.
2498
+ * return 0 on success.
2499
+ */
2500
+ int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet_number)
2501
+ {
2502
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2503
+
2504
+ if (conn == 0)
2505
+ return -1;
2506
+
2507
+ uint32_t num = conn->send_array.buffer_end - conn->send_array.buffer_start;
2508
+ uint32_t num1 = packet_number - conn->send_array.buffer_start;
2509
+
2510
+ if (num < num1) {
2511
+ return 0;
2512
+ } else {
2513
+ return -1;
2514
+ }
2515
+ }
2516
+
2517
+ /* return -1 on failure.
2518
+ * return 0 on success.
2519
+ *
2520
+ * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*)
2521
+ */
2522
+ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length)
2523
+ {
2524
+ if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
2525
+ return -1;
2526
+
2527
+ if (data[0] < PACKET_ID_LOSSY_RANGE_START)
2528
+ return -1;
2529
+
2530
+ if (data[0] >= (PACKET_ID_LOSSY_RANGE_START + PACKET_ID_LOSSY_RANGE_SIZE))
2531
+ return -1;
2532
+
2533
+ pthread_mutex_lock(&c->connections_mutex);
2534
+ ++c->connection_use_counter;
2535
+ pthread_mutex_unlock(&c->connections_mutex);
2536
+
2537
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2538
+
2539
+ int ret = -1;
2540
+
2541
+ if (conn) {
2542
+ ret = send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, data,
2543
+ length);
2544
+ }
2545
+
2546
+ pthread_mutex_lock(&c->connections_mutex);
2547
+ --c->connection_use_counter;
2548
+ pthread_mutex_unlock(&c->connections_mutex);
2549
+
2550
+ return ret;
2551
+ }
2552
+
2553
+ /* Kill a crypto connection.
2554
+ *
2555
+ * return -1 on failure.
2556
+ * return 0 on success.
2557
+ */
2558
+ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2559
+ {
2560
+ while (1) { /* TODO: is this really the best way to do this? */
2561
+ pthread_mutex_lock(&c->connections_mutex);
2562
+
2563
+ if (!c->connection_use_counter) {
2564
+ break;
2565
+ }
2566
+
2567
+ pthread_mutex_unlock(&c->connections_mutex);
2568
+ }
2569
+
2570
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2571
+
2572
+ int ret = -1;
2573
+
2574
+ if (conn) {
2575
+ if (conn->status == CRYPTO_CONN_ESTABLISHED)
2576
+ send_kill_packet(c, crypt_connection_id);
2577
+
2578
+ disconnect_peer_tcp(c, crypt_connection_id);
2579
+ bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
2580
+ ret = wipe_crypto_connection(c, crypt_connection_id);
2581
+ }
2582
+
2583
+ pthread_mutex_unlock(&c->connections_mutex);
2584
+
2585
+ return ret;
2586
+ }
2587
+
2588
+ /* return one of CRYPTO_CONN_* values indicating the state of the connection.
2589
+ *
2590
+ * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2591
+ */
2592
+ unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected)
2593
+ {
2594
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2595
+
2596
+ if (conn == 0)
2597
+ return CRYPTO_CONN_NO_CONNECTION;
2598
+
2599
+ *direct_connected = 0;
2600
+
2601
+ if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic())
2602
+ *direct_connected = 1;
2603
+
2604
+ return conn->status;
2605
+ }
2606
+
2607
+ void new_keys(Net_Crypto *c)
2608
+ {
2609
+ crypto_box_keypair(c->self_public_key, c->self_secret_key);
2610
+ }
2611
+
2612
+ /* Save the public and private keys to the keys array.
2613
+ * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2614
+ */
2615
+ void save_keys(const Net_Crypto *c, uint8_t *keys)
2616
+ {
2617
+ memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES);
2618
+ memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
2619
+ }
2620
+
2621
+ /* Load the public and private keys from the keys array.
2622
+ * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2623
+ */
2624
+ void load_keys(Net_Crypto *c, const uint8_t *keys)
2625
+ {
2626
+ memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES);
2627
+ memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
2628
+ }
2629
+
2630
+ /* Run this to (re)initialize net_crypto.
2631
+ * Sets all the global connection variables to their default values.
2632
+ */
2633
+ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2634
+ {
2635
+ unix_time_update();
2636
+
2637
+ if (dht == NULL)
2638
+ return NULL;
2639
+
2640
+ Net_Crypto *temp = calloc(1, sizeof(Net_Crypto));
2641
+
2642
+ if (temp == NULL)
2643
+ return NULL;
2644
+
2645
+ temp->dht = dht;
2646
+
2647
+ new_keys(temp);
2648
+ new_symmetric_key(temp->secret_symmetric_key);
2649
+
2650
+ temp->current_sleep_time = CRYPTO_SEND_PACKET_INTERVAL;
2651
+
2652
+ networking_registerhandler(dht->net, NET_PACKET_COOKIE_REQUEST, &udp_handle_cookie_request, temp);
2653
+ networking_registerhandler(dht->net, NET_PACKET_COOKIE_RESPONSE, &udp_handle_packet, temp);
2654
+ networking_registerhandler(dht->net, NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp);
2655
+ networking_registerhandler(dht->net, NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp);
2656
+
2657
+ bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
2658
+
2659
+ pthread_mutexattr_t attr;
2660
+ pthread_mutexattr_init(&attr);
2661
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2662
+ pthread_mutex_init(&temp->tcp_mutex, &attr);
2663
+ pthread_mutex_init(&temp->connections_mutex, NULL);
2664
+
2665
+ if (proxy_info) {
2666
+ temp->proxy_info = *proxy_info;
2667
+ temp->proxy_set = 1;
2668
+ }
2669
+
2670
+ return temp;
2671
+ }
2672
+
2673
+ static void kill_timedout(Net_Crypto *c)
2674
+ {
2675
+ uint32_t i;
2676
+ //uint64_t temp_time = current_time_monotonic();
2677
+
2678
+ for (i = 0; i < c->crypto_connections_length; ++i) {
2679
+ Crypto_Connection *conn = get_crypto_connection(c, i);
2680
+
2681
+ if (conn == 0)
2682
+ return;
2683
+
2684
+ if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT)
2685
+ continue;
2686
+
2687
+ if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
2688
+ || conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
2689
+ if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
2690
+ continue;
2691
+
2692
+ conn->killed = 1;
2693
+
2694
+ }
2695
+
2696
+ if (conn->killed) {
2697
+ if (conn->connection_status_callback) {
2698
+ conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
2699
+ crypto_kill(c, i);
2700
+ continue;
2701
+ }
2702
+
2703
+ conn->status = CRYPTO_CONN_TIMED_OUT;
2704
+ continue;
2705
+ }
2706
+
2707
+ if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2708
+ //TODO: add a timeout here?
2709
+ }
2710
+ }
2711
+ }
2712
+
2713
+ /* return the optimal interval in ms for running do_net_crypto.
2714
+ */
2715
+ uint32_t crypto_run_interval(const Net_Crypto *c)
2716
+ {
2717
+ return c->current_sleep_time;
2718
+ }
2719
+
2720
+ /* Main loop. */
2721
+ void do_net_crypto(Net_Crypto *c)
2722
+ {
2723
+ unix_time_update();
2724
+ kill_timedout(c);
2725
+ do_tcp(c);
2726
+ clear_disconnected_tcp(c);
2727
+ send_crypto_packets(c);
2728
+ }
2729
+
2730
+ void kill_net_crypto(Net_Crypto *c)
2731
+ {
2732
+ uint32_t i;
2733
+
2734
+ for (i = 0; i < c->crypto_connections_length; ++i) {
2735
+ crypto_kill(c, i);
2736
+ }
2737
+
2738
+ for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2739
+ kill_TCP_connection(c->tcp_connections_new[i]);
2740
+ kill_TCP_connection(c->tcp_connections[i]);
2741
+ }
2742
+
2743
+ pthread_mutex_destroy(&c->tcp_mutex);
2744
+ pthread_mutex_destroy(&c->connections_mutex);
2745
+
2746
+ bs_list_free(&c->ip_port_list);
2747
+ networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
2748
+ networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
2749
+ networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL);
2750
+ networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_DATA, NULL, NULL);
2751
+ memset(c, 0, sizeof(Net_Crypto));
2752
+ free(c);
2753
+ }