implement all the commandline parameters, add more, and plan for more

This commit is contained in:
Green Sky 2023-01-16 23:20:37 +01:00
parent 999ef20437
commit c0187ae405
No known key found for this signature in database
6 changed files with 124 additions and 34 deletions

View File

@ -1,5 +1,6 @@
#include "./command_line.hpp" #include "./command_line.hpp"
#include <charconv>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
@ -76,6 +77,40 @@ CommandLine::CommandLine(int argc, char** argv) {
PRINT_HELP_AND_BAIL; PRINT_HELP_AND_BAIL;
} }
receive_id = argv[++i]; 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 <host> and/or <port> 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 <port>!\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 <port> 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 <port>!\n\n";
PRINT_HELP_AND_BAIL;
}
std::cout << "CL set tox_port to " << tox_port << "\n";
} else { } else {
std::cerr << "ERROR: unknown parameter '" << arg_sv << "' !\n\n"; std::cerr << "ERROR: unknown parameter '" << arg_sv << "' !\n\n";
PRINT_HELP_AND_BAIL; PRINT_HELP_AND_BAIL;
@ -102,7 +137,7 @@ void CommandLine::printHelp(void) {
<< " -N <self_name> (defaults to 'tox_ngc_ft1_tool')\n" << " -N <self_name> (defaults to 'tox_ngc_ft1_tool')\n"
<< " will print friend id at startup\n" << " will print friend id at startup\n"
<< " will autoaccept any invite\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" << " if profile exists load, otherwise create new\n"
<< "\n" << "\n"
<< " transfer variant:\n" << " transfer variant:\n"
@ -114,6 +149,19 @@ void CommandLine::printHelp(void) {
<< " receive:\n" << " receive:\n"
<< " -d dump/everything/in/this/dir\n" << " -d dump/everything/in/this/dir\n"
<< " -D <id/hash> (what to dl)\n" << " -D <id/hash> (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"
; ;
} }

View File

@ -2,30 +2,6 @@
#include <string> #include <string>
// meta:
// -v version info
// -V verbose
// -h help
//
// connectivity:
// -G <chat_id>
// -F profile.tox
// -N <self_name>
// 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 <id/hash> (what to dl)
enum class TransferE { enum class TransferE {
INVALID, INVALID,
@ -68,6 +44,28 @@ struct CommandLine {
// -D <id/hash> (what to dl) // -D <id/hash> (what to dl)
std::string receive_id; 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); CommandLine(int argc, char** argv);
void printHelp(void); void printHelp(void);

View File

@ -20,7 +20,7 @@
namespace States { 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()) { if (cl.receive_id.empty()) {
throw std::runtime_error("receiver missing id"); throw std::runtime_error("receiver missing id");
} }
@ -72,33 +72,43 @@ std::unique_ptr<StateI> ReceiveStartSHA1::nextState(void) {
std::cout << "ReceiveStartSHA1 info is: \n" << sha1_info; 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) { if (!file_existed) {
std::ofstream(sha1_info.file_name) << '\0'; // create the file if (!_dump_dir.empty()) {
std::filesystem::create_directories(_dump_dir);
} }
std::filesystem::resize_file(sha1_info.file_name, sha1_info.file_size); std::ofstream(file_path) << '\0'; // create the file
}
std::filesystem::resize_file(file_path, sha1_info.file_size);
// open file for writing (pre allocate?) // open file for writing (pre allocate?)
std::error_code err; 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<bool> have_chunk(sha1_info.chunks.size(), false); std::vector<bool> have_chunk(sha1_info.chunks.size(), false);
// dont overwrite correct existing data // dont overwrite correct existing data
if (file_existed) { if (file_existed) {
std::cout << "ReceiveStartSHA1 checking existing file\n"; 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++) { 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)) { if (sha1_info.chunks[c_i] == hash_sha1(file_map.data()+f_i, FTInfoSHA1::chunk_size)) {
have_chunk[c_i] = true; have_chunk[c_i] = true;
tmp_have_count++;
} }
} }
if (f_i < file_map.length()) { if (f_i < file_map.length()) {
if (sha1_info.chunks.back() == hash_sha1(file_map.data()+f_i, file_map.length()-f_i)) { if (sha1_info.chunks.back() == hash_sha1(file_map.data()+f_i, file_map.length()-f_i)) {
have_chunk.back() = true; 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"; std::cout << "ReceiveStartSHA1 switching state to SHA1\n";

View File

@ -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; 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: private:
std::string _dump_dir;
//FTInfoSHA1 _sha1_info; //FTInfoSHA1 _sha1_info;
std::vector<uint8_t> _sha1_info_data; std::vector<uint8_t> _sha1_info_data;
SHA1Digest _sha1_info_hash; // treat as const SHA1Digest _sha1_info_hash; // treat as const

View File

@ -6,6 +6,8 @@
#include "./states/send_start_sha1.hpp" #include "./states/send_start_sha1.hpp"
#include "./states/receive_start_sha1.hpp" #include "./states/receive_start_sha1.hpp"
#include "ngc_ft1.h" #include "ngc_ft1.h"
#include "tox/tox.h"
#include "toxcore/tox.h"
#include <memory> #include <memory>
#include <sodium.h> #include <sodium.h>
@ -26,9 +28,22 @@ ToxClient::ToxClient(const CommandLine& cl) :
// use cl for options // use cl for options
tox_options_set_log_callback(options, log_cb); tox_options_set_log_callback(options, log_cb);
tox_options_set_local_discovery_enabled(options, false); tox_options_set_local_discovery_enabled(options, !cl.tox_disable_local_discovery);
tox_options_set_udp_enabled(options, true); tox_options_set_udp_enabled(options, !cl.tox_disable_udp);
tox_options_set_hole_punching_enabled(options, true); 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<uint8_t> profile_data{}; std::vector<uint8_t> profile_data{};
if (!_tox_profile_path.empty()) { 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; _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_TCP: std::cout << "TCP-relayed\n"; break;
case TOX_CONNECTION::TOX_CONNECTION_UDP: std::cout << "UDP-direct\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; _tox_profile_dirty = true;
} }

View File

@ -13,6 +13,7 @@
#include <string_view> #include <string_view>
#include <map> #include <map>
#include <set> #include <set>
#include <vector>
// fwd // fwd
namespace States { namespace States {
@ -77,6 +78,8 @@ struct ToxClient {
std::string _tox_profile_path; std::string _tox_profile_path;
bool _tox_profile_dirty {false}; // set in callbacks bool _tox_profile_dirty {false}; // set in callbacks
std::vector<uint8_t> _join_group_after_dht_connect;
std::unique_ptr<StateI> _state; std::unique_ptr<StateI> _state;
// key groupid, value set of peer ids // key groupid, value set of peer ids