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
  1. Saibato commented at 3:55 pm on July 10, 2020: contributor
    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.
  2. fanquake added the label P2P on Jul 10, 2020
  3. 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?

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. Saibato force-pushed on Jul 12, 2020
  10. Saibato renamed this:
    torcontrol: Add V3 ED25519-V3 onions.
    torcontrol: Create also a V3 ed25519-V3 onion address.
    on Jul 13, 2020
  11. 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.

  12. jonatack commented at 4:30 am on July 20, 2020: member
    Concept ACK. Would you mind adding test coverage (and perhaps clang-format the changes)?
  13. Saibato force-pushed on Jul 23, 2020
  14. Saibato commented at 10:52 am on July 23, 2020: contributor
    fixup-update: clang-format source
  15. Saibato commented at 6:14 pm on July 28, 2020: contributor

    fixup: Add -ephemeraltoronion option,to generate v3 onions that are ADDRv2 prepared. Now we can generate ephemeral tor v3 onion addresses on node reboot.

    edit@saibato Now a single PR #19635

  16. luke-jr changes_requested
  17. 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.

  18. Saibato commented at 9:31 am on July 30, 2020: contributor
    @luke-jr yes, quite ugly and just works and in the side show comments a little bit maxwell style ;-).
  19. DrahtBot added the label Needs rebase on Jul 30, 2020
  20. Saibato force-pushed on Jul 30, 2020
  21. Saibato force-pushed on Jul 30, 2020
  22. DrahtBot removed the label Needs rebase on Jul 30, 2020
  23. 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.

    https://blog.torproject.org/v2-deprecation-timeline

  24. Saibato force-pushed on Jul 31, 2020
  25. 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.

  26. DrahtBot added the label Needs rebase on Aug 9, 2020
  27. 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.
    cb8f28a8f8
  28. Saibato force-pushed on Aug 15, 2020
  29. DrahtBot removed the label Needs rebase on Aug 15, 2020
  30. Saibato commented at 1:23 pm on September 11, 2020: contributor

    Concept ACK. Would you mind adding test coverage … @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”, :haircut_woman:

  31. laanwj commented at 11:48 am on September 30, 2020: member
    I’m closing this in favor of #19954, which seems to include the same behvavior.
  32. laanwj closed this on Sep 30, 2020

  33. 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, ;-)

  34. Sjors commented at 12:32 pm on October 1, 2020: member
    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.
  35. 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 ;-)

  36. 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.

    https://bitcoinhackers.org/web/statuses/105531638557051583

    https://darknetdaily.com/?p=1030

  37. Rspigler commented at 10:35 pm on January 10, 2021: contributor
    I 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.
  38. 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 over onion_v3_private_key
  39. 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.

  40. 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

  41. sipa commented at 9:15 pm on January 11, 2021: member
    I don’t think there is anything to do here. By the time current master is released, TorV2 will be dead and gone.
  42. 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.

  43. sipa commented at 3:32 pm on January 12, 2021: member
    Current master will become 22.0. 0.21.0 will be out imminently.
  44. 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?

  45. deadalnix referenced this in commit 4adf771f68 on Feb 9, 2021
  46. DrahtBot locked this on Aug 16, 2022

github-metadata-mirror

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

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me