mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Some work on the onion part done.
This commit is contained in:
parent
d46891c3b7
commit
7e2d21271a
|
@ -10,7 +10,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "../toxcore/onion.h"
|
#include "../toxcore/onion.h"
|
||||||
|
#include "../toxcore/onion_announce.h"
|
||||||
|
|
||||||
void do_onion(Onion *onion)
|
void do_onion(Onion *onion)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,7 @@ static int handle_test_1(void *object, IP_Port source, uint8_t *packet, uint32_t
|
||||||
if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0)
|
if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (send_onion_response(onion->net, source, "install gentoo", sizeof("install gentoo"),
|
if (send_onion_response(onion->net, source, (uint8_t *)"install gentoo", sizeof("install gentoo"),
|
||||||
packet + sizeof("Install Gentoo")) == -1)
|
packet + sizeof("Install Gentoo")) == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -40,12 +40,13 @@ static int handle_test_2(void *object, IP_Port source, uint8_t *packet, uint32_t
|
||||||
if (length != sizeof("install Gentoo"))
|
if (length != sizeof("install Gentoo"))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (memcmp(packet, "install gentoo", sizeof("install gentoo")) != 0)
|
if (memcmp(packet, (uint8_t *)"install gentoo", sizeof("install gentoo")) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
handled_test_2 = 1;
|
handled_test_2 = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(test_basic)
|
START_TEST(test_basic)
|
||||||
{
|
{
|
||||||
IP ip;
|
IP ip;
|
||||||
|
@ -71,7 +72,7 @@ START_TEST(test_basic)
|
||||||
nodes[1] = n2;
|
nodes[1] = n2;
|
||||||
nodes[2] = n1;
|
nodes[2] = n1;
|
||||||
nodes[3] = n2;
|
nodes[3] = n2;
|
||||||
int ret = send_onion_packet(onion1, nodes, "Install Gentoo", sizeof("Install Gentoo"));
|
int ret = send_onion_packet(onion1, nodes, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
|
||||||
ck_assert_msg(ret == 0, "Failed to create/send onion packet.");
|
ck_assert_msg(ret == 0, "Failed to create/send onion packet.");
|
||||||
|
|
||||||
handled_test_1 = 0;
|
handled_test_1 = 0;
|
||||||
|
@ -91,6 +92,12 @@ START_TEST(test_basic)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_announce)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
#define DEFTESTCASE(NAME) \
|
#define DEFTESTCASE(NAME) \
|
||||||
TCase *tc_##NAME = tcase_create(#NAME); \
|
TCase *tc_##NAME = tcase_create(#NAME); \
|
||||||
|
@ -105,6 +112,7 @@ Suite *onion_suite(void)
|
||||||
Suite *s = suite_create("Onion");
|
Suite *s = suite_create("Onion");
|
||||||
|
|
||||||
DEFTESTCASE_SLOW(basic, 5);
|
DEFTESTCASE_SLOW(basic, 5);
|
||||||
|
DEFTESTCASE_SLOW(announce, 5);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,8 +104,9 @@ encrypted (with our real long term private key if we want to announce ourselves,
|
||||||
add the part used to send data to our list (if the list is full make it replace the furthest entry))
|
add the part used to send data to our list (if the list is full make it replace the furthest entry))
|
||||||
|
|
||||||
data to route request packet:
|
data to route request packet:
|
||||||
[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]encrypted with that temporary private key and the nonce:[data]
|
[uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key]
|
||||||
(if Node D contains the used to send data for, it sends the stuff in this packet as a data to route response packet to the right node)
|
encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
|
||||||
|
(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)
|
||||||
|
|
||||||
Data sent to us:
|
Data sent to us:
|
||||||
announce response packet:
|
announce response packet:
|
||||||
|
@ -114,8 +115,8 @@ encrypted with the DHT private key of Node D, the public key in the request and
|
||||||
(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node)
|
(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node)
|
||||||
|
|
||||||
data to route response packet:
|
data to route response packet:
|
||||||
[uint8_t packet id (134)][nonce]encrypted with that temporary private key and the nonce:[data]
|
[uint8_t packet id (134)][nonce][temporary just generated public key]
|
||||||
|
encrypted with that temporary private key and the nonce and the real public key of the destination node:[data]
|
||||||
Onion packet (response):
|
Onion packet (response):
|
||||||
|
|
||||||
initial (sent from node D to node C):
|
initial (sent from node D to node C):
|
||||||
|
|
|
@ -31,6 +31,8 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
|
||||||
../toxcore/assoc.c \
|
../toxcore/assoc.c \
|
||||||
../toxcore/onion.h \
|
../toxcore/onion.h \
|
||||||
../toxcore/onion.c \
|
../toxcore/onion.c \
|
||||||
|
../toxcore/onion_announce.h \
|
||||||
|
../toxcore/onion_announce.c \
|
||||||
../toxcore/misc_tools.h
|
../toxcore/misc_tools.h
|
||||||
|
|
||||||
libtoxcore_la_CFLAGS = -I$(top_srcdir) \
|
libtoxcore_la_CFLAGS = -I$(top_srcdir) \
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef ONION_H
|
||||||
|
#define ONION_H
|
||||||
|
|
||||||
#include "DHT.h"
|
#include "DHT.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -58,3 +61,6 @@ int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint3
|
||||||
Onion *new_onion(DHT *dht);
|
Onion *new_onion(DHT *dht);
|
||||||
|
|
||||||
void kill_onion(Onion *onion);
|
void kill_onion(Onion *onion);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES)
|
#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES)
|
||||||
#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
|
#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
|
||||||
|
|
||||||
|
#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES + ONION_RETURN_3)
|
||||||
|
|
||||||
/* Generate a ping_id and put it in ping_id */
|
/* Generate a ping_id and put it in ping_id */
|
||||||
static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret,
|
static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret,
|
||||||
uint8_t *ping_id)
|
uint8_t *ping_id)
|
||||||
|
@ -47,26 +49,89 @@ static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *pu
|
||||||
crypto_hash_sha256(ping_id, data, sizeof(data));
|
crypto_hash_sha256(ping_id, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if public key is in entries list
|
||||||
|
*
|
||||||
|
* return -1 if no
|
||||||
|
* return position in list if yes
|
||||||
|
*/
|
||||||
|
static int in_entries(Onion_Announce *onion_a, uint8_t *public_key)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
|
||||||
|
if (!is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)
|
||||||
|
&& memcpy(onion_a->entries[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cmp_public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
static int cmp_entry(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
Onion_Announce_Entry entry1, entry2;
|
||||||
|
memcpy(&entry1, a, sizeof(Onion_Announce_Entry));
|
||||||
|
memcpy(&entry2, b, sizeof(Onion_Announce_Entry));
|
||||||
|
int t1 = is_timeout(entry1.time, ONION_ANNOUNCE_TIMEOUT);
|
||||||
|
int t2 = is_timeout(entry2.time, ONION_ANNOUNCE_TIMEOUT);
|
||||||
|
|
||||||
|
if (t1 && t2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (t1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (t2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
|
||||||
|
|
||||||
|
if (close == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (close == 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* add entry to entries list
|
/* add entry to entries list
|
||||||
*
|
*
|
||||||
* return 0 if failure
|
* return 0 if failure
|
||||||
* return 1 if added
|
* return 1 if added
|
||||||
*/
|
*/
|
||||||
static int add_to_entries(Onion_Announce *onion_a, uint8_t *public_key, uint8_t *ret)
|
static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret)
|
||||||
{
|
{
|
||||||
|
|
||||||
return 0;
|
int pos = in_entries(onion_a, public_key);
|
||||||
}
|
|
||||||
|
|
||||||
/* check if public key is in entries list
|
uint32_t i;
|
||||||
*
|
|
||||||
* return 0 if no
|
|
||||||
* return 1 if yes
|
|
||||||
*/
|
|
||||||
static int in_entries(Onion_Announce *onion_a, uint8_t *public_key)
|
|
||||||
{
|
|
||||||
|
|
||||||
return 0;
|
if (pos == -1) {
|
||||||
|
for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
|
||||||
|
if (is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT))
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos == -1) {
|
||||||
|
if (id_closest(onion_a->dht->self_public_key, public_key, onion_a->entries[0].public_key) == 1)
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
||||||
|
onion_a->entries[pos].ret_ip_port = ret_ip_port;
|
||||||
|
memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
|
||||||
|
onion_a->entries[pos].time = unix_time();
|
||||||
|
|
||||||
|
memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||||
|
qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
|
||||||
|
@ -95,10 +160,10 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
|
||||||
int stored = 0;
|
int stored = 0;
|
||||||
|
|
||||||
if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) {
|
if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) {
|
||||||
stored = add_to_entries(onion_a, packet + 1 + crypto_box_NONCEBYTES,
|
stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
|
||||||
packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3));
|
packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3));
|
||||||
} else {
|
} else {
|
||||||
stored = in_entries(onion_a, plain + PING_ID_SIZE);
|
stored = (in_entries(onion_a, plain + PING_ID_SIZE) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Respond with a announce response packet*/
|
/*Respond with a announce response packet*/
|
||||||
|
@ -138,6 +203,25 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui
|
||||||
{
|
{
|
||||||
Onion_Announce *onion_a = object;
|
Onion_Announce *onion_a = object;
|
||||||
|
|
||||||
|
if (length <= DATA_REQUEST_MIN_SIZE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (length >= MAX_DATA_SIZE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int index = in_entries(onion_a, packet + 1);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
uint8_t data[length - (crypto_box_PUBLICKEYBYTES + ONION_RETURN_3)];
|
||||||
|
data[0] = NET_PACKET_ONION_DATA_RESPONSE;
|
||||||
|
memcpy(data + 1, packet + 1 + crypto_box_PUBLICKEYBYTES, length - (1 + crypto_box_PUBLICKEYBYTES + ONION_RETURN_3));
|
||||||
|
|
||||||
|
if (send_onion_response(onion_a->net, onion_a->entries[index].ret_ip_port, data, sizeof(data),
|
||||||
|
onion_a->entries[index].ret) == -1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,17 +20,25 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef ONION_ANNOUNCE_H
|
||||||
|
#define ONION_ANNOUNCE_H
|
||||||
|
|
||||||
#include "onion.h"
|
#include "onion.h"
|
||||||
|
|
||||||
#define ONION_ANNOUNCE_MAX_ENTRIES 32
|
#define ONION_ANNOUNCE_MAX_ENTRIES 32
|
||||||
|
#define ONION_ANNOUNCE_TIMEOUT 300
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
IP_Port ret_ip_port;
|
||||||
|
uint8_t ret[ONION_RETURN_3];
|
||||||
|
uint64_t time;
|
||||||
|
} Onion_Announce_Entry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DHT *dht;
|
DHT *dht;
|
||||||
Networking_Core *net;
|
Networking_Core *net;
|
||||||
struct {
|
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
|
||||||
IP_Port first;
|
|
||||||
uint8_t ret[ONION_RETURN_3];
|
|
||||||
} entries[ONION_ANNOUNCE_MAX_ENTRIES];
|
|
||||||
/* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */
|
/* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */
|
||||||
uint8_t secret_bytes[crypto_secretbox_KEYBYTES];
|
uint8_t secret_bytes[crypto_secretbox_KEYBYTES];
|
||||||
} Onion_Announce;
|
} Onion_Announce;
|
||||||
|
@ -40,3 +48,6 @@ typedef struct {
|
||||||
Onion_Announce *new_onion_announce(DHT *dht);
|
Onion_Announce *new_onion_announce(DHT *dht);
|
||||||
|
|
||||||
void kill_onion_announce(Onion_Announce *onion_a);
|
void kill_onion_announce(Onion_Announce *onion_a);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user