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.
- checksums.yaml +4 -4
- data/ProjectTox-Core/AUTHORS +0 -0
- data/ProjectTox-Core/ChangeLog +0 -0
- data/ProjectTox-Core/INSTALL +370 -0
- data/ProjectTox-Core/INSTALL.md +455 -56
- data/ProjectTox-Core/Makefile.am +35 -0
- data/ProjectTox-Core/NEWS +0 -0
- data/ProjectTox-Core/README +43 -0
- data/ProjectTox-Core/README.md +34 -44
- data/ProjectTox-Core/auto_tests/Makefile.inc +110 -0
- data/ProjectTox-Core/auto_tests/TCP_test.c +519 -0
- data/ProjectTox-Core/auto_tests/assoc_test.c +160 -0
- data/ProjectTox-Core/auto_tests/crypto_test.c +302 -0
- data/ProjectTox-Core/auto_tests/dht_test.c +362 -0
- data/ProjectTox-Core/auto_tests/encryptsave_test.c +104 -0
- data/ProjectTox-Core/auto_tests/friends_test.c +238 -0
- data/ProjectTox-Core/auto_tests/helpers.h +15 -0
- data/ProjectTox-Core/auto_tests/messenger_test.c +365 -0
- data/ProjectTox-Core/auto_tests/network_test.c +171 -0
- data/ProjectTox-Core/auto_tests/onion_test.c +363 -0
- data/ProjectTox-Core/auto_tests/skeleton_test.c +49 -0
- data/ProjectTox-Core/auto_tests/tox_test.c +454 -0
- data/ProjectTox-Core/auto_tests/toxav_basic_test.c +597 -0
- data/ProjectTox-Core/auto_tests/toxav_many_test.c +402 -0
- data/ProjectTox-Core/autogen.sh +6 -0
- data/ProjectTox-Core/build/Makefile.am +14 -0
- data/ProjectTox-Core/configure.ac +694 -0
- data/ProjectTox-Core/dist-build/android-arm.sh +3 -0
- data/ProjectTox-Core/dist-build/android-armv7.sh +3 -0
- data/ProjectTox-Core/dist-build/android-build.sh +59 -0
- data/ProjectTox-Core/dist-build/android-mips.sh +3 -0
- data/ProjectTox-Core/dist-build/android-x86.sh +3 -0
- data/ProjectTox-Core/docs/Group-Chats.md +71 -0
- data/ProjectTox-Core/docs/Hardening.txt +60 -0
- data/ProjectTox-Core/docs/Hardening_docs.txt +30 -0
- data/ProjectTox-Core/docs/Prevent_Tracking.txt +160 -0
- data/ProjectTox-Core/docs/TCP_Network.txt +154 -0
- data/ProjectTox-Core/docs/TODO +62 -0
- data/ProjectTox-Core/docs/Tox_middle_level_network_protocol.txt +120 -0
- data/ProjectTox-Core/docs/av_api.md +194 -0
- data/ProjectTox-Core/libtoxav.pc.in +11 -0
- data/ProjectTox-Core/libtoxcore.pc.in +11 -0
- data/ProjectTox-Core/m4/ax_have_epoll.m4 +104 -0
- data/ProjectTox-Core/m4/ax_pthread.m4 +317 -0
- data/ProjectTox-Core/m4/pkg.m4 +199 -0
- data/ProjectTox-Core/other/DHT_bootstrap.c +121 -58
- data/ProjectTox-Core/other/DHTnodes +3 -0
- data/ProjectTox-Core/other/Makefile.inc +20 -0
- data/ProjectTox-Core/other/bootstrap_node_packets.c +65 -0
- data/ProjectTox-Core/other/tox.png +0 -0
- data/ProjectTox-Core/testing/DHT_test.c +170 -98
- data/ProjectTox-Core/testing/Makefile.inc +112 -0
- data/ProjectTox-Core/testing/Messenger_test.c +133 -69
- data/ProjectTox-Core/testing/dns3_test.c +115 -0
- data/ProjectTox-Core/testing/misc_tools.c +59 -13
- data/ProjectTox-Core/testing/nTox.c +1127 -264
- data/ProjectTox-Core/testing/nTox.h +10 -19
- data/ProjectTox-Core/testing/tox_shell.c +159 -0
- data/ProjectTox-Core/testing/tox_sync.c +299 -0
- data/ProjectTox-Core/tools/README +11 -0
- data/ProjectTox-Core/tools/astylerc +11 -0
- data/ProjectTox-Core/tools/pre-commit +17 -0
- data/ProjectTox-Core/toxav/Makefile.inc +36 -0
- data/ProjectTox-Core/toxav/codec.c +357 -0
- data/ProjectTox-Core/toxav/codec.h +116 -0
- data/ProjectTox-Core/toxav/msi.c +1949 -0
- data/ProjectTox-Core/toxav/msi.h +267 -0
- data/ProjectTox-Core/toxav/rtp.c +600 -0
- data/ProjectTox-Core/toxav/rtp.h +196 -0
- data/ProjectTox-Core/toxav/toxav.c +1148 -0
- data/ProjectTox-Core/toxav/toxav.h +389 -0
- data/ProjectTox-Core/toxcore/DHT.c +2521 -0
- data/ProjectTox-Core/toxcore/DHT.h +412 -0
- data/ProjectTox-Core/toxcore/LAN_discovery.c +322 -0
- data/ProjectTox-Core/{core → toxcore}/LAN_discovery.h +17 -12
- data/ProjectTox-Core/toxcore/Makefile.inc +67 -0
- data/ProjectTox-Core/toxcore/Messenger.c +3006 -0
- data/ProjectTox-Core/toxcore/Messenger.h +818 -0
- data/ProjectTox-Core/toxcore/TCP_client.c +858 -0
- data/ProjectTox-Core/toxcore/TCP_client.h +156 -0
- data/ProjectTox-Core/toxcore/TCP_server.c +1332 -0
- data/ProjectTox-Core/toxcore/TCP_server.h +181 -0
- data/ProjectTox-Core/toxcore/assoc.c +1033 -0
- data/ProjectTox-Core/toxcore/assoc.h +104 -0
- data/ProjectTox-Core/toxcore/crypto_core.c +278 -0
- data/ProjectTox-Core/toxcore/crypto_core.h +151 -0
- data/ProjectTox-Core/toxcore/friend_requests.c +175 -0
- data/ProjectTox-Core/toxcore/friend_requests.h +83 -0
- data/ProjectTox-Core/toxcore/group_chats.c +837 -0
- data/ProjectTox-Core/toxcore/group_chats.h +199 -0
- data/ProjectTox-Core/toxcore/list.c +256 -0
- data/ProjectTox-Core/toxcore/list.h +85 -0
- data/ProjectTox-Core/toxcore/logger.c +153 -0
- data/ProjectTox-Core/toxcore/logger.h +84 -0
- data/ProjectTox-Core/toxcore/misc_tools.h +70 -0
- data/ProjectTox-Core/toxcore/net_crypto.c +2753 -0
- data/ProjectTox-Core/toxcore/net_crypto.h +410 -0
- data/ProjectTox-Core/toxcore/network.c +979 -0
- data/ProjectTox-Core/toxcore/network.h +367 -0
- data/ProjectTox-Core/toxcore/onion.c +540 -0
- data/ProjectTox-Core/toxcore/onion.h +150 -0
- data/ProjectTox-Core/toxcore/onion_announce.c +433 -0
- data/ProjectTox-Core/toxcore/onion_announce.h +139 -0
- data/ProjectTox-Core/toxcore/onion_client.c +1347 -0
- data/ProjectTox-Core/toxcore/onion_client.h +253 -0
- data/ProjectTox-Core/toxcore/ping.c +346 -0
- data/ProjectTox-Core/toxcore/ping.h +47 -0
- data/ProjectTox-Core/toxcore/ping_array.c +162 -0
- data/ProjectTox-Core/toxcore/ping_array.h +75 -0
- data/ProjectTox-Core/toxcore/tox.c +940 -0
- data/ProjectTox-Core/toxcore/tox.h +734 -0
- data/ProjectTox-Core/toxcore/util.c +193 -0
- data/ProjectTox-Core/toxcore/util.h +63 -0
- data/ProjectTox-Core/toxdns/Makefile.inc +29 -0
- data/ProjectTox-Core/toxdns/toxdns.c +238 -0
- data/ProjectTox-Core/toxdns/toxdns.h +88 -0
- data/ProjectTox-Core/toxencryptsave/Makefile.inc +45 -0
- data/ProjectTox-Core/toxencryptsave/toxencryptsave.c +179 -0
- data/ProjectTox-Core/toxencryptsave/toxencryptsave.h +74 -0
- data/interfaces/libtox.i +2 -6
- data/lib/ffi-tox/libtox.rb +406 -28
- metadata +124 -46
- data/ProjectTox-Core/CMakeLists.txt +0 -50
- data/ProjectTox-Core/cmake/FindLIBCONFIG.cmake +0 -15
- data/ProjectTox-Core/cmake/FindNaCl.cmake +0 -17
- data/ProjectTox-Core/cmake/FindSODIUM.cmake +0 -15
- data/ProjectTox-Core/core/CMakeLists.txt +0 -19
- data/ProjectTox-Core/core/DHT.c +0 -1104
- data/ProjectTox-Core/core/DHT.h +0 -111
- data/ProjectTox-Core/core/LAN_discovery.c +0 -79
- data/ProjectTox-Core/core/Lossless_UDP.c +0 -755
- data/ProjectTox-Core/core/Lossless_UDP.h +0 -106
- data/ProjectTox-Core/core/Messenger.c +0 -596
- data/ProjectTox-Core/core/Messenger.h +0 -165
- data/ProjectTox-Core/core/friend_requests.c +0 -131
- data/ProjectTox-Core/core/friend_requests.h +0 -51
- data/ProjectTox-Core/core/net_crypto.c +0 -575
- data/ProjectTox-Core/core/net_crypto.h +0 -134
- data/ProjectTox-Core/core/network.c +0 -205
- data/ProjectTox-Core/core/network.h +0 -134
- data/ProjectTox-Core/docs/commands.md +0 -25
- data/ProjectTox-Core/docs/start_guide.de.md +0 -40
- data/ProjectTox-Core/docs/start_guide.md +0 -38
- data/ProjectTox-Core/other/CMakeLists.txt +0 -9
- data/ProjectTox-Core/testing/CMakeLists.txt +0 -18
- data/ProjectTox-Core/testing/DHT_cryptosendfiletest.c +0 -228
- data/ProjectTox-Core/testing/DHT_sendfiletest.c +0 -176
- data/ProjectTox-Core/testing/Lossless_UDP_testclient.c +0 -214
- data/ProjectTox-Core/testing/Lossless_UDP_testserver.c +0 -201
- data/ProjectTox-Core/testing/misc_tools.h +0 -29
- data/ProjectTox-Core/testing/nTox_win32.c +0 -387
- data/ProjectTox-Core/testing/nTox_win32.h +0 -40
- 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
|
+
}
|