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_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; }
//send a getnodes request static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) { if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself { return 1; } if(is_gettingnodes(ip_port, 0)) { return 1; } uint64_t ping_id = add_gettingnodes(ip_port); if(ping_id == 0) { return 1; } uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; uint8_t nonce[crypto_box_NONCEBYTES]; random_nonce(nonce); memcpy(plain, &ping_id, sizeof(ping_id)); memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) { return -1; } data[0] = 2; memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); return sendpacket(ip_port, data, sizeof(data)); }
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; }
//send a getnodes request unsigned int getnodes(IP_Port ip_port, char * client_id) { if(is_gettingnodes(ip_port, 0)) { return 0; } int ping_id = add_gettingnodes(ip_port); if(ping_id == 0) { return 0; } char data[5 + CLIENT_ID_SIZE*2]; data[0] = 2; memcpy(data + 1, &ping_id, 4); memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); memcpy(data + 5 + CLIENT_ID_SIZE, client_id, CLIENT_ID_SIZE); return sendpacket(ip_port, data, sizeof(data)); }