CNeighbour* CNeighboursConnections::OnAccept(CNetworkConnection* pConn) { // TODO: Make new CNeighbour deriviate for handshaking with Gnutella clients systemLog.postLog(LogSeverity::Debug, "CNeighbours::OnAccept"); //qDebug() << "CNeighbours::OnAccept"; if(!m_bActive) { pConn->Close(); return 0; } if(!m_pSection.tryLock(50)) { systemLog.postLog(LogSeverity::Debug, "Not accepting incoming connection. Neighbours overloaded"); pConn->Close(); return 0; } CG2Node* pNew = new CG2Node(); pNew->AttachTo(pConn); AddNode(pNew); pNew->moveToThread(&NetworkThread); m_pSection.unlock(); return pNew; }
bool CNetwork::RoutePacket(QUuid& pTargetGUID, G2Packet* pPacket) { CG2Node* pNode = 0; CEndPoint pAddr; if(m_oRoutingTable.Find(pTargetGUID, &pNode, &pAddr)) { if(pNode) { pNode->SendPacket(pPacket, true, false); systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 routed to neighbour: %3").arg(pTargetGUID.toString()).arg(pPacket->GetType()).arg(pNode->m_oAddress.toString().toAscii().constData())); //qDebug() << "CNetwork::RoutePacket " << pTargetGUID.toString() << " Packet: " << pPacket->GetType() << " routed to neighbour: " << pNode->m_oAddress.toString().toAscii().constData(); return true; } else if(!pAddr.isNull()) { Datagrams.SendPacket(pAddr, pPacket, true); systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 routed to remote node: %3").arg(pTargetGUID.toString()).arg(pPacket->GetType()).arg(pNode->m_oAddress.toString().toAscii().constData())); //qDebug() << "CNetwork::RoutePacket " << pTargetGUID.toString() << " Packet: " << pPacket->GetType() << " routed to remote node: " << pNode->m_oAddress.toString().toAscii().constData(); return true; } systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket - No node and no address!")); //qDebug() << "CNetwork::RoutePacket - weird thing, should not happen..."; } systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 DROPED!").arg(pTargetGUID.toString()).arg(pPacket->GetType())); //qDebug() << "CNetwork::RoutePacket " << pTargetGUID.toString() << " Packet: " << pPacket->GetType() << " DROPPED!"; return false; }
void CNetwork::ConnectTo(CEndPoint& addr) { // TODO: Verify network is connected before attempting connection and create connection if it is not CG2Node* pNew = Neighbours.ConnectTo(addr); if(pNew) { pNew->moveToThread(&NetworkThread); } }
bool CNetwork::RoutePacket(G2Packet* pPacket, CG2Node* pNbr) { QUuid pGUID; if(pPacket->GetTo(pGUID) && pGUID != quazaaSettings.Profile.GUID) // no i adres != moj adres { CG2Node* pNode = 0; CEndPoint pAddr; if(m_oRoutingTable.Find(pGUID, &pNode, &pAddr)) { bool bForwardTCP = false; bool bForwardUDP = false; if(pNbr) { if(pNbr->m_nType == G2_LEAF) // if received from leaf - can forward anywhere { bForwardTCP = bForwardUDP = true; } else // if received from a hub - can be forwarded to leaf { if(pNode && pNode->m_nType == G2_LEAF) { bForwardTCP = true; } } } else // received from udp - do not forward via udp { bForwardTCP = true; } if(pNode && bForwardTCP) { pNode->SendPacket(pPacket, true, false); return true; } else if(!pAddr.isNull() && bForwardUDP) { Datagrams.SendPacket(pAddr, pPacket, true); return true; } // drop } return true; } return false; }
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<CG2Node*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode) { CG2Node* pNode = *itNode; if(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<CG2Node*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode) { CG2Node* pNode = *itNode; if(pNode->m_nState == nsConnected) { pNode->SendPacket(pKHL, false, false); } } pKHL->Release(); }
bool CNetwork::routePacket(QUuid& pTargetGUID, G2Packet* pPacket, bool bLockNeighbours, bool bBuffered) { CG2Node* pNode = 0; CEndPoint pAddr; if(m_oRoutingTable.find(pTargetGUID, &pNode, &pAddr)) { if(pNode) { if( bLockNeighbours ) { Neighbours.m_pSection.lock(); } if( Neighbours.neighbourExists(pNode) ) { pNode->sendPacket(pPacket, bBuffered, false); systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 routed to neighbour: %3").arg(pTargetGUID.toString()).arg(pPacket->getType()).arg(pNode->m_oAddress.toString().toLocal8Bit().constData())); } if( bLockNeighbours ) { Neighbours.m_pSection.unlock(); } return true; } else if(pAddr.isValid()) { Datagrams.sendPacket(pAddr, pPacket, true); systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 routed to remote node: %3").arg(pTargetGUID.toString()).arg(pPacket->getType()).arg(pAddr.toString().toLocal8Bit().constData())); return true; } systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket - No node and no address!")); } systemLog.postLog(LogSeverity::Debug, QString("CNetwork::RoutePacket %1 Packet: %2 DROPPED!").arg(pTargetGUID.toString()).arg(pPacket->getType())); return false; }
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(); } }
void CNetwork::OnSecondTimer() { if(!m_pSection.tryLock(150)) { qWarning() << "WARNING: Network core overloaded!"; return; } if(!m_bActive) { m_pSection.unlock(); return; } if(Neighbours.m_nHubsConnected == 0 && !WebCache.isRequesting() && (HostCache.isEmpty() || HostCache.GetConnectable() == 0)) { WebCache.RequestRandom(); } if(m_tCleanRoutesNext > 0) { m_tCleanRoutesNext--; } else { //m_oRoutingTable.Dump(); m_oRoutingTable.ExpireOldRoutes(); m_tCleanRoutesNext = 60; } //Datagrams.FlushSendCache(); emit Datagrams.SendQueueUpdated(); if(isHub() && quazaaSettings.Gnutella2.AdaptiveHub && --m_nNextCheck == 0) { AdaptiveHubRun(); m_nNextCheck = quazaaSettings.Gnutella2.AdaptiveCheckPeriod; } if(!QueryHashMaster.IsValid()) { QueryHashMaster.Build(); } Neighbours.Maintain(); m_nSecsToHubBalancing--; if(m_nSecsToHubBalancing == 0) { m_nSecsToHubBalancing = HUB_BALANCING_INTERVAL; HubBalancing(); } SearchManager.OnTimer(); if(m_bPacketsPending) { RoutePackets(); } if(m_nLNIWait == 0) { if(m_bNeedUpdateLNI) { QMutexLocker l(&Neighbours.m_pSection); m_bNeedUpdateLNI = false; for(QList<CG2Node*>::iterator itNode = Neighbours.begin(); itNode != Neighbours.end(); ++itNode) { CG2Node* pNode = *itNode; if(pNode->m_nState == nsConnected) { pNode->SendLNI(); } } } m_nLNIWait = quazaaSettings.Gnutella2.LNIMinimumUpdate; } else { m_nLNIWait--; } if(m_nKHLWait == 0) { HostCache.m_pSection.lock(); HostCache.Save(); DispatchKHL(); m_nKHLWait = quazaaSettings.Gnutella2.KHLPeriod; HostCache.m_pSection.unlock(); } else { m_nKHLWait--; } m_pSection.unlock(); }