Protected discovery preparation.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
Martin Bremmer 2019-10-23 17:52:18 +02:00 committed by eboasson
parent 7f59a46ff8
commit d0035cfdbd
12 changed files with 764 additions and 122 deletions

View file

@ -18,6 +18,7 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
ddsi_raweth.c
ddsi_ipaddr.c
ddsi_mcgroup.c
ddsi_security_omg.c
ddsi_serdata.c
ddsi_serdata_default.c
ddsi_sertopic.c
@ -70,6 +71,7 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
ddsi_ipaddr.h
ddsi_mcgroup.h
ddsi_plist_generic.h
ddsi_security_omg.h
ddsi_serdata.h
ddsi_sertopic.h
ddsi_serdata_default.h

View file

@ -0,0 +1,152 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited 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
*/
#ifndef DDSI_OMG_SECURITY_H
#define DDSI_OMG_SECURITY_H
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/q_plist.h"
#include "dds/ddsi/q_globals.h"
#if defined (__cplusplus)
extern "C" {
#endif
#ifdef DDSI_INCLUDE_SECURITY
/**
* @brief Check if security is enabled for the participant.
*
* @param[in] pp Participant to check if it is secure.
*
* @returns bool
* @retval true Participant is secure
* @retval false Participant is not secure
*/
bool q_omg_participant_is_secure(const struct participant *pp);
/**
* @brief Get security info flags of the given writer.
*
* @param[in] wr Writer to get the security info from.
* @param[out] info The security info.
*
* @returns bool
* @retval true Security info set.
* @retval false Security info not set (probably unsecure writer).
*/
bool q_omg_get_writer_security_info(const struct writer *wr, nn_security_info_t *info);
/**
* @brief Get security info flags of the given reader.
*
* @param[in] rd Reader to get the security info from.
* @param[out] info The security info.
*
* @returns bool
* @retval true Security info set.
* @retval false Security info not set (probably unsecure reader).
*/
bool q_omg_get_reader_security_info(const struct reader *rd, nn_security_info_t *info);
/**
* @brief Return the builtin writer id for this readers' discovery.
*
* Return builtin entity id of the writer to use for the subscription
* discovery information.
* Depending on whether the discovery is protected or not (for the
* given reader), either the default writer or protected writer needs
* to be used.
*
* @param[in] rd Reader to determine the subscription writer from.
*
* @returns unsigned
* @retval NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER
* @retval NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER
*/
unsigned determine_subscription_writer(const struct reader *rd);
/**
* @brief Return the builtin writer id for this writers' discovery.
*
* Return builtin entity id of the writer to use for the publication
* discovery information.
* Depending on whether the discovery is protected or not (for the
* given writer), either the default writer or protected writer needs
* to be used.
*
* @param[in] wr Writer to determine the publication writer from.
*
* @returns unsigned
* @retval NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER
* @retval NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER
*/
unsigned determine_publication_writer(const struct writer *wr);
/**
* @brief Determine if the proxy participant is allowed to be deleted
* by the given writer.
*
* If an proxy participant is authenticated, it is only allowed to
* to deleted when a dispose is received from the proper protected
* discovery writer.
*
* @param[in] gv Used for tracing.
* @param[in] guid Guid of the proxy participant to be deleted.
* @param[in] pwr_entityid Writer that send the dispose.
*
* @returns bool
* @retval true The proxy participant may be deleted.
* @retval false The proxy participant may not be deleted by this writer.
*/
bool allow_proxy_participant_deletion(struct q_globals * const gv, const struct ddsi_guid *guid, const ddsi_entityid_t pwr_entityid);
#else /* DDSI_INCLUDE_SECURITY */
#include "dds/ddsi/q_unused.h"
inline bool
q_omg_participant_is_secure(
UNUSED_ARG(const struct participant *pp))
{
return false;
}
inline unsigned
determine_subscription_writer(
UNUSED_ARG(const struct reader *rd))
{
return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER;
}
inline unsigned
determine_publication_writer(
UNUSED_ARG(const struct writer *wr))
{
return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;
}
inline bool
allow_proxy_participant_deletion(
UNUSED_ARG(struct q_globals * const gv),
UNUSED_ARG(const struct ddsi_guid *guid),
UNUSED_ARG(const ddsi_entityid_t pwr_entityid))
{
return true;
}
#endif /* DDSI_INCLUDE_SECURITY */
#if defined (__cplusplus)
}
#endif
#endif /* DDSI_OMG_SECURITY_H */

View file

