More refactoring done.

This commit is contained in:
irungentoo 2013-08-20 12:08:55 -04:00
parent 9f0efe9201
commit a1c40d753e
16 changed files with 461 additions and 427 deletions

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,20 @@ extern "C" {
/* size of the client_id in bytes */
#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
/* maximum number of clients stored per friend. */
#define MAX_FRIEND_CLIENTS 8
/* A list of the clients mathematically closest to ours. */
#define LCLIENT_LIST 32
/* The list of ip ports along with the ping_id of what we sent them and a timestamp */
#define LPING_ARRAY 256 //NOTE Deprecated (doesn't do anything)
#define LSEND_NODES_ARRAY LPING_ARRAY/2
/*Maximum newly announced nodes to ping per TIME_TOPING seconds*/
#define MAX_TOPING 16
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
IP_Port ip_port;
@ -45,19 +59,64 @@ typedef struct {
uint64_t ret_timestamp;
} Client_data;
Client_data *DHT_get_close_list(void);
/*----------------------------------------------------------------------------------*/
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
Client_data client_list[MAX_FRIEND_CLIENTS];
/* time at which the last get_nodes request was sent. */
uint64_t lastgetnode;
/* Symetric NAT hole punching stuff */
/* 1 if currently hole punching, otherwise 0 */
uint8_t hole_punching;
uint32_t punching_index;
uint64_t punching_timestamp;
uint64_t recvNATping_timestamp;
uint64_t NATping_id;
uint64_t NATping_timestamp;
} DHT_Friend;
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
IP_Port ip_port;
} Node_format;
typedef struct {
IP_Port ip_port;
uint64_t ping_id;
uint64_t timestamp;
} Pinged;
/*----------------------------------------------------------------------------------*/
typedef struct {
Net_Crypto *c;
Client_data close_clientlist[LCLIENT_LIST];
DHT_Friend *friends_list;
uint16_t num_friends;
Pinged send_nodes[LSEND_NODES_ARRAY];
Node_format toping[MAX_TOPING];
uint64_t last_toping;
uint64_t close_lastgetnodes;
} DHT;
/*----------------------------------------------------------------------------------*/
DHT * temp_DHT; //TODO: remove
Client_data *DHT_get_close_list(DHT * dht);
/* Add a new friend to the friends list
client_id must be CLIENT_ID_SIZE bytes long.
returns 0 if success
returns 1 if failure (friends list is full) */
int DHT_addfriend(uint8_t *client_id);
int DHT_addfriend(DHT * dht, uint8_t *client_id);
/* Delete a friend from the friends list
client_id must be CLIENT_ID_SIZE bytes long.
returns 0 if success
returns 1 if failure (client_id not in friends list) */
int DHT_delfriend(uint8_t *client_id);
int DHT_delfriend(DHT * dht, uint8_t *client_id);
/* Get ip of friend
client_id must be CLIENT_ID_SIZE bytes long.
@ -66,14 +125,14 @@ int DHT_delfriend(uint8_t *client_id);
returns ip if success
returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
returns ip of 1 if friend is not in list. */
IP_Port DHT_getfriendip(uint8_t *client_id);
IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id);
/* Run this function at least a couple times per second (It's the main loop) */
void doDHT(void);
void do_DHT(DHT * dht);
/* Use this function to bootstrap the client
Sends a get nodes request to the given node with ip port and public_key */
void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key);
/* Add nodes to the toping list
all nodes in this list are pinged every TIME_TOPING seconds
@ -83,17 +142,17 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
network while preventing amplification attacks.
return 0 if node was added
return -1 if node was not added */
int add_toping(uint8_t *client_id, IP_Port ip_port);
int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port);
/* ROUTING FUNCTIONS */
/* send the given packet to node with client_id
returns -1 if failure */
int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length);
int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length);
/* Send the following packet to everyone who tells us they are connected to friend_id
returns the number of nodes it sent the packet to */
int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length);
/* NAT PUNCHING FUNCTIONS */
@ -101,29 +160,31 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
ip_portlist must be at least MAX_FRIEND_CLIENTS big
returns the number of ips returned
returns -1 if no such friend*/
int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id);
int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id);
/* SAVE/LOAD functions */
/* get the size of the DHT (for saving) */
uint32_t DHT_size(void);
uint32_t DHT_size(DHT * dht);
/* save the DHT in data where data is an array of size DHT_size() */
void DHT_save(uint8_t *data);
void DHT_save(DHT * dht, uint8_t *data);
/* init DHT */
void DHT_init(void);
DHT * new_DHT(Net_Crypto *c);
void kill_DHT(DHT * dht);
/* load the DHT from data of size size;
return -1 if failure
return 0 if success */
int DHT_load(uint8_t *data, uint32_t size);
int DHT_load(DHT * dht, uint8_t *data, uint32_t size);
/* returns 0 if we are not connected to the DHT
returns 1 if we are */
int DHT_isconnected();
int DHT_isconnected(DHT * dht);
void addto_lists(IP_Port ip_port, uint8_t *client_id);
void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id);
#ifdef __cplusplus
}

