/* * Created on 02-Jan-2005 * Created by Paul Gardner * Copyright (C) 2004, 2005, 2006 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 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.pluginsimpl.local.test; import org.gudy.azureus2.core3.util.AEMonitor; import org.gudy.azureus2.core3.util.AESemaphore; import org.gudy.azureus2.core3.util.AEThread; import org.gudy.azureus2.core3.util.AEThread2; import org.gudy.azureus2.core3.util.ByteFormatter; import org.gudy.azureus2.core3.util.Debug; import org.gudy.azureus2.plugins.Plugin; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.plugins.PluginListener; import org.gudy.azureus2.plugins.PluginManager; import org.gudy.azureus2.plugins.ddb.*; import org.gudy.azureus2.plugins.disk.DiskManager; import org.gudy.azureus2.plugins.disk.DiskManagerException; import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo; import org.gudy.azureus2.plugins.disk.DiskManagerReadRequest; import org.gudy.azureus2.plugins.disk.DiskManagerReadRequestListener; import org.gudy.azureus2.plugins.disk.DiskManagerWriteRequest; import org.gudy.azureus2.plugins.disk.DiskManagerWriteRequestListener; import org.gudy.azureus2.plugins.download.Download; import org.gudy.azureus2.plugins.download.DownloadManagerListener; import org.gudy.azureus2.plugins.download.DownloadPeerListener; import org.gudy.azureus2.plugins.messaging.Message; import org.gudy.azureus2.plugins.messaging.MessageException; import org.gudy.azureus2.plugins.messaging.MessageManager; import org.gudy.azureus2.plugins.messaging.MessageManagerListener; import org.gudy.azureus2.plugins.messaging.bittorrent.BTMessageCancel; import org.gudy.azureus2.plugins.messaging.bittorrent.BTMessagePiece; import org.gudy.azureus2.plugins.messaging.bittorrent.BTMessageRequest; import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnection; import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnectionListener; import org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpoint; import org.gudy.azureus2.plugins.messaging.generic.GenericMessageHandler; import org.gudy.azureus2.plugins.messaging.generic.GenericMessageRegistration; import org.gudy.azureus2.plugins.network.IncomingMessageQueueListener; import org.gudy.azureus2.plugins.peers.Peer; import org.gudy.azureus2.plugins.peers.PeerManager; import org.gudy.azureus2.plugins.peers.PeerManagerEvent; import org.gudy.azureus2.plugins.peers.PeerManagerListener2; import org.gudy.azureus2.plugins.peers.Piece; import org.gudy.azureus2.plugins.torrent.TorrentAttribute; import org.gudy.azureus2.plugins.torrent.TorrentAttributeEvent; import org.gudy.azureus2.plugins.torrent.TorrentAttributeListener; import org.gudy.azureus2.plugins.utils.PooledByteBuffer; import org.gudy.azureus2.plugins.utils.Utilities; import org.gudy.azureus2.plugins.utils.search.Search; import org.gudy.azureus2.plugins.utils.search.SearchInitiator; import org.gudy.azureus2.plugins.utils.search.SearchListener; import org.gudy.azureus2.plugins.utils.search.SearchProvider; import org.gudy.azureus2.plugins.utils.search.SearchProviderResults; import org.gudy.azureus2.plugins.utils.search.SearchResult; import org.gudy.azureus2.plugins.utils.security.SEPublicKey; import org.gudy.azureus2.plugins.utils.security.SEPublicKeyLocator; import org.gudy.azureus2.plugins.utils.security.SESecurityManager; import org.gudy.azureus2.plugins.utils.subscriptions.Subscription; import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager; import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionResult; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler; import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler.passwordDetails; import java.io.File; import java.io.RandomAccessFile; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.*; /** * @author parg * */ public class Test implements Plugin { protected PluginInterface plugin_interface; public void initialize( PluginInterface _pi ) { plugin_interface = _pi; plugin_interface.addListener( new PluginListener() { public void initializationComplete() { Thread t = new AEThread("test") { public void runSupport() { testBTMessageHandler(); } }; t.setDaemon(true); t.start(); } public void closedownInitiated() { } public void closedownComplete() { } }); } private void testBTMessageHandler() { try{ MessageManager man = plugin_interface.getMessageManager(); man.registerMessageType( new BorkMessage( "" )); man.locateCompatiblePeers( plugin_interface, new TestMessage( "" ), new MessageManagerListener() { public void compatiblePeerFound( Download download, final Peer peer, Message message ) { System.out.println( "Compatible peer found: " + peer.getIp()); peer.getConnection().getIncomingMessageQueue().registerPriorityListener( new IncomingMessageQueueListener() { public boolean messageReceived( Message message ) { System.out.println( peer.getIp() + ": " + message.getDescription() + " (" + message + ")"); if ( message instanceof BorkMessage ){ System.out.println( "Got a borker: " + ((BorkMessage)message).getArg()); return( true ); } return( false ); } public void bytesReceived( int byte_count ) { } }); //peer.getConnection().getOutgoingMessageQueue().sendMessage( new BorkMessage( "Hello Mr Borker" )); } public void peerRemoved( Download download, Peer peer ) { } }); }catch( Throwable e ){ e.printStackTrace(); } /* plugin_interface.getDownloadManager().addListener( new DownloadManagerListener() { public void downloadAdded( Download download ) { download.addPeerListener( new DownloadPeerListener() { public void peerManagerAdded( final Download download, final PeerManager peer_manager ) { peer_manager.addListener( new PeerManagerListener2() { public void eventOccurred( PeerManagerEvent event ) { if ( event.getType() == PeerManagerEvent.ET_PEER_ADDED ){ event.getPeer().getConnection().getIncomingMessageQueue().registerPriorityListener( new IncomingMessageQueueListener() { public boolean messageReceived( Message message ) { if ( message instanceof BTMessageRequest ){ BTMessageRequest request = (BTMessageRequest)message; System.out.println( "BT_REQUEST: " + request.getPieceNumber() + "/" + request.getPieceOffset() + "/" + request.getLength()); }else if ( message instanceof BTMessageCancel ){ BTMessageCancel cancel = (BTMessageCancel)message; System.out.println( "BT_CANCEL: " + cancel.getPieceNumber() + "/" + cancel.getPieceOffset() + "/" + cancel.getLength()); }else if ( message instanceof BTMessagePiece ){ BTMessagePiece piece = (BTMessagePiece)message; System.out.println( "BT_PIECE: " + piece.getPieceNumber() + "/" + piece.getPieceOffset() + "/" + piece.getPieceData().remaining()); } return( false ); } public void bytesReceived( int byte_count ) { } }); } } }); } public void peerManagerRemoved( Download download, PeerManager peer_manager ) { } }); } public void downloadRemoved( Download download ) { } }); */ } private class BorkMessage implements Message { private ByteBuffer buffer; private String arg; private BorkMessage( String _arg ) { arg = _arg; try{ byte[] arg_bytes = arg.getBytes( "UTF-8" ); buffer = ByteBuffer.allocate( 4 + arg_bytes.length ); buffer.putInt( arg_bytes.length ); buffer.put( arg_bytes ); buffer.flip(); }catch( Throwable e ){ e.printStackTrace(); } } public String getID() { return( "BORK_MESSAGE" ); } public int getType() { return( TYPE_PROTOCOL_PAYLOAD ); } public String getDescription() { return( "borker message" ); } public ByteBuffer[] getPayload() { return new ByteBuffer[] { buffer }; } public String getArg() { return( arg ); } public Message create( ByteBuffer data ) throws MessageException { try{ int size = data.getInt(); byte[] bytes = new byte[ size ]; data.get( bytes ); return( new BorkMessage(new String(bytes, "UTF-8" ))); }catch( Throwable e ){ throw( new MessageException( "create failed", e )); } } public void destroy() { } } private class TestMessage implements Message { private ByteBuffer buffer; private String arg; private TestMessage( String _arg ) { arg = _arg; try{ byte[] arg_bytes = arg.getBytes( "UTF-8" ); buffer = ByteBuffer.allocate( 4 + arg_bytes.length ); buffer.putInt( arg_bytes.length ); buffer.put( arg_bytes ); buffer.flip(); }catch( Throwable e ){ e.printStackTrace(); } } public String getID() { return( "BT_REQUEST" ); } public int getType() { return( TYPE_PROTOCOL_PAYLOAD ); } public String getDescription() { return( "borker message" ); } public ByteBuffer[] getPayload() { return new ByteBuffer[] { buffer }; } public String getArg() { return( arg ); } public Message create( ByteBuffer data ) throws MessageException { try{ int size = data.getInt(); byte[] bytes = new byte[ size ]; data.get( bytes ); return( new BorkMessage(new String(bytes, "UTF-8" ))); }catch( Throwable e ){ throw( new MessageException( "create failed", e )); } } public void destroy() { } } private void testPluginWrite() { plugin_interface.getDownloadManager().addListener( new DownloadManagerListener() { public void downloadAdded( Download download ) { download.addPeerListener( new DownloadPeerListener() { public void peerManagerAdded( final Download download, final PeerManager peer_manager ) { new AEThread2( "" ) { public void run() { DiskManager dm = peer_manager.getDiskManager(); File f = new File( "C:\\temp\\capture2.pcap" ); long len = f.length(); int piece_size = (int)download.getTorrent().getPieceSize(); int max_blocks = piece_size / DiskManager.BLOCK_SIZE; List<long[]> chunks = new ArrayList<long[]>(); long i = 0; while( i < len ){ int blocks = ((int)(Math.random()*max_blocks))+1; long rem_in_piece = i - ((i/piece_size)*piece_size); if ( rem_in_piece == 0 ){ rem_in_piece = piece_size; } rem_in_piece = Math.min( len-i, rem_in_piece); long chunk_size = Math.min(rem_in_piece,blocks*DiskManager.BLOCK_SIZE); chunks.add( new long[]{ i, chunk_size }); i += chunk_size; } Utilities utils = plugin_interface.getUtilities(); try{ RandomAccessFile raf = new RandomAccessFile(f, "r" ); while( !chunks.isEmpty()){ long[] chunk = chunks.remove((int)(Math.random()*chunks.size())); final long position = chunk[0]; final int size = (int)chunk[1]; raf.seek( position ); byte[] buffer = new byte[ size ]; raf.read( buffer ); int piece_number = (int)(position/piece_size); int piece_offset = (int)(position % piece_size); dm.write( piece_number, piece_offset, utils.allocatePooledByteBuffer( buffer ), new DiskManagerWriteRequestListener() { public void complete( DiskManagerWriteRequest request ) { System.out.println( "write ok: offset=" + position + ",size=" + size ); } public void failed( DiskManagerWriteRequest request, DiskManagerException error ) { System.out.println( "write failed" ); error.printStackTrace(); } }); Thread.sleep(10); } }catch( Throwable e ){ e.printStackTrace(); } } }.start(); } public void peerManagerRemoved( Download download, PeerManager peer_manager ) { } }); } public void downloadRemoved( Download download ) { } }); } private void testPieceListener() { plugin_interface.getDownloadManager().addListener( new DownloadManagerListener() { public void downloadAdded( Download download ) { download.addPeerListener( new DownloadPeerListener() { public void peerManagerAdded( Download download, final PeerManager peer_manager ) { peer_manager.addListener( new PeerManagerListener2() { public void eventOccurred( PeerManagerEvent event ) { if ( event.getType() == PeerManagerEvent.ET_PIECE_COMPLETION_CHANGED ){ Piece piece = (Piece)event.getData(); System.out.println( "piece: " + piece.getIndex() + ", done=" + piece.isDone()); try{ peer_manager.getDiskManager().read( piece.getIndex(), 0, piece.getLength(), new DiskManagerReadRequestListener() { public void complete( DiskManagerReadRequest request, PooledByteBuffer buffer ) { System.out.println( " read ok" ); buffer.returnToPool(); } public void failed( DiskManagerReadRequest request, DiskManagerException error ) { System.out.println( " read failed: " + Debug.getNestedExceptionMessage( error )); } }); }catch( Throwable e ){ e.printStackTrace(); } } } }); } public void peerManagerRemoved( Download download, PeerManager peer_manager ) { } }); } public void downloadRemoved( Download download ) { } }); } private void testSubs() { try{ SubscriptionManager sm = plugin_interface.getUtilities().getSubscriptionManager(); Subscription[] subs = sm.getSubscriptions(); for ( Subscription s: subs ){ System.out.println( "subs: " + s.getName()); SubscriptionResult[] results = s.getResults(); for ( SubscriptionResult result: results ){ System.out.println( " " + result.getProperty( SearchResult.PR_NAME ) + ", read=" + result.isRead()); } } }catch( Throwable e ){ e.printStackTrace(); } } private void testMessaging() { try{ AzureusCoreFactory.getSingleton().getCryptoManager().addPasswordHandler( new CryptoManagerPasswordHandler() { public int getHandlerType() { return( HANDLER_TYPE_USER ); } public passwordDetails getPassword( int handler_type, int action_type, boolean last_pw_incorrect, String reason ) { System.out.println( "CryptoPassword (" + reason + ")"); return( new passwordDetails() { public char[] getPassword() { return( "changeit".toCharArray()); } public int getPersistForSeconds() { return( 0 ); } }); } public void passwordOK( int handler_type, passwordDetails details) { } }); final SESecurityManager sec_man = plugin_interface.getUtilities().getSecurityManager(); final SEPublicKey my_key = sec_man.getPublicKey( SEPublicKey.KEY_TYPE_ECC_192, "test" ); final int stream_crypto = MessageManager.STREAM_ENCRYPTION_RC4_REQUIRED; final boolean use_sts = true; final int block_crypto = SESecurityManager.BLOCK_ENCRYPTION_AES; GenericMessageRegistration reg = plugin_interface.getMessageManager().registerGenericMessageType( "GENTEST", "Gen test desc", stream_crypto, new GenericMessageHandler() { public boolean accept( GenericMessageConnection connection ) throws MessageException { System.out.println( "accept" ); try{ if ( use_sts ){ connection = sec_man.getSTSConnection( connection, my_key, new SEPublicKeyLocator() { public boolean accept( Object context, SEPublicKey other_key ) { System.out.println( "acceptKey" ); return( true ); } }, "test", block_crypto ); } connection.addListener( new GenericMessageConnectionListener() { public void connected( GenericMessageConnection connection ) { } public void receive( GenericMessageConnection connection, PooledByteBuffer message ) throws MessageException { System.out.println( "receive: " + message.toByteArray().length ); PooledByteBuffer reply = plugin_interface.getUtilities().allocatePooledByteBuffer( new byte[connection.getMaximumMessageSize()]); connection.send( reply ); } public void failed( GenericMessageConnection connection, Throwable error ) throws MessageException { System.out.println( "Responder connection error:" ); error.printStackTrace(); } }); }catch( Throwable e ){ connection.close(); e.printStackTrace(); } return( true ); } }); InetSocketAddress tcp_target = new InetSocketAddress( "127.0.0.1", 6889 ); InetSocketAddress udp_target = new InetSocketAddress( "212.159.18.92", 6881 ); GenericMessageEndpoint endpoint = reg.createEndpoint( tcp_target ); endpoint.addTCP( tcp_target ); endpoint.addUDP( udp_target ); while( true ){ try{ for (int i=0;i<1000;i++){ System.out.println( "Test: initiating connection" ); final AESemaphore sem = new AESemaphore( "wait!" ); GenericMessageConnection con = reg.createConnection( endpoint ); if ( use_sts ){ con = sec_man.getSTSConnection( con, my_key, new SEPublicKeyLocator() { public boolean accept( Object context, SEPublicKey other_key ) { System.out.println( "acceptKey" ); return( true ); } }, "test", block_crypto ); } con.addListener( new GenericMessageConnectionListener() { public void connected( GenericMessageConnection connection ) { System.out.println( "connected" ); PooledByteBuffer data = plugin_interface.getUtilities().allocatePooledByteBuffer( "1234".getBytes()); try{ connection.send( data ); }catch( Throwable e ){ e.printStackTrace(); } } public void receive( GenericMessageConnection connection, PooledByteBuffer message ) throws MessageException { System.out.println( "receive: " + message.toByteArray().length ); try{ Thread.sleep(30000); }catch( Throwable e ){ } /* PooledByteBuffer reply = plugin_interface.getUtilities().allocatePooledByteBuffer( new byte[16*1024]); connection.send( reply ); */ System.out.println( "closing connection" ); connection.close(); sem.release(); } public void failed( GenericMessageConnection connection, Throwable error ) throws MessageException { System.out.println( "Initiator connection error:" ); error.printStackTrace(); sem.release(); } }); con.connect(); sem.reserve(); Thread.sleep( 1000 ); } }catch( Throwable e ){ e.printStackTrace(); try{ System.out.println( "Sleeping before retrying" ); Thread.sleep( 30000 ); }catch( Throwable f ){ } } } }catch( Throwable e ){ e.printStackTrace(); } } private void testSearch() { while( true ){ try{ Thread.sleep(1000); SearchInitiator si = plugin_interface.getUtilities().getSearchInitiator(); SearchProvider[] providers = si.getProviders(); System.out.println( "search providers=" + providers.length ); if ( providers.length > 0 ){ Map<String,String> properties = new HashMap<String,String>(); properties.put( SearchInitiator.PR_SEARCH_TERM, "monkey" ); properties.put( SearchInitiator.PR_MATURE, "true" ); /* * final boolean[] complete = {false}; Search s = si.createSearch( providers, properties, new SearchListener() { public void receivedResults( SearchProviderResults[] results ) { System.out.println( "received results" ); for ( SearchProviderResults result: results ){ System.out.println( " " + result.getProvider().getProperty( SearchProvider.PR_NAME ) + ": comp=" + result.isComplete() + ", error=" + result.getError()); SearchResult[] srs = result.getResults(); for ( SearchResult sr: srs ){ System.out.println( " " + sr.getProperty( SearchResult.PR_NAME )); } } } public void completed() { System.out.println( "received completed" ); complete[0] = true; } }); while( !complete[0] ){ Thread.sleep(1000); System.out.println( "waiting for results" ); } */ Search s = si.createSearch( providers, properties, null ); while( !s.isComplete()){ Thread.sleep(1000); SearchProviderResults[] results = s.getResults(); if ( results.length > 0 ){ System.out.println( "Got results: " + results.length ); for ( SearchProviderResults result: results ){ System.out.println( " " + result.getProvider().getProperty( SearchProvider.PR_NAME ) + ": comp=" + result.isComplete() + ", error=" + result.getError()); SearchResult[] srs = result.getResults(); for ( SearchResult sr: srs ){ System.out.println( " " + sr.getProperty( SearchResult.PR_NAME )); } } } } break; } }catch( Throwable e){ e.printStackTrace(); } } } private void testLinks() { plugin_interface.getDownloadManager().addListener( new DownloadManagerListener() { public void downloadAdded( Download download ) { DiskManagerFileInfo[] info = download.getDiskManagerFileInfo(); for (int i=0;i<info.length;i++){ info[i].setLink( new File( "C:\\temp" )); } } public void downloadRemoved( Download download ) { } }); } private void testDDB() { try{ DistributedDatabase db = plugin_interface.getDistributedDatabase(); DistributedDatabaseKey key = db.createKey( new byte[]{ 4,7,1,2,5,8 }); boolean do_write = false; if ( do_write ){ DistributedDatabaseValue[] values = new DistributedDatabaseValue[500]; for (int i=0;i<values.length;i++){ byte[] val = new byte[20]; Arrays.fill( val, (byte)i ); values[i] = db.createValue( val ); } db.write( new DistributedDatabaseListener() { public void event( DistributedDatabaseEvent event ) { System.out.println( "Event:" + event.getType()); if ( event.getType() == DistributedDatabaseEvent.ET_VALUE_WRITTEN ){ try{ System.out.println( " write - key = " + ByteFormatter.encodeString((byte[])event.getKey().getKey()) + ", val = " + ByteFormatter.encodeString((byte[]) event.getValue().getValue(byte[].class))); }catch( Throwable e ){ e.printStackTrace(); } } } }, key, values ); }else{ db.read( new DistributedDatabaseListener() { public void event( DistributedDatabaseEvent event ) { System.out.println( "Event:" + event.getType()); if ( event.getType() == DistributedDatabaseEvent.ET_VALUE_READ ){ try{ System.out.println( " read - key = " + ByteFormatter.encodeString((byte[])event.getKey().getKey()) + ", val = " + ByteFormatter.encodeString((byte[]) event.getValue().getValue(byte[].class))); }catch( Throwable e ){ e.printStackTrace(); } } } }, key, 60000 ); } }catch( Throwable e ){ e.printStackTrace(); } } private void taTest() { try{ final TorrentAttribute ta = plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_CATEGORY); ta.addTorrentAttributeListener( new TorrentAttributeListener() { public void event( TorrentAttributeEvent ev ) { System.out.println( "ev: " + ev.getType() + ", " + ev.getData()); if ( ev.getType() == TorrentAttributeEvent.ET_ATTRIBUTE_VALUE_ADDED ){ if ( "plop".equals( ev.getData())){ ta.removeDefinedValue( "plop" ); } } } }); ta.addDefinedValue( "wibble" ); plugin_interface.getDownloadManager().addListener( new DownloadManagerListener() { public void downloadAdded( Download download ) { try{ download.setAttribute( ta, "wibble" ); }catch( Throwable e ){ e.printStackTrace(); } } public void downloadRemoved( Download download ) { } }); }catch( Throwable e ){ e.printStackTrace(); } } public static void main( String[] args ) { System.setProperty( "azureus.dynamic.plugins", "org.gudy.azureus2.pluginsimpl.local.test.Test" ); org.gudy.azureus2.ui.swt.Main.main( args ); } }