void doFriends() { uint32_t i, j; uint32_t temp_time = unix_time(); uint32_t num_nodes = 0; uint32_t rand_node; uint32_t index[MAX_FRIEND_CLIENTS]; for(i = 0; i < num_friends; i++) { for(j = 0; j < MAX_FRIEND_CLIENTS; j++) { if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead. { //TODO: Make this better, it only works if the function is called more than once per second. if((temp_time - friends_list[i].client_list[j].timestamp) % PING_INTERVAL == 0) { pingreq(friends_list[i].client_list[j].ip_port); } if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. { index[num_nodes] = j; num_nodes++; } } } if(friend_lastgetnode[i] + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { rand_node = rand() % num_nodes; getnodes(friends_list[i].client_list[index[rand_node]].ip_port, friends_list[i].client_list[index[rand_node]].client_id); friend_lastgetnode[i] = temp_time; } } }
//Ping each client in the close nodes list every 60 seconds. //Send a get nodes request every 20 seconds to a random good node in the list. void doClose()//tested { uint32_t i; uint32_t temp_time = unix_time(); uint32_t num_nodes = 0; uint32_t rand_node; uint32_t index[LCLIENT_LIST]; for(i = 0; i < LCLIENT_LIST; i++) { if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead. { //TODO: Make this better, it only works if the function is called more than once per second. if((temp_time - close_clientlist[i].timestamp) % PING_INTERVAL == 0) { pingreq(close_clientlist[i].ip_port); } if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. { index[num_nodes] = i; num_nodes++; } } } if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { rand_node = rand() % num_nodes; getnodes(close_clientlist[index[rand_node]].ip_port, close_clientlist[index[rand_node]].client_id); close_lastgetnodes = temp_time; } }
//Ping each client in the close nodes list every 60 seconds. //Send a get nodes request every 20 seconds to a random good node in the list. void doClose()//tested { uint32_t i; uint32_t temp_time = unix_time(); uint32_t num_nodes = 0; uint32_t rand_node; uint32_t index[LCLIENT_LIST]; for(i = 0; i < LCLIENT_LIST; i++) { if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead. { if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); close_clientlist[i].last_pinged = temp_time; } if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. { index[num_nodes] = i; num_nodes++; } } } if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { rand_node = rand() % num_nodes; getnodes(close_clientlist[index[rand_node]].ip_port, close_clientlist[index[rand_node]].client_id, self_public_key); close_lastgetnodes = temp_time; } }
int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested { if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) || (length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) { return 1; } uint32_t num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); uint32_t i; uint32_t ping_id; memcpy(&ping_id, packet + 1, 4); if(!is_gettingnodes(source, ping_id)) { return 1; } Node_format nodes_list[MAX_SENT_NODES]; memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); for(i = 0; i < num_nodes; i++) { pingreq(nodes_list[i].ip_port); } addto_lists(source, packet + 5); return 0; }
int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) { uint64_t ping_id; if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) { return 1; } if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. { return 1; } 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; }
int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) { uint64_t ping_id; 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; } uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); 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)) { return 1; } Node_format nodes_list[MAX_SENT_NODES]; memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); uint32_t i; for(i = 0; i < num_nodes; i++) { pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); } addto_lists(source, packet + 1); return 0; }
int handle_getnodes(char * packet, uint32_t length, IP_Port source) { if(length != (5 + CLIENT_ID_SIZE*2)) { return 1; } uint32_t ping_id; 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; } pingreq(source); return 0; }
int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested { if(length != 5 + CLIENT_ID_SIZE) { 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. { return 1; } pingres(source, ping_id); pingreq(source); return 0; }
void doDHTFriends() { uint32_t i, j; uint32_t temp_time = unix_time(); uint32_t num_nodes = 0; uint32_t rand_node; uint32_t index[MAX_FRIEND_CLIENTS]; for(i = 0; i < num_friends; i++) { for(j = 0; j < MAX_FRIEND_CLIENTS; j++) { if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time)//if node is not dead. { if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 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; } if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. { index[num_nodes] = j; num_nodes++; } } } if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { rand_node = rand() % num_nodes; 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_id); friends_list[i].lastgetnode = temp_time; } } }