00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00043
00044 CCrawlSession::CCrawlSession()
00045 {
00046 m_bActive = FALSE;
00047 }
00048
00049 CCrawlSession::~CCrawlSession()
00050 {
00051 Clear();
00052 }
00053
00055
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
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
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
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
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
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
00167 }
00168
00170
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
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
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
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 }