Beispiel #1
0
void CG2Node::OnQuery(G2Packet *pPacket)
{
	// just read guid for now to have it in routing table

	QUuid oGUID;
	if( pPacket->m_bCompound )
		pPacket->SkipCompound();

	if( pPacket->GetRemaining() >= 16 )
	{
		oGUID = pPacket->ReadGUID();
		Network.m_oRoutingTable.Add(oGUID, this, false);

		if( m_nType == G2_LEAF ) // temporary
		{
			G2Packet* pQA = G2Packet::New("QA", true);
			quint32 tNow = time(0);
			pQA->WritePacket("TS", 4)->WriteIntLE(tNow);
			pQA->WritePacket("D", 8)->WriteHostAddress(&Network.m_oAddress);
			pQA->WriteIntLE(Network.m_nLeavesConnected);

			quint32 nCount = 0;

			for( uint i = 0; i < HostCache.size() && nCount < 100u; i++, nCount++ )
			{
				pQA->WritePacket("S", 6)->WriteHostAddress(&HostCache.m_lHosts[i]->m_oAddress);
			}

			pQA->WriteByte(0);
			pQA->WriteGUID(oGUID);
			//qDebug() << "Sending query ACK " << pQA->ToHex() << pQA->ToASCII();
			SendPacket(pQA, true, true);
		}
	}
}
Beispiel #2
0
G2Packet* CQuery::ToG2Packet(CEndPoint* pAddr, quint32 nKey)
{
	G2Packet* pPacket = G2Packet::New("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);
	}

	foreach(CHash pHash, m_lHashes)
	{
		pPacket->WritePacket("URN", pHash.GetFamilyName().size() + CHash::ByteCount(pHash.getAlgorithm()) + 1);
		pPacket->WriteString(pHash.GetFamilyName() + "\0" + pHash.RawValue(), false);
	}
Beispiel #3
0
void CG2Node::SendStartups()
{
	if( Network.IsListening() )
    {
        IPv4_ENDPOINT addr = Network.GetLocalAddress();
		G2Packet* pPacket = G2Packet::New("PI", true);
		pPacket->WritePacket("UDP", 6);
		pPacket->WriteHostAddress(&addr);
		pPacket->WritePacket("TFW", 0);
		SendPacket(pPacket, false, true);
    }

	SendLNI();
}
void CNetwork::DispatchKHL()
{
	QMutexLocker l(&Neighbours.m_pSection);

	if(Neighbours.m_lNodes.isEmpty())
	{
		return;
	}

	G2Packet* pKHL = G2Packet::New("KHL");
	quint32 ts = time(0);
	pKHL->WritePacket("TS", 4)->WriteIntLE(ts);

	for(QList<CNeighbour*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode)
	{
		CNeighbour* pNode = *itNode;

		if( pNode->m_nProtocol != dpGnutella2 )
				continue;

		if(((CG2Node*)pNode)->m_nType == G2_HUB && pNode->m_nState == nsConnected)
		{
			pKHL->WritePacket("NH", 6)->WriteHostAddress(&pNode->m_oAddress);
		}
	}

	quint32 nCount = 0;

	for(; nCount < (quint32)quazaaSettings.Gnutella2.KHLHubCount && HostCache.size() > nCount; nCount++)
	{
		pKHL->WritePacket("CH", 10)->WriteHostAddress(&HostCache.m_lHosts.at(nCount)->m_oAddress);
		pKHL->WriteIntLE(&HostCache.m_lHosts.at(nCount)->m_tTimestamp);
	}


	for(QList<CNeighbour*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode)
	{
		CNeighbour* pNode = *itNode;

		if( pNode->m_nProtocol != dpGnutella2 )
			continue;

		if(pNode->m_nState == nsConnected)
		{
			((CG2Node*)pNode)->SendPacket(pKHL, false, false);
		}
	}
	pKHL->Release();
}
void CChatSessionG2::SendMessage(QString sMessage, bool bAction)
{
	qDebug() << "Send message:" << sMessage << bAction;

	G2Packet* pPacket = G2Packet::New("CMSG", true);
	if( bAction )
		pPacket->WritePacket("ACT", 0);

	G2Packet* pBody = G2Packet::New("BODY");
	pBody->WriteString(sMessage);
	pPacket->WritePacket(pBody);
	pBody->Release();

	SendPacket(pPacket);
}
Beispiel #6
0
void CG2Node::OnQKR(G2Packet *pPacket)
{
	if( !pPacket->m_bCompound || m_nType != G2_LEAF )
		return;

	char szType[9];
	quint32 nLength = 0, nNext = 0;
	bool bCacheOK = true;
	IPv4_ENDPOINT addr;

	while( pPacket->ReadPacket(&szType[0], nLength) )
	{
		nNext = pPacket->m_nPosition + nLength;

		if( strcmp("QNA", szType) == 0 && nLength >= 6 )
		{
			pPacket->ReadHostAddress(&addr);
		}
		else if( strcmp("REF", szType) == 0 )
		{
			bCacheOK = false;
		}

		pPacket->m_nPosition = nNext;
	}

	if( addr.ip == 0 || addr.port == 0 ) // TODO: sprawdzene czy adres jest za fw
		return;

	CHostCacheHost* pHost = bCacheOK ? HostCache.Find(addr) : 0;

	if( pHost != 0 && pHost->m_nQueryKey != 0 && pHost->m_nKeyHost == Network.m_oAddress.ip && time(0) - pHost->m_nKeyTime < quazaaSettings.Gnutella2.QueryKeyTime )
	{
		G2Packet* pQKA = G2Packet::New("QKA", true);
		pQKA->WritePacket("QNA", 6)->WriteHostAddress(&addr);
		pQKA->WritePacket("QK", 4)->WriteIntBE(pHost->m_nQueryKey);
		pQKA->WritePacket("CACHED", 0);
		SendPacket(pQKA, true, true);
	}
	else
	{
		G2Packet* pQKR = G2Packet::New("QKR", true);
		pQKR->WritePacket("SNA", 6)->WriteHostAddress(&m_oAddress);
		Datagrams.SendPacket(addr, pQKR, false);
		pQKR->Release();
	}
}
void CChatSessionG2::OnUPROC(G2Packet *pPacket)
{
	Q_UNUSED(pPacket);

	// Temporary code, needs to be moved to GProfile class

	QString sXML = "<?xml version=\"1.0\"?><gprofile xmlns=\"http://www.shareaza.com/schemas/GProfile.xsd\"><gnutella guid=\"%1\"/><identity><handle primary=\"%2\"/></identity></gprofile>";
	sXML = sXML.arg(quazaaSettings.Profile.GUID.toString().toUpper().replace("{", "").replace("}", "")).arg(quazaaSettings.Profile.GnutellaScreenName);

	G2Packet* pD = G2Packet::New("UPROD", true);
	pD->WritePacket("XML", sXML.toUtf8().size());
	pD->WriteString(sXML);

	SendPacket(pD);
}
Beispiel #8
0
void CG2Node::SendLNI()
{
	G2Packet* pLNI = G2Packet::New("LNI", true);
	pLNI->WritePacket("NA", 6)->WriteHostAddress(&Network.m_oAddress);
	pLNI->WritePacket("GU", 16)->WriteGUID(quazaaSettings.Profile.GUID);
	pLNI->WritePacket("V", 4)->WriteString(quazaaGlobals.VendorCode(), false);

	if( Network.isHub() )
	{
		quint16 nLeafs = quazaaSettings.Gnutella2.NumLeafs;
		pLNI->WritePacket("HS", 4);
		pLNI->WriteIntLE(Network.m_nLeavesConnected);
		pLNI->WriteIntLE(nLeafs);
		pLNI->WritePacket("QK", 0);
	}

	pLNI->WritePacket("g2core", 0);

	SendPacket(pLNI, false, true);
}
void CChatSessionG2::OnUPROD(G2Packet *pPacket)
{
	qDebug() << "OnUPROD";

	if( !pPacket->m_bCompound )
		return;

	QUuid oGUID;
	bool hasXML = false;

	char szType[9];
	quint32 nLength = 0, nNext = 0;

	while(pPacket->ReadPacket(&szType[0], nLength))
	{
		nNext = pPacket->m_nPosition + nLength;

		if(strcmp("XML", szType) == 0)
		{
			// Temporary code, needs to be moved to GProfile class
			QXmlStreamReader oXML;
			bool hasGprofile = false;
			bool hasGUID = false;
			bool hasIdentity = false;
			bool hasNick = false;
			oXML.addData(pPacket->ReadString(nLength));

			while(!oXML.atEnd() && !oXML.hasError())
			{
				QXmlStreamReader::TokenType token = oXML.readNext();

				if( token == QXmlStreamReader::StartDocument)
				{
					continue;
				}
				else if( token == QXmlStreamReader::StartElement )
				{
					if( oXML.name() == "gprofile" )
					{
						/*
						if( oXML.attributes().value("xmlns") != "http://www.shareaza.com/schemas/GProfile.xsd" )
							return;*/
						hasGprofile = true;
						continue;
					}
					else if( hasGprofile && oXML.name() == "gnutella" )
					{
						if( oXML.attributes().hasAttribute("guid") )
						{
							QString sTemp = oXML.attributes().value("guid").toString();
							QUuid oTemp(sTemp);
							oGUID = oTemp;
							hasGUID = true;
							continue;
						}
					}
					else if( hasGprofile && oXML.name() == "identity" )
					{
						hasIdentity = true;
						continue;
					}
					else if( hasGprofile && hasIdentity && oXML.name() == "handle" )
					{
						if( oXML.attributes().hasAttribute("primary") )
						{
							m_sNick = oXML.attributes().value("primary").toString();
							hasNick = true;
							continue;
						}
					}
				}
			}

			if( !hasNick || !hasGUID )
				return;

			hasXML = true;
		}

		pPacket->m_nPosition = nNext;
	}

	if( !hasXML )
		return;

	m_oGUID = oGUID;
	emit guidChanged(oGUID);
	emit nickChanged(m_sNick);

	if( m_bInitiated ) // TODO PUSH handling
	{
		G2Packet* pReq = G2Packet::New("CHATREQ", true);
		pReq->WritePacket("USERGUID", 16);
		pReq->WriteGUID(m_oGUID);

		SendPacket(pReq);
	}
}
Beispiel #10
0
void CG2Node::OnPing(G2Packet* pPacket)
{
	bool bUdp = false;
    bool bRelay = false;
    bool bTestFirewall = false;
    IPv4_ENDPOINT 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("UDP", szType) == 0 && nLength >= 6)
			{
				pPacket->ReadHostAddress(&addr);
				if( addr.ip != 0 && addr.port != 0)
					bUdp = true;
			}
			else if( strcmp("RELAY", szType) == 0 )
			{
				bRelay = true;
			}
			else if( strcmp("TFW", szType) == 0 )
			{
				bTestFirewall = true;
			}

			pPacket->m_nPosition = nNext;
		}

    }

    if( !bUdp && !bRelay )
    {
        // direct ping
		G2Packet* pPong = G2Packet::New("PO", false);
		SendPacket(pPong, false, true);
        return;
    }

    if( bUdp && !bRelay )
    {
        // /PI/UDP

        if( Network.isHub() )
        {
			char* pRelay = pPacket->WriteGetPointer(7, 0);
			*pRelay++ = 0x60;
			*pRelay++ = 0;
			*pRelay++ = 'R'; *pRelay++ = 'E'; *pRelay++ = 'L';
			*pRelay++ = 'A'; *pRelay++ = 'Y';


            QList<CG2Node*> lToRelay;

            for( int i = 0; i < Network.m_lNodes.size(); i++ )
            {
                if( Network.m_lNodes.at(i)->m_nState == nsConnected )
                    lToRelay.append(Network.m_lNodes[i]);
            }

			for( int nCount = 0; nCount < quazaaSettings.Gnutella2.PingRelayLimit && lToRelay.size(); nCount++ )
            {
                int nIndex = qrand() % lToRelay.size();
                pPacket->AddRef();
                CG2Node* pNode = lToRelay.at(nIndex);
				pNode->SendPacket(pPacket, true, true);
                lToRelay.removeAt(nIndex);
            }

            return;
        }
    }

    if( bUdp && bRelay )
    {
		G2Packet* pPong = G2Packet::New("PO", true);
		pPong->WritePacket("RELAY", 0);
        Datagrams.SendPacket(addr, pPong, true);
        pPong->Release();
	}
}