Skip to content

Commit

Permalink
Use JitsiXmppStringprep, update smack (#2127)
Browse files Browse the repository at this point in the history
* ref: Do not register xmpp extensions for RAW UDP, we only support ICE.

* ref: Remove unused code.

* feat: Use JitsiXmppStringprep

* Initialize Smack using the default configuration from jitsi-xmpp-extensions.
* Move registering extension providers out of Videobridge.java

* doc: Fix javadocs.

* ref: Move queue stats out of Videobridge.java.

* ref: Move ulimit check out of Videobridge.java.

* ref: Move videobridgeExpireThread out of Videobridge.java.

* squash: Remove obsolete TODO.

* chore: Update jitsi-xmpp-extensions (JitsiXmppStringprep).
  • Loading branch information
bgrozev authored Apr 29, 2024
1 parent 748a626 commit b623d6a
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 172 deletions.
2 changes: 1 addition & 1 deletion jvb/src/main/java/org/jitsi/videobridge/Conference.java
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ private double getMaxReceiverRtt(String excludedEndpointId)
* respective <tt>Channel</tt>s. Releases the resources acquired by this
* instance throughout its life time and prepares it to be garbage
* collected.
*
* <p/>
* NOTE: this should _only_ be called by the Conference "manager" (in this
* case, Videobridge). If you need to expire a Conference from elsewhere, use
* {@link Videobridge#expireConference(Conference)}
Expand Down
167 changes: 3 additions & 164 deletions jvb/src/main/java/org/jitsi/videobridge/Videobridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,20 @@
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.*;
import org.jitsi.health.Result;
import org.jitsi.nlj.*;
import org.jitsi.shutdown.*;
import org.jitsi.utils.*;
import org.jitsi.utils.logging2.*;
import org.jitsi.utils.queue.*;
import org.jitsi.utils.version.*;
import org.jitsi.videobridge.health.*;
import org.jitsi.videobridge.load_management.*;
import org.jitsi.videobridge.metrics.*;
import org.jitsi.videobridge.relay.*;
import org.jitsi.videobridge.shutdown.*;
import org.jitsi.videobridge.stats.*;
import org.jitsi.videobridge.util.*;
import org.jitsi.videobridge.xmpp.*;
import org.jitsi.xmpp.extensions.*;
import org.jitsi.xmpp.extensions.colibri.*;
import org.jitsi.xmpp.extensions.colibri2.*;
import org.jitsi.xmpp.extensions.health.*;
import org.jitsi.xmpp.extensions.jingle.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.json.simple.*;
import org.jxmpp.jid.*;
import org.jxmpp.jid.impl.*;
Expand Down Expand Up @@ -78,7 +71,7 @@ public class Videobridge

/**
* The <tt>Conference</tt>s of this <tt>Videobridge</tt> mapped by their local IDs.
*
* <p/>
* TODO: The only remaining uses of this ID are for the HTTP debug interface and the colibri WebSocket conference
* identifier. This should be replaced with meetingId (while making sure jvb-rtcstats-push doesn't break).
*/
Expand All @@ -94,26 +87,19 @@ public class Videobridge

/**
* The clock to use, pluggable for testing purposes.
*
* <p/>
* Note that currently most code uses the system clock directly.
*/
@NotNull
private final Clock clock;

/**
* Thread that checks expiration for conferences, contents, channels and
* execute expire procedure for any of them.
*/
private final VideobridgeExpireThread videobridgeExpireThread;

/**
* The {@link JvbLoadManager} instance used for this bridge.
*/
@NotNull
private final JvbLoadManager<?> jvbLoadManager;

@NotNull private final Version version;
@Nullable private final String releaseId;

@NotNull private final ShutdownManager shutdownManager;

Expand All @@ -138,18 +124,15 @@ public Videobridge(
@Nullable XmppConnection xmppConnection,
@NotNull ShutdownServiceImpl shutdownService,
@NotNull Version version,
@Nullable String releaseId,
@NotNull Clock clock)
{
this.clock = clock;
videobridgeExpireThread = new VideobridgeExpireThread(this);
jvbLoadManager = JvbLoadManager.create(this);
if (xmppConnection != null)
{
xmppConnection.setEventHandler(new XmppConnectionEventHandler());
}
this.version = version;
this.releaseId = releaseId;
this.shutdownManager = new ShutdownManager(shutdownService, logger);
jvbHealthChecker.start();
}
Expand Down Expand Up @@ -495,75 +478,11 @@ public ShutdownState getShutdownState()
return shutdownManager.getState();
}

/**
* Starts this {@link Videobridge}.
*
* NOTE: we have to make this public so Jicofo can call it from its tests.
*/
public void start()
{
UlimitCheck.printUlimits();

videobridgeExpireThread.start();

// <force-shutdown>
ForcefulShutdownIqProvider.registerIQProvider();

// <graceful-shutdown>
GracefulShutdownIqProvider.registerIQProvider();

// <stats>
new ColibriStatsIqProvider(); // registers itself with Smack

// ICE-UDP <transport>
ProviderManager.addExtensionProvider(
IceUdpTransportPacketExtension.ELEMENT,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<>(IceUdpTransportPacketExtension.class));

// RAW-UDP <candidate xmlns=urn:xmpp:jingle:transports:raw-udp:1>
DefaultPacketExtensionProvider<UdpCandidatePacketExtension> udpCandidatePacketExtensionProvider
= new DefaultPacketExtensionProvider<>(UdpCandidatePacketExtension.class);
ProviderManager.addExtensionProvider(
UdpCandidatePacketExtension.ELEMENT,
UdpCandidatePacketExtension.NAMESPACE,
udpCandidatePacketExtensionProvider);

// ICE-UDP <candidate xmlns=urn:xmpp:jingle:transports:ice-udp:1">
DefaultPacketExtensionProvider<IceCandidatePacketExtension> iceCandidatePacketExtensionProvider
= new DefaultPacketExtensionProvider<>(IceCandidatePacketExtension.class);
ProviderManager.addExtensionProvider(
IceCandidatePacketExtension.ELEMENT,
IceCandidatePacketExtension.NAMESPACE,
iceCandidatePacketExtensionProvider);

// ICE <rtcp-mux/>
ProviderManager.addExtensionProvider(
IceRtcpmuxPacketExtension.ELEMENT,
IceRtcpmuxPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<>(IceRtcpmuxPacketExtension.class));

// DTLS-SRTP <fingerprint>
ProviderManager.addExtensionProvider(
DtlsFingerprintPacketExtension.ELEMENT,
DtlsFingerprintPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<>(DtlsFingerprintPacketExtension.class));

// Health-check
HealthCheckIQProvider.registerIQProvider();

// Colibri2
IqProviderUtils.registerProviders();
}

/**
* Stops this {@link Videobridge}.
*
* NOTE: we have to make this public so Jicofo can call it from its tests.
*/
public void stop()
void stop()
{
videobridgeExpireThread.stop();
jvbLoadManager.stop();
}

Expand Down Expand Up @@ -622,83 +541,12 @@ public OrderedJsonObject getDebugState(String conferenceId, String endpointId, b
return debugState;
}

/**
* Gets statistics for the different {@code PacketQueue}s that this bridge
* uses.
* TODO: is there a better place for this?
*/
@SuppressWarnings("unchecked")
public JSONObject getQueueStats()
{
JSONObject queueStats = new JSONObject();

queueStats.put(
"srtp_send_queue",
getJsonFromQueueStatisticsAndErrorHandler(Endpoint.queueErrorCounter,
"Endpoint-outgoing-packet-queue"));
queueStats.put(
"relay_srtp_send_queue",
getJsonFromQueueStatisticsAndErrorHandler(Relay.queueErrorCounter,
"Relay-outgoing-packet-queue"));
queueStats.put(
"relay_endpoint_sender_srtp_send_queue",
getJsonFromQueueStatisticsAndErrorHandler(RelayEndpointSender.queueErrorCounter,
"RelayEndpointSender-outgoing-packet-queue"));
queueStats.put(
"rtp_receiver_queue",
getJsonFromQueueStatisticsAndErrorHandler(RtpReceiverImpl.Companion.getQueueErrorCounter(),
"rtp-receiver-incoming-packet-queue"));
queueStats.put(
"rtp_sender_queue",
getJsonFromQueueStatisticsAndErrorHandler(RtpSenderImpl.Companion.getQueueErrorCounter(),
"rtp-sender-incoming-packet-queue"));
queueStats.put(
"colibri_queue",
QueueStatistics.Companion.getStatistics().get("colibri-queue")
);

queueStats.put(
AbstractEndpointMessageTransport.INCOMING_MESSAGE_QUEUE_ID,
getJsonFromQueueStatisticsAndErrorHandler(
null,
AbstractEndpointMessageTransport.INCOMING_MESSAGE_QUEUE_ID));

return queueStats;
}

private OrderedJsonObject getJsonFromQueueStatisticsAndErrorHandler(
CountingErrorHandler countingErrorHandler,
String queueName)
{
OrderedJsonObject json = (OrderedJsonObject)QueueStatistics.Companion.getStatistics().get(queueName);
if (countingErrorHandler != null)
{
if (json == null)
{
json = new OrderedJsonObject();
json.put("dropped_packets", countingErrorHandler.getNumPacketsDropped());
}
json.put("exceptions", countingErrorHandler.getNumExceptions());
}

return json;
}

@NotNull
public Version getVersion()
{
return version;
}

/**
* Get the release ID of this videobridge.
* @return The release ID. Returns null if not in use.
*/
public @Nullable String getReleaseId()
{
return releaseId;
}

private class XmppConnectionEventHandler implements XmppConnection.EventHandler
{
@Override
Expand Down Expand Up @@ -741,15 +589,6 @@ public IQ healthCheckIqReceived(@NotNull HealthCheckIQ iq)
}
}

