Example #1
0
CVariant CKademlia::StartLookup(const CUInt128& TargetID, const CVariant& CodeID, const TCallMap& Execute, const TStoreMap& Store, CPrivateKey* pStoreKey, const TLoadMap& Load
									, int Timeout, int HopLimit, int JumpCount, int SpreadCount, bool bTrace, const wstring& Name)
{
	if(!m_pKadHandler)
		return CVariant();

	if(!CodeID.IsValid() && Store.empty() && Load.empty())
	{
		LogLine(LOG_ERROR, L"Attempted to start an empty Lookup");
		return CVariant();
	}

	CPointer<CKadTask> pLookup = new CKadTask(TargetID, m_pLookupManager);
	pLookup->SetName(Name);

	if(Timeout != -1)
		pLookup->SetTimeOut(Timeout);

	if(HopLimit != -1)
		pLookup->SetHopLimit(HopLimit);
	if(JumpCount != -1)
		pLookup->SetJumpCount(JumpCount);
	if(SpreadCount != -1)
		pLookup->SetSpreadCount(SpreadCount);
	if(bTrace)
		pLookup->EnableTrace();

	if(pStoreKey)
		pLookup->SetStoreKey(pStoreKey);

	for(TStoreMap::const_iterator I = Store.begin(); I != Store.end(); I++)
		pLookup->Store(I->first, I->second.Path, I->second.Data);
	
	for(TLoadMap::const_iterator I = Load.begin(); I != Load.end(); I++)
		pLookup->Load(I->first, I->second.Path);

	if(CodeID.IsValid())
	{
		if(!pLookup->SetupScript(CodeID))
		{
			LogLine(LOG_ERROR, L"Attempted to start a smart lookup with an unavailable script: %s", ToHex(CodeID.GetData(), CodeID.GetSize()).c_str());
			return CVariant();
		}
	
		for(TCallMap::const_iterator I = Execute.begin(); I != Execute.end(); I++)
			pLookup->AddCall(I->second.Function, I->second.Parameters, I->first);
	}

	CVariant LookupID = m_pLookupManager->StartLookup(pLookup.Obj());

	return LookupID;
}
Example #2
0
void CLookupProxy::LogReport(UINT Flags, const wstring& ErrorMessage, const string& Error, const CVariant& Trace)
{
	CKadOperation::LogReport(Flags, ErrorMessage, Error, Trace);

	if(!Trace.IsValid()) // if the trace is valid its a remote report that means it wil be relayed automatically, send only local reports
		GetParent<CKademlia>()->Handler()->SendReportPkt(GetReturnChannel(), Flags, ErrorMessage, Error);
}
Example #3
0
CVariant CKadOperator::Init(const CVariant& InitParam)
{
	ASSERT(m_pJSScript); // WARNING: this is a week pointer
	if(!m_pJSScript)
		return CVariant();
	CKadOperation* pOperation = GetParent<CKadOperation>();
	ASSERT(pOperation);

	if(CLookupProxy* pProxy = pOperation->Cast<CLookupProxy>())
	{
		CJSKadNode* &JSKadNode = m_KadNodes[NULL]; // NULL means its the return node
		if(JSKadNode = (CJSKadNode*)m_pJSScript->SetObject(pProxy->GetReturnNode())) // Note: the instance handler for this object is persistent!
			JSKadNode->SetOperation(pOperation);
	}

	if(!m_pJSScript->Has("lookupAPI", "init"))
		return CVariant(); // nothing to do here

	CDebugScope Debug(m_pKadScript, pOperation);

	vector<CPointer<CObject> > Parameters;
	Parameters.push_back(pOperation);
	if(InitParam.IsValid())
		Parameters.push_back(new CVariantPrx(InitParam));
	CPointer<CObject> Return;
	m_pJSScript->Call(string("lookupAPI"), "init", Parameters, Return);
	if(CVariantPrx* pVariant = Return->Cast<CVariantPrx>())
		return pVariant->GetCopy();
	return CVariant();
}
Example #4
0
bool CKademlia::InvokeScript(const CVariant& CodeID, const string& Function, const CVariant& Arguments, CVariant& Result, const CVariant& CallerID)
{
	CKadScript* pKadScript = m_pKadEngine->GetScript(CodeID);
	if(!pKadScript)
		return false;

	CDebugScope Debug(pKadScript);

	vector<CPointer<CObject> > Parameters;
	Parameters.push_back(new CVariantPrx(Arguments));
	if(CallerID.IsValid())
		Parameters.push_back(new CVariantPrx(CallerID));

	try
	{
		CJSScript* pScript = pKadScript->GetJSScript(true);

		CPointer<CObject> Return;
		pScript->Call(string("localAPI"), Function, Parameters, Return);
		if(CVariantPrx* pVariant = Return->Cast<CVariantPrx>())
			Result = pVariant->GetCopy();
	}
	catch(const CJSException& Exception)
	{
		pKadScript->LogReport(Exception.GetFlag(), Exception.GetLine(), Exception.GetError());
		return false;
	}
	return true;
}
Example #5
0
bool CKadHandler::SendRelayRes(CKadNode* pNode, CComChannel* pChannel, const CVariant& Frame, const string& Error, const CVariant& Load)
{
	CVariant RelayRes;

	CVariant FrameRes;
	if(Frame.Has("TID"))
		FrameRes["TID"] = Frame["TID"];
	FrameRes["EID"] = Frame["EID"];
	FrameRes["RID"] = Frame["RID"];
	FrameRes["FID"] = Frame["FID"]; // peer to peer (local) ACK
	if(!Error.empty())
		FrameRes["ERR"] = Error;
	if(Load.IsValid())
		FrameRes["LOAD"] = Load;
	RelayRes["FRM"] = FrameRes;

	if(GetParent<CKademlia>()->Cfg()->GetBool("DebugRE"))
		LogLine(LOG_DEBUG, L"Sending 'Relay Response' to %s", pNode->GetID().ToHex().c_str());
	return pChannel->QueuePacket(KAD_RELAY_RESPONSE, RelayRes);
}
Example #6
0
CKademlia::CKademlia(uint16 Port, bool bIPv6, const CVariant& Config, const string& Version)
{
	m_Protocol = KAD_PROT_VER;

	if(!Version.empty())
		m_Version += Version;
	else
		m_Version = "v " STR(KAD_PROT_MJR) "." STR(KAD_PROT_MIN);

	m_pConfig = new CKadConfig(this);
	if(Config.IsValid())
		m_pConfig->Merge(Config);

	LoadData();

	if(m_pKadKey->GetAlgorithm() == CAbstractKey::eUndefined)
	{
		m_pKadKey->SetAlgorithm(CAbstractKey::eECP);
		//m_pKadKey->GenerateKey("secp256r1"); // NIST: P-256
		m_pKadKey->GenerateKey("brainpoolP256r1"); // dont trust NIST (NSA) curves, use brainpool
		LogLine(LOG_INFO, L"Generated new Private NodeKey");
		SaveData();
	}

	m_pSocket = new CSmartSocket(SEC2MS(Cfg()->GetInt("ConnectionTimeout")), this);

	CScoped<CPublicKey> pKey = m_pKadKey->PublicKey();

	CUInt128 ID;
	CKadID::MakeID(pKey, ID.GetData(), ID.GetSize());
	LogLine(LOG_INFO, L"Neo Kad ID: %s", ID.ToHex().c_str());

	uint64 RecvKey;
	CAbstractKey::Fold(ID.GetData(), ID.GetSize(),(byte*)&RecvKey, sizeof(RecvKey));
	m_pSocket->SetupCrypto(RecvKey, m_pKadKey);

#ifdef _DEBUG
	LogLine(LOG_INFO, L"Socket PassKey is %I64u", RecvKey);
#endif

	m_Port = 0;
	m_IPv4 = CAddress(CAddress::IPv4);
	m_IPv6 = CAddress(CAddress::IPv6);

	for(int i=Port; i < Port + 1000; i++)
	{
		CUTPSocketListner* pSocketListner = new CUTPSocketListner(m_pSocket);
		CUTPSocketListner* pSocketListnerV6 = bIPv6 ? new CUTPSocketListner(m_pSocket) : NULL;
		bool bV4 = pSocketListner->Bind(i, CAddress(CAddress::IPv4));
		bool bV6 = !pSocketListnerV6 || pSocketListnerV6->Bind(i, CAddress(CAddress::IPv6));
		if(bV4 && bV6)
		{
			m_pSocket->InstallListener(pSocketListner);
			if(pSocketListnerV6)
				m_pSocket->InstallListener(pSocketListnerV6);
			m_Port = i;
			break;
		}
		delete pSocketListner;
		delete pSocketListnerV6;
	}
}