aboutsummaryrefslogtreecommitdiff
path: root/src/netaddress.cpp
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2020-10-21 11:35:19 +0200
committerVasil Dimov <vd@FreeBSD.org>2021-03-01 13:22:11 +0100
commitcff65c4a270887ec171293409ab84f5d0d0be7fc (patch)
tree3b0f9abf229eb94d5fd7e17c004e779d77ba756e /src/netaddress.cpp
parentf6c267db3be2d7077fd2bdbd34860eba838dea99 (diff)
downloadbitcoin-cff65c4a270887ec171293409ab84f5d0d0be7fc.tar.xz
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>
Diffstat (limited to 'src/netaddress.cpp')
-rw-r--r--src/netaddress.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 85e46fd373..80313b88ce 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;