This test WITHOUT encryption reveals something is majorly wrong with our packet decoding causing random and frequent disconnects.

This commit is contained in:
md_5 2013-03-12 17:53:18 +11:00
parent 5688099605
commit ac2c96c2ea
3 changed files with 52 additions and 15 deletions

View File

@ -73,6 +73,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
this.ch = channel; this.ch = channel;
} }
@Override
public void exception(Throwable t) throws Exception
{
disconnect( ChatColor.RED + Util.exception( t ) );
}
@Override @Override
public void handle(Packet1Login login) throws Exception public void handle(Packet1Login login) throws Exception
{ {
@ -113,7 +119,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
Preconditions.checkArgument( handshake.username.length() <= 16, "Cannot have username longer than 16 characters" ); Preconditions.checkArgument( handshake.username.length() <= 16, "Cannot have username longer than 16 characters" );
this.handshake = handshake; this.handshake = handshake;
ch.write( forgeMods ); ch.write( forgeMods );
ch.write( request = EncryptionUtil.encryptRequest() ); handle( (PacketCDClientStatus) null );
//ch.write( request = EncryptionUtil.encryptRequest() );
thisState = State.ENCRYPT; thisState = State.ENCRYPT;
} }
@ -195,7 +202,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override @Override
public void handle(PacketCDClientStatus clientStatus) throws Exception public void handle(PacketCDClientStatus clientStatus) throws Exception
{ {
Preconditions.checkState( thisState == State.LOGIN, "Not expecting LOGIN" ); // Preconditions.checkState( thisState == State.LOGIN, "Not expecting LOGIN" );
UserConnection userCon = new UserConnection( (BungeeCord) bungee, ch, this, handshake, forgeLogin, loginMessages ); UserConnection userCon = new UserConnection( (BungeeCord) bungee, ch, this, handshake, forgeLogin, loginMessages );
ch.pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) ); ch.pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) );

View File

@ -15,6 +15,7 @@ public class CipherCodec extends ByteToByteCodec
private Cipher encrypt; private Cipher encrypt;
private Cipher decrypt; private Cipher decrypt;
private ByteBuf heapOut;
public CipherCodec(Cipher encrypt, Cipher decrypt) public CipherCodec(Cipher encrypt, Cipher decrypt)
{ {
@ -25,33 +26,58 @@ public class CipherCodec extends ByteToByteCodec
@Override @Override
public void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception public void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception
{ {
cipher( encrypt, in, out ); cipher( ctx, in, out, encrypt );
} }
@Override @Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception public void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception
{ {
cipher( decrypt, in, out ); cipher( ctx, in, out, decrypt );
} }
private void cipher(Cipher cipher, ByteBuf in, ByteBuf out) throws Exception @Override
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception
{ {
try super.freeInboundBuffer( ctx );
if ( heapOut != null )
{ {
heapOut.release();
heapOut = null;
}
}
@Override
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception
{
super.freeOutboundBuffer( ctx );
if ( heapOut != null )
{
heapOut.release();
heapOut = null;
}
}
private void cipher(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out, Cipher cipher) throws Exception
{
synchronized ( this )
{
if ( heapOut == null )
{
heapOut = ctx.alloc().heapBuffer();
}
int available = in.readableBytes(); int available = in.readableBytes();
int outputSize = cipher.getOutputSize( available ); int outputSize = cipher.getOutputSize( available );
int writerIndex = out.writerIndex(); if ( heapOut.capacity() < outputSize )
if ( out.capacity() + writerIndex < outputSize )
{ {
out.capacity( outputSize + writerIndex ); heapOut.capacity( outputSize );
} }
int processed = cipher.update( in.nioBuffer(), out.nioBuffer( out.writerIndex(), outputSize ) ); int processed = cipher.update( in.array(), in.arrayOffset() + in.readerIndex(), available, heapOut.array(), heapOut.arrayOffset() + heapOut.writerIndex() );
in.readerIndex( in.readerIndex() + processed ); in.readerIndex( in.readerIndex() + processed );
out.writerIndex( writerIndex + processed ); heapOut.writerIndex( heapOut.writerIndex() + processed );
} catch ( Exception ex )
{ out.writeBytes( heapOut );
ex.printStackTrace(); heapOut.discardSomeReadBytes();
throw ex;
} }
} }
} }

View File

@ -83,6 +83,10 @@ public class HandlerBoss extends ChannelInboundMessageHandlerAdapter<ByteBuf>
{ {
ProxyServer.getInstance().getLogger().log( Level.SEVERE, handler + " - encountered exception", cause ); ProxyServer.getInstance().getLogger().log( Level.SEVERE, handler + " - encountered exception", cause );
} }
if ( handler != null )
{
handler.exception( cause );
}
ctx.close(); ctx.close();
} }
} }