00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "StdAfx.h"
00027 #include "Shareaza.h"
00028 #include "Settings.h"
00029 #include "Network.h"
00030 #include "Neighbours.h"
00031 #include "Neighbour.h"
00032 #include "Security.h"
00033 #include "RouteCache.h"
00034 #include "Library.h"
00035 #include "Buffer.h"
00036 #include "Packet.h"
00037 #include "G1Packet.h"
00038 #include "G2Packet.h"
00039 #include "SearchManager.h"
00040 #include "QueryHashTable.h"
00041 #include "QueryHashGroup.h"
00042 #include "QueryHashMaster.h"
00043 #include "QueryHit.h"
00044 #include "GProfile.h"
00045 #include "Statistics.h"
00046 #include <zlib.h>
00047
00048
00049 #ifdef _DEBUG
00050 #undef THIS_FILE
00051 static char THIS_FILE[]=__FILE__;
00052 #define new DEBUG_NEW
00053 #endif
00054
00055
00056 #define Z_TIMER 200
00057
00059
00060
00061
00062
00063 CNeighbour::CNeighbour(PROTOCOLID nProtocol)
00064 {
00065
00066 m_nProtocol = nProtocol;
00067
00068
00069 m_nState = nrsNull;
00070 m_pVendor = NULL;
00071 m_bGUID = FALSE;
00072 m_pProfile = NULL;
00073
00074
00075 m_bAutomatic = FALSE;
00076 m_bShareaza = FALSE;
00077 m_nNodeType = ntNode;
00078 m_bQueryRouting = FALSE;
00079 m_bPongCaching = FALSE;
00080 m_bVendorMsg = FALSE;
00081 m_bGGEP = FALSE;
00082 m_bObsoleteClient= FALSE;
00083 m_bBadClient = FALSE;
00084
00085
00086 m_tLastQuery = 0;
00087 m_tLastPacket = 0;
00088
00089
00090 m_nInputCount = m_nOutputCount = 0;
00091 m_nDropCount = 0;
00092 m_nLostCount = 0;
00093 m_nOutbound = 0;
00094 m_nFileCount = 0;
00095 m_nFileVolume = 0;
00096
00097
00098 m_pQueryTableLocal = NULL;
00099 m_pQueryTableRemote = NULL;
00100
00101
00102 m_pZInput = NULL;
00103 m_pZOutput = NULL;
00104 m_nZInput = 0;
00105 m_nZOutput = 0;
00106 m_pZSInput = NULL;
00107 m_pZSOutput = NULL;
00108 m_bZFlush = FALSE;
00109 m_tZOutput = 0;
00110
00111
00112 m_pMoreResultsGUID = NULL;
00113 }
00114
00115
00116
00117 CNeighbour::CNeighbour(PROTOCOLID nProtocol, CNeighbour* pBase)
00118 {
00119
00120 AttachTo( pBase );
00121
00122
00123 CopyMemory( &m_zStart, &pBase->m_zStart, (LPBYTE)&m_zEnd - (LPBYTE)&m_zStart );
00124
00125
00126 m_nState = nrsConnected;
00127 m_nProtocol = nProtocol;
00128 m_tConnected = GetTickCount();
00129 m_tLastPacket = m_tConnected;
00130
00131
00132 if ( m_bQueryRouting )
00133 {
00134
00135 m_pQueryTableLocal = new CQueryHashTable();
00136 m_pQueryTableRemote = new CQueryHashTable();
00137 }
00138
00139
00140 Neighbours.Add( this, FALSE );
00141 }
00142
00143
00144 CNeighbour::~CNeighbour()
00145 {
00146
00147 if ( z_streamp pStream = (z_streamp)m_pZSOutput )
00148 {
00149
00150 deflateEnd( pStream );
00151 delete pStream;
00152 }
00153
00154
00155 if ( z_streamp pStream = (z_streamp)m_pZSInput )
00156 {
00157
00158 inflateEnd( pStream );
00159 delete pStream;
00160 }
00161
00162
00163 if ( m_pProfile ) delete m_pProfile;
00164 if ( m_pZOutput ) delete m_pZOutput;
00165 if ( m_pZInput ) delete m_pZInput;
00166 if ( m_pQueryTableRemote ) delete m_pQueryTableRemote;
00167 if ( m_pQueryTableLocal ) delete m_pQueryTableLocal;
00168 }
00169
00171
00172
00173
00174
00175 void CNeighbour::Close(UINT nError)
00176 {
00177
00178 ASSERT( m_hSocket != INVALID_SOCKET );
00179
00180
00181 BOOL bVoluntary = ( nError == IDS_CONNECTION_CLOSED || nError == IDS_CONNECTION_PEERPRUNE );
00182
00183
00184 Neighbours.Remove( this );
00185
00186
00187 CConnection::Close();
00188
00189
00190 if ( nError )
00191 {
00192
00193 theApp.Message( bVoluntary ? MSG_DEFAULT : MSG_ERROR, nError, (LPCTSTR)m_sAddress );
00194 }
00195
00196
00197 delete this;
00198 }
00199
00200
00201
00202 void CNeighbour::DelayClose(UINT nError)
00203 {
00204
00205 if ( nError ) theApp.Message( MSG_ERROR, nError, (LPCTSTR)m_sAddress );
00206
00207
00208 m_nState = nrsClosing;
00209
00210
00211 QueueRun();
00212 }
00213
00215
00216
00217
00218
00219 BOOL CNeighbour::Send(CPacket* pPacket, BOOL bRelease, BOOL bBuffered)
00220 {
00221
00222 if ( bRelease ) pPacket->Release();
00223
00224
00225 return FALSE;
00226 }
00227
00228
00229 BOOL CNeighbour::SendQuery(CQuerySearch* pSearch, CPacket* pPacket, BOOL bLocal)
00230 {
00231
00232 return FALSE;
00233 }
00234
00236
00237
00238
00239
00240 BOOL CNeighbour::OnRun()
00241 {
00242
00243 DWORD tNow = GetTickCount();
00244
00245
00246 if ( tNow - m_tLastPacket > Settings.Connection.TimeoutTraffic * 3 )
00247 {
00248
00249 Close( IDS_CONNECTION_TIMEOUT_TRAFFIC );
00250 return FALSE;
00251 }
00252
00253
00254 if ( m_nNodeType == ntHub || ( m_nNodeType == ntNode && m_nProtocol == PROTOCOL_G2 ) )
00255 {
00256
00257 if ( m_pQueryTableLocal != NULL && m_pQueryTableLocal->m_nCookie != QueryHashMaster.m_nCookie )
00258 {
00259
00260 if ( tNow - QueryHashMaster.m_nCookie > 30000 ||
00261 QueryHashMaster.m_nCookie - m_pQueryTableLocal->m_nCookie > 60000 ||
00262 m_pQueryTableLocal->m_bLive == FALSE )
00263 {
00264
00265 if ( m_pQueryTableLocal->PatchTo( &QueryHashMaster, this ) )
00266 {
00267
00268 theApp.Message( MSG_SYSTEM, IDS_PROTOCOL_QRP_SENT, (LPCTSTR)m_sAddress,
00269 m_pQueryTableLocal->m_nBits, m_pQueryTableLocal->m_nHash,
00270 m_pQueryTableLocal->m_nInfinity, m_pQueryTableLocal->GetPercent() );
00271 }
00272 }
00273 }
00274 }
00275
00276
00277 return TRUE;
00278 }
00279
00281
00282
00283
00284
00285 void CNeighbour::OnDropped(BOOL bError)
00286 {
00287
00288 DWORD nTime1 = ( GetTickCount() - m_tConnected ) / 1000;
00289 DWORD nTime2 = ( GetTickCount() - m_tLastPacket ) / 1000;
00290
00291
00292 theApp.Message( MSG_DEBUG, _T("Dropped neighbour %s (%s), conn: %.2i:%.2i, packet: %.2i:%.2i"),
00293 (LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent,
00294 nTime1 / 60, nTime1 % 60, nTime2 / 60, nTime2 % 60 );
00295
00296
00297 Close( IDS_CONNECTION_DROPPED );
00298 }
00299
00301
00302
00303
00304
00305 BOOL CNeighbour::OnRead()
00306 {
00307
00308 CConnection::OnRead();
00309
00310
00311
00312 if ( m_pZInput == NULL || m_pInput->m_nLength == 0 ) return TRUE;
00313
00314
00315 BOOL bNew = ( m_pZSInput == NULL );
00316 if ( bNew ) m_pZSInput = new z_stream;
00317 z_streamp pStream = (z_streamp)m_pZSInput;
00318
00319
00320 if ( bNew )
00321 {
00322
00323 ZeroMemory( pStream, sizeof(z_stream) );
00324 if ( inflateInit( pStream ) != Z_OK )
00325 {
00326
00327 delete pStream;
00328 delete m_pZInput;
00329 m_pZInput = NULL;
00330 m_pZSInput = NULL;
00331 return TRUE;
00332 }
00333 }
00334
00335
00336 while ( m_pInput->m_nLength ||
00337 m_pZInput->m_nLength == m_pZInput->m_nBuffer ||
00338 pStream->avail_out == 0 )
00339 {
00340
00341 m_pZInput->EnsureBuffer( 1024 );
00342
00343
00344 pStream->next_in = m_pInput->m_pBuffer;
00345 pStream->avail_in = m_pInput->m_nLength;
00346 pStream->next_out = m_pZInput->m_pBuffer + m_pZInput->m_nLength;
00347 pStream->avail_out = m_pZInput->m_nBuffer - m_pZInput->m_nLength;
00348
00349
00350 inflate( pStream, Z_SYNC_FLUSH );
00351
00352
00353 if ( pStream->avail_in >= 0 && pStream->avail_in < m_pInput->m_nLength )
00354 {
00355
00356 m_pInput->Remove( m_pInput->m_nLength - pStream->avail_in );
00357 }
00358
00359
00360 DWORD nBlock = ( m_pZInput->m_nBuffer - m_pZInput->m_nLength ) - pStream->avail_out;
00361
00362
00363 m_pZInput->m_nLength += nBlock;
00364
00365
00366 m_nZInput += nBlock;
00367
00368
00369 if ( ! nBlock ) break;
00370 }
00371
00372
00373 return TRUE;
00374 }
00375
00376
00377
00378 BOOL CNeighbour::OnWrite()
00379 {
00380
00381 if ( m_pZOutput == NULL ) return CConnection::OnWrite();
00382
00383
00384 BOOL bNew = ( m_pZSOutput == NULL );
00385 if ( bNew ) m_pZSOutput = new z_stream;
00386 z_streamp pStream = (z_streamp)m_pZSOutput;
00387
00388
00389 if ( bNew )
00390 {
00391
00392 ZeroMemory( pStream, sizeof(z_stream) );
00393 if ( deflateInit( pStream, 6 ) != Z_OK )
00394 {
00395
00396 delete pStream;
00397 delete m_pZOutput;
00398 m_pZOutput = NULL;
00399 m_pZSOutput = NULL;
00400 return TRUE;
00401 }
00402 }
00403
00404
00405 if ( m_pOutput->m_nLength )
00406 {
00407
00408 CConnection::OnWrite();
00409 if ( m_pOutput->m_nLength ) return TRUE;
00410 }
00411
00412
00413 DWORD tNow = GetTickCount();
00414 if ( tNow - m_tZOutput >= Z_TIMER ) m_bZFlush = TRUE;
00415
00416
00417 while ( ( m_pZOutput->m_nLength && ! m_pOutput->m_nLength )
00418 || pStream->avail_out == 0 )
00419 {
00420
00421 m_pOutput->EnsureBuffer( 1024 );
00422
00423
00424 pStream->next_in = m_pZOutput->m_pBuffer;
00425 pStream->avail_in = m_pZOutput->m_nLength;
00426 pStream->next_out = m_pOutput->m_pBuffer + m_pOutput->m_nLength;
00427 pStream->avail_out = m_pOutput->m_nBuffer - m_pOutput->m_nLength;
00428
00429
00430 deflate( pStream, m_bZFlush ? Z_SYNC_FLUSH : 0 );
00431
00432
00433 m_nZOutput += m_pZOutput->m_nLength - pStream->avail_in;
00434
00435
00436 m_pZOutput->Remove( m_pZOutput->m_nLength - pStream->avail_in );
00437
00438
00439 int nOutput = ( m_pOutput->m_nBuffer - m_pOutput->m_nLength ) - pStream->avail_out;
00440
00441
00442 if ( nOutput )
00443 {
00444
00445 m_pOutput->m_nLength += nOutput;
00446 m_tZOutput = tNow;
00447
00448
00449 }
00450 else if ( m_bZFlush )
00451 {
00452
00453 m_bZFlush = FALSE;
00454 }
00455
00456
00457 CConnection::OnWrite();
00458 }
00459
00460
00461 return TRUE;
00462 }
00463
00465
00466
00467 BOOL CNeighbour::OnCommonHit(CPacket* pPacket)
00468 {
00469 CQueryHit* pHits = NULL;
00470 int nHops = 0;
00471
00472 if ( pPacket->m_nProtocol == PROTOCOL_G1 )
00473 {
00474 pHits = CQueryHit::FromPacket( (CG1Packet*)pPacket, &nHops );
00475 }
00476 else if ( pPacket->m_nProtocol == PROTOCOL_G2 )
00477 {
00478 pHits = CQueryHit::FromPacket( (CG2Packet*)pPacket, &nHops );
00479 }
00480 else
00481 {
00482 ASSERT( FALSE );
00483 }
00484
00485 if ( pHits == NULL )
00486 {
00487 pPacket->Debug( _T("BadHit") );
00488 theApp.Message( MSG_ERROR, IDS_PROTOCOL_BAD_HIT, (LPCTSTR)m_sAddress );
00489 m_nDropCount++;
00490 if ( m_nProtocol == PROTOCOL_G1 )
00491 Statistics.Current.Gnutella1.Dropped++;
00492 else if ( m_nProtocol == PROTOCOL_G2 )
00493 Statistics.Current.Gnutella2.Dropped++;
00494 return TRUE;
00495 }
00496
00497 if ( Security.IsDenied( &pHits->m_pAddress ) || nHops > (int)Settings.Gnutella1.MaximumTTL )
00498 {
00499 pHits->Delete();
00500 m_nDropCount++;
00501 if ( m_nProtocol == PROTOCOL_G1 )
00502 Statistics.Current.Gnutella1.Dropped++;
00503 else if ( m_nProtocol == PROTOCOL_G2 )
00504 Statistics.Current.Gnutella2.Dropped++;
00505 return TRUE;
00506 }
00507
00508 Network.NodeRoute->Add( &pHits->m_pClientID, this );
00509
00510 if ( SearchManager.OnQueryHits( pHits ) )
00511 {
00512 Network.RouteHits( pHits, pPacket );
00513 }
00514
00515 Network.OnQueryHits( pHits );
00516
00517 return TRUE;
00518 }
00519
00521
00522
00523 BOOL CNeighbour::OnCommonQueryHash(CPacket* pPacket)
00524 {
00525 if ( m_pQueryTableRemote == NULL )
00526 {
00527 m_pQueryTableRemote = new CQueryHashTable();
00528 theApp.Message( MSG_DEFAULT, IDS_PROTOCOL_QRP_UNEXPECTED, (LPCTSTR)m_sAddress );
00529 }
00530
00531 BOOL bLive = m_pQueryTableRemote->m_bLive;
00532
00533 if ( ! m_pQueryTableRemote->OnPacket( pPacket ) )
00534 {
00535 theApp.Message( MSG_ERROR, IDS_PROTOCOL_QRP_FAILED, (LPCTSTR)m_sAddress );
00536 return FALSE;
00537 }
00538
00539 if ( m_pQueryTableRemote->m_bLive && ! bLive )
00540 {
00541 theApp.Message( MSG_DEFAULT, IDS_PROTOCOL_QRP_UPDATED, (LPCTSTR)m_sAddress,
00542 m_pQueryTableRemote->m_nBits, m_pQueryTableRemote->m_nHash,
00543 m_pQueryTableRemote->m_nInfinity, m_pQueryTableRemote->GetPercent() );
00544 }
00545
00546 if ( m_nNodeType == ntLeaf && m_pQueryTableRemote->m_pGroup == NULL )
00547 {
00548 QueryHashMaster.Add( m_pQueryTableRemote );
00549 }
00550
00551 return TRUE;
00552 }
00553
00555
00556
00557
00558
00559 void CNeighbour::GetCompression(float* pnInRate, float* pnOutRate)
00560 {
00561
00562 *pnInRate = -1; *pnOutRate = -1;
00563
00564
00565 if ( m_pZInput != NULL && m_nZInput > 0.)
00566 {
00567
00568 *pnInRate = 1.0f
00569 - (float)m_mInput.nTotal
00570 / (float)m_nZInput;
00571
00572
00573 if ( *pnInRate < 0 ) *pnInRate = 0;
00574 else if ( *pnInRate > 1 ) *pnInRate = 1;
00575 }
00576
00577
00578 if ( m_pZOutput != NULL && m_mOutput.nTotal > 0.)
00579 {
00580
00581 *pnOutRate = 1.0f
00582 - (float)m_mOutput.nTotal
00583 / (float)m_nZOutput;
00584
00585
00586 if ( *pnOutRate < 0 ) *pnOutRate = 0;
00587 else if ( *pnOutRate > 1 ) *pnOutRate = 1;
00588 }
00589 }