June 21, 2015

excising DNS lookups from bitcoind: asciilifeform's patches

Filed under: Uncategorized — @ 12:00 a.m.
excising DNS lookups from bitcoind: asciilifeform's patches

asciilifeform submitted 4 patches to the Foundation's mailing list culminating in a complete and total elimination of DNS from bitcoind. Let's take these one at a time (NB: these patches should be applied in order, unless you feel like resolving diffs manually):


Touches 2 files:

  • init.cpp:
    • Removes the "-nodnsseed" flag and the corresponding "SoftSetArg" call from init.cpp
  • net.cpp
    • Removes a bunch of (pointless?) newlines from net.cpp
    • Removes the DNS seeds (,,,
    • Removes ThreadDNSAddressSeed2 declaration and implementation
    • Removes ThreadDNSAddressSeed
    • Removes invocation of ThreadDNSAddressSeed from StartNode


Touches 1 file, removing the hard-coded array of seeds from which a running bitcoind might be able to get new nodes from which to download blocks or to which it might consider broadcasting transactions. You know, those dirty things that nodes do with one another.

  • net.cpp:
    • excises the pnSeeds array
    • excises a local boolean (fAddSeeds) set by an instrospection routine (that behaves differently if the testnet flag is set…)
    • excises the logic branch the program calls if the introspection routine fails

The excised branch iterated through the pnSeed array, adding new addresses to the list of other nodes about which the running node knows. Without this branch, the DNS seeds are no longer added to the mapAddresses data structure that bitcoind uses to track the nodes to which its currently connected/knows about.


Touches the same file (net.cpp):

  • net.cpp:
    • removing GetMyExternalIP2 in its entirety
    • removing GetMyExternalIP in its entirety
    • removing the invocation of GetMyExternalIP from ThreadGetMyExternalIP

This patch leaves ThreadGetMyExternalIP with 1 block of logic:

void ThreadGetMyExternalIP(void* parg)
    // Wait for IRC to get it first
    if (!GetBoolArg("-noirc"))
        for (int i = 0; i < 2 * 60; i++)
            if (fGotExternalIP || fShutdown)

    // Fallback in case IRC fails to get it
    // ... nope.

Which waits for the IRC thread to provide the instance's IP address for what looks like 2 minutes. fGotExternalIP lives in irc.cpp:

void ThreadIRCSeed2(void* parg)
        // snipped for brevity

        // Get our external IP from the IRC server and re-nick before joining the channel
        CAddress addrFromIRC;
        if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
            printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
            if (!fUseProxy && addrFromIRC.IsRoutable())
                // IRC lets you to re-nick
                fGotExternalIP = true;
                addrLocalHost.ip = addrFromIRC.ip;
                strMyName = EncodeAddress(addrLocalHost);
                Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());

        // remainder snipped for brevity


bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
    Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());

    string strLine;
    if (!RecvCodeLine(hSocket, "302", strLine))
        return false;

    vector<string> vWords;
    ParseString(strLine, ' ', vWords);
    if (vWords.size() < 4)
        return false;

    string str = vWords[3];
    if (str.rfind("@") == string::npos)
        return false;
    string strHost = str.substr(str.rfind("@")+1);

    // Hybrid IRC used by lfnet always returns IP when you userhost yourself,
    // but in case another IRC is ever used this should work.
    printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
    if (fUseProxy)
        return false;
    CAddress addr(strHost, 0, true);
    if (!addr.IsValid())
        return false;
    ipRet = addr.ip;

    return true;

Now, booting bitcoind with the -noirc flag without providing it at least one other node to which it should connect will lead the program to hang indefinitely.


This beast changes six files. Let's go!

  • bitcoin/src/init.cpp
    • removes DNS CLI args and SoftSetArg equivalent
    • drops fAllowDNS argument from CAddress instantiation
    • (there are changes to CAddress in protocol.cpp that support this excision, we'll get there)
  • bitcoin/src/irc.cpp
    • drops a DNS lookup of for the IRC seeding mechanism
  • bitcoin/src/net.cpp
    • drops the global fAllowDNS boolean
    • changes CAddress invocations to omit fAllowDNS boolean argument
    • changes 2 Lookup signatures to drop fAllowLookup boolean argument
    • drops fAllowLookup argument from CNode invocation in StartNode function
    • changes Lookup implementation to:
      • drop references to fAllowLookup
      • drop invocations of gethostbyname (devilry that has plagued the Foundation's efforts to make a true static binary, as this function wreaks all sorts of havoc on the "modern" compiler toolchain [I suspect that we'll be vendoring GCC before much longer])
      • function now returns false unless the IP passed it as an argument can be coerced into a CAddress
  • bitcoin/src/net.h
    • changes 2 Lookup function declarations to omit fAllowLookup boolean argument
  • bitcoin/src/protocol.cpp
    • changes 2 Lookup function declarations to omit fAllowLookup boolean argument
    • changes CAddress::CAddress constructor signatures to omit fNameLookup (referred to as fAllowLookup elsewhere) boolean arguments
    • changes CAddress:CAddress implementations to call Lookup without fNameLookup/fAllowLookup boolean argument
  • bitcoin/src/protocol.h
    • changes CAddress constructor signatures to omit fNameLookup/fAllowLookup boolean arguments

Now I'm going to apply this patch and watch her run.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL


« The American consumer, in two photos --- Perceived vs. actual barriers to homeownership for young adults »