Skip to content
Closed
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
4 changes: 2 additions & 2 deletions docs/manual/config/config_file_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2795,8 +2795,8 @@ The default value is: ``none``

..
generated from ddsi_config.h[6b6cd6f2af797765bc3753758bdd5f166f64b418]
generated from ddsi_config.c[a48ec3d818f2ad852949a7832951709c3488dc10]
generated from ddsi__cfgelems.h[32ba43b085108475f0fc5041d4593a9926c0f6f9]
generated from ddsi_config.c[98a66b82efe4476934c17d3df879e70add3b65a2]
generated from ddsi__cfgelems.h[7fe8f980955d7eab1f9515a474d5a51042698343]
generated from cfgunits.h[05f093223fce107d24dd157ebaafa351dc9df752]
generated from _confgen.h[bb9a0fc6ef1f7f7c46790ee00132e340e5fff36d]
generated from _confgen.c[0d833a6f2c98902f1249e63aed03a6164f0791d6]
Expand Down
4 changes: 2 additions & 2 deletions docs/manual/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -1961,8 +1961,8 @@ The categorisation of tracing output is incomplete and hence most of the verbosi

The default value is: `none`
<!--- generated from ddsi_config.h[6b6cd6f2af797765bc3753758bdd5f166f64b418] -->
<!--- generated from ddsi_config.c[a48ec3d818f2ad852949a7832951709c3488dc10] -->
<!--- generated from ddsi__cfgelems.h[32ba43b085108475f0fc5041d4593a9926c0f6f9] -->
<!--- generated from ddsi_config.c[98a66b82efe4476934c17d3df879e70add3b65a2] -->
<!--- generated from ddsi__cfgelems.h[7fe8f980955d7eab1f9515a474d5a51042698343] -->
<!--- generated from cfgunits.h[05f093223fce107d24dd157ebaafa351dc9df752] -->
<!--- generated from _confgen.h[bb9a0fc6ef1f7f7c46790ee00132e340e5fff36d] -->
<!--- generated from _confgen.c[0d833a6f2c98902f1249e63aed03a6164f0791d6] -->
Expand Down
4 changes: 2 additions & 2 deletions etc/cyclonedds.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -1360,8 +1360,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
maybe_memsize = xsd:token { pattern = "default|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" }
}
# generated from ddsi_config.h[6b6cd6f2af797765bc3753758bdd5f166f64b418]
# generated from ddsi_config.c[a48ec3d818f2ad852949a7832951709c3488dc10]
# generated from ddsi__cfgelems.h[32ba43b085108475f0fc5041d4593a9926c0f6f9]
# generated from ddsi_config.c[98a66b82efe4476934c17d3df879e70add3b65a2]
# generated from ddsi__cfgelems.h[7fe8f980955d7eab1f9515a474d5a51042698343]
# generated from cfgunits.h[05f093223fce107d24dd157ebaafa351dc9df752]
# generated from _confgen.h[bb9a0fc6ef1f7f7c46790ee00132e340e5fff36d]
# generated from _confgen.c[0d833a6f2c98902f1249e63aed03a6164f0791d6]
Expand Down
4 changes: 2 additions & 2 deletions etc/cyclonedds.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -2047,8 +2047,8 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==&lt;br&gt;
</xs:simpleType>
</xs:schema>
<!--- generated from ddsi_config.h[6b6cd6f2af797765bc3753758bdd5f166f64b418] -->
<!--- generated from ddsi_config.c[a48ec3d818f2ad852949a7832951709c3488dc10] -->
<!--- generated from ddsi__cfgelems.h[32ba43b085108475f0fc5041d4593a9926c0f6f9] -->
<!--- generated from ddsi_config.c[98a66b82efe4476934c17d3df879e70add3b65a2] -->
<!--- generated from ddsi__cfgelems.h[7fe8f980955d7eab1f9515a474d5a51042698343] -->
<!--- generated from cfgunits.h[05f093223fce107d24dd157ebaafa351dc9df752] -->
<!--- generated from _confgen.h[bb9a0fc6ef1f7f7c46790ee00132e340e5fff36d] -->
<!--- generated from _confgen.c[0d833a6f2c98902f1249e63aed03a6164f0791d6] -->
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ option(ENABLE_TYPELIB "Enable Type Library support" ON)
option(ENABLE_TYPE_DISCOVERY "Enable Type Discovery support" ON)
option(ENABLE_TOPIC_DISCOVERY "Enable Topic Discovery support" ON)
option(ENABLE_QOS_PROVIDER "Enable Qos Provider support" ON)
option(ENABLE_TCP "Enable PoC support for DDS-over-TCP" OFF)
if(ENABLE_TYPE_DISCOVERY)
if(NOT ENABLE_TYPELIB)
message(FATAL_ERROR "ENABLE_TYPE_DISCOVERY requires ENABLE_TYPELIB to be enabled")
Expand Down
5 changes: 5 additions & 0 deletions src/core/ddsc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ if(ENABLE_QOS_PROVIDER)
"qos_provider.c")
endif()

