Resolve Tor control plane address #22288

pull adriansmares wants to merge 1 commits into bitcoin:master from adriansmares:feature/tor-control-dns-resolve changing 1 files +15 −8
  1. adriansmares commented at 11:15 AM on June 20, 2021: none

    Closes #22236

    This PR forces the Tor control plane address to be resolved before a connection attempt is made, similar to how the -proxy / -onion address is resolved.

    The use case for this change is that the control plane may not have a stable address - in a containerized environment perhaps.

  2. DrahtBot added the label P2P on Jun 20, 2021
  3. unknown approved
  4. unknown commented at 2:17 PM on June 20, 2021: none

    ACK https://github.com/bitcoin/bitcoin/pull/22288/commits/5ed8657cf7c17fb1bc15bfa6ec0f1ab9fe28ec18

    Tested this branch on POP!_OS with:

    $ cat /etc/hosts
    127.0.0.1	localghost
    
    $ cat .bitcoin/bitcoin.conf
    torcontrol=localghost:9051
    

    Confirmed that it fails on master branch with error:

    tor: Error parsing socket address localghost:9051
    tor: Initializing connection to Tor Control Port localghost:9051 failed
    
  5. Zero-1729 approved
  6. Zero-1729 commented at 4:21 PM on June 20, 2021: contributor

    tACK 5ed8657

    Tested branch on MacOS 11.3.1.

    Used the following configurations in the /etc/hosts/ and bitcoin.conf files respectively:

    $ cat /etc/hosts
    127.0.0.1   	zerohost
    
    $ cat bitcoin.conf
    torcontrol=zerohost:9051
    

    I got the following errors on master (as expected):

    tor: Error parsing socket address zerohost:9051
    tor: Initiating connection to Tor control port zerohost:9051 failed
    

    After this patch, the errors are no longer reported, and the tor connections are established.

    Nice first-time contribution and a warm welcome @adriansmares as a contributor! ;)

  7. in src/torcontrol.cpp:140 in 5ed8657cf7 outdated
     141 | -        (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) {
     142 | -        LogPrintf("tor: Error parsing socket address %s\n", tor_control_center);
     143 | +
     144 | +    CService control_service;
     145 | +    if (!Lookup(tor_control_center, control_service, 9051, fNameLookup)) {
     146 | +        LogPrintf("tor: Failed to lookup control center %s\n", tor_control_center.c_str());
    


    jonatack commented at 4:36 PM on June 20, 2021:

    The verb form is "look up".

            LogPrintf("tor: Failed to look up control center %s\n", tor_control_center.c_str());
    
  8. in src/torcontrol.cpp:146 in 5ed8657cf7 outdated
     147 | +        return false;
     148 | +    }
     149 | +
     150 | +    struct sockaddr_storage control_address;
     151 | +    socklen_t control_address_len = sizeof(sockaddr);
     152 | +    if (!control_service.GetSockAddr((struct sockaddr*)&control_address, &control_address_len)) {
    


    jonatack commented at 4:42 PM on June 20, 2021:

    while retouching this, could use a named cast (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es49-if-you-must-use-a-cast-use-a-named-cast)

        if (!control_service.GetSockAddr(reinterpret_cast<struct sockaddr*>(&control_address), &control_address_len)) {
    
  9. in src/torcontrol.cpp:161 in 5ed8657cf7 outdated
     157 | @@ -153,8 +158,8 @@ bool TorControlConnection::Connect(const std::string& tor_control_center, const
     158 |      this->disconnected = _disconnected;
     159 |  
     160 |      // Finally, connect to tor_control_center
     161 | -    if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) {
     162 | -        LogPrintf("tor: Error connecting to address %s\n", tor_control_center);
     163 | +    if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&control_address, control_address_len) < 0) {
    


    jonatack commented at 4:45 PM on June 20, 2021:

    idem

        if (bufferevent_socket_connect(b_conn, reinterpret_cast<struct sockaddr*>(&control_address), control_address_len) < 0) {
    
  10. in src/torcontrol.cpp:136 in 5ed8657cf7 outdated
     133 | @@ -134,12 +134,17 @@ bool TorControlConnection::Connect(const std::string& tor_control_center, const
     134 |  {
     135 |      if (b_conn)
     136 |          Disconnect();
    


    jonatack commented at 4:54 PM on June 20, 2021:

    Don't hesitate to fix this if you retouch (per doc/developer-notes.md about code style for conditionals)

    -    if (b_conn)
    +    if (b_conn) {
             Disconnect();
    +    }
    
  11. jonatack commented at 4:54 PM on June 20, 2021: member

    Concept ACK, thanks for looking into this.

  12. adriansmares requested review from jonatack on Jun 20, 2021
  13. in src/torcontrol.cpp:164 in 0d492da526 outdated
     169 |  
     170 |      // Finally, connect to tor_control_center
     171 | -    if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) {
     172 | -        LogPrintf("tor: Error connecting to address %s\n", tor_control_center);
     173 | +    if (bufferevent_socket_connect(b_conn, reinterpret_cast<struct sockaddr*>(&control_address), control_address_len) < 0) {
     174 | +        LogPrintf("tor: Error connecting to address %s\n", tor_control_center.c_str());
    


    jonatack commented at 5:28 PM on June 20, 2021:

    Untested, but ISTM you can omit the 3 uses of c_str()

    <details><summary>diff</summary><p>

    diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
    index 4a56159228..dcb2175c94 100644
    --- a/src/torcontrol.cpp
    +++ b/src/torcontrol.cpp
    @@ -138,14 +138,14 @@ bool TorControlConnection::Connect(const std::string& tor_control_center, const
     
         CService control_service;
         if (!Lookup(tor_control_center, control_service, 9051, fNameLookup)) {
    -        LogPrintf("tor: Failed to look up control center %s\n", tor_control_center.c_str());
    +        LogPrintf("tor: Failed to look up control center %s\n", tor_control_center);
             return false;
         }
     
         struct sockaddr_storage control_address;
         socklen_t control_address_len = sizeof(sockaddr);
         if (!control_service.GetSockAddr(reinterpret_cast<struct sockaddr*>(&control_address), &control_address_len)) {
    -        LogPrintf("tor: Error parsing socket address %s\n", tor_control_center.c_str());
    +        LogPrintf("tor: Error parsing socket address %s\n", tor_control_center);
             return false;
         }
     
    @@ -161,7 +161,7 @@ bool TorControlConnection::Connect(const std::string& tor_control_center, const
     
         // Finally, connect to tor_control_center
         if (bufferevent_socket_connect(b_conn, reinterpret_cast<struct sockaddr*>(&control_address), control_address_len) < 0) {
    -        LogPrintf("tor: Error connecting to address %s\n", tor_control_center.c_str());
    +        LogPrintf("tor: Error connecting to address %s\n", tor_control_center);
             return false;
         }
    

    </p></details>

    (Optional, you'll save time by squashing the commits after each update, to the final version for review.)


    adriansmares commented at 5:36 PM on June 20, 2021:

    Indeed, I see now LogPrintf is based on templates, not untyped varargs.

  14. jrawsthorne approved
  15. jrawsthorne commented at 9:50 PM on June 20, 2021: none

    tACK 809d02044957b55a2869c0da71ff57656f53ffe4

    Thanks for looking into this. This change fixes my original issue

  16. Zero-1729 commented at 6:31 AM on June 21, 2021: contributor

    re-ACK 809d02044957b55a2869c0da71ff57656f53ffe4

  17. jonatack commented at 1:13 PM on June 21, 2021: member

    ACK 809d02044957b55a2869c0da71ff57656f53ffe4 tested various configurations on signet with this branch versus master

  18. in src/torcontrol.cpp:146 in 809d020449 outdated
     147 | +        LogPrintf("tor: Failed to look up control center %s\n", tor_control_center);
     148 | +        return false;
     149 | +    }
     150 | +
     151 | +    struct sockaddr_storage control_address;
     152 | +    socklen_t control_address_len = sizeof(sockaddr);
    


    theStack commented at 5:09 PM on June 27, 2021:
        struct sockaddr_storage control_address;
        socklen_t control_address_len = sizeof(control_address);
    
  19. theStack changes_requested
  20. theStack commented at 5:24 PM on June 27, 2021: member

    Concept ACK

    Welcome as a new contributor adriansmares! 🎉

    Note that on the PR branch connecting to a IPv6 Tor control port doesn't work anymore:

    $ ./src/bitcoind -torcontrol=::1:9051
    ...
    tor: Error parsing socket address ::1:9051
    tor: Initiating connection to Tor control port ::1:9051 failed
    ...
    

    Looking a bit deeper into the problem, it seems like the address length passed to GetSockAddr() is too small (16 bytes on my machine), leading to the failure. On all other places in the codebase, sizeof(sockaddr) refers to the size of an sockaddr_storage instance (always defined one line above), whereas in this case it takes the size of the sockaddr structure. See fix below.

  21. torcontrol: Resolve Tor control plane address cdd51e8ee1
  22. adriansmares requested review from theStack on Jun 27, 2021
  23. theStack approved
  24. theStack commented at 6:05 PM on June 27, 2021: member

    ACK cdd51e8ee156f3bb3135be8aa51530a53734153e 🪐 Tested on Debian bullseye/sid by running ./src/bitcoind -torcontrol=localhost:9051 twice, once with localhost set to 127.0.0.1 in /etc/hosts, once set to ::1.

  25. luke-jr referenced this in commit 37fbbac6b9 on Jun 27, 2021
  26. jonatack commented at 1:03 PM on June 28, 2021: member

    @theStack nice catch.

    ACK cdd51e8ee156f3bb3135be8aa51530a53734153e tested various configurations on signet with this branch versus master

  27. unknown approved
  28. unknown commented at 6:47 PM on July 2, 2021: none

    Looking a bit deeper into the problem, it seems like the address length passed to GetSockAddr() is too small (16 bytes on my machine), leading to the failure

    Good observation.

    ACK https://github.com/bitcoin/bitcoin/pull/22288/commits/cdd51e8ee156f3bb3135be8aa51530a53734153e

    Confirmed it works for ipv6 as well

  29. laanwj commented at 10:17 AM on July 21, 2021: member

    One argument for not using DNS in the case of Tor is to prevent DNS leaks. I don't think this change, in itself, adds any extra risk of that though (as it only looks up the control host, which hopefully is local).

    LGTM ACK cdd51e8ee156f3bb3135be8aa51530a53734153e

  30. laanwj merged this on Jul 21, 2021
  31. laanwj closed this on Jul 21, 2021

  32. adriansmares deleted the branch on Jul 21, 2021
  33. sidhujag referenced this in commit fd10b9caec on Jul 23, 2021
  34. schildbach commented at 3:06 PM on October 15, 2021: contributor

    I'm currently running into this issue of the Tor control address not being resolved, as I have set up Tor within a separate Docker container. Unfortunately, this PR doesn't seem to have made it into 22.0. Does someone know a quick workaround to deal with the dynamically changing IP address, until a 22.1 is released?

    I could go back to managing the hidden service within Tor (and not use a control port) as I have done in the past, but actually I'd prefer to hand over control to bitcoind.

  35. schildbach commented at 7:17 PM on October 27, 2021: contributor

    Should this be considered for backporting to 22.x?

  36. DrahtBot locked this on Oct 30, 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: 2026-04-13 18:14 UTC

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