Add I2P support using I2P SAM #20685

pull vasild wants to merge 20 commits into bitcoin:master from vasild:i2p_sam changing 22 files +1304 −113
  1. vasild commented at 12:49 pm on December 17, 2020: member

    Add I2P support by using the I2P SAM protocol. Unlike Tor, for incoming connections we get the I2P address of the peer (and they also receive ours when we are the connection initiator).

    Two new options are added:

     0  -i2psam=<ip:port>
     1       I2P SAM proxy to reach I2P peers and accept I2P connections (default:
     2       none)
     3
     4  -i2pacceptincoming
     5       If set and -i2psam is also set then incoming I2P connections are
     6       accepted via the SAM proxy. If this is not set but -i2psam is set
     7       then only outgoing connections will be made to the I2P network.
     8       Ignored if -i2psam is not set. Notice that listening for incoming
     9       I2P connections is done through the SAM proxy, not by binding to
    10       a local address and port (default: true)
    

    Overview of the changes

    Make ReadBinary() and WriteBinary() reusable

    We would need to dump the I2P private key to a file and read it back later. Move those two functions out of torcontrol.cpp.

    0util: extract {Read,Write}BinaryFile() to its own files
    1util: fix ReadBinaryFile() returning partial contents
    2util: fix WriteBinaryFile() claiming success even if error occurred
    

    Split CConnman::AcceptConnection()

    Most of CConnman::AcceptConnection() is agnostic of how the socket was accepted. The other part of it deals with the details of the accept(2) system call. Split those so that the protocol-agnostic part can be reused if we accept a socket by other means.

    0net: check for invalid socket earlier in CConnman::AcceptConnection()
    1net: get the bind address earlier in CConnman::AcceptConnection()
    2net: isolate the protocol-agnostic part of CConnman::AcceptConnection()
    3net: avoid unnecessary GetBindAddress() call
    

    Implement the I2P SAM protocol (not all of it)

    Just the parts that would enable us to make outgoing and accept incoming I2P connections.

    0net: extend CNetAddr::SetSpecial() to support I2P
    1net: move the constant maxWait out of InterruptibleRecv()
    2net: dedup MSG_NOSIGNAL and MSG_DONTWAIT definitions
    3net: extend Sock::Wait() to report a timeout
    4net: extend Sock with methods for robust send & read until terminator
    5net: extend Sock with a method to check whether connected
    6net: implement the necessary parts of the I2P SAM protocol
    

    Use I2P SAM to connect to and accept connections from I2P peers

    Profit from all of the preceding commits.

    0init: introduce I2P connectivity options
    1net: add I2P to the reachability map
    2net: make outgoing I2P connections from CConnman
    3net: accept incoming I2P connections from CConnman
    4net: recognize I2P from ParseNetwork() so that -onlynet=i2p works
    5net: Do not skip the I2P network from GetNetworkNames()
    
  2. DrahtBot added the label Build system on Dec 17, 2020
  3. DrahtBot added the label Docs on Dec 17, 2020
  4. DrahtBot added the label P2P on Dec 17, 2020
  5. DrahtBot added the label RPC/REST/ZMQ on Dec 17, 2020
  6. DrahtBot added the label Utils/log/libs on Dec 17, 2020
  7. laanwj commented at 3:36 pm on December 17, 2020: member
    Awesome work, concept ACK.
  8. DrahtBot commented at 8:13 pm on December 17, 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:

    • #19461 (multiprocess: Add bitcoin-gui -ipcconnect option by ryanofsky)
    • #19460 (multiprocess: Add bitcoin-wallet -ipcconnect option by ryanofsky)
    • #19288 (fuzz: Add fuzzing harness for TorController by practicalswift)
    • #19160 (multiprocess: Add basic spawn and IPC support by ryanofsky)
    • #16365 (Log RPC parameters (arguments) if -debug=rpcparams by LarryRuane)
    • #10102 ([experimental] Multiprocess bitcoin by ryanofsky)

    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.

  9. naumenkogs commented at 9:05 am on December 18, 2020: member

    Concept ACK


    Once this is enabled, we should clearly communicate that using a non-popular overlay has privacy/security side-effects

  10. practicalswift commented at 3:09 pm on December 18, 2020: contributor

    @vasild Nice work!

    I like the abstraction (Sock) you’ve added on top of the socket API. I’m adding something similar in #19203 (see MockableSocket and FuzzedSocket) to allow for fuzzing the more low-level parts of our networking code (in this specific case a regression fuzz harness for CVE-2017-18350).

    If you have time: please check that PR out. It would be great if your socket abstraction also covered the needs of the the “fuzzed socket” use case. Ideally I’d like to implement my low-level networking code fuzzers using your socket abstraction (something along the lines of class FuzzedSock : public Sock) :)

    Aside from of the I2P work I think your socket abstraction would be valuable on a stand-alone PR basis :)

  11. in src/util/readwritefile.cpp:29 in a0dc3a2d32 outdated
    24+        if (ferror(f)) {
    25+            fclose(f);
    26+            return std::make_pair(false,"");
    27+        }
    28+        retval.append(buffer, buffer+n);
    29+    } while (!feof(f) && retval.size() <= maxsize);
    


    lontivero commented at 6:58 pm on December 27, 2020:
    Q: in case retval contains the maximum allowed data shouldn’t it get out of the loop? I mean, I know this is how the previous version of this method worked but I would like to understand why is this how it is.

    vasild commented at 8:27 am on December 29, 2020:

    Yes, it should get out of the loop and it does due to retval.size() <= maxsize.

    It is true that if maxsize==10 and fread() returns 7 bytes and then 5 bytes, this function will return a retval that contains 12 bytes, exceeding maxsize. This is also how it works in master right now.

    For the purposes of this PR it suffices to move ReadBinaryFile() out of torcontrol.cpp so that it can be reused by other code. So I tried to keep changes to the minimum - moved the function and only fixed a gross bug (commit util: fix ReadBinaryFile() returning partial contents).

  12. in src/util/readwritefile.cpp:47 in a0dc3a2d32 outdated
    42+    }
    43+    if (fclose(f) != 0) {
    44+        return false;
    45+    }
    46+    return true;
    47+}
    


    lontivero commented at 7:26 pm on December 27, 2020:

    Non-cpp programmer question: is this idiomatically valid?

     0bool WriteBinaryFile(const fs::path &filename, const std::string &data)
     1{
     2    FILE *f = fsbridge::fopen(filename, "wb");
     3    if (f == nullptr)
     4        return false;
     5    if (fwrite(data.data(), 1, data.size(), f) == data.size()) {
     6        return fclose(f) == 0;
     7    }        
     8    fclose(f);
     9    return false;
    10}
    

    vasild commented at 8:28 am on December 29, 2020:
    Yes, those are the same. I guess, when writing new code, it would be a matter of taste which one to use.
  13. in src/util/strencodings.cpp:266 in a0dc3a2d32 outdated
    261@@ -262,21 +262,22 @@ std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid)
    262         }
    263         ++p;
    264     }
    265-    valid = valid && (p - e) % 8 == 0 && p - q < 8;
    266+    const bool pad_ok = (p - e) % 8 == 0 || !require_padding;
    267+    valid = valid && pad_ok && p - q < 8;
    


    lontivero commented at 8:43 pm on December 27, 2020:
    This makes my, my=, my== and so on until my===== all equivalent. Is this ok? I would have expected partial padding to be invalid.

    lontivero commented at 8:20 pm on December 28, 2020:
    Clarification: I am asking this because if this is allow then invalid addresses could be allowed by SetSpecial, I mean, something like udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna=.b32.i2p would be okay.

    vasild commented at 1:11 pm on December 29, 2020:

    Hah, good catch! It occurred to me that we need not to support decoding base32 strings without padding in general and instead we can append ==== to the 52 chars before .b32.i2p and decode it as padded base32 string.

    This simplifies this PR as I dropped one commit from it: util: support DecodeBase32() without padding. Also, added a check that the address is 52 base32 chars since we expect that adding 4 = symbols will make it multiple of 8. You suggested such a check elsewhere.

  14. lontivero commented at 8:44 pm on December 27, 2020: contributor
    Concept ACK (great work). Just a few questions.
  15. in src/netbase.cpp:1082 in a0dc3a2d32 outdated
    1074@@ -958,3 +1075,131 @@ void InterruptSocks5(bool interrupt)
    1075 {
    1076     interruptSocks5Recv = interrupt;
    1077 }
    1078+
    1079+
    1080+static inline bool IOErrorIsPermanent(int err)
    1081+{
    1082+    return err != WSAEAGAIN && err != WSAEWOULDBLOCK && err != WSAEINTR && err != WSAEINPROGRESS;
    


    jonatack commented at 5:48 pm on December 28, 2020:
    Build warning here, logical AND of equal expressions [-Wlogical-op]

    vasild commented at 9:51 am on December 29, 2020:

    Is this on Windows? Which compiler version? Is it upset that WSAEAGAIN equals to WSAEWOULDBLOCK and so we end up doing something like err != 5 && err != 5?

    I checked that gcc 10.2.1, 9.3.0 and 8.4.0 don’t emit the warning if we do err != 5 && err != 6 && err != 5, so I just reordered the expressions as a simple fixup ro this. Will include in the next push.


    jonatack commented at 10:22 am on December 29, 2020:
    gcc Debian 10.2.1

    vasild commented at 1:00 pm on December 29, 2020:
    Fixed in f0577c4?

    jonatack commented at 4:23 pm on December 29, 2020:
    Yes, thank you – tested that it is fixed in 188ba34 and in 2ae504c
  16. DrahtBot added the label Needs rebase on Dec 28, 2020
  17. vasild force-pushed on Dec 29, 2020
  18. vasild commented at 9:40 am on December 29, 2020: member
    a0dc3a2d3…188ba34b4: rebased to resolve conflicts with master
  19. DrahtBot removed the label Needs rebase on Dec 29, 2020
  20. vasild force-pushed on Dec 29, 2020
  21. vasild commented at 12:59 pm on December 29, 2020: member

    188ba34b4…f0577c4d7:

    • disallow partial padding when decoding .b32.i2p addresses
    • fix gcc warning (hopefully)
  22. vasild force-pushed on Dec 29, 2020
  23. vasild commented at 1:27 pm on December 29, 2020: member
    f0577c4d7…2ae504c4b: allow uppercase and mixedcase I2P addresses, suggestion
  24. in src/netbase.cpp:1144 in 06286e5b83 outdated
    1140+    // at a time is about 50 times slower.
    1141+
    1142+    for (;;) {
    1143+        char buf[512];
    1144+
    1145+        const ssize_t peek_ret = recv(socket, buf, sizeof(buf), MSG_PEEK);
    


    lontivero commented at 10:14 pm on December 30, 2020:

    Time ago Winsock used to have problems with peeking from sockets. According to the KB article below (old) recv with MSG_PEEK:

    The peek operation will report the number of bytes up until the first buffer boundary. The bytes remaining in the other boundaries might never be reported, resulting in an incorrect count of data for code algorithms that depend upon the peek values to be accurate. Subsequent peek attempts will not reveal the “hidden” data, which can still be received from the buffers.

    I don’t know if this is still a problem with winsock2 but even in that case it is probably not a problem this algorithm doesn’t depend on the accuracy of the peek_ret value. Anyway, something to have in mind.

    https://mskb.pkisolutions.com/kb/192599


    vasild commented at 2:43 pm on December 31, 2020:
    Yeah, even if the behavior is still the same, we are fine with it.
  25. in src/netbase.cpp:1186 in 06286e5b83 outdated
    1181+            }
    1182+        }
    1183+
    1184+        const auto now = GetTime<std::chrono::milliseconds>();
    1185+
    1186+        if (now > deadline) {
    


    lontivero commented at 10:14 pm on December 30, 2020:

    I think that in case it reaches the deadline it should throw because otherwise the timeout will be infringed.

    0if (now >= deadline)
    

    vasild commented at 2:46 pm on December 31, 2020:
    Right, and also SendComplete() uses >=. Changed.
  26. lontivero commented at 10:15 pm on December 30, 2020: contributor
    Partial review
  27. vasild force-pushed on Dec 31, 2020
  28. vasild commented at 2:47 pm on December 31, 2020: member
    2ae504c4b…9445dd490: consider it a timeout if the current time is exactly equal to the deadline
  29. DrahtBot added the label Needs rebase on Jan 2, 2021
  30. luke-jr commented at 0:22 am on January 3, 2021: member
    Do we actually want to share our address, though? I would think an anonymous connection is strictly better?
  31. vasild commented at 1:39 pm on January 8, 2021: member

    Do we actually want to share our address, though?

    In I2P, like in IP, connections have “source address”.

    I would think an anonymous connection is strictly better?

    Why? In a P2P network peers are supposed to connect to each other, right? Not hide from each other? If we don’t want connections to us, then we don’t listen on the I2P address (-i2pacceptincoming=0) and nobody can reach back.

  32. vasild force-pushed on Jan 9, 2021
  33. vasild commented at 12:25 pm on January 9, 2021: member
    9445dd490…1cced4679: rebase due to conflicts
  34. DrahtBot removed the label Needs rebase on Jan 9, 2021
  35. DrahtBot commented at 11:46 am on January 13, 2021: member

    🕵️ @harding @hebasto have been requested to review this pull request as specified in the REVIEWERS file.

  36. in src/i2p.cpp:194 in 1da3155d6e outdated
    189+                    RecvUntilTerminator(sock.Get(), '\n', MAX_WAIT_FOR_IO, *m_interrupt);
    190+
    191+                accepted.peer = CService(DestB64ToAddr(peer_dest), Params().GetDefaultPort());
    192+                accepted.socket = sock.Release();
    193+
    194+                err_wait = err_wait_begin;
    


    lontivero commented at 4:22 pm on January 13, 2021:
    I think this is unnecessary.

    vasild commented at 11:02 am on January 15, 2021:
    You mean the incremental wait time or just this line?

    lontivero commented at 2:17 pm on January 15, 2021:
    Just this line because the next line is a return true;

    vasild commented at 12:13 pm on January 17, 2021:
    You are right, removed!
  37. in src/i2p.cpp:189 in 1da3155d6e outdated
    224+        }
    225+
    226+        const Reply& lookup_reply =
    227+            SendRequestAndGetReply(sock, strprintf("NAMING LOOKUP NAME=%s", to.ToStringIP()));
    228+
    229+        const std::string& dest = lookup_reply.Get("VALUE");
    


    lontivero commented at 4:30 pm on January 13, 2021:
    What if no VALUE is received?

    vasild commented at 11:06 am on January 15, 2021:
    Then we will get an exception which is properly handled. Do you see any problems?

    lontivero commented at 2:13 pm on January 15, 2021:
    No, I don’t see any problem, it is just that I didn’t see the exception handling.

    vasild commented at 12:07 pm on January 17, 2021:
    Ok :)
  38. in src/i2p.cpp:247 in 1da3155d6e outdated
    282+
    283+    Reply reply;
    284+
    285+
    286+    // Don't log the full "SESSION CREATE ..." because it contains our private key.
    287+    reply.request = request.substr(0, 14) == "SESSION CREATE" ? "SESSION CREATE ..." : request;
    


    lontivero commented at 4:42 pm on January 13, 2021:
    If there is some kind of startsWith function i think it would be better.

    vasild commented at 12:07 pm on January 17, 2021:
    HasPrefix() is a good candidate, would need some enchanting.
  39. in src/i2p.cpp:266 in 1da3155d6e outdated
    301+        } else {
    302+            reply.keys.emplace(std::string{kv.begin(), kv.end()}, std::nullopt);
    303+        }
    304+    }
    305+
    306+    if (check_result_ok && reply.Get("RESULT") != "OK") {
    


    lontivero commented at 4:50 pm on January 13, 2021:

    It seems correct to assume that RESULT is always returned but in one place in the i2p code I can see this:

    0} else if (ARG_IS(0,"NAMING") &&
    1           ARG_IS(1, "REPLY")) {
    2    if(NULL == (arg = ARG_FIND("RESULT"))) {
    3        SAMLOGS("Naming reply with no result");
    4       return 0;
    5   }
    

    lontivero commented at 4:51 pm on January 13, 2021:
    The Reply class could have a isOk() function, what do you think?

    vasild commented at 12:29 pm on January 15, 2021:
    Yes, if no RESULT is present then this function will throw an exception, which is ok. I think we should expect any reply from the I2P proxy, including malicious one.

    vasild commented at 12:31 pm on January 15, 2021:
    I think it is not worth to add isOk() method because it would be used in just one place - here and reply.Get("RESULT") != "OK" is readable enough.
  40. lontivero commented at 4:55 pm on January 13, 2021: contributor
    Partial review.
  41. felipsoarez commented at 4:15 pm on January 15, 2021: none
    utACK
  42. jonatack commented at 4:38 pm on January 15, 2021: member
    Concept ACK. This builds and runs cleanly. If anyone is running an i2p service, ping me on irc to try connecting to each other.
  43. in src/init.cpp:451 in 1cced46791 outdated
    446@@ -447,7 +447,9 @@ void SetupServerArgs(NodeContext& node)
    447     argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    448     argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h). Limit does not apply to peers with 'download' permission. 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    449     argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    450-    argsman.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    451+    argsman.AddArg("-i2psam=<ip:port>", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    452+    argsman.AddArg("-i2pacceptincoming", "If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Notice that listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: true)", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
    


    laanwj commented at 11:23 pm on January 16, 2021:
    i’d use default: 1, not “true”

    vasild commented at 12:24 pm on January 17, 2021:
    Changed.
  44. jonatack commented at 11:53 am on January 17, 2021: member

    We have an I2P-to-I2P Bitcoin network connection up this Sunday morning. EDIT: 2 connections :tada:

    Screenshot from 2021-01-17 13-40-57

    If helpful, I added the following setting to ~/.bitcoin/bitcoin.conf

    0i2psam=127.0.0.1:7656
    
  45. mshalabi1990 commented at 12:01 pm on January 17, 2021: none

    It needs to be anonymous others wise i2p address will never work fully On Sun, Jan 17, 2021 at 6:55 AM Jon Atack notifications@github.com wrote:

    We have an I2P-to-I2P Bitcoin network connection up this Sunday morning.

    [image: Screenshot from 2021-01-17 11-41-47] https://user-images.githubusercontent.com/2415484/104839627-3027ad00-58ba-11eb-8cc6-8c572d222561.png

    If helpful, I added the following settings to ~/.bitcoin/bitcoin.conf

    i2psam=127.0.0.1:7656 i2pacceptincoming=1

    — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bitcoin/bitcoin/pull/20685#issuecomment-761799484, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASPKBM7LRCYPKYZKNVKG6GLS2LF4RANCNFSM4U7TL45Q .

  46. mshalabi1990 commented at 12:03 pm on January 17, 2021: none
    It needs to be annymous to full work or else it will never work fully decentralized
  47. vasild force-pushed on Jan 17, 2021
  48. vasild commented at 12:24 pm on January 17, 2021: member
    1cced4679…45e571315: rebase and address suggestions
  49. jonatack commented at 4:11 pm on January 17, 2021: member

    Stepping through the commits and building one-by-one.

    In 87ebd74 SocketEvents() interrupt is used like an “in” param but it is passed by reference like an “out” param

    0+++ b/src/net.h
    1@@ -1069,8 +1069,9 @@ private:
    2      * [@param](/bitcoin-bitcoin/contributor/param/)[in,out] sockets When the function is called this is expected to contain the
    3      * sockets that should be checked for readiness. Upon return only ready sockets are
    4      * left in it (non-ready sockets are removed).
    5+     * [@param](/bitcoin-bitcoin/contributor/param/)[in] interrupt Cancel the operation if this is signaled.
    6      */
    7-    void SocketEvents(Sockets& sockets);
    8+    void SocketEvents(Sockets& sockets, CThreadInterrupt& interrupt);
    
  50. jonatack commented at 4:42 pm on January 17, 2021: member
    Starting from ad56288e9b2f, it seems the various std::chrono::milliseconds timeout params can be passed by value.
  51. in src/net.cpp:1046 in 45e571315a outdated
    1056-        NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT);
    1057-        if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY);
    1058-        if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, PF_RELAY);
    1059-        NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL);
    1060-        NetPermissions::AddFlag(permissionFlags, PF_NOBAN);
    1061+    const CAddress& addr_bind = GetBindAddress(socket);
    


    jonatack commented at 5:37 pm on January 17, 2021:

    782de68a7008a

    0    const CAddress addr_bind = GetBindAddress(socket);
    

    vasild commented at 4:17 pm on January 18, 2021:
    Done.
  52. jonatack commented at 5:59 pm on January 17, 2021: member

    Consider dropping a3b33637f as the renaming is to a generic name that is less useful for searching for the variable in the code (false positives go from none to many), or renaming to a more unique name but the current one seems fine; this isn’t new code.

    Edit: same feedback for ccc5966a; consider dropping the change or using a slightly less generic name, like permission_flags. This isn’t new code, so you aren’t required to rename the variables.

  53. jonatack commented at 6:01 pm on January 17, 2021: member
    Reviewed up to a3b33637f234c0f66bacd7afe0fd0dbe, one fixup in addition to the comments above.
  54. in src/netaddress.cpp:289 in 45e571315a outdated
    283@@ -275,6 +284,33 @@ bool CNetAddr::SetSpecial(const std::string& str)
    284     return false;
    285 }
    286 
    287+bool CNetAddr::SetI2P(const std::string& str)
    288+{
    289+    // I2P addresses that we support consist of 52 base32 characters + .b32.i2p.
    


    jonatack commented at 7:48 pm on January 17, 2021:

    484dc6559 suggest adding quotes and/or removing the trailing “.” (if you add quotes here, maybe also line 298)

    0    // I2P addresses that we support consist of 52 base32 characters + ".b32.i2p"
    

    vasild commented at 4:16 pm on January 18, 2021:

    Added quotes, but left the dot.

    0// Comments start with a capital letter and end with a dot, like real sentences.
    
    0// Comments start with a capital letter and end with a dot, like real sentences. This
    1// makes it easy to extend with another sentence.
    
  55. in src/test/net_tests.cpp:364 in 45e571315a outdated
    355+    const char* i2p_addr = "UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P";
    356+    BOOST_REQUIRE(addr.SetSpecial(i2p_addr));
    357+    BOOST_REQUIRE(addr.IsValid());
    358+    BOOST_REQUIRE(addr.IsI2P());
    359+
    360+    BOOST_CHECK(!addr.IsBindAny());
    


    jonatack commented at 7:52 pm on January 17, 2021:

    484dc65591b perhaps a few additional sanity checks

     0@@ -321,6 +321,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic)
     1     BOOST_REQUIRE(addr.IsTor());
     2 
     3+    BOOST_CHECK(!addr.IsI2P());
     4     BOOST_CHECK(!addr.IsBindAny());
     5     BOOST_CHECK(addr.IsAddrV1Compatible());
     6     BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion");
     7@@ -331,6 +332,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic)
     8     BOOST_REQUIRE(addr.IsTor());
     9 
    10+    BOOST_CHECK(!addr.IsI2P());
    11     BOOST_CHECK(!addr.IsBindAny());
    12     BOOST_CHECK(!addr.IsAddrV1Compatible());
    13     BOOST_CHECK_EQUAL(addr.ToString(), torv3_addr);
    14@@ -357,6 +359,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic)
    15     BOOST_REQUIRE(addr.IsI2P());
    16 
    17+    BOOST_CHECK(!addr.IsTor());
    18     BOOST_CHECK(!addr.IsBindAny());
    19     BOOST_CHECK(!addr.IsAddrV1Compatible());
    20     BOOST_CHECK_EQUAL(addr.ToString(), ToLower(i2p_addr));
    

    vasild commented at 4:13 pm on January 18, 2021:
    Added, thanks!
  56. jonatack commented at 9:31 pm on January 17, 2021: member
    Reviewed up to 383bb95d49
  57. dunxen commented at 7:45 am on January 18, 2021: contributor
    Concept ACK. Built and working with no major issues.
  58. vasild force-pushed on Jan 18, 2021
  59. vasild commented at 4:04 pm on January 18, 2021: member

    45e571315…b49a4a06e: address review suggestions

    SocketEvents() interrupt is used like an “in” param but it is passed by reference like an “out” param

    The sleep_for() method of CThreadInterrupt is not const, thus the variable is passed by non-const reference. I changed the comment to say @param[in,out].

    Starting from ad56288, it seems the various std::chrono::milliseconds timeout params can be passed by value.

    I am not sure those are trivial types like int, double, etc. Thus I pass them by const reference.

    Consider dropping a3b3363 as the renaming…

    Dropped the two renames, reducing the size of this PR.

    Note: if the above were posted as “review comments” attached to some line, then the replies would be next to them and also they could be hidden/collapsed once resolved.

  60. vasild commented at 4:40 pm on January 18, 2021: member

    A few notes:

    • We use SAM version 3.1 (HELLO VERSION MIN=3.1 MAX=3.1) because it is the maximum supported by the C++ i2p daemon (as of i2pd 2.35.0).

    • Ports seem to be ignored, so I default them to 8333. SAM 3.2 defines FROM_PORT and TO_PORT, but we use SAM 3.1. As a consequence we can connect to any port on a given I2P address - once we listen on foo.b32.i2p, a peer can connect to us on foo.b32.i2p:8333, foo.b32.i2p:1234, foo.b32.i2p:80, etc.

    • RemoveLocal() is not called if the connection to the I2P daemon dies, e.g. the I2P daemon is shut down. In order to stop advertising our I2P address (via other connections, if we have such ones, e.g. IPv4) we need to do that. Probably Session::Accept() needs to be split to two methods: Session:Listen() and Session::Accept(). Fixed.

  61. jonatack commented at 11:53 pm on January 18, 2021: member

    I am not sure those are trivial types like int, double, etc. Thus I pass them by const reference.

    IIUC according to https://en.cppreference.com/w/cpp/chrono/duration “The only data stored in a duration is a tick count of type Rep”: std::chrono::milliseconds | duration</*signed integer type of at least 45 bits*/, std::milli>. If that is correct, it would be nice to avoid a situation like with CAmounts, which are a cheaply copied value but are passed around by reference to const all over this codebase, presumably because early on someone thought it wasn’t cheap and then that style was replicated in code changes down the line. Not a huge issue but we may as well start off on the right foot.

  62. vasild force-pushed on Jan 22, 2021
  63. vasild commented at 8:41 am on January 22, 2021: member

    b49a4a06e…39021d931:

    • Split the Accept() method to Listen() and Accept(), so that the caller from net.cpp can do AddLocal() when we are listening and RemoveLocal() when listening fails (e.g. the I2P proxy is shut down).

    • Do not AddLocal() after we connect to a I2P peer - should only do this when listening. As a result the newly added function AddLocalIfNotKnown() is not needed and thus dropped.

    • After a failure to listen, accept or connect - check whether the control socket is still connected and if not, then destroy the session. This is not strictly necessary, but makes us detect a possible I2P proxy shutdown earlier.

    • If -listen=0 is given, then soft-flip -i2pacceptincoming from 1 to 0. Still, if -listen=0 -i2pacceptincoming=1 is explicitly given, then allow that as there is no technical reason it would not work as expected (listen for and accept only I2P connections).

  64. vasild commented at 1:25 pm on January 22, 2021: member
    39021d931…7da1e29fc: rebase due to conflicts
  65. vasild force-pushed on Jan 22, 2021
  66. DrahtBot added the label Needs rebase on Jan 22, 2021
  67. DrahtBot removed the label Needs rebase on Jan 22, 2021
  68. DrahtBot added the label Needs rebase on Jan 26, 2021
  69. laanwj commented at 11:37 am on January 26, 2021: member

    I’m still testing this on one of my nodes. It is working great. I’ve had a few connections to other I2P peers.

    I’m testing with the Java implementation of I2P, it has some typical java problems like high CPU and memory use. Compared to Tor at least. Of course, this is not the fault of this PR :slightly_smiling_face:

    Another thing (that @jonatack) noted is that I2P has higher latency than Tor onion services. At least I suppose this is an inherent problem with I2P and not the code here. Network latency is not generally a problem for bitcoin but as eviction decisions are made based on (among other things) ping times. This might be something to look into, but not necessarily in this PR, as a first step adding I2P support at all is a good and self-contained change.

  70. jonatack commented at 1:06 pm on January 26, 2021: member

    Another thing (that @jonatack) noted is that I2P has higher latency than Tor onion services. At least I suppose this is an inherent problem with I2P and not the code here. Network latency is not generally a problem for bitcoin but as eviction decisions are made based on (among other things) ping times. This might be something to look into, but not necessarily in this PR.

    Working on this either for #20197 or a follow-up.

  71. lontivero commented at 2:33 pm on January 28, 2021: contributor
    utACK 7da1e29fcc8a4fdff19f24d5be501ce4c0eeaa21
  72. vasild commented at 10:38 am on January 29, 2021: member
    7da1e29fc…08d0c27d7: rebase due to conflicts
  73. vasild force-pushed on Jan 29, 2021
  74. vasild force-pushed on Jan 29, 2021
  75. vasild commented at 10:41 am on January 29, 2021: member
    08d0c27d7…2caf1bff3: pass std::chrono variables by value instead of by const reference, as per suggestion. Thanks, @jonatack!
  76. DrahtBot removed the label Needs rebase on Jan 29, 2021
  77. laanwj removed the label Build system on Feb 3, 2021
  78. laanwj removed the label Docs on Feb 3, 2021
  79. laanwj removed the label RPC/REST/ZMQ on Feb 3, 2021
  80. laanwj removed the label Utils/log/libs on Feb 3, 2021
  81. laanwj added the label Feature on Feb 3, 2021
  82. jonatack commented at 5:15 pm on February 3, 2021: member
    I’d like to help move this forward. Is this pull independent of #20788?
  83. laanwj added this to the milestone 22.0 on Feb 3, 2021
  84. lontivero commented at 2:56 am on February 4, 2021: contributor
    This PR is independent of #20788. However, #20788 was born as a subset of this PR because it adds goodness independently of this PR. Some of the suggestions made there and here (drop commits with renames, for example) have been made here but not in #20788 yet. Anyway, imo i think merging #20788 first could help to reduce the size of this one.
  85. jonatack commented at 3:13 pm on February 5, 2021: member
    @lontivero thank you, that is very helpful; will finishing reviewing here then as it is ahead of #20788 in its updates. @vasild you can drop my -netinfo commit now that #20764 is merged, sorry for the rebase (but it is now i2p-ready :sunglasses:)
  86. DrahtBot added the label Needs rebase on Feb 5, 2021
  87. fluffypony commented at 3:48 pm on February 5, 2021: contributor

    Per my conversation with @jonatack on Clubhouse, this i2p router that some Monero contributors have created may be of use: https://github.com/i2p-zero/i2p-zero

    It’s VERY lightweight, even compared to i2pd and the full i2p router, implements SAM, and bundles a JVM.

  88. vasild force-pushed on Feb 6, 2021
  89. vasild commented at 1:52 pm on February 6, 2021: member
    2caf1bff3…2f71ee2b2: rebase due to conflicts and drop the last commit cli: add i2p network to -netinfo because an enhanced version of it is now in master via #20764. @jonatack, excellent, reducing the size of this PR! Getting #20788 merged will reduce it further.
  90. DrahtBot removed the label Needs rebase on Feb 6, 2021
  91. DrahtBot added the label Needs rebase on Feb 11, 2021
  92. jonatack commented at 1:26 pm on February 11, 2021: member

    Noting here some IRC discussions on installing I2P as a reference for later, e.g. a future doc/i2p.md, or for people looking to install it:

  93. vasild force-pushed on Feb 13, 2021
  94. DrahtBot removed the label Needs rebase on Feb 13, 2021
  95. vasild commented at 1:17 pm on February 13, 2021: member

    2f71ee2b2…a456bd3f2:

    • Remove the Sock definition from this PR as it is now merged in master.
    • Do not extract CConnman::SocketEvents() as a standalone function since it is not needed anymore - in all places we wait for an event on one socket and for this we can use Sock::Wait().
    • Extend Sock::Wait() to report to the caller whether a timeout occurred or one of the requested events.
    • Add SendComplete() and RecvUntilTerminator() as Sock methods instead of as standalone functions whose first argument is the socket.
    • When generating our pub/priv keys (aka I2P destination) use 7 instead of EdDSA_SHA512_Ed25519 since i2pd <2.24.0 only understand the numeric one (thanks to @sdaftuar for nailing this!)
  96. laanwj commented at 10:37 pm on February 13, 2021: member
    Updated my I2P-using node to the new version (a456bd3f296f18e463e36048c866c404b69363b6) for testing.
  97. jonatack commented at 0:20 am on February 14, 2021: member

    Testing a Clang 9 build of a456bd3f296f18e463e36048c866c404b69363b6 with i2pd 2.35 did not work

    02021-02-13T23:31:35Z I2P: SAM session created: session id=86eaxxaxxxx, my address=zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtyxxxxxxxx.b32.i2p:8333
    12021-02-13T23:31:35Z AddLocal(zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtyxxxxxxxx.b32.i2p:8333,2)
    2Illegal instruction
    
    0Debian 5.10.13-1 (2021-02-06) x86_64 GNU/Linux
    
    0i2pd version 2.35.0 (0.9.48)
    1Boost version 1.74.0
    2OpenSSL 1.1.1i  8 Dec 2020
    

    Made two further attempts with the same result :crying_cat_face:…it’s after 1 am and I have not yet looked into the code changes since the last push, but then built with the same config on 2f71ee2b2 (previous push) and it’s working again…:cat:

  98. laanwj commented at 10:53 am on February 14, 2021: member

    2021-02-13T23:31:35Z AddLocal(zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtyxxxxxxxx.b32.i2p:8333,2) Illegal instruction

    Can you give a gdb backtrace please? With disassembly (disass) at the crash location, if possible. The post common cause of Illegal Instruction is your compiler generating extension instructions that the specific CPU can’t handle. I don’t understand how it could be introduced here though.

  99. jonatack commented at 2:54 pm on February 14, 2021: member

    Hm, gdb didn’t hit the issue (I’ll try again) but valgrind did.

     02021-02-14T14:45:19Z New outbound peer connected: version: 70015, blocks=670586, peer=1, peeraddr=144.76.81.194:8333 (outbound-full-relay)
     12021-02-14T14:45:39Z I2P: SAM session created: session id=qqqq, my address=qqqq.b32.i2p:8333
     22021-02-14T14:45:41Z UpdateTip: new best=00000000000000000009e0b532bf3ff388c9d7c4489b0bcf2631f75195609c57 height=670580 version=0x3fff0000 log2_work=92.668088 tx=616177992 date='2021-02-14T13:15:07Z' progress=0.999969 cache=1.5MiB(10863txo)
     32021-02-14T14:45:41Z AddLocal(qqqq.b32.i2p:8333,2)
     4==5137== valgrind: Unrecognised instruction at address 0x17e85a.
     5==5137==    at 0x17E85A: CConnman::ConnectNode(CAddress, char const*, bool, ConnectionType) (net.cpp:437)
     6==5137==    by 0x188529: CConnman::OpenNetworkConnection(CAddress const&, bool, CSemaphoreGrant*, char const*, ConnectionType) (net.cpp:2152)
     7==5137==    by 0x192136: CConnman::ThreadOpenAddedConnections() (net.cpp:2119)
     8==5137==    by 0x1AABAD: __invoke_impl<void, void (CConnman::*&)(), CConnman *&> (invoke.h:73)
     9==5137==    by 0x1AABAD: __invoke<void (CConnman::*&)(), CConnman *&> (invoke.h:95)
    10==5137==    by 0x1AABAD: __call<void, 0> (functional:416)
    11==5137==    by 0x1AABAD: operator()<, void> (functional:499)
    12==5137==    by 0x1AABAD: __invoke_impl<void, std::_Bind<void (CConnman::*(CConnman *))()> &> (invoke.h:60)
    13==5137==    by 0x1AABAD: __invoke_r<void, std::_Bind<void (CConnman::*(CConnman *))()> &> (invoke.h:110)
    14==5137==    by 0x1AABAD: std::_Function_handler<void (), std::_Bind<void (CConnman::*(CConnman*))()> >::_M_invoke(std::_Any_data const&) (std_function.h:291)
    15==5137==    by 0x16A038: operator() (std_function.h:622)
    16==5137==    by 0x16A038: void TraceThread<std::function<void ()> >(char const*, std::function<void ()>) (system.h:470)
    17==5137==    by 0x1AAD7F: __invoke_impl<void, void (*)(const char *, std::function<void ()>), const char *, std::function<void ()> > (invoke.h:60)
    18==5137==    by 0x1AAD7F: __invoke<void (*)(const char *, std::function<void ()>), const char *, std::function<void ()> > (invoke.h:95)
    19==5137==    by 0x1AAD7F: _M_invoke<0, 1, 2> (thread:264)
    20==5137==    by 0x1AAD7F: operator() (thread:271)
    21==5137==    by 0x1AAD7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > > >::_M_run() (thread:215)
    22==5137==    by 0x4DE1ECF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
    23==5137==    by 0x4875EA6: start_thread (pthread_create.c:477)
    24==5137==    by 0x513DDEE: clone (clone.S:95)
    25==5137== Your program just tried to execute an instruction that Valgrind
    26==5137== did not recognise.  There are two possible reasons for this.
    27==5137== 1. Your program has a bug and erroneously jumped to a non-code
    28==5137==    location.  If you are running Memcheck and you just saw a
    29==5137==    warning about a bad jump, it's probably your program's fault.
    30==5137== 2. The instruction is legitimate but Valgrind doesn't handle it,
    31==5137==    i.e. it's Valgrind's fault.  If you think this is the case or
    32==5137==    you are not sure, please let us know and we'll try to fix it.
    33==5137== Either way, Valgrind will now raise a SIGILL signal which will
    34==5137== probably kill your program.
    35==5137== 
    36==5137== Process terminating with default action of signal 4 (SIGILL)
    37==5137==  Illegal opcode at address 0x17E85A
    38==5137==    at 0x17E85A: CConnman::ConnectNode(CAddress, char const*, bool, ConnectionType) (net.cpp:437)
    39==5137==    by 0x188529: CConnman::OpenNetworkConnection(CAddress const&, bool, CSemaphoreGrant*, char const*, ConnectionType) (net.cpp:2152)
    40==5137==    by 0x192136: CConnman::ThreadOpenAddedConnections() (net.cpp:2119)
    41==5137==    by 0x1AABAD: __invoke_impl<void, void (CConnman::*&)(), CConnman *&> (invoke.h:73)
    42==5137==    by 0x1AABAD: __invoke<void (CConnman::*&)(), CConnman *&> (invoke.h:95)
    43==5137==    by 0x1AABAD: __call<void, 0> (functional:416)
    44==5137==    by 0x1AABAD: operator()<, void> (functional:499)
    45==5137==    by 0x1AABAD: __invoke_impl<void, std::_Bind<void (CConnman::*(CConnman *))()> &> (invoke.h:60)
    46==5137==    by 0x1AABAD: __invoke_r<void, std::_Bind<void (CConnman::*(CConnman *))()> &> (invoke.h:110)
    47==5137==    by 0x1AABAD: std::_Function_handler<void (), std::_Bind<void (CConnman::*(CConnman*))()> >::_M_invoke(std::_Any_data const&) (std_function.h:291)
    48==5137==    by 0x16A038: operator() (std_function.h:622)
    49==5137==    by 0x16A038: void TraceThread<std::function<void ()> >(char const*, std::function<void ()>) (system.h:470)
    50==5137==    by 0x1AAD7F: __invoke_impl<void, void (*)(const char *, std::function<void ()>), const char *, std::function<void ()> > (invoke.h:60)
    51==5137==    by 0x1AAD7F: __invoke<void (*)(const char *, std::function<void ()>), const char *, std::function<void ()> > (invoke.h:95)
    52==5137==    by 0x1AAD7F: _M_invoke<0, 1, 2> (thread:264)
    53==5137==    by 0x1AAD7F: operator() (thread:271)
    54==5137==    by 0x1AAD7F: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > > >::_M_run() (thread:215)
    55==5137==    by 0x4DE1ECF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
    56==5137==    by 0x4875EA6: start_thread (pthread_create.c:477)
    57==5137==    by 0x513DDEE: clone (clone.S:95)
    58==5137== 
    59==5137== HEAP SUMMARY:
    60==5137==     in use at exit: 238,728,213 bytes in 1,629,048 blocks
    61==5137==   total heap usage: 9,884,111 allocs, 8,255,063 frees, 4,818,980,752 bytes allocated
    62==5137== 
    63==5137== LEAK SUMMARY:
    64==5137==    definitely lost: 562,000 bytes in 138 blocks
    65==5137==    indirectly lost: 0 bytes in 0 blocks
    66==5137==      possibly lost: 7,987,784 bytes in 414 blocks
    67==5137==    still reachable: 230,178,429 bytes in 1,628,496 blocks
    68==5137==                       of which reachable via heuristic:
    69==5137==                         length64           : 213,760 bytes in 360 blocks
    70==5137==                         newarray           : 72 bytes in 1 blocks
    71==5137==         suppressed: 0 bytes in 0 blocks
    72==5137== Rerun with --leak-check=full to see details of leaked memory
    73==5137== 
    74==5137== Use --track-origins=yes to see where uninitialised values come from
    75==5137== For lists of detected and suppressed errors, rerun with: -s
    76==5137== ERROR SUMMARY: 9 errors from 1 contexts (suppressed: 0 from 0)
    77Illegal instruction
    
  100. jonatack commented at 3:57 pm on February 14, 2021: member

    Ok, hit it with gdb

    02021-02-14T15:33:36Z I2P: SAM session created: session id=qqqq, my address=h3r6bkn4...q.b32.i2p:8333
    12021-02-14T15:33:36Z AddLocal(h3r6bkn4...q.b32.i2p:8333,2)
    2
    3Thread 18 "b-addcon" received signal SIGSEGV, Segmentation fault.
    4[Switching to Thread 0x7fff39ed7700 (LWP 54120)]
    50x0000555555621ede in CConnman::ConnectNode (this=0x5555566e3ec0, addrConnect=..., 
    6    pszDest=0x7fff28002e50 "h3r6bkn4...q.b32.i2p", fCountFailure=false, conn_type=ConnectionType::MANUAL) at net.cpp:437
    7437	                *sock = std::move(conn.sock);
    
     0(gdb) bt
     1[#0](/bitcoin-bitcoin/0/)  0x0000555555621ede in CConnman::ConnectNode (this=0x5555566e3ec0, addrConnect=..., 
     2    pszDest=0x7fff28002e50 "qqqq.b32.i2p", fCountFailure=false, conn_type=ConnectionType::MANUAL) at net.cpp:437
     3[#1](/bitcoin-bitcoin/1/)  0x0000555555629c1e in CConnman::OpenNetworkConnection (this=0x5555566e3ec0, addrConnect=..., fCountFailure=false, grantOutbound=0x7fff39ed6830, 
     4    pszDest=0x7fff28002e50 "qqqq.b32.i2p", conn_type=ConnectionType::MANUAL) at net.cpp:2152
     5[#2](/bitcoin-bitcoin/2/)  0x000055555563195a in CConnman::ThreadOpenAddedConnections (this=0x5555566e3ec0) at net.cpp:2119
     6[#3](/bitcoin-bitcoin/3/)  0x00005555556902c8 in std::__invoke_impl<void, void (CConnman::*&)(), CConnman*&> (
     7    __f=@0x5555603a3f60: (void (CConnman::*)(CConnman * const)) 0x5555556317c0 <CConnman::ThreadOpenAddedConnections()>, __t=@0x5555603a3f70: 0x5555566e3ec0)
     8    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:73
     9[#4](/bitcoin-bitcoin/4/)  0x0000555555690163 in std::__invoke<void (CConnman::*&)(), CConnman*&> (
    10    __fn=@0x5555603a3f60: (void (CConnman::*)(CConnman * const)) 0x5555556317c0 <CConnman::ThreadOpenAddedConnections()>, __args=@0x5555603a3f70: 0x5555566e3ec0)
    11    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95
    12[#5](/bitcoin-bitcoin/5/)  0x00005555556900f4 in std::_Bind<void (CConnman::*(CConnman*))()>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (this=0x5555603a3f60, __args=...)
    13    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:416
    14[#6](/bitcoin-bitcoin/6/)  0x0000555555690077 in std::_Bind<void (CConnman::*(CConnman*))()>::operator()<, void>() (this=0x5555603a3f60)
    15    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:499
    16[#7](/bitcoin-bitcoin/7/)  0x000055555568ffce in std::__invoke_impl<void, std::_Bind<void (CConnman::*(CConnman*))()>&>(std::__invoke_other, std::_Bind<void (CConnman::*(CConnman*))()>&) (
    17    __f=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60
    18[#8](/bitcoin-bitcoin/8/)  0x000055555568ff1e in std::__invoke_r<void, std::_Bind<void (CConnman::*(CConnman*))()>&>(std::_Bind<void (CConnman::*(CConnman*))()>&) (__fn=...)
    19    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:110
    20[#9](/bitcoin-bitcoin/9/)  0x000055555568fbae in std::_Function_handler<void (), std::_Bind<void (CConnman::*(CConnman*))()> >::_M_invoke(std::_Any_data const&) (__functor=...)
    21    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:291
    22[#10](/bitcoin-bitcoin/10/) 0x0000555555614dff in std::function<void ()>::operator()() const (this=0x7fff39ed6b48)
    23    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_function.h:622
    24[#11](/bitcoin-bitcoin/11/) 0x00005555555d4f40 in TraceThread<std::function<void ()> >(char const*, std::function<void ()>) (name=0x55555611dc37 "addcon", func=...) at ./util/system.h:470
    25[#12](/bitcoin-bitcoin/12/) 0x0000555555691182 in std::__invoke_impl<void, void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> >(std::__invoke_other, void (*&&)(char const*, std::function<void ()>), char const*&&, std::function<void ()>&&) (
    26    __f=@0x5555603a41f0: 0x5555555d4eb0 <TraceThread<std::function<void ()> >(char const*, std::function<void ()>)>, __args=..., __args=...)
    27    at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60
    28[#13](/bitcoin-bitcoin/13/) 0x0000555555690f78 in std::__invoke<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> >(void (*&&)(char const*, std::function<void ()>), char const*&&, std::function<void ()>&&) (__fn=@0x5555603a41f0: 0x5555555d4eb0 <TraceThread<std::function<void ()> >(char const*, std::function<void ()>)>, 
    29    __args=..., __args=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95
    30[#14](/bitcoin-bitcoin/14/) 0x0000555555690eff in std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) (this=0x5555603a41c8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264
    31[#15](/bitcoin-bitcoin/15/) 0x0000555555690e66 in std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > >::operator()() (
    32    this=0x5555603a41c8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271
    33[#16](/bitcoin-bitcoin/16/) 0x00005555556909ed in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > > >::_M_run() (this=0x5555603a41c0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215
    34[#17](/bitcoin-bitcoin/17/) 0x00007ffff79ffed0 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
    35[#18](/bitcoin-bitcoin/18/) 0x00007ffff7f8aea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
    36[#19](/bitcoin-bitcoin/19/) 0x00007ffff7709def in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
    
       0(gdb) disass /m
       1Dump of assembler code for function _ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType:
       2377	{
       3   0x0000555555621490 <+0>:	endbr64 
       4   0x0000555555621494 <+4>:	push   %rbp
       5   0x0000555555621495 <+5>:	mov    %rsp,%rbp
       6   0x0000555555621498 <+8>:	sub    $0x620,%rsp
       7   0x000055555562149f <+15>:	mov    %fs:0x28,%rax
       8   0x00005555556214a8 <+24>:	mov    %rax,-0x8(%rbp)
       9   0x00005555556214ac <+28>:	mov    %rdi,-0x3c8(%rbp)
      10   0x00005555556214b3 <+35>:	mov    %rdx,-0x340(%rbp)
      11   0x00005555556214ba <+42>:	and    $0x1,%cl
      12   0x00005555556214bd <+45>:	mov    %cl,-0x3c9(%rbp)
      13   0x00005555556214c3 <+51>:	mov    %r8d,-0x3d0(%rbp)
      14   0x00005555556214ca <+58>:	mov    -0x3c8(%rbp),%rax
      15
      16378	    assert(conn_type != ConnectionType::INBOUND);
      17   0x00005555556214d1 <+65>:	cmpl   $0x0,-0x3d0(%rbp)
      18   0x00005555556214d8 <+72>:	mov    %rsi,-0x428(%rbp)
      19   0x00005555556214df <+79>:	mov    %rax,-0x430(%rbp)
      20   0x00005555556214e6 <+86>:	je     0x5555556214f1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+97>
      21   0x00005555556214ec <+92>:	jmp    0x555555621510 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+128>
      22   0x00005555556214f1 <+97>:	lea    0xafb9c5(%rip),%rdi        # 0x55555611cebd
      23   0x00005555556214f8 <+104>:	lea    0xb26cd2(%rip),%rsi        # 0x5555561481d1
      24   0x00005555556214ff <+111>:	mov    $0x17a,%edx
      25   0x0000555555621504 <+116>:	lea    0xafb9d7(%rip),%rcx        # 0x55555611cee2
      26   0x000055555562150b <+123>:	call   0x555555581490 <__assert_fail@plt>
      27
      28379	
      29380	    if (pszDest == nullptr) {
      30   0x0000555555621510 <+128>:	cmpq   $0x0,-0x340(%rbp)
      31   0x0000555555621518 <+136>:	jne    0x5555556215e4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+340>
      32   0x000055555562151e <+142>:	mov    -0x428(%rbp),%rax
      33
      34381	        if (IsLocal(addrConnect))
      35   0x0000555555621525 <+149>:	mov    %rax,%rdi
      36   0x0000555555621528 <+152>:	call   0x555555620940 <_Z7IsLocalRK8CService>
      37   0x000055555562152d <+157>:	test   $0x1,%al
      38   0x000055555562152f <+159>:	jne    0x55555562153a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+170>
      39   0x0000555555621535 <+165>:	jmp    0x55555562154a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+186>
      40
      41382	            return nullptr;
      42   0x000055555562153a <+170>:	movq   $0x0,-0x3c0(%rbp)
      43   0x0000555555621545 <+181>:	jmp    0x5555556228fd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5229>
      44   0x000055555562154a <+186>:	lea    -0x30(%rbp),%rax
      45
      46383	
      47384	        // Look for an existing connection
      48385	        CNode* pnode = FindNode(static_cast<CService>(addrConnect));
      49   0x000055555562154e <+190>:	mov    %rax,%rdi
      50   0x0000555555621551 <+193>:	mov    -0x428(%rbp),%rsi
      51   0x0000555555621558 <+200>:	mov    %rax,-0x438(%rbp)
      52   0x000055555562155f <+207>:	call   0x5555555d5980 <_ZN8CServiceC2ERKS_>
      53   0x0000555555621564 <+212>:	mov    -0x430(%rbp),%rdi
      54   0x000055555562156b <+219>:	mov    -0x438(%rbp),%rsi
      55   0x0000555555621572 <+226>:	call   0x555555620fe0 <_ZN8CConnman8FindNodeERK8CService>
      56   0x0000555555621577 <+231>:	mov    %rax,-0x440(%rbp)
      57   0x000055555562157e <+238>:	jmp    0x555555621583 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+243>
      58   0x0000555555621583 <+243>:	lea    -0x30(%rbp),%rdi
      59   0x0000555555621587 <+247>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
      60   0x000055555562158c <+252>:	mov    -0x440(%rbp),%rax
      61   0x0000555555621593 <+259>:	mov    %rax,-0x3d8(%rbp)
      62   0x00005555556215d1 <+321>:	lea    -0x30(%rbp),%rdi
      63   0x00005555556215d5 <+325>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
      64   0x00005555556215da <+330>:	jmp    0x555555622931 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5281>
      65   0x0000555555622931 <+5281>:	mov    -0x3e0(%rbp),%rdi
      66   0x0000555555622938 <+5288>:	call   0x5555555821a0 <_Unwind_Resume@plt>
      67   0x000055555562293d <+5293>:	call   0x5555555817d0 <__stack_chk_fail@plt>
      68   0x0000555555622942:	nopw   %cs:0x0(%rax,%rax,1)
      69   0x000055555562294c:	nopl   0x0(%rax)
      70
      71386	        if (pnode)
      72   0x000055555562159a <+266>:	cmpq   $0x0,-0x3d8(%rbp)
      73   0x00005555556215a2 <+274>:	je     0x5555556215df <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+335>
      74
      75387	        {
      76388	            LogPrintf("Failed to open new connection, already connected\n");
      77   0x00005555556215a8 <+280>:	lea    0xafb97e(%rip),%rdi        # 0x55555611cf2d
      78   0x00005555556215af <+287>:	call   0x555555622950 <_ZL9LogPrintfIJEEvPKcDpRKT_>
      79
      80389	            return nullptr;
      81   0x00005555556215b4 <+292>:	movq   $0x0,-0x3c0(%rbp)
      82   0x00005555556215bf <+303>:	jmp    0x5555556228fd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5229>
      83
      84390	        }
      85391	    }
      86   0x00005555556215df <+335>:	jmp    0x5555556215e4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+340>
      87
      88392	
      89393	    /// debug print
      90394	    LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
      91   0x00005555556215e4 <+340>:	jmp    0x5555556215e9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+345>
      92   0x00005555556215e9 <+345>:	mov    $0x1,%edi
      93   0x00005555556215ee <+350>:	call   0x55555561fd20 <_ZL17LogAcceptCategoryN5BCLog8LogFlagsE>
      94   0x00005555556215f3 <+355>:	test   $0x1,%al
      95   0x00005555556215f5 <+357>:	jne    0x555555621600 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+368>
      96   0x00005555556215fb <+363>:	jmp    0x5555556217a1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+785>
      97   0x0000555555621600 <+368>:	mov    -0x340(%rbp),%rax
      98   0x0000555555621607 <+375>:	movb   $0x0,-0x3e5(%rbp)
      99   0x000055555562160e <+382>:	cmp    $0x0,%rax
     100   0x0000555555621612 <+386>:	je     0x555555621664 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+468>
     101   0x0000555555621618 <+392>:	mov    -0x340(%rbp),%rsi
     102   0x000055555562161f <+399>:	lea    -0x348(%rbp),%rax
     103   0x0000555555621626 <+406>:	mov    %rax,%rdi
     104   0x0000555555621629 <+409>:	mov    %rsi,-0x448(%rbp)
     105   0x0000555555621630 <+416>:	mov    %rax,-0x450(%rbp)
     106   0x0000555555621637 <+423>:	call   0x555555582c40 <_ZNSaIcEC1Ev@plt>
     107   0x000055555562163c <+428>:	movb   $0x1,-0x3e5(%rbp)
     108   0x0000555555621643 <+435>:	lea    -0x50(%rbp),%rdi
     109   0x0000555555621647 <+439>:	mov    -0x448(%rbp),%rsi
     110   0x000055555562164e <+446>:	mov    -0x450(%rbp),%rdx
     111   0x0000555555621655 <+453>:	call   0x55555559c0c0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_>
     112   0x000055555562165a <+458>:	jmp    0x55555562165f <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+463>
     113   0x000055555562165f <+463>:	jmp    0x55555562167e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+494>
     114   0x0000555555621664 <+468>:	lea    -0x50(%rbp),%rdi
     115   0x0000555555621668 <+472>:	mov    -0x428(%rbp),%rsi
     116   0x000055555562166f <+479>:	call   0x555555eaef60 <_ZNK8CService8ToStringB5cxx11Ev>
     117   0x0000555555621674 <+484>:	jmp    0x555555621679 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+489>
     118   0x0000555555621679 <+489>:	jmp    0x55555562167e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+494>
     119   0x000055555562167e <+494>:	cmpq   $0x0,-0x340(%rbp)
     120   0x0000555555621686 <+502>:	je     0x55555562169c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+524>
     121   0x000055555562168c <+508>:	xorps  %xmm0,%xmm0
     122   0x000055555562168f <+511>:	movsd  %xmm0,-0x458(%rbp)
     123   0x0000555555621697 <+519>:	jmp    0x5555556216fe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+622>
     124   0x000055555562169c <+524>:	call   0x5555559d35f0 <_Z15GetAdjustedTimev>
     125   0x00005555556216a1 <+529>:	mov    %rax,-0x460(%rbp)
     126   0x00005555556216a8 <+536>:	jmp    0x5555556216ad <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+541>
     127   0x00005555556216ad <+541>:	mov    -0x428(%rbp),%rax
     128   0x00005555556216b4 <+548>:	mov    0x24(%rax),%ecx
     129   0x00005555556216b7 <+551>:	mov    %ecx,%edx
     130   0x00005555556216b9 <+553>:	mov    -0x460(%rbp),%rsi
     131   0x00005555556216c0 <+560>:	sub    %rdx,%rsi
     132   0x00005555556216c3 <+563>:	seto   %dil
     133   0x00005555556216c7 <+567>:	xor    $0xff,%dil
     134   0x00005555556216cb <+571>:	test   $0x1,%dil
     135   0x00005555556216cf <+575>:	mov    %rsi,-0x468(%rbp)
     136   0x00005555556216d6 <+582>:	jne    0x5555556216de <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+590>
     137   0x00005555556216dc <+588>:	ud2    
     138   0x00005555556216de <+590>:	movsd  0xafb552(%rip),%xmm0        # 0x55555611cc38
     139   0x00005555556216e6 <+598>:	mov    -0x468(%rbp),%rax
     140   0x00005555556216ed <+605>:	cvtsi2sd %rax,%xmm1
     141   0x00005555556216f2 <+610>:	divsd  %xmm0,%xmm1
     142   0x00005555556216f6 <+614>:	movsd  %xmm1,-0x458(%rbp)
     143   0x00005555556216fe <+622>:	movsd  -0x458(%rbp),%xmm0
     144   0x0000555555621706 <+630>:	movsd  %xmm0,-0x350(%rbp)
     145   0x000055555562170e <+638>:	lea    0xafb84a(%rip),%rdi        # 0x55555611cf5f
     146   0x0000555555621715 <+645>:	lea    -0x50(%rbp),%rsi
     147   0x0000555555621719 <+649>:	lea    -0x350(%rbp),%rdx
     148   0x0000555555621720 <+656>:	call   0x555555622c30 <_ZL9LogPrintfIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvPKcDpRKT_>
     149   0x0000555555621725 <+661>:	jmp    0x55555562172a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+666>
     150   0x000055555562172a <+666>:	lea    -0x50(%rbp),%rdi
     151   0x000055555562172e <+670>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     152   0x0000555555621733 <+675>:	testb  $0x1,-0x3e5(%rbp)
     153   0x000055555562173a <+682>:	jne    0x555555621745 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+693>
     154   0x0000555555621740 <+688>:	jmp    0x555555621751 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+705>
     155   0x0000555555621745 <+693>:	lea    -0x348(%rbp),%rdi
     156   0x000055555562174c <+700>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     157   0x0000555555621751 <+705>:	jmp    0x5555556217a1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+785>
     158   0x0000555555621775 <+741>:	lea    -0x50(%rbp),%rdi
     159   0x0000555555621779 <+745>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     160   0x000055555562177e <+750>:	testb  $0x1,-0x3e5(%rbp)
     161   0x0000555555621785 <+757>:	jne    0x555555621790 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+768>
     162   0x000055555562178b <+763>:	jmp    0x55555562179c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+780>
     163   0x0000555555621790 <+768>:	lea    -0x348(%rbp),%rdi
     164   0x0000555555621797 <+775>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     165   0x000055555562179c <+780>:	jmp    0x555555622931 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5281>
     166   0x00005555556217a1 <+785>:	jmp    0x5555556217a6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+790>
     167
     168395	        pszDest ? pszDest : addrConnect.ToString(),
     169396	        pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
     170397	
     171398	    // Resolve
     172399	    const int default_port = Params().GetDefaultPort();
     173   0x00005555556217a6 <+790>:	call   0x555555e7b5b0 <_Z6Paramsv>
     174   0x00005555556217ab <+795>:	mov    %rax,%rdi
     175   0x00005555556217ae <+798>:	call   0x5555555cf590 <_ZNK12CChainParams14GetDefaultPortEv>
     176   0x00005555556217b3 <+803>:	mov    %eax,-0x3ec(%rbp)
     177
     178400	    if (pszDest) {
     179   0x00005555556217b9 <+809>:	cmpq   $0x0,-0x340(%rbp)
     180   0x00005555556217c1 <+817>:	je     0x555555621d13 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2179>
     181   0x00005555556217c7 <+823>:	lea    -0x368(%rbp),%rdi
     182
     183401	        std::vector<CService> resolved;
     184   0x00005555556217ce <+830>:	call   0x5555555ed810 <_ZNSt6vectorI8CServiceSaIS0_EEC2Ev>
     185
     186402	        if (Lookup(pszDest, resolved,  default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
     187   0x00005555556217d3 <+835>:	mov    -0x340(%rbp),%rsi
     188   0x00005555556217da <+842>:	lea    -0x370(%rbp),%rax
     189   0x00005555556217e1 <+849>:	mov    %rax,%rdi
     190   0x00005555556217e4 <+852>:	mov    %rsi,-0x470(%rbp)
     191   0x00005555556217eb <+859>:	mov    %rax,-0x478(%rbp)
     192   0x00005555556217f2 <+866>:	call   0x555555582c40 <_ZNSaIcEC1Ev@plt>
     193   0x00005555556217f7 <+871>:	lea    -0x70(%rbp),%rdi
     194   0x00005555556217fb <+875>:	mov    -0x470(%rbp),%rsi
     195   0x0000555555621802 <+882>:	mov    -0x478(%rbp),%rdx
     196   0x0000555555621809 <+889>:	call   0x55555559c0c0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_>
     197   0x000055555562180e <+894>:	jmp    0x555555621813 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+899>
     198   0x0000555555621813 <+899>:	xor    %eax,%eax
     199   0x0000555555621815 <+901>:	lea    0xedae88(%rip),%rcx        # 0x5555564fc6a4 <fNameLookup>
     200   0x000055555562181c <+908>:	mov    -0x3ec(%rbp),%edx
     201   0x0000555555621822 <+914>:	testb  $0x1,(%rcx)
     202   0x0000555555621825 <+917>:	mov    %edx,-0x47c(%rbp)
     203   0x000055555562182b <+923>:	mov    %al,-0x47d(%rbp)
     204   0x0000555555621831 <+929>:	je     0x555555621855 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+965>
     205   0x0000555555621837 <+935>:	call   0x555555eb8110 <_Z13HaveNameProxyv>
     206   0x000055555562183c <+940>:	mov    %al,-0x47e(%rbp)
     207   0x0000555555621842 <+946>:	jmp    0x555555621847 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+951>
     208   0x0000555555621847 <+951>:	mov    -0x47e(%rbp),%al
     209   0x000055555562184d <+957>:	xor    $0xff,%al
     210   0x000055555562184f <+959>:	mov    %al,-0x47d(%rbp)
     211   0x0000555555621855 <+965>:	mov    -0x47d(%rbp),%al
     212   0x000055555562185b <+971>:	movzbl %al,%ecx
     213   0x000055555562185e <+974>:	and    $0x1,%ecx
     214   0x0000555555621861 <+977>:	lea    -0x70(%rbp),%rdi
     215   0x0000555555621865 <+981>:	lea    -0x368(%rbp),%rsi
     216   0x000055555562186c <+988>:	mov    $0x100,%r8d
     217   0x0000555555621872 <+994>:	mov    -0x47c(%rbp),%edx
     218   0x0000555555621878 <+1000>:	call   0x555555eb6560 <_Z6LookupRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorI8CServiceSaIS8_EEibj>
     219   0x000055555562187d <+1005>:	mov    %al,-0x47f(%rbp)
     220   0x0000555555621883 <+1011>:	jmp    0x555555621888 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1016>
     221--Type <RET> for more, q to quit, c to continue without paging--
     222   0x0000555555621888 <+1016>:	xor    %eax,%eax
     223   0x000055555562188a <+1018>:	mov    -0x47f(%rbp),%cl
     224   0x0000555555621890 <+1024>:	test   $0x1,%cl
     225   0x0000555555621893 <+1027>:	mov    %al,-0x480(%rbp)
     226   0x0000555555621899 <+1033>:	jne    0x5555556218a4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1044>
     227   0x000055555562189f <+1039>:	jmp    0x5555556218b8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1064>
     228   0x00005555556218a4 <+1044>:	lea    -0x368(%rbp),%rdi
     229   0x00005555556218ab <+1051>:	call   0x5555555d5830 <_ZNKSt6vectorI8CServiceSaIS0_EE5emptyEv>
     230   0x00005555556218b0 <+1056>:	xor    $0xff,%al
     231   0x00005555556218b2 <+1058>:	mov    %al,-0x480(%rbp)
     232   0x00005555556218b8 <+1064>:	mov    -0x480(%rbp),%al
     233   0x00005555556218be <+1070>:	lea    -0x70(%rbp),%rdi
     234   0x00005555556218c2 <+1074>:	mov    %al,-0x481(%rbp)
     235   0x00005555556218c8 <+1080>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     236   0x00005555556218cd <+1085>:	lea    -0x370(%rbp),%rdi
     237   0x00005555556218d4 <+1092>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     238   0x00005555556218d9 <+1097>:	mov    -0x481(%rbp),%al
     239   0x00005555556218df <+1103>:	test   $0x1,%al
     240   0x00005555556218e1 <+1105>:	jne    0x5555556218ec <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1116>
     241   0x00005555556218e7 <+1111>:	jmp    0x555555621ccf <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2111>
     242   0x00005555556218ec <+1116>:	lea    -0x368(%rbp),%rax
     243   0x0000555555621a37 <+1447>:	lea    -0x70(%rbp),%rdi
     244   0x0000555555621a3b <+1451>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     245   0x0000555555621a40 <+1456>:	lea    -0x370(%rbp),%rdi
     246   0x0000555555621a47 <+1463>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     247   0x0000555555621a4c <+1468>:	jmp    0x555555621d02 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2162>
     248
     249403	            addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
     250   0x00005555556218f3 <+1123>:	mov    %rax,%rdi
     251   0x00005555556218f6 <+1126>:	mov    %rax,-0x490(%rbp)
     252   0x00005555556218fd <+1133>:	call   0x5555555d59f0 <_ZNKSt6vectorI8CServiceSaIS0_EE4sizeEv>
     253   0x0000555555621902 <+1138>:	mov    %rax,%rdi
     254   0x0000555555621905 <+1141>:	call   0x555555f58ff0 <_Z7GetRandm>
     255   0x000055555562190a <+1146>:	mov    -0x490(%rbp),%rdi
     256   0x0000555555621911 <+1153>:	mov    %rax,%rsi
     257   0x0000555555621914 <+1156>:	call   0x55555563e7c0 <_ZNSt6vectorI8CServiceSaIS0_EEixEm>
     258   0x0000555555621919 <+1161>:	lea    -0xc8(%rbp),%rdi
     259   0x0000555555621920 <+1168>:	mov    %rax,%rsi
     260   0x0000555555621923 <+1171>:	call   0x5555555d5980 <_ZN8CServiceC2ERKS_>
     261   0x0000555555621928 <+1176>:	jmp    0x55555562192d <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1181>
     262   0x000055555562192d <+1181>:	xor    %eax,%eax
     263   0x000055555562192f <+1183>:	mov    %eax,%edx
     264   0x0000555555621931 <+1185>:	lea    -0xa0(%rbp),%rdi
     265   0x0000555555621938 <+1192>:	lea    -0xc8(%rbp),%rsi
     266   0x000055555562193f <+1199>:	call   0x55555563ddb0 <_ZN8CAddressC2E8CService12ServiceFlags>
     267   0x0000555555621944 <+1204>:	jmp    0x555555621949 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1209>
     268   0x0000555555621949 <+1209>:	lea    -0xa0(%rbp),%rsi
     269   0x0000555555621950 <+1216>:	mov    -0x428(%rbp),%rdi
     270   0x0000555555621957 <+1223>:	call   0x55555563de20 <_ZN8CAddressaSEOS_>
     271   0x000055555562195c <+1228>:	jmp    0x555555621961 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1233>
     272   0x0000555555621961 <+1233>:	lea    -0xa0(%rbp),%rdi
     273   0x0000555555621968 <+1240>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     274   0x000055555562196d <+1245>:	lea    -0xc8(%rbp),%rdi
     275   0x0000555555621974 <+1252>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     276   0x0000555555621979 <+1257>:	mov    -0x428(%rbp),%rdi
     277--Type <RET> for more, q to quit, c to continue without paging--
     278   0x0000555555621a82 <+1522>:	lea    -0xa0(%rbp),%rdi
     279   0x0000555555621a89 <+1529>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     280   0x0000555555621a8e <+1534>:	lea    -0xc8(%rbp),%rdi
     281   0x0000555555621a95 <+1541>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     282   0x0000555555621a9a <+1546>:	jmp    0x555555621d02 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2162>
     283
     284404	            if (!addrConnect.IsValid()) {
     285   0x0000555555621980 <+1264>:	call   0x555555eaba70 <_ZNK8CNetAddr7IsValidEv>
     286   0x0000555555621985 <+1269>:	mov    %al,-0x491(%rbp)
     287   0x000055555562198b <+1275>:	jmp    0x555555621990 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1280>
     288   0x0000555555621990 <+1280>:	mov    -0x491(%rbp),%al
     289   0x0000555555621996 <+1286>:	test   $0x1,%al
     290   0x0000555555621998 <+1288>:	jne    0x555555621ae1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1617>
     291   0x000055555562199e <+1294>:	jmp    0x5555556219a3 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1299>
     292
     293405	                LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
     294   0x00005555556219a3 <+1299>:	jmp    0x5555556219a8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1304>
     295   0x00005555556219a8 <+1304>:	mov    $0x1,%edi
     296   0x00005555556219ad <+1309>:	call   0x55555561fd20 <_ZL17LogAcceptCategoryN5BCLog8LogFlagsE>
     297   0x00005555556219b2 <+1314>:	mov    %al,-0x492(%rbp)
     298   0x00005555556219b8 <+1320>:	jmp    0x5555556219bd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1325>
     299   0x00005555556219bd <+1325>:	mov    -0x492(%rbp),%al
     300   0x00005555556219c3 <+1331>:	test   $0x1,%al
     301   0x00005555556219c5 <+1333>:	jne    0x5555556219d0 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1344>
     302   0x00005555556219cb <+1339>:	jmp    0x555555621abd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1581>
     303   0x00005555556219d0 <+1344>:	lea    -0xe8(%rbp),%rdi
     304   0x00005555556219d7 <+1351>:	mov    -0x428(%rbp),%rsi
     305   0x00005555556219de <+1358>:	call   0x555555eaef60 <_ZNK8CService8ToStringB5cxx11Ev>
     306   0x00005555556219e3 <+1363>:	jmp    0x5555556219e8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1368>
     307   0x00005555556219e8 <+1368>:	lea    0xafb597(%rip),%rdi        # 0x55555611cf86
     308   0x00005555556219ef <+1375>:	lea    -0xe8(%rbp),%rsi
     309   0x00005555556219f6 <+1382>:	lea    -0x340(%rbp),%rdx
     310   0x00005555556219fd <+1389>:	call   0x555555622f20 <_ZL9LogPrintfIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKcEEvS7_DpRKT_>
     311   0x0000555555621a02 <+1394>:	jmp    0x555555621a07 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1399>
     312   0x0000555555621a07 <+1399>:	lea    -0xe8(%rbp),%rdi
     313   0x0000555555621a0e <+1406>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     314   0x0000555555621a13 <+1411>:	jmp    0x555555621abd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1581>
     315   0x0000555555621aac <+1564>:	lea    -0xe8(%rbp),%rdi
     316   0x0000555555621ab3 <+1571>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     317   0x0000555555621ab8 <+1576>:	jmp    0x555555621d02 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2162>
     318   0x0000555555621abd <+1581>:	jmp    0x555555621ac2 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1586>
     319   0x0000555555621ac2 <+1586>:	jmp    0x555555621ac7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1591>
     320
     321406	                return nullptr;
     322   0x0000555555621ac7 <+1591>:	movq   $0x0,-0x3c0(%rbp)
     323   0x0000555555621ad2 <+1602>:	movl   $0x1,-0x3f0(%rbp)
     324   0x0000555555621adc <+1612>:	jmp    0x555555621cd9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2121>
     325   0x0000555555621ae1 <+1617>:	mov    -0x430(%rbp),%rax
     326
     327407	            }
     328408	            // It is possible that we already have a connection to the IP/port pszDest resolved to.
     329409	            // In that case, drop the connection that was just created, and return the existing CNode instead.
     330410	            // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
     331411	            // name catch this early.
     332412	            LOCK(cs_vNodes);
     333   0x0000555555621ae8 <+1624>:	add    $0x50370,%rax
     334   0x0000555555621aee <+1630>:	lea    0xafb3be(%rip),%rdx        # 0x55555611ceb3
     335   0x0000555555621af5 <+1637>:	lea    0xb266d5(%rip),%rcx        # 0x5555561481d1
     336   0x0000555555621afc <+1644>:	lea    -0x338(%rbp),%rdi
     337   0x0000555555621b03 <+1651>:	mov    $0x19c,%r8d
     338   0x0000555555621b09 <+1657>:	xor    %r9d,%r9d
     339   0x0000555555621b0c <+1660>:	mov    %rax,%rsi
     340   0x0000555555621b0f <+1663>:	call   0x5555555cd8e0 <_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexESt11unique_lockIS1_EEC2ERS2_PKcS8_ib>
     341   0x0000555555621b14 <+1668>:	jmp    0x555555621b19 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1673>
     342   0x0000555555621b19 <+1673>:	lea    -0x110(%rbp),%rdi
     343   0x0000555555621b20 <+1680>:	mov    -0x428(%rbp),%rsi
     344
     345413	            CNode* pnode = FindNode(static_cast<CService>(addrConnect));
     346   0x0000555555621b27 <+1687>:	call   0x5555555d5980 <_ZN8CServiceC2ERKS_>
     347   0x0000555555621b2c <+1692>:	jmp    0x555555621b31 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1697>
     348   0x0000555555621b31 <+1697>:	lea    -0x110(%rbp),%rsi
     349   0x0000555555621b38 <+1704>:	mov    -0x430(%rbp),%rdi
     350   0x0000555555621b3f <+1711>:	call   0x555555620fe0 <_ZN8CConnman8FindNodeERK8CService>
     351   0x0000555555621b44 <+1716>:	mov    %rax,-0x4a0(%rbp)
     352   0x0000555555621b4b <+1723>:	jmp    0x555555621b50 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1728>
     353   0x0000555555621b50 <+1728>:	lea    -0x110(%rbp),%rdi
     354   0x0000555555621b57 <+1735>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     355   0x0000555555621b5c <+1740>:	mov    -0x4a0(%rbp),%rax
     356   0x0000555555621b63 <+1747>:	mov    %rax,-0x3f8(%rbp)
     357   0x0000555555621c43 <+1971>:	lea    -0x110(%rbp),%rdi
     358   0x0000555555621c4a <+1978>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     359   0x0000555555621c4f <+1983>:	jmp    0x555555621cbe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2094>
     360
     361414	            if (pnode)
     362   0x0000555555621b6a <+1754>:	cmpq   $0x0,-0x3f8(%rbp)
     363   0x0000555555621b72 <+1762>:	je     0x555555621c90 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2048>
     364
     365415	            {
     366416	                pnode->MaybeSetAddrName(std::string(pszDest));
     367   0x0000555555621b78 <+1768>:	mov    -0x3f8(%rbp),%rdi
     368   0x0000555555621b7f <+1775>:	mov    -0x340(%rbp),%rsi
     369   0x0000555555621b86 <+1782>:	lea    -0x378(%rbp),%rax
     370   0x0000555555621b8d <+1789>:	mov    %rdi,-0x4a8(%rbp)
     371   0x0000555555621b94 <+1796>:	mov    %rax,%rdi
     372   0x0000555555621b97 <+1799>:	mov    %rsi,-0x4b0(%rbp)
     373   0x0000555555621b9e <+1806>:	mov    %rax,-0x4b8(%rbp)
     374   0x0000555555621ba5 <+1813>:	call   0x555555582c40 <_ZNSaIcEC1Ev@plt>
     375   0x0000555555621baa <+1818>:	lea    -0x130(%rbp),%rdi
     376   0x0000555555621bb1 <+1825>:	mov    -0x4b0(%rbp),%rsi
     377   0x0000555555621bb8 <+1832>:	mov    -0x4b8(%rbp),%rdx
     378   0x0000555555621bbf <+1839>:	call   0x55555559c0c0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_>
     379   0x0000555555621bc4 <+1844>:	jmp    0x555555621bc9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1849>
     380   0x0000555555621bc9 <+1849>:	lea    -0x130(%rbp),%rsi
     381   0x0000555555621bd0 <+1856>:	mov    -0x4a8(%rbp),%rdi
     382   0x0000555555621bd7 <+1863>:	call   0x555555623210 <_ZN5CNode16MaybeSetAddrNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>
     383   0x0000555555621bdc <+1868>:	jmp    0x555555621be1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1873>
     384   0x0000555555621be1 <+1873>:	lea    -0x130(%rbp),%rdi
     385   0x0000555555621be8 <+1880>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     386   0x0000555555621bed <+1885>:	lea    -0x378(%rbp),%rdi
     387   0x0000555555621bf4 <+1892>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     388--Type <RET> for more, q to quit, c to continue without paging--
     389   0x0000555555621c73 <+2019>:	lea    -0x130(%rbp),%rdi
     390   0x0000555555621c7a <+2026>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     391   0x0000555555621c7f <+2031>:	lea    -0x378(%rbp),%rdi
     392   0x0000555555621c86 <+2038>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     393   0x0000555555621c8b <+2043>:	jmp    0x555555621cbe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2094>
     394
     395417	                LogPrintf("Failed to open new connection, already connected\n");
     396   0x0000555555621bf9 <+1897>:	lea    0xafb32d(%rip),%rdi        # 0x55555611cf2d
     397   0x0000555555621c00 <+1904>:	call   0x555555622950 <_ZL9LogPrintfIJEEvPKcDpRKT_>
     398   0x0000555555621c05 <+1909>:	jmp    0x555555621c0a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1914>
     399
     400418	                return nullptr;
     401   0x0000555555621c0a <+1914>:	movq   $0x0,-0x3c0(%rbp)
     402   0x0000555555621c15 <+1925>:	movl   $0x1,-0x3f0(%rbp)
     403   0x0000555555621c1f <+1935>:	jmp    0x555555621c9a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2058>
     404
     405419	            }
     406420	        }
     407   0x0000555555621c90 <+2048>:	movl   $0x0,-0x3f0(%rbp)
     408   0x0000555555621c9a <+2058>:	lea    -0x338(%rbp),%rdi
     409   0x0000555555621ca1 <+2065>:	call   0x5555555cd9c0 <_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexESt11unique_lockIS1_EED2Ev>
     410   0x0000555555621ca6 <+2070>:	mov    -0x3f0(%rbp),%eax
     411   0x0000555555621cac <+2076>:	test   %eax,%eax
     412   0x0000555555621cae <+2078>:	jne    0x555555621cd9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2121>
     413   0x0000555555621cb4 <+2084>:	jmp    0x555555621cb9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2089>
     414   0x0000555555621cb9 <+2089>:	jmp    0x555555621ccf <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2111>
     415   0x0000555555621cbe <+2094>:	lea    -0x338(%rbp),%rdi
     416   0x0000555555621cc5 <+2101>:	call   0x5555555cd9c0 <_ZN10UniqueLockI14AnnotatedMixinISt15recursive_mutexESt11unique_lockIS1_EED2Ev>
     417   0x0000555555621cca <+2106>:	jmp    0x555555621d02 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2162>
     418
     419421	    }
     420   0x0000555555621ccf <+2111>:	movl   $0x0,-0x3f0(%rbp)
     421   0x0000555555621cd9 <+2121>:	lea    -0x368(%rbp),%rdi
     422   0x0000555555621ce0 <+2128>:	call   0x5555555efee0 <_ZNSt6vectorI8CServiceSaIS0_EED2Ev>
     423   0x0000555555621ce5 <+2133>:	mov    -0x3f0(%rbp),%eax
     424   0x0000555555621ceb <+2139>:	test   %eax,%eax
     425   0x0000555555621ced <+2141>:	je     0x555555621cfd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2157>
     426   0x0000555555621cf3 <+2147>:	jmp    0x555555621cf8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2152>
     427   0x0000555555621cf8 <+2152>:	jmp    0x5555556228fd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5229>
     428   0x0000555555621cfd <+2157>:	jmp    0x555555621d13 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2179>
     429   0x0000555555621d02 <+2162>:	lea    -0x368(%rbp),%rdi
     430   0x0000555555621d09 <+2169>:	call   0x5555555efee0 <_ZNSt6vectorI8CServiceSaIS0_EED2Ev>
     431   0x0000555555621d0e <+2174>:	jmp    0x555555622931 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5281>
     432
     433422	
     434423	    // Connect
     435424	    bool connected = false;
     436   0x0000555555621d13 <+2179>:	movb   $0x0,-0x3f9(%rbp)
     437   0x0000555555621d1a <+2186>:	lea    -0x380(%rbp),%rdi
     438
     439425	    std::unique_ptr<Sock> sock;
     440   0x0000555555621d21 <+2193>:	call   0x55555563e820 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EEC2IS2_vEEv>
     441   0x0000555555621d26 <+2198>:	lea    -0x160(%rbp),%rdi
     442
     443426	    proxyType proxy;
     444   0x0000555555621d2d <+2205>:	call   0x55555563e880 <_ZN9proxyTypeC2Ev>
     445   0x0000555555621d32 <+2210>:	jmp    0x555555621d37 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2215>
     446   0x0000555555621d37 <+2215>:	lea    -0x190(%rbp),%rdi
     447
     448427	    CAddress addr_bind;
     449   0x0000555555621d3e <+2222>:	call   0x55555563e8e0 <_ZN8CAddressC2Ev>
     450   0x0000555555621d43 <+2227>:	jmp    0x555555621d48 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2232>
     451   0x0000555555621d48 <+2232>:	lea    -0x190(%rbp),%rdi
     452
     453428	    assert(!addr_bind.IsValid());
     454   0x0000555555621d4f <+2239>:	call   0x555555eaba70 <_ZNK8CNetAddr7IsValidEv>
     455   0x0000555555621d54 <+2244>:	mov    %al,-0x4b9(%rbp)
     456   0x0000555555621d5a <+2250>:	jmp    0x555555621d5f <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2255>
     457   0x0000555555621d5f <+2255>:	mov    -0x4b9(%rbp),%al
     458   0x0000555555621d65 <+2261>:	xor    $0xff,%al
     459   0x0000555555621d67 <+2263>:	test   $0x1,%al
     460   0x0000555555621d69 <+2265>:	jne    0x555555621d74 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2276>
     461   0x0000555555621d6f <+2271>:	jmp    0x555555621d79 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2281>
     462   0x0000555555621d74 <+2276>:	jmp    0x555555621dce <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2366>
     463   0x0000555555621d79 <+2281>:	lea    0xafb233(%rip),%rdi        # 0x55555611cfb3
     464   0x0000555555621d80 <+2288>:	lea    0xb2644a(%rip),%rsi        # 0x5555561481d1
     465   0x0000555555621d87 <+2295>:	mov    $0x1ac,%edx
     466   0x0000555555621d8c <+2300>:	lea    0xafb14f(%rip),%rcx        # 0x55555611cee2
     467   0x0000555555621d93 <+2307>:	call   0x555555581490 <__assert_fail@plt>
     468
     469429	
     470430	    if (addrConnect.IsValid()) {
     471=> 0x0000555555621dd5 <+2373>:	call   0x555555eaba70 <_ZNK8CNetAddr7IsValidEv>
     472   0x0000555555621dda <+2378>:	mov    %al,-0x4ba(%rbp)
     473   0x0000555555621de0 <+2384>:	jmp    0x555555621de5 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2389>
     474   0x0000555555621de5 <+2389>:	mov    -0x4ba(%rbp),%al
     475   0x0000555555621deb <+2395>:	test   $0x1,%al
     476   0x0000555555621ded <+2397>:	jne    0x555555621df8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2408>
     477   0x0000555555621df3 <+2403>:	jmp    0x5555556222e1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3665>
     478
     479431	        bool proxyConnectionFailed = false;
     480   0x0000555555621df8 <+2408>:	movb   $0x0,-0x381(%rbp)
     481   0x0000555555621dff <+2415>:	mov    -0x428(%rbp),%rdi
     482
     483432	
     484433	        if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {
     485   0x0000555555621e06 <+2422>:	call   0x555555eabf20 <_ZNK8CNetAddr10GetNetworkEv>
     486   0x0000555555621e0b <+2427>:	mov    %eax,-0x4c0(%rbp)
     487   0x0000555555621e11 <+2433>:	jmp    0x555555621e16 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2438>
     488   0x0000555555621e16 <+2438>:	mov    -0x4c0(%rbp),%eax
     489   0x0000555555621e1c <+2444>:	cmp    $0x4,%eax
     490   0x0000555555621e1f <+2447>:	jne    0x555555621fcf <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2879>
     491   0x0000555555621e25 <+2453>:	mov    -0x430(%rbp),%rax
     492   0x0000555555621e2c <+2460>:	add    $0x50518,%rax
     493   0x0000555555621e32 <+2466>:	mov    %rax,%rdi
     494   0x0000555555621e35 <+2469>:	call   0x55555563e950 <_ZNKSt10unique_ptrIN3i2p3sam7SessionESt14default_deleteIS2_EE3getEv>
     495   0x0000555555621e3a <+2474>:	cmp    $0x0,%rax
     496   0x0000555555621e3e <+2478>:	je     0x555555621fcf <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2879>
     497   0x0000555555621e44 <+2484>:	lea    -0x1f0(%rbp),%rdi
     498
     499434	            i2p::Connection conn;
     500   0x0000555555621e4b <+2491>:	call   0x55555563e9b0 <_ZN3i2p10ConnectionC2Ev>
     501   0x0000555555621e50 <+2496>:	jmp    0x555555621e55 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2501>
     502   0x0000555555621e55 <+2501>:	mov    -0x430(%rbp),%rax
     503
     504435	            if (m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed)) {
     505   0x0000555555621e5c <+2508>:	add    $0x50518,%rax
     506   0x0000555555621e62 <+2514>:	mov    %rax,%rdi
     507   0x0000555555621e65 <+2517>:	call   0x55555563ea70 <_ZNKSt10unique_ptrIN3i2p3sam7SessionESt14default_deleteIS2_EEptEv>
     508   0x0000555555621e6a <+2522>:	lea    -0x1f0(%rbp),%rdx
     509   0x0000555555621e71 <+2529>:	lea    -0x381(%rbp),%rcx
     510   0x0000555555621e78 <+2536>:	mov    %rax,%rdi
     511   0x0000555555621e7b <+2539>:	mov    -0x428(%rbp),%rsi
     512   0x0000555555621e82 <+2546>:	call   0x555555b78370 <_ZN3i2p3sam7Session7ConnectERK8CServiceRNS_10ConnectionERb>
     513   0x0000555555621e87 <+2551>:	mov    %al,-0x4c1(%rbp)
     514   0x0000555555621e8d <+2557>:	jmp    0x555555621e92 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2562>
     515   0x0000555555621e92 <+2562>:	mov    -0x4c1(%rbp),%al
     516   0x0000555555621e98 <+2568>:	test   $0x1,%al
     517   0x0000555555621e9a <+2570>:	jne    0x555555621ea5 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2581>
     518   0x0000555555621ea0 <+2576>:	jmp    0x555555621fad <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2845>
     519
     520436	                connected = true;
     521   0x0000555555621ea5 <+2581>:	movb   $0x1,-0x3f9(%rbp)
     522   0x0000555555621eac <+2588>:	lea    -0x1f0(%rbp),%rdi
     523
     524437	                *sock = std::move(conn.sock);
     525   0x0000555555621eb3 <+2595>:	call   0x55555563eac0 <_ZSt4moveIR4SockEONSt16remove_referenceIT_E4typeEOS3_>
     526   0x0000555555621eb8 <+2600>:	lea    -0x380(%rbp),%rdi
     527   0x0000555555621ebf <+2607>:	mov    %rax,-0x4d0(%rbp)
     528   0x0000555555621ec6 <+2614>:	call   0x55555563eb10 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEdeEv>
     529   0x0000555555621ecb <+2619>:	mov    %rax,-0x4d8(%rbp)
     530   0x0000555555621ed2 <+2626>:	jmp    0x555555621ed7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2631>
     531   0x0000555555621ed7 <+2631>:	mov    -0x4d8(%rbp),%rax
     532   0x0000555555621ede <+2638>:	mov    (%rax),%rcx
     533   0x0000555555621ee1 <+2641>:	mov    0x10(%rcx),%rcx
     534   0x0000555555621ee5 <+2645>:	mov    %rax,%rdi
     535   0x0000555555621ee8 <+2648>:	mov    -0x4d0(%rbp),%rsi
     536   0x0000555555621eef <+2655>:	call   *%rcx
     537   0x0000555555621ef1 <+2657>:	jmp    0x555555621ef6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2662>
     538
     539438	                addr_bind = CAddress{conn.me, NODE_NONE};
     540   0x0000555555621ef6 <+2662>:	lea    -0x1e0(%rbp),%rsi
     541   0x0000555555621efd <+2669>:	lea    -0x248(%rbp),%rdi
     542   0x0000555555621f04 <+2676>:	call   0x5555555d5980 <_ZN8CServiceC2ERKS_>
     543   0x0000555555621f09 <+2681>:	jmp    0x555555621f0e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2686>
     544   0x0000555555621f0e <+2686>:	xor    %eax,%eax
     545   0x0000555555621f10 <+2688>:	mov    %eax,%edx
     546   0x0000555555621f12 <+2690>:	lea    -0x220(%rbp),%rdi
     547   0x0000555555621f19 <+2697>:	lea    -0x248(%rbp),%rsi
     548   0x0000555555621f20 <+2704>:	call   0x55555563ddb0 <_ZN8CAddressC2E8CService12ServiceFlags>
     549   0x0000555555621f25 <+2709>:	jmp    0x555555621f2a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2714>
     550   0x0000555555621f2a <+2714>:	lea    -0x190(%rbp),%rdi
     551   0x0000555555621f31 <+2721>:	lea    -0x220(%rbp),%rsi
     552   0x0000555555621f38 <+2728>:	call   0x55555563de20 <_ZN8CAddressaSEOS_>
     553   0x0000555555621f3d <+2733>:	jmp    0x555555621f42 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2738>
     554   0x0000555555621f42 <+2738>:	lea    -0x220(%rbp),%rdi
     555   0x0000555555621f49 <+2745>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     556   0x0000555555621f4e <+2750>:	lea    -0x248(%rbp),%rdi
     557   0x0000555555621f55 <+2757>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     558   0x0000555555621f90 <+2816>:	lea    -0x220(%rbp),%rdi
     559   0x0000555555621f97 <+2823>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     560   0x0000555555621f9c <+2828>:	lea    -0x248(%rbp),%rdi
     561   0x0000555555621fa3 <+2835>:	call   0x5555555d3b20 <_ZN8CServiceD2Ev>
     562   0x0000555555621fa8 <+2840>:	jmp    0x555555621fbe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2862>
     563
     564439	            }
     565   0x0000555555621f5a <+2762>:	jmp    0x555555621fad <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2845>
     566
     567440	        } else if (GetProxy(addrConnect.GetNetwork(), proxy)) {
     568   0x0000555555621fad <+2845>:	lea    -0x1f0(%rbp),%rdi
     569   0x0000555555621fb4 <+2852>:	call   0x55555563eb60 <_ZN3i2p10ConnectionD2Ev>
     570   0x0000555555621fb9 <+2857>:	jmp    0x55555562225e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3534>
     571   0x0000555555621fbe <+2862>:	lea    -0x1f0(%rbp),%rdi
     572   0x0000555555621fc5 <+2869>:	call   0x55555563eb60 <_ZN3i2p10ConnectionD2Ev>
     573   0x0000555555621fca <+2874>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
     574   0x0000555555621fcf <+2879>:	mov    -0x428(%rbp),%rdi
     575   0x0000555555621fd6 <+2886>:	call   0x555555eabf20 <_ZNK8CNetAddr10GetNetworkEv>
     576   0x0000555555621fdb <+2891>:	mov    %eax,-0x4dc(%rbp)
     577   0x0000555555621fe1 <+2897>:	jmp    0x555555621fe6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2902>
     578   0x0000555555621fe6 <+2902>:	lea    -0x160(%rbp),%rsi
     579   0x0000555555621fed <+2909>:	mov    -0x4dc(%rbp),%edi
     580   0x0000555555621ff3 <+2915>:	call   0x555555eb7dd0 <_Z8GetProxy7NetworkR9proxyType>
     581   0x0000555555621ff8 <+2920>:	mov    %al,-0x4dd(%rbp)
     582   0x0000555555621ffe <+2926>:	jmp    0x555555622003 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2931>
     583   0x0000555555622003 <+2931>:	mov    -0x4dd(%rbp),%al
     584   0x0000555555622009 <+2937>:	test   $0x1,%al
     585   0x000055555562200b <+2939>:	jne    0x555555622016 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2950>
     586   0x0000555555622011 <+2945>:	jmp    0x55555562215a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3274>
     587
     588441	            sock = CreateSock(proxy.proxy);
     589   0x0000555555622016 <+2950>:	lea    0xee2773(%rip),%rsi        # 0x555556504790 <CreateSock>
     590   0x000055555562201d <+2957>:	lea    -0x390(%rbp),%rdi
     591   0x0000555555622024 <+2964>:	lea    -0x160(%rbp),%rdx
     592   0x000055555562202b <+2971>:	call   0x55555563ebd0 <_ZNKSt8functionIFSt10unique_ptrI4SockSt14default_deleteIS1_EERK8CServiceEEclES7_>
     593   0x0000555555622030 <+2976>:	jmp    0x555555622035 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2981>
     594   0x0000555555622035 <+2981>:	lea    -0x380(%rbp),%rdi
     595   0x000055555562203c <+2988>:	lea    -0x390(%rbp),%rsi
     596   0x0000555555622043 <+2995>:	call   0x55555563ec80 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EEaSEOS3_>
     597   0x0000555555622048 <+3000>:	lea    -0x390(%rbp),%rdi
     598   0x000055555562204f <+3007>:	mov    %rax,-0x4e8(%rbp)
     599   0x0000555555622056 <+3014>:	call   0x55555563ece0 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EED2Ev>
     600
     601442	            if (!sock) {
     602   0x000055555562205b <+3019>:	lea    -0x380(%rbp),%rdi
     603   0x0000555555622062 <+3026>:	call   0x55555563ed90 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEcvbEv>
     604   0x0000555555622067 <+3031>:	test   $0x1,%al
     605   0x0000555555622069 <+3033>:	jne    0x555555622089 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3065>
     606
     607443	                return nullptr;
     608   0x000055555562206f <+3039>:	movq   $0x0,-0x3c0(%rbp)
     609--Type <RET> for more, q to quit, c to continue without paging--
     610   0x000055555562207a <+3050>:	movl   $0x1,-0x3f0(%rbp)
     611   0x0000555555622084 <+3060>:	jmp    0x5555556228ab <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5147>
     612   0x0000555555622089 <+3065>:	lea    -0x268(%rbp),%rdi
     613   0x0000555555622090 <+3072>:	mov    -0x428(%rbp),%rsi
     614
     615444	            }
     616445	            connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(),
     617   0x0000555555622097 <+3079>:	call   0x555555eabfc0 <_ZNK8CNetAddr10ToStringIPB5cxx11Ev>
     618   0x000055555562209c <+3084>:	jmp    0x5555556220a1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3089>
     619   0x00005555556220a1 <+3089>:	mov    -0x428(%rbp),%rdi
     620   0x00005555556220a8 <+3096>:	call   0x555555eae740 <_ZNK8CService7GetPortEv>
     621   0x00005555556220ad <+3101>:	mov    %ax,-0x4ea(%rbp)
     622   0x00005555556220b4 <+3108>:	jmp    0x5555556220b9 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3113>
     623   0x00005555556220b9 <+3113>:	mov    -0x4ea(%rbp),%ax
     624   0x00005555556220c0 <+3120>:	movzwl %ax,%edx
     625   0x00005555556220c3 <+3123>:	lea    -0x380(%rbp),%rdi
     626   0x00005555556220ca <+3130>:	mov    %edx,-0x4f0(%rbp)
     627   0x000055555562210d <+3197>:	call   0x555555eb8320 <_Z19ConnectThroughProxyRK9proxyTypeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRK4SockiRb>
     628   0x0000555555622112 <+3202>:	mov    %al,-0x4f9(%rbp)
     629   0x0000555555622118 <+3208>:	jmp    0x55555562211d <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3213>
     630   0x000055555562211d <+3213>:	mov    -0x4f9(%rbp),%al
     631   0x0000555555622123 <+3219>:	and    $0x1,%al
     632   0x0000555555622125 <+3221>:	mov    %al,-0x3f9(%rbp)
     633   0x000055555562212b <+3227>:	lea    -0x268(%rbp),%rdi
     634   0x0000555555622132 <+3234>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     635   0x0000555555622149 <+3257>:	lea    -0x268(%rbp),%rdi
     636   0x0000555555622150 <+3264>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     637   0x0000555555622155 <+3269>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
     638
     639446	                                            *sock, nConnectTimeout, proxyConnectionFailed);
     640   0x00005555556220d0 <+3136>:	call   0x55555563eb10 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEdeEv>
     641   0x00005555556220d5 <+3141>:	mov    %rax,-0x4f8(%rbp)
     642   0x00005555556220dc <+3148>:	jmp    0x5555556220e1 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3153>
     643   0x00005555556220e1 <+3153>:	lea    0xeda5b8(%rip),%rax        # 0x5555564fc6a0 <nConnectTimeout>
     644   0x00005555556220e8 <+3160>:	mov    (%rax),%r8d
     645   0x00005555556220eb <+3163>:	lea    -0x160(%rbp),%rdi
     646   0x00005555556220f2 <+3170>:	lea    -0x268(%rbp),%rsi
     647   0x00005555556220f9 <+3177>:	lea    -0x381(%rbp),%r9
     648   0x0000555555622100 <+3184>:	mov    -0x4f0(%rbp),%edx
     649   0x0000555555622106 <+3190>:	mov    -0x4f8(%rbp),%rcx
     650
     651447	        } else {
     652   0x0000555555622137 <+3239>:	jmp    0x555555622259 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3529>
     653
     654448	            // no proxy needed (none set for target network)
     655449	            sock = CreateSock(addrConnect);
     656   0x000055555562215a <+3274>:	lea    0xee262f(%rip),%rsi        # 0x555556504790 <CreateSock>
     657   0x0000555555622161 <+3281>:	lea    -0x398(%rbp),%rdi
     658   0x0000555555622168 <+3288>:	mov    -0x428(%rbp),%rdx
     659   0x000055555562216f <+3295>:	call   0x55555563ebd0 <_ZNKSt8functionIFSt10unique_ptrI4SockSt14default_deleteIS1_EERK8CServiceEEclES7_>
     660   0x0000555555622174 <+3300>:	jmp    0x555555622179 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3305>
     661   0x0000555555622179 <+3305>:	lea    -0x380(%rbp),%rdi
     662   0x0000555555622180 <+3312>:	lea    -0x398(%rbp),%rsi
     663   0x0000555555622187 <+3319>:	call   0x55555563ec80 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EEaSEOS3_>
     664   0x000055555562218c <+3324>:	lea    -0x398(%rbp),%rdi
     665   0x0000555555622193 <+3331>:	mov    %rax,-0x508(%rbp)
     666   0x000055555562219a <+3338>:	call   0x55555563ece0 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EED2Ev>
     667
     668450	            if (!sock) {
     669   0x000055555562219f <+3343>:	lea    -0x380(%rbp),%rdi
     670   0x00005555556221a6 <+3350>:	call   0x55555563ed90 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEcvbEv>
     671   0x00005555556221ab <+3355>:	test   $0x1,%al
     672   0x00005555556221ad <+3357>:	jne    0x5555556221cd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3389>
     673
     674451	                return nullptr;
     675   0x00005555556221b3 <+3363>:	movq   $0x0,-0x3c0(%rbp)
     676   0x00005555556221be <+3374>:	movl   $0x1,-0x3f0(%rbp)
     677   0x00005555556221c8 <+3384>:	jmp    0x5555556228ab <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5147>
     678   0x00005555556221cd <+3389>:	mov    -0x428(%rbp),%rax
     679   0x00005555556221d4 <+3396>:	lea    -0x380(%rbp),%rdi
     680   0x00005555556221db <+3403>:	mov    %rax,-0x510(%rbp)
     681
     682452	            }
     683453	            connected = ConnectSocketDirectly(addrConnect, sock->Get(), nConnectTimeout,
     684   0x00005555556221e2 <+3410>:	call   0x55555563edf0 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEptEv>
     685   0x00005555556221e7 <+3415>:	mov    (%rax),%rcx
     686   0x00005555556221ea <+3418>:	mov    0x18(%rcx),%rcx
     687   0x00005555556221ee <+3422>:	mov    %rax,%rdi
     688   0x00005555556221f1 <+3425>:	call   *%rcx
     689   0x00005555556221f3 <+3427>:	mov    %eax,-0x514(%rbp)
     690   0x00005555556221f9 <+3433>:	jmp    0x5555556221fe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3438>
     691   0x00005555556221fe <+3438>:	mov    -0x514(%rbp),%eax
     692   0x0000555555622204 <+3444>:	mov    %eax,-0x39c(%rbp)
     693   0x000055555562220a <+3450>:	lea    0xeda48f(%rip),%rcx        # 0x5555564fc6a0 <nConnectTimeout>
     694   0x0000555555622211 <+3457>:	mov    (%rcx),%edx
     695   0x0000555555622220 <+3472>:	movzbl %dil,%ecx
     696   0x0000555555622224 <+3476>:	lea    -0x39c(%rbp),%r8
     697   0x000055555562222b <+3483>:	mov    -0x510(%rbp),%rdi
     698   0x0000555555622232 <+3490>:	mov    %esi,-0x518(%rbp)
     699   0x0000555555622238 <+3496>:	mov    %r8,%rsi
     700   0x000055555562223b <+3499>:	call   0x555555eb71f0 <_Z21ConnectSocketDirectlyRK8CServiceRKjib>
     701   0x0000555555622240 <+3504>:	mov    %al,-0x519(%rbp)
     702   0x0000555555622246 <+3510>:	jmp    0x55555562224b <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3515>
     703   0x000055555562224b <+3515>:	mov    -0x519(%rbp),%al
     704   0x0000555555622251 <+3521>:	and    $0x1,%al
     705   0x0000555555622253 <+3523>:	mov    %al,-0x3f9(%rbp)
     706   0x0000555555622259 <+3529>:	jmp    0x55555562225e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3534>
     707
     708454	                                              conn_type == ConnectionType::MANUAL);
     709   0x0000555555622213 <+3459>:	mov    -0x3d0(%rbp),%esi
     710   0x0000555555622219 <+3465>:	sub    $0x2,%esi
     711   0x000055555562221c <+3468>:	sete   %dil
     712
     713455	        }
     714456	        if (!proxyConnectionFailed) {
     715   0x000055555562225e <+3534>:	testb  $0x1,-0x381(%rbp)
     716   0x0000555555622265 <+3541>:	jne    0x5555556222dc <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3660>
     717   0x000055555562226b <+3547>:	mov    -0x430(%rbp),%rax
     718
     719457	            // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
     720--Type <RET> for more, q to quit, c to continue without paging--
     721458	            // the proxy, mark this as an attempt.
     722459	            addrman.Attempt(addrConnect, fCountFailure);
     723   0x0000555555622272 <+3554>:	add    $0xc0,%rax
     724   0x0000555555622278 <+3560>:	mov    -0x428(%rbp),%rcx
     725   0x000055555562227f <+3567>:	mov    -0x3c9(%rbp),%dl
     726   0x0000555555622285 <+3573>:	mov    %rax,-0x528(%rbp)
     727   0x000055555562228c <+3580>:	mov    %rcx,-0x530(%rbp)
     728   0x0000555555622293 <+3587>:	mov    %dl,-0x531(%rbp)
     729   0x0000555555622299 <+3593>:	call   0x5555559d35f0 <_Z15GetAdjustedTimev>
     730   0x000055555562229e <+3598>:	mov    %rax,-0x540(%rbp)
     731   0x00005555556222a5 <+3605>:	jmp    0x5555556222aa <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3610>
     732   0x00005555556222aa <+3610>:	mov    -0x531(%rbp),%al
     733   0x00005555556222b0 <+3616>:	movzbl %al,%ecx
     734   0x00005555556222b3 <+3619>:	and    $0x1,%ecx
     735   0x00005555556222b6 <+3622>:	mov    -0x528(%rbp),%rdi
     736   0x00005555556222bd <+3629>:	mov    -0x530(%rbp),%rsi
     737   0x00005555556222c4 <+3636>:	mov    %ecx,%edx
     738   0x00005555556222c6 <+3638>:	mov    -0x540(%rbp),%rcx
     739   0x00005555556222cd <+3645>:	call   0x55555563ee40 <_ZN8CAddrMan7AttemptERK8CServicebl>
     740   0x00005555556222d2 <+3650>:	jmp    0x5555556222d7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3655>
     741
     742460	        }
     743   0x00005555556222d7 <+3655>:	jmp    0x5555556222dc <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3660>
     744
     745461	    } else if (pszDest && GetNameProxy(proxy)) {
     746   0x00005555556222dc <+3660>:	jmp    0x5555556224fc <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4204>
     747   0x00005555556222e1 <+3665>:	cmpq   $0x0,-0x340(%rbp)
     748   0x00005555556222e9 <+3673>:	je     0x5555556224f7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4199>
     749   0x00005555556222ef <+3679>:	lea    -0x160(%rbp),%rdi
     750   0x00005555556222f6 <+3686>:	call   0x555555eb8020 <_Z12GetNameProxyR9proxyType>
     751   0x00005555556222fb <+3691>:	mov    %al,-0x541(%rbp)
     752   0x0000555555622301 <+3697>:	jmp    0x555555622306 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3702>
     753   0x0000555555622306 <+3702>:	mov    -0x541(%rbp),%al
     754   0x000055555562230c <+3708>:	test   $0x1,%al
     755   0x000055555562230e <+3710>:	jne    0x555555622319 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3721>
     756   0x0000555555622314 <+3716>:	jmp    0x5555556224f7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4199>
     757
     758462	        sock = CreateSock(proxy.proxy);
     759   0x0000555555622319 <+3721>:	lea    0xee2470(%rip),%rsi        # 0x555556504790 <CreateSock>
     760   0x0000555555622320 <+3728>:	lea    -0x3a8(%rbp),%rdi
     761   0x0000555555622327 <+3735>:	lea    -0x160(%rbp),%rdx
     762   0x000055555562232e <+3742>:	call   0x55555563ebd0 <_ZNKSt8functionIFSt10unique_ptrI4SockSt14default_deleteIS1_EERK8CServiceEEclES7_>
     763   0x0000555555622333 <+3747>:	jmp    0x555555622338 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3752>
     764   0x0000555555622338 <+3752>:	lea    -0x380(%rbp),%rdi
     765   0x000055555562233f <+3759>:	lea    -0x3a8(%rbp),%rsi
     766   0x0000555555622346 <+3766>:	call   0x55555563ec80 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EEaSEOS3_>
     767   0x000055555562234b <+3771>:	lea    -0x3a8(%rbp),%rdi
     768   0x0000555555622352 <+3778>:	mov    %rax,-0x550(%rbp)
     769   0x0000555555622359 <+3785>:	call   0x55555563ece0 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EED2Ev>
     770
     771463	        if (!sock) {
     772   0x000055555562235e <+3790>:	lea    -0x380(%rbp),%rdi
     773   0x0000555555622365 <+3797>:	call   0x55555563ed90 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEcvbEv>
     774   0x000055555562236a <+3802>:	test   $0x1,%al
     775   0x000055555562236c <+3804>:	jne    0x55555562238c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3836>
     776
     777464	            return nullptr;
     778   0x0000555555622372 <+3810>:	movq   $0x0,-0x3c0(%rbp)
     779   0x000055555562237d <+3821>:	movl   $0x1,-0x3f0(%rbp)
     780   0x0000555555622387 <+3831>:	jmp    0x5555556228ab <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5147>
     781   0x000055555562238c <+3836>:	lea    -0x288(%rbp),%rdi
     782
     783465	        }
     784466	        std::string host;
     785   0x0000555555622393 <+3843>:	call   0x555555581920 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@plt>
     786
     787467	        int port = default_port;
     788   0x0000555555622398 <+3848>:	mov    -0x3ec(%rbp),%eax
     789   0x000055555562239e <+3854>:	mov    %eax,-0x3ac(%rbp)
     790
     791468	        SplitHostPort(std::string(pszDest), port, host);
     792   0x00005555556223a4 <+3860>:	mov    -0x340(%rbp),%rsi
     793   0x00005555556223ab <+3867>:	lea    -0x3b0(%rbp),%rcx
     794   0x00005555556223b2 <+3874>:	mov    %rcx,%rdi
     795   0x00005555556223b5 <+3877>:	mov    %rsi,-0x558(%rbp)
     796   0x00005555556223bc <+3884>:	mov    %rcx,-0x560(%rbp)
     797   0x00005555556223c3 <+3891>:	call   0x555555582c40 <_ZNSaIcEC1Ev@plt>
     798   0x00005555556223c8 <+3896>:	lea    -0x2a8(%rbp),%rdi
     799   0x00005555556223cf <+3903>:	mov    -0x558(%rbp),%rsi
     800   0x00005555556223d6 <+3910>:	mov    -0x560(%rbp),%rdx
     801   0x00005555556223dd <+3917>:	call   0x55555559c0c0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_>
     802   0x00005555556223e2 <+3922>:	jmp    0x5555556223e7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3927>
     803   0x00005555556223e7 <+3927>:	lea    -0x2a8(%rbp),%rdi
     804   0x00005555556223ee <+3934>:	lea    -0x3ac(%rbp),%rsi
     805   0x00005555556223f5 <+3941>:	lea    -0x288(%rbp),%rdx
     806   0x00005555556223fc <+3948>:	call   0x555555fa7de0 <_Z13SplitHostPortNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERiRS4_>
     807   0x0000555555622401 <+3953>:	jmp    0x555555622406 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+3958>
     808   0x0000555555622406 <+3958>:	lea    -0x2a8(%rbp),%rdi
     809   0x000055555562240d <+3965>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     810   0x0000555555622412 <+3970>:	lea    -0x3b0(%rbp),%rdi
     811   0x0000555555622419 <+3977>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     812   0x00005555556224bc <+4140>:	lea    -0x2a8(%rbp),%rdi
     813   0x00005555556224c3 <+4147>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     814   0x00005555556224c8 <+4152>:	lea    -0x3b0(%rbp),%rdi
     815   0x00005555556224cf <+4159>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     816   0x00005555556224d4 <+4164>:	jmp    0x5555556224e6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4182>
     817
     818469	        bool proxyConnectionFailed;
     819470	        connected = ConnectThroughProxy(proxy, host, port, *sock, nConnectTimeout,
     820   0x000055555562241e <+3982>:	mov    -0x3ac(%rbp),%edx
     821   0x0000555555622424 <+3988>:	lea    -0x380(%rbp),%rdi
     822   0x000055555562242b <+3995>:	mov    %edx,-0x564(%rbp)
     823   0x0000555555622431 <+4001>:	call   0x55555563eb10 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEdeEv>
     824   0x0000555555622436 <+4006>:	mov    %rax,-0x570(%rbp)
     825   0x000055555562243d <+4013>:	jmp    0x555555622442 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4018>
     826   0x0000555555622442 <+4018>:	lea    0xeda257(%rip),%rax        # 0x5555564fc6a0 <nConnectTimeout>
     827   0x0000555555622449 <+4025>:	mov    (%rax),%r8d
     828   0x000055555562244c <+4028>:	lea    -0x160(%rbp),%rdi
     829   0x0000555555622453 <+4035>:	lea    -0x288(%rbp),%rsi
     830   0x000055555562245a <+4042>:	lea    -0x3b1(%rbp),%r9
     831   0x0000555555622461 <+4049>:	mov    -0x564(%rbp),%edx
     832   0x0000555555622467 <+4055>:	mov    -0x570(%rbp),%rcx
     833   0x000055555562246e <+4062>:	call   0x555555eb8320 <_Z19ConnectThroughProxyRK9proxyTypeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRK4SockiRb>
     834   0x0000555555622473 <+4067>:	mov    %al,-0x571(%rbp)
     835   0x0000555555622479 <+4073>:	jmp    0x55555562247e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4078>
     836   0x000055555562247e <+4078>:	mov    -0x571(%rbp),%al
     837   0x0000555555622484 <+4084>:	and    $0x1,%al
     838   0x0000555555622486 <+4086>:	mov    %al,-0x3f9(%rbp)
     839
     840471	                                        proxyConnectionFailed);
     841472	    }
     842   0x000055555562248c <+4092>:	lea    -0x288(%rbp),%rdi
     843   0x0000555555622493 <+4099>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     844   0x0000555555622498 <+4104>:	jmp    0x5555556224f7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4199>
     845   0x00005555556224e6 <+4182>:	lea    -0x288(%rbp),%rdi
     846   0x00005555556224ed <+4189>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     847   0x00005555556224f2 <+4194>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
     848   0x00005555556224f7 <+4199>:	jmp    0x5555556224fc <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4204>
     849
     850473	    if (!connected) {
     851   0x00005555556224fc <+4204>:	testb  $0x1,-0x3f9(%rbp)
     852   0x0000555555622503 <+4211>:	jne    0x555555622523 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4243>
     853
     854474	        return nullptr;
     855   0x0000555555622509 <+4217>:	movq   $0x0,-0x3c0(%rbp)
     856   0x0000555555622514 <+4228>:	movl   $0x1,-0x3f0(%rbp)
     857   0x000055555562251e <+4238>:	jmp    0x5555556228ab <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5147>
     858   0x0000555555622523 <+4243>:	mov    -0x430(%rbp),%rdi
     859
     860475	    }
     861476	
     862477	    // Add node
     863478	    NodeId id = GetNewNodeId();
     864   0x000055555562252a <+4250>:	call   0x5555556232f0 <_ZN8CConnman12GetNewNodeIdEv>
     865   0x000055555562252f <+4255>:	mov    %rax,-0x580(%rbp)
     866   0x0000555555622536 <+4262>:	jmp    0x55555562253b <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4267>
     867   0x000055555562253b <+4267>:	mov    -0x580(%rbp),%rax
     868   0x0000555555622542 <+4274>:	mov    %rax,-0x408(%rbp)
     869   0x0000555555622549 <+4281>:	lea    -0x2d8(%rbp),%rdi
     870   0x0000555555622550 <+4288>:	movabs $0xd93e69e2bbfa5735,%rdx
     871   0x000055555562255a <+4298>:	mov    -0x430(%rbp),%rsi
     872
     873479	    uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
     874   0x0000555555622561 <+4305>:	call   0x555555623400 <_ZNK8CConnman26GetDeterministicRandomizerEm>
     875   0x0000555555622566 <+4310>:	jmp    0x55555562256b <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4315>
     876   0x000055555562256b <+4315>:	mov    -0x408(%rbp),%rsi
     877   0x0000555555622572 <+4322>:	lea    -0x2d8(%rbp),%rdi
     878   0x0000555555622579 <+4329>:	call   0x55555601ba30 <_ZN10CSipHasher5WriteEm>
     879   0x000055555562257e <+4334>:	mov    %rax,-0x588(%rbp)
     880   0x0000555555622585 <+4341>:	jmp    0x55555562258a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4346>
     881   0x000055555562258a <+4346>:	mov    -0x588(%rbp),%rdi
     882   0x0000555555622591 <+4353>:	call   0x55555601c070 <_ZNK10CSipHasher8FinalizeEv>
     883   0x0000555555622596 <+4358>:	mov    %rax,-0x590(%rbp)
     884   0x000055555562259d <+4365>:	jmp    0x5555556225a2 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4370>
     885   0x00005555556225a2 <+4370>:	mov    -0x590(%rbp),%rax
     886--Type <RET> for more, q to quit, c to continue without paging--
     887   0x00005555556225a9 <+4377>:	mov    %rax,-0x410(%rbp)
     888   0x00005555556225b0 <+4384>:	lea    -0x190(%rbp),%rdi
     889
     890480	    if (!addr_bind.IsValid()) {
     891   0x00005555556225b7 <+4391>:	call   0x555555eaba70 <_ZNK8CNetAddr7IsValidEv>
     892   0x00005555556225bc <+4396>:	mov    %al,-0x591(%rbp)
     893   0x00005555556225c2 <+4402>:	jmp    0x5555556225c7 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4407>
     894   0x00005555556225c7 <+4407>:	mov    -0x591(%rbp),%al
     895   0x00005555556225cd <+4413>:	test   $0x1,%al
     896   0x00005555556225cf <+4415>:	jne    0x55555562265b <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4555>
     897   0x00005555556225d5 <+4421>:	jmp    0x5555556225da <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4426>
     898   0x00005555556225da <+4426>:	lea    -0x380(%rbp),%rdi
     899
     900481	        addr_bind = GetBindAddress(sock->Get());
     901   0x00005555556225e1 <+4433>:	call   0x55555563edf0 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEptEv>
     902   0x00005555556225e6 <+4438>:	mov    (%rax),%rcx
     903   0x00005555556225e9 <+4441>:	mov    0x18(%rcx),%rcx
     904   0x00005555556225ed <+4445>:	mov    %rax,%rdi
     905   0x00005555556225f0 <+4448>:	call   *%rcx
     906   0x00005555556225f2 <+4450>:	mov    %eax,-0x598(%rbp)
     907   0x00005555556225f8 <+4456>:	jmp    0x5555556225fd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4461>
     908   0x00005555556225fd <+4461>:	lea    -0x308(%rbp),%rdi
     909   0x0000555555622604 <+4468>:	mov    -0x598(%rbp),%esi
     910   0x000055555562260a <+4474>:	call   0x5555556234a0 <_ZL14GetBindAddressj>
     911   0x000055555562260f <+4479>:	jmp    0x555555622614 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4484>
     912   0x0000555555622614 <+4484>:	lea    -0x190(%rbp),%rdi
     913   0x000055555562261b <+4491>:	lea    -0x308(%rbp),%rsi
     914   0x0000555555622622 <+4498>:	call   0x55555563de20 <_ZN8CAddressaSEOS_>
     915   0x0000555555622627 <+4503>:	jmp    0x55555562262c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4508>
     916   0x000055555562262c <+4508>:	lea    -0x308(%rbp),%rdi
     917   0x0000555555622633 <+4515>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     918   0x000055555562264a <+4538>:	lea    -0x308(%rbp),%rdi
     919   0x0000555555622651 <+4545>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
     920   0x0000555555622656 <+4550>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
     921   0x000055555562265b <+4555>:	mov    $0x430,%edi
     922
     923482	    }
     924   0x0000555555622638 <+4520>:	jmp    0x55555562265b <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4555>
     925
     926483	    CNode* pnode = new CNode(id, nLocalServices, sock->Release(), addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type);
     927   0x0000555555622660 <+4560>:	call   0x555555581420 <_Znwm@plt>
     928   0x0000555555622665 <+4565>:	mov    %rax,-0x5a0(%rbp)
     929   0x000055555562266c <+4572>:	jmp    0x555555622671 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4577>
     930   0x0000555555622671 <+4577>:	movb   $0x1,-0x419(%rbp)
     931   0x0000555555622678 <+4584>:	mov    -0x5a0(%rbp),%rax
     932   0x000055555562267f <+4591>:	mov    -0x408(%rbp),%rsi
     933   0x0000555555622686 <+4598>:	mov    -0x430(%rbp),%rcx
     934   0x000055555562268d <+4605>:	mov    0x503d8(%rcx),%rdx
     935   0x0000555555622694 <+4612>:	lea    -0x380(%rbp),%rdi
     936   0x000055555562269b <+4619>:	mov    %rax,-0x5a8(%rbp)
     937   0x00005555556226a2 <+4626>:	mov    %rsi,-0x5b0(%rbp)
     938   0x00005555556226a9 <+4633>:	mov    %rdx,-0x5b8(%rbp)
     939   0x00005555556226b0 <+4640>:	call   0x55555563edf0 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEptEv>
     940   0x00005555556226b5 <+4645>:	mov    (%rax),%rcx
     941--Type <RET> for more, q to quit, c to continue without paging--
     942   0x00005555556226b8 <+4648>:	mov    0x20(%rcx),%rcx
     943   0x00005555556226bc <+4652>:	mov    %rax,%rdi
     944   0x00005555556226bf <+4655>:	call   *%rcx
     945   0x00005555556226c1 <+4657>:	mov    %eax,-0x5bc(%rbp)
     946   0x00005555556226c7 <+4663>:	jmp    0x5555556226cc <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4668>
     947   0x00005555556226cc <+4668>:	mov    -0x430(%rbp),%rdi
     948   0x00005555556226d3 <+4675>:	mov    -0x428(%rbp),%rsi
     949   0x00005555556226da <+4682>:	call   0x555555623610 <_ZNK8CConnman22CalculateKeyedNetGroupERK8CAddress>
     950   0x00005555556226df <+4687>:	mov    %rax,-0x5c8(%rbp)
     951   0x00005555556226e6 <+4694>:	jmp    0x5555556226eb <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4699>
     952   0x00005555556226eb <+4699>:	mov    -0x410(%rbp),%rax
     953   0x00005555556226f2 <+4706>:	cmpq   $0x0,-0x340(%rbp)
     954   0x00005555556226fa <+4714>:	mov    %rax,-0x5d0(%rbp)
     955   0x0000555555622701 <+4721>:	je     0x55555562271a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4746>
     956   0x0000555555622707 <+4727>:	mov    -0x340(%rbp),%rax
     957   0x000055555562270e <+4734>:	mov    %rax,-0x5d8(%rbp)
     958   0x0000555555622715 <+4741>:	jmp    0x55555562272d <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4765>
     959   0x000055555562271a <+4746>:	lea    0xb5c546(%rip),%rax        # 0x55555617ec67
     960   0x0000555555622721 <+4753>:	mov    %rax,-0x5d8(%rbp)
     961   0x0000555555622728 <+4760>:	jmp    0x55555562272d <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4765>
     962   0x000055555562272d <+4765>:	mov    -0x5d8(%rbp),%rax
     963   0x0000555555622734 <+4772>:	lea    -0x3b8(%rbp),%rcx
     964   0x000055555562273b <+4779>:	mov    %rcx,%rdi
     965   0x000055555562273e <+4782>:	mov    %rax,-0x5e0(%rbp)
     966   0x0000555555622745 <+4789>:	mov    %rcx,-0x5e8(%rbp)
     967   0x000055555562274c <+4796>:	call   0x555555582c40 <_ZNSaIcEC1Ev@plt>
     968   0x0000555555622751 <+4801>:	lea    -0x328(%rbp),%rdi
     969   0x0000555555622758 <+4808>:	mov    -0x5e0(%rbp),%rsi
     970   0x000055555562275f <+4815>:	mov    -0x5e8(%rbp),%rdx
     971   0x0000555555622766 <+4822>:	call   0x55555559c0c0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_>
     972   0x000055555562276b <+4827>:	jmp    0x555555622770 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4832>
     973   0x0000555555622770 <+4832>:	mov    -0x3d0(%rbp),%eax
     974   0x0000555555622776 <+4838>:	mov    %rsp,%rcx
     975   0x0000555555622779 <+4841>:	mov    %eax,0x18(%rcx)
     976   0x000055555562277c <+4844>:	lea    -0x328(%rbp),%rdx
     977   0x0000555555622783 <+4851>:	mov    %rdx,0x10(%rcx)
     978   0x0000555555622787 <+4855>:	lea    -0x190(%rbp),%rdx
     979   0x000055555562278e <+4862>:	mov    %rdx,0x8(%rcx)
     980   0x0000555555622792 <+4866>:	mov    -0x5d0(%rbp),%rdx
     981   0x0000555555622799 <+4873>:	mov    %rdx,(%rcx)
     982   0x000055555562279c <+4876>:	movl   $0x0,0x20(%rcx)
     983   0x00005555556227a3 <+4883>:	mov    -0x5a8(%rbp),%rdi
     984   0x00005555556227aa <+4890>:	mov    -0x5b0(%rbp),%rsi
     985   0x00005555556227b1 <+4897>:	mov    -0x5b8(%rbp),%rdx
     986   0x00005555556227b8 <+4904>:	mov    -0x5bc(%rbp),%ecx
     987   0x00005555556227be <+4910>:	mov    -0x428(%rbp),%r8
     988   0x00005555556227c5 <+4917>:	mov    -0x5c8(%rbp),%r9
     989   0x00005555556227cc <+4924>:	call   0x5555556388d0 <_ZN5CNodeC2El12ServiceFlagsjRK8CAddressmmS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14ConnectionTypeb>
     990   0x00005555556227d1 <+4929>:	jmp    0x5555556227d6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4934>
     991   0x00005555556227d6 <+4934>:	movb   $0x0,-0x419(%rbp)
     992   0x00005555556227dd <+4941>:	lea    -0x328(%rbp),%rdi
     993   0x00005555556227e4 <+4948>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
     994   0x00005555556227e9 <+4953>:	lea    -0x3b8(%rbp),%rdi
     995   0x00005555556227f0 <+4960>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
     996   0x00005555556227f5 <+4965>:	mov    -0x5a8(%rbp),%rax
     997   0x00005555556227fc <+4972>:	mov    %rax,-0x418(%rbp)
     998   0x0000555555622870 <+5088>:	lea    -0x328(%rbp),%rdi
     999   0x0000555555622877 <+5095>:	call   0x5555555833d0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
    1000   0x000055555562287c <+5100>:	lea    -0x3b8(%rbp),%rdi
    1001   0x0000555555622883 <+5107>:	call   0x5555555833a0 <_ZNSaIcED1Ev@plt>
    1002   0x0000555555622888 <+5112>:	testb  $0x1,-0x419(%rbp)
    1003   0x000055555562288f <+5119>:	jne    0x55555562289a <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5130>
    1004   0x0000555555622895 <+5125>:	jmp    0x5555556228a6 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5142>
    1005   0x000055555562289a <+5130>:	mov    -0x5a0(%rbp),%rdi
    1006   0x00005555556228a1 <+5137>:	call   0x555555581f10 <_ZdlPv@plt>
    1007   0x00005555556228a6 <+5142>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
    1008
    1009484	    pnode->AddRef();
    1010   0x0000555555622803 <+4979>:	mov    -0x418(%rbp),%rdi
    1011   0x000055555562280a <+4986>:	call   0x55555563ef20 <_ZN5CNode6AddRefEv>
    1012   0x000055555562280f <+4991>:	jmp    0x555555622814 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4996>
    1013
    1014485	
    1015486	    // We're making a new connection, harvest entropy from the time (and our peer count)
    1016487	    RandAddEvent((uint32_t)id);
    1017   0x0000555555622814 <+4996>:	mov    -0x408(%rbp),%rax
    1018   0x000055555562281b <+5003>:	mov    %eax,%edi
    1019   0x000055555562281d <+5005>:	call   0x555555f58da0 <_Z12RandAddEventj>
    1020
    1021488	
    1022489	    return pnode;
    1023   0x0000555555622822 <+5010>:	mov    -0x418(%rbp),%rcx
    1024   0x0000555555622829 <+5017>:	mov    %rcx,-0x3c0(%rbp)
    1025   0x0000555555622830 <+5024>:	movl   $0x1,-0x3f0(%rbp)
    1026   0x000055555562283a <+5034>:	jmp    0x5555556228ab <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5147>
    1027
    1028490	}
    1029   0x00005555556215c4 <+308>:	mov    %rax,-0x3e0(%rbp)
    1030   0x00005555556215cb <+315>:	mov    %edx,-0x3e4(%rbp)
    1031   0x0000555555621756 <+710>:	mov    %rax,-0x3e0(%rbp)
    1032   0x000055555562175d <+717>:	mov    %edx,-0x3e4(%rbp)
    1033   0x0000555555621763 <+723>:	jmp    0x55555562177e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+750>
    1034   0x0000555555621768 <+728>:	mov    %rax,-0x3e0(%rbp)
    1035   0x000055555562176f <+735>:	mov    %edx,-0x3e4(%rbp)
    1036   0x0000555555621a18 <+1416>:	mov    %rax,-0x3e0(%rbp)
    1037   0x0000555555621a1f <+1423>:	mov    %edx,-0x3e4(%rbp)
    1038   0x0000555555621a25 <+1429>:	jmp    0x555555621a40 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1456>
    1039   0x0000555555621a2a <+1434>:	mov    %rax,-0x3e0(%rbp)
    1040   0x0000555555621a31 <+1441>:	mov    %edx,-0x3e4(%rbp)
    1041   0x0000555555621a51 <+1473>:	mov    %rax,-0x3e0(%rbp)
    1042   0x0000555555621a58 <+1480>:	mov    %edx,-0x3e4(%rbp)
    1043   0x0000555555621a5e <+1486>:	jmp    0x555555621d02 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2162>
    1044   0x0000555555621a63 <+1491>:	mov    %rax,-0x3e0(%rbp)
    1045   0x0000555555621a6a <+1498>:	mov    %edx,-0x3e4(%rbp)
    1046   0x0000555555621a70 <+1504>:	jmp    0x555555621a8e <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+1534>
    1047   0x0000555555621a75 <+1509>:	mov    %rax,-0x3e0(%rbp)
    1048   0x0000555555621a7c <+1516>:	mov    %edx,-0x3e4(%rbp)
    1049   0x0000555555621a9f <+1551>:	mov    %rax,-0x3e0(%rbp)
    1050   0x0000555555621aa6 <+1558>:	mov    %edx,-0x3e4(%rbp)
    1051   0x0000555555621c24 <+1940>:	mov    %rax,-0x3e0(%rbp)
    1052   0x0000555555621c2b <+1947>:	mov    %edx,-0x3e4(%rbp)
    1053   0x0000555555621c31 <+1953>:	jmp    0x555555621cbe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2094>
    1054   0x0000555555621c36 <+1958>:	mov    %rax,-0x3e0(%rbp)
    1055   0x0000555555621c3d <+1965>:	mov    %edx,-0x3e4(%rbp)
    1056   0x0000555555621c54 <+1988>:	mov    %rax,-0x3e0(%rbp)
    1057   0x0000555555621c5b <+1995>:	mov    %edx,-0x3e4(%rbp)
    1058   0x0000555555621c61 <+2001>:	jmp    0x555555621c7f <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2031>
    1059   0x0000555555621c66 <+2006>:	mov    %rax,-0x3e0(%rbp)
    1060   0x0000555555621c6d <+2013>:	mov    %edx,-0x3e4(%rbp)
    1061   0x0000555555621d98 <+2312>:	mov    %rax,-0x3e0(%rbp)
    1062   0x0000555555621d9f <+2319>:	mov    %edx,-0x3e4(%rbp)
    1063   0x0000555555621da5 <+2325>:	jmp    0x5555556228ec <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5212>
    1064   0x0000555555621daa <+2330>:	mov    %rax,-0x3e0(%rbp)
    1065   0x0000555555621db1 <+2337>:	mov    %edx,-0x3e4(%rbp)
    1066   0x0000555555621db7 <+2343>:	jmp    0x5555556228e0 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5200>
    1067   0x0000555555621dbc <+2348>:	mov    %rax,-0x3e0(%rbp)
    1068   0x0000555555621dc3 <+2355>:	mov    %edx,-0x3e4(%rbp)
    1069   0x0000555555621dc9 <+2361>:	jmp    0x5555556228d4 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5188>
    1070   0x0000555555621dce <+2366>:	mov    -0x428(%rbp),%rdi
    1071   0x0000555555621f5f <+2767>:	mov    %rax,-0x3e0(%rbp)
    1072   0x0000555555621f66 <+2774>:	mov    %edx,-0x3e4(%rbp)
    1073   0x0000555555621f6c <+2780>:	jmp    0x555555621fbe <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2862>
    1074   0x0000555555621f71 <+2785>:	mov    %rax,-0x3e0(%rbp)
    1075   0x0000555555621f78 <+2792>:	mov    %edx,-0x3e4(%rbp)
    1076   0x0000555555621f7e <+2798>:	jmp    0x555555621f9c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+2828>
    1077   0x0000555555621f83 <+2803>:	mov    %rax,-0x3e0(%rbp)
    1078   0x0000555555621f8a <+2810>:	mov    %edx,-0x3e4(%rbp)
    1079   0x000055555562213c <+3244>:	mov    %rax,-0x3e0(%rbp)
    1080   0x0000555555622143 <+3251>:	mov    %edx,-0x3e4(%rbp)
    1081   0x000055555562249d <+4109>:	mov    %rax,-0x3e0(%rbp)
    1082   0x00005555556224a4 <+4116>:	mov    %edx,-0x3e4(%rbp)
    1083   0x00005555556224aa <+4122>:	jmp    0x5555556224c8 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+4152>
    1084   0x00005555556224af <+4127>:	mov    %rax,-0x3e0(%rbp)
    1085   0x00005555556224b6 <+4134>:	mov    %edx,-0x3e4(%rbp)
    1086   0x00005555556224d9 <+4169>:	mov    %rax,-0x3e0(%rbp)
    1087   0x00005555556224e0 <+4176>:	mov    %edx,-0x3e4(%rbp)
    1088   0x000055555562263d <+4525>:	mov    %rax,-0x3e0(%rbp)
    1089   0x0000555555622644 <+4532>:	mov    %edx,-0x3e4(%rbp)
    1090   0x000055555562283f <+5039>:	mov    %rax,-0x3e0(%rbp)
    1091   0x0000555555622846 <+5046>:	mov    %edx,-0x3e4(%rbp)
    1092   0x000055555562284c <+5052>:	jmp    0x555555622888 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5112>
    1093   0x0000555555622851 <+5057>:	mov    %rax,-0x3e0(%rbp)
    1094   0x0000555555622858 <+5064>:	mov    %edx,-0x3e4(%rbp)
    1095   0x000055555562285e <+5070>:	jmp    0x55555562287c <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5100>
    1096   0x0000555555622863 <+5075>:	mov    %rax,-0x3e0(%rbp)
    1097   0x000055555562286a <+5082>:	mov    %edx,-0x3e4(%rbp)
    1098   0x00005555556228ab <+5147>:	lea    -0x190(%rbp),%rdi
    1099   0x00005555556228b2 <+5154>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
    1100   0x00005555556228b7 <+5159>:	lea    -0x160(%rbp),%rdi
    1101   0x00005555556228be <+5166>:	call   0x5555555d3ad0 <_ZN9proxyTypeD2Ev>
    1102   0x00005555556228c3 <+5171>:	lea    -0x380(%rbp),%rdi
    1103   0x00005555556228ca <+5178>:	call   0x55555563ece0 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EED2Ev>
    1104   0x00005555556228cf <+5183>:	jmp    0x5555556228fd <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5229>
    1105   0x00005555556228d4 <+5188>:	lea    -0x190(%rbp),%rdi
    1106--Type <RET> for more, q to quit, c to continue without paging--
    1107   0x00005555556228db <+5195>:	call   0x55555563de90 <_ZN8CAddressD2Ev>
    1108   0x00005555556228e0 <+5200>:	lea    -0x160(%rbp),%rdi
    1109   0x00005555556228e7 <+5207>:	call   0x5555555d3ad0 <_ZN9proxyTypeD2Ev>
    1110   0x00005555556228ec <+5212>:	lea    -0x380(%rbp),%rdi
    1111   0x00005555556228f3 <+5219>:	call   0x55555563ece0 <_ZNSt10unique_ptrI4SockSt14default_deleteIS0_EED2Ev>
    1112   0x00005555556228f8 <+5224>:	jmp    0x555555622931 <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5281>
    1113   0x00005555556228fd <+5229>:	mov    -0x3c0(%rbp),%rax
    1114   0x0000555555622904 <+5236>:	mov    %fs:0x28,%rcx
    1115   0x000055555562290d <+5245>:	mov    -0x8(%rbp),%rdx
    1116   0x0000555555622911 <+5249>:	cmp    %rdx,%rcx
    1117   0x0000555555622914 <+5252>:	mov    %rax,-0x5f0(%rbp)
    1118   0x000055555562291b <+5259>:	jne    0x55555562293d <_ZN8CConnman11ConnectNodeE8CAddressPKcb14ConnectionType+5293>
    1119   0x0000555555622921 <+5265>:	mov    -0x5f0(%rbp),%rax
    1120   0x0000555555622928 <+5272>:	add    $0x620,%rsp
    1121   0x000055555562292f <+5279>:	pop    %rbp
    1122   0x0000555555622930 <+5280>:	ret    
    1123
    1124End of assembler dump.
    1125(gdb) 
    
  101. in src/net.cpp:437 in a456bd3f29 outdated
    433-        if (GetProxy(addrConnect.GetNetwork(), proxy)) {
    434+        if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {
    435+            i2p::Connection conn;
    436+            if (m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed)) {
    437+                connected = true;
    438+                *sock = std::move(conn.sock);
    


    jonatack commented at 3:59 pm on February 14, 2021:
    Both gdb and valgrind are hitting this line

    vasild commented at 9:32 am on February 15, 2021:
    Yes, that is an invalid way to assign a new value to unique_ptr that is not set. :bomb: Fixed!

    jonatack commented at 9:37 am on February 15, 2021:
    Makes sense. Building the new push.
  102. laanwj commented at 7:24 pm on February 14, 2021: member

    So it hits an illegal instruction on this line:

    0   0x0000555555621ede <+2638>:	mov    (%rax),%rcx
    

    This is really strange. That looks like a perfectly basic x86 instruction. I could understand a segmentation fault here, but illegal instruction is strange. At least it is in code that is affected by this PR.

  103. jonatack commented at 9:01 am on February 15, 2021: member

    The previous tests were with clang 9; seeing the same segfault with gcc 10.2.1:

    0$ gcc --version
    1gcc (Debian 10.2.1-6) 10.2.1 20210110
    2$ gdb bitcoind
    3GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
    
     02021-02-15T08:47:39Z I2P: SAM session created: session id=qqqq, my address=qqqq.b32.i2p:8333
     12021-02-15T08:47:39Z AddLocal(qqqq.b32.i2p:8333,2)
     22021-02-15T08:47:47Z UpdateTip: new best=000000000000000000099c233db18ba6797892a9d0e0a915207ceb635b39f21c height=670691 version=0x20600000 log2_work=92.669960 tx=616400432 date='2021-02-15T08:47:12Z' progress=1.000000 cache=9.3MiB(70444txo)
     32021-02-15T08:47:48Z New outbound peer connected: version: 70015, blocks=670691, peer=9, peeraddr=jvmq5xt2xcbe32ug.onion:8333 (outbound-full-relay)
     4
     5Thread 18 "b-addcon" received signal SIGSEGV, Segmentation fault.
     6[Switching to Thread 0x7fff4baf1700 (LWP 55615)]
     7CConnman::ConnectNode (this=0x555556c59f50, addrConnect=..., pszDest=0x7fff28002e50 "qqqq.b32.i2p", 
     8    fCountFailure=false, conn_type=ConnectionType::MANUAL) at net.cpp:437
     9437	                *sock = std::move(conn.sock);
    10
    11(gdb) disass /m
    12.../...
    13437	                *sock = std::move(conn.sock);
    14   0x00005555555fb83a <+1692>:	lea    -0x3e8(%rbp),%rax
    15   0x00005555555fb841 <+1699>:	mov    %rax,%rdi
    16   0x00005555555fb844 <+1702>:	call   0x55555561c796 <_ZNKSt10unique_ptrI4SockSt14default_deleteIS0_EEdeEv>
    17   0x00005555555fb849 <+1707>:	mov    %rax,%rbx
    18=> 0x00005555555fb84c <+1710>:	mov    (%rbx),%rax
    19   0x00005555555fb84f <+1713>:	add    $0x10,%rax
    20   0x00005555555fb853 <+1717>:	mov    (%rax),%r12
    21   0x00005555555fb856 <+1720>:	lea    -0x90(%rbp),%rax
    22   0x00005555555fb85d <+1727>:	mov    %rax,%rdi
    23   0x00005555555fb860 <+1730>:	call   0x55555561c7d7 <_ZSt4moveIR4SockEONSt16remove_referenceIT_E4typeEOS3_>
    24   0x00005555555fb865 <+1735>:	mov    %rax,%rsi
    25   0x00005555555fb868 <+1738>:	mov    %rbx,%rdi
    26   0x00005555555fb86b <+1741>:	call   *%r12
    
     0(gdb) bt
     1[#0](/bitcoin-bitcoin/0/)  CConnman::ConnectNode (this=0x555556c59f50, addrConnect=..., pszDest=0x7fff28002e50 "qqqq.b32.i2p", 
     2    fCountFailure=false, conn_type=ConnectionType::MANUAL) at net.cpp:437
     3[#1](/bitcoin-bitcoin/1/)  0x0000555555605be1 in CConnman::OpenNetworkConnection (this=0x555556c59f50, addrConnect=..., fCountFailure=false, grantOutbound=0x7fff4baf0810, 
     4    pszDest=0x7fff28002e50 "qqqq.b32.i2p", conn_type=ConnectionType::MANUAL) at net.cpp:2152
     5[#2](/bitcoin-bitcoin/2/)  0x000055555560581c in CConnman::ThreadOpenAddedConnections (this=0x555556c59f50) at net.cpp:2119
     6[#3](/bitcoin-bitcoin/3/)  0x00005555556605f2 in std::__invoke_impl<void, void (CConnman::*&)(), CConnman*&> (
     7    __f=@0x5555639f9670: (void (CConnman::*)(CConnman * const)) 0x555555605692 <CConnman::ThreadOpenAddedConnections()>, __t=@0x5555639f9680: 0x555556c59f50)
     8    at /usr/include/c++/10/bits/invoke.h:73
     9[#4](/bitcoin-bitcoin/4/)  0x000055555565e4bf in std::__invoke<void (CConnman::*&)(), CConnman*&> (
    10    __fn=@0x5555639f9670: (void (CConnman::*)(CConnman * const)) 0x555555605692 <CConnman::ThreadOpenAddedConnections()>) at /usr/include/c++/10/bits/invoke.h:95
    11[#5](/bitcoin-bitcoin/5/)  0x000055555565b1b7 in std::_Bind<void (CConnman::*(CConnman*))()>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (this=0x5555639f9670, 
    12    __args=...) at /usr/include/c++/10/functional:416
    13[#6](/bitcoin-bitcoin/6/)  0x00005555556559df in std::_Bind<void (CConnman::*(CConnman*))()>::operator()<, void>() (this=0x5555639f9670) at /usr/include/c++/10/functional:499
    14[#7](/bitcoin-bitcoin/7/)  0x000055555564dddb in std::__invoke_impl<void, std::_Bind<void (CConnman::*(CConnman*))()>&>(std::__invoke_other, std::_Bind<void (CConnman::*(CConnman*))()>&)
    15    (__f=...) at /usr/include/c++/10/bits/invoke.h:60
    16[#8](/bitcoin-bitcoin/8/)  0x00005555556423ae in std::__invoke_r<void, std::_Bind<void (CConnman::*(CConnman*))()>&>(std::_Bind<void (CConnman::*(CConnman*))()>&) (__fn=...)
    17    at /usr/include/c++/10/bits/invoke.h:110
    18[#9](/bitcoin-bitcoin/9/)  0x00005555556327d0 in std::_Function_handler<void (), std::_Bind<void (CConnman::*(CConnman*))()> >::_M_invoke(std::_Any_data const&) (__functor=...)
    19    at /usr/include/c++/10/bits/std_function.h:291
    20[#10](/bitcoin-bitcoin/10/) 0x00005555555cda5f in std::function<void ()>::operator()() const (this=0x7fff4baf0b20) at /usr/include/c++/10/bits/std_function.h:622
    21[#11](/bitcoin-bitcoin/11/) 0x00005555555c2aa5 in TraceThread<std::function<void ()> >(char const*, std::function<void ()>) (name=0x555556000af8 "addcon", func=...) at ./util/system.h:470
    22[#12](/bitcoin-bitcoin/12/) 0x0000555555662ea0 in std::__invoke_impl<void, void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> >(std::__invoke_other, void (*&&)(char const*, std::function<void ()>), char const*&&, std::function<void ()>&&) (
    23    __f=@0x55555ff62670: 0x5555555c2a1b <TraceThread<std::function<void ()> >(char const*, std::function<void ()>)>) at /usr/include/c++/10/bits/invoke.h:60
    24[#13](/bitcoin-bitcoin/13/) 0x0000555555662d16 in std::__invoke<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> >(void (*&&)(char const*, std::function<void ()>), char const*&&, std::function<void ()>&&) (
    25    __fn=@0x55555ff62670: 0x5555555c2a1b <TraceThread<std::function<void ()> >(char const*, std::function<void ()>)>) at /usr/include/c++/10/bits/invoke.h:95
    26[#14](/bitcoin-bitcoin/14/) 0x0000555555662b82 in std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) (this=0x55555ff62648) at /usr/include/c++/10/thread:264
    27[#15](/bitcoin-bitcoin/15/) 0x0000555555662af9 in std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > >::operator()() (
    28    this=0x55555ff62648) at /usr/include/c++/10/thread:271
    29[#16](/bitcoin-bitcoin/16/) 0x0000555555662ab7 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(char const*, std::function<void ()>), char const*, std::function<void ()> > > >::_M_run() (this=0x55555ff62640) at /usr/include/c++/10/thread:215
    30[#17](/bitcoin-bitcoin/17/) 0x00007ffff7beced0 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
    31[#18](/bitcoin-bitcoin/18/) 0x00007ffff7f8aea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
    32[#19](/bitcoin-bitcoin/19/) 0x00007ffff78f8def in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
    33(gdb) 
    
  104. vasild force-pushed on Feb 15, 2021
  105. vasild commented at 9:30 am on February 15, 2021: member
    a456bd3f2..da2ba3e87: don’t dereference an unset unique_ptr, thanks @jonatack, @laanwj!
  106. jonatack commented at 10:14 am on February 15, 2021: member
    Thanks – da2ba3e following the fix is working now.
  107. DrahtBot added the label Needs rebase on Feb 15, 2021
  108. vasild force-pushed on Feb 15, 2021
  109. vasild commented at 3:47 pm on February 15, 2021: member
    da2ba3e87...e19bc9938: rebase due to conflicts
  110. in src/netbase.cpp:81 in 433d9a9f1e outdated
    77@@ -78,7 +78,7 @@ std::vector<std::string> GetNetworkNames(bool append_unroutable)
    78     std::vector<std::string> names;
    79     for (int n = 0; n < NET_MAX; ++n) {
    80         const enum Network network{static_cast<Network>(n)};
    81-        if (network == NET_UNROUTABLE || network == NET_I2P || network == NET_CJDNS || network == NET_INTERNAL) continue;
    82+        if (network == NET_UNROUTABLE || network == NET_CJDNS || network == NET_INTERNAL) continue;
    


    jonatack commented at 4:17 pm on February 15, 2021:

    This will need the following change (if not already made but I didn’t see it)

     0/test/functional/rpc_net.py
     1@@ -105,7 +105,7 @@ class NetTest(BitcoinTestFramework):
     2         assert_equal(peer_info[1][1]['connection_type'], 'inbound')
     3 
     4         # Check dynamically generated networks list in getpeerinfo help output.
     5-        assert "(ipv4, ipv6, onion, not_publicly_routable)" in self.nodes[0].help("getpeerinfo")
     6+        assert "(ipv4, ipv6, onion, i2p, not_publicly_routable)" in self.nodes[0].help("getpeerinfo")
     7 
     8     def test_getnettotals(self):
     9         self.log.info("Test getnettotals")
    10@@ -156,7 +156,7 @@ class NetTest(BitcoinTestFramework):
    11             assert_net_servicesnames(int(info["localservices"], 0x10), info["localservicesnames"])
    12 
    13         # Check dynamically generated networks list in getnetworkinfo help output.
    14-        assert "(ipv4, ipv6, onion)" in self.nodes[0].help("getnetworkinfo")
    15+        assert "(ipv4, ipv6, onion, i2p)" in self.nodes[0].help("getnetworkinfo")
    16 
    17     def test_getaddednodeinfo(self):
    

    vasild commented at 3:18 pm on February 16, 2021:
    Fixed, thanks!
  111. DrahtBot removed the label Needs rebase on Feb 15, 2021
  112. vasild force-pushed on Feb 16, 2021
  113. vasild commented at 3:18 pm on February 16, 2021: member
    433d9a9f1...2a7bb343a: fix failing rpc_net.py
  114. laanwj commented at 8:02 am on February 17, 2021: member

    I’m trying with i2pd now on FreeBSD. Not having much luck. I could install it and start it quite easily (much more easily than the Java one):

    0$ pkg install i2pd
    1# add i2pd_enable="YES"  and optionally i2pd_flags="--bandwidth X"
    2$ vi /etc/rc.conf
    3$ service i2pd start
    4$ i2pd --version
    5i2pd version 2.33.0 (0.9.47)
    

    That’s it. SAM is enabled on port 7656.

    Edit: below issue is fixed


    However, it doesn’t seem to succesfully start the I2P listener. It looks like it hangs after sending the session create, doesn’t get a reply.

    02021-02-17T07:52:35Z I2P: Creating SAM session with 127.0.0.1:7656
    122021-02-17T07:55:35Z I2P: Error listening: Receive timeout (received 0 bytes without terminator before that)
    32021-02-17T07:55:35Z I2P: Control socket error: not connected
    

    On the i2pd side:

     008:55:36@682/error - NetDb: runtime exception: No known routers, reseed seems to be totally failed
     108:55:36@270/debug - SAM: new connection from 127.0.0.1:14315
     208:55:36@270/debug - SAM: handshake HELLO VERSION MIN=3.1 MAX=3.1
     308:55:36@270/debug - SAM: session create: STYLE=STREAM ID=b66590c3b4 DESTINATION=[snip]
     408:55:36@270/warn - Clients: Local destination [snip].b32.i2p exists
     508:55:37@7/warn - Tunnel: can't find any router, skip creating tunnel
     608:55:37@7/debug - Tunnels: Creating destination outbound tunnel...
     7 809:00:07@7/error - Tunnels: Can't create inbound tunnel, no peers available
     909:00:07@7/debug - Tunnels: Creating destination inbound tunnel...
    1009:00:07@7/error - Tunnels: Can't select next hop for G[snip]=
    1109:00:07@7/error - Tunnels: Can't create inbound tunnel, no peers available
    

    The latter part keeps repeating and repeating. It looks like a problem on the i2pd side not the bitcoind one. I have no networking issues, IPv4 and IPv6 and Tor works on the host. Anyone with ideas?

  115. jonatack commented at 9:03 am on February 17, 2021: member
    If this is the issue Suhas encountered, upgrade to i2pd v2.35 (latest release, build from source or on Debian it’s in the testing sources).
  116. laanwj commented at 9:07 am on February 17, 2021: member

    I don’t think it’s the same issue. He had a much older version (2.23 instead of 2.33), which had problems handling the commands from bitcoind. My i2pd seems completely broken, it doesn’t get any peer connections.

    The whole “runtime exception: No known routers, reseed seems to be totally failed” message gives only one result on Google, some Russian github thread. Argh.

    Edit: oh, it could have been something with clock skew. After running ntpdate europe.pool.ntp.org and restarting the service it seems to be doing more!

    010:14:29@122/error - SSU: clock skew detected 4294967197. Check your clock
    

    Edit.2 yes, that fixed it!:

    02021-02-17T09:21:44Z I2P: SAM session created: session id=be83961cec, my address=[snip].b32.i2p:8333
    12021-02-17T09:21:44Z AddLocal([snip].b32.i2p:8333,2)
    
  117. laanwj commented at 8:45 am on February 22, 2021: member

    Code review and extensively manually tested ACK 2a7bb343ac77f2bf52ea1a8959a22ef266d49aa6

    I think it would be nice to have unit tests for the Reply parsing in i2p.cpp and maybe the alt-Base64 parsing, however this can be done in a later PR (and doesn’t need to hold up progress here). Maybe someone will even look into fuzzing.

  118. jonatack commented at 11:02 am on February 25, 2021: member

    Update, about halfway through reviewing the commits. Each builds cleanly and no comments so far.

    I’ve been testing this these past weeks using i2pd 2.35. Apparently, i2pd 2.36 was released last week and I plan to test with it.

    The only oddity I’ve been seeing from the first day of testing until now is inbound I2P peers can regularly have two connections, present for a few minutes. I haven’t looked further into it yet. Here are two screenshots taken on February 14 and 20:

    Screenshot from 2021-02-14 01-33-45

    Screenshot from 2021-02-20 11-37-26

  119. ghost commented at 8:15 pm on February 25, 2021: none
    1. Unable to build for Windows using instructions mentioned in this doc: https://github.com/bitcoin/bitcoin/blob/master/doc/build-windows.md (It worked for other pull request recently)
    1. Compiled successfully on Ubuntu 20.04.2 LTS. Tests passed.

    Installed i2p with the instructions mentioned here: https://geti2p.net/en/download/debian followed by i2prouter start

    bitcoin.conf file:

    Don’t see any i2p_private_key file created in .bitcoin/testnet3

    Logs:

  120. laanwj commented at 8:26 pm on February 25, 2021: member

    @prayank23 Strange. Adding debug=i2p to your config might give some more information in the log as to why it’s not working.

    The windows linker issue seems unrelated (you could create a new issue for it if you want).

  121. ghost commented at 9:29 pm on February 25, 2021: none
  122. laanwj commented at 9:39 pm on February 25, 2021: member
    It doesn’t look like it’s a SAM proxy you’re connecting to, but a HTTP proxy (it’s clearly speaking HTTP). From what I remember the Java I2P router doesn’t start a SAM service by default and you need to add it.
  123. fanquake commented at 2:00 am on February 26, 2021: member

    Unable to build for Windows

    The Windows linking issue has been fixed in master in #21226. This PR just needs rebasing.

  124. vasild commented at 4:32 pm on February 26, 2021: member
    @jonatack, next time you observe two incoming connections from the same peer, try to capture the output of bitcoin-cli getpeerinfo |jq 'map(select(.network == "i2p")) |map({inbound: .inbound, addr: .addr, addrbind: .addrbind})'. I suspect it has something to do with the ports. @prayank23, the SAM proxy is usually listening on port 7656. Surely it can be changed to anything, but I guess you did not change it and your config i2psam=127.0.0.1:7658 is pointing to the HTTP proxy, as @laanwj mentioned.
  125. jonatack commented at 5:06 pm on February 26, 2021: member
    @prayank23 yes, fwiw I’m building and reviewing the PR after rebasing to current master (let it run last night building and testing each commit and they are all clean/green), as mentioned above, if you do that it should(:tm:) build on Windows. @vasild sure np. Should finish reviewing the current branch today.
  126. in src/netaddress.h:156 in 2a7bb343ac outdated
    150@@ -151,7 +151,16 @@ class CNetAddr
    151 
    152         bool SetInternal(const std::string& name);
    153 
    154-        bool SetSpecial(const std::string &strName); // for Tor addresses
    155+        /**
    156+         * Parse a Tor or I2P address and set this object to it.
    157+         * @param[in] name Address to parse, for example
    


    jonatack commented at 5:56 pm on February 26, 2021:
    2ee63a5 For the six SetSpecial, SetTor and SetI2P declarations and definitions, I think it would be clearer to use the same param name. It’s currently sometimes name and sometimes str and different between the declarations and the definitions for SetTor and SetI2P. (I’d propose const std::string& addr for all six.)

    vasild commented at 5:08 pm on March 1, 2021:
    Done.
  127. in src/util/sock.cpp:171 in 2a7bb343ac outdated
    167+                "Send interrupted (sent only %u of %u bytes before that)", sent, data.size()));
    168+        }
    169+
    170+        // Wait for a short while (or the socket to become ready for sending) before retrying
    171+        // if nothing was sent.
    172+        const auto timeout = std::min(deadline - now, std::chrono::milliseconds{MAX_WAIT_FOR_IO});
    


    jonatack commented at 7:57 pm on February 26, 2021:
    45cfaf0d296b6b6f9d4c86d4ec1b4c4392947b36 here and also line 248, maybe use a different name for the timeout local variable (maybe wait_time or wait_timeout) than the timeout input param

    vasild commented at 5:08 pm on March 1, 2021:
    Done.
  128. in src/util/sock.cpp:187 in 2a7bb343ac outdated
    183+    bool terminator_found = false;
    184+
    185+    // We must not consume any bytes past the terminator from the socket.
    186+    // One option is to read one byte at a time and check if we have read a terminator.
    187+    // However that is very slow. Instead, we peek at what is in the socket and only read
    188+    // as much bytes as possible without crossing the terminator.
    


    jonatack commented at 7:59 pm on February 26, 2021:

    45cfaf0

    0    // as many bytes as possible without crossing the terminator.
    

    vasild commented at 5:09 pm on March 1, 2021:
    Done.
  129. in src/util/sock.cpp:225 in 2a7bb343ac outdated
    221+                              "peek claimed %u bytes are available",
    222+                              read_ret, try_len, peek_ret));
    223+            }
    224+
    225+            // Don't include the terminator in the output.
    226+            const size_t append_len = terminator_found ? read_ret - 1 : read_ret;
    


    jonatack commented at 8:17 pm on February 26, 2021:

    45cfaf0d296b6b6f9d4c86d4ec1b4c4392947b36 maybe make explicit that this is narrowing from long to unsigned long (size_t)

    0            const size_t append_len{static_cast<size_t>(terminator_found ? read_ret - 1 : read_ret)};
    

    (In general, in these two added functions Sock::SendComplete() and Sock::RecvUntilTerminator(), I would personally find it more clear and reassuring if uniform initialization with explicit typing was used.)


    vasild commented at 5:10 pm on March 1, 2021:
    In this case we can use try_len which is size_t and we already checked that it equals to read_ret just above this snippet.
  130. in src/i2p.h:198 in 2a7bb343ac outdated
    193+     * @throws std::runtime_error if an error occurs
    194+     */
    195+    void CreateIfNotCreatedAlready() EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
    196+
    197+    /**
    198+     * Open a new connection to the SAM proxy and issue "STREAM ACCEPT" request using the existent
    


    jonatack commented at 9:05 pm on February 26, 2021:

    6da5c7eb32b51ab89f27a84e6c5e33db0e8e3e6e

    0     * Open a new connection to the SAM proxy and issue "STREAM ACCEPT" request using the existing
    

    vasild commented at 5:10 pm on March 1, 2021:
    Done.
  131. in src/i2p.h:246 in 2a7bb343ac outdated
    241+     * See https://geti2p.net/en/docs/api/samv3
    242+     */
    243+    Sock m_control_sock GUARDED_BY(m_mutex);
    244+
    245+    /**
    246+     * The .b32.i2p address of this peer.
    


    jonatack commented at 9:10 pm on February 26, 2021:
    6da5c7e A peer = a node that is not us. If m_my_addr is for our own address only, maybe s/this peer/our node/ or * Our .b32.i2p address.

    vasild commented at 5:11 pm on March 1, 2021:
    Done.
  132. in src/init.cpp:451 in 2a7bb343ac outdated
    445@@ -446,7 +446,9 @@ void SetupServerArgs(NodeContext& node)
    446     argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    447     argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h). Limit does not apply to peers with 'download' permission. 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    448     argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    449-    argsman.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks. Warning: if it is used with ipv4 or ipv6 but not onion and the -onion or -proxy option is set, then outbound onion connections will still be made; use -noonion or -onion=0 to disable outbound onion connections in this case.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    450+    argsman.AddArg("-i2psam=<ip:port>", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
    451+    argsman.AddArg("-i2pacceptincoming", "If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Notice that listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: 1)", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
    


    jonatack commented at 10:19 pm on February 26, 2021:

    300a654feb8cc68fc12bc8baff0f69ef031bd51f s/Notice/Note/ (or just omit “Notice that”)

    0    argsman.AddArg("-i2pacceptincoming", "If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: 1)", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
    

    vasild commented at 5:10 pm on March 1, 2021:
    Done.
  133. in src/init.cpp:2000 in 2a7bb343ac outdated
    1990@@ -1986,6 +1991,21 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
    1991             connOptions.m_specified_outgoing = connect;
    1992         }
    1993     }
    1994+
    1995+    const std::string& i2psam_arg = args.GetArg("-i2psam", "");
    1996+    if (i2psam_arg != "") {
    


    jonatack commented at 10:21 pm on February 26, 2021:

    300a654feb8cc68fc12bc8baff0f69ef031bd51f

    0    if (!i2psam_arg.empty()) {
    

    vasild commented at 5:11 pm on March 1, 2021:
    Done.
  134. in src/i2p.cpp:365 in 2a7bb343ac outdated
    359+    const std::string& private_key_b64 = SwapBase64(EncodeBase64(m_private_key));
    360+
    361+    SendRequestAndGetReply(sock, strprintf("SESSION CREATE STYLE=STREAM ID=%s DESTINATION=%s",
    362+                                           session_id, private_key_b64));
    363+
    364+    m_my_addr = CService(DestBinToAddr(MyDestination()), Params().GetDefaultPort());
    


    jonatack commented at 7:16 pm on February 27, 2021:
    0    m_my_addr = CService{DestBinToAddr(MyDestination()), static_cast<uint16_t>(Params().GetDefaultPort())};
    

    luke-jr commented at 10:13 pm on February 28, 2021:
    Why?

    jonatack commented at 10:31 pm on February 28, 2021:
    To be explicit about the narrowing conversion, same as #20685 (review) above

    luke-jr commented at 10:36 pm on February 28, 2021:
    Being explicit with a static_cast has no benefits I’m aware of, just would silence warnings in cases where the warning is warranted…?

    jonatack commented at 11:18 am on March 1, 2021:

    @luke-jr I think it’s the opposite, brace (uniform) initialization raises compile time warnings, e.g. for narrowing and conversions, and named casts provide compile time checks as well.

    “Use brace initialization to convert arithmetic types (e.g., int64{x}). This is the safest approach because code will not compile if conversion can result in information loss. The syntax is also concise. Use static_cast as the equivalent of a C-style cast that does value conversion.”

    “Brace initialization makes it clear that the type conversion was intended and also prevents conversions between types that might result in loss of precision. (It is a compilation error to try to initialize a float from a double in this fashion, for example.)”


    jonatack commented at 11:21 am on March 1, 2021:
    For example, without the named cast here, brace initialization raises a compile time error for the narrowing conversion.

    vasild commented at 4:42 pm on March 1, 2021:

    The thing is that here GetDefaultPort() returns int and CService constructor takes uint16_t argument. So we would get a justified warning that we want to silence. The proper fix would be to change GetDefaultPort() to return uint16_t which is out of the scope of this PR.

    I don’t see a point in using a brace initialization for the warning and then to silence the warning with a static_cast.

    0int x = 300;
    1
    2// no warning
    3uint16_t c1 = x;
    4
    5// non-constant-expression cannot be narrowed from type 'int' to 'uint16_t'
    6uint16_t c2{x};
    7
    8// no warning
    9uint16_t c3{static_cast<uint16_t>(x)};
    

    Left it as is.


    jonatack commented at 4:50 pm on March 1, 2021:
    I agree it can be considered out of scope to change GetDefaultPort(), but the suggested (ugly!) change would make explicit the type mismatch and maybe encourage improving it. As mentioned in the parent comment, none of these are blockers, just items I noted while reviewing.

    jonatack commented at 4:59 pm on March 1, 2021:
    Anyway, no worries. I’ll look into improving it.

    jonatack commented at 10:26 pm on March 1, 2021:
    Proposed #21328 to address it without requiring any changes here.
  135. jonatack commented at 7:48 pm on February 27, 2021: member

    ACK 2a7bb343ac77f2bf52ea1a8959a22ef266d49aa6 modulo a few comments below and more suggestions in the top commit at https://github.com/jonatack/bitcoin/commits/pr20685-review. In addition, it looks like src/i2p.{h,cpp} could benefit from unit test coverage. After rebasing to current master at b54a10e777f91208, I checked that each of the commits is hygienic, e.g. debug-builds cleanly with clang 9 and unit tests pass. I have also been running a node on this branch on and off since a few months with i2pd 2.35.0, and apart from the same peer being able to make more than one inbound connection, it appears to be running well and the 2 outbound and 1 inbound I2P peer connections I’ve been seeing appear to be at least as robust as the other ones, though generally with higher ping times (which I believe is inherent to the I2P network and not related to this change).

    None of my suggestions below or in the linked branch are blockers but I’m happy to re-review very responsively if you update. That said, this seems to be working robustly and I think it would be good to merge this soon and not too late in this release cycle, with test coverage added in a follow-up.

  136. practicalswift commented at 7:53 pm on February 28, 2021: contributor

    @laanwj

    I think it would be nice to have unit tests for the Reply parsing in i2p.cpp and maybe the alt-Base64 parsing, however this can be done in a later PR (and doesn’t need to hold up progress here). Maybe someone will even look into fuzzing.

    Agreed! I plan to add a fuzzing harness for the I2P Reply parsing code (unless @vasild plans to do it as part of this PR of course :)).

    Shameless plug: a fuzzing harness for the Tor controller reply parsing code was submitted in June last year in the still open PR #19288. Review welcome! :)

  137. ghost commented at 10:14 pm on February 28, 2021: none

    Finally i2p_private_key created :)

    image

    It was port: 7656 and I had to use i2pd instead of i2prouter. Thanks for the help @laanwj @vasild @jonatack @fanquake Thanks. Will try to build for Windows. I think we will also need a i2p.md file in docs for everyone to setup i2p service for Bitcoin Core.

  138. jonatack commented at 10:27 pm on February 28, 2021: member

    I think we will also need a i2p.md file in docs for everyone to setup i2p service for Bitcoin Core. @prayank23 yes, discussed above at #20685 (comment)

  139. laanwj commented at 10:59 am on March 1, 2021: member
    I would recommend against extending the scope of this PR. Let’s make sure that this change is correct, address remaining comments, and then merge it. It’s useful to have this on the branch so that other people can work on it. Documentation and additional testing can be added in a later PR.
  140. jonatack commented at 11:27 am on March 1, 2021: member

    It’s useful to have this on the branch so that other people can work on it.

    Agree! Though per @vasild’s IRC comments last week (http://www.erisian.com.au/bitcoin-core-dev/log-2021-02-25.html#l-242) he may have planned one more update.

  141. util: extract {Read,Write}BinaryFile() to its own files
    Extract `ReadBinaryFile()` and `WriteBinaryFile()` from `torcontrol.cpp`
    to its own `readwritefile.{h,cpp}` files, so that it can be reused from
    other modules.
    4cba2fdafa
  142. util: fix ReadBinaryFile() returning partial contents
    If an error occurs and `fread()` returns `0` (nothing was read) then the
    code before this patch would have returned "success" with a partially
    read contents of the file.
    8b6e4b3b23
  143. util: fix WriteBinaryFile() claiming success even if error occurred
    `fclose()` is flushing any buffered data to disk, so if it fails then
    that could mean that the data was not completely written to disk.
    
    Thus, check if `fclose()` succeeds and only then claim success from
    `WriteBinaryFile()`.
    545bc5f81d
  144. net: check for invalid socket earlier in CConnman::AcceptConnection()
    This check is related to an `accept()` failure. So do the check earlier,
    closer to the `accept()` call.
    
    This will allow to isolate the `accept()`-specific code at the beginning
    of `CConnman::AcceptConnection()` and reuse the code that follows it.
    25605895af
  145. net: get the bind address earlier in CConnman::AcceptConnection()
    Call `GetBindAddress()` earlier in `CConnman::AcceptConnection()`. That
    is specific to the TCP protocol and makes the code below it reusable for
    other protocols, if the caller provides `addr_bind`, retrieved by other
    means.
    1f75a653dd
  146. net: isolate the protocol-agnostic part of CConnman::AcceptConnection()
    Isolate the second half of `CConnman::AcceptConnection()` into a new
    separate method, which could be reused if we accept incoming connections
    by other means than `accept()` (first half of
    `CConnman::AcceptConnection()`).
    7c224fdac4
  147. net: avoid unnecessary GetBindAddress() call
    Our local (bind) address is already saved in `CNode::addrBind` and there
    is no need to re-retrieve it again with `GetBindAddress()`.
    
    Also, for I2P connections `CNode::addrBind` would contain our I2P
    address, but `GetBindAddress()` would return something like
    `127.0.0.1:RANDOM_PORT`.
    f6c267db3b
  148. vasild force-pushed on Mar 1, 2021
  149. vasild commented at 12:14 pm on March 1, 2021: member
    2a7bb343a...e41cb7dbd: rebase to fix the windows fuzz build issue
  150. net: extend CNetAddr::SetSpecial() to support I2P
    Recognize also I2P addresses in the form `base32hashofpublickey.b32.i2p`
    from `CNetAddr::SetSpecial()`.
    
    This makes `Lookup()` support them, which in turn makes it possible to
    manually connect to an I2P node by using
    `-proxy=i2p_socks5_proxy:port -addnode=i2p_address.b32.i2p:port`
    
    Co-authored-by: Lucas Ontivero <lucasontivero@gmail.com>
    cff65c4a27
  151. net: move the constant maxWait out of InterruptibleRecv()
    Move `maxWait` out of `InterruptibleRecv()` and rename it to
    `MAX_WAIT_FOR_IO` so that it can be reused by other code.
    34bcfab562
  152. net: dedup MSG_NOSIGNAL and MSG_DONTWAIT definitions
    Deduplicate `MSG_NOSIGNAL` and `MSG_DONTWAIT` definitions from `net.cpp`
    and `netbase.cpp` to `compat.h` where they can also be reused by other
    code.
    78fdfbea66
  153. net: extend Sock::Wait() to report a timeout
    Previously `Sock::Wait()` would not have signaled to the caller whether
    a timeout or one of the requested events occurred since that was not
    needed by any of the callers.
    
    Such functionality will be needed in the I2P implementation, thus extend
    the `Sock::Wait()` method.
    ea1845315a
  154. net: extend Sock with methods for robust send & read until terminator
    Introduce two high level, convenience methods in the `Sock` class:
    
    * `SendComplete()`: keep trying to send the specified data until either
      successfully sent all of it, timeout or interrupted.
    
    * `RecvUntilTerminator()`: read until a terminator is encountered (never
      after it), timeout or interrupted.
    
    These will be convenient in the I2P SAM implementation.
    
    `SendComplete()` can also be used in the SOCKS5 implementation instead
    of calling `send()` directly.
    42c779f503
  155. net: extend Sock with a method to check whether connected
    This will be convenient in the I2P SAM implementation.
    5bac7e45e1
  156. vasild force-pushed on Mar 1, 2021
  157. vasild commented at 5:08 pm on March 1, 2021: member
    e41cb7dbd...f181f24ca: address suggestions (no tests yet)
  158. net: implement the necessary parts of the I2P SAM protocol
    Implement the following commands from the I2P SAM protocol:
    
    * HELLO: needed for all of the remaining ones
    * DEST GENERATE: to generate our private key and destination
    * NAMING LOOKUP: to convert .i2p addresses to destinations
    * SESSION CREATE: needed for STREAM CONNECT and STREAM ACCEPT
    * STREAM CONNECT: to make outgoing connections
    * STREAM ACCEPT: to accept incoming connections
    c22daa2ecf
  159. init: introduce I2P connectivity options
    Introduce two new options to reach the I2P network:
    
    * `-i2psam=<ip:port>` point to the I2P SAM proxy. If this is set then
      the I2P network is considered reachable and we can make outgoing
      connections to I2P peers via that proxy. We listen for and accept
      incoming connections from I2P peers if the below is set in addition to
      `-i2psam=<ip:port>`
    
    * `-i2pacceptincoming` if this is set together with `-i2psam=<ip:port>`
      then we accept incoming I2P connections via the I2P SAM proxy.
    76c35c60f3
  160. net: add I2P to the reachability map
    Update `CNetAddr::GetReachabilityFrom()` to recognize the I2P network so
    that we would prefer to advertise our I2P address to I2P peers.
    9559bd1404
  161. net: make outgoing I2P connections from CConnman 0635233a1e
  162. net: accept incoming I2P connections from CConnman b905363fa8
  163. net: recognize I2P from ParseNetwork() so that -onlynet=i2p works 0181e24439
  164. net: Do not skip the I2P network from GetNetworkNames()
    So that help texts include "i2p" in:
    * `./bitcoind -help` (in `-onlynet` description)
    * `getpeerinfo` RPC
    * `getnetworkinfo` RPC
    
    Co-authored-by: Jon Atack <jon@atack.com>
    a701fcf01f
  165. vasild force-pushed on Mar 1, 2021
  166. vasild commented at 5:30 pm on March 1, 2021: member
    f181f24ca...a701fcf01: pet the linter which seems to be upset by R"(foo "%s" bar")
  167. jonatack approved
  168. jonatack commented at 6:18 pm on March 1, 2021: member

    re-ACK a701fcf01f3ea9a12e869bfa52321302cf68351c reviewed diff per git range-diff ad89812 2a7bb34 a701fcf, debug built and launched bitcoind with i2pd v2.35 running a dual I2P+Torv3 service with the I2P config settings listed below (did not test onlynet=i2p); operation appears nominal (same as it has been these past weeks), and tested the bitcoind help outputs grepping for -i i2p and the rpc getpeerinfo and getnetworkinfo helps

    config settings

    0i2psam=127.0.0.1:7656  # apt install i2pd / systemctl enable i2pd.service / systemctl start i2pd.service
    1i2pacceptincoming=1  # default value
    2debug=i2p
    

    tested with i2pd on Debian 5.10.13-1 (2021-02-06) x86_64 GNU/Linux

    0$ i2pd --version
    1i2pd version 2.35.0 (0.9.48)
    2Boost version 1.74.0
    3OpenSSL 1.1.1i  8 Dec 2020
    

    help output grepping for -i i2p

     0  -i2pacceptincoming
     1       If set and -i2psam is also set then incoming I2P connections are
     2       accepted via the SAM proxy. If this is not set but -i2psam is set
     3       then only outgoing connections will be made to the I2P network.
     4       Ignored if -i2psam is not set. Listening for incoming I2P
     5       connections is done through the SAM proxy, not by binding to a
     6       local address and port (default: 1)
     7
     8  -i2psam=<ip:port>
     9       I2P SAM proxy to reach I2P peers and accept I2P connections (default:
    10       none)
    11
    12  -onlynet=<net>
    13       Make outgoing connections only through network <net> (ipv4, ipv6, onion,
    14       i2p). Incoming connections are not affected by this option. This
    15       option can be specified multiple times to allow multiple
    16       networks. Warning: if it is used with non-onion networks and the
    17       -onion or -proxy option is set, then outbound onion connections
    18       will still be made; use -noonion or -onion=0 to disable outbound
    19       onion connections in this case.
    20
    21  -debug=<category>
    22       Output debugging information (default: -nodebug, supplying <category> is
    23       optional). If <category> is not supplied or if <category> = 1,
    24       output all debugging information. <category> can be: net, tor,
    25       mempool, http, bench, zmq, walletdb, rpc, estimatefee, addrman,
    26       selectcoins, reindex, cmpctblock, rand, prune, proxy, mempoolrej,
    27       libevent, coindb, qt, leveldb, validation, i2p. This option can
    28       be specified multiple times to output multiple categories.
    

    relevant lines of RPC helps

    0getpeerinfo
    1    "network" : "str",                (string) Network (ipv4, ipv6, onion, i2p, not_publicly_routable)
    
    0getnetworkinfo
    1  "networks" : [                                     (json array) information per network
    2    {                                                (json object)
    3      "name" : "str",                                (string) network (ipv4, ipv6, onion, i2p)
    

    Edit: updated ACK commit hash from f181f24ca to a701fcf01 after checking diff, re-building and re-running bitcoind as a dual I2P+Torv3 service.

  169. laanwj commented at 10:38 am on March 2, 2021: member
    re-ACK a701fcf01f3ea9a12e869bfa52321302cf68351c
  170. laanwj merged this on Mar 2, 2021
  171. laanwj closed this on Mar 2, 2021

  172. vasild deleted the branch on Mar 2, 2021
  173. sidhujag referenced this in commit 730aeb9a53 on Mar 2, 2021
  174. vasild commented at 4:40 pm on March 4, 2021: member

    @practicalswift

    I plan to add a fuzzing harness for the I2P Reply parsing code (unless @vasild plans to do it as part of this PR of course :)).

    I am adding some basic fuzzing of the i2p::sam::Session public interface using FuzzedSock (not to Reply()). Will open a PR soonish…

  175. practicalswift commented at 8:15 pm on March 4, 2021: contributor

    @vasild

    I plan to add a fuzzing harness for the I2P Reply parsing code (unless @vasild plans to do it as part of this PR of course :)).

    I am adding some basic fuzzing of the i2p::sam::Session public interface using FuzzedSock (not to Reply()). Will open a PR soonish…

    That’s great news! Looking forward to reviewing it: don’t hesitate to ping me when ready :)

  176. jonatack commented at 10:04 am on March 5, 2021: member

    @vasild here are a couple more screenshots of being connected twice to the same I2P peer (one example of inbound+outbound, which can be persistent (and not unique to I2P peers IIRC, here we are each manually addnode-ing each other I believe), and one example of double inbound, which doesn’t usually last more than ~5 minutes AFAICT but happens the most often, I see it a few times a day).

    The addrbind in every case is my local I2P address.

    Screenshot from 2021-03-05 10-58-35

    Screenshot from 2021-03-05 01-59-28

  177. vasild commented at 12:54 pm on March 8, 2021: member
    @practicalswift: fuzzing tests in #21387.
  178. vasild commented at 5:21 pm on March 8, 2021: member

    @jonatack

    one example of inbound+outbound, which can be persistent (and not unique to I2P peers

    Right. A->B and A<-B is not forbidden and can be done even with IPv4 addresses.

    and one example of double inbound

    I opened #21389 to track this.

  179. jonatack commented at 7:25 pm on March 8, 2021: member

    (did not test onlynet=i2p)

    Since writing that, I’ve been running onlynet=i2p with onlynet=onion and it seems to be working well.

  180. MarcoFalke referenced this in commit 18cd0888ef on Mar 19, 2021
  181. rebroad commented at 1:48 pm on May 3, 2021: contributor
    @jonatack those i2p pings look much higher than the tor pings. Is that normal? Does i2p offer any advantage over tor?
  182. jonatack commented at 2:05 pm on May 3, 2021: member
    @rebroad indeed (see #21261). An advantage is potentially better decentralization, network robustness and censorship resistance, e.g. I2P may be operational when Tor isn’t or has degraded operation, like in January and February.
  183. vasild commented at 2:38 pm on May 3, 2021: member
    In addition, I2P connections have a “source address” - it is certain that the peer who connects from a given I2P address to us possesses the private key that corresponds to that I2P address. This can be used for white-listing “friends”. It is a stronger guarantee than IP addresses (which can be spoofed by e.g. your ISP).
  184. in src/net.cpp:2217 in b905363fa8 outdated
    2212+
    2213+            continue;
    2214+        }
    2215+
    2216+        if (!advertising_listen_addr) {
    2217+            AddLocal(conn.me, LOCAL_BIND);
    


    sdaftuar commented at 1:35 pm on May 4, 2021:

    I don’t entirely understand how these enums (LOCAL_BIND, LOCAL_MANUAL, etc) are meant to be used, but I wonder if this should be LOCAL_MANUAL instead? That seems to be what we use for listening on an onion address: https://github.com/bitcoin/bitcoin/blob/0ca8b7e7ecd5bc537fbc1e372f6755a34a136f7f/src/torcontrol.cpp#L354

    I noticed that when I’m running with -externalip, I don’t get my i2p address listed as a local address (presumably because fDiscover gets defaulted to false and then anything less than LOCAL_MANUAL is ignored in AddLocal()), even though my onion address is unaffected by the setting. Changing this to LOCAL_MANUAL seems to fix this issue.


    vasild commented at 2:57 pm on May 4, 2021:

    I played with the LOCAL_* enums, but I don’t remember why I chose LOCAL_BIND :-( I wonder why AddLocal() induced by -externalip did not work:

    https://github.com/bitcoin/bitcoin/blob/0ca8b7e7ecd5bc537fbc1e372f6755a34a136f7f/src/init.cpp#L1304-L1307


    sdaftuar commented at 2:59 pm on May 4, 2021:

    Sorry I should have been more clear – I was using -externalip with an ipv4 address (this node is listening on an ipv4 address, onion address, and i2p address). However I noticed that with -externalip enabled, the AddLocal for the i2p address didn’t work.

    Presumably if I set -discover=1 explicitly then it would have worked? But I was just surprised that there’s a difference between what we do for onion vs i2p.


    vasild commented at 10:58 am on May 11, 2021:

    Presumably if I set -discover=1 explicitly then it would have worked?

    Yes.

    Fixed in #21914.

  185. laanwj referenced this in commit 5c4f0c4d46 on Jun 14, 2021
  186. sidhujag referenced this in commit b9e1e110ed on Jun 14, 2021
  187. luke-jr referenced this in commit dce01c8bad on Jun 27, 2021
  188. Fabcien referenced this in commit 4557b8ebb2 on Feb 10, 2022
  189. Fabcien referenced this in commit c577087f76 on Feb 10, 2022
  190. Fabcien referenced this in commit b4f3921ff5 on Feb 10, 2022
  191. Fabcien referenced this in commit fb406d6140 on Feb 10, 2022
  192. Fabcien referenced this in commit 1e55ff33b8 on Feb 10, 2022
  193. Fabcien referenced this in commit 2dd02eaa67 on Feb 10, 2022
  194. Fabcien referenced this in commit aff7e41f00 on Feb 10, 2022
  195. Fabcien referenced this in commit 60329d3282 on Feb 11, 2022
  196. Fabcien referenced this in commit c1e9bd7401 on Feb 11, 2022
  197. Fabcien referenced this in commit 3526cd88a6 on Feb 11, 2022
  198. Fabcien referenced this in commit bdcf5ed386 on Feb 15, 2022
  199. Fabcien referenced this in commit 9f22e70a42 on Feb 15, 2022
  200. Fabcien referenced this in commit 795cafd9a4 on Feb 15, 2022
  201. DrahtBot locked this on Aug 18, 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-07-01 10:13 UTC

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