From c0187ae405a4da2350e0db841ac83930a5b4c662 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Mon, 16 Jan 2023 23:20:37 +0100 Subject: [PATCH] implement all the commandline parameters, add more, and plan for more --- src/command_line.cpp | 50 ++++++++++++++++++++++++++++++- src/command_line.hpp | 46 ++++++++++++++-------------- src/states/receive_start_sha1.cpp | 22 ++++++++++---- src/states/receive_start_sha1.hpp | 2 ++ src/tox_client.cpp | 35 ++++++++++++++++++++-- src/tox_client.hpp | 3 ++ 6 files changed, 124 insertions(+), 34 deletions(-) diff --git a/src/command_line.cpp b/src/command_line.cpp index 93b4ea0..bc6cacb 100644 --- a/src/command_line.cpp +++ b/src/command_line.cpp @@ -1,5 +1,6 @@ #include "./command_line.hpp" +#include #include #include @@ -76,6 +77,40 @@ CommandLine::CommandLine(int argc, char** argv) { PRINT_HELP_AND_BAIL; } receive_id = argv[++i]; + } else if (arg_sv == "-L") { + tox_disable_local_discovery = true; + } else if (arg_sv == "-U") { + tox_disable_udp = true; + } else if (arg_sv == "-P") { + if (i+2 >= argc) { + std::cerr << "ERROR: -P missing and/or parameter!\n\n"; + PRINT_HELP_AND_BAIL; + } + + std::string_view host_sv{argv[++i]}; + std::string_view port_sv{argv[++i]}; + + proxy_host = host_sv; + + auto res = std::from_chars(port_sv.data(), port_sv.data()+port_sv.size(), proxy_port); + if (res.ptr != port_sv.data()+port_sv.size()) { + std::cerr << "ERROR: invalid !\n\n"; + PRINT_HELP_AND_BAIL; + } + std::cout << "CL set proxy to " << proxy_host << proxy_port << "\n"; + } else if (arg_sv == "-p") { + if (i+1 >= argc) { + std::cerr << "ERROR: -p missing parameter!\n\n"; + PRINT_HELP_AND_BAIL; + } + + std::string_view port_sv{argv[++i]}; + auto res = std::from_chars(port_sv.data(), port_sv.data()+port_sv.size(), tox_port); + if (res.ptr != port_sv.data()+port_sv.size()) { + std::cerr << "ERROR: invalid !\n\n"; + PRINT_HELP_AND_BAIL; + } + std::cout << "CL set tox_port to " << tox_port << "\n"; } else { std::cerr << "ERROR: unknown parameter '" << arg_sv << "' !\n\n"; PRINT_HELP_AND_BAIL; @@ -102,7 +137,7 @@ void CommandLine::printHelp(void) { << " -N (defaults to 'tox_ngc_ft1_tool')\n" << " will print friend id at startup\n" << " will autoaccept any invite\n" - << " if no -F give, will not save profile.\n" + << " if no -F given, will not save profile.\n" << " if profile exists load, otherwise create new\n" << "\n" << " transfer variant:\n" @@ -114,6 +149,19 @@ void CommandLine::printHelp(void) { << " receive:\n" << " -d dump/everything/in/this/dir\n" << " -D (what to dl)\n" + << "\n" + << "!!! ADVANCED !!!\n" + << " tox:\n" + << " -L disable local discovery\n" + << " -U disable udp\n" + << " -P proxy_host proxy_port\n" + << " -p tox_port (bind tox to that port)\n" + << "\n" + << " FT1:\n" + << " TODO\n" + << "\n" + << " transfer logic:\n" + << " TODO\n" ; } diff --git a/src/command_line.hpp b/src/command_line.hpp index ebea48c..9eb531e 100644 --- a/src/command_line.hpp +++ b/src/command_line.hpp @@ -2,30 +2,6 @@ #include -// meta: -// -v version info -// -V verbose -// -h help -// -// connectivity: -// -G -// -F profile.tox -// -N -// will print friend id at startup -// will autoaccept any invite -// if no -F give, will not save profile. -// if profile exists load, otherwise create new -// -// transfer variant: -// -a id1/sha1_single/sha1_info/sha2_single/sha2_info -// -// send: -// -f send_this_file.zip -// -// receive: -// -d dump/everything/in/this/dir -// -D (what to dl) - enum class TransferE { INVALID, @@ -68,6 +44,28 @@ struct CommandLine { // -D (what to dl) std::string receive_id; + // advanced tox: + // -L disable local discovery + bool tox_disable_local_discovery {false}; + // -U disable udp (why?) + bool tox_disable_udp {false}; + // -P proxy_host proxy_port + std::string proxy_host; + uint16_t proxy_port {0}; + // -p port (start and end is set to the same port) + uint16_t tox_port {0}; + + // ---- TODO ---- + + // advanced FT1: + // -w packet_window_size + // TODO: all them timeouts + + // advaced dl: + // -I max_incoming_transfers (default 16) + // -O max_outgoing_transfers (default 4) + // -u request chunks only from UDP-direct peers + CommandLine(int argc, char** argv); void printHelp(void); diff --git a/src/states/receive_start_sha1.cpp b/src/states/receive_start_sha1.cpp index 63ad90e..04d5b62 100644 --- a/src/states/receive_start_sha1.cpp +++ b/src/states/receive_start_sha1.cpp @@ -20,7 +20,7 @@ namespace States { -ReceiveStartSHA1::ReceiveStartSHA1(ToxClient& tcl, const CommandLine& cl) : StateI(tcl) { +ReceiveStartSHA1::ReceiveStartSHA1(ToxClient& tcl, const CommandLine& cl) : StateI(tcl), _dump_dir(cl.receive_dump_dir) { if (cl.receive_id.empty()) { throw std::runtime_error("receiver missing id"); } @@ -72,33 +72,43 @@ std::unique_ptr ReceiveStartSHA1::nextState(void) { std::cout << "ReceiveStartSHA1 info is: \n" << sha1_info; - bool file_existed = std::filesystem::exists(sha1_info.file_name); + auto file_path = std::filesystem::path{_dump_dir} / sha1_info.file_name; + + bool file_existed = std::filesystem::exists(file_path); if (!file_existed) { - std::ofstream(sha1_info.file_name) << '\0'; // create the file + if (!_dump_dir.empty()) { + std::filesystem::create_directories(_dump_dir); + } + std::ofstream(file_path) << '\0'; // create the file } - std::filesystem::resize_file(sha1_info.file_name, sha1_info.file_size); + std::filesystem::resize_file(file_path, sha1_info.file_size); // open file for writing (pre allocate?) std::error_code err; - mio::mmap_sink file_map = mio::make_mmap_sink(sha1_info.file_name, 0, sha1_info.file_size, err); + mio::mmap_sink file_map = mio::make_mmap_sink(file_path.string(), 0, sha1_info.file_size, err); std::vector have_chunk(sha1_info.chunks.size(), false); // dont overwrite correct existing data if (file_existed) { std::cout << "ReceiveStartSHA1 checking existing file\n"; - size_t f_i = 0; + size_t f_i {0}; + size_t tmp_have_count {0}; for (size_t c_i = 0; f_i + FTInfoSHA1::chunk_size < file_map.length(); f_i += FTInfoSHA1::chunk_size, c_i++) { if (sha1_info.chunks[c_i] == hash_sha1(file_map.data()+f_i, FTInfoSHA1::chunk_size)) { have_chunk[c_i] = true; + tmp_have_count++; } } if (f_i < file_map.length()) { if (sha1_info.chunks.back() == hash_sha1(file_map.data()+f_i, file_map.length()-f_i)) { have_chunk.back() = true; + tmp_have_count++; } } + + std::cout << "ReceiveStartSHA1 have " << tmp_have_count << "/" << sha1_info.chunks.size() << "chunks (" << float(tmp_have_count)/sha1_info.chunks.size() << "%)\n"; } std::cout << "ReceiveStartSHA1 switching state to SHA1\n"; diff --git a/src/states/receive_start_sha1.hpp b/src/states/receive_start_sha1.hpp index 8264e69..812c348 100644 --- a/src/states/receive_start_sha1.hpp +++ b/src/states/receive_start_sha1.hpp @@ -33,6 +33,8 @@ struct ReceiveStartSHA1 final : public StateI { void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) override; private: + std::string _dump_dir; + //FTInfoSHA1 _sha1_info; std::vector _sha1_info_data; SHA1Digest _sha1_info_hash; // treat as const diff --git a/src/tox_client.cpp b/src/tox_client.cpp index ac3720c..0a88c59 100644 --- a/src/tox_client.cpp +++ b/src/tox_client.cpp @@ -6,6 +6,8 @@ #include "./states/send_start_sha1.hpp" #include "./states/receive_start_sha1.hpp" #include "ngc_ft1.h" +#include "tox/tox.h" +#include "toxcore/tox.h" #include #include @@ -26,9 +28,22 @@ ToxClient::ToxClient(const CommandLine& cl) : // use cl for options tox_options_set_log_callback(options, log_cb); - tox_options_set_local_discovery_enabled(options, false); - tox_options_set_udp_enabled(options, true); - tox_options_set_hole_punching_enabled(options, true); + tox_options_set_local_discovery_enabled(options, !cl.tox_disable_local_discovery); + tox_options_set_udp_enabled(options, !cl.tox_disable_udp); + tox_options_set_hole_punching_enabled(options, !cl.tox_disable_udp); + if (!cl.proxy_host.empty()) { + tox_options_set_proxy_host(options, cl.proxy_host.c_str()); + tox_options_set_proxy_port(options, cl.proxy_port); + tox_options_set_proxy_type(options, Tox_Proxy_Type::TOX_PROXY_TYPE_SOCKS5); + } else { + tox_options_set_proxy_type(options, Tox_Proxy_Type::TOX_PROXY_TYPE_NONE); + } + + if (cl.tox_port != 0) { + tox_options_set_start_port(options, cl.tox_port); + // TODO: extra end port? + tox_options_set_end_port(options, cl.tox_port); + } std::vector profile_data{}; if (!_tox_profile_path.empty()) { @@ -163,6 +178,12 @@ ToxClient::ToxClient(const CommandLine& cl) : } } + if (!cl.chat_id.empty()) { + // TODO: move conversion and size check to cl + _join_group_after_dht_connect = hex2bin(cl.chat_id); + assert(_join_group_after_dht_connect.size() == TOX_GROUP_CHAT_ID_SIZE); + } + _tox_profile_dirty = true; } @@ -210,6 +231,14 @@ void ToxClient::onToxSelfConnectionStatus(TOX_CONNECTION connection_status) { case TOX_CONNECTION::TOX_CONNECTION_TCP: std::cout << "TCP-relayed\n"; break; case TOX_CONNECTION::TOX_CONNECTION_UDP: std::cout << "UDP-direct\n"; break; } + + if (connection_status != TOX_CONNECTION::TOX_CONNECTION_NONE && !_join_group_after_dht_connect.empty()) { + // TODO: error checking + tox_group_join(_tox, _join_group_after_dht_connect.data(), nullptr, 0, nullptr, 0, nullptr); + std::cout << "TCL joining group " << bin2hex(_join_group_after_dht_connect) << "\n"; + _join_group_after_dht_connect.clear(); + } + _tox_profile_dirty = true; } diff --git a/src/tox_client.hpp b/src/tox_client.hpp index a3dd2a6..2d10845 100644 --- a/src/tox_client.hpp +++ b/src/tox_client.hpp @@ -13,6 +13,7 @@ #include #include #include +#include // fwd namespace States { @@ -77,6 +78,8 @@ struct ToxClient { std::string _tox_profile_path; bool _tox_profile_dirty {false}; // set in callbacks + std::vector _join_group_after_dht_connect; + std::unique_ptr _state; // key groupid, value set of peer ids