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