diff --git a/src/init.cpp b/src/init.cpp index 35da20336c..f9ea998cee 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -180,12 +180,13 @@ bool AppInit2(int argc, char* argv[]) " -timeout= \t " + _("Specify connection timeout (in milliseconds)") + "\n" + " -proxy= \t " + _("Connect through socks proxy") + "\n" + " -socks= \t " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" + - " -dns \t " + _("Allow DNS lookups for addnode and connect") + "\n" + + " -dns \t " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" + " -proxydns \t " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" + " -port= \t\t " + _("Listen for connections on (default: 8333 or testnet: 18333)") + "\n" + " -maxconnections=\t " + _("Maintain at most connections to peers (default: 125)") + "\n" + " -addnode= \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + " -connect= \t\t " + _("Connect only to the specified node") + "\n" + + " -seednode= \t\t " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + " -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" + " -listen \t " + _("Accept connections from outside (default: 1)") + "\n" + #ifdef QT_GUI @@ -536,6 +537,9 @@ bool AppInit2(int argc, char* argv[]) fNoListen = !GetBoolArg("-listen", true); nSocksVersion = GetArg("-socks", 5); + BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) + AddOneShot(strDest); + // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. // This can be removed eventually... diff --git a/src/main.cpp b/src/main.cpp index 427e435a90..6a3cbe710d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2264,7 +2264,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } // Get recent addresses - if (pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) + if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) { pfrom->PushMessage("getaddr"); pfrom->fGetAddr = true; @@ -2280,7 +2280,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Ask the first connected node for block updates static int nAskedForBlocks = 0; - if (!pfrom->fClient && + if (!pfrom->fClient && !pfrom->fOneShot && (pfrom->nVersion < NOBLKS_VERSION_START || pfrom->nVersion >= NOBLKS_VERSION_END) && (nAskedForBlocks < 1 || vNodes.size() <= 1)) @@ -2378,6 +2378,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) addrman.Add(vAddr, pfrom->addr, 2 * 60 * 60); if (vAddr.size() < 1000) pfrom->fGetAddr = false; + if (pfrom->fOneShot) + pfrom->fDisconnect = true; } diff --git a/src/net.cpp b/src/net.cpp index ca137b70fa..0483206969 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -35,7 +35,7 @@ void ThreadOpenAddedConnections2(void* parg); void ThreadMapPort2(void* parg); #endif void ThreadDNSAddressSeed2(void* parg); -bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest = NULL); +bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest = NULL, bool fOneShot = false); @@ -59,6 +59,8 @@ deque > vRelayExpiration; CCriticalSection cs_mapRelay; map mapAlreadyAskedFor; +static deque vOneShots; +CCriticalSection cs_vOneShots; set setservAddNodeAddresses; CCriticalSection cs_setservAddNodeAddresses; @@ -68,6 +70,12 @@ static int nOutbound = 0; static CConditionVariable condOutbound; +void AddOneShot(string strDest) +{ + LOCK(cs_vOneShots); + vOneShots.push_back(strDest); +} + unsigned short GetListenPort() { return (unsigned short)(GetArg("-port", GetDefaultPort())); @@ -328,7 +336,7 @@ CNode* FindNode(const CService& addr) CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout) { - if (pszDest != NULL) { + if (pszDest == NULL) { if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost) return NULL; @@ -1038,8 +1046,7 @@ void ThreadDNSAddressSeed2(void* parg) for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { if (fProxyNameLookup) { - CAddress addr; - OpenNetworkConnection(addr, strDNSSeed[seed_idx][1]); + AddOneShot(strDNSSeed[seed_idx][1]); } else { vector vaddr; vector vAdd; @@ -1205,6 +1212,21 @@ void ThreadOpenConnections(void* parg) printf("ThreadOpenConnections exiting\n"); } +void static ProcessOneShot() +{ + string strDest; + { + LOCK(cs_vOneShots); + if (vOneShots.empty()) + return; + strDest = vOneShots.front(); + vOneShots.pop_front(); + } + CAddress addr; + if (!OpenNetworkConnection(addr, strDest.c_str(), true)) + AddOneShot(strDest); +} + void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); @@ -1214,9 +1236,10 @@ void ThreadOpenConnections2(void* parg) { for (int64 nLoop = 0;; nLoop++) { + ProcessOneShot(); BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) { - CAddress addr(CService("0.0.0.0:0")); + CAddress addr; OpenNetworkConnection(addr, strAddr.c_str()); for (int i = 0; i < 10 && i < nLoop; i++) { @@ -1232,6 +1255,8 @@ void ThreadOpenConnections2(void* parg) int64 nStart = GetTime(); loop { + ProcessOneShot(); + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; Sleep(500); vnThreadsRunning[THREAD_OPENCONNECTIONS]++; @@ -1403,7 +1428,7 @@ void ThreadOpenAddedConnections2(void* parg) } } -bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest) +bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest, bool fOneShot) { // // Initiate outbound network connection @@ -1426,6 +1451,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest) if (!pnode) return false; pnode->fNetworkNode = true; + if (fOneShot) + pnode->fOneShot = true; return true; } diff --git a/src/net.h b/src/net.h index 0f48c515b0..d48512a5dc 100644 --- a/src/net.h +++ b/src/net.h @@ -30,6 +30,7 @@ extern int nBestHeight; inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } +void AddOneShot(std::string strDest); bool RecvLine(SOCKET hSocket, std::string& strLine); bool GetMyExternalIP(CNetAddr& ipRet); void AddressCurrentlyConnected(const CService& addr); @@ -122,6 +123,7 @@ public: std::string addrName; int nVersion; std::string strSubVer; + bool fOneShot; bool fClient; bool fInbound; bool fNetworkNode; @@ -171,6 +173,7 @@ public: addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; nVersion = 0; strSubVer = ""; + fOneShot = false; fClient = false; // set by version message fInbound = fInboundIn; fNetworkNode = false;