diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/command_line.h | 47 | ||||
-rw-r--r-- | src/common/dns_utils.cpp | 28 | ||||
-rw-r--r-- | src/common/dns_utils.h | 2 | ||||
-rw-r--r-- | src/common/int-util.h | 9 | ||||
-rw-r--r-- | src/common/password.cpp | 15 | ||||
-rw-r--r-- | src/common/password.h | 2 | ||||
-rw-r--r-- | src/common/perf_timer.cpp | 7 | ||||
-rw-r--r-- | src/common/rpc_client.h | 16 | ||||
-rw-r--r-- | src/common/threadpool.cpp | 18 | ||||
-rw-r--r-- | src/common/threadpool.h | 3 | ||||
-rw-r--r-- | src/common/util.cpp | 2 | ||||
-rw-r--r-- | src/common/util.h | 6 |
12 files changed, 119 insertions, 36 deletions
diff --git a/src/common/command_line.h b/src/common/command_line.h index 7b183d86b..f67efcf86 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -30,7 +30,9 @@ #pragma once +#include <functional> #include <iostream> +#include <sstream> #include <type_traits> #include <boost/program_options/parsers.hpp> @@ -46,7 +48,7 @@ namespace command_line //! \return True if `str` is `is_iequal("n" || "no" || `tr("no"))`. bool is_no(const std::string& str); - template<typename T, bool required = false> + template<typename T, bool required = false, bool dependent = false> struct arg_descriptor; template<typename T> @@ -81,6 +83,22 @@ namespace command_line }; template<typename T> + struct arg_descriptor<T, false, true> + { + typedef T value_type; + + const char* name; + const char* description; + + T default_value; + + const arg_descriptor<bool, false>& ref; + std::function<T(bool, bool, T)> depf; + + bool not_use_default; + }; + + template<typename T> boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, true>& /*arg*/) { return boost::program_options::value<T>()->required(); @@ -96,6 +114,20 @@ namespace command_line } template<typename T> + boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false, true>& arg) + { + auto semantic = boost::program_options::value<T>(); + if (!arg.not_use_default) { + std::ostringstream format; + format << arg.depf(false, true, arg.default_value) << ", " + << arg.depf(true, true, arg.default_value) << " if '" + << arg.ref.name << "'"; + semantic->default_value(arg.depf(arg.ref.default_value, true, arg.default_value), format.str()); + } + return semantic; + } + + template<typename T> boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg, const T& def) { auto semantic = boost::program_options::value<T>(); @@ -112,8 +144,8 @@ namespace command_line return semantic; } - template<typename T, bool required> - void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, required>& arg, bool unique = true) + template<typename T, bool required, bool dependent> + void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, required, dependent>& arg, bool unique = true) { if (0 != description.find_nothrow(arg.name, false)) { @@ -189,12 +221,17 @@ namespace command_line return !value.empty(); } - template<typename T, bool required> - bool is_arg_defaulted(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg) + template<typename T, bool required, bool dependent> + bool is_arg_defaulted(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, dependent>& arg) { return vm[arg.name].defaulted(); } + template<typename T, bool required> + T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, true>& arg) + { + return arg.depf(get_arg(vm, arg.ref), is_arg_defaulted(vm, arg), vm[arg.name].template as<T>()); + } template<typename T, bool required> T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg) diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 06f127c25..1ecdae8ec 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -36,13 +36,21 @@ #include <boost/filesystem/fstream.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> +#include <boost/algorithm/string/join.hpp> using namespace epee; namespace bf = boost::filesystem; #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.dns" -#define DEFAULT_DNS_PUBLIC_ADDR "8.8.4.4" +static const char *DEFAULT_DNS_PUBLIC_ADDR[] = +{ + "194.150.168.168", // CCC (Germany) + "81.3.27.54", // Lightning Wire Labs (Germany) + "31.3.135.232", // OpenNIC (Switzerland) + "80.67.169.40", // FDN (France) + "209.58.179.186", // Cyberghost (Singapore) +}; static boost::mutex instance_lock; @@ -201,13 +209,13 @@ public: DNSResolver::DNSResolver() : m_data(new DNSResolverData()) { int use_dns_public = 0; - std::string dns_public_addr = DEFAULT_DNS_PUBLIC_ADDR; + std::vector<std::string> dns_public_addr; if (auto res = getenv("DNS_PUBLIC")) { dns_public_addr = tools::dns_utils::parse_dns_public(res); if (!dns_public_addr.empty()) { - MGINFO("Using public DNS server: " << dns_public_addr << " (TCP)"); + MGINFO("Using public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)"); use_dns_public = 1; } else @@ -221,7 +229,8 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData()) if (use_dns_public) { - ub_ctx_set_fwd(m_data->m_ub_context, dns_public_addr.c_str()); + for (const auto &ip: dns_public_addr) + ub_ctx_set_fwd(m_data->m_ub_context, ip.c_str()); ub_ctx_set_option(m_data->m_ub_context, string_copy("do-udp:"), string_copy("no")); ub_ctx_set_option(m_data->m_ub_context, string_copy("do-tcp:"), string_copy("yes")); } @@ -526,15 +535,16 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std return true; } -std::string parse_dns_public(const char *s) +std::vector<std::string> parse_dns_public(const char *s) { unsigned ip0, ip1, ip2, ip3; char c; - std::string dns_public_addr; + std::vector<std::string> dns_public_addr; if (!strcmp(s, "tcp")) { - dns_public_addr = DEFAULT_DNS_PUBLIC_ADDR; - LOG_PRINT_L0("Using default public DNS server: " << dns_public_addr << " (TCP)"); + for (size_t i = 0; i < sizeof(DEFAULT_DNS_PUBLIC_ADDR) / sizeof(DEFAULT_DNS_PUBLIC_ADDR[0]); ++i) + dns_public_addr.push_back(DEFAULT_DNS_PUBLIC_ADDR[i]); + LOG_PRINT_L0("Using default public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)"); } else if (sscanf(s, "tcp://%u.%u.%u.%u%c", &ip0, &ip1, &ip2, &ip3, &c) == 4) { @@ -544,7 +554,7 @@ std::string parse_dns_public(const char *s) } else { - dns_public_addr = std::string(s + strlen("tcp://")); + dns_public_addr.push_back(std::string(s + strlen("tcp://"))); } } else diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h index d5dc03283..f46bca3dd 100644 --- a/src/common/dns_utils.h +++ b/src/common/dns_utils.h @@ -167,7 +167,7 @@ std::string get_account_address_as_str_from_url(const std::string& url, bool& dn bool load_txt_records_from_dns(std::vector<std::string> &records, const std::vector<std::string> &dns_urls); -std::string parse_dns_public(const char *s); +std::vector<std::string> parse_dns_public(const char *s); } // namespace tools::dns_utils diff --git a/src/common/int-util.h b/src/common/int-util.h index 11e39895e..3bcc085e2 100644 --- a/src/common/int-util.h +++ b/src/common/int-util.h @@ -34,7 +34,10 @@ #include <stdbool.h> #include <stdint.h> #include <string.h> + +#ifndef _MSC_VER #include <sys/param.h> +#endif #if defined(__ANDROID__) #include <byteswap.h> @@ -206,6 +209,12 @@ static inline void memcpy_swap64(void *dst, const void *src, size_t n) { } } +#ifdef _MSC_VER +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# define BYTE_ORDER LITTLE_ENDIAN +#endif + #if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled"); #endif diff --git a/src/common/password.cpp b/src/common/password.cpp index ef026c979..9336a14fc 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -42,12 +42,10 @@ #include <unistd.h> #endif -#ifdef HAVE_READLINE - #include "readline_buffer.h" -#endif - #include "memwipe.h" +#define EOT 0x4 + namespace { #if defined(_WIN32) @@ -134,7 +132,7 @@ namespace while (aPass.size() < tools::password_container::max_password_size) { int ch = getch(); - if (EOF == ch) + if (EOF == ch || ch == EOT) { return false; } @@ -229,13 +227,20 @@ namespace tools m_password.clear(); } + std::atomic<bool> password_container::is_prompting(false); + boost::optional<password_container> password_container::prompt(const bool verify, const char *message) { + is_prompting = true; password_container pass1{}; password_container pass2{}; if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password)) + { + is_prompting = false; return {std::move(pass1)}; + } + is_prompting = false; return boost::none; } diff --git a/src/common/password.h b/src/common/password.h index 7c29effe4..61937b93a 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -31,6 +31,7 @@ #pragma once #include <string> +#include <atomic> #include <boost/optional/optional.hpp> #include "wipeable_string.h" @@ -49,6 +50,7 @@ namespace tools //! \return A password from stdin TTY prompt or `std::cin` pipe. static boost::optional<password_container> prompt(bool verify, const char *mesage = "Password"); + static std::atomic<bool> is_prompting; password_container(const password_container&) = delete; password_container(password_container&& rhs) = default; diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp index 41e23130d..16abdfd99 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -49,16 +49,15 @@ namespace #ifdef __x86_64__ uint64_t get_ticks_per_ns() { - uint64_t t0 = epee::misc_utils::get_ns_count(); + uint64_t t0 = epee::misc_utils::get_ns_count(), t1; uint64_t r0 = get_tick_count(); while (1) { - uint64_t t = epee::misc_utils::get_ns_count(); - if (t - t0 > 1*1000000000) break; // work one second + t1 = epee::misc_utils::get_ns_count(); + if (t1 - t0 > 1*1000000000) break; // work one second } - uint64_t t1 = epee::misc_utils::get_ns_count(); uint64_t r1 = get_tick_count(); uint64_t tpns256 = 256 * (r1 - r0) / (t1 - t0); return tpns256 ? tpns256 : 1; diff --git a/src/common/rpc_client.h b/src/common/rpc_client.h index 64c84ed19..9665966ae 100644 --- a/src/common/rpc_client.h +++ b/src/common/rpc_client.h @@ -72,10 +72,10 @@ namespace tools fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); return false; } - ok = ok && epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); + ok = epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); if (!ok) { - fail_msg_writer() << "Daemon request failed"; + fail_msg_writer() << "basic_json_rpc_request: Daemon request failed"; return false; } else @@ -95,15 +95,15 @@ namespace tools t_http_connection connection(&m_http_client); bool ok = connection.is_open(); - ok = ok && epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); if (!ok) { fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); return false; } - else if (res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? + ok = epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); + if (!ok || res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? { - fail_msg_writer() << fail_msg << " -- " << res.status; + fail_msg_writer() << fail_msg << " -- json_rpc_request: " << res.status; return false; } else @@ -123,15 +123,15 @@ namespace tools t_http_connection connection(&m_http_client); bool ok = connection.is_open(); - ok = ok && epee::net_utils::invoke_http_json(relative_url, req, res, m_http_client, t_http_connection::TIMEOUT()); if (!ok) { fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); return false; } - else if (res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? + ok = epee::net_utils::invoke_http_json(relative_url, req, res, m_http_client, t_http_connection::TIMEOUT()); + if (!ok || res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? { - fail_msg_writer() << fail_msg << " -- " << res.status; + fail_msg_writer() << fail_msg << "-- rpc_request: " << res.status; return false; } else diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 7fd16ceaf..51e071577 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -25,6 +25,7 @@ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "misc_log_ex.h" #include "common/threadpool.h" #include <cassert> @@ -81,6 +82,23 @@ int threadpool::get_max_concurrency() { return max; } +threadpool::waiter::~waiter() +{ + { + boost::unique_lock<boost::mutex> lock(mt); + if (num) + MERROR("wait should have been called before waiter dtor - waiting now"); + } + try + { + wait(); + } + catch (const std::exception &e) + { + /* ignored */ + } +} + void threadpool::waiter::wait() { boost::unique_lock<boost::mutex> lock(mt); while(num) cv.wait(lock); diff --git a/src/common/threadpool.h b/src/common/threadpool.h index a0e53b011..34152541c 100644 --- a/src/common/threadpool.h +++ b/src/common/threadpool.h @@ -34,6 +34,7 @@ #include <functional> #include <utility> #include <vector> +#include <stdexcept> namespace tools { @@ -57,7 +58,7 @@ public: void dec(); void wait(); //! Wait for a set of tasks to finish. waiter() : num(0){} - ~waiter() { wait(); } + ~waiter(); }; // Submit a task to the pool. The waiter pointer may be diff --git a/src/common/util.cpp b/src/common/util.cpp index 659ea31b8..e0f3cd655 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -552,8 +552,6 @@ std::string get_nix_version_display_string() } bool on_startup() { - wipeable_string::set_wipe(&memwipe); - mlog_configure("", true); sanitize_locale(); diff --git a/src/common/util.h b/src/common/util.h index 5afb42c97..d3ba47a4f 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -153,8 +153,12 @@ namespace tools } return r; #else + static struct sigaction sa; + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_handler = posix_handler; + sa.sa_flags = 0; /* Only blocks SIGINT, SIGTERM and SIGPIPE */ - signal(SIGINT, posix_handler); + sigaction(SIGINT, &sa, NULL); signal(SIGTERM, posix_handler); signal(SIGPIPE, SIG_IGN); m_handler = t; |