New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
torcontrol: Create also a V3 ed25519-V3 onion address. #19485
Conversation
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... ? 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.
This PR create both V2 and V3 in one sweep. |
I don't know why it wouldn't need a BIP... it's a protocol change at the p2p layer still. |
So then we propose this ? 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. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
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 supportdiff --git a/src/addrman.h b/src/addrman.h
index 8e82020df..4a810e53f 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -61,6 +61,7 @@ public:
SERIALIZE_METHODS(CAddrInfo, obj)
{
READWRITEAS(CAddress, obj);
+ READWRITEAS(CNetAddr, obj);
READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
}
diff --git a/src/net.cpp b/src/net.cpp
index 244b0094d..36af03d33 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -156,6 +156,7 @@ static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn
struct in6_addr ip;
memcpy(&ip, seed_in.addr, sizeof(ip));
CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE));
+ LogPrintf("seeds %s\n", CNetAddr(addr).ToString());
addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
vSeedsOut.push_back(addr);
}
@@ -368,6 +369,9 @@ static CAddress GetBindAddress(SOCKET sock)
return addr_bind;
}
+static CAddress getadrr(std::string name) {
+ return CAddress(CService(name,18444), NODE_NONE);
+}
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only)
{
if (pszDest == nullptr) {
@@ -384,16 +388,23 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
}
/// debug print
- LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
- pszDest ? pszDest : addrConnect.ToString(),
+ LogPrint(BCLog::NET, "trying connection %s unresolved address %s lastseen=%.1fhrs\n",
+ pszDest ? pszDest:"", addrConnect.ToString(),
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
+ std::string strName = std::string( pszDest ? pszDest:"");
// Resolve
const int default_port = Params().GetDefaultPort();
if (pszDest) {
std::vector<CService> resolved;
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
+
+ // dont resolv local the onions
+ if (!strName.find(".onion")) {
+
addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
+
+
if (!addrConnect.IsValid()) {
LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
return nullptr;
@@ -410,6 +421,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
LogPrintf("Failed to open new connection, already connected\n");
return nullptr;
}
+ }
}
}
@@ -417,7 +429,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
bool connected = false;
SOCKET hSocket = INVALID_SOCKET;
proxyType proxy;
- if (addrConnect.IsValid()) {
+ if (addrConnect.IsValid() && addrConnect.IsTor() && !pszDest) {
bool proxyConnectionFailed = false;
if (GetProxy(addrConnect.GetNetwork(), proxy)) {
@@ -425,14 +437,21 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (hSocket == INVALID_SOCKET) {
return nullptr;
}
- connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed);
+
+ if (addrConnect.ToStringIP() != "") {
+ connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, proxyConnectionFailed);
+ } else return nullptr;
+
} else {
- // no proxy needed (none set for target network)
+ // no proxy needed (none set for tastrName.find(".onion")rget network)
hSocket = CreateSocket(addrConnect);
if (hSocket == INVALID_SOCKET) {
return nullptr;
}
- connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
+
+ if (addrConnect.ToString() != "") {
+ connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
+ } else return nullptr;
}
if (!proxyConnectionFailed) {
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
@@ -444,14 +463,24 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (hSocket == INVALID_SOCKET) {
return nullptr;
}
+
std::string host;
int port = default_port;
SplitHostPort(std::string(pszDest), port, host);
bool proxyConnectionFailed;
- connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed);
+ connected = false;
+ //proxyConnectionFailed = true;
+
+
+ if (strlen(pszDest) > 0) //strName.find(".onion"))
+ {
+ LogPrintf("Address to connect over proxz %s %d\n", host, port);
+ connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, proxyConnectionFailed);
+ } else return nullptr;
+
}
if (!connected) {
- CloseSocket(hSocket);
+ if (hSocket) CloseSocket(hSocket);
return nullptr;
}
@@ -1705,17 +1734,6 @@ void CConnman::ThreadDNSAddressSeed()
LogPrintf("%d addresses found from DNS seeds\n", found);
}
-
-
-
-
-
-
-
-
-
-
-
void CConnman::DumpAddresses()
{
int64_t nStart = GetTimeMillis();
@@ -2057,6 +2075,8 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
}
} else if (FindNode(std::string(pszDest)))
return;
+ // will "":port ever work?
+ if(!pszDest && (addrConnect.ToStringIP() == "")) return;
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection, block_relay_only);
@@ -2756,6 +2776,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
// peers (to prevent adversaries from inferring these links from addr
// traffic).
m_addr_known{block_relay_only ? nullptr : MakeUnique<CRollingBloomFilter>(5000, 0.001)},
+
id(idIn),
nLocalHostNonce(nLocalHostNonceIn),
nLocalServices(nLocalServicesIn),
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index bfc60b18f..ecd83188e 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -2454,14 +2454,47 @@ void ProcessMessage(
std::vector<CAddress> vAddrOk;
int64_t nNow = GetAdjustedTime();
int64_t nSince = nNow - 10 * 60;
+ int i = 0;
+ size_t len = 10;
+ CAddress Tor = CAddress(vAddr[0]);
+ char rawaddr[256] = {};
+
for (CAddress& addr : vAddr)
{
if (interruptMsgProc)
return;
+ if (addr.IsTorSequence(i)) {
+ if (i == 0 ) {
+ // LogPrintf("Adrress addr V3 raw rec =");
+ Tor = addr;
+ }
+ //V3sequence())
+ addr.SetSpecial_v3(addr, 256); //fill hostdata from ip;
+ memcpy(&rawaddr[i*10], &addr.fqdn.c_str()[0], 10);
+ i++;
+ if (i != 8) {
+ continue;
+ }
+ } else addr.fqdn = {};
+
+ //LogPrintf("\nAdrress add raw? %s\n", &rawaddr[0]);
+
+ if (i == 8) {
+ Tor.SetSpecial_v3(addr, 255); // set clasic tor flag
+ Tor.fqdn = rawaddr;
+ if ( i == 8 ) Tor.fqdn = rawaddr;
+ addr = Tor;
+ }
+
+ if (addr.IsTor() && strlen(addr.fqdn.c_str()) < 32) addr.SetSpecial_v3(addr, 255); // v2 stzle
+ LogPrint(BCLog::NET, "Adrress add? %s\n", addr.ToString());
+
+
// We only bother storing full nodes, though this may include
// things which we would not make an outbound connection to, in
// part because we may make feeler connections to them.
+
if (!MayHaveUsefulAddressDB(addr.nServices) && !HasAllDesirableServiceFlags(addr.nServices))
continue;
@@ -3901,12 +3934,25 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
std::vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
assert(pto->m_addr_known);
+ CAddress addr_add;
for (const CAddress& addr : pto->vAddrToSend)
{
if (!pto->m_addr_known->contains(addr.GetKey()))
{
pto->m_addr_known->insert(addr.GetKey());
- vAddr.push_back(addr);
+ if (!addr.IsTor()) vAddr.push_back(addr);
+ if (addr.IsTor()) LogPrint(BCLog::NET, "Try to send onion address = %s\n", addr.fqdn);
+
+ if (addr.IsTor() && strlen(addr.fqdn.c_str()) > 32) {
+ for (int i=0;i<8;i++) {
+ addr_add = addr;
+ addr_add.SetSpecial_v3(addr, (i)*10);
+
+ vAddr.push_back(addr_add);
+
+ }
+ } else vAddr.push_back(addr); //v2 tor
+
// receiver rejects addr messages larger than 1000
if (vAddr.size() >= 1000)
{
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 674439161..8c8bad0f8 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -5,13 +5,17 @@
#include <cstdint>
#include <netaddress.h>
+#include <netbase.h>
+
#include <hash.h>
#include <util/strencodings.h>
#include <util/asmap.h>
#include <tinyformat.h>
+#include <util/system.h>
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
+static const unsigned char pchOnionSeq[] = {0xFD,'l','o','r','3',0x00};
// 0xFD + sha256("bitcoin")[0:5]
static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 };
@@ -47,6 +51,11 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
}
}
+void CNetAddr::SetRawByte(char p , int pos)
+{
+ ip[6+pos] = p;
+}
+
/**
* Try to make this a dummy address that maps the specified name into IPv6 like
* so: (0xFD + %sha256("bitcoin")[0:5]) + %sha256(name)[0:10]. Such dummy
@@ -70,6 +79,7 @@ bool CNetAddr::SetInternal(const std::string &name)
CSHA256().Write((const unsigned char*)name.data(), name.size()).Finalize(hash);
memcpy(ip, g_internal_prefix, sizeof(g_internal_prefix));
memcpy(ip + sizeof(g_internal_prefix), hash, sizeof(ip) - sizeof(g_internal_prefix));
+ fqdn = name;
return true;
}
@@ -83,20 +93,51 @@ bool CNetAddr::SetInternal(const std::string &name)
*
* @see CNetAddr::IsTor(), CNetAddr::IsRFC4193()
*/
-bool CNetAddr::SetSpecial(const std::string &strName)
+bool CNetAddr::SetSpecial(const std::string &strName, int flag)
{
if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
- std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
- if (vchAddr.size() != 16-sizeof(pchOnionCat))
+ std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(flag*10, strName.size() - 6).c_str());
+ if (vchAddr.size() != 16-sizeof(pchOnionCat) && vchAddr.size() != 35)
return false;
memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++)
ip[i + sizeof(pchOnionCat)] = vchAddr[i];
+ fqdn = strName;
+ LogPrint(BCLog::NET, "setspecail called with %s %d\n", strName, flag);
return true;
}
return false;
}
+bool CNetAddr::SetSpecial_v3(CNetAddr ref , int flag)
+{
+ //fqdn.resize(256);
+ std::string cp = ref.fqdn;
+ cp.resize(256);
+ if( flag < 254 ) { memcpy(ip, pchOnionSeq, sizeof(pchOnionSeq));
+ for (unsigned int i=0; i<16-sizeof(pchOnionSeq); i++) {
+ ip[i + sizeof(pchOnionSeq)] = cp.c_str()[flag+i];
+ }
+ fqdn = cp.substr(flag,10);
+ }
+ if (flag == 255) { // backward comp
+ std::string name = EncodeBase32(&ip[6], 10) + ".onion";
+ fqdn = name;
+ }
+ if (flag == 256) {
+ for (unsigned int i=0; i<16-sizeof(pchOnionSeq); i++) {
+ fqdn[i] = char(ip[i + sizeof(pchOnionSeq)]);
+ }
+ }
+ return true;
+}
+
+CNetAddr::CNetAddr(const std::string &strName)
+{
+ SetSpecial(strName);
+ LogPrint(BCLog::NET, "CNetAddr internal setspecail called from addr by name\n");
+}
+
CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
{
SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
@@ -224,7 +265,15 @@ bool CNetAddr::IsHeNet() const
*/
bool CNetAddr::IsTor() const
{
- return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
+ return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0) || IsTorSequence(0x0);
+}
+
+/**
+ * @see CNetAddr::SetSpecial(const std::string &)
+ */
+bool CNetAddr::IsTorSequence(char seq) const
+{
+ return memcmp(ip, pchOnionSeq, sizeof(pchOnionSeq)) == 0;
}
bool CNetAddr::IsLocal() const
@@ -333,8 +382,9 @@ enum Network CNetAddr::GetNetwork() const
std::string CNetAddr::ToStringIP() const
{
- if (IsTor())
- return EncodeBase32(&ip[6], 10) + ".onion";
+ if (IsTor()) {
+ return fqdn;
+ }
if (IsInternal())
return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal";
CService serv(*this, 0);
@@ -640,6 +690,10 @@ CService::CService(const struct in6_addr& ipv6Addr, uint16_t portIn) : CNetAddr(
{
}
+CService::CService(const std::string fqdn, uint16_t portIn) : CNetAddr(fqdn), port(portIn)
+{
+}
+
CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
{
assert(addr.sin_family == AF_INET);
diff --git a/src/netaddress.h b/src/netaddress.h
index c20101215..e18cc31a1 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -38,16 +38,18 @@ class CNetAddr
CNetAddr();
explicit CNetAddr(const struct in_addr& ipv4Addr);
void SetIP(const CNetAddr& ip);
+ std::string fqdn = {};
/**
* Set raw IPv4 or IPv6 address (in network byte order)
- * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
+ * @note void SetRawBytes(const uint8_t *ip_in);Only NET_IPV4 and NET_IPV6 are allowed for network.
*/
void SetRaw(Network network, const uint8_t *data);
-
+ void SetRawByte(char b, int pos);
bool SetInternal(const std::string& name);
- bool SetSpecial(const std::string &strName); // for Tor addresses
+ bool SetSpecial_v3(CNetAddr ref , int flag); // for Tor addresses
+ bool SetSpecial(const std::string &strName, int flag = 0);
bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
@@ -67,6 +69,7 @@ class CNetAddr
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)
bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
bool IsTor() const;
+ bool IsTorSequence(char pseq) const;
bool IsLocal() const;
bool IsRoutable() const;
bool IsInternal() const;
@@ -94,13 +97,14 @@ class CNetAddr
int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
+ CNetAddr(const std::string &strName);
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); }
friend bool operator<(const CNetAddr& a, const CNetAddr& b);
- SERIALIZE_METHODS(CNetAddr, obj) { READWRITE(obj.ip); }
+ SERIALIZE_METHODS(CNetAddr, obj) { READWRITE(obj.ip, obj.fqdn); }
friend class CSubNet;
};
@@ -144,7 +148,8 @@ class CService : public CNetAddr
public:
CService();
CService(const CNetAddr& ip, uint16_t port);
- CService(const struct in_addr& ipv4Addr, uint16_t port);
+ CService(const struct in_addr& ipv4Addr, uint16_t port);;
+ CService(const std::string, uint16_t port);
explicit CService(const struct sockaddr_in& addr);
uint16_t GetPort() const;
bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 3a3b5f3e6..816d66228 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -4,6 +4,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <netbase.h>
+#include <net.h>
#include <sync.h>
#include <tinyformat.h>
@@ -69,17 +70,18 @@ bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, un
return false;
}
- {
- CNetAddr addr;
- // From our perspective, onion addresses are not hostnames but rather
- // direct encodings of CNetAddr much like IPv4 dotted-decimal notation
- // or IPv6 colon-separated hextet notation. Since we can't use
- // getaddrinfo to decode them and it wouldn't make sense to resolve
- // them, we return a network address representing it instead. See
- // CNetAddr::SetSpecial(const std::string&) for more details.
- if (addr.SetSpecial(name)) {
+ CNetAddr addr;
+ // From our perspective, onion addresses are not hostnames but rather
+ // direct encodings of CNetAddr much like IPv4 dotted-decimal notation
+ // or IPv6 colon-separated hextet notation. Since we can't use
+ // getaddrinfo to decode them and it wouldn't make sense to resolve
+ // them, we return a network address representing it instead. See
+ // CNetAddr::SetSpecial(const std::string&) for more details.
+
+ if (name.find(".onion")) {
+ if (addr.SetSpecial(name,0)) {
vIP.push_back(addr);
- return true;
+ return false;
}
}
@@ -97,12 +99,19 @@ bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, un
// If we don't allow lookups, then use the AI_NUMERICHOST flag for
// getaddrinfo to only decode numerical network addresses and suppress
// hostname lookups.
- aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
+ aiHint.ai_flags = fAllowLookup && !HaveNameProxy() ? AI_ADDRCONFIG : AI_NUMERICHOST;
struct addrinfo *aiRes = nullptr;
int nErr = getaddrinfo(name.c_str(), nullptr, &aiHint, &aiRes);
- if (nErr)
- return false;
+ LogPrintf("Resolver :%s error = %d local resolve allowed %s %s\n", name.c_str() ,nErr,fAllowLookup, nErr?"fail":"local resolved");
+ if (nErr ) {
+ CNetAddr resolved;
+ resolved.SetInternal(name);
+ if (resolved.IsInternal()) {
+ vIP.push_back(resolved);
+ }
+ return false;
+ }
// Traverse the linked list starting with aiTrav, add all non-internal
// IPv4,v6 addresses to vIP while respecting nMaxSolutions.
struct addrinfo *aiTrav = aiRes;
@@ -182,7 +191,7 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup)
addr = vIP.front();
return true;
}
-
+;
/**
* Resolve a service string to its corresponding service.
*
@@ -214,8 +223,17 @@ bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefau
std::vector<CNetAddr> vIP;
bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup);
- if (!fRet)
- return false;
+ if (vIP[0].IsTor()) {
+ vAddr.resize(hostname.size());
+ vAddr[0] = CService(hostname, port);
+ return true;
+ }
+ if (!fRet) // mayby just a name and only onion we do not resovel so use tor
+ {
+ vAddr.resize(hostname.size());
+ vAddr[0] = CService(hostname, port);
+ return true;
+ }
vAddr.resize(vIP.size());
for (unsigned int i = 0; i < vIP.size(); i++)
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 Btw the tor browser like Orbot sits at 9150/9151 not 9050/9051 |
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 At some point in the future when everyone supports bitcoin addrv2 mesages, we could stop creating and advertising a Tor v2 address. |
Concept ACK. Would you mind adding test coverage (and perhaps clang-format the changes)? |
fixup-update: clang-format source |
fixup: edit@saibato |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@luke-jr yes, quite ugly and just works and in the side show comments a little bit maxwell style ;-). |
9e96284
to
7f27f95
Compare
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. |
@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. |
If the Tor version supports this, from now on we also create also ED25519-V3 in torcontrol.
rebased cb8f28a |
@jonatack In general i thnk the coder who wrote a feature should not write the test. There is a. lot of success bias and b. "Most makers are bad breakers", 💇♀️ |
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 Btw. At least i know now that mastodon Avatar is not a bot, ;-) |
I'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. |
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? @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. 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, |
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. |
I agree that having |
With current
or
|
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. |
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. 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 |
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. |
Current master will become 22.0. 0.21.0 will be out imminently. |
rc6 anyway...? btw we should skip 22 and 23 to obvious or misleading how about 24,0? |
Summary: ``` Move the class `HasReason` from `miner_tests.cpp` to `setup_common.h` so that it can be reused by other tests. ``` Partial backport (2/4) of core [[bitcoin/bitcoin#19485 | PR19485]]: bitcoin/bitcoin@fe42411 Depends on D9186. Test Plan: ninja check-bitcoin-miner_tests Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D9187
While 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.