@@ -412,6 +412,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
412
412
// Resolve
413
413
const uint16_t default_port{pszDest != nullptr ? GetDefaultPort (pszDest) :
414
414
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{};
415
418
if (pszDest) {
416
419
std::vector<CService> resolved{Lookup (pszDest, default_port, fNameLookup && !HaveNameProxy (), 256 )};
417
420
if (!resolved.empty ()) {
@@ -432,8 +435,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
432
435
LogPrintf (" Not opening a connection to %s, already connected to %s\n " , pszDest, addrConnect.ToStringAddrPort ());
433
436
return nullptr ;
434
437
}
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);
435
440
}
441
+ } else {
442
+ // For resolution via proxy
443
+ connect_to.push_back (addrConnect);
436
444
}
445
+ } else {
446
+ // Connect via addrConnect directly
447
+ connect_to.push_back (addrConnect);
437
448
}
438
449
439
450
// Connect
@@ -443,94 +454,99 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
443
454
assert (!addr_bind.IsValid ());
444
455
std::unique_ptr<i2p::sam::Session> i2p_transient_session;
445
456
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 ;
449
461
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 };
453
465
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
+ }
465
478
}
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
+ }
472
485
}
473
486
}
474
- }
475
487
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);
479
498
}
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 ;
486
514
}
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);
491
525
}
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 ();
502
542
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);
506
545
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;
512
547
}
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);
532
548
533
- return pnode ;
549
+ return nullptr ;
534
550
}
535
551
536
552
void CNode::CloseSocketDisconnect ()
0 commit comments