Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/main.cpp
#include <clientversion.h> | #include <clientversion.h> | ||||
#include <fs.h> | #include <fs.h> | ||||
#include <logging.h> | #include <logging.h> | ||||
#include <protocol.h> | #include <protocol.h> | ||||
#include <seeder/bitcoin.h> | #include <seeder/bitcoin.h> | ||||
#include <seeder/db.h> | #include <seeder/db.h> | ||||
#include <seeder/dns.h> | #include <seeder/dns.h> | ||||
#include <streams.h> | #include <streams.h> | ||||
#include <util/strencodings.h> | |||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <atomic> | #include <atomic> | ||||
#include <cinttypes> | #include <cinttypes> | ||||
#include <csignal> | #include <csignal> | ||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <getopt.h> | |||||
#include <pthread.h> | #include <pthread.h> | ||||
const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr; | const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr; | ||||
static const int DEFAULT_NUM_THREADS = 96; | static const int DEFAULT_NUM_THREADS = 96; | ||||
static const int DEFAULT_PORT = 53; | static const int DEFAULT_PORT = 53; | ||||
static const int DEFAULT_NUM_DNS_THREADS = 4; | static const int DEFAULT_NUM_DNS_THREADS = 4; | ||||
static const bool DEFAULT_TESTNET = false; | static const bool DEFAULT_TESTNET = false; | ||||
static const bool DEFAULT_WIPE_BAN = false; | static const bool DEFAULT_WIPE_BAN = false; | ||||
static const bool DEFAULT_WIPE_IGNORE = false; | static const bool DEFAULT_WIPE_IGNORE = false; | ||||
static const std::string DEFAULT_EMAIL = ""; | static const std::string DEFAULT_EMAIL = ""; | ||||
static const std::string DEFAULT_NAMESERVER = ""; | static const std::string DEFAULT_NAMESERVER = ""; | ||||
static const std::string DEFAULT_HOST = ""; | static const std::string DEFAULT_HOST = ""; | ||||
static const std::string DEFAULT_TOR_PROXY = ""; | static const std::string DEFAULT_TOR_PROXY = ""; | ||||
static const std::string DEFAULT_IPV4_PROXY = ""; | static const std::string DEFAULT_IPV4_PROXY = ""; | ||||
static const std::string DEFAULT_IPV6_PROXY = ""; | static const std::string DEFAULT_IPV6_PROXY = ""; | ||||
class CDnsSeedOpts { | class CDnsSeedOpts { | ||||
public: | public: | ||||
int nThreads; | int nThreads; | ||||
int nPort; | int nPort; | ||||
int nDnsThreads; | int nDnsThreads; | ||||
int fUseTestNet; | bool fUseTestNet; | ||||
int fWipeBan; | bool fWipeBan; | ||||
int fWipeIgnore; | bool fWipeIgnore; | ||||
std::string mbox; | std::string mbox; | ||||
std::string ns; | std::string ns; | ||||
std::string host; | std::string host; | ||||
std::string tor; | std::string tor; | ||||
std::string ipv4_proxy; | std::string ipv4_proxy; | ||||
std::string ipv6_proxy; | std::string ipv6_proxy; | ||||
std::set<uint64_t> filter_whitelist; | std::set<uint64_t> filter_whitelist; | ||||
bool helpRequested; | |||||
CDnsSeedOpts() | CDnsSeedOpts() | ||||
: nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT), | : nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT), | ||||
nDnsThreads(DEFAULT_NUM_DNS_THREADS), fUseTestNet(DEFAULT_TESTNET), | nDnsThreads(DEFAULT_NUM_DNS_THREADS), fUseTestNet(DEFAULT_TESTNET), | ||||
fWipeBan(DEFAULT_WIPE_BAN), fWipeIgnore(DEFAULT_WIPE_IGNORE), | fWipeBan(DEFAULT_WIPE_BAN), fWipeIgnore(DEFAULT_WIPE_IGNORE), | ||||
mbox(DEFAULT_EMAIL), ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), | mbox(DEFAULT_EMAIL), ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), | ||||
tor(DEFAULT_TOR_PROXY), ipv4_proxy(DEFAULT_IPV4_PROXY), | tor(DEFAULT_TOR_PROXY), ipv4_proxy(DEFAULT_IPV4_PROXY), | ||||
ipv6_proxy(DEFAULT_IPV6_PROXY) {} | ipv6_proxy(DEFAULT_IPV6_PROXY), helpRequested(false) {} | ||||
void ParseCommandLine(int argc, char **argv) { | bool ParseCommandLine(int argc, char **argv) { | ||||
static const char *help = | SetupSeederArgs(); | ||||
"Bitcoin-cash-seeder\n" | std::string error; | ||||
"Usage: %s -h <host> -n <ns> [-m <mbox>] [-t <threads>] [-p " | if (!gArgs.ParseParameters(argc, argv, error)) { | ||||
"<port>]\n" | fprintf(stderr, "Error parsing command line arguments: %s\n", | ||||
"\n" | error.c_str()); | ||||
"Options:\n" | return false; | ||||
"-h <host> Hostname of the DNS seed\n" | } | ||||
"-n <ns> Hostname of the nameserver\n" | if (HelpRequested(gArgs)) { | ||||
"-m <mbox> E-Mail address reported in SOA records\n" | std::string strUsage = "Bitcoin-cash-seeder\nUsage: bitcoin-seeder " | ||||
"-t <threads> Number of crawlers to run in parallel (default " | "-host=<host> -ns=<ns> [-mbox=<mbox>] " | ||||
"96)\n" | "[-threads=<threads>] [-port=<port>]\n\n" + | ||||
"-d <threads> Number of DNS server threads (default 4)\n" | gArgs.GetHelpMessage(); | ||||
"-p <port> UDP port to listen on (default 53)\n" | |||||
"-o <ip:port> Tor proxy IP/Port\n" | fprintf(stdout, "%s", strUsage.c_str()); | ||||
"-i <ip:port> IPV4 SOCKS5 proxy IP/Port\n" | helpRequested = true; | ||||
"-k <ip:port> IPV6 SOCKS5 proxy IP/Port\n" | return true; | ||||
"-w f1,f2,... Allow these flag combinations as filters\n" | } | ||||
jasonbcox: Why introduce a member variable when the return value will do? This is indicative that the… | |||||
"--testnet Use testnet\n" | |||||
"--wipeban Wipe list of banned nodes\n" | nThreads = gArgs.GetArg("-threads", DEFAULT_NUM_THREADS); | ||||
"--wipeignore Wipe list of ignored nodes\n" | nPort = gArgs.GetArg("-port", DEFAULT_PORT); | ||||
"-?, --help Show this text\n" | nDnsThreads = gArgs.GetArg("-dnsthreads", DEFAULT_NUM_DNS_THREADS); | ||||
"\n"; | fUseTestNet = gArgs.GetBoolArg("-testnet", DEFAULT_TESTNET); | ||||
bool showHelp = false; | fWipeBan = gArgs.GetBoolArg("-wipeban", DEFAULT_WIPE_BAN); | ||||
fWipeIgnore = gArgs.GetBoolArg("-wipeignore", DEFAULT_WIPE_IGNORE); | |||||
while (1) { | mbox = gArgs.GetArg("-mbox", DEFAULT_EMAIL); | ||||
static struct option long_options[] = { | ns = gArgs.GetArg("-ns", DEFAULT_NAMESERVER); | ||||
{"host", required_argument, 0, 'h'}, | host = gArgs.GetArg("-host", DEFAULT_HOST); | ||||
{"ns", required_argument, 0, 'n'}, | tor = gArgs.GetArg("-onion", DEFAULT_TOR_PROXY); | ||||
{"mbox", required_argument, 0, 'm'}, | ipv4_proxy = gArgs.GetArg("-proxyipv4", DEFAULT_IPV4_PROXY); | ||||
{"threads", required_argument, 0, 't'}, | ipv6_proxy = gArgs.GetArg("-proxyipv6", DEFAULT_IPV6_PROXY); | ||||
{"dnsthreads", required_argument, 0, 'd'}, | |||||
{"port", required_argument, 0, 'p'}, | if (gArgs.IsArgSet("-filter")) { | ||||
{"onion", required_argument, 0, 'o'}, | // Parse whitelist additions | ||||
{"proxyipv4", required_argument, 0, 'i'}, | std::string flags = gArgs.GetArg("-filter", ""); | ||||
{"proxyipv6", required_argument, 0, 'k'}, | size_t flagstartpos = 0; | ||||
{"filter", required_argument, 0, 'w'}, | while (flagstartpos < flags.size()) { | ||||
{"testnet", no_argument, &fUseTestNet, 1}, | size_t flagendpos = flags.find_first_of(",", flagstartpos); | ||||
{"wipeban", no_argument, &fWipeBan, 1}, | uint64_t flag = atoi64( | ||||
{"wipeignore", no_argument, &fWipeIgnore, 1}, | flags.substr(flagstartpos, (flagendpos - flagstartpos))); | ||||
{"help", no_argument, 0, 'h'}, | filter_whitelist.insert(flag); | ||||
{0, 0, 0, 0}}; | if (flagendpos == std::string::npos) { | ||||
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; | |||||
} | |||||
case '?': { | |||||
showHelp = true; | |||||
break; | break; | ||||
} | } | ||||
flagstartpos = flagendpos + 1; | |||||
} | } | ||||
} | } | ||||
if (filter_whitelist.empty()) { | if (filter_whitelist.empty()) { | ||||
filter_whitelist.insert(NODE_NETWORK); | filter_whitelist.insert(NODE_NETWORK); | ||||
filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM); | filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM); | ||||
filter_whitelist.insert(NODE_NETWORK | NODE_XTHIN); | filter_whitelist.insert(NODE_NETWORK | NODE_XTHIN); | ||||
filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM | NODE_XTHIN); | filter_whitelist.insert(NODE_NETWORK | NODE_BLOOM | NODE_XTHIN); | ||||
} | } | ||||
if (!host.empty() && ns.empty()) showHelp = true; | return true; | ||||
if (showHelp) fprintf(stderr, help, argv[0]); | } | ||||
private: | |||||
void SetupSeederArgs() { | |||||
gArgs.AddArg("-?", _("Print this help message and exit"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-host=<host>", _("Hostname of the DNS seed"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-ns=<ns>", _("Hostname of the nameserver"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-mbox=<mbox>", | |||||
_("E-Mail address reported in SOA records"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-threads=<threads>", | |||||
_("Number of crawlers to run in parallel (default 96)"), | |||||
false, OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-dnsthreads=<threads>", | |||||
_("Number of DNS server threads (default 4)"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-port=<port>", _("UDP port to listen on (default 53)"), | |||||
false, OptionsCategory::CONNECTION); | |||||
gArgs.AddArg("-onion=<ip:port>", _("Tor proxy IP/Port"), false, | |||||
OptionsCategory::CONNECTION); | |||||
gArgs.AddArg("-proxyipv4=<ip:port>", _("IPV4 SOCKS5 proxy IP/Port"), | |||||
false, OptionsCategory::CONNECTION); | |||||
gArgs.AddArg("-proxyipv6=<ip:port>", _("IPV6 SOCKS5 proxy IP/Port"), | |||||
false, OptionsCategory::CONNECTION); | |||||
gArgs.AddArg("-filter=<f1,f2,...>", | |||||
_("Allow these flag combinations as filters"), false, | |||||
OptionsCategory::OPTIONS); | |||||
gArgs.AddArg("-testnet", _("Use testnet"), false, | |||||
OptionsCategory::CHAINPARAMS); | |||||
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); | |||||
} | } | ||||
}; | }; | ||||
extern "C" { | extern "C" { | ||||
#include <seeder/dns.h> | #include <seeder/dns.h> | ||||
} | } | ||||
CAddrDb db; | CAddrDb db; | ||||
▲ Show 20 Lines • Show All 300 Lines • ▼ Show 20 Lines | |||||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
// The logger dump everything on the console by default. | // The logger dump everything on the console by default. | ||||
GetLogger().m_print_to_console = true; | GetLogger().m_print_to_console = true; | ||||
signal(SIGPIPE, SIG_IGN); | signal(SIGPIPE, SIG_IGN); | ||||
setbuf(stdout, nullptr); | setbuf(stdout, nullptr); | ||||
CDnsSeedOpts opts; | CDnsSeedOpts opts; | ||||
opts.ParseCommandLine(argc, argv); | if (!opts.ParseCommandLine(argc, argv)) { | ||||
return 1; | |||||
} | |||||
if (opts.helpRequested) { | |||||
return 0; | |||||
} | |||||
fprintf(stdout, "Supporting whitelisted filters: "); | fprintf(stdout, "Supporting whitelisted filters: "); | ||||
for (std::set<uint64_t>::const_iterator it = opts.filter_whitelist.begin(); | for (std::set<uint64_t>::const_iterator it = opts.filter_whitelist.begin(); | ||||
it != opts.filter_whitelist.end(); it++) { | it != opts.filter_whitelist.end(); it++) { | ||||
if (it != opts.filter_whitelist.begin()) { | if (it != opts.filter_whitelist.begin()) { | ||||
fprintf(stdout, ","); | fprintf(stdout, ","); | ||||
} | } | ||||
fprintf(stdout, "0x%lx", (unsigned long)*it); | fprintf(stdout, "0x%lx", (unsigned long)*it); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |
Why introduce a member variable when the return value will do? This is indicative that the return type doesn't match the use case.