aboutsummaryrefslogtreecommitdiff
path: root/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'net.cpp')
-rw-r--r--net.cpp173
1 files changed, 102 insertions, 71 deletions
diff --git a/net.cpp b/net.cpp
index db138e13a5..22b84f9dee 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<int, 10> vnThreadsRunning;
+SOCKET hListenSocket = INVALID_SOCKET;
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
@@ -34,9 +37,11 @@ deque<pair<int64, CInv> > vRelayExpiration;
CCriticalSection cs_mapRelay;
map<CInv, int64> 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<CNode*> 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<CAddress> 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<CAddress> 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();
}
}