static Tox *init_tox(void) { struct Tox_Options tox_opts; memset(&tox_opts, 0, sizeof(struct Tox_Options)); tox_options_default(&tox_opts); Tox *m = load_tox(&tox_opts, DATA_FILE); if (!m) return NULL; tox_callback_self_connection_status(m, cb_self_connection_change, NULL); tox_callback_friend_connection_status(m, cb_friend_connection_change, NULL); tox_callback_friend_request(m, cb_friend_request, NULL); tox_callback_friend_message(m, cb_friend_message, NULL); tox_callback_group_invite(m, cb_group_invite, NULL); tox_callback_group_title(m, cb_group_titlechange, NULL); size_t s_len = tox_self_get_status_message_size(m); if (s_len == 0) { const char *statusmsg = "Send me the command 'help' for more info"; tox_self_set_status_message(m, (uint8_t *) statusmsg, strlen(statusmsg), NULL); } size_t n_len = tox_self_get_name_size(m); if (n_len == 0) tox_self_set_name(m, (uint8_t *) "[LUGNSK]", strlen("[LUGNSK]"), NULL); return m; }
static void init_tox_options(struct Tox_Options *tox_opts) { tox_options_default(tox_opts); tox_opts->ipv6_enabled = !arg_opts.use_ipv4; tox_opts->udp_enabled = !arg_opts.force_tcp; tox_opts->proxy_type = arg_opts.proxy_type; tox_opts->tcp_port = arg_opts.tcp_port; if (!tox_opts->ipv6_enabled) queue_init_message("Forcing IPv4 connection"); if (tox_opts->tcp_port) queue_init_message("TCP relaying enabled on port %d", tox_opts->tcp_port); if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { tox_opts->proxy_port = arg_opts.proxy_port; tox_opts->proxy_host = arg_opts.proxy_address; const char *ps = tox_opts->proxy_type == TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : "HTTP"; char tmp[48]; snprintf(tmp, sizeof(tmp), "Using %s proxy %s : %d", ps, arg_opts.proxy_address, arg_opts.proxy_port); queue_init_message("%s", tmp); } if (!tox_opts->udp_enabled) { queue_init_message("UDP disabled"); } else if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { const char *msg = "WARNING: Using a proxy without disabling UDP may leak your real IP address."; queue_init_message("%s", msg); msg = "Use the -t option to disable UDP."; queue_init_message("%s", msg); } }
struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error) { struct Tox_Options *options = (struct Tox_Options *)malloc(sizeof(struct Tox_Options)); if (options) { tox_options_default(options); SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); return options; } SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); return nullptr; }
/** * @brief Initializes Tox_Options instance * @param savedata Previously saved Tox data * @return Tox_Options instance needed to create Tox instance */ Tox_Options initToxOptions(const QByteArray& savedata) { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be // disabled in options. const Settings& s = Settings::getInstance(); bool enableIPv6 = s.getEnableIPv6(); bool forceTCP = s.getForceTCP(); Settings::ProxyType proxyType = s.getProxyType(); quint16 proxyPort = s.getProxyPort(); QString proxyAddr = s.getProxyAddr(); QByteArray proxyAddrData = proxyAddr.toUtf8(); if (enableIPv6) { qDebug() << "Core starting with IPv6 enabled"; } else { qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; } Tox_Options toxOptions; tox_options_default(&toxOptions); toxOptions.ipv6_enabled = enableIPv6; toxOptions.udp_enabled = !forceTCP; toxOptions.start_port = toxOptions.end_port = 0; // No proxy by default toxOptions.proxy_type = TOX_PROXY_TYPE_NONE; toxOptions.proxy_host = nullptr; toxOptions.proxy_port = 0; toxOptions.savedata_type = !savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE; toxOptions.savedata_data = reinterpret_cast<const uint8_t*>(savedata.data()); toxOptions.savedata_length = savedata.size(); if (proxyType != Settings::ProxyType::ptNone) { if (proxyAddr.length() > MAX_PROXY_ADDRESS_LENGTH) { qWarning() << "proxy address" << proxyAddr << "is too long"; } else if (!proxyAddr.isEmpty() && proxyPort > 0) { qDebug() << "using proxy" << proxyAddr << ":" << proxyPort; // protection against changings in TOX_PROXY_TYPE enum if (proxyType == Settings::ProxyType::ptSOCKS5) { toxOptions.proxy_type = TOX_PROXY_TYPE_SOCKS5; } else if (proxyType == Settings::ProxyType::ptHTTP) { toxOptions.proxy_type = TOX_PROXY_TYPE_HTTP; } toxOptions.proxy_host = proxyAddrData.data(); toxOptions.proxy_port = proxyPort; } } return toxOptions; }
/* * Returns a pointer to an inactive crawler in the threads array. * Returns NULL if there are no crawlers available. */ Crawler *crawler_new(void) { Crawler *cwl = calloc(1, sizeof(Crawler)); if (cwl == NULL) { return cwl; } Node_format *nodes_list = malloc(DEFAULT_NODES_LIST_SIZE * sizeof(Node_format)); if (nodes_list == NULL) { free(cwl); return NULL; } struct Tox_Options options; tox_options_default(&options); TOX_ERR_NEW err; Tox *tox = tox_new(&options, &err); if (err != TOX_ERR_NEW_OK || tox == NULL) { fprintf(stderr, "tox_new() failed: %d\n", err); free(cwl); free(nodes_list); return NULL; } Messenger *m = (Messenger *) tox; // Casting fuckery so we can access the DHT object directly cwl->dht = m->dht; cwl->tox = tox; cwl->nodes_list = nodes_list; cwl->nodes_list_size = DEFAULT_NODES_LIST_SIZE; DHT_callback_getnodes_response(cwl->dht, cb_getnodes_response, cwl); cwl->last_getnodes_request = get_time(); cwl->last_new_node = get_time(); bootstrap_tox(cwl); return cwl; }
int main(void) { uint32_t conference_number; struct Tox_Options to; Tox *t; TOX_ERR_CONFERENCE_NEW conference_err; TOX_ERR_CONFERENCE_TITLE title_err; tox_options_default(&to); t = tox_new(&to, NULL); tox_callback_conference_title(t, &cbtitlechange); if ((conference_number = tox_conference_new(t, &conference_err)) == UINT32_MAX) { tox_kill(t); fprintf(stderr, "error: could not create new conference, error code %d\n", conference_err); return 2; } tox_iterate(t, NULL); c_sleep(tox_iteration_interval(t)); if (!tox_conference_set_title(t, conference_number, (const uint8_t *)newtitle, strlen(newtitle), &title_err)) { tox_kill(t); fprintf(stderr, "error: could not set conference title, error code %d\n", title_err); return 3; } tox_iterate(t, NULL); c_sleep(tox_iteration_interval(t)); tox_iterate(t, NULL); fprintf(stderr, "error: title was not changed in callback. exiting.\n"); tox_kill(t); return 1; }
static void test_one(void) { uint8_t name[TOX_MAX_NAME_LENGTH]; uint8_t status_message[TOX_MAX_STATUS_MESSAGE_LENGTH]; uint8_t name2[TOX_MAX_NAME_LENGTH]; uint8_t status_message2[TOX_MAX_STATUS_MESSAGE_LENGTH]; uint32_t index[] = { 1, 2 }; Tox *tox1 = tox_new_log(nullptr, nullptr, &index[0]); set_random_name_and_status_message(tox1, name, status_message); Tox *tox2 = tox_new_log(nullptr, nullptr, &index[1]); set_random_name_and_status_message(tox2, name2, status_message2); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox1, address); Tox_Err_Friend_Add error; uint32_t ret = tox_friend_add(tox1, address, (const uint8_t *)"m", 1, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_OWN_KEY, "Adding own address worked."); tox_self_get_address(tox2, address); uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH + 1]; ret = tox_friend_add(tox1, address, nullptr, 0, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_NULL, "Sending request with no message worked."); ret = tox_friend_add(tox1, address, message, 0, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_NO_MESSAGE, "Sending request with no message worked."); ret = tox_friend_add(tox1, address, message, sizeof(message), &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_TOO_LONG, "TOX_MAX_FRIEND_REQUEST_LENGTH is too big."); address[0]++; ret = tox_friend_add(tox1, address, (const uint8_t *)"m", 1, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM, "Adding address with bad checksum worked."); tox_self_get_address(tox2, address); ret = tox_friend_add(tox1, address, message, TOX_MAX_FRIEND_REQUEST_LENGTH, &error); ck_assert_msg(ret == 0 && error == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend."); ret = tox_friend_add(tox1, address, message, TOX_MAX_FRIEND_REQUEST_LENGTH, &error); ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_ALREADY_SENT, "Adding friend twice worked."); tox_self_set_name(tox1, name, sizeof(name), nullptr); ck_assert_msg(tox_self_get_name_size(tox1) == sizeof(name), "Can't set name of TOX_MAX_NAME_LENGTH"); tox_self_set_status_message(tox1, status_message, sizeof(status_message), nullptr); ck_assert_msg(tox_self_get_status_message_size(tox1) == sizeof(status_message), "Can't set status message of TOX_MAX_STATUS_MESSAGE_LENGTH"); tox_self_get_address(tox1, address); size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, data, save_size); tox_get_savedata(tox1, data); tox_kill(tox2); Tox_Err_New err_n; struct Tox_Options *options = tox_options_new(nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, data, save_size); tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); ck_assert_msg(tox_self_get_name_size(tox2) == sizeof name, "Wrong name size."); ck_assert_msg(tox_self_get_status_message_size(tox2) == sizeof status_message, "Wrong status message size"); uint8_t name_loaded[TOX_MAX_NAME_LENGTH] = { 0 }; tox_self_get_name(tox2, name_loaded); ck_assert_msg(!memcmp(name, name_loaded, sizeof name), "Wrong name."); uint8_t status_message_loaded[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; tox_self_get_status_message(tox2, status_message_loaded); ck_assert_msg(!memcmp(status_message, status_message_loaded, sizeof status_message_loaded), "Wrong status message."); uint8_t address2[TOX_ADDRESS_SIZE] = { 0 }; tox_self_get_address(tox2, address2); ck_assert_msg(memcmp(address2, address, TOX_ADDRESS_SIZE) == 0, "Wrong address."); uint8_t new_name[TOX_MAX_NAME_LENGTH] = { 0 }; tox_self_get_name(tox2, new_name); ck_assert_msg(memcmp(name, new_name, TOX_MAX_NAME_LENGTH) == 0, "Wrong name"); uint8_t sk[TOX_SECRET_KEY_SIZE]; tox_self_get_secret_key(tox2, sk); tox_kill(tox2); tox_options_default(options); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_SECRET_KEY); tox_options_set_savedata_data(options, sk, sizeof(sk)); tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); uint8_t address3[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address3); ck_assert_msg(memcmp(address3, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key."); uint8_t pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, pk); ck_assert_msg(memcmp(pk, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key."); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); }
void Core::makeTox(QByteArray savedata) { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); bool forceTCP = Settings::getInstance().getForceTCP(); Settings::ProxyType proxyType = Settings::getInstance().getProxyType(); quint16 proxyPort = Settings::getInstance().getProxyPort(); QString proxyAddr = Settings::getInstance().getProxyAddr(); QByteArray proxyAddrData = proxyAddr.toUtf8(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; tox_options_default(&toxOptions); toxOptions.ipv6_enabled = enableIPv6; toxOptions.udp_enabled = !forceTCP; toxOptions.start_port = toxOptions.end_port = 0; // No proxy by default toxOptions.proxy_type = TOX_PROXY_TYPE_NONE; toxOptions.proxy_host = nullptr; toxOptions.proxy_port = 0; toxOptions.savedata_type = (!savedata.isNull() ? TOX_SAVEDATA_TYPE_TOX_SAVE : TOX_SAVEDATA_TYPE_NONE); toxOptions.savedata_data = (uint8_t*)savedata.data(); toxOptions.savedata_length = savedata.size(); if (proxyType != Settings::ProxyType::ptNone) { if (proxyAddr.length() > 255) { qWarning() << "proxy address" << proxyAddr << "is too long"; } else if (proxyAddr != "" && proxyPort > 0) { qDebug() << "using proxy" << proxyAddr << ":" << proxyPort; // protection against changings in TOX_PROXY_TYPE enum if (proxyType == Settings::ProxyType::ptSOCKS5) toxOptions.proxy_type = TOX_PROXY_TYPE_SOCKS5; else if (proxyType == Settings::ProxyType::ptHTTP) toxOptions.proxy_type = TOX_PROXY_TYPE_HTTP; toxOptions.proxy_host = proxyAddrData.data(); toxOptions.proxy_port = proxyPort; } } TOX_ERR_NEW tox_err; tox = tox_new(&toxOptions, &tox_err); switch (tox_err) { case TOX_ERR_NEW_OK: break; case TOX_ERR_NEW_LOAD_BAD_FORMAT: qWarning() << "failed to parse Tox save data"; break; case TOX_ERR_NEW_PORT_ALLOC: if (enableIPv6) { toxOptions.ipv6_enabled = false; tox = tox_new(&toxOptions, &tox_err); if (tox_err == TOX_ERR_NEW_OK) { qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; break; } } qCritical() << "can't to bind the port"; emit failedToStart(); return; case TOX_ERR_NEW_PROXY_BAD_HOST: case TOX_ERR_NEW_PROXY_BAD_PORT: case TOX_ERR_NEW_PROXY_BAD_TYPE: qCritical() << "bad proxy, error code:" << tox_err; emit badProxy(); return; case TOX_ERR_NEW_PROXY_NOT_FOUND: qCritical() << "proxy not found"; emit badProxy(); return; case TOX_ERR_NEW_LOAD_ENCRYPTED: qCritical() << "attempted to load encrypted Tox save data"; emit failedToStart(); return; case TOX_ERR_NEW_MALLOC: qCritical() << "memory allocation failed"; emit failedToStart(); return; case TOX_ERR_NEW_NULL: qCritical() << "a parameter was null"; emit failedToStart(); return; default: qCritical() << "Tox core failed to start, unknown error code:" << tox_err; emit failedToStart(); return; } av = new CoreAV(tox); if (av->getToxAv() == nullptr) { qCritical() << "Toxav core failed to start"; emit failedToStart(); return; } }
int main(int argc, char *argv[]) { unsigned char tox_id[TOX_ADDRESS_SIZE]; unsigned char tox_printable_id[TOX_ADDRESS_SIZE * 2 + 1]; TOX_ERR_NEW tox_new_err; int oc; size_t save_size = 0; uint8_t *save_data = NULL; allowed_toxid *allowed_toxid_obj = NULL; log_init(); while ((oc = getopt(argc, argv, "L:pi:C:s:P:dqhSF:DU:")) != -1) { switch(oc) { case 'L': /* Local port forwarding */ client_mode = 1; client_local_port_mode = 1; if(parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port) < 0) { log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n"); exit(1); } if(min_log_level == L_UNSET) { min_log_level = L_INFO; } log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port); break; case 'P': /* Pipe forwarding */ client_mode = 1; client_pipe_mode = 1; if(parse_pipe_port_forward(optarg, &remote_host, &remote_port) < 0) { log_printf(L_ERROR, "Invalid value for -P option - use something like -P 127.0.0.1:22\n"); exit(1); } if(min_log_level == L_UNSET) { min_log_level = L_ERROR; } log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port); break; case 'p': /* Ping */ client_mode = 1; ping_mode = 1; if(min_log_level == L_UNSET) { min_log_level = L_INFO; } break; case 'i': /* Tox ID */ server_whitelist_mode = 1; log_printf(L_DEBUG, "Server whitelist mode enabled"); allowed_toxid_obj = (allowed_toxid *)calloc(sizeof(allowed_toxid), 1); if(!allowed_toxid_obj) { log_printf(L_ERROR, "Could not allocate memory for allowed_toxid"); exit(1); } remote_tox_id = optarg; if(!string_to_id(allowed_toxid_obj->toxid, optarg)) { log_printf(L_ERROR, "Invalid Tox ID"); exit(1); } LL_APPEND(allowed_toxids, allowed_toxid_obj); break; case 'C': /* Config directory */ strncpy(config_path, optarg, sizeof(config_path) - 1); if(optarg[strlen(optarg) - 1] != '/') { int optarg_len = strlen(optarg); config_path[optarg_len] = '/'; config_path[optarg_len + 1] = '\0'; } load_saved_toxid_in_client_mode = 1; break; case 's': /* Shared secret */ use_shared_secret = 1; memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH); strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1); break; case 'd': min_log_level = L_DEBUG; break; case 'q': min_log_level = L_ERROR; break; case 'S': use_syslog = 1; break; case 'D': daemonize = 1; use_syslog = 1; break; case 'F': pidfile = optarg; break; case 'U': daemon_username = optarg; break; case '?': case 'h': default: print_version(); help(); exit(1); } } if(!client_mode && min_log_level == L_UNSET) { min_log_level = L_INFO; } if(!client_mode && server_whitelist_mode) { log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); } if(daemonize) { do_daemonize(); } atexit(cleanup); print_version(); /* Bootstrap tox */ tox_options_default(&tox_options); if((!client_mode) || load_saved_toxid_in_client_mode) { uint8_t *save_data = NULL; save_size = load_save(&save_data); if(save_data && save_size) { tox_options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; tox_options.savedata_data = save_data; tox_options.savedata_length = save_size; } } tox = tox_new(&tox_options, &tox_new_err); if(tox == NULL) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying without proxy\n", tox_new_err); if((tox_options.proxy_type != TOX_PROXY_TYPE_NONE) || (tox_options.proxy_type = TOX_PROXY_TYPE_NONE, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying without IPv6\n", tox_new_err); if(!tox_options.ipv6_enabled || (tox_options.ipv6_enabled = 0, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying with Tor\n", tox_new_err); if((tox_options.proxy_type = TOX_PROXY_TYPE_SOCKS5, tox_options.proxy_host="127.0.0.1", tox_options.proxy_port=9050, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_ERROR, "tox_new() failed (%u) - exiting\n", tox_new_err); exit(1); } } } } if(save_size && save_data) { free(save_data); } set_tox_username(tox); tox_callback_self_connection_status(tox, handle_connection_status_change, NULL); do_bootstrap(tox); if(client_mode) { tox_self_get_address(tox, tox_id); id_to_string(tox_printable_id, tox_id); tox_printable_id[TOX_ADDRESS_SIZE * 2] = '\0'; log_printf(L_DEBUG, "Generated Tox ID: %s\n", tox_printable_id); if(!remote_tox_id) { log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n"); exit(1); } do_client_loop(remote_tox_id); } else { write_save(tox); if(!use_shared_secret) { log_printf(L_WARNING, "Shared secret authentication is not used - skilled attackers may connect to your tuntox server"); } tox_self_get_address(tox, tox_id); memset(tox_printable_id, '\0', sizeof(tox_printable_id)); id_to_string(tox_printable_id, tox_id); tox_printable_id[TOX_ADDRESS_SIZE * 2] = '\0'; log_printf(L_INFO, "Using Tox ID: %s\n", tox_printable_id); tox_callback_friend_request(tox, accept_friend_request, NULL); do_server_loop(); } return 0; }
END_TEST #define NUM_TCP_RELAYS 3 START_TEST(test_many_clients_tcp_b) { long long unsigned int cur_time = time(NULL); 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_default(&opts); if (i < NUM_TCP_RELAYS) { opts.tcp_port = TCP_RELAY_PORT + i; } else { opts.udp_enabled = 0; } index[i] = i + 1; toxes[i] = tox_new_log(&opts, 0, &index[i]); ck_assert_msg(toxes[i] != 0, "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, 0), "add relay error"); tox_self_get_dht_id(toxes[0], dpk); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, 33445, dpk, 0), "Bootstrap error"); } { TOX_ERR_GET_PORT error; ck_assert_msg(tox_self_get_udp_port(toxes[0], &error) == 33445, "First Tox instance did not bind to udp port 33445.\n"); ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); ck_assert_msg(tox_self_get_tcp_port(toxes[0], &error) == TCP_RELAY_PORT, "First Tox instance did not bind to tcp port %u.\n", TCP_RELAY_PORT); ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); } 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 = rand() % NUM_TOXES_TCP; pairs[i].tox2 = (pairs[i].tox1 + rand() % (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, 0) == 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(NULL) - cur_time); }
END_TEST START_TEST(test_save_friend) { Tox *tox1 = tox_new(0, 0); Tox *tox2 = tox_new(0, 0); ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances"); uint32_t to_compare = 974536; tox_callback_friend_request(tox2, accept_friend_request, &to_compare); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox1, address, (uint8_t *)"Gentoo", 7, 0); ck_assert_msg(test != UINT32_MAX, "Failed to add friend"); size_t size = tox_get_savedata_size(tox1); uint8_t data[size]; tox_get_savedata(tox1, data); size_t size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t enc_data[size2]; TOX_ERR_ENCRYPTION error1; bool ret = tox_pass_encrypt(data, size, "correcthorsebatterystaple", 25, enc_data, &error1); ck_assert_msg(ret, "failed to encrypted save: %u", error1); ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); struct Tox_Options options; tox_options_default(&options); options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; options.savedata_data = enc_data; options.savedata_length = size2; TOX_ERR_NEW err2; Tox *tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2, TOX_ERR_NEW_LOAD_ENCRYPTED); uint8_t dec_data[size]; TOX_ERR_DECRYPTION err3; ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3); ck_assert_msg(ret, "failed to decrypt save: %u", err3); options.savedata_data = dec_data; options.savedata_length = size; tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2); uint8_t address2[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox3, 0, address2, 0); ck_assert_msg(ret, "no friends!"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match!"); size = tox_get_savedata_size(tox3); uint8_t data2[size]; tox_get_savedata(tox3, data2); TOX_PASS_KEY key; memcpy(key.salt, salt, 32); memcpy(key.key, known_key2, crypto_box_BEFORENMBYTES); size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t encdata2[size2]; ret = tox_pass_key_encrypt(data2, size, &key, encdata2, &error1); ck_assert_msg(ret, "failed to key encrypt %u", error1); ck_assert_msg(tox_is_data_encrypted(encdata2), "magic number the second missing"); uint8_t out1[size], out2[size]; ret = tox_pass_decrypt(encdata2, size2, pw, pwlen, out1, &err3); ck_assert_msg(ret, "failed to pw decrypt %u", err3); ret = tox_pass_key_decrypt(encdata2, size2, &key, out2, &err3); ck_assert_msg(ret, "failed to key decrypt %u", err3); ck_assert_msg(memcmp(out1, out2, size) == 0, "differing output data"); // and now with the code in use (I only bothered with manually to debug this, and it seems a waste // to remove the manual check now that it's there) options.savedata_data = out1; options.savedata_length = size; Tox *tox4 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); uint8_t address5[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox4, 0, address5, 0); ck_assert_msg(ret, "no friends! the third"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third"); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); tox_kill(tox4); }
void Core::make_tox(QByteArray savedata) { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); bool forceTCP = Settings::getInstance().getForceTCP(); ProxyType proxyType = Settings::getInstance().getProxyType(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; tox_options_default(&toxOptions); toxOptions.ipv6_enabled = enableIPv6; toxOptions.udp_enabled = !forceTCP; toxOptions.start_port = toxOptions.end_port = 0; // No proxy by default toxOptions.proxy_type = TOX_PROXY_TYPE_NONE; toxOptions.proxy_host = nullptr; toxOptions.proxy_port = 0; if (proxyType != ProxyType::ptNone) { QString proxyAddr = Settings::getInstance().getProxyAddr(); int proxyPort = Settings::getInstance().getProxyPort(); if (proxyAddr.length() > 255) { qWarning() << "Core: proxy address" << proxyAddr << "is too long"; } else if (proxyAddr != "" && proxyPort > 0) { qDebug() << "Core: using proxy" << proxyAddr << ":" << proxyPort; // protection against changings in TOX_PROXY_TYPE enum if (proxyType == ProxyType::ptSOCKS5) toxOptions.proxy_type = TOX_PROXY_TYPE_SOCKS5; else if (proxyType == ProxyType::ptHTTP) toxOptions.proxy_type = TOX_PROXY_TYPE_HTTP; QByteArray proxyAddrData = proxyAddr.toUtf8(); /// TODO: We're leaking a tiny amount of memory there, go fix that later char* proxyAddrCopy = new char[proxyAddrData.size()+1]; memcpy(proxyAddrCopy, proxyAddrData.data(), proxyAddrData.size()+1); toxOptions.proxy_host = proxyAddrCopy; toxOptions.proxy_port = proxyPort; } } tox = tox_new(&toxOptions, (uint8_t*)savedata.data(), savedata.size(), nullptr); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6_enabled = false; tox = tox_new(&toxOptions, (uint8_t*)savedata.data(), savedata.size(), nullptr); if (tox == nullptr) { if (toxOptions.proxy_type != TOX_PROXY_TYPE_NONE) { qCritical() << "Core: bad proxy! no toxcore!"; emit badProxy(); } else { qCritical() << "Tox core failed to start"; emit failedToStart(); } return; } else { qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; } } else if (toxOptions.proxy_type != TOX_PROXY_TYPE_NONE) { emit badProxy(); return; } else { qCritical() << "Tox core failed to start"; emit failedToStart(); return; } } toxav = toxav_new(tox, TOXAV_MAX_CALLS); if (toxav == nullptr) { qCritical() << "Toxav core failed to start"; emit failedToStart(); return; } }