Skip to content

Commit

Permalink
Add new option to configure ICE nomination mode, if libnice is recent…
Browse files Browse the repository at this point in the history
… enough (meetecho#2541)

* Add new option to configure ICE nomination mode, if libnice is recent enough
* Added support for libnice keepalive-conncheck property
  • Loading branch information
lminiero committed Feb 12, 2021
1 parent af8cc6e commit ad54495
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 2 deletions.
12 changes: 11 additions & 1 deletion conf/janus.jcfg.sample.in
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,15 @@ media: {
# configured to do full-trickle (Janus also trickles its candidates to
# users) rather than the default half-trickle (Janus supports trickle
# candidates from users, but sends its own within the SDP), and whether
# it should work in ICE-Lite mode (by default it doesn't). Finally,
# it should work in ICE-Lite mode (by default it doesn't). If libnice is
# at least 0.1.15, you can choose which ICE nomination mode to use: valid
# values are "regular" and "aggressive" (the default depends on the libnice
# version itself; if we can set it, we set regular nomination). You can
# also configure whether to use connectivity checks as keep-alives, which
# might help detecting when a peer is no longer available (notice that
# current libnice master is breaking connections after 50 seconds when
# keepalive-conncheck is being used, so if you want to use it, better
# sticking to 0.1.18 until the issue is addressed upstream). Finally,
# you can also enable ICE-TCP support (beware that this may lead to problems
# if you do not enable ICE Lite as well), choose which interfaces should
# be used for gathering candidates, and enable or disable the
Expand All @@ -249,6 +257,8 @@ nat: {
#stun_port = 3478
nice_debug = false
#full_trickle = true
#ice_nomination = "regular"
#ice_keepalive_conncheck = true
#ice_lite = true
#ice_tcp = true

Expand Down
6 changes: 6 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ AC_CHECK_LIB([nice],
[AC_MSG_NOTICE([libnice version does not have nice_agent_close_async])]
)

AC_CHECK_LIB([nice],
[nice_agent_new_full],
[AC_DEFINE(HAVE_ICE_NOMINATION)],
[AC_MSG_NOTICE([libnice version does not have nice_agent_new_full])]
)

AC_CHECK_LIB([dl],
[dlopen],
[JANUS_MANUAL_LIBS="${JANUS_MANUAL_LIBS} -ldl"],
Expand Down
39 changes: 39 additions & 0 deletions ice.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,41 @@ gboolean janus_ice_is_ipv6_enabled(void) {
return janus_ipv6_enabled;
}

#ifdef HAVE_ICE_NOMINATION
/* Since libnice 0.1.15, we can configure the ICE nomination mode: it was
* always "aggressive" before, we set it to "regular" by default if we can */
static NiceNominationMode janus_ice_nomination = NICE_NOMINATION_MODE_REGULAR;
void janus_ice_set_nomination_mode(const char *nomination) {
if(nomination == NULL) {
JANUS_LOG(LOG_WARN, "Invalid ICE nomination mode, falling back to 'regular'\n");
} else if(!strcasecmp(nomination, "regular")) {
JANUS_LOG(LOG_INFO, "Configuring Janus to use ICE regular nomination\n");
janus_ice_nomination = NICE_NOMINATION_MODE_REGULAR;
} else if(!strcasecmp(nomination, "aggressive")) {
JANUS_LOG(LOG_INFO, "Configuring Janus to use ICE aggressive nomination\n");
janus_ice_nomination = NICE_NOMINATION_MODE_AGGRESSIVE;
} else {
JANUS_LOG(LOG_WARN, "Unsupported ICE nomination mode '%s', falling back to 'regular'\n", nomination);
}
}
const char *janus_ice_get_nomination_mode(void) {
return (janus_ice_nomination == NICE_NOMINATION_MODE_REGULAR ? "regular" : "aggressive");
}
#endif

/* Keepalive via connectivity checks */
static gboolean janus_ice_keepalive_connckecks = FALSE;
void janus_ice_set_keepalive_conncheck_enabled(gboolean enabled) {
janus_ice_keepalive_connckecks = enabled;
if(janus_ice_keepalive_connckecks) {
JANUS_LOG(LOG_INFO, "Using connectivity checks as PeerConnection keep-alives\n");
JANUS_LOG(LOG_WARN, "Notice that the current libnice master is breaking connections after 50s when keepalive-conncheck enabled. As such, better to stick to 0.1.18 until the issue is addressed upstream\n");
}
}
gboolean janus_ice_is_keepalive_conncheck_enabled(void) {
return janus_ice_keepalive_connckecks;
}

/* Opaque IDs set by applications are by default only passed to event handlers
* for correlation purposes, but not sent back to the user or application in
* the related Janus API responses or events, unless configured otherwise */
Expand Down Expand Up @@ -3461,6 +3496,10 @@ int janus_ice_setup_local(janus_ice_handle *handle, int offer, int audio, int vi
"main-context", handle->mainctx,
"reliable", FALSE,
"full-mode", janus_ice_lite_enabled ? FALSE : TRUE,
#ifdef HAVE_ICE_NOMINATION
"nomination-mode", janus_ice_nomination,
#endif
"keepalive-conncheck", janus_ice_keepalive_connckecks ? FALSE : TRUE,
#ifdef HAVE_LIBNICE_TCP
"ice-udp", TRUE,
"ice-tcp", janus_ice_tcp_enabled ? TRUE : FALSE,
Expand Down
18 changes: 17 additions & 1 deletion ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ gboolean janus_ice_is_mdns_enabled(void);
/*! \brief Method to check whether IPv6 candidates are enabled/supported or not
* @returns true if IPv6 candidates are enabled/supported, false otherwise */
gboolean janus_ice_is_ipv6_enabled(void);
#ifdef HAVE_ICE_NOMINATION
/*! \brief Method to configure the ICE nomination mode (regular or aggressive)
* @param[in] nomination The ICE nomination mode (regular or aggressive) */
void janus_ice_set_nomination_mode(const char *nomination);
/*! \brief Method to return a string description of the configured ICE nomination mode
* @returns "regular" or "aggressive" */
const char *janus_ice_get_nomination_mode(void);
#endif
/*! \brief Method to enable/disable connectivity checks as keepalives for PeerConnections.
* \note The main rationale behind this setting is provided in the libnice documentation:
* https://libnice.freedesktop.org/libnice/NiceAgent.html#NiceAgent--keepalive-conncheck
* @param[in] enabled Whether the functionality should be enabled or disabled */
void janus_ice_set_keepalive_conncheck_enabled(gboolean enabled);
/*! \brief Method to check whether connectivity checks will be used as keepalives
* @returns true if enabled, false (default) otherwise */
gboolean janus_ice_is_keepalive_conncheck_enabled(void);
/*! \brief Method to modify the min NACK value (i.e., the minimum time window of packets per handle to store for retransmissions)
* @param[in] mnq The new min NACK value */
void janus_set_min_nack_queue(uint16_t mnq);
Expand All @@ -140,7 +156,7 @@ uint16_t janus_get_min_nack_queue(void);
* keyframe, as any missing packet won't be needed since the keyframe will allow the
* media recipient to still restore a complete image anyway. Since this optimization
* seems to cause some issues in some edge cases, it's disabled by default.
* @param[in] optimize Whether the opzimization should be enabled or disabled */
* @param[in] optimize Whether the optimization should be enabled or disabled */
void janus_set_nack_optimizations_enabled(gboolean optimize);
/*! \brief Method to check whether NACK optimizations on outgoing keyframes are enabled or not
* @returns optimize if optimizations are enabled, false otherwise */
Expand Down
15 changes: 15 additions & 0 deletions janus.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,10 @@ static json_t *janus_info(const char *transaction) {
json_object_set_new(info, "ipv6", janus_ice_is_ipv6_enabled() ? json_true() : json_false());
json_object_set_new(info, "ice-lite", janus_ice_is_ice_lite_enabled() ? json_true() : json_false());
json_object_set_new(info, "ice-tcp", janus_ice_is_ice_tcp_enabled() ? json_true() : json_false());
#ifdef HAVE_ICE_NOMINATION
json_object_set_new(info, "ice-nomination", json_string(janus_ice_get_nomination_mode()));
#endif
json_object_set_new(info, "ice-keepalive-conncheck", janus_ice_is_keepalive_conncheck_enabled() ? json_true() : json_false());
json_object_set_new(info, "full-trickle", janus_ice_is_full_trickle_enabled() ? json_true() : json_false());
json_object_set_new(info, "mdns-enabled", janus_ice_is_mdns_enabled() ? json_true() : json_false());
json_object_set_new(info, "min-nack-queue", json_integer(janus_get_min_nack_queue()));
Expand Down Expand Up @@ -4787,6 +4791,17 @@ gint main(int argc, char *argv[])
JANUS_LOG(LOG_ERR, "Invalid STUN address %s:%u. STUN will be disabled\n", stun_server, stun_port);
}
}
item = janus_config_get(config, config_nat, janus_config_type_item, "ice_nomination");
if(item && item->value) {
#ifndef HAVE_ICE_NOMINATION
JANUS_LOG(LOG_WARN, "This version of libnice doesn't support setting the ICE nomination mode, ignoring '%s'\n", item->value);
#else
janus_ice_set_nomination_mode(item->value);
#endif
}
item = janus_config_get(config, config_nat, janus_config_type_item, "ice_keepalive_conncheck");
if(item && item->value)
janus_ice_set_keepalive_conncheck_enabled(janus_is_true(item->value));
if(janus_ice_set_turn_server(turn_server, turn_port, turn_type, turn_user, turn_pwd) < 0) {
if(!ignore_unreachable_ice_server) {
JANUS_LOG(LOG_FATAL, "Invalid TURN address %s:%u\n", turn_server, turn_port);
Expand Down

0 comments on commit ad54495

Please sign in to comment.