FileDocCategorySizeDatePackage
GenericMessageConnectionImpl.javaAPI DocAzureus 3.0.3.412383Tue Nov 21 16:13:12 GMT 2006org.gudy.azureus2.pluginsimpl.local.messaging

GenericMessageConnectionImpl

public class GenericMessageConnectionImpl extends Object implements org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnection

Fields Summary
private static final boolean
TRACE
private static final boolean
TEST_TUNNEL
private MessageManagerImpl
message_manager
private String
msg_id
private String
msg_desc
private GenericMessageEndpointImpl
endpoint
private int
stream_crypto
byte[]
shared_secrets
private boolean
incoming
private volatile GenericMessageConnectionAdapter
delegate
private volatile boolean
closed
private volatile boolean
connecting
private List
listeners
Constructors Summary
protected GenericMessageConnectionImpl(MessageManagerImpl _message_manager, GenericMessageConnectionAdapter _delegate)


	
	
	
						
			 
	
		message_manager	= _message_manager;
		delegate		= _delegate;
		
		incoming	= true;
		
		delegate.setOwner( this );
	
protected GenericMessageConnectionImpl(MessageManagerImpl _message_manager, String _msg_id, String _msg_desc, GenericMessageEndpointImpl _endpoint, int _stream_crypto, byte[] _shared_secrets)

		message_manager	= _message_manager;
		msg_id			= _msg_id;
		msg_desc		= _msg_desc;
		endpoint		= _endpoint;
		stream_crypto	= _stream_crypto;
		shared_secrets	= _shared_secrets;
		
		incoming	= false;
	
Methods Summary
protected voidaccepted()
Incoming connection has been accepted

		delegate.accepted();
	
public voidaddListener(org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnectionListener listener)

		listeners.add( listener );
	
public voidclose()

		closed	= true;
		
		if ( delegate != null ){
			
			delegate.close();
		}
	
public voidconnect()

		connect( null );
	
public voidconnect(java.nio.ByteBuffer initial_data)
Outgoing connection

param
initial_data
throws
MessageException

		if ( incoming ){
			
			throw( new MessageException( "Already connected" ));
		}
		
		if ( connecting ){
			
			throw( new MessageException( "Connect already performed" ));
		}
		
		connecting	= true;
		
		if ( closed ){
			
			throw( new MessageException( "Connection has been closed" ));
		}
		
		InetSocketAddress	tcp_ep = endpoint.getTCP();
				
		if ( tcp_ep != null ){
			
			connectTCP( initial_data, tcp_ep );
			
		}else{
			
			InetSocketAddress	udp_ep = endpoint.getUDP();

			if ( udp_ep != null ){
				
				connectUDP( initial_data, udp_ep, false );
				
			}else{
				
				throw( new MessageException( "No protocols availabld" ));
			}
		}
	
protected voidconnectTCP(java.nio.ByteBuffer initial_data, java.net.InetSocketAddress tcp_ep)

		if ( TRACE ){
			System.out.println( "TCP connection attempt to " + tcp_ep  );
		}
		
		GenericMessageEndpointImpl	gen_tcp = new GenericMessageEndpointImpl( endpoint.getNotionalAddress());
		
		gen_tcp.addTCP( tcp_ep );
		
		final GenericMessageConnectionDirect tcp_delegate = new GenericMessageConnectionDirect( msg_id, msg_desc, gen_tcp, stream_crypto, shared_secrets );
			
		tcp_delegate.setOwner( this );

		tcp_delegate.connect( 
				initial_data,
				new GenericMessageConnectionAdapter.ConnectionListener()
				{
					public void
					connectSuccess()
					{
						delegate = tcp_delegate;
						
						if ( closed ){
							
							try{
								delegate.close();
								
							}catch( Throwable e ){
							}
							
							reportFailed( new MessageException( "Connection has been closed" ));

						}else{
							
							reportConnected();
						}
					}
					
					public void 
					connectFailure( 
						Throwable failure_msg )
					{
						InetSocketAddress	udp_ep = endpoint.getUDP();

						if ( udp_ep != null ){
							
							initial_data.rewind();
							
							connectUDP( initial_data, udp_ep, false );
							
						}else{
							
							reportFailed( failure_msg );
						}
					}
				});
	
protected voidconnectTunnel(java.nio.ByteBuffer initial_data, org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpoint ep, java.net.InetSocketAddress rendezvous, java.net.InetSocketAddress target)

		if ( TRACE ){
			System.out.println( "Tunnel connection attempt to " + target + " (rendezvous=" + rendezvous + ")" );
		}
		
		final GenericMessageConnectionIndirect tunnel_delegate = 
			new GenericMessageConnectionIndirect( message_manager, msg_id, msg_desc, ep, rendezvous, target );
		
		tunnel_delegate.setOwner( this );
		
		tunnel_delegate.connect( 
				initial_data,
				new GenericMessageConnectionAdapter.ConnectionListener()
				{
					public void
					connectSuccess()
					{
						delegate = tunnel_delegate;
						
						if ( closed ){
							
							try{
								delegate.close();
								
							}catch( Throwable e ){
								
							}
							
							reportFailed( new MessageException( "Connection has been closed" ));

						}else{
							
							reportConnected();
						}
					}
					
					public void 
					connectFailure( 
						Throwable failure_msg )
					{
						reportFailed( failure_msg );
					}
				});
	
