diff options
-rw-r--r-- | src/init.cpp | 41 | ||||
-rw-r--r-- | src/net.cpp | 19 | ||||
-rw-r--r-- | src/net.h | 7 |
3 files changed, 54 insertions, 13 deletions
diff --git a/src/init.cpp b/src/init.cpp index 74d30b0733..773e23d084 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -441,7 +441,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); + argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); @@ -1911,9 +1911,6 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } LogPrintf("nBestHeight = %d\n", chain_active_height); - if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) - StartTorControl(DefaultOnionServiceTarget()); - Discover(); // Map ports with UPnP @@ -1940,13 +1937,39 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA connOptions.nMaxOutboundLimit = nMaxOutboundLimit; connOptions.m_peer_connect_timeout = peer_connect_timeout; - for (const std::string& strBind : args.GetArgs("-bind")) { - CService addrBind; - if (!Lookup(strBind, addrBind, GetListenPort(), false)) { - return InitError(ResolveErrMsg("bind", strBind)); + for (const std::string& bind_arg : args.GetArgs("-bind")) { + CService bind_addr; + const size_t index = bind_arg.rfind('='); + if (index == std::string::npos) { + if (Lookup(bind_arg, bind_addr, GetListenPort(), false)) { + connOptions.vBinds.push_back(bind_addr); + continue; + } + } else { + const std::string network_type = bind_arg.substr(index + 1); + if (network_type == "onion") { + const std::string truncated_bind_arg = bind_arg.substr(0, index); + if (Lookup(truncated_bind_arg, bind_addr, BaseParams().OnionServiceTargetPort(), false)) { + connOptions.onion_binds.push_back(bind_addr); + continue; + } + } } - connOptions.vBinds.push_back(addrBind); + return InitError(ResolveErrMsg("bind", bind_arg)); } + + if (connOptions.onion_binds.empty()) { + connOptions.onion_binds.push_back(DefaultOnionServiceTarget()); + } + + if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) { + const auto bind_addr = connOptions.onion_binds.front(); + if (connOptions.onion_binds.size() > 1) { + InitWarning(strprintf(_("More than one onion bind address is provided. Using %s for the automatically created Tor onion service."), bind_addr.ToStringIPPort())); + } + StartTorControl(bind_addr); + } + for (const std::string& strBind : args.GetArgs("-whitebind")) { NetWhitebindPermissions whitebind; bilingual_str error; diff --git a/src/net.cpp b/src/net.cpp index 0d906ec573..7f575b66c6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -84,6 +84,11 @@ enum BindFlags { BF_NONE = 0, BF_EXPLICIT = (1U << 0), BF_REPORT_ERROR = (1U << 1), + /** + * Do not call AddLocal() for our special addresses, e.g., for incoming + * Tor connections, to prevent gossiping them over the network. + */ + BF_DONT_ADVERTISE = (1U << 2), }; // The set of sockets cannot be modified while waiting @@ -2305,14 +2310,17 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags return false; } - if (addr.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0) { + if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) { AddLocal(addr, LOCAL_BIND); } return true; } -bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds) +bool CConnman::InitBinds( + const std::vector<CService>& binds, + const std::vector<NetWhitebindPermissions>& whiteBinds, + const std::vector<CService>& onion_binds) { bool fBound = false; for (const auto& addrBind : binds) { @@ -2328,6 +2336,11 @@ bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<N fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE); fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE); } + + for (const auto& addr_bind : onion_binds) { + fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::PF_NONE); + } + return fBound; } @@ -2346,7 +2359,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) nMaxOutboundCycleStartTime = 0; } - if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) { + if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds, connOptions.onion_binds)) { if (clientInterface) { clientInterface->ThreadSafeMessageBox( _("Failed to listen on any port. Use -listen=0 if you want this."), @@ -209,6 +209,7 @@ public: std::vector<NetWhitelistPermissions> vWhitelistedRange; std::vector<NetWhitebindPermissions> vWhiteBinds; std::vector<CService> vBinds; + std::vector<CService> onion_binds; bool m_use_addrman_outgoing = true; std::vector<std::string> m_specified_outgoing; std::vector<std::string> m_added_nodes; @@ -406,7 +407,11 @@ private: bool BindListenPort(const CService& bindAddr, bilingual_str& strError, NetPermissionFlags permissions); bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions); - bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds); + bool InitBinds( + const std::vector<CService>& binds, + const std::vector<NetWhitebindPermissions>& whiteBinds, + const std::vector<CService>& onion_binds); + void ThreadOpenAddedConnections(); void AddAddrFetch(const std::string& strDest); void ProcessAddrFetch(); |