Skip to content

Commit

Permalink
improve channel exception handling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
hex-agon committed Aug 5, 2023
1 parent d53943c commit 8e900d9
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package work.fking.pangya.game.net

import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.unix.Errors
import org.slf4j.LoggerFactory
import work.fking.pangya.game.GameServer
import work.fking.pangya.game.player.Player
Expand All @@ -26,7 +27,12 @@ class ClientPacketDispatcher(
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
LOGGER.error("Exception caught in dispatcher", cause)
ctx.disconnect()
when (cause) {
is Errors.NativeIoException -> ctx.disconnect()
else -> {
LOGGER.error("Exception caught in dispatcher", cause)
ctx.disconnect()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package work.fking.pangya.game.net
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.unix.Errors
import io.netty.handler.codec.TooLongFrameException
import io.netty.handler.timeout.ReadTimeoutException
import org.slf4j.LoggerFactory
import work.fking.pangya.game.GameServer
import work.fking.pangya.game.task.HandoverTask
Expand Down Expand Up @@ -38,4 +41,25 @@ class HandoverHandler(
gameServer.runTask(HandoverTask(gameServer, ctx.channel(), cryptKey, sessionKey))
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
when (cause) {
is Errors.NativeIoException -> ctx.disconnect()
is TooLongFrameException -> ctx.disconnect()
is PangCrypt.PangCryptException -> ctx.disconnect()
is IndexOutOfBoundsException -> {
LOGGER.warn("{} - {}", ctx.channel().remoteAddress(), cause.message)
ctx.disconnect()
}

is ReadTimeoutException -> {
LOGGER.debug("{} read timeout", ctx.channel().remoteAddress())
ctx.disconnect()
}

else -> {
LOGGER.warn("Exception caught in the pipeline for client ${ctx.channel().remoteAddress()}", cause)
ctx.disconnect()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInboundHandlerAdapter
import io.netty.handler.codec.LengthFieldBasedFrameDecoder
import io.netty.handler.timeout.ReadTimeoutHandler
import org.apache.logging.log4j.LogManager
import work.fking.pangya.game.GameServer
import work.fking.pangya.game.Rand
import work.fking.pangya.game.packet.outbound.HelloPacket
import work.fking.pangya.networking.crypt.PangCrypt
import work.fking.pangya.networking.protocol.ProtocolEncoder
import java.nio.ByteOrder
import java.util.concurrent.TimeUnit

private val LOGGER = LogManager.getLogger(HelloHandler::class.java)

Expand All @@ -28,6 +30,7 @@ class HelloHandler(
val pipeline = ctx.pipeline()
pipeline.remove(this)
pipeline.replace("encoder", "protocolEncoder", ProtocolEncoder(cryptKey))
pipeline.addLast("timeoutHandler", ReadTimeoutHandler(10, TimeUnit.SECONDS))
pipeline.addLast("framer", LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 2500, 1, 2, 1, 0, true))
pipeline.addLast("handoverHandler", HandoverHandler(gameServer, cryptKey))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class HandoverTask(
// modify the pipeline
val pipeline = channel.pipeline()
pipeline.remove("handoverHandler")
pipeline.remove("timeoutHandler")
pipeline.addLast("decoder", ProtocolDecoder(PROTOCOL, cryptKey))
pipeline.addLast("packetDispatcher", ClientPacketDispatcher(gameServer, player, PROTOCOL.handlers()))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package work.fking.pangya.login.net

import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.unix.Errors.NativeIoException
import org.slf4j.LoggerFactory
import work.fking.pangya.login.LoginServer
import work.fking.pangya.login.Player
Expand All @@ -26,7 +27,12 @@ class ClientPacketDispatcher(
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
LOGGER.error("Exception caught in dispatcher", cause)
ctx.disconnect()
when (cause) {
is NativeIoException -> ctx.disconnect()
else -> {
LOGGER.error("Exception caught in dispatcher", cause)
ctx.disconnect()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInboundHandlerAdapter
import io.netty.handler.codec.LengthFieldBasedFrameDecoder
import io.netty.handler.timeout.ReadTimeoutHandler
import org.slf4j.LoggerFactory
import work.fking.pangya.login.LoginServer
import work.fking.pangya.login.Rand
import work.fking.pangya.login.packet.outbound.HelloPacket
import work.fking.pangya.networking.crypt.PangCrypt
import work.fking.pangya.networking.protocol.ProtocolEncoder
import java.nio.ByteOrder
import java.util.concurrent.TimeUnit

private val LOGGER = LoggerFactory.getLogger(HelloHandler::class.java)

Expand All @@ -28,6 +30,7 @@ class HelloHandler(
val pipeline = channel.pipeline()
pipeline.remove(this)
pipeline.replace("encoder", "protocolEncoder", ProtocolEncoder(cryptKey))
pipeline.addLast("timeoutHandler", ReadTimeoutHandler(10, TimeUnit.SECONDS))
pipeline.addLast("framer", LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 250, 1, 2, 1, 0, true))
pipeline.addLast("loginHandler", LoginHandler(loginServer, cryptKey))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ package work.fking.pangya.login.net.pipe
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.unix.Errors.NativeIoException
import io.netty.handler.codec.TooLongFrameException
import io.netty.handler.timeout.ReadTimeoutException
import org.slf4j.LoggerFactory
import work.fking.pangya.login.LoginServer
import work.fking.pangya.login.packet.outbound.LoginReplies
import work.fking.pangya.login.task.LoginTask
import work.fking.pangya.networking.crypt.PangCrypt
import work.fking.pangya.networking.crypt.PangCrypt.PangCryptException
import work.fking.pangya.networking.protocol.readPString
import work.fking.pangya.networking.protocol.readPStringCharArray

Expand All @@ -24,6 +28,8 @@ class LoginHandler(
override fun channelRead0(ctx: ChannelHandlerContext, buffer: ByteBuf) {
PangCrypt.decrypt(buffer, cryptKey)

if (buffer.readableBytes() < 2) return

when (val packetId = buffer.readShortLE().toInt()) {
LOGIN_PACKET_ID -> handleLogin(ctx, buffer)
RECONNECT_PACKET_ID -> handleReconnect(ctx, buffer)
Expand All @@ -50,4 +56,26 @@ class LoginHandler(
LOGGER.debug("Rejecting reconnect for username={} uid={} loginKey={}", username, playerUid, loginKey)
ctx.writeAndFlush(LoginReplies.error(LoginReplies.Error.INCORRECT_USERNAME_PASSWORD))
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
when (cause) {
is NativeIoException -> ctx.disconnect()
is TooLongFrameException -> ctx.disconnect()
is PangCryptException -> ctx.disconnect()
is IndexOutOfBoundsException -> {
LOGGER.warn("{} - {}", ctx.channel().remoteAddress(), cause.message)
ctx.disconnect()
}

is ReadTimeoutException -> {
LOGGER.debug("{} read timeout", ctx.channel().remoteAddress())
ctx.disconnect()
}

else -> {
LOGGER.warn("Exception caught in the pipeline for client ${ctx.channel().remoteAddress()}", cause)
ctx.disconnect()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LoginTask(

val pipeline = channel.pipeline()
pipeline.remove("loginHandler")
pipeline.remove("timeoutHandler")
pipeline.addLast("decoder", ProtocolDecoder(PROTOCOL, cryptKey))
pipeline.addLast("packetDispatcher", ClientPacketDispatcher(loginServer, player, PROTOCOL.handlers()))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ object PangCrypt {
private const val CRYPT_SALT_MAX = 0xFF
private const val CRYPT_STRIDE = 4

class PangCryptException(message: String) : RuntimeException(message) {
}
class PangCryptException(message: String) : RuntimeException(message)

@JvmStatic
fun decrypt(buffer: ByteBuf, key: Int) {
Expand Down

0 comments on commit 8e900d9

Please sign in to comment.