void CDatagrams::onQA(CEndPoint& addr, G2Packet* pPacket) { hostCache.m_pSection.lock(); CHostCacheHost* pHost = hostCache.add( addr, common::getTNowUTC() ); if ( pHost ) { pHost->m_tAck = 0; } hostCache.m_pSection.unlock(); QUuid oGuid; // Hubs are only supposed to route UDP /QA - we'll drop it if we're in leaf mode if ( SearchManager.onQueryAcknowledge( pPacket, addr, oGuid ) && Neighbours.isG2Hub() ) { // Add from address G2Packet* pFR = G2Packet::newPacket( "FR" ); pFR->writeHostAddress( &addr ); pPacket->addOrReplaceChild( "FR", pFR ); Network.m_pSection.lock(); Network.routePacket( oGuid, pPacket, true, false ); Network.m_pSection.unlock(); } }
G2Packet* Query::toG2Packet( EndPoint* pAddr, quint32 nKey ) { G2Packet* pPacket = G2Packet::newPacket( "Q2", true ); //bool bWantURL = true; bool bWantDN = ( !m_sDescriptiveName.isEmpty() ); bool bWantMD = !m_sMetadata.isEmpty(); //bool bWantPFS = true; if ( pAddr ) { G2Packet* pUDP = pPacket->writePacket( "UDP", 10 ); pUDP->writeHostAddress( *pAddr ); pUDP->writeIntLE( nKey ); } if ( bWantDN ) { pPacket->writePacket( "DN", m_sDescriptiveName.toUtf8().size() )->writeString( m_sDescriptiveName, false ); } if ( bWantMD ) { pPacket->writePacket( "MD", m_sMetadata.toUtf8().size() )->writeString( m_sMetadata, false ); } for ( quint8 i = 0, nSize = m_vHashes.size(); i < nSize; ++i ) { if ( m_vHashes[i] ) { pPacket->writePacket( "URN", m_vHashes[i]->getFamilyName().size() + Hash::byteCount( m_vHashes[i]->algorithm() ) + 1 ); pPacket->writeString( m_vHashes[i]->getFamilyName() + "\0" + m_vHashes[i]->rawValue(), false ); } } /*if( m_nMinimumSize > 0 && m_nMaximumSize < 0xFFFFFFFFFFFFFFFF ) { G2Packet* pSZR = pPacket->WriteChild("SZR"); pSZR->writeIntLE(m_nMinimumSize); pSZR->writeIntLE(m_nMaximumSize); } else if( m_nMinimumSize > 0 ) { G2Packet* pSZR = pPacket->WriteChild("SZR"); pSZR->writeIntLE(m_nMinimumSize); pSZR->writeIntLE(0xFFFFFFFFFFFFFFFF); } else if( m_nMaximumSize < 0xFFFFFFFFFFFFFFFF ) { G2Packet* pSZR = pPacket->WriteChild("SZR"); pSZR->writeIntLE(0); pSZR->writeIntLE(m_nMaximumSize); } if( bWantURL || bWantDN || bWantMD || bWantPFS ) { G2Packet* pInt = pPacket->WriteChild("I"); if( bWantURL ) pInt->writeString("URL", true); if( bWantDN ) pInt->writeString("DN", true); if( bWantMD ) pInt->writeString("MD", true); if( bWantPFS ) pInt->writeString("PFS", true); }*/ pPacket->writeByte( 0 ); pPacket->writeGUID( m_oGUID ); return pPacket; }
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 }
void CDatagrams::onQKA(CEndPoint& addr, G2Packet* pPacket) { if ( !pPacket->m_bCompound ) { return; } quint32 nKey = 0; QHostAddress nKeyHost; char szType[9]; quint32 nLength = 0, nNext = 0; while(pPacket->readPacket(&szType[0], nLength)) { nNext = pPacket->m_nPosition + nLength; if(strcmp("QK", szType) == 0 && nLength >= 4) { nKey = pPacket->readIntLE<quint32>(); } else if(strcmp("SNA", szType) == 0 && nLength >= 4) { if(nLength >= 16) { Q_IPV6ADDR ip; pPacket->read(&ip, 16); nKeyHost.setAddress(ip); } else { quint32 nIp = pPacket->readIntBE<quint32>(); nKeyHost.setAddress(nIp); } } pPacket->m_nPosition = nNext; } hostCache.m_pSection.lock(); CHostCacheHost* pCache = hostCache.add( addr, common::getTNowUTC() ); if ( pCache ) { if( !nKey ) // null QK means a hub does not want to be queried or just downgraded { hostCache.remove( pCache ); } else { pCache->setKey( nKey ); } } hostCache.m_pSection.unlock(); #if LOG_QUERY_HANDLING systemLog.postLog(LogSeverity::Debug, QString("Got a query key for %1 = 0x%2").arg(addr.toString().toLocal8Bit().constData()).arg(nKey)); //qDebug("Got a query key for %s = 0x%x", addr.toString().toLocal8Bit().constData(), nKey); #endif // LOG_QUERY_HANDLING if(Neighbours.isG2Hub() && !nKeyHost.isNull() && nKeyHost != ((QHostAddress)Network.m_oAddress)) { G2Packet* pQNA = G2Packet::newPacket("QNA"); pQNA->writeHostAddress(&addr); pPacket->prependPacket(pQNA); Neighbours.m_pSection.lock(); CNeighbour* pNode = Neighbours.find(nKeyHost, dpG2); if( pNode ) { ((CG2Node*)pNode)->sendPacket(pPacket, true, false); } Neighbours.m_pSection.unlock(); } }
void CDatagrams::onQuery(CEndPoint &addr, G2Packet *pPacket) { CQueryPtr pQuery = CQuery::fromPacket(pPacket, &addr); if(pQuery.isNull()) { #if LOG_QUERY_HANDLING qDebug() << "Received malformed query from" << qPrintable(addr.toStringWithPort()); #endif // LOG_QUERY_HANDLING return; } if( !Neighbours.isG2Hub() ) { // Stop receiving queries from others // We are here because we just downgraded to leaf mode // Shareaza should not retry with QK == 0 // TODO: test this #if LOG_QUERY_HANDLING systemLog.postLog(LogSeverity::Debug, "Sending null query key to %s because we're not a hub.", qPrintable(addr.toStringWithPort())); #endif // LOG_QUERY_HANDLING G2Packet* pQKA = G2Packet::newPacket("QKA", true); pQKA->writePacket("QK", 4)->writeIntLE<quint32>(0); if( addr != pQuery->m_oEndpoint ) { pQKA->writePacket("SNA", (pQuery->m_oEndpoint.protocol() == QAbstractSocket::IPv6Protocol ? 18 : 6))->writeHostAddress(&pQuery->m_oEndpoint); } sendPacket(pQuery->m_oEndpoint, pQKA); pQKA->release(); return; } if(!QueryKeys.check(pQuery->m_oEndpoint, pQuery->m_nQueryKey)) { #if LOG_QUERY_HANDLING systemLog.postLog(LogSeverity::Debug, "Issuing query key correction for %s.", qPrintable(addr.toStringWithPort())); #endif // LOG_QUERY_HANDLING G2Packet* pQKA = G2Packet::newPacket("QKA", true); pQKA->writePacket("QK", 4)->writeIntLE<quint32>(QueryKeys.create(pQuery->m_oEndpoint)); if( addr != pQuery->m_oEndpoint ) { pQKA->writePacket("SNA", (pQuery->m_oEndpoint.protocol() == QAbstractSocket::IPv6Protocol ? 18 : 6))->writeHostAddress(&pQuery->m_oEndpoint); } sendPacket(addr, pPacket); pQKA->release(); return; } if( !Network.m_oRoutingTable.add(pQuery->m_oGUID, pQuery->m_oEndpoint) ) { #if LOG_QUERY_HANDLING qDebug() << "Query already processed, ignoring"; #endif // LOG_QUERY_HANDLING G2Packet* pQA = Neighbours.createQueryAck(pQuery->m_oGUID, false, 0, false); sendPacket(pQuery->m_oEndpoint, pQA, true); pQA->release(); return; } #if LOG_QUERY_HANDLING qDebug() << "Processing query from: " << qPrintable(addr.toStringWithPort()); #endif // LOG_QUERY_HANDLING // just in case if( pQuery->m_oEndpoint == Network.m_oAddress ) { systemLog.postLog( LogSeverity::Error, Components::Network, "Q2 received via UDP and return address points to us, changing return address to source %s", qPrintable( addr.toStringWithPort() ) ); G2Packet* pUDP = G2Packet::newPacket("UDP"); pUDP->writeHostAddress(&addr); pUDP->writeIntLE<quint32>(0); pPacket->addOrReplaceChild("UDP", pUDP); } Neighbours.m_pSection.lock(); G2Packet* pQA = Neighbours.createQueryAck(pQuery->m_oGUID); sendPacket(pQuery->m_oEndpoint, pQA, true); pQA->release(); Neighbours.routeQuery(pQuery, pPacket); Neighbours.m_pSection.unlock(); // local search }