if(ENABLE_TCP)
list(APPEND ddsc_test_sources
"tcp.c")
endif()

add_cunit_executable(cunit_ddsc ${ddsc_test_sources})

if(MSVC)
Expand Down
239 changes: 239 additions & 0 deletions src/core/ddsc/tests/tcp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
// Copyright(c) 2025 ZettaScale Technology and others
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
// v. 1.0 which is available at
// http://www.eclipse.org/org/documents/edl-v10.php.
//
// SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause

#include <stdio.h>
#include <ctype.h>

#include "dds/ddsi/ddsi_protocol.h"
#include "dds/ddsi/ddsi_thread.h"
#include "dds/ddsrt/time.h"
#include "dds__guid.h"
#include "ddsi__tran.h"
#include "test_common.h"
#include "dds/ddsi/ddsi_entity_index.h"
#include "dds/ddsi/ddsi_proxy_participant.h"
#include "dds/ddsi/ddsi_addrset.h"

#include "dds/dds.h"
#include "dds/ddsrt/io.h"
#include "dds/ddsrt/heap.h"
#include "ddsi__addrset.h"

static ddsrt_atomic_uint32_t framing_errors;

static void scan_for_framing_error (void *ptr, const dds_log_data_t *data)
{
(void) ptr;
//tprintf ("[%"PRIu32"] %s", data->domid, data->message);
if (strstr (data->message, "framing error, dropping connection") != NULL)
ddsrt_atomic_or32 (&framing_errors, 1u << data->domid);
}

static void do_tcp (void (*action) (dds_entity_t rd, dds_entity_t wr, void *arg), void *arg)
{
const char *config_fmt =
"<General>"
" <Interfaces>"
" <NetworkInterface address=\"127.0.0.1\"/>"
" </Interfaces>"
" <Transport>tcp</Transport>"
"</General>"
"<Discovery>"
" <ExternalDomainId>0</ExternalDomainId>"
" <Tag>${CYCLONEDDS_PID}</Tag>"
" <Peers>"
" %s"
" </Peers>"
"</Discovery>"
"<TCP>"
" <Port>%d</Port>"
"</TCP>"
"<Tracing><Category>trace,tcp</Category><OutputFile>stdout</OutputFile></Tracing>";

ddsrt_atomic_st32 (&framing_errors, 0);
dds_set_log_sink (scan_for_framing_error, NULL);
dds_set_trace_sink (scan_for_framing_error, NULL);

// Start up a new domain listening to an ephemeral TCP port
char *configs = NULL;
(void) ddsrt_asprintf (&configs, config_fmt, "", 0);
const dds_entity_t doms = dds_create_domain (0, configs);
CU_ASSERT_GT_FATAL (doms, 0);
ddsrt_free (configs);
struct ddsi_domaingv * const gvs = get_domaingv (doms);
CU_ASSERT_NEQ_FATAL (gvs, NULL);

// Create a second domain instance without a server socket and with the
// first domain's ephemeral port as the peer
char peerlocbuf[DDSI_LOCSTRLEN];
char *peerstr = NULL;
(void) ddsrt_asprintf (&peerstr, "<Peer address=\"%s\"/>", ddsi_locator_to_string (peerlocbuf, sizeof (peerlocbuf), &gvs->loc_meta_uc));
char *configc = NULL;
(void) ddsrt_asprintf (&configc, config_fmt, peerstr, -1);
const dds_entity_t domc = dds_create_domain (1, configc);
CU_ASSERT_GT_FATAL (domc, 0);
ddsrt_free (configc);
ddsrt_free (peerstr);

const dds_entity_t pp_pub = dds_create_participant (0, NULL, NULL);
CU_ASSERT_GT_FATAL (pp_pub, 0);
const dds_entity_t pp_sub = dds_create_participant (1, NULL, NULL);
CU_ASSERT_GT_FATAL (pp_sub, 0);
char topicname[100];
create_unique_topic_name ("tcp_basic", topicname, sizeof (topicname));
dds_qos_t *qos = dds_create_qos ();
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);
const dds_entity_t tp_pub = dds_create_topic (pp_pub, &Space_Type1_desc, topicname, qos, NULL);
const dds_entity_t tp_sub = dds_create_topic (pp_sub, &Space_Type1_desc, topicname, qos, NULL);
dds_delete_qos (qos);

