@@ -413,7 +413,10 @@ CNode* CConnman::FindNode(const CService& addr)
413
413
414
414
bool CConnman::AlreadyConnectedToAddress (const CAddress& addr)
415
415
{
416
- return FindNode (static_cast <CNetAddr>(addr)) || FindNode (addr.ToStringIPPort ());
416
+ CNode* found_by_addr = FindNode (static_cast <CNetAddr>(addr));
417
+ CNode* found_by_ip_port = FindNode (addr.ToStringIPPort ());
418
+ return (found_by_addr && !found_by_addr->fDisconnect ) ||
419
+ (found_by_ip_port && !found_by_ip_port->fDisconnect );
417
420
}
418
421
419
422
bool CConnman::CheckIncomingNonce (uint64_t nonce)
@@ -478,8 +481,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
478
481
479
482
// Look for an existing connection
480
483
CNode* pnode = FindNode (static_cast <CService>(addrConnect));
481
- if (pnode)
482
- {
484
+ if (pnode && !pnode->fDisconnect ) {
483
485
LogPrintf (" Failed to open new connection, already connected\n " );
484
486
return nullptr ;
485
487
}
@@ -505,7 +507,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
505
507
// In that case, drop the connection that was just created.
506
508
LOCK (m_nodes_mutex);
507
509
CNode* pnode = FindNode (static_cast <CService>(addrConnect));
508
- if (pnode) {
510
+ if (pnode && !pnode-> fDisconnect ) {
509
511
LogPrintf (" Failed to open new connection, already connected\n " );
510
512
return nullptr ;
511
513
}
@@ -1460,6 +1462,16 @@ bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds
1460
1462
return node.m_connected + m_peer_connect_timeout < now;
1461
1463
}
1462
1464
1465
+ void CConnman::DowngradeToV1Transport (CNode& node)
1466
+ {
1467
+ AssertLockNotHeld (m_total_bytes_sent_mutex);
1468
+ LogPrint (BCLog::NET, " downgrading to v1 transport protocol for peer=%d\n " , node.GetId ());
1469
+ CAddress addr = node.addr ;
1470
+ addr.nServices = ServiceFlags (addr.nServices & ~NODE_P2P_V2);
1471
+ OpenNetworkConnection (addr, false , &node.grantOutbound , addr.ToStringIPPort ().c_str (), node.m_conn_type );
1472
+ node.m_bip324_shared_state ->key_exchange_complete = true ;
1473
+ }
1474
+
1463
1475
bool CConnman::InactivityCheck (const CNode& node) const
1464
1476
{
1465
1477
// Tests that see disconnects after using mocktime can start nodes with a
@@ -1758,6 +1770,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1758
1770
LogPrint (BCLog::NET, " socket closed for peer=%d\n " , pnode->GetId ());
1759
1771
}
1760
1772
pnode->CloseSocketDisconnect ();
1773
+
1774
+ // Downgrade if a v2 outbound connection was met with a disconnection before receiving anything
1775
+ if (pnode->PreferV2Conn () &&
1776
+ !pnode->IsInboundConn () &&
1777
+ (pnode->m_bip324_shared_state ->peer_ellswift_buf .empty () &&
1778
+ !pnode->m_bip324_node_state ->keys_derived )) {
1779
+ DowngradeToV1Transport (*pnode);
1780
+ }
1761
1781
} else if (nBytes < 0 ) {
1762
1782
// error
1763
1783
int nErr = WSAGetLastError ();
@@ -1777,7 +1797,17 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1777
1797
if (bytes_sent) RecordBytesSent (bytes_sent);
1778
1798
}
1779
1799
1780
- if (InactivityCheck (*pnode)) pnode->fDisconnect = true ;
1800
+ if (InactivityCheck (*pnode)) {
1801
+ pnode->fDisconnect = true ;
1802
+ // Downgrade if a v2 outbound connection was met with inactivity before receiving anything
1803
+ if (pnode->PreferV2Conn () &&
1804
+ !pnode->IsInboundConn () &&
1805
+ (pnode->m_bip324_shared_state ->peer_ellswift_buf .empty () &&
1806
+ !pnode->m_bip324_node_state ->keys_derived ) &&
1807
+ pnode->m_last_recv .load ().count () == 0 ) {
1808
+ DowngradeToV1Transport (*pnode);
1809
+ }
1810
+ }
1781
1811
}
1782
1812
}
1783
1813
@@ -2411,8 +2441,10 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
2411
2441
if (IsLocal (addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress (addrConnect)) {
2412
2442
return ;
2413
2443
}
2414
- } else if (FindNode (std::string (pszDest)))
2415
- return ;
2444
+ } else {
2445
+ auto existing_node = FindNode (std::string (pszDest));
2446
+ if (existing_node && !existing_node->fDisconnect ) return ;
2447
+ }
2416
2448
2417
2449
CNode* pnode = ConnectNode (addrConnect, pszDest, fCountFailure , conn_type);
2418
2450
0 commit comments