From c98e118a2e4366d2a5a6af8cbcecdf112bf9e4ab Mon Sep 17 00:00:00 2001 From: Marcel Jordense Date: Wed, 13 Mar 2019 13:26:41 +0100 Subject: [PATCH] OSPL-12837 DDSI: respond to a retransmit request for a large sample with just the first fragment --- src/services/ddsi2e/core/q_config.c | 3 +++ src/services/ddsi2e/core/q_config.h | 1 + src/services/ddsi2e/core/q_transmit.c | 12 +++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/services/ddsi2e/core/q_config.c b/src/services/ddsi2e/core/q_config.c index 16153afbe..88935dd61 100644 --- a/src/services/ddsi2e/core/q_config.c +++ b/src/services/ddsi2e/core/q_config.c @@ -688,6 +688,9 @@ static const struct cfgelem unsupp_cfgelems[] = { "

Do not use.

" }, { LEAF_W_ATTRS ("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "10s", ABSOFF (prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration, "

This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.

" }, + { LEAF ("AlwaysRetransmitCompleteSample"), 1, "false", ABSOFF (retransmit_complete_sample), 0, uf_boolean, 0, pf_boolean, + "

This element controls if a sample is retransitted completely or only missing fragments.

" + }, { MGROUP ("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0, "

The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.

" }, { GROUP ("Test", unsupp_test_cfgelems), diff --git a/src/services/ddsi2e/core/q_config.h b/src/services/ddsi2e/core/q_config.h index b37164556..86f599c78 100644 --- a/src/services/ddsi2e/core/q_config.h +++ b/src/services/ddsi2e/core/q_config.h @@ -354,6 +354,7 @@ struct config int unicast_response_to_spdp_messages; int synchronous_delivery_priority_threshold; os_int64 synchronous_delivery_latency_bound; + int retransmit_complete_sample; /* Write cache */ diff --git a/src/services/ddsi2e/core/q_transmit.c b/src/services/ddsi2e/core/q_transmit.c index 6adc11017..7ec1d3bfe 100644 --- a/src/services/ddsi2e/core/q_transmit.c +++ b/src/services/ddsi2e/core/q_transmit.c @@ -715,6 +715,7 @@ int enqueue_sample_wrlock_held (struct writer *wr, os_int64 seq, const struct nn { unsigned i, sz, nfrags; int enqueued = 1; + int ret_on_success = 0; ASSERT_MUTEX_HELD (&wr->e.lock); @@ -725,6 +726,15 @@ int enqueue_sample_wrlock_held (struct writer *wr, os_int64 seq, const struct nn /* end-of-transaction messages are empty, but still need to be sent */ nfrags = 1; } + else if (nfrags > 1 && !isnew && !config.retransmit_complete_sample) + { + /* retransmit only a single fragment for a retransmit request of a + full sample, so that afterward it switches to NACKFRAG mode - + should do so only do for implementations with known behaviours */ + nfrags = 1; + /* return -1 to prevent the retransmit loop from resending more samples */ + ret_on_success = -1; + } for (i = 0; i < nfrags && enqueued; i++) { struct nn_xmsg *fmsg = NULL; @@ -762,7 +772,7 @@ int enqueue_sample_wrlock_held (struct writer *wr, os_int64 seq, const struct nn } } } - return enqueued ? 0 : -1; + return enqueued ? ret_on_success : -1; } static int insert_sample_in_whc (struct writer *wr, os_int64 seq, struct nn_plist *plist, serdata_t serdata)