View File

@ -123,28 +123,29 @@ static int LAN_ip(IP ip)
static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length)
{
DHT *dht = object;
if (LAN_ip(source.ip) == -1)
return 1;
if (length != crypto_box_PUBLICKEYBYTES + 1)
return 1;
DHT_bootstrap(source, packet + 1);
DHT_bootstrap(dht, source, packet + 1);
return 0;
}
int send_LANdiscovery(uint16_t port)
int send_LANdiscovery(uint16_t port, Net_Crypto *c)
{
uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
data[0] = 33;
memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
IP_Port ip_port = {broadcast_ip(), port};
return sendpacket(temp_net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
}
void LANdiscovery_init(void)
void LANdiscovery_init(DHT *dht)
{
networking_registerhandler(temp_net, 33, &handle_LANdiscovery, NULL);
networking_registerhandler(dht->c->lossless_udp->net, 33, &handle_LANdiscovery, dht);
}

View File

@ -40,11 +40,11 @@ extern "C" {
#endif
/*Send a LAN discovery pcaket to the broadcast address with port port*/
int send_LANdiscovery(uint16_t port);
int send_LANdiscovery(uint16_t port, Net_Crypto *c);
/* sets up packet handlers */
void LANdiscovery_init(void);
void LANdiscovery_init(DHT *dht);

View File

@ -108,9 +108,8 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
*/
void getaddress(Messenger *m, uint8_t *address)
{
//memcpy(address, m->public_key, crypto_box_PUBLICKEYBYTES); //TODO
memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES);
uint32_t nospam = get_nospam();
memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES);
uint32_t nospam = get_nospam(&(m->fr));
memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
@ -150,7 +149,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
if (length < 1)
return FAERR_NOMESSAGE;
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
return FAERR_OWNKEY;
int friend_id = getfriend_id(m, client_id);
@ -176,7 +175,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
for (i = 0; i <= m->numfriends; ++i) {
if (m->friendlist[i].status == NOFRIEND) {
DHT_addfriend(client_id);
DHT_addfriend(m->dht, client_id);
m->friendlist[i].status = FRIEND_ADDED;
m->friendlist[i].crypt_connection_id = -1;
m->friendlist[i].friendrequest_lastsent = 0;
@ -216,7 +215,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
for (i = 0; i <= m->numfriends; ++i) {
if (m->friendlist[i].status == NOFRIEND) {
DHT_addfriend(client_id);
DHT_addfriend(m->dht, client_id);
m->friendlist[i].status = FRIEND_CONFIRMED;
m->friendlist[i].crypt_connection_id = -1;
m->friendlist[i].friendrequest_lastsent = 0;
@ -245,7 +244,7 @@ int m_delfriend(Messenger *m, int friendnumber)
if (friendnumber >= m->numfriends || friendnumber < 0)
return -1;
DHT_delfriend(m->friendlist[friendnumber].client_id);
DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id);
crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
free(m->friendlist[friendnumber].statusmessage);
memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
@ -522,7 +521,7 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
/* set the function that will be executed when a friend request is received. */
void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
{
callback_friendrequest(function, userdata);
callback_friendrequest(&(m->fr), function, userdata);
}
/* set the function that will be executed when a message from a friend is received. */
@ -617,7 +616,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
int LANdiscovery(timer *t, void *arg)
{
send_LANdiscovery(htons(PORT));
send_LANdiscovery(htons(PORT), temp_net_crypto);
timer_start(t, LAN_DISCOVERY_INTERVAL);
return 0;
}
@ -637,19 +636,26 @@ Messenger *initMessenger(void)
}
m->net_crypto = new_net_crypto(m->net);
if (m->net_crypto == NULL) {
kill_networking(m->net);
free(m);
return NULL;
}
m->dht = new_DHT(m->net_crypto);
if (m->dht == NULL) {
kill_net_crypto(m->net_crypto);
kill_networking(m->net);
free(m);
free(m->net);
return NULL;
}
new_keys(m->net_crypto);
m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
DHT_init();
friendreq_init();
LANdiscovery_init();
set_nospam(random_int());
friendreq_init(&(m->fr), m->net_crypto);
LANdiscovery_init(m->dht);
set_nospam(&(m->fr), random_int());
init_cryptopackets(m->dht);
send_LANdiscovery(htons(PORT));
send_LANdiscovery(htons(PORT), m->net_crypto);
timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL);
return m;
@ -661,7 +667,9 @@ void cleanupMessenger(Messenger *m)
/* FIXME TODO ideally cleanupMessenger will mirror initMessenger
* this requires the other modules to expose cleanup functions
*/
kill_DHT(m->dht);
kill_net_crypto(m->net_crypto);
kill_networking(m->net);
free(m->friendlist);
free(m);
}
@ -677,7 +685,7 @@ void doFriends(Messenger *m)
for (i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status == FRIEND_ADDED) {
int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
m->friendlist[i].info_size);
if (fr >= 0) {
@ -699,7 +707,7 @@ void doFriends(Messenger *m)
}
}
IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id);
switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
case 0:
@ -883,7 +891,7 @@ void doMessenger(Messenger *m)
{
networking_poll(m->net);
doDHT();
do_DHT(m->dht);
do_net_crypto(m->net_crypto);
doInbound(m);
doFriends(m);
@ -897,7 +905,7 @@ uint32_t Messenger_size(Messenger *m)
return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
+ sizeof(uint32_t) // nospam
+ sizeof(uint32_t) // DHT size
+ DHT_size() // DHT itself
+ DHT_size(m->dht) // DHT itself
+ sizeof(uint32_t) // Friendlist size
+ sizeof(Friend) * m->numfriends // Friendlist itself
+ sizeof(uint16_t) // Own nickname length
@ -910,13 +918,13 @@ void Messenger_save(Messenger *m, uint8_t *data)
{
save_keys(m->net_crypto, data);
data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
uint32_t nospam = get_nospam();
uint32_t nospam = get_nospam(&(m->fr));
memcpy(data, &nospam, sizeof(nospam));
data += sizeof(nospam);
uint32_t size = DHT_size();
uint32_t size = DHT_size(m->dht);
memcpy(data, &size, sizeof(size));
data += sizeof(size);
DHT_save(data);
DHT_save(m->dht, data);
data += size;
size = sizeof(Friend) * m->numfriends;
memcpy(data, &size, sizeof(size));
@ -943,7 +951,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
uint32_t nospam;
memcpy(&nospam, data, sizeof(nospam));
set_nospam(nospam);
set_nospam(&(m->fr), nospam);
data += sizeof(nospam);
uint32_t size;
memcpy(&size, data, sizeof(size));
@ -954,7 +962,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
length -= size;
if (DHT_load(data, size) == -1)
if (DHT_load(m->dht, data, size) == -1)
return -1;
data += size;

View File

@ -115,6 +115,8 @@ typedef struct Messenger {
Networking_Core *net;
Net_Crypto * net_crypto;
DHT * dht;
Friend_Requests fr;
uint8_t name[MAX_NAME_LENGTH];
uint16_t name_length;

View File

@ -23,15 +23,12 @@
#include "friend_requests.h"
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
/* Try to send a friendrequest to peer with public_key
data is the data in the request and length is the length.
return -1 if failure.
return 0 if it sent the friend request directly to the friend.
return the number of peers it was routed through if it did not send it directly.*/
int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
{
if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
return -1;
@ -40,25 +37,25 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
memcpy(temp, &nospam_num, sizeof(nospam_num));
memcpy(temp + sizeof(nospam_num), data, length);
uint8_t packet[MAX_DATA_SIZE];
int len = create_request(self_public_key, self_secret_key, packet, public_key, temp, length + sizeof(nospam_num),
int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp, length + sizeof(nospam_num),
32); /* 32 is friend request packet id */
if (len == -1)
return -1;
IP_Port ip_port = DHT_getfriendip(public_key);
IP_Port ip_port = DHT_getfriendip(dht, public_key);
if (ip_port.ip.i == 1)
return -1;
if (ip_port.ip.i != 0) {
if (sendpacket(temp_net->sock, ip_port, packet, len) != -1)
if (sendpacket(dht->c->lossless_udp->net->sock, ip_port, packet, len) != -1)
return 0;
return -1;
}
int num = route_tofriend(public_key, packet, len);
int num = route_tofriend(dht, public_key, packet, len);
if (num == 0)
return -1;
@ -66,58 +63,47 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data,
return num;
}
static uint32_t nospam;
/*
* Set and get the nospam variable used to prevent one type of friend request spam
*/
void set_nospam(uint32_t num)
void set_nospam(Friend_Requests *fr, uint32_t num)
{
nospam = num;
fr->nospam = num;
}
uint32_t get_nospam()
uint32_t get_nospam(Friend_Requests *fr)
{
return nospam;
return fr->nospam;
}
static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *);
static uint8_t handle_friendrequest_isset = 0;
static void *handle_friendrequest_userdata;
/* set the function that will be executed when a friend request is received. */
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
{
handle_friendrequest = function;
handle_friendrequest_isset = 1;
handle_friendrequest_userdata = userdata;
fr->handle_friendrequest = function;
fr->handle_friendrequest_isset = 1;
fr->handle_friendrequest_userdata = userdata;
}
/*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem
TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/
#define MAX_RECEIVED_STORED 32
static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES];
static uint16_t received_requests_index;
/*Add to list of received friend requests*/
static void addto_receivedlist(uint8_t *client_id)
static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id)
{
if (received_requests_index >= MAX_RECEIVED_STORED)
received_requests_index = 0;
if (fr->received_requests_index >= MAX_RECEIVED_STORED)
fr->received_requests_index = 0;
memcpy(received_requests[received_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
++received_requests_index;
memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
++fr->received_requests_index;
}
/* Check if a friend request was already received
return 0 if not, 1 if we did */
static int request_received(uint8_t *client_id)
static int request_received(Friend_Requests *fr, uint8_t *client_id)
{
uint32_t i;
for (i = 0; i < MAX_RECEIVED_STORED; ++i) {
if (memcmp(received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0)
return 1;
}
@ -125,26 +111,27 @@ static int request_received(uint8_t *client_id)
}
static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
{
if (handle_friendrequest_isset == 0)
Friend_Requests *fr = object;
if (fr->handle_friendrequest_isset == 0)
return 1;
if (length <= sizeof(nospam))
if (length <= sizeof(fr->nospam))
return 1;
if (request_received(source_pubkey))
if (request_received(fr, source_pubkey))
return 1;
if (memcmp(packet, &nospam, sizeof(nospam)) != 0)
if (memcmp(packet, &fr->nospam, sizeof(fr->nospam)) != 0)
return 1;
addto_receivedlist(source_pubkey);
(*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata);
addto_receivedlist(fr, source_pubkey);
(*fr->handle_friendrequest)(source_pubkey, packet + 4, length - 4, fr->handle_friendrequest_userdata);
return 0;
}
void friendreq_init(void)
void friendreq_init(Friend_Requests *fr, Net_Crypto *c)
{
cryptopacket_registerhandler(temp_net_crypto, 32, &friendreq_handlepacket);
cryptopacket_registerhandler(c, 32, &friendreq_handlepacket, fr);
}

View File

@ -31,21 +31,36 @@
extern "C" {
#endif
typedef struct {
uint32_t nospam;
void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *);
uint8_t handle_friendrequest_isset;
void *handle_friendrequest_userdata;
/*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem
TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/
#define MAX_RECEIVED_STORED 32
uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES];
uint16_t received_requests_index;
} Friend_Requests;
/* Try to send a friendrequest to peer with public_key
data is the data in the request and length is the length. */
int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
/*
* Set and get the nospam variable used to prevent one type of friend request spam
*/
void set_nospam(uint32_t num);
uint32_t get_nospam();
void set_nospam(Friend_Requests *fr, uint32_t num);
uint32_t get_nospam(Friend_Requests *fr);
/* set the function that will be executed when a friend request for us is received.
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
/* sets up friendreq packet handlers */
void friendreq_init(void);
void friendreq_init(Friend_Requests *fr, Net_Crypto *c);
#ifdef __cplusplus
}

View File

@ -265,34 +265,35 @@ static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uin
return -1;
}
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb)
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object)
{
c->cryptopackethandlers[byte] = cb;
c->cryptopackethandlers[byte].function = cb;
c->cryptopackethandlers[byte].object = object;
}
static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
{
Net_Crypto *c = object;
DHT *dht = object;
if (packet[0] == 32) {
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING ||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
return 1;
if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t data[MAX_DATA_SIZE];
uint8_t number;
int len = handle_request(c, public_key, data, &number, packet, length);
int len = handle_request(dht->c, public_key, data, &number, packet, length);
if (len == -1 || len == 0)
return 1;
if (!c->cryptopackethandlers[number]) return 1;
if (!dht->c->cryptopackethandlers[number].function) return 1;
c->cryptopackethandlers[number](source, public_key, data, len);
dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, data, len);
} else { /* if request is not for us, try routing it. */
if (route_packet(packet + 1, packet, length) == length) //NOTE
if (route_packet(dht, packet + 1, packet, length) == length) //NOTE
return 0;
}
}
@ -572,17 +573,9 @@ int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id)
return CONN_NO_CONNECTION;
}
/* Generate our public and private keys
Only call this function the first time the program starts. */
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
void new_keys(Net_Crypto *c)
{
crypto_box_keypair(c->self_public_key, c->self_secret_key);
memcpy(self_public_key, c->self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(self_secret_key, c->self_secret_key, crypto_box_PUBLICKEYBYTES);
}
/* save the public and private keys to the keys array
@ -713,12 +706,16 @@ Net_Crypto * new_net_crypto(Networking_Core * net)
if (temp->lossless_udp == NULL)
return NULL;
memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING);
//networking_registerhandler(temp, 32, &cryptopacket_handle);
networking_registerhandler(net, 32, &cryptopacket_handle, temp);
temp_net_crypto = temp; //TODO remove
return temp;
}
void init_cryptopackets(void *dht)
{
DHT *s_dht = dht;
networking_registerhandler(s_dht->c->lossless_udp->net, 32, &cryptopacket_handle, s_dht);
}
static void kill_timedout(Net_Crypto *c)
{
uint32_t i;

View File

@ -25,7 +25,6 @@
#define NET_CRYPTO_H
#include "Lossless_UDP.h"
#include "DHT.h"
#ifdef __cplusplus
extern "C" {
@ -33,9 +32,6 @@ extern "C" {
#define MAX_INCOMING 64
extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
typedef struct {
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */
uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */
@ -51,25 +47,32 @@ typedef struct {
} Crypto_Connection;
typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
typedef int (*cryptopacket_handler_callback)(void * object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
typedef struct {
Lossless_UDP * lossless_udp;
cryptopacket_handler_callback function;
void * object;
}Cryptopacket_Handles;
Crypto_Connection *crypto_connections;
typedef struct {
Lossless_UDP * lossless_udp;
uint32_t crypto_connections_length; /* Length of connections array */
Crypto_Connection *crypto_connections;
/* Our public and secret keys. */
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
uint32_t crypto_connections_length; /* Length of connections array */
/* keeps track of the connection numbers for friends request so we can check later if they were sent */
int incoming_connections[MAX_INCOMING];
/* Our public and secret keys. */
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
cryptopacket_handler_callback cryptopackethandlers[256];
/* keeps track of the connection numbers for friends request so we can check later if they were sent */
int incoming_connections[MAX_INCOMING];
Cryptopacket_Handles cryptopackethandlers[256];
} Net_Crypto;
#include "DHT.h"
Net_Crypto * temp_net_crypto; //TODO: remove this
#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
@ -130,7 +133,7 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *
/* Function to call when request beginning with byte is received */
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb);
void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void * object);
/* Start a secure connection with other peer who has public_key and ip_port
returns -1 if failure
@ -183,6 +186,9 @@ void do_net_crypto(Net_Crypto *c);
void kill_net_crypto(Net_Crypto *c);
/* Init the cryptopacket handling */
void init_cryptopackets(void *dht);
#ifdef __cplusplus
}
#endif

