mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
net: extend CNetAddr::SetSpecial() to support I2P
Recognize also I2P addresses in the form `base32hashofpublickey.b32.i2p` from `CNetAddr::SetSpecial()`. This makes `Lookup()` support them, which in turn makes it possible to manually connect to an I2P node by using `-proxy=i2p_socks5_proxy:port -addnode=i2p_address.b32.i2p:port` Co-authored-by: Lucas Ontivero <lucasontivero@gmail.com>
This commit is contained in:
@@ -221,25 +221,34 @@ static void Checksum(Span<const uint8_t> addr_pubkey, uint8_t (&checksum)[CHECKS
|
||||
|
||||
}; // namespace torv3
|
||||
|
||||
/**
|
||||
* Parse a TOR address and set this object to it.
|
||||
*
|
||||
* @returns Whether or not the operation was successful.
|
||||
*
|
||||
* @see CNetAddr::IsTor()
|
||||
*/
|
||||
bool CNetAddr::SetSpecial(const std::string& str)
|
||||
bool CNetAddr::SetSpecial(const std::string& addr)
|
||||
{
|
||||
if (!ValidAsCString(addr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SetTor(addr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SetI2P(addr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CNetAddr::SetTor(const std::string& addr)
|
||||
{
|
||||
static const char* suffix{".onion"};
|
||||
static constexpr size_t suffix_len{6};
|
||||
|
||||
if (!ValidAsCString(str) || str.size() <= suffix_len ||
|
||||
str.substr(str.size() - suffix_len) != suffix) {
|
||||
if (addr.size() <= suffix_len || addr.substr(addr.size() - suffix_len) != suffix) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invalid;
|
||||
const auto& input = DecodeBase32(str.substr(0, str.size() - suffix_len).c_str(), &invalid);
|
||||
const auto& input = DecodeBase32(addr.substr(0, addr.size() - suffix_len).c_str(), &invalid);
|
||||
|
||||
if (invalid) {
|
||||
return false;
|
||||
@@ -275,6 +284,34 @@ bool CNetAddr::SetSpecial(const std::string& str)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CNetAddr::SetI2P(const std::string& addr)
|
||||
{
|
||||
// I2P addresses that we support consist of 52 base32 characters + ".b32.i2p".
|
||||
static constexpr size_t b32_len{52};
|
||||
static const char* suffix{".b32.i2p"};
|
||||
static constexpr size_t suffix_len{8};
|
||||
|
||||
if (addr.size() != b32_len + suffix_len || ToLower(addr.substr(b32_len)) != suffix) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so DecodeBase32()
|
||||
// can decode it.
|
||||
const std::string b32_padded = addr.substr(0, b32_len) + "====";
|
||||
|
||||
bool invalid;
|
||||
const auto& address_bytes = DecodeBase32(b32_padded.c_str(), &invalid);
|
||||
|
||||
if (invalid || address_bytes.size() != ADDR_I2P_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_net = NET_I2P;
|
||||
m_addr.assign(address_bytes.begin(), address_bytes.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
|
||||
{
|
||||
m_net = NET_IPV4;
|
||||
|
||||
Reference in New Issue
Block a user