⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liteproxyserverview.cpp

📁 代理服务器是怎样操作和运行的,希望能提供一种参考和学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		CString str;
		str.Format("%s %s:%d", sAppProtocolTypes[pRequest->nAppProtocol], pRequest->strHost, pRequest->nPort);
		pRequest->nLogID = gpView->Log(pRequest, str);
	}

	sockaddr_in host;
	host.sin_family = AF_INET;
	host.sin_port = htons(pRequest->nPort);
	if(inet_addr(pRequest->strHost) == INADDR_NONE )  // connect to the appropriate server
	{
		hostent* hp = gethostbyname(pRequest->strHost); // server address is a DNS name
		if(hp == NULL)
		{			
			gpView->UpdateLog(pRequest->nLogID, 7, "Failed to resolve "+pRequest->strHost);
			return false;
		}		
		host.sin_addr.s_addr = *((unsigned long *) hp->h_addr);
	}
	else
		host.sin_addr.s_addr = inet_addr(pRequest->strHost); // directly use the IP address

	gpView->UpdateLog(pRequest->nLogID, 7, "Connecting "+pRequest->strHost);
	if(connect(s, (sockaddr*)&host, sizeof(host)) == SOCKET_ERROR)
	{
		gpView->UpdateLog(pRequest->nLogID, 7, "Failed to Connect " + pRequest->strHost);
		return false;
	}
	return true;
}

void HostPort(CString &strHost, INTERNET_PORT &nPort)
{
	int nIndex;
	if((nIndex = strHost.Find(':')) != -1)
	{
		nPort = atoi(strHost.Mid(nIndex+1));
		strHost = strHost.Left(nIndex);
	}
}

UINT StartRequest(void* lpv)
{
	Request *pRequest = (Request *)lpv;
	pRequest->nTime = ::GetTickCount();
	SOCKET SocketClient = pRequest->socket;
	try
	{
		SOCKET SocketHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		pRequest->strIP = inet_ntoa(pRequest->address.sin_addr);
		bool bFtpPortCmd = pRequest->pListener->nAppProtocol == Listener::ApplicationProtocol::TYPE_FTP_PORT;
		int nIndex;
		CString str;

		if(pRequest->pListener->strNextServerIP.IsEmpty() == false)
		{
			pRequest->strHost = pRequest->pListener->strNextServerIP;
			pRequest->nPort = pRequest->pListener->nNextServerPort;
			if(ConnectHost(SocketHost, pRequest) == false)
				goto END_REQUEST;
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_HTTP)
		{
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_FTP)
		{
			send(SocketClient, "220 FTP Virtual Server\r\n", 24, 0);
			pRequest->nPort = 21;
			CString strPass;
			while(true)
			{
				pRequest->nLength = recv(SocketClient, str.GetBuffer(1024), 1024, 0);
				str.ReleaseBuffer(pRequest->nLength);
				if(memicmp(str, "USER", 4) == 0)
				{
					if((nIndex = str.Find("@")) != -1)
					{
						pRequest->strHost = str.Mid(nIndex+1);
						pRequest->strHost.TrimRight();
						HostPort(pRequest->strHost, pRequest->nPort);
						pRequest->strRequest = str.Left(nIndex)+"\r\n";
						break;
					}
					else
					{
						pRequest->strRequest = str;
						str.TrimRight();
						if(str.GetLength() == 4)
							pRequest->strRequest.Insert(5, "anonymous");
						// if host still not found then ask for login password
						send(SocketClient, "331 send password.\r\n", 20, 0);
					}
				}
				else	if(memicmp(str, "SITE", 4) == 0 || memicmp(str, "OPEN", 4) == 0)
				{
					if((nIndex = str.Find(" ")) == -1)
						goto END_REQUEST;
					pRequest->strHost = str.Mid(nIndex+1);
					pRequest->strHost.TrimRight();
					HostPort(pRequest->strHost, pRequest->nPort);
					break;
				}
				else	if(memicmp(str, "PASS", 4) == 0)
				{
					strPass = str;
					send(SocketClient, "230 Login OK. Proceed.\r\n", 24, 0);
				}
				else
					break;
			}

			// connect to ftp server
			if(ConnectHost(SocketHost, pRequest) == false)
				goto END_REQUEST;
			if(pRequest->strRequest.IsEmpty() == false)
			{
				// Receive ready command
				RequestRecv(pRequest, SocketHost, str.GetBuffer(1024), 1024);
				// send USER command
				RequestSend(pRequest, SocketHost, pRequest->strRequest.GetBuffer(0), pRequest->strRequest.GetLength());
				if(strPass.IsEmpty() == false)
				{
					// Receive reply of USER command
					nIndex = RequestRecv(pRequest, SocketHost, str.GetBuffer(1024), 1024);
					str.ReleaseBuffer(nIndex);
					// send password
					RequestSend(pRequest, SocketHost, strPass.GetBuffer(0), strPass.GetLength());
				}
			}
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_NNTP)
		{
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_DNS)
		{
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_SMTP_SERVER)
		{
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_SOCKS4)
		{
		}
		else	if(pRequest->nAppProtocol == Listener::ApplicationProtocol::TYPE_SOCKS5)
		{
		}
		
		gpView->UpdateLog(pRequest->nLogID, 7, "In progress...");
		// gets ready to relay traffic on both directions
		AfxBeginThread(TwoWayThread, new TwoWayStruct(SocketHost, SocketClient, !bFtpPortCmd, pRequest));
		AfxBeginThread(TwoWayThread, new TwoWayStruct(SocketClient, SocketHost, bFtpPortCmd, pRequest));

		return 0;
	}
	catch(...)
	{
	}

END_REQUEST:
	shutdown(SocketClient, 2);
	closesocket(SocketClient);
	gpView->UpdateLog(pRequest->nLogID, 8, Commas(::GetTickCount()-pRequest->nTime));
	delete pRequest;

	return 1;
}

