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