void CDatagrams::listen()
{
	QMutexLocker l(&m_pSection);

	if(m_bActive)
	{
		systemLog.postLog(LogSeverity::Debug, QString("CDatagrams::Listen - already listening"));
		return;
	}

	Q_ASSERT(m_pSocket == 0);

	m_pSocket = new QUdpSocket(this);

	CEndPoint addr = Network.getLocalAddress();
	if(m_pSocket->bind(addr.port()))
	{
		systemLog.postLog(LogSeverity::Debug, QString("Datagrams listening on %1").arg(m_pSocket->localPort()));
		m_nDiscarded = 0;

		for(int i = 0; i < quazaaSettings.Gnutella2.UdpBuffers; i++)
		{
			m_FreeBuffer.append(new CBuffer(1024));
		}

		for(int i = 0; i < quazaaSettings.Gnutella2.UdpInFrames; i++)
		{
			m_FreeDatagramIn.append(new DatagramIn);
		}

		for(int i = 0; i < quazaaSettings.Gnutella2.UdpOutFrames; i++)
		{
			m_FreeDatagramOut.append(new DatagramOut);
		}

		connect(this, SIGNAL(sendQueueUpdated()), this, SLOT(flushSendCache()), Qt::QueuedConnection);
		connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(onDatagram()), Qt::QueuedConnection);

		m_bActive = true;
	}
	else
	{
		systemLog.postLog(LogSeverity::Debug, QString("Can't bind UDP socket! UDP communication disabled!"));
		disconnectNode();
	}

	m_bFirewalled = true;
}
void CNetworkConnection::ConnectTo(CEndPoint oAddress)
{
	m_oAddress = oAddress;

	m_bInitiated = true;
	m_bConnected = false;
	m_tConnected = time(0);

	Q_ASSERT(m_pInput == 0);
	Q_ASSERT(m_pOutput == 0);
	m_pInput = new CBuffer(8192);
	m_pOutput = new CBuffer(8192);
	Q_ASSERT(m_pSocket == 0);

	m_pSocket = new QTcpSocket();
	initializeSocket();
	m_pSocket->connectToHost(oAddress, oAddress.port());

}
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
}