void CDatagrams::onQKR(CEndPoint& addr, G2Packet* pPacket) { if(!Neighbours.isG2Hub()) { return; } CEndPoint oRequestedAddress = addr; CEndPoint oSendingAddress = addr; if(pPacket->m_bCompound) { char szType[9]; quint32 nLength = 0, nNext = 0; while(pPacket->readPacket(&szType[0], nLength)) { nNext = pPacket->m_nPosition + nLength; if(strcmp("SNA", szType) == 0 && nLength >= 4) { if(nLength >= 16) { Q_IPV6ADDR ip; pPacket->read(&ip, 16); oSendingAddress.setAddress(ip); } else { quint32 nIp = pPacket->readIntBE<quint32>(); oSendingAddress.setAddress(nIp); } } else if(strcmp("RNA", szType) == 0 && nLength >= 6) { if(nLength >= 18) { pPacket->readHostAddress(&oRequestedAddress, false); } else { pPacket->readHostAddress(&oRequestedAddress); } } pPacket->m_nPosition = nNext; } } if(!oRequestedAddress.port() || oRequestedAddress.isFirewalled()) { return; } G2Packet* pAns = G2Packet::newPacket("QKA", true); quint32 nKey = QueryKeys.create(oRequestedAddress); pAns->writePacket("QK", 4); pAns->writeIntLE<quint32>(nKey); G2Packet* pSNA = G2Packet::newPacket("SNA"); pSNA->writeHostAddress(&oSendingAddress); pAns->writePacket(pSNA); pSNA->release(); sendPacket(oRequestedAddress, pAns, false); pAns->release(); #if LOG_QUERY_HANDLING systemLog.postLog(LogSeverity::Debug, "Node %s asked for a query key (0x%08x) for node %s", qPrintable(addr.toStringWithPort()), nKey, qPrintable(oRequestedAddress.toStringWithPort())); #endif // LOG_QUERY_HANDLING }
bool CSearchManager::OnQueryAcknowledge(G2Packet* pPacket, CEndPoint& addr, QUuid& oGUID) { if(!pPacket->m_bCompound) { return false; } pPacket->SkipCompound(); // skip children to get search GUID if(pPacket->GetRemaining() < 16) // must be at least 16 bytes for GUID { return false; } oGUID = pPacket->ReadGUID(); // Read search GUID QMutexLocker l(&m_pSection); if(CManagedSearch* pSearch = Find(oGUID)) // is it our Query Ack? { // YES, this is ours, let's parse the packet and process it CEndPoint oFromIp = addr; QList<QHostAddress> lDone; quint32 nRetryAfter = 0; qint64 tAdjust = 0; quint32 tNow = time(0); quint32 nHubs = 0, nLeaves = 0, nSuggestedHubs = 0; pPacket->m_nPosition = 0; // reset position char szType[9]; quint32 nLength = 0, nNext = 0; while(pPacket->ReadPacket(&szType[0], nLength)) { nNext = pPacket->m_nPosition + nLength; if(strcmp("D", szType) == 0 && nLength >= 4) { QHostAddress ha; if( nLength >= 16 ) { // IPv6 Q_IPV6ADDR nIP; pPacket->Read(&nIP, 16); ha.setAddress(nIP); if( nLength >= 18 ) { quint16 nPort = pPacket->ReadIntLE<quint16>(); CEndPoint a(nIP, nPort); HostCache.Add(a, tNow); } if(nLength >= 20) { nLeaves += pPacket->ReadIntLE<quint16>(); } } else { // IPv4 quint32 nIP = pPacket->ReadIntBE<quint32>(); ha.setAddress(nIP); if(nLength >= 6) { quint16 nPort = pPacket->ReadIntLE<quint16>(); CEndPoint a(nIP, nPort); HostCache.Add(a, tNow); } if(nLength >= 8) { nLeaves += pPacket->ReadIntLE<quint16>(); } } lDone.append(ha); nHubs++; } else if(strcmp("S", szType) == 0 && nLength >= 6) { CEndPoint a; pPacket->ReadHostAddress(&a, !(nLength >= 18)); quint32 tSeen = (nLength >= (a.protocol() == 0 ? 10 : 22)) ? pPacket->ReadIntLE<quint32>() + tAdjust : tNow; HostCache.Add(a, tSeen); nSuggestedHubs++; } else if(strcmp("TS", szType) == 0 && nLength >= 4) { tAdjust = tNow - pPacket->ReadIntLE<quint32>(); } else if(strcmp("RA", szType) == 0 && nLength >= 2) { if(nLength >= 4) { nRetryAfter = pPacket->ReadIntLE<quint32>(); } else if(nLength >= 2) { nRetryAfter = pPacket->ReadIntLE<quint16>(); } CHostCacheHost* pHost = HostCache.Find(oFromIp); if(pHost) { pHost->m_tRetryAfter = tNow + nRetryAfter; } } else if(strcmp("FR", szType) == 0 && nLength >= 4) { if( nLength >= 16 ) { Q_IPV6ADDR ip; pPacket->Read(&ip, 16); oFromIp.setAddress(ip); } else { quint32 nFromIp = pPacket->ReadIntBE<quint32>(); oFromIp.setAddress(nFromIp); } } pPacket->m_nPosition = nNext; } // we already know QA GUID systemLog.postLog(LogSeverity::Debug, "Processing query acknowledge from %s (time adjust %+d seconds): %d hubs, %d leaves, %d suggested hubs, retry after %d seconds.", addr.toString().toAscii().constData(), int(tAdjust), nHubs, nLeaves, nSuggestedHubs, nRetryAfter); //qDebug("Processing query acknowledge from %s (time adjust %+d seconds): %d hubs, %d leaves, %d suggested hubs, retry after %d seconds.", // addr.toString().toAscii().constData(), int(tAdjust), nHubs, nLeaves, nSuggestedHubs, nRetryAfter); pSearch->m_nHubs += nHubs; pSearch->m_nLeaves += nLeaves; pSearch->OnHostAcknowledge(oFromIp, tNow); for(int i = 0; i < lDone.size(); i++) { pSearch->OnHostAcknowledge(lDone[i], tNow); } emit pSearch->StatsUpdated(); return false; } // not our ack - tell caller to route it return true; }