Fakeid packets are now also sent via the DHT.

This commit is contained in:
irungentoo 2014-01-20 12:23:10 -05:00
parent 81dd4a8083
commit 9aa94bfe1d
2 changed files with 101 additions and 10 deletions

View File

@ -384,6 +384,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
return 1;
}
onion_c->friends_list[friend_num].is_fake_clientid = 1;
memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
}
@ -454,11 +455,76 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
return good;
}
/* Send the packets to tell our friends what our DHT public key is.
/* Try to send the fakeid via the DHT instead of onion
*
* Even if this function succeeds, the friend might not recieve any data.
*
* return the number of packets sent on success
* return -1 on failure.
*/
static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num)
static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length)
{
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;
if (!onion_c->friends_list[friend_num].is_fake_clientid)
return -1;
uint8_t nonce[crypto_box_NONCEBYTES];
new_nonce(nonce);
uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
return -1;
uint8_t packet[MAX_DATA_SIZE];
len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
if (len == -1)
return -1;
return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, packet, len);
}
static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
{
Onion_Client *onion_c = object;
if (length < FAKEID_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
return 1;
if (length > FAKEID_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
return 1;
uint8_t plain[FAKEID_DATA_MAX_LENGTH];
int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES))
return 1;
if (memcpy(source_pubkey, packet, crypto_box_PUBLICKEYBYTES) != 0)
return 1;
return handle_fakeid_announce(onion_c, packet, plain, len);
}
/* Send the packets to tell our friends what our DHT public key is.
*
* if onion_dht_both is 0, use only the onion to send the packet.
* if it is 1, use only the dht.
* if it is something else, use both.
*
* return the number of packets sent on success
* return -1 on failure.
*/
static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
{
if (friend_num >= onion_c->num_friends)
return -1;
@ -472,9 +538,21 @@ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num)
Node_format nodes[MAX_SENT_NODES];
uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);
memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
return send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
//TODO: somehow make this function send our DHT client id directly to the other if we know theirs but they don't
//seem to know ours.
int num1 = -1, num2 = -1;
if (onion_dht_both != 1)
num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
if (onion_dht_both != 0)
num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
if (num1 == -1)
return num2;
if (num2 == -1)
return num1;
return num1 + num2;
}
/* Get the friend_num of a friend.
@ -565,7 +643,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;
DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
if (onion_c->friends_list[friend_num].is_fake_clientid)
DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend));
uint32_t i;
@ -597,6 +677,9 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
if (onion_c->friends_list[friend_num].status == 0)
return -1;
if (!onion_c->friends_list[friend_num].is_fake_clientid)
return -1;
return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port);
}
@ -675,9 +758,13 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
/* send packets to friend telling them our fake DHT id. */
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_sent, ONION_FAKEID_INTERVAL))
if (send_fakeid_announce(onion_c, friendnum) > 1)
onion_c->friends_list[friendnum].last_fakeid_sent = unix_time();
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL))
if (send_fakeid_announce(onion_c, friendnum, 0) > 1)
onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time();
if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL))
if (send_fakeid_announce(onion_c, friendnum, 1) > 1)
onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time();
}
}
/* Function to call when onion data packet with contents beginning with byte is received. */
@ -757,6 +844,7 @@ Onion_Client *new_onion_client(DHT *dht)
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
return onion_c;
}

View File

@ -31,6 +31,7 @@
/* The interval in seconds at which to tell our friends where we are */
#define ONION_FAKEID_INTERVAL 60
#define DHT_FAKEID_INTERVAL 20
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
@ -48,6 +49,7 @@ typedef struct {
uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
uint8_t is_online; /* Set by the onion_set_friend_status function. */
uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
@ -55,7 +57,8 @@ typedef struct {
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
uint64_t last_fakeid_sent;
uint64_t last_fakeid_onion_sent;
uint64_t last_fakeid_dht_sent;
uint64_t last_noreplay;
} Onion_Friend;