const dds_entity_t wr = dds_create_writer (pp_pub, tp_pub, NULL, NULL);
const dds_entity_t rd = dds_create_reader (pp_sub, tp_sub, NULL, NULL);
sync_reader_writer (pp_sub, rd, pp_pub, wr);

action (rd, wr, arg);

dds_return_t rc;
rc = dds_delete (domc);
CU_ASSERT_EQ_FATAL (rc, 0);
rc = dds_delete (doms);
CU_ASSERT_EQ_FATAL (rc, 0);

dds_set_log_sink (scan_for_framing_error, NULL);
dds_set_trace_sink (scan_for_framing_error, NULL);
}

static void do_basic_write (dds_entity_t rd, dds_entity_t wr, void *varg)
{
(void) varg;

dds_return_t rc;
rc = dds_write (wr, &(Space_Type1){345,678,101});
CU_ASSERT_EQ_FATAL (rc, 0);

const dds_entity_t ws = dds_create_waitset (dds_get_participant (rd));
CU_ASSERT_GT_FATAL (ws, 0);
rc = dds_set_status_mask (rd, DDS_DATA_AVAILABLE_STATUS);
CU_ASSERT_EQ_FATAL (rc, 0);
rc = dds_waitset_attach (ws, rd, 0);
CU_ASSERT_EQ_FATAL (rc, 0);
rc = dds_waitset_wait (ws, NULL, 0, DDS_MSECS (5000));
CU_ASSERT_EQ (rc, 1);

Space_Type1 sample;
void *rawsample = &sample;
dds_sample_info_t si;
rc = dds_take (rd, &rawsample, &si, 1, 1);
CU_ASSERT_EQ_FATAL (rc, 1);
CU_ASSERT_FATAL(si.valid_data);
CU_ASSERT_EQ_FATAL (sample.long_1, 345);
CU_ASSERT_EQ_FATAL (sample.long_2, 678);
CU_ASSERT_EQ_FATAL (sample.long_3, 101);
}

CU_Test (ddsc_tcp, basic)
{
do_tcp (do_basic_write, NULL);
}

struct inject_arg {
ddsrt_iovec_t data;
};

static void do_inject (dds_entity_t rd, dds_entity_t wr, void *varg)
{
const struct inject_arg *arg = varg;
struct ddsi_domaingv * const gvwr = get_domaingv (wr);

// Find reader's proxy participant in writer's domain
dds_guid_t rdguid;
dds_get_guid (rd, &rdguid);
ddsi_guid_t rdpp_guid = dds_guid_to_ddsi_guid (rdguid);
rdpp_guid.entityid.u = DDSI_ENTITYID_PARTICIPANT;
ddsi_thread_state_awake (ddsi_lookup_thread_state (), gvwr);
struct ddsi_proxy_participant *rdproxypp = ddsi_entidx_lookup_proxy_participant_guid (gvwr->entity_index, &rdpp_guid);
CU_ASSERT_NEQ_FATAL (rdproxypp, NULL);
ddsi_thread_state_asleep (ddsi_lookup_thread_state ());
// ... because we need the address
ddsi_xlocator_t xloc;
ddsi_addrset_any_uc (rdproxypp->as_default, &xloc);

// Make writer's domain mute so we can inject garbage in the TCP connection without
// interfering with RTPS messages being sent in the background
dds_domain_set_deafmute (wr, false, true, DDS_INFINITY);

DDSI_DECL_TRAN_WRITE_MSGFRAGS_PTR(mf, 1);
mf->niov = 1;
mf->iov[0] = arg->data;
ddsi_conn_write (xloc.conn, &xloc.c, mf, 0);

// logger should
dds_domainid_t rd_domain_id;
dds_return_t rc;
rc = dds_get_domainid (rd, &rd_domain_id);
CU_ASSERT_EQ_FATAL (rc, 0);
while (ddsrt_atomic_ld32 (&framing_errors) == 0)
dds_sleepfor (DDS_MSECS (10));
CU_ASSERT_EQ_FATAL (ddsrt_atomic_ld32 (&framing_errors), (1u << rd_domain_id));
}

