From 8b3725c91675775e653318362e762930d7954014 Mon Sep 17 00:00:00 2001 From: Mataes Date: Sat, 23 Jun 2018 13:34:27 +0300 Subject: Netlib: patch for proxySwitch --- include/m_netlib.h | 42 +++++++++++++ src/mir_app/src/netlib.cpp | 120 +++++++++++++++++++++++++------------ src/mir_app/src/netlib.h | 3 + src/mir_app/src/netlibbind.cpp | 19 ++++++ src/mir_app/src/netlibopenconn.cpp | 19 ++++++ 5 files changed, 166 insertions(+), 37 deletions(-) diff --git a/include/m_netlib.h b/include/m_netlib.h index 10fa59eb31..42b0a4d432 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -200,6 +200,16 @@ struct NETLIBUSERSETTINGS EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *result); +///////////////////////////////////////////////////////////////////////////////////////// +//Gets the user-configured settings for a netlib user idetified by name +// +//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) +//This function behaves like Netlib_GetUserSettings but the user is identified +//by the name provided by registration. When the name is not found NETLIBUSERSETTINGS is set to NULL. +//Errors: ERROR_INVALID_PARAMETER + +EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result); + ///////////////////////////////////////////////////////////////////////////////////////// // Changes the user-configurable settings for a netlib user // @@ -212,6 +222,16 @@ EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETT EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *result); +///////////////////////////////////////////////////////////////////////////////////////// +//Changes the user-configurable settings for a netlib user idetified by name +// +//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) +//This function behaves like Netlib_SetUserSettings but the user is identified +//by the name provided by registration. Nothing will be changed when the name is not found. +//Errors: ERROR_INVALID_PARAMETER + +EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result); + ///////////////////////////////////////////////////////////////////////////////////////// // Closes a netlib handle // @@ -762,4 +782,26 @@ struct NETLIBNOTIFY #define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send #define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump +struct NETLIBCONNECTIONEVENTINFO +{ + BOOL connected; // 1-opening socket 0-closing socket + BOOL listening; // 1-bind 0-connect + SOCKADDR_IN local; // local IP+port (always used) + SOCKADDR_IN remote; // remote IP+port (only connect (opening + closing only if no proxy)) + SOCKADDR_IN proxy; // proxy IP+port (only connect when used) + char *szSettingsModule; // name of the registered Netlib user that requested the action +}; + +//This event is sent as a new port is bound or a new connection opened. +//It is NOT sent for sigle HTTP(S) requests. +//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo +//lParam=(LPARAM)0 (not used) +#define ME_NETLIB_EVENT_CONNECTED "Netlib/Event/Connected" + +//This event is sent if coneection or listening socket is closed. +//It is NOT sent for sigle HTTP(S) requests. +//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo +//lParam=(LPARAM)0 (not used) +#define ME_NETLIB_EVENT_DISCONNECTED "Netlib/Event/Disconnected" + #endif // M_NETLIB_H__ diff --git a/src/mir_app/src/netlib.cpp b/src/mir_app/src/netlib.cpp index 64f76962bb..02c7c0d7d7 100644 --- a/src/mir_app/src/netlib.cpp +++ b/src/mir_app/src/netlib.cpp @@ -27,12 +27,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static BOOL bModuleInitialized = FALSE; -HANDLE hConnectionHeaderMutex, hConnectionOpenMutex; +HANDLE hConnectionHeaderMutex, hConnectionOpenMutex, hEventConnected = NULL, hEventDisconnected = NULL; DWORD g_LastConnectionTick; int connectionTimeout; HANDLE hSendEvent = nullptr, hRecvEvent = nullptr; -typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); +typedef BOOL(WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); static int CompareNetlibUser(const NetlibUser* p1, const NetlibUser* p2) { @@ -58,7 +58,7 @@ int GetNetlibHandleType(void *p) __try { return *(int*)p; } - __except(EXCEPTION_EXECUTE_HANDLER) + __except (EXCEPTION_EXECUTE_HANDLER) {} return NLH_INVALID; @@ -162,7 +162,7 @@ MIR_APP_DLL(HNETLIBUSER) Netlib_RegisterUser(const NETLIBUSER *nlu) if ((thisUser->user.szSettingsModule = mir_strdup(nlu->szSettingsModule)) == nullptr || (nlu->szDescriptiveName.w && thisUser->user.szDescriptiveName.w == nullptr) - || (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent = mir_strdup(nlu->szHttpGatewayUserAgent)) == nullptr)) + || (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent = mir_strdup(nlu->szHttpGatewayUserAgent)) == nullptr)) { mir_free(thisUser); SetLastError(ERROR_OUTOFMEMORY); @@ -214,6 +214,18 @@ MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *nlu return 1; } +MIR_APP_DLL(int) NetlibGetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *nlus) +{ + mir_cslock lck(csNetlibUser); + for (int i = 0; i < netlibUser.getCount(); i++) + if (!mir_strcmp(netlibUser[i]->user.szSettingsModule, UserSettingsName)) { + int out = Netlib_GetUserSettings(netlibUser[i], nlus); + return out; + } + SetLastError(ERROR_INVALID_PARAMETER); + return 0; +} + MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *nlus) { if (GetNetlibHandleType(nlu) != NLH_USER || nlus == nullptr || nlus->cbSize != sizeof(NETLIBUSERSETTINGS)) { @@ -224,6 +236,18 @@ MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTING return 1; } +MIR_APP_DLL(int) NetlibSetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *nlus) +{ + mir_cslock lck(csNetlibUser); + for (int i = 0; i < netlibUser.getCount(); i++) + if (!mir_strcmp(netlibUser[i]->user.szSettingsModule, UserSettingsName)) { + int out = Netlib_SetUserSettings(netlibUser[i], nlus); + return out; + } + SetLastError(ERROR_INVALID_PARAMETER); + return 0; +} + ///////////////////////////////////////////////////////////////////////////////////////// void NetlibDoCloseSocket(NetlibConnection *nlc, bool noShutdown) @@ -237,6 +261,25 @@ void NetlibDoCloseSocket(NetlibConnection *nlc, bool noShutdown) sslApi.sfree(nlc->hSsl); nlc->hSsl = nullptr; } + + NETLIBCONNECTIONEVENTINFO ncei; + ZeroMemory(&ncei, sizeof(ncei)); + ncei.connected = 0; + ncei.szSettingsModule = nlc->nlu->user.szSettingsModule; + int size = sizeof(SOCKADDR_IN); + getsockname(nlc->s, (SOCKADDR *)&ncei.local, &size); + if (nlc->nlu->settings.useProxy) { + size = sizeof(SOCKADDR_IN); + getpeername(nlc->s, (SOCKADDR *)&ncei.proxy, &size); + + } + else { + size = sizeof(SOCKADDR_IN); + getpeername(nlc->s, (SOCKADDR *)&ncei.remote, &size); + + } + NotifyEventHooks(hEventDisconnected, (WPARAM)&ncei, 0); + closesocket(nlc->s); nlc->s = INVALID_SOCKET; } @@ -248,23 +291,23 @@ MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE hNetlib) switch (GetNetlibHandleType(hNetlib)) { case NLH_USER: + { + NetlibUser *nlu = (NetlibUser*)hNetlib; { - NetlibUser *nlu = (NetlibUser*)hNetlib; - { - mir_cslock lck(csNetlibUser); - int i = netlibUser.getIndex(nlu); - if (i >= 0) - netlibUser.remove(i); - } - - NetlibFreeUserSettingsStruct(&nlu->settings); - mir_free(nlu->user.szSettingsModule); - mir_free(nlu->user.szDescriptiveName.a); - mir_free(nlu->user.szHttpGatewayHello); - mir_free(nlu->user.szHttpGatewayUserAgent); - mir_free(nlu->szStickyHeaders); + mir_cslock lck(csNetlibUser); + int i = netlibUser.getIndex(nlu); + if (i >= 0) + netlibUser.remove(i); } - break; + + NetlibFreeUserSettingsStruct(&nlu->settings); + mir_free(nlu->user.szSettingsModule); + mir_free(nlu->user.szDescriptiveName.a); + mir_free(nlu->user.szHttpGatewayHello); + mir_free(nlu->user.szHttpGatewayUserAgent); + mir_free(nlu->szStickyHeaders); + } + break; case NLH_CONNECTION: WaitForSingleObject(hConnectionHeaderMutex, INFINITE); @@ -301,11 +344,11 @@ MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE hNetlib) return NetlibFreeBoundPort((NetlibBoundPort*)hNetlib); case NLH_PACKETRECVER: - { - struct NetlibPacketRecver *nlpr = (NetlibPacketRecver*)hNetlib; - mir_free(nlpr->packetRecver.buffer); - } - break; + { + struct NetlibPacketRecver *nlpr = (NetlibPacketRecver*)hNetlib; + mir_free(nlpr->packetRecver.buffer); + } + break; default: SetLastError(ERROR_INVALID_PARAMETER); @@ -361,19 +404,19 @@ MIR_APP_DLL(void) Netlib_Shutdown(HNETLIBCONN h) WaitForSingleObject(hConnectionHeaderMutex, INFINITE); switch (GetNetlibHandleType(h)) { case NLH_CONNECTION: - { - NetlibConnection *nlc = h; - if (!nlc->termRequested) { - if (nlc->hSsl) sslApi.shutdown(nlc->hSsl); - if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, SD_BOTH); - if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, SD_BOTH); - nlc->termRequested = true; - } + { + NetlibConnection *nlc = h; + if (!nlc->termRequested) { + if (nlc->hSsl) sslApi.shutdown(nlc->hSsl); + if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, SD_BOTH); + if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, SD_BOTH); + nlc->termRequested = true; } - break; + } + break; case NLH_BOUNDPORT: - NetlibBoundPort *nlb = (NetlibBoundPort*)h; + NetlibBoundPort * nlb = (NetlibBoundPort*)h; if (nlb->s != INVALID_SOCKET) shutdown(nlb->s, SD_BOTH); break; @@ -416,7 +459,7 @@ int LoadNetlibModule(void) connectionTimeout = 0; - OSVERSIONINFOEX osvi = {0}; + OSVERSIONINFOEX osvi = { 0 }; osvi.dwOSVersionInfoSize = sizeof(osvi); if (GetVersionEx((LPOSVERSIONINFO)&osvi)) { // Connection limiting was introduced in Windows XP SP2 and later and set to 10 / sec @@ -425,9 +468,9 @@ int LoadNetlibModule(void) // Connection limiting has limits based on addition Windows Vista pre SP2 else if (osvi.dwMajorVersion == 6 && osvi.wServicePackMajor < 2) { DWORD dwType = 0; - tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(GetModuleHandleA("kernel32"), "GetProductInfo"); + tGetProductInfo pGetProductInfo = (tGetProductInfo)GetProcAddress(GetModuleHandleA("kernel32"), "GetProductInfo"); if (pGetProductInfo != nullptr) 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; @@ -464,6 +507,9 @@ int LoadNetlibModule(void) hRecvEvent = CreateHookableEvent(ME_NETLIB_FASTRECV); hSendEvent = CreateHookableEvent(ME_NETLIB_FASTSEND); + hEventConnected = CreateHookableEvent(ME_NETLIB_EVENT_CONNECTED); + hEventDisconnected = CreateHookableEvent(ME_NETLIB_EVENT_DISCONNECTED); + NetlibUPnPInit(); NetlibLoadIeProxy(); return 0; diff --git a/src/mir_app/src/netlib.h b/src/mir_app/src/netlib.h index e9c20e9042..7457d1bb50 100644 --- a/src/mir_app/src/netlib.h +++ b/src/mir_app/src/netlib.h @@ -146,6 +146,9 @@ void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs); extern mir_cs csNetlibUser; extern LIST netlibUser; +extern HANDLE hEventConnected; +extern HANDLE hEventDisconnected; + // netlibautoproxy.c void NetlibLoadIeProxy(void); void NetlibUnloadIeProxy(void); diff --git a/src/mir_app/src/netlibbind.cpp b/src/mir_app/src/netlibbind.cpp index 2a592dce89..4fef5341a4 100644 --- a/src/mir_app/src/netlibbind.cpp +++ b/src/mir_app/src/netlibbind.cpp @@ -111,6 +111,16 @@ bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn) int NetlibFreeBoundPort(NetlibBoundPort *nlbp) { + NETLIBCONNECTIONEVENTINFO ncei; + + ZeroMemory(&ncei, sizeof(ncei)); + ncei.connected = 0; + ncei.listening = 1; + ncei.szSettingsModule = nlbp->nlu->user.szSettingsModule; + int size = sizeof(SOCKADDR_IN); + getsockname(nlbp->s, (SOCKADDR *)&ncei.local, &size); + NotifyEventHooks(hEventDisconnected, (WPARAM)&ncei, 0); + nlbp->close(); if (nlbp->hThread) WaitForSingleObject(nlbp->hThread, INFINITE); @@ -281,6 +291,15 @@ LBL_Error: } nlbp->hThread = mir_forkThread(NetlibBindAcceptThread, nlbp); + + NETLIBCONNECTIONEVENTINFO ncei; + ZeroMemory(&ncei, sizeof(ncei)); + ncei.connected = 1; + ncei.listening = 1; + ncei.szSettingsModule = nlu->user.szSettingsModule; + memcpy(&ncei.local, &sin, sizeof(sin)); + NotifyEventHooks(hEventConnected, (WPARAM)&ncei, 0); + return nlbp; } diff --git a/src/mir_app/src/netlibopenconn.cpp b/src/mir_app/src/netlibopenconn.cpp index eb5c368ffe..187e3c60f3 100644 --- a/src/mir_app/src/netlibopenconn.cpp +++ b/src/mir_app/src/netlibopenconn.cpp @@ -773,6 +773,25 @@ bool NetlibDoConnect(NetlibConnection *nlc) Netlib_Logf(nlu, "(%d) Connected to %s:%d", nlc->s, nloc->szHost, nloc->wPort); + NETLIBCONNECTIONEVENTINFO ncei; + ZeroMemory(&ncei, sizeof(ncei)); + ncei.connected = 1; + ncei.szSettingsModule = nlu->user.szSettingsModule; + int size = sizeof(SOCKADDR_IN); + getsockname(nlc->s, (SOCKADDR *)&ncei.local, &size); + if (nlu->settings.useProxy) { + size = sizeof(SOCKADDR_IN); + getpeername(nlc->s, (SOCKADDR *)&ncei.proxy, &size); + ncei.remote.sin_family = AF_INET; + ncei.remote.sin_port = htons((short)nloc->wPort); + ncei.remote.sin_addr.S_un.S_addr = DnsLookup(nlu, nloc->szHost); + } + else { + size = sizeof(SOCKADDR_IN); + getpeername(nlc->s, (SOCKADDR *)&ncei.remote, &size); + } + NotifyEventHooks(hEventConnected, (WPARAM)&ncei, 0); + if (NLOCF_SSL & nloc->flags) return Netlib_StartSsl(nlc, nullptr) != 0; -- cgit v1.2.3