/*
* Created on 17-Jan-2006
* Created by Paul Gardner
* Copyright (C) 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 com.aelitis.azureus.core.networkmanager.impl.test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.AEDiagnostics;
import org.gudy.azureus2.core3.util.Debug;
import com.aelitis.azureus.core.networkmanager.VirtualChannelSelector;
import com.aelitis.azureus.core.networkmanager.VirtualServerChannelSelector;
import com.aelitis.azureus.core.networkmanager.VirtualServerChannelSelectorFactory;
import com.aelitis.azureus.core.networkmanager.VirtualChannelSelector.VirtualSelectorListener;
import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoder;
import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoderInitial;
import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoderAdapter;
import com.aelitis.azureus.core.networkmanager.impl.TransportHelperFilter;
import com.aelitis.azureus.core.networkmanager.impl.TransportHelper;
import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPTransportHelper;
public class
PHETester
{
private final VirtualChannelSelector connect_selector = new VirtualChannelSelector( "PHETester", VirtualChannelSelector.OP_CONNECT, true );
private byte[] TEST_HEADER = "TestHeader".getBytes();
private static boolean OUTGOING_PLAIN = false;
private static byte[] shared_secret = "sdsjdksjdkj".getBytes();
public
PHETester()
{
ProtocolDecoder.addSecrets( new byte[][]{ shared_secret });
VirtualServerChannelSelector
accept_server = VirtualServerChannelSelectorFactory.createNonBlocking(
new InetSocketAddress( 8765 ),
0,
new VirtualServerChannelSelector.SelectListener()
{
public void
newConnectionAccepted(
ServerSocketChannel server,
SocketChannel channel )
{
incoming( channel );
}
});
accept_server.start();
new Thread()
{
public void
run()
{
while( true ){
try{
connect_selector.select( 100 );
}
catch( Throwable t ) {
Debug.out( "connnectSelectLoop() EXCEPTION: ", t );
}
}
}
}.start();
outgoings();
}
protected void
incoming(
SocketChannel channel )
{
try{
TransportHelper helper = new TCPTransportHelper( channel );
final ProtocolDecoderInitial decoder =
new ProtocolDecoderInitial(
helper,
null,
false,
null,
new ProtocolDecoderAdapter()
{
public void
decodeComplete(
ProtocolDecoder decoder,
ByteBuffer remaining_initial_data )
{
System.out.println( "incoming decode complete: " + decoder.getFilter().getName(false));
readStream( "incoming", decoder.getFilter() );
writeStream( "ten fat monkies", decoder.getFilter() );
}
public void
decodeFailed(
ProtocolDecoder decoder,
Throwable cause )
{
System.out.println( "incoming decode failed: " + Debug.getNestedExceptionMessage(cause));
}
public void
gotSecret(
byte[] session_secret )
{
}
public int
getMaximumPlainHeaderLength()
{
return( TEST_HEADER.length );
}
public int
matchPlainHeader(
ByteBuffer buffer )
{
int pos = buffer.position();
int lim = buffer.limit();
buffer.flip();
boolean match = buffer.compareTo( ByteBuffer.wrap( TEST_HEADER )) == 0;
buffer.position( pos );
buffer.limit( lim );
System.out.println( "Match - " + match );
return( match?ProtocolDecoderAdapter.MATCH_CRYPTO_NO_AUTO_FALLBACK:ProtocolDecoderAdapter.MATCH_NONE );
}
});
}catch( Throwable e ){
e.printStackTrace();
}
}
protected void
outgoings()
{
while( true ){
outgoing();
try{
Thread.sleep(1000000);
}catch( Throwable e ){
}
}
}
protected void
outgoing()
{
try{
final SocketChannel channel = SocketChannel.open();
channel.configureBlocking( false );
if ( channel.connect( new InetSocketAddress("localhost", 8765 ))){
outgoing( channel );
}else{
connect_selector.register(
channel,
new VirtualSelectorListener()
{
public boolean
selectSuccess(
VirtualChannelSelector selector, SocketChannel sc, Object attachment)
{
try{
if ( channel.finishConnect()){
outgoing( channel );
return( true );
}else{
throw( new IOException( "finishConnect failed" ));
}
}catch( Throwable e ){
e.printStackTrace();
return( false );
}
}
public void
selectFailure(
VirtualChannelSelector selector, SocketChannel sc, Object attachment, Throwable msg)
{
msg.printStackTrace();
}
},
null );
}
}catch( Throwable e ){
e.printStackTrace();
}
}
protected void
outgoing(
SocketChannel channel )
{
try{
if ( OUTGOING_PLAIN ){
writeStream( TEST_HEADER, channel);
writeStream( "two jolly porkers".getBytes(), channel );
}else{
TransportHelper helper = new TCPTransportHelper( channel );
final ProtocolDecoderInitial decoder =
new ProtocolDecoderInitial(
helper,
new byte[][]{ shared_secret },
true,
null,
new ProtocolDecoderAdapter()
{
public void
decodeComplete(
ProtocolDecoder decoder,
ByteBuffer remaining_initial_data )
{
System.out.println( "outgoing decode complete: " + decoder.getFilter().getName(false));
readStream( "incoming", decoder.getFilter() );
writeStream( TEST_HEADER, decoder.getFilter());
writeStream( "two jolly porkers", decoder.getFilter() );
}
public void
decodeFailed(
ProtocolDecoder decoder,
Throwable cause )
{
System.out.println( "outgoing decode failed: " + Debug.getNestedExceptionMessage(cause));
}
public void
gotSecret(
byte[] session_secret )
{
}
public int
getMaximumPlainHeaderLength()
{
throw( new RuntimeException());
}
public int
matchPlainHeader(
ByteBuffer buffer )
{
throw( new RuntimeException());
}
});
}
}catch( Throwable e ){
e.printStackTrace();
}
}
protected void
readStream(
final String str,
final TransportHelperFilter filter )
{
try{
TCPNetworkManager.getSingleton().getReadSelector().register(
((TCPTransportHelper)filter.getHelper()).getSocketChannel(),
new VirtualSelectorListener()
{
public boolean
selectSuccess(
VirtualChannelSelector selector, SocketChannel sc, Object attachment)
{
ByteBuffer buffer = ByteBuffer.allocate(1024);
try{
long len = filter.read( new ByteBuffer[]{ buffer }, 0, 1 );
byte[] data = new byte[buffer.position()];
buffer.flip();
buffer.get( data );
System.out.println( str + ": " + new String(data));
return( len > 0 );
}catch( Throwable e ){
e.printStackTrace();
return( false );
}
}
public void
selectFailure(
VirtualChannelSelector selector, SocketChannel sc, Object attachment, Throwable msg)
{
msg.printStackTrace();
}
},
null );
}catch( Throwable e ){
e.printStackTrace();
}
}
protected void
writeStream(
String str,
TransportHelperFilter filter )
{
writeStream( str.getBytes(), filter );
}
protected void
writeStream(
byte[] data,
TransportHelperFilter filter )
{
try{
filter.write( new ByteBuffer[]{ ByteBuffer.wrap(data)}, 0, 1 );
}catch( Throwable e ){
e.printStackTrace();
}
}
protected void
writeStream(
byte[] data,
SocketChannel channel )
{
try{
channel.write( new ByteBuffer[]{ ByteBuffer.wrap(data)}, 0, 1 );
}catch( Throwable e ){
e.printStackTrace();
}
}
public static void
main(
String[] args )
{
AEDiagnostics.startup( false );
// OUTGOING_PLAIN = true;
COConfigurationManager.setParameter( "network.transport.encrypted.require", true );
COConfigurationManager.setParameter( "network.transport.encrypted.min_level", "Plain" );
new PHETester();
try{
Thread.sleep(10000000);
}catch( Throwable e ){
}
}
}