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

📄 shakeneighbour.cpp

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

BOOL CShakeNeighbour::ReadResponse()
{
	CString strLine;

	if ( ! m_pInput->ReadLine( strLine ) ) return TRUE;
	if ( strLine.GetLength() > 1024 ) strLine = _T("#LINE_TOO_LONG#");

	theApp.Message( MSG_DEBUG, _T("%s: HANDSHAKE: %s"), (LPCTSTR)m_sAddress, (LPCTSTR)strLine );

	if ( strLine == _T("GNUTELLA OK") && m_bInitiated )
	{
		m_bShake06 = FALSE;
		OnHandshakeComplete();
		return FALSE;
	}
	else if ( strLine.GetLength() > 13 && strLine.Left( 12 ) == _T("GNUTELLA/0.6") )
	{
		if ( strLine != _T("GNUTELLA/0.6 200 OK") )
		{
			strLine = strLine.Mid( 13 );
			theApp.Message( MSG_ERROR, IDS_HANDSHAKE_REJECTED, (LPCTSTR)m_sAddress, (LPCTSTR)strLine );
			m_nState = nrsRejected;
		}
		else if ( ! m_bInitiated )
		{
			m_nState = nrsHandshake3;
		}
		else
		{
			m_bShake06 = TRUE;
			m_nState = nrsHandshake2;
		}
	}
	else if ( strLine == _T("GNUTELLA CONNECT/0.4") && ! m_bInitiated )
	{
		if ( Neighbours.IsLeaf() )
		{
			DelayClose( IDS_HANDSHAKE_IAMLEAF );
			return FALSE;
		}
		else if ( ! Neighbours.NeedMoreHubs( TS_FALSE ) )
		{
			DelayClose( IDS_HANDSHAKE_SURPLUS );
			return FALSE;
		}
		else
		{
			m_bShake06 = FALSE;
			m_pOutput->Print( "GNUTELLA OK\n\n" );
			OnHandshakeComplete();
			return FALSE;
		}
	}
	else if ( strLine.GetLength() > 17 && strLine.Left( 17 ) == _T("GNUTELLA CONNECT/") && ! m_bInitiated )
	{
		m_bShake06 = TRUE;
		m_nState = nrsHandshake2;
	}
	else if ( strLine.GetLength() > 21 && strLine.Left( 21 ) == _T("SHAREAZABETA CONNECT/") && ! m_bInitiated )
	{
		m_bShake06 = TRUE;
		m_nState = nrsHandshake2;
	}
	else
	{
		Close( IDS_HANDSHAKE_FAIL, TRUE );
		return FALSE;
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CShakeNeighbour handshake header processing

BOOL CShakeNeighbour::OnHeaderLine(CString& strHeader, CString& strValue)
{
	theApp.Message( MSG_DEBUG, _T("%s: GNUTELLA HEADER: %s: %s"),
		(LPCTSTR)m_sAddress, (LPCTSTR)strHeader, (LPCTSTR)strValue );
	
	if ( strHeader.CompareNoCase( _T("User-Agent") ) == 0 )
	{
		m_sUserAgent = strValue;
		if ( _tcsistr( m_sUserAgent, _T("Shareaza") ) ) m_bShareaza = TRUE;
	}
	else if ( strHeader.CompareNoCase( _T("Remote-IP") ) == 0 )
	{
		Network.AcquireLocalAddress( strValue );
	}
	else if (	strHeader.CompareNoCase( _T("X-My-Address") ) == 0 ||
				strHeader.CompareNoCase( _T("Listen-IP") ) == 0 ||
				strHeader.CompareNoCase( _T("Node") ) == 0 )
	{
		int nColon = strValue.Find( ':' );

		if ( nColon > 0 )
		{
			int nPort = GNUTELLA_DEFAULT_PORT;

			if ( _stscanf( strValue.Mid( nColon + 1 ), _T("%lu"), &nPort ) == 1 && nPort != 0 )
			{
				m_pHost.sin_port = htons( nPort );
			}
		}
	}
	else if ( strHeader.CompareNoCase( _T("Pong-Caching") ) == 0 )
	{
		m_bPongCaching = TRUE;
	}
	else if ( strHeader.CompareNoCase( _T("Vendor-Message") ) == 0 )
	{
		m_bVendorMsg = TRUE;
	}
	else if ( strHeader.CompareNoCase( _T("X-Query-Routing") ) == 0 )
	{
		m_bQueryRouting =  ( strValue != _T("0") && strValue != _T("0.0") );
	}
	else if (	strHeader.CompareNoCase( _T("X-Ultrapeer") ) == 0 ||
				strHeader.CompareNoCase( _T("X-Hub") ) == 0 )
	{
		m_bUltraPeerSet = ( strValue.CompareNoCase( _T("True") ) == 0 ) ? TS_TRUE : TS_FALSE;
	}
	else if (	strHeader.CompareNoCase( _T("X-Ultrapeer-Needed") ) == 0 ||
				strHeader.CompareNoCase( _T("X-Hub-Needed") ) == 0 )
	{
		m_bUltraPeerNeeded = ( strValue.CompareNoCase( _T("True") ) == 0 ) ? TS_TRUE : TS_FALSE;
	}
	else if (	strHeader.CompareNoCase( _T("X-Ultrapeer-Loaded") ) == 0 ||
				strHeader.CompareNoCase( _T("X-Hub-Loaded") ) == 0 )
	{
		m_bUltraPeerLoaded = ( strValue.CompareNoCase( _T("True") ) == 0 ) ? TS_TRUE : TS_FALSE;
	}
	else if ( strHeader.CompareNoCase( _T("GGEP") ) == 0 )
	{
		if ( Settings.Gnutella1.EnableGGEP )
		{
			m_bGGEP = ( strValue != _T("0") && strValue != _T("0.0") );
		}
	}
	else if ( strHeader.CompareNoCase( _T("Accept") ) == 0 && Settings.Gnutella2.EnableToday )
	{
		m_bG2Accept |= ( strValue.Find( _T("application/x-gnutella2") ) >= 0 );
		m_bG2Accept |= ( strValue.Find( _T("application/x-shareaza") ) >= 0 );
	}
	else if ( strHeader.CompareNoCase( _T("Content-Type") ) == 0 && Settings.Gnutella2.EnableToday )
	{
		m_bG2Send |= ( strValue.Find( _T("application/x-gnutella2") ) >= 0 );
		m_bG2Send |= ( strValue.Find( _T("application/x-shareaza") ) >= 0 );
	}
	else if ( strHeader.CompareNoCase( _T("Accept-Encoding") ) == 0 && m_bCanDeflate )
	{
		m_bDeflateAccept |= ( strValue.Find( _T("deflate") ) >= 0 );
	}
	else if ( strHeader.CompareNoCase( _T("Content-Encoding") ) == 0 && m_bCanDeflate )
	{
		m_bDeflateSend |= ( strValue.Find( _T("deflate") ) >= 0 );
	}
	else if (	strHeader.CompareNoCase( _T("X-Try-Ultrapeers") ) == 0 ||
				strHeader.CompareNoCase( _T("X-Try-Hubs") ) == 0 )
	{
		int nCount = 0;

		for ( strValue += ',' ; ; )
		{
			int nPort	= Settings.Connection.InPort;
			int nPos	= strValue.Find( ',' );
			
			if ( nPos < 0 ) break;
			
			CString strHost = strValue.Left( nPos );
			strValue = strValue.Mid( nPos + 1 );
			
			if ( m_bG2Accept || m_bG2Send || m_bShareaza )
			{
				if ( HostCache.Gnutella2.Add( strHost, 0, m_bShareaza ? SHAREAZA_VENDOR_T : NULL ) ) nCount++;
			}
			else
			{
				if ( HostCache.Gnutella1.Add( strHost, 0, m_bShareaza ? SHAREAZA_VENDOR_T : NULL ) ) nCount++;
			}
		}
		
		DiscoveryServices.OnGnutellaAdded( &m_pHost.sin_addr, nCount );
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CShakeNeighbour handshake end of headers

BOOL CShakeNeighbour::OnHeadersComplete()
{
	if ( ! Settings.Gnutella1.EnableToday && m_nState < nrsRejected )
	{
		if ( ! m_bG2Accept || ( m_bInitiated && ! m_bG2Send ) )
		{
			m_pOutput->Print( "GNUTELLA/0.6 503 G2 Required\r\n" );
			SendMinimalHeaders();
			m_pOutput->Print( "\r\n" );
			HostCache.OnFailure( &m_pHost.sin_addr, htons( m_pHost.sin_port ) );
			DelayClose( IDS_HANDSHAKE_NOTG2 );
			return FALSE;
		}
	}
	
	if ( m_nState == nrsRejected )
	{
		Close( 0 );
		return FALSE;
	}
	else if ( m_nState == nrsHandshake3 )
	{
		if ( m_bUltraPeerSet == TS_FALSE && m_nNodeType == ntNode &&
			 ( Neighbours.IsHub() || Neighbours.IsHubCapable() ) )
		{
			theApp.Message( MSG_DEFAULT, IDS_HANDSHAKE_BACK2LEAF, (LPCTSTR)m_sAddress );
			m_nNodeType = ntLeaf;
		}
		
		OnHandshakeComplete();
		return FALSE;
	}
	else if ( m_bInitiated )
	{
		BOOL bFallback = FALSE;

		if ( Neighbours.IsHub() || Neighbours.IsHubCapable() )
		{
			if ( m_bUltraPeerSet == TS_FALSE )
			{
				m_nNodeType = ntLeaf;
			}
			else if (	m_bUltraPeerSet == TS_TRUE && m_bUltraPeerNeeded == TS_TRUE
						/* && Network.NeedMoreHubs() */ )
			{
				m_nNodeType = ntNode;
			}
			else if ( m_bUltraPeerSet == TS_TRUE && m_bUltraPeerNeeded == TS_FALSE )
			{
				if ( Neighbours.GetCount( -1, nrsConnected, ntLeaf ) > 0 )
				{
					SendHostHeaders( _T("GNUTELLA/0.6 503 I have leaves") );
					DelayClose( IDS_HANDSHAKE_CANTBEPEER );
					return FALSE;
				}

				if ( ! Settings.Gnutella.LeafEnable )
				{
					SendHostHeaders( _T("GNUTELLA/0.6 503 Ultrapeer disabled") );
					DelayClose( IDS_HANDSHAKE_NOULTRAPEER );
					return FALSE;
				}

				m_nNodeType = ntHub;
				bFallback = TRUE;
			}
		}
		else if ( m_bUltraPeerSet == TS_TRUE )
		{
			if ( ! Settings.Gnutella.LeafEnable )
			{
				SendHostHeaders( _T("GNUTELLA/0.6 503 Ultrapeer disabled") );
				DelayClose( IDS_HANDSHAKE_NOULTRAPEER );
				return FALSE;
			}

			m_nNodeType = ntHub;
		}
		else if ( m_bUltraPeerSet != TS_TRUE )
		{
			if ( Settings.Gnutella.LeafEnable && Settings.Gnutella.LeafForce )
			{
				SendHostHeaders( _T("GNUTELLA/0.6 503 Need an Ultrapeer") );
				DelayClose( IDS_HANDSHAKE_NEEDAPEER );
				return FALSE;
			}
		}

		m_pOutput->Print( "GNUTELLA/0.6 200 OK\r\n" );
		SendPrivateHeaders();
		if ( bFallback ) m_pOutput->Print( "X-Ultrapeer: False\r\n" );
		m_pOutput->Print( "\r\n" );

		OnHandshakeComplete();
		return FALSE;
	}
	else
	{
		if ( Neighbours.IsLeaf() )
		{
			SendHostHeaders( _T("GNUTELLA/0.6 503 Shielded leaf node") );
			DelayClose( IDS_HANDSHAKE_IAMLEAF );
			return FALSE;
		}
		else if ( Neighbours.IsHub() || Neighbours.IsHubCapable() )
		{
			if ( m_bUltraPeerSet == TS_FALSE )
			{
				m_nNodeType = ntLeaf;
			}
			else if ( m_bUltraPeerSet == TS_TRUE )
			{
				m_nNodeType = ntNode;
			}
		}
		else if ( m_bUltraPeerSet == TS_TRUE && Settings.Gnutella.LeafEnable )
		{
			m_nNodeType = ntHub;
		}
		
		if ( ( m_nNodeType == ntLeaf && ! Neighbours.NeedMoreHubs( m_bG2Accept ? TS_TRUE : TS_FALSE ) &&
			 ! Neighbours.NeedMoreLeafs( m_bG2Accept ? TS_TRUE : TS_FALSE ) ) ||
			 ( m_nNodeType != ntLeaf && ! Neighbours.NeedMoreHubs( m_bG2Accept ? TS_TRUE : TS_FALSE ) ) )
		{
			SendHostHeaders( _T("GNUTELLA/0.6 503 Maximum connections reached") );
			DelayClose( IDS_HANDSHAKE_SURPLUS );
			return FALSE;
		}
		else if ( ( m_nNodeType == ntHub && ! Settings.Gnutella.LeafEnable ) ||
				  ( m_nNodeType == ntLeaf && ! Settings.Gnutella.HubEnable ) )
		{
			SendHostHeaders( _T("GNUTELLA/0.6 503 Ultrapeer disabled") );
			DelayClose( IDS_HANDSHAKE_NOULTRAPEER );
			return FALSE;
		}
		else if ( m_nNodeType != ntHub && Settings.Gnutella.LeafEnable && Settings.Gnutella.LeafForce )
		{
			SendHostHeaders( _T("GNUTELLA/0.6 503 Need an Ultrapeer") );
			DelayClose( IDS_HANDSHAKE_NEEDAPEER );
			return FALSE;
		}
		else
		{
			m_pOutput->Print( "GNUTELLA/0.6 200 OK\r\n" );
			SendPublicHeaders();
			SendPrivateHeaders();
			SendHostHeaders();

			if ( m_nNodeType != ntLeaf &&
				 Neighbours.NeedMoreHubs( m_bG2Accept ? TS_TRUE : TS_FALSE ) )
			{
				if ( Settings.Gnutella.HubEnable )
				{
					m_pOutput->Print( "X-Ultrapeer-Needed: True\r\n" );
				}
			}
			else
			{
				if ( Settings.Gnutella.LeafEnable )
				{
					m_pOutput->Print( "X-Ultrapeer-Needed: False\r\n" );
				}
			}

			m_pOutput->Print( "\r\n" );
			m_nState = nrsHandshake1;
		}
	}

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CShakeNeighbour handshake completed

void CShakeNeighbour::OnHandshakeComplete()
{
	Neighbours.Remove( this );

	switch ( m_nNodeType )
	{
	case ntHub:
		m_mInput.pLimit		= &Settings.Bandwidth.HubIn;
		m_mOutput.pLimit	= &Settings.Bandwidth.HubOut;
		break;
	case ntLeaf:
		m_mInput.pLimit		= &Settings.Bandwidth.LeafIn;
		m_mOutput.pLimit	= &Settings.Bandwidth.LeafOut;
		break;
	case ntNode:
		m_mInput.pLimit		= &Settings.Bandwidth.PeerIn;
		m_mOutput.pLimit	= &Settings.Bandwidth.PeerOut;
		break;
	}

	if ( m_bDeflateSend )	m_pZInput	= new CBuffer();
	if ( m_bDeflateAccept )	m_pZOutput	= new CBuffer();

	if ( Settings.Connection.SendBuffer )
	{
		setsockopt( m_hSocket, SOL_SOCKET, SO_SNDBUF, (LPSTR)&Settings.Connection.SendBuffer, 4 );
	}

	CNeighbour* pNeighbour = NULL;

	if ( m_bG2Send && m_bG2Accept )
	{
		m_bQueryRouting = TRUE;
		pNeighbour = new CG2Neighbour( this );
	}
	else
	{
		m_bShareaza = FALSE;
		pNeighbour = new CG1Neighbour( this );
	}

	if ( m_nNodeType == ntHub )
	{
		theApp.Message( MSG_DEFAULT, IDS_HANDSHAKE_GOTPEER );
		Neighbours.PeerPrune();
	}
	else if ( m_nNodeType == ntLeaf )
	{
		theApp.Message( MSG_DEFAULT, IDS_HANDSHAKE_GOTLEAF, (LPCTSTR)m_sAddress );
	}

	m_pZInput	= NULL;
	m_pZOutput	= NULL;
	
	delete this;
}

⌨️ 快捷键说明

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