Package org.gudy.azureus2.core3.tracker.server.impl

Source Code of org.gudy.azureus2.core3.tracker.server.impl.TRTrackerServerProcessor$lightweightPeer

/*
* File    : TRTrackerServerProcessor.java
* Created : 20-Jan-2004
* By      : parg
*
* Azureus - a Java Bittorrent client
*
* 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.
*
* 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 ( see the LICENSE file ).
*
* 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
*/

package org.gudy.azureus2.core3.tracker.server.impl;

/**
* @author parg
*
*/

import java.io.UnsupportedEncodingException;
import java.util.*;

import org.gudy.azureus2.core3.logging.LogEvent;
import org.gudy.azureus2.core3.logging.LogIDs;
import org.gudy.azureus2.core3.logging.Logger;
import org.gudy.azureus2.core3.tracker.server.*;
import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
import org.gudy.azureus2.core3.config.*;
import org.gudy.azureus2.core3.util.*;

import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;

public abstract class
TRTrackerServerProcessor
  extends ThreadPoolTask
{
  private static final boolean QUEUE_TEST  = false;
 
  static{
    if ( QUEUE_TEST ){
      System.out.println( "**** TRTrackerServerProcessor::QUEUE_TEST ****" );
    }
  }
 
  private TRTrackerServerImpl    server;
 
  private long          start;
  private int            request_type;
 
  protected TRTrackerServerTorrentImpl
  processTrackerRequest(
    TRTrackerServerImpl      _server,
    String            request,
    Map[]            root_out,    // output
    TRTrackerServerPeerImpl[]  peer_out,    // output
    int              _request_type,
    byte[][]          hashes,
    String            link,
    String            scrape_flags,
    HashWrapper          peer_id,
    boolean            no_peer_id,
    byte            compact_mode,
    String            key,
    String            event,
    boolean            stop_to_queue,
    int              port,
    int              udp_port,
    int              http_port,
    String            real_ip_address,
    String            original_client_ip_address,
    long            downloaded,
    long            uploaded,
    long            left,
    int              num_want,
    byte            crypto_level,
    byte            az_ver,
    int              up_speed,
    DHTNetworkPosition      network_position )
 
    throws TRTrackerServerException
  {
    server      = _server;
    request_type  = _request_type;
   
    if ( !server.isReady()){
     
      throw( new TRTrackerServerException( "Tracker initialising, please wait" ));
    }   
   
    start = SystemTime.getHighPrecisionCounter();

    boolean  ip_override = real_ip_address != original_client_ip_address;
   
    boolean  loopback  = TRTrackerUtils.isLoopback( real_ip_address );
   
    if ( loopback ){
         
        // any override is purely for routing purposes for loopback connections and we don't
        // want to apply the ip-override precedence rules against us
           
      ip_override  = false;
    }
   
      // translate any 127.0.0.1 local addresses back to the tracker address. Note this
      // fixes up .i2p and onion addresses back to their real values when needed
   
    String client_ip_address = TRTrackerUtils.adjustHostFromHosting( original_client_ip_address );
   
    if ( client_ip_address != original_client_ip_address ){
     
      if ( Logger.isEnabled()){
       
        Logger.log(
          new LogEvent(LogIDs.TRACKER,
            "    address adjusted: original=" +  original_client_ip_address +
            ", real=" + real_ip_address +
            ", adjusted=" + client_ip_address +
            ", loopback=" + loopback ));
     
    }
   
    if ( !TRTrackerServerImpl.getAllNetworksSupported()){
   
      String  network = AENetworkClassifier.categoriseAddress( client_ip_address );
     
      String[]  permitted_networks = TRTrackerServerImpl.getPermittedNetworks();
     
      boolean ok = false;
     
      for (int i=0;i<permitted_networks.length;i++){
       
        if ( network == permitted_networks[i] ){
         
          ok = true;
         
          break;
        }
      }
     
      if ( !ok ){
       
        throw( new TRTrackerServerException( "Network '" + network + "' not supported" ));
      }
    }
     
    TRTrackerServerTorrentImpl  torrent = null;
   
    if ( request_type != TRTrackerServerRequest.RT_FULL_SCRAPE ){
                 
      // System.out.println( "TRTrackerServerProcessor::request:" + request_type + ",event:" + event + " - " + client_ip_address + ":" + port );
     
      // System.out.println( "    hash = " + ByteFormatter.nicePrint(hash));
     
      if ( request_type == TRTrackerServerRequest.RT_ANNOUNCE ){
               
        if ( hashes == null || hashes.length == 0 ){
         
          throw( new TRTrackerServerException( "Hash missing from request "));
        }

        if ( hashes.length != 1 ){
         
          throw( new TRTrackerServerException( "Too many hashes for announce"));
        }
       
        byte[]  hash = hashes[0];
       
        torrent = server.getTorrent( hash );
       
        if ( torrent == null ){
         
          if ( !COConfigurationManager.getBooleanParameter( "Tracker Public Enable")){
           
            throw( new TRTrackerServerException( "Torrent unauthorised" ));
           
          }else{
           
            try{
             
              torrent = (TRTrackerServerTorrentImpl)server.permit( real_ip_address, hash, false );
                         
            }catch( Throwable e ){
             
              throw( new TRTrackerServerException( "Torrent unauthorised", e ));               
            }
          }
        }
       
        if ( peer_id == null ){
         
          throw( new TRTrackerServerException( "peer_id missing from request"));
        }
       
        boolean  queue_it = stop_to_queue;
       
        if ( queue_it ){
         
          Set biased = server.getBiasedPeers();
         
          if ( biased != null && biased.contains( real_ip_address )){
           
              // biased peers get to queue whatever
           
          }else{
         
            if ( loopback || ip_override ){
             
              queue_it = false;
            }
          }
        }

        long  interval;
        long  min_interval;
       
        if ( queue_it ){
         
            // when queued we use the scrape timeouts as it is scrape operations that
            // will keep the entry alive from this point on
         
          interval     = server.getScrapeRetryInterval( torrent );
          min_interval  = server.getMinScrapeRetryInterval();
         
        }else{
         
          interval     = server.getAnnounceRetryInterval( torrent );
          min_interval   = server.getMinAnnounceRetryInterval();
         
          if ( left == 0 ){
           
            long  mult = server.getSeedAnnounceIntervalMultiplier();
           
            interval     *= mult;
            min_interval  *= mult;
          }
        }
       
        TRTrackerServerPeerImpl peer =
          torrent.peerContact(  
            request,
            event,
            peer_id, port, udp_port, http_port, crypto_level, az_ver,
            real_ip_address, client_ip_address, ip_override, loopback, key,
            uploaded, downloaded, left,
            interval,
            up_speed, network_position );
       
        if ( queue_it ){
         
          torrent.peerQueued( client_ip_address, port, udp_port, http_port, crypto_level, az_ver, interval, left==0 );
        }
       
        HashMap  pre_map = new HashMap();
       
        TRTrackerServerPeer  pre_process_peer = peer;
       
        if ( pre_process_peer == null ){
         
            // can be null for stop events received without a previous start
         
          pre_process_peer = new lightweightPeer(client_ip_address,port,peer_id);
        }
       
        server.preProcess( pre_process_peer, torrent, request_type, request, pre_map );
       
          // set num_want to 0 for stopped events as no point in returning peers
       
        boolean  stopped   = event != null && event.equalsIgnoreCase("stopped");
       
        root_out[0] = torrent.exportAnnounceToMap( client_ip_address, pre_map, peer, left > 0, stopped?0:num_want, interval, min_interval, no_peer_id, compact_mode, crypto_level, network_position );
       
        peer_out[0= peer; 
       
      }else if ( request_type == TRTrackerServerRequest.RT_QUERY ){
       
        if ( link == null ){
         
          if ( hashes == null || hashes.length == 0 ){
           
            throw( new TRTrackerServerException( "Hash missing from request "));
          }
         
          if ( hashes.length != 1 ){
           
            throw( new TRTrackerServerException( "Too many hashes for query"));
          }
       
          byte[]  hash = hashes[0];
       
          torrent = server.getTorrent( hash );
         
        }else{
         
          torrent = server.getTorrent( link );
        }
       
        if ( torrent == null ){
         
          throw( new TRTrackerServerException( "Torrent unauthorised" ));
        }
       
        long  interval = server.getAnnounceRetryInterval( torrent );

        root_out[0] = torrent.exportAnnounceToMap( client_ip_address, new HashMap(), null, true, num_want, interval, server.getMinAnnounceRetryInterval(), true, compact_mode, crypto_level, network_position );

      }else{
       
        if ( hashes == null || hashes.length == 0 ){
         
          throw( new TRTrackerServerException( "Hash missing from request "));
        }

        boolean  local_scrape = client_ip_address.equals( "127.0.0.1" );
       
        long  max_interval  = server.getMinScrapeRetryInterval();
       
        Map  root = new HashMap();
       
        root_out[0] = root;
       
        Map  files = new ByteEncodedKeyHashMap();
       
        root.put( "files", files );
       
        char[]  scrape_chars = scrape_flags==null?null:scrape_flags.toCharArray();
       
        if ( scrape_chars != null && scrape_chars.length != hashes.length ){
         
          scrape_chars  = null;
        }
       
        for (int i=0;i<hashes.length;i++){
         
          byte[]  hash = hashes[i];
         
          String  str_hash;
         
          try{
            str_hash = new String( hash, Constants.BYTE_ENCODING );

              // skip duplicates
           
            if ( i > 0 && files.get( str_hash ) != null ){
             
              continue;
            }
           
          }catch( UnsupportedEncodingException e ){
           
            continue;
          }
         
          torrent = server.getTorrent( hash );
         
          if ( torrent == null ){
           
            if ( !COConfigurationManager.getBooleanParameter( "Tracker Public Enable")){
             
              continue;
             
            }else{
             
              try{             
                torrent = (TRTrackerServerTorrentImpl)server.permit( real_ip_address, hash, false );
                 
              }catch( Throwable e ){
               
                continue;             
              }
            }
          }
         
          long  interval = server.getScrapeRetryInterval( torrent );       
         
          if ( interval > max_interval ){
           
            max_interval  = interval;
          }

          if ( scrape_chars != null && ( QUEUE_TEST || !( loopback || ip_override ))){
           
              // note, 'Q' is complete+queued so we set seed true below
           
            if ( scrape_chars[i] == 'Q' ){
             
              torrent.peerQueuedclient_ip_address, port, udp_port, http_port, crypto_level, az_ver, (int)interval, true );
            }
          }
         
          if ( torrent.getRedirects() != null ){
           
            if ( hashes.length > 1 ){
             
                // just drop this from the set. this will cause the client to revert
                // to single-hash scrapes and subsequently pick up the redirect
             
              continue;             
            }
          }
         
          server.preProcess( new lightweightPeer(client_ip_address,port,peer_id), torrent, request_type, request, null );

          // we don't cache local scrapes as if we do this causes the hosting of
          // torrents to retrieve old values initially. Not a fatal error but not
          // the best behaviour as the (local) seed isn't initially visible.
       
          Map  hash_entry = torrent.exportScrapeToMap( request, client_ip_address, !local_scrape );
                   
            // System.out.println( "tracker - encoding: " + ByteFormatter.nicePrint(torrent_hash) + " -> " + ByteFormatter.nicePrint( str_hash.getBytes( Constants.BYTE_ENCODING )));
         
          files.put( str_hash, hash_entry );
        }
       
        if ( hashes.length > 1 ){
         
          torrent  = null// no specific torrent
        }
       
        // System.out.println( "scrape: hashes = " + hashes.length + ", files = " + files.size() + ", tim = " + max_interval );
       
        addScrapeInterval( max_interval, root );
      }
    }else{
     
     
      if ( !TRTrackerServerImpl.isFullScrapeEnabled()){
       
        throw( new TRTrackerServerException( "Full scrape disabled" ));
      }
     
      Map  files = new ByteEncodedKeyHashMap();
       
      TRTrackerServerTorrentImpl[] torrents = server.getTorrents();
     
      for (int i=0;i<torrents.length;i++){
       
        TRTrackerServerTorrentImpl  this_torrent = torrents[i];
         
        if ( this_torrent.getRedirects() != null ){
         
            // not visible to a full-scrape
         
          continue;
        }
       
        server.preProcess( new lightweightPeer(client_ip_address,port,peer_id), this_torrent, request_type, request, null );

        byte[]  torrent_hash = this_torrent.getHash().getHash();
       
        try{
          String  str_hash = new String( torrent_hash,Constants.BYTE_ENCODING );
         
          // System.out.println( "tracker - encoding: " + ByteFormatter.nicePrint(torrent_hash) + " -> " + ByteFormatter.nicePrint( str_hash.getBytes( Constants.BYTE_ENCODING )));
         
          Map  hash_entry = this_torrent.exportScrapeToMap( request, client_ip_address, true );
         
          files.put( str_hash, hash_entry );
         
        }catch( UnsupportedEncodingException e ){
     
          throw( new TRTrackerServerException( "Encoding error", e ));

        }
      }
     
      Map  root = new HashMap();
     
      root_out[0] = root;
     
      addScrapeInterval( null, root );
     
      root.put( "files", files );
    }
   
    return( torrent );
  }
 
  protected void
  addScrapeInterval(
    TRTrackerServerTorrentImpl  torrent,
    Map              root )
  {
    long interval = server.getScrapeRetryInterval( torrent );

    addScrapeInterval( interval, root );
  }
 
  protected void
  addScrapeInterval(
    long    interval,
    Map      root )
  {
    if ( interval > 0 ){
     
      Map  flags = new HashMap();
     
      flags.put("min_request_interval", new Long(interval));
     
      root.put( "flags", flags );
    }
  }
 
  public void
  taskCompleted()
  {
    if ( start > 0 ){
     
      long  time = SystemTime.getHighPrecisionCounter() - start;
             
      server.updateTime( request_type, time );
    }
  }
 
  protected static class
  lightweightPeer
    implements TRTrackerServerPeer
  {
    private String  ip;
    private int    port;
    private byte[]  peer_id;
   
    public
    lightweightPeer(
      String    _ip,
      int      _port,
      HashWrapper  _peer_id )
    {
      ip    = _ip;
      port  = _port;
      peer_id  = _peer_id==null?null:_peer_id.getBytes();
    }
   
    public long
    getUploaded()
    {
      return( -1 );
    }
   
    public long
    getDownloaded()
    {
      return( -1 );
    }
   
    public long
    getAmountLeft()
    {
      return( -1 );
    }
   
    public String
    getIP()
    {
      return( ip );
    }
   
    public String
    getIPRaw()
    {
      return( ip );
    }
 
    public byte
    getNATStatus()
    {
      return( NAT_CHECK_UNKNOWN );
    }
   
    public int
    getTCPPort()
    {
      return( port );
    }
   
    public int
    getHTTPPort()
    {
      return( 0 );
    }
   
    public int
    getUDPPort()
    {
      return( 0 );
    }
   
    public byte[]
    getPeerID()
    {
      return( peer_id );
    }
   
    public boolean
    isBiased()
    {
      return( false );
    }
   
    public void
    setBiased(
      boolean    biased )
    { 
    }
   
    public void
    setUserData(
      Object    key,
      Object    data )
    {
    }
   
    public Object
    getUserData(
      Object    key )
    {
      return( null );
    }
   
    public int
    getSecsToLive()
    {
      return( -1 );
    }
   
    public Map
    export()
    {
      return( null );
    }
  }
}
TOP

Related Classes of org.gudy.azureus2.core3.tracker.server.impl.TRTrackerServerProcessor$lightweightPeer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.