Monero
Loading...
Searching...
No Matches
net_node.inl
Go to the documentation of this file.
1// Copyright (c) 2014-2022, The Monero Project
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30
31// IP blocking adapted from Boolberry
32
33#include <algorithm>
34#include <boost/bind/bind.hpp>
35#include <boost/date_time/posix_time/posix_time.hpp>
36#include <boost/filesystem/operations.hpp>
37#include <boost/optional/optional.hpp>
38#include <boost/thread/thread.hpp>
39#include <boost/uuid/uuid_io.hpp>
40#include <boost/algorithm/string.hpp>
41#include <atomic>
42#include <functional>
43#include <limits>
44#include <memory>
45#include <tuple>
46#include <vector>
47
48#include "version.h"
49#include "string_tools.h"
50#include "common/util.h"
51#include "common/dns_utils.h"
52#include "common/pruning.h"
53#include "net/error.h"
54#include "net/net_helper.h"
55#include "math_helper.h"
56#include "misc_log_ex.h"
57#include "p2p_protocol_defs.h"
58#include "crypto/crypto.h"
61#include "net/parse.h"
62
66
67#undef MONERO_DEFAULT_LOG_CATEGORY
68#define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
69
70#define NET_MAKE_IP(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
71
72#define MIN_WANTED_SEED_NODES 12
73
74static inline boost::asio::ip::address_v4 make_address_v4_from_v6(const boost::asio::ip::address_v6& a)
75{
76 const auto &bytes = a.to_bytes();
77 uint32_t v4 = 0;
78 v4 = (v4 << 8) | bytes[12];
79 v4 = (v4 << 8) | bytes[13];
80 v4 = (v4 << 8) | bytes[14];
81 v4 = (v4 << 8) | bytes[15];
82 return boost::asio::ip::address_v4(v4);
83}
84
85namespace nodetool
86{
87 template<class t_payload_net_handler>
89 {
90 // tcp server uses io_context in destructor, and every zone uses
91 // io_service from public zone.
92 for (auto current = m_network_zones.begin(); current != m_network_zones.end(); /* below */)
93 {
94 if (current->first != epee::net_utils::zone::public_)
95 current = m_network_zones.erase(current);
96 else
97 ++current;
98 }
99 }
100 //-----------------------------------------------------------------------------------
101 inline bool append_net_address(std::vector<epee::net_utils::network_address> & seed_nodes, std::string const & addr, uint16_t default_port);
102 //-----------------------------------------------------------------------------------
103 template<class t_payload_net_handler>
104 void node_server<t_payload_net_handler>::init_options(boost::program_options::options_description& desc)
105 {
134 }
135 //-----------------------------------------------------------------------------------
136 template<class t_payload_net_handler>
138 {
139 TRY_ENTRY();
141 if (storage)
142 m_peerlist_storage = std::move(*storage);
143
145 public_zone.m_config.m_support_flags = P2P_SUPPORT_FLAGS;
146 public_zone.m_config.m_peer_id = crypto::rand<uint64_t>();
148
149 CATCH_ENTRY_L0("node_server::init_config", false);
150 return true;
151 }
152 //-----------------------------------------------------------------------------------
153 template<class t_payload_net_handler>
154 void node_server<t_payload_net_handler>::for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f)
155 {
156 for(auto& zone : m_network_zones)
157 {
158 zone.second.m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntx){
159 return f(cntx, cntx.peer_id, cntx.support_flags);
160 });
161 }
162 }
163 //-----------------------------------------------------------------------------------
164 template<class t_payload_net_handler>
165 bool node_server<t_payload_net_handler>::for_connection(const boost::uuids::uuid &connection_id, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f)
166 {
167 for(auto& zone : m_network_zones)
168 {
169 const bool result = zone.second.m_net_server.get_config_object().for_connection(connection_id, [&](p2p_connection_context& cntx){
170 return f(cntx, cntx.peer_id, cntx.support_flags);
171 });
172 if (result)
173 return true;
174 }
175 return false;
176 }
177 //-----------------------------------------------------------------------------------
178 template<class t_payload_net_handler>
180 {
182
183 const time_t now = time(nullptr);
184
185 // look in the hosts list
186 auto it = m_blocked_hosts.find(address.host_str());
187 if (it != m_blocked_hosts.end())
188 {
189 if (now >= it->second)
190 {
191 m_blocked_hosts.erase(it);
192 MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
193 it = m_blocked_hosts.end();
194 }
195 else
196 {
197 if (t)
198 *t = it->second - now;
199 return false;
200 }
201 }
202
203 // manually loop in subnets
204 if (address.get_type_id() == epee::net_utils::address_type::ipv4)
205 {
206 auto ipv4_address = address.template as<epee::net_utils::ipv4_network_address>();
207 std::map<epee::net_utils::ipv4_network_subnet, time_t>::iterator it;
208 for (it = m_blocked_subnets.begin(); it != m_blocked_subnets.end(); )
209 {
210 if (now >= it->second)
211 {
212 it = m_blocked_subnets.erase(it);
213 MCLOG_CYAN(el::Level::Info, "global", "Subnet " << it->first.host_str() << " unblocked.");
214 continue;
215 }
216 if (it->first.matches(ipv4_address))
217 {
218 if (t)
219 *t = it->second - now;
220 return false;
221 }
222 ++it;
223 }
224 }
225
226 // not found in hosts or subnets, allowed
227 return true;
228 }
229 //-----------------------------------------------------------------------------------
230 template<class t_payload_net_handler>
232 {
233 const network_zone& zone = m_network_zones.at(address.get_zone());
234 if (zone.m_current_number_of_in_peers >= zone.m_config.m_net_config.max_in_connection_count) // in peers limit
235 {
236 MWARNING("Exceeded max incoming connections, so dropping this one.");
237 return true;
238 }
239
241 {
242 MWARNING("CONNECTION FROM " << address.host_str() << " REFUSED, too many connections from the same address");
243 return true;
244 }
245
246 return false;
247 }
248
249 //-----------------------------------------------------------------------------------
250 template<class t_payload_net_handler>
252 {
253 if(!addr.is_blockable())
254 return false;
255
256 const time_t now = time(nullptr);
257 bool added = false;
258
260 time_t limit;
261 if (now > std::numeric_limits<time_t>::max() - seconds)
262 limit = std::numeric_limits<time_t>::max();
263 else
264 limit = now + seconds;
265 const std::string host_str = addr.host_str();
266 auto it = m_blocked_hosts.find(host_str);
267 if (it == m_blocked_hosts.end())
269 m_blocked_hosts[host_str] = limit;
271 // if the host was already blocked due to being in a blocked subnet, let it be silent
272 bool matches_blocked_subnet = false;
275 auto ipv4_address = addr.template as<epee::net_utils::ipv4_network_address>();
276 for (auto jt = m_blocked_subnets.begin(); jt != m_blocked_subnets.end(); ++jt)
278 if (jt->first.matches(ipv4_address))
279 {
280 matches_blocked_subnet = true;
281 break;
285 if (!matches_blocked_subnet)
286 added = true;
287 }
288 else if (it->second < limit || !add_only)
289 it->second = limit;
291 // drop any connection to that address. This should only have to look into
292 // the zone related to the connection, but really make sure everything is
293 // swept ...
294 std::vector<boost::uuids::uuid> conns;
295 for(auto& zone : m_network_zones)
296 {
297 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
298 {
299 if (cntxt.m_remote_address.is_same_host(addr))
301 conns.push_back(cntxt.m_connection_id);
303 return true;
304 });
305
306 peerlist_entry pe{};
307 pe.adr = addr;
308 if (addr.port() == 0)
309 {
310 zone.second.m_peerlist.evict_host_from_peerlist(true, pe);
311 zone.second.m_peerlist.evict_host_from_peerlist(false, pe);
312 }
313 else
314 {
315 zone.second.m_peerlist.remove_from_peer_white(pe);
316 zone.second.m_peerlist.remove_from_peer_gray(pe);
317 zone.second.m_peerlist.remove_from_peer_anchor(addr);
318 }
319
320 for (const auto &c: conns)
321 zone.second.m_net_server.get_config_object().close(c);
322
323 conns.clear();
324 }
325
326 if (added)
327 MCLOG_CYAN(el::Level::Info, "global", "Host " << host_str << " blocked.");
328 else
329 MINFO("Host " << host_str << " block time updated.");
330 return true;
331 }
332 //-----------------------------------------------------------------------------------
333 template<class t_payload_net_handler>
337 auto i = m_blocked_hosts.find(address.host_str());
338 if (i == m_blocked_hosts.end())
339 return false;
340 m_blocked_hosts.erase(i);
341 MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
342 return true;
344 //-----------------------------------------------------------------------------------
345 template<class t_payload_net_handler>
348 const time_t now = time(nullptr);
351 time_t limit;
352 if (now > std::numeric_limits<time_t>::max() - seconds)
353 limit = std::numeric_limits<time_t>::max();
354 else
355 limit = now + seconds;
356 const bool added = m_blocked_subnets.find(subnet) == m_blocked_subnets.end();
357 m_blocked_subnets[subnet] = limit;
359 // drop any connection to that subnet. This should only have to look into
360 // the zone related to the connection, but really make sure everything is
361 // swept ...
362 std::vector<boost::uuids::uuid> conns;
363 for(auto& zone : m_network_zones)
364 {
365 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
367 if (cntxt.m_remote_address.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
368 return true;
369 auto ipv4_address = cntxt.m_remote_address.template as<epee::net_utils::ipv4_network_address>();
370 if (subnet.matches(ipv4_address))
371 {
372 conns.push_back(cntxt.m_connection_id);
374 return true;
375 });
376 for (const auto &c: conns)
377 zone.second.m_net_server.get_config_object().close(c);
379 for (int i = 0; i < 2; ++i)
380 zone.second.m_peerlist.filter(i == 0, [&subnet](const peerlist_entry &pe){
381 if (pe.adr.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
382 return false;
383 return subnet.matches(pe.adr.as<const epee::net_utils::ipv4_network_address>());
384 });
386 conns.clear();
389 if (added)
390 MCLOG_CYAN(el::Level::Info, "global", "Subnet " << subnet.host_str() << " blocked.");
391 else
392 MINFO("Subnet " << subnet.host_str() << " blocked.");
393 return true;
395 //-----------------------------------------------------------------------------------
396 template<class t_payload_net_handler>
400 auto i = m_blocked_subnets.find(subnet);
401 if (i == m_blocked_subnets.end())
402 return false;
404 MCLOG_CYAN(el::Level::Info, "global", "Subnet " << subnet.host_str() << " unblocked.");
405 return true;
407 //-----------------------------------------------------------------------------------
408 template<class t_payload_net_handler>
410 {
411 if(!address.is_blockable())
412 return false;
415 uint64_t fails = m_host_fails_score[address.host_str()] += score;
416 MDEBUG("Host " << address.host_str() << " fail score=" << fails);
418 {
419 auto it = m_host_fails_score.find(address.host_str());
420 CHECK_AND_ASSERT_MES(it != m_host_fails_score.end(), false, "internal error");
421 it->second = P2P_IP_FAILS_BEFORE_BLOCK/2;
423 }
424 return true;
426 //-----------------------------------------------------------------------------------
427 template<class t_payload_net_handler>
429 const boost::program_options::variables_map& vm
430 )
431 {
434 const bool pad_txs = command_line::get_arg(vm, arg_pad_transactions);
436
438 public_zone.m_connect = &public_connect;
443 public_zone.m_can_pingback = true;
446 const bool has_no_igd = command_line::get_arg(vm, arg_no_igd);
447 const std::string sigd = command_line::get_arg(vm, arg_igd);
448 if (sigd == "enabled")
449 {
450 if (has_no_igd)
451 {
452 MFATAL("Cannot have both --" << arg_no_igd.name << " and --" << arg_igd.name << " enabled");
453 return false;
454 }
455 m_igd = igd;
456 }
457 else if (sigd == "disabled")
458 {
459 m_igd = no_igd;
460 }
461 else if (sigd == "delayed")
462 {
463 if (has_no_igd && !command_line::is_arg_defaulted(vm, arg_igd))
464 {
465 MFATAL("Cannot have both --" << arg_no_igd.name << " and --" << arg_igd.name << " delayed");
466 return false;
467 }
468 m_igd = has_no_igd ? no_igd : delayed_igd;
469 }
470 else
471 {
472 MFATAL("Invalid value for --" << arg_igd.name << ", expected enabled, disabled or delayed");
473 return false;
474 }
477 m_require_ipv4 = !command_line::get_arg(vm, arg_p2p_ignore_ipv4);
478 public_zone.m_notifier = cryptonote::levin::notify{
479 public_zone.m_net_server.get_io_context(), public_zone.m_net_server.get_config_shared(), nullptr, epee::net_utils::zone::public_, pad_txs, m_payload_handler.get_core()
480 };
481
483 {
484 std::vector<std::string> perrs = command_line::get_arg(vm, arg_p2p_add_peer);
485 for(const std::string& pr_str: perrs)
486 {
489 const uint16_t default_port = cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT;
490 expect<epee::net_utils::network_address> adr = net::get_network_address(pr_str, default_port);
491 if (adr)
493 add_zone(adr->get_zone());
494 pe.adr = std::move(*adr);
495 m_command_line_peers.push_back(std::move(pe));
496 continue;
497 }
498 CHECK_AND_ASSERT_MES(
499 adr == net::error::unsupported_address, false, "Bad address (\"" << pr_str << "\"): " << adr.error().message()
500 );
501
502 std::vector<epee::net_utils::network_address> resolved_addrs;
503 bool r = append_net_address(resolved_addrs, pr_str, default_port);
504 CHECK_AND_ASSERT_MES(r, false, "Failed to parse or resolve address from string: " << pr_str);
505 for (const epee::net_utils::network_address& addr : resolved_addrs)
506 {
508 pe.adr = addr;
509 m_command_line_peers.push_back(pe);
510 }
511 }
512 }
513
515 {
516 if (!parse_peers_and_add_to_container(vm, arg_p2p_add_exclusive_node, m_exclusive_peers))
517 return false;
518 }
519
521 {
522 if (!parse_peers_and_add_to_container(vm, arg_p2p_add_priority_node, m_priority_peers))
523 return false;
524 }
525
527 {
528 boost::unique_lock<boost::shared_mutex> lock(public_zone.m_seed_nodes_lock);
529
530 if (!parse_peers_and_add_to_container(vm, arg_p2p_seed_node, public_zone.m_seed_nodes))
531 return false;
532 }
533
535 {
536 const std::string ban_list = command_line::get_arg(vm, arg_ban_list);
537
538 const boost::filesystem::path ban_list_path(ban_list);
539 boost::system::error_code ec;
540 if (!boost::filesystem::exists(ban_list_path, ec))
541 {
542 throw std::runtime_error("Can't find ban list file " + ban_list + " - " + ec.message());
543 }
544
545 std::string banned_ips;
546 if (!epee::file_io_utils::load_file_to_string(ban_list_path.string(), banned_ips))
547 {
548 throw std::runtime_error("Failed to read ban list file " + ban_list);
549 }
550
551 std::istringstream iss(banned_ips);
552 for (std::string line; std::getline(iss, line); )
553 {
554 // ignore comments after '#' character
555 const size_t pound_idx = line.find('#');
556 if (pound_idx != std::string::npos)
557 line.resize(pound_idx);
558
559 // trim whitespace and ignore empty lines
560 boost::trim(line);
561 if (line.empty())
562 continue;
563
564 auto subnet = net::get_ipv4_subnet_address(line);
565 if (subnet)
566 {
567 block_subnet(*subnet, std::numeric_limits<time_t>::max());
568 continue;
569 }
570 const expect<epee::net_utils::network_address> parsed_addr = net::get_network_address(line, 0);
571 if (parsed_addr)
572 {
573 block_host(*parsed_addr, std::numeric_limits<time_t>::max());
574 continue;
575 }
576 MERROR("Invalid IP address or IPv4 subnet: " << line);
577 }
578 }
579
581 m_hide_my_port = true;
582
584 m_payload_handler.set_no_sync(true);
585
586 m_enable_dns_blocklist = command_line::get_arg(vm, arg_enable_dns_blocklist);
587
588 if ( !set_max_out_peers(public_zone, command_line::get_arg(vm, arg_out_peers) ) )
589 return false;
590 else
591 m_payload_handler.set_max_out_peers(epee::net_utils::zone::public_, public_zone.m_config.m_net_config.max_out_connection_count);
592
593
594 if ( !set_max_in_peers(public_zone, command_line::get_arg(vm, arg_in_peers) ) )
595 return false;
596
597 if ( !set_tos_flag(vm, command_line::get_arg(vm, arg_tos_flag) ) )
598 return false;
599
600 if ( !set_rate_up_limit(vm, command_line::get_arg(vm, arg_limit_rate_up) ) )
601 return false;
602
603 if ( !set_rate_down_limit(vm, command_line::get_arg(vm, arg_limit_rate_down) ) )
604 return false;
605
606 if ( !set_rate_limit(vm, command_line::get_arg(vm, arg_limit_rate) ) )
607 return false;
608
609
610 epee::byte_slice noise = nullptr;
611 auto proxies = get_proxies(vm);
612 if (!proxies)
613 return false;
614
615 for (auto& proxy : *proxies)
616 {
617 network_zone& zone = add_zone(proxy.zone);
618 if (zone.m_connect != nullptr)
619 {
620 MERROR("Listed --" << arg_tx_proxy.name << " twice with " << epee::net_utils::zone_to_string(proxy.zone));
621 return false;
622 }
623 zone.m_connect = &socks_connect;
624 zone.m_proxy_address = std::move(proxy.address);
625
626 if (!set_max_out_peers(zone, proxy.max_connections))
627 return false;
628 else
629 m_payload_handler.set_max_out_peers(proxy.zone, proxy.max_connections);
630
631 epee::byte_slice this_noise = nullptr;
632 if (proxy.noise)
633 {
634 static_assert(sizeof(epee::levin::bucket_head2) < CRYPTONOTE_NOISE_BYTES, "noise bytes too small");
635 if (noise.empty())
637
638 this_noise = noise.clone();
639 }
640
641 zone.m_notifier = cryptonote::levin::notify{
642 zone.m_net_server.get_io_context(), zone.m_net_server.get_config_shared(), std::move(this_noise), proxy.zone, pad_txs, m_payload_handler.get_core()
643 };
644 }
645
646 for (const auto& zone : m_network_zones)
647 {
648 if (zone.second.m_connect == nullptr)
649 {
650 MERROR("Set outgoing peer for " << epee::net_utils::zone_to_string(zone.first) << " but did not set --" << arg_tx_proxy.name);
651 return false;
652 }
653 }
654
655 auto inbounds = get_anonymous_inbounds(vm);
656 if (!inbounds)
657 return false;
658
659 const std::size_t tx_relay_zones = m_network_zones.size();
660 for (auto& inbound : *inbounds)
661 {
662 network_zone& zone = add_zone(inbound.our_address.get_zone());
663
664 if (!zone.m_bind_ip.empty())
665 {
666 MERROR("Listed --" << arg_anonymous_inbound.name << " twice with " << epee::net_utils::zone_to_string(inbound.our_address.get_zone()) << " network");
667 return false;
668 }
669
670 if (zone.m_connect == nullptr && tx_relay_zones <= 1)
671 {
672 MERROR("Listed --" << arg_anonymous_inbound.name << " without listing any --" << arg_tx_proxy.name << ". The latter is necessary for sending local txes over anonymity networks");
673 return false;
674 }
675
676 zone.m_bind_ip = std::move(inbound.local_ip);
677 zone.m_port = std::move(inbound.local_port);
678 zone.m_net_server.set_default_remote(std::move(inbound.default_remote));
679 zone.m_our_address = std::move(inbound.our_address);
680
681 if (!set_max_in_peers(zone, inbound.max_connections))
682 return false;
683 }
684
686
687 return true;
688 }
689 //-----------------------------------------------------------------------------------
691 std::vector<epee::net_utils::network_address> & seed_nodes
692 , std::string const & addr
693 , uint16_t default_port
694 )
695 {
696 using namespace boost::asio;
697
698 // Split addr string into host string and port string
699 std::string host;
700 std::string port = std::to_string(default_port);
702 MINFO("Resolving node address: host=" << host << ", port=" << port);
703
704 boost::system::error_code ec;
705 io_context io_srv;
706 ip::tcp::resolver resolver(io_srv);
707 const auto results = resolver.resolve(host, port, boost::asio::ip::tcp::resolver::canonical_name, ec);
708 CHECK_AND_ASSERT_MES(!ec && !results.empty(), false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value());
709
710 for (const auto& result : results)
711 {
712 const auto& endpoint = result.endpoint();
713 if (endpoint.address().is_v4())
714 {
715 epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_uint()), endpoint.port()}};
716 seed_nodes.push_back(na);
717 MINFO("Added node: " << na.str());
718 }
719 else
720 {
721 epee::net_utils::network_address na{epee::net_utils::ipv6_network_address{endpoint.address().to_v6(), endpoint.port()}};
722 seed_nodes.push_back(na);
723 MINFO("Added node: " << na.str());
724 }
725 }
726 return true;
727 }
728
729 //-----------------------------------------------------------------------------------
730 template<class t_payload_net_handler>
732 {
733 std::set<std::string> full_addrs;
735 {
736 full_addrs.insert("176.9.0.187:28080");
737 full_addrs.insert("192.99.8.110:28080");
738 full_addrs.insert("37.187.74.171:28080");
739 full_addrs.insert("88.99.195.15:28080");
740 full_addrs.insert("5.104.84.64:28080");
741 }
743 {
744 full_addrs.insert("176.9.0.187:38080");
745 full_addrs.insert("192.99.8.110:38080");
746 full_addrs.insert("37.187.74.171:38080");
747 full_addrs.insert("88.99.195.15:38080");
748 full_addrs.insert("5.104.84.64:38080");
749 }
751 {
752 }
753 else
754 {
755 full_addrs.insert("176.9.0.187:18080");
756 full_addrs.insert("88.198.163.90:18080");
757 full_addrs.insert("192.99.8.110:18080");
758 full_addrs.insert("37.187.74.171:18080");
759 full_addrs.insert("88.99.195.15:18080");
760 full_addrs.insert("5.104.84.64:18080");
761 }
762 return full_addrs;
763 }
764 //-----------------------------------------------------------------------------------
765 template<class t_payload_net_handler>
767 {
768 if (!m_exclusive_peers.empty() || m_offline)
769 {
770 return {};
771 }
773 {
774 return get_ip_seed_nodes();
775 }
777 {
778 return get_ip_seed_nodes();
779 }
781 {
782 // TODO: a domain can be set through socks, so that the remote side does the lookup for the DNS seed nodes.
783 m_fallback_seed_nodes_added.test_and_set();
784 return get_ip_seed_nodes();
785 }
786
787 std::set<std::string> full_addrs;
788
789 // for each hostname in the seed nodes list, attempt to DNS resolve and
790 // add the result addresses as seed nodes
791 // TODO: at some point add IPv6 support, but that won't be relevant
792 // for some time yet.
793
794 std::vector<std::vector<std::string>> dns_results;
795 dns_results.resize(m_seed_nodes_list.size());
796
797 // some libc implementation provide only a very small stack
798 // for threads, e.g. musl only gives +- 80kb, which is not
799 // enough to do a resolve with unbound. we request a stack
800 // of 1 mb, which should be plenty
801 boost::thread::attributes thread_attributes;
802 thread_attributes.set_stack_size(1024*1024);
803
804 std::list<boost::thread> dns_threads;
805 uint64_t result_index = 0;
806 for (const std::string& addr_str : m_seed_nodes_list)
807 {
808 boost::thread th = boost::thread(thread_attributes, [=, &dns_results, &addr_str]
809 {
810 MDEBUG("dns_threads[" << result_index << "] created for: " << addr_str);
811 // TODO: care about dnssec avail/valid
812 bool avail, valid;
813 std::vector<std::string> addr_list;
814
815 try
816 {
817 addr_list = tools::DNSResolver::instance().get_ipv4(addr_str, avail, valid);
818 MDEBUG("dns_threads[" << result_index << "] DNS resolve done");
819 boost::this_thread::interruption_point();
820 }
821 catch(const boost::thread_interrupted&)
822 {
823 // thread interruption request
824 // even if we now have results, finish thread without setting
825 // result variables, which are now out of scope in main thread
826 MWARNING("dns_threads[" << result_index << "] interrupted");
827 return;
828 }
829
830 MINFO("dns_threads[" << result_index << "] addr_str: " << addr_str << " number of results: " << addr_list.size());
831 dns_results[result_index] = addr_list;
832 });
833
834 dns_threads.push_back(std::move(th));
835 ++result_index;
836 }
837
838 MDEBUG("dns_threads created, now waiting for completion or timeout of " << CRYPTONOTE_DNS_TIMEOUT_MS << "ms");
839 boost::chrono::system_clock::time_point deadline = boost::chrono::system_clock::now() + boost::chrono::milliseconds(CRYPTONOTE_DNS_TIMEOUT_MS);
840 uint64_t i = 0;
841 for (boost::thread& th : dns_threads)
842 {
843 if (! th.try_join_until(deadline))
844 {
845 MWARNING("dns_threads[" << i << "] timed out, sending interrupt");
846 th.interrupt();
847 }
848 ++i;
849 }
850
851 i = 0;
852 for (const auto& result : dns_results)
853 {
854 MDEBUG("DNS lookup for " << m_seed_nodes_list[i] << ": " << result.size() << " results");
855 // if no results for node, thread's lookup likely timed out
856 if (result.size())
857 {
858 for (const auto& addr_string : result)
859 full_addrs.insert(addr_string + ":" + std::to_string(cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT));
860 }
861 ++i;
862 }
863
864 // append the fallback nodes if we have too few seed nodes to start with
865 if (full_addrs.size() < MIN_WANTED_SEED_NODES)
866 {
867 if (full_addrs.empty())
868 MINFO("DNS seed node lookup either timed out or failed, falling back to defaults");
869 else
870 MINFO("Not enough DNS seed nodes found, using fallback defaults too");
871
872 for (const auto &peer: get_ip_seed_nodes())
873 full_addrs.insert(peer);
874 m_fallback_seed_nodes_added.test_and_set();
875 }
876
877 return full_addrs;
878 }
879 //-----------------------------------------------------------------------------------
880 template<class t_payload_net_handler>
882 {
883 switch (zone)
884 {
886 return get_dns_seed_nodes();
889 {
890 return {
891 "zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18083",
892 "plowsof3t5hogddwabaeiyrno25efmzfxyro2vligremt7sxpsclfaid.onion:18083",
893 "plowsoffjexmxalw73tkjmf422gq6575fc7vicuu4javzn2ynnte6tyd.onion:18083",
894 "plowsofe6cleftfmk2raiw5h2x66atrik3nja4bfd3zrfa2hdlgworad.onion:18083",
895 "aclc4e2jhhtr44guufbnwk5bzwhaecinax4yip4wr4tjn27sjsfg6zqd.onion:18083",
896 "lykcas4tus7mkm4bhsgqe4drtd4awi7gja24goscc47xfgzj54yofyqd.onion:18083",
897 };
898 }
899 return {};
902 {
903 return {
904 "uqj3aphckqtjsitz7kxx5flqpwjlq5ppr3chazfued7xucv3nheq.b32.i2p",
905 "vdmnehdjkpkg57nthgnjfuaqgku673r5bpbqg56ix6fyqoywgqrq.b32.i2p",
906 "ugnlcdciyhghh2zert7c3kl4biwkirc43ke33jiy5slnd3mv2trq.b32.i2p",
907 };
908 }
909 return {};
910 default:
911 break;
912 }
913 throw std::logic_error{"Bad zone given to get_seed_nodes"};
914 }
915 //-----------------------------------------------------------------------------------
916 template<class t_payload_net_handler>
918 {
919 const auto zone_ = m_network_zones.lower_bound(zone);
920 if (zone_ != m_network_zones.end() && zone_->first == zone)
921 return zone_->second;
922
924 return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_context()))->second;
925 }
926 //-----------------------------------------------------------------------------------
927 template<class t_payload_net_handler>
928 bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm, const std::string& proxy, bool proxy_dns_leaks_allowed)
929 {
930 bool res = handle_command_line(vm);
931 CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line");
932 if (proxy.size())
933 {
934 const auto endpoint = net::get_tcp_endpoint(proxy);
935 CHECK_AND_ASSERT_MES(endpoint, false, "Failed to parse proxy: " << proxy << " - " << endpoint.error());
937 public_zone.m_connect = &socks_connect;
938 public_zone.m_proxy_address = *endpoint;
939 public_zone.m_can_pingback = false;
940 m_enable_dns_seed_nodes &= proxy_dns_leaks_allowed;
941 m_enable_dns_blocklist &= proxy_dns_leaks_allowed;
942 }
943
945 {
947 }
949 {
951 }
952 else
953 {
955 }
956
959
960 if ((m_nettype == cryptonote::MAINNET && public_zone.m_port != std::to_string(::config::P2P_DEFAULT_PORT))
961 || (m_nettype == cryptonote::TESTNET && public_zone.m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT))
962 || (m_nettype == cryptonote::STAGENET && public_zone.m_port != std::to_string(::config::stagenet::P2P_DEFAULT_PORT))) {
963 m_config_folder = m_config_folder + "/" + public_zone.m_port;
964 }
965
966 res = init_config();
967 CHECK_AND_ASSERT_MES(res, false, "Failed to init config.");
968
969 for (auto& zone : m_network_zones)
970 {
971 res = zone.second.m_peerlist.init(m_peerlist_storage.take_zone(zone.first), m_allow_local_ip);
972 CHECK_AND_ASSERT_MES(res, false, "Failed to init peerlist.");
973 }
974
975 for(const auto& p: m_command_line_peers)
976 m_network_zones.at(p.adr.get_zone()).m_peerlist.append_with_peer_white(p);
977
978 //only in case if we really sure that we have external visible ip
979 m_have_address = true;
980
981 //configure self
982
983 public_zone.m_net_server.set_threads_prefix("P2P"); // all zones use these threads/asio::io_service
984
985 // from here onwards, it's online stuff
986 if (m_offline)
987 return res;
988
989 //try to bind
991 for (auto& zone : m_network_zones)
992 {
993 zone.second.m_net_server.get_config_object().set_handler(this);
994 zone.second.m_net_server.get_config_object().m_invoke_timeout = P2P_DEFAULT_INVOKE_TIMEOUT;
995
996 if (!zone.second.m_bind_ip.empty())
997 {
998 std::string ipv6_addr = "";
999 std::string ipv6_port = "";
1000 zone.second.m_net_server.set_connection_filter(this);
1001 zone.second.m_net_server.set_connection_limit(this);
1002 MINFO("Binding (IPv4) on " << zone.second.m_bind_ip << ":" << zone.second.m_port);
1003 if (!zone.second.m_bind_ipv6_address.empty() && m_use_ipv6)
1004 {
1005 ipv6_addr = zone.second.m_bind_ipv6_address;
1006 ipv6_port = zone.second.m_port_ipv6;
1007 MINFO("Binding (IPv6) on " << zone.second.m_bind_ipv6_address << ":" << zone.second.m_port_ipv6);
1008 }
1009 res = zone.second.m_net_server.init_server(zone.second.m_port, zone.second.m_bind_ip, ipv6_port, ipv6_addr, m_use_ipv6, m_require_ipv4, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
1010 CHECK_AND_ASSERT_MES(res, false, "Failed to bind server");
1011 }
1012 }
1013
1015 MLOG_GREEN(el::Level::Info, "Net service bound (IPv4) to " << public_zone.m_bind_ip << ":" << m_listening_port);
1016 if (m_use_ipv6)
1017 {
1019 MLOG_GREEN(el::Level::Info, "Net service bound (IPv6) to " << public_zone.m_bind_ipv6_address << ":" << m_listening_port_ipv6);
1020 }
1021 if(m_external_port)
1022 MDEBUG("External port defined as " << m_external_port);
1023
1024 // add UPnP port mapping
1025 if(m_igd == igd)
1026 {
1028 if (m_use_ipv6)
1029 {
1031 }
1032 }
1033
1034 return res;
1035 }
1036 //-----------------------------------------------------------------------------------
1037 template<class t_payload_net_handler>
1042 //-----------------------------------------------------------------------------------
1043 template<class t_payload_net_handler>
1045 {
1046 // creating thread to log number of connections
1047 mPeersLoggerThread.reset(new boost::thread([&]()
1048 {
1049 _note("Thread monitor number of peers - start");
1051 while (!is_closing && !public_zone.m_net_server.is_stop_signal_sent())
1052 { // main loop of thread
1053 //number_of_peers = m_net_server.get_config_object().get_connections_count();
1054 for (auto& zone : m_network_zones)
1055 {
1056 unsigned int number_of_in_peers = 0;
1057 unsigned int number_of_out_peers = 0;
1058 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
1059 {
1060 if (cntxt.m_is_income)
1061 {
1062 ++number_of_in_peers;
1063 }
1064 else if (!cntxt.is_ping)
1065 {
1066 ++number_of_out_peers;
1067 }
1068 return true;
1069 }); // lambda
1070 zone.second.m_current_number_of_in_peers = number_of_in_peers;
1071 zone.second.m_current_number_of_out_peers = number_of_out_peers;
1072 }
1073 boost::this_thread::sleep_for(boost::chrono::seconds(1));
1074 } // main loop of thread
1075 _note("Thread monitor number of peers - done");
1076 })); // lambda
1077
1080 public_zone.m_net_server.add_idle_handler(boost::bind(&t_payload_net_handler::on_idle, &m_payload_handler), 1000);
1081
1082 //here you can set worker threads count
1083 int thrds_count = 10;
1084 boost::thread::attributes attrs;
1085 attrs.set_stack_size(THREAD_STACK_SIZE);
1086 //go to loop
1087 MINFO("Run net_service loop( " << thrds_count << " threads)...");
1088 if(!public_zone.m_net_server.run_server(thrds_count, true, attrs))
1089 {
1090 LOG_ERROR("Failed to run net tcp server!");
1091 }
1092
1093 MINFO("net_service loop stopped.");
1094 return true;
1095 }
1096 //-----------------------------------------------------------------------------------
1097 template<class t_payload_net_handler>
1099 {
1100 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
1101 if (public_zone == m_network_zones.end())
1102 return 0;
1103 return public_zone->second.m_net_server.get_config_object().get_connections_count();
1104 }
1105 //-----------------------------------------------------------------------------------
1106 template<class t_payload_net_handler>
1108 {
1109 kill();
1110
1111 if (!m_offline)
1112 {
1113 for(auto& zone : m_network_zones)
1114 zone.second.m_net_server.deinit_server();
1115 // remove UPnP port mapping
1116 if(m_igd == igd)
1118 }
1119 return store_config();
1120 }
1121 //-----------------------------------------------------------------------------------
1122 template<class t_payload_net_handler>
1124 {
1125 TRY_ENTRY();
1126
1128 {
1129 MWARNING("Failed to create data directory \"" << m_config_folder);
1130 return false;
1131 }
1132
1133 peerlist_types active{};
1134 for (auto& zone : m_network_zones)
1135 zone.second.m_peerlist.get_peerlist(active);
1136
1137 const std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME;
1138 if (!m_peerlist_storage.store(state_file_path, active))
1139 {
1140 MWARNING("Failed to save config to file " << state_file_path);
1141 return false;
1142 }
1143 CATCH_ENTRY_L0("node_server::store", false);
1144 return true;
1145 }
1146 //-----------------------------------------------------------------------------------
1147 template<class t_payload_net_handler>
1149 {
1150 MDEBUG("[node] sending stop signal");
1151 for (auto& zone : m_network_zones)
1152 zone.second.m_net_server.send_stop_signal();
1153 MDEBUG("[node] Stop signal sent");
1154
1155 for (auto& zone : m_network_zones)
1156 {
1157 std::list<boost::uuids::uuid> connection_ids;
1158 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) {
1159 connection_ids.push_back(cntxt.m_connection_id);
1160 return true;
1161 });
1162 for (const auto &connection_id: connection_ids)
1163 zone.second.m_net_server.get_config_object().close(connection_id);
1164 }
1165 m_payload_handler.stop();
1166 return true;
1167 }
1168 //-----------------------------------------------------------------------------------
1169 template<class t_payload_net_handler>
1171 {
1172 network_zone& zone = m_network_zones.at(context_.m_remote_address.get_zone());
1173
1174 typename COMMAND_HANDSHAKE::request arg;
1175 typename COMMAND_HANDSHAKE::response rsp;
1176 get_local_node_data(arg.node_data, zone);
1177 m_payload_handler.get_payload_sync_data(arg.payload_data);
1178
1180 std::atomic<bool> hsh_result(false);
1181 bool timeout = false;
1182
1183 bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_, COMMAND_HANDSHAKE::ID, arg, zone.m_net_server.get_config_object(),
1184 [this, &pi, &ev, &hsh_result, &just_take_peerlist, &context_, &timeout](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
1185 {
1186 epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ev.raise();});
1187
1188 if(code < 0)
1189 {
1190 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE invoke failed. (" << code << ", " << epee::levin::get_err_descr(code) << ")");
1192 timeout = true;
1193 return;
1194 }
1195
1196 if(rsp.node_data.network_id != m_network_id)
1197 {
1198 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE Failed, wrong network! (" << rsp.node_data.network_id << "), closing connection.");
1199 return;
1200 }
1201
1202 if(!handle_remote_peerlist(rsp.local_peerlist_new, context))
1203 {
1204 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE: failed to handle_remote_peerlist(...), closing connection.");
1205 add_host_fail(context.m_remote_address);
1206 return;
1207 }
1208 hsh_result = true;
1209 if(!just_take_peerlist)
1210 {
1211 if(!m_payload_handler.process_payload_sync_data(rsp.payload_data, context, true))
1212 {
1213 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE invoked, but process_payload_sync_data returned false, dropping connection.");
1214 hsh_result = false;
1215 return;
1216 }
1217
1218 pi = context.peer_id = rsp.node_data.peer_id;
1219 context.m_rpc_port = rsp.node_data.rpc_port;
1220 context.m_rpc_credits_per_hash = rsp.node_data.rpc_credits_per_hash;
1221 context.support_flags = rsp.node_data.support_flags;
1222 const auto azone = context.m_remote_address.get_zone();
1223 network_zone& zone = m_network_zones.at(azone);
1224 zone.m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address, context.m_pruning_seed, context.m_rpc_port, context.m_rpc_credits_per_hash);
1225
1226 // move
1227 if(azone == epee::net_utils::zone::public_ && rsp.node_data.peer_id == zone.m_config.m_peer_id)
1228 {
1229 LOG_DEBUG_CC(context, "Connection to self detected, dropping connection");
1230 hsh_result = false;
1231 return;
1232 }
1233 LOG_INFO_CC(context, "New connection handshaked, pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed));
1234 LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE INVOKED OK");
1235 }else
1236 {
1237 LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
1238 }
1239 context_ = context;
1241
1242 if(r)
1243 {
1244 ev.wait();
1245 }
1246
1247 if(!hsh_result)
1248 {
1249 LOG_WARNING_CC(context_, "COMMAND_HANDSHAKE Failed");
1250 if (!timeout)
1251 zone.m_net_server.get_config_object().close(context_.m_connection_id);
1252 }
1253 else if (!just_take_peerlist)
1254 {
1255 if (context_.support_flags == 0)
1256 try_get_support_flags(context_, [](p2p_connection_context& flags_context, const uint32_t& support_flags)
1257 {
1258 flags_context.support_flags = support_flags;
1259 });
1260 }
1261
1262 return hsh_result;
1263 }
1264 //-----------------------------------------------------------------------------------
1265 template<class t_payload_net_handler>
1267 {
1268 typename COMMAND_TIMED_SYNC::request arg = AUTO_VAL_INIT(arg);
1269 m_payload_handler.get_payload_sync_data(arg.payload_data);
1270
1272 bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_TIMED_SYNC::response>(context_, COMMAND_TIMED_SYNC::ID, arg, zone.m_net_server.get_config_object(),
1273 [this](int code, const typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context)
1274 {
1275 context.m_in_timedsync = false;
1276 if(code < 0)
1277 {
1278 LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC invoke failed. (" << code << ", " << epee::levin::get_err_descr(code) << ")");
1279 return;
1280 }
1281
1282 if(!handle_remote_peerlist(rsp.local_peerlist_new, context))
1283 {
1284 LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
1285 m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id );
1286 add_host_fail(context.m_remote_address);
1287 }
1288 if(!context.m_is_income)
1289 m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address, context.m_pruning_seed, context.m_rpc_port, context.m_rpc_credits_per_hash);
1290 if (!m_payload_handler.process_payload_sync_data(rsp.payload_data, context, false))
1291 {
1292 m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id );
1293 }
1294 });
1295
1296 if(!r)
1297 {
1298 LOG_WARNING_CC(context_, "COMMAND_TIMED_SYNC Failed");
1299 return false;
1300 }
1301 return true;
1302 }
1303 //-----------------------------------------------------------------------------------
1304 template<class t_payload_net_handler>
1306 {
1307 //divide by zero workaround
1308 if(!max_index)
1309 return 0;
1310
1311 size_t x = crypto::rand<size_t>()%(16*max_index+1);
1312 size_t res = (x*x*x)/(max_index*max_index*16*16*16); //parabola \/
1313 MDEBUG("Random connection index=" << res << "(x="<< x << ", max_index=" << max_index << ")");
1314 return res;
1315 }
1316 //-----------------------------------------------------------------------------------
1317 template<class t_payload_net_handler>
1319 {
1320 const auto zone = peer.adr.get_zone();
1321 const auto server = m_network_zones.find(zone);
1322 if (server == m_network_zones.end())
1323 return false;
1324
1325 const bool is_public = (zone == epee::net_utils::zone::public_);
1326 if(is_public && server->second.m_config.m_peer_id == peer.id)
1327 return true;//dont make connections to ourself
1328
1329 bool used = false;
1330 server->second.m_net_server.get_config_object().foreach_connection([&, is_public](const p2p_connection_context& cntxt)
1331 {
1332 if((is_public && cntxt.peer_id == peer.id && peer.adr.is_same_host(cntxt.m_remote_address)) || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
1333 {
1334 used = true;
1335 return false;//stop enumerating
1336 }
1337 return true;
1338 });
1339 return used;
1340 }
1341 //-----------------------------------------------------------------------------------
1342 template<class t_payload_net_handler>
1344 {
1345 const auto zone = peer.adr.get_zone();
1346 const auto server = m_network_zones.find(zone);
1347 if (server == m_network_zones.end())
1348 return false;
1349
1350 const bool is_public = (zone == epee::net_utils::zone::public_);
1351 if(is_public && server->second.m_config.m_peer_id == peer.id)
1352 return true;//dont make connections to ourself
1353
1354 bool used = false;
1355 server->second.m_net_server.get_config_object().foreach_connection([&, is_public](const p2p_connection_context& cntxt)
1356 {
1357 if((is_public && cntxt.peer_id == peer.id && peer.adr.is_same_host(cntxt.m_remote_address)) || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
1358 {
1359 used = true;
1360 return false;//stop enumerating
1361 }
1362 return true;
1363 });
1364 return used;
1365 }
1366 //-----------------------------------------------------------------------------------
1367 template<class t_payload_net_handler>
1369 {
1370 const auto zone = m_network_zones.find(peer.get_zone());
1371 if (zone == m_network_zones.end())
1372 return false;
1373
1374 bool connected = false;
1375 zone->second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
1376 {
1377 if(!cntxt.m_is_income && peer == cntxt.m_remote_address)
1378 {
1379 connected = true;
1380 return false;//stop enumerating
1381 }
1382 return true;
1383 });
1384
1385 return connected;
1386 }
1387
1388#define LOG_PRINT_CC_PRIORITY_NODE(priority, con, msg) \
1389 do { \
1390 if (priority) {\
1391 LOG_INFO_CC(con, "[priority]" << msg); \
1392 } else {\
1393 LOG_INFO_CC(con, msg); \
1394 } \
1395 } while(0)
1396
1397 template<class t_payload_net_handler>
1399 {
1400 network_zone& zone = m_network_zones.at(na.get_zone());
1401 if (zone.m_connect == nullptr) // outgoing connections in zone not possible
1402 return false;
1403
1404 if (zone.m_our_address == na)
1405 return false;
1406
1407 if (zone.m_current_number_of_out_peers == zone.m_config.m_net_config.max_out_connection_count) // out peers limit
1408 {
1409 return false;
1410 }
1411 else if (zone.m_current_number_of_out_peers > zone.m_config.m_net_config.max_out_connection_count)
1412 {
1413 zone.m_net_server.get_config_object().del_out_connections(1);
1414 --(zone.m_current_number_of_out_peers); // atomic variable, update time = 1s
1415 return false;
1416 }
1417
1418
1419 MDEBUG("Connecting to " << na.str() << " (peer_type=" << peer_type << ", last_seen: "
1420 << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
1421 << ")...");
1422
1423 auto con = zone.m_connect(zone, na, m_ssl_support);
1424 if(!con)
1425 {
1426 bool is_priority = is_priority_node(na);
1427 LOG_PRINT_CC_PRIORITY_NODE(is_priority, bool(con), "Connect failed to " << na.str()
1428 /*<< ", try " << try_count*/);
1430 return false;
1431 }
1432
1433 con->m_anchor = peer_type == anchor;
1434 peerid_type pi = AUTO_VAL_INIT(pi);
1435 bool res = do_handshake_with_peer(pi, *con, just_take_peerlist);
1436
1437 if(!res)
1438 {
1439 bool is_priority = is_priority_node(na);
1440 LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer "
1441 << na.str()
1442 /*<< ", try " << try_count*/);
1444 return false;
1445 }
1446
1447 if(just_take_peerlist)
1448 {
1449 zone.m_net_server.get_config_object().close(con->m_connection_id);
1450 LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
1451 return true;
1452 }
1453
1454 peerlist_entry pe_local = AUTO_VAL_INIT(pe_local);
1455 pe_local.adr = na;
1456 pe_local.id = pi;
1457 time_t last_seen;
1458 time(&last_seen);
1459 pe_local.last_seen = static_cast<int64_t>(last_seen);
1460 pe_local.pruning_seed = con->m_pruning_seed;
1461 pe_local.rpc_port = con->m_rpc_port;
1462 pe_local.rpc_credits_per_hash = con->m_rpc_credits_per_hash;
1463 zone.m_peerlist.append_with_peer_white(pe_local);
1464 //update last seen and push it to peerlist manager
1465
1467 ape.adr = na;
1468 ape.id = pi;
1469 ape.first_seen = first_seen_stamp ? first_seen_stamp : time(nullptr);
1470
1471 zone.m_peerlist.append_with_peer_anchor(ape);
1472 zone.m_notifier.on_handshake_complete(con->m_connection_id, con->m_is_income);
1473 zone.m_notifier.new_out_connection();
1474
1475 LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK.");
1476 return true;
1477 }
1478
1479 template<class t_payload_net_handler>
1481 {
1482 network_zone& zone = m_network_zones.at(na.get_zone());
1483 if (zone.m_connect == nullptr)
1484 return false;
1485
1486 LOG_PRINT_L1("Connecting to " << na.str() << "(last_seen: "
1487 << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
1488 << ")...");
1489
1490 auto con = zone.m_connect(zone, na, m_ssl_support);
1491 if (!con) {
1492 bool is_priority = is_priority_node(na);
1493
1494 LOG_PRINT_CC_PRIORITY_NODE(is_priority, p2p_connection_context{}, "Connect failed to " << na.str());
1496
1497 return false;
1498 }
1499
1500 con->m_anchor = false;
1501 peerid_type pi = AUTO_VAL_INIT(pi);
1502 const bool res = do_handshake_with_peer(pi, *con, true);
1503 if (!res) {
1504 bool is_priority = is_priority_node(na);
1505
1506 LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer " << na.str());
1508 return false;
1509 }
1510
1511 zone.m_net_server.get_config_object().close(con->m_connection_id);
1512
1513 LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED.");
1514
1515 return true;
1516 }
1517
1518#undef LOG_PRINT_CC_PRIORITY_NODE
1519
1520 //-----------------------------------------------------------------------------------
1521 template<class t_payload_net_handler>
1527 //-----------------------------------------------------------------------------------
1528 template<class t_payload_net_handler>
1530 {
1532 auto it = m_conn_fails_cache.find(addr.host_str());
1533 if(it == m_conn_fails_cache.end())
1534 return false;
1535
1536 if(time(NULL) - it->second > P2P_FAILED_ADDR_FORGET_SECONDS)
1537 return false;
1538 else
1539 return true;
1540 }
1541 //-----------------------------------------------------------------------------------
1542 template<class t_payload_net_handler>
1543 bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist)
1544 {
1545 for (const auto& pe: anchor_peerlist) {
1546 _note("Considering connecting (out) to anchor peer: " << peerid_to_string(pe.id) << " " << pe.adr.str());
1547
1548 if(is_peer_used(pe)) {
1549 _note("Peer is used");
1550 continue;
1551 }
1552
1553 if(!is_remote_host_allowed(pe.adr)) {
1554 continue;
1555 }
1556
1558 continue;
1559 }
1560
1561 MDEBUG("Selected peer: " << peerid_to_string(pe.id) << " " << pe.adr.str()
1562 << "[peer_type=" << anchor
1563 << "] first_seen: " << epee::misc_utils::get_time_interval_string(time(NULL) - pe.first_seen));
1564
1565 if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, 0, anchor, pe.first_seen)) {
1566 _note("Handshake failed");
1567 continue;
1568 }
1569
1570 return true;
1571 }
1572
1573 return false;
1574 }
1575 //-----------------------------------------------------------------------------------
1576 // Find a single candidate from the given peer list in the given zone and connect to it if possible
1577 template<class t_payload_net_handler>
1579 {
1580
1581 // Local helper method to get the host string, i.e. the pure IP address without port
1582 const auto get_host_string = [](const epee::net_utils::network_address &address) {
1584 {
1585 const boost::asio::ip::address_v6 actual_ip = address.as<const epee::net_utils::ipv6_network_address>().ip();
1586 if (actual_ip.is_v4_mapped())
1587 {
1588 boost::asio::ip::address_v4 v4ip = make_address_v4_from_v6(actual_ip);
1589 uint32_t actual_ipv4;
1590 memcpy(&actual_ipv4, v4ip.to_bytes().data(), sizeof(actual_ipv4));
1591 return epee::net_utils::ipv4_network_address(actual_ipv4, 0).host_str();
1592 }
1593 }
1594 return address.host_str();
1595 };
1596
1597 // Get the current list of known peers of the desired kind, ordered by 'last_seen'.
1598 // Deduplicate ports right away, i.e. if we know several peers on the same host address but
1599 // with different ports, take only one of them, to avoid giving such peers undue weight
1600 // and make it impossible to game peer selection by advertising on a large number of ports.
1601 // Making this list also insulates us from any changes that may happen to the original list
1602 // while we are working here, and allows an easy retry in the inner try loop.
1603 std::vector<peerlist_entry> peers;
1604 std::unordered_set<std::string> hosts;
1605 size_t total_peers_size = 0;
1606 zone.m_peerlist.foreach(use_white_list, [&peers, &hosts, &total_peers_size, &get_host_string](const peerlist_entry &peer)
1607 {
1608 ++total_peers_size;
1609 const std::string host_string = get_host_string(peer.adr);
1610 if (hosts.insert(host_string).second)
1611 {
1612 peers.push_back(peer);
1613 }
1614 // else ignore this additional peer on the same IP number
1615
1616 return true;
1617 });
1618
1619 const size_t peers_size = peers.size();
1620 MDEBUG("Looking at " << peers_size << " port-deduplicated peers out of " << total_peers_size
1621 << ", i.e. dropping " << (total_peers_size - peers_size));
1622
1623 std::set<uint64_t> tried_peers; // all peers ever tried
1624
1625 // Outer try loop, with up to 3 attempts to actually connect to a suitable randomly choosen candidate
1626 size_t outer_loop_count = 0;
1627 while ((outer_loop_count < 3) && !zone.m_net_server.is_stop_signal_sent())
1628 {
1629 ++outer_loop_count;
1630
1631 const uint32_t next_needed_pruning_stripe = m_payload_handler.get_next_needed_pruning_stripe().second;
1632
1633 // Build a list of all distinct /24 subnets we are connected to now right now; to catch
1634 // any connection changes, re-build the list for every outer try loop pass
1635 std::set<uint32_t> connected_subnets;
1636 const uint32_t subnet_mask = ntohl(0xffffff00);
1637 const bool is_public_zone = &zone == &m_network_zones.at(epee::net_utils::zone::public_);
1638 if (is_public_zone)
1639 {
1640 zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
1641 {
1642 if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
1643 {
1644 const epee::net_utils::network_address na = cntxt.m_remote_address;
1645 const uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip();
1646 connected_subnets.insert(actual_ip & subnet_mask);
1647 }
1648 else if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id())
1649 {
1650 const epee::net_utils::network_address na = cntxt.m_remote_address;
1651 const boost::asio::ip::address_v6 &actual_ip = na.as<const epee::net_utils::ipv6_network_address>().ip();
1652 if (actual_ip.is_v4_mapped())
1653 {
1654 boost::asio::ip::address_v4 v4ip = make_address_v4_from_v6(actual_ip);
1655 uint32_t actual_ipv4;
1656 memcpy(&actual_ipv4, v4ip.to_bytes().data(), sizeof(actual_ipv4));
1657 connected_subnets.insert(actual_ipv4 & subnet_mask);
1658 }
1659 }
1660 return true;
1661 });
1662 }
1663
1664 std::vector<peerlist_entry> subnet_peers;
1665 std::vector<peerlist_entry> filtered;
1666
1667 // Inner try loop: Find candidates first with subnet deduplication, if none found again without.
1668 // Finding none happens if all candidates are from subnets we are already connected to and/or
1669 // they don't offer the needed stripe when pruning. Only actually loop and deduplicate if we are
1670 // in the public zone because private zones don't have subnets.
1671 for (int step = 0; step < 2; ++step)
1672 {
1673 if ((step == 1) && !is_public_zone)
1674 break;
1675
1676 const bool try_subnet_dedup = step == 0 && is_public_zone;
1677 const std::vector<peerlist_entry> &candidate_peers = try_subnet_dedup ? subnet_peers : peers;
1678 if (try_subnet_dedup)
1679 {
1680 // Deduplicate subnets using 3 steps
1681
1682 // Step 1: Prepare to access the peers in a random order
1683 std::vector<size_t> shuffled_indexes(peers.size());
1684 std::iota(shuffled_indexes.begin(), shuffled_indexes.end(), 0);
1685 std::shuffle(shuffled_indexes.begin(), shuffled_indexes.end(), crypto::random_device{});
1686
1687 // Step 2: Deduplicate by only taking 1 candidate from each /24 subnet that occurs, the FIRST
1688 // candidate seen from each subnet within the now random order
1689 std::set<uint32_t> subnets = connected_subnets;
1690 for (size_t index : shuffled_indexes)
1691 {
1692 const peerlist_entry &peer = peers.at(index);
1693 bool take = true;
1695 {
1696 const epee::net_utils::network_address na = peer.adr;
1697 const uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip();
1698 const uint32_t subnet = actual_ip & subnet_mask;
1699 take = subnets.find(subnet) == subnets.end();
1700 if (take)
1701 // This subnet is now "occupied", don't take any more candidates from this one
1702 subnets.insert(subnet);
1703 }
1705 {
1706 const epee::net_utils::network_address na = peer.adr;
1707 const boost::asio::ip::address_v6 &actual_ip = na.as<const epee::net_utils::ipv6_network_address>().ip();
1708 if (actual_ip.is_v4_mapped())
1709 {
1710 boost::asio::ip::address_v4 v4ip = make_address_v4_from_v6(actual_ip);
1711 uint32_t actual_ipv4;
1712 memcpy(&actual_ipv4, v4ip.to_bytes().data(), sizeof(actual_ipv4));
1713 uint32_t subnet = actual_ipv4 & subnet_mask;
1714 take = subnets.find(subnet) == subnets.end();
1715 if (take)
1716 subnets.insert(subnet);
1717 }
1718 // else 'take' stays true, we will take an IPv6 address that is not V4 mapped
1719 }
1720 if (take)
1721 subnet_peers.push_back(peer);
1722 }
1723
1724 // Step 3: Put back into order according to 'last_seen', i.e. most recently seen first
1725 std::sort(subnet_peers.begin(), subnet_peers.end(), [](const peerlist_entry &a, const peerlist_entry &b)
1726 {
1727 return a.last_seen > b.last_seen;
1728 });
1729
1730 const size_t subnet_peers_size = subnet_peers.size();
1731 MDEBUG("Looking at " << subnet_peers_size << " subnet-deduplicated peers out of " << peers_size
1732 << ", i.e. dropping " << (peers_size - subnet_peers_size));
1733 } // deduplicate
1734 // else, for step 1 / second pass of inner try loop, take all peers from all subnets
1735
1736 // Take as many candidates as we need and care about stripes if pruning
1737 const size_t limit = use_white_list ? 20 : std::numeric_limits<size_t>::max();
1738 for (const peerlist_entry &peer : candidate_peers) {
1739 if (filtered.size() >= limit)
1740 break;
1741 if (tried_peers.count(peer.id))
1742 // Already tried, not a possible candidate
1743 continue;
1744
1745 if (next_needed_pruning_stripe == 0 || peer.pruning_seed == 0)
1746 filtered.push_back(peer);
1747 else if (next_needed_pruning_stripe == tools::get_pruning_stripe(peer.pruning_seed))
1748 filtered.insert(filtered.begin(), peer);
1749 // else wrong stripe, skip
1750 }
1751
1752 if (!filtered.empty())
1753 break;
1754 } // inner try loop
1755
1756 if (filtered.empty())
1757 {
1758 MINFO("No available peer in " << (use_white_list ? "white" : "gray") << " list filtered by " << next_needed_pruning_stripe);
1759 return false;
1760 }
1761
1762 size_t random_index;
1763 if (use_white_list)
1764 {
1765 // If using the white list, we first pick in the set of peers we've already been using earlier;
1766 // that "fixed probability" heavily favors the peers most recently seen in the candidate list
1767 random_index = get_random_index_with_fixed_probability(filtered.size() - 1);
1768
1770 if (next_needed_pruning_stripe > 0 && next_needed_pruning_stripe <= (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES) && !m_used_stripe_peers[next_needed_pruning_stripe-1].empty())
1771 {
1772 const epee::net_utils::network_address na = m_used_stripe_peers[next_needed_pruning_stripe-1].front();
1773 m_used_stripe_peers[next_needed_pruning_stripe-1].pop_front();
1774 for (size_t i = 0; i < filtered.size(); ++i)
1775 {
1776 const peerlist_entry &peer = filtered.at(i);
1777 if (peer.adr == na)
1778 {
1779 MDEBUG("Reusing stripe " << next_needed_pruning_stripe << " peer " << peer.adr.str());
1780 random_index = i;
1781 break;
1782 }
1783 }
1784 }
1785 }
1786 else
1787 random_index = crypto::rand_idx(filtered.size());
1788 CHECK_AND_ASSERT_MES(random_index < filtered.size(), false, "random_index < filtered.size() failed!!");
1789
1790 // We have our final candidate for this pass of the outer try loop
1791 const peerlist_entry &candidate = filtered.at(random_index);
1792
1793 if (tried_peers.count(candidate.id))
1794 // Already tried, don't try that one again
1795 continue;
1796 tried_peers.insert(candidate.id);
1797
1798 _note("Considering connecting (out) to " << (use_white_list ? "white" : "gray") << " list peer: " <<
1799 peerid_to_string(candidate.id) << " " << candidate.adr.str() << ", pruning seed " << epee::string_tools::to_string_hex(candidate.pruning_seed) <<
1800 " (stripe " << next_needed_pruning_stripe << " needed), in loop pass " << outer_loop_count);
1801
1802 if (zone.m_our_address == candidate.adr)
1803 // It's ourselves, obviously don't take that
1804 continue;
1805
1806 if (is_peer_used(candidate)) {
1807 _note("Peer is used");
1808 continue;
1809 }
1810
1811 if (!is_remote_host_allowed(candidate.adr)) {
1812 _note("Not allowed");
1813 continue;
1814 }
1815
1816 if (is_addr_recently_failed(candidate.adr)) {
1817 _note("Recently failed");
1818 continue;
1819 }
1820
1821 MDEBUG("Selected peer: " << peerid_to_string(candidate.id) << " " << candidate.adr.str()
1822 << ", pruning seed " << epee::string_tools::to_string_hex(candidate.pruning_seed) << " "
1823 << "[peer_list=" << (use_white_list ? white : gray)
1824 << "] last_seen: " << (candidate.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - candidate.last_seen) : "never"));
1825
1826 const time_t begin_connect = time(NULL);
1827 if (!try_to_connect_and_handshake_with_new_peer(candidate.adr, false, candidate.last_seen, use_white_list ? white : gray)) {
1828 time_t fail_connect = time(NULL);
1829 _note("Handshake failed after " << epee::misc_utils::get_time_interval_string(fail_connect - begin_connect));
1830 continue;
1831 }
1832
1833 return true;
1834 } // outer try loop
1835
1836 return false;
1837 }
1838 //-----------------------------------------------------------------------------------
1839 template<class t_payload_net_handler>
1841 {
1843 boost::upgrade_lock<boost::shared_mutex> seed_nodes_upgrade_lock(server.m_seed_nodes_lock);
1844
1845 if (!server.m_seed_nodes_initialized)
1846 {
1847 const std::uint16_t default_port = cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT;
1848 boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
1849 server.m_seed_nodes_initialized = true;
1850 for (const auto& full_addr : get_seed_nodes(zone))
1851 {
1852 // seeds should have hostname converted to IP already
1853 MDEBUG("Seed node: " << full_addr);
1854 server.m_seed_nodes.push_back(MONERO_UNWRAP(net::get_network_address(full_addr, default_port)));
1855 }
1856 MDEBUG("Number of seed nodes: " << server.m_seed_nodes.size());
1857 }
1858
1859 if (server.m_seed_nodes.empty() || m_offline || !m_exclusive_peers.empty())
1860 return true;
1861
1862 size_t try_count = 0;
1863 bool is_connected_to_at_least_one_seed_node = false;
1864 size_t current_index = crypto::rand_idx(server.m_seed_nodes.size());
1865 while(true)
1866 {
1867 if(server.m_net_server.is_stop_signal_sent())
1868 return false;
1869
1870 peerlist_entry pe_seed{};
1871 pe_seed.adr = server.m_seed_nodes[current_index];
1872 if (is_peer_used(pe_seed))
1873 is_connected_to_at_least_one_seed_node = true;
1874 else if (try_to_connect_and_handshake_with_new_peer(server.m_seed_nodes[current_index], true))
1875 break;
1876 if(++try_count > server.m_seed_nodes.size())
1877 {
1878 // only IP zone has fallback (to direct IP) seeds
1879 if (zone == epee::net_utils::zone::public_ && !m_fallback_seed_nodes_added.test_and_set())
1880 {
1881 MWARNING("Failed to connect to any of seed peers, trying fallback seeds");
1882 current_index = server.m_seed_nodes.size() - 1;
1883 {
1884 boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
1885
1886 for (const auto &peer: get_ip_seed_nodes())
1887 {
1888 MDEBUG("Fallback seed node: " << peer);
1889 append_net_address(server.m_seed_nodes, peer, cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT);
1890 }
1891 }
1892 if (current_index == server.m_seed_nodes.size() - 1)
1893 {
1894 MWARNING("No fallback seeds, continuing without seeds");
1895 break;
1896 }
1897 // continue for another few cycles
1898 }
1899 else
1900 {
1901 if (!is_connected_to_at_least_one_seed_node)
1902 MWARNING("Failed to connect to any of seed peers, continuing without seeds");
1903 break;
1904 }
1905 }
1906 if(++current_index >= server.m_seed_nodes.size())
1907 current_index = 0;
1908 }
1909 return true;
1910 }
1911 //-----------------------------------------------------------------------------------
1912 template<class t_payload_net_handler>
1914 {
1915 using zone_type = epee::net_utils::zone;
1916
1917 if (m_offline) return true;
1918 if (!connect_to_peerlist(m_exclusive_peers)) return false;
1919
1920 if (!m_exclusive_peers.empty()) return true;
1921
1922 bool one_succeeded = false;
1923 for(auto& zone : m_network_zones)
1924 {
1925 size_t start_conn_count = get_outgoing_connections_count(zone.second);
1926 if(!zone.second.m_peerlist.get_white_peers_count() && !connect_to_seed(zone.first))
1927 {
1928 continue;
1929 }
1930
1931 if (zone.first == zone_type::public_ && !connect_to_peerlist(m_priority_peers)) continue;
1932
1933 size_t base_expected_white_connections = (zone.second.m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
1934
1935 // carefully avoid `continue` in nested loop
1936
1937 size_t conn_count = get_outgoing_connections_count(zone.second);
1938 while(conn_count < zone.second.m_config.m_net_config.max_out_connection_count)
1939 {
1940 const size_t expected_white_connections = m_payload_handler.get_next_needed_pruning_stripe().second ? zone.second.m_config.m_net_config.max_out_connection_count : base_expected_white_connections;
1941 if(conn_count < expected_white_connections)
1942 {
1943 //start from anchor list
1946 //then do white list
1947 while (get_outgoing_connections_count(zone.second) < expected_white_connections
1948 && make_expected_connections_count(zone.second, white, expected_white_connections));
1949 //then do grey list
1950 while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count
1951 && make_expected_connections_count(zone.second, gray, zone.second.m_config.m_net_config.max_out_connection_count));
1952 }else
1953 {
1954 //start from grey list
1955 while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count
1956 && make_expected_connections_count(zone.second, gray, zone.second.m_config.m_net_config.max_out_connection_count));
1957 //and then do white list
1958 while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count
1959 && make_expected_connections_count(zone.second, white, zone.second.m_config.m_net_config.max_out_connection_count));
1960 }
1961 if(zone.second.m_net_server.is_stop_signal_sent())
1962 return false;
1963 size_t new_conn_count = get_outgoing_connections_count(zone.second);
1964 if (new_conn_count <= conn_count)
1965 {
1966 // we did not make any connection, sleep a bit to avoid a busy loop in case we don't have
1967 // any peers to try, then break so we will try seeds to get more peers
1968 boost::this_thread::sleep_for(boost::chrono::seconds(1));
1969 break;
1970 }
1971 conn_count = new_conn_count;
1972 }
1973
1974 if (start_conn_count == get_outgoing_connections_count(zone.second) && start_conn_count < zone.second.m_config.m_net_config.max_out_connection_count)
1975 {
1976 MINFO("Failed to connect to any, trying seeds");
1977 if (!connect_to_seed(zone.first))
1978 continue;
1979 }
1980 one_succeeded = true;
1981 }
1982
1983 return one_succeeded;
1984 }
1985 //-----------------------------------------------------------------------------------
1986 template<class t_payload_net_handler>
1988 {
1989 if (m_offline)
1990 return false;
1991
1992 std::vector<anchor_peerlist_entry> apl;
1993
1994 if (peer_type == anchor) {
1995 zone.m_peerlist.get_and_empty_anchor_peerlist(apl);
1996 }
1997
1998 size_t conn_count = get_outgoing_connections_count(zone);
1999 //add new connections from white peers
2000 if(conn_count < expected_connections)
2001 {
2002 if(zone.m_net_server.is_stop_signal_sent())
2003 return false;
2004
2005 MDEBUG("Making expected connection, type " << peer_type << ", " << conn_count << "/" << expected_connections << " connections");
2006
2007 if (peer_type == anchor && !make_new_connection_from_anchor_peerlist(apl)) {
2008 return false;
2009 }
2010
2011 if (peer_type == white && !make_new_connection_from_peerlist(zone, true)) {
2012 return false;
2013 }
2014
2015 if (peer_type == gray && !make_new_connection_from_peerlist(zone, false)) {
2016 return false;
2017 }
2018 }
2019 return true;
2020 }
2021 //-----------------------------------------------------------------------------------
2022 template<class t_payload_net_handler>
2024 {
2025 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2026 if (public_zone == m_network_zones.end())
2027 return 0;
2028 return get_outgoing_connections_count(public_zone->second);
2029 }
2030 //-----------------------------------------------------------------------------------
2031 template<class t_payload_net_handler>
2033 {
2034 size_t count = 0;
2035 zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
2036 {
2037 if(cntxt.m_is_income)
2038 ++count;
2039 return true;
2040 });
2041 return count;
2042 }
2043 //-----------------------------------------------------------------------------------
2044 template<class t_payload_net_handler>
2046 {
2047 size_t count = 0;
2048 zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
2049 {
2050 if(!cntxt.m_is_income && !cntxt.is_ping)
2051 ++count;
2052 return true;
2053 });
2054
2055 // Refresh the counter in the zone. The thread that the 'run' method sets up for the
2056 // job to update the counters runs only once every second. If we only rely on that,
2057 // 'try_to_connect_and_handshake_with_new_peer' called in 'make_new_connection_from_peerlist'
2058 // will often fail right away because it thinks there are still enough connections, with
2059 // perfectly good new peer candidates totally wasted, and a bad success rate choosing peers
2060 zone.m_current_number_of_out_peers = count;
2061
2062 return count;
2063 }
2064 //-----------------------------------------------------------------------------------
2065 template<class t_payload_net_handler>
2067 {
2068 size_t count = 0;
2069 for(auto& zone : m_network_zones)
2070 count += get_outgoing_connections_count(zone.second);
2071 return count;
2072 }
2073 //-----------------------------------------------------------------------------------
2074 template<class t_payload_net_handler>
2076 {
2077 size_t count = 0;
2078 for (auto& zone : m_network_zones)
2079 {
2080 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
2081 {
2082 if(cntxt.m_is_income)
2083 ++count;
2084 return true;
2085 });
2086 }
2087 return count;
2088 }
2089 //-----------------------------------------------------------------------------------
2090 template<class t_payload_net_handler>
2092 {
2093 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2094 if (public_zone == m_network_zones.end())
2095 return 0;
2096 return public_zone->second.m_peerlist.get_white_peers_count();
2097 }
2098 //-----------------------------------------------------------------------------------
2099 template<class t_payload_net_handler>
2101 {
2102 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2103 if (public_zone == m_network_zones.end())
2104 return 0;
2105 return public_zone->second.m_peerlist.get_gray_peers_count();
2106 }
2107 //-----------------------------------------------------------------------------------
2108 template<class t_payload_net_handler>
2109 void node_server<t_payload_net_handler>::get_public_peerlist(std::vector<peerlist_entry>& gray, std::vector<peerlist_entry>& white)
2110 {
2111 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2112 if (public_zone != m_network_zones.end())
2113 public_zone->second.m_peerlist.get_peerlist(gray, white);
2114 }
2115 //-----------------------------------------------------------------------------------
2116 template<class t_payload_net_handler>
2117 void node_server<t_payload_net_handler>::get_peerlist(std::vector<peerlist_entry>& gray, std::vector<peerlist_entry>& white)
2118 {
2119 for (auto &zone: m_network_zones)
2120 {
2121 zone.second.m_peerlist.get_peerlist(gray, white); // appends
2122 }
2123 }
2124 //-----------------------------------------------------------------------------------
2125 template<class t_payload_net_handler>
2136 //-----------------------------------------------------------------------------------
2137 template<class t_payload_net_handler>
2139 {
2141 return true;
2143 return true;
2144
2145 static const std::vector<std::string> dns_urls = {
2146 "blocklist.moneropulse.se"
2147 , "blocklist.moneropulse.org"
2148 , "blocklist.moneropulse.net"
2149 , "blocklist.moneropulse.co"
2150 , "blocklist.moneropulse.fr"
2151 , "blocklist.moneropulse.de"
2152 , "blocklist.moneropulse.ch"
2153 };
2154
2155 std::vector<std::string> records;
2156 if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
2157 return true;
2158
2159 unsigned good = 0, bad = 0;
2160 for (const auto& record : records)
2161 {
2162 std::vector<std::string> ips;
2163 boost::split(ips, record, boost::is_any_of(";"));
2164 for (const auto &ip: ips)
2165 {
2166 if (ip.empty())
2167 continue;
2168 auto subnet = net::get_ipv4_subnet_address(ip);
2169 if (subnet)
2170 {
2172 ++good;
2173 continue;
2174 }
2176 if (parsed_addr)
2177 {
2178 block_host(*parsed_addr, DNS_BLOCKLIST_LIFETIME, true);
2179 ++good;
2180 continue;
2181 }
2182 MWARNING("Invalid IP address or subnet from DNS blocklist: " << ip << " - " << parsed_addr.error());
2183 ++bad;
2184 }
2185 }
2186 if (good > 0)
2187 MINFO(good << " addresses added to the blocklist");
2188 return true;
2189 }
2190 //-----------------------------------------------------------------------------------
2191 template<class t_payload_net_handler>
2193 {
2194 if (m_offline)
2195 return true;
2196
2197 const auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2198 if (public_zone != m_network_zones.end() && get_incoming_connections_count(public_zone->second) == 0)
2199 {
2200 if (m_hide_my_port || public_zone->second.m_config.m_net_config.max_in_connection_count == 0)
2201 {
2202 MGINFO("Incoming connections disabled, enable them for full connectivity");
2203 }
2204 else
2205 {
2206 if (m_igd == delayed_igd)
2207 {
2208 MWARNING("No incoming connections, trying to setup IGD");
2210 m_igd = igd;
2211 }
2212 else
2213 {
2214 const el::Level level = el::Level::Warning;
2215 MCLOG_RED(level, "global", "No incoming connections - check firewalls/routers allow port " << get_this_peer_port());
2216 }
2217 }
2218 }
2219 return true;
2220 }
2221 //-----------------------------------------------------------------------------------
2222 template<class t_payload_net_handler>
2224 {
2225 MDEBUG("STARTED PEERLIST IDLE HANDSHAKE");
2226 typedef std::list<std::pair<epee::net_utils::connection_context_base, peerid_type> > local_connects_type;
2227 local_connects_type cncts;
2228 for(auto& zone : m_network_zones)
2229 {
2230 zone.second.m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntxt)
2231 {
2232 if(cntxt.peer_id && !cntxt.m_in_timedsync)
2233 {
2234 cntxt.m_in_timedsync = true;
2235 cncts.push_back(local_connects_type::value_type(cntxt, cntxt.peer_id));//do idle sync only with handshaked connections
2236 }
2237 return true;
2238 });
2239 }
2240
2241 std::for_each(cncts.begin(), cncts.end(), [&](const typename local_connects_type::value_type& vl){do_peer_timed_sync(vl.first, vl.second);});
2242
2243 MDEBUG("FINISHED PEERLIST IDLE HANDSHAKE");
2244 return true;
2245 }
2246 //-----------------------------------------------------------------------------------
2247 template<class t_payload_net_handler>
2248 bool node_server<t_payload_net_handler>::sanitize_peerlist(std::vector<peerlist_entry>& local_peerlist)
2249 {
2250 for (size_t i = 0; i < local_peerlist.size(); ++i)
2251 {
2252 bool ignore = false;
2253 peerlist_entry &be = local_peerlist[i];
2255 if (na.is_loopback() || na.is_local())
2256 {
2257 ignore = true;
2258 }
2260 {
2262 if (ipv4.ip() == 0)
2263 ignore = true;
2264 else if (ipv4.port() == be.rpc_port)
2265 ignore = true;
2266 }
2268 ignore = true;
2269 if (ignore)
2270 {
2271 MDEBUG("Ignoring " << be.adr.str());
2272 std::swap(local_peerlist[i], local_peerlist[local_peerlist.size() - 1]);
2273 local_peerlist.resize(local_peerlist.size() - 1);
2274 --i;
2275 continue;
2276 }
2277 local_peerlist[i].last_seen = 0;
2278 }
2279 return true;
2280 }
2281 //-----------------------------------------------------------------------------------
2282 template<class t_payload_net_handler>
2284 {
2285 if (peerlist.size() > P2P_MAX_PEERS_IN_HANDSHAKE)
2286 {
2287 MWARNING(context << "peer sent " << peerlist.size() << " peers, considered spamming");
2288 return false;
2289 }
2290 std::vector<peerlist_entry> peerlist_ = peerlist;
2291 if(!sanitize_peerlist(peerlist_))
2292 return false;
2293
2294 const epee::net_utils::zone zone = context.m_remote_address.get_zone();
2295 for(const auto& peer : peerlist_)
2296 {
2297 if(peer.adr.get_zone() != zone)
2298 {
2299 MWARNING(context << " sent peerlist from another zone, dropping");
2300 return false;
2301 }
2302 }
2303
2304 LOG_DEBUG_CC(context, "REMOTE PEERLIST: remote peerlist size=" << peerlist_.size());
2305 LOG_TRACE_CC(context, "REMOTE PEERLIST: " << ENDL << print_peerlist_to_string(peerlist_));
2307 return m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.merge_peerlist(peerlist_, [this](const peerlist_entry &pe) {
2309 });
2310 }
2311 //-----------------------------------------------------------------------------------
2312 template<class t_payload_net_handler>
2314 {
2315 node_data.peer_id = zone.m_config.m_peer_id;
2316 if(!m_hide_my_port && zone.m_can_pingback)
2318 else
2319 node_data.my_port = 0;
2320 node_data.rpc_port = zone.m_can_pingback ? m_rpc_port : 0;
2321 node_data.rpc_credits_per_hash = zone.m_can_pingback ? m_rpc_credits_per_hash : 0;
2322 node_data.network_id = m_network_id;
2323 node_data.support_flags = zone.m_config.m_support_flags;
2324 return true;
2325 }
2326 //-----------------------------------------------------------------------------------
2327 template<class t_payload_net_handler>
2329 {
2330 rsp.support_flags = m_network_zones.at(context.m_remote_address.get_zone()).m_config.m_support_flags;
2331 return 1;
2332 }
2333 //-----------------------------------------------------------------------------------
2334 template<class t_payload_net_handler>
2336 {
2337 m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().request_callback(context.m_connection_id);
2338 }
2339 //-----------------------------------------------------------------------------------
2340 template<class t_payload_net_handler>
2341 bool node_server<t_payload_net_handler>::relay_notify_to_list(int command, epee::levin::message_writer data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections)
2342 {
2343 epee::byte_slice message = data_buff.finalize_notify(command);
2344 std::sort(connections.begin(), connections.end());
2345 auto zone = m_network_zones.begin();
2346 for(const auto& c_id: connections)
2347 {
2348 for (;;)
2349 {
2350 if (zone == m_network_zones.end())
2351 {
2352 MWARNING("Unable to relay all messages, " << epee::net_utils::zone_to_string(c_id.first) << " not available");
2353 return false;
2354 }
2355 if (c_id.first <= zone->first)
2356 break;
2357
2358 ++zone;
2359 }
2360 if (zone->first == c_id.first)
2361 zone->second.m_net_server.get_config_object().send(message.clone(), c_id.second);
2362 }
2363 return true;
2364 }
2365 //-----------------------------------------------------------------------------------
2366 template<class t_payload_net_handler>
2367 epee::net_utils::zone node_server<t_payload_net_handler>::send_txs(std::vector<cryptonote::blobdata> txs, const epee::net_utils::zone origin, const boost::uuids::uuid& source, const cryptonote::relay_method tx_relay)
2368 {
2369 namespace enet = epee::net_utils;
2370
2371 const auto send = [&txs, &source, tx_relay] (std::pair<const enet::zone, network_zone>& network)
2372 {
2373 if (network.second.m_notifier.send_txs(std::move(txs), source, tx_relay))
2374 return network.first;
2375 return enet::zone::invalid;
2376 };
2377
2378 if (m_network_zones.empty())
2379 return enet::zone::invalid;
2380
2381 if (origin != enet::zone::invalid)
2382 return send(*m_network_zones.begin()); // send all txs received via p2p over public network
2383
2384 if (m_network_zones.size() <= 2)
2385 return send(*m_network_zones.rbegin()); // see static asserts below; sends over anonymity network iff enabled
2386
2387 /* These checks are to ensure that i2p is highest priority if multiple
2388 zones are selected. Make sure to update logic if the values cannot be
2389 in the same relative order. `m_network_zones` must be sorted map too. */
2390 static_assert(std::is_same<std::underlying_type<enet::zone>::type, std::uint8_t>{}, "expected uint8_t zone");
2391 static_assert(unsigned(enet::zone::invalid) == 0, "invalid expected to be 0");
2392 static_assert(unsigned(enet::zone::public_) == 1, "public_ expected to be 1");
2393 static_assert(unsigned(enet::zone::i2p) == 2, "i2p expected to be 2");
2394 static_assert(unsigned(enet::zone::tor) == 3, "tor expected to be 3");
2395
2396 // check for anonymity networks with noise and connections
2397 for (auto network = ++m_network_zones.begin(); network != m_network_zones.end(); ++network)
2398 {
2399 if (enet::zone::tor < network->first)
2400 break; // unknown network
2401
2402 const auto status = network->second.m_notifier.get_status();
2403 if (status.has_noise && status.connections_filled)
2404 return send(*network);
2405 }
2406
2407 // use the anonymity network with outbound support
2408 for (auto network = ++m_network_zones.begin(); network != m_network_zones.end(); ++network)
2409 {
2410 if (enet::zone::tor < network->first)
2411 break; // unknown network
2412
2413 const auto status = network->second.m_notifier.get_status();
2414 if (network->second.m_connect && status.has_outgoing)
2415 return send(*network);
2416 }
2417
2418 MWARNING("Unable to send " << txs.size() << " transaction(s): anonymity networks had no outgoing connections");
2419 return enet::zone::invalid;
2420 }
2421 //-----------------------------------------------------------------------------------
2422 template<class t_payload_net_handler>
2424 {
2425 m_payload_handler.on_callback(context);
2426 }
2427 //-----------------------------------------------------------------------------------
2428 template<class t_payload_net_handler>
2430 {
2431 if(is_filtered_command(context.m_remote_address, command))
2432 return false;
2433
2434 network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone());
2435 int res = zone.m_net_server.get_config_object().send(message.finalize_notify(command), context.m_connection_id);
2436 return res > 0;
2437 }
2438 //-----------------------------------------------------------------------------------
2439 template<class t_payload_net_handler>
2441 {
2442 m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id);
2443 return true;
2444 }
2445 //-----------------------------------------------------------------------------------
2446 template<class t_payload_net_handler> template<class t_callback>
2448 {
2449 if(!node_data.my_port)
2450 return false;
2451
2452 bool address_ok = (context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id() || context.m_remote_address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id());
2453 CHECK_AND_ASSERT_MES(address_ok, false,
2454 "Only IPv4 or IPv6 addresses are supported here");
2455
2456 const epee::net_utils::network_address na = context.m_remote_address;
2457 std::string ip;
2458 uint32_t ipv4_addr = 0;
2459 boost::asio::ip::address_v6 ipv6_addr;
2460 bool is_ipv4;
2462 {
2463 ipv4_addr = na.as<const epee::net_utils::ipv4_network_address>().ip();
2465 is_ipv4 = true;
2466 }
2467 else
2468 {
2469 ipv6_addr = na.as<const epee::net_utils::ipv6_network_address>().ip();
2470 ip = ipv6_addr.to_string();
2471 is_ipv4 = false;
2472 }
2473 network_zone& zone = m_network_zones.at(na.get_zone());
2474
2475 if(!zone.m_peerlist.is_host_allowed(context.m_remote_address))
2476 return false;
2477
2478 std::string port = epee::string_tools::num_to_string_fast(node_data.my_port);
2479
2481 if (is_ipv4)
2482 {
2484 }
2485 else
2486 {
2488 }
2489 peerid_type pr = node_data.peer_id;
2490 bool r = zone.m_net_server.connect_async(ip, port, zone.m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ address, pr, this](
2491 const typename net_server::t_connection_context& ping_context,
2492 const boost::system::error_code& ec)->bool
2493 {
2494 if(ec)
2495 {
2496 LOG_WARNING_CC(ping_context, "back ping connect failed to " << address.str());
2497 return false;
2498 }
2501 //vc2010 workaround
2502 /*std::string ip_ = ip;
2503 std::string port_=port;
2504 peerid_type pr_ = pr;
2505 auto cb_ = cb;*/
2506
2507 // GCC 5.1.0 gives error with second use of uint64_t (peerid_type) variable.
2508 peerid_type pr_ = pr;
2509
2510 network_zone& zone = m_network_zones.at(address.get_zone());
2511
2512 bool inv_call_res = epee::net_utils::async_invoke_remote_command2<COMMAND_PING::response>(ping_context, COMMAND_PING::ID, req, zone.m_net_server.get_config_object(),
2513 [=](int code, const COMMAND_PING::response& rsp, p2p_connection_context& context)
2514 {
2515 if(code <= 0)
2516 {
2517 LOG_WARNING_CC(ping_context, "Failed to invoke COMMAND_PING to " << address.str() << "(" << code << ", " << epee::levin::get_err_descr(code) << ")");
2518 return;
2519 }
2520
2521 network_zone& zone = m_network_zones.at(address.get_zone());
2522 if(rsp.status != PING_OK_RESPONSE_STATUS_TEXT || pr != rsp.peer_id)
2523 {
2524 LOG_WARNING_CC(ping_context, "back ping invoke wrong response \"" << rsp.status << "\" from" << address.str() << ", hsh_peer_id=" << pr_ << ", rsp.peer_id=" << peerid_to_string(rsp.peer_id));
2525 zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
2526 return;
2527 }
2528 zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
2529 cb();
2530 });
2531
2532 if(!inv_call_res)
2533 {
2534 LOG_WARNING_CC(ping_context, "back ping invoke failed to " << address.str());
2535 zone.m_net_server.get_config_object().close(ping_context.m_connection_id);
2536 return false;
2537 }
2538 return true;
2539 }, "0.0.0.0", m_ssl_support, p2p_connection_context{true /* is_ping */});
2540 if(!r)
2541 {
2542 LOG_WARNING_CC(context, "Failed to call connect_async, network error.");
2543 }
2544 return r;
2545 }
2546 //-----------------------------------------------------------------------------------
2547 template<class t_payload_net_handler>
2549 {
2550 if(context.m_remote_address.get_zone() != epee::net_utils::zone::public_)
2551 return false;
2552
2553 COMMAND_REQUEST_SUPPORT_FLAGS::request support_flags_request;
2555 (
2556 context,
2558 support_flags_request,
2559 m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object(),
2560 [=](int code, const typename COMMAND_REQUEST_SUPPORT_FLAGS::response& rsp, p2p_connection_context& context_)
2561 {
2562 if(code < 0)
2563 {
2564 LOG_WARNING_CC(context_, "COMMAND_REQUEST_SUPPORT_FLAGS invoke failed. (" << code << ", " << epee::levin::get_err_descr(code) << ")");
2565 return;
2566 }
2567
2568 f(context_, rsp.support_flags);
2569 },
2571 );
2572
2573 return r;
2574 }
2575 //-----------------------------------------------------------------------------------
2576 template<class t_payload_net_handler>
2578 {
2579 if(!m_payload_handler.process_payload_sync_data(arg.payload_data, context, false))
2580 {
2581 LOG_WARNING_CC(context, "Failed to process_payload_sync_data(), dropping connection");
2582 drop_connection(context);
2583 return 1;
2584 }
2585
2586 //fill response
2587 const epee::net_utils::zone zone_type = context.m_remote_address.get_zone();
2588 network_zone& zone = m_network_zones.at(zone_type);
2589
2590 //will add self to peerlist if in same zone as outgoing later in this function
2591 const bool outgoing_to_same_zone = !context.m_is_income && zone.m_our_address.get_zone() == zone_type;
2592 const uint32_t max_peerlist_size = P2P_DEFAULT_PEERS_IN_HANDSHAKE - (outgoing_to_same_zone ? 1 : 0);
2593
2594 std::vector<peerlist_entry> local_peerlist_new;
2595 zone.m_peerlist.get_peerlist_head(local_peerlist_new, true, max_peerlist_size);
2596
2597 /* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
2598 do not know the address of the connecting peer. This is relayed to them,
2599 iff the node has setup an inbound hidden service.
2600
2601 \note Insert into `local_peerlist_new` so that it is only sent once like
2602 the other peers. */
2603 if(outgoing_to_same_zone)
2604 {
2605 local_peerlist_new.insert(
2606 local_peerlist_new.begin() + crypto::rand_range(std::size_t(0), local_peerlist_new.size()),
2607 peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, 0}
2608 );
2609 }
2610
2611 //only include out peers we did not already send
2612 rsp.local_peerlist_new.reserve(local_peerlist_new.size());
2613 for (auto &pe: local_peerlist_new)
2614 {
2615 if (!context.sent_addresses.insert(pe.adr).second)
2616 continue;
2617 rsp.local_peerlist_new.push_back(std::move(pe));
2618 }
2619 m_payload_handler.get_payload_sync_data(rsp.payload_data);
2620
2621 LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC");
2622 return 1;
2623 }
2624 //-----------------------------------------------------------------------------------
2625 template<class t_payload_net_handler>
2627 {
2628 if(arg.node_data.network_id != m_network_id)
2629 {
2630
2631 LOG_INFO_CC(context, "WRONG NETWORK AGENT CONNECTED! id=" << arg.node_data.network_id);
2632 drop_connection(context);
2633 add_host_fail(context.m_remote_address);
2634 return 1;
2635 }
2636
2637 if(!context.m_is_income)
2638 {
2639 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came not from incoming connection");
2640 drop_connection(context);
2641 add_host_fail(context.m_remote_address);
2642 return 1;
2643 }
2644
2645 if(context.peer_id)
2646 {
2647 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but seems that connection already have associated peer_id (double COMMAND_HANDSHAKE?)");
2648 drop_connection(context);
2649 return 1;
2650 }
2651
2652 const auto azone = context.m_remote_address.get_zone();
2653 network_zone& zone = m_network_zones.at(azone);
2654
2655 // test only the remote end's zone, otherwise an attacker could connect to you on clearnet
2656 // and pass in a tor connection's peer id, and deduce the two are the same if you reject it
2657 if(azone == epee::net_utils::zone::public_ && arg.node_data.peer_id == zone.m_config.m_peer_id)
2658 {
2659 LOG_DEBUG_CC(context, "Connection to self detected, dropping connection");
2660 drop_connection(context);
2661 return 1;
2662 }
2663
2664 if(!m_payload_handler.process_payload_sync_data(arg.payload_data, context, true))
2665 {
2666 LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but process_payload_sync_data returned false, dropping connection.");
2667 drop_connection(context);
2668 return 1;
2669 }
2670
2671 zone.m_notifier.on_handshake_complete(context.m_connection_id, context.m_is_income);
2672
2673 //associate peer_id with this connection
2674 context.peer_id = arg.node_data.peer_id;
2675 context.m_in_timedsync = false;
2676 context.m_rpc_port = arg.node_data.rpc_port;
2677 context.m_rpc_credits_per_hash = arg.node_data.rpc_credits_per_hash;
2678 context.support_flags = arg.node_data.support_flags;
2679
2680 if(arg.node_data.my_port && zone.m_can_pingback)
2681 {
2682 peerid_type peer_id_l = arg.node_data.peer_id;
2683 uint32_t port_l = arg.node_data.my_port;
2684 //try ping to be sure that we can add this peer to peer_list
2685 try_ping(arg.node_data, context, [peer_id_l, port_l, context, this]()
2686 {
2687 CHECK_AND_ASSERT_MES((context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id() || context.m_remote_address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id()), void(),
2688 "Only IPv4 or IPv6 addresses are supported here");
2689 //called only(!) if success pinged, update local peerlist
2690 peerlist_entry pe;
2691 const epee::net_utils::network_address na = context.m_remote_address;
2692 if (context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
2693 {
2694 pe.adr = epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l);
2695 }
2696 else
2697 {
2698 pe.adr = epee::net_utils::ipv6_network_address(na.as<epee::net_utils::ipv6_network_address>().ip(), port_l);
2699 }
2700 time_t last_seen;
2701 time(&last_seen);
2702 pe.last_seen = static_cast<int64_t>(last_seen);
2703 pe.id = peer_id_l;
2704 pe.pruning_seed = context.m_pruning_seed;
2705 pe.rpc_port = context.m_rpc_port;
2706 pe.rpc_credits_per_hash = context.m_rpc_credits_per_hash;
2707 this->m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.append_with_peer_white(pe);
2708 LOG_DEBUG_CC(context, "PING SUCCESS " << context.m_remote_address.host_str() << ":" << port_l);
2709 });
2710 }
2711
2712 if (context.support_flags == 0)
2713 try_get_support_flags(context, [](p2p_connection_context& flags_context, const uint32_t& support_flags)
2714 {
2715 flags_context.support_flags = support_flags;
2716 });
2717
2718 //fill response
2719 zone.m_peerlist.get_peerlist_head(rsp.local_peerlist_new, true);
2720 for (const auto &e: rsp.local_peerlist_new)
2721 context.sent_addresses.insert(e.adr);
2722 get_local_node_data(rsp.node_data, zone);
2723 m_payload_handler.get_payload_sync_data(rsp.payload_data);
2724 LOG_DEBUG_CC(context, "COMMAND_HANDSHAKE");
2725 return 1;
2726 }
2727 //-----------------------------------------------------------------------------------
2728 template<class t_payload_net_handler>
2730 {
2731 LOG_DEBUG_CC(context, "COMMAND_PING");
2732 rsp.status = PING_OK_RESPONSE_STATUS_TEXT;
2733 rsp.peer_id = m_network_zones.at(context.m_remote_address.get_zone()).m_config.m_peer_id;
2734 return 1;
2735 }
2736 //-----------------------------------------------------------------------------------
2737 template<class t_payload_net_handler>
2739 {
2740 std::vector<peerlist_entry> pl_white;
2741 std::vector<peerlist_entry> pl_gray;
2742 for (auto& zone : m_network_zones)
2743 zone.second.m_peerlist.get_peerlist(pl_gray, pl_white);
2744 MINFO(ENDL << "Peerlist white:" << ENDL << print_peerlist_to_string(pl_white) << ENDL << "Peerlist gray:" << ENDL << print_peerlist_to_string(pl_gray) );
2745 return true;
2746 }
2747 //-----------------------------------------------------------------------------------
2748 template<class t_payload_net_handler>
2750 {
2751 MINFO("Connections: \r\n" << print_connections_container() );
2752 return true;
2753 }
2754 //-----------------------------------------------------------------------------------
2755 template<class t_payload_net_handler>
2757 {
2758
2759 std::stringstream ss;
2760 for (auto& zone : m_network_zones)
2761 {
2762 zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
2763 {
2764 ss << cntxt.m_remote_address.str()
2765 << " \t\tpeer_id " << peerid_to_string(cntxt.peer_id)
2766 << " \t\tconn_id " << cntxt.m_connection_id << (cntxt.m_is_income ? " INC":" OUT")
2767 << std::endl;
2768 return true;
2769 });
2770 }
2771 std::string s = ss.str();
2772 return s;
2773 }
2774 //-----------------------------------------------------------------------------------
2775 template<class t_payload_net_handler>
2777 {
2778 MINFO("["<< epee::net_utils::print_connection_context(context) << "] NEW CONNECTION");
2779 }
2780 //-----------------------------------------------------------------------------------
2781 template<class t_payload_net_handler>
2783 {
2784 network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone());
2785 if (!zone.m_net_server.is_stop_signal_sent() && !context.m_is_income) {
2787 na = context.m_remote_address;
2788
2789 zone.m_peerlist.remove_from_peer_anchor(na);
2790 }
2791
2792 if (!zone.m_net_server.is_stop_signal_sent()) {
2793 zone.m_notifier.on_connection_close(context.m_connection_id);
2794 }
2795 m_payload_handler.on_connection_close(context);
2796
2797 MINFO("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
2798 }
2799
2800 template<class t_payload_net_handler>
2802 {
2803 return (std::find(m_priority_peers.begin(), m_priority_peers.end(), na) != m_priority_peers.end()) || (std::find(m_exclusive_peers.begin(), m_exclusive_peers.end(), na) != m_exclusive_peers.end());
2804 }
2805
2806 template<class t_payload_net_handler> template <class Container>
2808 {
2810 for(const epee::net_utils::network_address& na: peers)
2811 {
2812 if(public_zone.m_net_server.is_stop_signal_sent())
2813 return false;
2814
2815 if(is_addr_connected(na))
2816 continue;
2817
2819 }
2820
2821 return true;
2822 }
2823
2824 template<class t_payload_net_handler> template <class Container>
2825 bool node_server<t_payload_net_handler>::parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container)
2826 {
2827 std::vector<std::string> perrs = command_line::get_arg(vm, arg);
2828
2829 for(const std::string& pr_str: perrs)
2830 {
2833 if (adr)
2834 {
2835 add_zone(adr->get_zone());
2836 container.push_back(std::move(*adr));
2837 continue;
2838 }
2839 std::vector<epee::net_utils::network_address> resolved_addrs;
2840 bool r = append_net_address(resolved_addrs, pr_str, default_port);
2841 CHECK_AND_ASSERT_MES(r, false, "Failed to parse or resolve address from string: " << pr_str);
2842 for (const epee::net_utils::network_address& addr : resolved_addrs)
2843 {
2844 container.push_back(addr);
2845 }
2846 }
2847
2848 return true;
2849 }
2850
2851 template<class t_payload_net_handler>
2853 {
2854 if(max == -1) {
2855 zone.m_config.m_net_config.max_out_connection_count = P2P_DEFAULT_CONNECTIONS_COUNT;
2856 return true;
2857 }
2858 zone.m_config.m_net_config.max_out_connection_count = max;
2859 return true;
2860 }
2861
2862 template<class t_payload_net_handler>
2864 {
2865 zone.m_config.m_net_config.max_in_connection_count = max;
2866 return true;
2867 }
2868
2869 template<class t_payload_net_handler>
2871 {
2872 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2873 if (public_zone != m_network_zones.end())
2874 {
2875 const auto current = public_zone->second.m_net_server.get_config_object().get_out_connections_count();
2876 public_zone->second.m_config.m_net_config.max_out_connection_count = count;
2877 if(current > count)
2878 public_zone->second.m_net_server.get_config_object().del_out_connections(current - count);
2879 m_payload_handler.set_max_out_peers(epee::net_utils::zone::public_, count);
2880 }
2881 }
2882
2883 template<class t_payload_net_handler>
2885 {
2886 const auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2887 if (public_zone == m_network_zones.end())
2888 return 0;
2889 return public_zone->second.m_config.m_net_config.max_out_connection_count;
2890 }
2891
2892 template<class t_payload_net_handler>
2894 {
2895 auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2896 if (public_zone != m_network_zones.end())
2897 {
2898 const auto current = public_zone->second.m_net_server.get_config_object().get_in_connections_count();
2899 public_zone->second.m_config.m_net_config.max_in_connection_count = count;
2900 if(current > count)
2901 public_zone->second.m_net_server.get_config_object().del_in_connections(current - count);
2902 }
2903 }
2904
2905 template<class t_payload_net_handler>
2907 {
2908 const auto public_zone = m_network_zones.find(epee::net_utils::zone::public_);
2909 if (public_zone == m_network_zones.end())
2910 return 0;
2911 return public_zone->second.m_config.m_net_config.max_in_connection_count;
2912 }
2913
2914 template<class t_payload_net_handler>
2915 bool node_server<t_payload_net_handler>::set_tos_flag(const boost::program_options::variables_map& vm, int flag)
2916 {
2917 if(flag==-1){
2918 return true;
2919 }
2921 _dbg1("Set ToS flag " << flag);
2922 return true;
2923 }
2924
2925 template<class t_payload_net_handler>
2926 bool node_server<t_payload_net_handler>::set_rate_up_limit(const boost::program_options::variables_map& vm, int64_t limit)
2927 {
2928 this->islimitup=(limit != -1) && (limit != default_limit_up);
2929
2930 if (limit==-1) {
2931 limit=default_limit_up;
2932 }
2933
2935 MINFO("Set limit-up to " << limit << " kB/s");
2936 return true;
2937 }
2938
2939 template<class t_payload_net_handler>
2940 bool node_server<t_payload_net_handler>::set_rate_down_limit(const boost::program_options::variables_map& vm, int64_t limit)
2941 {
2942 this->islimitdown=(limit != -1) && (limit != default_limit_down);
2943 if(limit==-1) {
2944 limit=default_limit_down;
2945 }
2947 MINFO("Set limit-down to " << limit << " kB/s");
2948 return true;
2949 }
2950
2951 template<class t_payload_net_handler>
2952 bool node_server<t_payload_net_handler>::set_rate_limit(const boost::program_options::variables_map& vm, int64_t limit)
2953 {
2954 int64_t limit_up = 0;
2955 int64_t limit_down = 0;
2956
2957 if(limit == -1)
2958 {
2959 limit_up = default_limit_up;
2960 limit_down = default_limit_down;
2961 }
2962 else
2963 {
2964 limit_up = limit;
2965 limit_down = limit;
2966 }
2967 if(!this->islimitup) {
2969 MINFO("Set limit-up to " << limit_up << " kB/s");
2970 }
2971 if(!this->islimitdown) {
2973 MINFO("Set limit-down to " << limit_down << " kB/s");
2974 }
2975
2976 return true;
2977 }
2978
2979 template<class t_payload_net_handler>
2981 {
2982 if (address.get_zone() != epee::net_utils::zone::public_)
2983 return false; // Unable to determine how many connections from host
2984
2985 uint32_t count = 0;
2986
2987 m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
2988 {
2989 if (cntxt.m_is_income && cntxt.m_remote_address.is_same_host(address)) {
2990 count++;
2991
2992 // the only call location happens BEFORE foreach_connection list is updated
2993 if (count >= max_connections) {
2994 return false;
2995 }
2996 }
2997
2998 return true;
2999 });
3000 // the only call location happens BEFORE foreach_connection list is updated
3001 return count >= max_connections;
3002 }
3003
3004 template<class t_payload_net_handler>
3006 {
3007 if (m_offline) return true;
3008 if (!m_exclusive_peers.empty()) return true;
3009
3010 for (auto& zone : m_network_zones)
3011 {
3012 if (m_payload_handler.needs_new_sync_connections(zone.first))
3013 continue;
3014
3015 if (zone.second.m_net_server.is_stop_signal_sent())
3016 return false;
3017
3018 if (zone.second.m_connect == nullptr)
3019 continue;
3020
3021 peerlist_entry pe{};
3022 if (!zone.second.m_peerlist.get_random_gray_peer(pe))
3023 continue;
3024
3026 {
3027 zone.second.m_peerlist.remove_from_peer_gray(pe);
3028 LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST: address: " << pe.adr.host_str() << " Peer ID: " << peerid_to_string(pe.id));
3029 }
3030 else
3031 {
3032 zone.second.m_peerlist.set_peer_just_seen(pe.id, pe.adr, pe.pruning_seed, pe.rpc_port, pe.rpc_credits_per_hash);
3033 LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_to_string(pe.id));
3034 }
3035 }
3036 return true;
3037 }
3038
3039 template<class t_payload_net_handler>
3040 void node_server<t_payload_net_handler>::add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
3041 {
3042 const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed);
3043 if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES))
3044 return;
3045 const uint32_t index = stripe - 1;
3047 MINFO("adding stripe " << stripe << " peer: " << context.m_remote_address.str());
3048 m_used_stripe_peers[index].erase(std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(),
3049 [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; }), m_used_stripe_peers[index].end());
3050 m_used_stripe_peers[index].push_back(context.m_remote_address);
3051 }
3052
3053 template<class t_payload_net_handler>
3054 void node_server<t_payload_net_handler>::remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
3055 {
3056 const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed);
3057 if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES))
3058 return;
3059 const uint32_t index = stripe - 1;
3061 MINFO("removing stripe " << stripe << " peer: " << context.m_remote_address.str());
3062 m_used_stripe_peers[index].erase(std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(),
3063 [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; }), m_used_stripe_peers[index].end());
3064 }
3065
3066 template<class t_payload_net_handler>
3068 {
3070 MINFO("clearing used stripe peers");
3071 for (auto &e: m_used_stripe_peers)
3072 e.clear();
3073 }
3074
3075 template<class t_payload_net_handler>
3076 void node_server<t_payload_net_handler>::add_upnp_port_mapping_impl(uint32_t port, bool ipv6) // if ipv6 false, do ipv4
3077 {
3078 std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)";
3079 MDEBUG("Attempting to add IGD port mapping " << ipversion << ".");
3080 int result;
3081 const int ipv6_arg = ipv6 ? 1 : 0;
3082
3083#if MINIUPNPC_API_VERSION > 13
3084 // default according to miniupnpc.h
3085 unsigned char ttl = 2;
3086 UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, ttl, &result);
3087#else
3088 UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, &result);
3089#endif
3090 UPNPUrls urls;
3091 IGDdatas igdData;
3092 char lanAddress[64];
3093 result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress);
3094 freeUPNPDevlist(deviceList);
3095 if (result > 0) {
3096 if (result == 1) {
3097 std::ostringstream portString;
3098 portString << port;
3099
3100 // Delete the port mapping before we create it, just in case we have dangling port mapping from the daemon not being shut down correctly
3101 UPNP_DeletePortMapping(urls.controlURL, igdData.first.servicetype, portString.str().c_str(), "TCP", 0);
3102
3103 int portMappingResult;
3104 portMappingResult = UPNP_AddPortMapping(urls.controlURL, igdData.first.servicetype, portString.str().c_str(), portString.str().c_str(), lanAddress, CRYPTONOTE_NAME, "TCP", 0, "0");
3105 if (portMappingResult != 0) {
3106 LOG_ERROR("UPNP_AddPortMapping failed, error: " << strupnperror(portMappingResult));
3107 } else {
3108 MLOG_GREEN(el::Level::Info, "Added IGD port mapping.");
3109 }
3110 } else if (result == 2) {
3111 MWARNING("IGD was found but reported as not connected.");
3112 } else if (result == 3) {
3113 MWARNING("UPnP device was found but not recognized as IGD.");
3114 } else {
3115 MWARNING("UPNP_GetValidIGD returned an unknown result code.");
3116 }
3117
3118 FreeUPNPUrls(&urls);
3119 } else {
3120 MINFO("No IGD was found.");
3121 }
3122 }
3123
3124 template<class t_payload_net_handler>
3129
3130 template<class t_payload_net_handler>
3135
3136 template<class t_payload_net_handler>
3138 {
3139 if (ipv4) add_upnp_port_mapping_v4(port);
3140 if (ipv6) add_upnp_port_mapping_v6(port);
3141 }
3142
3143
3144 template<class t_payload_net_handler>
3146 {
3147 std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)";
3148 MDEBUG("Attempting to delete IGD port mapping " << ipversion << ".");
3149 int result;
3150 const int ipv6_arg = ipv6 ? 1 : 0;
3151#if MINIUPNPC_API_VERSION > 13
3152 // default according to miniupnpc.h
3153 unsigned char ttl = 2;
3154 UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, ttl, &result);
3155#else
3156 UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, ipv6_arg, &result);
3157#endif
3158 UPNPUrls urls;
3159 IGDdatas igdData;
3160 char lanAddress[64];
3161 result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress);
3162 freeUPNPDevlist(deviceList);
3163 if (result > 0) {
3164 if (result == 1) {
3165 std::ostringstream portString;
3166 portString << port;
3167
3168 int portMappingResult;
3169 portMappingResult = UPNP_DeletePortMapping(urls.controlURL, igdData.first.servicetype, portString.str().c_str(), "TCP", 0);
3170 if (portMappingResult != 0) {
3171 LOG_ERROR("UPNP_DeletePortMapping failed, error: " << strupnperror(portMappingResult));
3172 } else {
3173 MLOG_GREEN(el::Level::Info, "Deleted IGD port mapping.");
3174 }
3175 } else if (result == 2) {
3176 MWARNING("IGD was found but reported as not connected.");
3177 } else if (result == 3) {
3178 MWARNING("UPnP device was found but not recognized as IGD.");
3179 } else {
3180 MWARNING("UPNP_GetValidIGD returned an unknown result code.");
3181 }
3182
3183 FreeUPNPUrls(&urls);
3184 } else {
3185 MINFO("No IGD was found.");
3186 }
3187 }
3188
3189 template<class t_payload_net_handler>
3194
3195 template<class t_payload_net_handler>
3200
3201 template<class t_payload_net_handler>
3207
3208 template<typename t_payload_net_handler>
3209 boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>>
3211 {
3212 auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_context(), zone.m_proxy_address, remote);
3213 if (result) // if no error
3214 {
3215 p2p_connection_context context{};
3216 if (zone.m_net_server.add_connection(context, std::move(*result), remote, ssl_support))
3217 return {std::move(context)};
3218 }
3219 return boost::none;
3220 }
3221
3222 template<typename t_payload_net_handler>
3223 boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>>
3225 {
3228 CHECK_AND_ASSERT_MES(is_ipv4 || is_ipv6, boost::none,
3229 "Only IPv4 or IPv6 addresses are supported here");
3230
3231 std::string address;
3232 std::string port;
3233
3234 if (is_ipv4)
3235 {
3238 port = epee::string_tools::num_to_string_fast(ipv4.port());
3239 }
3240 else if (is_ipv6)
3241 {
3243 address = ipv6.ip().to_string();
3244 port = epee::string_tools::num_to_string_fast(ipv6.port());
3245 }
3246 else
3247 {
3248 LOG_ERROR("Only IPv4 or IPv6 addresses are supported here");
3249 return boost::none;
3250 }
3251
3252 typename net_server::t_connection_context con{};
3253 const bool res = zone.m_net_server.connect(address, port,
3254 zone.m_config.m_net_config.connection_timeout,
3255 con, "0.0.0.0", ssl_support);
3256
3257 if (res)
3258 return {std::move(con)};
3259 return boost::none;
3260 }
3261}
#define s(x, c)
Definition aesb.c:47
cryptonote::block b
Definition block.cpp:40
Definition byte_slice.h:69
byte_slice clone() const noexcept
Definition byte_slice.h:124
bool empty() const noexcept
Definition byte_slice.h:132
Provides space for levin (p2p) header, so that payload can be sent without copy.
Definition levin_base.h:132
byte_slice finalize_notify(uint32_t command)
Definition levin_base.h:152
bool add_idle_handler(t_handler t_callback, uint64_t timeout_ms)
Definition abstract_tcp_server2.h:468
bool is_stop_signal_sent() const noexcept
Definition abstract_tcp_server2.h:384
boost::asio::io_context & get_io_context()
Definition abstract_tcp_server2.h:437
epee::levin::async_protocol_handler< p2p_connection_context >::connection_context t_connection_context
Definition abstract_tcp_server2.h:357
int get_binded_port_ipv6()
Definition abstract_tcp_server2.h:428
t_protocol_handler::config_type & get_config_object()
Definition abstract_tcp_server2.h:415
bool run_server(size_t threads_count, bool wait=true, const boost::thread::attributes &attrs=boost::thread::attributes())
Run the server's io_context loop.
Definition abstract_tcp_server2.inl:1455
void set_threads_prefix(const std::string &prefix_name)
Definition abstract_tcp_server2.inl:1424
std::shared_ptr< typename t_protocol_handler::config_type > get_config_shared()
Definition abstract_tcp_server2.h:421
int get_binded_port()
Definition abstract_tcp_server2.h:427
Represents a single connection from a client.
Definition abstract_tcp_server2.h:100
Definition net_utils_base.h:69
static constexpr address_type get_type_id() noexcept
Definition net_utils_base.h:92
std::string host_str() const
Definition net_utils_base.cpp:31
Definition net_utils_base.h:125
bool matches(const ipv4_network_address &address) const
Definition net_utils_base.cpp:61
std::string host_str() const
Definition net_utils_base.cpp:58
Definition net_utils_base.h:172
static constexpr address_type get_type_id() noexcept
Definition net_utils_base.h:198
Definition net_utils_base.h:225
bool is_loopback() const
Definition net_utils_base.h:314
std::string str() const
Definition net_utils_base.h:312
address_type get_type_id() const
Definition net_utils_base.h:316
bool is_same_host(const network_address &other) const
Definition net_utils_base.cpp:90
std::uint16_t port() const
Definition net_utils_base.h:319
bool is_local() const
Definition net_utils_base.h:315
std::string host_str() const
Definition net_utils_base.h:313
zone get_zone() const
Definition net_utils_base.h:317
bool is_blockable() const
Definition net_utils_base.h:318
const Type & as() const
Definition net_utils_base.h:320
Definition expect.h:134
*return False if otherwise error()
virtual void callback(p2p_connection_context &context)
Definition net_node.inl:2423
bool set_max_in_peers(network_zone &zone, int64_t max)
Definition net_node.inl:2863
peerlist_storage m_peerlist_storage
Definition net_node.h:475
bool try_ping(basic_node_data &node_data, p2p_connection_context &context, const t_callback &cb)
Definition net_node.inl:2447
std::map< epee::net_utils::zone, network_zone > m_network_zones
Definition net_node.h:501
bool set_max_out_peers(network_zone &zone, int64_t max)
Definition net_node.inl:2852
virtual void on_connection_new(p2p_connection_context &context)
Definition net_node.inl:2776
if(is_filtered_command(context.m_remote_address, command)) return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED
bool m_first_connection_maker_call
Definition net_node.h:457
virtual void for_each_connection(std::function< bool(typename t_payload_net_handler::connection_context &, peerid_type, uint32_t)> f)
Definition net_node.inl:154
std::vector< nodetool::peerlist_entry > m_command_line_peers
Definition net_node.h:487
epee::critical_section m_conn_fails_cache_lock
Definition net_node.h:505
static boost::optional< p2p_connection_context > public_connect(network_zone &, epee::net_utils::network_address const &, epee::net_utils::ssl_support_t)
Definition net_node.inl:3224
virtual void remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
Definition net_node.inl:3054
void change_max_in_public_peers(size_t count)
Definition net_node.inl:2893
bool connect_to_seed(epee::net_utils::zone)
Definition net_node.inl:1840
std::list< epee::net_utils::network_address > m_priority_peers
Definition net_node.h:484
std::string print_connections_container()
Definition net_node.inl:2756
virtual bool block_host(epee::net_utils::network_address address, time_t seconds=P2P_IP_BLOCKTIME, bool add_only=false)
Definition net_node.inl:251
virtual bool relay_notify_to_list(int command, epee::levin::message_writer message, std::vector< std::pair< epee::net_utils::zone, boost::uuids::uuid > > connections) final
Definition net_node.inl:2341
void change_max_out_public_peers(size_t count)
Definition net_node.inl:2870
bool try_to_connect_and_handshake_with_new_peer(const epee::net_utils::network_address &na, bool just_take_peerlist=false, uint64_t last_seen_stamp=0, PeerType peer_type=white, uint64_t first_seen_stamp=0)
Definition net_node.inl:1398
bool m_enable_dns_seed_nodes
Definition net_node.h:522
boost::mutex m_used_stripe_peers_mutex
Definition net_node.h:514
bool m_offline
Definition net_node.h:466
bool do_peer_timed_sync(const epee::net_utils::connection_context_base &context, peerid_type peer_id)
Definition net_node.inl:1266
std::string m_config_folder
Definition net_node.h:454
uint32_t get_this_peer_port()
Definition net_node.h:273
void delete_upnp_port_mapping_v4(uint32_t port)
Definition net_node.inl:3190
bool islimitup
Definition net_node.h:312
void kill()
Definition net_node.h:429
PeerType
Definition net_node.h:329
@ gray
Definition net_node.h:329
@ anchor
Definition net_node.h:329
@ white
Definition net_node.h:329
bool set_tos_flag(const boost::program_options::variables_map &vm, int limit)
Definition net_node.inl:2915
std::unique_ptr< boost::thread > mPeersLoggerThread
Definition net_node.h:470
virtual ~node_server()
Definition net_node.inl:88
virtual void clear_used_stripe_peers()
Definition net_node.inl:3067
std::atomic< bool > is_closing
Definition net_node.h:469
bool handle_command_line(const boost::program_options::variables_map &vm)
Definition net_node.inl:428
bool log_peerlist()
Definition net_node.inl:2738
epee::math_helper::once_a_time_seconds< 7000 > m_dns_blocklist_interval
Definition net_node.h:482
int handle_ping(int command, COMMAND_PING::request &arg, COMMAND_PING::response &rsp, p2p_connection_context &context)
Definition net_node.inl:2729
uint32_t get_max_out_public_peers() const
Definition net_node.inl:2884
std::map< std::string, time_t > m_blocked_hosts
Definition net_node.h:508
bool check_connection_and_handshake_with_peer(const epee::net_utils::network_address &na, uint64_t last_seen_stamp)
Definition net_node.inl:1480
virtual bool drop_connection(const epee::net_utils::connection_context_base &context)
Definition net_node.inl:2440
t_payload_net_handler & get_payload_object()
Definition net_node.inl:1038
bool islimitdown
Definition net_node.h:313
@ igd
Definition net_node.h:243
@ delayed_igd
Definition net_node.h:244
virtual uint64_t get_public_connections_count()
Definition net_node.inl:1098
void delete_upnp_port_mapping_v6(uint32_t port)
Definition net_node.inl:3196
bool run()
Definition net_node.inl:1044
void add_upnp_port_mapping_impl(uint32_t port, bool ipv6=false)
Definition net_node.inl:3076
size_t get_outgoing_connections_count()
Definition net_node.inl:2066
virtual bool unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet)
Definition net_node.inl:397
epee::critical_section m_blocked_hosts_lock
Definition net_node.h:507
epee::math_helper::once_a_time_seconds< 60 *30, false > m_peerlist_store_interval
Definition net_node.h:479
uint32_t m_rpc_credits_per_hash
Definition net_node.h:462
virtual void on_connection_close(p2p_connection_context &context)
Definition net_node.inl:2782
void delete_upnp_port_mapping_impl(uint32_t port, bool ipv6=false)
Definition net_node.inl:3145
bool handle_remote_peerlist(const std::vector< peerlist_entry > &peerlist, const epee::net_utils::connection_context_base &context)
Definition net_node.inl:2283
igd_t m_igd
Definition net_node.h:465
bool is_addr_recently_failed(const epee::net_utils::network_address &addr)
Definition net_node.inl:1529
static boost::optional< p2p_connection_context > socks_connect(network_zone &, epee::net_utils::network_address const &, epee::net_utils::ssl_support_t)
Definition net_node.inl:3210
network_zone & add_zone(epee::net_utils::zone zone)
Definition net_node.inl:917
size_t get_public_white_peers_count()
Definition net_node.inl:2091
void add_upnp_port_mapping_v6(uint32_t port)
Definition net_node.inl:3131
epee::math_helper::once_a_time_seconds< 1 > m_connections_maker_interval
Definition net_node.h:478
bool make_new_connection_from_anchor_peerlist(const std::vector< anchor_peerlist_entry > &anchor_peerlist)
Definition net_node.inl:1543
virtual epee::net_utils::zone send_txs(std::vector< cryptonote::blobdata > txs, const epee::net_utils::zone origin, const boost::uuids::uuid &source, cryptonote::relay_method tx_relay)
Definition net_node.inl:2367
bool make_expected_connections_count(network_zone &zone, PeerType peer_type, size_t expected_connections)
Definition net_node.inl:1987
bool init(const boost::program_options::variables_map &vm, const std::string &proxy={}, bool proxy_dns_leaks_allowed={})
Definition net_node.inl:928
bool idle_worker()
Definition net_node.inl:2126
epee::math_helper::once_a_time_seconds< P2P_DEFAULT_HANDSHAKE_INTERVAL > m_peer_handshake_idle_maker_interval
Definition net_node.h:477
int handle_timed_sync(int command, typename COMMAND_TIMED_SYNC::request &arg, typename COMMAND_TIMED_SYNC::response &rsp, p2p_connection_context &context)
Definition net_node.inl:2577
void get_public_peerlist(std::vector< peerlist_entry > &gray, std::vector< peerlist_entry > &white)
Definition net_node.inl:2109
std::set< std::string > get_seed_nodes(epee::net_utils::zone)
Definition net_node.inl:881
epee::math_helper::once_a_time_seconds< 60 > m_gray_peerlist_housekeeping_interval
Definition net_node.h:480
virtual bool invoke_notify_to_peer(int command, epee::levin::message_writer message, const epee::net_utils::connection_context_base &context) final
Definition net_node.inl:2429
bool connect_to_peerlist(const Container &peers)
Definition net_node.inl:2807
const std::vector< std::string > m_seed_nodes_list
Definition net_node.h:305
bool store_config()
Definition net_node.inl:1123
void get_peerlist(std::vector< peerlist_entry > &gray, std::vector< peerlist_entry > &white)
Definition net_node.inl:2117
void add_upnp_port_mapping(uint32_t port, bool ipv4=true, bool ipv6=false)
Definition net_node.inl:3137
bool get_local_node_data(basic_node_data &node_data, const network_zone &zone)
Definition net_node.inl:2313
bool check_incoming_connections()
Definition net_node.inl:2192
static void init_options(boost::program_options::options_description &desc)
Definition net_node.inl:104
void record_addr_failed(const epee::net_utils::network_address &addr)
Definition net_node.inl:1522
bool sanitize_peerlist(std::vector< peerlist_entry > &local_peerlist)
Definition net_node.inl:2248
uint16_t m_rpc_port
Definition net_node.h:461
std::atomic_flag m_fallback_seed_nodes_added
Definition net_node.h:486
virtual bool block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds=P2P_IP_BLOCKTIME)
Definition net_node.inl:346
bool set_rate_limit(const boost::program_options::variables_map &vm, int64_t limit)
Definition net_node.inl:2952
bool gray_peerlist_housekeeping()
Definition net_node.inl:3005
size_t get_random_index_with_fixed_probability(size_t max_index)
Definition net_node.inl:1305
bool is_peer_used(const peerlist_entry &peer)
Definition net_node.inl:1318
bool connections_maker()
Definition net_node.inl:1913
epee::math_helper::once_a_time_seconds< 3600, false > m_incoming_connections_interval
Definition net_node.h:481
size_t get_incoming_connections_count()
Definition net_node.inl:2075
t_payload_net_handler payload_net_handler
Definition net_node.h:248
bool deinit()
Definition net_node.inl:1107
bool update_dns_blocklist()
Definition net_node.inl:2138
uint32_t max_connections
Definition net_node.h:525
virtual bool is_host_limit(const epee::net_utils::network_address &address)
Definition net_node.inl:231
int handle_get_support_flags(int command, COMMAND_REQUEST_SUPPORT_FLAGS::request &arg, COMMAND_REQUEST_SUPPORT_FLAGS::response &rsp, p2p_connection_context &context)
Definition net_node.inl:2328
virtual bool unblock_host(const epee::net_utils::network_address &address)
Definition net_node.inl:334
bool set_rate_down_limit(const boost::program_options::variables_map &vm, int64_t limit)
Definition net_node.inl:2940
int handle_handshake(int command, typename COMMAND_HANDSHAKE::request &arg, typename COMMAND_HANDSHAKE::response &rsp, p2p_connection_context &context)
Definition net_node.inl:2626
bool set_rate_up_limit(const boost::program_options::variables_map &vm, int64_t limit)
Definition net_node.inl:2926
virtual void add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
Definition net_node.inl:3040
void delete_upnp_port_mapping(uint32_t port)
Definition net_node.inl:3202
std::map< std::string, uint64_t > m_host_fails_score
Definition net_node.h:512
bool is_priority_node(const epee::net_utils::network_address &na)
Definition net_node.inl:2801
boost::uuids::uuid m_network_id
Definition net_node.h:517
virtual bool for_connection(const boost::uuids::uuid &, std::function< bool(typename t_payload_net_handler::connection_context &, peerid_type, uint32_t)> f)
Definition net_node.inl:165
bool do_handshake_with_peer(peerid_type &pi, p2p_connection_context &context, bool just_take_peerlist=false)
Definition net_node.inl:1170
bool make_new_connection_from_peerlist(network_zone &zone, bool use_white_list)
Definition net_node.inl:1578
bool parse_peers_and_add_to_container(const boost::program_options::variables_map &vm, const command_line::arg_descriptor< std::vector< std::string > > &arg, Container &container)
Definition net_node.inl:2825
void add_upnp_port_mapping_v4(uint32_t port)
Definition net_node.inl:3125
virtual bool add_host_fail(const epee::net_utils::network_address &address, unsigned int score=1)
Definition net_node.inl:409
cryptonote::network_type m_nettype
Definition net_node.h:518
p2p_connection_context_t< typename t_payload_net_handler::connection_context > p2p_connection_context
Definition net_node.h:137
t_payload_net_handler & m_payload_handler
Definition net_node.h:474
bool init_config()
Definition net_node.inl:137
bool m_hide_my_port
Definition net_node.h:464
bool m_enable_dns_blocklist
Definition net_node.h:523
epee::net_utils::ssl_support_t m_ssl_support
Definition net_node.h:520
std::map< std::string, time_t > m_conn_fails_cache
Definition net_node.h:504
bool send_stop_signal()
Definition net_node.inl:1148
bool log_connections()
Definition net_node.inl:2749
std::set< std::string > get_ip_seed_nodes() const
Definition net_node.inl:731
virtual void request_callback(const epee::net_utils::connection_context_base &context)
Definition net_node.inl:2335
uint32_t m_listening_port
Definition net_node.h:458
bool try_get_support_flags(const p2p_connection_context &context, std::function< void(p2p_connection_context &, const uint32_t &)> f)
Definition net_node.inl:2548
size_t get_public_outgoing_connections_count()
Definition net_node.inl:2023
uint32_t get_max_in_public_peers() const
Definition net_node.inl:2906
std::array< std::list< epee::net_utils::network_address >, 1<< CRYPTONOTE_PRUNING_LOG_STRIPES > m_used_stripe_peers
Definition net_node.h:515
size_t get_public_gray_peers_count()
Definition net_node.inl:2100
bool m_have_address
Definition net_node.h:456
std::set< std::string > get_dns_seed_nodes()
Definition net_node.inl:766
uint32_t m_listening_port_ipv6
Definition net_node.h:459
bool is_addr_connected(const epee::net_utils::network_address &peer)
Definition net_node.inl:1368
bool has_too_many_connections(const epee::net_utils::network_address &address)
Definition net_node.inl:2980
bool m_require_ipv4
Definition net_node.h:468
std::map< epee::net_utils::ipv4_network_subnet, time_t > m_blocked_subnets
Definition net_node.h:509
bool peer_sync_idle_maker()
Definition net_node.inl:2223
std::vector< epee::net_utils::network_address > m_exclusive_peers
Definition net_node.h:485
bool m_use_ipv6
Definition net_node.h:467
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t=NULL)
Definition net_node.inl:179
void get_peerlist(std::vector< peerlist_entry > &pl_gray, std::vector< peerlist_entry > &pl_white)
Definition net_peerlist.cpp:275
size_t get_gray_peers_count()
Definition net_peerlist.h:104
size_t get_white_peers_count()
Definition net_peerlist.h:103
static boost::optional< peerlist_storage > open(std::istream &src, const bool new_format)
Definition net_peerlist.cpp:163
static DNSResolver & instance()
Gets the singleton instance of DNSResolver.
Definition dns_utils.cpp:401
std::vector< std::string > get_ipv4(const std::string &url, bool &dnssec_available, bool &dnssec_valid)
gets ipv4 addresses from DNS query of a URL
Definition dns_utils.cpp:362
#define CRYPTONOTE_NOISE_BYTES
Definition cryptonote_config.h:118
#define P2P_MAX_PEERS_IN_HANDSHAKE
Definition cryptonote_config.h:143
#define P2P_SUPPORT_FLAGS
Definition cryptonote_config.h:161
#define P2P_NET_DATA_FILENAME
Definition cryptonote_config.h:168
#define P2P_FAILED_ADDR_FORGET_SECONDS
Definition cryptonote_config.h:155
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT
Definition cryptonote_config.h:148
#define P2P_DEFAULT_PEERS_IN_HANDSHAKE
Definition cryptonote_config.h:142
#define CRYPTONOTE_PRUNING_LOG_STRIPES
Definition cryptonote_config.h:207
#define P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT
Definition cryptonote_config.h:150
#define P2P_DEFAULT_INVOKE_TIMEOUT
Definition cryptonote_config.h:147
#define CRYPTONOTE_NAME
Definition cryptonote_config.h:165
#define THREAD_STACK_SIZE
Definition cryptonote_config.h:172
#define P2P_DEFAULT_CONNECTIONS_COUNT
Definition cryptonote_config.h:139
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT
Definition cryptonote_config.h:149
#define DNS_BLOCKLIST_LIFETIME
Definition cryptonote_config.h:212
#define P2P_IP_FAILS_BEFORE_BLOCK
Definition cryptonote_config.h:157
#define CRYPTONOTE_DNS_TIMEOUT_MS
Definition cryptonote_config.h:38
#define MONERO_UNWRAP(...)
Definition expect.h:61
void * memcpy(void *a, const void *b, size_t c)
Definition glibc_compat.cpp:16
const char * res
Definition hmac_keccak.cpp:42
#define LEVIN_ERROR_CONNECTION_DESTROYED
Definition levin_base.h:105
#define LEVIN_ERROR_CONNECTION_TIMEDOUT
Definition levin_base.h:106
static int server(unsigned short port, const char *expected_file_name, int ipv6)
Definition minihttptestserver.c:544
uint32_t address
Definition getifaddr.c:269
MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev *devlist)
Definition upnpdev.c:13
MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char *multicastif, const char *minissdpdsock, int localport, int ipv6, unsigned char ttl, int *error)
Definition miniupnpc.c:342
MINIUPNP_LIBSPEC void FreeUPNPUrls(struct UPNPUrls *urls)
Definition miniupnpc.c:497
MINIUPNP_LIBSPEC int UPNP_GetValidIGD(struct UPNPDev *devlist, struct UPNPUrls *urls, struct IGDdatas *data, char *lanaddr, int lanaddrlen)
Definition miniupnpc.c:544
#define AUTO_VAL_INIT(v)
Definition misc_language.h:36
line
Definition check.py:23
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
Definition command_line.h:187
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
Definition command_line.h:263
std::enable_if<!std::is_same< T, bool >::value, bool >::type has_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
Definition command_line.h:256
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
Definition command_line.h:269
boost::uuids::uuid const NETWORK_ID
Definition cryptonote_config.h:291
uint16_t const P2P_DEFAULT_PORT
Definition cryptonote_config.h:288
boost::uuids::uuid const NETWORK_ID
Definition cryptonote_config.h:276
uint16_t const P2P_DEFAULT_PORT
Definition cryptonote_config.h:273
boost::uuids::uuid const NETWORK_ID
Definition cryptonote_config.h:233
uint16_t const P2P_DEFAULT_PORT
Definition cryptonote_config.h:230
T rand()
Definition crypto.h:174
std::enable_if< std::is_integral< T >::value, T >::type rand_range(T range_min, T range_max)
Definition crypto.h:195
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition crypto.h:204
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
Definition cryptonote_core.cpp:100
@ FAKECHAIN
Definition cryptonote_config.h:306
@ TESTNET
Definition cryptonote_config.h:304
@ MAINNET
Definition cryptonote_config.h:303
@ STAGENET
Definition cryptonote_config.h:305
const command_line::arg_descriptor< bool > arg_offline
Definition cryptonote_core.cpp:113
relay_method
Methods tracking how a tx was received and relayed.
Definition enums.h:37
const command_line::arg_descriptor< bool, false > arg_testnet_on
Definition cryptonote_core.cpp:75
const command_line::arg_descriptor< bool, false > arg_stagenet_on
Definition cryptonote_core.cpp:80
const config_t & get_config(network_type nettype)
Definition cryptonote_config.h:321
Level
Represents enumeration for severity level used to determine level of logging.
Definition easylogging++.h:591
@ Warning
Useful when application has potentially harmful situtaions.
Definition easylogging++.h:603
@ Info
Mainly useful to represent current progress of application.
Definition easylogging++.h:607
bool load_file_to_string(const std::string &path_to_file, std::string &target_str, size_t max_size=1000000000)
Definition file_io_utils.cpp:105
const char * get_err_descr(int err)
Definition levin_base.h:113
byte_slice make_noise_notify(std::size_t noise_bytes)
Definition levin_base.cpp:69
std::string get_time_interval_string(const time_t &time_)
Definition time_helper.h:58
Definition abstract_http_client.h:36
const char * zone_to_string(zone value) noexcept
Definition net_utils_base.cpp:135
@ ipv4
Definition enums.h:43
zone
Definition enums.h:50
@ public_
Definition enums.h:52
@ i2p
Definition enums.h:53
@ tor
Definition enums.h:54
std::string print_connection_context(const connection_context_base &ctx)
Definition net_utils_base.cpp:121
bool async_invoke_remote_command2(const epee::net_utils::connection_context_base &context, int command, const t_arg &out_struct, t_transport &transport, const callback_t &cb, size_t inv_timeout=LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
Definition levin_abstract_invoke2.h:87
ssl_support_t
Definition net_ssl.h:49
@ e_ssl_support_disabled
Definition net_ssl.h:50
std::string get_ip_string_from_int32(uint32_t ip)
Definition string_tools.cpp:68
std::string to_string_hex(const T &val)
Definition string_tools.h:118
std::string num_to_string_fast(int64_t val)
Definition string_tools.cpp:126
expect< epee::net_utils::network_address > get_network_address(const boost::string_ref address, const std::uint16_t default_port)
Definition parse.cpp:67
expect< boost::asio::ip::tcp::endpoint > get_tcp_endpoint(const boost::string_ref address)
Definition parse.cpp:134
void get_network_address_host_and_port(const std::string &address, std::string &host, std::string &port)
Takes a valid address string (IP, Tor, I2P, or DNS name) and splits it into host and port.
Definition parse.cpp:39
@ unsupported_address
Type not supported by get_network_address.
Definition error.h:49
expect< epee::net_utils::ipv4_network_subnet > get_ipv4_subnet_address(const boost::string_ref address, bool allow_implicit_32)
Definition parse.cpp:112
Definition levin_notify.h:52
const command_line::arg_descriptor< std::vector< std::string > > arg_p2p_add_priority_node
Definition net_node.cpp:146
bool is_filtered_command(const epee::net_utils::network_address &address, int command)
Definition net_node.cpp:310
const command_line::arg_descriptor< int > arg_tos_flag
Definition net_node.cpp:163
const command_line::arg_descriptor< uint32_t > arg_p2p_external_port
Definition net_node.cpp:143
const int64_t default_limit_up
Definition net_node.h:528
const command_line::arg_descriptor< std::string > arg_ban_list
Definition net_node.cpp:152
static std::string peerid_to_string(peerid_type peer_id)
Definition p2p_protocol_defs.h:51
boost::optional< boost::asio::ip::tcp::socket > socks_connect_internal(const std::atomic< bool > &stop_signal, boost::asio::io_context &service, const boost::asio::ip::tcp::endpoint &proxy, const epee::net_utils::network_address &remote)
Definition net_node.cpp:330
const command_line::arg_descriptor< bool > arg_enable_dns_blocklist
Definition net_node.cpp:155
const command_line::arg_descriptor< bool > arg_pad_transactions
Definition net_node.cpp:169
uint64_t peerid_type
Definition p2p_protocol_defs.h:49
const command_line::arg_descriptor< bool > arg_no_igd
Definition net_node.cpp:157
const command_line::arg_descriptor< std::vector< std::string > > arg_tx_proxy
Definition net_node.cpp:150
const command_line::arg_descriptor< int64_t > arg_limit_rate
Definition net_node.cpp:167
const command_line::arg_descriptor< std::string, false, true, 2 > arg_p2p_bind_port
Definition net_node.cpp:116
const command_line::arg_descriptor< bool > arg_no_sync
Definition net_node.cpp:154
const command_line::arg_descriptor< bool > arg_p2p_use_ipv6
Definition net_node.cpp:159
boost::optional< std::vector< anonymous_inbound > > get_anonymous_inbounds(boost::program_options::variables_map const &vm)
Definition net_node.cpp:243
std::string print_peerlist_to_string(const std::vector< peerlist_entry > &pl)
Definition p2p_protocol_defs.h:146
bool append_net_address(std::vector< epee::net_utils::network_address > &seed_nodes, std::string const &addr, uint16_t default_port)
Definition net_node.inl:690
const command_line::arg_descriptor< bool > arg_p2p_allow_local_ip
Definition net_node.cpp:144
const command_line::arg_descriptor< int64_t > arg_limit_rate_down
Definition net_node.cpp:166
const command_line::arg_descriptor< std::string > arg_p2p_bind_ip
Definition net_node.cpp:114
const command_line::arg_descriptor< int64_t > arg_limit_rate_up
Definition net_node.cpp:165
boost::optional< std::vector< proxy > > get_proxies(boost::program_options::variables_map const &vm)
Definition net_node.cpp:174
anchor_peerlist_entry_base< epee::net_utils::network_address > anchor_peerlist_entry
Definition p2p_protocol_defs.h:120
const command_line::arg_descriptor< std::vector< std::string > > arg_anonymous_inbound
Definition net_node.cpp:151
const command_line::arg_descriptor< std::string > arg_p2p_bind_ipv6_address
Definition net_node.cpp:115
const command_line::arg_descriptor< int64_t > arg_out_peers
Definition net_node.cpp:161
const command_line::arg_descriptor< std::string, false, true, 2 > arg_p2p_bind_port_ipv6
Definition net_node.cpp:129
const command_line::arg_descriptor< uint32_t > arg_max_connections_per_ip
Definition net_node.cpp:172
const command_line::arg_descriptor< bool > arg_p2p_hide_my_port
Definition net_node.cpp:153
const command_line::arg_descriptor< bool > arg_p2p_ignore_ipv4
Definition net_node.cpp:160
const command_line::arg_descriptor< std::string > arg_igd
Definition net_node.cpp:158
const command_line::arg_descriptor< int64_t > arg_in_peers
Definition net_node.cpp:162
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
Definition p2p_protocol_defs.h:99
const command_line::arg_descriptor< std::vector< std::string > > arg_p2p_seed_node
Definition net_node.cpp:149
const command_line::arg_descriptor< std::vector< std::string > > arg_p2p_add_peer
Definition net_node.cpp:145
const int64_t default_limit_down
Definition net_node.h:529
const command_line::arg_descriptor< std::vector< std::string > > arg_p2p_add_exclusive_node
Definition net_node.cpp:147
r
Definition testupnpigd.py:61
bool load_txt_records_from_dns(std::vector< std::string > &good_records, const std::vector< std::string > &dns_urls)
Definition dns_utils.cpp:499
bool create_directories_if_necessary(const std::string &path)
creates directories for a path
Definition util.cpp:660
uint32_t get_pruning_stripe(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes)
Definition pruning.cpp:55
uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes)
Definition pruning.cpp:38
#define LOG_PRINT_CC_PRIORITY_NODE(priority, con, msg)
Definition net_node.inl:1388
#define MIN_WANTED_SEED_NODES
Definition net_node.inl:72
static boost::asio::ip::address_v4 make_address_v4_from_v6(const boost::asio::ip::address_v6 &a)
Definition net_node.inl:74
#define LOG_DEBUG_CC(ct, message)
Definition net_utils_base.h:472
#define LOG_WARNING_CC(ct, message)
Definition net_utils_base.h:470
#define LOG_INFO_CC(ct, message)
Definition net_utils_base.h:471
#define LOG_TRACE_CC(ct, message)
Definition net_utils_base.h:473
#define PING_OK_RESPONSE_STATUS_TEXT
Definition p2p_protocol_defs.h:286
const CharType(& source)[N]
Definition pointer.h:1147
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
const portMappingElt code
Definition portlistingparse.c:22
tools::wallet2::message_signature_result_t result
Definition signature.cpp:62
unsigned short uint16_t
Definition stdint.h:125
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
char servicetype[MINIUPNPC_URL_MAXSIZE]
Definition igd_desc_parse.h:19
Definition igd_desc_parse.h:23
struct IGDdatas_service first
Definition igd_desc_parse.h:33
Definition upnpdev.h:17
Definition miniupnpc.h:99
char * controlURL
Definition miniupnpc.h:100
Definition command_line.h:53
Definition crypto.h:185
uint16_t const P2P_DEFAULT_PORT
Definition cryptonote_config.h:314
Definition net_utils_base.h:367
const network_address m_remote_address
Definition net_utils_base.h:369
Definition syncobj.h:53
epee::misc_utils::struct_init< request_t > request
Definition p2p_protocol_defs.h:225
epee::misc_utils::struct_init< response_t > response
Definition p2p_protocol_defs.h:239
static const int ID
Definition p2p_protocol_defs.h:284
epee::misc_utils::struct_init< request_t > request
Definition p2p_protocol_defs.h:295
epee::misc_utils::struct_init< response_t > response
Definition p2p_protocol_defs.h:307
epee::misc_utils::struct_init< response_t > response
Definition p2p_protocol_defs.h:333
static const int ID
Definition p2p_protocol_defs.h:316
epee::misc_utils::struct_init< request_t > request
Definition p2p_protocol_defs.h:323
epee::misc_utils::struct_init< response_t > response
Definition p2p_protocol_defs.h:270
epee::misc_utils::struct_init< request_t > request
Definition p2p_protocol_defs.h:258
int64_t first_seen
Definition p2p_protocol_defs.h:106
AddressType adr
Definition p2p_protocol_defs.h:104
peerid_type id
Definition p2p_protocol_defs.h:105
Definition p2p_protocol_defs.h:186
uint32_t support_flags
Definition p2p_protocol_defs.h:192
uint32_t my_port
Definition p2p_protocol_defs.h:188
peerid_type peer_id
Definition p2p_protocol_defs.h:191
uint16_t rpc_port
Definition p2p_protocol_defs.h:189
uint32_t rpc_credits_per_hash
Definition p2p_protocol_defs.h:190
uuid network_id
Definition p2p_protocol_defs.h:187
Definition net_node.h:163
cryptonote::levin::notify m_notifier
Definition net_node.h:215
net_server m_net_server
Definition net_node.h:209
std::string m_port_ipv6
Definition net_node.h:214
std::string m_bind_ip
Definition net_node.h:211
boost::asio::ip::tcp::endpoint m_proxy_address
Definition net_node.h:219
bool m_can_pingback
Definition net_node.h:223
boost::shared_mutex m_seed_nodes_lock
Definition net_node.h:222
std::vector< epee::net_utils::network_address > m_seed_nodes
Definition net_node.h:210
std::string m_port
Definition net_node.h:213
peerlist_manager m_peerlist
Definition net_node.h:217
config m_config
Definition net_node.h:218
connect_func * m_connect
Definition net_node.h:208
std::string m_bind_ipv6_address
Definition net_node.h:212
uint32_t support_flags
Definition net_node.h:121
bool is_ping
Definition net_node.h:123
peerid_type peer_id
Definition net_node.h:120
bool m_in_timedsync
Definition net_node.h:122
uint32_t pruning_seed
Definition p2p_protocol_defs.h:77
AddressType adr
Definition p2p_protocol_defs.h:74
uint16_t rpc_port
Definition p2p_protocol_defs.h:78
peerid_type id
Definition p2p_protocol_defs.h:75
int64_t last_seen
Definition p2p_protocol_defs.h:76
uint32_t rpc_credits_per_hash
Definition p2p_protocol_defs.h:79
Definition net_peerlist.h:56
Definition net_node.h:68
epee::net_utils::zone zone
Definition net_node.h:78
boost::asio::ip::tcp::endpoint address
Definition net_node.h:77
bool noise
Definition net_node.h:79
std::int64_t max_connections
Definition net_node.h:76
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153
randomx_vm * vm
Definition tests.cpp:20
MINIUPNP_LIBSPEC int UPNP_DeletePortMapping(const char *controlURL, const char *servicetype, const char *extPort, const char *proto, const char *remoteHost)
Definition upnpcommands.c:471
MINIUPNP_LIBSPEC int UPNP_AddPortMapping(const char *controlURL, const char *servicetype, const char *extPort, const char *inPort, const char *inClient, const char *desc, const char *proto, const char *remoteHost, const char *leaseDuration)
Definition upnpcommands.c:339
const char * strupnperror(int err)
Definition upnperrors.c:15