⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 discoveryservices.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices thread bootstrap

UINT CDiscoveryServices::ThreadStart(LPVOID pParam)
{
	CDiscoveryServices* pClass = (CDiscoveryServices*)pParam;
	pClass->OnRun();
	return 0;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices thread run

void CDiscoveryServices::OnRun()
{
	BOOL bSuccess = TRUE;
	
	if ( m_nWebCache == wcmServerMet )
	{
		bSuccess = RunServerMet();
	}
	else if ( m_nWebCache == wcmHosts )
	{
		bSuccess = RunWebCacheGet( FALSE );
		
		if ( bSuccess && m_hInternet )
		{
			CSingleLock pLock( &Network.m_pSection, TRUE );
			
			if ( m_bFirstTime || ( GetCount( CDiscoveryService::dsWebCache ) < (int)Settings.Discovery.Lowpoint ) )
			{
				m_bFirstTime = FALSE;
				pLock.Unlock();
				bSuccess = RunWebCacheGet( TRUE );
			}
		}
	}
	else if ( m_nWebCache == wcmCaches )
	{
		bSuccess = RunWebCacheGet( TRUE );
	}
	else if ( m_nWebCache == wcmUpdate )
	{
		bSuccess = RunWebCacheUpdate();
		if ( ! bSuccess ) m_tUpdated = 0;
	}
	else if ( m_nWebCache == wcmSubmit )
	{
		bSuccess = RunWebCacheUpdate();
	}
	
	if ( m_hInternet && ! bSuccess )
	{
		CSingleLock pLock( &Network.m_pSection );
		if ( pLock.Lock( 250 ) && Check( m_pWebCache ) ) m_pWebCache->OnFailure();
	}
	
	if ( m_hInternet != NULL )
	{
		if ( m_hRequest != NULL ) InternetCloseHandle( m_hRequest );
		InternetCloseHandle( m_hInternet );
		m_hInternet	= NULL;
		m_hRequest	= NULL;
	}
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices execute hosts request

BOOL CDiscoveryServices::RunWebCacheGet(BOOL bCaches)
{
	CSingleLock pLock( &Network.m_pSection, TRUE );
	CString strURL, strOutput;
	
	if ( ! Check( m_pWebCache ) ) return FALSE;
	m_pWebCache->OnAccess();
	
	if ( bCaches )
		strURL = m_pWebCache->m_sAddress + _T("?get=1&urlfile=1");
	else
		strURL = m_pWebCache->m_sAddress + _T("?get=1&hostfile=1");
	
	if ( m_bForG2 ) strURL += _T("&net=gnutella2");
	
	pLock.Unlock();
	if ( ! SendWebCacheRequest( strURL, strOutput ) ) return FALSE;
	pLock.Lock();
	
	if ( ! Check( m_pWebCache ) ) return FALSE;
	
	BOOL bSuccess = FALSE;
	int nIP[4], nIPs = 0;
	
	for ( strOutput += '\n' ; strOutput.GetLength() ; )
	{
		CString strLine	= strOutput.SpanExcluding( _T("\r\n") );
		strOutput		= strOutput.Mid( strLine.GetLength() + 1 );
		
		strLine.TrimLeft();
		strLine.TrimRight();
		if ( strLine.IsEmpty() ) continue;
		
		theApp.Message( MSG_DEBUG, _T("GWebCache(get): %s"), (LPCTSTR)strLine );
		
		if ( _tcsnicmp( strLine, _T("h|"), 2 ) == 0 )
		{
			// IP ADDRESS AT: strLine.Mid( 2 )
			// CORRECT (REQUESTED) NETWORK
			
			strLine = strLine.Mid( 2 );
			int nBreak	= strLine.Find( '|' );
			DWORD tSeen	= 0;

			if ( nBreak > 0 )
			{
				int nSeconds = 0;
				_stscanf( strLine.Mid( nBreak + 1 ), _T("%lu"), &nSeconds );
				nSeconds = max( 0, min( 18000, nSeconds ) );
				strLine = strLine.Left( nBreak );
				tSeen = time( NULL ) - nSeconds;
			}
			
			if ( m_bForG2 )
				HostCache.Gnutella2.Add( strLine, tSeen );
			else
				HostCache.Gnutella1.Add( strLine, tSeen );
			
			m_pWebCache->OnHostAdd();
			m_pWebCache->m_bGnutella2 = TRUE;
			bSuccess = TRUE;
			nIPs ++;
		}
		else if ( _tcsnicmp( strLine, _T("u|"), 2 ) == 0 )
		{
			// URL ADDRESS AT: strLine.Mid( 2 )
			// CORRECT (REQUESTED) NETWORK
			Add( strLine.Mid( 2 ).SpanExcluding( _T("|") ), CDiscoveryService::dsWebCache, m_bForG2 );
			m_pWebCache->m_bGnutella2 = TRUE;
			m_bFirstTime = FALSE;
			bSuccess = TRUE;
		}
		else if ( _tcsnicmp( strLine, _T("i|"), 2 ) == 0 )
		{
			// INFORMATIONAL
			
			bSuccess = TRUE;
			m_pWebCache->m_bGnutella2 = TRUE;
			
			if ( _tcsnicmp( strLine, _T("i|access|period|"), 16 ) == 0 )
			{
				_stscanf( (LPCTSTR)strLine + 16, _T("%lu"), &m_pWebCache->m_nAccessPeriod );
			}
			else if ( strLine == _T("i|force|remove") )
			{
				m_pWebCache->Remove();
				return FALSE;
			}
			
			if ( _tcsistr( strLine, _T("ERROR") ) != NULL )
			{
				// ERROR CONDITION
				return FALSE;
			}
		}
		else if ( _tcsistr( strLine, _T("ERROR") ) != NULL )
		{
			// ERROR CONDITION
			return FALSE;
		}
		else if ( _stscanf( strLine, _T("%i.%i.%i.%i"), &nIP[0], &nIP[1], &nIP[2], &nIP[3] ) == 4 )
		{
			// Plain IP, NOT G2
			HostCache.Gnutella1.Add( strLine );
			m_pWebCache->OnHostAdd();
			m_pWebCache->m_bGnutella2 = FALSE;
			bSuccess = TRUE;
		}
		else
		{
			// Plain URL, WRONG NETWORK
			Add( strLine.SpanExcluding( _T(" ") ), CDiscoveryService::dsWebCache, FALSE );
			m_pWebCache->m_bGnutella2 = FALSE;
			m_bFirstTime = FALSE;
		}
	}
	
	if ( bSuccess )
	{
		m_pWebCache->OnSuccess();
		if ( HostCache.Gnutella2.GetNewest() != NULL && nIPs > 0 ) m_tQueried = time( NULL );
		return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices execute update request

BOOL CDiscoveryServices::RunWebCacheUpdate()
{
	CSingleLock pLock( &Network.m_pSection, TRUE );
	CString strURL, strOutput;

	if ( ! Check( m_pWebCache, CDiscoveryService::dsWebCache ) ) return FALSE;
	m_pWebCache->OnAccess();
	
	if ( m_nWebCache == wcmUpdate )
	{
		if ( ! Network.IsListening() ) return TRUE;

		strURL.Format( _T("%s?update=1&ip=%s:%lu&x.leaves=%lu"),
			(LPCTSTR)m_pWebCache->m_sAddress,
			(LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ),
			htons( Network.m_pHost.sin_port ),
			Neighbours.GetCount( -1, -1, ntLeaf ) );
	}
	
	if ( m_pSubmit != NULL && Check( m_pSubmit, CDiscoveryService::dsWebCache ) &&
		 m_pWebCache->m_bGnutella2 == m_pSubmit->m_bGnutella2 )
	{
		if ( strURL.IsEmpty() )
		{
			strURL.Format( _T("%s?url="), (LPCTSTR)m_pWebCache->m_sAddress );
		}
		else
		{
			strURL += _T("&url=");
		}
		
		CString strSubmit( m_pSubmit->m_sAddress );
		
		for ( int nSubmit = 0 ; nSubmit < strSubmit.GetLength() ; nSubmit ++ )
		{
			if ( (WORD)strSubmit.GetAt( nSubmit ) > 127 )
			{
				strSubmit = strSubmit.Left( nSubmit );
				break;
			}
		}
		
		strURL += CConnection::URLEncode( strSubmit );
	}
	
	if ( Settings.Gnutella2.EnableToday ) strURL += _T("&net=gnutella2");
	
	pLock.Unlock();
	
	if ( strURL.IsEmpty() ) return FALSE;
	
	if ( ! SendWebCacheRequest( strURL, strOutput ) ) return FALSE;
	
	pLock.Lock();
	if ( ! Check( m_pWebCache, CDiscoveryService::dsWebCache ) ) return FALSE;
	
	for ( strOutput += '\n' ; strOutput.GetLength() ; )
	{
		CString strLine	= strOutput.SpanExcluding( _T("\r\n") );
		strOutput		= strOutput.Mid( strLine.GetLength() + 1 );
		
		strLine.TrimLeft();
		strLine.TrimRight();
		
		if ( strLine.IsEmpty() ) continue;
		
		theApp.Message( MSG_DEBUG, _T("GWebCache(update): %s"), (LPCTSTR)strLine );
		
		if ( _tcsstr( strLine, _T("OK") ) )
		{
			m_pWebCache->m_tUpdated = (DWORD)time( NULL );
			m_pWebCache->m_nUpdates++;
			m_pWebCache->OnSuccess();
			return TRUE;
		}
		else if ( _tcsstr( strLine, _T("ERROR") ) )
		{
			return FALSE;
		}
		else if ( _tcsnicmp( strLine, _T("i|access|period|"), 16 ) == 0 )
		{
			_stscanf( (LPCTSTR)strLine + 16, _T("%lu"), &m_pWebCache->m_nAccessPeriod );
		}
		else if ( _tcsnicmp( strLine, _T("i|update|period|"), 16 ) == 0 )
		{
			_stscanf( (LPCTSTR)strLine + 16, _T("%lu"), &m_pWebCache->m_nUpdatePeriod );
		}
		else if ( strLine == _T("i|force|remove") )
		{
			m_pWebCache->Remove();
			break;
		}
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices HTTP request controllor

BOOL CDiscoveryServices::SendWebCacheRequest(CString strURL, CString& strOutput)
{
	strOutput.Empty();
	
	strURL += _T("&client=RAZA&version=");
	strURL += theApp.m_sVersion;
	
	theApp.Message( MSG_DEBUG, _T("DiscoveryService URL: %s"), (LPCTSTR)strURL );
	
	if ( m_hRequest ) InternetCloseHandle( m_hRequest );
	
	m_hRequest = InternetOpenUrl( m_hInternet, strURL, _T("Connection: close"), -1,
		INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_NO_COOKIES, 0 );
	if ( m_hRequest == NULL ) return FALSE;
	
	DWORD nStatusCode = 0, nStatusLen = 32;
	TCHAR szStatusCode[32];
	
	if ( ! HttpQueryInfo( m_hRequest, HTTP_QUERY_STATUS_CODE, szStatusCode,
		&nStatusLen, NULL ) ) return FALSE;
	
	_stscanf( szStatusCode, _T("%lu"), &nStatusCode );
	if ( nStatusCode < 200 || nStatusCode > 299 ) return FALSE;
	
	DWORD nRemaining, nResponse = 0;
	LPBYTE pResponse = NULL;
	
	while ( InternetQueryDataAvailable( m_hRequest, &nRemaining, 0, 0 ) && nRemaining > 0 )
	{
		pResponse = (LPBYTE)realloc( pResponse, nResponse + nRemaining );
		InternetReadFile( m_hRequest, pResponse + nResponse, nRemaining, &nRemaining );
		nResponse += nRemaining;
	}
	
	if ( nRemaining )
	{
		free( pResponse );
		return FALSE;
	}
	
	LPTSTR pszResponse = strOutput.GetBuffer( nResponse );
	for ( nStatusCode = 0 ; nStatusCode < nResponse ; nStatusCode++ )
		pszResponse[ nStatusCode ] = (TCHAR)pResponse[ nStatusCode ];
	strOutput.ReleaseBuffer( nResponse );
	
	free( pResponse );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryServices execute server.met request

BOOL CDiscoveryServices::RunServerMet()
{
	CSingleLock pLock( &Network.m_pSection, TRUE );
	CString strURL;
	
	if ( ! Check( m_pWebCache, CDiscoveryService::dsServerMet ) ) return FALSE;
	
	m_pWebCache->OnAccess();
	strURL = m_pWebCache->m_sAddress;
	
	pLock.Unlock();
	
	if ( m_hRequest != NULL ) InternetCloseHandle( m_hRequest );
	
	m_hRequest = InternetOpenUrl( m_hInternet, strURL, NULL, 0,
		INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE, 0 );
	
	if ( m_hRequest == NULL ) return FALSE;
	
	DWORD nRemaining = 0;
	BYTE pBuffer[1024];
	CMemFile pFile;
	
	while ( InternetQueryDataAvailable( m_hRequest, &nRemaining, 0, 0 ) && nRemaining > 0 )
	{
		while ( nRemaining > 0 )
		{
			DWORD nBuffer = min( nRemaining, 1024 );
			InternetReadFile( m_hRequest, pBuffer, nBuffer, &nBuffer );
			pFile.Write( pBuffer, nBuffer );
			nRemaining -= nBuffer;
		}
	}
	
	pFile.Seek( 0, CFile::begin );
	
	pLock.Lock();
	
	if ( ! Check( m_pWebCache, CDiscoveryService::dsServerMet ) ) return FALSE;
	
	int nCount = HostCache.eDonkey.ImportMET( &pFile );
	
	if ( ! nCount ) return FALSE;
	
	HostCache.Save();
	m_pWebCache->OnHostAdd( nCount );
	m_pWebCache->OnSuccess();
	
	return TRUE;
}


//////////////////////////////////////////////////////////////////////
// CDiscoveryService construction

CDiscoveryService::CDiscoveryService(int nType, LPCTSTR pszAddress)
{
	m_nType			= nType;
	m_bGnutella2	= FALSE;
	m_tCreated		= (DWORD)time( NULL );
	m_tAccessed		= 0;
	m_nAccesses		= 0;
	m_tUpdated		= 0;
	m_nUpdates		= 0;
	m_nFailures		= 0;
	m_nHosts		= 0;
	m_nAccessPeriod	= max( Settings.Discovery.UpdatePeriod, 1800 );
	m_nUpdatePeriod	= Settings.Discovery.DefaultUpdate;
	
	if ( pszAddress != NULL ) m_sAddress = pszAddress;
}

CDiscoveryService::~CDiscoveryService()
{
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryService remove

void CDiscoveryService::Remove()
{
	DiscoveryServices.Remove( this );
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryService serialize

void CDiscoveryService::Serialize(CArchive& ar, int nVersion)
{
	if ( ar.IsStoring() )
	{
		ar << m_nType;
		ar << m_sAddress;
		ar << m_bGnutella2;
		ar << m_tCreated;
		ar << m_tAccessed;
		ar << m_nAccesses;
		ar << m_tUpdated;
		ar << m_nUpdates;
		ar << m_nFailures;
		ar << m_nHosts;
		ar << m_nAccessPeriod;
		ar << m_nUpdatePeriod;
	}
	else
	{
		ar >> m_nType;
		ar >> m_sAddress;
		ar >> m_bGnutella2;
		ar >> m_tCreated;
		ar >> m_tAccessed;
		ar >> m_nAccesses;
		ar >> m_tUpdated;
		ar >> m_nUpdates;
		ar >> m_nFailures;
		ar >> m_nHosts;
		ar >> m_nAccessPeriod;
		ar >> m_nUpdatePeriod;
	}
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryService execute

BOOL CDiscoveryService::Execute(int nMode)
{
	CSingleLock pLock( &Network.m_pSection );
	if ( ! pLock.Lock( 250 ) ) return FALSE;
	
	if ( nMode != CDiscoveryServices::wcmSubmit )
	{
		theApp.Message( MSG_SYSTEM, IDS_DISCOVERY_QUERY, (LPCTSTR)m_sAddress );
	}
	else
	{
		theApp.Message( MSG_SYSTEM, IDS_DISCOVERY_SUBMIT, (LPCTSTR)m_sAddress );
	}
	
	if ( m_nType == dsGnutella )
	{
		return ResolveGnutella();
	}
	else if ( m_nType == dsWebCache )
	{
		return DiscoveryServices.RequestWebCache( this, nMode );
	}
	else if ( m_nType == dsServerMet )
	{
		return DiscoveryServices.RequestWebCache( this, CDiscoveryServices::wcmServerMet );
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryService resolve a gnutella node

BOOL CDiscoveryService::ResolveGnutella()
{
	CString strHost	= m_sAddress;
	int nPort		= GNUTELLA_DEFAULT_PORT;
	int nPos		= strHost.Find( ':' );
	
	if ( nPos >= 0 && _stscanf( strHost.Mid( nPos + 1 ), _T("%i"), &nPort ) == 1 )
		strHost = strHost.Left( nPos );
	
	if ( ! Network.Connect( FALSE ) ) return FALSE;
	
	if ( Network.AsyncResolve( strHost, (WORD)nPort, PROTOCOL_G1, 0 ) )
	{
		OnSuccess();
		return TRUE;
	}
	
	OnFailure();
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDiscoveryService events

void CDiscoveryService::OnAccess()
{
	m_tAccessed = (DWORD)time( NULL );
	m_nAccesses ++;
}

void CDiscoveryService::OnHostAdd(int nCount)
{
	m_nHosts += nCount;
	m_nFailures = 0;
}

void CDiscoveryService::OnSuccess()
{
	m_nFailures = 0;

	if ( m_nType == dsWebCache || m_nType == dsServerMet )
	{
		theApp.Message( MSG_DEFAULT, IDS_DISCOVERY_WEB_SUCCESS,
			(LPCTSTR)m_sAddress );
	}
}

void CDiscoveryService::OnFailure()
{
	m_nFailures++;
	
	theApp.Message( MSG_ERROR, IDS_DISCOVERY_FAILED,
		(LPCTSTR)m_sAddress, m_nFailures );
	
	if ( m_nFailures >= Settings.Discovery.FailureLimit )
	{
		theApp.Message( MSG_ERROR, IDS_DISCOVERY_FAIL_REMOVE,
			(LPCTSTR)m_sAddress, m_nFailures );
		Remove();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -