onion_client almost done.

This commit is contained in:
irungentoo 2014-01-15 20:47:26 -05:00
parent b345bcea8b
commit aff78b159c
4 changed files with 86 additions and 7 deletions

View File

@ -2021,6 +2021,44 @@ Node_format random_node(DHT *dht, sa_family_t sa_family)
return nodes_list[rand() % num_nodes];
}
/* Put up to max_num nodes in nodes from the closelist.
*
* return the number of nodes.
*/
uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
{
if (max_num == 0)
return 0;
uint16_t count = 0;
Client_data *list = dht->close_clientlist;
uint32_t i;
for (i = LCLIENT_LIST; i != 0; --i) {
IPPTsPng *assoc = NULL;
if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT))
assoc = &list[i - 1].assoc4;
if (!is_timeout(list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) {
if (assoc == NULL)
assoc = &list[i - 1].assoc6;
else if (rand() % 2)
assoc = &list[i - 1].assoc6;
}
if (assoc != NULL) {
memcpy(nodes[count].client_id, list[i - 1].client_id, CLIENT_ID_SIZE);
nodes[count].ip_port = assoc->ip_port;
++count;
if (count >= max_num)
return count;
}
}
return count;
}
void do_hardening(DHT *dht)
{

View File

@ -48,9 +48,9 @@
#define PING_INTERVAL 60
/* The number of seconds for a non responsive node to become bad. */
#define PINGS_MISSED_NODE_GOES_BAD 3
#define PINGS_MISSED_NODE_GOES_BAD 1
#define PING_ROUNDTRIP 2
#define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * PING_INTERVAL + PING_ROUNDTRIP)
#define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * (PING_INTERVAL + PING_ROUNDTRIP))
/* Redefinitions of variables for safe transfer over wire. */
#define TOX_AF_INET 2
@ -220,6 +220,13 @@ int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2);
int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN,
uint8_t want_good);
/* Put up to max_num nodes in nodes from the closelist.
*
* return the number of nodes.
*/
uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
/* Run this function at least a couple times per second (It's the main loop). */
void do_DHT(DHT *dht);

View File

@ -359,6 +359,8 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
if (DHT_addfriend(onion_c->dht, data + 1) == 1) {
return 1;
}
memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1, crypto_box_PUBLICKEYBYTES);
}
uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format);
@ -368,7 +370,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
for (i = 0; i < num_nodes; ++i) {
to_host_family(&nodes[i].ip_port.ip);
DHT_bootstrap(onion_c->dht, nodes[i].ip_port, nodes[i].client_id);
DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
}
//TODO replay protection
@ -429,6 +431,24 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
return good;
}
/* Send the packets to tell our friends
* 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)
{
if (friend_num >= onion_c->num_friends)
return -1;
uint8_t data[FAKEID_DATA_MAX_LENGTH];
data[0] = FAKEID_DATA_ID;
memcpy(data + 1, onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
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);
}
/* Get the friend_num of a friend.
*
* return -1 on failure.
@ -516,7 +536,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;
//TODO
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;
@ -544,8 +564,13 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;
//TODO
return 0;
if (onion_c->friends_list[friend_num].status == 0)
return -1;
if (DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port) == 1)
return 0;
return -1;
}
/* Takes 3 random nodes that we know and puts them in nodes
@ -597,7 +622,10 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
}
//TODO send packets to friend telling them our fake DHT id.
/* 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) > 3)
onion_c->friends_list[friendnum].last_fakeid_sent = unix_time();
}
/* Function to call when onion data packet with contents beginning with byte is received. */
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object)

View File

@ -28,6 +28,10 @@
#define MAX_ONION_CLIENTS 8
#define ONION_NODE_TIMEOUT 200
/* The interval in seconds at which to tell our friends where we are */
#define ONION_FAKEID_INTERVAL 60
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
IP_Port ip_port;
@ -46,6 +50,8 @@ typedef struct {
Onion_Node clients_list[MAX_ONION_CLIENTS];
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
uint64_t last_fakeid_sent;
} Onion_Friend;
typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);