From ac2c96c2eaa3abf054d920120e0f96a8db372356 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 12 Mar 2013 17:53:18 +1100 Subject: [PATCH] This test WITHOUT encryption reveals something is majorly wrong with our packet decoding causing random and frequent disconnects. --- .../bungee/connection/InitialHandler.java | 11 +++- .../net/md_5/bungee/netty/CipherCodec.java | 52 ++++++++++++++----- .../net/md_5/bungee/netty/HandlerBoss.java | 4 ++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 08eae4354..9a7fc199c 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -73,6 +73,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection this.ch = channel; } + @Override + public void exception(Throwable t) throws Exception + { + disconnect( ChatColor.RED + Util.exception( t ) ); + } + @Override 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" ); this.handshake = handshake; ch.write( forgeMods ); - ch.write( request = EncryptionUtil.encryptRequest() ); + handle( (PacketCDClientStatus) null ); + //ch.write( request = EncryptionUtil.encryptRequest() ); thisState = State.ENCRYPT; } @@ -195,7 +202,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection @Override 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 ); ch.pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) ); diff --git a/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java b/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java index 7e7756fc8..76ad65a70 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java @@ -15,6 +15,7 @@ public class CipherCodec extends ByteToByteCodec private Cipher encrypt; private Cipher decrypt; + private ByteBuf heapOut; public CipherCodec(Cipher encrypt, Cipher decrypt) { @@ -25,33 +26,58 @@ public class CipherCodec extends ByteToByteCodec @Override public void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception { - cipher( encrypt, in, out ); + cipher( ctx, in, out, encrypt ); } @Override 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 outputSize = cipher.getOutputSize( available ); - int writerIndex = out.writerIndex(); - if ( out.capacity() + writerIndex < outputSize ) + if ( heapOut.capacity() < 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 ); - out.writerIndex( writerIndex + processed ); - } catch ( Exception ex ) - { - ex.printStackTrace(); - throw ex; + heapOut.writerIndex( heapOut.writerIndex() + processed ); + + out.writeBytes( heapOut ); + heapOut.discardSomeReadBytes(); } } } diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java index 01c031cd4..4e91b3960 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java @@ -83,6 +83,10 @@ public class HandlerBoss extends ChannelInboundMessageHandlerAdapter { ProxyServer.getInstance().getLogger().log( Level.SEVERE, handler + " - encountered exception", cause ); } + if ( handler != null ) + { + handler.exception( cause ); + } ctx.close(); } }