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,59 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
if [ -z "$ANDROID_NDK_HOME" ]; then
|
4
|
+
echo "You should probably set ANDROID_NDK_HOME to the directory containing"
|
5
|
+
echo "the Android NDK"
|
6
|
+
exit
|
7
|
+
fi
|
8
|
+
|
9
|
+
if [ -z "$SODIUM_HOME" ]; then
|
10
|
+
echo "You should probably set SODIUM_HOME to the directory containing root sodium sources"
|
11
|
+
exit
|
12
|
+
fi
|
13
|
+
|
14
|
+
if [[ -z $TARGET_ARCH ]] || [[ -z $HOST_COMPILER ]]; then
|
15
|
+
echo "You shouldn't use android-build.sh directly, use android-[arch].sh instead"
|
16
|
+
exit 1
|
17
|
+
fi
|
18
|
+
|
19
|
+
if [ ! -f ./configure ]; then
|
20
|
+
echo "Can't find ./configure. Wrong directory or haven't run autogen.sh?"
|
21
|
+
exit 1
|
22
|
+
fi
|
23
|
+
|
24
|
+
if [ -z "$TOOLCHAIN_DIR" ]; then
|
25
|
+
export TOOLCHAIN_DIR="$(pwd)/android-toolchain-${TARGET_ARCH}"
|
26
|
+
export MAKE_TOOLCHAIN="${ANDROID_NDK_HOME}/build/tools/make-standalone-toolchain.sh"
|
27
|
+
|
28
|
+
if [ -z "$MAKE_TOOLCHAIN" ]; then
|
29
|
+
echo "Cannot find a make-standalone-toolchain.sh in ndk dir, interrupt..."
|
30
|
+
exit 1
|
31
|
+
fi
|
32
|
+
|
33
|
+
$MAKE_TOOLCHAIN --platform="${NDK_PLATFORM:-android-14}" \
|
34
|
+
--arch="${TARGET_ARCH}" \
|
35
|
+
--toolchain="${TOOLCHAIN_NAME:-arm-linux-androideabi-4.8}" \
|
36
|
+
--install-dir="${TOOLCHAIN_DIR}"
|
37
|
+
fi
|
38
|
+
|
39
|
+
export PREFIX="$(pwd)/toxcore-android-${TARGET_ARCH}"
|
40
|
+
export SYSROOT="${TOOLCHAIN_DIR}/sysroot"
|
41
|
+
export PATH="${PATH}:${TOOLCHAIN_DIR}/bin"
|
42
|
+
|
43
|
+
# Clean up before build
|
44
|
+
rm -rf "${PREFIX}"
|
45
|
+
|
46
|
+
export CFLAGS="${CFLAGS} --sysroot=${SYSROOT} -I${SYSROOT}/usr/include"
|
47
|
+
export CPPFLAGS="${CFLAGS}"
|
48
|
+
export LDFLAGS="${LDFLAGS} -L${SYSROOT}/usr/lib"
|
49
|
+
|
50
|
+
./configure --host="${HOST_COMPILER}" \
|
51
|
+
--with-sysroot="${SYSROOT}" \
|
52
|
+
--with-libsodium-headers="${SODIUM_HOME}/libsodium-android-${TARGET_ARCH}/include" \
|
53
|
+
--with-libsodium-libs="${SODIUM_HOME}/libsodium-android-${TARGET_ARCH}/lib" \
|
54
|
+
--disable-av \
|
55
|
+
--prefix="${PREFIX}" && \
|
56
|
+
|
57
|
+
make clean && \
|
58
|
+
make -j3 install && \
|
59
|
+
echo "libtoxcore has been installed into ${PREFIX}"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Massive public group chats.
|
2
|
+
|
3
|
+
Note that not all this document has been implemented: only private (invite only) group chats are currently implemented.
|
4
|
+
|
5
|
+
Everyone generates a short term public private key pair right before joining
|
6
|
+
the chat.
|
7
|
+
|
8
|
+
Note that for public group chats it is impossible to protect the chat from
|
9
|
+
being spied on by a very dedicated attacker, encryption is therefor used as a
|
10
|
+
form of spam/access control.
|
11
|
+
|
12
|
+
## Joining the chats
|
13
|
+
|
14
|
+
|
15
|
+
## Protocol
|
16
|
+
|
17
|
+
|
18
|
+
Node format:
|
19
|
+
See DHT, currently uses the IPv6 Node_format.
|
20
|
+
|
21
|
+
Get nodes (Request):
|
22
|
+
Packet contents:
|
23
|
+
```
|
24
|
+
[char with a value of 48][Bob's (The receiver's) Public key (client_id) (32 bytes))][Alice's (The sender's) Public key (client_id) (32 bytes)][Random nonce (24 bytes)][Encrypted with the nonce, private key of the sender and public key of the receiver:[char with a value of 48][random 8 byte (ping_id)]
|
25
|
+
```
|
26
|
+
Valid replies: a send_nodes packet
|
27
|
+
|
28
|
+
Send_nodes (response):
|
29
|
+
```
|
30
|
+
[char with a value of 48][Bob's (The receiver's) Public key (client_id) (32 bytes))][Alice's (The sender's) Public key (client_id) (32 bytes)][Random nonce (24 bytes)][Encrypted with the nonce, private key of the sender and public key of the receiver:[char with a value of 49][random 8 byte (ping_id)][Nodes in node format, length=40 * (number of nodes (maximum of 6 nodes)) bytes]]
|
31
|
+
```
|
32
|
+
|
33
|
+
Broadcast packet:
|
34
|
+
```
|
35
|
+
[char with a value of 48][Bob's (The receiver's) Public key (client_id) (32 bytes))][Alice's (The sender's) Public key (client_id) (32 bytes)][nonce][Encrypted with the nonce, private key of the sender and public key of the receiver:[char with a value of 50][Data to send to everyone]]
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
Data to send to everyone:
|
40
|
+
TODO: signing and spam control + permissions.
|
41
|
+
[client_id of sender][uint32_t message number][char with a value representing id of message][data]
|
42
|
+
|
43
|
+
Note: the message number is increased by 1 for each sent message.
|
44
|
+
|
45
|
+
message ids:
|
46
|
+
0 - ping
|
47
|
+
sent every ~60 seconds by every peer.
|
48
|
+
No data.
|
49
|
+
|
50
|
+
16 - new_peer
|
51
|
+
Tell everyone about a new peer in the chat.
|
52
|
+
[uint8_t public_key[public_key_len]]
|
53
|
+
|
54
|
+
17 - ban_peer
|
55
|
+
Ban a peer
|
56
|
+
[uint8_t public_key[public_key_len]]
|
57
|
+
|
58
|
+
18 - topic change
|
59
|
+
[uint8_t topic[topiclen]]
|
60
|
+
|
61
|
+
48 - name change
|
62
|
+
[uint8_t name[namelen]]
|
63
|
+
|
64
|
+
49 - status change
|
65
|
+
[uint8_t (status id)]
|
66
|
+
|
67
|
+
64 - chat message
|
68
|
+
[uint8_t message[messagelen]]
|
69
|
+
|
70
|
+
65 - action (/me)
|
71
|
+
[uint8_t message[messagelen]]
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Currently an attacker with sufficient resources could launch a large scale
|
2
|
+
denial of service type attack by flooding the Tox network with a bunch of nodes
|
3
|
+
that do not act like real nodes to prevent people from finding each other.
|
4
|
+
|
5
|
+
Due to the design of Tox, this is the worst thing an attacker can do to disrupt
|
6
|
+
the network.
|
7
|
+
|
8
|
+
This solution's goal is to make these denial of service attack very very hard
|
9
|
+
to accomplish.
|
10
|
+
|
11
|
+
For the network to work every Tox node must:
|
12
|
+
1. Respond to ping requests.
|
13
|
+
2. Respond to get node requests with the ids of nodes closest to a queried id
|
14
|
+
(It is assumed each nodes know at least the 32 nodes closest to them.)
|
15
|
+
3. Properly send crypto request packets to their intended destination.
|
16
|
+
|
17
|
+
Currently the only thing a node needs to do to be part of the network is
|
18
|
+
respond correctly to ping requests.
|
19
|
+
|
20
|
+
The only people we really trust on the network are the nodes in our friends
|
21
|
+
list.
|
22
|
+
|
23
|
+
|
24
|
+
The behavior of each Tox node is easily predictable. This means that it possible
|
25
|
+
for Tox nodes to test the nodes that they are connected to to see if they
|
26
|
+
behave like normal Tox nodes and only send nodes that are confirmed to behave
|
27
|
+
like real Tox nodes as part of send node replies when other nodes query them.
|
28
|
+
|
29
|
+
If correctly done, this means that to poison the network an attacker can only
|
30
|
+
infiltrate the network if his "fake" nodes behave exactly like real nodes
|
31
|
+
completely defeating the purpose of the attack. Of course nodes must be
|
32
|
+
rechecked regularly to defeat an attack where someone floods the network with
|
33
|
+
many good nodes then suddenly turns them all bad.
|
34
|
+
|
35
|
+
This also prevents someone from accidentally killing the tox network with a bad
|
36
|
+
implementation of the protocol.
|
37
|
+
|
38
|
+
Implementation ideas (In Progress):
|
39
|
+
|
40
|
+
1. Use our friends to check if the nodes in our close list are good.
|
41
|
+
|
42
|
+
EX: If our friend queries a node close to us and it correctly returns our
|
43
|
+
ip/port and then sends a crypto request packet to it and it routes it correctly
|
44
|
+
to us then it is good.
|
45
|
+
|
46
|
+
Problems with this: People don't always have at least one online friend.
|
47
|
+
|
48
|
+
2. Pick random nodes (add ourselves some random (fake) friends to increase the
|
49
|
+
pool of available nodes) and make then send requests to other nodes, the
|
50
|
+
response is then relayed back to us and compared to how the node should have
|
51
|
+
behaved. If the node is found to be behaving correctly, it is set as trusted.
|
52
|
+
Only trusted nodes are sent in send node packets, that is unless the exact node
|
53
|
+
being queried for in the getnode packet is present, it will be sent in the
|
54
|
+
sendnode packet even if it is not trusted.
|
55
|
+
|
56
|
+
The hypothesis is that if to be part of the network nodes have to behave
|
57
|
+
correctly it should prevent disruption from nodes that behave incorrectly.
|
58
|
+
|
59
|
+
(This idea is currently being implemented in the harden branch.)
|
60
|
+
...
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Hardening request packets are sent as crypto request packets (see crypto docs.)
|
2
|
+
NOTE: currently only get nodes requests are tested in the code which is why
|
3
|
+
there is only one test (more will be added soon.)
|
4
|
+
|
5
|
+
All hardening requests must contain exactly 768 bytes of data. (The data sent
|
6
|
+
must be padded with zeros if it is smaller than that.)
|
7
|
+
|
8
|
+
1. Get the information (IP_port, client_id) of the node we want to test.
|
9
|
+
2. Find a couple random nodes that is not that node (one for each test.)
|
10
|
+
3. Send crypto request packets to each of these random nodes with the data being:
|
11
|
+
|
12
|
+
[byte with value: 02 (get nodes test request)][struct Node_format (the node to
|
13
|
+
test.)][client_id(32 bytes) the id to query the node with.][padding]
|
14
|
+
|
15
|
+
4. The random node receives a packet.
|
16
|
+
-The packet is a get nodes test request:
|
17
|
+
send a get_node request to that node with the id to query in the request.
|
18
|
+
when a send_node response is received, send the following response to the
|
19
|
+
person who sent us the get nodes test request packet:
|
20
|
+
[byte with value: 03 (get nodes test response)][client_id(32 bytes):
|
21
|
+
the id of the tested node][The list of nodes it responded with in IPv6
|
22
|
+
Node format (struct Node_Format)]
|
23
|
+
PROTIP: (get node requests and response contain an encrypted part that you
|
24
|
+
can use to store information so that you don't
|
25
|
+
have to store in your memory where/if to send back the response from the
|
26
|
+
send node)
|
27
|
+
|
28
|
+
5. Receive the test responses.
|
29
|
+
-If the test(s) pass (the nodes behave in a satisfactory manner), make these
|
30
|
+
nodes have priority over those who don't pass the test(s).
|
@@ -0,0 +1,160 @@
|
|
1
|
+
Current privacy issues with the Tox DHT:
|
2
|
+
|
3
|
+
1. It makes tracking people across different IPs very easy.
|
4
|
+
Solution: Have each new DHT use a temporary public/private key pair not related
|
5
|
+
to the long term public/private key pair.
|
6
|
+
|
7
|
+
2. Metadata on which key is friends to which can be collected (The hardening
|
8
|
+
makes this somewhat harder by introducing a bunch of random traffic but not
|
9
|
+
impossible.).
|
10
|
+
Solution: If no long term keys were used in the DHT it would solve this
|
11
|
+
problem. (possibly knowing which ip is connected to which is much less
|
12
|
+
precious.)
|
13
|
+
|
14
|
+
|
15
|
+
So, it seems all our privacy problems are solved if we can manage to make every
|
16
|
+
node in the DHT have a keypair that is not related to the long term keys and is
|
17
|
+
generated every session.
|
18
|
+
|
19
|
+
|
20
|
+
So, every node in the DHT now has a temporary keypair not related to their real
|
21
|
+
long term one.
|
22
|
+
|
23
|
+
But, how do people find themselves then? We have to add a way for people to
|
24
|
+
tell their friends what their DHT public key is. We also have to somehow make
|
25
|
+
it so people can send/receive friend requests. This has to be done without
|
26
|
+
non-friends being able to find out where a node is.
|
27
|
+
|
28
|
+
The solution: Onion routing + enable the storage of some small amount of data
|
29
|
+
on DHT nodes.
|
30
|
+
|
31
|
+
|
32
|
+
Alice and bob are friends. Before joining the DHT they generate temporary
|
33
|
+
session keypairs to be used for the DHT instead of their long term keys.
|
34
|
+
|
35
|
+
Bob finds a bunch of random nodes then picks 3 random working ones (A, B, C).
|
36
|
+
|
37
|
+
Bob gets the known working node with an id closest to his real one from his list (D)
|
38
|
+
|
39
|
+
Bob then creates an onion (the packet will go through A, B, C and will end up at D)
|
40
|
+
announce request packet with his real public key, ping_id as zeros and
|
41
|
+
searching for his real public key.
|
42
|
+
|
43
|
+
Bob will announce response packets and will recursively send onion announce request
|
44
|
+
packets to closer and closer nodes until he finds the ones closest to his real public key.
|
45
|
+
|
46
|
+
Once he has done this, he will send some onion announce request packets with the right
|
47
|
+
ping_id previously received from the node when he queried it to announce himself to the node.
|
48
|
+
|
49
|
+
The nodes he announces himself to keep the information to send onion packets to that node in
|
50
|
+
memory.
|
51
|
+
|
52
|
+
Alice meanwhile searches for the nodes closest to Bobs real id using a temporary keypair and
|
53
|
+
announce request packets. She does this until she finds nodes that respond with a ping_id of zero.
|
54
|
+
|
55
|
+
She sends data to route request packet with information telling Bob her temporary id in the DHT
|
56
|
+
(or a friend request if she is not friends with him).
|
57
|
+
|
58
|
+
Bob finds her by using her temporary id and they connect to each other.
|
59
|
+
|
60
|
+
|
61
|
+
NOTE: crypto_box is used for all the asymmetric encryption and crypto_secretbox is used for all
|
62
|
+
the symmetric. Also every DHT node have a random symmetric key which they use to encrypt the stuff
|
63
|
+
in normal get node request that is used to encrypt stuff in the following.
|
64
|
+
|
65
|
+
Onion packet (request):
|
66
|
+
|
67
|
+
initial (sent from us to node A):
|
68
|
+
|
69
|
+
[uint8_t packet id (128)][nonce]
|
70
|
+
[our temp DHT public key]encrypted with our temp DHT private key and the pub key of Node A and the nonce:[
|
71
|
+
[IP_Port of node B][a random public key]encrypted with the random private key and the pub key of Node B and the nonce:[
|
72
|
+
[IP_Port of node C][a random public key]encrypted with the random private key and the pub key of Node C and the nonce:[
|
73
|
+
[IP_Port of node D][data to send to Node D]]]]
|
74
|
+
|
75
|
+
(sent from node A to node B):
|
76
|
+
|
77
|
+
[uint8_t packet id (129)][nonce]
|
78
|
+
[a random public key]encrypted with the random private key and the pub key of Node B and the nonce:[
|
79
|
+
[IP_Port of node C][a random public key]encrypted with the random private key and the pub key of Node C and the nonce:[
|
80
|
+
[IP_Port of node D][data to send to Node D]]][nonce (for the following symmetric encryption)]encrypted with temp symmetric key of Node A: [IP_Port (of us)]
|
81
|
+
|
82
|
+
(sent from node B to node C):
|
83
|
+
|
84
|
+
[uint8_t packet id (130)][nonce]
|
85
|
+
[a random public key]encrypted with the random private key and the pub key of Node C and the nonce:[
|
86
|
+
[IP_Port of node D][data to send to Node D]][nonce (for the following symmetric encryption)]
|
87
|
+
encrypted with temp symmetric key of Node B:[IP_Port (of Node A)[nonce (for the following symmetric encryption)]
|
88
|
+
encrypted with temp symmetric key of Node A: [IP_Port (of us)]]
|
89
|
+
|
90
|
+
(sent from node C to node D):
|
91
|
+
[data to send to Node D][nonce (for the following symmetric encryption)]encrypted with temp symmetric key of Node C:
|
92
|
+
[IP_Port (of Node B)[nonce (for the following symmetric encryption)]
|
93
|
+
encrypted with temp symmetric key of Node B:[IP_Port (of Node A)[nonce (for the following symmetric encryption)]
|
94
|
+
encrypted with temp symmetric key of Node A: [IP_Port (of us)]]]
|
95
|
+
|
96
|
+
Data sent to Node D:
|
97
|
+
|
98
|
+
announce request packet:
|
99
|
+
[uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)]
|
100
|
+
encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:
|
101
|
+
[[(32 bytes) ping_id][client id we are searching for][public key that we want those sending back data packets to use.][data to send back in response(fixed size)]]
|
102
|
+
|
103
|
+
(if the ping id is zero, respond with a announce response packet)
|
104
|
+
(If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for,
|
105
|
+
add the part used to send data to our list (if the list is full make it replace the furthest entry))
|
106
|
+
|
107
|
+
data to route request packet:
|
108
|
+
[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]
|
109
|
+
encrypted with that temporary private key and the nonce and the public key from the announce response packet of the destination node:[data]
|
110
|
+
(if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node)
|
111
|
+
|
112
|
+
The data in the previous packet is in format: [real public key of sender]
|
113
|
+
encrypted with real private key of the sender, the nonce in the data packet and
|
114
|
+
the real public key of the receiver:[[uint8_t id][data (optional)]]
|
115
|
+
|
116
|
+
Data sent to us:
|
117
|
+
announce response packet:
|
118
|
+
[uint8_t packet id (132)][data to send back in response(fixed size)][nonce]
|
119
|
+
encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[uint8_t is_stored]
|
120
|
+
[(32 bytes) ping_id if is_stored is 0 or 2, public key that must be used to send data packets if is_stored is 1][Node_Format * (maximum of 8)]]
|
121
|
+
(if the is_stored is not 0, it means the information to reach the client id we are searching for is stored on this node)
|
122
|
+
is_stored is 2 as a response to a peer trying to announce himself to tell the
|
123
|
+
peer that he is currently announced successfully.
|
124
|
+
|
125
|
+
data to route response packet:
|
126
|
+
[uint8_t packet id (134)][nonce][temporary just generated public key]
|
127
|
+
encrypted with that temporary private key, the nonce and the public key from the announce response packet of the destination node:[data]
|
128
|
+
|
129
|
+
|
130
|
+
Onion packet (response):
|
131
|
+
|
132
|
+
initial (sent from node D to node C):
|
133
|
+
|
134
|
+
[uint8_t packet id (140)][nonce (for the following symmetric encryption)]encrypted with temp symmetric key of Node C:
|
135
|
+
[IP_Port (of Node B)[nonce (for the following symmetric encryption)]
|
136
|
+
encrypted with temp symmetric key of Node B:[IP_Port (of Node A)[nonce (for the following symmetric encryption)]
|
137
|
+
encrypted with temp symmetric key of Node A: [IP_Port (of us)]]][data to send back]
|
138
|
+
|
139
|
+
(sent from node C to node B):
|
140
|
+
|
141
|
+
[uint8_t packet id (141)][nonce (for the following symmetric encryption)]
|
142
|
+
encrypted with temp symmetric key of Node B:[IP_Port (of Node A)[nonce (for the following symmetric encryption)]
|
143
|
+
encrypted with temp symmetric key of Node A: [IP_Port (of us)]][data to send back]
|
144
|
+
|
145
|
+
(sent from node B to node A):
|
146
|
+
|
147
|
+
[uint8_t packet id (142)][nonce (for the following symmetric encryption)]
|
148
|
+
encrypted with temp symmetric key of Node A: [IP_Port (of us)][data to send back]
|
149
|
+
|
150
|
+
(sent from node A to us):
|
151
|
+
|
152
|
+
[data to send back]
|
153
|
+
|
154
|
+
|
155
|
+
Data packets:
|
156
|
+
|
157
|
+
To tell our friend what our DHT public key is so that he can connect to us we send a data packet
|
158
|
+
with id 156 and the data being:[uint64_t (in network byte order) no_replay, the packet will only be
|
159
|
+
accepted if this number is bigger than the last one received] [our dht public key][Node_Format * (
|
160
|
+
maximum of 8) nodes closest to us so that the friend can find us faster]
|
@@ -0,0 +1,154 @@
|
|
1
|
+
It has come to our attention that to achieve decent market penetration Tox
|
2
|
+
must work behind ALL internet connections, may they be behind enterprise NATs
|
3
|
+
or any other bad network conditions.
|
4
|
+
|
5
|
+
The people who have issues with the UDP direct connection approach seem to be a
|
6
|
+
small minority though it is hard to estimate how many.
|
7
|
+
|
8
|
+
This means that routing their packets using good nodes on the network will
|
9
|
+
probably not take a huge toll on the network and will assure that people
|
10
|
+
can use Tox regardless of the quality of their internet connection.
|
11
|
+
|
12
|
+
|
13
|
+
How it's going to work:
|
14
|
+
1. Alice, a Tox client on a TCP only network generates a temporary public key
|
15
|
+
and connects to a bootstrap node.
|
16
|
+
|
17
|
+
2. Using the bootstrap node she finds and connects to a couple (exact number
|
18
|
+
to be determined later) number of random nodes that have TCP relay support.
|
19
|
+
|
20
|
+
3. She uses the onion through the TCP relay connections to send friend requests
|
21
|
+
or tell online friends which TCP nodes she is connected to and her temporary
|
22
|
+
public key.
|
23
|
+
|
24
|
+
4. Bob receives an onion packet from Alice telling him which nodes she is
|
25
|
+
connected to. Bob connects to these nodes and establishes a routed connection
|
26
|
+
with alice using that temporary public key.
|
27
|
+
|
28
|
+
5. That connection is used by both to transmit encrypted Messenger and A/V
|
29
|
+
packets.
|
30
|
+
|
31
|
+
6. If one of the nodes shuts down while it is currently routing traffic, Alice
|
32
|
+
and bob just switch to one of the other nodes they are both connected to.
|
33
|
+
|
34
|
+
|
35
|
+
Detailed implementation details:
|
36
|
+
|
37
|
+
There are two distinct parts for TCP relays, the client part and the server
|
38
|
+
part.
|
39
|
+
|
40
|
+
The server acts as the actual relay. Servers must have fully forwarded TCP
|
41
|
+
ports (NAT-PMP and uPNP can help here). The first port the server will try
|
42
|
+
binding to is 443 followed by port 3389 and possibly some others. Onion packets
|
43
|
+
can be sent/received through the TCP servers.
|
44
|
+
|
45
|
+
|
46
|
+
Server:
|
47
|
+
|
48
|
+
The public/private key pair the TCP server uses is the same one he uses for the
|
49
|
+
DHT.
|
50
|
+
|
51
|
+
all crypto for communication with the server uses the crypto_box() function of
|
52
|
+
NaCl.
|
53
|
+
|
54
|
+
TCP doesn't have packets so what we will refer to as packets are sent this way:
|
55
|
+
[[uint16_t (length of data)][data]]
|
56
|
+
|
57
|
+
So if you would inspect the TCP stream you would see:
|
58
|
+
[[uint16_t (length of data)][data]][[uint16_t (length of
|
59
|
+
data)][data]][[uint16_t (length of data)][data]]
|
60
|
+
|
61
|
+
Note that both handshake packets don't have this format (the length for them is
|
62
|
+
always the same so we don't need to specify it.)
|
63
|
+
|
64
|
+
When the client connects to the server, he sends this packet:
|
65
|
+
[public key of client (32 bytes)][nonce for the encrypted data [24
|
66
|
+
bytes]][encrypted with the private key of the client and public key of the
|
67
|
+
server and the nonce:[public key (32 bytes) and][base nonce we want the server
|
68
|
+
to use to encrypt the packets sent to us (24 bytes)]]
|
69
|
+
|
70
|
+
The server responds with:
|
71
|
+
[nonce for the encrypted data [24 bytes]][encrypted with the public key of the
|
72
|
+
client and private key of the server and the nonce:[public key (32 bytes)
|
73
|
+
and][base nonce we want the client to use to encrypt the packets sent to us (24
|
74
|
+
bytes)]]
|
75
|
+
|
76
|
+
All packets to the server are end to end encrypted with the information
|
77
|
+
received
|
78
|
+
(and sent) in the handshake.
|
79
|
+
|
80
|
+
(first packet is encrypted with the base nonce the private key for which the
|
81
|
+
client sent the server the public key and the public key we sent to the client,
|
82
|
+
the next with base nonce + 1...)
|
83
|
+
|
84
|
+
The connection is set to an unconfirmed state until a packet is received and
|
85
|
+
decrypted correctly using the information in the handshake.
|
86
|
+
|
87
|
+
each packet sent to/from the server has an id (the first byte of the plain text
|
88
|
+
data of the packet.)
|
89
|
+
|
90
|
+
ids 0 to 15 are reserved for special packets, ids 16 to 255 are used to denote
|
91
|
+
who we want the data to be routed to/who the packet is from.
|
92
|
+
|
93
|
+
special ids and packets:
|
94
|
+
0 - Routing request.
|
95
|
+
[uint8_t id (0)][public key (32 bytes)]
|
96
|
+
1 - Routing request response.
|
97
|
+
[uint8_t id (1)][uint8_t (rpid) 0 if refused, packet id if accepted][public key
|
98
|
+
(32 bytes)]
|
99
|
+
2 - Connect notification:
|
100
|
+
[uint8_t id (2)][uint8_t (packet id of connection that got connected)]
|
101
|
+
3 - Disconnect notification:
|
102
|
+
[uint8_t id (3)][uint8_t (packet id of connection that got disconnected)]
|
103
|
+
4 - ping packet
|
104
|
+
[uint8_t id (4)][uint64_t ping_id (0 is invalid)]
|
105
|
+
5 - ping response (pong)
|
106
|
+
[uint8_t id (5)][uint64_t ping_id (0 is invalid)]
|
107
|
+
6 - OOB send
|
108
|
+
[uint8_t id (6)][destination public key (32 bytes)][data]
|
109
|
+
7 - OOB recv
|
110
|
+
[uint8_t id (7)][senders public key (32 bytes)][data]
|
111
|
+
8 - onion packet (same format as initial onion packet (See: Prevent
|
112
|
+
tracking.txt) but packet id is 8 instead of 128)
|
113
|
+
9 - onion packet response (same format as onion packet with id 142 but id is 9
|
114
|
+
instead.)
|
115
|
+
|
116
|
+
The rest of the special ids are reserved for possible future usage.
|
117
|
+
|
118
|
+
If the server receives a routing request he stores server side that the client
|
119
|
+
wants to connect to the person with that public key and sends back a Routing
|
120
|
+
request response with the rpid along with the public key sent in the request.
|
121
|
+
|
122
|
+
If for some reason the server must refuse the routing request (too many) he
|
123
|
+
sends the response with a rpid of 0.
|
124
|
+
|
125
|
+
If the person who the client wants to connect to is also online and wants to
|
126
|
+
connect to the client a connect notification is sent to both with the
|
127
|
+
appropriate packet id.
|
128
|
+
|
129
|
+
If either one disconnects, a disconnect notification is sent to the other with
|
130
|
+
appropriate packet id.
|
131
|
+
|
132
|
+
If a client sends a disconnect notification, the entry on the server for that
|
133
|
+
routed connection is cleared and a disconnect notification is sent to the peer
|
134
|
+
(if he was online)
|
135
|
+
|
136
|
+
If the server receives an onion packet he handles it the same as he would if it
|
137
|
+
was one received normally via UDP, he must also assure himself that any
|
138
|
+
responses must be sent to the proper client.
|
139
|
+
|
140
|
+
Ping responses must have the same ping_id as the request.
|
141
|
+
|
142
|
+
If the server receives a ping packet he must respond with a ping response.
|
143
|
+
|
144
|
+
The server will send a ping packet to clients every 30 seconds, they have 30
|
145
|
+
seconds to respond, if they don't the connection is deleted.
|
146
|
+
|
147
|
+
OOB send packets will be sent to the peer connected to the TCP server with the
|
148
|
+
destination public key as a OOB recv packet. The client sending this packet has
|
149
|
+
no way of knowing if the packet reached its destination.
|
150
|
+
|
151
|
+
|
152
|
+
Client:
|
153
|
+
|
154
|
+
Implementation details coming soon.
|