/* 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); }
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; }
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); }
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); } }