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

📄 network.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Network.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Network.h"
#include "Security.h"
#include "Handshakes.h"
#include "Neighbours.h"
#include "Neighbour.h"
#include "Datagrams.h"
#include "HostCache.h"
#include "RouteCache.h"
#include "QueryKeys.h"
#include "GProfile.h"
#include "Transfers.h"
#include "Downloads.h"
#include "Statistics.h"
#include "DiscoveryServices.h"

#include "CrawlSession.h"
#include "SearchManager.h"
#include "QueryHashMaster.h"
#include "QuerySearch.h"
#include "QueryHit.h"
#include "Buffer.h"
#include "G1Packet.h"
#include "G2Packet.h"
#include "G1Neighbour.h"

#include "WndMain.h"
#include "WndChild.h"
#include "WndSearchMonitor.h"
#include "WndHitMonitor.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CNetwork Network;


//////////////////////////////////////////////////////////////////////
// CNetwork construction

CNetwork::CNetwork()
{
	NodeRoute		= new CRouteCache();
	QueryRoute		= new CRouteCache();
	QueryKeys		= new CQueryKeys();
	
	m_bEnabled		= FALSE;
	m_bAutoConnect	= FALSE;
	m_nSequence		= 0;
	m_hThread		= NULL;
}

CNetwork::~CNetwork()
{
	delete QueryKeys;
	delete QueryRoute;
	delete NodeRoute;
}

//////////////////////////////////////////////////////////////////////
// CNetwork attributes

BOOL CNetwork::IsAvailable() const
{
	DWORD dwState = 0;
	// return InternetGetConnectedState( &dwState, 0 );
	return FALSE;
}

BOOL CNetwork::IsConnected() const
{
	return m_bEnabled;
}

BOOL CNetwork::IsListening() const
{
	return m_bEnabled
		&& ( m_pHost.sin_addr.S_un.S_addr != 0 )
		&& ( m_pHost.sin_port != 0 )
		&& ( Handshakes.IsListening() );
}

int CNetwork::IsWellConnected() const
{
	return Neighbours.m_nStableCount;
}

BOOL CNetwork::IsStable() const
{
	return IsListening() && ( Handshakes.m_nStableCount > 0 );
}

DWORD CNetwork::GetStableTime() const
{
	if ( ! IsStable() || ! Handshakes.m_tStableTime ) return 0;
	return (DWORD)time( NULL ) - Handshakes.m_tStableTime;
}

BOOL CNetwork::IsConnectedTo(IN_ADDR* pAddress)
{
	if ( pAddress->S_un.S_addr == m_pHost.sin_addr.S_un.S_addr ) return TRUE;
	if ( Handshakes.IsConnectedTo( pAddress ) ) return TRUE;
	if ( Neighbours.Get( pAddress ) != NULL ) return TRUE;
	if ( Transfers.IsConnectedTo( pAddress ) ) return TRUE;
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CNetwork connection

BOOL CNetwork::Connect(BOOL bAutoConnect)
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	if ( bAutoConnect ) m_bAutoConnect = TRUE;
	Settings.Live.AutoClose = FALSE;
	
	if ( m_bEnabled )
	{
		if ( bAutoConnect ) DiscoveryServices.Execute();
		return TRUE;
	}
	
	theApp.Message( MSG_SYSTEM, IDS_NETWORK_STARTUP );
	
	Resolve( Settings.Connection.InHost, Settings.Connection.InPort, &m_pHost );
	
	if ( Settings.Connection.Firewalled )
		theApp.Message( MSG_DEFAULT, IDS_NETWORK_FIREWALLED );
	
	SOCKADDR_IN pOutgoing;

	if ( Resolve( Settings.Connection.OutHost, 0, &pOutgoing ) )
	{
		theApp.Message( MSG_DEFAULT, IDS_NETWORK_OUTGOING,
			(LPCTSTR)CString( inet_ntoa( pOutgoing.sin_addr ) ),
			htons( pOutgoing.sin_port ) );
	}
	else if ( Settings.Connection.OutHost.GetLength() )
	{
		theApp.Message( MSG_ERROR, IDS_NETWORK_CANT_OUTGOING,
			(LPCTSTR)Settings.Connection.OutHost );
	}
	
	Handshakes.Listen();
	Datagrams.Listen();
	Neighbours.Connect();
	
	NodeRoute->SetDuration( Settings.Gnutella.RouteCache );
	QueryRoute->SetDuration( Settings.Gnutella.RouteCache );
	
	m_bEnabled	= TRUE;
	m_hThread	= AfxBeginThread( ThreadStart, this, THREAD_PRIORITY_NORMAL )->m_hThread;
	
	// if ( m_bAutoConnect && bAutoConnect ) DiscoveryServices.Execute();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CNetwork disconnect

void CNetwork::Disconnect()
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	if ( ! m_bEnabled ) return;
	
	theApp.Message( MSG_DEFAULT, _T("") );
	theApp.Message( MSG_SYSTEM, IDS_NETWORK_DISCONNECTING );
	
	m_bEnabled		= FALSE;
	m_bAutoConnect	= FALSE;
	
	Neighbours.Close();
	
	pLock.Unlock();
	
	if ( m_hThread != NULL )
	{
		m_pWakeup.SetEvent();
		
		for ( int nAttempt = 10 ; nAttempt > 0 ; nAttempt-- )
		{
			DWORD nCode;
			if ( ! GetExitCodeThread( m_hThread, &nCode ) ) break;
			if ( nCode != STILL_ACTIVE ) break;
			Sleep( 100 );
		}
		
		if ( nAttempt == 0 )
		{
			TerminateThread( m_hThread, 0 );
			theApp.Message( MSG_DEBUG, _T("WARNING: Terminating CNetwork thread.") );
			Sleep( 100 );
		}
		
		m_hThread = NULL;
	}
	
	Handshakes.Disconnect();
	pLock.Lock();
	
	Neighbours.Close();
	Datagrams.Disconnect();
	
	NodeRoute->Clear();
	QueryRoute->Clear();
	
	if ( TRUE )
	{
		for ( POSITION pos = m_pLookups.GetStartPosition() ; pos ; )
		{
			LPBYTE pAsync, pBuffer;
			m_pLookups.GetNextAssoc( pos, (VOID*&)pAsync, (VOID*&)pBuffer );
			WSACancelAsyncRequest( (HANDLE)pAsync );
			delete *(CString**)pBuffer;
			free( pBuffer );
		}
		
		m_pLookups.RemoveAll();
	}
	
	pLock.Unlock();
	
	DiscoveryServices.Stop();
	
	theApp.Message( MSG_SYSTEM, IDS_NETWORK_DISCONNECTED ); 
	theApp.Message( MSG_DEFAULT, _T("") );
}

