summaryrefslogtreecommitdiff
path: root/protocols/MRA/src/MraMRIMProxy.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-10-13 08:54:34 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-10-13 08:54:34 +0000
commitde6eb3e4bc30eff928dc932c03812ede3077926a (patch)
tree966a57948af890b1c47699e5ec0db23a26a7add9 /protocols/MRA/src/MraMRIMProxy.cpp
parent870d3d99c22c77a94a352ad292ed67e8eb81edf0 (diff)
MRA: folders restructurization
git-svn-id: http://svn.miranda-ng.org/main/trunk@1900 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/MRA/src/MraMRIMProxy.cpp')
-rw-r--r--protocols/MRA/src/MraMRIMProxy.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/protocols/MRA/src/MraMRIMProxy.cpp b/protocols/MRA/src/MraMRIMProxy.cpp
new file mode 100644
index 0000000000..01a46ecc49
--- /dev/null
+++ b/protocols/MRA/src/MraMRIMProxy.cpp
@@ -0,0 +1,211 @@
+#include "Mra.h"
+#include "MraMRIMProxy.h"
+#include "proto.h"
+
+struct MRA_MRIMPROXY_DATA
+{
+ LPSTR lpszEMail; // LPS to
+ size_t dwEMailSize;
+ DWORD dwIDRequest; // DWORD id_request
+ DWORD dwDataType; // DWORD data_type
+ LPSTR lpszUserData; // LPS user_data
+ size_t dwUserDataSize;
+ MRA_ADDR_LIST malAddrList; // LPS lps_ip_port
+ MRA_GUID mguidSessionID; // DWORD session_id[4]
+ HANDLE hConnection;
+ HANDLE hWaitHandle; // internal
+};
+
+HANDLE MraMrimProxyCreate()
+{
+ MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)mir_calloc(sizeof(MRA_MRIMPROXY_DATA));
+ return (HANDLE)pmmpd;
+}
+
+DWORD MraMrimProxySetData(HANDLE hMraMrimProxyData, LPSTR lpszEMail, size_t dwEMailSize, DWORD dwIDRequest, DWORD dwDataType, LPSTR lpszUserData, size_t dwUserDataSize, LPSTR lpszAddreses, size_t dwAddresesSize, MRA_GUID *pmguidSessionID)
+{
+ if (!hMraMrimProxyData)
+ return ERROR_INVALID_HANDLE;
+
+ MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)hMraMrimProxyData;
+
+ if (lpszEMail && dwEMailSize) {
+ mir_free(pmmpd->lpszEMail);
+ pmmpd->lpszEMail = (LPSTR)mir_calloc(dwEMailSize);
+ memmove(pmmpd->lpszEMail, lpszEMail, dwEMailSize);
+ pmmpd->dwEMailSize = dwEMailSize;
+ }
+
+ if (dwIDRequest) pmmpd->dwIDRequest = dwIDRequest;
+ if (dwDataType) pmmpd->dwDataType = dwDataType;
+
+ if (lpszUserData) {
+ mir_free(pmmpd->lpszUserData);
+ pmmpd->lpszUserData = (LPSTR)mir_calloc(dwUserDataSize);
+ memmove(pmmpd->lpszUserData, lpszUserData, dwUserDataSize);
+ pmmpd->dwUserDataSize = dwUserDataSize;
+ }
+
+ if (lpszAddreses && dwAddresesSize)
+ MraAddrListGetFromBuff(lpszAddreses, dwAddresesSize, &pmmpd->malAddrList);
+ if (pmguidSessionID)
+ memmove(&pmmpd->mguidSessionID, pmguidSessionID, sizeof(MRA_GUID));
+
+ SetEvent(pmmpd->hWaitHandle);
+ return 0;
+}
+
+void MraMrimProxyFree(HANDLE hMraMrimProxyData)
+{
+ if (hMraMrimProxyData) {
+ MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)hMraMrimProxyData;
+
+ CloseHandle(pmmpd->hWaitHandle);
+ Netlib_CloseHandle(pmmpd->hConnection);
+ mir_free(pmmpd->lpszEMail);
+ mir_free(pmmpd->lpszUserData);
+ MraAddrListFree(&pmmpd->malAddrList);
+ mir_free(hMraMrimProxyData);
+ }
+}
+
+void MraMrimProxyCloseConnection(HANDLE hMraMrimProxyData)
+{
+ if (hMraMrimProxyData) {
+ MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)hMraMrimProxyData;
+ SetEvent(pmmpd->hWaitHandle);
+ Netlib_CloseHandle(pmmpd->hConnection);
+ }
+}
+
+DWORD CMraProto::MraMrimProxyConnect(HANDLE hMraMrimProxyData, HANDLE *phConnection)
+{
+ DWORD dwRetErrorCode;
+
+ if (hMraMrimProxyData && phConnection) {
+ BOOL bIsHTTPSProxyUsed, bContinue;
+ BYTE lpbBufferRcv[BUFF_SIZE_RCV_MIN_FREE];
+ DWORD dwBytesReceived, dwConnectReTryCount, dwCurConnectReTryCount;
+ size_t dwRcvBuffSize = BUFF_SIZE_RCV_MIN_FREE, dwRcvBuffSizeUsed;
+ NETLIBSELECT nls = {0};
+ MRA_MRIMPROXY_DATA *pmmpd = (MRA_MRIMPROXY_DATA*)hMraMrimProxyData;
+ NETLIBOPENCONNECTION nloc = {0};
+
+ // адреса есть, значит инициаторы не мы
+ if (pmmpd->malAddrList.dwAddrCount) {
+ MraAddrListGetToBuff(&pmmpd->malAddrList, (LPSTR)lpbBufferRcv, SIZEOF(lpbBufferRcv), &dwRcvBuffSizeUsed);
+ MraProxyAck(PROXY_STATUS_OK, pmmpd->lpszEMail, pmmpd->dwEMailSize, pmmpd->dwIDRequest, pmmpd->dwDataType, pmmpd->lpszUserData, pmmpd->dwUserDataSize, (LPSTR)lpbBufferRcv, dwRcvBuffSizeUsed, pmmpd->mguidSessionID);
+ }
+ // мы инициаторы
+ else {
+ pmmpd->hWaitHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (pmmpd->lpszEMail && pmmpd->dwEMailSize)
+ if (MraProxy(pmmpd->lpszEMail, pmmpd->dwEMailSize, pmmpd->dwIDRequest, pmmpd->dwDataType, pmmpd->lpszUserData, pmmpd->dwUserDataSize, NULL, 0, pmmpd->mguidSessionID))
+ WaitForSingleObjectEx(pmmpd->hWaitHandle, INFINITE, FALSE);
+
+ CloseHandle(pmmpd->hWaitHandle);
+ pmmpd->hWaitHandle = NULL;
+ }
+
+ dwRetErrorCode = ERROR_NO_NETWORK;
+ if (pmmpd->malAddrList.dwAddrCount) {
+ pmmpd->hConnection = NULL;
+ bIsHTTPSProxyUsed = IsHTTPSProxyUsed(hNetlibUser);
+ dwConnectReTryCount = mraGetDword(NULL, "ConnectReTryCountMRIMProxy", MRA_DEFAULT_CONN_RETRY_COUNT_MRIMPROXY);
+ nloc.cbSize = sizeof(nloc);
+ nloc.flags = NLOCF_V2;
+ nloc.timeout = ((MRA_TIMEOUT_DIRECT_CONN-1)/(pmmpd->malAddrList.dwAddrCount*dwConnectReTryCount));// -1 сек чтобы был запас
+ if (nloc.timeout<MRA_TIMEOUT_CONN_MIN) nloc.timeout = MRA_TIMEOUT_CONN_MIN;
+ if (nloc.timeout>MRA_TIMEOUT_CONN_МАХ) nloc.timeout = MRA_TIMEOUT_CONN_МАХ;
+
+ // Set up the sockaddr structure
+ for (size_t i = 0; i < pmmpd->malAddrList.dwAddrCount && dwRetErrorCode != NO_ERROR; i++) {
+ // через https прокси только 443 порт
+ if ((pmmpd->malAddrList.pmaliAddress[i].dwPort == MRA_SERVER_PORT_HTTPS && bIsHTTPSProxyUsed) || bIsHTTPSProxyUsed == FALSE) {
+ if (pmmpd->dwDataType == MRIM_PROXY_TYPE_FILES)
+ ProtoBroadcastAck(m_szModuleName, MraHContactFromEmail(pmmpd->lpszEMail, pmmpd->dwEMailSize, FALSE, TRUE, NULL), ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)pmmpd->dwIDRequest, 0);
+
+ nloc.szHost = inet_ntoa((*((in_addr*)&pmmpd->malAddrList.pmaliAddress[i].dwAddr)));
+ nloc.wPort = (WORD)pmmpd->malAddrList.pmaliAddress[i].dwPort;
+
+ dwCurConnectReTryCount = dwConnectReTryCount;
+ do {
+ pmmpd->hConnection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&nloc);
+ }
+ while (--dwCurConnectReTryCount && pmmpd->hConnection == NULL);
+
+ if (pmmpd->hConnection) {
+ nls.cbSize = sizeof(nls);
+ nls.dwTimeout = (MRA_TIMEOUT_DIRECT_CONN*1000*2);
+ nls.hReadConns[0] = pmmpd->hConnection;
+ bContinue = TRUE;
+ dwRcvBuffSizeUsed = 0;
+
+ if (pmmpd->dwDataType == MRIM_PROXY_TYPE_FILES)
+ ProtoBroadcastAck(m_szModuleName, MraHContactFromEmail(pmmpd->lpszEMail, pmmpd->dwEMailSize, FALSE, TRUE, NULL), ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)pmmpd->dwIDRequest, 0);
+ MraSendPacket(nls.hReadConns[0], 0, MRIM_CS_PROXY_HELLO, &pmmpd->mguidSessionID, sizeof(MRA_GUID));
+
+ while (bContinue) {
+ switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM)&nls)) {
+ case SOCKET_ERROR:
+ case 0:// Time out
+ dwRetErrorCode = GetLastError();
+ ShowFormattedErrorMessage(L"Disconnected, socket error", dwRetErrorCode);
+ bContinue = FALSE;
+ break;
+
+ case 1:
+ if (dwRcvBuffSizeUsed == BUFF_SIZE_RCV_MIN_FREE) { // bad packet
+ bContinue = FALSE;
+ DebugBreak();
+ }
+ else {
+ dwBytesReceived = Netlib_Recv(nls.hReadConns[0], (LPSTR)(lpbBufferRcv+dwRcvBuffSizeUsed), (dwRcvBuffSize-dwRcvBuffSizeUsed), 0);
+ if (dwBytesReceived && dwBytesReceived != SOCKET_ERROR) { // connected
+ dwRcvBuffSizeUsed += dwBytesReceived;
+ if (dwRcvBuffSizeUsed >= sizeof(mrim_packet_header_t)) { // packet header received
+ if (((mrim_packet_header_t*)lpbBufferRcv)->magic == CS_MAGIC) { // packet OK
+ if ((dwRcvBuffSizeUsed-sizeof(mrim_packet_header_t)) >= ((mrim_packet_header_t*)lpbBufferRcv)->dlen) { // full packet received, may be more than one
+ if (((mrim_packet_header_t*)lpbBufferRcv)->msg == MRIM_CS_PROXY_HELLO_ACK) // connect OK!
+ dwRetErrorCode = NO_ERROR;
+ else // bad/wrong
+ DebugBreak();
+
+ bContinue = FALSE;
+ }
+ else // not all packet received, continue receiving
+ DebugPrintCRLF(L"Not all packet received, continue receiving");
+ }
+ else { // bad packet
+ DebugPrintCRLF(L"Bad packet");
+ DebugBreak();
+ bContinue = FALSE;
+ }
+ }
+ else // packet too small, continue receiving
+ DebugPrintCRLF(L"Packet to small, continue receiving");
+ }
+ else { // disconnected
+ dwRetErrorCode = GetLastError();
+ ShowFormattedErrorMessage(L"Disconnected, socket read error", dwRetErrorCode);
+ bContinue = FALSE;
+ }
+ }
+ break;
+ }// end switch
+ }// end while
+ }
+ else dwRetErrorCode = GetLastError();
+ }// filtered
+ }// end for
+
+ if (dwRetErrorCode != NO_ERROR) { // кажется не туда подключились :)
+ Netlib_CloseHandle(pmmpd->hConnection);
+ pmmpd->hConnection = NULL;
+ }
+ }
+ *phConnection = pmmpd->hConnection;
+ }
+ else dwRetErrorCode = ERROR_INVALID_HANDLE;
+ return dwRetErrorCode;
+}