Skip to content

Commit fe069b8

Browse files
committed
p2p: BIP324 v2.0 clients retry with v1 protocol
1 parent 64f3b0e commit fe069b8

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/net.cpp

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,10 @@ CNode* CConnman::FindNode(const CService& addr)
414414

415415
bool CConnman::AlreadyConnectedToAddress(const CAddress& addr)
416416
{
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);
418421
}
419422

420423
bool CConnman::CheckIncomingNonce(uint64_t nonce)
@@ -479,8 +482,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
479482

480483
// Look for an existing connection
481484
CNode* pnode = FindNode(static_cast<CService>(addrConnect));
482-
if (pnode)
483-
{
485+
if (pnode && !pnode->fDisconnect) {
484486
LogPrintf("Failed to open new connection, already connected\n");
485487
return nullptr;
486488
}
@@ -506,7 +508,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
506508
// In that case, drop the connection that was just created.
507509
LOCK(m_nodes_mutex);
508510
CNode* pnode = FindNode(static_cast<CService>(addrConnect));
509-
if (pnode) {
511+
if (pnode && !pnode->fDisconnect) {
510512
LogPrintf("Failed to open new connection, already connected\n");
511513
return nullptr;
512514
}
@@ -1465,6 +1467,16 @@ bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds
14651467
return node.m_connected + m_peer_connect_timeout < now;
14661468
}
14671469

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+
14681480
bool CConnman::InactivityCheck(const CNode& node) const
14691481
{
14701482
// Tests that see disconnects after using mocktime can start nodes with a
@@ -1763,6 +1775,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
17631775
LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
17641776
}
17651777
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+
}
17661786
} else if (nBytes < 0) {
17671787
// error
17681788
int nErr = WSAGetLastError();
@@ -1782,7 +1802,17 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
17821802
if (bytes_sent) RecordBytesSent(bytes_sent);
17831803
}
17841804

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+
}
17861816
}
17871817
}
17881818

@@ -2416,8 +2446,10 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
24162446
if (IsLocal(addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress(addrConnect)) {
24172447
return;
24182448
}
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+
}
24212453

24222454
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
24232455

src/net.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,8 @@ class CConnman
10601060
void NotifyNumConnectionsChanged();
10611061
/** Return true if the peer is inactive and should be disconnected. */
10621062
bool InactivityCheck(const CNode& node) const;
1063+
void DowngradeToV1Transport(CNode& node)
1064+
EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
10631065

10641066
/**
10651067
* Generate a collection of sockets to check for IO readiness.

0 commit comments

Comments
 (0)