//////////////////////////////////////////////////////////////////////
// CNetwork host connection

BOOL CNetwork::ConnectTo(LPCTSTR pszAddress, int nPort, PROTOCOLID nProtocol, BOOL bNoUltraPeer)
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	if ( ! m_bEnabled && ! Connect() ) return FALSE;
	
	if ( nPort == 0 ) nPort = GNUTELLA_DEFAULT_PORT;
	theApp.Message( MSG_DEFAULT, IDS_NETWORK_RESOLVING, pszAddress );
	
	if ( AsyncResolve( pszAddress, (WORD)nPort, nProtocol, bNoUltraPeer ? 2 : 1 ) ) return TRUE;
	
	theApp.Message( MSG_ERROR, IDS_NETWORK_RESOLVE_FAIL, pszAddress );
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CNetwork local IP aquisition and sending

void CNetwork::AcquireLocalAddress(LPCTSTR pszHeader)
{
	int nIP[4];
	
	if ( _stscanf( pszHeader, _T("%i.%i.%i.%i"), &nIP[0], &nIP[1], &nIP[2], &nIP[3] ) != 4 ) return;
	
	IN_ADDR pAddress;
	
	pAddress.S_un.S_un_b.s_b1 = (BYTE)nIP[0];
	pAddress.S_un.S_un_b.s_b2 = (BYTE)nIP[1];
	pAddress.S_un.S_un_b.s_b3 = (BYTE)nIP[2];
	pAddress.S_un.S_un_b.s_b4 = (BYTE)nIP[3];
	
	if ( IsFirewalledAddress( &pAddress ) ) return;
	
	m_pHost.sin_addr = pAddress;
}

//////////////////////////////////////////////////////////////////////
// CNetwork GGUID generation

void CNetwork::CreateID(GGUID* pID)
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	*pID = MyProfile.GUID;
	
	DWORD *pNum = (DWORD*)pID;
	pNum[0] += GetTickCount();
	pNum[1] += ( m_nSequence++ );
	pNum[2] += rand() * rand();
	pNum[3] += rand() * rand();
}

//////////////////////////////////////////////////////////////////////
// CNetwork firewalled address checking

BOOL CNetwork::IsFirewalledAddress(LPVOID pAddress, BOOL bIncludeSelf)
{
	if ( ! pAddress ) return TRUE;
	if ( ! Settings.Connection.IgnoreLocalIP ) return FALSE;
	
	DWORD nAddress = *(DWORD*)pAddress;
	
	if ( ! nAddress ) return TRUE;
	if ( ( nAddress & 0xFFFF ) == 0xA8C0 ) return TRUE;
	if ( ( nAddress & 0xF0AC ) == 0x08AC ) return TRUE;
	if ( ( nAddress & 0xFF ) == 0x0A ) return TRUE;
	if ( ( nAddress & 0xFF ) == 0x7F ) return TRUE;		// 127.*
	
	if ( bIncludeSelf && nAddress == *(DWORD*)(&m_pHost.sin_addr) ) return TRUE;
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CNetwork name resolution

BOOL CNetwork::Resolve(LPCTSTR pszHost, int nPort, SOCKADDR_IN* pHost, BOOL bNames) const
{
	ZeroMemory( pHost, sizeof(*pHost) );
	pHost->sin_family	= PF_INET;
	pHost->sin_port		= htons( nPort );
	
	if ( pszHost == NULL || *pszHost == 0 ) return FALSE;
	
	CString strHost( pszHost );
	
	int nColon = strHost.Find( ':' );
	
	if ( nColon >= 0 )
	{
		if ( _stscanf( strHost.Mid( nColon + 1 ), _T("%i"), &nPort ) == 1 )
		{
			pHost->sin_port = htons( nPort );
		}
		
		strHost = strHost.Left( nColon );
	}
	
	USES_CONVERSION;
	LPCSTR pszaHost = T2CA( (LPCTSTR)strHost );
	
	DWORD dwIP = inet_addr( pszaHost );
	
	if ( dwIP == INADDR_NONE )
	{
		if ( ! bNames ) return TRUE;
		
		HOSTENT* pLookup = gethostbyname( pszaHost );
		
		if ( pLookup == NULL ) return FALSE;
		
		CopyMemory( &pHost->sin_addr, pLookup->h_addr, 4 );
	}
	else

⌨️ 快捷键说明

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