Beispiel #1
0
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;
}
Beispiel #2
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();
}
Beispiel #3
0
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;
	
}
Beispiel #5
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;
}
Beispiel #6
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;
}
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;
}