ProtocolDecoderInitialpublic class ProtocolDecoderInitial extends ProtocolDecoder
Fields Summary |
---|
private static final org.gudy.azureus2.core3.logging.LogIDs | LOGID | private ProtocolDecoderAdapter | adapter | private TransportHelperFilter | filter | private TransportHelper | transport | private byte[] | shared_secrets | private ByteBuffer | initial_data | private ByteBuffer | decode_buffer | private int | decode_read | private long | start_time | private ProtocolDecoderPHE | phe_decoder | private long | last_read_time | private boolean | processing_complete |
Constructors Summary |
---|
public ProtocolDecoderInitial(TransportHelper _transport, byte[] _shared_secrets, boolean _outgoing, ByteBuffer _initial_data, ProtocolDecoderAdapter _adapter)
super( true );
transport = _transport;
shared_secrets = _shared_secrets;
initial_data = _initial_data;
adapter = _adapter;
final TransportHelperFilterTransparent transparent_filter = new TransportHelperFilterTransparent( transport, false );
filter = transparent_filter;
if ( _outgoing ){ //we assume that for outgoing connections, if we are here, we want to use crypto
if ( ProtocolDecoderPHE.isCryptoOK()){
decodePHE( null );
}else{
throw( new IOException( "Crypto required but unavailable" ));
}
}else{
decode_buffer = ByteBuffer.allocate( adapter.getMaximumPlainHeaderLength());
transport.registerForReadSelects(
new TransportHelper.selectListener()
{
public boolean
selectSuccess(
TransportHelper helper,
Object attachment )
{
try{
int len = helper.read( decode_buffer );
if ( len < 0 ){
failed( new IOException( "end of stream on socket read: in=" + decode_buffer.position()));
}else if ( len == 0 ){
return( false );
}
last_read_time = SystemTime.getCurrentTime();
decode_read += len;
int match = adapter.matchPlainHeader( decode_buffer );
if ( match != ProtocolDecoderAdapter.MATCH_NONE ){
helper.cancelReadSelects();
if ( NetworkManager.REQUIRE_CRYPTO_HANDSHAKE && match == ProtocolDecoderAdapter.MATCH_CRYPTO_NO_AUTO_FALLBACK ){
if ( NetworkManager.INCOMING_HANDSHAKE_FALLBACK_ALLOWED ){
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Incoming connection ["+ transport.getAddress() + "] is not encrypted but has been accepted as fallback is enabled" ));
}
else if( AddressUtils.isLANLocalAddress( transport.getAddress().getAddress().getHostAddress() ) == AddressUtils.LAN_LOCAL_YES ) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Incoming connection ["+ transport.getAddress() + "] is not encrypted but has been accepted as lan-local" ));
}
else{
throw( new IOException( "Crypto required but incoming connection has none" ));
}
}
decode_buffer.flip();
transparent_filter.insertRead( decode_buffer );
complete( initial_data );
}else{
if ( !decode_buffer.hasRemaining()){
helper.cancelReadSelects();
decode_buffer.flip();
decodePHE( decode_buffer );
}
}
return( true );
}catch( Throwable e ){
selectFailure( helper, attachment, e );
return( false );
}
}
public void
selectFailure(
TransportHelper helper,
Object attachment,
Throwable msg)
{
helper.cancelReadSelects();
failed( msg );
}
},
this );
}
|
Methods Summary |
---|
protected void | complete(java.nio.ByteBuffer remaining_initial_data)
if ( !processing_complete ){
processing_complete = true;
adapter.decodeComplete( this, remaining_initial_data );
}
| protected void | decodePHE(java.nio.ByteBuffer buffer)
ProtocolDecoderAdapter phe_adapter =
new ProtocolDecoderAdapter()
{
public void
decodeComplete(
ProtocolDecoder decoder,
ByteBuffer remaining_initial_data )
{
filter = decoder.getFilter();
complete( remaining_initial_data );
}
public void
decodeFailed(
ProtocolDecoder decoder,
Throwable cause )
{
failed( cause );
}
public void
gotSecret(
byte[] session_secret )
{
adapter.gotSecret( session_secret );
}
public int
getMaximumPlainHeaderLength()
{
throw( new RuntimeException());
}
public int
matchPlainHeader(
ByteBuffer buffer )
{
throw( new RuntimeException());
}
};
phe_decoder = new ProtocolDecoderPHE( transport, shared_secrets, buffer, initial_data, phe_adapter );
| protected void | failed(java.lang.Throwable reason)
if ( !processing_complete ){
processing_complete = true;
adapter.decodeFailed( this, reason );
}
| public TransportHelperFilter | getFilter()
return( filter );
| public boolean | isComplete(long now)
if ( !processing_complete ){
if ( start_time > now ){
start_time = now;
}
if ( last_read_time > now ){
last_read_time = now;
}
if ( phe_decoder != null ){
last_read_time = phe_decoder.getLastReadTime();
}
long timeout;
long time;
if ( last_read_time == 0 ){
timeout = transport.getConnectTimeout();
time = start_time;
}else{
timeout = transport.getReadTimeout();
time = last_read_time;
}
if ( now - time > timeout ){
try{
transport.cancelReadSelects();
transport.cancelWriteSelects();
}catch( Throwable e ){
}
String phe_str = "";
if ( phe_decoder != null ){
phe_str = ", crypto: " + phe_decoder.getString();
}
if ( Logger.isEnabled()){
Logger.log(new LogEvent(LOGID, "Connection ["
+ transport.getAddress() + "] forcibly timed out after "
+ timeout/1000 + "sec due to socket inactivity"));
}
failed( new Throwable( "Protocol decode aborted: timed out after " + timeout/1000+ "sec: " + decode_read + " bytes read" + phe_str ));
}
}
return( processing_complete );
|
|