/**
* Basic statistics/metrics about the videobridge like cumulative/total
* number of channels created, cumulative/total number of channels failed,
* etc.
*/
public static class Statistics
{
}

private static class ConferenceNotFoundException extends Exception {}
private static class ConferenceAlreadyExistsException extends Exception {}
private static class InGracefulShutdownException extends Exception {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ public String getJvbFeatureStats(@PathParam("feature") DebugFeatures feature)
return ByteBufferPool.getStatsJson().toJSONString();
}
case QUEUE_STATS: {
return videobridge.getQueueStats().toJSONString();
return QueueStats.getQueueStats().toJSONString();
}
case TRANSIT_STATS: {
return PacketTransitStats.getStatsJson().toJSONString();
Expand Down
10 changes: 6 additions & 4 deletions jvb/src/main/kotlin/org/jitsi/videobridge/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ import org.jitsi.videobridge.metrics.VideobridgePeriodicMetrics
import org.jitsi.videobridge.rest.root.Application
import org.jitsi.videobridge.stats.MucPublisher
import org.jitsi.videobridge.util.TaskPools
import org.jitsi.videobridge.util.UlimitCheck
import org.jitsi.videobridge.version.JvbVersionService
import org.jitsi.videobridge.websocket.ColibriWebSocketService
import org.jitsi.videobridge.xmpp.XmppConnection
import org.jitsi.videobridge.xmpp.config.XmppClientConnectionConfig
import org.jxmpp.stringprep.XmppStringPrepUtil
import java.time.Clock
import kotlin.concurrent.thread
import kotlin.system.exitProcess
Expand Down Expand Up @@ -75,12 +75,13 @@ fun main() {

logger.info("Starting jitsi-videobridge version ${JvbVersionService.instance.currentVersion}")

UlimitCheck.printUlimits()
startIce4j()

// Initialize, binding on the main ICE port.
Harvesters.init()

XmppStringPrepUtil.setMaxCacheSizes(XmppClientConnectionConfig.config.jidCacheSize)
org.jitsi.videobridge.xmpp.Smack.initialize()
PacketQueue.setEnableStatisticsDefault(true)

// Trigger an exception early in case the DTLS cipher suites are misconfigured
Expand All @@ -99,9 +100,9 @@ fun main() {
xmppConnection,
shutdownService,
JvbVersionService.instance.currentVersion,
VersionConfig.config.release,
Clock.systemUTC()
).apply { start() }
)
val videobridgeExpireThread = VideobridgeExpireThread(videobridge)
Metrics.metricsUpdater.addUpdateTask {
VideobridgePeriodicMetrics.update(videobridge)
}
Expand Down Expand Up @@ -169,6 +170,7 @@ fun main() {
} catch (t: Throwable) {
logger.error("Error shutting down http servers", t)
}
videobridgeExpireThread.stop()
videobridge.stop()
stopIce4j()
Metrics.stop()
Expand Down
Loading

0 comments on commit b623d6a

Please sign in to comment.