Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new option to configure ICE nomination mode, if libnice is recent enough #2541

Merged
merged 3 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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