Package com.aelitis.azureus.core.peer.cache.cachelogic

Source Code of com.aelitis.azureus.core.peer.cache.cachelogic.CLCacheDiscovery$CDPQuery

/*
* Created on Jan 31, 2007
* Created by Paul Gardner
* Copyright (C) 2007 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 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

/**
*
* This class handles communication with the CDP server.
* Original code from
* @author Matthias Scheler <mscheler@cachelogic.com>
*
*/

package com.aelitis.azureus.core.peer.cache.cachelogic;

import java.io.File;
import java.net.*;

import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentException;
import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
import org.gudy.azureus2.core3.util.Constants;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.SHA1Hasher;

import com.aelitis.azureus.core.peer.cache.CacheDiscoverer;
import com.aelitis.azureus.core.peer.cache.CacheDiscovery;
import com.aelitis.azureus.core.peer.cache.CachePeer;
import com.aelitis.azureus.core.peermanager.utils.PeerClassifier;

public class
CLCacheDiscovery
  implements CacheDiscoverer
{
  public static final String  CDPDomainName = ".find-cache.com";
  public static final String  CDPServerName = "cls" + CDPDomainName;
  public static final int  CDPPort = 19523;
  public static final int  CDPVersion = 0;
  public static final int  CDPTimeout = 5000;

  static CDPResponse    Response;

  /* Convert an array of bytes into a its hexadecimal representation. */
 
  private String
  byteArrayToHex(byte[] Bytes, int Max) {
    int    Length, Index, Value;
    String  Result;

    Length = Bytes.length;
    if (Length > Max)
      Length = Max;

    Result = new String();
    for (Index = 0; Index < Length; Index++) {
      Value = Bytes[Index] & 0xff;
      if (Value < 16)
        Result += "0";
      Result += Integer.toHexString(Value);
    }
    return Result;
  }

    /* Find out the farm name via CDP. */
 
  private String
  lookupFarm()
  {
    if (Response != null) {
     
      if (Response.isStillValid()){
     
        return Response.getFarmID();
      }
     
      Response = null;
    }

    try {
      InetAddress  CDPServer;
      DatagramSocket  Socket;
      CDPQuery    Query;
      byte[]    Buffer;
      DatagramPacket  Packet;

      /* Get the IP address of the CDP servers. */
      CDPServer = InetAddress.getByName(CDPServerName);

      /* Create a UDP socket for the CDP query. */
      Socket = new DatagramSocket();
      Socket.setSoTimeout(CDPTimeout);

      /* Build the CDP query. */
      Query = new CDPQuery(Constants.AZUREUS_NAME + " " +  Constants.AZUREUS_VERSION);
      Buffer = Query.getBytes();
      Packet = new DatagramPacket(Buffer, Buffer.length, CDPServer, CDPPort);

      /* Send the query to the CDP server. */
      Socket.send(Packet);

      /* Receive the CDP response. */
      Buffer = new byte[CDPResponse.MaxSize];
      Packet.setData(Buffer);
      Socket.receive(Packet);
      if (Packet.getAddress() != CDPServer || Packet.getPort() != CDPPort)
        throw(new Exception("CDP server address mismatch on response"));

      /* Parse the CDP response. */
      Response = new CDPResponse(Packet.getData());

      /* Return the farmID from the CDP response. */
      return Response.getFarmID();
    } catch (Throwable Excpt) {
     
      if ( Excpt instanceof UnknownHostException ){
       
      }else{
       
        Excpt.printStackTrace();
      }
     
      return "default";
    }
  }

  /* Calculate publisher string for DNS query from announce URL. */
 
  private String
  hashAnnounceURL(
    URL   announce_url )
  {
    /* Calculate SHA1 hash of the hostname. */
   
    byte[] Digest = new SHA1Hasher().calculateHash( announce_url.getHost().getBytes());

    /*
     * Return first 32 characters of the hexadecimal representation of the
     * SHA1 hash.
     */
   
    return byteArrayToHex(Digest, 16);
  }

  /* Find a cache for a given announce URL and BitTorrent hash. */
 
  public InetAddress[]
  findCache(
    URL    announce_url,
    String   hex_hash )
  {
    String    Hostname;
    InetAddress[]  Caches;

    /*
     * Build the hostname for the DNS query:
     * bt-<short hash>.bt-<announce hash>-<farm>.find-cache.com
     *
     * short hash:  first four hexadecimal digits of the BitTorrent hash
     * announce hash:  see hashAnnounceURL()
     * farm:    farm name returned by CDP query.
     */
    Hostname = "bt-" + hex_hash.substring(0, 4) +
    ".bt-" + hashAnnounceURL(announce_url) +
    "-" + lookupFarm() + CDPDomainName;
    // System.out.println("findCache(): " + announce_url + " " + hex_hash + " --> " +  Hostname);
    try {
      Caches = InetAddress.getAllByName(Hostname);
    } catch (UnknownHostException NoCache) {
      Caches = new InetAddress[0];
    }
    return Caches;
  }

  /* Find a cache for a given announce URL and BitTorrent hash. */
 
  public InetAddress[]
  findCache(
    URL     announce_url,
    byte[]   hash )
  {
    return findCache(announce_url, byteArrayToHex(hash, 4));
  }
 
  public CachePeer[]
  lookup(
    TOTorrent  torrent )
  {
    try{
      InetAddress[]  addresses = findCache( torrent.getAnnounceURL(), torrent.getHash());
     
      CachePeer[] result = new CachePeer[addresses.length];
     
      for (int i=0;i<addresses.length;i++){
       
        result[i] = new CacheDiscovery.CachePeerImpl( CachePeer.PT_CACHE_LOGIC, addresses[i], 6881 );
      }
     
      return( result );
     
    }catch( TOTorrentException e ){
     
      Debug.printStackTrace( e );
     
      return( new CachePeer[0] );
    }
  }
 
  public CachePeer
  lookup(
    byte[]       peer_id,
    InetAddress   ip,
    int       port )
  {
    if ( PeerClassifier.getClientDescription( peer_id ).startsWith( PeerClassifier.CACHE_LOGIC )){
     
      return( new CacheDiscovery.CachePeerImpl( CachePeer.PT_CACHE_LOGIC, ip, port ));
    }
   
    return( null );
  }
 
  class
  CDPQuery
  {
    private String Client;

    /* Construct a query for a given client identifier. */
    public CDPQuery(String _Client)
    {
      Client = _Client;
    }

    /* Return the binary representation. */
    byte[] getBytes()
    {
      String  Temp;
      byte[]  Bytes;

      Temp = "@@@" + Client;
      Bytes = Temp.getBytes();
      Bytes[0] = CDPVersion;  // Version
      Bytes[1] = 0;          // Flags
      Bytes[2] = (byte)Client.length();      // Length of the client identifier

      return Bytes;
    }
  }

  /**
   *
   * This class parses a CDP response returned by the CDP server.
   *
   * @author Matthias Scheler <mscheler@cachelogic.com>
   *
   */
  class
  CDPResponse
  {
    public static final int  MinSize = 7;
    public static final int  MaxSize = 262;

    /* The CDP farm ID. */
    String  farmID;
    /* This CDP response is valid until this point of time. */
    long    validUntil;

    /* Create a response object from a given binary encoded CDP message. */
    public CDPResponse(byte[] Bytes) throws Exception
    {
      int    Index;
      long  Timeout;

      if (Bytes.length < MinSize || MinSize + Bytes[6] > Bytes.length)
        throw new Exception("CDP response too short");

      if (Bytes[0] != CDPVersion)
        throw new Exception("Unsupported CDP version");

      farmID = new String();
      for (Index = 0; Index < Bytes[6]; Index++)
        farmID += (char)Bytes[MinSize + Index];

      Timeout = 0;
      for (Index = 2; Index < 6; Index++)
        Timeout = (Timeout << 8) + ((int)Bytes[Index] & 0xff);
      validUntil = System.currentTimeMillis() + Timeout * 1000;
    }

    /* Return the farm ID. */
    public String getFarmID()
    {
      return farmID;
    }

    /* Is the information in this CDP response still valid? */
    public boolean isStillValid()
    {
      return (System.currentTimeMillis() < validUntil);
    }
  }
 
  public static void
  main(
    String[]  args )
  {
    try{
      TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile( new File( "C:\\temp\\test.torrent" ));
     
      CachePeer[]  peers = new CLCacheDiscovery().lookup( torrent );
     
      System.out.println( "peers=" + peers.length );
     
      for (int i=0;i<peers.length;i++){
       
        System.out.println( "    cache: " + peers[i].getAddress() + ":" + peers[i].getPort() );
      }
    }catch( Throwable e ){
     
      e.printStackTrace();
    }
  }
}
TOP

Related Classes of com.aelitis.azureus.core.peer.cache.cachelogic.CLCacheDiscovery$CDPQuery

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.