int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key); return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); }
int tox_bootstrap_from_address(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key) { Messenger *m = tox; int ret = tox_add_tcp_relay(tox, address, port, public_key); if (m->options.udp_disabled) { return ret; } else { /* DHT only works on UDP. */ return DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key); } }
void CToxProto::BootstrapNode(const char *address, int port, const char *hexKey) { if (hexKey == NULL) return; ToxBinAddress binKey(hexKey, TOX_PUBLIC_KEY_SIZE * 2); TOX_ERR_BOOTSTRAP error; if (!tox_bootstrap(tox, address, port, binKey, &error)) debugLogA(__FUNCTION__ ": failed to bootstrap node %s:%d \"%s\" (%d)", address, port, hexKey, error); if (!tox_add_tcp_relay(tox, address, port, binKey, &error)) debugLogA(__FUNCTION__ ": failed to add tcp relay%s:%d \"%s\" (%d)", address, port, hexKey, error); }
/* From uTox/tox.c */ static void do_bootstrap(Tox *tox) { static unsigned int j = 0; if (j == 0) j = rand(); int i = 0; while(i < 4) { struct bootstrap_node *d = &bootstrap_nodes[j % countof(bootstrap_nodes)]; tox_bootstrap(tox, d->address, d->port, d->key, 0); tox_add_tcp_relay(tox, d->address, d->port, d->key, 0); i++; j++; } }
void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc != 3) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Require: <ip> <port> <key>"); return; } const char *ip = argv[1]; const char *port_str = argv[2]; const char *ascii_key = argv[3]; long int port = strtol(port_str, NULL, 10); if (port <= 0 || port > MAX_PORT_RANGE) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); return; } char key_binary[TOX_PUBLIC_KEY_SIZE * 2 + 1]; if (hex_string_to_bin(ascii_key, strlen(ascii_key), key_binary, TOX_PUBLIC_KEY_SIZE) == -1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid key."); return; } TOX_ERR_BOOTSTRAP err; tox_bootstrap(m, ip, port, (uint8_t *) key_binary, &err); tox_add_tcp_relay(m, ip, port, (uint8_t *) key_binary, &err); switch (err) { case TOX_ERR_BOOTSTRAP_BAD_HOST: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid IP."); break; case TOX_ERR_BOOTSTRAP_BAD_PORT: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid port."); break; case TOX_ERR_BOOTSTRAP_NULL: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed."); break; default: break; } }
/* Bootstraps and adds as TCP relay. * Returns 0 if both actions are successful. * Returns -1 otherwise. */ int init_connection_helper(Tox *m, int line) { TOX_ERR_BOOTSTRAP err; tox_bootstrap(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); if (err != TOX_ERR_BOOTSTRAP_OK) { fprintf(stderr, "Failed to bootstrap %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); return -1; } tox_add_tcp_relay(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); if (err != TOX_ERR_BOOTSTRAP_OK) { fprintf(stderr, "Failed to add TCP relay %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); return -1; } return 0; }
/** * @brief Connects us to the Tox network */ void Core::bootstrapDht() { const Settings& s = Settings::getInstance(); QList<DhtServer> dhtServerList = s.getDhtServerList(); int listSize = dhtServerList.size(); if (listSize == 0) { qWarning() << "no bootstrap list?!?"; return; } static int j = qrand() % listSize; int i=0; while (i < 2) // i think the more we bootstrap, the more we jitter because the more we overwrite nodes { const DhtServer& dhtServer = dhtServerList[j % listSize]; qDebug() << "Connecting to "+QString(dhtServer.address.toLatin1().data()) +':'+QString().setNum(dhtServer.port)+" ("+dhtServer.name+')'; QByteArray address = dhtServer.address.toLatin1(); // TODO: constucting the pk via ToxId is a workaround ToxPk pk = ToxId{dhtServer.userId}.getPublicKey(); const uint8_t* pkPtr = reinterpret_cast<const uint8_t*>(pk.getBytes()); if (!tox_bootstrap(tox, address.constData(), dhtServer.port, pkPtr, nullptr)) { qDebug() << "Error bootstrapping from "+dhtServer.name; } if (!tox_add_tcp_relay(tox, address.constData(), dhtServer.port, pkPtr, nullptr)) { qDebug() << "Error adding TCP relay from "+dhtServer.name; } ++j; ++i; } }
void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc != 3) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Require: <ip> <port> <key>"); return; } const char *ip = argv[1]; const char *port = argv[2]; const char *key = argv[3]; if (atoi(port) == 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); return; } char *binary_string = hex_string_to_bin(key); TOX_ERR_BOOTSTRAP err; tox_bootstrap(m, ip, atoi(port), (uint8_t *) binary_string, &err); tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) binary_string, &err); free(binary_string); switch (err) { case TOX_ERR_BOOTSTRAP_BAD_HOST: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid IP."); break; case TOX_ERR_BOOTSTRAP_BAD_PORT: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid port."); break; case TOX_ERR_BOOTSTRAP_NULL: line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed."); break; default: break; } }
/** * @brief Connects us to the Tox network */ void Core::bootstrapDht() { const Settings& s = Settings::getInstance(); QList<DhtServer> dhtServerList = s.getDhtServerList(); int listSize = dhtServerList.size(); if (listSize == 0) { qWarning() << "no bootstrap list?!?"; return; } static int j = qrand() % listSize; int i=0; while (i < 2) // i think the more we bootstrap, the more we jitter because the more we overwrite nodes { const DhtServer& dhtServer = dhtServerList[j % listSize]; qDebug() << "Connecting to "+QString(dhtServer.address.toLatin1().data()) +':'+QString().setNum(dhtServer.port)+" ("+dhtServer.name+')'; if (!tox_bootstrap(tox, dhtServer.address.toLatin1().data(), dhtServer.port, CUserId(dhtServer.userId).data(), nullptr)) { qDebug() << "Error bootstrapping from "+dhtServer.name; } if (!tox_add_tcp_relay(tox, dhtServer.address.toLatin1().data(), dhtServer.port, CUserId(dhtServer.userId).data(), nullptr)) { qDebug() << "Error adding TCP relay from "+dhtServer.name; } j++; i++; } }
END_TEST #define NUM_TCP_RELAYS 3 START_TEST(test_many_clients_tcp_b) { long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; uint32_t i, j; uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { struct Tox_Options *opts = tox_options_new(nullptr); if (i < NUM_TCP_RELAYS) { tox_options_set_tcp_port(opts, TCP_RELAY_PORT + i); } else { tox_options_set_udp_enabled(opts, 0); } index[i] = i + 1; toxes[i] = tox_new_log(opts, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, TCP_RELAY_PORT + (i % NUM_TCP_RELAYS), dpk, nullptr), "add relay error"); tox_self_get_dht_id(toxes[0], dpk); uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error"); tox_options_free(opts); } struct { uint16_t tox1; uint16_t tox2; } pairs[NUM_FRIENDS]; uint8_t address[TOX_ADDRESS_SIZE]; for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: pairs[i].tox1 = random_u32() % NUM_TOXES_TCP; pairs[i].tox2 = (pairs[i].tox1 + random_u32() % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { goto loop_top; } } tox_self_get_address(toxes[pairs[i].tox1], address); TOX_ERR_FRIEND_ADD test; uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test); if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { goto loop_top; } ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); } uint16_t last_count = 0; while (1) { uint16_t counter = 0; for (i = 0; i < NUM_TOXES_TCP; ++i) { for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) { if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) { ++counter; } } } if (counter != last_count) { printf("many_clients_tcp_b got to %u\n", counter); last_count = counter; } if (counter == NUM_FRIENDS * 2) { break; } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_iterate(toxes[i], &to_comp); } c_sleep(30); } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time); }