diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -9,3 +9,10 @@ is similar to `listunspent` but does not use a wallet, meaning that the wallet can be disabled at compile or run time. This call is experimental, as such, is subject to changes or removal in future releases. + - `bitcoin-seeder` no longer takes single letter parameter names. Please use + the full length parameter names. See `bitcoin-seeder -?` for more + information. + - If the `-?`, `-h`, or `-help` options are used, `bitcoin-seeder` will now + output its help message and then cease operation. + - `bitcoin-seeder` will output an error if there are unknown options given as + inputs and not run. diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -558,7 +558,8 @@ $(LIBBITCOIN_SEEDER) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) + $(LIBBITCOIN_CRYPTO) \ + $(LIBBITCOIN_CONSENSUS) bitcoin_seeder_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # diff --git a/src/seeder/CMakeLists.txt b/src/seeder/CMakeLists.txt --- a/src/seeder/CMakeLists.txt +++ b/src/seeder/CMakeLists.txt @@ -13,7 +13,10 @@ main.cpp ) -target_link_libraries(bitcoin-seeder common) +target_link_libraries(bitcoin-seeder + common + bitcoinconsensus +) include(BinaryTest) add_to_symbols_check(bitcoin-seeder) diff --git a/src/seeder/README.md b/src/seeder/README.md --- a/src/seeder/README.md +++ b/src/seeder/README.md @@ -33,10 +33,10 @@ On the system vps.example.com, you can now run dnsseed: -./bitcoin-seeder -h dnsseed.example.com -n vps.example.com +./bitcoin-seeder -host=dnsseed.example.com -ns=vps.example.com If you want the DNS server to report SOA records, please provide an -e-mail address (with the @ part replaced by .) using -m. +e-mail address (with the @ part replaced by .) using -mbox. RUNNING AS NON-ROOT @@ -50,7 +50,7 @@ $ iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5353 If properly configured, this will allow you to run dnsseed in userspace, using -the -p 5353 option. +the -port=5353 option. Generate Seed Lists ------------------- diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp --- a/src/seeder/main.cpp +++ b/src/seeder/main.cpp @@ -2,6 +2,8 @@ // 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 @@ -10,6 +12,7 @@ #include #include #include +#include #include #include @@ -17,15 +20,16 @@ #include #include #include -#include #include 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_TESTNET = false; +static const std::string DEFAULT_NETWORK = CBaseChainParams::MAIN; static const bool DEFAULT_WIPE_BAN = false; static const bool DEFAULT_WIPE_IGNORE = false; static const std::string DEFAULT_EMAIL = ""; @@ -40,9 +44,9 @@ int nThreads; int nPort; int nDnsThreads; - int fUseTestNet; - int fWipeBan; - int fWipeIgnore; + std::string fNetwork; + bool fWipeBan; + bool fWipeIgnore; std::string mbox; std::string ns; std::string host; @@ -53,126 +57,62 @@ CDnsSeedOpts() : nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT), - nDnsThreads(DEFAULT_NUM_DNS_THREADS), fUseTestNet(DEFAULT_TESTNET), + nDnsThreads(DEFAULT_NUM_DNS_THREADS), fNetwork(DEFAULT_NETWORK), fWipeBan(DEFAULT_WIPE_BAN), fWipeIgnore(DEFAULT_WIPE_IGNORE), mbox(DEFAULT_EMAIL), ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), tor(DEFAULT_TOR_PROXY), ipv4_proxy(DEFAULT_IPV4_PROXY), ipv6_proxy(DEFAULT_IPV6_PROXY) {} - void ParseCommandLine(int argc, char **argv) { - static const char *help = - "Bitcoin-cash-seeder\n" - "Usage: %s -h -n [-m ] [-t ] [-p " - "]\n" - "\n" - "Options:\n" - "-h Hostname of the DNS seed\n" - "-n Hostname of the nameserver\n" - "-m E-Mail address reported in SOA records\n" - "-t Number of crawlers to run in parallel (default " - "96)\n" - "-d Number of DNS server threads (default 4)\n" - "-p UDP port to listen on (default 53)\n" - "-o Tor proxy IP/Port\n" - "-i IPV4 SOCKS5 proxy IP/Port\n" - "-k IPV6 SOCKS5 proxy IP/Port\n" - "-w f1,f2,... Allow these flag combinations as filters\n" - "--testnet Use testnet\n" - "--wipeban Wipe list of banned nodes\n" - "--wipeignore Wipe list of ignored nodes\n" - "-?, --help Show this text\n" - "\n"; - bool showHelp = false; - - while (1) { - static struct option long_options[] = { - {"host", required_argument, 0, 'h'}, - {"ns", required_argument, 0, 'n'}, - {"mbox", required_argument, 0, 'm'}, - {"threads", required_argument, 0, 't'}, - {"dnsthreads", required_argument, 0, 'd'}, - {"port", required_argument, 0, 'p'}, - {"onion", required_argument, 0, 'o'}, - {"proxyipv4", required_argument, 0, 'i'}, - {"proxyipv6", required_argument, 0, 'k'}, - {"filter", required_argument, 0, 'w'}, - {"testnet", no_argument, &fUseTestNet, 1}, - {"wipeban", no_argument, &fWipeBan, 1}, - {"wipeignore", no_argument, &fWipeIgnore, 1}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0}}; - int option_index = 0; - int c = - getopt_long(argc, argv, "h:n:m:t:p:d:o:i:k:w:", long_options, - &option_index); - if (c == -1) break; - switch (c) { - case 'h': { - host = std::string(optarg); - break; - } - - case 'm': { - mbox = std::string(optarg); - break; - } - - case 'n': { - ns = std::string(optarg); - break; - } - - case 't': { - int n = strtol(optarg, nullptr, 10); - if (n > 0 && n < 1000) nThreads = n; - break; - } - - case 'd': { - int n = strtol(optarg, nullptr, 10); - if (n > 0 && n < 1000) nDnsThreads = n; - break; - } - - case 'p': { - int p = strtol(optarg, nullptr, 10); - if (p > 0 && p < 65536) nPort = p; - break; - } - - case 'o': { - tor = std::string(optarg); - break; - } - - case 'i': { - ipv4_proxy = std::string(optarg); - break; - } - - case 'k': { - ipv6_proxy = std::string(optarg); - break; - } - - case 'w': { - char *ptr = optarg; - while (*ptr != 0) { - unsigned long l = strtoul(ptr, &ptr, 0); - if (*ptr == ',') { - ptr++; - } else if (*ptr != 0) { - break; - } - filter_whitelist.insert(l); - } - break; - } + int ParseCommandLine(int argc, char **argv) { + SetupSeederArgs(); + std::string error; + if (!gArgs.ParseParameters(argc, argv, error)) { + fprintf(stderr, "Error parsing command line arguments: %s\n", + error.c_str()); + return EXIT_FAILURE; + } + if (HelpRequested(gArgs)) { + std::string strUsage = "Bitcoin-cash-seeder\nUsage: bitcoin-seeder " + "-host= -ns= [-mbox=] " + "[-threads=] [-port=]\n\n" + + gArgs.GetHelpMessage(); + + fprintf(stdout, "%s", strUsage.c_str()); + return EXIT_SUCCESS; + } - case '?': { - showHelp = true; + nThreads = gArgs.GetArg("-threads", DEFAULT_NUM_THREADS); + nPort = gArgs.GetArg("-port", DEFAULT_PORT); + nDnsThreads = gArgs.GetArg("-dnsthreads", DEFAULT_NUM_DNS_THREADS); + fNetwork = gArgs.GetChainName(); + SelectParams(fNetwork); + if (fNetwork == CBaseChainParams::REGTEST) { + fprintf(stdout, "Seeder does not support use of %s.\n", + CBaseChainParams::REGTEST.c_str()); + return EXIT_FAILURE; + } + 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); + ipv4_proxy = gArgs.GetArg("-proxyipv4", DEFAULT_IPV4_PROXY); + ipv6_proxy = gArgs.GetArg("-proxyipv6", DEFAULT_IPV6_PROXY); + + if (gArgs.IsArgSet("-filter")) { + // Parse whitelist additions + std::string flags = gArgs.GetArg("-filter", ""); + size_t flagstartpos = 0; + while (flagstartpos < flags.size()) { + size_t flagendpos = flags.find_first_of(",", flagstartpos); + uint64_t flag = atoi64( + flags.substr(flagstartpos, (flagendpos - flagstartpos))); + filter_whitelist.insert(flag); + if (flagendpos == std::string::npos) { break; } + flagstartpos = flagendpos + 1; } } if (filter_whitelist.empty()) { @@ -181,8 +121,45 @@ filter_whitelist.insert(NODE_NETWORK | NODE_XTHIN); filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM | NODE_XTHIN); } - if (!host.empty() && ns.empty()) showHelp = true; - if (showHelp) fprintf(stderr, help, argv[0]); + return CONTINUE_EXECUTION; + } + +private: + void SetupSeederArgs() { + gArgs.AddArg("-?", _("Print this help message and exit"), false, + OptionsCategory::OPTIONS); + gArgs.AddArg("-host=", _("Hostname of the DNS seed"), false, + OptionsCategory::OPTIONS); + gArgs.AddArg("-ns=", _("Hostname of the nameserver"), false, + OptionsCategory::OPTIONS); + gArgs.AddArg("-mbox=", + _("E-Mail address reported in SOA records"), false, + OptionsCategory::OPTIONS); + gArgs.AddArg("-threads=", + _("Number of crawlers to run in parallel (default 96)"), + false, OptionsCategory::OPTIONS); + gArgs.AddArg("-dnsthreads=", + _("Number of DNS server threads (default 4)"), false, + OptionsCategory::OPTIONS); + gArgs.AddArg("-port=", _("UDP port to listen on (default 53)"), + false, OptionsCategory::CONNECTION); + gArgs.AddArg("-onion=", _("Tor proxy IP/Port"), false, + OptionsCategory::CONNECTION); + gArgs.AddArg("-proxyipv4=", _("IPV4 SOCKS5 proxy IP/Port"), + false, OptionsCategory::CONNECTION); + gArgs.AddArg("-proxyipv6=", _("IPV6 SOCKS5 proxy IP/Port"), + false, OptionsCategory::CONNECTION); + gArgs.AddArg("-filter=", + _("Allow these flag combinations as filters"), false, + OptionsCategory::OPTIONS); + SetupChainParamsBaseOptions(); + gArgs.AddArg("-wipeban", _("Wipe list of banned nodes"), false, + OptionsCategory::CONNECTION); + gArgs.AddArg("-wipeignore", _("Wipe list of ignored nodes"), false, + OptionsCategory::CONNECTION); + + gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN); + gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN); } }; @@ -499,7 +476,11 @@ signal(SIGPIPE, SIG_IGN); setbuf(stdout, nullptr); CDnsSeedOpts opts; - opts.ParseCommandLine(argc, argv); + int parseResults = opts.ParseCommandLine(argc, argv); + if (parseResults != CONTINUE_EXECUTION) { + return parseResults; + } + fprintf(stdout, "Supporting whitelisted filters: "); for (std::set::const_iterator it = opts.filter_whitelist.begin(); it != opts.filter_whitelist.end(); it++) { @@ -534,8 +515,8 @@ } } bool fDNS = true; - if (opts.fUseTestNet) { - fprintf(stdout, "Using testnet.\n"); + fprintf(stdout, "Using %s.\n", opts.fNetwork.c_str()); + if (opts.fNetwork == CBaseChainParams::TESTNET) { netMagic[0] = 0xf4; netMagic[1] = 0xe5; netMagic[2] = 0xf3; @@ -601,5 +582,5 @@ pthread_create(&threadDump, nullptr, ThreadDumper, nullptr); void *res; pthread_join(threadDump, &res); - return 0; + return EXIT_SUCCESS; }