mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-25 15:39:27 -05:00
Limit the concurrent connection attempts in Windows XP. Its's only a hack.
Problem: RetroShare connects to all ssl's at once. In Windows XP there is a build-in connection limit of concurrent incomplete connections. Quote: "The TCP/IP stack in Windows XP with Service Pack 2 (SP2) installed limits the number of concurrent, incomplete outbound TCP connection attempts. When the limit is reached, subsequent connection attempts are put in a queue and resolved at a fixed rate so that there are only a limited number of connections in the incomplete state." This results in a high usage of the nonepaged pool and when it runs over the limit it results in the following error in the system log: German: "TCP/IP hat das Sicherheitslimit erreicht, das für die Anzahl gleichzeitiger TCP-Verbindungsversuche festgelegt wurde." English: "TCP/IP has reached the security limit imposed on the number of concurrent (incomplete) TCP connect attempts." After a longer runtime of RetroShare and a very high usage of the nonepaged pool all connections of all running programs are lost and no new connections can be made. At the end it can cause a blue screen. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3631 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
c134b5f605
commit
f4bbd3e933
@ -1453,6 +1453,19 @@ void p3ConnectMgr::tickMonitors()
|
||||
(*mit)->statusChange(actionList);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
|
||||
/* notify all monitors */
|
||||
std::list<pqiMonitor *>::iterator mit;
|
||||
for(mit = clients.begin(); mit != clients.end(); mit++) {
|
||||
(*mit)->statusChanged();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,6 +112,14 @@ virtual ~pqiMonitor() { return; }
|
||||
*@param plist contains list of states and actions of the client's peers
|
||||
*/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist) = 0;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
virtual void statusChanged() {};
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
//virtual void ownStatusChange(pqipeer &) { return; } // SIGNAL reset or similar.
|
||||
//virtual void peerStatus(std::string id, uint32_t mode) = 0;
|
||||
|
||||
|
@ -32,6 +32,15 @@
|
||||
|
||||
const int pqipersongrpzone = 354;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
#include "retroshare/rsinit.h"
|
||||
static std::list<std::string> waitingIds;
|
||||
#define MAX_CONNECT_COUNT 5
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
/****
|
||||
*#define PGRP_DEBUG 1
|
||||
****/
|
||||
@ -296,6 +305,73 @@ void pqipersongrp::statusChange(const std::list<pqipeer> &plist)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
void pqipersongrp::statusChanged()
|
||||
{
|
||||
#warning "Windows connection limited hacked together - please fix"
|
||||
|
||||
if (RsInit::isWindowsXP() == false) {
|
||||
/* the problem only exist in Windows XP */
|
||||
waitingIds.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for active connections and start waiting id's */
|
||||
long connect_count = 0;
|
||||
|
||||
{
|
||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||
|
||||
/* get address from p3connmgr */
|
||||
if (!mConnMgr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for active connections and start waiting id's */
|
||||
std::list<std::string> peers;
|
||||
mConnMgr->getFriendList(peers);
|
||||
|
||||
/* count connection attempts */
|
||||
std::list<std::string>::iterator peer;
|
||||
for (peer = peers.begin(); peer != peers.end(); peer++) {
|
||||
peerConnectState state;
|
||||
if (mConnMgr->getFriendNetStatus(*peer, state) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state.inConnAttempt) {
|
||||
connect_count++;
|
||||
if (connect_count >= MAX_CONNECT_COUNT) {
|
||||
#ifdef PGRP_DEBUG
|
||||
std::cerr << "pqipersongrp::connectPeer() Too many connections due to windows limitations. There are " << waitingIds.size() << " waiting connections." << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* UNLOCKED */
|
||||
|
||||
#ifdef PGRP_DEBUG
|
||||
std::cerr << "pqipersongrp::connectPeer() There are " << connect_count << " connection attempts and " << waitingIds.size() << " waiting connections. Can start " << (MAX_CONNECT_COUNT - connect_count) << " connection attempts." << std::endl;
|
||||
#endif
|
||||
|
||||
/* there is no need for a mutex for waitingIds */
|
||||
|
||||
/* start some waiting id's */
|
||||
for (int i = connect_count; i < MAX_CONNECT_COUNT; i++) {
|
||||
if (waitingIds.empty()) {
|
||||
break;
|
||||
}
|
||||
std::string waitingId = waitingIds.front();
|
||||
waitingIds.pop_front();
|
||||
connectPeer(waitingId, true);
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
|
||||
int pqipersongrp::addPeer(std::string id)
|
||||
@ -393,7 +469,14 @@ int pqipersongrp::tagHeartbeatRecvd(std::string id)
|
||||
|
||||
|
||||
|
||||
int pqipersongrp::connectPeer(std::string id)
|
||||
int pqipersongrp::connectPeer(std::string id
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
, bool bConnect /*= false*/
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* get status from p3connectMgr */
|
||||
#ifdef PGRP_DEBUG
|
||||
@ -423,6 +506,33 @@ int pqipersongrp::connectPeer(std::string id)
|
||||
if (!mConnMgr)
|
||||
return 0;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
|
||||
if (RsInit::isWindowsXP()) {
|
||||
/* the problem only exist in Windows XP */
|
||||
if (bConnect == false) {
|
||||
/* check for id is waiting */
|
||||
if (std::find(waitingIds.begin(), waitingIds.end(), id) != waitingIds.end()) {
|
||||
/* id is waiting for a connection */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add id to waiting */
|
||||
waitingIds.push_back(id);
|
||||
|
||||
/* wait for call to connectPeer with empty id */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* remove id from waiting */
|
||||
waitingIds.remove(id);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
struct sockaddr_in addr;
|
||||
uint32_t delay;
|
||||
uint32_t period;
|
||||
|
@ -64,10 +64,24 @@ int load_config();
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
virtual void statusChanged();
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
/******************* Peer Control **************************/
|
||||
virtual int addPeer(std::string id); /* can be overloaded for testing */
|
||||
int removePeer(std::string id);
|
||||
int connectPeer(std::string id);
|
||||
int connectPeer(std::string id
|
||||
#ifdef WINDOWS_SYS
|
||||
///////////////////////////////////////////////////////////
|
||||
// hack for too many connections
|
||||
, bool bConnect = false
|
||||
///////////////////////////////////////////////////////////
|
||||
#endif
|
||||
);
|
||||
|
||||
/* Work-around to dodgy pointer stuff */
|
||||
int tagHeartbeatRecvd(std::string id);
|
||||
|
@ -67,7 +67,7 @@ class RsInit
|
||||
*/
|
||||
static char dirSeperator();
|
||||
static bool isPortable();
|
||||
|
||||
static bool isWindowsXP();
|
||||
|
||||
/*!
|
||||
* Account Details (Combined GPG+SSL Setup)
|
||||
|
@ -76,6 +76,7 @@ class RsInitConfig
|
||||
static std::string homePath;
|
||||
#ifdef WINDOWS_SYS
|
||||
static bool portable;
|
||||
static bool isWindowsXP;
|
||||
#endif
|
||||
|
||||
static std::list<accountId> accountIds;
|
||||
@ -169,6 +170,7 @@ std::string RsInitConfig::basedir;
|
||||
std::string RsInitConfig::homePath;
|
||||
#ifdef WINDOWS_SYS
|
||||
bool RsInitConfig::portable = false;
|
||||
bool RsInitConfig::isWindowsXP = false;
|
||||
#endif
|
||||
|
||||
/* Listening Port */
|
||||
@ -252,10 +254,38 @@ void RsInit::InitRsConfig()
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
// test for portable version
|
||||
if (GetFileAttributes (L"gpg.exe") != (DWORD) -1 && GetFileAttributes (L"gpgme-w32spawn.exe") != (DWORD) -1) {
|
||||
if (GetFileAttributes (L"gpg.exe") != (DWORD) -1 && GetFileAttributes (L"gpgme-w32spawn.exe") != (DWORD) -1) {
|
||||
// use portable version
|
||||
RsInitConfig::portable = true;
|
||||
}
|
||||
|
||||
// test for Windows XP
|
||||
OSVERSIONINFOEX osvi;
|
||||
memset(&osvi, 0, sizeof(osvi));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
|
||||
if (GetVersionEx((OSVERSIONINFO*) &osvi)) {
|
||||
if (osvi.dwMajorVersion == 5) {
|
||||
if (osvi.dwMinorVersion == 1) {
|
||||
/* Windows XP */
|
||||
RsInitConfig::isWindowsXP = true;
|
||||
} else if (osvi.dwMinorVersion == 2) {
|
||||
SYSTEM_INFO si;
|
||||
memset(&si, 0, sizeof(si));
|
||||
GetSystemInfo(&si);
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
/* Windows XP Professional x64 Edition */
|
||||
RsInitConfig::isWindowsXP = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RsInitConfig::isWindowsXP) {
|
||||
std::cerr << "Running Windows XP" << std::endl;
|
||||
} else {
|
||||
std::cerr << "Not running Windows XP" << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup the Debugging */
|
||||
@ -1988,6 +2018,15 @@ bool RsInit::isPortable()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RsInit::isWindowsXP()
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
return RsInitConfig::isWindowsXP;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string RsInit::RsConfigDirectory()
|
||||
{
|
||||
return RsInitConfig::basedir;
|
||||
|
Loading…
Reference in New Issue
Block a user