Skip to content

Commit bab691d

Browse files
committed
p2p: BIP324 v2.0 clients retry with v1 protocol
1 parent 4aa9943 commit bab691d

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/net.cpp

+39-7
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
@@ -1762,6 +1774,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
17621774
LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
17631775
}
17641776
pnode->CloseSocketDisconnect();
1777+
1778+
// Downgrade if a v2 outbound connection was met with a disconnection before receiving anything
1779+
if (pnode->PreferV2Conn() &&
1780+
!pnode->IsInboundConn() &&
1781+
(pnode->m_bip324_shared_state->peer_ellswift_buf.empty() &&
1782+
!pnode->m_bip324_node_state->keys_derived)) {
1783+
DowngradeToV1Transport(*pnode);
1784+
}
17651785
} else if (nBytes < 0) {
17661786
// error
17671787
int nErr = WSAGetLastError();
@@ -1781,7 +1801,17 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
17811801
if (bytes_sent) RecordBytesSent(bytes_sent);
17821802
}
17831803

1784-
if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
1804+
if (InactivityCheck(*pnode)) {
1805+
pnode->fDisconnect = true;
1806+
// Downgrade if a v2 outbound connection was met with inactivity before receiving anything
1807+
if (pnode->PreferV2Conn() &&
1808+
!pnode->IsInboundConn() &&
1809+
(pnode->m_bip324_shared_state->peer_ellswift_buf.empty() &&
1810+
!pnode->m_bip324_node_state->keys_derived) &&
1811+
pnode->m_last_recv.load().count() == 0) {
1812+
DowngradeToV1Transport(*pnode);
1813+
}
1814+
}
17851815
}
17861816
}
17871817

@@ -2427,8 +2457,10 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
24272457
if (IsLocal(addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress(addrConnect)) {
24282458
return;
24292459
}
2430-
} else if (FindNode(std::string(pszDest)))
2431-
return;
2460+
} else {
2461+
auto existing_node = FindNode(std::string(pszDest));
2462+
if (existing_node && !existing_node->fDisconnect) return;
2463+
}
24322464

24332465
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
24342466

src/net.h

+2
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)