예제 #1
0
파일: g2node.cpp 프로젝트: geekt/quazaa
void CG2Node::OnRead()
{
	if( !Network.m_pSection.tryLock(50) )
	{
		emit readyRead(); // it is a queued connection, lets requeue the missed signal
		return;
	}

    //qDebug() << "CG2Node::OnRead";
    if( m_nState == nsHandshaking )
    {
        if( peek(bytesAvailable()).indexOf("\r\n\r\n") != -1 )
        {
            if( m_bInitiated )
            {
                ParseOutgoingHandshake();
            }
            else
            {
                ParseIncomingHandshake();
            }
        }
    }
    else if ( m_nState == nsConnected )
    {

		G2Packet* pPacket = 0;
        try
        {
			while( (pPacket = G2Packet::ReadBuffer(GetInputBuffer())) )
            {
				m_tLastPacketIn = time(0);
				m_nPacketsIn++;

				OnPacket(pPacket);

				pPacket->Release();
            }
        }
		catch(...)
        {
			if( pPacket )
			{
				qDebug() << pPacket->ToHex() << "\n" << pPacket->ToASCII();
				pPacket->Release();
			}

            qDebug() << "Packet error - " << m_oAddress.toString().toAscii();
            m_nState = nsClosing;
            emit NodeStateChanged();
            deleteLater();
        }
    }

	Network.m_pSection.unlock();
}
예제 #2
0
파일: g2node.cpp 프로젝트: geekt/quazaa
void CG2Node::FlushSendQueue(bool bFullFlush)
{
    QByteArray* pOutput = GetOutputBuffer();

	while( bytesToWrite() == 0 && m_lSendQueue.size() )
	{
		while( pOutput->size() < 4096 && m_lSendQueue.size() )
		{
			G2Packet* pPacket = m_lSendQueue.dequeue();
			pPacket->ToBuffer(pOutput);
			pPacket->Release();
		}
		emit readyToTransfer();
	}


    if( bFullFlush )
    {
        if( m_bCompressedOutput && pOutput->size() )
            m_bOutputPending = true;
    }

    if( pOutput->size() )
        emit readyToTransfer();
}
예제 #3
0
void CChatSessionG2::OnRead()
{
	if( m_nState == csHandshaking )
	{
		if(Peek(bytesAvailable()).indexOf("\r\n\r\n") != -1)
		{
			if(m_bInitiated)
			{
				ParseOutgoingHandshake();
			}
			else
			{
				//ParseIncomingHandshake();
			}
		}
	}
	else if( m_nState == csConnected || m_nState == csActive )
	{
		G2Packet* pPacket = 0;
		try
		{
			while((pPacket = G2Packet::ReadBuffer(GetInputBuffer())))
			{
				OnPacket(pPacket);

				pPacket->Release();
			}
		}
		catch(...)
		{
			if(pPacket)
			{
				pPacket->Release();
			}

			emit systemMessage("Received corrupted G2 packet, connection lost.");

			CNetworkConnection::Close();
		}
		m_bReadyReadSent = false;
	}
}
예제 #4
0
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();
}
예제 #5
0
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);
}
예제 #6
0
파일: g2node.cpp 프로젝트: geekt/quazaa
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();
	}
}
예제 #7
0
파일: g2node.cpp 프로젝트: geekt/quazaa
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();
	}
}