View File

@ -196,7 +196,6 @@ Networking_Core * new_networking(IP ip, uint16_t port)
/* Bind our socket to port PORT and address 0.0.0.0 */
ADDR addr = {AF_INET, htons(port), ip};
bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr));
temp_net = temp;
return temp;
}

View File

@ -112,7 +112,6 @@ typedef struct {
int sock;
}Networking_Core;
Networking_Core * temp_net;
/* returns current time in milleseconds since the epoch. */
uint64_t current_time(void);

View File

@ -26,7 +26,6 @@ typedef struct {
static pinged_t pings[PING_NUM_MAX];
static size_t num_pings;
static size_t pos_pings;
static clientid_t *self_id = (clientid_t *) &self_public_key;
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
@ -115,19 +114,19 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
int rc;
uint64_t ping_id;
if (is_pinging(ipp, 0) || id_eq(client_id, self_id))
if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key))
return 1;
// Generate random ping_id
ping_id = add_ping(ipp);
pk.magic = PACKET_PING_REQ;
id_cpy(&pk.client_id, self_id); // Our pubkey
id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey
random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
// Encrypt ping_id using recipient privkey
rc = encrypt_data((uint8_t *) client_id,
self_secret_key,
temp_net_crypto->self_secret_key,
(uint8_t *) &pk.nonce,
(uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t *) &pk.ping_id);
@ -135,7 +134,7 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id)
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
return 1;
return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
}
int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
@ -143,16 +142,16 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
pingres_t pk;
int rc;
if (id_eq(client_id, self_id))
if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key))
return 1;
pk.magic = PACKET_PING_RES;
id_cpy(&pk.client_id, self_id); // Our pubkey
id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey
random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
// Encrypt ping_id using recipient privkey
rc = encrypt_data((uint8_t *) client_id,
self_secret_key,
temp_net_crypto->self_secret_key,
(uint8_t *) &pk.nonce,
(uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t *) &pk.ping_id);
@ -160,21 +159,22 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
return 1;
return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk));
}
int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length)
{
DHT * dht = object;
pingreq_t *p = (pingreq_t *) packet;
int rc;
uint64_t ping_id;
if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id))
if (length != sizeof(pingreq_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key))
return 1;
// Decrypt ping_id
rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key,
dht->c->self_secret_key,
(uint8_t *) &p->nonce,
(uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING,
@ -185,23 +185,24 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t
// Send response
send_ping_response(source, &p->client_id, ping_id);
add_toping((uint8_t *) &p->client_id, source);
add_toping(dht, (uint8_t *) &p->client_id, source);
return 0;
}
int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length)
{
DHT * dht = object;
pingres_t *p = (pingres_t *) packet;
int rc;
uint64_t ping_id;
if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id))
if (length != sizeof(pingres_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key))
return 1;
// Decrypt ping_id
rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key,
dht->c->self_secret_key,
(uint8_t *) &p->nonce,
(uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING,
@ -215,6 +216,6 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_
return 1;
// Associate source ip with client_id
addto_lists(source, (uint8_t *) &p->client_id);
addto_lists(dht, source, (uint8_t *) &p->client_id);
return 0;
}

