Esempio n. 1
0
/* add entry to entries list
 *
 * return -1 if failure
 * return position if added
 */
static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const uint8_t *public_key,
                          const uint8_t *data_public_key, const uint8_t *ret)
{

    int pos = in_entries(onion_a, public_key);

    if (pos == -1) {
        for (unsigned i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
            if (mono_time_is_timeout(onion_a->mono_time, onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)) {
                pos = i;
            }
        }
    }

    if (pos == -1) {
        if (id_closest(dht_get_self_public_key(onion_a->dht), public_key, onion_a->entries[0].public_key) == 1) {
            pos = 0;
        }
    }

    if (pos == -1) {
        return -1;
    }

    memcpy(onion_a->entries[pos].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
    onion_a->entries[pos].ret_ip_port = ret_ip_port;
    memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
    memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
    onion_a->entries[pos].time = mono_time_get(onion_a->mono_time);

    sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, onion_a->mono_time,
                             dht_get_self_public_key(onion_a->dht));
    return in_entries(onion_a, public_key);
}
Esempio n. 2
0
int lan_discovery_send(uint16_t port, DHT *dht)
{
    uint8_t data[CRYPTO_PUBLIC_KEY_SIZE + 1];
    data[0] = NET_PACKET_LAN_DISCOVERY;
    id_copy(data + 1, dht_get_self_public_key(dht));

    send_broadcasts(dht_get_net(dht), port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE);

    int res = -1;
    IP_Port ip_port;
    ip_port.port = port;

    /* IPv6 multicast */
    if (net_family(dht_get_net(dht)) == TOX_AF_INET6) {
        ip_port.ip = broadcast_ip(TOX_AF_INET6, TOX_AF_INET6);

        if (ip_isset(&ip_port.ip)) {
            if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) {
                res = 1;
            }
        }
    }

    /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is TOX_AF_INET6 */
    ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), TOX_AF_INET);

    if (ip_isset(&ip_port.ip)) {
        if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) {
            res = 1;
        }
    }

    return res;
}
Esempio n. 3
0
static void manage_keys(DHT *dht)
{
    enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
    uint8_t keys[KEYS_SIZE];

    FILE *keys_file = fopen("key", "r");

    if (keys_file != nullptr) {
        /* If file was opened successfully -- load keys,
           otherwise save new keys */
        size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);

        if (read_size != KEYS_SIZE) {
            printf("Error while reading the key file\nExiting.\n");
            exit(1);
        }

        dht_set_self_public_key(dht, keys);
        dht_set_self_secret_key(dht, keys + CRYPTO_PUBLIC_KEY_SIZE);
        printf("Keys loaded successfully.\n");
    } else {
        memcpy(keys, dht_get_self_public_key(dht), CRYPTO_PUBLIC_KEY_SIZE);
        memcpy(keys + CRYPTO_PUBLIC_KEY_SIZE, dht_get_self_secret_key(dht), CRYPTO_SECRET_KEY_SIZE);
        keys_file = fopen("key", "w");

        if (keys_file == nullptr) {
            printf("Error opening key file in write mode.\nKeys will not be saved.\n");
            return;
        }

        if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) {
            printf("Error while writing the key file.\nExiting.\n");
            exit(1);
        }

        printf("Keys saved successfully.\n");
    }

    fclose(keys_file);
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
    if (argc == 2 && !tox_strncasecmp(argv[1], "-h", 3)) {
        printf("Usage (connected)  : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]);
        printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]);
        exit(0);
    }

    /* let user override default by cmdline */
    bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
    int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);

    if (argvoffset < 0) {
        exit(1);
    }

    /* Initialize networking -
       Bind to ip 0.0.0.0 / [::] : PORT */
    IP ip;
    ip_init(&ip, ipv6enabled);

    Logger *logger = logger_new();

    if (MIN_LOGGER_LEVEL == LOGGER_LEVEL_TRACE || MIN_LOGGER_LEVEL == LOGGER_LEVEL_DEBUG) {
        logger_callback_log(logger, print_log, nullptr, nullptr);
    }

    Mono_Time *mono_time = mono_time_new();
    DHT *dht = new_dht(logger, mono_time, new_networking(logger, ip, PORT), true);
    Onion *onion = new_onion(mono_time, dht);
    Onion_Announce *onion_a = new_onion_announce(mono_time, dht);

#ifdef DHT_NODE_EXTRA_PACKETS
    bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
#endif

    if (!(onion && onion_a)) {
        printf("Something failed to initialize.\n");
        exit(1);
    }

    perror("Initialization");

    manage_keys(dht);
    printf("Public key: ");
    uint32_t i;

#ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3
    uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
    TCP_Server *tcp_s = new_TCP_server(ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion);

    if (tcp_s == nullptr) {
        printf("TCP server failed to initialize.\n");
        exit(1);
    }

#endif

    const char *const public_id_filename = "PUBLIC_ID.txt";
    FILE *file = fopen(public_id_filename, "w");

    if (file == nullptr) {
        printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename);
        exit(1);
    }

    for (i = 0; i < 32; i++) {
        const uint8_t *const self_public_key = dht_get_self_public_key(dht);
        printf("%02X", self_public_key[i]);
        fprintf(file, "%02X", self_public_key[i]);
    }

    fclose(file);

    printf("\n");
    printf("Port: %u\n", net_ntohs(net_port(dht_get_net(dht))));

    if (argc > argvoffset + 3) {
        printf("Trying to bootstrap into the network...\n");
        uint16_t port = net_htons(atoi(argv[argvoffset + 2]));
        uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
        int res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
                                             ipv6enabled, port, bootstrap_key);
        free(bootstrap_key);

        if (!res) {
            printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
            exit(1);
        }
    }

    int is_waiting_for_dht_connection = 1;

    uint64_t last_LANdiscovery = 0;
    lan_discovery_init(dht);

    while (1) {
        mono_time_update(mono_time);

        if (is_waiting_for_dht_connection && dht_isconnected(dht)) {
            printf("Connected to other bootstrap node successfully.\n");
            is_waiting_for_dht_connection = 0;
        }

        do_dht(dht);

        if (mono_time_is_timeout(mono_time, last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
            lan_discovery_send(net_htons(PORT), dht);
            last_LANdiscovery = mono_time_get(mono_time);
        }

#ifdef TCP_RELAY_ENABLED
        do_TCP_server(tcp_s, mono_time);
#endif
        networking_poll(dht_get_net(dht), nullptr);

        c_sleep(1);
    }
}