Ejemplo n.º 1
0
unsigned int do_dump(void)
{
	int i1;
	unsigned char *pByte_Val, byte_val;
	char ascii_result[18];

	old_dump_beg = dump_beg;
	DebugPrint("\r\n %08X - ",dump_beg & 0xfffffff0);
	strcpy(ascii_result,"................");
	for (i1=0;i1<(dump_beg & 0x000f);i1++) DebugSend("   ");
	while (dump_beg <= dump_end)
	{
		pByte_Val = (unsigned char *)dump_beg++;
		byte_val = *pByte_Val;
		DebugPrint("%02X ",byte_val);
		if (!iscntrl(byte_val&0x7f)) ascii_result[i1] = byte_val;
		i1++;
		if (!(dump_beg & 0x000f))
		{
			DebugSend("  ");
			DebugSend(ascii_result);
			i1 = 0;
			strcpy(ascii_result,"................");
			if (dump_beg==0) break;
			if (dump_beg <= dump_end)
			{
				DebugPrint("\r\n %08X - ",dump_beg & 0xfffffff0);
			}
		}
	}

	return (dump_beg);
}
Ejemplo n.º 2
0
void DebugPrint(const char *format, ...)
{
	char debug_result[82];
	va_list argptr;
    va_start(argptr, format);
    vsprintf(debug_result, format, argptr);
    va_end(argptr);
	DebugSend(debug_result);
}
Ejemplo n.º 3
0
bool CUpDownClient::SendPeerCacheFileRequest()
{
	if (GetDownloadState() == DS_ONQUEUE){
		ASSERT( m_ePeerCacheDownState == PCDS_NONE );
		ASSERT( m_pPCDownSocket == NULL );
	}
	else if (GetDownloadState() == DS_DOWNLOADING){
		ASSERT( m_ePeerCacheDownState == PCDS_NONE );
		ASSERT( m_pPCDownSocket == NULL );
	}
	else{
		ASSERT(0);
	}

	if (!SupportPeerCache() || socket == NULL){
		ASSERT(0);
		return false;
	}

	m_uPeerCacheDownloadPushId = GetRandomUInt32();

	CSafeMemFile data(128);
	data.WriteUInt8(PCPCK_VERSION);
	data.WriteUInt8(PCOP_REQ);
	data.WriteUInt8(5);
	CTag tagCacheIP(PCTAG_CACHEIP, theApp.m_pPeerCache->GetCacheIP());
	tagCacheIP.WriteNewEd2kTag(&data);
	CTag tagPushId(PCTAG_PUSHID, m_uPeerCacheDownloadPushId);
	tagPushId.WriteNewEd2kTag(&data);
	CTag tagFileId(PCTAG_FILEID, (uchar*)reqfile->GetFileHash());
	tagFileId.WriteNewEd2kTag(&data);
	CTag tagPublicIP(PCTAG_PUBLICIP, theApp.GetPublicIP());
	tagPublicIP.WriteNewEd2kTag(&data);
	CTag tagCachePort(PCTAG_CACHEPORT, theApp.m_pPeerCache->GetCachePort());
	tagCachePort.WriteNewEd2kTag(&data);

	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("OP__PeerCacheQuery", this, reqfile->GetFileHash());
		Debug(_T("  CacheIP=%s  PushId=%u  PublicIP=%s  FileId=%s\n"), ipstr(tagCacheIP.GetInt()), tagPushId.GetInt(), ipstr(tagPublicIP.GetInt()), md4str(tagFileId.GetHash()));
	}

	Packet* pEd2kPacket = new Packet(&data, OP_EMULEPROT, OP_PEERCACHE_QUERY);
	theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size);
	socket->SendPacket(pEd2kPacket);
	SetDownloadState(DS_DOWNLOADING);
	m_dwLastBlockReceived = ::GetTickCount();
	SetPeerCacheDownState(PCDS_WAIT_CLIENT_REPLY);
	return true;
}
Ejemplo n.º 4
0
bool CListenSocket::SendPortTestReply(char result, bool disconnect)
{
	POSITION pos2;
	for(POSITION pos1 = socket_list.GetHeadPosition(); ( pos2 = pos1 ) != NULL; )
	{
		socket_list.GetNext(pos1);
		CClientReqSocket* cur_sock = socket_list.GetAt(pos2);
		if (cur_sock->m_bPortTestCon)
		{
			if (thePrefs.GetDebugClientTCPLevel() > 0)
				DebugSend("OP__PortTest", cur_sock->client);
			Packet* replypacket = new Packet(OP_PORTTEST, 1);
			replypacket->pBuffer[0]=result;
			theStats.AddUpDataOverheadOther(replypacket->size);
			cur_sock->SendPacket(replypacket);
			if (disconnect)
				cur_sock->m_bPortTestCon = false;
			return true;
		}
	}
	return false;
}
Ejemplo n.º 5
0
void CClientList::Process()
{
	///////////////////////////////////////////////////////////////////////////
	// Cleanup banned client list
	//
	const uint32 cur_tick = ::GetTickCount();
	if (m_dwLastBannCleanUp + BAN_CLEANUP_TIME < cur_tick)
	{
		m_dwLastBannCleanUp = cur_tick;
		
		POSITION pos = m_bannedList.GetStartPosition();
		uint32 nKey;
		uint32 dwBantime;
		while (pos != NULL)
		{
			m_bannedList.GetNextAssoc( pos, nKey, dwBantime );
			if (dwBantime + CLIENTBANTIME < cur_tick )
				RemoveBannedClient(nKey);
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// Cleanup tracked client list
	//
	if (m_dwLastTrackedCleanUp + TRACKED_CLEANUP_TIME < cur_tick)
	{
		m_dwLastTrackedCleanUp = cur_tick;
		if (thePrefs.GetLogBannedClients())
			AddDebugLogLine(false, _T("Cleaning up TrackedClientList, %i clients on List..."), m_trackedClientsList.GetCount());
		POSITION pos = m_trackedClientsList.GetStartPosition();
		uint32 nKey;
		CDeletedClient* pResult;
		while (pos != NULL)
		{
			m_trackedClientsList.GetNextAssoc( pos, nKey, pResult );
			if (pResult->m_dwInserted + KEEPTRACK_TIME < cur_tick ){
				m_trackedClientsList.RemoveKey(nKey);
				delete pResult;
			}
		}
		if (thePrefs.GetLogBannedClients())
			AddDebugLogLine(false, _T("...done, %i clients left on list"), m_trackedClientsList.GetCount());
	}

	///////////////////////////////////////////////////////////////////////////
	// Process Kad client list
	//
	//We need to try to connect to the clients in m_KadList
	//If connected, remove them from the list and send a message back to Kad so we can send a ACK.
	//If we don't connect, we need to remove the client..
	//The sockets timeout should delete this object.
	//MORPH START - Removed by Stulle, Optimize Process Kad client list [WiZaRd]
	/*
	POSITION pos1, pos2;
	*/
	//MORPH END   - Removed by Stulle, Optimize Process Kad client list [WiZaRd]

	// buddy is just a flag that is used to make sure we are still connected or connecting to a buddy.
	buddyState buddy = Disconnected;

	//MORPH START - Changed by Stulle, Optimize Process Kad client list [WiZaRd]
	/*
	for (pos1 = m_KadList.GetHeadPosition(); (pos2 = pos1) != NULL; )
	{
		m_KadList.GetNext(pos1);
		CUpDownClient* cur_client =	m_KadList.GetAt(pos2);
	*/
	for (POSITION pos = m_KadList.GetHeadPosition(); pos != NULL; )
	{
		POSITION posLast = pos;
		CUpDownClient* cur_client =     m_KadList.GetNext(pos);
	//MORPH END   - Changed by Stulle, Optimize Process Kad client list [WiZaRd]
		if( !Kademlia::CKademlia::IsRunning() )
		{
			//Clear out this list if we stop running Kad.
			//Setting the Kad state to KS_NONE causes it to be removed in the switch below.
			cur_client->SetKadState(KS_NONE);
		}
		switch(cur_client->GetKadState())
		{
			case KS_QUEUED_FWCHECK:
			case KS_QUEUED_FWCHECK_UDP:
				//Another client asked us to try to connect to them to check their firewalled status.
				cur_client->TryToConnect(true, true);
				break;
			case KS_CONNECTING_FWCHECK:
				//Ignore this state as we are just waiting for results.
				break;
			case KS_FWCHECK_UDP:
			case KS_CONNECTING_FWCHECK_UDP:
				// we want a UDP firewallcheck from this client and are just waiting to get connected to send the request
				break;
			case KS_CONNECTED_FWCHECK:
				//We successfully connected to the client.
				//We now send a ack to let them know.
				if (cur_client->GetKadVersion() >= KADEMLIA_VERSION7_49a){
					// the result is now sent per TCP instead of UDP, because this will fail if our intern UDP port is unreachable.
					// But we want the TCP testresult regardless if UDP is firewalled, the new UDP state and test takes care of the rest					
					ASSERT( cur_client->socket != NULL && cur_client->socket->IsConnected() );
					if (thePrefs.GetDebugClientTCPLevel() > 0)
						DebugSend("OP_KAD_FWTCPCHECK_ACK", cur_client);
					Packet* pPacket = new Packet(OP_KAD_FWTCPCHECK_ACK, 0, OP_EMULEPROT);
					if (!cur_client->SafeConnectAndSendPacket(pPacket))
						cur_client = NULL;
				}
				else {
					if (thePrefs.GetDebugClientKadUDPLevel() > 0)
						DebugSend("KADEMLIA_FIREWALLED_ACK_RES", cur_client->GetIP(), cur_client->GetKadPort());
					Kademlia::CKademlia::GetUDPListener()->SendNullPacket(KADEMLIA_FIREWALLED_ACK_RES, ntohl(cur_client->GetIP()), cur_client->GetKadPort(), 0, NULL);
				}
				//We are done with this client. Set Kad status to KS_NONE and it will be removed in the next cycle.
				if (cur_client != NULL)
					cur_client->SetKadState(KS_NONE);
				break;

			case KS_INCOMING_BUDDY:
				//A firewalled client wants us to be his buddy.
				//If we already have a buddy, we set Kad state to KS_NONE and it's removed in the next cycle.
				//If not, this client will change to KS_CONNECTED_BUDDY when it connects.
				if( m_nBuddyStatus == Connected )
					cur_client->SetKadState(KS_NONE);
				break;

			case KS_QUEUED_BUDDY:
				//We are firewalled and want to request this client to be a buddy.
				//But first we check to make sure we are not already trying another client.
				//If we are not already trying. We try to connect to this client.
				//If we are already connected to a buddy, we set this client to KS_NONE and it's removed next cycle.
				//If we are trying to connect to a buddy, we just ignore as the one we are trying may fail and we can then try this one.
				if( m_nBuddyStatus == Disconnected )
				{
					buddy = Connecting;
					m_nBuddyStatus = Connecting;
					cur_client->SetKadState(KS_CONNECTING_BUDDY);
					cur_client->TryToConnect(true, true);
					theApp.emuledlg->serverwnd->UpdateMyInfo();
				}
				else if( m_nBuddyStatus == Connected )
					cur_client->SetKadState(KS_NONE);
				break;

			case KS_CONNECTING_BUDDY:
				//We are trying to connect to this client.
				//Although it should NOT happen, we make sure we are not already connected to a buddy.
				//If we are we set to KS_NONE and it's removed next cycle.
				//But if we are not already connected, make sure we set the flag to connecting so we know 
				//things are working correctly.
				if( m_nBuddyStatus == Connected )
					cur_client->SetKadState(KS_NONE);
				else
				{
					ASSERT( m_nBuddyStatus == Connecting );
					buddy = Connecting;
				}
				break;

			case KS_CONNECTED_BUDDY:
				//A potential connected buddy client wanting to me in the Kad network
				//We set our flag to connected to make sure things are still working correctly.
				buddy = Connected;
				
				//If m_nBuddyStatus is not connected already, we set this client as our buddy!
				if( m_nBuddyStatus != Connected )
				{
					m_pBuddy = cur_client;
					m_nBuddyStatus = Connected;
					theApp.emuledlg->serverwnd->UpdateMyInfo();
				}
				if( m_pBuddy == cur_client && theApp.IsFirewalled() && cur_client->SendBuddyPingPong() )
				{
					if (thePrefs.GetDebugClientTCPLevel() > 0)
						DebugSend("OP__BuddyPing", cur_client);
					Packet* buddyPing = new Packet(OP_BUDDYPING, 0, OP_EMULEPROT);
					theStats.AddUpDataOverheadOther(buddyPing->size);
					VERIFY( cur_client->SendPacket(buddyPing, true, true) );
					cur_client->SetLastBuddyPingPongTime();
				}
				break;

			default:
				//MORPH START - Changed by Stulle, Optimize Process Kad client list [WiZaRd]
				/*
				RemoveFromKadList(cur_client);
				*/
				//removed function overhead
				if(cur_client == m_pBuddy)
				{
					//MORPH START - Added by Stulle, Fix for setting buddy state on removing buddy [WiZaRd]
					buddy = Disconnected;
					m_nBuddyStatus = Disconnected;
					//MORPH END   - Added by Stulle, Fix for setting buddy state on removing buddy [WiZaRd]
					m_pBuddy = NULL;
					theApp.emuledlg->serverwnd->UpdateMyInfo();
				}
				m_KadList.RemoveAt(posLast);
				//MORPH END   - Changed by Stulle, Optimize Process Kad client list [WiZaRd]
		}
	}
	
	//We either never had a buddy, or lost our buddy..
	if( buddy == Disconnected )
	{
		if( m_nBuddyStatus != Disconnected || m_pBuddy )
		{
			if( Kademlia::CKademlia::IsRunning() && theApp.IsFirewalled() && Kademlia::CUDPFirewallTester::IsFirewalledUDP(true))
			{
				//We are a lowID client and we just lost our buddy.
				//Go ahead and instantly try to find a new buddy.
				Kademlia::CKademlia::GetPrefs()->SetFindBuddy();
			}
			m_pBuddy = NULL;
			m_nBuddyStatus = Disconnected;
			theApp.emuledlg->serverwnd->UpdateMyInfo();
		}
	}

	if ( Kademlia::CKademlia::IsConnected() )
	{
		//we only need a buddy if direct callback is not available
		if( Kademlia::CKademlia::IsFirewalled() && Kademlia::CUDPFirewallTester::IsFirewalledUDP(true))
		{
			//TODO 0.49b: Kad buddies won'T work with RequireCrypt, so it is disabled for now but should (and will)
			//be fixed in later version
			// Update: Buddy connections itself support obfuscation properly since 0.49a (this makes it work fine if our buddy uses require crypt)
			// ,however callback requests don't support it yet so we wouldn't be able to answer callback requests with RequireCrypt, protocolchange intended for the next version
			if( m_nBuddyStatus == Disconnected && Kademlia::CKademlia::GetPrefs()->GetFindBuddy() && !thePrefs.IsClientCryptLayerRequired())
			{
				DEBUG_ONLY( DebugLog(_T("Starting Buddysearch")) );
				//We are a firewalled client with no buddy. We have also waited a set time 
				//to try to avoid a false firewalled status.. So lets look for a buddy..
				if( !Kademlia::CSearchManager::PrepareLookup(Kademlia::CSearch::FINDBUDDY, true, Kademlia::CUInt128(true).Xor(Kademlia::CKademlia::GetPrefs()->GetKadID())) )
				{
					//This search ID was already going. Most likely reason is that
					//we found and lost our buddy very quickly and the last search hadn't
					//had time to be removed yet. Go ahead and set this to happen again
					//next time around.
					Kademlia::CKademlia::GetPrefs()->SetFindBuddy();
				}
			}
		}
		else
		{
			if( m_pBuddy )
			{
				//Lets make sure that if we have a buddy, they are firewalled!
				//If they are also not firewalled, then someone must have fixed their firewall or stopped saturating their line.. 
				//We just set the state of this buddy to KS_NONE and things will be cleared up with the next cycle.
				if( !m_pBuddy->HasLowID() )
					m_pBuddy->SetKadState(KS_NONE);
			}
		}
	}
	else
	{
		if( m_pBuddy )
		{
			//We are not connected anymore. Just set this buddy to KS_NONE and things will be cleared out on next cycle.
			m_pBuddy->SetKadState(KS_NONE);
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// Cleanup client list
	//
	CleanUpClientList();

	///////////////////////////////////////////////////////////////////////////
	// Process Direct Callbacks for Timeouts
	//
	ProcessConnectingClientsList();
}
Ejemplo n.º 6
0
/**
 * Add a client to the waiting queue for uploads.
 *
 * @param client address of the client that should be added to the waiting queue
 *
 * @param bIgnoreTimelimit don't check time limit to possibly ban the client.
 */
void CUploadQueue::AddClientToQueue(CUpDownClient* client, bool bIgnoreTimelimit)
{
	//This is to keep users from abusing the limits we put on lowID callbacks.
	//1)Check if we are connected to any network and that we are a lowID.
	//(Although this check shouldn't matter as they wouldn't have found us..
	// But, maybe I'm missing something, so it's best to check as a precaution.)
	//2)Check if the user is connected to Kad. We do allow all Kad Callbacks.
	//3)Check if the user is in our download list or a friend..
	//We give these users a special pass as they are helping us..
	//4)Are we connected to a server? If we are, is the user on the same server?
	//TCP lowID callbacks are also allowed..
	//5)If the queue is very short, allow anyone in as we want to make sure
	//our upload is always used.
	if (theApp.IsConnected() 
		&& theApp.IsFirewalled()
		&& !client->GetKadPort()
		&& client->GetDownloadState() == DS_NONE 
		&& !client->IsFriend()
		&& theApp.serverconnect
		&& !theApp.serverconnect->IsLocalServer(client->GetServerIP(),client->GetServerPort())
		&& GetWaitingUserCount() > 50)
		return;
	client->AddAskedCount();
	client->SetLastUpRequest();
	if (!bIgnoreTimelimit)
		client->AddRequestCount(client->GetUploadFileID());
	if (client->IsBanned())
		return;
	uint16 cSameIP = 0;
	// check for double
	POSITION pos1, pos2;
	for (pos1 = waitinglist.GetHeadPosition();( pos2 = pos1 ) != NULL;)
	{
		waitinglist.GetNext(pos1);
		CUpDownClient* cur_client= waitinglist.GetAt(pos2);
		if (cur_client == client)
		{	
			if (client->m_bAddNextConnect && AcceptNewClient(client->m_bAddNextConnect))
			{
				//Special care is given to lowID clients that missed their upload slot
				//due to the saving bandwidth on callbacks.
				if(thePrefs.GetLogUlDlEvents())
					AddDebugLogLine(true, _T("Adding ****lowid when reconnecting. Client: %s"), client->DbgGetClientInfo());
				client->m_bAddNextConnect = false;
				RemoveFromWaitingQueue(client, true);
				// statistic values // TODO: Maybe we should change this to count each request for a file only once and ignore reasks
				CKnownFile* reqfile = theApp.sharedfiles->GetFileByID((uchar*)client->GetUploadFileID());
				if (reqfile)
					reqfile->statistic.AddRequest();
				AddUpNextClient(_T("Adding ****lowid when reconnecting."), client);
				return;
			}
			client->SendRankingInfo();
			theApp.emuledlg->transferwnd->queuelistctrl.RefreshClient(client);
			return;			
		}
		else if ( client->Compare(cur_client) ) 
		{
			theApp.clientlist->AddTrackClient(client); // in any case keep track of this client

			// another client with same ip:port or hash
			// this happens only in rare cases, because same userhash / ip:ports are assigned to the right client on connecting in most cases
			if (cur_client->credits != NULL && cur_client->credits->GetCurrentIdentState(cur_client->GetIP()) == IS_IDENTIFIED)
			{
				//cur_client has a valid secure hash, don't remove him
				if (thePrefs.GetVerbose())
					AddDebugLogLine(false, GetResString(IDS_SAMEUSERHASH), client->GetUserName(), cur_client->GetUserName(), client->GetUserName());
				return;
			}
			if (client->credits != NULL && client->credits->GetCurrentIdentState(client->GetIP()) == IS_IDENTIFIED)
			{
				//client has a valid secure hash, add him remove other one
				if (thePrefs.GetVerbose())
					AddDebugLogLine(false, GetResString(IDS_SAMEUSERHASH), client->GetUserName(), cur_client->GetUserName(), cur_client->GetUserName());
				RemoveFromWaitingQueue(pos2,true);
				if (!cur_client->socket)
				{
					if(cur_client->Disconnected(_T("AddClientToQueue - same userhash 1")))
						delete cur_client;
				}
			}
			else
			{
				// remove both since we do not know who the bad one is
				if (thePrefs.GetVerbose())
					AddDebugLogLine(false, GetResString(IDS_SAMEUSERHASH), client->GetUserName() ,cur_client->GetUserName(), _T("Both"));
				RemoveFromWaitingQueue(pos2,true);	
				if (!cur_client->socket)
				{
					if(cur_client->Disconnected(_T("AddClientToQueue - same userhash 2")))
						delete cur_client;
				}
				return;
			}
		}
		else if (client->GetIP() == cur_client->GetIP())
		{
			// same IP, different port, different userhash
			cSameIP++;
		}
	}
	if (cSameIP >= 3)
	{
		// do not accept more than 3 clients from the same IP
		if (thePrefs.GetVerbose())
			DEBUG_ONLY( AddDebugLogLine(false,_T("%s's (%s) request to enter the queue was rejected, because of too many clients with the same IP"), client->GetUserName(), ipstr(client->GetConnectIP())) );
		return;
	}
	else if (theApp.clientlist->GetClientsFromIP(client->GetIP()) >= 3)
	{
		if (thePrefs.GetVerbose())
			DEBUG_ONLY( AddDebugLogLine(false,_T("%s's (%s) request to enter the queue was rejected, because of too many clients with the same IP (found in TrackedClientsList)"), client->GetUserName(), ipstr(client->GetConnectIP())) );
		return;
	}
	// done

	// statistic values // TODO: Maybe we should change this to count each request for a file only once and ignore reasks
	CKnownFile* reqfile = theApp.sharedfiles->GetFileByID((uchar*)client->GetUploadFileID());
	if (reqfile)
		reqfile->statistic.AddRequest();

	// emule collection will bypass the queue
	if (reqfile != NULL && CCollection::HasCollectionExtention(reqfile->GetFileName()) && reqfile->GetFileSize() < (uint64)MAXPRIORITYCOLL_SIZE
		&& !client->IsDownloading() && client->socket != NULL && client->socket->IsConnected())
	{
		client->SetCollectionUploadSlot(true);
		RemoveFromWaitingQueue(client, true);
		AddUpNextClient(_T("Collection Priority Slot"), client);
		return;
	}
	else
		client->SetCollectionUploadSlot(false);

   // cap the list
    // the queue limit in prefs is only a soft limit. Hard limit is 25% higher, to let in powershare clients and other
    // high ranking clients after soft limit has been reached
    uint32 softQueueLimit = thePrefs.GetQueueSize();
    uint32 hardQueueLimit = thePrefs.GetQueueSize() + max(thePrefs.GetQueueSize()/4, 200);

    // if soft queue limit has been reached, only let in high ranking clients
    if ((uint32)waitinglist.GetCount() >= hardQueueLimit ||
        (uint32)waitinglist.GetCount() >= softQueueLimit && // soft queue limit is reached
        (client->IsFriend() && client->GetFriendSlot()) == false && // client is not a friend with friend slot
        client->GetCombinedFilePrioAndCredit() < GetAverageCombinedFilePrioAndCredit()) { // and client has lower credits/wants lower prio file than average client in queue

        // then block client from getting on queue
		return;
	}
	if (client->IsDownloading())
	{
		// he's already downloading and wants probably only another file
		if (thePrefs.GetDebugClientTCPLevel() > 0)
			DebugSend("OP__AcceptUploadReq", client);
		Packet* packet = new Packet(OP_ACCEPTUPLOADREQ,0);
		theStats.AddUpDataOverheadFileRequest(packet->size);
		client->SendPacket(packet, true);
		return;
	}
	if (waitinglist.IsEmpty() && ForceNewClient(true))
	{
		AddUpNextClient(_T("Direct add with empty queue."), client);
	}
	else
	{
		waitinglist.AddTail(client);
		client->SetUploadState(US_ONUPLOADQUEUE);
		theApp.emuledlg->transferwnd->queuelistctrl.AddClient(client,true);
		theApp.emuledlg->transferwnd->ShowQueueCount(waitinglist.GetCount());
		client->SendRankingInfo();
	}
}
Ejemplo n.º 7
0
bool CUploadQueue::AddUpNextClient(LPCTSTR pszReason, CUpDownClient* directadd){
	CUpDownClient* newclient = NULL;
	// select next client or use given client
	if (!directadd)
	{
        newclient = FindBestClientInQueue();

        if(newclient)
		{
		    RemoveFromWaitingQueue(newclient, true);
		    theApp.emuledlg->transferwnd->ShowQueueCount(waitinglist.GetCount());
        }
	}
	else 
		newclient = directadd;

    if(newclient == NULL) 
        return false;

	if (!thePrefs.TransferFullChunks())
		UpdateMaxClientScore(); // refresh score caching, now that the highest score is removed

	if (IsDownloading(newclient))
		return false;

    if(pszReason && thePrefs.GetLogUlDlEvents())
        AddDebugLogLine(false, _T("Adding client to upload list: %s Client: %s"), pszReason, newclient->DbgGetClientInfo());

	if (newclient->HasCollectionUploadSlot() && directadd == NULL){
		ASSERT( false );
		newclient->SetCollectionUploadSlot(false);
	}

	// tell the client that we are now ready to upload
	if (!newclient->socket || !newclient->socket->IsConnected())
	{
		newclient->SetUploadState(US_CONNECTING);
		if (!newclient->TryToConnect(true))
			return false;
	}
	else
	{
		if (thePrefs.GetDebugClientTCPLevel() > 0)
			DebugSend("OP__AcceptUploadReq", newclient);
		Packet* packet = new Packet(OP_ACCEPTUPLOADREQ,0);
		theStats.AddUpDataOverheadFileRequest(packet->size);
		newclient->SendPacket(packet, true);
		newclient->SetUploadState(US_UPLOADING);
	}
	newclient->SetUpStartTime();
	newclient->ResetSessionUp();

    InsertInUploadingList(newclient);

    m_nLastStartUpload = ::GetTickCount();
	
	// statistic
	CKnownFile* reqfile = theApp.sharedfiles->GetFileByID((uchar*)newclient->GetUploadFileID());
	if (reqfile)
		reqfile->statistic.AddAccepted();
		
	theApp.emuledlg->transferwnd->uploadlistctrl.AddClient(newclient);

	return true;
}
Ejemplo n.º 8
0
void debug_parse(char *cmd_line)
{
	int params, result;
	unsigned int temp1,temp2,temp3,temp4;
	unsigned short tempword;
	unsigned char tempbyte;

	while (*cmd_line == ' ') cmd_line++;

	switch (toupper(*cmd_line++))
	{
	case '?':
		DebugPrint("\r\n Compile Date: %s, Time: %s",__DATE__,__TIME__);
		break;
	case 'A':  // assemble
		break;
	case 'B':
		break;
	case 'C':  // compare
		break;
	case 'D':  // dump
		params = sscanf(cmd_line,"%X %X",&temp2,&temp3);
		switch (params) {
		case 0:
			case EOF:
			dump_end = dump_beg + 127;
			do_dump();
			break;
		case 1:
			dump_beg = temp2;
			dump_end = dump_beg + 127;
			do_dump();
			break;
		case 2:
			if (temp3<temp2) temp3=temp2;
			dump_beg = temp2;
			dump_end = temp3;
			do_dump();
			break;
		}
		break;
	case 'E':  // read unsigned int
		if (sscanf(cmd_line,"%X",&temp1)==1)
			debug_port = (unsigned char*)(temp1&0xFFFFFFFC);
		temp2 = *(unsigned int*)debug_port;
		DebugPrint("\r\n %08X -> %08X",(int)debug_port,temp2);
//		debug_port += sizeof(int);
		break;
	case 'F':  // fill
		params = sscanf(cmd_line,"%X %X %X",&temp2,&temp3,&temp4);
		switch (params) {
		case 3:
			dump_end = temp3;
			for (old_dump_beg=temp2;old_dump_beg<=dump_end;old_dump_beg++)
			{
//				pokeb(dump_seg,old_dump_beg,temp4);
			}
			break;
		default:
			{
				DebugSend(" ?? \r\n");
			}
			break;
		}
		break;
	case 'G':  // go
		DebugInit();
		break;
	case 'H':  // hex
		break;
	case 'I':  // read byte
		break;
	case 'J':  // read word
		break;
	case 'K':
		break;
	case 'L':  // load
		break;
	case 'M':  // write unsigned int
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)(temp1&0xFFFFFFFC);
			DebugPrint("\r\n %08X <- %08X",(int)debug_port,temp2);
			*(unsigned int*)debug_port = temp2;
			debug_port += sizeof(int);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'N':  // name
		break;
	case 'O':  // output byte
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)temp1;
			tempbyte = temp2;
			DebugPrint("\r\n %08X <- %02X",(int)debug_port,tempbyte);
			*debug_port = tempbyte;
			debug_port += sizeof(tempbyte);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'P':  // proceed
		if (sscanf(cmd_line,"%d",&temp1)==1)
		{
			gain_Ap = temp1;
		}
		DebugPrint("\r\n gain_Ap = %5.1f",gain_Ap);
		break;
	case 'Q':  // quit
		if (sscanf(cmd_line,"%d",&temp1)==1)
		{
			gain_Ai = temp1;
		}
		DebugPrint("\r\n gain_Ai = %5.1f",gain_Ai);
		break;
	case 'R':  // register
		if (sscanf(cmd_line,"%d",&temp1)==1)
		{
			gain_Ad = temp1;
		}
		DebugPrint("\r\n gain_Ad = %5.1f",gain_Ad);
		break;
	case 'S':  // search
		if (sscanf(cmd_line,"%X",&temp2)==1)
		{
		}
		break;
	case 'T':  // Test
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				#ifdef	_MPU6050_H_			
				result = MPU6050_Setup();
				if (result==STATUS_OK)
				{
					DebugPrint("\r\n MPU6050 Init Success!");
				}
				else
				{
					DebugPrint("\r\n MPU6050 Init Fail. Error = %i", result);
				}
				#endif
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
			bTest = !bTest;
			if (bTest)
			{
				DebugPrint("\r\n Test ON!");
				ResetTimer(DEBUG_TIMER);
				StartTimer(DEBUG_TIMER,50);
			}
			else
			{
				DebugPrint("\r\n Test OFF!");
			}
		}
		break;
	case 'U':
		if (sscanf(cmd_line,"%d %d",&temp1,&temp2)==2)
		{
			DebugPrint("\r\n L298_set_speed(%d,%d)", temp1, temp2);
			L298_set_speed(temp1,temp2);
		}
		else
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:	//U5
				break;
			case 6:	//U6
				break;
			case 7:	//U7
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'W':  // write word
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)(temp1&0xFFFFFFFE);
			tempword = temp2;
			DebugPrint("\r\n %08X <- %04X",(int)debug_port,tempword);
			*(unsigned short*)debug_port = tempword;
			debug_port += sizeof(tempword);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'X':
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'Y':
		temp4 = sscanf(cmd_line,"%X %X",&temp1,&temp2);
		if (temp4>=1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'Z':
		debug_main_Z(cmd_line);
		break;
	default:
		;
	}
}
Ejemplo n.º 9
0
void CUpDownClient::ProcessHttpBlockPacket(const BYTE* pucData, UINT uSize)
{
	if (reqfile == NULL)
		throw CString(_T("Failed to process HTTP data block - No 'reqfile' attached"));

	if (reqfile->IsStopped() || (reqfile->GetStatus() != PS_READY && reqfile->GetStatus() != PS_EMPTY))
		throw CString(_T("Failed to process HTTP data block - File not ready for receiving data"));

	if (m_nUrlStartPos == -1)
		throw CString(_T("Failed to process HTTP data block - Unexpected file data"));

	uint32 nStartPos = m_nUrlStartPos;
	uint32 nEndPos = m_nUrlStartPos + uSize;

	m_nUrlStartPos += uSize;

//	if (thePrefs.GetDebugClientTCPLevel() > 0)
//		Debug("  Start=%u  End=%u  Size=%u  %s\n", nStartPos, nEndPos, size, DbgGetFileInfo(reqfile->GetFileHash()));

	if (!(GetDownloadState() == DS_DOWNLOADING || GetDownloadState() == DS_NONEEDEDPARTS))
		throw CString(_T("Failed to process HTTP data block - Invalid download state"));

	m_dwLastBlockReceived = ::GetTickCount();

	if (nEndPos == nStartPos || uSize != nEndPos - nStartPos)
		throw CString(_T("Failed to process HTTP data block - Invalid block start/end offsets"));

	thePrefs.Add2SessionTransferData(GetClientSoft(), (GetClientSoft()==SO_URL) ? (UINT)-2 : (UINT)-1, false, false, uSize);
	m_nDownDataRateMS += uSize;
	if (credits)
		credits->AddDownloaded(uSize, GetIP());
	nEndPos--;

	for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL; )
	{
		POSITION posLast = pos;
		Pending_Block_Struct *cur_block = m_PendingBlocks_list.GetNext(pos);
		if (cur_block->block->StartOffset <= nStartPos && nStartPos <= cur_block->block->EndOffset)
		{
			if (thePrefs.GetDebugClientTCPLevel() > 0){
				// NOTE: 'Left' is only accurate in case we have one(!) request block!
				void* p = m_pPCDownSocket ? (void*)m_pPCDownSocket : (void*)socket;
				Debug(_T("%08x  Start=%u  End=%u  Size=%u  Left=%u  %s\n"), p, nStartPos, nEndPos, uSize, cur_block->block->EndOffset - (nStartPos + uSize) + 1, DbgGetFileInfo(reqfile->GetFileHash()));
			}

			m_nLastBlockOffset = nStartPos;
			uint32 lenWritten = reqfile->WriteToBuffer(uSize, pucData, nStartPos, nEndPos, cur_block->block, this);
			if (lenWritten > 0)
			{
				m_nTransferredDown += uSize;
				SetTransferredDownMini();

				if (nEndPos >= cur_block->block->EndOffset)
				{
					reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset);
					delete cur_block->block;
					delete cur_block;
					m_PendingBlocks_list.RemoveAt(posLast);

					if (m_PendingBlocks_list.IsEmpty())
					{
						if (thePrefs.GetDebugClientTCPLevel() > 0)
							DebugSend("More block requests", this);
						m_nUrlStartPos = (UINT)-1;
						SendHttpBlockRequests();
					}
				}
//				else
//					TRACE("%hs - %d bytes missing\n", __FUNCTION__, cur_block->block->EndOffset - nEndPos);
			}

			return;
		}
	}

	TRACE("%s - Dropping packet\n", __FUNCTION__);
}
Ejemplo n.º 10
0
bool CUpDownClient::ProcessPeerCacheQuery(const uchar* packet, UINT size)
{
	const bool bDebug = (thePrefs.GetDebugClientTCPLevel() > 0);
	if (bDebug)
		DebugRecv("OP_PeerCacheQuery", this);

	if (socket == NULL){
		ASSERT(0);
		return false;
	}

	CSafeMemFile dataRecv(packet, size);
	uint8 uPCVersion = dataRecv.ReadUInt8();
	if (uPCVersion != PCPCK_VERSION){
		if (bDebug)
			Debug(_T("   ***Invalid packet version: 0x%02x\n"), uPCVersion);
		ASSERT(0);
		return false;
	}
	uint8 uPCOpcode = dataRecv.ReadUInt8();
	if (uPCOpcode != PCOP_REQ){
		if (bDebug)
			Debug(_T("   ***Invalid packet opcode: 0x%02x\n"), uPCOpcode);
		ASSERT(0);
		return false;
	}

	uint32 uCacheIP = 0;
	uint16 uCachePort = 0;
	uint32 uPushId = 0;
	uchar aucFileHash[16];
	uint32 uRemoteIP = 0;
	md4clr(aucFileHash);

	CString strInfo;
	UINT uTags = dataRecv.ReadUInt8();
	while (uTags--)
	{
		CTag tag(&dataRecv, GetUnicodeSupport()!=utf8strNone);
		if (tag.GetNameID() == PCTAG_CACHEIP && tag.IsInt())
		{
			uCacheIP = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  CacheIP=%s"), ipstr(uCacheIP));
		}
		else if (tag.GetNameID() == PCTAG_CACHEPORT && tag.IsInt())
		{
			uCachePort = (uint16)tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  CachePort=%u"), uCachePort);
		}
		else if (tag.GetNameID() == PCTAG_PUSHID && tag.IsInt())
		{
			uPushId = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  PushId=%u"), uPushId);
		}
		else if (tag.GetNameID() == PCTAG_FILEID && tag.IsHash() && tag.GetHash() != NULL)
		{
			md4cpy(aucFileHash, tag.GetHash());
			if (bDebug)
				strInfo.AppendFormat(_T("  FileId=%s"), md4str(aucFileHash));
		}
		else if (tag.GetNameID() == PCTAG_PUBLICIP && tag.IsInt())
		{
			uRemoteIP = tag.GetInt();
			if (bDebug)
				strInfo.AppendFormat(_T("  PublicIP=%s"), ipstr(uRemoteIP));
		}
		else
		{
			if (bDebug)
				strInfo.AppendFormat(_T("  ***UnkTag: %s"), tag.GetFullInfo());
			ASSERT(0);
		}
	}

	if (bDebug)
	{
		if (dataRecv.GetPosition() < dataRecv.GetLength())
			strInfo.AppendFormat(_T("  ***AddData: %u bytes"), (UINT)(dataRecv.GetLength() - dataRecv.GetPosition()));
		Debug(_T("%s\n"), strInfo);
	}

	if (uCacheIP == 0 || uCachePort == 0 || uPushId == 0 || isnulmd4(aucFileHash)){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("Invalid PeerCacheQuery; %s"), DbgGetClientInfo());
		return false;
	}

	CKnownFile* pUploadFile = theApp.sharedfiles->GetFileByID(aucFileHash);
	if (pUploadFile == NULL){
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("PeerCacheQuery reqfile does not match ed2k reqfile; %s"), DbgGetClientInfo());
		return false;
	}

	if (m_pPCUpSocket != NULL)
	{
        SetPeerCacheUpState(PCUS_NONE);
		m_pPCUpSocket->Safe_Delete();
		ASSERT( m_pPCUpSocket == NULL );
	}
	m_pPCUpSocket = new CPeerCacheUpSocket(this);
	m_pPCUpSocket->SetTimeOut(GetPeerCacheSocketUploadTimeout());
	m_pPCUpSocket->Create();

	SOCKADDR_IN sockAddr = {0};
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(uCachePort);
	sockAddr.sin_addr.S_un.S_addr = uCacheIP;
	//Try to always tell the socket to WaitForOnConnect before you call Connect.
	m_pPCUpSocket->WaitForOnConnect();
	m_pPCUpSocket->Connect((SOCKADDR*)&sockAddr, sizeof sockAddr);

	CStringA strPCRequest;
	strPCRequest.AppendFormat("GIVE %u\r\n", uPushId);

	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("PeerCache-GIVE", this, pUploadFile->GetFileHash());
		Debug(_T("  %hs\n"), strPCRequest);
	}
	
	CRawPacket* pHttpPacket = new CRawPacket(strPCRequest);
	theStats.AddUpDataOverheadFileRequest(pHttpPacket->size);
	m_pPCUpSocket->SendPacket(pHttpPacket);
	m_pPCUpSocket->SetHttpState(HttpStateRecvExpected);
	m_bPeerCacheUpHit = false;
	SetPeerCacheUpState(PCUS_WAIT_CACHE_REPLY);
	//theApp.uploadBandwidthThrottler->AddToStandardList(0, m_pPCUpSocket);

	CSafeMemFile dataSend(128);
	dataSend.WriteUInt8(PCPCK_VERSION);
	dataSend.WriteUInt8(PCOP_RES);
	dataSend.WriteUInt8(3);
	CTag tagPushId(PCTAG_PUSHID, uPushId);
	tagPushId.WriteNewEd2kTag(&dataSend);
	CTag tagPublicIP(PCTAG_PUBLICIP, theApp.GetPublicIP());
	tagPublicIP.WriteNewEd2kTag(&dataSend);
	CTag tagFileId(PCTAG_FILEID, (BYTE*)aucFileHash);
	tagFileId.WriteNewEd2kTag(&dataSend);
	
	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("OP__PeerCacheAnswer", this, aucFileHash);
		Debug(_T("  PushId=%u  PublicIP=%s  FileId=%s\n"), tagPushId.GetInt(), ipstr(tagPublicIP.GetInt()), md4str(tagFileId.GetHash()));
	}
	
	Packet* pEd2kPacket = new Packet(&dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER);
	theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size);
	socket->SendPacket(pEd2kPacket);
	return true;
}
Ejemplo n.º 11
0
bool CUpDownClient::SendHttpBlockRequests()
{
	USES_CONVERSION;
	ASSERT( GetDownloadState() == DS_DOWNLOADING );
	ASSERT( m_ePeerCacheDownState == PCDS_WAIT_CLIENT_REPLY || m_ePeerCacheDownState == PCDS_DOWNLOADING );

	m_bPeerCacheDownHit = false;
	m_dwLastBlockReceived = ::GetTickCount();
	if (reqfile == NULL)
		throw CString(_T("Failed to send block requests - No 'reqfile' attached"));

	CreateBlockRequests(1);
	if (m_PendingBlocks_list.IsEmpty()){
		if (m_pPCDownSocket != NULL){
			m_pPCDownSocket->Safe_Delete();
			ASSERT( m_pPCDownSocket == NULL );
			SetPeerCacheDownState(PCDS_NONE);
		}
		SetDownloadState(DS_NONEEDEDPARTS);
        SwapToAnotherFile(_T("A4AF for NNP file. CUpDownClient::SendHttpBlockRequests()"), true, false, false, NULL, true, true);
		return false;
	}

	// PeerCache does not support persistant HTTP connections
	if (m_pPCDownSocket != NULL)
	{
		m_pPCDownSocket->Safe_Delete();
		ASSERT( m_pPCDownSocket == NULL );
		SetPeerCacheDownState(PCDS_NONE);
		return SendPeerCacheFileRequest();
	}

	ASSERT( m_pPCDownSocket == NULL );
	m_pPCDownSocket = new CPeerCacheDownSocket(this);
	m_pPCDownSocket->SetTimeOut(GetPeerCacheSocketDownloadTimeout());
	if (!m_pPCDownSocket->Create()){
		m_pPCDownSocket->Safe_Delete();
		ASSERT( m_pPCDownSocket == NULL );
		return false;
	}

	ASSERT( !m_pPCDownSocket->IsConnected() );
	SOCKADDR_IN sockAddr = {0};
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons( theApp.m_pPeerCache->GetCachePort() );
	sockAddr.sin_addr.S_un.S_addr = theApp.m_pPeerCache->GetCacheIP();
	//Try to always tell the socket to WaitForOnConnect before you call Connect.
	m_pPCDownSocket->WaitForOnConnect();
	m_pPCDownSocket->Connect((SOCKADDR*)&sockAddr, sizeof sockAddr);

	POSITION pos = m_PendingBlocks_list.GetHeadPosition();
	Pending_Block_Struct* pending = m_PendingBlocks_list.GetNext(pos);
	ASSERT( pending->block->StartOffset <= pending->block->EndOffset );

	m_uReqStart = pending->block->StartOffset;
	m_uReqEnd = pending->block->EndOffset;
	m_nUrlStartPos = (uint64)-1;

	CStringA strPCRequest;
	strPCRequest.AppendFormat("GET http://%s/.ed2khash=%s HTTP/1.0\r\n", ipstrA(m_uPeerCacheRemoteIP), md4strA(reqfile->GetFileHash()));
	strPCRequest.AppendFormat("X-ED2K-PushId: %u\r\n", m_uPeerCacheDownloadPushId);
	strPCRequest.AppendFormat("Range: bytes=%I64u-%I64u\r\n", m_uReqStart, m_uReqEnd);
	strPCRequest.AppendFormat("User-Agent: eMule/%s\r\n", T2CA(theApp.m_strCurVersionLong));
	strPCRequest.AppendFormat("X-Network: eDonkey,Kademlia\r\n");
	strPCRequest.AppendFormat("\r\n");

	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("PeerCache-GET", this, reqfile->GetFileHash());
		Debug(_T("  %hs\n"), strPCRequest);
	}
	CRawPacket* pHttpPacket = new CRawPacket(strPCRequest);
	theStats.AddUpDataOverheadFileRequest(pHttpPacket->size);
	m_pPCDownSocket->SendPacket(pHttpPacket);
	m_pPCDownSocket->SetHttpState(HttpStateRecvExpected);
	SetPeerCacheDownState(PCDS_WAIT_CACHE_REPLY);
	return true;
}
Ejemplo n.º 12
0
bool CUpDownClient::ProcessPeerCacheDownHttpResponse(const CStringAArray& astrHeaders)
{
	ASSERT( GetDownloadState() == DS_DOWNLOADING );
	ASSERT( m_ePeerCacheDownState == PCDS_WAIT_CACHE_REPLY );

	if (reqfile == NULL)
		throw CString(_T("Failed to process HTTP response - No 'reqfile' attached"));
	if (GetDownloadState() != DS_DOWNLOADING)
		throw CString(_T("Failed to process HTTP response - Invalid client download state"));
	if (astrHeaders.GetCount() == 0)
		throw CString(_T("Unexpected HTTP response - No headers available"));

	const CStringA& rstrHdr = astrHeaders.GetAt(0);
	UINT uHttpMajVer, uHttpMinVer, uHttpStatusCode;
	if (sscanf(rstrHdr, "HTTP/%u.%u %u", &uHttpMajVer, &uHttpMinVer, &uHttpStatusCode) != 3){
		CString strError;
		strError.Format(_T("Unexpected HTTP response: \"%hs\""), rstrHdr);
		throw strError;
	}
	if (uHttpMajVer != 1 || (uHttpMinVer != 0 && uHttpMinVer != 1)){
		CString strError;
		strError.Format(_T("Unexpected HTTP version: \"%hs\""), rstrHdr);
		throw strError;
	}
	bool bExpectData = uHttpStatusCode == HTTP_STATUS_OK || uHttpStatusCode == HTTP_STATUS_PARTIAL_CONTENT;
	if (!bExpectData){
		CString strError;
		strError.Format(_T("Unexpected HTTP status code \"%u\""), uHttpStatusCode);
		throw strError;
	}

	uint64 uContentLength = 0;
	bool bCacheHit = false;
	bool bValidContentRange = false;
	for (int i = 1; i < astrHeaders.GetCount(); i++)
	{
		const CStringA& rstrHdr = astrHeaders.GetAt(i);
		if (bExpectData && strnicmp(rstrHdr, "Content-Length:", 15) == 0)
		{
			uContentLength = _atoi64((LPCSTR)rstrHdr + 15);
			if (uContentLength > m_uReqEnd - m_uReqStart + 1){
				CString strError;
				strError.Format(_T("Unexpected HTTP header field \"%hs\""), rstrHdr);
				throw strError;
			}
		}
		else if (bExpectData && strnicmp(rstrHdr, "Content-Range:", 14) == 0)
		{
			uint64 ui64Start = 0, ui64End = 0, ui64Len = 0;
			if (sscanf((LPCSTR)rstrHdr + 14," bytes %I64u - %I64u / %I64u", &ui64Start, &ui64End, &ui64Len) != 3){
				CString strError;
				strError.Format(_T("Unexpected HTTP header field \"%hs\""), rstrHdr);
				throw strError;
			}

			if (ui64Start > ui64End 
				|| ui64Len != reqfile->GetFileSize()
				|| ui64Start < m_uReqStart || ui64Start > m_uReqEnd 
				|| ui64End < m_uReqStart || ui64End > m_uReqEnd){
				CString strError;
				strError.Format(_T("Unexpected HTTP header field \"%hs\""), rstrHdr);
				throw strError;
			}
			bValidContentRange = true;
			m_nUrlStartPos = ui64Start;
		}
		else if (strnicmp(rstrHdr, "Server:", 7) == 0)
		{
			if (m_strClientSoftware.IsEmpty())
				m_strClientSoftware = rstrHdr.Mid(7).Trim();
		}
		else if (bExpectData && strnicmp(rstrHdr, "X-Cache: MISS", 13) == 0)
		{
			bCacheHit = false;
		}
		else if (bExpectData && strnicmp(rstrHdr, "X-Cache: HIT", 12) == 0)
		{
			bCacheHit = true;
		}
	}

	// we either get a 'Content-Range' or (for very small files) just a 'Content-Length' for the entire file
	if (!bValidContentRange && uContentLength == reqfile->GetFileSize())
	{
		bValidContentRange = true;
		m_nUrlStartPos = 0;
	}

	if (!bValidContentRange){
		if (thePrefs.GetDebugClientTCPLevel() <= 0)
			DebugHttpHeaders(astrHeaders);
		CString strError;
		strError.Format(_T("Unexpected HTTP response - No valid HTTP content range found"));
		throw strError;
	}

	if (m_pPCDownSocket)
	{
		CSafeMemFile dataAck(128);
		dataAck.WriteUInt8( bCacheHit ? 1 : 0 );
		if (thePrefs.GetDebugClientTCPLevel() > 0){
			DebugSend("OP__PeerCacheAck", this, reqfile->GetFileHash());
			Debug(_T("  %s\n"), bCacheHit ? _T("CacheHit") : _T("CacheMiss"));
		}

		Packet* pEd2kPacket = new Packet(&dataAck, OP_EMULEPROT, OP_PEERCACHE_ACK);
		theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size);
		socket->SendPacket(pEd2kPacket);
	}