@ -237,6 +237,10 @@ struct q_globals {
dds_qos_t spdp_endpoint_xqos;
dds_qos_t builtin_endpoint_xqos_rd;
dds_qos_t builtin_endpoint_xqos_wr;
#ifdef DDSI_INCLUDE_SECURITY
dds_qos_t builtin_stateless_xqos_rd;
dds_qos_t builtin_stateless_xqos_wr;
#endif
/* SPDP packets get very special treatment (they're the only packets
we accept from writers we don't know) and have their very own

View file

@ -172,6 +172,9 @@ typedef struct nn_security_info
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_AUTHENTICATED (1u << 3)
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED (1u << 4)
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED (1u << 5)
#else
struct nn_security_info;
typedef struct nn_security_info nn_security_info_t;
#endif

View file

@ -89,6 +89,19 @@ typedef struct {
#define NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER (1u << 12)
#define NN_DISC_BUILTIN_ENDPOINT_TOPIC_DETECTOR (1u << 13)
/* Security extensions: */
#define NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER (1u<<16)
#define NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR (1u<<17)
#define NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER (1u<<18)
#define NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR (1u<<19)
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER (1u<<20)
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR (1u<<21)
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER (1u<<22)
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR (1u<<23)
/* TODO: ENDPOINT_PARTICIPANT_VOLATILE */
#define NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER (1u << 26)
#define NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR (1u << 27)
/* PrismTech extensions: */
#define NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_WRITER (1u << 0)
#define NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_READER (1u << 1)

View file

@ -44,6 +44,19 @@ typedef int64_t seqno_t;
#define NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER 0x100c7
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER 0x200c2
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER 0x200c7
#define NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER 0xff0003c2
#define NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER 0xff0003c7
#define NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER 0xff0004c2
#define NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER 0xff0004c7
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER 0x201c3
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER 0x201c4
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER 0xff0200c2
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER 0xff0200c7
/* TODO: ENDPOINT_PARTICIPANT_VOLATILE */
#define NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER 0xff0101c2
#define NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER 0xff0101c7
#define NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER 0x142
#define NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_READER 0x147
#define NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_WRITER 0x242

View file

@ -0,0 +1,148 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited 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
*/
#ifdef DDSI_INCLUDE_SECURITY
#include <string.h>
#include "dds/ddsrt/misc.h"
#include "dds/ddsi/q_unused.h"
#include "dds/ddsi/ddsi_security_omg.h"
bool
q_omg_participant_is_secure(
const struct participant *pp)
{
/* TODO: Register local participant. */
DDSRT_UNUSED_ARG(pp);
return false;
}
static bool
q_omg_writer_is_discovery_protected(
const struct writer *wr)
{
/* TODO: Register local writer. */
DDSRT_UNUSED_ARG(wr);
return false;
}
static bool
q_omg_reader_is_discovery_protected(
const struct reader *rd)
{
/* TODO: Register local reader. */
DDSRT_UNUSED_ARG(rd);
return false;
}
bool
q_omg_get_writer_security_info(
const struct writer *wr,
nn_security_info_t *info)
{
assert(wr);
assert(info);
/* TODO: Register local writer. */
DDSRT_UNUSED_ARG(wr);
info->plugin_security_attributes = 0;
info->security_attributes = 0;
return false;
}
bool
q_omg_get_reader_security_info(
const struct reader *rd,
nn_security_info_t *info)
{
assert(rd);
assert(info);
/* TODO: Register local reader. */
DDSRT_UNUSED_ARG(rd);
info->plugin_security_attributes = 0;
info->security_attributes = 0;
return false;
}
static bool
q_omg_proxyparticipant_is_authenticated(
struct proxy_participant *proxypp)
{
/* TODO: Handshake */
DDSRT_UNUSED_ARG(proxypp);
return false;
}
unsigned
determine_subscription_writer(
const struct reader *rd)
{
if (q_omg_reader_is_discovery_protected(rd))
{
return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER;
}
return NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER;
}
unsigned
determine_publication_writer(
const struct writer *wr)
{
if (q_omg_writer_is_discovery_protected(wr))
{
return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER;
}
return NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;
}
bool
allow_proxy_participant_deletion(
struct q_globals * const gv,
const struct ddsi_guid *guid,
const ddsi_entityid_t pwr_entityid)
{
struct proxy_participant *proxypp;
assert(gv);
assert(guid);
/* Always allow deletion from a secure proxy writer. */
if (pwr_entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER)
return true;
/* Not from a secure proxy writer.
* Only allow deletion when proxy participant is not authenticated. */
proxypp = ephash_lookup_proxy_participant_guid(gv->guid_hash, guid);
if (!proxypp)
{
GVLOGDISC (" unknown");
return false;
}
return (!q_omg_proxyparticipant_is_authenticated(proxypp));
}
#else /* DDSI_INCLUDE_SECURITY */
#include "dds/ddsi/ddsi_security_omg.h"
extern inline bool q_omg_participant_is_secure(UNUSED_ARG(const struct participant *pp));
extern inline unsigned determine_subscription_writer(UNUSED_ARG(const struct reader *rd));
extern inline unsigned determine_publication_writer(UNUSED_ARG(const struct writer *wr));
extern inline bool allow_proxy_participant_deletion(
UNUSED_ARG(struct q_globals * const gv),
UNUSED_ARG(const struct ddsi_guid *guid),
UNUSED_ARG(const ddsi_entityid_t pwr_entityid));
#endif /* DDSI_INCLUDE_SECURITY */

View file

@ -43,6 +43,7 @@
#include "dds/ddsi/q_lease.h"
#include "dds/ddsi/ddsi_serdata_default.h"
#include "dds/ddsi/q_feature_check.h"
#include "dds/ddsi/ddsi_security_omg.h"
static int get_locator (const struct q_globals *gv, nn_locator_t *loc, const nn_locators_t *locs, int uc_same_subnet)
{
@ -327,16 +328,18 @@ int spdp_write (struct participant *pp)
return ret;
}
int spdp_dispose_unregister (struct participant *pp)
static int spdp_dispose_unregister_with_wr (struct participant *pp, unsigned entityid)
{
struct nn_xmsg *mpayload;
nn_plist_t ps;
struct writer *wr;
int ret;
if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL)
if ((wr = get_builtin_writer (pp, entityid)) == NULL)
{
ETRACE (pp, "spdp_dispose_unregister("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
ETRACE (pp, "spdp_dispose_unregister("PGUIDFMT") - builtin participant %s writer not found\n",
PGUID (pp->e.guid),
entityid == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER ? "secure" : "");
return 0;
}
@ -353,6 +356,21 @@ int spdp_dispose_unregister (struct participant *pp)
return ret;
}
int spdp_dispose_unregister (struct participant *pp)
{
/*
* When disposing a participant, it should be announced on both the
* non-secure and secure writers.
* The receiver will decide from which writer it accepts the dispose.
*/
int ret = spdp_dispose_unregister_with_wr(pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER);
if ((ret > 0) && q_omg_participant_is_secure(pp))
{
ret = spdp_dispose_unregister_with_wr(pp, NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER);
}
return ret;
}
static unsigned pseudo_random_delay (const ddsi_guid_t *x, const ddsi_guid_t *y, nn_mtime_t tnow)
{
/* You know, an ordinary random generator would be even better, but
@ -407,7 +425,7 @@ static void respond_to_spdp (const struct q_globals *gv, const ddsi_guid_t *dest
ephash_enum_participant_fini (&est);
}
static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo)
static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo)
{
struct q_globals * const gv = rst->gv;
ddsi_guid_t guid;
@ -419,6 +437,8 @@ static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t times
guid = datap->participant_guid;
GVLOGDISC (" %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (guid));
assert (guid.entityid.u == NN_ENTITYID_PARTICIPANT);
if (allow_proxy_participant_deletion(gv, &guid, pwr_entityid))
{
if (delete_proxy_participant_by_guid (gv, &guid, timestamp, 0) < 0)
{
GVLOGDISC (" unknown");
@ -429,6 +449,11 @@ static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t times
}
}
else
{
GVLOGDISC (" not allowed");
}
}
else
{
GVWARNING ("data (SPDP, vendor %u.%u): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]);
}
@ -793,7 +818,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, nn_
return 1;
}
static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
static void handle_SPDP (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, seqno_t seq, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len)
{
struct q_globals * const gv = rst->gv;
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
@ -832,7 +857,7 @@ static void handle_SPDP (const struct receiver_state *rst, seqno_t seq, nn_wctim
case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER:
case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER):
interesting = handle_SPDP_dead (rst, timestamp, &decoded_data, statusinfo);
interesting = handle_SPDP_dead (rst, pwr_entityid, timestamp, &decoded_data, statusinfo);
break;
}
@ -888,7 +913,7 @@ static int sedp_write_endpoint
(
struct writer *wr, int alive, const ddsi_guid_t *epguid,
const struct entity_common *common, const struct endpoint_common *epcommon,
const dds_qos_t *xqos, struct addrset *as)
const dds_qos_t *xqos, struct addrset *as, nn_security_info_t *security)
{
struct q_globals * const gv = wr->e.gv;
const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv->default_xqos_wr : &gv->default_xqos_rd;
@ -908,6 +933,17 @@ static int sedp_write_endpoint
ps.entity_name = common->name;
}
#ifdef DDSI_INCLUDE_SECURITY
if (security)
{
ps.present |= PP_ENDPOINT_SECURITY_INFO;
memcpy(&ps.endpoint_security_info, security, sizeof(nn_security_info_t));
}
#else
(void)security;
assert(security == NULL);
#endif
if (!alive)
{
assert (xqos == NULL);
@ -987,13 +1023,22 @@ int sedp_write_writer (struct writer *wr)
{
if ((!is_builtin_entityid(wr->e.guid.entityid, NN_VENDORID_ECLIPSE)) && (!wr->e.onlylocal))
{
struct writer *sedp_wr = get_sedp_writer (wr->c.pp, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER);
unsigned entityid = determine_publication_writer(wr);
struct writer *sedp_wr = get_sedp_writer (wr->c.pp, entityid);
nn_security_info_t *security = NULL;
#ifdef DDSI_INCLUDE_SSM
struct addrset *as = wr->ssm_as;
#else
struct addrset *as = NULL;
#endif
return sedp_write_endpoint (sedp_wr, 1, &wr->e.guid, &wr->e, &wr->c, wr->xqos, as);
#ifdef DDSI_INCLUDE_SECURITY
nn_security_info_t tmp;
if (q_omg_get_writer_security_info(wr, &tmp))
{
security = &tmp;
}
#endif
return sedp_write_endpoint (sedp_wr, 1, &wr->e.guid, &wr->e, &wr->c, wr->xqos, as, security);
}
return 0;
}
@ -1002,13 +1047,22 @@ int sedp_write_reader (struct reader *rd)
{
if ((!is_builtin_entityid (rd->e.guid.entityid, NN_VENDORID_ECLIPSE)) && (!rd->e.onlylocal))
{
struct writer *sedp_wr = get_sedp_writer (rd->c.pp, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER);
unsigned entityid = determine_subscription_writer(rd);
struct writer *sedp_wr = get_sedp_writer (rd->c.pp, entityid);
nn_security_info_t *security = NULL;
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
struct addrset *as = rd->as;
#else
struct addrset *as = NULL;
#endif
return sedp_write_endpoint (sedp_wr, 1, &rd->e.guid, &rd->e, &rd->c, rd->xqos, as);
#ifdef DDSI_INCLUDE_SECURITY
nn_security_info_t tmp;
if (q_omg_get_reader_security_info(rd, &tmp))
{
security = &tmp;
}
#endif
return sedp_write_endpoint (sedp_wr, 1, &rd->e.guid, &rd->e, &rd->c, rd->xqos, as, security);
}
return 0;
}
@ -1017,8 +1071,9 @@ int sedp_dispose_unregister_writer (struct writer *wr)
{
if ((!is_builtin_entityid(wr->e.guid.entityid, NN_VENDORID_ECLIPSE)) && (!wr->e.onlylocal))
{
struct writer *sedp_wr = get_sedp_writer (wr->c.pp, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER);
return sedp_write_endpoint (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL);
unsigned entityid = determine_publication_writer(wr);
struct writer *sedp_wr = get_sedp_writer (wr->c.pp, entityid);
return sedp_write_endpoint (sedp_wr, 0, &wr->e.guid, NULL, NULL, NULL, NULL, NULL);
}
return 0;
}
@ -1027,8 +1082,9 @@ int sedp_dispose_unregister_reader (struct reader *rd)
{
if ((!is_builtin_entityid(rd->e.guid.entityid, NN_VENDORID_ECLIPSE)) && (!rd->e.onlylocal))
{
struct writer *sedp_wr = get_sedp_writer (rd->c.pp, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER);
return sedp_write_endpoint (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL);
unsigned entityid = determine_subscription_writer(rd);
struct writer *sedp_wr = get_sedp_writer (rd->c.pp, entityid);
return sedp_write_endpoint (sedp_wr, 0, &rd->e.guid, NULL, NULL, NULL, NULL, NULL);
}
return 0;
}
@ -1594,7 +1650,13 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
pwr = sampleinfo->pwr;
if (pwr == NULL)
assert (srcguid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER);
{
/* NULL with NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER is normal. It is possible that
* NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER has NULL as well if there
* is a security mismatch being handled. */
assert ((srcguid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
(srcguid.entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER));
}
else
{
assert (is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor));
@ -1690,6 +1752,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
{
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER:
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
pid = PID_PARTICIPANT_GUID;
break;
case NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_WRITER:
@ -1698,6 +1761,8 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
pid = PID_ENDPOINT_GUID;
break;
case NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER:
@ -1736,18 +1801,27 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
switch (srcguid.entityid.u)
{
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:
handle_SPDP (sampleinfo->rst, sampleinfo->seq, timestamp, statusinfo, datap, datasz);
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
handle_SPDP (sampleinfo->rst, srcguid.entityid, sampleinfo->seq, timestamp, statusinfo, datap, datasz);
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
handle_SEDP (sampleinfo->rst, sampleinfo->seq, timestamp, statusinfo, datap, datasz);
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER:
handle_PMD (sampleinfo->rst, timestamp, statusinfo, datap, datasz);
break;
case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER:
handle_SEDP_CM (sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz);
break;
#ifdef DDSI_INCLUDE_SECURITY
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
/* TODO: Handshake */
break;
#endif
default:
GVLOGDISC ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": not handled\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],

View file

@ -48,6 +48,7 @@
#include "dds__whc.h"
#include "dds/ddsi/ddsi_iid.h"
#include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/ddsi_security_omg.h"
struct deleted_participant {
ddsrt_avl_node_t avlnode;
@ -461,6 +462,76 @@ static void pp_release_entityid(struct participant *pp, ddsi_entityid_t id)
ddsrt_mutex_unlock (&pp->e.lock);
}
static void force_as_disc_address(struct q_globals *gv, const ddsi_guid_t *subguid)
{
struct writer *wr = ephash_lookup_writer_guid (gv->guid_hash, subguid);
assert (wr != NULL);
ddsrt_mutex_lock (&wr->e.lock);
unref_addrset (wr->as);
unref_addrset (wr->as_group);
wr->as = ref_addrset (gv->as_disc);
wr->as_group = ref_addrset (gv->as_disc_group);
ddsrt_mutex_unlock (&wr->e.lock);
}
#ifdef DDSI_INCLUDE_SECURITY
static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *subguid, const ddsi_guid_t *group_guid, struct q_globals *gv, bool add_writers, bool add_readers)
{
if (add_writers)
{
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, 1, 1, 1), NULL, NULL);
/* But we need the as_disc address set for SPDP, because we need to
send it to everyone regardless of the existence of readers. */
force_as_disc_address(gv, subguid);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_stateless_xqos_wr, whc_new(gv, 0, 1, 1), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, 1, 1, 1), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, 1, 1, 1), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, 1, 1, 1), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER;
}
if (add_readers)
{
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR;
}
/*
* When security is enabled configure the associated necessary builtin readers independent of the
* besmode flag setting, because all participant do require authentication.
*/
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_stateless_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR;
}
#endif
dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *gv, unsigned flags, const nn_plist_t *plist)
{
struct participant *pp;
@ -591,16 +662,7 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->spdp_endpoint_xqos, whc_new(gv, 1, 1, 1), LAST_WR_PARAMS);
/* But we need the as_disc address set for SPDP, because we need to
send it to everyone regardless of the existence of readers. */
{
struct writer *wr = ephash_lookup_writer_guid (gv->guid_hash, &subguid);
assert (wr != NULL);
ddsrt_mutex_lock (&wr->e.lock);
unref_addrset (wr->as);
unref_addrset (wr->as_group);
wr->as = ref_addrset (gv->as_disc);
wr->as_group = ref_addrset (gv->as_disc_group);
ddsrt_mutex_unlock (&wr->e.lock);
}
force_as_disc_address(gv, &subguid);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER;
}
@ -679,6 +741,14 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct q_globals *
pp->prismtech_bes |= NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_READER;
}
#ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure(pp))
{
add_security_builtin_endpoints(pp, &subguid, &group_guid, gv, !(flags & RTPS_PF_NO_BUILTIN_WRITERS), !(flags & RTPS_PF_NO_BUILTIN_READERS));
}
#endif
#undef LAST_WR_PARAMS
/* If the participant doesn't have the full set of builtin writers
@ -830,6 +900,17 @@ static void unref_participant (struct participant *pp, const struct ddsi_guid *g
NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER,
NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER,
NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER,
/* Security ones: */
NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER,
NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER,
NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER,
NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER,
NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER,
NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER,
NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER,
NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER,
NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER,
NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER,
/* PrismTech ones: */
NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER,
NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_READER,
@ -913,7 +994,7 @@ static void unref_participant (struct participant *pp, const struct ddsi_guid *g
(pp->prismtech_bes & prismtech_builtin_writers_besmask) != prismtech_builtin_writers_besmask)
{
/* Participant doesn't have a full complement of built-in
writers, therefore, it relies on gv.privileged_pp, and
writers, therefore, it relies on gv->privileged_pp, and
therefore we must decrement the reference count of that one.
Why read it with the lock held, only to release it and use it
@ -1002,9 +1083,15 @@ struct writer *get_builtin_writer (const struct participant *pp, unsigned entity
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
bes_mask = NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER;
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
bes_mask = NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER;
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
bes_mask = NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
bes_mask = NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER:
bes_mask = NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
break;
@ -1020,6 +1107,15 @@ struct writer *get_builtin_writer (const struct participant *pp, unsigned entity
case NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER:
bes_mask = NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER;
break;
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
bes_mask = NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
bes_mask = NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER:
bes_mask = NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER;
break;
default:
DDS_FATAL ("get_builtin_writer called with entityid %x\n", entityid);
return NULL;
@ -1385,7 +1481,7 @@ void rebuild_or_clear_writer_addrsets (struct q_globals *gv, int rebuild)
else
{
/* SPDP writers have no matched readers, instead they all use the same address space,
gv.as_disc. Keep as_disc unchanged, and instead make the participants point to the
gv->as_disc. Keep as_disc unchanged, and instead make the participants point to the
empty one. */
unref_addrset(wr->as);
if (rebuild)
@ -2112,6 +2208,13 @@ static ddsi_entityid_t builtin_entityid_match (ddsi_entityid_t x)
res.u = NN_ENTITYID_UNKNOWN;
break;
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
res.u = NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER;
break;
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER:
res.u = NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER;
break;
case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_READER:
res.u = NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER;
break;
@ -2130,6 +2233,30 @@ static ddsi_entityid_t builtin_entityid_match (ddsi_entityid_t x)
case NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_WRITER:
res.u = NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_READER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
res.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER:
res.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER:
res.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER:
res.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER;
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
res.u = NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER;
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER:
res.u = NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER;
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
res.u = NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER;
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER:
res.u = NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER;
break;
default:
assert (0);
@ -2815,7 +2942,8 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
if (is_builtin_entityid (wr->e.guid.entityid, NN_VENDORID_ECLIPSE))
{
assert (wr->xqos->history.kind == DDS_HISTORY_KEEP_LAST);
assert (wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL);
assert (wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL ||
wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER);
}
wr->handle_as_transient_local = (wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL);
wr->include_keyhash =
@ -3614,6 +3742,158 @@ void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct
ddsrt_mutex_unlock (&proxypp->e.lock);
}
struct bestab {
unsigned besflag;
unsigned prismtech_besflag;
unsigned entityid;
};
static void create_proxy_builtin_endpoints(
struct q_globals *gv,
const struct bestab *bestab,
int nbes,
const struct ddsi_guid *ppguid,
struct proxy_participant *proxypp,
nn_wctime_t timestamp,
dds_qos_t *xqos_wr,
dds_qos_t *xqos_rd)
{
nn_plist_t plist_rd, plist_wr;
int i;
/* Note: no entity name or group GUID supplied, but that shouldn't
* matter, as these are internal to DDSI and don't use group
* coherency
*/
nn_plist_init_empty (&plist_wr);
nn_plist_init_empty (&plist_rd);
nn_xqos_copy (&plist_wr.qos, xqos_wr);
nn_xqos_copy (&plist_rd.qos, xqos_rd);
for (i = 0; i < nbes; i++)
{
const struct bestab *te = &bestab[i];
if ((proxypp->bes & te->besflag) || (proxypp->prismtech_bes & te->prismtech_besflag))
{
ddsi_guid_t guid1;
guid1.prefix = proxypp->e.guid.prefix;
guid1.entityid.u = te->entityid;
assert (is_builtin_entityid (guid1.entityid, proxypp->vendor));
if (is_writer_entityid (guid1.entityid))
{
new_proxy_writer (gv, ppguid, &guid1, proxypp->as_meta, &plist_wr, gv->builtins_dqueue, gv->xevents, timestamp, 0);
}
else
{
#ifdef DDSI_INCLUDE_SSM
const int ssm = addrset_contains_ssm (gv, proxypp->as_meta);
#else
const int ssm = 0;
#endif
new_proxy_reader (gv, ppguid, &guid1, proxypp->as_meta, &plist_rd, timestamp, 0, ssm);
}
}
}
nn_plist_fini (&plist_wr);
nn_plist_fini (&plist_rd);
}
static void add_proxy_builtin_endpoints(
struct q_globals *gv,
const struct ddsi_guid *ppguid,
struct proxy_participant *proxypp,
nn_wctime_t timestamp)
{
/* Add proxy endpoints based on the advertised (& possibly augmented
...) built-in endpoint set. */
#define PT_TE(ap_, a_, bp_, b_) { 0, NN_##ap_##BUILTIN_ENDPOINT_##a_, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define TE(ap_, a_, bp_, b_) { NN_##ap_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define LTE(a_, bp_, b_) { NN_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
/* 'Default' proxy endpoints. */
static const struct bestab bestab_default[] = {
#if 0
/* SPDP gets special treatment => no need for proxy
writers/readers */
TE (DISC_, PARTICIPANT_ANNOUNCER, SPDP, PARTICIPANT_WRITER),
#endif
TE (DISC_, PARTICIPANT_DETECTOR, SPDP, PARTICIPANT_READER),
TE (DISC_, PUBLICATION_ANNOUNCER, SEDP, PUBLICATIONS_WRITER),
TE (DISC_, PUBLICATION_DETECTOR, SEDP, PUBLICATIONS_READER),
TE (DISC_, SUBSCRIPTION_ANNOUNCER, SEDP, SUBSCRIPTIONS_WRITER),
TE (DISC_, SUBSCRIPTION_DETECTOR, SEDP, SUBSCRIPTIONS_READER),
LTE (PARTICIPANT_MESSAGE_DATA_WRITER, P2P, PARTICIPANT_MESSAGE_WRITER),
LTE (PARTICIPANT_MESSAGE_DATA_READER, P2P, PARTICIPANT_MESSAGE_READER),
TE (DISC_, TOPIC_ANNOUNCER, SEDP, TOPIC_WRITER),
TE (DISC_, TOPIC_DETECTOR, SEDP, TOPIC_READER),
PT_TE (DISC_, CM_PARTICIPANT_READER, SEDP, CM_PARTICIPANT_READER),
PT_TE (DISC_, CM_PARTICIPANT_WRITER, SEDP, CM_PARTICIPANT_WRITER),
PT_TE (DISC_, CM_PUBLISHER_READER, SEDP, CM_PUBLISHER_READER),
PT_TE (DISC_, CM_PUBLISHER_WRITER, SEDP, CM_PUBLISHER_WRITER),
PT_TE (DISC_, CM_SUBSCRIBER_READER, SEDP, CM_SUBSCRIBER_READER),
PT_TE (DISC_, CM_SUBSCRIBER_WRITER, SEDP, CM_SUBSCRIBER_WRITER)
};
create_proxy_builtin_endpoints(gv,
bestab_default,
(int)(sizeof (bestab_default) / sizeof (*bestab_default)),
ppguid,
proxypp,
timestamp,
&gv->builtin_endpoint_xqos_wr,
&gv->builtin_endpoint_xqos_rd);
#ifdef DDSI_INCLUDE_SECURITY
/* Security 'default' proxy endpoints. */
static const struct bestab bestab_security[] = {
LTE (PUBLICATION_MESSAGE_SECURE_ANNOUNCER, SEDP, PUBLICATIONS_SECURE_WRITER),
LTE (PUBLICATION_MESSAGE_SECURE_DETECTOR, SEDP, PUBLICATIONS_SECURE_READER),
LTE (SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER, SEDP, SUBSCRIPTIONS_SECURE_WRITER),
LTE (SUBSCRIPTION_MESSAGE_SECURE_DETECTOR, SEDP, SUBSCRIPTIONS_SECURE_READER),
LTE (PARTICIPANT_MESSAGE_SECURE_ANNOUNCER, P2P, PARTICIPANT_MESSAGE_SECURE_WRITER),
LTE (PARTICIPANT_MESSAGE_SECURE_DETECTOR, P2P, PARTICIPANT_MESSAGE_SECURE_READER),
TE (DISC_, PARTICIPANT_SECURE_ANNOUNCER, SPDP_RELIABLE, PARTICIPANT_SECURE_WRITER),
TE (DISC_, PARTICIPANT_SECURE_DETECTOR, SPDP_RELIABLE, PARTICIPANT_SECURE_READER)
};
create_proxy_builtin_endpoints(gv,
bestab_security,
(int)(sizeof (bestab_security) / sizeof (*bestab_security)),
ppguid,
proxypp,
timestamp,
&gv->builtin_endpoint_xqos_wr,
&gv->builtin_endpoint_xqos_rd);
/* Security 'stateless' proxy endpoints. */
static const struct bestab bestab_stateless[] = {
LTE (PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER, P2P, PARTICIPANT_STATELESS_MESSAGE_WRITER),
LTE (PARTICIPANT_STATELESS_MESSAGE_DETECTOR, P2P, PARTICIPANT_STATELESS_MESSAGE_READER)
};
create_proxy_builtin_endpoints(gv,
bestab_stateless,
(int)(sizeof (bestab_stateless) / sizeof (*bestab_stateless)),
ppguid,
proxypp,
timestamp,
&gv->builtin_stateless_xqos_wr,
&gv->builtin_stateless_xqos_rd);
#endif
/* Register lease, but be careful not to accidentally re-register
DDSI2's lease, as we may have become dependent on DDSI2 any time
after ephash_insert_proxy_participant_guid even if
privileged_pp_guid was NULL originally */
ddsrt_mutex_lock (&proxypp->e.lock);
if (proxypp->owns_lease)
lease_register (ddsrt_atomic_ldvoidp (&proxypp->lease));
builtintopic_write (gv->builtin_topic_interface, &proxypp->e, timestamp, true);
ddsrt_mutex_unlock (&proxypp->e.lock);
#undef PT_TE
#undef TE
#undef LTE
}
void new_proxy_participant
(
struct q_globals *gv,
@ -3720,89 +4000,8 @@ void new_proxy_participant
new_proxy_{writer,reader} to work */
ephash_insert_proxy_participant_guid (gv->guid_hash, proxypp);
/* Add proxy endpoints based on the advertised (& possibly augmented
...) built-in endpoint set. */
{
#define PT_TE(ap_, a_, bp_, b_) { 0, NN_##ap_##BUILTIN_ENDPOINT_##a_, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define TE(ap_, a_, bp_, b_) { NN_##ap_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
#define LTE(a_, bp_, b_) { NN_##BUILTIN_ENDPOINT_##a_, 0, NN_ENTITYID_##bp_##_BUILTIN_##b_ }
static const struct bestab {
unsigned besflag;
unsigned prismtech_besflag;
unsigned entityid;
} bestab[] = {
#if 0
/* SPDP gets special treatment => no need for proxy
writers/readers */
TE (DISC_, PARTICIPANT_ANNOUNCER, SPDP, PARTICIPANT_WRITER),
#endif
TE (DISC_, PARTICIPANT_DETECTOR, SPDP, PARTICIPANT_READER),
TE (DISC_, PUBLICATION_ANNOUNCER, SEDP, PUBLICATIONS_WRITER),
TE (DISC_, PUBLICATION_DETECTOR, SEDP, PUBLICATIONS_READER),
TE (DISC_, SUBSCRIPTION_ANNOUNCER, SEDP, SUBSCRIPTIONS_WRITER),
TE (DISC_, SUBSCRIPTION_DETECTOR, SEDP, SUBSCRIPTIONS_READER),
LTE (PARTICIPANT_MESSAGE_DATA_WRITER, P2P, PARTICIPANT_MESSAGE_WRITER),
LTE (PARTICIPANT_MESSAGE_DATA_READER, P2P, PARTICIPANT_MESSAGE_READER),
TE (DISC_, TOPIC_ANNOUNCER, SEDP, TOPIC_WRITER),
TE (DISC_, TOPIC_DETECTOR, SEDP, TOPIC_READER),
PT_TE (DISC_, CM_PARTICIPANT_READER, SEDP, CM_PARTICIPANT_READER),
PT_TE (DISC_, CM_PARTICIPANT_WRITER, SEDP, CM_PARTICIPANT_WRITER),
PT_TE (DISC_, CM_PUBLISHER_READER, SEDP, CM_PUBLISHER_READER),
PT_TE (DISC_, CM_PUBLISHER_WRITER, SEDP, CM_PUBLISHER_WRITER),
PT_TE (DISC_, CM_SUBSCRIBER_READER, SEDP, CM_SUBSCRIBER_READER),
PT_TE (DISC_, CM_SUBSCRIBER_WRITER, SEDP, CM_SUBSCRIBER_WRITER)
};
#undef PT_TE
#undef TE
#undef LTE
nn_plist_t plist_rd, plist_wr;
int i;
/* Note: no entity name or group GUID supplied, but that shouldn't
matter, as these are internal to DDSI and don't use group
coherency */
nn_plist_init_empty (&plist_wr);
nn_plist_init_empty (&plist_rd);
nn_xqos_copy (&plist_wr.qos, &gv->builtin_endpoint_xqos_wr);
nn_xqos_copy (&plist_rd.qos, &gv->builtin_endpoint_xqos_rd);
for (i = 0; i < (int) (sizeof (bestab) / sizeof (*bestab)); i++)
{
const struct bestab *te = &bestab[i];
if ((proxypp->bes & te->besflag) || (proxypp->prismtech_bes & te->prismtech_besflag))
{
ddsi_guid_t guid1;
guid1.prefix = proxypp->e.guid.prefix;
guid1.entityid.u = te->entityid;
assert (is_builtin_entityid (guid1.entityid, proxypp->vendor));
if (is_writer_entityid (guid1.entityid))
{
new_proxy_writer (gv, ppguid, &guid1, proxypp->as_meta, &plist_wr, gv->builtins_dqueue, gv->xevents, timestamp, 0);
}
else
{
#ifdef DDSI_INCLUDE_SSM
const int ssm = addrset_contains_ssm (gv, proxypp->as_meta);
new_proxy_reader (gv, ppguid, &guid1, proxypp->as_meta, &plist_rd, timestamp, 0, ssm);
#else
new_proxy_reader (gv, ppguid, &guid1, proxypp->as_meta, &plist_rd, timestamp, 0);
#endif
}
}
}
nn_plist_fini (&plist_wr);
nn_plist_fini (&plist_rd);
}
/* Register lease, but be careful not to accidentally re-register
DDSI2's lease, as we may have become dependent on DDSI2 any time
after ephash_insert_proxy_participant_guid even if
privileged_pp_guid was NULL originally */
ddsrt_mutex_lock (&proxypp->e.lock);
if (proxypp->owns_lease)
lease_register (ddsrt_atomic_ldvoidp (&proxypp->lease));
builtintopic_write (gv->builtin_topic_interface, &proxypp->e, timestamp, true);
ddsrt_mutex_unlock (&proxypp->e.lock);
/* TODO: Do security checks on the proxy participant. Either add the endpoints or delete the proxy. */
add_proxy_builtin_endpoints(gv, ppguid, proxypp, timestamp);
}
int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp)
@ -4104,12 +4303,27 @@ static void proxy_endpoint_common_fini (struct entity_common *e, struct proxy_en
/* PROXY-WRITER ----------------------------------------------------- */
static enum nn_reorder_mode
get_proxy_writer_reorder_mode(const ddsi_entityid_t pwr_entityid, int isreliable)
{
if (isreliable)
{
return NN_REORDER_MODE_NORMAL;
}
if (pwr_entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)
{
return NN_REORDER_MODE_ALWAYS_DELIVER;
}
return NN_REORDER_MODE_MONOTONICALLY_INCREASING;
}
int new_proxy_writer (struct q_globals *gv, const struct ddsi_guid *ppguid, const struct ddsi_guid *guid, struct addrset *as, const nn_plist_t *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp, seqno_t seq)
{
struct proxy_participant *proxypp;
struct proxy_writer *pwr;
int isreliable;
nn_mtime_t tnow = now_mt ();
enum nn_reorder_mode reorder_mode;
assert (is_writer_entityid (guid->entityid));
assert (ephash_lookup_proxy_writer_guid (gv->guid_hash, guid) == NULL);
@ -4168,13 +4382,13 @@ int new_proxy_writer (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
if (isreliable)
{
pwr->defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_LATEST, gv->config.defrag_reliable_maxsamples);
pwr->reorder = nn_reorder_new (&gv->logconfig, NN_REORDER_MODE_NORMAL, gv->config.primary_reorder_maxsamples, gv->config.late_ack_mode);
}
else
{
pwr->defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples);
pwr->reorder = nn_reorder_new (&gv->logconfig, NN_REORDER_MODE_MONOTONICALLY_INCREASING, gv->config.primary_reorder_maxsamples, gv->config.late_ack_mode);
}
reorder_mode = get_proxy_writer_reorder_mode(pwr->e.guid.entityid, isreliable);
pwr->reorder = nn_reorder_new (&gv->logconfig, reorder_mode, gv->config.primary_reorder_maxsamples, gv->config.late_ack_mode);
pwr->dqueue = dqueue;
pwr->evq = evq;
pwr->ddsi2direct_cb = 0;

View file

@ -1013,6 +1013,12 @@ int rtps_init (struct q_globals *gv)
gv->spdp_endpoint_xqos.durability.kind = DDS_DURABILITY_TRANSIENT_LOCAL;
make_builtin_endpoint_xqos (&gv->builtin_endpoint_xqos_rd, &gv->default_xqos_rd);
make_builtin_endpoint_xqos (&gv->builtin_endpoint_xqos_wr, &gv->default_xqos_wr);
#ifdef DDSI_INCLUDE_SECURITY
nn_xqos_copy (&gv->builtin_stateless_xqos_rd, &gv->default_xqos_rd);
nn_xqos_copy (&gv->builtin_stateless_xqos_wr, &gv->default_xqos_wr);
gv->builtin_stateless_xqos_wr.reliability.kind = DDS_RELIABILITY_BEST_EFFORT;
gv->builtin_stateless_xqos_wr.durability.kind = DDS_DURABILITY_VOLATILE;
#endif
make_special_topics (gv);
@ -1329,6 +1335,10 @@ err_unicast_sockets:
ddsrt_cond_destroy (&gv->participant_set_cond);
ddsrt_mutex_destroy (&gv->participant_set_lock);
free_special_topics (gv);
#ifdef DDSI_INCLUDE_SECURITY
nn_xqos_fini (&gv->builtin_stateless_xqos_wr);
nn_xqos_fini (&gv->builtin_stateless_xqos_rd);
#endif
nn_xqos_fini (&gv->builtin_endpoint_xqos_wr);
nn_xqos_fini (&gv->builtin_endpoint_xqos_rd);
nn_xqos_fini (&gv->spdp_endpoint_xqos);
@ -1657,6 +1667,10 @@ void rtps_fini (struct q_globals *gv)
ddsrt_cond_destroy (&gv->participant_set_cond);
free_special_topics (gv);
#ifdef DDSI_INCLUDE_SECURITY
nn_xqos_fini (&gv->builtin_stateless_xqos_wr);
nn_xqos_fini (&gv->builtin_stateless_xqos_rd);
#endif
nn_xqos_fini (&gv->builtin_endpoint_xqos_wr);
nn_xqos_fini (&gv->builtin_endpoint_xqos_rd);
nn_xqos_fini (&gv->spdp_endpoint_xqos);

View file

@ -2305,7 +2305,8 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con
/* No proxy writer means nothing really gets done with, unless it
is SPDP. SPDP is periodic, so oversize discovery packets would
cause periodic warnings. */
if (msg->writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
if ((msg->writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
(msg->writerId.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER))
{
DDS_CWARNING (&rst->gv->logconfig, "dropping oversize (%"PRIu32" > %"PRIu32") SPDP sample %"PRId64" from remote writer "PGUIDFMT"\n",
sampleinfo->size, rst->gv->config.max_sample_size, sampleinfo->seq,
@ -2374,7 +2375,8 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r
}
rdata = nn_rdata_new (rmsg, 0, sampleinfo->size, submsg_offset, payload_offset);
if (msg->x.writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
if ((msg->x.writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
(msg->x.writerId.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER))
/* SPDP needs special treatment: there are no proxy writers for it
and we accept data from unknown sources */
{
@ -2409,7 +2411,8 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct
struct nn_rdata *rdata;
unsigned submsg_offset, payload_offset;
uint32_t begin, endp1;
if (msg->x.writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)
if ((msg->x.writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
(msg->x.writerId.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER))
{
DDS_CWARNING (&rst->gv->logconfig, "DATAFRAG("PGUIDFMT" #%"PRId64" -> "PGUIDFMT") - fragmented builtin data not yet supported\n",
PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, fromSN (msg->x.writerSN),

View file

@ -884,7 +884,9 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct nn_plist
res = 1;
#ifndef NDEBUG
if (wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER && !is_local_orphan_endpoint (&wr->e))
if (((wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
(wr->e.guid.entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER)) &&
!is_local_orphan_endpoint (&wr->e))
{
struct whc_state whcst;
whc_get_state(wr->whc, &whcst);