From 33721da46ab45ff6073cabf5bc97eacb0129fce9 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 26 Sep 2014 17:56:06 -0400 Subject: [PATCH] Added callbacks to DHT called when the ip of a peer is discovered. --- testing/DHT_test.c | 2 +- toxcore/DHT.c | 77 ++++++++++++++++++++++++++++++++---------- toxcore/DHT.h | 20 ++++++++--- toxcore/onion_client.c | 9 ++--- 4 files changed, 82 insertions(+), 26 deletions(-) diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 2636ed02..5cdd1823 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c @@ -208,7 +208,7 @@ int main(int argc, char *argv[]) temp_id[strlen(temp_id) - 1] = '\0'; uint8_t *bin_id = hex_string_to_bin(temp_id); - DHT_addfriend(dht, bin_id); + DHT_addfriend(dht, bin_id, 0, 0, 0, 0); free(bin_id); perror("Initialization"); diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 789df9aa..7977896f 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -712,10 +712,23 @@ int addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *client_id) if (!client_or_ip_port_in_list(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) { if (replace_all(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, - client_id, ip_port, dht->friends_list[i].client_id)) + client_id, ip_port, dht->friends_list[i].client_id)) { + DHT_Friend *friend = &dht->friends_list[i]; + + if (memcmp(client_id, friend->client_id, CLIENT_ID_SIZE) == 0) { + uint32_t j; + + for (j = 0; j < friend->lock_count; ++j) { + if (friend->callbacks[j].ip_callback) + friend->callbacks[j].ip_callback(friend->callbacks[j].data, friend->callbacks[j].number, ip_port); + } + } + used++; - } else + } + } else { used++; + } } #ifdef ENABLE_ASSOC_DHT @@ -1089,12 +1102,28 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_ } } */ -int DHT_addfriend(DHT *dht, const uint8_t *client_id) +int DHT_addfriend(DHT *dht, const uint8_t *client_id, void (*ip_callback)(void *data, int32_t number, IP_Port), + void *data, int32_t number, uint16_t *lock_count) { int friend_num = friend_number(dht, client_id); + uint16_t lock_num; + if (friend_num != -1) { /* Is friend already in DHT? */ - ++dht->friends_list[friend_num].lock_count; + DHT_Friend *friend = &dht->friends_list[friend_num]; + + if (friend->lock_count == DHT_FRIEND_MAX_LOCKS) + return -1; + + lock_num = friend->lock_count; + ++friend->lock_count; + friend->callbacks[lock_num].ip_callback = ip_callback; + friend->callbacks[lock_num].data = data; + friend->callbacks[lock_num].number = number; + + if (lock_count) + *lock_count = lock_num + 1; + return 0; } @@ -1102,14 +1131,25 @@ int DHT_addfriend(DHT *dht, const uint8_t *client_id) temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); if (temp == NULL) - return 1; + return -1; dht->friends_list = temp; - memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend)); - memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE); + DHT_Friend *friend = &dht->friends_list[dht->num_friends]; + memset(friend, 0, sizeof(DHT_Friend)); + memcpy(friend->client_id, client_id, CLIENT_ID_SIZE); - dht->friends_list[dht->num_friends].nat.NATping_id = random_64b(); + friend->nat.NATping_id = random_64b(); ++dht->num_friends; + + lock_num = friend->lock_count; + ++friend->lock_count; + friend->callbacks[lock_num].ip_callback = ip_callback; + friend->callbacks[lock_num].data = data; + friend->callbacks[lock_num].number = number; + + if (lock_count) + *lock_count = lock_num + 1; + #ifdef ENABLE_ASSOC_DHT if (dht->assoc) { @@ -1147,18 +1187,24 @@ int DHT_addfriend(DHT *dht, const uint8_t *client_id) return 0; } -int DHT_delfriend(DHT *dht, const uint8_t *client_id) +int DHT_delfriend(DHT *dht, const uint8_t *client_id, uint16_t lock_count) { int friend_num = friend_number(dht, client_id); if (friend_num == -1) { - return 1; + return -1; } - --dht->friends_list[friend_num].lock_count; + DHT_Friend *friend = &dht->friends_list[friend_num]; + --friend->lock_count; - if (dht->friends_list[friend_num].lock_count) /* DHT friend is still in use.*/ + if (friend->lock_count && lock_count) { /* DHT friend is still in use.*/ + --lock_count; + friend->callbacks[lock_count].ip_callback = NULL; + friend->callbacks[lock_count].data = NULL; + friend->callbacks[lock_count].number = 0; return 0; + } uint32_t i; DHT_Friend *temp; @@ -1180,13 +1226,10 @@ int DHT_delfriend(DHT *dht, const uint8_t *client_id) temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends)); if (temp == NULL) - return 1; + return -1; dht->friends_list = temp; return 0; - - - return 1; } /* TODO: Optimize this. */ @@ -2227,7 +2270,7 @@ DHT *new_DHT(Networking_Core *net) for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) { uint8_t random_key_bytes[CLIENT_ID_SIZE]; randombytes(random_key_bytes, sizeof(random_key_bytes)); - DHT_addfriend(dht, random_key_bytes); + DHT_addfriend(dht, random_key_bytes, 0, 0, 0, 0); } return dht; diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 289deb1e..459dd7a5 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -122,6 +122,8 @@ typedef struct { uint64_t NATping_timestamp; } NAT; +#define DHT_FRIEND_MAX_LOCKS 2 + typedef struct { uint8_t client_id[CLIENT_ID_SIZE]; Client_data client_list[MAX_FRIEND_CLIENTS]; @@ -135,6 +137,12 @@ typedef struct { NAT nat; uint16_t lock_count; + struct { + void (*ip_callback)(void *, int32_t, IP_Port); + void *data; + int32_t number; + } callbacks[DHT_FRIEND_MAX_LOCKS]; + } DHT_Friend; typedef struct { @@ -247,18 +255,22 @@ void DHT_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, con /* Add a new friend to the friends list. * client_id must be CLIENT_ID_SIZE bytes long. * + * ip_callback is the callback of a function that will be called when the ip address + * is found along with arguments data and number. + * * return 0 if success. - * return 1 if failure (friends list is full). + * return -1 if failure (friends list is full). */ -int DHT_addfriend(DHT *dht, const uint8_t *client_id); +int DHT_addfriend(DHT *dht, const uint8_t *client_id, void (*ip_callback)(void *data, int32_t number, IP_Port), + void *data, int32_t number, uint16_t *lock_count); /* Delete a friend from the friends list. * client_id must be CLIENT_ID_SIZE bytes long. * * return 0 if success. - * return 1 if failure (client_id not in friends list). + * return -1 if failure (client_id not in friends list). */ -int DHT_delfriend(DHT *dht, const uint8_t *client_id); +int DHT_delfriend(DHT *dht, const uint8_t *client_id, uint16_t lock_count); /* Get ip of friend. * client_id must be CLIENT_ID_SIZE bytes long. diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 3b130602..4be3cc12 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -958,7 +958,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) return -1; if (onion_c->friends_list[friend_num].is_fake_clientid) - DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); + DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, 0); memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); uint32_t i; @@ -1019,10 +1019,11 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin return -1; } - DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); + DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, 0); + onion_c->friends_list[friend_num].is_fake_clientid = 0; } - if (DHT_addfriend(onion_c->dht, dht_key) == 1) { + if (DHT_addfriend(onion_c->dht, dht_key, 0, 0, 0, 0) == -1) { return -1; } @@ -1203,7 +1204,7 @@ static void cleanup_friend(Onion_Client *onion_c, uint16_t friendnum) if (onion_c->friends_list[friendnum].is_fake_clientid && !onion_c->friends_list[friendnum].is_online && is_timeout(onion_c->friends_list[friendnum].last_seen, DEAD_ONION_TIMEOUT)) { onion_c->friends_list[friendnum].is_fake_clientid = 0; - DHT_delfriend(onion_c->dht, onion_c->friends_list[friendnum].fake_client_id); + DHT_delfriend(onion_c->dht, onion_c->friends_list[friendnum].fake_client_id, 0); } }