//	SetDownloadState(DS_DOWNLOADING);

	//PC-TODO: Where does this flag need to be cleared again? 
	// When client is allowed to send more block requests?
	// Also, we have to support both type of downloads within in the same connection.
	SetPeerCacheDownState(PCDS_DOWNLOADING);
	m_bPeerCacheDownHit = bCacheHit;

	return true;
}
Ejemplo n.º 13
0
bool CClientUDPSocket::ProcessPacket(const BYTE* packet, uint16 size, uint8 opcode, uint32 ip, uint16 port)
{
	switch(opcode)
	{
		case OP_REASKCALLBACKUDP:
		{
			if (thePrefs.GetDebugClientUDPLevel() > 0)
				DebugRecv("OP_ReaskCallbackUDP", NULL, NULL, ip);
			theStats.AddDownDataOverheadOther(size);
			CUpDownClient* buddy = theApp.clientlist->GetBuddy();
			if( buddy )
			{
				if( size < 17 || buddy->socket == NULL )
					break;
				if (!md4cmp(packet, buddy->GetBuddyID()))
				{
					PokeUInt32(const_cast<BYTE*>(packet)+10, ip);
					PokeUInt16(const_cast<BYTE*>(packet)+14, port);
					Packet* response = new Packet(OP_EMULEPROT);
					response->opcode = OP_REASKCALLBACKTCP;
					response->pBuffer = new char[size];
					memcpy(response->pBuffer, packet+10, size-10);
					response->size = size-10;
					if (thePrefs.GetDebugClientTCPLevel() > 0)
						DebugSend("OP__ReaskCallbackTCP", buddy);
					theStats.AddUpDataOverheadFileRequest(response->size);
					buddy->socket->SendPacket(response);
				}
			}
			break;
		}
		case OP_REASKFILEPING:
		{
			theStats.AddDownDataOverheadFileRequest(size);
			CSafeMemFile data_in(packet, size);
			uchar reqfilehash[16];
			data_in.ReadHash16(reqfilehash);
			CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(reqfilehash);
			if (!reqfile)
			{
				if (thePrefs.GetDebugClientUDPLevel() > 0) {
					DebugRecv("OP_ReaskFilePing", NULL, reqfilehash, ip);
					DebugSend("OP__FileNotFound", NULL);
				}

				Packet* response = new Packet(OP_FILENOTFOUND,0,OP_EMULEPROT);
				theStats.AddUpDataOverheadFileRequest(response->size);
				SendPacket(response, ip, port);
				break;
			}
			CUpDownClient* sender = theApp.uploadqueue->GetWaitingClientByIP_UDP(ip, port);
			if (sender)
			{
				if (thePrefs.GetDebugClientUDPLevel() > 0)
					DebugRecv("OP_ReaskFilePing", sender, reqfilehash);

				//Make sure we are still thinking about the same file
				if (md4cmp(reqfilehash, sender->GetUploadFileID()) == 0)
				{
					sender->AddAskedCount();
					sender->SetLastUpRequest();
					//I messed up when I first added extended info to UDP
					//I should have originally used the entire ProcessExtenedInfo the first time.
					//So now I am forced to check UDPVersion to see if we are sending all the extended info.
					//For now on, we should not have to change anything here if we change
					//anything to the extended info data as this will be taken care of in ProcessExtendedInfo()
					//Update extended info. 
					if (sender->GetUDPVersion() > 3)
					{
						sender->ProcessExtendedInfo(&data_in, reqfile);
					}
					//Update our complete source counts.
					else if (sender->GetUDPVersion() > 2)
					{
						uint16 nCompleteCountLast= sender->GetUpCompleteSourcesCount();
						uint16 nCompleteCountNew = data_in.ReadUInt16();
						sender->SetUpCompleteSourcesCount(nCompleteCountNew);
						if (nCompleteCountLast != nCompleteCountNew)
						{
							reqfile->UpdatePartsInfo();
						}
					}
					CSafeMemFile data_out(128);
					if(sender->GetUDPVersion() > 3)
					{
						if (reqfile->IsPartFile())
							((CPartFile*)reqfile)->WritePartStatus(&data_out);
						else
							data_out.WriteUInt16(0);
					}
					data_out.WriteUInt16(theApp.uploadqueue->GetWaitingPosition(sender));
					if (thePrefs.GetDebugClientUDPLevel() > 0)
						DebugSend("OP__ReaskAck", sender);
					Packet* response = new Packet(&data_out, OP_EMULEPROT);
					response->opcode = OP_REASKACK;
					theStats.AddUpDataOverheadFileRequest(response->size);
					theApp.clientudp->SendPacket(response, ip, port);
				}
				else
				{
					DebugLogError(_T("Client UDP socket; ReaskFilePing; reqfile does not match"));
					TRACE(_T("reqfile:         %s\n"), DbgGetFileInfo(reqfile->GetFileHash()));
					TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)"));
				}
			}
			else
			{
				if (thePrefs.GetDebugClientUDPLevel() > 0)
					DebugRecv("OP_ReaskFilePing", NULL, reqfilehash, ip);

				if (((uint32)theApp.uploadqueue->GetWaitingUserCount() + 50) > thePrefs.GetQueueSize())
				{
					if (thePrefs.GetDebugClientUDPLevel() > 0)
						DebugSend("OP__QueueFull", NULL);
					Packet* response = new Packet(OP_QUEUEFULL,0,OP_EMULEPROT);
					theStats.AddUpDataOverheadFileRequest(response->size);
					SendPacket(response, ip, port);
				}
			}
			break;
		}
		case OP_QUEUEFULL:
		{
			theStats.AddDownDataOverheadFileRequest(size);
			CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
			if (thePrefs.GetDebugClientUDPLevel() > 0)
				DebugRecv("OP_QueueFull", sender, NULL, ip);
			if (sender){
				sender->SetRemoteQueueFull(true);
				sender->UDPReaskACK(0);
			}
			break;
		}
		case OP_REASKACK:
		{
			theStats.AddDownDataOverheadFileRequest(size);
			CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
			if (thePrefs.GetDebugClientUDPLevel() > 0)
				DebugRecv("OP_ReaskAck", sender, NULL, ip);
			if (sender){
				CSafeMemFile data_in(packet, size);
				if ( sender->GetUDPVersion() > 3 )
				{
					sender->ProcessFileStatus(true, &data_in, sender->GetRequestFile());
				}
				uint16 nRank = data_in.ReadUInt16();
				sender->SetRemoteQueueFull(false);
				sender->UDPReaskACK(nRank);
				sender->AddAskedCountDown();
			}
			break;
		}
		case OP_FILENOTFOUND:
		{
			theStats.AddDownDataOverheadFileRequest(size);
			CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
			if (thePrefs.GetDebugClientUDPLevel() > 0)
				DebugRecv("OP_FileNotFound", sender, NULL, ip);
			if (sender){
				sender->UDPReaskFNF(); // may delete 'sender'!
				sender = NULL;
			}
			break;
		}
		case OP_PORTTEST:
		{
			if (thePrefs.GetDebugClientUDPLevel() > 0)
				DebugRecv("OP_PortTest", NULL, NULL, ip);
			theStats.AddDownDataOverheadOther(size);
			if (size == 1){
				if (packet[0] == 0x12){
					bool ret = theApp.listensocket->SendPortTestReply('1', true);
					AddDebugLogLine(true, _T("UDP Portcheck packet arrived - ACK sent back (status=%i)"), ret);
				}
			}
			break;
		}
		default:
			theStats.AddDownDataOverheadOther(size);
			if (thePrefs.GetDebugClientUDPLevel() > 0)
			{
				CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
				Debug(_T("Unknown client UDP packet: host=%s:%u (%s) opcode=0x%02x  size=%u\n"), ipstr(ip), port, sender ? sender->DbgGetClientInfo() : _T(""), opcode, size);
			}
			return false;
	}
	return true;
}
Ejemplo n.º 14
0
void debug_parse(char *cmd_line)
{
	int params;
	unsigned int temp1,temp2,temp3,temp4;
	unsigned short tempword;
	unsigned char tempbyte;

	while (*cmd_line == ' ') cmd_line++;

	switch (toupper(*cmd_line++))
	{
	case '?':
		DebugPrint("\r\n Compile Date: %s, Time: %s",__DATE__,__TIME__);
		break;
	case 'A':  // assemble
		break;
	case 'B':
		break;
	case 'C':  // compare
		break;
	case 'D':  // dump
		params = sscanf(cmd_line,"%X %X",&temp2,&temp3);
		switch (params) {
		case 0:
			case EOF:
			dump_end = dump_beg + 127;
			do_dump();
			break;
		case 1:
			dump_beg = temp2;
			dump_end = dump_beg + 127;
			do_dump();
			break;
		case 2:
			if (temp3<temp2) temp3=temp2;
			dump_beg = temp2;
			dump_end = temp3;
			do_dump();
			break;
		}
		break;
	case 'E':  // read unsigned int
		if (sscanf(cmd_line,"%X",&temp1)==1)
			debug_port = (unsigned char*)(temp1&0xFFFFFFFC);
		temp2 = *(unsigned int*)debug_port;
		DebugPrint("\r\n %08X -> %08X",(int)debug_port,temp2);
//		debug_port += sizeof(int);
		break;
	case 'F':  // fill
		params = sscanf(cmd_line,"%X %X %X",&temp2,&temp3,&temp4);
		switch (params) {
		case 3:
			dump_end = temp3;
			for (old_dump_beg=temp2;old_dump_beg<=dump_end;old_dump_beg++)
			{
//				pokeb(dump_seg,old_dump_beg,temp4);
			}
			break;
		default:
			{
				DebugSend(" ?? \r\n");
			}
			break;
		}
		break;
	case 'G':  // go
		DebugInit();
		break;
	case 'H':  // hex
		break;
	case 'I':  // read byte
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			debug_port = (unsigned char*)temp1;
			tempbyte = *(unsigned char*)debug_port;
			DebugPrint("\r\n %08X -> %02X",(int)debug_port,tempbyte);
			debug_port += sizeof(tempbyte);
		}
		break;
	case 'J':  // read word
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			debug_port = (unsigned char*)(temp1&0xFFFFFFFE);
		}
		tempword = *(unsigned short*)debug_port;
		DebugPrint("\r\n %08X -> %04X",(int)debug_port,tempword);
		break;
	case 'K':
		break;
	case 'L':  // load
		break;
	case 'M':  // write unsigned int
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)(temp1&0xFFFFFFFC);
			DebugPrint("\r\n %08X <- %08X",(int)debug_port,temp2);
			*(unsigned int*)debug_port = temp2;
			debug_port += sizeof(int);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'N':  // name
		break;
	case 'O':  // output byte
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)temp1;
			tempbyte = temp2;
			DebugPrint("\r\n %08X <- %02X",(int)debug_port,tempbyte);
			*debug_port = tempbyte;
			debug_port += sizeof(tempbyte);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'P':  // proceed
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'Q':  // quit
		DebugSend("\r\nYou can't quit now!");
		break;
	case 'R':  // register
		break;
	case 'S':  // search
		if (sscanf(cmd_line,"%X",&temp2)==1)
		{
		}
		break;
	case 'T':  // Test
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
			bTest = !bTest;
			if (bTest)
			{
				ResetTimer(BLINK_TIMER);
				StartTimer(BLINK_TIMER, 500);
				DebugSend("\r\n LED Blink Started.");
			}
			else
			{
				DebugSend("\r\n LED Blink Stopped.");
			}
		}
		break;
	case 'U':
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:	//U5
				break;
			case 6:	//U6
				break;
			case 7:	//U7
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'W':  // write word
		if (sscanf(cmd_line,"%X %X",&temp1,&temp2)==2)
		{
			debug_port = (unsigned char*)(temp1&0xFFFFFFFE);
			tempword = temp2;
			DebugPrint("\r\n %08X <- %04X",(int)debug_port,tempword);
			*(unsigned short*)debug_port = tempword;
			debug_port += sizeof(tempword);
		}
		else
		{
			DebugSend(" ?? \r\n");
		}
		break;
	case 'X':
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'Y':
		temp4 = sscanf(cmd_line,"%X %X",&temp1,&temp2);
		if (temp4>=1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	case 'Z':
		if (sscanf(cmd_line,"%i %i",&temp1,&temp2)==2)
		{
		}
		else
		if (sscanf(cmd_line,"%X",&temp1)==1)
		{
			switch (temp1){
			case 0:
				break;
			case 1:
				break;
			case 2:
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			case 9:
				break;
			}
		}
		else
		{
		}
		break;
	default:
		;
	}
}