Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CrawlSession.cpp

Go to the documentation of this file.
00001 //
00002 // CrawlSession.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Network.h"
00025 #include "Datagrams.h"
00026 #include "G2Packet.h"
00027 #include "CrawlSession.h"
00028 
00029 #include "Neighbours.h"
00030 #include "Neighbour.h"
00031 
00032 #ifdef _DEBUG
00033 #undef THIS_FILE
00034 static char THIS_FILE[]=__FILE__;
00035 #define new DEBUG_NEW
00036 #endif
00037 
00038 CCrawlSession CrawlSession;
00039 
00040 
00042 // CCrawlSession construction
00043 
00044 CCrawlSession::CCrawlSession()
00045 {
00046         m_bActive = FALSE;
00047 }
00048 
00049 CCrawlSession::~CCrawlSession()
00050 {
00051         Clear();
00052 }
00053 
00055 // CCrawlSession clear
00056 
00057 void CCrawlSession::Clear()
00058 {
00059         for ( POSITION pos = m_pNodes.GetHeadPosition() ; pos ; )
00060         {
00061                 delete (CCrawlNode*)m_pNodes.GetNext( pos );
00062         }
00063 
00064         m_pNodes.RemoveAll();
00065 }
00066 
00068 // CCrawlSession bootstrap
00069 
00070 void CCrawlSession::Bootstrap()
00071 {
00072         for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
00073         {
00074                 CNeighbour* pNeighbour = Neighbours.GetNext( pos );
00075 
00076                 if ( pNeighbour->m_nNodeType != ntLeaf &&
00077                          pNeighbour->m_nProtocol == PROTOCOL_G2 )
00078                 {
00079                         SendCrawl( &pNeighbour->m_pHost );
00080                 }
00081         }
00082 }
00083 
00085 // CCrawlSession send a crawl request
00086 
00087 void CCrawlSession::SendCrawl(SOCKADDR_IN* pHost)
00088 {
00089         theApp.Message( MSG_TEMP, _T("CRAWL: Crawling host %s"),
00090                 (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) );
00091 
00092         CG2Packet* pPacket = CG2Packet::New( G2_PACKET_CRAWL_REQ, TRUE );
00093         pPacket->WritePacket( "RLEAF", 0 );
00094         pPacket->WritePacket( "RNAME", 0 );
00095         pPacket->WritePacket( "RGPS", 0 );
00096         Datagrams.Send( pHost, pPacket );
00097 }
00098 
00100 // CCrawlSession counts
00101 
00102 int CCrawlSession::GetHubCount()
00103 {
00104         int nCount = 0;
00105 
00106         for ( POSITION pos = m_pNodes.GetHeadPosition() ; pos ; )
00107         {
00108                 CCrawlNode* pNode = (CCrawlNode*)m_pNodes.GetNext( pos );
00109                 if ( pNode->m_nType == CCrawlNode::ntHub ) nCount ++;
00110         }
00111 
00112         return nCount;
00113 }
00114 
00115 int CCrawlSession::GetLeafCount()
00116 {
00117         int nCount = 0;
00118 
00119         for ( POSITION pos = m_pNodes.GetHeadPosition() ; pos ; )
00120         {
00121                 CCrawlNode* pNode = (CCrawlNode*)m_pNodes.GetNext( pos );
00122                 if ( pNode->m_nType == CCrawlNode::ntLeaf ) nCount ++;
00123         }
00124 
00125         return nCount;
00126 }
00127 
00129 // CCrawlSession run
00130 
00131 void CCrawlSession::OnRun()
00132 {
00133         if ( ! m_bActive ) return;
00134 
00135         DWORD tNow = time( NULL );
00136 
00137         for ( POSITION pos = m_pNodes.GetTailPosition() ; pos ; )
00138         {
00139                 CCrawlNode* pNode = (CCrawlNode*)m_pNodes.GetPrev( pos );
00140 
00141                 if ( pNode->m_nType == CCrawlNode::ntHub &&
00142                          pNode->m_tResponse == 0 &&
00143                          tNow - pNode->m_tCrawled >= 30 )
00144                 {
00145                         pNode->m_tCrawled = tNow;
00146                         SendCrawl( &pNode->m_pHost );
00147                         break;
00148                 }
00149         }
00150 }
00151 
00153 // CCrawlSession process a crawl reply
00154 
00155 void CCrawlSession::OnCrawl(SOCKADDR_IN* pHost, CG2Packet* pPacket)
00156 {
00157         if ( ! m_bActive ) return;
00158 
00159         theApp.Message( MSG_TEMP, _T("CRAWL: Response from %s"),
00160                 (LPCTSTR)CString( inet_ntoa( pHost->sin_addr ) ) );
00161 
00162         CCrawlNode* pNode = Find( &pHost->sin_addr, TRUE );
00163 
00164         pNode->OnCrawl( this, pPacket );
00165 
00166         // pNode->Dump();
00167 }
00168 
00170 // CCrawlSession find a crawled node
00171 
00172 CCrawlNode* CCrawlSession::Find(IN_ADDR* pAddress, BOOL bCreate)
00173 {
00174         for ( POSITION pos = m_pNodes.GetTailPosition() ; pos ; )
00175         {
00176                 CCrawlNode* pNode = (CCrawlNode*)m_pNodes.GetPrev( pos );
00177 
00178                 if ( pNode->m_pHost.sin_addr.S_un.S_addr == pAddress->S_un.S_addr )
00179                 {
00180                         return pNode;
00181                 }
00182         }
00183 
00184         if ( ! bCreate ) return NULL;
00185 
00186         CCrawlNode* pNode = new CCrawlNode();
00187         pNode->m_nUnique = (DWORD)m_pNodes.AddTail( pNode );
00188 
00189         return pNode;
00190 }
00191 
00192 
00194 // CCrawlNode construction
00195 
00196 CCrawlNode::CCrawlNode()
00197 {
00198         ZeroMemory( &m_pHost, sizeof(m_pHost) );
00199 
00200         m_nType                 = ntUnknown;
00201         m_nLeaves               = 0;
00202         m_nLatitude             = 0;
00203         m_nLongitude    = 0;
00204 
00205         m_tDiscovered   = time( NULL );
00206         m_tCrawled              = 0;
00207         m_tResponse             = 0;
00208 }
00209 
00210 CCrawlNode::~CCrawlNode()
00211 {
00212 }
00213 
00215 // CCrawlNode process a crawl reply
00216 
00217 void CCrawlNode::OnCrawl(CCrawlSession* pSession, CG2Packet* pPacket)
00218 {
00219         BOOL bCompound;
00220         CHAR szType[9];
00221         DWORD nLength;
00222 
00223         m_tResponse = time( NULL );
00224         if ( m_tCrawled == 0 ) m_tCrawled = m_tResponse;
00225 
00226         while ( pPacket->ReadPacket( szType, nLength, &bCompound ) )
00227         {
00228                 DWORD nNext = pPacket->m_nPosition + nLength;
00229 
00230                 if ( strcmp( szType, "SELF" ) == 0 )
00231                 {
00232                         OnNode( pSession, pPacket, nLength, parseSelf );
00233                 }
00234                 else if ( strcmp( szType, "NH" ) == 0 )
00235                 {
00236                         OnNode( pSession, pPacket, nLength, parseHub );
00237                 }
00238                 else if ( strcmp( szType, "NL" ) == 0 )
00239                 {
00240                         OnNode( pSession, pPacket, nLength, parseLeaf );
00241                 }
00242 
00243                 pPacket->m_nPosition = nNext;
00244         }
00245 }
00246 
00248 // CCrawlNode process a crawl reply node
00249 
00250 void CCrawlNode::OnNode(CCrawlSession* pSession, CG2Packet* pPacket, DWORD nPacket, int nType)
00251 {
00252         SOCKADDR_IN pHost;
00253         pHost.sin_family = PF_INET + 1;
00254 
00255         BOOL bHub = FALSE;
00256         int nLeafs = 0;
00257 
00258         CString strNick;
00259         float nLatitude = 0;
00260         float nLongitude = 0;
00261 
00262         CHAR szType[9];
00263         DWORD nLength;
00264 
00265         while ( pPacket->ReadPacket( szType, nLength ) )
00266         {
00267                 DWORD nNext = pPacket->m_nPosition + nLength;
00268 
00269                 if ( strcmp( szType, "NA" ) == 0 && nLength >= 6 )
00270                 {
00271                         pHost.sin_family = PF_INET;
00272                         pHost.sin_addr.S_un.S_addr = pPacket->ReadLongLE();
00273                         pHost.sin_port = htons( pPacket->ReadShortBE() );
00274                 }
00275                 else if ( strcmp( szType, "HS" ) == 0 && nLength >= 2 )
00276                 {
00277                         bHub = TRUE;
00278                         nLeafs = (int)pPacket->ReadShortBE();
00279                 }
00280                 else if ( strcmp( szType, "NAME" ) == 0 )
00281                 {
00282                         strNick = pPacket->ReadString( nLength );
00283                 }
00284                 else if ( strcmp( szType, "GPS" ) == 0 && nLength >= 4 )
00285                 {
00286                         DWORD nGPS = pPacket->ReadLongBE();
00287                         nLatitude       = (float)HIWORD( nGPS ) / 65535.0f * 180.0f - 90.0f;
00288                         nLongitude      = (float)LOWORD( nGPS ) / 65535.0f * 360.0f - 180.0f;
00289                 }
00290 
00291                 pPacket->m_nPosition = nNext;
00292         }
00293 
00294         if ( pHost.sin_family != PF_INET ) return;
00295 
00296         if ( nType == parseSelf )
00297         {
00298                 m_pHost                 = pHost;
00299                 m_nType                 = bHub ? ntHub : ntLeaf;
00300                 m_nLeaves               = nLeafs;
00301                 m_sNick                 = strNick;
00302                 m_nLatitude             = nLatitude;
00303                 m_nLongitude    = nLongitude;
00304 
00305                 theApp.Message( MSG_TEMP, _T("CRAWL: Found %s, %s(%i), \"%s\", lat: %.3f, lon: %.3f :"),
00306                         (LPCTSTR)CString( inet_ntoa( pHost.sin_addr ) ), bHub ? _T("hub") : _T("leaf"),
00307                         nLeafs, (LPCTSTR)strNick, double( nLatitude ), double( nLongitude ) );
00308         }
00309         else
00310         {
00311                 CCrawlNode* pNode = pSession->Find( &pHost.sin_addr, TRUE );
00312 
00313                 if ( pNode->m_tResponse == 0 )
00314                 {
00315                         pNode->m_pHost          = pHost;
00316                         pNode->m_nType          = nType;
00317                         pNode->m_nLeaves        = nLeafs;
00318                         pNode->m_sNick          = strNick;
00319                         pNode->m_nLatitude      = nLatitude;
00320                         pNode->m_nLongitude     = nLongitude;
00321                 }
00322 
00323                 if ( m_pNeighbours.Find( pNode ) == NULL )
00324                 {
00325                         m_pNeighbours.AddTail( pNode );
00326                 }
00327 
00328                 theApp.Message( MSG_TEMP, _T("CRAWL:    %s, %s(%i), \"%s\", lat: %.3f, lon: %.3f"),
00329                         (LPCTSTR)CString( inet_ntoa( pHost.sin_addr ) ), bHub ? _T("hub") : _T("leaf"),
00330                         nLeafs, (LPCTSTR)strNick, double( nLatitude ), double( nLongitude ) );
00331         }
00332 }

Generated on Thu Dec 15 10:39:34 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2