static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id) { Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id); if (!friend_con) { return 0; } Node_format nodes[MAX_SHARED_RELAYS]; uint8_t data[1024]; const int n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS); for (int i = 0; i < n; ++i) { /* Associated the relays being sent with this connection. On receiving the peer will do the same which will establish the connection. */ friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key); } int length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n); if (length <= 0) { return 0; } data[0] = PACKET_ID_SHARE_RELAYS; ++length; if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) { friend_con->share_relays_lastsent = mono_time_get(fr_c->mono_time); return 1; } return 0; }
void BVH::build(Progress& progress) { progress.set_substatus("Building BVH"); /* build nodes */ BVHBuild bvh_build(objects, pack.prim_type, pack.prim_index, pack.prim_object, params, progress); BVHNode *root = bvh_build.run(); if(progress.get_cancel()) { if(root) root->deleteSubtree(); return; } /* pack triangles */ progress.set_substatus("Packing BVH triangles and strands"); pack_primitives(); if(progress.get_cancel()) { root->deleteSubtree(); return; } /* pack nodes */ progress.set_substatus("Packing BVH nodes"); pack_nodes(root); /* free build nodes */ root->deleteSubtree(); }
int main () { Node *pf1, *pf3, *pf0; Node **children; pf1 = create_leaf(1, int_node, "1", NULL); pf3 = create_leaf(1, int_node, "2", NULL); pack_nodes(&children, 0, pf1); pack_nodes(&children, 1, pf3); printf("h = %d\n", height(pf1)); /* deve imprimir 1 */ pf0 = create_node(1, int_node, "0", NULL, 2, children); /* pf0 é o pai de pf1 e pf3 */ printf("h = %d\n", height(pf0)); /* deve imiprimir 2 */ printf("n = %d\n", nb_of_children(pf0)); /* deve imprimir 2 */ printf("n = %d\n", nb_of_children(child(pf0, 0))); /* deve imprimir 0, porque o retorno de child é o filho de pf0, que é uma folha. */ deep_free_node(pf0); }
int main(int argc, char *argv[]) { /* * n * t a * b * */ Node** children1; Node** children2; Node* b = create_leaf(4,305, "lexeme ( b ) \n", NULL); pack_nodes(&children1, 0, b); Node* t = create_node(23, 305, "lexeme ( t ) \n", NULL, 1, children1); Node* a = create_leaf(5, 302, "lexeme ( a ) \n", NULL); pack_nodes(&children2, 0, t); pack_nodes(&children2, 1, a); Node* n = create_node(5, 302, "lexeme ( n ) : root \n", NULL, 2, children2); /* imprime a altura da arvore */ printf ( "height: %d \n", height(a)); printf ( "%s" , n->lexeme); printf ( "%s" , child(n,1)->lexeme); printf ( "%s" , child(n,2)->lexeme); printf ( "%s", child(child(n,1),1)->lexeme); deep_free_node(n); return 0; }
/* Send the packets to tell our friends what our DHT public key is. * * if onion_dht_both is 0, use only the onion to send the packet. * if it is 1, use only the dht. * if it is something else, use both. * * return the number of packets sent on success * return -1 on failure. */ static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) { if (friend_num >= onion_c->num_friends) return -1; uint8_t data[FAKEID_DATA_MAX_LENGTH]; data[0] = FAKEID_DATA_ID; uint64_t no_replay = unix_time(); host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); memcpy(data + 1, &no_replay, sizeof(no_replay)); memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); Node_format nodes[MAX_SENT_NODES]; uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2)); uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays); num_nodes += num_relays; int nodes_len = 0; if (num_nodes != 0) { nodes_len = pack_nodes(data + FAKEID_DATA_MIN_LENGTH, FAKEID_DATA_MAX_LENGTH - FAKEID_DATA_MIN_LENGTH, nodes, num_nodes); if (nodes_len <= 0) return -1; } int num1 = -1, num2 = -1; if (onion_dht_both != 1) num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); if (onion_dht_both != 0) num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len); if (num1 == -1) return num2; if (num2 == -1) return num1; return num1 + num2; }
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; }
METHOD(array, Binary_encode, NodeInfo) { CHECK_SIZE(args, 3); CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER); uint64_t protocol = args.ptr[0].via.u64; CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_ARRAY); msgpack_object_array address = args.ptr[1].via.array; CHECK_SIZE(address, 2); CHECK_TYPE(address.ptr[0], MSGPACK_OBJECT_ARRAY); msgpack_object_array host_address = address.ptr[0].via.array; CHECK_TYPE(address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER); uint64_t port_number = address.ptr[1].via.u64; CHECK_SIZE(host_address, 2); CHECK_TYPE(host_address.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER); uint64_t address_family = host_address.ptr[0].via.u64; CHECK_TYPE(args.ptr[2], MSGPACK_OBJECT_BIN); msgpack_object_bin public_key = args.ptr[2].via.bin; CHECK_SIZE(public_key, crypto_box_PUBLICKEYBYTES); IP_Port ipp; ipp.port = htons(port_number); switch (address_family) { case 0: { /* IPv4*/ if (protocol == 1) { ipp.ip.family = TCP_INET; } else { ipp.ip.family = AF_INET; } CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER); uint64_t addr = host_address.ptr[1].via.u64; ipp.ip.ip4.uint32 = htonl(addr); break; } case 1: { /* IPv6 */ if (protocol == 1) { ipp.ip.family = TCP_INET6; } else { ipp.ip.family = AF_INET6; } CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_ARRAY); msgpack_object_array addr = host_address.ptr[1].via.array; int i; for (i = 0; i < 4; ++i) { CHECK_TYPE(addr.ptr[i], MSGPACK_OBJECT_POSITIVE_INTEGER); uint64_t component = addr.ptr[i].via.u64; ipp.ip.ip6.uint32[i] = htonl(component); } break; } } Node_format node; node.ip_port = ipp; memcpy(&node.public_key, public_key.ptr, crypto_box_PUBLICKEYBYTES); /* We assume IP6 because it's bigger */ uint8_t packed_node[PACKED_NODE_SIZE_IP6]; int len = pack_nodes(packed_node, sizeof packed_node, &node, 1); if (len < 0) { return failure; } SUCCESS { msgpack_pack_bin(res, len); msgpack_pack_bin_body(res, packed_node, len); } return 0; }