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,367 @@
1
+ /* network.h
2
+ *
3
+ * Datatypes, functions and includes for the core networking.
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 NETWORK_H
25
+ #define NETWORK_H
26
+
27
+ #ifdef PLAN9
28
+ #include <u.h> //Plan 9 requires this is imported first
29
+ #include <libc.h>
30
+ #endif
31
+
32
+ #include <stdlib.h>
33
+ #include <stdio.h>
34
+ #include <stdint.h>
35
+ #include <string.h>
36
+ #include <time.h>
37
+
38
+ #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) /* Put win32 includes here */
39
+ #ifndef WINVER
40
+ //Windows XP
41
+ #define WINVER 0x0501
42
+ #endif
43
+ #include <winsock2.h>
44
+ #include <windows.h>
45
+ #include <ws2tcpip.h>
46
+
47
+ #ifndef IPV6_V6ONLY
48
+ #define IPV6_V6ONLY 27
49
+ #endif
50
+
51
+ typedef unsigned int sock_t;
52
+ /* sa_family_t is the sockaddr_in / sockaddr_in6 family field */
53
+ typedef short sa_family_t;
54
+
55
+ #ifndef EWOULDBLOCK
56
+ #define EWOULDBLOCK WSAEWOULDBLOCK
57
+ #endif
58
+
59
+ #else // Linux includes
60
+
61
+ #include <fcntl.h>
62
+ #include <sys/socket.h>
63
+ #include <netinet/in.h>
64
+ #include <arpa/inet.h>
65
+ #include <errno.h>
66
+ #include <sys/time.h>
67
+ #include <sys/types.h>
68
+ #include <netdb.h>
69
+ #include <unistd.h>
70
+
71
+ typedef int sock_t;
72
+
73
+ #endif
74
+
75
+ #if defined(__AIX__)
76
+ # define _XOPEN_SOURCE 1
77
+ #endif
78
+
79
+ #if defined(__sun__)
80
+ #define __EXTENSIONS__ 1 // SunOS!
81
+ #if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__) || defined(__SunOS5_9__) || defined(__SunOS5_10__)
82
+ //Nothing needed
83
+ #else
84
+ #define __MAKECONTEXT_V2_SOURCE 1
85
+ #endif
86
+ #endif
87
+
88
+ #ifndef IPV6_ADD_MEMBERSHIP
89
+ #ifdef IPV6_JOIN_GROUP
90
+ #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
91
+ #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
92
+ #endif
93
+ #endif
94
+
95
+ #define MAX_UDP_PACKET_SIZE 2048
96
+
97
+ #define NET_PACKET_PING_REQUEST 0 /* Ping request packet ID. */
98
+ #define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */
99
+ #define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */
100
+ #define NET_PACKET_SEND_NODES 3 /* Send nodes response packet ID for IPv4 addresses. */
101
+ #define NET_PACKET_SEND_NODES_IPV6 4 /* Send nodes response packet ID for other addresses. */
102
+ #define NET_PACKET_COOKIE_REQUEST 24 /* Cookie request packet */
103
+ #define NET_PACKET_COOKIE_RESPONSE 25 /* Cookie response packet */
104
+ #define NET_PACKET_CRYPTO_HS 26 /* Crypto handshake packet */
105
+ #define NET_PACKET_CRYPTO_DATA 27 /* Crypto data packet */
106
+ #define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */
107
+ #define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */
108
+ #define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */
109
+
110
+ /* See: docs/Prevent_Tracking.txt and onion.{c, h} */
111
+ #define NET_PACKET_ONION_SEND_INITIAL 128
112
+ #define NET_PACKET_ONION_SEND_1 129
113
+ #define NET_PACKET_ONION_SEND_2 130
114
+
115
+ #define NET_PACKET_ANNOUNCE_REQUEST 131
116
+ #define NET_PACKET_ANNOUNCE_RESPONSE 132
117
+ #define NET_PACKET_ONION_DATA_REQUEST 133
118
+ #define NET_PACKET_ONION_DATA_RESPONSE 134
119
+
120
+ #define NET_PACKET_ONION_RECV_3 140
121
+ #define NET_PACKET_ONION_RECV_2 141
122
+ #define NET_PACKET_ONION_RECV_1 142
123
+
124
+ /* Only used for bootstrap nodes */
125
+ #define BOOTSTRAP_INFO_PACKET_ID 240
126
+
127
+
128
+ #define TOX_PORTRANGE_FROM 33445
129
+ #define TOX_PORTRANGE_TO 33545
130
+ #define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
131
+
132
+ /* TCP related */
133
+ #define TCP_ONION_FAMILY (AF_INET6 + 1)
134
+ #define TCP_INET (AF_INET6 + 2)
135
+ #define TCP_INET6 (AF_INET6 + 3)
136
+ #define TCP_FAMILY (AF_INET6 + 4)
137
+
138
+ typedef union __attribute__ ((__packed__))
139
+ {
140
+ uint8_t uint8[4];
141
+ uint16_t uint16[2];
142
+ uint32_t uint32;
143
+ struct in_addr in_addr;
144
+ }
145
+ IP4;
146
+
147
+ typedef union __attribute__ ((__packed__))
148
+ {
149
+ uint8_t uint8[16];
150
+ uint16_t uint16[8];
151
+ uint32_t uint32[4];
152
+ uint64_t uint64[2];
153
+ struct in6_addr in6_addr;
154
+ }
155
+ IP6;
156
+
157
+ typedef struct __attribute__ ((__packed__))
158
+ {
159
+ uint8_t family;
160
+ union {
161
+ IP4 ip4;
162
+ IP6 ip6;
163
+ };
164
+ }
165
+ IP;
166
+
167
+ typedef struct __attribute__ ((__packed__)) __attribute__((gcc_struct))
168
+ {
169
+ IP ip;
170
+ uint16_t port;
171
+ }
172
+ IP_Port;
173
+
174
+ /* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
175
+ #define IPV6_IPV4_IN_V6(a) ((a.uint64[0] == 0) && (a.uint32[2] == htonl (0xffff)))
176
+
177
+ #define SIZE_IP4 4
178
+ #define SIZE_IP6 16
179
+ #define SIZE_IP (1 + SIZE_IP6)
180
+ #define SIZE_PORT 2
181
+ #define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
182
+
183
+ #define TOX_ENABLE_IPV6_DEFAULT 1
184
+
185
+ /* ip_ntoa
186
+ * converts ip into a string
187
+ * uses a static buffer, so mustn't used multiple times in the same output
188
+ */
189
+ const char *ip_ntoa(const IP *ip);
190
+
191
+ /*
192
+ * addr_parse_ip
193
+ * directly parses the input into an IP structure
194
+ * tries IPv4 first, then IPv6
195
+ *
196
+ * input
197
+ * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
198
+ *
199
+ * output
200
+ * IP: family and the value is set on success
201
+ *
202
+ * returns 1 on success, 0 on failure
203
+ */
204
+ int addr_parse_ip(const char *address, IP *to);
205
+
206
+ /* ip_equal
207
+ * compares two IPAny structures
208
+ * unset means unequal
209
+ *
210
+ * returns 0 when not equal or when uninitialized
211
+ */
212
+ int ip_equal(const IP *a, const IP *b);
213
+
214
+ /* ipport_equal
215
+ * compares two IPAny_Port structures
216
+ * unset means unequal
217
+ *
218
+ * returns 0 when not equal or when uninitialized
219
+ */
220
+ int ipport_equal(const IP_Port *a, const IP_Port *b);
221
+
222
+ /* nulls out ip */
223
+ void ip_reset(IP *ip);
224
+ /* nulls out ip, sets family according to flag */
225
+ void ip_init(IP *ip, uint8_t ipv6enabled);
226
+ /* checks if ip is valid */
227
+ int ip_isset(const IP *ip);
228
+ /* checks if ip is valid */
229
+ int ipport_isset(const IP_Port *ipport);
230
+ /* copies an ip structure */
231
+ void ip_copy(IP *target, const IP *source);
232
+ /* copies an ip_port structure */
233
+ void ipport_copy(IP_Port *target, const IP_Port *source);
234
+
235
+
236
+ /* packs IP into data, writes SIZE_IP bytes to data */
237
+ void ip_pack(uint8_t *data, const IP *source);
238
+ /* unpacks IP from data, reads SIZE_IP bytes from data */
239
+ void ip_unpack(IP *target, const uint8_t *data);
240
+ /* packs IP_Port into data, writes SIZE_IPPORT bytes to data */
241
+ void ipport_pack(uint8_t *data, const IP_Port *source);
242
+ /* unpacks IP_Port from data, reads SIZE_IPPORT bytes to data */
243
+ void ipport_unpack(IP_Port *target, const uint8_t *data);
244
+
245
+ /*
246
+ * addr_resolve():
247
+ * uses getaddrinfo to resolve an address into an IP address
248
+ * uses the first IPv4/IPv6 addresses returned by getaddrinfo
249
+ *
250
+ * input
251
+ * address: a hostname (or something parseable to an IP address)
252
+ * to: to.family MUST be initialized, either set to a specific IP version
253
+ * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
254
+ * IP versions are acceptable
255
+ * extra can be NULL and is only set in special circumstances, see returns
256
+ *
257
+ * returns in *to a valid IPAny (v4/v6),
258
+ * prefers v6 if ip.family was AF_UNSPEC and both available
259
+ * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
260
+ * returns 0 on failure
261
+ */
262
+ int addr_resolve(const char *address, IP *to, IP *extra);
263
+
264
+ /*
265
+ * addr_resolve_or_parse_ip
266
+ * resolves string into an IP address
267
+ *
268
+ * address: a hostname (or something parseable to an IP address)
269
+ * to: to.family MUST be initialized, either set to a specific IP version
270
+ * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
271
+ * IP versions are acceptable
272
+ * extra can be NULL and is only set in special circumstances, see returns
273
+ *
274
+ * returns in *tro a matching address (IPv6 or IPv4)
275
+ * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC
276
+ * returns 1 on success
277
+ * returns 0 on failure
278
+ */
279
+ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
280
+
281
+ /* Function to receive data, ip and port of sender is put into ip_port.
282
+ * Packet data is put into data.
283
+ * Packet length is put into length.
284
+ */
285
+ typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, const uint8_t *data, uint32_t len);
286
+
287
+ typedef struct {
288
+ packet_handler_callback function;
289
+ void *object;
290
+ } Packet_Handles;
291
+
292
+ typedef struct {
293
+ Packet_Handles packethandlers[256];
294
+
295
+ sa_family_t family;
296
+ uint16_t port;
297
+ /* Our UDP socket. */
298
+ sock_t sock;
299
+ } Networking_Core;
300
+
301
+ /* Run this before creating sockets.
302
+ *
303
+ * return 0 on success
304
+ * return -1 on failure
305
+ */
306
+ int networking_at_startup(void);
307
+
308
+ /* Check if socket is valid.
309
+ *
310
+ * return 1 if valid
311
+ * return 0 if not valid
312
+ */
313
+ int sock_valid(sock_t sock);
314
+
315
+ /* Close the socket.
316
+ */
317
+ void kill_sock(sock_t sock);
318
+
319
+ /* Set socket as nonblocking
320
+ *
321
+ * return 1 on success
322
+ * return 0 on failure
323
+ */
324
+ int set_socket_nonblock(sock_t sock);
325
+
326
+ /* Set socket to not emit SIGPIPE
327
+ *
328
+ * return 1 on success
329
+ * return 0 on failure
330
+ */
331
+ int set_socket_nosigpipe(sock_t sock);
332
+
333
+ /* Set socket to dual (IPv4 + IPv6 socket)
334
+ *
335
+ * return 1 on success
336
+ * return 0 on failure
337
+ */
338
+ int set_socket_dualstack(sock_t sock);
339
+
340
+ /* return current monotonic time in milliseconds (ms). */
341
+ uint64_t current_time_monotonic(void);
342
+
343
+ /* Basic network functions: */
344
+
345
+ /* Function to send packet(data) of length length to ip_port. */
346
+ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint32_t length);
347
+
348
+ /* Function to call when packet beginning with byte is received. */
349
+ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object);
350
+
351
+ /* Call this several times a second. */
352
+ void networking_poll(Networking_Core *net);
353
+
354
+ /* Initialize networking.
355
+ * bind to ip and port.
356
+ * ip must be in network order EX: 127.0.0.1 = (7F000001).
357
+ * port is in host byte order (this means don't worry about it).
358
+ *
359
+ * return 0 if no problems.
360
+ * return -1 if there were problems.
361
+ */
362
+ Networking_Core *new_networking(IP ip, uint16_t port);
363
+
364
+ /* Function to cleanup networking stuff (doesn't do much right now). */
365
+ void kill_networking(Networking_Core *net);
366
+
367
+ #endif
@@ -0,0 +1,540 @@
1
+ /*
2
+ * onion.c -- Implementation of the onion part of docs/Prevent_Tracking.txt
3
+ *
4
+ * Copyright (C) 2013 Tox project All Rights Reserved.
5
+ *
6
+ * This file is part of Tox.
7
+ *
8
+ * Tox is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * Tox is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with Tox. If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+ #ifdef HAVE_CONFIG_H
23
+ #include "config.h"
24
+ #endif
25
+
26
+ #include "onion.h"
27
+ #include "util.h"
28
+
29
+ #define RETURN_1 ONION_RETURN_1
30
+ #define RETURN_2 ONION_RETURN_2
31
+ #define RETURN_3 ONION_RETURN_3
32
+
33
+ #define SEND_BASE ONION_SEND_BASE
34
+ #define SEND_3 ONION_SEND_3
35
+ #define SEND_2 ONION_SEND_2
36
+ #define SEND_1 ONION_SEND_1
37
+
38
+ /* Change symmetric keys every hour to make paths expire eventually. */
39
+ #define KEY_REFRESH_INTERVAL (60 * 60)
40
+ static void change_symmetric_key(Onion *onion)
41
+ {
42
+ if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) {
43
+ new_symmetric_key(onion->secret_symmetric_key);
44
+ onion->timestamp = unix_time();
45
+ }
46
+ }
47
+
48
+ /* Create a new onion path.
49
+ *
50
+ * Create a new onion path out of nodes (nodes is a list of 3 nodes)
51
+ *
52
+ * new_path must be an empty memory location of atleast Onion_Path size.
53
+ *
54
+ * return -1 on failure.
55
+ * return 0 on success.
56
+ */
57
+ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes)
58
+ {
59
+ if (!new_path || !nodes)
60
+ return -1;
61
+
62
+ encrypt_precompute(nodes[0].client_id, dht->self_secret_key, new_path->shared_key1);
63
+ memcpy(new_path->public_key1, dht->self_public_key, crypto_box_PUBLICKEYBYTES);
64
+
65
+ uint8_t random_public_key[crypto_box_PUBLICKEYBYTES];
66
+ uint8_t random_secret_key[crypto_box_SECRETKEYBYTES];
67
+
68
+ crypto_box_keypair(random_public_key, random_secret_key);
69
+ encrypt_precompute(nodes[1].client_id, random_secret_key, new_path->shared_key2);
70
+ memcpy(new_path->public_key2, random_public_key, crypto_box_PUBLICKEYBYTES);
71
+
72
+ crypto_box_keypair(random_public_key, random_secret_key);
73
+ encrypt_precompute(nodes[2].client_id, random_secret_key, new_path->shared_key3);
74
+ memcpy(new_path->public_key3, random_public_key, crypto_box_PUBLICKEYBYTES);
75
+
76
+ new_path->ip_port1 = nodes[0].ip_port;
77
+ new_path->ip_port2 = nodes[1].ip_port;
78
+ new_path->ip_port3 = nodes[2].ip_port;
79
+
80
+ /* to_net_family(&new_path->ip_port1.ip); */
81
+ to_net_family(&new_path->ip_port2.ip);
82
+ to_net_family(&new_path->ip_port3.ip);
83
+
84
+ return 0;
85
+ }
86
+
87
+ /* Create a onion packet.
88
+ *
89
+ * Use Onion_Path path to create packet for data of length to dest.
90
+ * Maximum length of data is ONION_MAX_DATA_SIZE.
91
+ * packet should be at least ONION_MAX_PACKET_SIZE big.
92
+ *
93
+ * return -1 on failure.
94
+ * return length of created packet on success.
95
+ */
96
+ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
97
+ const uint8_t *data, uint32_t length)
98
+ {
99
+ if (1 + length + SEND_1 > max_packet_length || length == 0)
100
+ return -1;
101
+
102
+ to_net_family(&dest.ip);
103
+ uint8_t step1[SIZE_IPPORT + length];
104
+
105
+
106
+ ipport_pack(step1, &dest);
107
+ memcpy(step1 + SIZE_IPPORT, data, length);
108
+
109
+ uint8_t nonce[crypto_box_NONCEBYTES];
110
+ random_nonce(nonce);
111
+
112
+ uint8_t step2[SIZE_IPPORT + SEND_BASE + length];
113
+ ipport_pack(step2, &path->ip_port3);
114
+ memcpy(step2 + SIZE_IPPORT, path->public_key3, crypto_box_PUBLICKEYBYTES);
115
+
116
+ int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1),
117
+ step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
118
+
119
+ if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES)
120
+ return -1;
121
+
122
+ uint8_t step3[SIZE_IPPORT + SEND_BASE * 2 + length];
123
+ ipport_pack(step3, &path->ip_port2);
124
+ memcpy(step3 + SIZE_IPPORT, path->public_key2, crypto_box_PUBLICKEYBYTES);
125
+ len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2),
126
+ step3 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
127
+
128
+ if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES)
129
+ return -1;
130
+
131
+ packet[0] = NET_PACKET_ONION_SEND_INITIAL;
132
+ memcpy(packet + 1, nonce, crypto_box_NONCEBYTES);
133
+ memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES);
134
+
135
+ len = encrypt_data_symmetric(path->shared_key1, nonce, step3, sizeof(step3),
136
+ packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
137
+
138
+ if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES)
139
+ return -1;
140
+
141
+ return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len;
142
+ }
143
+
144
+ /* Create a onion packet to be sent over tcp.
145
+ *
146
+ * Use Onion_Path path to create packet for data of length to dest.
147
+ * Maximum length of data is ONION_MAX_DATA_SIZE.
148
+ * packet should be at least ONION_MAX_PACKET_SIZE big.
149
+ *
150
+ * return -1 on failure.
151
+ * return length of created packet on success.
152
+ */
153
+ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
154
+ const uint8_t *data, uint32_t length)
155
+ {
156
+ if (crypto_box_NONCEBYTES + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0)
157
+ return -1;
158
+
159
+ to_net_family(&dest.ip);
160
+ uint8_t step1[SIZE_IPPORT + length];
161
+
162
+
163
+ ipport_pack(step1, &dest);
164
+ memcpy(step1 + SIZE_IPPORT, data, length);
165
+
166
+ uint8_t nonce[crypto_box_NONCEBYTES];
167
+ random_nonce(nonce);
168
+
169
+ uint8_t step2[SIZE_IPPORT + SEND_BASE + length];
170
+ ipport_pack(step2, &path->ip_port3);
171
+ memcpy(step2 + SIZE_IPPORT, path->public_key3, crypto_box_PUBLICKEYBYTES);
172
+
173
+ int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1),
174
+ step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
175
+
176
+ if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES)
177
+ return -1;
178
+
179
+ ipport_pack(packet + crypto_box_NONCEBYTES, &path->ip_port2);
180
+ memcpy(packet + crypto_box_NONCEBYTES + SIZE_IPPORT, path->public_key2, crypto_box_PUBLICKEYBYTES);
181
+ len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2),
182
+ packet + crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
183
+
184
+ if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES)
185
+ return -1;
186
+
187
+ memcpy(packet, nonce, crypto_box_NONCEBYTES);
188
+
189
+ return crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES + len;
190
+ }
191
+
192
+ /* Create and send a onion packet.
193
+ *
194
+ * Use Onion_Path path to send data of length to dest.
195
+ * Maximum length of data is ONION_MAX_DATA_SIZE.
196
+ *
197
+ * return -1 on failure.
198
+ * return 0 on success.
199
+ */
200
+ int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint32_t length)
201
+ {
202
+ uint8_t packet[ONION_MAX_PACKET_SIZE];
203
+ int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
204
+
205
+ if (len == -1)
206
+ return -1;
207
+
208
+ if (sendpacket(net, path->ip_port1, packet, len) != len)
209
+ return -1;
210
+
211
+ return 0;
212
+ }
213
+
214
+ /* Create and send a onion response sent initially to dest with.
215
+ * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
216
+ *
217
+ * return -1 on failure.
218
+ * return 0 on success.
219
+ */
220
+ int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data, uint32_t length, const uint8_t *ret)
221
+ {
222
+ if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0)
223
+ return -1;
224
+
225
+ uint8_t packet[1 + RETURN_3 + length];
226
+ packet[0] = NET_PACKET_ONION_RECV_3;
227
+ memcpy(packet + 1, ret, RETURN_3);
228
+ memcpy(packet + 1 + RETURN_3, data, length);
229
+
230
+ if ((uint32_t)sendpacket(net, dest, packet, sizeof(packet)) != sizeof(packet))
231
+ return -1;
232
+
233
+ return 0;
234
+ }
235
+
236
+ static int handle_send_initial(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
237
+ {
238
+ Onion *onion = object;
239
+
240
+ if (length > ONION_MAX_PACKET_SIZE)
241
+ return 1;
242
+
243
+ if (length <= 1 + SEND_1)
244
+ return 1;
245
+
246
+ change_symmetric_key(onion);
247
+
248
+ uint8_t plain[ONION_MAX_PACKET_SIZE];
249
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
250
+ get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
251
+ int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
252
+ length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain);
253
+
254
+ if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES))
255
+ return 1;
256
+
257
+ return onion_send_1(onion, plain, len, source, packet + 1);
258
+ }
259
+
260
+ int onion_send_1(const Onion *onion, const uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce)
261
+ {
262
+ if (len > ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + crypto_box_NONCEBYTES + ONION_RETURN_1))
263
+ return 1;
264
+
265
+ if (len <= SIZE_IPPORT + SEND_BASE * 2)
266
+ return 1;
267
+
268
+ IP_Port send_to;
269
+ ipport_unpack(&send_to, plain);
270
+ to_host_family(&send_to.ip);
271
+
272
+ uint8_t ip_port[SIZE_IPPORT];
273
+ ipport_pack(ip_port, &source);
274
+
275
+ uint8_t data[ONION_MAX_PACKET_SIZE];
276
+ data[0] = NET_PACKET_ONION_SEND_1;
277
+ memcpy(data + 1, nonce, crypto_box_NONCEBYTES);
278
+ memcpy(data + 1 + crypto_box_NONCEBYTES, plain + SIZE_IPPORT, len - SIZE_IPPORT);
279
+ uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - SIZE_IPPORT);
280
+ uint8_t *ret_part = data + data_len;
281
+ new_nonce(ret_part);
282
+ len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
283
+ ret_part + crypto_box_NONCEBYTES);
284
+
285
+ if (len != SIZE_IPPORT + crypto_box_MACBYTES)
286
+ return 1;
287
+
288
+ data_len += crypto_box_NONCEBYTES + len;
289
+
290
+ if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
291
+ return 1;
292
+
293
+ return 0;
294
+ }
295
+
296
+ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
297
+ {
298
+ Onion *onion = object;
299
+
300
+ if (length > ONION_MAX_PACKET_SIZE)
301
+ return 1;
302
+
303
+ if (length <= 1 + SEND_2)
304
+ return 1;
305
+
306
+ change_symmetric_key(onion);
307
+
308
+ uint8_t plain[ONION_MAX_PACKET_SIZE];
309
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
310
+ get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
311
+ int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
312
+ length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain);
313
+
314
+ if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES))
315
+ return 1;
316
+
317
+ IP_Port send_to;
318
+ ipport_unpack(&send_to, plain);
319
+ to_host_family(&send_to.ip);
320
+
321
+ uint8_t data[ONION_MAX_PACKET_SIZE];
322
+ data[0] = NET_PACKET_ONION_SEND_2;
323
+ memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES);
324
+ memcpy(data + 1 + crypto_box_NONCEBYTES, plain + SIZE_IPPORT, len - SIZE_IPPORT);
325
+ uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - SIZE_IPPORT);
326
+ uint8_t *ret_part = data + data_len;
327
+ new_nonce(ret_part);
328
+ uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
329
+ ipport_pack(ret_data, &source);
330
+ memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
331
+ len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
332
+ ret_part + crypto_box_NONCEBYTES);
333
+
334
+ if (len != RETURN_2 - crypto_box_NONCEBYTES)
335
+ return 1;
336
+
337
+ data_len += crypto_box_NONCEBYTES + len;
338
+
339
+ if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
340
+ return 1;
341
+
342
+ return 0;
343
+ }
344
+
345
+ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
346
+ {
347
+ Onion *onion = object;
348
+
349
+ if (length > ONION_MAX_PACKET_SIZE)
350
+ return 1;
351
+
352
+ if (length <= 1 + SEND_3)
353
+ return 1;
354
+
355
+ change_symmetric_key(onion);
356
+
357
+ uint8_t plain[ONION_MAX_PACKET_SIZE];
358
+ uint8_t shared_key[crypto_box_BEFORENMBYTES];
359
+ get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
360
+ int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
361
+ length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain);
362
+
363
+ if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES))
364
+ return 1;
365
+
366
+ IP_Port send_to;
367
+ ipport_unpack(&send_to, plain);
368
+ to_host_family(&send_to.ip);
369
+
370
+ uint8_t data[ONION_MAX_PACKET_SIZE];
371
+ memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT);
372
+ uint32_t data_len = (len - SIZE_IPPORT);
373
+ uint8_t *ret_part = data + (len - SIZE_IPPORT);
374
+ new_nonce(ret_part);
375
+ uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
376
+ ipport_pack(ret_data, &source);
377
+ memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
378
+ len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
379
+ ret_part + crypto_box_NONCEBYTES);
380
+
381
+ if (len != RETURN_3 - crypto_box_NONCEBYTES)
382
+ return 1;
383
+
384
+ data_len += RETURN_3;
385
+
386
+ if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
387
+ return 1;
388
+
389
+ return 0;
390
+ }
391
+
392
+
393
+ static int handle_recv_3(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
394
+ {
395
+ Onion *onion = object;
396
+
397
+ if (length > ONION_MAX_PACKET_SIZE)
398
+ return 1;
399
+
400
+ if (length <= 1 + RETURN_3)
401
+ return 1;
402
+
403
+ change_symmetric_key(onion);
404
+
405
+ uint8_t plain[SIZE_IPPORT + RETURN_2];
406
+ int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
407
+ SIZE_IPPORT + RETURN_2 + crypto_box_MACBYTES, plain);
408
+
409
+ if ((uint32_t)len != sizeof(plain))
410
+ return 1;
411
+
412
+ IP_Port send_to;
413
+ ipport_unpack(&send_to, plain);
414
+
415
+ uint8_t data[ONION_MAX_PACKET_SIZE];
416
+ data[0] = NET_PACKET_ONION_RECV_2;
417
+ memcpy(data + 1, plain + SIZE_IPPORT, RETURN_2);
418
+ memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3));
419
+ uint32_t data_len = 1 + RETURN_2 + (length - (1 + RETURN_3));
420
+
421
+ if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
422
+ return 1;
423
+
424
+ return 0;
425
+ }
426
+
427
+ static int handle_recv_2(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
428
+ {
429
+ Onion *onion = object;
430
+
431
+ if (length > ONION_MAX_PACKET_SIZE)
432
+ return 1;
433
+
434
+ if (length <= 1 + RETURN_2)
435
+ return 1;
436
+
437
+ change_symmetric_key(onion);
438
+
439
+ uint8_t plain[SIZE_IPPORT + RETURN_1];
440
+ int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
441
+ SIZE_IPPORT + RETURN_1 + crypto_box_MACBYTES, plain);
442
+
443
+ if ((uint32_t)len != sizeof(plain))
444
+ return 1;
445
+
446
+ IP_Port send_to;
447
+ ipport_unpack(&send_to, plain);
448
+
449
+ uint8_t data[ONION_MAX_PACKET_SIZE];
450
+ data[0] = NET_PACKET_ONION_RECV_1;
451
+ memcpy(data + 1, plain + SIZE_IPPORT, RETURN_1);
452
+ memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2));
453
+ uint32_t data_len = 1 + RETURN_1 + (length - (1 + RETURN_2));
454
+
455
+ if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
456
+ return 1;
457
+
458
+ return 0;
459
+ }
460
+
461
+ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, uint32_t length)
462
+ {
463
+ Onion *onion = object;
464
+
465
+ if (length > ONION_MAX_PACKET_SIZE)
466
+ return 1;
467
+
468
+ if (length <= 1 + RETURN_1)
469
+ return 1;
470
+
471
+ change_symmetric_key(onion);
472
+
473
+ uint8_t plain[SIZE_IPPORT];
474
+ int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
475
+ SIZE_IPPORT + crypto_box_MACBYTES, plain);
476
+
477
+ if ((uint32_t)len != SIZE_IPPORT)
478
+ return 1;
479
+
480
+ IP_Port send_to;
481
+ ipport_unpack(&send_to, plain);
482
+
483
+ uint32_t data_len = length - (1 + RETURN_1);
484
+
485
+ if (onion->recv_1_function && send_to.ip.family != AF_INET && send_to.ip.family != AF_INET6)
486
+ return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len);
487
+
488
+ if ((uint32_t)sendpacket(onion->net, send_to, packet + (1 + RETURN_1), data_len) != data_len)
489
+ return 1;
490
+
491
+ return 0;
492
+ }
493
+
494
+ void set_callback_handle_recv_1(Onion *onion, int (*function)(void *, IP_Port, const uint8_t *, uint16_t), void *object)
495
+ {
496
+ onion->recv_1_function = function;
497
+ onion->callback_object = object;
498
+ }
499
+
500
+ Onion *new_onion(DHT *dht)
501
+ {
502
+ if (dht == NULL)
503
+ return NULL;
504
+
505
+ Onion *onion = calloc(1, sizeof(Onion));
506
+
507
+ if (onion == NULL)
508
+ return NULL;
509
+
510
+ onion->dht = dht;
511
+ onion->net = dht->net;
512
+ new_symmetric_key(onion->secret_symmetric_key);
513
+ onion->timestamp = unix_time();
514
+
515
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, &handle_send_initial, onion);
516
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, &handle_send_1, onion);
517
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, &handle_send_2, onion);
518
+
519
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_3, &handle_recv_3, onion);
520
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_2, &handle_recv_2, onion);
521
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_1, &handle_recv_1, onion);
522
+
523
+ return onion;
524
+ }
525
+
526
+ void kill_onion(Onion *onion)
527
+ {
528
+ if (onion == NULL)
529
+ return;
530
+
531
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL);
532
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL);
533
+ networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL);
534
+
535
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_3, NULL, NULL);
536
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_2, NULL, NULL);
537
+ networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_1, NULL, NULL);
538
+
539
+ free(onion);
540
+ }