FileDocCategorySizeDatePackage
AZPeerExchange.javaAPI DocAzureus 3.0.3.47506Sun Mar 04 21:08:14 GMT 2007com.aelitis.azureus.core.peermanager.messaging.azureus

AZPeerExchange

public class AZPeerExchange extends Object implements AZMessage
AZ peer exchange message.

Fields Summary
private static final org.gudy.azureus2.core3.logging.LogIDs
LOGID
private static final byte
bss
private DirectByteBuffer
buffer
private String
description
private final byte
version
private final byte[]
infohash
private final PeerItem[]
peers_added
private final PeerItem[]
peers_dropped
Constructors Summary
public AZPeerExchange(byte[] _infohash, PeerItem[] _peers_added, PeerItem[] _peers_dropped, byte version)

  
  
  
             
    this.infohash = _infohash;
    this.peers_added = _peers_added;
    this.peers_dropped = _peers_dropped;
    this.version = version;
  
Methods Summary
public Messagedeserialize(DirectByteBuffer data, byte version)

    if( data.remaining( bss ) > 2000 )  System.out.println( "Received PEX msg byte size = " +data.remaining( bss ) );
    
    Map root = MessagingUtil.convertBencodedByteStreamToPayload( data, 10, getID() );

    byte[] hash = (byte[])root.get( "infohash" );
    if( hash == null )  throw new MessageException( "hash == null" );
    if( hash.length != 20 )  throw new MessageException( "hash.length != 20: " +hash.length );

    PeerItem[] added = extractPeers( "added", root );
    PeerItem[] dropped = extractPeers( "dropped", root );
      
    if( added == null && dropped == null )  throw new MessageException( "[" +getID()+ "] received exchange message without any adds or drops" );

    return new AZPeerExchange( hash, added, dropped, version );
  
public voiddestroy()

    if( buffer != null )  buffer.returnToPool();
  
private PeerItem[]extractPeers(java.lang.String key_name, java.util.Map root_map)

    PeerItem[] return_peers = null;
    ArrayList peers = new ArrayList();

    List raw_peers = (List)root_map.get( key_name );
    if( raw_peers != null ) {
      int	peer_num = raw_peers.size();
      byte[] handshake_types = (byte[])root_map.get( key_name + "_HST" );
      byte[] udp_ports = (byte[])root_map.get( key_name + "_UDP" ); // 2403 B55+
      int pos = 0;
    
      if ( handshake_types != null && handshake_types.length != peer_num ){
     	  Logger.log(new LogEvent( LOGID, LogEvent.LT_WARNING,"PEX: invalid handshake types received: peers=" + peer_num + ",handshakes=" + handshake_types.length ));
       	  handshake_types = null;
      }
      
      if ( udp_ports != null && udp_ports.length != peer_num*2 ){
       	  Logger.log(new LogEvent( LOGID, LogEvent.LT_WARNING,"PEX: invalid udp ports received: peers=" + peer_num + ",udp_ports=" + udp_ports.length ));
    	  udp_ports = null;
      }
      
      for( Iterator it = raw_peers.iterator(); it.hasNext(); ) {
        byte[] full_address = (byte[])it.next();
        
        byte type = PeerItemFactory.HANDSHAKE_TYPE_PLAIN;        
        if( handshake_types != null ) { //only 2307+ send types
        	type = handshake_types[pos];
        }
        int	udp_port = 0;
        if ( udp_ports != null ){
        	udp_port = ((udp_ports[pos*2]<<8)&0xff00) + (udp_ports[pos*2+1]&0xff);
        }
        try{
        	PeerItem peer = PeerItemFactory.createPeerItem( full_address, PeerItemFactory.PEER_SOURCE_PEER_EXCHANGE, type, udp_port );
        	peers.add( peer );
        }catch( Exception t ){
            Logger.log(new LogEvent( LOGID, LogEvent.LT_WARNING,"PEX: invalid peer received" ));	 
        }
        pos++;
      }
    }
    
    if( !peers.isEmpty() ) {
      return_peers = new PeerItem[ peers.size() ];
      peers.toArray( return_peers );
    }
    
    return return_peers;
  
public PeerItem[]getAddedPeers()

  return peers_added;  
public DirectByteBuffer[]getData()

    if( buffer == null ) {
      Map payload_map = new HashMap();
      
      payload_map.put( "infohash", infohash );
      insertPeers( "added", payload_map, peers_added );
      insertPeers( "dropped", payload_map, peers_dropped );

      buffer = MessagingUtil.convertPayloadToBencodedByteStream( payload_map, DirectByteBuffer.AL_MSG_AZ_PEX );

      if( buffer.remaining( bss ) > 2000 )  System.out.println( "Generated AZPeerExchange size = " +buffer.remaining( bss )+ " bytes" );
    }
    
    return new DirectByteBuffer[]{ buffer };
  
public java.lang.StringgetDescription()

    if( description == null ) {
      int add_count = peers_added == null ? 0 : peers_added.length;
      int drop_count = peers_dropped == null ? 0 : peers_dropped.length;
      
      description = getID()+ " for infohash " +ByteFormatter.nicePrint( infohash, true )+ " with " +add_count+ " added and " +drop_count+ " dropped peers";
    }
    
    return description;
  
public PeerItem[]getDroppedPeers()

  return peers_dropped;  
public java.lang.StringgetFeatureID()

  return AZMessage.AZ_FEATURE_ID;  
public intgetFeatureSubID()

 return AZMessage.SUBID_AZ_PEER_EXCHANGE;  
public java.lang.StringgetID()

  return AZMessage.ID_AZ_PEER_EXCHANGE;  
public byte[]getIDBytes()

  return AZMessage.ID_AZ_PEER_EXCHANGE_BYTES;  
public byte[]getInfoHash()

  return infohash;  
public intgetType()

  return Message.TYPE_PROTOCOL_PAYLOAD;  
public bytegetVersion()

 return version; 
private voidinsertPeers(java.lang.String key_name, java.util.Map root_map, PeerItem[] peers)

    if( peers != null && peers.length > 0 ) {
      ArrayList raw_peers = new ArrayList();
      byte[] handshake_types = new byte[ peers.length ];
      byte[] udp_ports = new byte[peers.length*2];	// 2403 B55+
      int	num_valid_udp = 0;
      
      for( int i=0; i < peers.length; i++ ) {
        raw_peers.add( peers[i].getSerialization() );
        handshake_types[i] = (byte)peers[i].getHandshakeType();
        int	udp_port = peers[i].getUDPPort();
        if ( udp_port > 0 ){
        	num_valid_udp++;
           	udp_ports[i*2] = (byte)(udp_port>>8);
           	udp_ports[i*2+1] = (byte)udp_port;
        }
      }

      root_map.put( key_name, raw_peers );
      root_map.put( key_name + "_HST", handshake_types );
      if ( num_valid_udp > 0 ){
    	root_map.put( key_name + "_UDP", udp_ports );     
      }
    }