diff --git a/src/seeder/CMakeLists.txt b/src/seeder/CMakeLists.txt --- a/src/seeder/CMakeLists.txt +++ b/src/seeder/CMakeLists.txt @@ -8,6 +8,7 @@ bitcoin.cpp db.cpp dns.cpp + options.cpp ) target_link_libraries(seeder-base server) diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp --- a/src/seeder/main.cpp +++ b/src/seeder/main.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include #include @@ -11,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -27,165 +27,6 @@ const std::function G_TRANSLATION_FUN = nullptr; -static const int CONTINUE_EXECUTION = -1; - -static const int DEFAULT_NUM_THREADS = 96; -static const int DEFAULT_PORT = 53; -static const int DEFAULT_NUM_DNS_THREADS = 4; -static const bool DEFAULT_WIPE_BAN = false; -static const bool DEFAULT_WIPE_IGNORE = false; -static const std::string DEFAULT_EMAIL = ""; -static const std::string DEFAULT_NAMESERVER = ""; -static const std::string DEFAULT_HOST = ""; -static const std::string DEFAULT_TOR_PROXY = ""; -static const std::string DEFAULT_LISTEN_ADDRESS = "::"; -static const std::string DEFAULT_IPV4_PROXY = ""; -static const std::string DEFAULT_IPV6_PROXY = ""; - -class CDnsSeedOpts { -public: - int nThreads; - int nPort; - int nDnsThreads; - bool fWipeBan; - bool fWipeIgnore; - std::string mbox; - std::string ns; - std::string host; - std::string tor; - std::string ip_addr; - std::string ipv4_proxy; - std::string ipv6_proxy; - std::set filter_whitelist; - - CDnsSeedOpts() - : nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT), - nDnsThreads(DEFAULT_NUM_DNS_THREADS), fWipeBan(DEFAULT_WIPE_BAN), - fWipeIgnore(DEFAULT_WIPE_IGNORE), mbox(DEFAULT_EMAIL), - ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), tor(DEFAULT_TOR_PROXY), - ip_addr(DEFAULT_LISTEN_ADDRESS), ipv4_proxy(DEFAULT_IPV4_PROXY), - ipv6_proxy(DEFAULT_IPV6_PROXY) {} - - int ParseCommandLine(int argc, char **argv) { - SetupSeederArgs(gArgs); - std::string error; - if (!gArgs.ParseParameters(argc, argv, error)) { - tfm::format(std::cerr, "Error parsing command line arguments: %s\n", - error); - return EXIT_FAILURE; - } - if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { - std::string strUsage = - PACKAGE_NAME " Seeder " + FormatFullVersion() + "\n"; - if (HelpRequested(gArgs)) { - strUsage += - "\nUsage: bitcoin-seeder -host= -ns= " - "[-mbox=] [-threads=] [-port=]\n\n" + - gArgs.GetHelpMessage(); - } - - tfm::format(std::cout, "%s", strUsage); - return EXIT_SUCCESS; - } - - nThreads = gArgs.GetArg("-threads", DEFAULT_NUM_THREADS); - nPort = gArgs.GetArg("-port", DEFAULT_PORT); - nDnsThreads = gArgs.GetArg("-dnsthreads", DEFAULT_NUM_DNS_THREADS); - fWipeBan = gArgs.GetBoolArg("-wipeban", DEFAULT_WIPE_BAN); - fWipeIgnore = gArgs.GetBoolArg("-wipeignore", DEFAULT_WIPE_IGNORE); - mbox = gArgs.GetArg("-mbox", DEFAULT_EMAIL); - ns = gArgs.GetArg("-ns", DEFAULT_NAMESERVER); - host = gArgs.GetArg("-host", DEFAULT_HOST); - tor = gArgs.GetArg("-onion", DEFAULT_TOR_PROXY); - ip_addr = gArgs.GetArg("-address", DEFAULT_LISTEN_ADDRESS); - ipv4_proxy = gArgs.GetArg("-proxyipv4", DEFAULT_IPV4_PROXY); - ipv6_proxy = gArgs.GetArg("-proxyipv6", DEFAULT_IPV6_PROXY); - SelectParams(gArgs.GetChainName()); - - // Both IPv4 and IPv6 addresses are valid, but the listening address is - // treated as IPv6 internally - if (ip_addr.find(':') == std::string::npos) { - ip_addr.insert(0, "::FFFF:"); - } - - if (gArgs.IsArgSet("-filter")) { - // Parse whitelist additions - std::string flagString = gArgs.GetArg("-filter", ""); - size_t flagstartpos = 0; - while (flagstartpos < flagString.size()) { - size_t flagendpos = flagString.find_first_of(',', flagstartpos); - uint64_t flag = atoi64(flagString.substr( - flagstartpos, (flagendpos - flagstartpos))); - filter_whitelist.insert(flag); - if (flagendpos == std::string::npos) { - break; - } - flagstartpos = flagendpos + 1; - } - } - if (filter_whitelist.empty()) { - filter_whitelist.insert(NODE_NETWORK); - filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM); - filter_whitelist.insert(NODE_NETWORK_LIMITED); - filter_whitelist.insert(NODE_NETWORK_LIMITED | NODE_BLOOM); - } - return CONTINUE_EXECUTION; - } - -private: - void SetupSeederArgs(ArgsManager &argsman) { - SetupHelpOptions(argsman); - argsman.AddArg("-help-debug", - "Show all debugging options (usage: --help -help-debug)", - ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); - - SetupChainParamsBaseOptions(argsman); - - argsman.AddArg("-version", "Print version and exit", - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-host=", "Hostname of the DNS seed", - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-ns=", "Hostname of the nameserver", - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-mbox=", "E-Mail address reported in SOA records", - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg( - "-threads=", - strprintf("Number of crawlers to run in parallel (default: %d)", - DEFAULT_NUM_THREADS), - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-dnsthreads=", - strprintf("Number of DNS server threads (default: %d)", - DEFAULT_NUM_DNS_THREADS), - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-address=
", - strprintf("Address to listen on (default: '%s')", - DEFAULT_LISTEN_ADDRESS), - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg( - "-port=", - strprintf("UDP port to listen on (default: %d)", DEFAULT_PORT), - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-onion=", "Tor proxy IP/Port", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-overridednsseed", - "If set, only use the specified DNS seed when " - "querying for peer addresses via DNS lookup.", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-proxyipv4=", "IPV4 SOCKS5 proxy IP/Port", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-proxyipv6=", "IPV6 SOCKS5 proxy IP/Port", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-filter=", - "Allow these flag combinations as filters", - ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-wipeban", "Wipe list of banned nodes", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-wipeignore", "Wipe list of ignored nodes", - ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - } -}; - extern "C" { #include } @@ -507,7 +348,8 @@ signal(SIGPIPE, SIG_IGN); setbuf(stdout, nullptr); CDnsSeedOpts opts; - int parseResults = opts.ParseCommandLine(argc, argv); + int parseResults = + opts.ParseCommandLine(argc, const_cast(argv)); if (parseResults != CONTINUE_EXECUTION) { return parseResults; } diff --git a/src/seeder/options.h b/src/seeder/options.h new file mode 100644 --- /dev/null +++ b/src/seeder/options.h @@ -0,0 +1,58 @@ +// Copyright (c) 2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SEEDER_OPTIONS_H +#define BITCOIN_SEEDER_OPTIONS_H + +#include +#include + +static const int CONTINUE_EXECUTION = -1; + +static const int DEFAULT_NUM_THREADS = 96; +static const int DEFAULT_PORT = 53; +static const int DEFAULT_NUM_DNS_THREADS = 4; +static const bool DEFAULT_WIPE_BAN = false; +static const bool DEFAULT_WIPE_IGNORE = false; +static const std::string DEFAULT_EMAIL = ""; +static const std::string DEFAULT_NAMESERVER = ""; +static const std::string DEFAULT_HOST = ""; +static const std::string DEFAULT_TOR_PROXY = ""; +static const std::string DEFAULT_LISTEN_ADDRESS = "::"; +static const std::string DEFAULT_IPV4_PROXY = ""; +static const std::string DEFAULT_IPV6_PROXY = ""; + +class ArgsManager; + +class CDnsSeedOpts { +public: + int nThreads; + int nPort; + int nDnsThreads; + bool fWipeBan; + bool fWipeIgnore; + std::string mbox; + std::string ns; + std::string host; + std::string tor; + std::string ip_addr; + std::string ipv4_proxy; + std::string ipv6_proxy; + std::set filter_whitelist; + + CDnsSeedOpts() + : nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT), + nDnsThreads(DEFAULT_NUM_DNS_THREADS), fWipeBan(DEFAULT_WIPE_BAN), + fWipeIgnore(DEFAULT_WIPE_IGNORE), mbox(DEFAULT_EMAIL), + ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), tor(DEFAULT_TOR_PROXY), + ip_addr(DEFAULT_LISTEN_ADDRESS), ipv4_proxy(DEFAULT_IPV4_PROXY), + ipv6_proxy(DEFAULT_IPV6_PROXY) {} + + int ParseCommandLine(int argc, const char **argv); + +private: + void SetupSeederArgs(ArgsManager &argsman); +}; + +#endif // BITCOIN_SEEDER_OPTIONS_H diff --git a/src/seeder/options.cpp b/src/seeder/options.cpp new file mode 100644 --- /dev/null +++ b/src/seeder/options.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +#include + +int CDnsSeedOpts::ParseCommandLine(int argc, const char **argv) { + SetupSeederArgs(gArgs); + std::string error; + if (!gArgs.ParseParameters(argc, argv, error)) { + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", + error); + return EXIT_FAILURE; + } + if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { + std::string strUsage = + PACKAGE_NAME " Seeder " + FormatFullVersion() + "\n"; + if (HelpRequested(gArgs)) { + strUsage += + "\nUsage: bitcoin-seeder -host= -ns= " + "[-mbox=] [-threads=] [-port=]\n\n" + + gArgs.GetHelpMessage(); + } + + tfm::format(std::cout, "%s", strUsage); + return EXIT_SUCCESS; + } + + nThreads = gArgs.GetArg("-threads", DEFAULT_NUM_THREADS); + nPort = gArgs.GetArg("-port", DEFAULT_PORT); + nDnsThreads = gArgs.GetArg("-dnsthreads", DEFAULT_NUM_DNS_THREADS); + fWipeBan = gArgs.GetBoolArg("-wipeban", DEFAULT_WIPE_BAN); + fWipeIgnore = gArgs.GetBoolArg("-wipeignore", DEFAULT_WIPE_IGNORE); + mbox = gArgs.GetArg("-mbox", DEFAULT_EMAIL); + ns = gArgs.GetArg("-ns", DEFAULT_NAMESERVER); + host = gArgs.GetArg("-host", DEFAULT_HOST); + tor = gArgs.GetArg("-onion", DEFAULT_TOR_PROXY); + ip_addr = gArgs.GetArg("-address", DEFAULT_LISTEN_ADDRESS); + ipv4_proxy = gArgs.GetArg("-proxyipv4", DEFAULT_IPV4_PROXY); + ipv6_proxy = gArgs.GetArg("-proxyipv6", DEFAULT_IPV6_PROXY); + SelectParams(gArgs.GetChainName()); + + // Both IPv4 and IPv6 addresses are valid, but the listening address is + // treated as IPv6 internally + if (ip_addr.find(':') == std::string::npos) { + ip_addr.insert(0, "::FFFF:"); + } + + if (gArgs.IsArgSet("-filter")) { + // Parse whitelist additions + std::string flagString = gArgs.GetArg("-filter", ""); + size_t flagstartpos = 0; + while (flagstartpos < flagString.size()) { + size_t flagendpos = flagString.find_first_of(',', flagstartpos); + uint64_t flag = atoi64( + flagString.substr(flagstartpos, (flagendpos - flagstartpos))); + filter_whitelist.insert(flag); + if (flagendpos == std::string::npos) { + break; + } + flagstartpos = flagendpos + 1; + } + } + if (filter_whitelist.empty()) { + filter_whitelist.insert(NODE_NETWORK); + filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM); + filter_whitelist.insert(NODE_NETWORK_LIMITED); + filter_whitelist.insert(NODE_NETWORK_LIMITED | NODE_BLOOM); + } + return CONTINUE_EXECUTION; +} + +void CDnsSeedOpts::SetupSeederArgs(ArgsManager &argsman) { + SetupHelpOptions(argsman); + argsman.AddArg("-help-debug", + "Show all debugging options (usage: --help -help-debug)", + ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + + SetupChainParamsBaseOptions(argsman); + + argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, + OptionsCategory::OPTIONS); + argsman.AddArg("-host=", "Hostname of the DNS seed", + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-ns=", "Hostname of the nameserver", + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-mbox=", "E-Mail address reported in SOA records", + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg( + "-threads=", + strprintf("Number of crawlers to run in parallel (default: %d)", + DEFAULT_NUM_THREADS), + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-dnsthreads=", + strprintf("Number of DNS server threads (default: %d)", + DEFAULT_NUM_DNS_THREADS), + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-address=
", + strprintf("Address to listen on (default: '%s')", + DEFAULT_LISTEN_ADDRESS), + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg( + "-port=", + strprintf("UDP port to listen on (default: %d)", DEFAULT_PORT), + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-onion=", "Tor proxy IP/Port", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-overridednsseed", + "If set, only use the specified DNS seed when " + "querying for peer addresses via DNS lookup.", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-proxyipv4=", "IPV4 SOCKS5 proxy IP/Port", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-proxyipv6=", "IPV6 SOCKS5 proxy IP/Port", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-filter=", + "Allow these flag combinations as filters", + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-wipeban", "Wipe list of banned nodes", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + argsman.AddArg("-wipeignore", "Wipe list of ignored nodes", + ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); +} diff --git a/src/seeder/test/CMakeLists.txt b/src/seeder/test/CMakeLists.txt --- a/src/seeder/test/CMakeLists.txt +++ b/src/seeder/test/CMakeLists.txt @@ -13,6 +13,7 @@ TESTS message_writer_tests.cpp + options_tests.cpp p2p_messaging_tests.cpp parse_name_tests.cpp write_name_tests.cpp diff --git a/src/seeder/test/options_tests.cpp b/src/seeder/test/options_tests.cpp new file mode 100644 --- /dev/null +++ b/src/seeder/test/options_tests.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +BOOST_AUTO_TEST_SUITE(options_tests) + +BOOST_AUTO_TEST_CASE(options_basic_test) { + CDnsSeedOpts opts; + const char *argv[] = {"ignored", "-host=seeder.bitcoinabc.org", + "-ns=localhost", "-mbox=email@bitcoinabc.org", + "-port=5555"}; + BOOST_CHECK(opts.ParseCommandLine(5, argv) == CONTINUE_EXECUTION); + BOOST_CHECK(opts.host == "seeder.bitcoinabc.org"); + BOOST_CHECK(opts.ns == "localhost"); + BOOST_CHECK(opts.mbox == "email@bitcoinabc.org"); + BOOST_CHECK(opts.nPort == 5555); +} + +BOOST_AUTO_TEST_SUITE_END()