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

📄 kademliaudplistener.cpp

📁 电驴的源程序,想学网络编程的可以下载来看看.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// Verify packet is expected size
	if (uLenPacket != (UINT)(16+1 + (16+4+2+2+1)*uNumContacts))
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	ContactList *pResults = new ContactList;
	CUInt128 uIDResult;
	try
	{
		for (uint16 iIndex=0; iIndex<uNumContacts; iIndex++)
		{
			fileIO.ReadUInt128(&uIDResult);
			uint32 uIPResult = fileIO.ReadUInt32();
			uint16 uUDPPortResult = fileIO.ReadUInt16();
			uint16 uTCPPortResult = fileIO.ReadUInt16();
			fileIO.ReadUInt8();
			uint32 uhostIPResult = ntohl(uIPResult);
			if (::IsGoodIPPort(uhostIPResult, uUDPPortResult))
			{
				if (!::theApp.ipfilter->IsFiltered(uhostIPResult)) {
					pRoutingZone->AddUnfiltered(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, 0, false);
					pResults->push_back(new CContact(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uTarget, 0));
				}
				else if (::thePrefs.GetLogFilteredIPs())
					AddDebugLogLine(false, _T("Ignored kad contact (IP=%s) - IP filter (%s)") , ipstr(uhostIPResult), ::theApp.ipfilter->GetLastHit());
			}
			else if (::thePrefs.GetLogFilteredIPs())
				AddDebugLogLine(false, _T("Ignored kad contact (IP=%s) - Bad IP"), ipstr(uhostIPResult));
		}
	}
	catch(...)
	{
		for (ContactList::const_iterator it = pResults->begin(); it != pResults->end(); ++it)
			delete *it;
		delete pResults;
		throw;
	}
	CSearchManager::ProcessResponse(uTarget, uIP, uUDPPort, pResults);
}

// Used in Kad2.0 only
void CKademliaUDPListener::Process_KADEMLIA2_RES (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	if (!IsOnTrackList(uIP, KADEMLIA2_REQ)){
		CString strError;
		strError.Format(_T("***NOTE: Received unrequested repsonse packet, size (%u) in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	//Used Pointers
	CRoutingZone *pRoutingZone = CKademlia::GetRoutingZone();

	if(CKademlia::GetPrefs()->GetRecheckIP())
	{
		FirewalledCheck(uIP, uUDPPort);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
			DebugSend("KADEMLIA2_HELLO_REQ", uIP, uUDPPort);
		SendMyDetails(KADEMLIA2_HELLO_REQ, uIP, uUDPPort, true);
	}

	// What search does this relate to
	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	uint8 uNumContacts = fileIO.ReadUInt8();

	// Verify packet is expected size
	if (uLenPacket != (UINT)(16+1 + (16+4+2+2+1)*uNumContacts))
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	ContactList *pResults = new ContactList;
	CUInt128 uIDResult;
	try
	{
		for (uint8 iIndex=0; iIndex<uNumContacts; iIndex++)
		{
			fileIO.ReadUInt128(&uIDResult);
			uint32 uIPResult = fileIO.ReadUInt32();
			uint16 uUDPPortResult = fileIO.ReadUInt16();
			uint16 uTCPPortResult = fileIO.ReadUInt16();
			uint8 uVersion = fileIO.ReadUInt8();
			uint32 uhostIPResult = ntohl(uIPResult);
			if (::IsGoodIPPort(uhostIPResult, uUDPPortResult))
			{
				if (!::theApp.ipfilter->IsFiltered(uhostIPResult)) {
					pRoutingZone->AddUnfiltered(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uVersion, false);
					pResults->push_back(new CContact(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uTarget, uVersion));
				}
				else if (::thePrefs.GetLogFilteredIPs())
					AddDebugLogLine(false, _T("Ignored kad contact (IP=%s) - IP filter (%s)") , ipstr(uhostIPResult), ::theApp.ipfilter->GetLastHit());
			}
			else if (::thePrefs.GetLogFilteredIPs())
				AddDebugLogLine(false, _T("Ignored kad contact (IP=%s) - Bad IP"), ipstr(uhostIPResult));
		}
	}
	catch(...)
	{
		for (ContactList::const_iterator it = pResults->begin(); it != pResults->end(); ++it)
			delete *it;
		delete pResults;
		throw;
	}
	CSearchManager::ProcessResponse(uTarget, uIP, uUDPPort, pResults);
}

void CKademliaUDPListener::Free(SSearchTerm* pSearchTerms)
{
	if(pSearchTerms)
	{
		if (pSearchTerms->m_pLeft)
			Free(pSearchTerms->m_pLeft);
		if (pSearchTerms->m_pRight)
			Free(pSearchTerms->m_pRight);
		delete pSearchTerms;
	}
}

static void TokenizeOptQuotedSearchTerm(LPCTSTR pszString, CStringWArray* lst)
{
	LPCTSTR pch = pszString;
	while (*pch != _T('\0'))
	{
		if (*pch == _T('\"'))
		{
			// Start of quoted string found. If there is no terminating quote character found,
			// the start quote character is just skipped. If the quoted string is empty, no
			// new entry is added to 'list'.
			//
			pch++;
			LPCTSTR pchNextQuote = _tcschr(pch, _T('\"'));
			if (pchNextQuote)
			{
				size_t nLenQuoted = pchNextQuote - pch;
				if (nLenQuoted)
					lst->Add(CString(pch, nLenQuoted));
				pch = pchNextQuote + 1;
			}
		}
		else
		{
			// Search for next delimiter or quote character
			//
			size_t nNextDelimiter = _tcscspn(pch, _T(INV_KAD_KEYWORD_CHARS) _T("\""));
			if (nNextDelimiter)
			{
				lst->Add(CString(pch, nNextDelimiter));
				pch += nNextDelimiter;
				if (*pch == _T('\0'))
					break;
				if (*pch == _T('\"'))
					continue;
			}
			pch++;
		}
	}
}

static CString* _pstrDbgSearchExpr;

SSearchTerm* CKademliaUDPListener::CreateSearchExpressionTree(CSafeMemFile& fileIO, int iLevel)
{
	// the max. depth has to match our own limit for creating the search expression
	// (see also 'ParsedSearchExpression' and 'GetSearchPacket')
	if (iLevel >= 24)
	{
		AddDebugLogLine(false, _T("***NOTE: Search expression tree exceeds depth limit!"));
		return NULL;
	}
	iLevel++;

	uint8 uOp = fileIO.ReadUInt8();
	if (uOp == 0x00)
	{
		uint8 uBoolOp = fileIO.ReadUInt8();
		if (uBoolOp == 0x00) // AND
		{
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->m_type = SSearchTerm::AND;
			if (_pstrDbgSearchExpr)
				_pstrDbgSearchExpr->Append(_T(" AND"));
			if ((pSearchTerm->m_pLeft = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->m_pRight = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				Free(pSearchTerm->m_pLeft);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else if (uBoolOp == 0x01) // OR
		{
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->m_type = SSearchTerm::OR;
			if (_pstrDbgSearchExpr)
				_pstrDbgSearchExpr->Append(_T(" OR"));
			if ((pSearchTerm->m_pLeft = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->m_pRight = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				Free(pSearchTerm->m_pLeft);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else if (uBoolOp == 0x02) // NOT
		{
			SSearchTerm* pSearchTerm = new SSearchTerm;
			pSearchTerm->m_type = SSearchTerm::NOT;
			if (_pstrDbgSearchExpr)
				_pstrDbgSearchExpr->Append(_T(" NOT"));
			if ((pSearchTerm->m_pLeft = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				delete pSearchTerm;
				return NULL;
			}
			if ((pSearchTerm->m_pRight = CreateSearchExpressionTree(fileIO, iLevel)) == NULL)
			{
				ASSERT(0);
				Free(pSearchTerm->m_pLeft);
				delete pSearchTerm;
				return NULL;
			}
			return pSearchTerm;
		}
		else
		{
			AddDebugLogLine(false, _T("*** Unknown boolean search operator 0x%02x (CreateSearchExpressionTree)"), uBoolOp);
			return NULL;
		}
	}
	else if (uOp == 0x01) // String
	{
		CKadTagValueString str(fileIO.ReadStringUTF8());

		KadTagStrMakeLower(str); // make lowercase, the search code expects lower case strings!
		if (_pstrDbgSearchExpr)
			_pstrDbgSearchExpr->AppendFormat(_T(" \"%ls\""), str);

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->m_type = SSearchTerm::String;
		pSearchTerm->m_pastr = new CStringWArray;

		// pre-tokenize the string term (care about quoted parts)
		TokenizeOptQuotedSearchTerm(str, pSearchTerm->m_pastr);

		return pSearchTerm;
	}
	else if (uOp == 0x02) // Meta tag
	{
		// read tag value
		CKadTagValueString strValue(fileIO.ReadStringUTF8());

		KadTagStrMakeLower(strValue); // make lowercase, the search code expects lower case strings!

		// read tag name
		CStringA strTagName;
		uint16 lenTagName = fileIO.ReadUInt16();
		fileIO.Read(strTagName.GetBuffer(lenTagName), lenTagName);
		strTagName.ReleaseBuffer(lenTagName);

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->m_type = SSearchTerm::MetaTag;
		pSearchTerm->m_pTag = new Kademlia::CKadTagStr(strTagName, strValue);
		if (_pstrDbgSearchExpr)
		{
			if (lenTagName == 1)
				_pstrDbgSearchExpr->AppendFormat(_T(" Tag%02X=\"%ls\""), (BYTE)strTagName[0], strValue);
			else
				_pstrDbgSearchExpr->AppendFormat(_T(" \"%s\"=\"%ls\""), strTagName, strValue);
		}
		return pSearchTerm;
	}
	else if (uOp == 0x03 || uOp == 0x08) // Numeric Relation (0x03=32-bit or 0x08=64-bit)
	{
		static const struct
		{
			SSearchTerm::ESearchTermType eSearchTermOp;
			LPCTSTR pszOp;
		}
		_aOps[] =
		    {
		        { SSearchTerm::OpEqual,			_T("=")		}, // mmop=0x00
		        { SSearchTerm::OpGreater,		_T(">")		}, // mmop=0x01
		        { SSearchTerm::OpLess,			_T("<")		}, // mmop=0x02
		        { SSearchTerm::OpGreaterEqual,	_T(">=")	}, // mmop=0x03
		        { SSearchTerm::OpLessEqual,		_T("<=")	}, // mmop=0x04
		        { SSearchTerm::OpNotEqual,		_T("<>")	}  // mmop=0x05
		    };

		// read tag value
		uint64 ullValue = (uOp == 0x03) ? fileIO.ReadUInt32() : fileIO.ReadUInt64();

		// read integer operator
		uint8 mmop = fileIO.ReadUInt8();
		if (mmop >= ARRSIZE(_aOps))
		{
			AddDebugLogLine(false, _T("*** Unknown integer search op=0x%02x (CreateSearchExpressionTree)"), mmop);
			return NULL;
		}

		// read tag name
		CStringA strTagName;
		uint16 uLenTagName = fileIO.ReadUInt16();
		fileIO.Read(strTagName.GetBuffer(uLenTagName), uLenTagName);
		strTagName.ReleaseBuffer(uLenTagName);

		SSearchTerm* pSearchTerm = new SSearchTerm;
		pSearchTerm->m_type = _aOps[mmop].eSearchTermOp;
		pSearchTerm->m_pTag = new Kademlia::CKadTagUInt64(strTagName, ullValue);

		if (_pstrDbgSearchExpr)
		{
			if (uLenTagName == 1)
				_pstrDbgSearchExpr->AppendFormat(_T(" Tag%02X%s%I64u"), (BYTE)strTagName[0], _aOps[mmop].pszOp, ullValue);
			else
				_pstrDbgSearchExpr->AppendFormat(_T(" \"%s\"%s%I64u"), strTagName, _aOps[mmop].pszOp, ullValue);
		}

		return pSearchTerm;
	}
	else
	{
		AddDebugLogLine(false, _T("*** Unknown search op=0x%02x (CreateSearchExpressionTree)"), uOp);
		return NULL;
	}
}

// Used in Kad1.0 only
void CKademliaUDPListener::Process_KADEMLIA_SEARCH_REQ (const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 uUDPPort)
{
	// Verify packet is expected size
	if (uLenPacket < 17)
	{
		CString strError;
		strError.Format(_T("***NOTE: Received wrong size (%u) packet in %hs"), uLenPacket, __FUNCTION__);
		throw strError;
	}

	CSafeMemFile fileIO( pbyPacketData, uLenPacket);
	CUInt128 uTarget;
	fileIO.ReadUInt128(&uTarget);
	uint8 uRestrictive = fileIO.ReadUInt8();

	if(uLenPacket == 17 )
	{
		if(uRestrictive)
			CKademlia::GetIndexed()->SendValidSourceResult(uTarget, uIP, uUDPPort, false, 0, 0);
		else
			CKademlia::GetIndexed()->SendValidKeywordResult(uTarget, NULL, uIP, uUDPPort, true, false, 0);
	}
	else if(uLenPacket > 17)
	{
		SSearchTerm* pSearchTerms = NULL;
		bool bOldClient = true;
		if (uRestrictive)
		{
			try
			{
#if defined(_DEBUG) || defined(USE_DEBUG_DEVICE)
				_pstrDbgSearchExpr = (thePrefs.GetDebugServerSearchesLevel() > 0) ? new CString : NULL;
#endif

				pSearchTerms = CreateSearchExpressionTree(fileIO, 0);
				if (_pstrDbgSearchExpr)
				{
					Debug(_T("KadSearchTerm=%s\n"), *_pstrDbgSearchExpr);
					delete _pstrDbgSearchExpr;
					_pstrDbgSearchExpr = NULL;
				}
			}
			catch(...)
			{
				delete _pstrDbgSearchExpr;
				_pstrDbgSearchExpr = NULL;
				Free(pSearchTerms);
				throw;
			}
			if (pSearchTerms == NULL)
				throw CString(_T("Invalid search expression"));
			if(uRestrictive>1)
				bOldClient = false;
		}
		else
			bOldClient = false;

		//Keyword request with added options.

⌨️ 快捷键说明

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