diff options
Diffstat (limited to 'src/netaddress.cpp')
-rw-r--r-- | src/netaddress.cpp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 85e46fd373..69edc15c66 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -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; @@ -841,6 +878,11 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well case NET_ONION: return REACH_PRIVATE; } + case NET_I2P: + switch (ourNet) { + case NET_I2P: return REACH_PRIVATE; + default: return REACH_DEFAULT; + } case NET_TEREDO: switch(ourNet) { default: return REACH_DEFAULT; |