View File

@ -36,7 +36,7 @@ static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key)
static void dhtstatus_onDraw(ToxWindow *self)
{
Client_data *close_clientlist = DHT_get_close_list();
Client_data *close_clientlist = DHT_get_close_list(temp_DHT);
curs_set(0);
werase(self->window);

View File

@ -90,11 +90,11 @@ static Messenger *init_tox()
#define MAXSERVERS 50
/* Connects to a random DHT server listed in the DHTservers file */
int init_connection(void)
int init_connection(Messenger *m)
{
FILE *fp = NULL;
if (DHT_isconnected())
if (DHT_isconnected(m->dht))
return 0;
fp = fopen(SRVLIST_FILE, "r");
@ -135,7 +135,7 @@ int init_connection(void)
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
DHT_bootstrap(m->dht, dht, binary_string);
free(binary_string);
return 0;
}
@ -146,18 +146,18 @@ static void do_tox(Messenger *m, ToxWindow *prompt)
static int conn_err = 0;
static bool dht_on = false;
if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
if (!dht_on && !DHT_isconnected(m->dht) && !(conn_try++ % 100)) {
if (!conn_err) {
conn_err = init_connection();
conn_err = init_connection(m);
wprintw(prompt->window, "\nEstablishing connection...\n");
if (conn_err)
wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
}
} else if (!dht_on && DHT_isconnected()) {
} else if (!dht_on && DHT_isconnected(m->dht)) {
dht_on = true;
wprintw(prompt->window, "\nDHT connected.\n");
} else if (dht_on && !DHT_isconnected()) {
} else if (dht_on && !DHT_isconnected(m->dht)) {
dht_on = false;
wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
}

View File

@ -204,7 +204,7 @@ void cmd_connect(ToxWindow *self, Messenger *m, char **args)
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
DHT_bootstrap(m->dht, dht, binary_string);
free(binary_string);
}