Skip to content

Commit

Permalink
feat: ignore connection reset exception + log as warning CloseImmedia…
Browse files Browse the repository at this point in the history
…tely and RateLimit errors
  • Loading branch information
vincent4vx committed Jul 13, 2024
1 parent a56ec07 commit a88cf9a
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/main/java/fr/quatrevieux/araknemu/game/GameModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ public void configure(ContainerConfigurator configurator) {
container -> new SessionConfigurator<>(GameSession::new)
.add(new BanIpCheck<>(container.get(BanIpService.class)))
.add(new RateLimiter.Configurator<>(container.get(GameConfiguration.class).packetRateLimit()))
.add(new SessionLogger.Configurator<>(container.get(Logger.class)))
.add(new GameExceptionConfigurator(container.get(Logger.class)))
.add(new SessionLogger.Configurator<>(container.get(Logger.class)))
.add(new GamePacketConfigurator(
container.get(Dispatcher.class),
container.get(PacketParser.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public void run() {
executorLock.lock();

if (!alive) {
logger.warn("Cannot run task " + action.getClass().toString() + " on dead fight");
logger.warn("Cannot run task " + action.toString() + " on dead fight");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.util.NullnessUtil;

import java.io.IOException;

/**
* Configure base exception for a game session
*/
Expand Down Expand Up @@ -57,7 +59,7 @@ public void configure(ConfigurableSession inner, GameSession session) {
});

inner.addExceptionHandler(CloseImmediately.class, (cause, packet) -> {
logger.error(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", context(session, packet), cause.getMessage() == null ? cause.toString() : cause.getMessage());
logger.warn(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", context(session, packet), cause.getMessage() == null ? cause.toString() : cause.getMessage());

return true;
});
Expand All @@ -69,11 +71,23 @@ public void configure(ConfigurableSession inner, GameSession session) {
});

inner.addExceptionHandler(RateLimitException.class, cause -> {
logger.error(MarkerManager.getMarker("RATE_LIMIT"), "[{}] RateLimit : close session", session);
logger.warn(MarkerManager.getMarker("RATE_LIMIT"), "[{}] RateLimit : close session", session);
session.close();

return true;
});

inner.addExceptionHandler(IOException.class, cause -> {
// Ignore connection reset errors
if (
!"Connection reset by peer".equals(cause.getMessage())
&& !"Connexion ré-initialisée par le correspondant".equals(cause.getMessage())
) {
logger.error("[{}] IOException : {}", session, cause.getMessage() == null ? cause.toString() : cause.getMessage());
}

return false;
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.MarkerManager;

import java.io.IOException;

/**
* Configure session for realm
*/
Expand Down Expand Up @@ -63,6 +65,18 @@ public void configure(ConfigurableSession inner, RealmSession session) {
return true;
});

inner.addExceptionHandler(IOException.class, cause -> {
// Ignore connection reset errors
if (
!"Connection reset by peer".equals(cause.getMessage())
&& !"Connexion ré-initialisée par le correspondant".equals(cause.getMessage())
) {
logger.error("[{}] IOException : {}", session, cause.getMessage() == null ? cause.toString() : cause.getMessage());
}

return false;
});

inner.addReceiveMiddleware(new RealmPacketParserMiddleware(loginPackets, baseParser));
inner.addReceiveMiddleware((packet, next) -> dispatcher.dispatch(session, (Packet) packet));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ public void configure(ContainerConfigurator configurator) {
container -> new SessionConfigurator<>(RealmSession::new)
.add(new BanIpCheck<>(container.get(BanIpService.class)))
.add(new RateLimiter.Configurator<>(container.get(RealmConfiguration.class).packetRateLimit()))
.add(new SessionLogger.Configurator<>(container.get(Logger.class)))
.add(new RealmSessionConfigurator(
container.get(Dispatcher.class),
new PacketParser[] {DofusVersion.parser(), Credentials.parser()},
container.get(PacketParser.class),
container.get(Logger.class)
))
.add(new SessionLogger.Configurator<>(container.get(Logger.class)))
);

configurator.factory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class GameExceptionConfiguratorTest extends GameBaseCase {
private GameExceptionConfigurator configurator;
Expand All @@ -56,15 +59,15 @@ void exceptionCaughtCloseSession() {
gameSession.exception(new CloseImmediately("my error"));

assertFalse(session.isLogged());
Mockito.verify(logger).error(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", gameSession, "my error");
Mockito.verify(logger).warn(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", gameSession, "my error");
}

@Test
void exceptionCaughtCloseSessionWithPacket() {
gameSession.exception(new CloseImmediately("my error"), "my packet");

assertFalse(session.isLogged());
Mockito.verify(logger).error(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", gameSession + "; packet=my packet", "my error");
Mockito.verify(logger).warn(MarkerManager.getMarker("CLOSE_IMMEDIATELY"), "[{}] Session closed : {}", gameSession + "; packet=my packet", "my error");
}

@Test
Expand Down Expand Up @@ -103,6 +106,23 @@ void exceptionCaughtRateLimit() {
gameSession.exception(new RateLimitException());

assertFalse(session.isAlive());
Mockito.verify(logger).error(MarkerManager.getMarker("RATE_LIMIT"), "[{}] RateLimit : close session", gameSession);
Mockito.verify(logger).warn(MarkerManager.getMarker("RATE_LIMIT"), "[{}] RateLimit : close session", gameSession);
}

@Test
void exceptionShouldIgnoreConnectionReset() {
gameSession.exception(new IOException("Connection reset by peer"));
gameSession.exception(new IOException("Connexion ré-initialisée par le correspondant"));

assertTrue(session.isAlive());
Mockito.verifyNoInteractions(logger);
}

@Test
void exceptionShouldLogIOException() {
gameSession.exception(new IOException("My error"));

assertTrue(session.isAlive());
Mockito.verify(logger).error("[{}] IOException : {}", gameSession, "My error");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class RealmSessionConfiguratorTest extends RealmBaseCase {
private RealmSessionConfigurator configurator;
Expand Down Expand Up @@ -109,4 +112,31 @@ void exceptionCaughtRateLimit() {
assertFalse(session.isAlive());
Mockito.verify(logger).error(MarkerManager.getMarker("RATE_LIMIT"), "[{}] RateLimit : close session", realmSession);
}

@Test
void exceptionShouldIgnoreConnectionReset() {
ConfigurableSession session = new ConfigurableSession(channel);
RealmSession realmSession = new RealmSession(session);

configurator.configure(session, realmSession);

realmSession.exception(new IOException("Connection reset by peer"));
realmSession.exception(new IOException("Connexion ré-initialisée par le correspondant"));

assertFalse(session.isAlive());
Mockito.verifyNoInteractions(logger);
}

@Test
void exceptionShouldLogIOException() {
ConfigurableSession session = new ConfigurableSession(channel);
RealmSession realmSession = new RealmSession(session);

configurator.configure(session, realmSession);

realmSession.exception(new IOException("My error"));

assertFalse(session.isAlive());
Mockito.verify(logger).error("[{}] IOException : {}", realmSession, "My error");
}
}

0 comments on commit a88cf9a

Please sign in to comment.