@@ -412,6 +412,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
412412 // Resolve
413413 const uint16_t default_port{pszDest != nullptr ? GetDefaultPort (pszDest) :
414414 m_params.GetDefaultPort ()};
415+
416+ // Collection of addresses to try to connect to: either all dns resolved addresses if a domain name (pszDest) is provided, or addrConnect otherwise.
417+ std::vector<CAddress> connect_to{};
415418 if (pszDest) {
416419 std::vector<CService> resolved{Lookup (pszDest, default_port, fNameLookup && !HaveNameProxy (), 256 )};
417420 if (!resolved.empty ()) {
@@ -432,8 +435,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
432435 LogPrintf (" Not opening a connection to %s, already connected to %s\n " , pszDest, addrConnect.ToStringAddrPort ());
433436 return nullptr ;
434437 }
438+ // Add the address to the resolved addresses vector so we can try to connect to it later on
439+ connect_to.push_back (addrConnect);
435440 }
441+ } else {
442+ // For resolution via proxy
443+ connect_to.push_back (addrConnect);
436444 }
445+ } else {
446+ // Connect via addrConnect directly
447+ connect_to.push_back (addrConnect);
437448 }
438449
439450 // Connect
@@ -443,94 +454,99 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
443454 assert (!addr_bind.IsValid ());
444455 std::unique_ptr<i2p::sam::Session> i2p_transient_session;
445456
446- if (addrConnect.IsValid ()) {
447- const bool use_proxy{GetProxy (addrConnect.GetNetwork (), proxy)};
448- bool proxyConnectionFailed = false ;
457+ for (auto & target_addr: connect_to) {
458+ if (target_addr.IsValid ()) {
459+ const bool use_proxy{GetProxy (target_addr.GetNetwork (), proxy)};
460+ bool proxyConnectionFailed = false ;
449461
450- if (addrConnect .IsI2P () && use_proxy) {
451- i2p::Connection conn;
452- bool connected{false };
462+ if (target_addr .IsI2P () && use_proxy) {
463+ i2p::Connection conn;
464+ bool connected{false };
453465
454- if (m_i2p_sam_session) {
455- connected = m_i2p_sam_session->Connect (addrConnect, conn, proxyConnectionFailed);
456- } else {
457- {
458- LOCK (m_unused_i2p_sessions_mutex);
459- if (m_unused_i2p_sessions.empty ()) {
460- i2p_transient_session =
461- std::make_unique<i2p::sam::Session>(proxy, &interruptNet);
462- } else {
463- i2p_transient_session.swap (m_unused_i2p_sessions.front ());
464- m_unused_i2p_sessions.pop ();
466+ if (m_i2p_sam_session) {
467+ connected = m_i2p_sam_session->Connect (target_addr, conn, proxyConnectionFailed);
468+ } else {
469+ {
470+ LOCK (m_unused_i2p_sessions_mutex);
471+ if (m_unused_i2p_sessions.empty ()) {
472+ i2p_transient_session =
473+ std::make_unique<i2p::sam::Session>(proxy, &interruptNet);
474+ } else {
475+ i2p_transient_session.swap (m_unused_i2p_sessions.front ());
476+ m_unused_i2p_sessions.pop ();
477+ }
465478 }
466- }
467- connected = i2p_transient_session-> Connect (addrConnect, conn, proxyConnectionFailed);
468- if (!connected) {
469- LOCK (m_unused_i2p_sessions_mutex);
470- if ( m_unused_i2p_sessions.size () < MAX_UNUSED_I2P_SESSIONS_SIZE) {
471- m_unused_i2p_sessions. emplace (i2p_transient_session. release ());
479+ connected = i2p_transient_session-> Connect (target_addr, conn, proxyConnectionFailed);
480+ if (!connected) {
481+ LOCK (m_unused_i2p_sessions_mutex);
482+ if (m_unused_i2p_sessions. size () < MAX_UNUSED_I2P_SESSIONS_SIZE) {
483+ m_unused_i2p_sessions.emplace (i2p_transient_session. release ());
484+ }
472485 }
473486 }
474- }
475487
476- if (connected) {
477- sock = std::move (conn.sock );
478- addr_bind = CAddress{conn.me , NODE_NONE};
488+ if (connected) {
489+ sock = std::move (conn.sock );
490+ addr_bind = CAddress{conn.me , NODE_NONE};
491+ }
492+ } else if (use_proxy) {
493+ LogPrintLevel (BCLog::PROXY, BCLog::Level::Debug, " Using proxy: %s to connect to %s\n " , proxy.ToString (), target_addr.ToStringAddrPort ());
494+ sock = ConnectThroughProxy (proxy, target_addr.ToStringAddr (), target_addr.GetPort (), proxyConnectionFailed);
495+ } else {
496+ // no proxy needed (none set for target network)
497+ sock = ConnectDirectly (target_addr, conn_type == ConnectionType::MANUAL);
479498 }
480- } else if (use_proxy) {
481- LogPrintLevel (BCLog::PROXY, BCLog::Level::Debug, " Using proxy: %s to connect to %s:%s\n " , proxy.ToString (), addrConnect.ToStringAddr (), addrConnect.GetPort ());
482- sock = ConnectThroughProxy (proxy, addrConnect.ToStringAddr (), addrConnect.GetPort (), proxyConnectionFailed);
483- } else {
484- // no proxy needed (none set for target network)
485- sock = ConnectDirectly (addrConnect, conn_type == ConnectionType::MANUAL);
499+ if (!proxyConnectionFailed) {
500+ // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
501+ // the proxy, mark this as an attempt.
502+ addrman.Attempt (target_addr, fCountFailure );
503+ }
504+ } else if (pszDest && GetNameProxy (proxy)) {
505+ std::string host;
506+ uint16_t port{default_port};
507+ SplitHostPort (std::string (pszDest), port, host);
508+ bool proxyConnectionFailed;
509+ sock = ConnectThroughProxy (proxy, host, port, proxyConnectionFailed);
510+ }
511+ // Check any other resolved address (if any) if we fail to connect
512+ if (!sock) {
513+ continue ;
486514 }
487- if (!proxyConnectionFailed) {
488- // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
489- // the proxy, mark this as an attempt.
490- addrman.Attempt (addrConnect, fCountFailure );
515+
516+ NetPermissionFlags permission_flags = NetPermissionFlags::None;
517+ std::vector<NetWhitelistPermissions> whitelist_permissions = conn_type == ConnectionType::MANUAL ? vWhitelistedRangeOutgoing : std::vector<NetWhitelistPermissions>{};
518+ AddWhitelistPermissionFlags (permission_flags, target_addr, whitelist_permissions);
519+
520+ // Add node
521+ NodeId id = GetNewNodeId ();
522+ uint64_t nonce = GetDeterministicRandomizer (RANDOMIZER_ID_LOCALHOSTNONCE).Write (id).Finalize ();
523+ if (!addr_bind.IsValid ()) {
524+ addr_bind = GetBindAddress (*sock);
491525 }
492- } else if (pszDest && GetNameProxy (proxy)) {
493- std::string host;
494- uint16_t port{default_port};
495- SplitHostPort (std::string (pszDest), port, host);
496- bool proxyConnectionFailed;
497- sock = ConnectThroughProxy (proxy, host, port, proxyConnectionFailed);
498- }
499- if (!sock) {
500- return nullptr ;
501- }
526+ CNode* pnode = new CNode (id,
527+ std::move (sock),
528+ target_addr,
529+ CalculateKeyedNetGroup (target_addr),
530+ nonce,
531+ addr_bind,
532+ pszDest ? pszDest : " " ,
533+ conn_type,
534+ /* inbound_onion=*/ false ,
535+ CNodeOptions{
536+ .permission_flags = permission_flags,
537+ .i2p_sam_session = std::move (i2p_transient_session),
538+ .recv_flood_size = nReceiveFloodSize,
539+ .use_v2transport = use_v2transport,
540+ });
541+ pnode->AddRef ();
502542
503- NetPermissionFlags permission_flags = NetPermissionFlags::None;
504- std::vector<NetWhitelistPermissions> whitelist_permissions = conn_type == ConnectionType::MANUAL ? vWhitelistedRangeOutgoing : std::vector<NetWhitelistPermissions>{};
505- AddWhitelistPermissionFlags (permission_flags, addrConnect, whitelist_permissions);
543+ // We're making a new connection, harvest entropy from the time (and our peer count)
544+ RandAddEvent ((uint32_t )id);
506545
507- // Add node
508- NodeId id = GetNewNodeId ();
509- uint64_t nonce = GetDeterministicRandomizer (RANDOMIZER_ID_LOCALHOSTNONCE).Write (id).Finalize ();
510- if (!addr_bind.IsValid ()) {
511- addr_bind = GetBindAddress (*sock);
546+ return pnode;
512547 }
513- CNode* pnode = new CNode (id,
514- std::move (sock),
515- addrConnect,
516- CalculateKeyedNetGroup (addrConnect),
517- nonce,
518- addr_bind,
519- pszDest ? pszDest : " " ,
520- conn_type,
521- /* inbound_onion=*/ false ,
522- CNodeOptions{
523- .permission_flags = permission_flags,
524- .i2p_sam_session = std::move (i2p_transient_session),
525- .recv_flood_size = nReceiveFloodSize,
526- .use_v2transport = use_v2transport,
527- });
528- pnode->AddRef ();
529-
530- // We're making a new connection, harvest entropy from the time (and our peer count)
531- RandAddEvent ((uint32_t )id);
532548
533- return pnode ;
549+ return nullptr ;
534550}
535551
536552void CNode::CloseSocketDisconnect ()
0 commit comments