CU_Test (ddsc_tcp, inject_wrong_smid)
{
unsigned char msg[] = {
'R', 'T', 'P', 'S', /* version (don't care): */ 2,5,
/* vendor id (don't care, 1.16 = Cyclone */ 1,16,
/* GUID prefix (don't care) */ 1,16,3,4, 5,6,7,8, 9,10,11,12,
/* SMID_ADLINK_MSG_LEN, big-endian, 4 octets-to-next-header */ 130,0,0,4,
/* fake length */ 0x0,0x0,0x0,0x20
};
struct inject_arg arg = {
.data = {
.iov_len = 28,
.iov_base = msg
}
};
do_tcp (do_inject, &arg);
}

CU_Test (ddsc_tcp, inject_short_length)
{
unsigned char msg[] = {
'R', 'T', 'P', 'S', /* version (don't care): */ 2,5,
/* vendor id (don't care, 1.16 = Cyclone */ 1,16,
/* GUID prefix (don't care) */ 1,16,3,4, 5,6,7,8, 9,10,11,12,
/* SMID_ADLINK_MSG_LEN, big-endian, 4 octets-to-next-header */ 129,0,0,4,
/* fake length */ 0x0,0x0,0x0,0x3
};
struct inject_arg arg = {
.data = {
.iov_len = 28,
.iov_base = msg
}
};
do_tcp (do_inject, &arg);
}

CU_Test (ddsc_tcp, inject_oversize_length)
{
unsigned char msg[] = {
'R', 'T', 'P', 'S', /* version (don't care): */ 2,5,
/* vendor id (don't care, 1.16 = Cyclone */ 1,16,
/* GUID prefix (don't care) */ 1,16,3,4, 5,6,7,8, 9,10,11,12,
/* SMID_ADLINK_MSG_LEN, big-endian, 4 octets-to-next-header */ 129,0,0,4,
/* fake length */ 0x33,0x44,0x55,0x66
};
struct inject_arg arg = {
.data = {
.iov_len = 28,
.iov_base = msg
}
};
do_tcp (do_inject, &arg);
}
4 changes: 2 additions & 2 deletions src/core/ddsi/defconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ void ddsi_config_init_default (struct ddsi_config *cfg)
#endif /* DDS_HAS_TCP_TLS */
}
/* generated from ddsi_config.h[6b6cd6f2af797765bc3753758bdd5f166f64b418] */
/* generated from ddsi_config.c[a48ec3d818f2ad852949a7832951709c3488dc10] */
/* generated from ddsi__cfgelems.h[32ba43b085108475f0fc5041d4593a9926c0f6f9] */
/* generated from ddsi_config.c[98a66b82efe4476934c17d3df879e70add3b65a2] */
/* generated from ddsi__cfgelems.h[7fe8f980955d7eab1f9515a474d5a51042698343] */
/* generated from cfgunits.h[05f093223fce107d24dd157ebaafa351dc9df752] */
/* generated from _confgen.h[bb9a0fc6ef1f7f7c46790ee00132e340e5fff36d] */
/* generated from _confgen.c[0d833a6f2c98902f1249e63aed03a6164f0791d6] */
Expand Down
6 changes: 0 additions & 6 deletions src/core/ddsi/src/ddsi__addrset.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ struct ddsi_addrset {
ddsrt_avl_ctree_t ucaddrs, mcaddrs;
};

typedef ssize_t (*ddsi_addrset_forone_fun_t) (const ddsi_xlocator_t *loc, void *arg);

/** @component locators */
void ddsi_add_xlocator_to_addrset (const struct ddsi_domaingv *gv, struct ddsi_addrset *as, const ddsi_xlocator_t *loc)
ddsrt_nonnull_all;
Expand Down Expand Up @@ -98,10 +96,6 @@ bool ddsi_addrset_contains_non_psmx_uc (const struct ddsi_addrset *as)

/* Keeps AS locked */

/** @component locators */
int ddsi_addrset_forone (struct ddsi_addrset *as, ddsi_addrset_forone_fun_t f, void *arg)
ddsrt_nonnull ((1, 2));

/** @component locators */
size_t ddsi_addrset_forall_count (struct ddsi_addrset *as, ddsi_addrset_forall_fun_t f, void *arg)
ddsrt_nonnull ((1, 2));
Expand Down
Loading