static int handle_data_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata) { Onion_Announce *onion_a = (Onion_Announce *)object; if (length <= DATA_REQUEST_MIN_SIZE_RECV) { return 1; } if (length > ONION_MAX_PACKET_SIZE) { return 1; } int index = in_entries(onion_a, packet + 1); if (index == -1) { return 1; } uint8_t data[length - (CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3)]; data[0] = NET_PACKET_ONION_DATA_RESPONSE; memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3)); if (send_onion_response(onion_a->net, onion_a->entries[index].ret_ip_port, data, sizeof(data), onion_a->entries[index].ret) == -1) { return 1; } return 0; }
static int handle_test_1(void *object, IP_Port source, const uint8_t *packet, uint16_t length) { Onion *onion = object; if (memcmp(packet, "Install Gentoo", sizeof("Install Gentoo")) != 0) return 1; if (send_onion_response(onion->net, source, (uint8_t *)"install gentoo", sizeof("install gentoo"), packet + sizeof("Install Gentoo")) == -1) return 1; handled_test_1 = 1; return 0; }
static int handle_announce_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata) { Onion_Announce *onion_a = (Onion_Announce *)object; if (length != ANNOUNCE_REQUEST_SIZE_RECV) { return 1; } const uint8_t *packet_public_key = packet + 1 + CRYPTO_NONCE_SIZE; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; get_shared_key(&onion_a->shared_keys_recv, shared_key, onion_a->dht->self_secret_key, packet_public_key); uint8_t plain[ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != sizeof(plain)) { return 1; } uint8_t ping_id1[ONION_PING_ID_SIZE]; generate_ping_id(onion_a, unix_time(), packet_public_key, source, ping_id1); uint8_t ping_id2[ONION_PING_ID_SIZE]; generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet_public_key, source, ping_id2); int index = -1; uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE; if (crypto_memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || crypto_memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { index = add_to_entries(onion_a, source, packet_public_key, data_public_key, packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); } else { index = in_entries(onion_a, plain + ONION_PING_ID_SIZE); } /*Respond with a announce response packet*/ Node_format nodes_list[MAX_SENT_NODES]; unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, 0, LAN_ip(source.ip) == 0, 1); uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(nonce); uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)]; if (index == -1) { pl[0] = 0; memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); } else { if (public_key_cmp(onion_a->entries[index].public_key, packet_public_key) == 0) { if (public_key_cmp(onion_a->entries[index].data_public_key, data_public_key) != 0) { pl[0] = 0; memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); } else { pl[0] = 2; memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); } } else { pl[0] = 1; memcpy(pl + 1, onion_a->entries[index].data_public_key, CRYPTO_PUBLIC_KEY_SIZE); } } int nodes_length = 0; if (num_nodes != 0) { nodes_length = pack_nodes(pl + 1 + ONION_PING_ID_SIZE, sizeof(nodes_list), nodes_list, num_nodes); if (nodes_length <= 0) { return 1; } } uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; len = encrypt_data_symmetric(shared_key, nonce, pl, 1 + ONION_PING_ID_SIZE + nodes_length, data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE); if (len != 1 + ONION_PING_ID_SIZE + nodes_length + CRYPTO_MAC_SIZE) { return 1; } data[0] = NET_PACKET_ANNOUNCE_RESPONSE; memcpy(data + 1, plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE); if (send_onion_response(onion_a->net, source, data, 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len, packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)) == -1) { return 1; } return 0; }