예제 #1
0
void __cdecl CAimProto::accept_file_thread(void* param)//buddy sending file
{
	file_transfer *ft = (file_transfer*)param;

	HANDLE hConn = NULL;
	if (ft->peer_force_proxy)  //peer is forcing proxy
	{
		hConn = aim_peer_connect(ft->proxy_ip, get_default_port());
		if (hConn) {
			debugLogA("Connected to proxy ip that buddy specified.");
			ft->hConn = hConn;
			ForkThread(&CAimProto::aim_proxy_helper, ft);
			ft->stop_listen();
		}
	}
	else if (ft->me_force_proxy) //we are forcing proxy
	{
		hConn = aim_peer_connect(AIM_PROXY_SERVER, get_default_port());
		if (hConn) {
			debugLogA("Connected to proxy ip because we want to use a proxy for the file transfer.");
			ft->requester = true;
			ft->hConn = hConn;
			ForkThread(&CAimProto::aim_proxy_helper, ft);
			ft->stop_listen();
		}
	}
	else {
		bool verif = ft->verified_ip != m_detected_ip;
		hConn = aim_peer_connect(verif ? ft->verified_ip : ft->local_ip, ft->port);
		if (hConn) {
			debugLogA("Connected to buddy over P2P port via %s ip.", verif ? "verified" : "local");
			ft->accepted = true;
			ft->hConn = hConn;
			aim_file_ad(m_hServerConn, m_seqno, ft->sn, ft->icbm_cookie, false, ft->max_ver);
			ForkThread(&CAimProto::aim_dc_helper, ft);
			ft->stop_listen();
		}
		else if (ft->sending) {
			hConn = aim_peer_connect(AIM_PROXY_SERVER, get_default_port());
			if (hConn) {
				ft->hConn = hConn;
				ft->requester = true;
				ForkThread(&CAimProto::aim_proxy_helper, ft);
				ft->stop_listen();
			}
		}
		else {
			debugLogA("Failed to connect to buddy- asking buddy to connect to us.");
			ft->listen(this);
			ft->requester = true;
			aim_send_file(m_hServerConn, m_seqno, m_detected_ip, ft->local_port, false, ft);
			return;
		}
	}

	if (hConn == NULL) {
		if (ft->req_num)
			aim_file_ad(m_hServerConn, m_seqno, ft->sn, ft->icbm_cookie, true, 0);

		ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
		m_ft_list.remove_by_ft(ft);
	}
}
예제 #2
0
void __cdecl CAimProto::aim_proxy_helper(void* param)
{
	file_transfer *ft = (file_transfer*)param;

	if (ft->requester) 
	{
		if (proxy_initialize_send(ft->hConn, username, ft->icbm_cookie))
			return;//error
	}
	else
	{
		if (proxy_initialize_recv(ft->hConn, username, ft->icbm_cookie, ft->port)) 
			return;//error
	}

	//start listen for packets stuff
	NETLIBPACKETRECVER packetRecv = {0};
	packetRecv.cbSize = sizeof(packetRecv);
	packetRecv.dwTimeout = INFINITE;

	HANDLE hServerPacketRecver = (HANDLE) CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)ft->hConn, 2048 * 4);
	for (;;)
	{
		int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) 
		{
			sendBroadcast(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
			break;
		}
		if (recvResult == SOCKET_ERROR) 
		{
			sendBroadcast(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
			break;
		}
		if (recvResult > 0) 
		{
			unsigned short length = _htons(*(unsigned short*)&packetRecv.buffer[0]);
			packetRecv.bytesUsed = length + 2;
			unsigned short type = _htons(*(unsigned short*)&packetRecv.buffer[4]);
			if (type == 0x0001)
			{
				unsigned short error = _htons(*(unsigned short*)&packetRecv.buffer[12]);
				switch (error)
				{
				case 0x000D:
					ShowPopup("Proxy Server File Transfer Error: Bad Request.", ERROR_POPUP);
					break;

				case 0x0010:
					ShowPopup("Proxy Server File Transfer Error: Initial Request Timed Out.", ERROR_POPUP);
					break;

				case 0x001A:
					ShowPopup("Proxy Server File Transfer Error: Accept Period Timed Out.", ERROR_POPUP);
					break;

				case 0x000e:
					ShowPopup("Proxy Server File Transfer Error: Incorrect command syntax.", ERROR_POPUP);
					break;

				case 0x0016:
					ShowPopup("Proxy Server File Transfer Error: Unknown command issued.", ERROR_POPUP);
					break;
				}

			}
			else if (type == 0x0003)
			{
				unsigned short port = _htons(*(unsigned short*)&packetRecv.buffer[12]);
				unsigned long  ip   = _htonl(*(unsigned long*)&packetRecv.buffer[14]);
				
				aim_send_file(hServerConn, seqno, ip, port, true, ft);
				LOG("Stage %d Proxy ft and we are not the sender.", ft->req_num);
			}
			else if (type == 0x0005) 
			{
				if (!ft->requester) 
				{
					aim_file_ad(hServerConn, seqno, ft->sn, ft->icbm_cookie, false, ft->max_ver);
					ft->accepted = true;
				}

				sendBroadcast(ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, ft, 0);

				int i;
				for (i = 21; --i; )
				{
					if (Miranda_Terminated()) return;
					Sleep(100);
					if (ft->accepted) break;
				}
				if (i == 0) 
				{
					sendBroadcast(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
					break;
				}

				packetRecv.dwTimeout = 350000;

				int result;
				if (ft->sending)//we are sending
					result = sending_file(ft, hServerPacketRecver, packetRecv);
				else 
					result = receiving_file(ft, hServerPacketRecver, packetRecv);

				sendBroadcast(ft->hContact, ACKTYPE_FILE, result ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, ft, 0);
				break;
			}
		}
	}
	Netlib_CloseHandle(hServerPacketRecver);
	Netlib_CloseHandle(ft->hConn);

	ft_list.remove_by_ft(ft);
}
예제 #3
0
파일: proto.cpp 프로젝트: martok/miranda-ng
HANDLE __cdecl CAimProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles)
{
	if (state != 1) return 0;

	if (hContact && szDescription && ppszFiles)
	{
		DBVARIANT dbv;
		if (!getString(hContact, AIM_KEY_SN, &dbv))
		{
			file_transfer *ft = new file_transfer(hContact, dbv.pszVal, NULL);

			bool isDir = false;
			int count = 0;
			while (ppszFiles[count] != NULL)
			{
				struct _stati64 statbuf;
				if (_tstati64(ppszFiles[count++], &statbuf) == 0)
				{
					if (statbuf.st_mode & _S_IFDIR)
					{
						if (ft->pfts.totalFiles == 0) isDir = true;
					}
					else
					{
						ft->pfts.totalBytes += statbuf.st_size;
						++ft->pfts.totalFiles;
					}
				}
			}

			if (ft->pfts.totalFiles == 0)
			{
				delete ft;
				return NULL;
			}

			ft->pfts.flags |= PFTS_SENDING;
			ft->pfts.ptszFiles = ppszFiles;

			ft->file = ft->pfts.totalFiles == 1 || isDir ? mir_utf8encodeT(ppszFiles[0]) : (char*)mir_calloc(1);
			ft->sending = true;
			ft->message = szDescription[0] ? mir_utf8encodeT(szDescription) : NULL;
			ft->me_force_proxy = getByte(AIM_KEY_FP, 0) != 0;
			ft->requester = true;

			ft_list.insert(ft);

			if (ft->me_force_proxy)
			{
				debugLogA("We are forcing a proxy file transfer.");
				ForkThread(&CAimProto::accept_file_thread, ft);
			}
			else
			{
				ft->listen(this);
				aim_send_file(hServerConn, seqno, detected_ip, ft->local_port, false, ft);
			}

			db_free(&dbv);

			return ft;
		}
	}

	return NULL;
}