diff -uNr a/bitcoin/src/init.cpp b/bitcoin/src/init.cpp --- a/bitcoin/src/init.cpp 6c99f03bdbac5e74e0ecc62ef36deeb11e867906c53c52ca1ce9a30e41fe61f322aa231327cbe51a08a1d2c3544334ff266c5f2082576c921c22c5a579e5dbcf +++ b/bitcoin/src/init.cpp 44554f1de8c537c1746c5378a799e0dc3948f7b3069483f3dd32e3aeab615cc29dd610591756000ec519caa2e3e2d919685a0e10920af7a06d480afa29c1ecfd @@ -164,6 +164,8 @@ " -port= \t\t " + _("Listen for connections on (default: 8333)\n") + " -maxconnections=\t " + _("Maintain at most connections to peers (default: 125)\n") + " -myip= \t " + _("Set this node's external IP address.\n") + + " -addwire= \t " + _("Add a hardwired node to connect to\n") + + " -wirerefresh=\t " + _("Interval for refreshing wires.\n") + " -addnode= \t " + _("Add a node to connect to\n") + " -connect= \t\t " + _("Connect only to the specified node\n") + " -nolisten \t " + _("Don't accept connections from outside\n") + @@ -452,6 +454,24 @@ } } + if (mapArgs.count("-wirerefresh")) + { + wireRefresh = atoi(mapArgs["-wirerefresh"]); + } + + + if (mapArgs.count("-addwire")) + { + BOOST_FOREACH(string strAddr, mapMultiArgs["-addwire"]) + { + CAddress addr(strAddr); + if (addr.IsValid()) { + AddWire(addr); + fWires = true; + } + } + } + if (mapArgs.count("-addnode")) { BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"]) diff -uNr a/bitcoin/src/knobs.h b/bitcoin/src/knobs.h --- a/bitcoin/src/knobs.h 9b88b8f60d9a0ae98f9dd148dba06e132b6b1fc199719eacb3270fe6ce2af889422eee62c2cb08c3b93f22069aea880c657e771c4e4b4157a69c321550c8fc73 +++ b/bitcoin/src/knobs.h b9e9cc276d3abfd0d74515cb976ee85b0626a377e792e61c5a76ebed7217a06d00cba4bb8345bfa30771eae269d43afb5821ad1920424031707d8ad837624e64 @@ -4,4 +4,6 @@ #define DEFAULT_CLIENT_NAME "therealbitcoin.org" #define DEFAULT_CLIENT_VERSION 99999 /* 50400 */ +#define DEFAULT_WIRE_REFRESH 250 + #endif diff -uNr a/bitcoin/src/net.cpp b/bitcoin/src/net.cpp --- a/bitcoin/src/net.cpp 31eb2cbdf4f83f10ae8a7cdd3a69312ba6eafbecfafbeddf7546ce99847bd4f2a674037e2b89a0a7b91c37127d9770501c265a7977edb0ae0b3a5964272692f9 +++ b/bitcoin/src/net.cpp 4c763023d33ee372e2de34fe6f345f7971a670accec364e06828b7a24bf471f844f9535c263412ba779ef1a7e042d09cb7ab42fb7393a4afe72b62e82ec37d3e @@ -18,8 +18,8 @@ void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); void ThreadOpenConnections2(void* parg); -bool OpenNetworkConnection(const CAddress& addrConnect); - +void ThreadOpenWires2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect, bool fWireConnection=false); @@ -37,6 +37,7 @@ vector vNodes; CCriticalSection cs_vNodes; +map, CAddress> mapWires; map, CAddress> mapAddresses; CCriticalSection cs_mapAddresses; map mapRelay; @@ -243,6 +244,20 @@ } +// 'Wires' don't get saved to the DB; they don't get shared with peers, +// including one another; they don't voluntarily get disconnected; +// if disconnected by other side, they will bang on the door forever; +// they carry no ban score. Think of them as 'leased lines.' +// They are also permitted to be ports on localhost! (tunnelers, e.g., 'g'.) +// Use with caution!!! +bool AddWire(CAddress addr) +{ + printf("AddWire(%s)\n", addr.ToString().c_str()); + mapWires.insert(make_pair(addr.GetKey(), addr)); // NO error checking! + return true; +} + + bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB) { if (!addr.IsRoutable()) @@ -452,31 +467,29 @@ return NULL; } -CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout, bool fWireNode) { - if (addrConnect.ip == addrLocalHost.ip) + if (!fWireNode && (addrConnect.ip == addrLocalHost.ip)) return NULL; - - // Look for an existing connection - CNode* pnode = FindNode(addrConnect.ip); - if (pnode) - { - if (nTimeout != 0) - pnode->AddRef(nTimeout); - else - pnode->AddRef(); - return pnode; + + if (fWireNode) { + nTimeout = 0; + printf("Connecting to wire node... %s\n", + addrConnect.ToString().c_str()); } - + /// debug print printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n", addrConnect.ToString().c_str(), (double)(addrConnect.nTime - GetAdjustedTime())/3600.0, (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0); - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime(); - + if (!fWireNode) + { + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime(); + } + // Connect SOCKET hSocket; if (ConnectSocket(addrConnect, hSocket)) @@ -490,6 +503,10 @@ // Add node CNode* pnode = new CNode(hSocket, addrConnect, false); + pnode->fWireNode = fWireNode; + + if (fWireNode) printf("Added wire node !\n"); + if (nTimeout != 0) pnode->AddRef(nTimeout); else @@ -508,6 +525,10 @@ void CNode::CloseSocketDisconnect() { + if (fWireNode) { + printf("WARNING: disconnecting wire %s ! (will retry...)\n", + addr.ToString().c_str()); + } fDisconnect = true; if (hSocket != INVALID_SOCKET) { @@ -557,6 +578,12 @@ bool CNode::Misbehaving(int howmuch) { + if (fWireNode) + { + printf("Warning: wire node %s misbehaving (no disconnect)\n", addr.ToString().c_str()); + return false; + } + if (addr.IsLocal()) { printf("Warning: local node %s misbehaving\n", addr.ToString().c_str()); @@ -873,8 +900,8 @@ // if (pnode->vSend.empty()) pnode->nLastSendEmpty = GetTime(); - if (GetTime() - pnode->nTimeConnected > 60) - { + if ((!pnode->fWireNode) && (GetTime() - pnode->nTimeConnected > 60)) + { // these conditions do not apply to wires ! if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) { printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); @@ -1061,19 +1088,23 @@ } } -bool OpenNetworkConnection(const CAddress& addrConnect) +bool OpenNetworkConnection(const CAddress& addrConnect, bool fWireConnection) { // // Initiate outbound network connection // if (fShutdown) return false; - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || - FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip)) + + if (!fWireConnection && + (addrConnect.ip == addrLocalHost.ip || CNode::IsBanned(addrConnect.ip))) + return false; + + if (!addrConnect.IsIPv4() || FindNode(addrConnect.ip)) return false; vnThreadsRunning[1]--; - CNode* pnode = ConnectNode(addrConnect); + CNode* pnode = ConnectNode(addrConnect, 0, fWireConnection); vnThreadsRunning[1]++; if (fShutdown) return false; @@ -1085,10 +1116,42 @@ } +void ThreadOpenWires(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenWires(parg)); + try + { + vnThreadsRunning[5]++; + ThreadOpenWires2(parg); + vnThreadsRunning[5]--; + } + catch (std::exception& e) { + vnThreadsRunning[5]--; + PrintException(&e, "ThreadOpenWires()"); + } catch (...) { + vnThreadsRunning[5]--; + PrintException(NULL, "ThreadOpenWires()"); + } + printf("ThreadOpenWires exiting\n"); +} +void ThreadOpenWires2(void* parg) +{ + printf("ThreadOpenWires started\n"); - + while (1) + { + BOOST_FOREACH(const PAIRTYPE(vector, CAddress)& item, mapWires) + { + const CAddress& addr = item.second; + OpenNetworkConnection(addr, true); + if (fShutdown) + return; + } + Sleep(wireRefresh); + } +} void ThreadMessageHandler(void* parg) @@ -1298,6 +1361,10 @@ if (!CreateThread(ThreadOpenConnections, NULL)) printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + // Initiate outbound wires, if at least one was defined + if (fWires && !CreateThread(ThreadOpenWires, NULL)) + printf("Error: CreateThread(ThreadOpenWires) failed\n"); + // Process messages if (!CreateThread(ThreadMessageHandler, NULL)) printf("Error: CreateThread(ThreadMessageHandler) failed\n"); @@ -1312,7 +1379,7 @@ fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 || vnThreadsRunning[5] > 0 ) { if (GetTime() - nStart > 20) @@ -1324,6 +1391,7 @@ if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n"); + if (vnThreadsRunning[5] > 0) printf("ThreadOpenWires still running\n"); while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0) Sleep(20); Sleep(50); diff -uNr a/bitcoin/src/net.h b/bitcoin/src/net.h --- a/bitcoin/src/net.h bb842420bcc67752edf8e658524b135f499c5f8676557a6c12f47f204303e34bd73beabdf6e9146ba452947c4e5cd298529969fab90f16942f6bf0c1229f7043 +++ b/bitcoin/src/net.h 23936cb985a2896b4924efe4ef5e01efad61eb3800227b611ce8bdec0542869acccef2fadaac9ab4e18ccae527aa9df14f1bb87d3e5db14f810dc03a246f2647 @@ -29,9 +29,10 @@ bool Lookup(const char *pszName, std::vector& vaddr, int nServices, int nMaxSolutions, int portDefault = 0, bool fAllowPort = false); bool Lookup(const char *pszName, CAddress& addr, int nServices, int portDefault = 0, bool fAllowPort = false); bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL); +bool AddWire(CAddress addr); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); -CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0, bool fWireNode=false); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); void MapPort(bool fMapPort); @@ -76,6 +77,7 @@ extern std::vector vNodes; extern CCriticalSection cs_vNodes; +extern std::map, CAddress> mapWires; extern std::map, CAddress> mapAddresses; extern CCriticalSection cs_mapAddresses; extern std::map mapRelay; @@ -114,6 +116,7 @@ bool fClient; bool fInbound; bool fNetworkNode; + bool fWireNode; bool fSuccessfullyConnected; bool fDisconnect; protected: @@ -175,6 +178,7 @@ fClient = false; // set by version message fInbound = fInboundIn; fNetworkNode = false; + fWireNode = false; fSuccessfullyConnected = false; fDisconnect = false; nRefCount = 0; diff -uNr a/bitcoin/src/util.cpp b/bitcoin/src/util.cpp --- a/bitcoin/src/util.cpp 66a8ac388136aceac7d24bd73c18b06445c2580849dd6c548d6684b5f1e9c19eafd3f71427476fd982383dcfd0425f34ce524eac1d8320fd990a28a1e4933288 +++ b/bitcoin/src/util.cpp 2fd88baef1f634350325b6328558e675482362c70f9bb5d13060702d839d5b196ca6d66542c27d7a9d7bd70315007588dfc6ab6f57f0a92131753805f4604939 @@ -28,6 +28,8 @@ bool fShutdown = false; bool fDaemon = false; bool fServer = false; +bool fWires = false; +int wireRefresh = DEFAULT_WIRE_REFRESH; bool fCommandLine = false; string strMiscWarning; bool fNoListen = false; diff -uNr a/bitcoin/src/util.h b/bitcoin/src/util.h --- a/bitcoin/src/util.h f0c21c349b56516feac63c9cf8018c82b26583ad290a4b3610965e5a5a703d116671b1ef270395b8289c170b603630b5b7e493725e420e187ba1fbd326061ff5 +++ b/bitcoin/src/util.h fdcf2290002e39430bf5a0dd0c05a1005cecac03dec8defe551f0402fba5b83542cdc3d641cd71ef6f03b811935c9507d2c09ad8c9e07ee097a98ee4f756caf1 @@ -117,6 +117,8 @@ extern bool fShutdown; extern bool fDaemon; extern bool fServer; +extern bool fWires; +extern int wireRefresh; extern bool fCommandLine; extern std::string strMiscWarning; extern bool fNoListen;