UINT StartListenThread(void* lpv)
{
	CString str;
	Listener* pListener = (Listener*)lpv;
	int nType;
	if(pListener->nTransProtocol == Listener::TransportProtocol::TYPE_TCP)
		nType = SOCK_STREAM;
	else	if(pListener->nTransProtocol == Listener::TransportProtocol::TYPE_UDP)
		nType = SOCK_DGRAM;
	pListener->socketServer = socket(AF_INET, nType, 0);
	if(pListener->socketServer == INVALID_SOCKET)
	{
		pListener->pThread = NULL;
		if(pListener->IsTemp() == false)
			AfxMessageBox("Fail to create listener socket");
		return 1;
	}
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons((u_short)pListener->nPort); // listen this port
	if(bind(pListener->socketServer, (sockaddr *)&addr, sizeof(addr)) != 0)
	{
		pListener->pThread = NULL;
		str.Format("Socket bind failed: port %d", pListener->nPort);
		if(pListener->IsTemp() == false)
			AfxMessageBox(str);
		return 1;
	}
	if(pListener->nTransProtocol == Listener::TransportProtocol::TYPE_TCP)
		if(listen(pListener->socketServer, SOMAXCONN) != 0)
		{
			pListener->pThread = NULL;
			str.Format("Fail to start listening: port %d", pListener->nPort);
			if(pListener->IsTemp() == false)
				AfxMessageBox(str);
			return 1;
		}

	int nLength;
	do
	{
		Request *pRequest = new Request;
		pRequest->pListener = pListener;
		pRequest->nAppProtocol = pListener->nAppProtocol;
		pRequest->nTransProtocol = pListener->nTransProtocol;
		nLength = sizeof(pRequest->address);
		if(pListener->nTransProtocol == Listener::TransportProtocol::TYPE_TCP)
		{
			if((pRequest->socket = accept(pListener->socketServer, (sockaddr*)&pRequest->address, &nLength)) != INVALID_SOCKET && pListener->pThread)
				AfxBeginThread(StartRequest, (LPVOID)pRequest);
		}
		else	if(pListener->nTransProtocol == Listener::TransportProtocol::TYPE_UDP)
		{
		}
		else
			break;
	}
	while(pListener->pThread && pListener->IsTemp() == false);
	pListener->pThread = NULL;

	return 0; 
}

