Beispiel #1
0
static void do_announce(Onion_Client *onion_c)
{
    uint32_t i, count = 0;
    Onion_Node *list_nodes = onion_c->clients_announce_list;

    for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
        if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
            continue;

        ++count;
        uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;

        if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) {
            interval = ANNOUNCE_INTERVAL_ANNOUNCED;
        }

        if (is_timeout(list_nodes[i].last_pinged, interval)) {
            if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id,
                                             list_nodes[i].ping_id) == 0) {
                list_nodes[i].last_pinged = unix_time();
            }
        }
    }

    if (count < MAX_ONION_CLIENTS / 2) {
        Node_format nodes_list[MAX_SENT_NODES];
        uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list,
                                             rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1);

        for (i = 0; i < num_nodes; ++i)
            client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
    }
}
Beispiel #2
0
static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
{
    if (friendnum >= onion_c->num_friends)
        return;

    if (onion_c->friends_list[friendnum].status == 0)
        return;

    uint32_t i, count = 0;
    Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list;

    if (!onion_c->friends_list[friendnum].is_online) {
        for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
            if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
                continue;

            ++count;

            if (list_nodes[i].last_pinged == 0) {
                list_nodes[i].last_pinged = unix_time();
                continue;
            }

            if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) {
                if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) {
                    list_nodes[i].last_pinged = unix_time();
                }
            }
        }

        if (count != MAX_ONION_CLIENTS) {
            if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
                Node_format nodes_list[MAX_SENT_NODES];
                uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list,
                                                     (rand() % 2) ? AF_INET : AF_INET6, 1, 0);

                for (i = 0; i < num_nodes; ++i)
                    client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0);
            }
        }

        /* send packets to friend telling them our fake DHT id. */
        if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL))
            if (send_fakeid_announce(onion_c, friendnum, 0) >= 1)
                onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time();

        if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL))
            if (send_fakeid_announce(onion_c, friendnum, 1) >= 1)
                onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time();

    }
}
Beispiel #3
0
static void populate_path_nodes(Onion_Client *onion_c)
{
    Node_format nodes_list[MAX_SENT_NODES];
    uint8_t client_id[crypto_box_PUBLICKEYBYTES];
    uint32_t random_num = rand();
    memcpy(client_id, &random_num, sizeof(random_num));

    uint32_t num_nodes = get_close_nodes(onion_c->dht, client_id, nodes_list, (rand() % 2) ? AF_INET : AF_INET6, 1, 0);
    unsigned int i;

    for (i = 0; i < num_nodes; ++i) {
        onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].client_id);
    }
}
Beispiel #4
0
static void do_announce(Onion_Client *onion_c)
{
    uint32_t i, count = 0;
    Onion_Node *list_nodes = onion_c->clients_announce_list;

    for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
        if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
            continue;

        ++count;

        /* Don't announce ourselves the first time this is run to new peers */
        if (list_nodes[i].last_pinged == 0) {
            list_nodes[i].last_pinged = 1;
            continue;
        }

        uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;

        if (list_nodes[i].is_stored) {
            interval = ANNOUNCE_INTERVAL_ANNOUNCED;
        }

        if (is_timeout(list_nodes[i].last_pinged, interval)) {
            if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].client_id,
                                             list_nodes[i].ping_id, list_nodes[i].path_used) == 0) {
                list_nodes[i].last_pinged = unix_time();
            }
        }
    }

    if (count != MAX_ONION_CLIENTS) {
        if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
            Node_format nodes_list[MAX_SENT_NODES];
            uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list,
                                                 (rand() % 2) ? AF_INET : AF_INET6, 1, 0);

            for (i = 0; i < num_nodes; ++i) {
                client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0);
            }
        }
    }
}
Beispiel #5
0
//send a send nodes response
static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
{
    if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself
    {
        return 1;
    }
    
    uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 
                                    + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
                                    
    Node_format nodes_list[MAX_SENT_NODES];
    int num_nodes = get_close_nodes(client_id, nodes_list);
    
    if(num_nodes == 0)
    {
        return 0;
    }
    
    uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
    uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
    uint8_t nonce[crypto_box_NONCEBYTES];
    random_nonce(nonce);
    
    memcpy(plain, &ping_id, sizeof(ping_id));
    memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
    
    int len = encrypt_data(public_key, self_secret_key, nonce, plain, 
                                       sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
    
    if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
    {
        return -1;
    }
    
    data[0] = 3;
    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, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
   
}
Beispiel #6
0
Datei: DHT.c Projekt: nypox/nctox
//send a send nodes response
int sendnodes(IP_Port ip_port, char * client_id, uint32_t ping_id)
{
    char data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES];
    Node_format nodes_list[MAX_SENT_NODES];

    int num_nodes = get_close_nodes(client_id, nodes_list);

    if(num_nodes == 0)
    {
        return 0;
    }

    data[0] = 3;

    memcpy(data + 1, &ping_id, 4);
    memcpy(data + 5, self_client_id, CLIENT_ID_SIZE);
    memcpy(data + 5 + CLIENT_ID_SIZE, nodes_list, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));

    return sendpacket(ip_port, data, 5 + CLIENT_ID_SIZE + num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port)));
   
}
Beispiel #7
0
void test_list_main()
{
    DHT *dhts[NUM_DHT];

    uint8_t cmp_list1[NUM_DHT][MAX_FRIEND_CLIENTS][crypto_box_PUBLICKEYBYTES + 1];
    memset(cmp_list1, 0, sizeof(cmp_list1));

    IP ip;
    ip_init(&ip, 1);

    unsigned int i, j, k, l;

    for (i = 0; i < NUM_DHT; ++i) {
        IP ip;
        ip_init(&ip, 1);

        dhts[i] = new_DHT(new_networking(ip, DHT_DEFAULT_PORT + i));
        ck_assert_msg(dhts[i] != 0, "Failed to create dht instances %u", i);
        ck_assert_msg(dhts[i]->net->port != DHT_DEFAULT_PORT + i, "Bound to wrong port");
    }

    for (j = 0; j < NUM_DHT; ++j) {
        for (i = 1; i < NUM_DHT; ++i) {
            test_add_to_list(cmp_list1[j], MAX_FRIEND_CLIENTS, dhts[(i + j) % NUM_DHT]->self_public_key, dhts[j]->self_public_key);
        }
    }

    for (j = 0; j < NUM_DHT; ++j) {
        for (i = 0; i < NUM_DHT; ++i) {
            if (i == j)
                continue;

            IP_Port ip_port;
            ip_init(&ip_port.ip, 0);
            ip_port.ip.ip4.uint32 = rand();
            ip_port.port = rand() % (UINT16_MAX - 1);
            ++ip_port.port;
            addto_lists(dhts[j], ip_port, dhts[i]->self_public_key);
        }
    }

    /*
        print_pk(dhts[0]->self_public_key);

        for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
            printf("----Entry %u----\n", i);

            print_pk(cmp_list1[i]);
        }
    */
    unsigned int m_count = 0;

    for (l = 0; l < NUM_DHT; ++l) {
        for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
            for (j = 1; j < NUM_DHT; ++j) {
                if (memcmp(cmp_list1[l][i], dhts[(l + j) % NUM_DHT]->self_public_key, crypto_box_PUBLICKEYBYTES) != 0)
                    continue;

                unsigned int count = 0;

                for (k = 0; k < LCLIENT_LIST; ++k) {
                    if (memcmp(dhts[l]->self_public_key, dhts[(l + j) % NUM_DHT]->close_clientlist[k].public_key,
                               crypto_box_PUBLICKEYBYTES) == 0)
                        ++count;
                }

                if (count != 1) {
                    print_pk(dhts[l]->self_public_key);

                    for (k = 0; k < MAX_FRIEND_CLIENTS; ++k) {
                        printf("----Entry %u----\n", k);

                        print_pk(cmp_list1[l][k]);
                    }

                    for (k = 0; k < LCLIENT_LIST; ++k) {
                        printf("----Closel %u----\n", k);
                        print_pk(dhts[(l + j) % NUM_DHT]->close_clientlist[k].public_key);
                    }

                    print_pk(dhts[(l + j) % NUM_DHT]->self_public_key);
                }

                ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);

                Node_format ln[MAX_SENT_NODES];
                int n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, 0, 1, 0);
                ck_assert_msg(n == MAX_SENT_NODES, "bad num close %u | %u %u", n, i, j);

                count = 0;

                for (k = 0; k < MAX_SENT_NODES; ++k) {
                    if (memcmp(dhts[l]->self_public_key, ln[k].public_key, crypto_box_PUBLICKEYBYTES) == 0)
                        ++count;
                }

                ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);
                /*
                            for (k = 0; k < MAX_SENT_NODES; ++k) {
                                printf("----gn %u----\n", k);
                                print_pk(ln[k].public_key);
                            }*/
                ++m_count;
            }
        }
    }

    ck_assert_msg(m_count == (NUM_DHT) * (MAX_FRIEND_CLIENTS), "Bad count. %u != %u", m_count,
                  (NUM_DHT) * (MAX_FRIEND_CLIENTS));

    for (i = 0; i < NUM_DHT; ++i) {
        void *n = dhts[i]->net;
        kill_DHT(dhts[i]);
        kill_networking(n);
    }
}
Beispiel #8
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;
}