00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Network.h"
00026 #include "Datagrams.h"
00027 #include "Security.h"
00028 #include "HostCache.h"
00029 #include "Downloads.h"
00030 #include "DiscoveryServices.h"
00031 #include "NeighboursWithConnect.h"
00032 #include "ShakeNeighbour.h"
00033 #include "EDNeighbour.h"
00034 #include "Neighbours.h"
00035
00036 #ifdef _DEBUG
00037 #undef THIS_FILE
00038 static char THIS_FILE[]=__FILE__;
00039 #define new DEBUG_NEW
00040 #endif
00041
00042
00044
00045
00046 CNeighboursWithConnect::CNeighboursWithConnect()
00047 {
00048 ZeroMemory( m_tPresent, sizeof(m_tPresent) );
00049
00050 m_bG2Leaf = FALSE;
00051 m_bG2Hub = FALSE;
00052 m_bG1Leaf = FALSE;
00053 m_bG1Ultrapeer = FALSE;
00054
00055 m_tHubG2Promotion = 0;
00056 }
00057
00058 CNeighboursWithConnect::~CNeighboursWithConnect()
00059 {
00060 }
00061
00063
00064
00065 CNeighbour* CNeighboursWithConnect::ConnectTo(IN_ADDR* pAddress, WORD nPort, PROTOCOLID nProtocol, BOOL bAutomatic, BOOL bNoUltraPeer)
00066 {
00067 CSingleLock pLock( &Network.m_pSection, TRUE );
00068
00069 if ( Get( pAddress ) )
00070 {
00071 if ( bAutomatic ) return NULL;
00072 theApp.Message( MSG_ERROR, IDS_CONNECTION_ALREADY_ABORT,
00073 (LPCTSTR)CString( inet_ntoa( *pAddress ) ) );
00074 return NULL;
00075 }
00076
00077
00078 if ( Security.IsDenied( pAddress ) )
00079 {
00080 if ( bAutomatic ) return NULL;
00081 theApp.Message( MSG_ERROR, IDS_NETWORK_SECURITY_OUTGOING,
00082 (LPCTSTR)CString( inet_ntoa( *pAddress ) ) );
00083 return NULL;
00084 }
00085
00086 if ( bAutomatic && Network.IsFirewalledAddress( &pAddress, TRUE ) ) return NULL;
00087
00088 if ( ! Network.Connect() ) return NULL;
00089
00090 if ( ! bAutomatic )
00091 {
00092 switch ( nProtocol )
00093 {
00094 case PROTOCOL_G1:
00095 Settings.Gnutella1.EnableToday = TRUE;
00096 break;
00097 case PROTOCOL_G2:
00098 Settings.Gnutella2.EnableToday = TRUE;
00099 break;
00100 case PROTOCOL_ED2K:
00101 Settings.eDonkey.EnableToday = TRUE;
00102 CloseDonkeys();
00103 break;
00104 }
00105 }
00106
00107 if ( nProtocol == PROTOCOL_ED2K )
00108 {
00109 CEDNeighbour* pNeighbour = new CEDNeighbour();
00110 if ( pNeighbour->ConnectTo( pAddress, nPort, bAutomatic ) )
00111 {
00112
00113 return pNeighbour;
00114 }
00115 delete pNeighbour;
00116 }
00117 else
00118 {
00119 CShakeNeighbour* pNeighbour = new CShakeNeighbour();
00120 if ( pNeighbour->ConnectTo( pAddress, nPort, bAutomatic, bNoUltraPeer ) )
00121 {
00122
00123
00124
00125 if ( ( Settings.Gnutella.SpecifyProtocol ) && ( nProtocol == PROTOCOL_G1 ) && ( ! Neighbours.NeedMoreHubs( PROTOCOL_G2 ) ) )
00126 pNeighbour->m_nProtocol = PROTOCOL_G1;
00127 return pNeighbour;
00128 }
00129 delete pNeighbour;
00130 }
00131
00132
00133 return NULL;
00134 }
00135
00137
00138
00139 CNeighbour* CNeighboursWithConnect::OnAccept(CConnection* pConnection)
00140 {
00141 CSingleLock pLock( &Network.m_pSection );
00142 if ( ! pLock.Lock( 250 ) ) return NULL;
00143
00144 CShakeNeighbour* pNeighbour = new CShakeNeighbour();
00145 pNeighbour->AttachTo( pConnection );
00146
00147 return pNeighbour;
00148 }
00149
00151
00152
00153 void CNeighboursWithConnect::PeerPrune(PROTOCOLID nProtocol)
00154 {
00155 BOOL bNeedMore = NeedMoreHubs( nProtocol );
00156 BOOL bNeedMoreAnyProtocol = NeedMoreHubs( PROTOCOL_NULL );
00157
00158 for ( POSITION pos = GetIterator() ; pos ; )
00159 {
00160 CNeighbour* pNeighbour = GetNext( pos );
00161 if ( pNeighbour->m_nProtocol == nProtocol )
00162 {
00163 if ( pNeighbour->m_nNodeType != ntHub )
00164 {
00165 if ( ! bNeedMore || pNeighbour->m_nState == nrsConnected )
00166 pNeighbour->Close( IDS_CONNECTION_PEERPRUNE );
00167 }
00168 }
00169 else if ( pNeighbour->m_nProtocol == PROTOCOL_NULL )
00170 {
00171
00172 if ( pNeighbour->m_bInitiated )
00173 {
00174
00175 if ( ! bNeedMoreAnyProtocol )
00176 pNeighbour->Close( IDS_CONNECTION_PEERPRUNE );
00177 }
00178 }
00179 }
00180 }
00181
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 BOOL CNeighboursWithConnect::IsG2Leaf()
00200 {
00201
00202 return ( Network.m_bEnabled && m_bG2Leaf );
00203 }
00204
00205 BOOL CNeighboursWithConnect::IsG2Hub()
00206 {
00207
00208 return ( Network.m_bEnabled && m_bG2Hub );
00209 }
00210
00211 DWORD CNeighboursWithConnect::IsG2HubCapable(BOOL bDebug)
00212 {
00213
00214 DWORD nRating = 0;
00215
00216
00217 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("IsHubCapable():") );
00218
00219
00220 if ( ! Settings.Gnutella2.EnableToday )
00221 {
00222 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: G2 not enabled") );
00223 return FALSE;
00224 }
00225
00226
00227
00228 if ( ! theApp.m_bNT )
00229 {
00230 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: OS is not NT based") );
00231 return FALSE;
00232 }
00233 else
00234 {
00235 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: OS is NT based") );
00236 }
00237
00238
00239
00240 if ( Settings.Gnutella2.ClientMode == MODE_LEAF )
00241 {
00242 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: hub mode disabled") );
00243 return FALSE;
00244 }
00245
00246
00247 if ( IsG2Leaf() )
00248 {
00249 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: leaf") );
00250 return FALSE;
00251 }
00252 else
00253 {
00254 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: not a leaf") );
00255 }
00256
00257
00258
00259 if ( Settings.Gnutella2.NumPeers < 4 )
00260 {
00261 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 4x G2 hub to hub") );
00262 return FALSE;
00263 }
00264 if ( Settings.Gnutella2.NumLeafs < 50 )
00265 {
00266 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 50x G2 hub to leaf") );
00267 return FALSE;
00268 }
00269
00270
00271
00272 if ( Settings.Gnutella2.ClientMode == MODE_HUB )
00273 {
00274 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("YES: hub mode forced") );
00275 }
00276 else
00277 {
00278
00279
00280
00281 if ( theApp.m_nPhysicalMemory < 250*1024*1024 )
00282 {
00283 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 250 MB RAM") );
00284 return FALSE;
00285 }
00286 else
00287 {
00288 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: more than 250 MB RAM") );
00289 }
00290
00291
00292
00293 if ( Settings.Connection.InSpeed < 200 )
00294 {
00295 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 200 Kb/s in") );
00296 return FALSE;
00297 }
00298 if ( Settings.Connection.OutSpeed < 200 )
00299 {
00300 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 200 Kb/s out") );
00301 return FALSE;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 if ( Settings.Gnutella2.HubVerified )
00313 {
00314
00315 if ( Network.GetStableTime() < 7200 )
00316 {
00317 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: not stable for 2 hours") );
00318 return FALSE;
00319 }
00320 else
00321 {
00322 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: stable for 2 hours") );
00323 }
00324 }
00325 else
00326 {
00327
00328 if ( Network.GetStableTime() < 10800 )
00329 {
00330 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: not stable for 3 hours") );
00331 return FALSE;
00332 }
00333 else
00334 {
00335 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: stable for 3 hours") );
00336 }
00337 }
00338
00339 if ( ! Datagrams.IsStable() )
00340 {
00341 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: datagram not stable") );
00342 return FALSE;
00343 }
00344 else
00345 {
00346 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: datagram stable") );
00347 }
00348
00349
00350
00351 if ( Settings.Scheduler.Enable && ! Settings.Scheduler.AllowHub )
00352 {
00353 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: scheduler active") );
00354 return FALSE;
00355 }
00356 else
00357 {
00358 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: scheduler OK") );
00359 }
00360
00361
00362
00363 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("YES: hub capable by test") );
00364 }
00365 nRating = 1;
00366
00367
00368
00369
00370
00371 if ( theApp.m_nPhysicalMemory > 600*1024*1024 )
00372 {
00373 nRating++;
00374 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 600 MB RAM") );
00375 }
00376
00377
00378
00379 if ( Settings.Connection.InSpeed > 1000 )
00380 {
00381 nRating++;
00382 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 1 Mb/s in") );
00383 }
00384 if ( Settings.Connection.OutSpeed > 1000 )
00385 {
00386 nRating++;
00387 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 1 Mb/s out") );
00388 }
00389
00390
00391
00392 if ( ! Settings.eDonkey.EnableToday )
00393 {
00394 nRating++;
00395 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("eDonkey not enabled") );
00396 }
00397 if ( ! Settings.BitTorrent.AdvancedInterfaceSet )
00398 {
00399 nRating++;
00400 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("BT is not in use") );
00401 }
00402 if ( ! Settings.Gnutella1.EnableToday )
00403 {
00404 nRating++;
00405 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("G1 not enabled") );
00406 }
00407
00408
00409
00410 if ( Network.GetStableTime() > 28800 )
00411 {
00412 nRating++;
00413 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("Stable for 8 hours") );
00414 }
00415
00416
00417
00418 if ( ! Settings.Scheduler.Enable )
00419 {
00420
00421
00422 nRating++;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 if ( bDebug )
00437 {
00438 CString strRating;
00439 strRating.Format( _T("Hub rating: %d"), nRating );
00440 theApp.Message( MSG_DEBUG, strRating );
00441 }
00442
00443
00444 return nRating;
00445 }
00446
00447 BOOL CNeighboursWithConnect::IsG1Leaf()
00448 {
00449
00450 return ( Network.m_bEnabled && m_bG1Leaf );
00451 }
00452
00453 BOOL CNeighboursWithConnect::IsG1Ultrapeer()
00454 {
00455
00456 return ( Network.m_bEnabled && m_bG1Ultrapeer );
00457 }
00458
00459 DWORD CNeighboursWithConnect::IsG1UltrapeerCapable(BOOL bDebug)
00460 {
00461
00462 DWORD nRating = 0;
00463
00464
00465 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("IsUltrapeerCapable():") );
00466
00467
00468 if ( ! Settings.Gnutella1.EnableToday )
00469 {
00470 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: Gnutella1 not enabled") );
00471 return FALSE;
00472 }
00473
00474
00475
00476 if ( ! theApp.m_bNT )
00477 {
00478 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: OS is not NT based") );
00479 return FALSE;
00480 }
00481 else
00482 {
00483 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: OS is NT based") );
00484 }
00485
00486
00487
00488 if ( Settings.Gnutella1.ClientMode == MODE_LEAF )
00489 {
00490 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: ultrapeer mode disabled") );
00491 return FALSE;
00492 }
00493
00494
00495
00496 if ( IsG1Leaf() )
00497 {
00498 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: leaf") );
00499 return FALSE;
00500 }
00501 else
00502 {
00503 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: not a leaf") );
00504 }
00505
00506
00507
00508 if ( Settings.Gnutella1.ClientMode == MODE_ULTRAPEER )
00509 {
00510 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("YES: ultrapeer mode forced") );
00511 }
00512 else
00513 {
00514
00515
00516
00517
00518 if ( IsG2Hub() )
00519 {
00520 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: Acting as a G2 hub") );
00521 return FALSE;
00522 }
00523 else
00524 {
00525 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: not a G2 hub") );
00526 }
00527
00528
00529
00530 if ( theApp.m_nPhysicalMemory < 250*1024*1024 )
00531 {
00532 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 250 MB RAM") );
00533 return FALSE;
00534 }
00535 else
00536 {
00537 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: more than 250 MB RAM") );
00538 }
00539
00540
00541
00542 if ( Settings.Connection.InSpeed < 200 )
00543 {
00544 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 200 Kb/s in") );
00545 return FALSE;
00546 }
00547 if ( Settings.Connection.OutSpeed < 200 )
00548 {
00549 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 200 Kb/s out") );
00550 return FALSE;
00551 }
00552 if ( ( Settings.Bandwidth.Uploads <= 4096 ) && ( Settings.Bandwidth.Uploads != 0 ) )
00553 {
00554 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: Upload limit set too low") );
00555 return FALSE;
00556 }
00557
00558
00559
00560 if ( Settings.Gnutella1.NumPeers < 4 )
00561 {
00562 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 4x G1 peer to peer") );
00563 return FALSE;
00564 }
00565 if ( Settings.Gnutella1.NumLeafs < 5 )
00566 {
00567 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: less than 5x G1 ultrapeer to leaf") );
00568 return FALSE;
00569 }
00570
00571
00572
00573 if ( Network.GetStableTime() < 14400 )
00574 {
00575 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: not stable for 4 hours") );
00576 return FALSE;
00577 }
00578 else
00579 {
00580 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: stable for 4 hours") );
00581 }
00582 if ( ! Datagrams.IsStable() )
00583 {
00584 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: datagram not stable") );
00585 return FALSE;
00586 }
00587 else
00588 {
00589 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: datagram stable") );
00590 }
00591
00592
00593
00594 if ( Settings.Scheduler.Enable && ! Settings.Scheduler.AllowHub )
00595 {
00596 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("NO: scheduler active") );
00597 return FALSE;
00598 }
00599 else
00600 {
00601 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("OK: scheduler OK") );
00602 }
00603
00604
00605
00606 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("YES: ultrapeer capable by test") );
00607 }
00608 nRating = 1;
00609
00610
00611
00612
00613
00614 if ( theApp.m_nPhysicalMemory > 600*1024*1024 )
00615 {
00616 nRating++;
00617 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 600 MB RAM") );
00618 }
00619
00620
00621
00622 if ( Settings.Connection.InSpeed > 1000 )
00623 {
00624 nRating++;
00625 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 1 Mb/s in") );
00626 }
00627 if ( Settings.Connection.OutSpeed > 1000 )
00628 {
00629 nRating++;
00630 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("More than 1 Mb/s out") );
00631 }
00632
00633
00634
00635 if ( ! Settings.eDonkey.EnableToday )
00636 {
00637 nRating++;
00638 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("eDonkey not enabled") );
00639 }
00640 if ( ! Settings.BitTorrent.AdvancedInterface )
00641 {
00642 nRating++;
00643 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("BT is not in use") );
00644 }
00645 if ( ! Settings.Gnutella2.EnableToday )
00646 {
00647 nRating++;
00648 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("G2 not enabled") );
00649 }
00650
00651
00652
00653 if ( Network.GetStableTime() > 28800 )
00654 {
00655 nRating++;
00656 if ( bDebug ) theApp.Message( MSG_DEBUG, _T("Stable for 8 hours") );
00657 }
00658
00659
00660
00661 if ( ! Settings.Scheduler.Enable )
00662 {
00663
00664
00665 nRating++;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 if ( bDebug )
00681 {
00682 CString strRating;
00683 strRating.Format( _T("Ultrapeer rating: %d"), nRating );
00684 theApp.Message( MSG_DEBUG, strRating );
00685 }
00686
00687
00688 return nRating;
00689 }
00690
00691
00693
00694
00695 BOOL CNeighboursWithConnect::NeedMoreHubs(PROTOCOLID nProtocol)
00696 {
00697 if ( ! Network.IsConnected() ) return FALSE;
00698
00699 int nConnected[4] = { 0, 0, 0, 0 };
00700
00701
00702 for ( POSITION pos = GetIterator() ; pos ; )
00703 {
00704 CNeighbour* pNeighbour = GetNext( pos );
00705
00706 if ( pNeighbour->m_nState == nrsConnected && pNeighbour->m_nNodeType != ntLeaf )
00707 {
00708 nConnected[ pNeighbour->m_nProtocol ] ++;
00709 }
00710 }
00711
00712 switch ( nProtocol )
00713 {
00714 case PROTOCOL_NULL:
00715 return ( ( Settings.Gnutella1.EnableToday ) && ( ( nConnected[1] ) < ( IsG1Leaf() ? Settings.Gnutella1.NumHubs : Settings.Gnutella1.NumPeers ) ) ||
00716 ( Settings.Gnutella2.EnableToday ) && ( ( nConnected[2] ) < ( IsG2Leaf() ? Settings.Gnutella2.NumHubs : Settings.Gnutella2.NumPeers ) ) );
00717 case PROTOCOL_G1:
00718 if ( Settings.Gnutella1.EnableToday == FALSE ) return FALSE;
00719 return ( nConnected[1] ) < ( IsG1Leaf() ? Settings.Gnutella1.NumHubs : Settings.Gnutella1.NumPeers );
00720 case PROTOCOL_G2:
00721 if ( Settings.Gnutella2.EnableToday == FALSE ) return FALSE;
00722 return ( nConnected[2] ) < ( IsG2Leaf() ? Settings.Gnutella2.NumHubs : Settings.Gnutella2.NumPeers );
00723 default:
00724 return FALSE;
00725 }
00726 }
00727
00728 BOOL CNeighboursWithConnect::NeedMoreLeafs(PROTOCOLID nProtocol)
00729 {
00730 if ( ! Network.IsConnected() ) return FALSE;
00731
00732 int nConnected[4] = { 0, 0, 0, 0 };
00733
00734
00735 for ( POSITION pos = GetIterator() ; pos ; )
00736 {
00737 CNeighbour* pNeighbour = GetNext( pos );
00738
00739 if ( pNeighbour->m_nState == nrsConnected && pNeighbour->m_nNodeType == ntLeaf )
00740 {
00741 nConnected[ pNeighbour->m_nProtocol ] ++;
00742 }
00743 }
00744
00745 switch ( nProtocol )
00746 {
00747 case PROTOCOL_NULL:
00748 return ( ( ( Settings.Gnutella1.EnableToday ) && ( ( nConnected[1] ) < Settings.Gnutella1.NumLeafs ) ) ||
00749 ( ( Settings.Gnutella2.EnableToday ) && ( ( nConnected[2] ) < Settings.Gnutella2.NumLeafs ) ) );
00750 case PROTOCOL_G1:
00751 if ( Settings.Gnutella1.EnableToday == FALSE ) return FALSE;
00752 return ( nConnected[1] ) < Settings.Gnutella1.NumLeafs;
00753 case PROTOCOL_G2:
00754 if ( Settings.Gnutella2.EnableToday == FALSE ) return FALSE;
00755 return ( nConnected[2] ) < Settings.Gnutella2.NumLeafs;
00756 default:
00757 return FALSE;
00758 }
00759 }
00760
00761 BOOL CNeighboursWithConnect::IsHubLoaded(PROTOCOLID nProtocol)
00762 {
00763 int nConnected[4] = { 0, 0, 0, 0 };
00764
00765
00766 for ( POSITION pos = GetIterator() ; pos ; )
00767 {
00768 CNeighbour* pNeighbour = GetNext( pos );
00769
00770 if ( pNeighbour->m_nState == nrsConnected && pNeighbour->m_nNodeType == ntLeaf )
00771 {
00772 nConnected[ pNeighbour->m_nProtocol ] ++;
00773 }
00774 }
00775
00776 switch ( nProtocol )
00777 {
00778 case PROTOCOL_NULL:
00779 return ( nConnected[1] + nConnected[2] ) >= ( Settings.Gnutella1.NumLeafs + Settings.Gnutella2.NumLeafs ) * 3 / 4;
00780 case PROTOCOL_G1:
00781 if ( Settings.Gnutella1.EnableToday == FALSE ) return FALSE;
00782 return ( nConnected[1] ) > Settings.Gnutella1.NumLeafs * 3 / 4;
00783 case PROTOCOL_G2:
00784 if ( Settings.Gnutella2.EnableToday == FALSE ) return FALSE;
00785 return ( nConnected[2] ) > Settings.Gnutella2.NumLeafs * 3 / 4;
00786 default:
00787 return FALSE;
00788 }
00789 }
00790
00792
00793
00794 void CNeighboursWithConnect::OnRun()
00795 {
00796 CNeighboursWithRouting::OnRun();
00797
00798 if ( Network.m_pSection.Lock( 50 ) )
00799 {
00800 if ( Network.m_bEnabled && Network.m_bAutoConnect )
00801 {
00802 Maintain();
00803 }
00804
00805 Network.m_pSection.Unlock();
00806 }
00807 }
00808
00810
00811
00812 void CNeighboursWithConnect::Maintain()
00813 {
00814 int nCount[4][3], nLimit[4][3];
00815 DWORD tTimer = GetTickCount();
00816 DWORD tNow = time( NULL );
00817
00818
00819 if ( Settings.Connection.ConnectThrottle != 0 )
00820 {
00821 if ( tTimer < Network.m_tLastConnect ) return;
00822 if ( tTimer - Network.m_tLastConnect < Settings.Connection.ConnectThrottle ) return;
00823 }
00824
00825
00826 ZeroMemory( nCount, sizeof(int) * 4 * 3 );
00827 ZeroMemory( nLimit, sizeof(int) * 4 * 3 );
00828
00829
00830 m_bG2Leaf = FALSE;
00831 m_bG2Hub = FALSE;
00832 m_bG1Leaf = FALSE;
00833 m_bG1Ultrapeer = FALSE;
00834 for ( POSITION pos = GetIterator() ; pos ; )
00835 {
00836 CNeighbour* pNeighbour = GetNext( pos );
00837
00838 if ( pNeighbour->m_nState == nrsConnected )
00839 {
00840 if ( pNeighbour->m_nProtocol == PROTOCOL_G2 )
00841 {
00842 if ( pNeighbour->m_nNodeType == ntHub )
00843 m_bG2Leaf = TRUE;
00844 else if ( pNeighbour->m_nNodeType == ntLeaf )
00845 m_bG2Hub = TRUE;
00846 }
00847 else if ( pNeighbour->m_nProtocol == PROTOCOL_G1 )
00848 {
00849 if ( pNeighbour->m_nNodeType == ntHub )
00850 m_bG1Leaf = TRUE;
00851 else if ( pNeighbour->m_nNodeType == ntLeaf )
00852 m_bG1Ultrapeer = TRUE;
00853 }
00854 }
00855 }
00856
00857
00858 for ( POSITION pos = GetIterator() ; pos ; )
00859 {
00860 CNeighbour* pNeighbour = GetNext( pos );
00861
00862 if ( pNeighbour->m_nState == nrsConnected )
00863 {
00864 if ( pNeighbour->m_nNodeType != ntHub && m_bG2Leaf && pNeighbour->m_nProtocol == PROTOCOL_G2 )
00865 {
00866 pNeighbour->Close( IDS_CONNECTION_PEERPRUNE );
00867 }
00868 else if ( pNeighbour->m_nNodeType != ntHub && m_bG1Leaf && pNeighbour->m_nProtocol == PROTOCOL_G1 )
00869 {
00870 pNeighbour->Close( IDS_CONNECTION_PEERPRUNE );
00871 }
00872 else if ( pNeighbour->m_nNodeType != ntLeaf )
00873 {
00874 if ( tNow - pNeighbour->m_tConnected > 8000 )
00875 {
00876 nCount[ pNeighbour->m_nProtocol ][ ntHub ] ++;
00877 }
00878 }
00879 else
00880 {
00881 nCount[ pNeighbour->m_nProtocol ][ ntLeaf ] ++;
00882 }
00883 }
00884 else if ( pNeighbour->m_nState < nrsConnected )
00885 {
00886 nCount[ pNeighbour->m_nProtocol ][ 0 ] ++;
00887 }
00888 }
00889
00890
00891 if ( m_bG2Hub == FALSE )
00892 m_tHubG2Promotion = 0;
00893 else if ( m_tHubG2Promotion == 0 )
00894 m_tHubG2Promotion = tNow;
00895
00896
00897 if ( ( Settings.Gnutella2.HubVerified == FALSE ) && ( m_tHubG2Promotion > 0 ) && ( Network.m_bEnabled ) )
00898 {
00899
00900 if ( ( tNow - m_tHubG2Promotion ) > ( 8 * 60 * 60 ) )
00901 {
00902
00903 if ( ( nCount[ PROTOCOL_G2 ][ ntHub ] ) > ( Settings.Gnutella2.NumLeafs * 3 / 4 ) )
00904 {
00905
00906 Settings.Gnutella2.HubVerified = TRUE;
00907 }
00908 }
00909 }
00910
00911
00912 if ( Settings.Gnutella1.EnableToday == FALSE )
00913 {
00914 nLimit[ PROTOCOL_G1 ][ ntHub ] = nLimit[ PROTOCOL_G1 ][ ntLeaf ] = 0;
00915 }
00916 else if ( m_bG1Leaf )
00917 {
00918 nLimit[ PROTOCOL_G1 ][ ntHub ] = min( Settings.Gnutella1.NumHubs, 2 );
00919 }
00920 else
00921 {
00922 nLimit[ PROTOCOL_G1 ][ ntHub ] = max( Settings.Gnutella1.NumPeers, Settings.Gnutella1.NumHubs );
00923 nLimit[ PROTOCOL_G1 ][ ntLeaf ] = Settings.Gnutella1.NumLeafs;
00924 }
00925
00926
00927
00928
00929 if ( Settings.Gnutella2.EnableToday == FALSE )
00930 {
00931 nLimit[ PROTOCOL_G2 ][ ntHub ] = nLimit[ PROTOCOL_G2 ][ ntLeaf ] = 0;
00932 }
00933 else if ( m_bG2Leaf )
00934 {
00935 nLimit[ PROTOCOL_G2 ][ ntHub ] = min( Settings.Gnutella2.NumHubs, 3 );
00936 }
00937 else
00938 {
00939 nLimit[ PROTOCOL_G2 ][ ntHub ] = max( Settings.Gnutella2.NumPeers, Settings.Gnutella2.NumHubs );
00940 nLimit[ PROTOCOL_G2 ][ ntLeaf ] = Settings.Gnutella2.NumLeafs;
00941 }
00942
00943
00944
00945
00946 if ( Settings.eDonkey.EnableToday )
00947 {
00948 nLimit[ PROTOCOL_ED2K ][ ntHub ] = min( DWORD(1), Settings.eDonkey.NumServers );
00949 }
00950
00951 nCount[ PROTOCOL_G1 ][0] += nCount[ PROTOCOL_NULL ][0];
00952 nCount[ PROTOCOL_G2 ][0] += nCount[ PROTOCOL_NULL ][0];
00953
00954
00955 for ( int nProtocol = 3 ; nProtocol >= 1 ; nProtocol-- )
00956 {
00957 if ( nCount[ nProtocol ][ ntHub ] > 0 ) m_tPresent[ nProtocol ] = tNow;
00958
00959 if ( nCount[ nProtocol ][ ntHub ] < nLimit[ nProtocol ][ ntHub ] )
00960 {
00961
00962
00963 if ( ( nProtocol == PROTOCOL_G1 ) && ( Settings.Gnutella2.EnableToday == TRUE ) )
00964 {
00965
00966 if ( ! Network.ReadyToTransfer( tTimer ) ) return;
00967
00968
00969
00970
00971 }
00972
00973 CHostCacheList* pCache = HostCache.ForProtocol( nProtocol );
00974
00975 int nAttempt;
00976 if ( nProtocol != PROTOCOL_ED2K )
00977 {
00978
00979 nAttempt = ( nLimit[ nProtocol ][ ntHub ] - nCount[ nProtocol ][ ntHub ] );
00980 nAttempt *= Settings.Gnutella.ConnectFactor;
00981 }
00982 else
00983 {
00984
00985
00986 if ( ( Settings.eDonkey.FastConnect ) && ( Network.ReadyToTransfer( tTimer ) ) )
00987 nAttempt = 2;
00988 else
00989 nAttempt = 1;
00990 }
00991
00992
00993 nAttempt = min(nAttempt, ( Settings.Downloads.MaxConnectingSources - 2 ) );
00994
00995
00996 if ( nProtocol == PROTOCOL_ED2K )
00997 {
00998 for ( CHostCacheHost* pHost = pCache->GetNewest() ;
00999 pHost && nCount[ nProtocol ][0] < nAttempt ; pHost = pHost->m_pPrevTime )
01000 {
01001 if ( pHost->m_bPriority && pHost->CanConnect( tNow ) && pHost->ConnectTo( TRUE ) )
01002 {
01003 ASSERT( pHost->m_nProtocol == nProtocol );
01004 nCount[ nProtocol ][0] ++;
01005
01006
01007 pHost->m_tQuery = tNow;
01008
01009 if ( Settings.Connection.ConnectThrottle != 0 )
01010 {
01011
01012 Network.m_tLastConnect = tTimer;
01013 Downloads.m_tLastConnect = tTimer;
01014 return;
01015 }
01016 }
01017 }
01018 }
01019
01020
01021 for ( CHostCacheHost* pHost = pCache->GetNewest() ;
01022 pHost && nCount[ nProtocol ][0] < nAttempt ; pHost = pHost->m_pPrevTime )
01023 {
01024 if ( pHost->CanConnect( tNow ) && pHost->ConnectTo( TRUE ) )
01025 {
01026 ASSERT( pHost->m_nProtocol == nProtocol );
01027 nCount[ nProtocol ][0] ++;
01028
01029 if ( nProtocol == PROTOCOL_ED2K )
01030 {
01031
01032 pHost->m_tQuery = tNow;
01033 }
01034
01035 if ( Settings.Connection.ConnectThrottle != 0 )
01036 {
01037
01038 Network.m_tLastConnect = tTimer;
01039 Downloads.m_tLastConnect = tTimer;
01040 return;
01041 }
01042 }
01043 }
01044
01045 if ( Network.m_bAutoConnect )
01046 {
01047 if ( nCount[ nProtocol ][ 0 ] == 0 || tNow - m_tPresent[ nProtocol ] >= 30 )
01048 {
01049 if ( nProtocol == PROTOCOL_G2 )
01050 {
01051 DiscoveryServices.Execute( TRUE );
01052 }
01053 else if ( nProtocol == PROTOCOL_G1 )
01054 {
01055 if ( pCache->GetOldest() == NULL ) DiscoveryServices.Execute( TRUE );
01056 }
01057 }
01058 }
01059 }
01060 else if ( nCount[ nProtocol ][ ntHub ] > nLimit[ nProtocol ][ ntHub ] )
01061 {
01062 CNeighbour* pNewest = NULL;
01063
01064
01065 for ( POSITION pos = GetIterator() ; pos ; )
01066 {
01067 CNeighbour* pNeighbour = GetNext( pos );
01068
01069 if ( pNeighbour->m_nNodeType != ntLeaf &&
01070 pNeighbour->m_nProtocol == nProtocol &&
01071 ( pNeighbour->m_bAutomatic || ! pNeighbour->m_bInitiated || nLimit[ nProtocol ][ ntHub ] == 0 ) )
01072 {
01073 if ( pNewest == NULL || pNeighbour->m_tConnected > pNewest->m_tConnected )
01074 pNewest = pNeighbour;
01075 }
01076 }
01077
01078
01079 if ( pNewest != NULL ) pNewest->Close();
01080 }
01081
01082 if ( nCount[ nProtocol ][ ntLeaf ] > nLimit[ nProtocol ][ ntLeaf ] )
01083 {
01084 CNeighbour* pNewest = NULL;
01085
01086
01087 for ( POSITION pos = GetIterator() ; pos ; )
01088 {
01089 CNeighbour* pNeighbour = GetNext( pos );
01090
01091 if ( pNeighbour->m_nNodeType == ntLeaf && pNeighbour->m_nProtocol == nProtocol )
01092 {
01093 if ( pNewest == NULL || pNeighbour->m_tConnected > pNewest->m_tConnected )
01094 pNewest = pNeighbour;
01095 }
01096 }
01097
01098
01099 if ( pNewest != NULL ) pNewest->Close();
01100 }
01101 }
01102 }