diff -uNr a/bitcoin/src/init.cpp b/bitcoin/src/init.cpp --- a/bitcoin/src/init.cpp 6c99f03bdbac5e74e0ecc62ef36deeb11e867906c53c52ca1ce9a30e41fe61f322aa231327cbe51a08a1d2c3544334ff266c5f2082576c921c22c5a579e5dbcf +++ b/bitcoin/src/init.cpp bf4e182ae4c44170228fbcfc9335e48ffbfa413338135ee9875b2b476355cf5ce60dad8a98acf93bab301d5955c277d7e2604e8b29c550aa756931dda8689223 @@ -164,6 +164,7 @@ " -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") + " -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 +453,18 @@ } } + 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/net.cpp b/bitcoin/src/net.cpp --- a/bitcoin/src/net.cpp 31eb2cbdf4f83f10ae8a7cdd3a69312ba6eafbecfafbeddf7546ce99847bd4f2a674037e2b89a0a7b91c37127d9770501c265a7977edb0ae0b3a5964272692f9 +++ b/bitcoin/src/net.cpp 718f14e6eccffd8fc0448e37b114651d90fbf2076fdbb55167e8999a6066213d968e097de9802f5dea987cc66dc819e27ec9a01820da511c8dd2db064fda24d4 @@ -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,26 @@ 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; + /// 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 +500,8 @@ // Add node CNode* pnode = new CNode(hSocket, addrConnect, false); + pnode->fWireNode = fWireNode; + if (nTimeout != 0) pnode->AddRef(nTimeout); else @@ -508,6 +520,7 @@ void CNode::CloseSocketDisconnect() { + if (fWireNode) return; fDisconnect = true; if (hSocket != INVALID_SOCKET) { @@ -557,6 +570,12 @@ bool CNode::Misbehaving(int howmuch) { + if (fWireNode) + { + printf("Warning: wire node %s misbehaving\n", addr.ToString().c_str()); + return false; + } + if (addr.IsLocal()) { printf("Warning: local node %s misbehaving\n", addr.ToString().c_str()); @@ -624,8 +643,8 @@ vector vNodesCopy = vNodes; BOOST_FOREACH(CNode* pnode, vNodesCopy) { - if (pnode->fDisconnect || - (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) + if (!pnode->fWireNode && (pnode->fDisconnect || // NEVER disconnect wires + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); @@ -1061,19 +1080,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 +1108,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(500); + } +} void ThreadMessageHandler(void* parg) @@ -1298,6 +1353,10 @@ if (!CreateThread(ThreadOpenConnections, NULL)) printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + // Initiate outbound connections + if (!CreateThread(ThreadOpenWires, NULL)) + printf("Error: CreateThread(ThreadOpenWires) failed\n"); + // Process messages if (!CreateThread(ThreadMessageHandler, NULL)) printf("Error: CreateThread(ThreadMessageHandler) failed\n"); @@ -1312,7 +1371,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 +1383,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 3f2a913886cca162a19ccb416cbc3d3584e1bdaf101c785087190dbcad0feb68936931175f17f916bce8c5ce6a1d3c6f2746301eadb85238772cfb6815eb5f8c @@ -28,6 +28,7 @@ bool fShutdown = false; bool fDaemon = false; bool fServer = false; +bool fWires = false; 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 50ccfd6e76e87001940f837c8b0eaa0795f550a1f1c34a75b0e8c370187bd35cfaee8d0c5b23e3807b66dee321886147f0490c6e4768f1ff2ef8433e6765ace9 @@ -117,6 +117,7 @@ extern bool fShutdown; extern bool fDaemon; extern bool fServer; +extern bool fWires; extern bool fCommandLine; extern std::string strMiscWarning; extern bool fNoListen;