📄 peermanager.java
字号:
/*
* Created on Jan 20, 2005
* Created by Alon Rohter
* Copyright (C) 2004-2005 Aelitis, All Rights Reserved.
*
* This program 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.
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.core.peermanager;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.peer.PEPeer;
import org.gudy.azureus2.core3.peer.PEPeerListener;
import org.gudy.azureus2.core3.peer.PEPeerSource;
import org.gudy.azureus2.core3.peer.impl.*;
import org.gudy.azureus2.core3.peer.util.PeerIdentityManager;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.HashWrapper;
import org.gudy.azureus2.core3.util.SystemTime;
import com.aelitis.azureus.core.networkmanager.*;
import com.aelitis.azureus.core.networkmanager.impl.IncomingConnectionManager;
import com.aelitis.azureus.core.networkmanager.impl.TransportHelper;
import com.aelitis.azureus.core.peermanager.download.TorrentDownload;
import com.aelitis.azureus.core.peermanager.download.TorrentDownloadFactory;
import com.aelitis.azureus.core.peermanager.messaging.*;
import com.aelitis.azureus.core.peermanager.messaging.bittorrent.*;
import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
import com.aelitis.azureus.core.stats.AzureusCoreStats;
import com.aelitis.azureus.core.stats.AzureusCoreStatsProvider;
import com.aelitis.azureus.core.util.bloom.BloomFilter;
import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
/**
*
*/
public class PeerManager implements AzureusCoreStatsProvider{
private static final LogIDs LOGID = LogIDs.PEER;
private static final PeerManager instance = new PeerManager();
private static final int PENDING_TIMEOUT = 10*1000;
private static final AEMonitor timer_mon = new AEMonitor( "PeerManager:timeouts" );
private static Thread timer_thread;
private static Set timer_targets = new HashSet();
protected static void
registerForTimeouts(
PeerManagerRegistrationImpl reg )
{
try{
timer_mon.enter();
timer_targets.add( reg );
if ( timer_thread == null ){
timer_thread =
new AEThread( "PeerManager:timeouts", true )
{
public void
runSupport()
{
int idle_time = 0;
while( true ){
try{
Thread.sleep( PENDING_TIMEOUT / 2 );
}catch( Throwable e ){
}
try{
timer_mon.enter();
if ( timer_targets.size() == 0 ){
idle_time += PENDING_TIMEOUT / 2;
if ( idle_time >= 30*1000 ){
timer_thread = null;
break;
}
}else{
idle_time = 0;
Iterator it = timer_targets.iterator();
while( it.hasNext()){
PeerManagerRegistrationImpl registration = (PeerManagerRegistrationImpl)it.next();
if ( !registration.timeoutCheck()){
it.remove();
}
}
}
}finally{
timer_mon.exit();
}
}
}
};
timer_thread.start();
}
}finally{
timer_mon.exit();
}
}
/**
* Get the singleton instance of the peer manager.
* @return the peer manager
*/
public static PeerManager getSingleton() { return instance; }
private final HashMap registered_legacy_managers = new HashMap();
private final ByteBuffer legacy_handshake_header;
private final AEMonitor managers_mon = new AEMonitor( "PeerManager:managers" );
private PeerManager() {
legacy_handshake_header = ByteBuffer.allocate( 20 );
legacy_handshake_header.put( (byte)BTHandshake.PROTOCOL.length() );
legacy_handshake_header.put( BTHandshake.PROTOCOL.getBytes() );
legacy_handshake_header.flip();
Set types = new HashSet();
types.add( AzureusCoreStats.ST_PEER_MANAGER_COUNT );
AzureusCoreStats.registerProvider( types, this );
init();
}
public void
updateStats(
Set types,
Map values )
{
if ( types.contains( AzureusCoreStats.ST_PEER_MANAGER_COUNT )){
values.put( AzureusCoreStats.ST_PEER_MANAGER_COUNT, new Long( registered_legacy_managers.size()));
}
if ( types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_COUNT ) ||
types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_SNUBBED_COUNT ) ||
types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_STALLED_DISK_COUNT )){
long total_peers = 0;
long total_snubbed_peers = 0;
long total_stalled_pending_load = 0;
try{
managers_mon.enter();
Iterator it = registered_legacy_managers.values().iterator();
while( it.hasNext()){
List registrations = (List)it.next();
Iterator it2 = registrations.iterator();
while( it2.hasNext()){
PeerManagerRegistrationImpl reg = (PeerManagerRegistrationImpl)it2.next();
PEPeerControl control = reg.getActiveControl();
if ( control != null ){
total_peers += control.getNbPeers();
total_snubbed_peers += control.getNbPeersSnubbed();
total_stalled_pending_load += control.getNbPeersStalledPendingLoad();
}
}
}
}finally{
managers_mon.exit();
}
if ( types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_COUNT )){
values.put( AzureusCoreStats.ST_PEER_MANAGER_PEER_COUNT, new Long( total_peers ));
}
if ( types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_SNUBBED_COUNT )){
values.put( AzureusCoreStats.ST_PEER_MANAGER_PEER_SNUBBED_COUNT, new Long( total_snubbed_peers ));
}
if ( types.contains( AzureusCoreStats.ST_PEER_MANAGER_PEER_STALLED_DISK_COUNT )){
values.put( AzureusCoreStats.ST_PEER_MANAGER_PEER_STALLED_DISK_COUNT, new Long( total_stalled_pending_load ));
}
}
}
protected void
init()
{
MessageManager.getSingleton().initialize(); //ensure it gets initialized
NetworkManager.ByteMatcher matcher =
new NetworkManager.ByteMatcher()
{
public int matchThisSizeOrBigger(){ return( 48 );}
public int maxSize() { return 48; }
public int minSize() { return 20; }
public Object
matches(
TransportHelper transport,
ByteBuffer to_compare,
int port )
{
InetSocketAddress address = transport.getAddress();
int old_limit = to_compare.limit();
int old_position = to_compare.position();
to_compare.limit( old_position + 20 );
PeerManagerRegistrationImpl routing_data = null;
if( to_compare.equals( legacy_handshake_header ) ) { //compare header
to_compare.limit( old_position + 48 );
to_compare.position( old_position + 28 );
byte[] hash = new byte[to_compare.remaining()];
to_compare.get( hash );
try{
managers_mon.enter();
List registrations = (List)registered_legacy_managers.get( new HashWrapper( hash ));
if ( registrations != null ){
routing_data = (PeerManagerRegistrationImpl)registrations.get(0);
}
}finally{
managers_mon.exit();
}
}
//restore buffer structure
to_compare.limit( old_limit );
to_compare.position( old_position );
if ( routing_data != null ){
if ( !routing_data.isActive()){
if ( routing_data.isKnownSeed( address )){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied as known seed" ));
}
routing_data = null;
}else{
if ( !routing_data.getAdapter().activateRequest( address )){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied by rules" ));
}
routing_data = null;
}
}
}
}
return routing_data;
}
public Object
minMatches(
TransportHelper transport,
ByteBuffer to_compare,
int port )
{
boolean matches = false;
int old_limit = to_compare.limit();
int old_position = to_compare.position();
to_compare.limit( old_position + 20 );
if( to_compare.equals( legacy_handshake_header ) ) {
matches = true;
}
//restore buffer structure
to_compare.limit( old_limit );
to_compare.position( old_position );
return matches?"":null;
}
public byte[][]
getSharedSecrets()
{
return( null ); // registered manually above
}
public int
getSpecificPort()
{
return( -1 );
}
};
// register for incoming connection routing
NetworkManager.getSingleton().requestIncomingConnectionRouting(
matcher,
new NetworkManager.RoutingListener()
{
public void
connectionRouted(
NetworkConnection connection,
Object routing_data )
{
PeerManagerRegistrationImpl registration = (PeerManagerRegistrationImpl)routing_data;
registration.route( connection, null );
}
public boolean
autoCryptoFallback()
{
return( false );
}
},
new MessageStreamFactory() {
public MessageStreamEncoder createEncoder() { return new BTMessageEncoder(); }
public MessageStreamDecoder createDecoder() { return new BTMessageDecoder(); }
});
}
public PeerManagerRegistration
manualMatchHash(
InetSocketAddress address,
byte[] hash )
{
PeerManagerRegistrationImpl routing_data = null;
try{
managers_mon.enter();
List registrations = (List)registered_legacy_managers.get( new HashWrapper( hash ));
if ( registrations != null ){
routing_data = (PeerManagerRegistrationImpl)registrations.get(0);
}
}finally{
managers_mon.exit();
}
if ( routing_data != null ){
if ( !routing_data.isActive()){
if ( routing_data.isKnownSeed( address )){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied as known seed" ));
}
routing_data = null;
}else{
if ( !routing_data.getAdapter().activateRequest( address )){
if (Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied by rules" ));
}
routing_data = null;
}
}
}
}
return routing_data;
}
public void
manualRoute(
PeerManagerRegistration _registration,
NetworkConnection _connection,
PeerManagerRoutingListener _listener )
{
PeerManagerRegistrationImpl registration = (PeerManagerRegistrationImpl)_registration;
registration.route( _connection, _listener );
}
public PeerManagerRegistration
registerLegacyManager(
HashWrapper hash,
PeerManagerRegistrationAdapter adapter )
{
try{
managers_mon.enter();
// normally we only get a max of 1 of these. However, due to DownloadManager crazyness
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -