diff --git a/src/core/ddsi/include/dds/ddsi/q_entity.h b/src/core/ddsi/include/dds/ddsi/q_entity.h index c0ca424..7d8f8e1 100644 --- a/src/core/ddsi/include/dds/ddsi/q_entity.h +++ b/src/core/ddsi/include/dds/ddsi/q_entity.h @@ -300,6 +300,10 @@ struct writer unsigned force_md5_keyhash: 1; /* iff 1, when keyhash has to be hashed, no matter the size */ unsigned retransmitting: 1; /* iff 1, this writer is currently retransmitting */ unsigned alive: 1; /* iff 1, the writer is alive (lease for this writer is not expired); field may be modified only when holding both wr->e.lock and wr->c.pp->e.lock */ + unsigned test_ignore_acknack : 1; /* iff 1, the writer ignores all arriving ACKNACK messages */ + unsigned test_suppress_retransmit : 1; /* iff 1, the writer does not respond to retransmit requests */ + unsigned test_suppress_heartbeat : 1; /* iff 1, the writer suppresses all periodic heartbeats */ + unsigned test_drop_outgoing_data : 1; /* iff 1, the writer drops outgoing data, forcing the readers to request a retransmit */ #ifdef DDSI_INCLUDE_SSM unsigned supports_ssm: 1; struct addrset *ssm_as; diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 8443ef0..5f929b8 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -3641,6 +3641,10 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se wr->time_retransmit = 0; wr->force_md5_keyhash = 0; wr->alive = 1; + wr->test_ignore_acknack = 0; + wr->test_suppress_retransmit = 0; + wr->test_suppress_heartbeat = 0; + wr->test_drop_outgoing_data = 0; wr->alive_vclock = 0; wr->init_burst_size_limit = UINT32_MAX - UINT16_MAX; wr->rexmit_burst_size_limit = UINT32_MAX - UINT16_MAX; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index d5636db..5681783 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -785,6 +785,12 @@ static int handle_AckNack (struct receiver_state *rst, ddsrt_etime_t tnow, const } ddsrt_mutex_lock (&wr->e.lock); + if (wr->test_ignore_acknack) + { + RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" test_ignore_acknack)", PGUID (src), PGUID (dst)); + goto out; + } + if ((rn = ddsrt_avl_lookup (&wr_readers_treedef, &wr->readers, &src)) == NULL) { RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" not a connection)", PGUID (src), PGUID (dst)); @@ -944,6 +950,11 @@ static int handle_AckNack (struct receiver_state *rst, ddsrt_etime_t tnow, const hasn't been transmitted ever, the initial transmit should solve that issue; if it has, then the timing is terribly unlucky, but a future request'll fix it. */ + if (wr->test_suppress_retransmit && numbits > 0) + { + RSTTRACE (" test_suppress_retransmit"); + numbits = 0; + } enqueued = 1; seq_xmit = writer_read_seq_xmit (wr); nn_gap_info_init(&gi); diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index a0e1b14..77184df 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -1292,6 +1292,17 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack * ddsrt_free (plist); } } + else if (wr->test_drop_outgoing_data) + { + GVTRACE ("test_drop_outgoing_data"); + writer_update_seq_xmit (wr, seq); + ddsrt_mutex_unlock (&wr->e.lock); + if (plist != NULL) + { + ddsi_plist_fini (plist); + ddsrt_free (plist); + } + } else if (addrset_empty (wr->as) && (wr->as_group == NULL || addrset_empty (wr->as_group))) { /* No network destination, so no point in doing all the work involved diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index f17a93e..763a09d 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -778,7 +778,13 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt and we certainly don't want to hold the lock during that time. */ if (msg) { - nn_xpack_addmsg (xp, msg, 0); + if (!wr->test_suppress_heartbeat) + nn_xpack_addmsg (xp, msg, 0); + else + { + GVTRACE ("test_suppress_heartbeat\n"); + nn_xmsg_free (msg); + } } }