diff --git a/jvb/src/main/kotlin/org/jitsi/videobridge/health/JvbHealthChecker.kt b/jvb/src/main/kotlin/org/jitsi/videobridge/health/JvbHealthChecker.kt index a27e832787..4ac422933a 100644 --- a/jvb/src/main/kotlin/org/jitsi/videobridge/health/JvbHealthChecker.kt +++ b/jvb/src/main/kotlin/org/jitsi/videobridge/health/JvbHealthChecker.kt @@ -22,6 +22,7 @@ import org.jitsi.health.HealthChecker import org.jitsi.health.Result import org.jitsi.videobridge.health.config.HealthConfig.Companion.config import org.jitsi.videobridge.ice.Harvesters +import java.net.InetAddress class JvbHealthChecker : HealthCheckService { private val healthChecker = HealthChecker( @@ -36,7 +37,10 @@ class JvbHealthChecker : HealthCheckService { fun stop() = healthChecker.stop() private fun check(): Result { - if (MappingCandidateHarvesters.stunDiscoveryFailed) { + if (config.requireValidAddress && !hasValidAddress()) { + return Result(success = false, message = "No valid IP addresses available for harvesting.") + } + if (config.requireStun && MappingCandidateHarvesters.stunDiscoveryFailed) { return Result(success = false, message = "Address discovery through STUN failed") } if (!Harvesters.isHealthy()) { @@ -48,6 +52,20 @@ class JvbHealthChecker : HealthCheckService { return Result(success = true) } + private fun InetAddress.isValid(): Boolean { + return !this.isSiteLocalAddress && !this.isLinkLocalAddress && !this.isLoopbackAddress + } + + private fun hasValidAddress(): Boolean { + if (Harvesters.singlePortHarvesters.any { it.localAddress.address.isValid() }) { + return true + } + if (MappingCandidateHarvesters.getHarvesters().any { it.mask?.address?.isValid() == true }) { + return true + } + return false + } + override val result: Result get() = healthChecker.result } diff --git a/jvb/src/main/kotlin/org/jitsi/videobridge/health/config/HealthConfig.kt b/jvb/src/main/kotlin/org/jitsi/videobridge/health/config/HealthConfig.kt index 4564000274..db2a93576a 100644 --- a/jvb/src/main/kotlin/org/jitsi/videobridge/health/config/HealthConfig.kt +++ b/jvb/src/main/kotlin/org/jitsi/videobridge/health/config/HealthConfig.kt @@ -41,6 +41,14 @@ class HealthConfig private constructor() { "videobridge.health.sticky-failures".from(JitsiConfig.newConfig) } + val requireStun: Boolean by config { + "videobridge.health.require-stun".from(JitsiConfig.newConfig) + } + + val requireValidAddress: Boolean by config { + "videobridge.health.require-valid-address".from(JitsiConfig.newConfig) + } + companion object { @JvmField val config = HealthConfig() diff --git a/jvb/src/main/resources/reference.conf b/jvb/src/main/resources/reference.conf index 16dab152ca..5904c1f62f 100644 --- a/jvb/src/main/resources/reference.conf +++ b/jvb/src/main/resources/reference.conf @@ -21,6 +21,14 @@ videobridge { # (i.e. once the bridge becomes unhealthy, it will never # go back to a healthy state) sticky-failures = false + + # If enabled, health checks fail when there are no valid addresses available for ICE. Here "valid" means not + # site local, link local or loopback. + require-valid-address = true + + # If enabled, health checks will fail when a STUN mapping harvester is configured, but fails to get a mapping (even + # if there is a valid address available through other mappings or locally). + require-stun = false } ep-connection-status { # How long we'll wait for an endpoint to *start* sending