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); } }
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); }
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; }