Exemple #1
0
void CHTTPPostSocket::ParseOutput()
{
	tstring sReturn = RecvAll();
	bool bHTTPOver = false;
	tvector<tstring> vTokens;

	strtok(sReturn, vTokens, "\n");
	for (unsigned int i = 1; i < vTokens.size(); i++)
	{
		tstring sToken = vTokens[i];
		if (!trim(sToken).length())
		{
			bHTTPOver = true;
			continue;
		}

		if (!bHTTPOver)
			continue;

		tstring::size_type iColon = sToken.find(":");
		KeyValue(sToken.substr(0, iColon).c_str(), sToken.substr(iColon+2).c_str());
	}
}
// Listener thread
void ElListenerProc(THREAD *thread, void *param)
{
	TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param;
	EL *e;
	SOCK *s;
	UCHAR rand[SHA1_SIZE];
	UCHAR pass1[SHA1_SIZE], pass2[SHA1_SIZE];
	// Validate arguments
	if (data == NULL || thread == NULL)
	{
		return;
	}

	e = (EL *)data->r->ThreadParam;
	s = data->s;
	AddRef(s->ref);
	SetTimeout(s, 5000);
	LockList(e->AdminThreadList);
	{
		AddRef(thread->ref);
		AddRef(s->ref);
		Insert(e->AdminThreadList, thread);
		Insert(e->AdminSockList, s);
	}
	UnlockList(e->AdminThreadList);
	NoticeThreadInit(thread);

	// Submit a challenge
	Rand(rand, sizeof(rand));
	SendAll(s, rand, sizeof(rand), false);

	// Receive a response
	SecurePassword(pass1, e->HashedPassword, rand);
	Zero(pass2, sizeof(pass2));
	RecvAll(s, pass2, sizeof(pass2), false);

	if (Cmp(pass1, pass2, SHA1_SIZE) != 0)
	{
		// Password incorrect
		bool code = false;
		code = Endian32(code);
		SendAll(s, &code, sizeof(code), false);
	}
	else
	{
		// Password match
		bool code = true;
		RPC *r;

		code = Endian32(code);
		SendAll(s, &code, sizeof(code), false);

		SetTimeout(s, INFINITE);

		// Start operation as a RPC server
		r = StartRpcServer(s, ElRpcServer, e);
		RpcServer(r);
		RpcFree(r);
	}

	Disconnect(s);
	ReleaseSock(s);

	LockList(e->AdminThreadList);
	{
		if (Delete(e->AdminThreadList, thread))
		{
			ReleaseThread(thread);
		}
		if (Delete(e->AdminSockList, s))
		{
			ReleaseSock(s);
		}
	}
	UnlockList(e->AdminThreadList);
}
// RPC client connect
UINT EcConnect(char *host, UINT port, char *password, RPC **rpc)
{
	SOCK *s;
	UCHAR password_hash[SHA1_SIZE];
	UCHAR rand[SHA1_SIZE];
	UCHAR response[SHA1_SIZE];
	bool retcode;
	// Validate arguments
	if (host == NULL)
	{
		host = "localhost";
	}
	if (port == 0)
	{
		port = EL_ADMIN_PORT;
	}
	if (password == NULL)
	{
		password = "";
	}
	if (rpc == NULL)
	{
		return ERR_INTERNAL_ERROR;
	}

	// Connect to the server
	s = Connect(host, port);
	if (s == NULL)
	{
		// Connection failure
		return ERR_CONNECT_FAILED;
	}

	SetTimeout(s, 5000);

	// Hash the password
	Hash(password_hash, password, StrLen(password), true);

	// Receive the random number
	Zero(rand, sizeof(rand));
	RecvAll(s, rand, sizeof(rand), false);
	SecurePassword(response, password_hash, rand);

	// Send a response
	SendAll(s, response, sizeof(response), false);

	// Receive results
	retcode = false;
	if (RecvAll(s, &retcode, sizeof(retcode), false) == false)
	{
		// Disconnect
		ReleaseSock(s);
		return ERR_PROTOCOL_ERROR;
	}
	retcode = Endian32(retcode);

	if (retcode == false)
	{
		// Password incorrect
		ReleaseSock(s);
		return ERR_AUTH_FAILED;
	}

	// Successful connection
	SetTimeout(s, INFINITE);

	*rpc = StartRpcClient(s, NULL);

	ReleaseSock(s);

	return ERR_NO_ERROR;
}
Exemple #4
0
CString CMt5Client::RequestCodeThread(LPVOID pParam)
{
	//CRemoteDataTcpMt5 * pMt5 = (CRemoteDataTcpMt5 *)pParam;
	struct aa{ CString port; CString ip; } mtBroker;
	mtBroker.port = CString("5050");
	mtBroker.ip = CString("192.168.0.212");
	//mid 以下为TcpClient变量(本程序客户端,用于连接Mt5TcpServer)
	BOOL	bIsConnected = TRUE;
	BOOL	bReturn = FALSE;
	int		iTimesAlreadyConnected = 0;	//mid 已连接次数
	const	int	iTimesToConnect = 1;	//mid 尝试连接次数,超过次数之后,不在连接,并标注连接失败

	SOCKET			socketRequest;
	sockaddr_in		socketClientAddr;		//mid 远端Mt5TcpServerSocket地址

	//mid 1)设置将要连接的服务器地址
	//mid 獲取Port
	int iPort = _ttol(mtBroker.port);
	//mid 獲取Ip
	char szIp[30];
	memset(szIp, 0, sizeof(szIp));
	wcstombs(szIp, mtBroker.ip, mtBroker.ip.GetLength() * 2);
	//unsigned long lIp = ntohl(inet_addr(szIp));



	socketClientAddr.sin_addr.s_addr = inet_addr(szIp);
	socketClientAddr.sin_family = AF_INET;
	socketClientAddr.sin_port = htons(iPort); //5000;		
	//mid 2)创建socket
	socketRequest = socket(AF_INET, SOCK_STREAM, 0);

	/*mid
	此两方法成对出现,一个使有效,一个使无效
	CreateSocketClient("192.168.1.212", 5000);
	closesocket(m_SocketClient);
	*/
	while (connect(socketRequest, (sockaddr*)&(socketClientAddr), sizeof(socketClientAddr)))
	{//连接到服务器
		DWORD dwErr;
		dwErr = GetLastError();
		if (10056 == dwErr)
		{	//mid 在一个已连接的套接字上面进行连接,说明在Connect()函数中已有connect()成功
			bIsConnected = TRUE;
			break;
		}

		if (iTimesAlreadyConnected>iTimesToConnect)
		{	//mid 尝试连接
			bIsConnected = FALSE;
			AfxMessageBox(TEXT("Connect() Connect Error."));
			break;
		}
		iTimesAlreadyConnected++;
	}
	if (bIsConnected)
	{
		TRACE("\n连接成功\n");
		REQ_HEADER reqHeader;
		reqHeader.ReqType = ReqTypeCode;
		if (send(socketRequest, (char*)&reqHeader, sizeof(REQ_HEADER), 0) == sizeof(REQ_HEADER))
		{
			TRACE("\n请求类型数据头发送成功\n");
			RSP_CODE_HEADER rspCodeHeader;
			memset(&rspCodeHeader, 0, sizeof(RSP_CODE_HEADER));
			if (recv(socketRequest, (char*)&rspCodeHeader, sizeof(RSP_CODE_HEADER), 0) == sizeof(RSP_CODE_HEADER))
			{
				TRACE("\n历史数据数据头接收成功\n");
				CString 	strRspBroker = Utf_8ToUnicode(rspCodeHeader.m_szBroker);
				CString		strRspAccount = Utf_8ToUnicode(rspCodeHeader.m_szAccount);
				int			nRspCount = rspCodeHeader.m_nCount;
				//if (strRspBroker.CompareNoCase(pMt5->GetBrokerName() ) ==0 && strRspAccount.CompareNoCase(pMt5->GetAccountName()) == 0)
				if (TRUE)
				{
					RSP_CODE *pHistoryArray = new RSP_CODE[nRspCount];		//mid 据answer描述的数据大小定义数组大小,需要手动删除掉
					int const nTotalBytesToReceive = nRspCount*sizeof(RSP_CODE);		//mid 待接收数据总量,
					memset(pHistoryArray, 0, nTotalBytesToReceive);

					if (RecvAll(socketRequest, pHistoryArray, nTotalBytesToReceive))
					{
						TRACE("\nCodes数据接收成功\n");
						CString codes;
						for (int i = 0; i < nRspCount; i++)
						{
							CString str;
							str.Format(CString("%s,%s,%d\r\n"), Utf_8ToUnicode(pHistoryArray[i].m_szCode), Utf_8ToUnicode(pHistoryArray[i].m_szName), pHistoryArray[i].m_iDigits);
							codes = codes + str;
							TRACE(str);
						}
						delete[] pHistoryArray;
						return codes;
					}
					else
					{
						TRACE("\n历史数据接收失败\n");
					}
					//mid 无条件释放数据接收缓存
					delete[] pHistoryArray;
				}
				else
				{
					AfxMessageBox(TEXT("Responded Error History Data KType."));
				}
			}
			else
			{
				DWORD dwErr;
				dwErr = GetLastError();
				TRACE(TEXT("\n历史数据数据头接收失败\n"));
			}
		}
		else
		{
			DWORD dwErr;
			dwErr = GetLastError();
			TRACE("\n请求类型数据头发送失败\n");
		}
	}
	else
	{
		DWORD dwErr;
		dwErr = GetLastError();
		CString str;
		str.Format(TEXT("\n连接失败,ErrorNo:%d\n"), dwErr);
		TRACE(str);
	}
	closesocket(socketRequest);
	AfxEndThread(0);
	return 0;
}
Exemple #5
0
CString CMt5Client::RequestKDataThread(LPVOID pParam)
{
	struct aa
	{
		CString port;
		CString ip;
		CString symbol;
		EnumReqHistoryDataType ktype;
	} mtBroker;
	mtBroker.port = CString("5050");
	mtBroker.ip = CString("192.168.0.212");
	mtBroker.symbol = CString("XAUUSD");
	mtBroker.ktype = HistoryPeriodD1;

	//mid 以下为TcpClient变量(本程序客户端,用于连接Mt5TcpServer)
	BOOL	bIsConnected = TRUE;
	BOOL	bReturn = FALSE;
	int		iTimesAlreadyConnected = 0;	//mid 已连接次数
	const	int	iTimesToConnect = 1;	//mid 尝试连接次数,超过次数之后,不在连接,并标注连接失败

	SOCKET			socketRequest;
	sockaddr_in		socketClientAddr;		//mid 远端Mt5TcpServerSocket地址

	//mid 1)设置将要连接的服务器地址
	//mid 獲取Port
	int iPort = _ttol(mtBroker.port);
	//mid 獲取Ip
	char szIp[30];
	memset(szIp, 0, sizeof(szIp));
	wcstombs(szIp, mtBroker.ip, mtBroker.ip.GetLength() * 2);
	//unsigned long lIp = ntohl(inet_addr(szIp));



	socketClientAddr.sin_addr.s_addr = inet_addr(szIp);
	socketClientAddr.sin_family = AF_INET;
	socketClientAddr.sin_port = htons(iPort); //5000;		
	//mid 2)创建socket
	socketRequest = socket(AF_INET, SOCK_STREAM, 0);

	/*mid
	此两方法成对出现,一个使有效,一个使无效
	CreateSocketClient("192.168.1.212", 5000);
	closesocket(m_SocketClient);
	*/
	while (connect(socketRequest, (sockaddr*)&(socketClientAddr), sizeof(socketClientAddr)))
	{//连接到服务器
		DWORD dwErr;
		dwErr = GetLastError();
		if (10056 == dwErr)
		{	//mid 在一个已连接的套接字上面进行连接,说明在Connect()函数中已有connect()成功
			bIsConnected = TRUE;
			break;
		}

		if (iTimesAlreadyConnected>iTimesToConnect)
		{	//mid 尝试连接
			bIsConnected = FALSE;
			AfxMessageBox(TEXT("Connect() Connect Error."));
			break;
		}
		iTimesAlreadyConnected++;
	}
	if (bIsConnected)
	{
		TRACE("\n连接成功\n");
		REQ_HEADER reqHeader;
		reqHeader.ReqType = ReqTypeHistory;
		if (send(socketRequest, (char*)&reqHeader, sizeof(REQ_HEADER), 0) == sizeof(REQ_HEADER))
		{
			TRACE("\n请求类型数据头发送成功\n");
			REQ_HISTORY reqHistory;
			memset(&reqHistory, 0, sizeof(REQ_HISTORY));
			//mid 1)将UNICODE字串转化为utf8
			char * szSymbol = UnicodeToUTF_8First(mtBroker.symbol);
			strncpy(reqHistory.symbol, szSymbol, min(sizeof(reqHistory.symbol) / 2/*mid 只能假設每個字符佔用2個字節,防止溢出*/, mtBroker.symbol.GetLength()));
			//mid 2)释放转换结果
			delete[] szSymbol;
			//strncpy(reqHistory.symbol, "XAUUSD", min(sizeof(reqHistory.symbol) / 2/*mid 只能假設每個字符佔用2個字節,防止溢出*/, mtBroker.symbol.GetLength()));
			reqHistory.type = mtBroker.ktype;
			int iSizeOfReqHistory = sizeof(REQ_HISTORY);
			if (send(socketRequest, (char*)&reqHistory, sizeof(REQ_HISTORY), 0) == sizeof(REQ_HISTORY))
			{
				TRACE("\n历史数据请求发送成功\n");
				RSP_HISTORY_HEADER rspHistoryHeader;
				memset(&rspHistoryHeader, 0, sizeof(RSP_HISTORY_HEADER));
				if (recv(socketRequest, (char*)&rspHistoryHeader, sizeof(RSP_HISTORY_HEADER), 0) == sizeof(RSP_HISTORY_HEADER))
				{
					TRACE("\n历史数据数据头接收成功\n");
					EnumReqHistoryDataType	rspKType = rspHistoryHeader.m_type;
					CString					strRspSymbol = Utf_8ToUnicode(rspHistoryHeader.m_szSymbol);
					int						nRspCount = rspHistoryHeader.m_nCount;
					if (rspKType == mtBroker.ktype && mtBroker.symbol.CompareNoCase(strRspSymbol) == 0)
					{
						RSP_HISTORY *pHistoryArray = new RSP_HISTORY[nRspCount];		//mid 据answer描述的数据大小定义数组大小,需要手动删除掉
						int const nTotalBytesToReceive = nRspCount*sizeof(RSP_HISTORY);		//mid 待接收数据总量,
						memset(pHistoryArray, 0, nTotalBytesToReceive);

						if (RecvAll(socketRequest, pHistoryArray, nTotalBytesToReceive))
						{
							TRACE("\n历史数据接收成功\n");
							CString KData;
							for (int i = 0; i < nRspCount; i++)											//mid 按 [0,9] 共10个数循环	获得MT 发来数据。
							{																							//mid 装载	下标:[1,10],剩余下标[11],有何深意??,无用,已去除。
								//mid 1)获得code
								//strncpy(pKData[i].m_szCode, strRspSymbol, min(sizeof(pKData[i].m_szCode), strRspSymbol.GetLength()));
								//mid 2)获得时间
								MqlDateTime MqlTime = pHistoryArray[i].m_time;
								CTime timeReceived(MqlTime.year, MqlTime.mon, MqlTime.day, MqlTime.hour, MqlTime.min, MqlTime.sec);
								CString timeStr = timeReceived.Format("\n%Y年%m月%d日%H时%M分%S秒\n");
								//TRACE(timeStr);
								//pKDATA[i].m_qwTime = ToStockTime(&timeReceived);
								//mid 3)获得数值数据
								int m_dOpen = pHistoryArray[i].m_fOpen;	//mid 开始 OHLCVA数据,原先是要*0.001,是因数据在网上发送时使用整数(*1000),在此还原
								int m_dHigh = pHistoryArray[i].m_fHigh;	//mid MT数据暂时没有如此处理,所以不用转换。
								int m_dLow = pHistoryArray[i].m_fLow;
								int m_dClose = pHistoryArray[i].m_fClose;
								int m_llVolume = pHistoryArray[i].m_fVolume;
								int m_dAmount = pHistoryArray[i].m_fAmount;



								CString str;
								str.Format(CString("%s,%d,%d,%d,%d,%d,%d\r\n"), timeStr, m_dOpen, m_dHigh, m_dLow, m_dClose, m_llVolume, m_dAmount);
								KData = KData + str;


							}
							delete[] pHistoryArray;

							return KData;
							//---02
							//mid 以上数据准备完毕,以下准备发送
							//UINT nMsgType = CStock::dataK;//mid 發送的數據的類型
							//::SendMessage(pMt5->m_hExchangerWnd, pMt5->m_uiNewDataMsg, nMsgType, (LPARAM)(pKData));
						}
						else
						{
							TRACE("\n历史数据接收失败\n");
						}
						//mid 无条件释放数据接收缓存
						delete[] pHistoryArray;
					}
					else
					{
						AfxMessageBox(TEXT("Responded Error History Data KType."));
					}
				}
				else
				{
					DWORD dwErr;
					dwErr = GetLastError();
					TRACE(TEXT("\n历史数据数据头接收失败\n"));
				}
			}
			else
			{
				DWORD dwErr;
				dwErr = GetLastError();
				TRACE(TEXT("\n历史数据请求发送失败\n"));
			}
		}
		else
		{
			DWORD dwErr;
			dwErr = GetLastError();
			TRACE("\n请求类型数据头发送失败\n");
		}
	}
	else
	{
		DWORD dwErr;
		dwErr = GetLastError();
		CString str;
		str.Format(TEXT("\n连接失败,ErrorNo:%d\n"), dwErr);
		TRACE(str);
	}
	closesocket(socketRequest);
	AfxEndThread(0);
	return 0;
}
// VPN Azure client main thread
void AcMainThread(THREAD *thread, void *param)
{
	AZURE_CLIENT *ac = (AZURE_CLIENT *)param;
	UINT last_ip_revision = INFINITE;
	UINT64 last_reconnect_tick = 0;
	UINT64 next_reconnect_interval = AZURE_CONNECT_INITIAL_RETRY_INTERVAL;
	UINT num_reconnect_retry = 0;
	UINT64 next_ddns_retry_tick = 0;
	bool last_connect_ok = false;
	// Validate arguments
	if (ac == NULL || thread == NULL)
	{
		return;
	}

	while (ac->Halt == false)
	{
		UINT64 now = Tick64();
		bool connect_was_ok = false;
		// Wait for enabling VPN Azure function
		if (ac->IsEnabled)
		{
			// VPN Azure is enabled
			DDNS_CLIENT_STATUS st;
			bool connect_now = false;
			bool azure_ip_changed = false;

			Lock(ac->Lock);
			{
				Copy(&st, &ac->DDnsStatus, sizeof(DDNS_CLIENT_STATUS));

				if (StrCmpi(st.CurrentAzureIp, ac->DDnsStatusCopy.CurrentAzureIp) != 0)
				{
					if (IsEmptyStr(st.CurrentAzureIp) == false)
					{
						// Destination IP address is changed
						connect_now = true;
						num_reconnect_retry = 0;
					}
				}

				if (StrCmpi(st.CurrentHostName, ac->DDnsStatusCopy.CurrentHostName) != 0)
				{
					// DDNS host name is changed
					connect_now = true;
					num_reconnect_retry = 0;
				}

				Copy(&ac->DDnsStatusCopy, &st, sizeof(DDNS_CLIENT_STATUS));
			}
			Unlock(ac->Lock);

			if (last_ip_revision != ac->IpStatusRevision)
			{
				last_ip_revision = ac->IpStatusRevision;

				connect_now = true;

				num_reconnect_retry = 0;
			}

			if (last_reconnect_tick == 0 || (now >= (last_reconnect_tick + next_reconnect_interval)))
			{
				UINT r;

				last_reconnect_tick = now;
				num_reconnect_retry++;
				next_reconnect_interval = (UINT64)num_reconnect_retry * AZURE_CONNECT_INITIAL_RETRY_INTERVAL;
				next_reconnect_interval = MIN(next_reconnect_interval, AZURE_CONNECT_MAX_RETRY_INTERVAL);

				r = (UINT)next_reconnect_interval;

				r = GenRandInterval(r / 2, r);

				next_reconnect_interval = r;

				connect_now = true;
			}

			if (IsEmptyStr(st.CurrentAzureIp) == false && IsEmptyStr(st.CurrentHostName) == false)
			{
				if (connect_now)
				{
					SOCK *s;
					char *host = NULL;
					UINT port = AZURE_SERVER_PORT;

					Debug("VPN Azure: Connecting to %s...\n", st.CurrentAzureIp);

					if (ParseHostPort(st.CurrentAzureIp, &host, &port, AZURE_SERVER_PORT))
					{
						if (st.InternetSetting.ProxyType == PROXY_DIRECT)
						{
							s = ConnectEx2(host, port, 0, (bool *)&ac->Halt);
						}
						else
						{
							s = WpcSockConnect2(host, port, &st.InternetSetting, NULL, AZURE_VIA_PROXY_TIMEOUT);
						}

						if (s != NULL)
						{
							PACK *p;
							UINT64 established_tick = 0;

							Debug("VPN Azure: Connected.\n");

							SetTimeout(s, AZURE_PROTOCOL_CONTROL_TIMEOUT_DEFAULT);

							Lock(ac->Lock);
							{
								ac->CurrentSock = s;
								ac->IsConnected = true;
								StrCpy(ac->ConnectingAzureIp, sizeof(ac->ConnectingAzureIp), st.CurrentAzureIp);
							}
							Unlock(ac->Lock);

							SendAll(s, AZURE_PROTOCOL_CONTROL_SIGNATURE, StrLen(AZURE_PROTOCOL_CONTROL_SIGNATURE), false);

							// Receive parameter
							p = RecvPackWithHash(s);
							if (p != NULL)
							{
								UCHAR c;
								AZURE_PARAM param;
								bool hostname_changed = false;

								Zero(&param, sizeof(param));

								param.ControlKeepAlive = PackGetInt(p, "ControlKeepAlive");
								param.ControlTimeout = PackGetInt(p, "ControlTimeout");
								param.DataTimeout = PackGetInt(p, "DataTimeout");
								param.SslTimeout = PackGetInt(p, "SslTimeout");

								FreePack(p);

								param.ControlKeepAlive = MAKESURE(param.ControlKeepAlive, 1000, AZURE_SERVER_MAX_KEEPALIVE);
								param.ControlTimeout = MAKESURE(param.ControlTimeout, 1000, AZURE_SERVER_MAX_TIMEOUT);
								param.DataTimeout = MAKESURE(param.DataTimeout, 1000, AZURE_SERVER_MAX_TIMEOUT);
								param.SslTimeout = MAKESURE(param.SslTimeout, 1000, AZURE_SERVER_MAX_TIMEOUT);

								Lock(ac->Lock);
								{
									Copy(&ac->AzureParam, &param, sizeof(AZURE_PARAM));
								}
								Unlock(ac->Lock);

								SetTimeout(s, param.ControlTimeout);

								// Send parameter
								p = NewPack();
								PackAddStr(p, "CurrentHostName", st.CurrentHostName);
								PackAddStr(p, "CurrentAzureIp", st.CurrentAzureIp);
								PackAddInt64(p, "CurrentAzureTimestamp", st.CurrentAzureTimestamp);
								PackAddStr(p, "CurrentAzureSignature", st.CurrentAzureSignature);

								Lock(ac->Lock);
								{
									if (StrCmpi(st.CurrentHostName, ac->DDnsStatus.CurrentHostName) != 0)
									{
										hostname_changed = true;
									}
								}
								Unlock(ac->Lock);

								if (hostname_changed == false)
								{
									if (SendPackWithHash(s, p))
									{
										// Receive result
										if (RecvAll(s, &c, 1, false))
										{
											if (c && ac->Halt == false)
											{
												connect_was_ok = true;

												established_tick = Tick64();

												AcWaitForRequest(ac, s, &param);
											}
										}
									}
								}

								FreePack(p);
							}
							else
							{
								WHERE;
							}

							Debug("VPN Azure: Disconnected.\n");

							Lock(ac->Lock);
							{
								ac->IsConnected = false;
								ac->CurrentSock = NULL;
								ClearStr(ac->ConnectingAzureIp, sizeof(ac->ConnectingAzureIp));
							}
							Unlock(ac->Lock);

							if (established_tick != 0)
							{
								if ((established_tick + (UINT64)AZURE_CONNECT_MAX_RETRY_INTERVAL) <= Tick64())
								{
									// If the connected time exceeds the AZURE_CONNECT_MAX_RETRY_INTERVAL, reset the retry counter.
									last_reconnect_tick = 0;
									num_reconnect_retry = 0;
									next_reconnect_interval = AZURE_CONNECT_INITIAL_RETRY_INTERVAL;
								}
							}

							Disconnect(s);
							ReleaseSock(s);
						}
						else
						{
							Debug("VPN Azure: Error: Connect Failed.\n");
						}

						Free(host);
					}
				}
			}
		}
		else
		{
			last_reconnect_tick = 0;
			num_reconnect_retry = 0;
			next_reconnect_interval = AZURE_CONNECT_INITIAL_RETRY_INTERVAL;
		}

		if (ac->Halt)
		{
			break;
		}

		if (connect_was_ok)
		{
			// If connection goes out after connected, increment connection success count to urge DDNS client query
			next_ddns_retry_tick = Tick64() + MIN((UINT64)DDNS_VPN_AZURE_CONNECT_ERROR_DDNS_RETRY_TIME_DIFF * (UINT64)(num_reconnect_retry + 1), (UINT64)DDNS_VPN_AZURE_CONNECT_ERROR_DDNS_RETRY_TIME_DIFF_MAX);
		}

		if ((next_ddns_retry_tick != 0) && (Tick64() >= next_ddns_retry_tick))
		{
			next_ddns_retry_tick = 0;

			ac->DDnsTriggerInt++;
		}

		Wait(ac->Event, rand() % 1000);
	}
}
// Wait for connection request
void AcWaitForRequest(AZURE_CLIENT *ac, SOCK *s, AZURE_PARAM *param)
{
	// Validate arguments
	if (ac == NULL || s == NULL || param == NULL)
	{
		return;
	}

	while (ac->Halt == false)
	{
		UCHAR uc;

		// Receive 1 byte
		if (RecvAll(s, &uc, 1, false) == 0)
		{
			break;
		}

		if (uc != 0)
		{
			// Receive a Pack
			PACK *p = RecvPackWithHash(s);

			if (p == NULL)
			{
				break;
			}
			else
			{
				// Verify contents of Pack
				char opcode[MAX_SIZE];
				char cipher_name[MAX_SIZE];
				char hostname[MAX_SIZE];

				PackGetStr(p, "opcode", opcode, sizeof(opcode));
				PackGetStr(p, "cipher_name", cipher_name, sizeof(cipher_name));
				PackGetStr(p, "hostname", hostname, sizeof(hostname));

				if (StrCmpi(opcode, "relay") == 0)
				{
					IP client_ip, server_ip;
					UINT client_port;
					UINT server_port;
					UCHAR session_id[SHA1_SIZE];

					if (PackGetIp(p, "client_ip", &client_ip) &&
						PackGetIp(p, "server_ip", &server_ip) &&
						PackGetData2(p, "session_id", session_id, sizeof(session_id)))
					{
						client_port = PackGetInt(p, "client_port");
						server_port = PackGetInt(p, "server_port");

						if (client_port != 0 && server_port != 0)
						{
							SOCK *ns;
							Debug("Connect Request from %r:%u\n", &client_ip, client_port);

							// Create new socket and connect VPN Azure Server
							if (ac->DDnsStatusCopy.InternetSetting.ProxyType == PROXY_DIRECT)
							{
								ns = ConnectEx2(ac->DDnsStatusCopy.CurrentAzureIp, AZURE_SERVER_PORT,
									0, (bool *)&ac->Halt);
							}
							else
							{
								ns = WpcSockConnect2(ac->DDnsStatusCopy.CurrentAzureIp, AZURE_SERVER_PORT,
									&ac->DDnsStatusCopy.InternetSetting, NULL, AZURE_VIA_PROXY_TIMEOUT);
							}

							if (ns == NULL)
							{
								Debug("Connect Error.\n");
							}
							else
							{
								Debug("Connected to the relay server.\n");

								SetTimeout(ns, param->DataTimeout);

								if (StartSSLEx(ns, NULL, NULL, true, 0, NULL))
								{
									// Check certification
									char server_cert_hash_str[MAX_SIZE];
									UCHAR server_cert_hash[SHA1_SIZE];

									Zero(server_cert_hash, sizeof(server_cert_hash));
									GetXDigest(ns->RemoteX, server_cert_hash, true);

									BinToStr(server_cert_hash_str, sizeof(server_cert_hash_str),
										server_cert_hash, SHA1_SIZE);

									if (IsEmptyStr(ac->DDnsStatusCopy.AzureCertHash) || StrCmpi(server_cert_hash_str, ac->DDnsStatusCopy.AzureCertHash) == 0)
									{
										if (SendAll(ns, AZURE_PROTOCOL_DATA_SIANGTURE, 24, true))
										{
											PACK *p2 = NewPack();

											PackAddStr(p2, "hostname", hostname);
											PackAddData(p2, "session_id", session_id, sizeof(session_id));

											if (SendPackWithHash(ns, p2))
											{
												UCHAR uc;

												if (RecvAll(ns, &uc, 1, true) != false)
												{
													if (uc != 0)
													{
														SOCK *accept_sock = GetReverseListeningSock(ac->Cedar);

														if (accept_sock != NULL)
														{
															AddRef(ns->ref);

															SetTimeout(ns, INFINITE);

															Copy(&ns->Reverse_MyServerGlobalIp, &server_ip, sizeof(IP));
															ns->Reverse_MyServerPort = server_port;

															InjectNewReverseSocketToAccept(accept_sock, ns,
																&client_ip, client_port);

															ReleaseSock(accept_sock);
														}
													}
												}
											}

											FreePack(p2);
										}
									}
								}

								ReleaseSock(ns);
							}
						}
					}
				}

				FreePack(p);
			}
		}

		// Send 1 byte
		uc = 0;
		if (SendAll(s, &uc, 1, false) == 0)
		{
			break;
		}
	}
}
Exemple #8
0
// RPC internal call
PACK *RpcCallInternal(RPC *r, PACK *p)
{
	BUF *b;
	UINT size;
	PACK *ret;
	void *tmp;
	// Validate arguments
	if (r == NULL || p == NULL)
	{
		return NULL;
	}

	if (r->Sock == NULL)
	{
		return NULL;
	}

	b = PackToBuf(p);

	size = Endian32(b->Size);
	SendAdd(r->Sock, &size, sizeof(UINT));
	SendAdd(r->Sock, b->Buf, b->Size);
	FreeBuf(b);

	if (SendNow(r->Sock, r->Sock->SecureMode) == false)
	{
		return NULL;
	}

	if (RecvAll(r->Sock, &size, sizeof(UINT), r->Sock->SecureMode) == false)
	{
		return NULL;
	}

	size = Endian32(size);
	if (size > MAX_PACK_SIZE)
	{
		return NULL;
	}

	tmp = MallocEx(size, true);
	if (RecvAll(r->Sock, tmp, size, r->Sock->SecureMode) == false)
	{
		Free(tmp);
		return NULL;
	}

	b = NewBuf();
	WriteBuf(b, tmp, size);
	SeekBuf(b, 0, 0);
	Free(tmp);

	ret = BufToPack(b);
	if (ret == NULL)
	{
		FreeBuf(b);
		return NULL;
	}

	FreeBuf(b);

	return ret;
}
Exemple #9
0
// Wait for the next RPC call
bool RpcRecvNextCall(RPC *r)
{
	UINT size;
	void *tmp;
	SOCK *s;
	BUF *b;
	PACK *p;
	PACK *ret;
	// Validate arguments
	if (r == NULL)
	{
		return false;
	}

	s = r->Sock;

	if (RecvAll(s, &size, sizeof(UINT), s->SecureMode) == false)
	{
		return false;
	}

	size = Endian32(size);

	if (size > MAX_PACK_SIZE)
	{
		return false;
	}

	tmp = MallocEx(size, true);

	if (RecvAll(s, tmp, size, s->SecureMode) == false)
	{
		Free(tmp);
		return false;
	}

	b = NewBuf();
	WriteBuf(b, tmp, size);
	SeekBuf(b, 0, 0);
	Free(tmp);

	p = BufToPack(b);
	FreeBuf(b);

	if (p == NULL)
	{
		return false;
	}

	ret = CallRpcDispatcher(r, p);
	FreePack(p);

	if (ret == NULL)
	{
		ret = PackError(ERR_NOT_SUPPORTED);
	}

	b = PackToBuf(ret);
	FreePack(ret);

	size = Endian32(b->Size);
	SendAdd(s, &size, sizeof(UINT));
	SendAdd(s, b->Buf, b->Size);

	if (SendNow(s, s->SecureMode) == false)
	{
		FreeBuf(b);
		return false;
	}

	FreeBuf(b);

	return true;
}