void CKadOperation::ProxyingResponse(CKadNode* pNode, CComChannel* pChannel, const string &Error) { if(m_LookupHistory) m_LookupHistory->RegisterResponse(pNode->GetID()); SOpProgress* pProgress = GetProgress(pNode); if(!pProgress) return; pProgress->uTimeOut = -1; if(!Error.empty()) { pProgress->Shares = 0; pProgress->OpState = eOpFailed; LogLine(LOG_DEBUG, L"Recived error: '%S' on proxy lookup", Error.c_str()); } else { pProgress->OpState = eOpProxy; if(m_pOperator && m_pOperator->IsValid()) m_pOperator->OnProxyNode(pNode); SendRequests(pNode, pChannel, pProgress, false); } }
void CKadOperation::RequestStateless(CKadNode* pNode, CComChannel* pChannel, SOpProgress* pProgress) { pProgress->OpState = eOpStateless; pProgress->Shares = 1; if(m_pOperator) m_pOperator->AddNode(pNode); SendRequests(pNode, pChannel, pProgress, true); }
static void QueueHandler ( void ) { SendRequests (); if ( iSendReq >= 0 ) { iSignalSema ( iSendReq ); iSendReq = 0x80000000; } /* end if */ } /* end QueueHandler */
void Run() override { while (!this->GetExitState()) { this->Lock(); /* Queries can be non empty if one is pushed during SendRequests() */ if (queries.empty()) this->Wait(); this->Unlock(); SendRequests(); } }
void CKadOperation::Process(UINT Tick) { bool bLookupActive = m_LookupState == eLookupActive; CKadLookup::Process(Tick); // this looks for more nodes if(m_pOperator && m_pOperator->IsValid()) { m_pOperator->RunTimers(); if(bLookupActive && m_LookupState != eLookupActive) m_pOperator->OnClosestNodes(); } if((Tick & E10PerSec) == 0) return; if(m_LookupState == eLookupActive) return; // we are looking for closer nodes right now - just wait a second // Note: the kad operation mode for this kind of lookups is complicated, there are 3 modes of operation // // m_JumpCount > 0 // 1. Jumping, where we open channels to random nodes and request proxying // // m_HopLimit > 1 // 2. Routing, where we open channels to propabalistically choosen closest nodes // The propabalistically choice is based on the total desired spread area // If we hit a node that is already handling this lookup we need to choose a new one // // m_HopLimit == 1 // 3. Itterative Mode, here we do a normal lookup for closest nodes and than talk to them, not using proxying // // // m_HopLimit == 0 // 4. Target for a operations and messaging, not doing any own spreading // if(m_HopLimit == 0 || (m_HopLimit == 1 && !(CountCalls() || CountStores() || CountLoads()))) return; // we are not alowed to do anything - hoop 0 or hoop 1 and we have no hopable jobs just messages int FailedCount = 0; // Note: if we are in range we will act as one successfull share int UsedShares = m_InRange ? 1 : 0; int ShareHolders = 0; for(TNodeStatusMap::iterator I = m_Nodes.begin(); I != m_Nodes.end(); I++) { SOpProgress* pProgress = (SOpProgress*)I->second; if(pProgress->OpState == eOpFailed) { FailedCount++; continue; } if(pProgress->Shares == 0) continue; if(!I->first.pChannel) { ASSERT(0); continue; } UsedShares += pProgress->Shares; ShareHolders++; bool bStateless; if(!((bStateless = (pProgress->OpState == eOpStateless)) || pProgress->OpState == eOpProxy)) continue; // send newly added requests if there are any if (pProgress->Calls.size() != CountCalls() || pProgress->Stores.size() != CountStores() || pProgress->Loads.size() != CountLoads()) { SendRequests(I->first.pNode, I->first.pChannel, pProgress, bStateless); } } int FreeShares = GetSpreadShare() - UsedShares; //ASSERT(FreeShares >= 0); m_ActiveCount = ShareHolders; m_FailedCount = FailedCount; int TotalDoneJobs = 0; int TotalReplys = 0; if(m_pOperator) CountDone(m_pOperator->GetRequests(), TotalDoneJobs, TotalReplys); else CountDone(m_CallMap, TotalDoneJobs, TotalReplys); CountDone(m_StoreMap, TotalDoneJobs, TotalReplys); CountDone(m_LoadMap, TotalDoneJobs, TotalReplys); m_TotalDoneJobs = TotalDoneJobs; m_TotalReplys = TotalReplys; if(m_ManualMode) return; // Note: if we are in Jump Mode we prep the iterator to give uss randome nodes // If we are in Iterative Mode we prep the iterator to give us the closest node // If we are in Routong Mode it complicated, we want a random node from the m_SpreadCount closest nodes CRoutingZone::SIterator Iter(m_JumpCount > 0 ? 0 : (m_HopLimit > 1 ? m_SpreadCount : 1)); for(CKadNode* pNode = NULL; FreeShares > 0 && (pNode = GetParent<CKademlia>()->Root()->GetClosestNode(Iter, m_ID)) != NULL;) { if(m_JumpCount == 0 && ((pNode->GetID() ^ m_ID) > GetParent<CKademlia>()->Root()->GetMaxDistance())) break; // there are no nodes anymore in list that would be elegable here CComChannel* pChannel = GetChannel(pNode); if(!pChannel) continue; SOpProgress* pProgress = GetProgress(pNode); ASSERT(pProgress); // right after get channel this must work if(pProgress->OpState != eNoOp) continue; // this node has already been tryed if(m_HopLimit > 1) RequestProxying(pNode, pChannel, pProgress, FreeShares, ShareHolders, m_InitParam); else RequestStateless(pNode, pChannel, pProgress); if(pProgress->Shares) { FreeShares -= pProgress->Shares; ShareHolders ++; } } // if there are shares left we are out of nodes m_OutOfNodes = (FreeShares > 0); }
void CNCSJPCEcwpIOStream::ProcessReceivedPackets() { Lock(); while(m_ReceivedPackets.size()) { ReceivedPacket *pRP = *(m_ReceivedPackets.begin()); NCSPacket *pPacket = pRP->pPacket; INT32 nLength = pRP->nLength; m_ReceivedPackets.remove(pRP); NCSFree(pRP); if( pPacket ) { UINT32 iPacketSize; NCSPacketType ptType; NCSClientUID nClientUID; // have a valid file, so now unpack the blocks read NCS_PACKET_UNPACK_BEGIN(pPacket); NCS_PACKET_UNPACK_ELEMENT(iPacketSize); NCS_PACKET_UNPACK_ELEMENT(nClientUID); NCS_PACKET_UNPACK_ELEMENT(ptType); switch( ptType ) { case NCSPT_BLOCKS: { UINT16 nBlocks; UINT32 i; NCS_PACKET_UNPACK_ELEMENT(nBlocks); /* ** Unpack block data */ for(i = 0; i < nBlocks; i++) { NCSBlockId nBlock; UINT32 nBlockLength; UINT8 *pImage; NCS_PACKET_UNPACK_ELEMENT(nBlock); NCS_PACKET_UNPACK_ELEMENT(nBlockLength); pImage = (UINT8*)NCSMalloc(nBlockLength, FALSE); NCS_PACKET_UNPACK_ELEMENT_SIZE(pImage[0], nBlockLength); //char buf[1024]; //sprintf(buf, "Packet %ld size %ld (", nBlock, nBlockLength); //for(int v = 0; v < NCSMin(20, nBlockLength); v++) { // sprintf(buf + strlen(buf), "0x%lx,", pImage[v]); //} //sprintf(buf + strlen(buf), ")\r\n"); //OutputDebugStringA(buf); // m_pJPC->Lock(); if(GetPacketStatus(nBlock) == CNCSJPCPacketStatus::REQUESTED) { SetPacketStatus(nBlock, CNCSJPCPacketStatus::RECEIVED); CNCSJPCProgression p; p.m_nCurPacket = nBlock; CNCSJPCPacket *pHeader = m_pJPC->GetPacketHeader(nBlock); if(pHeader && m_pJPC->FindPacketRCPL(nBlock, p.m_nCurTile, p.m_nCurResolution, p.m_nCurComponent, p.m_nCurPrecinctX, p.m_nCurPrecinctY, p.m_nCurLayer)) { CNCSJPCEcwpIOStream Stream(m_pJPC, true); if(((CNCSJPCMemoryIOStream&)Stream).Open(pImage, nBlockLength) == NCS_SUCCESS) { pImage = NULL; pHeader->ParseHeader(*m_pJPC, Stream, &p); Stream.Close(); } } delete pHeader; } // m_pJPC->UnLock(); NCSFree(pImage); } } break; case NCSPT_FLOW_CONTROL: // NOTUSED break; case NCSPT_SYNCHRONISE: /* [03] */ { // m_pJPC->Lock(); if(m_bSendInProgress == false) { CNCSJPCPacketStatusIterator pCur = m_Packets.begin(); CNCSJPCPacketStatusIterator pEnd = m_Packets.end(); while(pCur != pEnd) { UINT32 nBlock = (*pCur).second.m_nPacket; if((*pCur).second.m_eStatus == CNCSJPCPacketStatus::REQUESTED) { SetPacketStatus(nBlock, CNCSJPCPacketStatus::NONE); pCur = m_Packets.begin(); CNCSJPCProgression p; p.m_nCurPacket = nBlock; if(m_pJPC->FindPacketRCPL(nBlock, p.m_nCurTile, p.m_nCurResolution, p.m_nCurComponent, p.m_nCurPrecinctX, p.m_nCurPrecinctY, p.m_nCurLayer)) { CNCSJPCTilePartHeader *pMainTP = m_pJPC->GetTile(p.m_nCurTile); RequestPrecinct((CNCSJPCPrecinct*)pMainTP->m_Components[p.m_nCurComponent]->m_Resolutions[p.m_nCurResolution]->m_Precincts.find(p.m_nCurPrecinctX, p.m_nCurPrecinctY)); } } pCur++; } } SendRequests(); // m_pJPC->UnLock(); } break; default: // ERROR unknown packet - ignore it break; } NCS_PACKET_UNPACK_END(pPacket); NCSFree(pPacket); } } UnLock(); }