Skip to content

Commit

Permalink
Adds a periodic check that triggers a disconnect if a half-open conne…
Browse files Browse the repository at this point in the history
…ction is detected. (#160)
  • Loading branch information
gpolitis committed Jan 17, 2022
1 parent d43f3d3 commit 45aeff4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
55 changes: 53 additions & 2 deletions jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java
Expand Up @@ -48,11 +48,15 @@
*/
public class MucClient
{
private static final int DEFAULT_PING_INTERVAL_SECONDS = 30;

private static final long HALF_OPEN_CONNECTION_CHECK_PERIOD_MS = 2 * 1000 * DEFAULT_PING_INTERVAL_SECONDS;

static
{
XMPPTCPConnection.setUseStreamManagementDefault(false);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(false);
PingManager.setDefaultPingInterval(30);
PingManager.setDefaultPingInterval(DEFAULT_PING_INTERVAL_SECONDS);
}

/**
Expand Down Expand Up @@ -795,7 +799,7 @@ private void removePresenceExtension(String elementName, String namespace)
{
return;
}

if (lastPresenceSent.removeExtension(elementName, namespace) != null)
{
updatedPresence = lastPresenceSent.build();
Expand Down Expand Up @@ -853,4 +857,51 @@ public void pingFailed()
}
}
}

private final PeriodicRunnable halfOpenConnectionPeriodicCheck = new HalfOpenConnectionPeriodicCheck();

/**
* @return the {@link PeriodicRunnable} that checks the XMPP connection state and triggers a disconnect if a
* half-open connection is detected.
*/
public PeriodicRunnable getHalfOpenConnectionPeriodicCheck()
{
return halfOpenConnectionPeriodicCheck;
}

/**
* Periodically checks the connection state and triggers a disconnect if a half-open connection is detected.
*/
class HalfOpenConnectionPeriodicCheck
extends PeriodicRunnable
{
public HalfOpenConnectionPeriodicCheck()
{
super(HALF_OPEN_CONNECTION_CHECK_PERIOD_MS);
}

/**
* Triggers a disconnect if a half-open connection is detected.
*/
@Override
public void run()
{
super.run();

AbstractXMPPConnection con = xmppConnection;
if (con != null && con.isConnected() && con.isAuthenticated())
{
long lastStanzaReceivedMs = con.getLastStanzaReceived();
if (lastStanzaReceivedMs > 0)
{
long nowMs = System.currentTimeMillis();
if (nowMs - lastStanzaReceivedMs > HALF_OPEN_CONNECTION_CHECK_PERIOD_MS)
{
logger.warn("Half-open XMPP connection detected, will trigger a disconnect.");
con.disconnect();
}
}
}
}
}
}
Expand Up @@ -17,6 +17,7 @@
package org.jitsi.xmpp.mucclient;

import org.jitsi.service.configuration.*;
import org.jitsi.utils.concurrent.*;
import org.jitsi.utils.logging2.*;
import org.jitsi.utils.logging2.Logger;
import org.jivesoftware.smack.*;
Expand Down Expand Up @@ -79,6 +80,11 @@ public class MucClientManager
*/
private final Object syncRoot = new Object();

/**
* The {@link RecurringRunnableExecutor} to be utilized by the {@link MucClientManager} class and its instances.
*/
private final RecurringRunnableExecutor recurringRunnableExecutor = new RecurringRunnableExecutor();

/**
* Initializes a new {@link MucClientManager} instance.
*
Expand Down Expand Up @@ -126,6 +132,7 @@ public boolean addMucClient(MucClientConfiguration config)

mucClient = new MucClient(config, MucClientManager.this);
mucClients.put(config.getId(), mucClient);
recurringRunnableExecutor.registerRecurringRunnable(mucClient.getHalfOpenConnectionPeriodicCheck());
}

mucClient.start();
Expand Down Expand Up @@ -325,7 +332,8 @@ public boolean removeMucClient(String id)
logger.info("Can not find MucClient to remove.");
return false;
}
mucClient.stop();
recurringRunnableExecutor.deRegisterRecurringRunnable(mucClient.getHalfOpenConnectionPeriodicCheck());
mucClient.stop();
return true;
}

Expand Down

0 comments on commit 45aeff4

Please sign in to comment.