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