summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2013-10-23 19:03:18 +0000
committerGeorge Hazan <george.hazan@gmail.com>2013-10-23 19:03:18 +0000
commit8ed8b8bee2fa6abdfaa4b92543070baef0f340cb (patch)
tree3531535e9094ca3cd7bb52ea6101dfaecca63e6c /src
parented81133e974f844c73ebf717cd0f5bc15e3981fc (diff)
- fix for the old & nasty bug in netlib that rarely crashed Facebook & VK
- code cleaning git-svn-id: http://svn.miranda-ng.org/main/trunk@6602 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src')
-rw-r--r--src/modules/netlib/netlib.cpp196
-rw-r--r--src/modules/netlib/netlib.h2
-rw-r--r--src/modules/netlib/netlibhttp.cpp3
3 files changed, 96 insertions, 105 deletions
diff --git a/src/modules/netlib/netlib.cpp b/src/modules/netlib/netlib.cpp
index 5825bc9801..b6deb4aef6 100644
--- a/src/modules/netlib/netlib.cpp
+++ b/src/modules/netlib/netlib.cpp
@@ -52,6 +52,17 @@ void NetlibFreeUserSettingsStruct(NETLIBUSERSETTINGS *settings)
mir_free(settings->szProxyServer);
}
+int GetNetlibHandleType(void *p)
+{
+ __try {
+ return *(int*)p;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {}
+
+ return NLH_INVALID;
+}
+
void NetlibInitializeNestedCS(NetlibNestedCriticalSection *nlncs)
{
nlncs->dwOwningThreadId = 0;
@@ -103,9 +114,9 @@ void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs)
static INT_PTR GetNetlibUserSettingInt(const char *szUserModule, const char *szSetting, int defValue)
{
DBVARIANT dbv;
- if (db_get(NULL, szUserModule, szSetting, &dbv)
- && db_get(NULL, "Netlib", szSetting, &dbv))
+ if (db_get(NULL, szUserModule, szSetting, &dbv) && db_get(NULL, "Netlib", szSetting, &dbv))
return defValue;
+
if (dbv.type == DBVT_BYTE) return dbv.bVal;
if (dbv.type == DBVT_WORD) return dbv.wVal;
return dbv.dVal;
@@ -114,26 +125,23 @@ static INT_PTR GetNetlibUserSettingInt(const char *szUserModule, const char *szS
static char *GetNetlibUserSettingString(const char *szUserModule, const char *szSetting, int decode)
{
DBVARIANT dbv;
- if (db_get_s(NULL, szUserModule, szSetting, &dbv)
- && db_get_s(NULL, "Netlib", szSetting, &dbv)) {
+ if (db_get_s(NULL, szUserModule, szSetting, &dbv) && db_get_s(NULL, "Netlib", szSetting, &dbv))
return NULL;
- }
- else {
- char *szRet;
- if (decode) CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
- szRet = mir_strdup(dbv.pszVal);
- db_free(&dbv);
- if (szRet == NULL) SetLastError(ERROR_OUTOFMEMORY);
- return szRet;
- }
+
+ if (decode) CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
+ char *szRet = mir_strdup(dbv.pszVal);
+ db_free(&dbv);
+ if (szRet == NULL) SetLastError(ERROR_OUTOFMEMORY);
+ return szRet;
}
static INT_PTR NetlibRegisterUser(WPARAM, LPARAM lParam)
{
NETLIBUSER *nlu = (NETLIBUSER*)lParam;
- if (nlu == NULL || nlu->cbSize != sizeof(NETLIBUSER) || nlu->szSettingsModule == NULL
- || ( !(nlu->flags&NUF_NOOPTIONS) && nlu->szDescriptiveName == NULL)
- || (nlu->flags&NUF_HTTPGATEWAY && (nlu->pfnHttpGatewayInit == NULL))) {
+ if (nlu == NULL || nlu->cbSize != sizeof(NETLIBUSER) || nlu->szSettingsModule == NULL ||
+ (!(nlu->flags & NUF_NOOPTIONS) && nlu->szDescriptiveName == NULL) ||
+ (nlu->flags & NUF_HTTPGATEWAY && (nlu->pfnHttpGatewayInit == NULL)))
+ {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
@@ -153,9 +161,9 @@ static INT_PTR NetlibRegisterUser(WPARAM, LPARAM lParam)
return 0;
}
- if (nlu->szDescriptiveName) {
+ if (nlu->szDescriptiveName)
thisUser->user.ptszDescriptiveName = (thisUser->user.flags&NUF_UNICODE ? mir_u2t((WCHAR*)nlu->ptszDescriptiveName) : mir_a2t(nlu->szDescriptiveName));
- }
+
if ((thisUser->user.szSettingsModule = mir_strdup(nlu->szSettingsModule)) == NULL
|| (nlu->szDescriptiveName && thisUser->user.ptszDescriptiveName == NULL)
|| (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent = mir_strdup(nlu->szHttpGatewayUserAgent)) == NULL))
@@ -229,8 +237,7 @@ void NetlibDoClose(NetlibConnection *nlc, bool noShutdown)
if (nlc->s == INVALID_SOCKET) return;
NetlibLogf(nlc->nlu, "(%p:%u) Connection closed internal", nlc, nlc->s);
- if (nlc->hSsl)
- {
+ if (nlc->hSsl) {
if ( !noShutdown) si.shutdown(nlc->hSsl);
si.sfree(nlc->hSsl);
nlc->hSsl = NULL;
@@ -241,9 +248,8 @@ void NetlibDoClose(NetlibConnection *nlc, bool noShutdown)
INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
{
- switch(GetNetlibHandleType(wParam))
- {
- case NLH_USER:
+ switch(GetNetlibHandleType((void*)wParam)) {
+ case NLH_USER:
{
NetlibUser *nlu = (NetlibUser*)wParam;
{
@@ -261,7 +267,7 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
mir_free(nlu->szStickyHeaders);
break;
}
- case NLH_CONNECTION:
+ case NLH_CONNECTION:
{
NetlibConnection *nlc = (struct NetlibConnection*)wParam;
HANDLE waitHandles[4];
@@ -269,14 +275,10 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
if (nlc->usingHttpGateway)
- {
HttpGatewayRemovePacket(nlc, -1);
- }
- else
- {
- if (nlc->s != INVALID_SOCKET) {
+ else {
+ if (nlc->s != INVALID_SOCKET)
NetlibDoClose(nlc);
- }
if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2);
nlc->s2 = INVALID_SOCKET;
}
@@ -305,19 +307,22 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
DeleteCriticalSection(&nlc->csHttpSequenceNums);
ReleaseMutex(hConnectionHeaderMutex);
NetlibLogf(nlc->nlu, "(%p:%u) Connection closed", nlc, nlc->s);
- break;
}
- case NLH_BOUNDPORT:
- return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam);
- case NLH_PACKETRECVER:
+ break;
+
+ case NLH_BOUNDPORT:
+ return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam);
+
+ case NLH_PACKETRECVER:
{
struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam;
mir_free(nlpr->packetRecver.buffer);
- break;
}
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
+ break;
+
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
}
mir_free((void*)wParam);
return 1;
@@ -326,26 +331,23 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM)
{
SOCKET s;
- if (wParam == 0)
- {
+ if (wParam == 0) {
s = INVALID_SOCKET;
SetLastError(ERROR_INVALID_PARAMETER);
}
- else
- {
+ else {
WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- switch (GetNetlibHandleType(wParam))
- {
- case NLH_CONNECTION:
- s = ((struct NetlibConnection*)wParam)->s;
- break;
- case NLH_BOUNDPORT:
- s = ((struct NetlibBoundPort*)wParam)->s;
- break;
- default:
- s = INVALID_SOCKET;
- SetLastError(ERROR_INVALID_PARAMETER);
- break;
+ switch (GetNetlibHandleType((void*)wParam)) {
+ case NLH_CONNECTION:
+ s = ((struct NetlibConnection*)wParam)->s;
+ break;
+ case NLH_BOUNDPORT:
+ s = ((struct NetlibBoundPort*)wParam)->s;
+ break;
+ default:
+ s = INVALID_SOCKET;
+ SetLastError(ERROR_INVALID_PARAMETER);
+ break;
}
ReleaseMutex(hConnectionHeaderMutex);
}
@@ -381,58 +383,51 @@ INT_PTR NetlibGetMyIp(WPARAM wParam, LPARAM)
INT_PTR NetlibShutdown(WPARAM wParam, LPARAM)
{
- if (wParam)
- {
+ if (wParam) {
WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- switch(GetNetlibHandleType(wParam)) {
- case NLH_CONNECTION:
- {
- struct NetlibConnection* nlc = (struct NetlibConnection*)wParam;
- if (nlc->hSsl) si.shutdown(nlc->hSsl);
- if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, 2);
- if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, 2);
- nlc->termRequested = true;
- }
- break;
- case NLH_BOUNDPORT:
- {
- struct NetlibBoundPort* nlb = (struct NetlibBoundPort*)wParam;
- if (nlb->s != INVALID_SOCKET) shutdown(nlb->s, 2);
- }
- break;
+ switch(GetNetlibHandleType((void*)wParam)) {
+ case NLH_CONNECTION:
+ {
+ struct NetlibConnection* nlc = (struct NetlibConnection*)wParam;
+ if (nlc->hSsl) si.shutdown(nlc->hSsl);
+ if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, 2);
+ if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, 2);
+ nlc->termRequested = true;
+ }
+ break;
+ case NLH_BOUNDPORT:
+ {
+ struct NetlibBoundPort* nlb = (struct NetlibBoundPort*)wParam;
+ if (nlb->s != INVALID_SOCKET) shutdown(nlb->s, 2);
+ }
+ break;
}
ReleaseMutex(hConnectionHeaderMutex);
-
}
return 0;
}
void UnloadNetlibModule(void)
{
- if ( !bModuleInitialized) return;
-
- if (hConnectionHeaderMutex != NULL)
- {
- int i;
+ if (!bModuleInitialized || hConnectionHeaderMutex == NULL) return;
- NetlibUnloadIeProxy();
- NetlibSecurityDestroy();
- NetlibUPnPDestroy();
- NetlibLogShutdown();
+ NetlibUnloadIeProxy();
+ NetlibSecurityDestroy();
+ NetlibUPnPDestroy();
+ NetlibLogShutdown();
- DestroyHookableEvent(hRecvEvent); hRecvEvent = NULL;
- DestroyHookableEvent(hSendEvent); hSendEvent = NULL;
+ DestroyHookableEvent(hRecvEvent); hRecvEvent = NULL;
+ DestroyHookableEvent(hSendEvent); hSendEvent = NULL;
- for (i = netlibUser.getCount(); i > 0; i--)
- NetlibCloseHandle((WPARAM)netlibUser[i-1], 0);
+ for (int i = netlibUser.getCount(); i > 0; i--)
+ NetlibCloseHandle((WPARAM)netlibUser[i-1], 0);
- netlibUser.destroy();
+ netlibUser.destroy();
- CloseHandle(hConnectionHeaderMutex);
- if (hConnectionOpenMutex) CloseHandle(hConnectionOpenMutex);
- DeleteCriticalSection(&csNetlibUser);
- WSACleanup();
- }
+ CloseHandle(hConnectionHeaderMutex);
+ if (hConnectionOpenMutex) CloseHandle(hConnectionOpenMutex);
+ DeleteCriticalSection(&csNetlibUser);
+ WSACleanup();
}
int LoadNetlibModule(void)
@@ -453,19 +448,16 @@ int LoadNetlibModule(void)
OSVERSIONINFOEX osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
- if (GetVersionEx((LPOSVERSIONINFO)&osvi))
- {
+ if (GetVersionEx((LPOSVERSIONINFO)&osvi)) {
// Connection limiting was introduced in Windows XP SP2 and later and set to 10 / sec
if (osvi.dwMajorVersion == 5 && ((osvi.dwMinorVersion == 1 && osvi.wServicePackMajor >= 2) || osvi.dwMinorVersion > 1))
connectionTimeout = 150;
// Connection limiting has limits based on addition Windows Vista pre SP2
- else if (osvi.dwMajorVersion == 6 && osvi.wServicePackMajor < 2)
- {
+ else if (osvi.dwMajorVersion == 6 && osvi.wServicePackMajor < 2) {
DWORD dwType = 0;
tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(GetModuleHandleA("kernel32"), "GetProductInfo");
if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType);
- switch(dwType)
- {
+ switch(dwType) {
case 0x01: // Vista Ultimate edition have connection limit of 25 / sec - plenty for Miranda
case 0x1c:
break;
@@ -481,21 +473,18 @@ int LoadNetlibModule(void)
}
}
// Connection limiting is disabled by default and is controlled by registry setting in Windows Vista SP2 and later
- else if (osvi.dwMajorVersion >= 6)
- {
+ else if (osvi.dwMajorVersion >= 6) {
static const char keyn[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
static const char valn[] = "EnableConnectionRateLimiting";
HKEY hSettings;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyn, 0, KEY_QUERY_VALUE, &hSettings) == ERROR_SUCCESS)
- {
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyn, 0, KEY_QUERY_VALUE, &hSettings) == ERROR_SUCCESS) {
DWORD tValueLen, enabled;
tValueLen = sizeof(enabled);
if (RegQueryValueExA(hSettings, valn, NULL, NULL, (BYTE*)&enabled, &tValueLen) == ERROR_SUCCESS && enabled)
connectionTimeout = 150; // if enabled limit is set to 10 / sec
RegCloseKey(hSettings);
}
-
}
}
@@ -535,7 +524,6 @@ int LoadNetlibModule(void)
NetlibUPnPInit();
NetlibSecurityInit();
NetlibLoadIeProxy();
-
return 0;
}
diff --git a/src/modules/netlib/netlib.h b/src/modules/netlib/netlib.h
index 290d9b44b6..0108604f6b 100644
--- a/src/modules/netlib/netlib.h
+++ b/src/modules/netlib/netlib.h
@@ -21,12 +21,12 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#define GetNetlibHandleType(h) (h?*(int*)h:NLH_INVALID)
#define NLH_INVALID 0
#define NLH_USER 'USER'
#define NLH_CONNECTION 'CONN'
#define NLH_BOUNDPORT 'BIND'
#define NLH_PACKETRECVER 'PCKT'
+int GetNetlibHandleType(void*);
struct NetlibUser
{
diff --git a/src/modules/netlib/netlibhttp.cpp b/src/modules/netlib/netlibhttp.cpp
index 9aafc3d066..1022e63e69 100644
--- a/src/modules/netlib/netlibhttp.cpp
+++ b/src/modules/netlib/netlibhttp.cpp
@@ -839,6 +839,9 @@ INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam)
return 0;
}
+ if (nlhr->nlc != NULL && GetNetlibHandleType(nlhr->nlc) != NLH_CONNECTION)
+ nlhr->nlc = NULL;
+
NetlibConnection* nlc = NetlibHttpProcessUrl(nlhr, nlu, (NetlibConnection*)nlhr->nlc);
if (nlc == NULL)
return 0;