END_TEST START_TEST(test_save_friend) { Tox *tox1 = tox_new(0); Tox *tox2 = tox_new(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_FRIEND_ADDRESS_SIZE]; tox_get_address(tox2, address); int test = tox_add_friend(tox1, address, (uint8_t *)"Gentoo", 7); ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); uint32_t size = tox_encrypted_size(tox1); uint8_t data[size]; test = tox_encrypted_save(tox1, data, "correcthorsebatterystaple", 25); ck_assert_msg(test == 0, "failed to encrypted save"); ck_assert_msg(tox_is_data_encrypted(data) == 1, "magic number missing"); Tox *tox3 = tox_new(0); test = tox_encrypted_load(tox3, data, size, "correcthorsebatterystaple", 25); ck_assert_msg(test == 0, "failed to encrypted load"); uint8_t address2[TOX_CLIENT_ID_SIZE]; test = tox_get_client_id(tox3, 0, address2); ck_assert_msg(test == 0, "no friends!"); ck_assert_msg(memcmp(address, address2, TOX_CLIENT_ID_SIZE) == 0, "addresses don't match!"); }
static Tox *init_tox(int ipv4) { /* Init core */ int ipv6 = !ipv4; Tox *m = tox_new(ipv6); /* * TOX_ENABLE_IPV6_DEFAULT is always 1. * Checking it is redundant, this *should* be doing ipv4 fallback */ if (ipv6 && m == NULL) { fprintf(stderr, "IPv6 didn't initialize, trying IPv4\n"); m = tox_new(0); } if (ipv4) fprintf(stderr, "Forcing IPv4 connection\n"); if (m == NULL) return NULL; /* Callbacks */ tox_callback_connection_status(m, on_connectionchange, NULL); tox_callback_typing_change(m, on_typing_change, NULL); tox_callback_friend_request(m, on_request, NULL); tox_callback_friend_message(m, on_message, NULL); tox_callback_name_change(m, on_nickchange, NULL); tox_callback_user_status(m, on_statuschange, NULL); tox_callback_status_message(m, on_statusmessagechange, NULL); tox_callback_friend_action(m, on_action, NULL); tox_callback_group_invite(m, on_groupinvite, NULL); tox_callback_group_message(m, on_groupmessage, NULL); tox_callback_group_action(m, on_groupaction, NULL); tox_callback_group_namelist_change(m, on_group_namelistchange, NULL); tox_callback_file_send_request(m, on_file_sendrequest, NULL); tox_callback_file_control(m, on_file_control, NULL); tox_callback_file_data(m, on_file_data, NULL); #ifdef __linux__ tox_set_name(m, (uint8_t *) "Cool dude", strlen("Cool dude")); #elif defined(__FreeBSD__) tox_set_name(m, (uint8_t *) "Nerd", strlen("Nerd")); #elif defined(__APPLE__) tox_set_name(m, (uint8_t *) "Hipster", strlen("Hipster")); /* This used to users of other Unixes are hipsters */ #else tox_set_name(m, (uint8_t *) "Registered Minix user #4", strlen("Registered Minix user #4")); #endif return m; }
void Core::start() { const Settings &settings = Settings::getInstance(); Tox_Options options; options.ipv6enabled = settings.isIPv6Enabled(); options.proxy_type = TOX_PROXY_NONE; options.udp_disabled = 0; tox = tox_new(&options); // if failed to initialize -- try to fallback to ipv4 if (tox == nullptr && settings.isIPv6Enabled() && settings.isIPv4FallbackEnabled()) { options.ipv6enabled = 0; tox = tox_new(&options); } // if still didn't manage to initialize -- throw an error if (tox == nullptr) { emit failedToStart(); return; } loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); CString cUsername(settings.getUsername()); tox_set_name(tox, cUsername.data(), cUsername.size()); CString cStatusMessage(settings.getStatusMessage()); tox_set_status_message(tox, cStatusMessage.data(), cStatusMessage.size()); bootstrapDht(); timer->start(tox_do_interval(tox)); }
static Tox *init_tox() { /* Init core */ Tox *m = tox_new(TOX_ENABLE_IPV6_DEFAULT); if (m == NULL) return NULL; /* Callbacks */ tox_callback_connectionstatus(m, on_connectionchange, NULL); tox_callback_friendrequest(m, on_request, NULL); tox_callback_friendmessage(m, on_message, NULL); tox_callback_namechange(m, on_nickchange, NULL); tox_callback_userstatus(m, on_statuschange, NULL); tox_callback_statusmessage(m, on_statusmessagechange, NULL); tox_callback_action(m, on_action, NULL); #ifdef __linux__ tox_setname(m, (uint8_t *) "Cool guy", sizeof("Cool guy")); #elif defined(_WIN32) tox_setname(m, (uint8_t *) "I should install GNU/Linux", sizeof("I should install GNU/Linux")); #elif defined(__APPLE__) tox_setname(m, (uint8_t *) "Hipster", sizeof("Hipster")); //This used to users of other Unixes are hipsters #else tox_setname(m, (uint8_t *) "Registered Minix user #4", sizeof("Registered Minix user #4")); #endif return m; }
void Core::start() { tox = tox_new(); tox_callback_friendrequest(tox, onFriendRequest, this); tox_callback_friendmessage(tox, onFriendMessage, this); tox_callback_namechange(tox, onFriendNameChange, this); tox_callback_statusmessage(tox, onStatusMessageChanged, this); tox_callback_userstatus(tox, onUserStatusChanged, this); tox_callback_connectionstatus(tox, onConnectionStatusChanged, this); tox_callback_action(tox, onAction, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_getaddress(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); CString cUsername(Settings::getInstance().getUsername()); tox_setname(tox, cUsername.data(), cUsername.size()); bootstrapDht(); timer->setInterval(30); timer->start(); }
static Tox *load_tox(struct Tox_Options *options, char *path) { FILE *fp = fopen(path, "rb"); Tox *m = NULL; if (fp == NULL) { TOX_ERR_NEW err; m = tox_new(options, &err); if (err != TOX_ERR_NEW_OK) { fprintf(stderr, "tox_new failed with error %d\n", err); return NULL; } save_data(m, path); return m; } off_t data_len = file_size(path); if (data_len == 0) { fclose(fp); return NULL; } char data[data_len]; if (fread(data, sizeof(data), 1, fp) != 1) { fclose(fp); return NULL; } TOX_ERR_NEW err; options->savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; options->savedata_data = (uint8_t *) data; options->savedata_length = data_len; m = tox_new(options, &err); if (err != TOX_ERR_NEW_OK) { fprintf(stderr, "tox_new failed with error %d\n", err); return NULL; } fclose(fp); return m; }
static Tox *init_tox() { Tox *m = tox_new(1); if (m == NULL) { printf(stderr, "IPv6 didn't initialize, trying IPv4\n"); m = tox_new(0); } if (m == NULL) printf(stderr, "Forcing IPv4 connection\n"); tox_callback_friend_message(m, friend_message, NULL); tox_set_name(m, MY_NAME, strlen(MY_NAME)); // Sets the username return m; }
Core::Core() : QObject(nullptr) { qRegisterMetaType<Core::FriendStatus>("FriendStatus"); timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &Core::process); connect(&Settings::getInstance(), &Settings::dhtServerListChanged, this, &Core::bootstrapDht); handle = tox_new(); }
/* * 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 upgrade(const char *file, const char *output) { FILE *f = fopen(file, "r"); if (!f) { perror("mio/upgrade"); return -1; } fseek(f, 0, SEEK_END); size_t bufsize = ftell(f); fseek(f, 0, 0); uint8_t *buf = malloc(bufsize); fread(buf, bufsize, 1, f); fclose(f); Tox *temptox = tox_new(1); tox_load(temptox, buf, (uint32_t)bufsize); free(buf); puts("mio/upgrade: letting Tox run for a bit"); for (int n = 0; n < 20; ++n) { tox_do(temptox); printf("."); fflush(stdout); usleep(50000); } puts(" done"); txd_intermediate_t txd = txd_intermediate_from_tox(temptox); tox_kill(temptox); uint8_t *clear; uint64_t clearlen; int eerr = txd_export_to_buf(txd, &clear, &clearlen); if (eerr != TXD_ERR_SUCCESS) { printf("mio/upgrade: error: txd_export_to_buf failed with code %d\n", eerr); return -1; } txd_intermediate_free(txd); char *template = strdup(".si-XXXXXXXX");
void Tox_Dispatcher::init_tox() { Tox_Options *tox_options = nullptr; try { /* create options */ TOX_ERR_OPTIONS_NEW eon; tox_options = tox_options_new(&eon); if (eon != TOX_ERR_OPTIONS_NEW_OK) { std::string msg("Creating tox options failed with error code: "); msg += std::to_string(eon); throw std::runtime_error(msg); } load_save_data(*tox_options); /* create tox */ TOX_ERR_NEW en; tox = tox_new(tox_options, &en); if (en != TOX_ERR_NEW_OK) { std::string msg("Creating tox failed with error code: "); msg += std::to_string(en); throw std::runtime_error(msg); } /* create user if necessary */ if (tox_options->savedata_type == TOX_SAVEDATA_TYPE_NONE) { LOG(INFO) << "Creating new user"; save_save_data(); } tox_options_free(tox_options); } catch (const std::exception& e) { if (tox_options != nullptr) { tox_options_free(tox_options); } throw e; } }
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; }
void Core::start() { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; toxOptions.ipv6enabled = enableIPv6; toxOptions.udp_disabled = 0; toxOptions.proxy_enabled = false; toxOptions.proxy_address[0] = 0; toxOptions.proxy_port = 0; tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6enabled = false; tox = tox_new(&toxOptions); if (tox == nullptr) { 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 { 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; } qsrand(time(nullptr)); loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_file_send_request(tox, onFileSendRequestCallback, this); tox_callback_file_control(tox, onFileControlCallback, this); tox_callback_file_data(tox, onFileDataCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_recv_callback(toxav, playCallAudio, this); toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); bootstrapDht(); toxTimer->start(tox_do_interval(tox)); }
/* Returns a new Tox object on success. * If object fails to initialize the toxic process will terminate. */ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW *new_err) { Tox *m = NULL; FILE *fp = fopen(data_path, "rb"); if (fp != NULL) { /* Data file exists */ off_t len = file_size(data_path); if (len == 0) { fclose(fp); exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } char data[len]; if (fread(data, sizeof(data), 1, fp) != 1) { fclose(fp); exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } bool is_encrypted = tox_is_data_encrypted((uint8_t *) data); /* attempt to encrypt an already encrypted data file */ if (arg_opts.encrypt_data && is_encrypted) { fclose(fp); exit_toxic_err("failed in load_tox", FATALERR_ENCRYPT); } if (arg_opts.unencrypt_data && is_encrypted) queue_init_message("Data file '%s' has been unencrypted", data_path); else if (arg_opts.unencrypt_data) queue_init_message("Warning: passed --unencrypt-data option with unencrypted data file '%s'", data_path); if (is_encrypted) { if (!arg_opts.unencrypt_data) user_password.data_is_encrypted = true; size_t pwlen = 0; int pweval = user_settings->password_eval[0]; if (!pweval) { system("clear"); // TODO: is this portable? printf("Enter password (q to quit) "); } size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; char plain[plain_len]; while (true) { if (pweval) { pwlen = password_eval(user_password.pass, sizeof(user_password.pass)); } else { pwlen = password_prompt(user_password.pass, sizeof(user_password.pass)); } user_password.len = pwlen; if (strcasecmp(user_password.pass, "q") == 0) { fclose(fp); exit(0); } if (pwlen < MIN_PASSWORD_LEN) { system("clear"); sleep(1); printf("Invalid password. Try again. "); pweval = 0; continue; } TOX_ERR_DECRYPTION pwerr; tox_pass_decrypt((uint8_t *) data, len, (uint8_t *) user_password.pass, pwlen, (uint8_t *) plain, &pwerr); if (pwerr == TOX_ERR_DECRYPTION_OK) { tox_opts->savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; tox_opts->savedata_data = (uint8_t *) plain; tox_opts->savedata_length = plain_len; m = tox_new(tox_opts, new_err); if (m == NULL) { fclose(fp); return NULL; } break; } else if (pwerr == TOX_ERR_DECRYPTION_FAILED) { system("clear"); sleep(1); printf("Invalid password. Try again. "); pweval = 0; } else { fclose(fp); exit_toxic_err("tox_pass_decrypt() failed", pwerr); } } } else { /* data is not encrypted */ tox_opts->savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; tox_opts->savedata_data = (uint8_t *) data; tox_opts->savedata_length = len; m = tox_new(tox_opts, new_err); if (m == NULL) { fclose(fp); return NULL; } } fclose(fp); } else { /* Data file does not/should not exist */ if (file_exists(data_path)) exit_toxic_err("failed in load_tox", FATALERR_FILEOP); tox_opts->savedata_type = TOX_SAVEDATA_TYPE_NONE; m = tox_new(tox_opts, new_err); if (m == NULL) return NULL; if (store_data(m, data_path) == -1) exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } return m; }
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); }
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; }
static Tox *init_tox(void) { Tox_Options tox_opts; tox_opts.ipv6enabled = !arg_opts.use_ipv4; tox_opts.udp_disabled = arg_opts.force_tcp; tox_opts.proxy_enabled = arg_opts.use_proxy; if (tox_opts.proxy_enabled) { tox_opts.proxy_port = arg_opts.proxy_port; snprintf(tox_opts.proxy_address, sizeof(tox_opts.proxy_address), "%s", arg_opts.proxy_address); } /* Init core */ Tox *m = tox_new(&tox_opts); if (tox_opts.ipv6enabled && m == NULL) { fprintf(stderr, "IPv6 failed to initialize. Trying IPv4\n"); tox_opts.ipv6enabled = 0; m = tox_new(&tox_opts); } if (!tox_opts.ipv6enabled) fprintf(stderr, "Forcing IPv4 connection\n"); if (tox_opts.udp_disabled) fprintf(stderr, "UDP disabled\n"); if (tox_opts.proxy_enabled && m == NULL) exit_toxic_err("Proxy error", FATALERR_PROXY); if (m == NULL) return NULL; /* Callbacks */ tox_callback_connection_status(m, on_connectionchange, NULL); tox_callback_typing_change(m, on_typing_change, NULL); tox_callback_friend_request(m, on_request, NULL); tox_callback_friend_message(m, on_message, NULL); tox_callback_name_change(m, on_nickchange, NULL); tox_callback_user_status(m, on_statuschange, NULL); tox_callback_status_message(m, on_statusmessagechange, NULL); tox_callback_friend_action(m, on_action, NULL); tox_callback_group_invite(m, on_groupinvite, NULL); tox_callback_group_message(m, on_groupmessage, NULL); tox_callback_group_action(m, on_groupaction, NULL); tox_callback_group_namelist_change(m, on_group_namelistchange, NULL); tox_callback_file_send_request(m, on_file_sendrequest, NULL); tox_callback_file_control(m, on_file_control, NULL); tox_callback_file_data(m, on_file_data, NULL); #ifdef __linux__ tox_set_name(m, (uint8_t *) "Cool dude", strlen("Cool dude")); #elif defined(__FreeBSD__) tox_set_name(m, (uint8_t *) "Nerd", strlen("Nerd")); #elif defined(__APPLE__) tox_set_name(m, (uint8_t *) "Hipster", strlen("Hipster")); /* This used to users of other Unixes are hipsters */ #else tox_set_name(m, (uint8_t *) "Registered Minix user #4", strlen("Registered Minix user #4")); #endif return m; }
END_TEST #define NUM_TOXES 66 #define NUM_FRIENDS 20 START_TEST(test_many_clients) { long long unsigned int cur_time = time(NULL); Tox *toxes[NUM_TOXES]; uint32_t i, j; uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES; ++i) { toxes[i] = tox_new(0); ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); } struct { uint16_t tox1; uint16_t tox2; } pairs[NUM_FRIENDS]; uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: pairs[i].tox1 = rand() % NUM_TOXES; pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) goto loop_top; } tox_get_address(toxes[pairs[i].tox1], address); int test = tox_add_friend(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7); if (test == TOX_FAERR_ALREADYSENT) { goto loop_top; } ck_assert_msg(test >= 0, "Failed to add friend error code: %i", test); } while (1) { uint16_t counter = 0; for (i = 0; i < NUM_TOXES; ++i) { for (j = 0; j < tox_count_friendlist(toxes[i]); ++j) if (tox_get_friend_connection_status(toxes[i], j) == 1) ++counter; } if (counter == NUM_FRIENDS * 2) { break; } for (i = 0; i < NUM_TOXES; ++i) { tox_do(toxes[i]); } c_sleep(50); } printf("test_many_clients succeeded, took %llu seconds\n", time(NULL) - cur_time); for (i = 0; i < NUM_TOXES; ++i) { tox_kill(toxes[i]); } }
int main(int argc, char *argv[]) { /* minimalistic locale support (i.e. when printing dates) */ setlocale(LC_ALL, ""); if (argc < 4) { if ((argc == 2) && !strcmp(argv[1], "-h")) { print_help(argv[0]); exit(0); } printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile] (or %s -h for help)\n", argv[0], argv[0]); exit(0); } /* let user override default by cmdline */ uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); if (argvoffset < 0) exit(1); int on = 0; char *filename = "data"; char idstring[200] = {0}; Tox *m; /* [-f keyfile] MUST be last two arguments, no point in walking over the list * especially not a good idea to accept it anywhere in the middle */ if (argc > argvoffset + 3) if (!strcmp(argv[argc - 2], "-f")) filename = argv[argc - 1]; m = tox_new(ipv6enabled); if ( !m ) { fputs("Failed to allocate Messenger datastructure", stderr); exit(0); } load_data_or_init(m, filename); tox_callback_friend_request(m, print_request, NULL); tox_callback_friend_message(m, print_message, NULL); tox_callback_name_change(m, print_nickchange, NULL); tox_callback_status_message(m, print_statuschange, NULL); tox_callback_group_invite(m, print_invite, NULL); tox_callback_group_message(m, print_groupmessage, NULL); tox_callback_file_data(m, write_file, NULL); tox_callback_file_control(m, file_print_control, NULL); tox_callback_file_send_request(m, file_request_accept, NULL); tox_callback_group_namelist_change(m, print_groupnamelistchange, NULL); initscr(); noecho(); raw(); getmaxyx(stdscr, y, x); new_lines("/h for list of commands"); get_id(m, idstring); new_lines(idstring); strcpy(input_line, ""); uint16_t port = htons(atoi(argv[argvoffset + 2])); unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); int res = tox_bootstrap_from_address(m, argv[argvoffset + 1], ipv6enabled, port, binary_string); free(binary_string); if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); endwin(); exit(1); } nodelay(stdscr, TRUE); new_lines("[i] change username with /n"); uint8_t name[TOX_MAX_NAME_LENGTH + 1]; uint16_t namelen = tox_get_self_name(m, name); name[namelen] = 0; if (namelen > 0) { char whoami[128 + TOX_MAX_NAME_LENGTH]; snprintf(whoami, sizeof(whoami), "[i] your current username is: %s", name); new_lines(whoami); } time_t timestamp0 = time(NULL); while (1) { if (on == 0) { if (tox_isconnected(m)) { new_lines("[i] connected to DHT"); on = 1; } else { time_t timestamp1 = time(NULL); if (timestamp0 + 10 < timestamp1) { timestamp0 = timestamp1; tox_bootstrap_from_address(m, argv[argvoffset + 1], ipv6enabled, port, binary_string); } } } send_filesenders(m); tox_do(m); do_refresh(); int c = timeout_getch(m); if (c == ERR || c == 27) continue; getmaxyx(stdscr, y, x); if ((c == 0x0d) || (c == 0x0a)) { line_eval(m, input_line); strcpy(input_line, ""); } else if (c == 8 || c == 127) { input_line[strlen(input_line) - 1] = '\0'; } else if (isalnum(c) || ispunct(c) || c == ' ') { strcpy(input_line, appender(input_line, (char) c)); } } tox_kill(m); endwin(); return 0; }
int main(int argc, char *argv[]) { Tox *tox1 = tox_new_log(0, 0, 0); Tox *tox2 = tox_new_log(0, 0, 0); struct test_data to_compare = { { 0 } }; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, NULL); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, NULL); uint8_t reference_name[TOX_MAX_NAME_LENGTH] = { 0 }; uint8_t reference_status[TOX_MAX_STATUS_MESSAGE_LENGTH] = { 0 }; set_random(tox1, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox2, tox_self_set_name, TOX_MAX_NAME_LENGTH); set_random(tox1, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); set_random(tox2, tox_self_set_status_message, TOX_MAX_STATUS_MESSAGE_LENGTH); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, 0) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, NULL); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); VLA(uint8_t, savedata, save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *options = tox_options_new(NULL); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *tox_to_compare = tox_new(options, 0); tox_friend_get_name(tox_to_compare, 0, to_compare.name, 0); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, 0); assert(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0); assert(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); return 0; }
void Core::start() { // 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(); bool useProxy = Settings::getInstance().getUseProxy(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; toxOptions.ipv6enabled = enableIPv6; toxOptions.udp_disabled = forceTCP; // No proxy by default toxOptions.proxy_enabled = false; toxOptions.proxy_address[0] = 0; toxOptions.proxy_port = 0; if (useProxy) { 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; toxOptions.proxy_enabled = true; uint16_t sz = CString::fromString(proxyAddr, (unsigned char*)toxOptions.proxy_address); toxOptions.proxy_address[sz] = 0; toxOptions.proxy_port = proxyPort; } } tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6enabled = false; tox = tox_new(&toxOptions); if (tox == nullptr) { if (toxOptions.proxy_enabled) { //QMessageBox::critical(Widget::getInstance(), tr("Proxy failure", "popup title"), //tr("toxcore failed to start with your proxy settings. qTox cannot run; please modify your " //"settings and restart.", "popup text")); 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_enabled) { 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; } qsrand(time(nullptr)); if (!loadConfiguration()) { emit failedToStart(); tox_kill(tox); tox = nullptr; return; } tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_file_send_request(tox, onFileSendRequestCallback, this); tox_callback_file_control(tox, onFileControlCallback, this); tox_callback_file_data(tox, onFileDataCallback, this); tox_callback_avatar_info(tox, onAvatarInfoCallback, this); tox_callback_avatar_data(tox, onAvatarDataCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_recv_callback(toxav, playCallAudio, this); toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); QPixmap pic = Settings::getInstance().getSavedAvatar(getSelfId().toString()); if (!pic.isNull() && !pic.size().isEmpty()) { QByteArray data; QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); pic.save(&buffer, "PNG"); buffer.close(); setAvatar(TOX_AVATAR_FORMAT_PNG, data); } else qDebug() << "Core: Error loading self avatar"; process(); // starts its own timer }
int main(int argc, char *argv[]) { uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); if (argvoffset < 0) exit(1); /* with optional --ipvx, now it can be 1-4 arguments... */ if ((argc != argvoffset + 3) && (argc != argvoffset + 5)) { printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node) folder (to sync)\n", argv[0]); exit(0); } Tox *tox = tox_new(ipv6enabled); tox_callback_file_data(tox, write_file, NULL); tox_callback_file_control(tox, file_print_control, NULL); tox_callback_file_send_request(tox, file_request_accept, NULL); tox_callback_connection_status(tox, print_online, NULL); uint16_t port = htons(atoi(argv[argvoffset + 2])); unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); int res = tox_bootstrap_from_address(tox, argv[argvoffset + 1], ipv6enabled, port, binary_string); free(binary_string); if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); exit(1); } uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, address); uint32_t i; for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) { printf("%02X", address[i]); } char temp_id[128]; printf("\nEnter the address of the other id you want to sync with (38 bytes HEX format):\n"); if (scanf("%s", temp_id) != 1) { return 1; } uint8_t *bin_id = hex_string_to_bin(temp_id); int num = tox_add_friend(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); free(bin_id); if (num < 0) { printf("\nSomething went wrong when adding friend.\n"); return 1; } memcpy(path, argv[argvoffset + 4], strlen(argv[argvoffset + 4])); DIR *d; struct dirent *dir; uint8_t notconnected = 1; while (1) { if (tox_isconnected(tox) && notconnected) { printf("\nDHT connected.\n"); notconnected = 0; } if (not_sending() && tox_get_friend_connection_status(tox, num)) { d = opendir(path); if (d) { while ((dir = readdir(d)) != NULL) { if (dir->d_type == DT_REG) { char fullpath[1024]; if (path[strlen(path) - 1] == '/') sprintf(fullpath, "%s%s", path, dir->d_name); else sprintf(fullpath, "%s/%s", path, dir->d_name); add_filesender(tox, num, fullpath); } } closedir(d); } else { printf("\nFailed to open directory.\n"); return 1; } } send_filesenders(tox); tox_do(tox); c_sleep(1); } return 0; }
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; } }
av_session_t *av_init_session() { av_session_t *_retu = malloc(sizeof(av_session_t)); /* Initialize our mutex */ pthread_mutex_init ( &_retu->_mutex, NULL ); _retu->_messenger = tox_new(1); if ( !_retu->_messenger ) { fprintf ( stderr, "tox_new() failed!\n" ); return NULL; } _retu->_friends = NULL; const ALchar *_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); int i = 0; const ALchar *device_names[20]; if ( _device_list ) { INFO("\nAvailable Capture Devices are:"); while (*_device_list ) { device_names[i] = _device_list; INFO("%d) %s", i, device_names[i]); _device_list += strlen( _device_list ) + 1; ++i; } } INFO("Enter capture device number"); char dev[2]; char *left; char *warned_ = fgets(dev, 2, stdin); (void)warned_; long selection = strtol(dev, &left, 10); if ( *left ) { printf("'%s' is not a number!", dev); fflush(stdout); exit(EXIT_FAILURE); } else { INFO("Selected: %d ( %s )", selection, device_names[selection]); } _retu->audio_capture_device = (struct ALCdevice *)alcCaptureOpenDevice( device_names[selection], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, AUDIO_FRAME_SIZE * 4); if (alcGetError((ALCdevice *)_retu->audio_capture_device) != AL_NO_ERROR) { printf("Could not start capture device! %d\n", alcGetError((ALCdevice *)_retu->audio_capture_device)); return 0; } uint16_t height = 0, width = 0; #ifdef TOX_FFMPEG avdevice_register_all(); avcodec_register_all(); av_register_all(); _retu->video_input_format = av_find_input_format(VIDEO_DRIVER); if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) { fprintf(stderr, "Opening video_input_format failed!\n"); //return -1; goto failed_init_ffmpeg; } avformat_find_stream_info(_retu->video_format_ctx, NULL); av_dump_format(_retu->video_format_ctx, 0, DEFAULT_WEBCAM, 0); for (i = 0; i < _retu->video_format_ctx->nb_streams; ++i) { if (_retu->video_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { _retu->video_stream = i; break; } } _retu->webcam_decoder_ctx = _retu->video_format_ctx->streams[_retu->video_stream]->codec; _retu->webcam_decoder = avcodec_find_decoder(_retu->webcam_decoder_ctx->codec_id); if (_retu->webcam_decoder == NULL) { fprintf(stderr, "Unsupported codec!\n"); //return -1; goto failed_init_ffmpeg; } if (_retu->webcam_decoder_ctx == NULL) { fprintf(stderr, "Init webcam_decoder_ctx failed!\n"); //return -1; goto failed_init_ffmpeg; } if (avcodec_open2(_retu->webcam_decoder_ctx, _retu->webcam_decoder, NULL) < 0) { fprintf(stderr, "Opening webcam decoder failed!\n"); //return -1; goto failed_init_ffmpeg; } width = _retu->webcam_decoder_ctx->width; height = _retu->webcam_decoder_ctx->height; failed_init_ffmpeg: ; #endif uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(_retu->_messenger, _byte_address ); fraddr_to_str( _byte_address, _retu->_my_public_id ); _retu->av = toxav_new(_retu->_messenger, width, height); /* ------------------ */ toxav_register_callstate_callback(callback_call_started, av_OnStart, _retu->av); toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, _retu->av); toxav_register_callstate_callback(callback_call_rejected, av_OnReject, _retu->av); toxav_register_callstate_callback(callback_call_ended, av_OnEnd, _retu->av); toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, _retu->av); toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, _retu->av); toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, _retu->av); toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, _retu->av); toxav_register_callstate_callback(callback_recv_error, av_OnError, _retu->av); toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, _retu->av); /* ------------------ */ return _retu; }
void tox_thread(void *UNUSED(args)) { Tox *tox; ToxAv *av; uint8_t id[TOX_FRIEND_ADDRESS_SIZE]; TOP:; debug("new tox object ipv6: %u no_udp: %u proxy: %u %s %u\n", options.ipv6enabled, options.udp_disabled, options.proxy_enabled, options.proxy_address, options.proxy_port); if((tox = tox_new(&options)) == NULL) { debug("trying without proxy\n"); if(!options.proxy_enabled || (options.proxy_enabled = 0, (tox = tox_new(&options)) == NULL)) { debug("trying without ipv6\n"); if(!options.ipv6enabled || (options.ipv6enabled = 0, (tox = tox_new(&options)) == NULL)) { debug("tox_new() failed\n"); exit(1); } dropdown_ipv6.selected = dropdown_ipv6.over = 1; } dropdown_proxy.selected = dropdown_proxy.over = 0; } if(!load_save(tox)) { debug("No save file, using defaults\n"); load_defaults(tox); } edit_setstr(&edit_name, self.name, self.name_length); edit_setstr(&edit_status, self.statusmsg, self.statusmsg_length); tox_get_address(tox, id); id_to_string(self.id, id); debug("Tox ID: %.*s\n", (int)sizeof(self.id), self.id); set_callbacks(tox); do_bootstrap(tox); av = toxav_new(tox, MAX_CALLS); set_av_callbacks(av); global_av = av; tox_thread_init = 1; thread(audio_thread, av); thread(video_thread, av); thread(toxav_thread, av); _Bool connected = 0, reconfig; uint64_t last_save = get_time(), time; while(1) { tox_do(tox); if(tox_isconnected(tox) != connected) { connected = !connected; postmessage(DHT_CONNECTED, connected, 0, NULL); debug("Connected to DHT: %u\n", connected); } time = get_time(); if(time - last_save >= (uint64_t)10 * 1000 * 1000 * 1000) { last_save = time; if(!connected) { do_bootstrap(tox); } write_save(tox); } if(tox_thread_msg) { TOX_MSG *msg = &tox_msg; if(!msg->msg) { reconfig = msg->param1; tox_thread_msg = 0; break; } tox_thread_message(tox, av, time, msg->msg, msg->param1, msg->param2, msg->data); tox_thread_msg = 0; } utox_thread_work_for_transfers(tox, time); utox_thread_work_for_typing_notifications(tox, time); uint32_t interval = tox_do_interval(tox); yieldcpu((interval > 20) ? 20 : interval); } write_save(tox); while(audio_thread_init || video_thread_init || toxav_thread_init) { yieldcpu(1); } debug("av_thread exit, tox thread ending\n"); toxav_kill(av); tox_kill(tox); if(reconfig) { goto TOP; } tox_thread_init = 0; }
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; } }
int main(int argc, char *argv[]) { int on = 0; int c = 0; int i = 0; char *filename = "data"; char idstring[200] = {0}; Tox *m; if (argc < 4) { printf("[!] Usage: %s [IP] [port] [public_key] <keyfile>\n", argv[0]); exit(0); } for (i = 0; i < argc; i++) { if (argv[i] == NULL) { break; } else if (argv[i][0] == '-') { if (argv[i][1] == 'h') { print_help(); exit(0); } else if (argv[i][1] == 'f') { if (argv[i + 1] != NULL) filename = argv[i + 1]; else { fputs("[!] you passed '-f' without giving an argument!\n", stderr); } } } } m = tox_new(); if ( !m ) { fputs("Failed to allocate Messenger datastructure", stderr); exit(0); } load_key(m, filename); tox_callback_friendrequest(m, print_request, NULL); tox_callback_friendmessage(m, print_message, NULL); tox_callback_namechange(m, print_nickchange, NULL); tox_callback_statusmessage(m, print_statuschange, NULL); initscr(); noecho(); raw(); getmaxyx(stdscr, y, x); new_lines("/h for list of commands"); get_id(m, idstring); new_lines(idstring); strcpy(line, ""); tox_IP_Port bootstrap_ip_port; bootstrap_ip_port.port = htons(atoi(argv[2])); int resolved_address = resolve_addr(argv[1]); if (resolved_address != 0) bootstrap_ip_port.ip.i = resolved_address; else exit(1); unsigned char *binary_string = hex_string_to_bin(argv[3]); tox_bootstrap(m, bootstrap_ip_port, binary_string); free(binary_string); nodelay(stdscr, TRUE); while (true) { if (on == 0 && tox_isconnected(m)) { new_lines("[i] connected to DHT\n[i] define username with /n"); on = 1; } tox_do(m); c_sleep(1); do_refresh(); c = getch(); if (c == ERR || c == 27) continue; getmaxyx(stdscr, y, x); if (c == '\n') { line_eval(m, line); strcpy(line, ""); } else if (c == 8 || c == 127) { line[strlen(line) - 1] = '\0'; } else if (isalnum(c) || ispunct(c) || c == ' ') { strcpy(line, appender(line, (char) c)); } } tox_kill(m); endwin(); return 0; }
/** * @brief Creates Tox instance from previously saved data * @param savedata Previously saved Tox data - null, if new profile was created */ void Core::makeTox(QByteArray savedata) { Tox_Options toxOptions = initToxOptions(savedata); 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: qCritical() << "failed to parse Tox save data"; emit failedToStart(); return; case TOX_ERR_NEW_PORT_ALLOC: if (Settings::getInstance().getEnableIPv6()) { 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; } }
static int r2tox_connect() { if (tox) { printf ("Status: Online\n"); print_tox_my_address (tox); return -1; } Tox *t = NULL; struct Tox_Options *options = tox_options_new(NULL); FILE *fd = fopen("tox.data", "rb"); if (fd) { eprintf ("Using tox.data\n"); size_t sz = fread (&data, 1, 4096, fd); fclose (fd); tox_options_set_savedata_length (options, sz); tox_options_set_savedata_type (options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data (options, data, sz); t = tox_new (options, NULL); if (!t) { printf("cannot new\n"); return 1; } } else { t = tox_new (NULL, NULL); if (!t) { eprintf ("cannot new\n"); return 1; } // r2tox_save(); } const char *username = "******"; const char *status = "Available"; tox_self_set_name (t, username, strlen(username), NULL); tox_self_set_status_message (t, status, strlen(status), NULL); tox_callback_friend_name(t, handle_friend_name); tox_callback_friend_request (t, handle_friend_request); tox_callback_friend_message (t, handle_friend_message); tox_callback_friend_lossy_packet (t, handle_friend_lossy_packet); tox_callback_friend_lossless_packet (t, handle_friend_lossless_packet); tox_callback_friend_read_receipt (t, handle_friend_read_receipt); tox_callback_conference_invite(t, handle_conference_invite); tox_callback_conference_message(t, handle_conference_message); tox_callback_conference_title(t, handle_conference_title); // bootstrap size_t i; for (i = 0; i < sizeof(nodes)/sizeof(DHT_node); i ++) { sodium_hex2bin(nodes[i].key_bin, sizeof(nodes[i].key_bin), nodes[i].key_hex, sizeof(nodes[i].key_hex)-1, NULL, NULL, NULL); tox_bootstrap(t, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL); } print_tox_my_address (t); tox_callback_self_connection_status (t, self_connection_status_cb); tox = t; // thread here if (!thread) { thread = r_th_new (r2tox_mainloop, NULL, 1); r_th_start (thread, true); } return 0; }
int main(int argc, char *argv[]) { uint8_t ipv6enabled = 1; /* x */ int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); if (argvoffset < 0) { exit(1); } /* with optional --ipvx, now it can be 1-4 arguments... */ if ((argc != argvoffset + 2) && (argc != argvoffset + 4)) { printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node)\n", argv[0]); exit(0); } int *master = (int *)malloc(sizeof(int)); int ret = forkpty(master, NULL, NULL, NULL); if (ret == -1) { printf("fork failed\n"); free(master); return 1; } if (ret == 0) { execl("/bin/sh", "sh", NULL); return 0; } int flags = fcntl(*master, F_GETFL, 0); int r = fcntl(*master, F_SETFL, flags | O_NONBLOCK); if (r < 0) { printf("error setting flags\n"); } Tox *tox = tox_new(0, 0); tox_callback_friend_connection_status(tox, print_online); tox_callback_friend_message(tox, print_message); uint16_t port = atoi(argv[argvoffset + 2]); unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); int res = tox_bootstrap(tox, argv[argvoffset + 1], port, binary_string, 0); free(binary_string); if (!res) { printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]); exit(1); } uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox, address); uint32_t i; for (i = 0; i < TOX_ADDRESS_SIZE; i++) { printf("%02X", address[i]); } char temp_id[128]; printf("\nEnter the address of the other id you want to sync with (38 bytes HEX format):\n"); if (scanf("%s", temp_id) != 1) { return 1; } uint8_t *bin_id = hex_string_to_bin(temp_id); uint32_t num = tox_friend_add(tox, bin_id, (const uint8_t *)"Install Gentoo", sizeof("Install Gentoo"), 0); free(bin_id); if (num == UINT32_MAX) { printf("\nSomething went wrong when adding friend.\n"); return 1; } uint8_t notconnected = 1; while (1) { if (tox_self_get_connection_status(tox) && notconnected) { printf("\nDHT connected.\n"); notconnected = 0; } while (tox_friend_get_connection_status(tox, num, 0)) { uint8_t buf[TOX_MAX_MESSAGE_LENGTH]; ret = read(*master, buf, sizeof(buf)); if (ret <= 0) { break; } tox_friend_send_message(tox, num, TOX_MESSAGE_TYPE_NORMAL, buf, ret, 0); } tox_iterate(tox, master); c_sleep(1); } }