protected voidconnectUDP(java.nio.ByteBuffer initial_data, java.net.InetSocketAddress udp_ep, boolean nat_traversal)

		if ( TRACE ){
			System.out.println( "UDP connection attempt to " + udp_ep + " (nat=" + nat_traversal + ")" );
		}

		final GenericMessageEndpointImpl	gen_udp = new GenericMessageEndpointImpl( endpoint.getNotionalAddress());
		
		gen_udp.addUDP( udp_ep );
		
		final GenericMessageConnectionAdapter udp_delegate = new GenericMessageConnectionDirect( msg_id, msg_desc, gen_udp, stream_crypto, shared_secrets );
		
		udp_delegate.setOwner( this );
		
		if ( nat_traversal || TEST_TUNNEL ){
			
			final NATTraverser	nat_traverser = message_manager.getNATTraverser();
			
			Map	request = new HashMap();
					
			nat_traverser.attemptTraversal(
					message_manager,
					udp_ep,
					request,
					false,
					new NATTraversalObserver()
					{
						public void
						succeeded(
							final InetSocketAddress	rendezvous,
							final InetSocketAddress	target,
							Map						reply )
						{
							if ( closed ){
															
								reportFailed( new MessageException( "Connection has been closed" ));

							}else{
								
								if ( TEST_TUNNEL ){
									
									initial_data.rewind();
									
									connectTunnel( initial_data, gen_udp, rendezvous, target );
									
								}else{
								
									udp_delegate.connect( 
											initial_data,
											new GenericMessageConnectionAdapter.ConnectionListener()
											{
												public void
												connectSuccess()
												{
													delegate = udp_delegate;
													
													if ( closed ){
														
														try{
															delegate.close();
															
														}catch( Throwable e ){													
														}
														
														reportFailed( new MessageException( "Connection has been closed" ));
														
													}else{
														
														reportConnected();
													}												
												}
												
												public void 
												connectFailure( 
													Throwable failure_msg )
												{
													initial_data.rewind();
	
													connectTunnel( initial_data, gen_udp, rendezvous, target );
												}
											});
								}
							}
						}
						
						public void
						failed(
							int			failure_type )
						{
							reportFailed( new Throwable( "UDP connection attempt failed - NAT traversal failed, type=" + failure_type ));
						}
						
						public void
						failed(
							Throwable 	cause )
						{
							reportFailed( cause );
						}
						
						public void
						disabled()
						{
							reportFailed( new Throwable( "UDP connection attempt failed as DDB is disabled" ));
						}
					});
		}else{
	
			udp_delegate.connect( 
					initial_data,
					new GenericMessageConnectionAdapter.ConnectionListener()
					{
						public void
						connectSuccess()
						{
							delegate = udp_delegate;
							
							if ( closed ){
								
								try{
									delegate.close();
									
								}catch( Throwable e ){	
								}
								
								reportFailed( new MessageException( "Connection has been closed" ));

							}else{
								
								reportConnected();
							}
						}
						
						public void 
						connectFailure( 
							Throwable failure_msg )
						{
							initial_data.rewind();
								
							connectUDP( initial_data, udp_ep, true );
						}
					});
		}
	
public org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpointgetEndpoint()

		return( endpoint==null?delegate.getEndpoint():endpoint);
	
public intgetMaximumMessageSize()

		return( delegate==null?GenericMessageConnectionIndirect.MAX_MESSAGE_SIZE:delegate.getMaximumMessageSize());
	
public booleanisIncoming()

		return( incoming );
	
protected voidreceive(GenericMessage message)

		boolean	handled = false;
		
		for (int i=0;i<listeners.size();i++){
			
			PooledByteBuffer	buffer = new PooledByteBufferImpl(message.getPayload());
			
			try{
				((GenericMessageConnectionListener)listeners.get(i)).receive( this, buffer );
				
				handled = true;
				
			}catch( Throwable f ){
				
				buffer.returnToPool();
				
				Debug.printStackTrace(f);
			}
		}
		
		if ( !handled ){
			
			Debug.out( "GenericMessage: incoming message not handled" );
		}
	
public voidremoveListener(org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnectionListener listener)

		listeners.remove( listener );
	
protected voidreportConnected()

		for (int i=0;i<listeners.size();i++){
			
			try{
				((GenericMessageConnectionListener)listeners.get(i)).connected( this );
				
			}catch( Throwable f ){
				
				Debug.printStackTrace(f);
			}
		}
	
protected voidreportFailed(java.lang.Throwable e)

		for (int i=0;i<listeners.size();i++){
			
			try{
				((GenericMessageConnectionListener)listeners.get(i)).failed( this, e );
				
			}catch( Throwable f ){
				
				Debug.printStackTrace(f);
			}
		}
	
public voidsend(org.gudy.azureus2.plugins.utils.PooledByteBuffer message)

		int	size = ((PooledByteBufferImpl)message).getBuffer().remaining( DirectByteBuffer.SS_EXTERNAL );
		
		if ( size > getMaximumMessageSize()){
			
			throw( new MessageException( "Message is too large: supplied is " + size + ", maximum is " + getMaximumMessageSize()));
		}
		
		delegate.send( message );