/* Like tox_bootstrap_from_address but for TCP relays only. * * return 0 on failure. * return 1 on success. */ int tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key) { Messenger *m = tox; IP_Port ip_port, ip_port_v4; if (!addr_parse_ip(address, &ip_port.ip)) { if (m->options.udp_disabled) /* Disable DNS when udp is disabled. */ return 0; IP *ip_extra = NULL; ip_init(&ip_port.ip, m->options.ipv6enabled); if (m->options.ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ ip_port.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (!addr_resolve(address, &ip_port.ip, ip_extra)) return 0; } ip_port.port = htons(port); add_tcp_relay(m->net_crypto, ip_port, public_key); onion_add_path_node(m->onion_c, ip_port, public_key); //TODO: move this return 1; }
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); } }
static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port, uint8_t is_stored, const uint8_t *pingid_or_key, uint32_t path_num) { if (num > onion_c->num_friends) return -1; Onion_Node *list_nodes = NULL; uint8_t *reference_id = NULL; if (num == 0) { list_nodes = onion_c->clients_announce_list; reference_id = onion_c->c->self_public_key; if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) { is_stored = 0; } } else { list_nodes = onion_c->friends_list[num - 1].clients_list; reference_id = onion_c->friends_list[num - 1].real_client_id; } memcpy(cmp_public_key, reference_id, crypto_box_PUBLICKEYBYTES); qsort(list_nodes, MAX_ONION_CLIENTS, sizeof(Onion_Node), cmp_entry); int index = -1, stored = 0; uint32_t i; if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) || id_closest(reference_id, list_nodes[0].client_id, public_key) == 2) { index = 0; } for (i = 0; i < MAX_ONION_CLIENTS; ++i) { if (memcmp(list_nodes[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { index = i; stored = 1; break; } } if (index == -1) return 0; memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); list_nodes[index].ip_port = ip_port; //TODO: remove this and find a better source of nodes to use for paths. onion_add_path_node(onion_c, ip_port, public_key); if (is_stored) { memcpy(list_nodes[index].data_public_key, pingid_or_key, crypto_box_PUBLICKEYBYTES); } else { memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE); } list_nodes[index].is_stored = is_stored; list_nodes[index].timestamp = unix_time(); if (!stored) list_nodes[index].last_pinged = 0; list_nodes[index].path_used = set_path_timeouts(onion_c, num, path_num); return 0; }