From c1bdbef9cfdfd1d66d12eb73af296fc253e80cd7 Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 16 Jan 2017 10:00:27 +1100 Subject: [PATCH 1/2] Give delayed close packets time to send on /end --- proxy/src/main/java/net/md_5/bungee/BungeeCord.java | 7 +++++++ .../main/java/net/md_5/bungee/netty/ChannelWrapper.java | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 159dab671a..9fdb4c76be 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -391,6 +391,13 @@ public void run() connectionLock.readLock().unlock(); } + try + { + Thread.sleep( 500 ); + } catch ( InterruptedException ex ) + { + } + getLogger().info( "Closing IO threads" ); eventLoops.shutdownGracefully(); try diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java index 0b0dd736e5..254c471775 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java @@ -75,7 +75,7 @@ public void delayedClose(final Runnable runnable) // Minecraft client can take some time to switch protocols. // Sending the wrong disconnect packet whilst a protocol switch is in progress will crash it. - // Delay 500ms to ensure that the protocol switch (if any) has definitely taken place. + // Delay 250ms to ensure that the protocol switch (if any) has definitely taken place. ch.eventLoop().schedule( new Runnable() { @@ -90,7 +90,7 @@ public void run() ChannelWrapper.this.close(); } } - }, 500, TimeUnit.MILLISECONDS ); + }, 250, TimeUnit.MILLISECONDS ); } } From 81de9d5a63a143c3267968d7fa5ec13db622d268 Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 16 Jan 2017 10:11:17 +1100 Subject: [PATCH 2/2] #2041: More robust closing code --- .../net/md_5/bungee/ServerConnection.java | 12 +----- .../java/net/md_5/bungee/UserConnection.java | 12 +----- .../bungee/connection/InitialHandler.java | 22 ++++------- .../net/md_5/bungee/netty/ChannelWrapper.java | 38 +++++++++++++------ 4 files changed, 37 insertions(+), 47 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java index 8c1260af32..b795bf9052 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -52,17 +52,7 @@ public void disconnect(BaseComponent... reason) { Preconditions.checkArgument( reason.length == 0, "Server cannot have disconnect reason" ); - if ( !ch.isClosed() ) - { - ch.getHandle().eventLoop().schedule( new Runnable() - { - @Override - public void run() - { - ch.getHandle().close(); - } - }, 100, TimeUnit.MILLISECONDS ); - } + ch.delayedClose( null ); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 866efb6dfc..d0e9ad5f8f 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -368,15 +368,7 @@ public void disconnect0(final BaseComponent... reason) getName(), BaseComponent.toLegacyText( reason ) } ); - ch.delayedClose( new Runnable() - { - - @Override - public void run() - { - unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) ); - } - } ); + ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) ); if ( server != null ) { @@ -614,7 +606,7 @@ public String getExtraDataInHandshake() public void setCompressionThreshold(int compressionThreshold) { - if ( ch.getHandle().isActive() && this.compressionThreshold == -1 && compressionThreshold >= 0 ) + if ( !ch.isClosing() && this.compressionThreshold == -1 && compressionThreshold >= 0 ) { this.compressionThreshold = compressionThreshold; unsafe.sendPacket( new SetCompression( compressionThreshold ) ); 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 d87b03c058..9852a0a0e4 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 @@ -140,8 +140,7 @@ public void handle(PluginMessage pluginMessage) throws Exception public void handle(LegacyHandshake legacyHandshake) throws Exception { this.legacy = true; - ch.getHandle().writeAndFlush( bungee.getTranslation( "outdated_client" ) ); - ch.close(); + ch.close( bungee.getTranslation( "outdated_client" ) ); } @Override @@ -492,7 +491,7 @@ public void done(LoginEvent result, Throwable error) @Override public void run() { - if ( ch.getHandle().isActive() ) + if ( !ch.isClosing() ) { UserConnection userCon = new UserConnection( bungee, ch, getName(), InitialHandler.this ); userCon.setCompressionThreshold( BungeeCord.getInstance().config.getCompressionThreshold() ); @@ -538,18 +537,13 @@ public void disconnect(String reason) @Override public void disconnect(final BaseComponent... reason) { - ch.delayedClose( new Runnable() + if ( thisState != State.STATUS && thisState != State.PING ) { - - @Override - public void run() - { - if ( thisState != State.STATUS && thisState != State.PING ) - { - unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) ); - } - } - } ); + ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) ); + } else + { + ch.close(); + } } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java index 254c471775..28a4f17604 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java @@ -2,6 +2,7 @@ import com.google.common.base.Preconditions; import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import java.util.concurrent.TimeUnit; @@ -12,6 +13,7 @@ import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.packet.Kick; public class ChannelWrapper { @@ -56,19 +58,37 @@ public void write(Object packet) } public void close() + { + close( null ); + } + + public void close(Object packet) { if ( !closed ) { closed = closing = true; - ch.flush(); - ch.close(); + + if ( packet != null && ch.isActive() ) + { + ch.writeAndFlush( packet ).addListeners( ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, ChannelFutureListener.CLOSE ); + ch.eventLoop().schedule( new Runnable() + { + @Override + public void run() + { + ch.close(); + } + }, 250, TimeUnit.MILLISECONDS ); + } else + { + ch.flush(); + ch.close(); + } } } - public void delayedClose(final Runnable runnable) + public void delayedClose(final Kick kick) { - Preconditions.checkArgument( runnable != null, "runnable" ); - if ( !closing ) { closing = true; @@ -82,13 +102,7 @@ public void delayedClose(final Runnable runnable) @Override public void run() { - try - { - runnable.run(); - } finally - { - ChannelWrapper.this.close(); - } + close( kick ); } }, 250, TimeUnit.MILLISECONDS ); }