From d723ab79adc84f5011fe6fb571f39dee26575ef2 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 16 May 2019 14:40:42 +0200 Subject: [PATCH] add option to prefer multicast for data Sometimes it can be useful to force all data transmissions to go out via multicasts, instead of using a unicast when a single unicast suffices. This commit adds a General/PreferMulticast setting that, when set to true, implements this behaviour. It is "PreferMulticast" because readers that only advertise unicast addresses will still receive the data via unicast. The default behaviour is unchanged. Signed-off-by: Erik Boasson --- src/core/ddsi/include/dds/ddsi/q_config.h | 1 + src/core/ddsi/src/q_config.c | 2 ++ src/core/ddsi/src/q_entity.c | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/ddsi/include/dds/ddsi/q_config.h b/src/core/ddsi/include/dds/ddsi/q_config.h index b0e160c..d7cd25d 100644 --- a/src/core/ddsi/include/dds/ddsi/q_config.h +++ b/src/core/ddsi/include/dds/ddsi/q_config.h @@ -239,6 +239,7 @@ struct config int tracingTimestamps; int tracingAppendToFile; uint32_t allowMulticast; + int prefer_multicast; enum transport_selector transport_selector; enum boolean_default compat_use_ipv6; enum boolean_default compat_tcp_enable; diff --git a/src/core/ddsi/src/q_config.c b/src/core/ddsi/src/q_config.c index cde5e86..382d2c1 100644 --- a/src/core/ddsi/src/q_config.c +++ b/src/core/ddsi/src/q_config.c @@ -244,6 +244,8 @@ static const struct cfgelem general_cfgelems[] = {
  • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
  • \n\ \n\

    When set to \"false\" all multicasting is disabled. The default, \"true\" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

    ") }, + { LEAF("PreferMulticast"), 1, "false", ABSOFF(prefer_multicast), 0, uf_boolean, 0, pf_boolean, + BLURB("

    When false (default) Cyclone DDS uses unicast for data whenever there a single unicast suffices. Setting this to true makes it prefer multicasting data, falling back to unicast only when no multicast address is available.

    ") }, { LEAF("MulticastTimeToLive"), 1, "32", ABSOFF(multicast_ttl), 0, uf_natint_255, 0, pf_int, BLURB("

    This element specifies the time-to-live setting for outgoing multicast packets.

    ") }, { LEAF("DontRoute"), 1, "false", ABSOFF(dontRoute), 0, uf_boolean, 0, pf_boolean, diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 53c0bc6..f7d3480 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -1107,7 +1107,7 @@ static void rebuild_trace_covered(int nreaders, int nlocs, const nn_locator_t *l { char buf[DDSI_LOCATORSTRLEN]; ddsi_locator_to_string(buf, sizeof(buf), &locs[i]); - DDS_LOG(DDS_LC_DISCOVERY, " loc %2d = %-20s %2d {", i, buf, locs_nrds[i]); + DDS_LOG(DDS_LC_DISCOVERY, " loc %2d = %-30s %2d {", i, buf, locs_nrds[i]); for (j = 0; j < nreaders; j++) if (covered[j * nlocs + i] >= 0) DDS_LOG(DDS_LC_DISCOVERY, " %d", covered[j * nlocs + i]); @@ -1123,7 +1123,9 @@ static int rebuild_select(int nlocs, const nn_locator_t *locs, const int *locs_n if (nlocs == 0) return -1; for (j = 0, i = 1; i < nlocs; i++) { - if (locs_nrds[i] > locs_nrds[j]) + if (config.prefer_multicast && locs_nrds[i] > 0 && ddsi_is_mcaddr(&locs[i]) && !ddsi_is_mcaddr(&locs[j])) + j = i; /* obviously first step must be to try and avoid unicast if configuration says so */ + else if (locs_nrds[i] > locs_nrds[j]) j = i; /* better coverage */ else if (locs_nrds[i] == locs_nrds[j]) {