Skip to content

Commit 24cad63

Browse files
committed
addrman: reset I2P ports in all "new" buckets
In `CAddrMan::ResetI2PPorts()`, if an I2P address is found in two or more "new" buckets, our first encounter of it would change the port to 0 and re-position it within that "new" bucket. The `CAddrInfo` object is shared between all occurrences of an address in all "new" buckets. So subsequent encounters of that address will see the `CAddrInfo` already with port 0 and will skip re-positioning. To fix that, check and re-position if necessary even for I2P entries with port 0. Fixes #22470
1 parent f8b20fd commit 24cad63

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/addrman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ void CAddrMan::ResetI2PPorts()
746746
return;
747747
}
748748
auto& addr_info = it->second;
749-
if (!addr_info.IsI2P() || addr_info.GetPort() == I2P_SAM31_PORT) {
749+
if (!addr_info.IsI2P()) {
750750
continue;
751751
}
752752

src/test/addrman_tests.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,13 @@ BOOST_AUTO_TEST_CASE(reset_i2p_ports)
10001000
NODE_NONE,
10011001
good_time};
10021002

1003+
// Will be located in 2 new buckets (due to coming from 2 different sources).
1004+
// Has its port changed, repositioned in the 2 new buckets and afterwards we make it "tried".
1005+
const CAddress i2p_new5{
1006+
ResolveService("zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p", port),
1007+
NODE_NONE,
1008+
good_time};
1009+
10031010
// Remains unchanged.
10041011
const CAddress ipv4_new{ResolveService("1.2.3.4", port), NODE_NONE, good_time};
10051012

@@ -1040,6 +1047,10 @@ BOOST_AUTO_TEST_CASE(reset_i2p_ports)
10401047
addrman1.Add(i2p_new2, source);
10411048
addrman1.Add(i2p_new3, source);
10421049
addrman1.Add(i2p_new4, source);
1050+
addrman1.Add(i2p_new5, source);
1051+
CAddress i2p_new5_updated_time{i2p_new5};
1052+
++i2p_new5_updated_time.nTime;
1053+
addrman1.Add(i2p_new5_updated_time, ResolveIP("1.2.3.4"));
10431054
addrman1.Add(ipv4_new, source);
10441055

10451056
addrman1.Add(i2p_tried1, source);
@@ -1060,7 +1071,7 @@ BOOST_AUTO_TEST_CASE(reset_i2p_ports)
10601071
const size_t max_pct{0};
10611072

10621073
auto addresses = addrman2.GetAddr(max_addresses, max_pct, NET_I2P);
1063-
BOOST_REQUIRE_EQUAL(addresses.size(), 7UL);
1074+
BOOST_REQUIRE_EQUAL(addresses.size(), 8UL);
10641075
std::sort(addresses.begin(), addresses.end()); // Just some deterministic order.
10651076
BOOST_CHECK_EQUAL(addresses[0].ToStringIP(), i2p_new4.ToStringIP());
10661077
BOOST_CHECK_EQUAL(addresses[0].GetPort(), I2P_SAM31_PORT);
@@ -1074,8 +1085,18 @@ BOOST_AUTO_TEST_CASE(reset_i2p_ports)
10741085
BOOST_CHECK_EQUAL(addresses[4].GetPort(), I2P_SAM31_PORT);
10751086
BOOST_CHECK_EQUAL(addresses[5].ToStringIP(), i2p_tried2.ToStringIP());
10761087
BOOST_CHECK_EQUAL(addresses[5].GetPort(), I2P_SAM31_PORT);
1077-
BOOST_CHECK_EQUAL(addresses[6].ToStringIP(), i2p_new1.ToStringIP());
1088+
BOOST_CHECK_EQUAL(addresses[6].ToStringIP(), i2p_new5.ToStringIP());
10781089
BOOST_CHECK_EQUAL(addresses[6].GetPort(), I2P_SAM31_PORT);
1090+
BOOST_CHECK_EQUAL(addresses[7].ToStringIP(), i2p_new1.ToStringIP());
1091+
BOOST_CHECK_EQUAL(addresses[7].GetPort(), I2P_SAM31_PORT);
1092+
1093+
const CAddress i2p_new5_changed_port{
1094+
ResolveService("zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p",
1095+
I2P_SAM31_PORT),
1096+
NODE_NONE,
1097+
good_time};
1098+
// Crashes due to https://github.com/bitcoin/bitcoin/issues/22470
1099+
addrman2.Good(i2p_new5_changed_port);
10791100

10801101
addresses = addrman2.GetAddr(max_addresses, max_pct, NET_IPV4);
10811102
BOOST_REQUIRE_EQUAL(addresses.size(), 2UL);

0 commit comments

Comments
 (0)