void CDatagrams::onPing(CEndPoint& addr, G2Packet* pPacket) { Q_UNUSED(pPacket); G2Packet* pNew = G2Packet::newPacket("PO", false); sendPacket(addr, pNew, false); pNew->release(); }
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::onCRAWLR(CEndPoint& addr, G2Packet* pPacket) { QMutexLocker l2(&Neighbours.m_pSection); // bool bRLeaf = false; // bool bRNick = false; // bool bRGPS = false; // bool bRExt = false; if(!pPacket->m_bCompound) { return; } char szType[9]; quint32 nLength = 0, nNext = 0; while(pPacket->readPacket(&szType[0], nLength)) { nNext = pPacket->m_nPosition + nLength; if(strcmp("RLEAF", szType) == 0) { // bRLeaf = true; } else if(strcmp("RNAME", szType) == 0) { // bRNick = true; } else if(strcmp("RGPS", szType) == 0) { // bRGPS = true; } else if(strcmp("REXT", szType) == 0) { // bRExt = true; } pPacket->m_nPosition = nNext; } G2Packet* pCA = G2Packet::newPacket("CRAWLA", true); G2Packet* pTmp = G2Packet::newPacket("SELF", true); if(Neighbours.isG2Hub()) { pTmp->writePacket("HUB", 0); } else { pTmp->writePacket("LEAF", 0); } pTmp->writePacket("NA", ((Network.m_oAddress.protocol() == 0) ? 6 : 18))->writeHostAddress(&Network.m_oAddress); pTmp->writePacket("CV", CQuazaaGlobals::USER_AGENT_STRING().toUtf8().size())->writeString(CQuazaaGlobals::USER_AGENT_STRING(), false); pTmp->writePacket("V", 4)->writeString(CQuazaaGlobals::VENDOR_CODE(), false);; quint16 nLeaves = Neighbours.m_nLeavesConnectedG2; pTmp->writePacket("HS", 2)->writeIntLE(nLeaves); if(!quazaaSettings.Profile.GnutellaScreenName.isEmpty()) { pTmp->writePacket("NAME", quazaaSettings.Profile.GnutellaScreenName.left(255).toUtf8().size())->writeString(quazaaSettings.Profile.GnutellaScreenName.left(255)); } pCA->writePacket(pTmp); pTmp->release(); for(QList<CNeighbour*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode) { if((*itNode)->m_nProtocol != dpG2) { continue; } CG2Node* pNode = (CG2Node*) * itNode; if(pNode->m_nState == nsConnected) { if(pNode->m_nType == G2_HUB) { G2Packet* pNH = G2Packet::newPacket("NH"); pNH->writePacket("NA", ((pNode->m_oAddress.protocol() == 0) ? 6 : 18))->writeHostAddress(&pNode->m_oAddress); pNH->writePacket("HS", 2)->writeIntLE(pNode->m_nLeafCount); pCA->writePacket(pNH); pNH->release(); } else if(pNode->m_nType == G2_LEAF) { G2Packet* pNL = G2Packet::newPacket("NL"); pNL->writePacket("NA", ((pNode->m_oAddress.protocol() == 0) ? 6 : 18))->writeHostAddress(&pNode->m_oAddress); pCA->writePacket(pNL); pNL->release(); } } } sendPacket(addr, pCA, true); pCA->release(); }
void CDatagrams::onReceiveGND() { GND_HEADER* pHeader = (GND_HEADER*)m_pRecvBuffer->data(); QHostAddress nIp = *m_pHostAddress; quint32 nSeq = ((pHeader->nSequence << 16) & 0xFFFF0000) + (m_nPort & 0x0000FFFF); #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, "Received GND from %s:%u nSequence = %u nPart = %u nCount = %u", m_pHostAddress->toString().toLocal8Bit().constData(), m_nPort, pHeader->nSequence, pHeader->nPart, pHeader->nCount); #endif DatagramIn* pDatagramIn = 0; if(m_RecvCache.contains(nIp) && m_RecvCache[nIp].contains(nSeq)) { pDatagramIn = m_RecvCache[nIp][nSeq]; // To give a chance for bigger packages ;) if(pDatagramIn->m_nLeft) { pDatagramIn->m_tStarted = time(0); } } else { QMutexLocker l(&m_pSection); if(!m_FreeDatagramIn.isEmpty()) { pDatagramIn = m_FreeDatagramIn.takeFirst(); } else { if(m_FreeDatagramIn.isEmpty()) { removeOldIn(true); if(m_FreeDatagramIn.isEmpty()) { #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, QString("UDP in frames exhausted")); #endif m_nDiscarded++; return; } } pDatagramIn = m_FreeDatagramIn.takeFirst(); } if(m_FreeBuffer.size() < pHeader->nCount) { m_nDiscarded++; m_FreeDatagramIn.append(pDatagramIn); removeOldIn(false); return; } pDatagramIn->create(CEndPoint(*m_pHostAddress, m_nPort), pHeader->nFlags, pHeader->nSequence, pHeader->nCount); for(int i = 0; i < pHeader->nCount; i++) { Q_ASSERT(pDatagramIn->m_pBuffer[i] == 0); pDatagramIn->m_pBuffer[i] = m_FreeBuffer.takeFirst(); } m_RecvCache[nIp][nSeq] = pDatagramIn; m_RecvCacheTime.prepend(pDatagramIn); } // It is here, in case if we did not have free datagrams // ACK = I've received a datagram, and if you have received and rejected it, do not send ACK-a if(pHeader->nFlags & 0x02) { GND_HEADER* pAck = new GND_HEADER; memcpy(pAck, pHeader, sizeof(GND_HEADER)); pAck->nCount = 0; pAck->nFlags = 0; #ifdef DEBUG_UDP systemLog.postLog(LogSeverity::Debug, "Sending UDP ACK to %s:%u", m_pHostAddress->toString().toLocal8Bit().constData(), m_nPort); #endif //m_pSocket->writeDatagram((char*)&oAck, sizeof(GND_HEADER), *m_pHostAddress, m_nPort); //m_mOutput.Add(sizeof(GND_HEADER)); m_AckCache.append(qMakePair(CEndPoint(*m_pHostAddress, m_nPort), reinterpret_cast<char*>(pAck))); if( m_AckCache.count() == 1 ) QMetaObject::invokeMethod(this, "flushSendCache", Qt::QueuedConnection); } if(pDatagramIn->add(pHeader->nPart, m_pRecvBuffer->data() + sizeof(GND_HEADER), m_pRecvBuffer->size() - sizeof(GND_HEADER))) { G2Packet* pPacket = 0; try { CEndPoint addr(*m_pHostAddress, m_nPort); pPacket = pDatagramIn->toG2Packet(); if(pPacket) { onPacket(addr, pPacket); } } catch(...) { } if(pPacket) { pPacket->release(); } m_pSection.lock(); remove(pDatagramIn, true); 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 }