@@ -414,7 +414,10 @@ CNode* CConnman::FindNode(const CService& addr)
414
414
415
415
bool CConnman::AlreadyConnectedToAddress (const CAddress& addr)
416
416
{
417
- return FindNode (static_cast <CNetAddr>(addr)) || FindNode (addr.ToStringIPPort ());
417
+ CNode* found_by_addr = FindNode (static_cast <CNetAddr>(addr));
418
+ CNode* found_by_ip_port = FindNode (addr.ToStringIPPort ());
419
+ return (found_by_addr && !found_by_addr->fDisconnect ) ||
420
+ (found_by_ip_port && !found_by_ip_port->fDisconnect );
418
421
}
419
422
420
423
bool CConnman::CheckIncomingNonce (uint64_t nonce)
@@ -479,8 +482,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
479
482
480
483
// Look for an existing connection
481
484
CNode* pnode = FindNode (static_cast <CService>(addrConnect));
482
- if (pnode)
483
- {
485
+ if (pnode && !pnode->fDisconnect ) {
484
486
LogPrintf (" Failed to open new connection, already connected\n " );
485
487
return nullptr ;
486
488
}
@@ -506,7 +508,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
506
508
// In that case, drop the connection that was just created.
507
509
LOCK (m_nodes_mutex);
508
510
CNode* pnode = FindNode (static_cast <CService>(addrConnect));
509
- if (pnode) {
511
+ if (pnode && !pnode-> fDisconnect ) {
510
512
LogPrintf (" Failed to open new connection, already connected\n " );
511
513
return nullptr ;
512
514
}
@@ -1465,6 +1467,16 @@ bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds
1465
1467
return node.m_connected + m_peer_connect_timeout < now;
1466
1468
}
1467
1469
1470
+ void CConnman::DowngradeToV1Transport (CNode& node)
1471
+ {
1472
+ AssertLockNotHeld (m_total_bytes_sent_mutex);
1473
+ LogPrint (BCLog::NET, " downgrading to v1 transport protocol for peer=%d\n " , node.GetId ());
1474
+ CAddress addr = node.addr ;
1475
+ addr.nServices = ServiceFlags (addr.nServices & ~NODE_P2P_V2);
1476
+ OpenNetworkConnection (addr, false , &node.grantOutbound , addr.ToStringIPPort ().c_str (), node.m_conn_type );
1477
+ node.m_bip324_shared_state ->key_exchange_complete = true ;
1478
+ }
1479
+
1468
1480
bool CConnman::InactivityCheck (const CNode& node) const
1469
1481
{
1470
1482
// Tests that see disconnects after using mocktime can start nodes with a
@@ -1763,6 +1775,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1763
1775
LogPrint (BCLog::NET, " socket closed for peer=%d\n " , pnode->GetId ());
1764
1776
}
1765
1777
pnode->CloseSocketDisconnect ();
1778
+
1779
+ // Downgrade if a v2 outbound connection was met with a disconnection before receiving anything
1780
+ if (pnode->PreferV2Conn () &&
1781
+ !pnode->IsInboundConn () &&
1782
+ (pnode->m_bip324_shared_state ->peer_ellswift_buf .empty () &&
1783
+ !pnode->m_bip324_node_state ->keys_derived )) {
1784
+ DowngradeToV1Transport (*pnode);
1785
+ }
1766
1786
} else if (nBytes < 0 ) {
1767
1787
// error
1768
1788
int nErr = WSAGetLastError ();
@@ -1782,7 +1802,17 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1782
1802
if (bytes_sent) RecordBytesSent (bytes_sent);
1783
1803
}
1784
1804
1785
- if (InactivityCheck (*pnode)) pnode->fDisconnect = true ;
1805
+ if (InactivityCheck (*pnode)) {
1806
+ pnode->fDisconnect = true ;
1807
+ // Downgrade if a v2 outbound connection was met with inactivity before receiving anything
1808
+ if (pnode->PreferV2Conn () &&
1809
+ !pnode->IsInboundConn () &&
1810
+ (pnode->m_bip324_shared_state ->peer_ellswift_buf .empty () &&
1811
+ !pnode->m_bip324_node_state ->keys_derived ) &&
1812
+ pnode->m_last_recv .load ().count () == 0 ) {
1813
+ DowngradeToV1Transport (*pnode);
1814
+ }
1815
+ }
1786
1816
}
1787
1817
}
1788
1818
@@ -2416,8 +2446,10 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
2416
2446
if (IsLocal (addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress (addrConnect)) {
2417
2447
return ;
2418
2448
}
2419
- } else if (FindNode (std::string (pszDest)))
2420
- return ;
2449
+ } else {
2450
+ auto existing_node = FindNode (std::string (pszDest));
2451
+ if (existing_node && !existing_node->fDisconnect ) return ;
2452
+ }
2421
2453
2422
2454
CNode* pnode = ConnectNode (addrConnect, pszDest, fCountFailure , conn_type);
2423
2455
0 commit comments