📄 peermanager.java
字号:
// we can get an extra one when adding a download that already exists...
List registrations = (List)registered_legacy_managers.get( hash );
byte[][] secrets = adapter.getSecrets();
if ( registrations == null ){
registrations = new ArrayList(1);
registered_legacy_managers.put( hash, registrations );
IncomingConnectionManager.getSingleton().addSharedSecrets( secrets );
}
PeerManagerRegistration registration = new PeerManagerRegistrationImpl( hash, adapter );
registrations.add( registration );
return( registration );
}finally{
managers_mon.exit();
}
}
private class
PeerManagerRegistrationImpl
implements PeerManagerRegistration
{
private HashWrapper hash;
private PeerManagerRegistrationAdapter adapter;
private TorrentDownload download;
private volatile PEPeerControl active_control;
private List pending_connections;
private BloomFilter known_seeds;
protected
PeerManagerRegistrationImpl(
HashWrapper _hash,
PeerManagerRegistrationAdapter _adapter )
{
hash = _hash;
adapter = _adapter;
}
protected PeerManagerRegistrationAdapter
getAdapter()
{
return( adapter );
}
public boolean
isActive()
{
return( active_control != null );
}
public void
activate(
PEPeerControl _active_control )
{
List connections = null;
try{
managers_mon.enter();
active_control = _active_control;
if ( download != null ){
Debug.out( "Already activated" );
}
download = TorrentDownloadFactory.getSingleton().createDownload( active_control ); //link legacy with new
connections = pending_connections;
pending_connections = null;
}finally{
managers_mon.exit();
}
if ( connections != null ){
for (int i=0;i<connections.size();i++){
Object[] entry = (Object[])connections.get(i);
NetworkConnection nc = (NetworkConnection)entry[0];
PeerManagerRoutingListener listener = (PeerManagerRoutingListener)entry[2];
route( _active_control, nc, true, listener );
}
}
}
public void
deactivate()
{
try{
managers_mon.enter();
if ( download == null ){
Debug.out( "Already deactivated" );
}else{
download.destroy(); //break legacy link
download = null;
}
active_control = null;
if ( pending_connections != null ){
for (int i=0;i<pending_connections.size();i++){
Object[] entry = (Object[])pending_connections.get(i);
NetworkConnection connection = (NetworkConnection)entry[0];
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
"Incoming connection from [" + connection
+ "] closed due to deactivation" ));
connection.close();
}
pending_connections = null;
}
}finally{
managers_mon.exit();
}
}
public void
unregister()
{
try{
managers_mon.enter();
if ( active_control != null ){
Debug.out( "Not deactivated" );
deactivate();
}
List registrations = (List)registered_legacy_managers.get( hash );
if ( registrations == null ){
Debug.out( "manager already deregistered" );
}else{
if ( registrations.remove( this )){
if ( registrations.size() == 0 ){
IncomingConnectionManager.getSingleton().removeSharedSecrets( adapter.getSecrets());
registered_legacy_managers.remove( hash );
}
}else{
Debug.out( "manager already deregistered" );
}
}
}finally{
managers_mon.exit();
}
}
protected boolean
isKnownSeed(
InetSocketAddress address )
{
try{
managers_mon.enter();
if ( known_seeds == null ){
return( false );
}
return( known_seeds.contains( address.getAddress().getAddress()));
}finally{
managers_mon.exit();
}
}
protected void
setKnownSeed(
InetSocketAddress address )
{
try{
managers_mon.enter();
if ( known_seeds == null ){
known_seeds = BloomFilterFactory.createAddOnly( 1024 );
}
// can't include port as it will be a randomly allocated one in general. two people behind the
// same NAT will have to connect to each other using LAN peer finder
known_seeds.add( address.getAddress().getAddress() );
}finally{
managers_mon.exit();
}
}
protected PEPeerControl
getActiveControl()
{
return( active_control );
}
protected void
route(
NetworkConnection connection,
PeerManagerRoutingListener listener )
{
PEPeerControl control;
boolean register_for_timeouts = false;
try{
managers_mon.enter();
control = active_control;
if ( control == null ){
// not yet activated, queue connection for use on activation
if ( pending_connections != null && pending_connections.size() > 10 ){
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
"Incoming connection from [" + connection
+ "] dropped too many pending activations" ));
connection.close();
}else{
if ( pending_connections == null ){
pending_connections = new ArrayList();
}
pending_connections.add( new Object[]{ connection, new Long( SystemTime.getCurrentTime()), listener });
if ( pending_connections.size() == 1 ){
register_for_timeouts = true;
}
}
}
}finally{
managers_mon.exit();
}
// do this outside the monitor as the timeout code calls us back holding the timeout monitor
// and we need to grab managers_mon inside this to run timeouts
if ( register_for_timeouts ){
registerForTimeouts( this );
}
if ( control != null ){
route( control, connection, false, listener );
}
}
protected boolean
timeoutCheck()
{
try{
managers_mon.enter();
if ( pending_connections == null ){
return( false );
}
Iterator it = pending_connections.iterator();
long now = SystemTime.getCurrentTime();
while( it.hasNext()){
Object[] entry = (Object[])it.next();
long start_time = ((Long)entry[1]).longValue();
if ( now < start_time ){
entry[1] = new Long( now );
}else if ( now - start_time > PENDING_TIMEOUT ){
it.remove();
NetworkConnection connection = (NetworkConnection)entry[0];
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
"Incoming connection from [" + connection
+ "] closed due to activation timeout" ));
connection.close();
}
}
if ( pending_connections.size() == 0 ){
pending_connections = null;
}
return( pending_connections != null );
}finally{
managers_mon.exit();
}
}
protected void
route(
PEPeerControl control,
final NetworkConnection connection,
boolean is_activation,
PeerManagerRoutingListener listener )
{
// make sure not already connected to the same IP address; allow
// loopback connects for co-located proxy-based connections and
// testing
String host_address = connection.getEndpoint().getNotionalAddress().getAddress().getHostAddress();
boolean same_allowed = COConfigurationManager.getBooleanParameter( "Allow Same IP Peers" ) || host_address.equals( "127.0.0.1" );
if( !same_allowed && PeerIdentityManager.containsIPAddress( control.getPeerIdentityDataID(), host_address ) ){
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
"Incoming connection from [" + connection
+ "] dropped as IP address already "
+ "connected for ["
+ control.getDisplayName() + "]"));
connection.close();
return;
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Incoming connection from ["
+ connection + "] routed to legacy download ["
+ control.getDisplayName() + "]"));
PEPeerTransport pt = PEPeerTransportFactory.createTransport( control, PEPeerSource.PS_INCOMING, connection );
if ( listener != null ){
boolean ok = false;
try{
if ( listener.routed( pt )){
ok = true;
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
if ( !ok ){
connection.close();
return;
}
}
pt.start();
if ( is_activation ){
pt.addListener(
new PEPeerListener()
{
public void
stateChanged(
PEPeer peer,
int new_state )
{
if ( new_state == PEPeer.CLOSING ){
if ( peer.isSeed()){
InetSocketAddress address = connection.getEndpoint().getNotionalAddress();
setKnownSeed( address );
// this is mainly to deal with seeds that incorrectly connect to us
adapter.deactivateRequest( address );
}
}
}
public void sentBadChunk(PEPeer peer, int piece_num, int total_bad_chunks ){}
public void addAvailability(final PEPeer peer, final BitFlags peerHavePieces){}
public void removeAvailability(final PEPeer peer, final BitFlags peerHavePieces){}
});
}
control.addPeerTransport( pt );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -