From dd519206a684c772a4a06ceecc87c665ad09d8be Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 02:52:48 +0000 Subject: addr relaying fixes, proxy option and privacy patches, detect connect to self, non-final tx locktime changes, fix hide unconfirmed generated git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@18 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- net.cpp | 173 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 102 insertions(+), 71 deletions(-) (limited to 'net.cpp') diff --git a/net.cpp b/net.cpp index db138e13a..22b84f9de 100644 --- a/net.cpp +++ b/net.cpp @@ -8,6 +8,7 @@ void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); void ThreadOpenConnections2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect); @@ -22,8 +23,10 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode* pnodeLocalHost = &nodeLocalHost; +uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; +SOCKET hListenSocket = INVALID_SOCKET; vector vNodes; CCriticalSection cs_vNodes; @@ -34,9 +37,11 @@ deque > vRelayExpiration; CCriticalSection cs_mapRelay; map mapAlreadyAskedFor; +// Settings +int fUseProxy = false; +CAddress addrProxy("127.0.0.1:9050"); -CAddress addrProxy; bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) { @@ -47,7 +52,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) return false; bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); - bool fProxy = (addrProxy.ip && fRoutable); + bool fProxy = (fUseProxy && fRoutable); struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) @@ -69,18 +74,18 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (ret != nSize) { closesocket(hSocket); - return error("Error sending to proxy\n"); + return error("Error sending to proxy"); } char pchRet[8]; if (recv(hSocket, pchRet, 8, 0) != 8) { closesocket(hSocket); - return error("Error reading proxy response\n"); + return error("Error reading proxy response"); } if (pchRet[1] != 0x5a) { closesocket(hSocket); - return error("Proxy returned error %d\n", pchRet[1]); + return error("Proxy returned error %d", pchRet[1]); } printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); } @@ -95,7 +100,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha { SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) - return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); send(hSocket, pszGet, strlen(pszGet), 0); @@ -131,7 +136,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha } } closesocket(hSocket); - return error("GetMyExternalIP() : connection closed\n"); + return error("GetMyExternalIP() : connection closed"); } @@ -141,6 +146,9 @@ bool GetMyExternalIP(unsigned int& ipRet) char* pszGet; char* pszKeyword; + if (fUseProxy) + return false; + for (int nLookup = 0; nLookup <= 1; nLookup++) for (int nHost = 1; nHost <= 2; nHost++) { @@ -416,14 +424,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } } -void CNode::Disconnect() +void CNode::DoDisconnect() { printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); // If outbound and never got version message, mark address as failed - if (!fInbound && nVersion == 0) + if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) mapAddresses[addr.GetKey()].nLastFailed = GetTime(); @@ -458,18 +466,18 @@ void ThreadSocketHandler(void* parg) loop { - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); try { ThreadSocketHandler2(parg); - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; } catch (std::exception& e) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(&e, "ThreadSocketHandler()"); } catch (...) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(NULL, "ThreadSocketHandler()"); } Sleep(5000); @@ -479,7 +487,6 @@ void ThreadSocketHandler(void* parg) void ThreadSocketHandler2(void* parg) { printf("ThreadSocketHandler started\n"); - SOCKET hListenSocket = *(SOCKET*)parg; list vNodesDisconnected; int nPrevNodeCount = 0; @@ -498,7 +505,7 @@ void ThreadSocketHandler2(void* parg) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); - pnode->Disconnect(); + pnode->DoDisconnect(); // hold in disconnected pool until all refs are released pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); @@ -562,9 +569,9 @@ void ThreadSocketHandler2(void* parg) } } - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); if (nSelect == SOCKET_ERROR) { @@ -577,7 +584,6 @@ void ThreadSocketHandler2(void* parg) } Sleep(timeout.tv_usec/1000); } - RandAddSeed(); //// debug print //foreach(CNode* pnode, vNodes) @@ -711,18 +717,18 @@ void ThreadOpenConnections(void* parg) loop { - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); try { ThreadOpenConnections2(parg); - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; } catch (std::exception& e) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(&e, "ThreadOpenConnections()"); } catch (...) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(NULL, "ThreadOpenConnections()"); } Sleep(5000); @@ -733,6 +739,13 @@ void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); + // Connect to one specified address + while (mapArgs.count("/connect")) + { + OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str())); + Sleep(10000); + } + // Initiate network connections int nTry = 0; bool fIRCOnly = false; @@ -740,14 +753,14 @@ void ThreadOpenConnections2(void* parg) loop { // Wait - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; Sleep(500); while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); Sleep(2000); } - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); @@ -835,43 +848,48 @@ void ThreadOpenConnections2(void* parg) // Once we've chosen an IP, we'll try every given port before moving on foreach(const CAddress& addrConnect, (*mi).second) - { - // - // Initiate outbound network connection - // - CheckForShutdown(1); - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) - continue; + if (OpenNetworkConnection(addrConnect)) + break; + } +} - vnThreadsRunning[1] = false; - CNode* pnode = ConnectNode(addrConnect); - vnThreadsRunning[1] = true; - CheckForShutdown(1); - if (!pnode) - continue; - pnode->fNetworkNode = true; +bool OpenNetworkConnection(const CAddress& addrConnect) +{ + // + // Initiate outbound network connection + // + CheckForShutdown(1); + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + return false; - if (addrLocalHost.IsRoutable()) - { - // Advertise our address - vector vAddrToSend; - vAddrToSend.push_back(addrLocalHost); - pnode->PushMessage("addr", vAddrToSend); - } + vnThreadsRunning[1]--; + CNode* pnode = ConnectNode(addrConnect); + vnThreadsRunning[1]++; + CheckForShutdown(1); + if (!pnode) + return false; + pnode->fNetworkNode = true; - // Get as many addresses as we can - pnode->PushMessage("getaddr"); + if (addrLocalHost.IsRoutable() && !fUseProxy) + { + // Advertise our address + vector vAddrToSend; + vAddrToSend.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddrToSend); + } - ////// should the one on the receiving end do this too? - // Subscribe our local subscription list - const unsigned int nHops = 0; - for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) - if (pnodeLocalHost->vfSubscribe[nChannel]) - pnode->PushMessage("subscribe", nChannel, nHops); + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + pnode->fGetAddr = true; // don't relay the results of the getaddr - break; - } - } + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + return true; } @@ -887,18 +905,18 @@ void ThreadMessageHandler(void* parg) loop { - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); try { ThreadMessageHandler2(parg); - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; } catch (std::exception& e) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(&e, "ThreadMessageHandler()"); } catch (...) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(NULL, "ThreadMessageHandler()"); } Sleep(5000); @@ -931,9 +949,9 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; Sleep(100); - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); } } @@ -982,7 +1000,7 @@ bool StartNode(string& strError) printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections - SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) { strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); @@ -1024,13 +1042,21 @@ bool StartNode(string& strError) } // Get our external IP address for incoming connections - if (addrIncoming.ip) - addrLocalHost.ip = addrIncoming.ip; - - if (GetMyExternalIP(addrLocalHost.ip)) + if (fUseProxy) { - addrIncoming = addrLocalHost; - CWalletDB().WriteSetting("addrIncoming", addrIncoming); + // Proxies can't take incoming connections + addrLocalHost.ip = CAddress("0.0.0.0").ip; + } + else + { + if (addrIncoming.ip) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + } } // Get addresses from IRC and advertise ours @@ -1040,7 +1066,7 @@ bool StartNode(string& strError) // // Start threads // - if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) + if (_beginthread(ThreadSocketHandler, 0, NULL) == -1) { strError = "Error: _beginthread(ThreadSocketHandler) failed"; printf("%s\n", strError.c_str()); @@ -1094,10 +1120,15 @@ void CheckForShutdown(int n) if (fShutdown) { if (n != -1) - vnThreadsRunning[n] = false; + if (--vnThreadsRunning[n] < 0) + vnThreadsRunning[n] = 0; if (n == 0) + { foreach(CNode* pnode, vNodes) closesocket(pnode->hSocket); + closesocket(hListenSocket); + } + printf("Thread %d exiting\n", n); _endthread(); } } -- cgit v1.2.3