📄 trtrackerservertorrentimpl.java
字号:
peer = (TRTrackerServerPeerImpl)biased_peers.get(i);
int bias = peer.getBias();
// base chance is "loop limit" in "peer count"
// +100 bias -> always select
// -100 bias -> never select
int base = limit;
if ( bias < 0 ){
// decrease the chance by bias percentage
base = ((100 + bias ) * base ) /100;
}else{
// increase the chance by bias percentage
base = base + (( peer_list_size - base ) * bias )/100;
}
if ( random.nextInt( peer_list_size ) > base ){
continue;
}
peer_index = -1; // don't know actual index and don't need to as biased peers processed separately
}else{
peer_index = random.nextInt(peer_list_size);
peer = (TRTrackerServerPeerImpl)peer_list.get(peer_index);
if ( peer == null || peer.isBiased()){
continue;
}
}
if ( now > peer.getTimeout()){
removePeer( peer, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null );
peer_removed = true;
}else if ( requesting_peer == peer || peer.getTCPPort() == 0 ){
// a port of 0 means that the peer definitely can't accept incoming connections
}else if ( crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ){
// don't return "crypto required" peers to those that can't correctly connect to them
}else if ( include_seeds || !peer.isSeed()){
boolean bad_nat = peer.isNATStatusBad();
if ( ( bad_nat_loop == 0 && !bad_nat ) ||
( bad_nat_loop == 1 )){
if ( peer_index == -1 || duplicate_peer_checker[peer_index] != duplicate_peer_checker_index ){
if ( peer_index != -1 ){
duplicate_peer_checker[peer_index] = duplicate_peer_checker_index;
}
//if ( bad_nat ){
//
// bad_nat_added++;
//}
added++;
Map rep_peer = new HashMap(3);
if ( send_peer_ids ){
rep_peer.put( "peer id", peer.getPeerId().getHash());
}
if ( compact_mode != COMPACT_MODE_NONE ){
byte[] peer_bytes = peer.getIPBytes();
if ( peer_bytes == null ){
continue;
}
rep_peer.put( "ip", peer_bytes );
if ( compact_mode >= COMPACT_MODE_AZ ){
rep_peer.put( "azver", new Long( peer.getAZVer()));
rep_peer.put( "azudp", new Long( peer.getUDPPort()));
if ( peer.isSeed()){
rep_peer.put( "azhttp", new Long( peer.getHTTPPort()));
}
rep_peer.put( "azup", new Long( peer.getUpSpeed()));
if ( peer.isBiased()){
rep_peer.put( "azbiased", "" );
}
if ( network_position != null ){
DHTNetworkPosition peer_pos = peer.getNetworkPosition();
if ( peer_pos != null && network_position.getPositionType() == peer_pos.getPositionType()){
rep_peer.put( "azrtt", new Long( (long)peer_pos.estimateRTT(network_position )));
}
}
}
}else{
rep_peer.put( "ip", peer.getIPAsRead() );
}
rep_peer.put( "port", new Long( peer.getTCPPort()));
if ( crypto_level != TRTrackerServerPeer.CRYPTO_NONE ){
rep_peer.put( "crypto_flag", new Long( peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED?1:0));
}
if ( peer.isBiased()){
rep_peers.addFirst( rep_peer );
}else{
rep_peers.addLast( rep_peer );
}
}
}
}
}
}
// System.out.println( "num_want = " + num_want + ", added = " + added + ", bad_nat = " + bad_nat_added );
}finally{
peer_list_compaction_suspended = false;
if ( peer_removed ){
checkForPeerListCompaction( false );
}
}
/*
}else{
// given up on this approach for the moment as too costly
// randomly select the peers to return
LinkedList peers = new LinkedList( peer_map.keySet());
int added = 0;
while( added < num_want && peers.size() > 0 ){
String key = (String)peers.remove(random.nextInt(peers.size()));
TRTrackerServerPeerImpl peer = (TRTrackerServerPeerImpl)peer_map.get(key);
if ( now > peer.getTimeout()){
removePeer( peer, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null );
}else if ( peer.getTCPPort() == 0 ){
// a port of 0 means that the peer definitely can't accept incoming connections
}else if ( crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ){
// don't return "crypto required" peers to those that can't correctly connect to them
}else if ( include_seeds || !peer.isSeed()){
added++;
Map rep_peer = new HashMap(3); // don't use TreeMap as default is "compact"
// so we never actually encode anyway
if ( send_peer_ids ){
rep_peer.put( "peer id", peer.getPeerId().getHash());
}
if ( compact_mode != COMPACT_MODE_NONE ){
byte[] peer_bytes = peer.getIPBytes();
if ( peer_bytes == null ){
continue;
}
rep_peer.put( "ip", peer_bytes );
if ( compact_mode >= COMPACT_MODE_AZ ){
rep_peer.put( "azver", new Long( peer.getAZVer()));
rep_peer.put( "azudp", new Long( peer.getUDPPort()));
if ( peer.isSeed()){
rep_peer.put( "azhttp", new Long( peer.getHTTPPort()));
}
}
}else{
rep_peer.put( "ip", peer.getIPAsRead() );
}
rep_peer.put( "port", new Long( peer.getTCPPort()));
if ( crypto_level != TRTrackerServerPeer.CRYPTO_NONE ){
rep_peer.put( "crypto_flag", new Long( peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED?1:0));
}
rep_peers.add( rep_peer );
}
}*/
}
}
if ( include_seeds &&
!send_peer_ids &&
seed_count < 3 &&
queued_peers != null ){
Iterator it = queued_peers.iterator();
List added = new ArrayList( QUEUED_PEERS_ADD_MAX );
while( it.hasNext() && num_want > rep_peers.size() && added.size() < QUEUED_PEERS_ADD_MAX ){
QueuedPeer peer = (QueuedPeer)it.next();
if ( peer.isTimedOut( now )){
it.remove();
}else if ( crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ){
// don't return "crypto required" peers to those that can't correctly connect to them
}else{
Map rep_peer = new HashMap(3);
if ( compact_mode != COMPACT_MODE_NONE ){
byte[] peer_bytes = peer.getIPBytes();
if ( peer_bytes == null ){
continue;
}
rep_peer.put( "ip", peer_bytes );
if ( compact_mode >= COMPACT_MODE_AZ ){
rep_peer.put( "azver", new Long( peer.getAZVer()));
rep_peer.put( "azudp", new Long( peer.getUDPPort()));
if ( peer.isSeed()){
rep_peer.put( "azhttp", new Long( peer.getHTTPPort()));
}
}
}else{
rep_peer.put( "ip", peer.getIP());
}
rep_peer.put( "port", new Long( peer.getTCPPort()));
if ( crypto_level != TRTrackerServerPeer.CRYPTO_NONE ){
rep_peer.put( "crypto_flag", new Long( peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED?1:0));
}
// System.out.println( "added queued peer " + peer.getString());
rep_peers.addLast( rep_peer );
added.add( peer );
it.remove();
}
}
for (int i=0;i<added.size();i++){
queued_peers.add( added.get(i));
}
}
Map root = new TreeMap(); // user TreeMap to pre-sort so encoding quicker
if ( preprocess_map.size() > 0 ){
root.putAll( preprocess_map );
}
int num_peers_returned = rep_peers.size();
Iterator it = rep_peers.iterator();
if ( compact_mode == COMPACT_MODE_AZ ){
byte[] compact_peers = new byte[num_peers_returned*9];
int index = 0;
while( it.hasNext()){
Map rep_peer = (Map)it.next();
byte[] ip = (byte[])rep_peer.get( "ip" );
int tcp_port = ((Long)rep_peer.get( "port" )).intValue();
int udp_port = ((Long)rep_peer.get( "azudp" )).intValue();
Long crypto_flag_l = (Long)rep_peer.get( "crypto_flag" );
byte crypto_flag = crypto_flag_l==null?0:crypto_flag_l.byteValue();
int pos = index*9;
System.arraycopy( ip, 0, compact_peers, pos, 4 );
pos += 4;
compact_peers[pos++] = (byte)(tcp_port>>8);
compact_peers[pos++] = (byte)(tcp_port&0xff);
compact_peers[pos++] = (byte)(udp_port>>8);
compact_peers[pos++] = (byte)(udp_port&0xff);
compact_peers[pos++] = crypto_flag;
index++;
}
root.put( "peers", compact_peers );
root.put( "azcompact", new Long(1));
}else if ( compact_mode == COMPACT_MODE_AZ_2 ){
List compact_peers = new ArrayList( num_peers_returned );
while( it.hasNext()){
Map rep_peer = (Map)it.next();
Map peer = new HashMap();
compact_peers.add( peer );
byte[] ip = (byte[])rep_peer.get( "ip" );
peer.put( "i", ip );
int tcp_port = ((Long)rep_peer.get( "port" )).intValue();
peer.put( "t", new byte[]{ (byte)(tcp_port>>8), (byte)(tcp_port&0xff) });
int udp_port = ((Long)rep_peer.get( "azudp" )).intValue();
if ( udp_port != 0 ){
if ( udp_port == tcp_port ){
peer.put( "u", new byte[0] );
}else{
peer.put( "u", new byte[]{ (byte)(udp_port>>8), (byte)(udp_port&0xff) });
}
}
Long http_port_l = (Long)rep_peer.get( "azhttp" );
if ( http_port_l != null ){
int http_port = http_port_l.intValue();
if ( http_port != 0 ){
peer.put( "h", new byte[]{ (byte)(http_port>>8), (byte)(http_port&0xff) });
}
}
Long crypto_flag_l = (Long)rep_peer.get( "crypto_flag" );
byte crypto_flag = crypto_flag_l==null?0:crypto_flag_l.byteValue();
if ( crypto_flag != 0 ){
peer.put( "c", new byte[]{ crypto_flag } );
}
Long az_ver_l = (Long)rep_peer.get( "azver" );
byte az_ver = az_ver_l==null?0:az_ver_l.byteValue();
if ( az_ver != 0 ){
peer.put( "v", new Long(az_ver));
}
Long up_speed = (Long)rep_peer.get( "azup" );
if ( up_speed != null && up_speed.longValue() != 0 ){
peer.put( "s", up_speed );
}
Long rtt = (Long)rep_peer.get( "azrtt" );
if ( rtt != null ){
peer.put( "r", rtt );
}
if ( rep_peer.containsKey("azbiased")){
peer.put( "b", new Long(1));
}
}
root.put( "peers", compact_peers );
root.put( "azcompact", new Long(2));
}else{
byte[] crypto_flags = null;
if ( crypto_level != TRTrackerServerPeer.CRYPTO_NONE ){
crypto_flags = new byte[num_peers_returned];
}
if ( compact_mode == COMPACT_MODE_NORMAL ){
byte[] compact_peers = new byte[num_peers_returned*6];
int index = 0;
while( it.hasNext()){
Map rep_peer = (Map)it.next();
byte[] ip = (byte[])rep_peer.get( "ip" );
int port = ((Long)rep_peer.get( "port" )).intValue();
int pos = index*6;
System.arraycopy( ip, 0, compact_peers, pos, 4 );
pos += 4;
compact_peers[pos++] = (byte)(port>>8);
compact_peers[pos++] = (byte)(port&0xff);
if ( crypto_flags != null ){
Long crypto_flag = (Long)rep_peer.remove( "crypto_flag" );
crypto_flags[index] = crypto_flag.byteValue();
}
index++;
}
root.put( "peers", compact_peers );
}else{
int index = 0;
while( it.hasNext()){
Map rep_peer = (Map)it.next();
if ( crypto_flags != null ){
Long crypto_flag = (Long)rep_peer.remove( "crypto_flag" );
crypto_flags[index] = crypto_flag.byteValue();
}
index++;
}
root.put( "peers", rep_peers );
}
if ( crypto_flags != null ){
root.put( "crypto_flags", crypto_flags );
}
}
root.put( "interval", new Long( interval ));
root.put( "min interval", new Long( min_interval ));
if ( nat_warning ){
requesting_peer.setNATStatus( TRTrackerServerPeerImpl.NAT_CHECK_FAILED_AND_REPORTED );
root.put(
"warning message",
("Unable to connect to your incoming data port (" + requesting_peer.getIP() + ":" + requesting_peer.getTCPPort() +"). " +
"This will result in slow downloads. Please check your firewall/router settings").getBytes());
}
// also include scrape details
root.put( "complete", new Long( getSeedCount() ));
root.put( "incomplete", new Long( getLeecherCount() ));
root.put( "downloaded", new Long(stats.getCompletedCount()));
if ( add_to_cache ){
announce_cache.put( new Integer((num_peers_returned+9)/10), new announceCacheEntry( root, send_peer_ids, compact_mode ));
}
return( root );
}finally{
this_mon.exit();
}
}
public Map
exportScrapeToMap(
String url_parameters,
String ip_address,
boolean allow_cache )
throws TRTrackerServerException
{
try{
this_mon.enter();
handleRedirects( url_parameters, ip_address, true );
stats.addScrape();
long now = SystemTime.getCurrentTime();
long diff = now - last_scrape_calc_time;
if( allow_cache && last_scrape != null && diff < TRTrackerServerImpl.getScrapeCachePeriod() && !(diff < 0) ){
return( last_scrape );
}
last_scrape = new TreeMap();
last_scrape_calc_time = now;
last_scrape.put( "complete", new Long( getSeedCount()));
last_scrape.put( "incomplete", new Long( getLeecherCount()));
last_scrape.put( "downloaded", new Long(stats.getCompletedCount()));
return( last_scrape );
}finally{
this_mon.exit();
}
}
protected void
checkTimeouts()
{
try{
this_mon.enter();
long now = SystemTime.getCurrentTime();
int new_bad_NAT_count = 0;
try{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -