BOOL CHostBrowser::OnPacket(CG1Packet* pPacket) { if ( pPacket->m_nType != G1_PACKET_HIT || pPacket->m_nLength <= 27 ) return TRUE; CQueryHit* pHits = CQueryHit::FromPacket( pPacket ); if ( pHits == NULL ) { theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress ); return FALSE; } m_bCanPush = TRUE; m_pClientID = pHits->m_pClientID; for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext ) m_nHits++; Downloads.OnQueryHits( pHits ); if ( ! m_bCanChat && pHits->m_bChat ) m_bCanChat = TRUE; if ( m_pNotify != NULL ) m_pNotify->OnBrowseHits( pHits ); else pHits->Delete(); return TRUE; }
BOOL CHostBrowser::OnPacket(CG2Packet* pPacket) { if ( pPacket->IsType( G2_PACKET_HIT ) ) { CQueryHit* pHits = CQueryHit::FromPacket( pPacket ); if ( pHits == NULL ) { theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress ); return FALSE; } m_bCanPush = TRUE; m_pClientID = pHits->m_pClientID; for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext ) { m_nHits++; } Downloads.OnQueryHits( pHits ); if ( ! m_bCanChat && pHits->m_bChat ) { m_bCanChat = TRUE; if ( m_pNotify && m_pProfile != NULL ) m_pNotify->OnProfileReceived(); } if ( m_pNotify != NULL ) m_pNotify->OnBrowseHits( pHits ); else pHits->Delete(); } else if ( pPacket->IsType( G2_PACKET_PHYSICAL_FOLDER ) ) { if ( m_pNotify != NULL ) m_pNotify->OnPhysicalTree( pPacket ); } else if ( pPacket->IsType( G2_PACKET_VIRTUAL_FOLDER ) ) { if ( m_pNotify != NULL ) m_pNotify->OnVirtualTree( pPacket ); } else if ( pPacket->IsType( G2_PACKET_PROFILE_DELIVERY ) ) { OnProfilePacket( pPacket ); if ( m_pProfile != NULL && m_pNotify != NULL ) { m_pNotify->OnProfileReceived(); } } else if ( pPacket->IsType( G2_PACKET_PROFILE_AVATAR ) ) { if ( m_pNotify != NULL ) m_pNotify->OnHeadPacket( pPacket ); } return TRUE; }
BOOL CNeighbour::OnCommonHit(CPacket* pPacket) { CQueryHit* pHits = NULL; int nHops = 0; if ( pPacket->m_nProtocol == PROTOCOL_G1 ) { pHits = CQueryHit::FromPacket( (CG1Packet*)pPacket, &nHops ); } else if ( pPacket->m_nProtocol == PROTOCOL_G2 ) { pHits = CQueryHit::FromPacket( (CG2Packet*)pPacket, &nHops ); } else { ASSERT( FALSE ); } if ( pHits == NULL ) { pPacket->Debug( _T("BadHit") ); theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT, (LPCTSTR)m_sAddress ); m_nDropCount++; if ( m_nProtocol == PROTOCOL_G1 ) Statistics.Current.Gnutella1.Dropped++; else if ( m_nProtocol == PROTOCOL_G2 ) Statistics.Current.Gnutella2.Dropped++; return TRUE; } if ( Security.IsDenied( &pHits->m_pAddress ) || nHops > (int)Settings.Gnutella1.MaximumTTL ) { pHits->Delete(); m_nDropCount++; if ( m_nProtocol == PROTOCOL_G1 ) Statistics.Current.Gnutella1.Dropped++; else if ( m_nProtocol == PROTOCOL_G2 ) Statistics.Current.Gnutella2.Dropped++; return TRUE; } Network.NodeRoute->Add( &pHits->m_pClientID, this ); if ( SearchManager.OnQueryHits( pHits ) ) { Network.RouteHits( pHits, pPacket ); } Network.OnQueryHits( pHits ); return TRUE; }
BOOL CNeighbour::OnCommonHit(CPacket* pPacket) { CQueryHit* pHits = NULL; int nHops = 0; if ( pPacket->m_nProtocol == PROTOCOL_G1 ) pHits = CQueryHit::FromG1Packet( (CG1Packet*)pPacket, &nHops ); else if ( pPacket->m_nProtocol == PROTOCOL_G2 ) pHits = CQueryHit::FromG2Packet( (CG2Packet*)pPacket, &nHops ); else ASSERT( FALSE ); if ( pHits == NULL ) { DEBUG_ONLY( pPacket->Debug( L"Malformed Hit" ) ); theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT, (LPCTSTR)m_sAddress ); m_nDropCount++; if ( m_nProtocol == PROTOCOL_G1 ) Statistics.Current.Gnutella1.Dropped++; else if ( m_nProtocol == PROTOCOL_G2 ) Statistics.Current.Gnutella2.Dropped++; return TRUE; // Stay connected } if ( Security.IsDenied( &pHits->m_pAddress ) ) { // DEBUG_ONLY( pPacket->Debug( L"Security manager denied Hit" ) ); theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT, (LPCTSTR)m_sAddress ); m_nDropCount++; if ( m_nProtocol == PROTOCOL_G1 ) Statistics.Current.Gnutella1.Dropped++; else if ( m_nProtocol == PROTOCOL_G2 ) Statistics.Current.Gnutella2.Dropped++; pHits->Delete(); return TRUE; // Stay connected } Network.NodeRoute->Add( pHits->m_oClientID, this ); // Don't route exceeded hits if ( nHops <= (int)Settings.Gnutella1.MaximumTTL && SearchManager.OnQueryHits( pHits ) ) { Network.RouteHits( pHits, pPacket ); } Network.OnQueryHits( pHits ); return TRUE; // Stay connected }
BOOL CHostBrowser::StreamHTML() { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_nProtocol == PROTOCOL_NULL ); CString strLine; CQueryHit* pHits = NULL; while ( m_pBuffer->ReadLine( strLine ) ) { int nPosHTTP = strLine.Find( L"http://" ); while ( nPosHTTP >= 0 && strLine.Find( L"/get/" ) > nPosHTTP ) { CString strURI = strLine.Mid( nPosHTTP ).SpanExcluding( L"?&\"'<>" ); CString strName; DWORD nSize = 0; int nPosSize = strLine.Find( L"<TD NOWRAP>" ); if ( nPosSize >= 0 && nPosSize < nPosHTTP ) { CString strSize = strLine.Mid( nPosSize + 11 ).SpanExcluding( L"</" ); float nFloat = 0; if ( _stscanf( strSize, L"%f", &nFloat ) == 1 && nFloat > 0 ) { if ( strSize.Find( L" GB" ) >= 0 ) nFloat *= 1024*1024*1024; else if ( strSize.Find( L" MB" ) >= 0 ) nFloat *= 1024*1024; else if ( strSize.Find( L" KB" ) >= 0 ) nFloat *= 1024; nSize = (DWORD)ceil( nFloat ); } } strLine = strLine.Mid( nPosHTTP + strURI.GetLength() ); int nPosName = strLine.Find( L">" ); if ( nPosName >= 0 ) strName = strLine.Mid( nPosName + 1 ).SpanExcluding( L"<>" ); if ( strName.IsEmpty() && ( nPosName = strURI.ReverseFind( L'/' ) ) > 0 ) strName = URLDecode( strURI.Mid( nPosName + 1 ) ); CQueryHit* pHit = new CQueryHit( PROTOCOL_NULL ); pHit->m_pAddress = m_pHost.sin_addr; pHit->m_nPort = htons( m_pHost.sin_port ); pHit->m_pVendor = m_pVendor ? m_pVendor : VendorCache.m_pNull; pHit->m_bPush = ( m_tPushed ) ? TRI_TRUE : TRI_FALSE; pHit->m_bBrowseHost = TRUE; pHit->m_nSize = nSize; pHit->m_bSize = TRUE; pHit->m_sName = strName; pHit->m_sURL = strURI; if ( m_bCanPush ) pHit->m_oClientID = m_oClientID; pHit->Resolve(); pHit->m_pNext = pHits; pHits = pHit; nPosHTTP = strLine.Find( L"http://" ); } } if ( pHits != NULL ) OnQueryHits( pHits ); return TRUE; }
CQueryHit* CQueryHit::ReadPacket(G2Packet *pPacket, QSharedPointer<QueryHitInfo> pHitInfo) { if( !pPacket->m_bCompound ) return 0; pPacket->m_nPosition = 0; // reset packet position bool bHaveHits = false; bool bFirstHit = true; CQueryHit* pThisHit = new CQueryHit(); try { char szType[9], szTypeX[9]; quint32 nLength = 0, nLengthX = 0, nNext = 0, nNextX = 0; bool bCompound = false; while( pPacket->ReadPacket(&szType[0], nLength, &bCompound) ) { nNext = pPacket->m_nPosition + nLength; if( strcmp("H", szType) == 0 && bCompound ) { CQueryHit* pHit = (bFirstHit ? pThisHit : new CQueryHit()); if( !bFirstHit ) { CQueryHit* pPrevHit = pThisHit; while( pPrevHit->m_pNext != 0 ) { pPrevHit = pPrevHit->m_pNext; } pPrevHit->m_pNext = pHit; } bool bHaveSize = false; QByteArray baTemp; bool bHaveDN = false; bool bHaveURN = false; while( pPacket->m_nPosition < nNext && pPacket->ReadPacket(&szTypeX[0], nLengthX)) { nNextX = pPacket->m_nPosition + nLengthX; if( strcmp("URN", szTypeX) == 0 ) { QString sURN; char hashBuff[256]; sURN = pPacket->ReadString(); if( nLengthX >= 44u && sURN.compare("bp") == 0 ) { pPacket->Read(&hashBuff[0], CSHA1::ByteCount()); if( pHit->m_oSha1.FromRawData(&hashBuff[0], CSHA1::ByteCount()) ) { bHaveURN = true; } else { pHit->m_oSha1.Clear(); } } else if( nLengthX >= CSHA1::ByteCount() + 5u && sURN.compare("sha1") == 0 ) { pPacket->Read(&hashBuff[0], CSHA1::ByteCount()); if( pHit->m_oSha1.FromRawData(&hashBuff[0], CSHA1::ByteCount()) ) { bHaveURN = true; } else { pHit->m_oSha1.Clear(); } } } else if( strcmp("URL", szTypeX) == 0 && nLengthX ) { // if url empty - try uri-res resolver or a node do not have this object // bez sensu... pHit->m_sURL = pPacket->ReadString(); } else if( strcmp("DN", szTypeX) == 0 ) { if( bHaveSize ) { pHit->m_sDescriptiveName = pPacket->ReadString(nLengthX); } else if( nLengthX > 4 ) { baTemp.resize(4); pPacket->Read(baTemp.data(), 4); pHit->m_sDescriptiveName = pPacket->ReadString(nLengthX - 4); } bHaveDN = true; } else if( strcmp("MD", szTypeX) == 0 ) { pHit->m_sMetadata = pPacket->ReadString(); } else if( strcmp("SZ", szTypeX) == 0 && nLengthX >= 4 ) { if( nLengthX >= 8 ) { if( !baTemp.isEmpty() ) { pHit->m_sDescriptiveName.prepend(baTemp); } pHit->m_nObjectSize = pPacket->ReadIntLE<quint64>(); bHaveSize = true; } else if( nLengthX >= 4 ) { if( !baTemp.isEmpty() ) { pHit->m_sDescriptiveName.prepend(baTemp); } pHit->m_nObjectSize = pPacket->ReadIntLE<quint32>(); bHaveSize = true; } } else if( strcmp("CSC", szTypeX) == 0 && nLengthX >= 2 ) { pHit->m_nCachedSources = pPacket->ReadIntLE<quint16>(); } else if( strcmp("PART", szTypeX) == 0 && nLengthX >= 4 ) { pHit->m_bIsPartial = true; pHit->m_nPartialBytesAvailable = pPacket->ReadIntLE<quint32>(); } pPacket->m_nPosition = nNextX; } if( !bHaveSize && baTemp.size() == 4 ) { pHit->m_nObjectSize = qFromLittleEndian(*(quint32*)baTemp.constData()); } else { pHit->m_sDescriptiveName.prepend(baTemp); } if( bHaveURN && bHaveDN ) { bFirstHit = false; bHaveHits = true; } else { if( !bFirstHit ) { // może teraz się nie wywali... // można by było to lepiej zrobić... for( CQueryHit* pTest = pThisHit; pTest != 0; pTest = pTest->m_pNext ) { if( pTest->m_pNext == pHit ) { pTest->m_pNext = 0; break; } } pHit->Delete(); } } } pPacket->m_nPosition = nNext; } } catch(...) // packet incomplete, packet error, parser takes care of stream end { qDebug() << "EXCEPTION IN QUERY HIT PARSING!"; if( pThisHit ) { pThisHit->Delete(); } //throw; return 0; } // we already know query hit informations, so don't reparse them if( !bHaveHits ) { pThisHit->Delete(); return 0; } CQueryHit* pHit = pThisHit; while( pHit != 0 ) { pHit->m_pHitInfo = pHitInfo; pHit = pHit->m_pNext; } // TODO: sprawdzic poprawnosc hita... (Validate hit) pHit = pThisHit; while( pHit != 0 ) { pHit->ResolveURLs(); pHit = pHit->m_pNext; } return pThisHit; }
BOOL CHostBrowser::StreamHTML() { CString strLine; CQueryHit* pHits = NULL; while ( m_pBuffer->ReadLine( strLine ) ) { if ( Settings.General.Debug && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) ) { theApp.Message( MSG_DEBUG, _T("HTML-BROWSE: %s"), (LPCTSTR)strLine ); } int nPosHTTP = strLine.Find( _T("http://") ); while ( nPosHTTP >= 0 && strLine.Find( _T("/get/") ) > nPosHTTP ) { CString strURI = strLine.Mid( nPosHTTP ).SpanExcluding( _T("?&\"'<>") ); CString strName; DWORD nSize = 0; int nPosSize = strLine.Find( _T("<TD NOWRAP>") ); if ( nPosSize >= 0 && nPosSize < nPosHTTP ) { CString strSize = strLine.Mid( nPosSize + 11 ).SpanExcluding( _T("</") ); float nFloat = 0; if ( _stscanf( strSize, _T("%f"), &nFloat ) == 1 && nFloat > 0 ) { if ( strSize.Find( _T(" GB") ) >= 0 ) nFloat *= 1024*1024*1024; else if ( strSize.Find( _T(" MB") ) >= 0 ) nFloat *= 1024*1024; else if ( strSize.Find( _T(" KB") ) >= 0 ) nFloat *= 1024; nSize = (DWORD)nFloat; } } strLine = strLine.Mid( nPosHTTP + strURI.GetLength() ); int nPosName = strLine.Find( _T(">") ); if ( nPosName >= 0 ) { strName = strLine.Mid( nPosName + 1 ).SpanExcluding( _T("<>") ); } if ( strName.IsEmpty() && ( nPosName = strURI.ReverseFind( '/' ) ) > 0 ) { strName = URLDecode( strURI.Mid( nPosName + 1 ) ); } CQueryHit* pHit = new CQueryHit( PROTOCOL_NULL, NULL ); pHit->m_pAddress = m_pHost.sin_addr; pHit->m_nPort = htons( m_pHost.sin_port ); pHit->m_pVendor = m_pVendor ? m_pVendor : VendorCache.m_pNull; pHit->m_bPush = ( m_tPushed ) ? TS_TRUE : TS_FALSE; pHit->m_bBrowseHost = TRUE; pHit->m_nSize = nSize; pHit->m_sName = strName; pHit->m_sURL = strURI; if ( m_bCanPush ) pHit->m_pClientID = m_pClientID; pHit->m_pNext = pHits; pHits = pHit; m_nHits ++; nPosHTTP = strLine.Find( _T("http://") ); } } if ( pHits != NULL ) { if ( m_pNotify != NULL ) m_pNotify->OnBrowseHits( pHits ); else pHits->Delete(); } return TRUE; }