void Listener::StartListen()
{
	if(pThread)
		return;
	pThread = AfxBeginThread(StartListenThread, this);
}

void Listener::StopListen()
{
	if(pThread == NULL)
		return;
	shutdown(socketServer, 2);
	closesocket(socketServer);
	if(pThread)
	{
		::TerminateThread(pThread, 0);
		pThread = NULL;
	}
}

int CLiteProxyServerView::Log(Request* pRequest, LPCSTR lpcsLog)
{
	int nItemCount = m_pList->GetItemCount();
	try
	{
		CString str;
		str.Format("%s", Commas(nItemCount+1));
		m_pList->InsertItem(nItemCount, str, pRequest->nAppProtocol ? pRequest->nAppProtocol : -1);
		m_pList->SetItemText(nItemCount, 1, CTime::GetCurrentTime().Format("%c"));
		m_pList->SetItemText(nItemCount, 2, pRequest->strIP);
		m_pList->SetItemText(nItemCount, 3, lpcsLog);
		if(m_bEnsureVisible)
			m_pList->EnsureVisible(nItemCount, FALSE);
	}
	catch(...)
	{
	}

	return nItemCount;
}

void CLiteProxyServerView::UpdateLog(int nLogID, int nCol, int nLength)
{
	if(nLogID < 0 || nLogID >= m_pList->GetItemCount())
		return;

	m_pList->SetItemText(nLogID, nCol, Commas(nLength));
}

void CLiteProxyServerView::UpdateLog(int nLogID, int nCol, LPCSTR lpcs)
{
	if(nLogID < 0 || nLogID >= m_pList->GetItemCount())
		return;

	m_pList->SetItemText(nLogID, nCol, lpcs);
}

void CLiteProxyServerView::OnFileNew()
{
	theApp.m_nInProgress = 0;
	m_pList->DeleteAllItems();
}

void CLiteProxyServerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	if(lHint == 0)
	{
		if(m_pListener != NULL)
			delete m_pListener;
		m_pListener = new Listener;
		m_pListener->nAppProtocol = Listener::ApplicationProtocol::TYPE_FTP;
		m_pListener->nTransProtocol = Listener::TransportProtocol::TYPE_TCP;
		m_pListener->nPort = 21;
		m_pListener->StartListen();
	}
	else	if(lHint == 1)
	{
		delete m_pListener;
		m_pListener = NULL;
	}
}

void CLiteProxyServerView::GetNetworkParams()
{
	try
	{
		m_strArrayDNS.RemoveAll();
		ULONG pOutBufLen = 0;
		::GetNetworkParams(NULL, &pOutBufLen);
		FIXED_INFO* pInfo = new FIXED_INFO[pOutBufLen/sizeof(FIXED_INFO)+1];
		if(ERROR_SUCCESS == ::GetNetworkParams(pInfo, &pOutBufLen))
		{
			IP_ADDR_STRING* pNext = &pInfo[0].DnsServerList;	
			do	m_strArrayDNS.Add(pNext->IpAddress.String);
			while(pNext = pNext->Next);
		}
		delete []pInfo;

		m_strArrayIP.RemoveAll();
		DWORD dwError;
		ULONG pdwSize = 0;
		GetIpAddrTable(NULL, &pdwSize, TRUE); 
		PMIB_IPADDRTABLE pIpAddrTable = new MIB_IPADDRTABLE[pdwSize/sizeof(MIB_IPADDRTABLE)+1];
		if((dwError = GetIpAddrTable(pIpAddrTable, &pdwSize, TRUE)) == NO_ERROR)
			for(int nIndex = 0; nIndex < (int)pIpAddrTable[0].dwNumEntries; nIndex++)
			{
				CString strIP = inet_ntoa((in_addr&)pIpAddrTable[0].table[nIndex].dwAddr);
				if(strIP != "127.0.0.1" && strIP != "0.0.0.0")
					m_strArrayIP.Add(strIP);
			}
		delete []pIpAddrTable;
	}
	catch(...)
	{
		AfxMessageBox("Failed in GetNetworkParams()");
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -