Example #1
0
CVariant CKadOperation::AddLoadRes(const CVariant& LoadRes, CKadNode* pNode)
{
	SOpProgress* pProgress = GetProgress(pNode);

	CVariant FilteredRes = LoadRes.Clone(false); // Make a Shellow Copy
	const CVariant& LoadedList = LoadRes["RES"];

	CVariant FilteredList;
	for(uint32 i=0; i < LoadedList.Count(); i++)
	{
		CVariant Loaded = LoadedList.At(i).Clone(false); // Make a Shellow Copy
		const CVariant& XID = Loaded["XID"];

		// Counting
		if(pProgress) // might be NULL if we filter our own index response right now
		{
			SOpStatus &Status = pProgress->Loads[XID];
			Status.Results++;
			if(!Loaded.Get("MORE"))
				Status.Done = true; // this marks that no more results are to be expected form this node
		}

		SOpStatus* pStatus = &m_LoadMap[XID].Status;
		pStatus->Results++;
		if(!pStatus->Done)
			pStatus->Done = IsDone(SOpProgress::GetLoads, XID);
		
		if(!pStatus->Done)
			Loaded.Insert("MORE", true);
		else
			Loaded.Remove("MORE");
		//

		if(Loaded.Has("ERR"))
		{
			FilteredList.Append(Loaded);
			continue;
		}

		// Filtering
		CVariant UniquePayloads;
		const CVariant& Payloads = Loaded["PLD"];
		for(uint32 j=0; j < Payloads.Count(); j++)
		{
			const CVariant& Payload = Payloads.At(j);
			if(m_LoadFilter[XID].insert(Payload["DATA"].GetFP()).second)
				UniquePayloads.Append(Payload);
		}

		// Note: we must add this even if UniquePayloads is empty or else we will misscount replys
		CVariant NewLoaded;
		NewLoaded["XID"] = XID;
		NewLoaded["PLD"] = UniquePayloads;
		FilteredList.Append(NewLoaded);
		//
	}

	FilteredRes.Insert("RES", FilteredList);
	return FilteredRes;
}
Example #2
0
void CKadHandler::HandleNodeReq(const CVariant& NodeReq, CKadNode* pNode, CComChannel* pChannel)
{
	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Recived 'Node Resuest' to %s", pNode->GetID().ToHex().c_str());

	CVariant NodeRes;

	uint32 uDesiredCount = NodeReq["RCT"];
	if(uDesiredCount == 0)
		throw CException(LOG_ERROR, L"node requested 0 nodes");

	int iMaxState = NodeReq.Get("MNC", NODE_2ND_CLASS);

	NodeMap Nodes;
	if(!NodeReq.Has("TID"))
		GetParent<CKademlia>()->Root()->GetBootstrapNodes(GetParent<CKademlia>()->Root()->GetID(), Nodes, uDesiredCount, pChannel->GetAddress().GetProtocol(), iMaxState);
	else
		GetParent<CKademlia>()->Root()->GetClosestNodes(NodeReq["TID"], Nodes, uDesiredCount, pChannel->GetAddress().GetProtocol(), iMaxState);
	
	CVariant List;
	for(NodeMap::iterator I = Nodes.begin(); I != Nodes.end(); I++)
		List.Append(I->second->Store());
	NodeRes["LIST"] = List;

	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Sending 'Node Response' to %s", pNode->GetID().ToHex().c_str());
	pChannel->QueuePacket(KAD_NODE_RESPONSE, NodeRes);
}
Example #3
0
CVariant CKadNode::Store(bool bFull) const
{
	CVariant Node;
	Node["PROT"] = m_Protocol;
	Node["NID"] = m_ID;

	CVariant Addr;
	for(AddressMap::const_iterator I = m_AddressMap.begin(); I != m_AddressMap.end(); I++)
	{
		if(bFull)
			Addr.Append(I->second.ToExtVariant());
		else
			Addr.Append(I->second.ToVariant());
	}
	Node["ADDR"] = Addr;

	Node["VER"] = m_Version;
	if(bFull)
	{
		Node["FSEN"] = m_uFirstSeen;
		Node["LSEN"] = m_uLastSeen;
	}
	return Node;
}
Example #4
0
void CKadHandler::HandleRouteRes(const CVariant& RouteRes, CKadNode* pNode, CComChannel* pChannel)
{
	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRU"))
		LogLine(LOG_DEBUG, L"Recived 'Route Response' from %s", pNode->GetID().ToHex().c_str());

	SKadData* pData = pChannel->GetData<SKadData>();
	CKadRelay* pRelay = pData->pLookup->Cast<CKadRelay>();
	if(!pRelay)
		throw CException(LOG_ERROR, L"Recived Route Response for a lookup that is not a CKadRelay");

	// Note: this is for trace only, it does not have any deeper purpose
	if(pRelay->IsTraced())
	{
		CVariant Trace = RouteRes.Get("TRACE").Clone();
		Trace.Append(pNode->GetID());

		if(!pRelay->Inherits("CKadRoute")) // if its just a relay we have to relay the trace back
		{
			CVariant RouteRel;
			RouteRel["TID"] = RouteRes["TID"]; // pRelay->GetID()
			RouteRel["TRACE"] = Trace;

			if(CFrameRelay* pDownLink = pRelay->GetDownLink())
			{
				CFrameRelay::TRelayMap& DownNodes = pDownLink->GetNodes();
				for(CFrameRelay::TRelayMap::iterator I = DownNodes.begin(); I != DownNodes.end(); I++)
				{
					if(I->first.pChannel->IsConnected())
					{
						if(GetParent<CKademlia>()->Cfg()->GetBool("DebugLU"))
							LogLine(LOG_DEBUG, L"Relaying 'Route Response' from %s to %s", pNode->GetID().ToHex().c_str(), I->first.pNode->GetID().ToHex().c_str());
						I->first.pChannel->QueuePacket(KAD_ROUTE_RESPONSE, RouteRel);
					}
				}
			}
		}
		else
			pRelay->RecivedTraceResults(Trace);
	}

	if(RouteRes.Has("TRACE")) // if this is set its a pro forma trace response ignore it
		return;
	
	pRelay->UpLinkResponse(pNode, pChannel, RouteRes.Get("ERR"));
}
Example #5
0
void CKadHandler::SendHello(CKadNode* pNode, CComChannel* pChannel, bool bReq)
{
	SKadData* pData = pChannel->GetData<SKadData>();

	CVariant Hello(CVariant::EMap);

	CVariant Addr;
	TMyAddressMap AddressMap = GetParent<CKademlia>()->Fwh()->AddrPool();
	for(TMyAddressMap::const_iterator I = AddressMap.begin(); I != AddressMap.end(); I++)
		Addr.Append(I->second.ToVariant());
	Hello["ADDR"] = Addr;

	pNode->SetLastHello();

	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Sending 'Hello %s' to %s", bReq ? L"Request" : L"Response", pNode->GetID().ToHex().c_str());
	pChannel->QueuePacket(bReq ? KAD_HELLO_REQUEST : KAD_HELLO_RESPONSE, Hello);
}
Example #6
0
void CKademlia::SaveNodes()
{
	wstring ConfigPath = Cfg()->GetString("ConfigPath");
	if(ConfigPath.empty())
		return;

	NodeList Nodes = m_pRootZone->GetAllNodes();

	CVariant NodeList;
	for (NodeList::iterator I = Nodes.begin(); I != Nodes.end(); I++)
	{
		CKadNode* pNode = *I;
		NodeList.Append(pNode->Store(true));
	}
	CVariant NeoNodes;
	NeoNodes["Nodes"] = NodeList;
	NeoNodes["LastContact"] = m_pKadHandler->GetLastContact();
	WriteFile(ConfigPath + L"NeoNodes.dat", NeoNodes);
}
Example #7
0
CVariant CKadOperation::AddStoreRes(const CVariant& StoreRes, CKadNode* pNode)
{
	SOpProgress* pProgress = GetProgress(pNode);

	CVariant FilteredRes = StoreRes.Clone(false); // Make a Shellow Copy
	const CVariant& StoredList = StoreRes["RES"];

	CVariant FilteredList;
	for(uint32 i=0; i < StoredList.Count(); i++)
	{
		CVariant Stored = StoredList.At(i).Clone(false); // Make a Shellow Copy
		const CVariant& XID = Stored["XID"];

		// Counting
		if(pProgress) // might be NULL if we filter our own index response right now
		{
			SOpStatus &Status = pProgress->Stores[XID];
			Status.Results++;
			if(!Stored.Get("MORE"))
				Status.Done = true; // this marks that no more results are to be expected form this node
		}

		SOpStatus* pStatus = &m_StoreMap[XID].Status;
		pStatus->Results++;
		if(!pStatus->Done)
			pStatus->Done = IsDone(SOpProgress::GetStores, XID);

		if(!pStatus->Done)
			Stored.Insert("MORE", true);
		else
			Stored.Remove("MORE");
		//

		//m_StoredCounter[Stored["XID"]].push_back(Stored.Get("EXP", 0)); // on error there is no EXP

		FilteredList.Append(Stored);
	}
	
	FilteredRes.Insert("RES", FilteredList);
	return FilteredRes;
}
Example #8
0
CVariant CKadOperation::AddCallRes(const CVariant& CallRes, CKadNode* pNode)
{
	SOpProgress* pProgress = GetProgress(pNode);

	CVariant FilteredRes = CallRes.Clone(false); // Make a Shellow Copy
	const CVariant& Results = CallRes["RET"];

	CVariant Filtered;
	for(uint32 i=0; i < Results.Count(); i++)
	{
        CVariant Result = Results.At(i).Clone(false); // Make a Shellow Copy
		const CVariant& XID = Result["XID"];

		// this checks if this particular response is the last and and if this node is done
		if(pProgress) // might be NULL if we filter our own index response right now
		{
			SOpStatus &Status = pProgress->Calls[XID];
			Status.Results++;
			if(!Result.Get("MORE"))
				Status.Done = true; // this marks that no more results are to be expected form this node
		}

		SOpStatus* pStatus = NULL;
		TCallOpMap::iterator I = m_CallMap.find(XID);
		if(I != m_CallMap.end())
		{
			pStatus = &I->second.Status;
			pStatus->Results++; // count the response even if it gets filtered lateron
			if(!pStatus->Done)
				pStatus->Done = IsDone(SOpProgress::GetCalls, XID);
		}

		if(m_pOperator)
		{
			CKadOperator::TRequestMap& ResuestMap = m_pOperator->GetRequests();
			CKadOperator::TRequestMap::iterator I = ResuestMap.find(XID);
			if(I != ResuestMap.end()) // this should not fail
			{
				SOpStatus* pAuxStatus = &I->second.Status;
				pAuxStatus->Results++; // count the response even if it gets filtered lateron
				if(!pAuxStatus->Done)
					pAuxStatus->Done = IsDone(SOpProgress::GetCalls, XID);
			}
		}

		if(!Result.Has("ERR"))
		{
			if(m_pOperator && m_pOperator->IsValid())
			{
				try
				{
					if(m_pOperator->AddCallRes(Result["RET"], XID))
						continue; // intercepted response - Note: if we add a response to this request now it wil be marked as no more results if thats so
				}
				catch(const CJSException& Exception)
				{
					LogReport(Exception.GetFlag(), Exception.GetLine(), Exception.GetError());
				}
			}
		}
		//else 
		//	LogLine(LOG_ERROR | LOG_DEBUG, L"Got Execution Error %s", Result["ERR"].To<wstring>().c_str());

		// check if this is a call we issued, that is one not present in the call map, in that case its never to be relayed
		if(pStatus)
		{
			// UpdateMore sets the "MORE" flag on the packet we relay further down to the source, and checks if we considder this request done
			if(!pStatus->Done)
				Result.Insert("MORE", true);
			else
				Result.Remove("MORE");

			Filtered.Append(Result);
		}
	}

	if(m_pOperator) // add new result to the filtered list
		Filtered.Merge(m_pOperator->GetResponses());
	FilteredRes.Insert("RET", Filtered);
	return FilteredRes;
}
Example #9
0
void CKadOperation::SendRequests(CKadNode* pNode, CComChannel* pChannel, SOpProgress* pProgress, bool bStateless)
{
	CKadHandler* pHandler = GetParent<CKademlia>()->Handler();

	CVariant Calls;
	if(m_pOperator)
	{
		const CKadOperator::TRequestMap& ResuestMap = m_pOperator->GetRequests();
		for(CKadOperator::TRequestMap::const_iterator I = ResuestMap.begin(); I != ResuestMap.end(); I++)
		{
			CKadRequest* pRequest = I->second.pRequest;
			if(pProgress->Calls.insert(TStatusMap::value_type(pRequest->GetXID(), SOpStatus())).second) // check if we already dealed this task
			{
				CVariant Call;
				Call["FX"] = pRequest->GetName();
				Call["ARG"] = pRequest->GetArguments();
				Call["XID"] = pRequest->GetXID();
				Calls.Append(Call);
			}
		}
	}
	else
	{
		for(TCallOpMap::const_iterator I = m_CallMap.begin(); I != m_CallMap.end(); I++)
		{
			CVariant Call = I->second.Call;
			if(pProgress->Calls.insert(TStatusMap::value_type(Call["XID"], SOpStatus())).second) // check if we already dealed this task
				Calls.Append(Call);
		}
	}
	if(Calls.Count() > 0)
		pHandler->SendExecuteReq(pNode, pChannel, this, Calls, bStateless);

	CVariant Stores;
	for(TStoreOpMap::const_iterator I = m_StoreMap.begin(); I != m_StoreMap.end(); I++)
	{
		if(pProgress->Stores.insert(TStatusMap::value_type(I->first, SOpStatus())).second) // check if we already dealed this task
		{
			CVariant Store;
			Store["XID"] = I->first;
			Store["PLD"] = I->second.Payload;
			Stores.Append(Store);
		}
	}
	if(Stores.Count() > 0)
		pHandler->SendStoreReq(pNode, pChannel, this, Stores, bStateless);
			
	CVariant Loads;
	for(TLoadOpMap::const_iterator I = m_LoadMap.begin(); I != m_LoadMap.end(); I++)
	{
		if(pProgress->Loads.insert(TStatusMap::value_type(I->first, SOpStatus())).second) // check if we already dealed this task
		{
			CVariant Load;
			Load["XID"] = I->first;
			Load["PATH"] = I->second.Path;
			Loads.Append(Load);
		}
	}
	if(Loads.Count() > 0)
		pHandler->SendLoadReq(pNode, pChannel, this, Loads, bStateless);
}