torcontrol: Create also a V3 ed25519-V3 onion address. #19485
pull Saibato wants to merge 1 commits into bitcoin:master from Saibato:add-ed25519 changing 1 files +57 −24-
Saibato commented at 3:55 pm on July 10, 2020: contributorWhile fiddling around with the path to ADDRv2 and #19031 I noticed that it might be useful if we have already ED25519-V3 onions for the node created in torcontrol.
-
fanquake added the label P2P on Jul 10, 2020
-
luke-jr commented at 3:59 pm on July 10, 2020: member
What’s the point if we can’t advertise the address?
Also, shouldn’t it be possible to have both v2 and v3 addresses?
-
Saibato commented at 4:17 pm on July 10, 2020: contributor
What’s the point if we can’t advertise the address?
Also, shouldn’t it be possible to have both v2 and v3 addresses?
If BIP155 get merged… ? I have a working patch for @vasild Tor v3/ADDRv2 implementation that i will post him now.
Btw. I use for myself a patch to tunnel V3 in V2 ADDR message that works ̶ ̶r̶i̶g̶h̶t̶ ̶n̶o̶w̶ ̶w̶i̶t̶h̶ ̶c̶u̶r̶r̶e̶n̶t̶ ̶m̶a̶s̶t̶e̶r̶.̶ on top of the current p2p ;protocol. The old nodes would barely notice and drop the new address, since they are unrouteable local ipv6. And only the patched nodes have full Tor v3 support. It uses FC00/7 address that we ignore and resembles on the end to a v3 address to drop in and out from the peers.dat, That should not even need a BIP since its fully transparent to the actual implementation, although a bit ugly and stealth.
Also, shouldn’t it be possible to have both v2 and v3 addresses?
This PR create both V2 and V3 in one sweep.
-
luke-jr commented at 4:30 pm on July 10, 2020: member
It uses FC00/7 address that we ignore and resembles on the end to a v3 address to drop in and out from the peers.dat, That should not even need a BIP since its fully transparent to the actual implementation, although a bit ugly and stealth.
I don’t know why it wouldn’t need a BIP… it’s a protocol change at the p2p layer still.
-
Saibato commented at 4:50 pm on July 10, 2020: contributor
I don’t know why it wouldn’t need a BIP… it’s a protocol change at the p2p layer …
So then we propose this ? I posted this tunnel patch in the comment as diff.
This v3 tunnel protocol is unrelated to this PR , Here we just create the service descriptor and do effectively none with it, but sure you can i.e. post the new v3 address grabbed from the log to your counterpart node and do a manual addnode on the remote side until BIP155 gets merged.
-
DrahtBot commented at 0:20 am on July 11, 2020: member
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
Conflicts
Reviewers, this pull request conflicts with the following ones:
- #19991 (net: Use alternative port for incoming Tor connections by hebasto)
- #19954 (tor: complete the TORv3 implementation by vasild)
- #19288 (tests: Add fuzzing harness for TorController by practicalswift)
- #19043 (torcontrol: add -tortarget config by MDrollette)
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
-
Saibato commented at 0:25 am on July 11, 2020: contributor
To add some fish here this POC tor v3 patch is in line with the current piggy pack of v2 onions in ipv6 Click here, to see the full diff of the POC ADDRv1 compatible tor v3 support
0diff --git a/src/addrman.h b/src/addrman.h 1index 8e82020df..4a810e53f 100644 2--- a/src/addrman.h 3+++ b/src/addrman.h 4@@ -61,6 +61,7 @@ public: 5 SERIALIZE_METHODS(CAddrInfo, obj) 6 { 7 READWRITEAS(CAddress, obj); 8+ READWRITEAS(CNetAddr, obj); 9 READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts); 10 } 11 12diff --git a/src/net.cpp b/src/net.cpp 13index 244b0094d..36af03d33 100644 14--- a/src/net.cpp 15+++ b/src/net.cpp 16@@ -156,6 +156,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn 17 struct in6_addr ip; 18 memcpy(&ip, seed_in.addr, sizeof(ip)); 19 CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE)); 20+ LogPrintf("seeds %s\n", CNetAddr(addr).ToString()); 21 addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek; 22 vSeedsOut.push_back(addr); 23 } 24@@ -368,6 +369,9 @@ static CAddress GetBindAddress(SOCKET sock) 25 return addr_bind; 26 } 27 28+static CAddress getadrr(std::string name) { 29+ return CAddress(CService(name,18444), NODE_NONE); 30+} 31 CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only) 32 { 33 if (pszDest == nullptr) { 34@@ -384,16 +388,23 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo 35 } 36 37 /// debug print 38- LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n", 39- pszDest ? pszDest : addrConnect.ToString(), 40+ LogPrint(BCLog::NET, "trying connection %s unresolved address %s lastseen=%.1fhrs\n", 41+ pszDest ? pszDest:"", addrConnect.ToString(), 42 pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); 43 44+ std::string strName = std::string( pszDest ? pszDest:""); 45 // Resolve 46 const int default_port = Params().GetDefaultPort(); 47 if (pszDest) { 48 std::vector<CService> resolved; 49 if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) { 50+ 51+ // dont resolv local the onions 52+ if (!strName.find(".onion")) { 53+ 54 addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE); 55+ 56+ 57 if (!addrConnect.IsValid()) { 58 LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest); 59 return nullptr; 60@@ -410,6 +421,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo 61 LogPrintf("Failed to open new connection, already connected\n"); 62 return nullptr; 63 } 64+ } 65 } 66 } 67 68@@ -417,7 +429,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo 69 bool connected = false; 70 SOCKET hSocket = INVALID_SOCKET; 71 proxyType proxy; 72- if (addrConnect.IsValid()) { 73+ if (addrConnect.IsValid() && addrConnect.IsTor() && !pszDest) { 74 bool proxyConnectionFailed = false; 75 76 if (GetProxy(addrConnect.GetNetwork(), proxy)) { 77@@ -425,14 +437,21 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo 78 if (hSocket == INVALID_SOCKET) { 79 return nullptr; 80 } 81- connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed); 82+ 83+ if (addrConnect.ToStringIP() != "") { 84+ connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed); 85+ } else return nullptr; 86+ 87 } else { 88- // no proxy needed (none set for target network) 89+ // no proxy needed (none set for tastrName.find(".onion")rget network) 90 hSocket = CreateSocket(addrConnect); 91 if (hSocket == INVALID_SOCKET) { 92 return nullptr; 93 } 94- connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection); 95+ 96+ if (addrConnect.ToString() != "") { 97+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection); 98+ } else return nullptr; 99 } 100 if (!proxyConnectionFailed) { 101 // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to 102@@ -444,14 +463,24 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo 103 if (hSocket == INVALID_SOCKET) { 104 return nullptr; 105 } 106+ 107 std::string host; 108 int port = default_port; 109 SplitHostPort(std::string(pszDest), port, host); 110 bool proxyConnectionFailed; 111- connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed); 112+ connected = false; 113+ //proxyConnectionFailed = true; 114+ 115+ 116+ if (strlen(pszDest) > 0) //strName.find(".onion")) 117+ { 118+ LogPrintf("Address to connect over proxz %s %d\n", host, port); 119+ connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed); 120+ } else return nullptr; 121+ 122 } 123 if (!connected) { 124- CloseSocket(hSocket); 125+ if (hSocket) CloseSocket(hSocket); 126 return nullptr; 127 } 128 129@@ -1705,17 +1734,6 @@ void CConnman::ThreadDNSAddressSeed() 130 LogPrintf("%d addresses found from DNS seeds\n", found); 131 } 132 133- 134- 135- 136- 137- 138- 139- 140- 141- 142- 143- 144 void CConnman::DumpAddresses() 145 { 146 int64_t nStart = GetTimeMillis(); 147@@ -2057,6 +2075,8 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai 148 } 149 } else if (FindNode(std::string(pszDest))) 150 return; 151+ // will "":port ever work? 152+ if(!pszDest && (addrConnect.ToStringIP() == "")) return; 153 154 CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection, block_relay_only); 155 156@@ -2756,6 +2776,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn 157 // peers (to prevent adversaries from inferring these links from addr 158 // traffic). 159 m_addr_known{block_relay_only ? nullptr : MakeUnique<CRollingBloomFilter>(5000, 0.001)}, 160+ 161 id(idIn), 162 nLocalHostNonce(nLocalHostNonceIn), 163 nLocalServices(nLocalServicesIn), 164diff --git a/src/net_processing.cpp b/src/net_processing.cpp 165index bfc60b18f..ecd83188e 100644 166--- a/src/net_processing.cpp 167+++ b/src/net_processing.cpp 168@@ -2454,14 +2454,47 @@ void ProcessMessage( 169 std::vector<CAddress> vAddrOk; 170 int64_t nNow = GetAdjustedTime(); 171 int64_t nSince = nNow - 10 * 60; 172+ int i = 0; 173+ size_t len = 10; 174+ CAddress Tor = CAddress(vAddr[0]); 175+ char rawaddr[256] = {}; 176+ 177 for (CAddress& addr : vAddr) 178 { 179 if (interruptMsgProc) 180 return; 181 182+ if (addr.IsTorSequence(i)) { 183+ if (i == 0 ) { 184+ // LogPrintf("Adrress addr V3 raw rec ="); 185+ Tor = addr; 186+ } 187+ //V3sequence()) 188+ addr.SetSpecial_v3(addr, 256); //fill hostdata from ip; 189+ memcpy(&rawaddr[i*10], &addr.fqdn.c_str()[0], 10); 190+ i++; 191+ if (i != 8) { 192+ continue; 193+ } 194+ } else addr.fqdn = {}; 195+ 196+ //LogPrintf("\nAdrress add raw? %s\n", &rawaddr[0]); 197+ 198+ if (i == 8) { 199+ Tor.SetSpecial_v3(addr, 255); // set clasic tor flag 200+ Tor.fqdn = rawaddr; 201+ if ( i == 8 ) Tor.fqdn = rawaddr; 202+ addr = Tor; 203+ } 204+ 205+ if (addr.IsTor() && strlen(addr.fqdn.c_str()) < 32) addr.SetSpecial_v3(addr, 255); // v2 stzle 206+ LogPrint(BCLog::NET, "Adrress add? %s\n", addr.ToString()); 207+ 208+ 209 // We only bother storing full nodes, though this may include 210 // things which we would not make an outbound connection to, in 211 // part because we may make feeler connections to them. 212+ 213 if (!MayHaveUsefulAddressDB(addr.nServices) && !HasAllDesirableServiceFlags(addr.nServices)) 214 continue; 215 216@@ -3901,12 +3934,25 @@ bool PeerLogicValidation::SendMessages(CNode* pto) 217 std::vector<CAddress> vAddr; 218 vAddr.reserve(pto->vAddrToSend.size()); 219 assert(pto->m_addr_known); 220+ CAddress addr_add; 221 for (const CAddress& addr : pto->vAddrToSend) 222 { 223 if (!pto->m_addr_known->contains(addr.GetKey())) 224 { 225 pto->m_addr_known->insert(addr.GetKey()); 226- vAddr.push_back(addr); 227+ if (!addr.IsTor()) vAddr.push_back(addr); 228+ if (addr.IsTor()) LogPrint(BCLog::NET, "Try to send onion address = %s\n", addr.fqdn); 229+ 230+ if (addr.IsTor() && strlen(addr.fqdn.c_str()) > 32) { 231+ for (int i=0;i<8;i++) { 232+ addr_add = addr; 233+ addr_add.SetSpecial_v3(addr, (i)*10); 234+ 235+ vAddr.push_back(addr_add); 236+ 237+ } 238+ } else vAddr.push_back(addr); //v2 tor 239+ 240 // receiver rejects addr messages larger than 1000 241 if (vAddr.size() >= 1000) 242 { 243diff --git a/src/netaddress.cpp b/src/netaddress.cpp 244index 674439161..8c8bad0f8 100644 245--- a/src/netaddress.cpp 246+++ b/src/netaddress.cpp 247@@ -5,13 +5,17 @@ 248 249 #include <cstdint> 250 #include <netaddress.h> 251+#include <netbase.h> 252+ 253 #include <hash.h> 254 #include <util/strencodings.h> 255 #include <util/asmap.h> 256 #include <tinyformat.h> 257+#include <util/system.h> 258 259 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; 260 static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43}; 261+static const unsigned char pchOnionSeq[] = {0xFD,'l','o','r','3',0x00}; 262 263 // 0xFD + sha256("bitcoin")[0:5] 264 static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 }; 265@@ -47,6 +51,11 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in) 266 } 267 } 268 269+void CNetAddr::SetRawByte(char p , int pos) 270+{ 271+ ip[6+pos] = p; 272+} 273+ 274 /** 275 * Try to make this a dummy address that maps the specified name into IPv6 like 276 * so: (0xFD + %sha256("bitcoin")[0:5]) + %sha256(name)[0:10]. Such dummy 277@@ -70,6 +79,7 @@ bool CNetAddr::SetInternal(const std::string &name) 278 CSHA256().Write((const unsigned char*)name.data(), name.size()).Finalize(hash); 279 memcpy(ip, g_internal_prefix, sizeof(g_internal_prefix)); 280 memcpy(ip + sizeof(g_internal_prefix), hash, sizeof(ip) - sizeof(g_internal_prefix)); 281+ fqdn = name; 282 return true; 283 } 284 285@@ -83,20 +93,51 @@ bool CNetAddr::SetInternal(const std::string &name) 286 * 287 * [@see](/bitcoin-bitcoin/contributor/see/) CNetAddr::IsTor(), CNetAddr::IsRFC4193() 288 */ 289-bool CNetAddr::SetSpecial(const std::string &strName) 290+bool CNetAddr::SetSpecial(const std::string &strName, int flag) 291 { 292 if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") { 293- std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); 294- if (vchAddr.size() != 16-sizeof(pchOnionCat)) 295+ std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(flag*10, strName.size() - 6).c_str()); 296+ if (vchAddr.size() != 16-sizeof(pchOnionCat) && vchAddr.size() != 35) 297 return false; 298 memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); 299 for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++) 300 ip[i + sizeof(pchOnionCat)] = vchAddr[i]; 301+ fqdn = strName; 302+ LogPrint(BCLog::NET, "setspecail called with %s %d\n", strName, flag); 303 return true; 304 } 305 return false; 306 } 307 308+bool CNetAddr::SetSpecial_v3(CNetAddr ref , int flag) 309+{ 310+ //fqdn.resize(256); 311+ std::string cp = ref.fqdn; 312+ cp.resize(256); 313+ if( flag < 254 ) { memcpy(ip, pchOnionSeq, sizeof(pchOnionSeq)); 314+ for (unsigned int i=0; i<16-sizeof(pchOnionSeq); i++) { 315+ ip[i + sizeof(pchOnionSeq)] = cp.c_str()[flag+i]; 316+ } 317+ fqdn = cp.substr(flag,10); 318+ } 319+ if (flag == 255) { // backward comp 320+ std::string name = EncodeBase32(&ip[6], 10) + ".onion"; 321+ fqdn = name; 322+ } 323+ if (flag == 256) { 324+ for (unsigned int i=0; i<16-sizeof(pchOnionSeq); i++) { 325+ fqdn[i] = char(ip[i + sizeof(pchOnionSeq)]); 326+ } 327+ } 328+ return true; 329+} 330+ 331+CNetAddr::CNetAddr(const std::string &strName) 332+{ 333+ SetSpecial(strName); 334+ LogPrint(BCLog::NET, "CNetAddr internal setspecail called from addr by name\n"); 335+} 336+ 337 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) 338 { 339 SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr); 340@@ -224,7 +265,15 @@ bool CNetAddr::IsHeNet() const 341 */ 342 bool CNetAddr::IsTor() const 343 { 344- return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); 345+ return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0) || IsTorSequence(0x0); 346+} 347+ 348+/** 349+ * [@see](/bitcoin-bitcoin/contributor/see/) CNetAddr::SetSpecial(const std::string &) 350+ */ 351+bool CNetAddr::IsTorSequence(char seq) const 352+{ 353+ return memcmp(ip, pchOnionSeq, sizeof(pchOnionSeq)) == 0; 354 } 355 356 bool CNetAddr::IsLocal() const 357@@ -333,8 +382,9 @@ enum Network CNetAddr::GetNetwork() const 358 359 std::string CNetAddr::ToStringIP() const 360 { 361- if (IsTor()) 362- return EncodeBase32(&ip[6], 10) + ".onion"; 363+ if (IsTor()) { 364+ return fqdn; 365+ } 366 if (IsInternal()) 367 return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal"; 368 CService serv(*this, 0); 369@@ -640,6 +690,10 @@ CService::CService(const struct in6_addr& ipv6Addr, uint16_t portIn) : CNetAddr( 370 { 371 } 372 373+CService::CService(const std::string fqdn, uint16_t portIn) : CNetAddr(fqdn), port(portIn) 374+{ 375+} 376+ 377 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) 378 { 379 assert(addr.sin_family == AF_INET); 380diff --git a/src/netaddress.h b/src/netaddress.h 381index c20101215..e18cc31a1 100644 382--- a/src/netaddress.h 383+++ b/src/netaddress.h 384@@ -38,16 +38,18 @@ class CNetAddr 385 CNetAddr(); 386 explicit CNetAddr(const struct in_addr& ipv4Addr); 387 void SetIP(const CNetAddr& ip); 388+ std::string fqdn = {}; 389 390 /** 391 * Set raw IPv4 or IPv6 address (in network byte order) 392- * [@note](/bitcoin-bitcoin/contributor/note/) Only NET_IPV4 and NET_IPV6 are allowed for network. 393+ * [@note](/bitcoin-bitcoin/contributor/note/) void SetRawBytes(const uint8_t *ip_in);Only NET_IPV4 and NET_IPV6 are allowed for network. 394 */ 395 void SetRaw(Network network, const uint8_t *data); 396- 397+ void SetRawByte(char b, int pos); 398 bool SetInternal(const std::string& name); 399 400- bool SetSpecial(const std::string &strName); // for Tor addresses 401+ bool SetSpecial_v3(CNetAddr ref , int flag); // for Tor addresses 402+ bool SetSpecial(const std::string &strName, int flag = 0); 403 bool IsBindAny() const; // INADDR_ANY equivalent 404 bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) 405 bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) 406@@ -67,6 +69,7 @@ class CNetAddr 407 bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765) 408 bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36) 409 bool IsTor() const; 410+ bool IsTorSequence(char pseq) const; 411 bool IsLocal() const; 412 bool IsRoutable() const; 413 bool IsInternal() const; 414@@ -94,13 +97,14 @@ class CNetAddr 415 int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const; 416 417 explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); 418+ CNetAddr(const std::string &strName); 419 bool GetIn6Addr(struct in6_addr* pipv6Addr) const; 420 421 friend bool operator==(const CNetAddr& a, const CNetAddr& b); 422 friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); } 423 friend bool operator<(const CNetAddr& a, const CNetAddr& b); 424 425- SERIALIZE_METHODS(CNetAddr, obj) { READWRITE(obj.ip); } 426+ SERIALIZE_METHODS(CNetAddr, obj) { READWRITE(obj.ip, obj.fqdn); } 427 428 friend class CSubNet; 429 }; 430@@ -144,7 +148,8 @@ class CService : public CNetAddr 431 public: 432 CService(); 433 CService(const CNetAddr& ip, uint16_t port); 434- CService(const struct in_addr& ipv4Addr, uint16_t port); 435+ CService(const struct in_addr& ipv4Addr, uint16_t port);; 436+ CService(const std::string, uint16_t port); 437 explicit CService(const struct sockaddr_in& addr); 438 uint16_t GetPort() const; 439 bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const; 440diff --git a/src/netbase.cpp b/src/netbase.cpp 441index 3a3b5f3e6..816d66228 100644 442--- a/src/netbase.cpp 443+++ b/src/netbase.cpp 444@@ -4,6 +4,7 @@ 445 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 446 447 #include <netbase.h> 448+#include <net.h> 449 450 #include <sync.h> 451 #include <tinyformat.h> 452@@ -69,17 +70,18 @@ bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, un 453 return false; 454 } 455 456- { 457- CNetAddr addr; 458- // From our perspective, onion addresses are not hostnames but rather 459- // direct encodings of CNetAddr much like IPv4 dotted-decimal notation 460- // or IPv6 colon-separated hextet notation. Since we can't use 461- // getaddrinfo to decode them and it wouldn't make sense to resolve 462- // them, we return a network address representing it instead. See 463- // CNetAddr::SetSpecial(const std::string&) for more details. 464- if (addr.SetSpecial(name)) { 465+ CNetAddr addr; 466+ // From our perspective, onion addresses are not hostnames but rather 467+ // direct encodings of CNetAddr much like IPv4 dotted-decimal notation 468+ // or IPv6 colon-separated hextet notation. Since we can't use 469+ // getaddrinfo to decode them and it wouldn't make sense to resolve 470+ // them, we return a network address representing it instead. See 471+ // CNetAddr::SetSpecial(const std::string&) for more details. 472+ 473+ if (name.find(".onion")) { 474+ if (addr.SetSpecial(name,0)) { 475 vIP.push_back(addr); 476- return true; 477+ return false; 478 } 479 } 480 481@@ -97,12 +99,19 @@ bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, un 482 // If we don't allow lookups, then use the AI_NUMERICHOST flag for 483 // getaddrinfo to only decode numerical network addresses and suppress 484 // hostname lookups. 485- aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; 486+ aiHint.ai_flags = fAllowLookup && !HaveNameProxy() ? AI_ADDRCONFIG : AI_NUMERICHOST; 487 struct addrinfo *aiRes = nullptr; 488 int nErr = getaddrinfo(name.c_str(), nullptr, &aiHint, &aiRes); 489- if (nErr) 490- return false; 491 492+ LogPrintf("Resolver :%s error = %d local resolve allowed %s %s\n", name.c_str() ,nErr,fAllowLookup, nErr?"fail":"local resolved"); 493+ if (nErr ) { 494+ CNetAddr resolved; 495+ resolved.SetInternal(name); 496+ if (resolved.IsInternal()) { 497+ vIP.push_back(resolved); 498+ } 499+ return false; 500+ } 501 // Traverse the linked list starting with aiTrav, add all non-internal 502 // IPv4,v6 addresses to vIP while respecting nMaxSolutions. 503 struct addrinfo *aiTrav = aiRes; 504@@ -182,7 +191,7 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup) 505 addr = vIP.front(); 506 return true; 507 } 508- 509+; 510 /** 511 * Resolve a service string to its corresponding service. 512 * 513@@ -214,8 +223,17 @@ bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefau 514 515 std::vector<CNetAddr> vIP; 516 bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup); 517- if (!fRet) 518- return false; 519+ if (vIP[0].IsTor()) { 520+ vAddr.resize(hostname.size()); 521+ vAddr[0] = CService(hostname, port); 522+ return true; 523+ } 524+ if (!fRet) // mayby just a name and only onion we do not resovel so use tor 525+ { 526+ vAddr.resize(hostname.size()); 527+ vAddr[0] = CService(hostname, port); 528+ return true; 529+ } 530 vAddr.resize(vIP.size()); 531 for (unsigned int i = 0; i < vIP.size(); i++) 532 vAddr[i] = CService(vIP[i], port);
i.e On a cruft with a running open tor browser you can generate v3 onions on the fly. Use ` bitcoin-qt -proxy=127.0.0.1:9150 -torcontrol=127.0.0.1:9151 -listen -onion=127.0.0.1:9150
Btw the tor browser like Orbot sits at 9150/9151 not 9050/9051 Note, if the bugfix #19358 gets merged bitcoin-qt -proxy=127.0.0.1:9150 -torcontrol=127.0.0.1:9151 -listen is sufficient and more intuitive. since you want to do a proxy onion outbound and hidden inbound edit: with adding -onlynet=onion -dns=0 and -dnsseed=0 your onion v3 test will stay in tor and not touch the tor ipv4 exitnodes to ping hello to the seeders.
-
Saibato force-pushed on Jul 12, 2020
-
Saibato renamed this:
torcontrol: Add V3 ED25519-V3 onions.
torcontrol: Create also a V3 ed25519-V3 onion address.
on Jul 13, 2020 -
laanwj commented at 12:12 pm on July 15, 2020: member
Concept ACK. I thought about advertising both kinds of addresses for a bit and I think it does make sense. Tor that is unable to connect to v3 addresses is sufficiently old that running it is a security risk in itself, so that’s not a valid reason to keep suporting v2 addresses, However with regard to advertising on the bitcoin P2P network it makes sense during the transition period to
addrv2
, becuase older node versions won’t be able to receive (and thus use) the new Tor addresses.At some point in the future when everyone supports bitcoin addrv2 mesages, we could stop creating and advertising a Tor v2 address.
-
jonatack commented at 4:30 am on July 20, 2020: memberConcept ACK. Would you mind adding test coverage (and perhaps clang-format the changes)?
-
Saibato force-pushed on Jul 23, 2020
-
Saibato commented at 10:52 am on July 23, 2020: contributorfixup-update: clang-format source
-
luke-jr changes_requested
-
luke-jr commented at 8:17 pm on July 29, 2020: member
I find this code hard to follow.
I think you should abstract the hidden service out of TorController, and have one for each of v2/v3.
-
DrahtBot added the label Needs rebase on Jul 30, 2020
-
Saibato force-pushed on Jul 30, 2020
-
Saibato force-pushed on Jul 30, 2020
-
DrahtBot removed the label Needs rebase on Jul 30, 2020
-
Rspigler commented at 5:21 pm on July 31, 2020: contributor
Tor is planning to deprecate v2 onion addresses by September 15th, no longer support by July 15th 2021 (0.4.6), and disable by October 15th 2021.
-
Saibato force-pushed on Jul 31, 2020
-
Saibato commented at 6:55 pm on July 31, 2020: contributor
Tor is planning to deprecate v2 onion addresses by September 15th, no longer support by July @Rspigler yes we have some work here, the plan was to have from now on v3 and v2 in parallel and by that allow easy testing the transition. And then fade out v2 by change v3 to default. And then way later refactor.
-
DrahtBot added the label Needs rebase on Aug 9, 2020
-
torcontrol: Create also a v3 ed25519-V3 service address.
If the Tor version supports this, from now on we also create also ED25519-V3 in torcontrol.
-
Saibato force-pushed on Aug 15, 2020
-
Saibato commented at 12:38 pm on August 15, 2020: contributor
-
DrahtBot removed the label Needs rebase on Aug 15, 2020
-
laanwj closed this on Sep 30, 2020
-
Saibato commented at 11:00 am on October 1, 2020: contributor
I’m closing this in favor of #19954, which seems to include the same behvavior.
It does not, when 19954 get merged as is, some old Tor only nodes will startup if updated without v2 and will not be reachable for some time inbound, before there new v3 is widely known AFAICS u and @Sjors where in favor of a dual stack i.e. with option to select for some time, but what is partly acked now is a plain v3 and has the potential as i was wary all the time to let old not updated nodes behind and unable to connect to there used known nodes and force thereby a kind of softfork, when we merge this as is and not provide the same functionality as before at least optional for some time.
Btw. At least i know now that mastodon Avatar is not a bot, ;-)
-
Sjors commented at 12:32 pm on October 1, 2020: memberI’m not opposed to dual stack. It might be worth discussing in a separate issue / PR. But it generally takes a while for people to upgrade their Bitcoin node, so I suspect there’ll be plenty of v2 nodes left when that’s shut down.
-
Saibato commented at 2:10 pm on October 1, 2020: contributor
I’m not opposed to dual stack. It might be worth discussing in a separate issue / PR
But, this PR here is a dual stack and provides Tor v2 and v3 in parallel and @vasild what is so complicated to just grab from here and do this from day one? So that i can close this here. I could live with this better if u could also add an option -useonlyv3service, that we then deprecate later to default, for those who know the dire implications, if they have a solely v3 node created on startup by the service call now, :woman_shrugging: @laanwj This whole thing might not be hanging that high, when we would not have the long awaited TAPROOT in the pipeline and then, in my view, we will have a lot of nodes that seek or hope for privacy might want to update fast.
So before -onlynet=onion is also respected outbound and seeders add also there v3 addresses to chainparsms.cpp instead of using outbound there FQDN over Tor exit nodes to bootstrap onion nodes, i will not consent.
I hoped since i addressed that and other Tor related problems now in multiple PR’s that one of the core team silent picks this up and does the right thing, but if nothing happens over month that;s also a message.
If u ask users ( and also some core members ) if there onion bootstrap is in Tor, i guess most will say sure because seeding is just over DNS UDP and that is not possible over Tor, so they believe that, but in fact what Bitcoin does is making outbound plain ipv4 calls to the seeders real nodes over the exit nodes to bootstrap pure onion nodes. So a. some doxing here and b. how many honest exit nodes are out there, that give u correct ADDR/ADDVv2 response messages?
Not even talking here about v3 Edwards and what that means for onions created over the service api, AFAICS we have here some profound misconceptions how Tor has changed from v2 to v3 and is about to change. imho.
We have socks5 name services and not socks4 and so one could have had just add .onion or FQDN as long domain names and relay them in simple messages to other nodes they then can or can not over socks5 proxy’s call the nodes outbound like any ip. btw that will be funny with i2p, good luck to create an “outbound” socks5 proxy relay for i2p ( maybe in java?) to even compare i2p with Tor is btw a joke imo.
To use only ip in ADDR messages in the original design, was to make sure there is no DNS like or address translation that can be tampered, since Satoshis probably knew that u can not stop the INTERNET (TCP/IP) but u can hijack DNS,Tor,i2p etc.?
The way the architecture seams to want to progress forward and is now in parts moved from the first design. is to treat other forms of transports also like IP addresses, but that is utterly wrong since those “addresses names” do not even exist without outbound/inbound proxy’s or programs and “address name” to IP directory’s, they are more like DNS names and can easy be hooked or hijacked and worse the ones that seek privacy might be the ones that easy end up on a premined alternative chain that verify;s “correctly” and reports there hooked balances correct on the screen and RPC but has nothing to do with the original chain.
BTW: In no way, when i do “not” comment on other PR’s, that does mean approve or that i even have red a PR. Since i am independent of anyone on this planet, an ACK is an ACK and if there is no ACK do not assume there is and or that i had interest in silent review bcs an PR tangent my assumed interests and just forgot to ACK or comment. DYOR verify not trust ;-)
-
Saibato commented at 2:03 pm on January 10, 2021: contributor
Probably no one ever reads that, but I still can only urge to have a dual stack as long as possible and all issues in Tor V3 are fixed and proven mature stable. The effect on the consensus is a know issue but who knows what else is there not disclosed yet. Don’t be reckless.
First 2021 full V3 Tor address outage. -
Rspigler commented at 10:35 pm on January 10, 2021: contributorI agree that having
peers.dat
backwards incompatible seems less of a conservative approach than is usually taken. A dual stack (advertising both addresses) seems supported by @laanwj (https://github.com/bitcoin/bitcoin/pull/19485#issuecomment-658731686) as well. -
vasild commented at 10:32 am on January 11, 2021: member
With current
master
, one can have his node behind the old, Tor v2 address by:- Configure the onion service in
torrc
and run bitcoind with-listenonion=0 -bind=127.0.0.1:8334=onion
,torrc
:
0HiddenServiceDir /var/db/tor/bitcoind-torv2/ 1HiddenServiceVersion 2 2HiddenServicePort 8333 127.0.0.1:8334
or
- Copy the old (v2)
onion_private_key
overonion_v3_private_key
- Configure the onion service in
-
jonatack commented at 12:58 pm on January 11, 2021: member
FWIW, the 0.21 release notes draft is at https://github.com/bitcoin-core/bitcoin-devwiki/wiki/0.21.0-Release-Notes-Draft and currently states:
“The Tor onion service that is automatically created by setting the -listenonion configuration parameter will now be created as a Tor v3 service instead of Tor v2. The private key that was used for Tor v2 (if any) will be left untouched in the onion_private_key file in the data directory (see -datadir) and can be removed if not needed. Bitcoin Core will no longer attempt to read it. The private key for the Tor v3 service will be saved in a file named onion_v3_private_key. To use the deprecated Tor v2 service (not recommended), the onion_private_key can be copied over onion_v3_private_key, e.g. cp -f onion_private_key onion_v3_private_key. (#19954)”
The wiki is publicly editable if anyone feels it could be more clear or complete.
-
Saibato commented at 2:48 pm on January 11, 2021: contributor
With current master, one can have his node behind the old, Tor v2 address by:
sure, most experienced user will have Tor anyway defined pure in torrc.and use multiple externalip= and addnode in conf and not expose the Tor service api anyway.
But if the mantra is that average Joe must not get screwed and not run into i..e. eclipse like things, we should keep v2 also in torcontrol as long as possible, 64 bit brute is cheap in reach and v2 address have also other problems but at least they work for ppl / nodes who just need to tunnel easy behind NAT’s and serve from there i.e. phones and termuxe’s or VM’s and do not care much about privacy. They often use things out of the box with standard settings.
btw for instance in c-LNs Tor implementation we have an option to let at least the user decide what kind of auto onion he wants to have and we can use v3 whiteout clamping the key that generates the address by user defined blobs.or derive them from the node key and also on softreboots we can easy create new addresses while keeping the old ones what is anyway a good idea for v3 until it is mature
-
sipa commented at 9:15 pm on January 11, 2021: memberI don’t think there is anything to do here. By the time current master is released, TorV2 will be dead and gone.
-
Saibato commented at 9:48 am on January 12, 2021: contributor
I don’t think there is anything to do here. By the time current master is released, TorV2 will be dead and gone.
I know they say i am hard to understand and often vage.but let me repharse with no intend of if a than b I don’t and will not.
But, if u don;t Ithink there is anything to do here. By the time v0.21.0 is released, TorV3 will be dead and gone.
-
sipa commented at 3:32 pm on January 12, 2021: memberCurrent master will become 22.0. 0.21.0 will be out imminently.
-
Saibato commented at 5:02 pm on January 12, 2021: contributor
0.21.0 will be out imminently.
rc6 anyway…?
btw we should skip 22 and 23 to obvious or misleading how about 24,0?
-
deadalnix referenced this in commit 4adf771f68 on Feb 9, 2021
-
DrahtBot locked this on Aug 16, 2022
This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-18 12:12 UTC
More mirrored repositories can be found on mirror.b10c.me