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; }
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; }
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(¶m, 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, ¶m, 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, ¶m); } } } } 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; } } }
// 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; }
// 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; }