mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
First part of DHT hardening done.
Added crypto to the DHT communications. This defeats completely the first attack mentioned in docs/DHT_hardening. Also updated the build system to build the latest test (it links it with libsodium)
This commit is contained in:
parent
e830861a9d
commit
79aa715514
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.travis.yml
|
|
||||||
|
|
||||||
//nacl build
|
//nacl build
|
||||||
nacl/build/
|
nacl/build/
|
||||||
|
|
|
@ -2,6 +2,15 @@ language: c
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- git clone git://github.com/jedisct1/libsodium.git
|
||||||
|
- cd libsodium
|
||||||
|
- ./autogen.sh
|
||||||
|
- ./configure && make check
|
||||||
|
- sudo make install
|
||||||
|
- sudo ldconfig
|
||||||
|
- cd ..
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cmake CMakeLists.txt
|
- cmake CMakeLists.txt
|
||||||
- make -j3
|
- make -j3
|
||||||
|
|
|
@ -2,14 +2,19 @@ cmake_minimum_required(VERSION 2.6.0)
|
||||||
project(TOX C)
|
project(TOX C)
|
||||||
|
|
||||||
set(core_sources
|
set(core_sources
|
||||||
#core/DHT.c
|
core/DHT.c
|
||||||
core/network.c)
|
core/network.c
|
||||||
|
core/Lossless_UDP.c
|
||||||
|
core/net_crypto.c
|
||||||
|
core/Messenger.c)
|
||||||
|
|
||||||
set(test_sources
|
set(test_sources
|
||||||
testing/DHT_test.c)
|
testing/Messenger_test.c)
|
||||||
|
|
||||||
set(exe_name TOX-app)
|
set(exe_name TOX-app)
|
||||||
|
|
||||||
|
target_link_libraries(sodium)
|
||||||
|
|
||||||
add_executable(${exe_name}
|
add_executable(${exe_name}
|
||||||
${core_sources}
|
${core_sources}
|
||||||
${test_sources})
|
${test_sources})
|
||||||
|
|
275
core/DHT.c
275
core/DHT.c
|
@ -54,36 +54,36 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IP_Port ip_port;
|
IP_Port ip_port;
|
||||||
uint32_t ping_id;
|
uint64_t ping_id;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
|
|
||||||
}Pinged;
|
}Pinged;
|
||||||
|
|
||||||
|
//Our client id/public key
|
||||||
uint8_t self_client_id[CLIENT_ID_SIZE];
|
uint8_t self_public_key[CLIENT_ID_SIZE];
|
||||||
|
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
|
||||||
|
|
||||||
//TODO: Move these out of here and put them into the .c file.
|
//TODO: Move these out of here and put them into the .c file.
|
||||||
//A list of the clients mathematically closest to ours.
|
//A list of the clients mathematically closest to ours.
|
||||||
#define LCLIENT_LIST 32
|
#define LCLIENT_LIST 32
|
||||||
Client_data close_clientlist[LCLIENT_LIST];
|
static Client_data close_clientlist[LCLIENT_LIST];
|
||||||
|
|
||||||
|
|
||||||
//Hard maximum number of friends
|
//Hard maximum number of friends
|
||||||
#define MAX_FRIENDS 256
|
#define MAX_FRIENDS 256
|
||||||
|
|
||||||
//Let's start with a static array for testing.
|
//Let's start with a static array for testing.
|
||||||
Friend friends_list[MAX_FRIENDS];
|
static Friend friends_list[MAX_FRIENDS];
|
||||||
uint16_t num_friends;
|
static uint16_t num_friends;
|
||||||
|
|
||||||
//The list of ip ports along with the ping_id of what we sent them and a timestamp
|
//The list of ip ports along with the ping_id of what we sent them and a timestamp
|
||||||
#define LPING_ARRAY 128
|
#define LPING_ARRAY 128
|
||||||
|
|
||||||
Pinged pings[LPING_ARRAY];
|
static Pinged pings[LPING_ARRAY];
|
||||||
|
|
||||||
#define LSEND_NODES_ARRAY LPING_ARRAY/2
|
#define LSEND_NODES_ARRAY LPING_ARRAY/2
|
||||||
|
|
||||||
Pinged send_nodes[LSEND_NODES_ARRAY];
|
static Pinged send_nodes[LSEND_NODES_ARRAY];
|
||||||
|
|
||||||
|
|
||||||
//Compares client_id1 and client_id2 with client_id
|
//Compares client_id1 and client_id2 with client_id
|
||||||
|
@ -298,7 +298,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
||||||
if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
|
if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
|
||||||
{
|
{
|
||||||
//if we can't replace bad nodes we try replacing good ones
|
//if we can't replace bad nodes we try replacing good ones
|
||||||
replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_client_id);
|
replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
||||||
if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
|
if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
|
||||||
{
|
{
|
||||||
//if we can't replace bad nodes we try replacing good ones
|
//if we can't replace bad nodes we try replacing good ones
|
||||||
replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_client_id);
|
replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_public_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
||||||
//if we are already, return 1
|
//if we are already, return 1
|
||||||
//else return 0
|
//else return 0
|
||||||
//TODO: Maybe optimize this
|
//TODO: Maybe optimize this
|
||||||
int is_pinging(IP_Port ip_port, uint32_t ping_id)
|
int is_pinging(IP_Port ip_port, uint64_t ping_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t pinging;
|
uint8_t pinging;
|
||||||
|
@ -364,7 +364,7 @@ int is_pinging(IP_Port ip_port, uint32_t ping_id)
|
||||||
|
|
||||||
|
|
||||||
//Same as last function but for get_node requests.
|
//Same as last function but for get_node requests.
|
||||||
int is_gettingnodes(IP_Port ip_port, uint32_t ping_id)
|
int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t pinging;
|
uint8_t pinging;
|
||||||
|
@ -407,10 +407,10 @@ int is_gettingnodes(IP_Port ip_port, uint32_t ping_id)
|
||||||
//returns the ping_id to put in the ping request
|
//returns the ping_id to put in the ping request
|
||||||
//returns 0 if problem.
|
//returns 0 if problem.
|
||||||
//TODO: Maybe optimize this
|
//TODO: Maybe optimize this
|
||||||
int add_pinging(IP_Port ip_port)
|
uint64_t add_pinging(IP_Port ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
int ping_id = rand();
|
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
||||||
uint32_t temp_time = unix_time();
|
uint32_t temp_time = unix_time();
|
||||||
|
|
||||||
for(i = 0; i < PING_TIMEOUT; i++ )
|
for(i = 0; i < PING_TIMEOUT; i++ )
|
||||||
|
@ -431,10 +431,10 @@ int add_pinging(IP_Port ip_port)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Same but for get node requests
|
//Same but for get node requests
|
||||||
int add_gettingnodes(IP_Port ip_port)
|
uint64_t add_gettingnodes(IP_Port ip_port)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
int ping_id = rand();
|
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
||||||
uint32_t temp_time = unix_time();
|
uint32_t temp_time = unix_time();
|
||||||
|
|
||||||
for(i = 0; i < PING_TIMEOUT; i++ )
|
for(i = 0; i < PING_TIMEOUT; i++ )
|
||||||
|
@ -458,23 +458,38 @@ int add_gettingnodes(IP_Port ip_port)
|
||||||
|
|
||||||
//send a ping request
|
//send a ping request
|
||||||
//Ping request only works if none has been sent to that ip/port in the last 5 seconds.
|
//Ping request only works if none has been sent to that ip/port in the last 5 seconds.
|
||||||
int pingreq(IP_Port ip_port)
|
static int pingreq(IP_Port ip_port, uint8_t * public_key)
|
||||||
{
|
{
|
||||||
|
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(is_pinging(ip_port, 0))
|
if(is_pinging(ip_port, 0))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ping_id = add_pinging(ip_port);
|
uint64_t ping_id = add_pinging(ip_port);
|
||||||
if(ping_id == 0)
|
if(ping_id == 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t data[5 + CLIENT_ID_SIZE];
|
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
|
||||||
|
uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
random_nonce(nonce);
|
||||||
|
|
||||||
|
int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
|
||||||
|
if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
data[0] = 0;
|
data[0] = 0;
|
||||||
memcpy(data + 1, &ping_id, 4);
|
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||||
memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
|
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||||
|
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||||
|
|
||||||
return sendpacket(ip_port, data, sizeof(data));
|
return sendpacket(ip_port, data, sizeof(data));
|
||||||
|
|
||||||
|
@ -482,51 +497,88 @@ int pingreq(IP_Port ip_port)
|
||||||
|
|
||||||
|
|
||||||
//send a ping response
|
//send a ping response
|
||||||
int pingres(IP_Port ip_port, uint32_t ping_id)
|
static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
|
||||||
{
|
{
|
||||||
uint8_t data[5 + CLIENT_ID_SIZE];
|
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself
|
||||||
data[0] = 1;
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(data + 1, &ping_id, 4);
|
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING];
|
||||||
memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
|
uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING];
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
random_nonce(nonce);
|
||||||
|
|
||||||
|
int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
|
||||||
|
if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data[0] = 1;
|
||||||
|
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||||
|
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||||
|
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||||
|
|
||||||
return sendpacket(ip_port, data, sizeof(data));
|
return sendpacket(ip_port, data, sizeof(data));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//send a getnodes request
|
//send a getnodes request
|
||||||
int getnodes(IP_Port ip_port, uint8_t * client_id)
|
static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
|
||||||
{
|
{
|
||||||
|
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(is_gettingnodes(ip_port, 0))
|
if(is_gettingnodes(ip_port, 0))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ping_id = add_gettingnodes(ip_port);
|
uint64_t ping_id = add_gettingnodes(ip_port);
|
||||||
|
|
||||||
if(ping_id == 0)
|
if(ping_id == 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t data[5 + CLIENT_ID_SIZE*2];
|
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
|
||||||
|
uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
|
||||||
|
uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
random_nonce(nonce);
|
||||||
|
|
||||||
|
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||||
|
memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
|
||||||
|
|
||||||
|
int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
|
||||||
|
|
||||||
|
if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
data[0] = 2;
|
data[0] = 2;
|
||||||
|
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||||
memcpy(data + 1, &ping_id, 4);
|
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||||
memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
|
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||||
memcpy(data + 5 + CLIENT_ID_SIZE, client_id, CLIENT_ID_SIZE);
|
|
||||||
|
|
||||||
return sendpacket(ip_port, data, sizeof(data));
|
return sendpacket(ip_port, data, sizeof(data));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//send a send nodes response
|
//send a send nodes response
|
||||||
int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id)
|
static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
|
||||||
{
|
{
|
||||||
uint8_t data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES];
|
if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself
|
||||||
Node_format nodes_list[MAX_SENT_NODES];
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||||
|
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||||
|
|
||||||
|
Node_format nodes_list[MAX_SENT_NODES];
|
||||||
int num_nodes = get_close_nodes(client_id, nodes_list);
|
int num_nodes = get_close_nodes(client_id, nodes_list);
|
||||||
|
|
||||||
if(num_nodes == 0)
|
if(num_nodes == 0)
|
||||||
|
@ -534,13 +586,28 @@ int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
|
||||||
|
uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
|
||||||
|
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||||
|
random_nonce(nonce);
|
||||||
|
|
||||||
|
memcpy(plain, &ping_id, sizeof(ping_id));
|
||||||
|
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
|
||||||
|
|
||||||
|
int len = encrypt_data(public_key, self_secret_key, nonce, plain,
|
||||||
|
sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
|
||||||
|
|
||||||
|
if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
data[0] = 3;
|
data[0] = 3;
|
||||||
|
memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
|
||||||
|
memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
|
||||||
|
memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
|
||||||
|
|
||||||
memcpy(data + 1, &ping_id, 4);
|
return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
|
||||||
memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
|
|
||||||
memcpy(data + 5 + CLIENT_ID_SIZE, nodes_list, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
|
|
||||||
|
|
||||||
return sendpacket(ip_port, data, 5 + CLIENT_ID_SIZE + num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,26 +617,32 @@ int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id)
|
||||||
//Packet handling functions
|
//Packet handling functions
|
||||||
//One to handle each types of packets we receive
|
//One to handle each types of packets we receive
|
||||||
//return 0 if handled correctly, 1 if packet is bad.
|
//return 0 if handled correctly, 1 if packet is bad.
|
||||||
int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested
|
int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
{
|
{
|
||||||
if(length != 5 + CLIENT_ID_SIZE)
|
uint64_t ping_id;
|
||||||
|
if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself.
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ping_id;
|
|
||||||
|
|
||||||
memcpy(&ping_id, packet + 1, 4);
|
|
||||||
IP_Port bad_ip = {{{0}}, 0};
|
|
||||||
|
|
||||||
if(is_pinging(bad_ip, ping_id))//check if packet is from ourself.
|
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||||
|
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||||
|
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||||
|
if(len != sizeof(ping_id))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pingres(source, ping_id);
|
|
||||||
|
|
||||||
pingreq(source);
|
pingres(source, packet + 1, ping_id);
|
||||||
|
|
||||||
|
pingreq(source, packet + 1);//TODO: make this smarter?
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -577,16 +650,29 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested
|
||||||
|
|
||||||
int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
|
int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
{
|
{
|
||||||
if(length != (5 + CLIENT_ID_SIZE))
|
uint64_t ping_id;
|
||||||
|
if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself.
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||||
|
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||||
|
sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
|
||||||
|
if(len != sizeof(ping_id))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint32_t ping_id;
|
|
||||||
|
|
||||||
memcpy(&ping_id, packet + 1, 4);
|
|
||||||
if(is_pinging(source, ping_id))
|
if(is_pinging(source, ping_id))
|
||||||
{
|
{
|
||||||
addto_lists(source, packet + 5);
|
addto_lists(source, packet + 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -595,53 +681,80 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
|
|
||||||
int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
{
|
{
|
||||||
if(length != (5 + CLIENT_ID_SIZE*2))
|
uint64_t ping_id;
|
||||||
|
if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint32_t ping_id;
|
if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself.
|
||||||
memcpy(&ping_id, packet + 1, 4);
|
|
||||||
sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id);
|
|
||||||
|
|
||||||
IP_Port bad_ip = {{{0}}, 0};
|
|
||||||
|
|
||||||
if(is_gettingnodes(bad_ip, ping_id))//check if packet is from ourself.
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pingreq(source);
|
uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
|
||||||
|
|
||||||
|
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||||
|
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||||
|
sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
|
||||||
|
|
||||||
|
if(len != sizeof(ping_id) + CLIENT_ID_SIZE)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(&ping_id, plain, sizeof(ping_id));
|
||||||
|
sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id);
|
||||||
|
|
||||||
|
pingreq(source, packet + 1);//TODO: make this smarter?
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)//tested
|
int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
|
||||||
{
|
{
|
||||||
if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) ||
|
uint64_t ping_id;
|
||||||
(length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0)
|
if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||||
|
+ sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) ||
|
||||||
|
(length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||||
|
+ ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
|
||||||
|
length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
|
||||||
|
+ sizeof(Node_format) + ENCRYPTION_PADDING)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint32_t num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port));
|
uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
|
||||||
uint32_t i;
|
+ sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
|
||||||
uint32_t ping_id;
|
|
||||||
|
|
||||||
memcpy(&ping_id, packet + 1, 4);
|
uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
|
||||||
|
|
||||||
|
int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
|
||||||
|
packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
|
||||||
|
sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
|
||||||
|
|
||||||
|
|
||||||
|
if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&ping_id, plain, sizeof(ping_id));
|
||||||
if(!is_gettingnodes(source, ping_id))
|
if(!is_gettingnodes(source, ping_id))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node_format nodes_list[MAX_SENT_NODES];
|
Node_format nodes_list[MAX_SENT_NODES];
|
||||||
memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
|
memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format));
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
for(i = 0; i < num_nodes; i++)
|
for(i = 0; i < num_nodes; i++)
|
||||||
{
|
{
|
||||||
pingreq(nodes_list[i].ip_port);
|
pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
addto_lists(source, packet + 5);
|
addto_lists(source, packet + 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -772,7 +885,7 @@ void doDHTFriends()
|
||||||
{
|
{
|
||||||
if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time)
|
if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time)
|
||||||
{
|
{
|
||||||
pingreq(friends_list[i].client_list[j].ip_port);
|
pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
|
||||||
friends_list[i].client_list[j].last_pinged = temp_time;
|
friends_list[i].client_list[j].last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good.
|
if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good.
|
||||||
|
@ -786,7 +899,8 @@ void doDHTFriends()
|
||||||
{
|
{
|
||||||
rand_node = rand() % num_nodes;
|
rand_node = rand() % num_nodes;
|
||||||
getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
|
getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
|
||||||
friends_list[i].client_list[index[rand_node]].client_id);
|
friends_list[i].client_list[index[rand_node]].client_id,
|
||||||
|
friends_list[i].client_id);
|
||||||
friend_lastgetnode[i] = temp_time;
|
friend_lastgetnode[i] = temp_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,7 +924,7 @@ void doClose()//tested
|
||||||
{
|
{
|
||||||
if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time)
|
if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time)
|
||||||
{
|
{
|
||||||
pingreq(close_clientlist[i].ip_port);
|
pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
|
||||||
close_clientlist[i].last_pinged = temp_time;
|
close_clientlist[i].last_pinged = temp_time;
|
||||||
}
|
}
|
||||||
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good.
|
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good.
|
||||||
|
@ -825,7 +939,8 @@ void doClose()//tested
|
||||||
{
|
{
|
||||||
rand_node = rand() % num_nodes;
|
rand_node = rand() % num_nodes;
|
||||||
getnodes(close_clientlist[index[rand_node]].ip_port,
|
getnodes(close_clientlist[index[rand_node]].ip_port,
|
||||||
close_clientlist[index[rand_node]].client_id);
|
close_clientlist[index[rand_node]].client_id,
|
||||||
|
self_public_key);
|
||||||
close_lastgetnodes = temp_time;
|
close_lastgetnodes = temp_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,10 +957,10 @@ void doDHT()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DHT_bootstrap(IP_Port ip_port)
|
void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
|
||||||
{
|
{
|
||||||
|
|
||||||
getnodes(ip_port, self_client_id);
|
getnodes(ip_port, public_key, self_public_key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
core/DHT.h
12
core/DHT.h
|
@ -26,13 +26,13 @@
|
||||||
#ifndef DHT_H
|
#ifndef DHT_H
|
||||||
#define DHT_H
|
#define DHT_H
|
||||||
|
|
||||||
#include "network.h"
|
#include "net_crypto.h"
|
||||||
|
|
||||||
//Current time, unix format
|
//Current time, unix format
|
||||||
#define unix_time() ((uint32_t)time(NULL))
|
#define unix_time() ((uint32_t)time(NULL))
|
||||||
|
|
||||||
//size of the client_id in bytes
|
//size of the client_id in bytes
|
||||||
#define CLIENT_ID_SIZE 32
|
#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,18 +68,14 @@ void doDHT();
|
||||||
int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
|
int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source);
|
||||||
|
|
||||||
//Use this function to bootstrap the client
|
//Use this function to bootstrap the client
|
||||||
//Sends a get nodes request to the given ip port
|
//Sends a get nodes request to the given node with ip port and public_key
|
||||||
void DHT_bootstrap(IP_Port ip_port);
|
void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key);
|
||||||
|
|
||||||
|
|
||||||
//TODO:
|
//TODO:
|
||||||
//Add functions to save and load the state(client list, friends list)
|
//Add functions to save and load the state(client list, friends list)
|
||||||
|
|
||||||
|
|
||||||
//Global variables
|
|
||||||
|
|
||||||
//Our client id
|
|
||||||
extern uint8_t self_client_id[CLIENT_ID_SIZE];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,10 @@ typedef struct
|
||||||
|
|
||||||
#define MAX_NUM_FRIENDS 256
|
#define MAX_NUM_FRIENDS 256
|
||||||
|
|
||||||
Friend friendlist[MAX_NUM_FRIENDS];
|
static Friend friendlist[MAX_NUM_FRIENDS];
|
||||||
|
|
||||||
|
|
||||||
uint32_t numfriends;
|
static uint32_t numfriends;
|
||||||
|
|
||||||
|
|
||||||
//return the friend id associated to that public key.
|
//return the friend id associated to that public key.
|
||||||
|
@ -189,7 +189,7 @@ int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
|
static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
|
||||||
|
|
||||||
//set the function that will be executed when a friend request is received.
|
//set the function that will be executed when a friend request is received.
|
||||||
void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
|
void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
|
||||||
|
@ -198,7 +198,7 @@ void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void (*friend_message)(int, uint8_t *, uint16_t);
|
static void (*friend_message)(int, uint8_t *, uint16_t);
|
||||||
|
|
||||||
//set the function that will be executed when a message from a friend is received.
|
//set the function that will be executed when a message from a friend is received.
|
||||||
void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
|
void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
|
||||||
|
@ -216,11 +216,10 @@ void initMessenger()
|
||||||
IP ip;
|
IP ip;
|
||||||
ip.i = 0;
|
ip.i = 0;
|
||||||
init_networking(ip, PORT);
|
init_networking(ip, PORT);
|
||||||
memcpy(self_client_id, self_public_key, crypto_box_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void doFriends()
|
static void doFriends()
|
||||||
{//TODO: add incoming connections and some other stuff.
|
{//TODO: add incoming connections and some other stuff.
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int len;
|
int len;
|
||||||
|
@ -280,7 +279,7 @@ void doFriends()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doFriendRequest()
|
static void doFriendRequest()
|
||||||
{
|
{
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
uint8_t temp[MAX_DATA_SIZE];
|
uint8_t temp[MAX_DATA_SIZE];
|
||||||
|
@ -296,7 +295,7 @@ void doFriendRequest()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void doInbound()
|
static void doInbound()
|
||||||
{
|
{
|
||||||
uint8_t secret_nonce[crypto_box_NONCEBYTES];
|
uint8_t secret_nonce[crypto_box_NONCEBYTES];
|
||||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
|
|
@ -50,17 +50,17 @@ typedef struct
|
||||||
|
|
||||||
#define MAX_CRYPTO_CONNECTIONS 256
|
#define MAX_CRYPTO_CONNECTIONS 256
|
||||||
|
|
||||||
Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
|
static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
|
||||||
|
|
||||||
#define MAX_FRIEND_REQUESTS 32
|
#define MAX_FRIEND_REQUESTS 32
|
||||||
|
|
||||||
//keeps track of the connection numbers for friends request so we can check later if they were sent
|
//keeps track of the connection numbers for friends request so we can check later if they were sent
|
||||||
int outbound_friendrequests[MAX_FRIEND_REQUESTS];
|
static int outbound_friendrequests[MAX_FRIEND_REQUESTS];
|
||||||
|
|
||||||
#define MAX_INCOMING 64
|
#define MAX_INCOMING 64
|
||||||
|
|
||||||
//keeps track of the connection numbers for friends request so we can check later if they were sent
|
//keeps track of the connection numbers for friends request so we can check later if they were sent
|
||||||
int incoming_connections[MAX_INCOMING];
|
static int incoming_connections[MAX_INCOMING];
|
||||||
|
|
||||||
//encrypts plain of length length to encrypted of length + 16 using the
|
//encrypts plain of length length to encrypted of length + 16 using the
|
||||||
//public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
//public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
||||||
|
@ -587,7 +587,7 @@ int new_incoming(int id)
|
||||||
|
|
||||||
//TODO: optimize this
|
//TODO: optimize this
|
||||||
//handle all new incoming connections.
|
//handle all new incoming connections.
|
||||||
void handle_incomings()
|
static void handle_incomings()
|
||||||
{
|
{
|
||||||
int income;
|
int income;
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -601,7 +601,7 @@ void handle_incomings()
|
||||||
}
|
}
|
||||||
|
|
||||||
//handle received packets for not yet established crypto connections.
|
//handle received packets for not yet established crypto connections.
|
||||||
void receive_crypto()
|
static void receive_crypto()
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++)
|
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++)
|
||||||
|
@ -687,7 +687,7 @@ void initNetCrypto()
|
||||||
memset(incoming_connections, -1 ,sizeof(incoming_connections));
|
memset(incoming_connections, -1 ,sizeof(incoming_connections));
|
||||||
}
|
}
|
||||||
|
|
||||||
void killTimedout()
|
static void killTimedout()
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++)
|
for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++)
|
||||||
|
|
|
@ -32,8 +32,9 @@
|
||||||
#endif
|
#endif
|
||||||
//Our public key.
|
//Our public key.
|
||||||
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
|
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
|
||||||
|
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
|
||||||
|
|
||||||
|
#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
||||||
|
|
||||||
//encrypts plain of length length to encrypted of length + 16 using the
|
//encrypts plain of length length to encrypted of length + 16 using the
|
||||||
//public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
//public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
|
||||||
|
@ -51,6 +52,10 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce,
|
||||||
uint8_t * encrypted, uint32_t length, uint8_t * plain);
|
uint8_t * encrypted, uint32_t length, uint8_t * plain);
|
||||||
|
|
||||||
|
|
||||||
|
//fill the given nonce with random bytes.
|
||||||
|
void random_nonce(uint8_t * nonce);
|
||||||
|
|
||||||
|
|
||||||
//return 0 if there is no received data in the buffer
|
//return 0 if there is no received data in the buffer
|
||||||
//return -1 if the packet was discarded.
|
//return -1 if the packet was discarded.
|
||||||
//return length of received data if successful
|
//return length of received data if successful
|
||||||
|
|
|
@ -39,8 +39,7 @@
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
//we use libsodium (Portable version of NaCl) because stock NaCl doesn't compile on windows.
|
#undef VANILLA_NACL//make sure on windows we use libsodium
|
||||||
#include <sodium.h>
|
|
||||||
|
|
||||||
#else //Linux includes
|
#else //Linux includes
|
||||||
|
|
||||||
|
@ -50,13 +49,21 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
//TODO: Including stuff like this is bad. This needs fixing.
|
|
||||||
//We keep support for the original NaCl for now on UNIX like Operating Systems.
|
|
||||||
//Commented out for now
|
|
||||||
//#include "../nacl/build/Linux/include/amd64/crypto_box.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef VANILLA_NACL
|
||||||
|
//we use libsodium by default
|
||||||
|
#include <sodium.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
//TODO: Including stuff like this is bad. This needs fixing.
|
||||||
|
//We keep support for the original NaCl for now.
|
||||||
|
#include "../nacl/build/Linux/include/amd64/crypto_box.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MAX_UDP_PACKET_SIZE 65507
|
#define MAX_UDP_PACKET_SIZE 65507
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
|
|
@ -2,7 +2,7 @@ DHT protocol:
|
||||||
Follows pretty much the principle of the torrent DHT: http://www.bittorrent.org/beps/bep_0005.html (READ IT)
|
Follows pretty much the principle of the torrent DHT: http://www.bittorrent.org/beps/bep_0005.html (READ IT)
|
||||||
|
|
||||||
But:
|
But:
|
||||||
Vastly simplified packet format.
|
Vastly simplified packet format and encryption.
|
||||||
|
|
||||||
Boostrapping:
|
Boostrapping:
|
||||||
The first time you install the client we bootstrap it with a node on our servers.(bandwidth should not be a problem as the client only needs to be sent one reply.)
|
The first time you install the client we bootstrap it with a node on our servers.(bandwidth should not be a problem as the client only needs to be sent one reply.)
|
||||||
|
@ -75,13 +75,12 @@ DHT protocol:
|
||||||
|
|
||||||
Valid queries and Responses:
|
Valid queries and Responses:
|
||||||
|
|
||||||
Ping(Request and response): [byte with value: 00 for request, 01 for response][random 4 byte (ping_id)][char array (client node_id), length=32 bytes]
|
Ping(Request and response): [byte with value: 00 for request, 01 for response][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender: [random 8 byte (ping_id)]]
|
||||||
ping_id = a random integer, the response must contain the exact same number as the request
|
ping_id = a random integer, the response must contain the exact same number as the request
|
||||||
|
|
||||||
|
|
||||||
Get nodes (Request):
|
Get nodes (Request):
|
||||||
Packet contents: [byte with value: 02][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][char array: requested_node_id (node_id of which we want the ip), length=32 bytes]
|
Packet contents: [byte with value: 02][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[random 8 byte (ping_id)][char array: requested_node_id (node_id of which we want the ip), length=32 bytes]]
|
||||||
Valid replies: a send_nodes packet
|
Valid replies: a send_nodes packet
|
||||||
|
|
||||||
Send_nodes (response): [byte with value: 03][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][Nodes in node format, length=40 * (number of nodes (maximum of 8 nodes)) bytes]
|
Send_nodes (response): [byte with value: 03][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[random 8 byte (ping_id)][Nodes in node format, length=40 * (number of nodes (maximum of 8 nodes)) bytes]]
|
||||||
ex: 03[Node][Node][Node]
|
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
*
|
*
|
||||||
* Compile with: gcc -O2 -Wall -o test ../core/network.c DHT_test.c
|
* Compile with: gcc -O2 -Wall -o test ../core/network.c DHT_test.c
|
||||||
*
|
*
|
||||||
* Command line arguments are the ip and port of a node and the client_id (32 bytes) of the friend you want to find the ip_port of
|
* Command line arguments are the ip, port and public key of a node.
|
||||||
* EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef
|
* EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
*
|
||||||
|
* The test will then ask you for the id (in hex format) of the friend you wish to add
|
||||||
*/
|
*/
|
||||||
#include "../core/network.h"
|
//#include "../core/network.h"
|
||||||
#include "../core/DHT.c"
|
#include "../core/DHT.c"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -94,15 +96,44 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port)
|
||||||
printf("\n--------------------END-----------------------------\n\n\n");
|
printf("\n--------------------END-----------------------------\n\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//horrible function from one of my first C programs.
|
||||||
|
//only here because I was too lazy to write a proper one.
|
||||||
|
unsigned char * hex_string_to_bin(char hex_string[])
|
||||||
|
{
|
||||||
|
unsigned char * val = malloc(strlen(hex_string));
|
||||||
|
char * pos = hex_string;
|
||||||
|
int i=0;
|
||||||
|
while(i < strlen(hex_string))
|
||||||
|
{
|
||||||
|
sscanf(pos,"%2hhx",&val[i]);
|
||||||
|
pos+=2;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
|
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
printf("usage %s ip port client_id(of friend to find ip_port of)\n", argv[0]);
|
printf("usage %s ip port public_key\n", argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
DHT_addfriend((uint8_t *)argv[3]);
|
new_keys();
|
||||||
|
printf("OUR ID: ");
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
if(self_public_key[i] < 16)
|
||||||
|
printf("0");
|
||||||
|
printf("%hhX",self_public_key[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp_id[128];
|
||||||
|
printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
|
||||||
|
scanf("%s", temp_id);
|
||||||
|
DHT_addfriend(hex_string_to_bin(temp_id));
|
||||||
|
|
||||||
//initialize networking
|
//initialize networking
|
||||||
//bind to ip 0.0.0.0:PORT
|
//bind to ip 0.0.0.0:PORT
|
||||||
|
@ -110,8 +141,7 @@ int main(int argc, char *argv[])
|
||||||
ip.i = 0;
|
ip.i = 0;
|
||||||
init_networking(ip, PORT);
|
init_networking(ip, PORT);
|
||||||
|
|
||||||
int randdomnum = random_int();
|
|
||||||
memcpy(self_client_id, &randdomnum, 4);
|
|
||||||
|
|
||||||
|
|
||||||
perror("Initialization");
|
perror("Initialization");
|
||||||
|
@ -122,7 +152,7 @@ int main(int argc, char *argv[])
|
||||||
//bootstrap_ip_port.ip.c[2] = 0;
|
//bootstrap_ip_port.ip.c[2] = 0;
|
||||||
//bootstrap_ip_port.ip.c[3] = 1;
|
//bootstrap_ip_port.ip.c[3] = 1;
|
||||||
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
|
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
|
||||||
DHT_bootstrap(bootstrap_ip_port);
|
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
|
||||||
|
|
||||||
IP_Port ip_port;
|
IP_Port ip_port;
|
||||||
uint8_t data[MAX_UDP_PACKET_SIZE];
|
uint8_t data[MAX_UDP_PACKET_SIZE];
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* If it recieves a message from a friend it replies back.
|
* If it recieves a message from a friend it replies back.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This is how I compile it: gcc -O2 -Wall -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/DHT.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/* Messenger_test.c
|
* This is how I compile it: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} Messenger_test.c
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Command line arguments are the ip and port of a node (for bootstrapping).
|
* Command line arguments are the ip and port of a node (for bootstrapping).
|
||||||
|
@ -77,8 +77,8 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc < 3) {
|
if (argc < 4) {
|
||||||
printf("usage %s ip port (of the DHT bootstrap node)\n", argv[0]);
|
printf("usage %s ip port public_key (of the DHT bootstrap node)\n", argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
initMessenger();
|
initMessenger();
|
||||||
|
@ -96,14 +96,17 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
char temp_id[128];
|
char temp_id[128];
|
||||||
printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
|
printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
|
||||||
scanf("%s", temp_id);
|
if(scanf("%s", temp_id) != 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
|
int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
|
||||||
|
|
||||||
perror("Initialization");
|
perror("Initialization");
|
||||||
IP_Port bootstrap_ip_port;
|
IP_Port bootstrap_ip_port;
|
||||||
bootstrap_ip_port.port = htons(atoi(argv[2]));
|
bootstrap_ip_port.port = htons(atoi(argv[2]));
|
||||||
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
|
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
|
||||||
DHT_bootstrap(bootstrap_ip_port);
|
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user