Example #1
0
void CKadHandler::HandleNodeRes(const CVariant& NodeRes, CKadNode* pNode, CComChannel* pChannel)
{
	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Recived 'Node Response' from %s", pNode->GetID().ToHex().c_str());

	CVariant List = NodeRes["LIST"];
	if(List.Count() > (uint32)GetParent<CKademlia>()->Cfg()->GetInt("NodeReqCount"))
		throw CException(LOG_ERROR, L"Node returned more nodes than requested (spam)");
	
	SKadData* pData = pChannel->GetData<SKadData>();
	// Note: if pData->pLookup is NULL this was just a bootstrap request

	NodeMap Nodes;
	for(uint32 i = 0; i<List.Count(); i++)
	{
		CPointer<CKadNode> pNewNode = new CKadNode(GetParent<CKademlia>()->Root());
		pNewNode->Load(List.At(i));
		if(GetParent<CKademlia>()->Root()->AddNode(pNewNode) && pData->pLookup)
		{
			CUInt128 uDistance = pData->pLookup->GetID() ^ pNewNode->GetID();
			Nodes.insert(NodeMap::value_type(uDistance, pNewNode));
		}
	}

	if(pData->pLookup)
		GetParent<CKademlia>()->Manager()->AddNodes(pData->pLookup, pNode, pChannel, Nodes);
}
Example #2
0
void CLookupHistory::RecivedTraceResults(const CVariant& Trace)
{
	if(Trace.Count() < 1)
		return;

	CUInt128 PrevID = Trace.At(Trace.Count()-1);
	for(int i=Trace.Count()-2; i >= 0; i--)
	{
		CUInt128 CurID = Trace.At(i);
		RecivedTraceResults(CurID, PrevID);
		PrevID = CurID;
	}
}
Example #3
0
CVariant CLookupProxy::AddCallReq(const CVariant& Requests)
{
	CVariant Results(CVariant::EList);

	for(uint32 i=0; i<Requests.Count(); i++)
	{
		const CVariant& Request = Requests[i];
		if(!m_CallMap.insert(TCallOpMap::value_type(Request["XID"], SCallOp(Request))).second)
			continue; // we already got this request, ignore it

		if(m_pOperator && m_pOperator->IsValid())
		{
			try
			{
				m_pOperator->AddCallReq(Request["FX"], Request["ARG"], Request["XID"]);
			}
			catch(const CJSException& Exception)
			{
				LogReport(Exception.GetFlag(), Exception.GetLine(), Exception.GetError());

				CKadOperation::SOpStatus &Progress = m_CallMap[Request["XID"]].Status;
				Progress.Done = true; // this one is finished

				CVariant Result;
				Result["XID"] = Request["XID"];
				Result["ERR"] = Exception.GetError();
				Results.Append(Result);
			}
		}
	}

	if(m_pOperator)
		Results.Merge(m_pOperator->GetResponses());
	return Results;
}
Example #4
0
void CKadOperation::LogReport(UINT Flags, const wstring& ErrorMessage, const string& Error, const CVariant& Trace)
{
	wstring Operation = L"Kad Operation";
	if(m_pOperator)
	{
		CKadScript* pKadScript = m_pOperator->GetScript();
		ASSERT(pKadScript);

		Operation += L" (" + pKadScript->GetName() + L" v" + CKadScript::GetVersion(pKadScript->GetVersion()) + L")";
	}
	
	if(Trace.Count() > 0) // remote result
	{
		wstring Sender = CUInt128(Trace.At((uint32)0)).ToHex();
		if(!Error.empty())
			LogLine(LOG_DEBUG | Flags, L"%s recived an Error: %s from %s", Operation.c_str(), ErrorMessage.c_str(), Sender.c_str());
		else
			LogLine(LOG_DEBUG | Flags, L"%s recived a Report: %s from %s", Operation.c_str(), ErrorMessage.c_str(), Sender.c_str());
	}
	else
	{
		if(!Error.empty())
			LogLine(LOG_DEBUG | Flags, L"%s caused an Error: %s", Operation.c_str(), ErrorMessage.c_str());
		else
			LogLine(LOG_DEBUG | Flags, L"%s Reports: %s", Operation.c_str(), ErrorMessage.c_str());
	}
}
Example #5
0
bool CKadOperator::CallLoadClBk(const CVariant& XID, const CVariant& Payloads)
{
	map<CVariant, uint32>::iterator I = m_LoadClBks.find(XID); 
	if(I == m_LoadClBks.end())
		return false;

	if(I->second == 0)
		return true;

	ASSERT(m_pJSScript); // WARNING: this is a week pointer
	if(!m_pJSScript)
		return false;
	CKadOperation* pOperation = GetParent<CKadOperation>();
	ASSERT(pOperation);

	CDebugScope Debug(m_pKadScript, pOperation);

	for(uint32 j=0; j < Payloads.Count(); j++)
	{
		const CVariant& Payload = Payloads[j];

		vector<CPointer<CObject> > Parameters;
		Parameters.push_back(pOperation); // lookup
		Parameters.push_back(new CVariantPrx(Payload["DATA"]));
		Parameters.push_back(new CVariantPrx(Payload["PATH"]));
		Parameters.push_back(new CVariantPrx(Payload["RELD"]));
		CPointer<CObject> Return;
		m_pJSScript->Callback(I->second, Parameters, Return, false, pOperation);
	}

	return true;
}
Example #6
0
void CKadHandler::HandleHello(const CVariant& Hello, CKadNode* pNode, CComChannel* pChannel, bool bReq)
{
	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRT"))
		LogLine(LOG_DEBUG, L"Recived 'Hello %s' to %s", bReq ? L"Request" : L"Response", pNode->GetID().ToHex().c_str());

	SKadData* pData = pChannel->GetData<SKadData>();

	CVariant Addr = Hello["ADDR"];
	vector<CNodeAddress> AuthAddress;
	for(uint32 i=0; i < Addr.Count(); i++)
	{
		AuthAddress.push_back(CNodeAddress());
		AuthAddress.back().FromVariant(Addr.At(i));
	}

	// update node addresses
	for(vector<CNodeAddress>::iterator I = AuthAddress.begin(); I != AuthAddress.end(); I++)
	{
		if(pData->Authenticated)
			I->SetVerifyed();
		pNode->UpdateAddress(*I);
	}

	if(bReq)
		SendHello(pNode, pChannel, false);
		
	SetLastContact();
	pNode->UpdateClass(true, pChannel->GetAddress());
}
Example #7
0
void CKadNode::Load(const CVariant& Node, bool bFull)
{
	m_Protocol = Node["PROT"];
	m_ID.SetValue(CUInt128(Node["NID"]));

	CVariant Addr = Node["ADDR"];
	for(uint32 i=0; i < Addr.Count(); i++)
	{
		CNodeAddress Address;
		if(bFull)
			Address.FromExtVariant(Addr.At(i));
		else
			Address.FromVariant(Addr.At(i));
		InsertAddress(Address);
	}

	if(bFull)
	{
		m_Version = Node["VER"].To<string>();
		m_uFirstSeen = Node["FSEN"];
		m_uLastSeen = Node["LSEN"];

		if(IsFading())
		{
			for(AddressMap::iterator I = m_AddressMap.begin(); I != m_AddressMap.end(); I++)
				I->second.SetClass(NODE_DEFAULT_CLASS);
			m_uLastSeen = GetTime();
		}
	}
}
Example #8
0
void CLookupProxy::AddLoadReq(const CVariant& LoadReq)
{
	for(int i=0; i < LoadReq.Count(); i++)
	{
		const CVariant& Load = LoadReq.At(i);
		if(!m_LoadMap.insert(TLoadOpMap::value_type(Load["XID"], SLoadOp(Load["PATH"]))).second)
			continue;
	}
}
Example #9
0
void CLookupProxy::AddStoreReq(const CVariant& StoreReq) 
{
	for(int i=0; i < StoreReq.Count(); i++)
	{
		const CVariant& Store = StoreReq.At(i);
		if(!m_StoreMap.insert(TStoreOpMap::value_type(Store["XID"], SStoreOp(Store["PLD"]))).second)
			continue;
	}
}
Example #10
0
void CLookupProxy::FlushCaches()
{
	if(m_pOperator)
	{
		CVariant Results = m_pOperator->GetResponses();
		if(Results.Count() > 0)
			GetParent<CKademlia>()->Handler()->SendExecuteRes(this, Results);
	}
}
Example #11
0
CVariant CKadScript::Execute(const CVariant& Requests, const CUInt128& TargetID, CReportLogger* pLogger)
{
	KeepAlive();

	m_pLogger = CPointer<CReportLogger>(pLogger, true); // this is a week pointer and it gets cleared when the caller exits

	CVariant Results(CVariant::EList);
	for(uint32 i=0; i < Requests.Count(); i++)
	{
		const CVariant& Request = Requests.At(i);
		Results.Append(Call(Request["FX"], Request["ARG"], TargetID, Request["XID"]));
	}
	return Results;
}
Example #12
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);
}