📄 network.cpp
字号:
//
// 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 + -