Clean up representation of discovery messages

* Remove the "plist" and "rawcdr" abuse of the "serdata_default" sample
  representation.

* Introduce a new "plist" topic type and a new "pserop" topic type.  The
  former represents parameter lists as used in discovery, the second
  arbitrary samples using the serialiser in ddsi_plist.c.

* Introduce sertopics for each of the built-in "topics" used by the DDSI
  discovery protocol using the two new topic types, and reference these
  in the readers/writers used in discovery.

* Construct and deconstruct the discovery message by using the
  conversion routines for these sample types, rather than fiddling with,
  e.g., the baroque interface for adding parameter lists to messages.

* As a consequence, it introduces standardized logging of received and
  transmitted discovery data and eliminates the annoying "(null)/(null)"
  and "(blob)" descriptions in the trace.

* Limits the dumping of octet sequences in discovery data to the first
  100 bytes to make the embedded certificates and permissions
  documents (somewhat) manageable.

* Eliminates the (many) null pointer checks on reader/writer topics.

* Fixes the printing of nested sequences in discovery data (not used
  before) and the formatting of GUIDs.

Various interfaces remain unchanged and so while this removes cruft from
the core code, it moves some of it into the conversion routines for the
new topic types.

It also now allocates some memory when processing incoming discovery
data, whereas before it had no need to do so.  Allowing for aliasing of
data in the new sertopics and adding a way to initialize these specific
types on the stack (both minor changes) suffices for eliminating those
allocations.

Signed-off-by: Erik Boasson <eb@ilities.com>

Check actual topic type before "downcasting"

Signed-off-by: Erik Boasson <eb@ilities.com>

Free the memory we own and is actually allocated

Signed-off-by: Erik Boasson <eb@ilities.com>

Ignore logging newlines if nothing is buffered

Signed-off-by: Erik Boasson <eb@ilities.com>

Suffix data with "(trunc)" one byte earlier

The sample printing code changed over time and now stops as soon as it
can once it has filled up the buffer.  As the return value is simply the
number of bytes written, if that number is equal to buffer size less
one (because of the terminating nul) it may or may not have been
truncated, but the likelihood is that it has been.  So add the "(trunc)"
suffix once that point has been reached.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-03-23 11:59:43 +01:00 committed by eboasson
parent b18fd395d3
commit 4f3cbf7a1c
38 changed files with 1489 additions and 1252 deletions

View file

@ -451,7 +451,7 @@ The default value is: "dds_security_crypto".
### //CycloneDDS/Domain/Discovery ### //CycloneDDS/Domain/Discovery
Children: [DSGracePeriod](#cycloneddsdomaindiscoverydsgraceperiod), [DefaultMulticastAddress](#cycloneddsdomaindiscoverydefaultmulticastaddress), [EnableTopicDiscovery](#cycloneddsdomaindiscoveryenabletopicdiscovery), [ExternalDomainId](#cycloneddsdomaindiscoveryexternaldomainid), [MaxAutoParticipantIndex](#cycloneddsdomaindiscoverymaxautoparticipantindex), [ParticipantIndex](#cycloneddsdomaindiscoveryparticipantindex), [Peers](#cycloneddsdomaindiscoverypeers), [Ports](#cycloneddsdomaindiscoveryports), [SPDPInterval](#cycloneddsdomaindiscoveryspdpinterval), [SPDPMulticastAddress](#cycloneddsdomaindiscoveryspdpmulticastaddress), [Tag](#cycloneddsdomaindiscoverytag) Children: [DSGracePeriod](#cycloneddsdomaindiscoverydsgraceperiod), [DefaultMulticastAddress](#cycloneddsdomaindiscoverydefaultmulticastaddress), [ExternalDomainId](#cycloneddsdomaindiscoveryexternaldomainid), [MaxAutoParticipantIndex](#cycloneddsdomaindiscoverymaxautoparticipantindex), [ParticipantIndex](#cycloneddsdomaindiscoveryparticipantindex), [Peers](#cycloneddsdomaindiscoverypeers), [Ports](#cycloneddsdomaindiscoveryports), [SPDPInterval](#cycloneddsdomaindiscoveryspdpinterval), [SPDPMulticastAddress](#cycloneddsdomaindiscoveryspdpmulticastaddress), [Tag](#cycloneddsdomaindiscoverytag)
The Discovery element allows specifying various parameters related to the The Discovery element allows specifying various parameters related to the
@ -482,14 +482,6 @@ Discovery/SPDPMulticastAddress.
The default value is: "auto". The default value is: "auto".
#### //CycloneDDS/Domain/Discovery/EnableTopicDiscovery
Boolean
Do not use.
The default value is: "true".
#### //CycloneDDS/Domain/Discovery/ExternalDomainId #### //CycloneDDS/Domain/Discovery/ExternalDomainId
Text Text

View file

@ -407,11 +407,6 @@ Discovery/SPDPMulticastAddress.</p><p>The default value is:
text text
}? }?
& [ a:documentation [ xml:lang="en" """ & [ a:documentation [ xml:lang="en" """
<p>Do not use.</p><p>The default value is: &quot;true&quot;.</p>""" ] ]
element EnableTopicDiscovery {
xsd:boolean
}?
& [ a:documentation [ xml:lang="en" """
<p>An override for the domain id, to be used in discovery and for <p>An override for the domain id, to be used in discovery and for
determining the port number mapping. This allows creating multiple determining the port number mapping. This allows creating multiple
domains in a single process while making them appear as a single domain domains in a single process while making them appear as a single domain

View file

@ -522,7 +522,6 @@ the discovery of peers.&lt;/p&gt;</xs:documentation>
<xs:all> <xs:all>
<xs:element minOccurs="0" ref="config:DSGracePeriod"/> <xs:element minOccurs="0" ref="config:DSGracePeriod"/>
<xs:element minOccurs="0" ref="config:DefaultMulticastAddress"/> <xs:element minOccurs="0" ref="config:DefaultMulticastAddress"/>
<xs:element minOccurs="0" ref="config:EnableTopicDiscovery"/>
<xs:element minOccurs="0" ref="config:ExternalDomainId"/> <xs:element minOccurs="0" ref="config:ExternalDomainId"/>
<xs:element minOccurs="0" ref="config:MaxAutoParticipantIndex"/> <xs:element minOccurs="0" ref="config:MaxAutoParticipantIndex"/>
<xs:element minOccurs="0" ref="config:ParticipantIndex"/> <xs:element minOccurs="0" ref="config:ParticipantIndex"/>
@ -556,12 +555,6 @@ Discovery/SPDPMulticastAddress.&lt;/p&gt;&lt;p&gt;The default value is:
&amp;quot;auto&amp;quot;.&lt;/p&gt;</xs:documentation> &amp;quot;auto&amp;quot;.&lt;/p&gt;</xs:documentation>
</xs:annotation> </xs:annotation>
</xs:element> </xs:element>
<xs:element name="EnableTopicDiscovery" type="xs:boolean">
<xs:annotation>
<xs:documentation>
&lt;p&gt;Do not use.&lt;/p&gt;&lt;p&gt;The default value is: &amp;quot;true&amp;quot;.&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="ExternalDomainId" type="xs:string"> <xs:element name="ExternalDomainId" type="xs:string">
<xs:annotation> <xs:annotation>
<xs:documentation> <xs:documentation>

View file

@ -247,6 +247,7 @@ static dds_return_t lookup_and_check_ktopic (struct dds_ktopic **ktp_out, dds_pa
static dds_entity_t create_topic_pp_locked (struct dds_participant *pp, struct dds_ktopic *ktp, bool implicit, struct ddsi_sertopic *sertopic_registered, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist) static dds_entity_t create_topic_pp_locked (struct dds_participant *pp, struct dds_ktopic *ktp, bool implicit, struct ddsi_sertopic *sertopic_registered, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
{ {
(void) sedp_plist;
dds_entity_t hdl; dds_entity_t hdl;
dds_topic *tp = dds_alloc (sizeof (*tp)); dds_topic *tp = dds_alloc (sizeof (*tp));
hdl = dds_entity_init (&tp->m_entity, &pp->m_entity, DDS_KIND_TOPIC, implicit, NULL, listener, DDS_TOPIC_STATUS_MASK); hdl = dds_entity_init (&tp->m_entity, &pp->m_entity, DDS_KIND_TOPIC, implicit, NULL, listener, DDS_TOPIC_STATUS_MASK);
@ -254,25 +255,6 @@ static dds_entity_t create_topic_pp_locked (struct dds_participant *pp, struct d
dds_entity_register_child (&pp->m_entity, &tp->m_entity); dds_entity_register_child (&pp->m_entity, &tp->m_entity);
tp->m_ktopic = ktp; tp->m_ktopic = ktp;
tp->m_stopic = sertopic_registered; tp->m_stopic = sertopic_registered;
/* Publish Topic */
if (sedp_plist)
{
struct participant *ddsi_pp;
ddsi_plist_t plist;
thread_state_awake (lookup_thread_state (), &pp->m_entity.m_domain->gv);
ddsi_pp = entidx_lookup_participant_guid (pp->m_entity.m_domain->gv.entity_index, &pp->m_entity.m_guid);
assert (ddsi_pp);
ddsi_plist_init_empty (&plist);
ddsi_plist_mergein_missing (&plist, sedp_plist, ~(uint64_t)0, ~(uint64_t)0);
ddsi_xqos_mergein_missing (&plist.qos, ktp->qos, ~(uint64_t)0);
sedp_write_topic (ddsi_pp, &plist);
ddsi_plist_fini (&plist);
thread_state_asleep (lookup_thread_state ());
}
dds_entity_init_complete (&tp->m_entity); dds_entity_init_complete (&tp->m_entity);
return hdl; return hdl;
} }

View file

@ -24,8 +24,12 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
ddsi_handshake.c ddsi_handshake.c
ddsi_serdata.c ddsi_serdata.c
ddsi_serdata_default.c ddsi_serdata_default.c
ddsi_serdata_pserop.c
ddsi_serdata_plist.c
ddsi_sertopic.c ddsi_sertopic.c
ddsi_sertopic_default.c ddsi_sertopic_default.c
ddsi_sertopic_pserop.c
ddsi_sertopic_plist.c
ddsi_iid.c ddsi_iid.c
ddsi_tkmap.c ddsi_tkmap.c
ddsi_vendor.c ddsi_vendor.c
@ -91,6 +95,8 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
ddsi_serdata.h ddsi_serdata.h
ddsi_sertopic.h ddsi_sertopic.h
ddsi_serdata_default.h ddsi_serdata_default.h
ddsi_serdata_pserop.h
ddsi_serdata_plist.h
ddsi_iid.h ddsi_iid.h
ddsi_tkmap.h ddsi_tkmap.h
ddsi_vendor.h ddsi_vendor.h

View file

@ -294,8 +294,18 @@ struct ddsi_domaingv {
transmit queue*/ transmit queue*/
struct serdatapool *serpool; struct serdatapool *serpool;
struct nn_xmsgpool *xmsgpool; struct nn_xmsgpool *xmsgpool;
struct ddsi_sertopic *plist_topic; /* used for all discovery data */ struct ddsi_sertopic *spdp_topic; /* key = participant GUID */
struct ddsi_sertopic *rawcdr_topic; /* used for participant message data */ struct ddsi_sertopic *sedp_reader_topic; /* key = endpoint GUID */
struct ddsi_sertopic *sedp_writer_topic; /* key = endpoint GUID */
struct ddsi_sertopic *pmd_topic; /* participant message data */
#ifdef DDSI_INCLUDE_SECURITY
struct ddsi_sertopic *spdp_secure_topic; /* key = participant GUID */
struct ddsi_sertopic *sedp_reader_secure_topic; /* key = endpoint GUID */
struct ddsi_sertopic *sedp_writer_secure_topic; /* key = endpoint GUID */
struct ddsi_sertopic *pmd_secure_topic; /* participant message data */
struct ddsi_sertopic *pgm_stateless_topic; /* participant generic message */
struct ddsi_sertopic *pgm_volatile_topic; /* participant generic message */
#endif
ddsrt_mutex_t sendq_lock; ddsrt_mutex_t sendq_lock;
ddsrt_cond_t sendq_cond; ddsrt_cond_t sendq_cond;

View file

@ -311,7 +311,7 @@ struct nn_rsample_info;
struct nn_rdata; struct nn_rdata;
DDS_EXPORT unsigned char *ddsi_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const ddsi_plist_src_t *src); DDS_EXPORT unsigned char *ddsi_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const ddsi_plist_src_t *src);
DDS_EXPORT const unsigned char *ddsi_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid); DDS_EXPORT dds_return_t ddsi_plist_findparam_checking (const void *buf, size_t bufsz, uint16_t encoding, nn_parameterid_t needle, void **needlep, size_t *needlesz);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -19,6 +19,7 @@
#include "dds/export.h" #include "dds/export.h"
#include "dds/ddsrt/attributes.h" #include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -48,9 +49,11 @@ enum pserop {
DDS_EXPORT void plist_fini_generic (void * __restrict dst, const enum pserop *desc, bool aliased); DDS_EXPORT void plist_fini_generic (void * __restrict dst, const enum pserop *desc, bool aliased);
DDS_EXPORT dds_return_t plist_deser_generic (void * __restrict dst, const void * __restrict src, size_t srcsize, bool bswap, const enum pserop * __restrict desc); DDS_EXPORT dds_return_t plist_deser_generic (void * __restrict dst, const void * __restrict src, size_t srcsize, bool bswap, const enum pserop * __restrict desc);
DDS_EXPORT dds_return_t plist_ser_generic (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc); DDS_EXPORT dds_return_t plist_ser_generic (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc);
DDS_EXPORT dds_return_t plist_ser_generic_be (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc);
DDS_EXPORT dds_return_t plist_unalias_generic (void * __restrict dst, const enum pserop * __restrict desc); DDS_EXPORT dds_return_t plist_unalias_generic (void * __restrict dst, const enum pserop * __restrict desc);
DDS_EXPORT bool plist_equal_generic (const void *srcx, const void *srcy, const enum pserop * __restrict desc); DDS_EXPORT bool plist_equal_generic (const void *srcx, const void *srcy, const enum pserop * __restrict desc);
DDS_EXPORT size_t plist_memsize_generic (const enum pserop * __restrict desc); DDS_EXPORT size_t plist_memsize_generic (const enum pserop * __restrict desc);
DDS_EXPORT size_t plist_print_generic (char * __restrict buf, size_t bufsize, const void * __restrict src, const enum pserop * __restrict desc);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -12,7 +12,12 @@
#ifndef DDSI_PMD_H #ifndef DDSI_PMD_H
#define DDSI_PMD_H #define DDSI_PMD_H
#include <stdint.h>
#include "dds/ddsrt/time.h" #include "dds/ddsrt/time.h"
#include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#include "dds/ddsi/ddsi_guid.h"
#include "dds/ddsi/ddsi_xqos.h"
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
@ -25,9 +30,20 @@ struct nn_xpack;
struct participant; struct participant;
struct receiver_state; struct receiver_state;
typedef struct ParticipantMessageData {
ddsi_guid_prefix_t participantGuidPrefix;
uint32_t kind; /* really 4 octets */
ddsi_octetseq_t value;
} ParticipantMessageData_t;
extern const enum pserop participant_message_data_ops[];
extern size_t participant_message_data_nops;
extern const enum pserop participant_message_data_ops_key[];
extern size_t participant_message_data_nops_key;
void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind); void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind);
void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, struct participant *pp, unsigned pmd_kind); void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, struct participant *pp, unsigned pmd_kind);
void handle_pmd_message (const struct receiver_state *rst, ddsrt_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len); void handle_pmd_message (const struct receiver_state *rst, struct ddsi_serdata *sample_common);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -29,8 +29,8 @@ extern "C" {
#define GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS "dds.sec.datareader_crypto_tokens" #define GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS "dds.sec.datareader_crypto_tokens"
bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id); bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id);
void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len); void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, struct ddsi_serdata *sample);
void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len); void handle_crypto_exchange_message(const struct receiver_state *rst, struct ddsi_serdata *sample);
void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq); void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq);
bool write_crypto_participant_tokens(const struct participant *pp, const struct proxy_participant *proxypp, const nn_dataholderseq_t *tokens); bool write_crypto_participant_tokens(const struct participant *pp, const struct proxy_participant *proxypp, const nn_dataholderseq_t *tokens);
bool write_crypto_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens); bool write_crypto_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens);

View file

@ -95,6 +95,7 @@ nn_participant_generic_message_serialize(
size_t *len); size_t *len);
DDS_EXPORT extern const enum pserop pserop_participant_generic_message[]; DDS_EXPORT extern const enum pserop pserop_participant_generic_message[];
DDS_EXPORT extern const size_t pserop_participant_generic_message_nops;
DDS_EXPORT int DDS_EXPORT int
volatile_secure_data_filter( volatile_secure_data_filter(

View file

@ -18,6 +18,7 @@
#include "dds/ddsrt/avl.h" #include "dds/ddsrt/avl.h"
#include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_sertopic.h" #include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#include "dds/dds.h" #include "dds/dds.h"
@ -136,8 +137,6 @@ extern DDS_EXPORT const struct ddsi_sertopic_ops ddsi_sertopic_ops_default;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_cdr; extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_cdr;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey; extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_plist;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr;
struct serdatapool * ddsi_serdatapool_new (void); struct serdatapool * ddsi_serdatapool_new (void);
void ddsi_serdatapool_free (struct serdatapool * pool); void ddsi_serdatapool_free (struct serdatapool * pool);

View file

@ -0,0 +1,76 @@
/*
* 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_SERDATA_PLIST_H
#define DDSI_SERDATA_PLIST_H
#include "dds/ddsi/q_protocol.h" /* for nn_parameterid_t */
#include "dds/ddsi/ddsi_keyhash.h"
#include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_sertopic.h"
#include "dds/dds.h"
#if defined (__cplusplus)
extern "C" {
#endif
/* There is an alignment requirement on the raw data (it must be at
offset mod 8 for the conversion to/from a dds_stream to work).
So we define two types: one without any additional padding, and
one where the appropriate amount of padding is inserted */
#define DDSI_SERDATA_PLIST_PREPAD \
struct ddsi_serdata c; \
uint32_t pos; \
uint32_t size; \
nn_vendorid_t vendorid; \
nn_protocol_version_t protoversion; \
ddsi_keyhash_t keyhash
#define DDSI_SERDATA_PLIST_POSTPAD \
uint16_t identifier; \
uint16_t options; \
char data[]
struct ddsi_serdata_plist_unpadded {
DDSI_SERDATA_PLIST_PREPAD;
DDSI_SERDATA_PLIST_POSTPAD;
};
#ifdef __GNUC__
#define DDSI_SERDATA_PLIST_PAD(n) ((n) % 8)
#else
#define DDSI_SERDATA_PLIST_PAD(n) (n)
#endif
struct ddsi_serdata_plist {
DDSI_SERDATA_PLIST_PREPAD;
char pad[DDSI_SERDATA_PLIST_PAD (8 - (offsetof (struct ddsi_serdata_plist_unpadded, data) % 8))];
DDSI_SERDATA_PLIST_POSTPAD;
};
#undef DDSI_SERDATA_PLIST_PAD
#undef DDSI_SERDATA_PLIST_POSTPAD
#undef DDSI_SERDATA_PLIST_PREPAD
struct ddsi_sertopic_plist {
struct ddsi_sertopic c;
uint16_t native_encoding_identifier; /* PL_CDR_(LE|BE) */
nn_parameterid_t keyparam;
};
extern DDS_EXPORT const struct ddsi_sertopic_ops ddsi_sertopic_ops_plist;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_plist;
#if defined (__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,78 @@
/*
* 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_SERDATA_PSEROP_H
#define DDSI_SERDATA_PSEROP_H
#include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#include "dds/dds.h"
#if defined (__cplusplus)
extern "C" {
#endif
/* There is an alignment requirement on the raw data (it must be at
offset mod 8 for the conversion to/from a dds_stream to work).
So we define two types: one without any additional padding, and
one where the appropriate amount of padding is inserted */
#define DDSI_SERDATA_PSEROP_PREPAD \
struct ddsi_serdata c; \
void *sample; \
bool keyless; /*cached from topic*/ \
uint32_t pos; \
uint32_t size
#define DDSI_SERDATA_PSEROP_POSTPAD \
uint16_t identifier; \
uint16_t options; \
char data[]
struct ddsi_serdata_pserop_unpadded {
DDSI_SERDATA_PSEROP_PREPAD;
DDSI_SERDATA_PSEROP_POSTPAD;
};
#ifdef __GNUC__
#define DDSI_SERDATA_PSEROP_PAD(n) ((n) % 8)
#else
#define DDSI_SERDATA_PSEROP_PAD(n) (n)
#endif
struct ddsi_serdata_pserop {
DDSI_SERDATA_PSEROP_PREPAD;
char pad[DDSI_SERDATA_PSEROP_PAD (8 - (offsetof (struct ddsi_serdata_pserop_unpadded, data) % 8))];
DDSI_SERDATA_PSEROP_POSTPAD;
};
#undef DDSI_SERDATA_PSEROP_PAD
#undef DDSI_SERDATA_PSEROP_POSTPAD
#undef DDSI_SERDATA_PSEROP_PREPAD
struct ddsi_sertopic_pserop {
struct ddsi_sertopic c;
uint16_t native_encoding_identifier; /* CDR_(LE|BE) */
size_t memsize;
size_t nops;
const enum pserop *ops;
size_t nops_key;
const enum pserop *ops_key; /* NULL <=> no key; != NULL <=> 16-byte key at offset 0 */
};
extern DDS_EXPORT const struct ddsi_sertopic_ops ddsi_sertopic_ops_pserop;
extern DDS_EXPORT const struct ddsi_serdata_ops ddsi_serdata_ops_pserop;
#if defined (__cplusplus)
}
#endif
#endif

View file

@ -261,8 +261,6 @@ struct config
unsigned delivery_queue_maxsamples; unsigned delivery_queue_maxsamples;
int do_topic_discovery;
uint32_t max_msg_size; uint32_t max_msg_size;
uint32_t fragment_size; uint32_t fragment_size;

View file

@ -25,7 +25,11 @@ struct nn_rsample_info;
struct nn_rdata; struct nn_rdata;
struct ddsi_plist; struct ddsi_plist;
void get_participant_builtin_topic_data(const struct participant *pp, struct nn_xmsg *mpayload, bool be); struct participant_builtin_topic_data_locators {
struct nn_locators_one def_uni_loc_one, def_multi_loc_one, meta_uni_loc_one, meta_multi_loc_one;
};
void get_participant_builtin_topic_data (const struct participant *pp, ddsi_plist_t *dst, struct participant_builtin_topic_data_locators *locs);
int spdp_write (struct participant *pp); int spdp_write (struct participant *pp);
int spdp_dispose_unregister (struct participant *pp); int spdp_dispose_unregister (struct participant *pp);
@ -35,8 +39,6 @@ int sedp_write_reader (struct reader *rd);
int sedp_dispose_unregister_writer (struct writer *wr); int sedp_dispose_unregister_writer (struct writer *wr);
int sedp_dispose_unregister_reader (struct reader *rd); int sedp_dispose_unregister_reader (struct reader *rd);
int sedp_write_topic (struct participant *pp, const struct ddsi_plist *datap);
int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const ddsi_guid_t *rdguid, void *qarg); int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const ddsi_guid_t *rdguid, void *qarg);
#if defined (__cplusplus) #if defined (__cplusplus)

View file

@ -291,7 +291,7 @@ struct writer
struct addrset *ssm_as; struct addrset *ssm_as;
#endif #endif
uint32_t alive_vclock; /* virtual clock counting transitions between alive/not-alive */ uint32_t alive_vclock; /* virtual clock counting transitions between alive/not-alive */
const struct ddsi_sertopic * topic; /* topic, but may be NULL for built-ins */ const struct ddsi_sertopic * topic; /* topic */
struct addrset *as; /* set of addresses to publish to */ struct addrset *as; /* set of addresses to publish to */
struct addrset *as_group; /* alternate case, used for SPDP, when using Cloud with multiple bootstrap locators */ struct addrset *as_group; /* alternate case, used for SPDP, when using Cloud with multiple bootstrap locators */
struct xevent *heartbeat_xevent; /* timed event for "periodically" publishing heartbeats when unack'd data present, NULL <=> unreliable */ struct xevent *heartbeat_xevent; /* timed event for "periodically" publishing heartbeats when unack'd data present, NULL <=> unreliable */
@ -350,7 +350,7 @@ struct reader
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
struct addrset *as; struct addrset *as;
#endif #endif
const struct ddsi_sertopic * topic; /* topic is NULL for built-in readers */ const struct ddsi_sertopic * topic; /* topic */
uint32_t num_writers; /* total number of matching PROXY writers */ uint32_t num_writers; /* total number of matching PROXY writers */
ddsrt_avl_tree_t writers; /* all matching PROXY writers, see struct rd_pwr_match */ ddsrt_avl_tree_t writers; /* all matching PROXY writers, see struct rd_pwr_match */
ddsrt_avl_tree_t local_writers; /* all matching LOCAL writers, see struct rd_wr_match */ ddsrt_avl_tree_t local_writers; /* all matching LOCAL writers, see struct rd_wr_match */

View file

@ -203,7 +203,7 @@ typedef uint16_t nn_parameterid_t; /* spec says short */
typedef struct nn_parameter { typedef struct nn_parameter {
nn_parameterid_t parameterid; nn_parameterid_t parameterid;
uint16_t length; /* spec says signed short */ uint16_t length; /* spec says signed short */
/* char value[]; O! how I long for C99 */ /* char value[] */
} nn_parameter_t; } nn_parameter_t;
typedef struct Data_DataFrag_common { typedef struct Data_DataFrag_common {
@ -318,18 +318,10 @@ typedef union Submessage {
NackFrag_t nackfrag; NackFrag_t nackfrag;
} Submessage_t; } Submessage_t;
DDSRT_WARNING_MSVC_OFF(4200)
typedef struct ParticipantMessageData {
ddsi_guid_prefix_t participantGuidPrefix;
uint32_t kind; /* really 4 octets */
uint32_t length;
char value[];
} ParticipantMessageData_t;
DDSRT_WARNING_MSVC_ON(4200)
#define PARTICIPANT_MESSAGE_DATA_KIND_UNKNOWN 0x0u #define PARTICIPANT_MESSAGE_DATA_KIND_UNKNOWN 0x0u
#define PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE 0x1u #define PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE 0x1u
#define PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE 0x2u #define PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE 0x2u
#define PARTICIPANT_MESSAGE_DATA_VENDER_SPECIFIC_KIND_FLAG 0x8000000u #define PARTICIPANT_MESSAGE_DATA_VENDOR_SPECIFIC_KIND_FLAG 0x8000000u
#define PID_VENDORSPECIFIC_FLAG 0x8000u #define PID_VENDORSPECIFIC_FLAG 0x8000u
#define PID_UNRECOGNIZED_INCOMPATIBLE_FLAG 0x4000u #define PID_UNRECOGNIZED_INCOMPATIBLE_FLAG 0x4000u

View file

@ -70,20 +70,6 @@ static int entity_guid_eq_wrapper (const void *a, const void *b)
return entity_guid_eq (a, b); return entity_guid_eq (a, b);
} }
static int all_entities_compare_isbuiltin (const struct entity_common *e, nn_vendorid_t vendor)
{
const unsigned char *guid_bytes = (const unsigned char *) &e->guid;
if (guid_bytes[0] != 0 && guid_bytes[0] != 0xff)
return is_builtin_endpoint (e->guid.entityid, vendor);
else
{
for (size_t i = 1; i < sizeof (e->guid); i++)
if (guid_bytes[i] != guid_bytes[0])
return is_builtin_endpoint (e->guid.entityid, vendor) && !is_local_orphan_endpoint (e);
return 0;
}
}
static int all_entities_compare (const void *va, const void *vb) static int all_entities_compare (const void *va, const void *vb)
{ {
const struct entity_common *a = va; const struct entity_common *a = va;
@ -104,28 +90,20 @@ static int all_entities_compare (const void *va, const void *vb)
case EK_WRITER: { case EK_WRITER: {
const struct writer *wra = va; const struct writer *wra = va;
const struct writer *wrb = vb; const struct writer *wrb = vb;
if (!all_entities_compare_isbuiltin (a, NN_VENDORID_ECLIPSE)) {
assert ((wra->xqos->present & QP_TOPIC_NAME) && wra->xqos->topic_name); assert ((wra->xqos->present & QP_TOPIC_NAME) && wra->xqos->topic_name);
tp_a = wra->xqos->topic_name;
}
if (!all_entities_compare_isbuiltin (b, NN_VENDORID_ECLIPSE)) {
assert ((wrb->xqos->present & QP_TOPIC_NAME) && wrb->xqos->topic_name); assert ((wrb->xqos->present & QP_TOPIC_NAME) && wrb->xqos->topic_name);
tp_a = wra->xqos->topic_name;
tp_b = wrb->xqos->topic_name; tp_b = wrb->xqos->topic_name;
}
break; break;
} }
case EK_READER: { case EK_READER: {
const struct reader *rda = va; const struct reader *rda = va;
const struct reader *rdb = vb; const struct reader *rdb = vb;
if (!all_entities_compare_isbuiltin (a, NN_VENDORID_ECLIPSE)) {
assert ((rda->xqos->present & QP_TOPIC_NAME) && rda->xqos->topic_name); assert ((rda->xqos->present & QP_TOPIC_NAME) && rda->xqos->topic_name);
tp_a = rda->xqos->topic_name;
}
if (!all_entities_compare_isbuiltin (b, NN_VENDORID_ECLIPSE)) {
assert ((rdb->xqos->present & QP_TOPIC_NAME) && rdb->xqos->topic_name); assert ((rdb->xqos->present & QP_TOPIC_NAME) && rdb->xqos->topic_name);
tp_a = rda->xqos->topic_name;
tp_b = rdb->xqos->topic_name; tp_b = rdb->xqos->topic_name;
}
break; break;
} }
@ -133,14 +111,11 @@ static int all_entities_compare (const void *va, const void *vb)
case EK_PROXY_READER: { case EK_PROXY_READER: {
const struct generic_proxy_endpoint *ga = va; const struct generic_proxy_endpoint *ga = va;
const struct generic_proxy_endpoint *gb = vb; const struct generic_proxy_endpoint *gb = vb;
if (!all_entities_compare_isbuiltin (a, ga->c.vendor)) { /* built-in reader/writer proxies don't have topic name set */
assert ((ga->c.xqos->present & QP_TOPIC_NAME) && ga->c.xqos->topic_name); if (ga->c.xqos->present & QP_TOPIC_NAME)
tp_a = ga->c.xqos->topic_name; tp_a = ga->c.xqos->topic_name;
} if (gb->c.xqos->present & QP_TOPIC_NAME)
if (!all_entities_compare_isbuiltin (b, gb->c.vendor)) {
assert ((gb->c.xqos->present & QP_TOPIC_NAME) && gb->c.xqos->topic_name);
tp_b = gb->c.xqos->topic_name; tp_b = gb->c.xqos->topic_name;
}
break; break;
} }
} }

View file

@ -1028,6 +1028,19 @@ dds_return_t plist_ser_generic (void **dst, size_t *dstsize, const void *src, co
return ret; return ret;
} }
dds_return_t plist_ser_generic_be (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc)
{
const size_t srcoff = 0;
size_t dstoff = 0;
dds_return_t ret;
*dstsize = ser_generic_size (src, srcoff, desc);
if ((*dst = ddsrt_malloc (*dstsize == 0 ? 1 : *dstsize)) == NULL)
return DDS_RETCODE_OUT_OF_RESOURCES;
ret = ser_generic_embeddable (*dst, &dstoff, src, srcoff, desc, true);
assert (dstoff == *dstsize);
return ret;
}
static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict dstoff, bool gen_seq_aliased, const enum pserop * __restrict desc) static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict dstoff, bool gen_seq_aliased, const enum pserop * __restrict desc)
{ {
#define COMPLEX(basecase_, type_, ...) do { \ #define COMPLEX(basecase_, type_, ...) do { \
@ -1249,7 +1262,14 @@ static uint32_t isprint_runlen (uint32_t n, const unsigned char *xs)
static bool prtf_octetseq (char * __restrict *buf, size_t * __restrict bufsize, uint32_t n, const unsigned char *xs) static bool prtf_octetseq (char * __restrict *buf, size_t * __restrict bufsize, uint32_t n, const unsigned char *xs)
{ {
/* Truncate octet sequences: 100 is arbitrary but experience suggests it is
usually enough, and truncating it helps a lot when printing handshake
messages during authentication. */
const uint32_t lim = 100;
bool trunc = (n > lim);
uint32_t i = 0; uint32_t i = 0;
if (trunc)
n = lim;
while (i < n) while (i < n)
{ {
uint32_t m = isprint_runlen (n - i, xs); uint32_t m = isprint_runlen (n - i, xs);
@ -1272,7 +1292,7 @@ static bool prtf_octetseq (char * __restrict *buf, size_t * __restrict bufsize,
} }
} }
} }
return true; return trunc ? prtf (buf, bufsize, "...") : true;
} }
static bool print_generic1 (char * __restrict *buf, size_t * __restrict bufsize, const void *src, size_t srcoff, const enum pserop * __restrict desc, const char *sep) static bool print_generic1 (char * __restrict *buf, size_t * __restrict bufsize, const void *src, size_t srcoff, const enum pserop * __restrict desc, const char *sep)
@ -1387,7 +1407,7 @@ static bool print_generic1 (char * __restrict *buf, size_t * __restrict bufsize,
} }
case XG: { /* GUID */ case XG: { /* GUID */
ddsi_guid_t const * const x = deser_generic_src (src, &srcoff, alignof (ddsi_guid_t)); ddsi_guid_t const * const x = deser_generic_src (src, &srcoff, alignof (ddsi_guid_t));
if (!prtf (buf, bufsize, "%s"PGUIDFMT, sep, PGUID (*x))) if (!prtf (buf, bufsize, "%s{"PGUIDFMT"}", sep, PGUID (*x)))
return false; return false;
srcoff += sizeof (*x); srcoff += sizeof (*x);
break; break;
@ -1415,14 +1435,13 @@ static bool print_generic1 (char * __restrict *buf, size_t * __restrict bufsize,
if (!prtf (buf, bufsize, "}")) if (!prtf (buf, bufsize, "}"))
return false; return false;
srcoff += sizeof (*x); srcoff += sizeof (*x);
while (*++desc != XSTOP) { }
break; break;
} }
case Xopt: case Xopt:
break; break;
} }
sep = ":"; sep = ":";
desc++; desc = pserop_advance(desc);
} }
} }
@ -2845,20 +2864,47 @@ dds_return_t ddsi_plist_init_frommsg (ddsi_plist_t *dest, char **nextafterplist,
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
} }
const unsigned char *ddsi_plist_findparam_native_unchecked (const void *src, nn_parameterid_t pid) dds_return_t ddsi_plist_findparam_checking (const void *buf, size_t bufsz, uint16_t encoding, nn_parameterid_t needle, void **needlep, size_t *needlesz)
{ {
/* Scans the parameter list starting at src looking just for pid, returning NULL if not found; /* set needle to PID_SENTINEL if all you want to do is scan the structure */
no further checking is done and the input is assumed to valid and in native format. Clearly assert (needle == PID_SENTINEL || (needlep != NULL && needlesz != NULL));
this is only to be used for internally generated data -- to precise, for grabbing the key bool bswap;
value from discovery data that is being sent out. */ if (needlep)
const nn_parameter_t *par = src; *needlep = NULL;
while (par->parameterid != pid) switch (encoding)
{ {
if (par->parameterid == PID_SENTINEL) case PL_CDR_LE:
return NULL; bswap = (DDSRT_ENDIAN != DDSRT_LITTLE_ENDIAN);
par = (const nn_parameter_t *) ((const char *) (par + 1) + par->length); break;
case PL_CDR_BE:
bswap = (DDSRT_ENDIAN != DDSRT_BIG_ENDIAN);
break;
default:
return DDS_RETCODE_BAD_PARAMETER;
} }
return (unsigned char *) (par + 1); const unsigned char *pl = buf;
const unsigned char *endp = pl + bufsz;
while (pl + sizeof (nn_parameter_t) <= endp)
{
const nn_parameter_t *par = (const nn_parameter_t *) pl;
nn_parameterid_t pid;
uint16_t length;
pid = (nn_parameterid_t) (bswap ? ddsrt_bswap2u (par->parameterid) : par->parameterid);
length = (uint16_t) (bswap ? ddsrt_bswap2u (par->length) : par->length);
pl += sizeof (*par);
if (pid == PID_SENTINEL)
return (needlep && *needlep == NULL) ? DDS_RETCODE_NOT_FOUND : DDS_RETCODE_OK;
else if (length > (size_t) (endp - pl) || (length % 4) != 0 /* DDSI 9.4.2.11 */)
return DDS_RETCODE_BAD_PARAMETER;
else if (pid == needle)
{
*needlep = (void *) pl;
*needlesz = length;
}
pl += length;
}
return DDS_RETCODE_BAD_PARAMETER;
} }
unsigned char *ddsi_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const ddsi_plist_src_t *src) unsigned char *ddsi_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const ddsi_plist_src_t *src)
@ -3379,6 +3425,9 @@ static void plist_or_xqos_print (char * __restrict *buf, size_t * __restrict buf
/* shift == 0: plist, shift > 0: just qos */ /* shift == 0: plist, shift > 0: just qos */
const char *sep = ""; const char *sep = "";
uint64_t pw, qw; uint64_t pw, qw;
if (*bufsize == 0)
return;
(*buf)[0] = 0;
if (shift > 0) if (shift > 0)
{ {
const dds_qos_t *qos = src; const dds_qos_t *qos = src;
@ -3464,3 +3513,10 @@ void ddsi_plist_log (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds
{ {
plist_or_xqos_log (cat, logcfg, plist, 0, ~(uint64_t)0, ~(uint64_t)0); plist_or_xqos_log (cat, logcfg, plist, 0, ~(uint64_t)0, ~(uint64_t)0);
} }
size_t plist_print_generic (char * __restrict buf, size_t bufsize, const void * __restrict src, const enum pserop * __restrict desc)
{
const size_t bufsize_in = bufsize;
(void) print_generic (&buf, &bufsize, src, 0, desc);
return bufsize_in - bufsize;
}

View file

@ -14,6 +14,7 @@
#include "dds/ddsi/ddsi_pmd.h" #include "dds/ddsi/ddsi_pmd.h"
#include "dds/ddsi/ddsi_serdata.h" #include "dds/ddsi/ddsi_serdata.h"
#include "dds/ddsi/ddsi_serdata_default.h" #include "dds/ddsi/ddsi_serdata_default.h"
#include "dds/ddsi/ddsi_serdata_pserop.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/q_bswap.h" #include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_entity.h" #include "dds/ddsi/q_entity.h"
@ -30,20 +31,13 @@
#include "dds/ddsi/sysdeps.h" #include "dds/ddsi/sysdeps.h"
static void debug_print_rawdata (const struct ddsi_domaingv *gv, const char *msg, const void *data, size_t len) /* note: treating guid prefix + kind as if it were a GUID because that matches
{ the octet-sequence/sequence-of-uint32 distinction between the specified wire
const unsigned char *c = data; representation and the internal representation */
size_t i; const enum pserop participant_message_data_ops[] = { XG, XO, XSTOP };
GVTRACE ("%s<", msg); size_t participant_message_data_nops = sizeof (participant_message_data_ops) / sizeof (participant_message_data_ops[0]);
for (i = 0; i < len; i++) const enum pserop participant_message_data_ops_key[] = { XG, XSTOP };
{ size_t participant_message_data_nops_key = sizeof (participant_message_data_ops_key) / sizeof (participant_message_data_ops_key[0]);
if (32 < c[i] && c[i] <= 127)
GVTRACE ("%s%c", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
else
GVTRACE ("%s\\x%02x", (i > 0 && (i%4) == 0) ? " " : "", c[i]);
}
GVTRACE (">");
}
void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind) void write_pmd_message_guid (struct ddsi_domaingv * const gv, struct ddsi_guid *pp_guid, unsigned pmd_kind)
{ {
@ -67,10 +61,8 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
#define PMD_DATA_LENGTH 1 #define PMD_DATA_LENGTH 1
struct ddsi_domaingv * const gv = pp->e.gv; struct ddsi_domaingv * const gv = pp->e.gv;
struct writer *wr; struct writer *wr;
union { unsigned char data[PMD_DATA_LENGTH] = { 0 };
ParticipantMessageData_t pmd; ParticipantMessageData_t pmd;
char pad[offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH];
} u;
struct ddsi_serdata *serdata; struct ddsi_serdata *serdata;
struct ddsi_tkmap_instance *tk; struct ddsi_tkmap_instance *tk;
@ -80,18 +72,11 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
return; return;
} }
u.pmd.participantGuidPrefix = nn_hton_guid_prefix (pp->e.guid.prefix); pmd.participantGuidPrefix = pp->e.guid.prefix;
u.pmd.kind = ddsrt_toBE4u (pmd_kind); pmd.kind = pmd_kind;
u.pmd.length = PMD_DATA_LENGTH; pmd.value.length = (uint32_t) sizeof (data);
memset (u.pmd.value, 0, u.pmd.length); pmd.value.value = data;
serdata = ddsi_serdata_from_sample (gv->pmd_topic, SDK_DATA, &pmd);
struct ddsi_rawcdr_sample raw = {
.blob = &u,
.size = offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH,
.key = &u.pmd,
.keysize = 16
};
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
serdata->timestamp = ddsrt_time_wallclock (); serdata->timestamp = ddsrt_time_wallclock ();
tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata);
@ -100,66 +85,44 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
#undef PMD_DATA_LENGTH #undef PMD_DATA_LENGTH
} }
void handle_pmd_message (const struct receiver_state *rst, ddsrt_wctime_t timestamp, uint32_t statusinfo, const void *vdata, uint32_t len) void handle_pmd_message (const struct receiver_state *rst, struct ddsi_serdata *sample_common)
{ {
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ /* use sample with knowledge of internal representation: there's a deserialized sample inside already */
const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN); const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
struct proxy_participant *proxypp; struct proxy_participant *proxypp;
ddsi_guid_t ppguid; ddsi_guid_t ppguid;
struct lease *l; struct lease *l;
RSTTRACE (" PMD ST%x", statusinfo); RSTTRACE (" PMD ST%x", sample->c.statusinfo);
if (data->identifier != CDR_LE && data->identifier != CDR_BE) switch (sample->c.statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
{ {
RSTTRACE (" PMD data->identifier %u !?\n", ntohs (data->identifier)); case 0: {
return; const ParticipantMessageData_t *pmd = sample->sample;
} RSTTRACE (" pp %"PRIx32":%"PRIx32":%"PRIx32" kind %"PRIu32" data %"PRIu32, PGUIDPREFIX (pmd->participantGuidPrefix), pmd->kind, pmd->value.length);
ppguid.prefix = pmd->participantGuidPrefix;
switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
{
case 0:
if (offsetof (ParticipantMessageData_t, value) > len - sizeof (struct CDRHeader))
debug_print_rawdata (rst->gv, " SHORT1", data, len);
else
{
const ParticipantMessageData_t *pmd = (ParticipantMessageData_t *) (data + 1);
ddsi_guid_prefix_t p = nn_ntoh_guid_prefix (pmd->participantGuidPrefix);
uint32_t kind = ntohl (pmd->kind);
uint32_t length = bswap ? ddsrt_bswap4u (pmd->length) : pmd->length;
RSTTRACE (" pp %"PRIx32":%"PRIx32":%"PRIx32" kind %u data %u", p.u[0], p.u[1], p.u[2], kind, length);
if (len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value) < length)
debug_print_rawdata (rst->gv, " SHORT2", pmd->value, len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value));
else
debug_print_rawdata (rst->gv, "", pmd->value, length);
ppguid.prefix = p;
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if ((proxypp = entidx_lookup_proxy_participant_guid (rst->gv->entity_index, &ppguid)) == NULL) if ((proxypp = entidx_lookup_proxy_participant_guid (rst->gv->entity_index, &ppguid)) == NULL)
RSTTRACE (" PPunknown"); RSTTRACE (" PPunknown");
else if (kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE && else if (pmd->kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE &&
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL) (l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
{ {
/* Renew lease for entity with shortest manual-by-participant lease */ /* Renew lease for entity with shortest manual-by-participant lease */
lease_renew (l, ddsrt_time_elapsed ()); lease_renew (l, ddsrt_time_elapsed ());
} }
}
break; break;
}
case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER: case NN_STATUSINFO_UNREGISTER:
case NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER: case NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER: {
/* Serialized key; BE or LE doesn't matter as both fields are const ParticipantMessageData_t *pmd = sample->sample;
defined as octets. */ ppguid.prefix = pmd->participantGuidPrefix;
if (len < sizeof (struct CDRHeader) + sizeof (ddsi_guid_prefix_t))
debug_print_rawdata (rst->gv, " SHORT3", data, len);
else
{
ppguid.prefix = nn_ntoh_guid_prefix (*((ddsi_guid_prefix_t *) (data + 1)));
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
if (delete_proxy_participant_by_guid (rst->gv, &ppguid, timestamp, 0) < 0) if (delete_proxy_participant_by_guid (rst->gv, &ppguid, sample->c.timestamp, 0) < 0)
RSTTRACE (" unknown"); RSTTRACE (" unknown");
else else
RSTTRACE (" delete"); RSTTRACE (" delete");
}
break; break;
} }
}
RSTTRACE ("\n"); RSTTRACE ("\n");
} }

View file

@ -22,6 +22,7 @@
#include "dds/ddsi/ddsi_serdata_default.h" #include "dds/ddsi/ddsi_serdata_default.h"
#include "dds/ddsi/ddsi_security_omg.h" #include "dds/ddsi/ddsi_security_omg.h"
#include "dds/ddsi/ddsi_handshake.h" #include "dds/ddsi/ddsi_handshake.h"
#include "dds/ddsi/ddsi_serdata_pserop.h"
#include "dds/ddsi/q_ddsi_discovery.h" #include "dds/ddsi/q_ddsi_discovery.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/q_xmsg.h" #include "dds/ddsi/q_xmsg.h"
@ -29,79 +30,11 @@
#include "dds/ddsi/q_log.h" #include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_bswap.h" #include "dds/ddsi/q_bswap.h"
//#define SECURITY_LOG_MESSAGE_DATA
#ifdef SECURITY_LOG_MESSAGE_DATA
static void nn_property_seq_log(struct ddsi_domaingv *gv, const dds_propertyseq_t *seq)
{
uint32_t i;
GVTRACE("{");
for (i = 0; i < seq->n; i++) {
GVTRACE("n=%s,v=%s", seq->props[i].name, seq->props[i].value);
}
GVTRACE("}");
}
static void nn_binary_property_seq_log(struct ddsi_domaingv *gv, const dds_binarypropertyseq_t *seq)
{
uint32_t i;
GVTRACE("{");
for (i = 0; i < seq->n; i++) {
uint32_t j;
GVTRACE("n=%s,v={", seq->props[i].name);
for (j = 0; j < seq->props[i].value.length; j++) {
GVTRACE("%02x", seq->props[i].value.value[j]);
}
GVTRACE("}");
}
GVTRACE("}");
}
static void nn_dataholder_seq_log(struct ddsi_domaingv *gv, const char *prefix, const nn_dataholderseq_t *dhseq)
{
uint32_t i;
GVTRACE("%s={", prefix);
for (i = 0; i < dhseq->n; i++) {
GVTRACE("cid=%s,", dhseq->tags[i].class_id);
nn_property_seq_log(gv, &dhseq->tags[i].properties);
GVTRACE(",");
nn_binary_property_seq_log(gv, &dhseq->tags[i].binary_properties);
}
GVTRACE("}");
}
#endif
static void nn_participant_generic_message_log(struct ddsi_domaingv *gv, const struct nn_participant_generic_message *msg, int conv)
{
ddsi_guid_t spguid = conv ? nn_ntoh_guid(msg->message_identity.source_guid ): msg->message_identity.source_guid;
ddsi_guid_t rmguid = conv ? nn_ntoh_guid(msg->related_message_identity.source_guid) : msg->related_message_identity.source_guid;
ddsi_guid_t dpguid = conv ? nn_ntoh_guid(msg->destination_participant_guid) : msg->destination_participant_guid;
ddsi_guid_t deguid = conv ? nn_ntoh_guid(msg->destination_endpoint_guid) : msg->destination_endpoint_guid;
ddsi_guid_t seguid = conv ? nn_ntoh_guid(msg->source_endpoint_guid) : msg->source_endpoint_guid;
GVTRACE (" msg=");
GVTRACE("mi=" PGUIDFMT "#%" PRId64 ",", PGUID(spguid), msg->message_identity.sequence_number);
GVTRACE("rmi=" PGUIDFMT "#%" PRId64 ",", PGUID(rmguid), msg->related_message_identity.sequence_number);
GVTRACE("dpg=" PGUIDFMT ",", PGUID(dpguid));
GVTRACE("deg=" PGUIDFMT ",", PGUID(deguid));
GVTRACE("seg=" PGUIDFMT ",", PGUID(seguid));
GVTRACE("cid=%s", msg->message_class_id);
#ifdef SECURITY_LOG_MESSAGE_DATA
nn_dataholder_seq_log(gv, ",mdata", &msg->message_data);
#endif
GVTRACE ("\n");
}
bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id) bool write_auth_handshake_message(const struct participant *pp, const struct proxy_participant *proxypp, nn_dataholderseq_t *mdata, bool request, const nn_message_identity_t *related_message_id)
{ {
struct ddsi_domaingv *gv = pp->e.gv; struct ddsi_domaingv *gv = pp->e.gv;
struct nn_participant_generic_message pmg; struct nn_participant_generic_message pmg;
struct ddsi_serdata *serdata; struct ddsi_serdata *serdata;
unsigned char *blob;
size_t len;
struct writer *wr; struct writer *wr;
int64_t seq; int64_t seq;
struct proxy_reader *prd; struct proxy_reader *prd;
@ -129,27 +62,10 @@ bool write_auth_handshake_message(const struct participant *pp, const struct pro
nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, &proxypp->e.guid, NULL, NULL, DDS_SECURITY_AUTH_HANDSHAKE, mdata, related_message_id); nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, &proxypp->e.guid, NULL, NULL, DDS_SECURITY_AUTH_HANDSHAKE, mdata, related_message_id);
} }
if (nn_participant_generic_message_serialize(&pmg, &blob, &len) != DDS_RETCODE_OK) serdata = ddsi_serdata_from_sample (wr->topic, SDK_DATA, &pmg);
return false;
GVTRACE("write_handshake("PGUIDFMT" --> "PGUIDFMT")(lguid="PGUIDFMT" rguid="PGUIDFMT") ",
PGUID (wr->e.guid), PGUID (prd_guid),
PGUID (pp->e.guid), PGUID (proxypp->e.guid));
nn_participant_generic_message_log(gv, &pmg, 1);
struct ddsi_rawcdr_sample raw = {
.blob = blob,
.size = len,
.key = NULL,
.keysize = 0
};
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
serdata->timestamp = ddsrt_time_wallclock (); serdata->timestamp = ddsrt_time_wallclock ();
result = enqueue_sample_wrlock_held (wr, seq, NULL, serdata, prd, 1) == 0; result = enqueue_sample_wrlock_held (wr, seq, NULL, serdata, prd, 1) == 0;
ddsi_serdata_unref (serdata); ddsi_serdata_unref (serdata);
dds_free(blob);
ddsrt_mutex_unlock (&wr->e.lock); ddsrt_mutex_unlock (&wr->e.lock);
nn_participant_generic_message_deinit(&pmg); nn_participant_generic_message_deinit(&pmg);
@ -159,71 +75,53 @@ bool write_auth_handshake_message(const struct participant *pp, const struct pro
void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq) void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq)
{ {
struct nn_xmsg *mpayload; struct nn_xmsg *mpayload;
ddsi_plist_t ps;
struct participant_builtin_topic_data_locators locs;
size_t sz; size_t sz;
char *payload; char *payload;
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, pp, 0, NN_XMSG_KIND_DATA); mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, pp, 0, NN_XMSG_KIND_DATA);
get_participant_builtin_topic_data (pp, &ps, &locs);
get_participant_builtin_topic_data(pp, mpayload, true); ddsi_plist_addtomsg_bo (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0, true);
nn_xmsg_addpar_sentinel_bo (mpayload, true);
ddsi_plist_fini (&ps);
payload = nn_xmsg_payload (&sz, mpayload); payload = nn_xmsg_payload (&sz, mpayload);
seq->length = (uint32_t) sz; seq->length = (uint32_t) sz;
seq->value = ddsrt_malloc (sz); seq->value = ddsrt_malloc (sz);
memcpy (seq->value, payload, sz); memcpy (seq->value, payload, sz);
nn_xmsg_free (mpayload); nn_xmsg_free (mpayload);
} }
void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, size_t len) void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, struct ddsi_serdata *sample_common)
{ {
const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */ const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
const bool bswap = (hdr->identifier == CDR_LE) ^ DDSRT_LITTLE_ENDIAN; const struct nn_participant_generic_message *msg = sample->sample;
const void *data = (void *) (hdr + 1);
size_t size = (len - sizeof(struct CDRHeader));
struct nn_participant_generic_message msg;
struct participant *pp = NULL; struct participant *pp = NULL;
struct proxy_writer *pwr = NULL; struct proxy_writer *pwr = NULL;
ddsi_guid_t guid; ddsi_guid_t guid;
ddsi_guid_t *pwr_guid; const ddsi_guid_t *pwr_guid;
struct ddsi_handshake *handshake; struct ddsi_handshake *handshake;
DDSRT_UNUSED_ARG(wr_entity_id); DDSRT_UNUSED_ARG(wr_entity_id);
DDSRT_UNUSED_ARG(timestamp);
RSTTRACE ("recv_handshake ST%x", statusinfo); if (msg->message_identity.source_guid.entityid.u == NN_ENTITYID_PARTICIPANT)
if ((hdr->identifier != CDR_LE) && (hdr->identifier != PL_CDR_LE) &&
(hdr->identifier != CDR_BE) && (hdr->identifier != PL_CDR_BE))
{ {
RSTTRACE (" data->identifier %d !?\n", ntohs (hdr->identifier)); guid = msg->message_identity.source_guid;
return;
}
if (nn_participant_generic_message_deseralize(&msg, data, size, bswap) < 0)
{
RSTTRACE ("deserialize failed\n");
goto err_deser;
}
nn_participant_generic_message_log(rst->gv, &msg, 0);
if (msg.message_identity.source_guid.entityid.u == NN_ENTITYID_PARTICIPANT)
{
guid = msg.message_identity.source_guid;
guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER; guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER;
pwr_guid = &guid; pwr_guid = &guid;
} }
else if (msg.message_identity.source_guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER) else if (msg->message_identity.source_guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)
{ {
pwr_guid= &msg.message_identity.source_guid; pwr_guid = &msg->message_identity.source_guid;
} }
else else
{ {
RSTTRACE ("invalid source entity id\n"); RSTTRACE ("invalid source entity id\n");
goto invalid_source; return;
} }
if ((pp = entidx_lookup_participant_guid(rst->gv->entity_index, &msg.destination_participant_guid)) == NULL) if ((pp = entidx_lookup_participant_guid(rst->gv->entity_index, &msg->destination_participant_guid)) == NULL)
{ {
RSTTRACE ("destination participant ("PGUIDFMT") not found\n", PGUID(msg.destination_participant_guid)); RSTTRACE ("destination participant ("PGUIDFMT") not found\n", PGUID (msg->destination_participant_guid));
} }
else if ((pwr = entidx_lookup_proxy_writer_guid(rst->gv->entity_index, pwr_guid)) == NULL) else if ((pwr = entidx_lookup_proxy_writer_guid(rst->gv->entity_index, pwr_guid)) == NULL)
{ {
@ -236,14 +134,9 @@ void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entity
else else
{ {
//RSTTRACE (" ("PGUIDFMT" --> "PGUIDFMT")\n", PGUID (pwr->c.proxypp->e.guid), PGUID (pp->e.guid)); //RSTTRACE (" ("PGUIDFMT" --> "PGUIDFMT")\n", PGUID (pwr->c.proxypp->e.guid), PGUID (pp->e.guid));
ddsi_handshake_handle_message(handshake, pp, pwr->c.proxypp, &msg); ddsi_handshake_handle_message (handshake, pp, pwr->c.proxypp, msg);
ddsi_handshake_release (handshake); ddsi_handshake_release (handshake);
} }
invalid_source:
nn_participant_generic_message_deinit(&msg);
err_deser:
return;
} }
static bool write_crypto_exchange_message(const struct participant *pp, const ddsi_guid_t *dst_pguid, const ddsi_guid_t *src_eguid, const ddsi_guid_t *dst_eguid, const char *classid, const nn_dataholderseq_t *tokens) static bool write_crypto_exchange_message(const struct participant *pp, const ddsi_guid_t *dst_pguid, const ddsi_guid_t *src_eguid, const ddsi_guid_t *dst_eguid, const char *classid, const nn_dataholderseq_t *tokens)
@ -254,8 +147,6 @@ static bool write_crypto_exchange_message(const struct participant *pp, const dd
struct ddsi_serdata *serdata; struct ddsi_serdata *serdata;
struct proxy_reader *prd; struct proxy_reader *prd;
ddsi_guid_t prd_guid; ddsi_guid_t prd_guid;
unsigned char *data;
size_t len;
struct writer *wr; struct writer *wr;
seqno_t seq; seqno_t seq;
int r; int r;
@ -278,30 +169,11 @@ static bool write_crypto_exchange_message(const struct participant *pp, const dd
/* Get serialized message. */ /* Get serialized message. */
nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, dst_pguid, dst_eguid, src_eguid, classid, tokens, NULL); nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, dst_pguid, dst_eguid, src_eguid, classid, tokens, NULL);
nn_participant_generic_message_serialize(&pmg, &data, &len); serdata = ddsi_serdata_from_sample (wr->topic, SDK_DATA, &pmg);
serdata->timestamp = ddsrt_time_wallclock ();
nn_participant_generic_message_log(gv, &pmg, 0);
/* Get the key value. */
ddsrt_md5_state_t md5st;
ddsrt_md5_byte_t digest[16];
ddsrt_md5_init (&md5st);
ddsrt_md5_append (&md5st, (const ddsrt_md5_byte_t *)data, sizeof (nn_message_identity_t));
ddsrt_md5_finish (&md5st, digest);
/* Write the sample. */
struct ddsi_rawcdr_sample raw = {
.blob = data,
.size = len,
.key = digest,
.keysize = 16
};
serdata = ddsi_serdata_from_sample (gv->rawcdr_topic, SDK_DATA, &raw);
tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata); tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata);
r = write_sample_p2p_wrlock_held(wr, seq, NULL, serdata, tk, prd); r = write_sample_p2p_wrlock_held(wr, seq, NULL, serdata, tk, prd);
ddsrt_mutex_unlock (&wr->e.lock); ddsrt_mutex_unlock (&wr->e.lock);
ddsrt_free(data);
ddsi_tkmap_instance_unref (gv->m_tkmap, tk); ddsi_tkmap_instance_unref (gv->m_tkmap, tk);
ddsi_serdata_unref (serdata); ddsi_serdata_unref (serdata);
@ -331,86 +203,51 @@ bool write_crypto_reader_tokens(const struct reader *rd, const struct proxy_writ
return write_crypto_exchange_message(pp, &proxypp->e.guid, &rd->e.guid, &pwr->e.guid, GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, tokens); return write_crypto_exchange_message(pp, &proxypp->e.guid, &rd->e.guid, &pwr->e.guid, GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, tokens);
} }
void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) void handle_crypto_exchange_message(const struct receiver_state *rst, struct ddsi_serdata *sample_common)
{ {
struct ddsi_domaingv *gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
const struct CDRHeader *hdr = vdata; /* built-ins not deserialized (yet) */ const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
const int bswap = (hdr->identifier == CDR_LE) ^ DDSRT_LITTLE_ENDIAN; const struct nn_participant_generic_message *msg = sample->sample;
const void *data = (void *) (hdr + 1);
unsigned size = (unsigned)(len - sizeof(struct CDRHeader));
struct nn_participant_generic_message msg;
ddsi_guid_t rd_guid;
ddsi_guid_t pwr_guid;
ddsi_guid_t proxypp_guid; ddsi_guid_t proxypp_guid;
struct participant *pp;
struct proxy_participant *proxypp;
DDSRT_UNUSED_ARG(timestamp); proxypp_guid.prefix = msg->message_identity.source_guid.prefix;
rd_guid.prefix = rst->dst_guid_prefix;
rd_guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
pwr_guid.prefix = rst->src_guid_prefix;
pwr_guid.entityid = wr_entity_id;
GVTRACE ("recv crypto tokens ("PGUIDFMT" --> "PGUIDFMT") ST%x", PGUID (pwr_guid), PGUID (rd_guid), statusinfo);
memset(&msg, 0, sizeof(msg));
if (nn_participant_generic_message_deseralize(&msg, data, size, bswap) < 0)
goto deser_msg_failed;
nn_participant_generic_message_log(gv, &msg, 0);
if (!msg.message_class_id)
{
ddsi_guid_t guid;
guid.prefix = rst->dst_guid_prefix;
guid.entityid.u = NN_ENTITYID_PARTICIPANT;
GVWARNING("participant "PGUIDFMT" received a crypto exchange message with empty class_id", PGUID(guid));
goto invalid_msg;
}
proxypp_guid.prefix = msg.message_identity.source_guid.prefix;
proxypp_guid.entityid.u = NN_ENTITYID_PARTICIPANT; proxypp_guid.entityid.u = NN_ENTITYID_PARTICIPANT;
if (strcmp(GMCLASSID_SECURITY_PARTICIPANT_CRYPTO_TOKENS, msg.message_class_id) == 0) if (strcmp(GMCLASSID_SECURITY_PARTICIPANT_CRYPTO_TOKENS, msg->message_class_id) == 0)
{ {
pp = entidx_lookup_participant_guid(gv->entity_index, &msg.destination_participant_guid); struct participant * const pp = entidx_lookup_participant_guid(gv->entity_index, &msg->destination_participant_guid);
if (!pp) if (!pp)
{ {
GVWARNING("received a crypto exchange message from "PGUIDFMT" with participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg.destination_participant_guid)); GVWARNING("received a crypto exchange message from "PGUIDFMT" with participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
goto invalid_msg; return;
} }
proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &proxypp_guid); struct proxy_participant *proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &proxypp_guid);
if (!proxypp) if (!proxypp)
{ {
GVWARNING("received a crypto exchange message from "PGUIDFMT" with proxy participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg.destination_participant_guid)); GVWARNING("received a crypto exchange message from "PGUIDFMT" with proxy participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
goto invalid_msg; return;
} }
q_omg_security_set_participant_crypto_tokens(pp, proxypp, &msg.message_data); q_omg_security_set_participant_crypto_tokens(pp, proxypp, &msg->message_data);
} }
else if (strcmp(GMCLASSID_SECURITY_DATAWRITER_CRYPTO_TOKENS, msg.message_class_id) == 0) else if (strcmp(GMCLASSID_SECURITY_DATAWRITER_CRYPTO_TOKENS, msg->message_class_id) == 0)
{ {
struct reader *rd; struct reader * const rd = entidx_lookup_reader_guid(gv->entity_index, &msg->destination_endpoint_guid);
rd = entidx_lookup_reader_guid(gv->entity_index, &msg.destination_endpoint_guid);
if (!rd) if (!rd)
{ {
GVWARNING("received a crypto exchange message from "PGUIDFMT" with reader unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg.destination_participant_guid)); GVWARNING("received a crypto exchange message from "PGUIDFMT" with reader unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
goto invalid_msg; return;
} }
q_omg_security_set_remote_writer_crypto_tokens(rd, &msg.source_endpoint_guid, &msg.message_data); q_omg_security_set_remote_writer_crypto_tokens(rd, &msg->source_endpoint_guid, &msg->message_data);
} }
else if (strcmp(GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, msg.message_class_id) == 0) else if (strcmp(GMCLASSID_SECURITY_DATAREADER_CRYPTO_TOKENS, msg->message_class_id) == 0)
{ {
struct writer *wr; struct writer * const wr = entidx_lookup_writer_guid(gv->entity_index, &msg->destination_endpoint_guid);
wr = entidx_lookup_writer_guid(gv->entity_index, &msg.destination_endpoint_guid);
if (!wr) if (!wr)
{ {
GVWARNING("received a crypto exchange message from "PGUIDFMT" with writer unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg.destination_participant_guid)); GVWARNING("received a crypto exchange message from "PGUIDFMT" with writer unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
goto invalid_msg; return;
} }
q_omg_security_set_remote_reader_crypto_tokens(wr, &msg.source_endpoint_guid, &msg.message_data); q_omg_security_set_remote_reader_crypto_tokens(wr, &msg->source_endpoint_guid, &msg->message_data);
} }
else else
{ {
@ -419,12 +256,6 @@ void handle_crypto_exchange_message(const struct receiver_state *rst, ddsi_entit
guid.entityid.u = NN_ENTITYID_PARTICIPANT; guid.entityid.u = NN_ENTITYID_PARTICIPANT;
GVWARNING("participant "PGUIDFMT" received a crypto exchange message with unknown class_id", PGUID(guid)); GVWARNING("participant "PGUIDFMT" received a crypto exchange message with unknown class_id", PGUID(guid));
} }
invalid_msg:
nn_participant_generic_message_deinit(&msg);
deser_msg_failed:
return;
} }
#endif /* DDSI_INCLUDE_SECURITY */ #endif /* DDSI_INCLUDE_SECURITY */

View file

@ -25,7 +25,6 @@
#include "dds/ddsi/ddsi_plist.h" #include "dds/ddsi/ddsi_plist.h"
#include "dds/security/core/dds_security_utils.h" #include "dds/security/core/dds_security_utils.h"
const enum pserop pserop_participant_generic_message[] = const enum pserop pserop_participant_generic_message[] =
{ {
/* nn_participant_generic_message */ /* nn_participant_generic_message */
@ -47,7 +46,7 @@ const enum pserop pserop_participant_generic_message[] =
XSTOP, XSTOP,
XSTOP /* end */ XSTOP /* end */
}; };
const size_t pserop_participant_generic_message_nops = sizeof (pserop_participant_generic_message) / sizeof (pserop_participant_generic_message[0]);
static void static void
alias_simple_sequence(ddsi_octetseq_t *dst, const ddsi_octetseq_t *src, size_t elem_size) alias_simple_sequence(ddsi_octetseq_t *dst, const ddsi_octetseq_t *src, size_t elem_size)

View file

@ -762,61 +762,6 @@ error:
return DDS_RETCODE_ERROR; return DDS_RETCODE_ERROR;
} }
static const char * get_builtin_topic_name(ddsi_entityid_t id)
{
switch (id.u) {
case NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_TOPIC_READER:
return "DCPSTopic";
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER:
return "DCPSPublication";
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER:
return "DCPSSubscription";
break;
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER:
return "DCPSParticipant";
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER:
return "DCPSParticipantMessage";
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER:
return "DCPSPublicationsSecure";
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER:
return "DCPSSubscriptionsSecure";
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER:
return "DCPSParticipantStatelessMessage";
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER:
return "DCPSParticipantMessageSecure";
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER:
return "DCPSParticipantVolatileMessageSecure";
break;
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER:
return "DCPSParticipantsSecure";
break;
default:
return "(null)";
break;
}
return NULL;
}
static void notify_handshake_recv_token(struct participant *pp, struct proxy_participant *proxypp) static void notify_handshake_recv_token(struct participant *pp, struct proxy_participant *proxypp)
{ {
struct ddsi_handshake *handshake; struct ddsi_handshake *handshake;
@ -828,22 +773,6 @@ static void notify_handshake_recv_token(struct participant *pp, struct proxy_par
} }
} }
static const char * get_reader_topic_name(struct reader *rd)
{
if (rd->topic) {
return rd->topic->name;
}
return get_builtin_topic_name(rd->e.guid.entityid);
}
static const char * get_writer_topic_name(struct writer *wr)
{
if (wr->topic) {
return wr->topic->name;
}
return get_builtin_topic_name(wr->e.guid.entityid);
}
bool q_omg_participant_is_secure(const struct participant *pp) bool q_omg_participant_is_secure(const struct participant *pp)
{ {
return ((pp->sec_attr != NULL) && (pp->sec_attr->crypto_handle != DDS_SECURITY_HANDLE_NIL)); return ((pp->sec_attr != NULL) && (pp->sec_attr->crypto_handle != DDS_SECURITY_HANDLE_NIL));
@ -1292,7 +1221,6 @@ void q_omg_security_register_writer(struct writer *wr)
DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT; DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
DDS_Security_PartitionQosPolicy partitions; DDS_Security_PartitionQosPolicy partitions;
DDS_Security_PropertySeq properties; DDS_Security_PropertySeq properties;
const char *topic_name;
if (!sc) if (!sc)
return; return;
@ -1303,8 +1231,7 @@ void q_omg_security_register_writer(struct writer *wr)
memset(&(partitions), 0, sizeof(DDS_Security_PartitionQosPolicy)); memset(&(partitions), 0, sizeof(DDS_Security_PartitionQosPolicy));
wr->sec_attr = writer_sec_attributes_new(); wr->sec_attr = writer_sec_attributes_new();
topic_name = get_writer_topic_name(wr); if (!sc->access_control_context->get_datawriter_sec_attributes(sc->access_control_context, pp->sec_attr->permissions_handle, wr->topic->name, &partitions, NULL, &wr->sec_attr->attr, &exception))
if (!sc->access_control_context->get_datawriter_sec_attributes(sc->access_control_context, pp->sec_attr->permissions_handle, topic_name, &partitions, NULL, &wr->sec_attr->attr, &exception))
{ {
EXCEPTION_ERROR(sc, &exception, "Failed to retrieve writer security attributes"); EXCEPTION_ERROR(sc, &exception, "Failed to retrieve writer security attributes");
goto no_attr; goto no_attr;
@ -1413,7 +1340,6 @@ void q_omg_security_register_reader(struct reader *rd)
DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT; DDS_Security_SecurityException exception = DDS_SECURITY_EXCEPTION_INIT;
DDS_Security_PartitionQosPolicy partitions; DDS_Security_PartitionQosPolicy partitions;
DDS_Security_PropertySeq properties; DDS_Security_PropertySeq properties;
const char *topic_name;
if (!sc) if (!sc)
return; return;
@ -1425,8 +1351,7 @@ void q_omg_security_register_reader(struct reader *rd)
rd->sec_attr = reader_sec_attributes_new(); rd->sec_attr = reader_sec_attributes_new();
topic_name = get_reader_topic_name(rd); if (!sc->access_control_context->get_datareader_sec_attributes(sc->access_control_context, pp->sec_attr->permissions_handle, rd->topic->name, &partitions, NULL, &rd->sec_attr->attr, &exception))
if (!sc->access_control_context->get_datareader_sec_attributes(sc->access_control_context, pp->sec_attr->permissions_handle, topic_name, &partitions, NULL, &rd->sec_attr->attr, &exception))
{ {
EXCEPTION_ERROR(sc, &exception, "Failed to retrieve reader security attributes"); EXCEPTION_ERROR(sc, &exception, "Failed to retrieve reader security attributes");
goto no_attr; goto no_attr;
@ -2650,7 +2575,7 @@ static bool q_omg_security_encode_datareader_submessage(struct reader *rd, const
const struct dds_security_context *sc = q_omg_security_get_secure_context (rd->c.pp); const struct dds_security_context *sc = q_omg_security_get_secure_context (rd->c.pp);
assert (sc); assert (sc);
GVTRACE (" encode_datareader_submessage "PGUIDFMT" %s/%s", PGUID (rd->e.guid), get_reader_topic_name (rd), rd->topic ? rd->topic->type_name : "(null)"); GVTRACE (" encode_datareader_submessage "PGUIDFMT" %s/%s", PGUID (rd->e.guid), rd->topic->name, rd->topic->type_name);
// FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_datareader_submessage(SOURCE)"); // FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_datareader_submessage(SOURCE)");
ddsrt_mutex_lock (&rd->e.lock); ddsrt_mutex_lock (&rd->e.lock);
@ -2665,8 +2590,7 @@ static bool q_omg_security_encode_datareader_submessage(struct reader *rd, const
if ((hdls._length = (DDS_Security_unsigned_long) idx) == 0) if ((hdls._length = (DDS_Security_unsigned_long) idx) == 0)
{ {
GVTRACE ("Submsg encoding failed for datareader "PGUIDFMT" %s/%s: no matching writers\n", PGUID (rd->e.guid), GVTRACE ("Submsg encoding failed for datareader "PGUIDFMT" %s/%s: no matching writers\n", PGUID (rd->e.guid), rd->topic->name, rd->topic->type_name);
get_reader_topic_name (rd), rd->topic ? rd->topic->type_name : "(null)");
goto err_enc_drd_subm; goto err_enc_drd_subm;
} }
@ -2678,8 +2602,8 @@ static bool q_omg_security_encode_datareader_submessage(struct reader *rd, const
if (!(result = sc->crypto_context->crypto_transform->encode_datareader_submessage ( if (!(result = sc->crypto_context->crypto_transform->encode_datareader_submessage (
sc->crypto_context->crypto_transform, &encoded_buffer, &plain_buffer, rd->sec_attr->crypto_handle, &hdls, &ex))) sc->crypto_context->crypto_transform, &encoded_buffer, &plain_buffer, rd->sec_attr->crypto_handle, &hdls, &ex)))
{ {
GVWARNING ("Submsg encoding failed for datareader "PGUIDFMT" %s/%s: %s", PGUID (rd->e.guid), get_reader_topic_name (rd), GVWARNING ("Submsg encoding failed for datareader "PGUIDFMT" %s/%s: %s", PGUID (rd->e.guid), rd->topic->name,
rd->topic ? rd->topic->type_name : "(null)", ex.message ? ex.message : "Unknown error"); rd->topic->type_name, ex.message ? ex.message : "Unknown error");
GVTRACE ("\n"); GVTRACE ("\n");
DDS_Security_Exception_reset (&ex); DDS_Security_Exception_reset (&ex);
goto err_enc_drd_subm; goto err_enc_drd_subm;
@ -2723,7 +2647,7 @@ static bool q_omg_security_encode_datawriter_submessage (struct writer *wr, cons
const struct dds_security_context *sc = q_omg_security_get_secure_context (wr->c.pp); const struct dds_security_context *sc = q_omg_security_get_secure_context (wr->c.pp);
assert (sc); assert (sc);
GVTRACE (" encode_datawriter_submessage "PGUIDFMT" %s/%s", PGUID (wr->e.guid), get_writer_topic_name (wr), wr->topic ? wr->topic->type_name : "(null)"); GVTRACE (" encode_datawriter_submessage "PGUIDFMT" %s/%s", PGUID (wr->e.guid), wr->topic->name, wr->topic->type_name);
// FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_datawriter_submessage(SOURCE)"); // FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_datawriter_submessage(SOURCE)");
@ -2738,7 +2662,7 @@ static bool q_omg_security_encode_datawriter_submessage (struct writer *wr, cons
if ((hdls._length = (DDS_Security_unsigned_long) idx) == 0) if ((hdls._length = (DDS_Security_unsigned_long) idx) == 0)
{ {
GVTRACE ("Submsg encoding failed for datawriter "PGUIDFMT" %s/%s: no matching readers\n", PGUID (wr->e.guid), GVTRACE ("Submsg encoding failed for datawriter "PGUIDFMT" %s/%s: no matching readers\n", PGUID (wr->e.guid),
get_writer_topic_name (wr), wr->topic ? wr->topic->type_name : "(null)"); wr->topic->name, wr->topic->type_name);
goto err_enc_dwr_subm; goto err_enc_dwr_subm;
} }
@ -2762,8 +2686,7 @@ static bool q_omg_security_encode_datawriter_submessage (struct writer *wr, cons
if (!result) if (!result)
{ {
GVWARNING ("Submsg encoding failed for datawriter "PGUIDFMT" %s/%s: %s", PGUID (wr->e.guid), get_writer_topic_name (wr), GVWARNING ("Submsg encoding failed for datawriter "PGUIDFMT" %s/%s: %s", PGUID (wr->e.guid), wr->topic->name, wr->topic->type_name, ex.message ? ex.message : "Unknown error");
wr->topic ? wr->topic->type_name : "(null)", ex.message ? ex.message : "Unknown error");
GVTRACE ("\n"); GVTRACE ("\n");
DDS_Security_Exception_reset (&ex); DDS_Security_Exception_reset (&ex);
goto err_enc_dwr_subm; goto err_enc_dwr_subm;
@ -2916,7 +2839,7 @@ static bool q_omg_security_encode_serialized_payload (const struct writer *wr, c
// FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_serialized_payload(SOURCE)"); // FIXME: print_buf(src_buf, src_len, "q_omg_security_encode_serialized_payload(SOURCE)");
GVTRACE (" encode_payload "PGUIDFMT" %s/%s\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", wr->topic ? wr->topic->type_name : "(null)"); GVTRACE (" encode_payload "PGUIDFMT" %s/%s\n", PGUID (wr->e.guid), wr->topic->name, wr->topic->type_name);
memset (&extra_inline_qos, 0, sizeof (extra_inline_qos)); memset (&extra_inline_qos, 0, sizeof (extra_inline_qos));
memset (&encoded_buffer, 0, sizeof (encoded_buffer)); memset (&encoded_buffer, 0, sizeof (encoded_buffer));

View file

@ -461,92 +461,6 @@ static struct ddsi_serdata *serdata_default_from_sample_cdr_nokey (const struct
return fix_serdata_default_nokey (d, tpcmn->serdata_basehash); return fix_serdata_default_nokey (d, tpcmn->serdata_basehash);
} }
static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample)
{
/* Currently restricted to DDSI discovery data (XTypes will need a rethink of the default representation and that may result in discovery data being moved to that new representation), and that means: keys are either GUIDs or an unbounded string for topics, for which MD5 is acceptable. Furthermore, these things don't get written very often, so scanning the parameter list to get the key value out is good enough for now. And at least it keeps the DDSI discovery data writing out of the internals of the sample representation */
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
const struct ddsi_plist_sample *sample = vsample;
struct ddsi_serdata_default *d = serdata_default_new(tp, kind);
if (d == NULL)
return NULL;
serdata_default_append_blob (&d, 1, sample->size, sample->blob);
const unsigned char *rawkey = ddsi_plist_findparam_native_unchecked (sample->blob, sample->keyparam);
#ifndef NDEBUG
size_t keysize;
#endif
assert(rawkey);
switch (sample->keyparam)
{
case PID_PARTICIPANT_GUID:
case PID_ENDPOINT_GUID:
case PID_GROUP_GUID:
d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1;
d->keyhash.m_keysize = sizeof(d->keyhash.m_hash);
memcpy (d->keyhash.m_hash, rawkey, 16);
#ifndef NDEBUG
keysize = 16;
#endif
break;
case PID_TOPIC_NAME: {
const char *topic_name = (const char *) (rawkey + sizeof(uint32_t));
uint32_t topic_name_sz;
uint32_t topic_name_sz_BE;
ddsrt_md5_state_t md5st;
ddsrt_md5_byte_t digest[16];
topic_name_sz = (uint32_t) strlen (topic_name) + 1;
topic_name_sz_BE = ddsrt_toBE4u (topic_name_sz);
d->keyhash.m_set = 1;
d->keyhash.m_iskey = 0;
d->keyhash.m_keysize = sizeof(d->keyhash.m_hash);
ddsrt_md5_init (&md5st);
ddsrt_md5_append (&md5st, (const ddsrt_md5_byte_t *) &topic_name_sz_BE, sizeof (topic_name_sz_BE));
ddsrt_md5_append (&md5st, (const ddsrt_md5_byte_t *) topic_name, topic_name_sz);
ddsrt_md5_finish (&md5st, digest);
memcpy (d->keyhash.m_hash, digest, 16);
#ifndef NDEBUG
keysize = sizeof (uint32_t) + topic_name_sz;
#endif
break;
}
default:
abort();
}
/* if it is supposed to be just a key, rawkey must be be the first field and followed only by a sentinel */
assert (kind != SDK_KEY || rawkey == (const unsigned char *)sample->blob + sizeof (nn_parameter_t));
assert (kind != SDK_KEY || sample->size == sizeof (nn_parameter_t) + alignup_size (keysize, 4) + sizeof (nn_parameter_t));
return fix_serdata_default (d, tp->c.serdata_basehash);
}
static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *vsample)
{
/* Currently restricted to DDSI discovery data (XTypes will need a rethink of the default representation and that may result in discovery data being moved to that new representation), and that means: keys are either GUIDs or an unbounded string for topics, for which MD5 is acceptable. Furthermore, these things don't get written very often, so scanning the parameter list to get the key value out is good enough for now. And at least it keeps the DDSI discovery data writing out of the internals of the sample representation */
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
const struct ddsi_rawcdr_sample *sample = vsample;
struct ddsi_serdata_default *d = serdata_default_new(tp, kind);
if (d == NULL)
return NULL;
assert (sample->keysize <= 16);
serdata_default_append_blob (&d, 1, sample->size, sample->blob);
serdata_default_append_aligned (&d, 0, 4);
d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1;
if (sample->keysize == 0)
{
d->keyhash.m_keysize = 0;
return fix_serdata_default_nokey (d, tp->c.serdata_basehash);
}
else
{
memcpy (&d->keyhash.m_hash, sample->key, sample->keysize);
d->keyhash.m_keysize = (unsigned)sample->keysize & 0x1f;
return fix_serdata_default (d, tp->c.serdata_basehash);
}
}
static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serdata *serdata_common) static struct ddsi_serdata *serdata_default_to_topicless (const struct ddsi_serdata *serdata_common)
{ {
const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common;
@ -669,37 +583,6 @@ static size_t serdata_default_print_cdr (const struct ddsi_sertopic *sertopic_co
return dds_stream_print_sample (&is, tp, buf, size); return dds_stream_print_sample (&is, tp, buf, size);
} }
static size_t serdata_default_print_plist (const struct ddsi_sertopic *sertopic_common, const struct ddsi_serdata *serdata_common, char *buf, size_t size)
{
const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common;
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)sertopic_common;
ddsi_plist_src_t src;
ddsi_plist_t tmp;
src.buf = (const unsigned char *) d->data;
src.bufsz = d->pos;
src.encoding = d->hdr.identifier;
src.factory = tp->c.gv->m_factory;
src.logconfig = &tp->c.gv->logconfig;
src.protocol_version.major = RTPS_MAJOR;
src.protocol_version.minor = RTPS_MINOR;
src.strict = false;
src.vendorid = NN_VENDORID_ECLIPSE;
if (ddsi_plist_init_frommsg (&tmp, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0)
return (size_t) snprintf (buf, size, "(unparseable-plist)");
else
{
size_t ret = ddsi_plist_print (buf, size, &tmp);
ddsi_plist_fini (&tmp);
return ret;
}
}
static size_t serdata_default_print_raw (const struct ddsi_sertopic *sertopic_common, const struct ddsi_serdata *serdata_common, char *buf, size_t size)
{
(void)sertopic_common; (void)serdata_common;
return (size_t) snprintf (buf, size, "(blob)");
}
static void serdata_default_get_keyhash (const struct ddsi_serdata *serdata_common, struct ddsi_keyhash *buf, bool force_md5) static void serdata_default_get_keyhash (const struct ddsi_serdata *serdata_common, struct ddsi_keyhash *buf, bool force_md5)
{ {
const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common; const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common;
@ -753,39 +636,3 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
.print = serdata_default_print_cdr, .print = serdata_default_print_cdr,
.get_keyhash = serdata_default_get_keyhash .get_keyhash = serdata_default_get_keyhash
}; };
const struct ddsi_serdata_ops ddsi_serdata_ops_plist = {
.get_size = serdata_default_get_size,
.eqkey = serdata_default_eqkey,
.free = serdata_default_free,
.from_ser = serdata_default_from_ser,
.from_ser_iov = serdata_default_from_ser_iov,
.from_keyhash = 0,
.from_sample = serdata_default_from_sample_plist,
.to_ser = serdata_default_to_ser,
.to_sample = 0,
.to_ser_ref = serdata_default_to_ser_ref,
.to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless,
.topicless_to_sample = 0,
.print = serdata_default_print_plist,
.get_keyhash = serdata_default_get_keyhash
};
const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = {
.get_size = serdata_default_get_size,
.eqkey = serdata_default_eqkey,
.free = serdata_default_free,
.from_ser = serdata_default_from_ser,
.from_ser_iov = serdata_default_from_ser_iov,
.from_keyhash = 0,
.from_sample = serdata_default_from_sample_rawcdr,
.to_ser = serdata_default_to_ser,
.to_sample = 0,
.to_ser_ref = serdata_default_to_ser_ref,
.to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless,
.topicless_to_sample = 0,
.print = serdata_default_print_raw,
.get_keyhash = serdata_default_get_keyhash
};

View file

@ -0,0 +1,303 @@
/*
* Copyright(c) 2020 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
*/
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/md5.h"
#include "dds/ddsrt/mh3.h"
#include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_freelist.h"
#include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/ddsi_cdrstream.h"
#include "dds/ddsi/q_radmin.h"
#include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/ddsi_serdata_plist.h"
#include "dds/ddsi/q_xmsg.h"
static uint32_t serdata_plist_get_size (const struct ddsi_serdata *dcmn)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *) dcmn;
return 4 + d->pos; // FIXME: +4 for CDR header should be eliminated
}
static bool serdata_plist_eqkey (const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn)
{
const struct ddsi_serdata_plist *a = (const struct ddsi_serdata_plist *) acmn;
const struct ddsi_serdata_plist *b = (const struct ddsi_serdata_plist *) bcmn;
return memcmp (&a->keyhash, &b->keyhash, sizeof (a->keyhash)) == 0;
}
static void serdata_plist_free (struct ddsi_serdata *dcmn)
{
struct ddsi_serdata_plist *d = (struct ddsi_serdata_plist *) dcmn;
ddsrt_free (d);
}
static struct ddsi_serdata_plist *serdata_plist_new (const struct ddsi_sertopic_plist *tp, enum ddsi_serdata_kind kind, size_t size, const void *cdr_header)
{
/* FIXME: check whether this really is the correct maximum: offsets are relative
to the CDR header, but there are also some places that use a serdata as-if it
were a stream, and those use offsets (m_index) relative to the start of the
serdata */
if (size < 4 || size > UINT32_MAX - offsetof (struct ddsi_serdata_plist, identifier))
return NULL;
struct ddsi_serdata_plist *d = ddsrt_malloc (sizeof (*d) + size);
if (d == NULL)
return NULL;
ddsi_serdata_init (&d->c, &tp->c, kind);
d->pos = 0;
d->size = (uint32_t) size;
// FIXME: vendorid/protoversion are not available when creating a serdata
// these should be overruled by the one creating the serdata
d->vendorid = NN_VENDORID_UNKNOWN;
d->protoversion.major = RTPS_MAJOR;
d->protoversion.minor = RTPS_MINOR;
const uint16_t *hdrsrc = cdr_header;
d->identifier = hdrsrc[0];
d->options = hdrsrc[1];
if (d->identifier != PL_CDR_LE && d->identifier != PL_CDR_BE)
{
ddsrt_free (d);
return NULL;
}
return d;
}
static struct ddsi_serdata *serdata_plist_fix (const struct ddsi_sertopic_plist *tp, struct ddsi_serdata_plist *d)
{
assert (tp->keyparam != PID_SENTINEL);
void *needlep;
size_t needlesz;
if (ddsi_plist_findparam_checking (d->data, d->pos, d->identifier, tp->keyparam, &needlep, &needlesz) != DDS_RETCODE_OK)
{
ddsrt_free (d);
return NULL;
}
assert (needlep);
if (needlesz != sizeof (d->keyhash))
{
ddsrt_free (d);
return NULL;
}
memcpy (&d->keyhash, needlep, 16);
d->c.hash = ddsrt_mh3 (&d->keyhash, sizeof (d->keyhash), 0) ^ tp->c.serdata_basehash;
return &d->c;
}
static struct ddsi_serdata *serdata_plist_from_ser (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size)
{
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) tpcmn;
struct ddsi_serdata_plist *d = serdata_plist_new (tp, kind, size, NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)));
uint32_t off = 4; /* must skip the CDR header */
assert (fragchain->min == 0);
assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */
while (fragchain)
{
assert (fragchain->min <= off);
assert (fragchain->maxp1 <= size);
if (fragchain->maxp1 > off)
{
/* only copy if this fragment adds data */
const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain));
uint32_t n = fragchain->maxp1 - off;
memcpy (d->data + d->pos, payload + off - fragchain->min, n);
d->pos += n;
off = fragchain->maxp1;
}
fragchain = fragchain->nextfrag;
}
return serdata_plist_fix (tp, d);
}
static struct ddsi_serdata *serdata_plist_from_ser_iov (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size)
{
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) tpcmn;
assert (niov >= 1);
struct ddsi_serdata_plist *d = serdata_plist_new (tp, kind, size, iov[0].iov_base);
memcpy (d->data + d->pos, (const char *) iov[0].iov_base + 4, iov[0].iov_len - 4);
d->pos += (uint32_t) iov[0].iov_len - 4;
for (ddsrt_msg_iovlen_t i = 1; i < niov; i++)
{
memcpy (d->data + d->pos, (const char *) iov[i].iov_base, iov[i].iov_len);
d->pos += (uint32_t) iov[i].iov_len;
}
return serdata_plist_fix (tp, d);
}
static struct ddsi_serdata *serdata_plist_from_keyhash (const struct ddsi_sertopic *tpcmn, const ddsi_keyhash_t *keyhash)
{
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) tpcmn;
const struct { uint16_t identifier, options; nn_parameter_t par; ddsi_keyhash_t kh; } in = {
.identifier = CDR_BE,
.options = 0,
.par = {
.parameterid = ddsrt_toBE2u (tp->keyparam),
.length = sizeof (*keyhash)
},
*keyhash
};
const ddsrt_iovec_t iov = { .iov_base = (void *) &in, .iov_len = sizeof (in) };
return serdata_plist_from_ser_iov (tpcmn, SDK_KEY, 1, &iov, sizeof (in) - 4);
}
static bool serdata_plist_topicless_to_sample (const struct ddsi_sertopic *topic_common, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *)serdata_common;
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) topic_common;
struct ddsi_domaingv * const gv = tp->c.gv;
if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */
ddsi_plist_src_t src = {
.buf = (const unsigned char *) d->data,
.bufsz = d->pos,
.encoding = d->identifier,
.factory = gv->m_factory,
.logconfig = &gv->logconfig,
.protocol_version = d->protoversion,
.strict = NN_STRICT_P (gv->config),
.vendorid = d->vendorid
};
const dds_return_t rc = ddsi_plist_init_frommsg (sample, NULL, ~(uint64_t)0, ~(uint64_t)0, &src);
// FIXME: need a more informative return type
if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_UNSUPPORTED)
GVWARNING ("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return (rc == DDS_RETCODE_OK);
}
static bool serdata_plist_to_sample (const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim)
{
/* the "plist" topics only differ in the parameter that is used as the key value */
return serdata_plist_topicless_to_sample (serdata_common->topic, serdata_common, sample, bufptr, buflim);
}
static void serdata_plist_to_ser (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, void *buf)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *)serdata_common;
memcpy (buf, (char *) &d->identifier + off, sz);
}
static struct ddsi_serdata *serdata_plist_to_ser_ref (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, ddsrt_iovec_t *ref)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *)serdata_common;
ref->iov_base = (char *) &d->identifier + off;
ref->iov_len = (ddsrt_iov_len_t) sz;
return ddsi_serdata_ref (serdata_common);
}
static void serdata_plist_to_ser_unref (struct ddsi_serdata *serdata_common, const ddsrt_iovec_t *ref)
{
(void) ref;
ddsi_serdata_unref (serdata_common);
}
static struct ddsi_serdata *serdata_plist_from_sample (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
{
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *)tpcmn;
const struct { uint16_t identifier, options; } header = { tp->native_encoding_identifier, 0 };
const ddsi_guid_t nullguid = { .prefix = { .u = { 0,0,0 } }, .entityid = { .u = 0 } };
// FIXME: key must not require byteswapping (GUIDs are ok)
// FIXME: rework plist stuff so it doesn't need an nn_xmsg
struct nn_xmsg *mpayload = nn_xmsg_new (tp->c.gv->xmsgpool, &nullguid, NULL, 0, NN_XMSG_KIND_DATA);
memcpy (nn_xmsg_append (mpayload, NULL, 4), &header, 4);
ddsi_plist_addtomsg (mpayload, sample, ~(uint64_t)0, ~(uint64_t)0);
nn_xmsg_addpar_sentinel (mpayload);
size_t sz;
unsigned char *blob = nn_xmsg_payload (&sz, mpayload);
#ifndef NDEBUG
void *needle;
size_t needlesz;
assert (ddsi_plist_findparam_checking (blob + 4, sz, header.identifier, tp->keyparam, &needle, &needlesz) == DDS_RETCODE_OK);
assert (needle && needlesz == 16);
#endif
ddsrt_iovec_t iov = { .iov_base = blob, .iov_len = (ddsrt_iov_len_t) sz };
struct ddsi_serdata *d = serdata_plist_from_ser_iov (tpcmn, kind, 1, &iov, sz - 4);
nn_xmsg_free (mpayload);
/* we know the vendor when we construct a serdata from a sample */
struct ddsi_serdata_plist *d_plist = (struct ddsi_serdata_plist *) d;
d_plist->vendorid = NN_VENDORID_ECLIPSE;
return d;
}
static struct ddsi_serdata *serdata_plist_to_topicless (const struct ddsi_serdata *serdata_common)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *) serdata_common;
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) d->c.topic;
ddsrt_iovec_t iov = { .iov_base = (char *) &d->identifier, .iov_len = 4 + d->pos };
struct ddsi_serdata *dcmn_tl = serdata_plist_from_ser_iov (&tp->c, SDK_KEY, 1, &iov, d->pos);
assert (dcmn_tl != NULL);
dcmn_tl->topic = NULL;
return dcmn_tl;
}
static void serdata_plist_get_keyhash (const struct ddsi_serdata *serdata_common, struct ddsi_keyhash *buf, bool force_md5)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *)serdata_common;
if (!force_md5)
memcpy (buf, &d->keyhash, 16);
else
{
ddsrt_md5_state_t md5st;
ddsrt_md5_init (&md5st);
ddsrt_md5_append (&md5st, (ddsrt_md5_byte_t *) &d->keyhash, 16);
ddsrt_md5_finish (&md5st, (ddsrt_md5_byte_t *) buf->value);
}
}
static size_t serdata_plist_print_plist (const struct ddsi_sertopic *sertopic_common, const struct ddsi_serdata *serdata_common, char *buf, size_t size)
{
const struct ddsi_serdata_plist *d = (const struct ddsi_serdata_plist *) serdata_common;
const struct ddsi_sertopic_plist *tp = (const struct ddsi_sertopic_plist *) sertopic_common;
ddsi_plist_src_t src = {
.buf = (const unsigned char *) d->data,
.bufsz = d->pos,
.encoding = d->identifier,
.factory = tp->c.gv->m_factory,
.logconfig = &tp->c.gv->logconfig,
.protocol_version = d->protoversion,
.strict = false,
.vendorid = d->vendorid
};
ddsi_plist_t tmp;
if (ddsi_plist_init_frommsg (&tmp, NULL, ~(uint64_t)0, ~(uint64_t)0, &src) < 0)
return (size_t) snprintf (buf, size, "(unparseable-plist)");
else
{
size_t ret = ddsi_plist_print (buf, size, &tmp);
ddsi_plist_fini (&tmp);
return ret;
}
}
const struct ddsi_serdata_ops ddsi_serdata_ops_plist = {
.get_size = serdata_plist_get_size,
.eqkey = serdata_plist_eqkey,
.free = serdata_plist_free,
.from_ser = serdata_plist_from_ser,
.from_ser_iov = serdata_plist_from_ser_iov,
.from_keyhash = serdata_plist_from_keyhash,
.from_sample = serdata_plist_from_sample,
.to_ser = serdata_plist_to_ser,
.to_sample = serdata_plist_to_sample,
.to_ser_ref = serdata_plist_to_ser_ref,
.to_ser_unref = serdata_plist_to_ser_unref,
.to_topicless = serdata_plist_to_topicless,
.topicless_to_sample = serdata_plist_topicless_to_sample,
.print = serdata_plist_print_plist,
.get_keyhash = serdata_plist_get_keyhash
};

View file

@ -0,0 +1,297 @@
/*
* Copyright(c) 2020 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
*/
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/md5.h"
#include "dds/ddsrt/mh3.h"
#include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_freelist.h"
#include "dds/ddsi/ddsi_tkmap.h"
#include "dds/ddsi/ddsi_cdrstream.h"
#include "dds/ddsi/q_radmin.h"
#include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/ddsi_serdata_pserop.h"
static uint32_t serdata_pserop_get_size (const struct ddsi_serdata *dcmn)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *) dcmn;
return 4 + d->pos; // FIXME: +4 for CDR header should be eliminated
}
static bool serdata_pserop_eqkey (const struct ddsi_serdata *acmn, const struct ddsi_serdata *bcmn)
{
const struct ddsi_serdata_pserop *a = (const struct ddsi_serdata_pserop *) acmn;
const struct ddsi_serdata_pserop *b = (const struct ddsi_serdata_pserop *) bcmn;
if (a->keyless != b->keyless)
return false;
else if (a->keyless)
return true;
else
return memcmp (a->sample, b->sample, 16) == 0;
}
static void serdata_pserop_free (struct ddsi_serdata *dcmn)
{
struct ddsi_serdata_pserop *d = (struct ddsi_serdata_pserop *) dcmn;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *) d->c.topic;
if (d->c.kind == SDK_DATA)
plist_fini_generic (d->sample, tp->ops, true);
if (d->sample)
ddsrt_free (d->sample);
ddsrt_free (d);
}
static struct ddsi_serdata_pserop *serdata_pserop_new (const struct ddsi_sertopic_pserop *tp, enum ddsi_serdata_kind kind, size_t size, const void *cdr_header)
{
/* FIXME: check whether this really is the correct maximum: offsets are relative
to the CDR header, but there are also some places that use a serdata as-if it
were a stream, and those use offsets (m_index) relative to the start of the
serdata */
assert (kind != SDK_EMPTY);
if (size < 4 || size > UINT32_MAX - offsetof (struct ddsi_serdata_pserop, identifier))
return NULL;
struct ddsi_serdata_pserop *d = ddsrt_malloc (sizeof (*d) + size);
if (d == NULL)
return NULL;
ddsi_serdata_init (&d->c, &tp->c, kind);
d->keyless = (tp->ops_key == NULL);
d->pos = 0;
d->size = (uint32_t) size;
const uint16_t *hdrsrc = cdr_header;
d->identifier = hdrsrc[0];
d->options = hdrsrc[1];
assert (d->identifier == CDR_LE || d->identifier == CDR_BE);
if (kind == SDK_KEY && d->keyless)
d->sample = NULL;
else if ((d->sample = ddsrt_malloc ((kind == SDK_DATA) ? tp->memsize : 16)) == NULL)
{
ddsrt_free (d);
return NULL;
}
return d;
}
static struct ddsi_serdata *serdata_pserop_fix (const struct ddsi_sertopic_pserop *tp, struct ddsi_serdata_pserop *d)
{
const bool needs_bswap = (d->identifier != tp->native_encoding_identifier);
const enum pserop *ops = (d->c.kind == SDK_DATA) ? tp->ops : tp->ops_key;
d->c.hash = tp->c.serdata_basehash;
if (ops != NULL)
{
assert (d->pos >= 16 && tp->memsize >= 16);
if (plist_deser_generic (d->sample, d->data, d->pos, needs_bswap, (d->c.kind == SDK_DATA) ? tp->ops : tp->ops_key) < 0)
{
ddsrt_free (d->sample);
ddsrt_free (d);
return NULL;
}
if (tp->ops_key)
{
assert (d->pos >= 16 && tp->memsize >= 16);
d->c.hash ^= ddsrt_mh3 (d->sample, 16, 0);
}
}
return &d->c;
}
static struct ddsi_serdata *serdata_pserop_from_ser (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)tpcmn;
struct ddsi_serdata_pserop *d = serdata_pserop_new (tp, kind, size, NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)));
uint32_t off = 4; /* must skip the CDR header */
assert (fragchain->min == 0);
assert (fragchain->maxp1 >= off); /* CDR header must be in first fragment */
while (fragchain)
{
assert (fragchain->min <= off);
assert (fragchain->maxp1 <= size);
if (fragchain->maxp1 > off)
{
/* only copy if this fragment adds data */
const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain));
uint32_t n = fragchain->maxp1 - off;
memcpy (d->data + d->pos, payload + off - fragchain->min, n);
d->pos += n;
off = fragchain->maxp1;
}
fragchain = fragchain->nextfrag;
}
return serdata_pserop_fix (tp, d);
}
static struct ddsi_serdata *serdata_pserop_from_ser_iov (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)tpcmn;
assert (niov >= 1);
struct ddsi_serdata_pserop *d = serdata_pserop_new (tp, kind, size, iov[0].iov_base);
const uint16_t *hdrsrc = (uint16_t *) iov[0].iov_base;
d->identifier = hdrsrc[0];
d->options = hdrsrc[1];
assert (d->identifier == CDR_LE || d->identifier == CDR_BE);
memcpy (d->data + d->pos, (const char *) iov[0].iov_base + 4, iov[0].iov_len - 4);
d->pos += (uint32_t) iov[0].iov_len - 4;
for (ddsrt_msg_iovlen_t i = 1; i < niov; i++)
{
memcpy (d->data + d->pos, (const char *) iov[i].iov_base, iov[i].iov_len);
d->pos += (uint32_t) iov[i].iov_len;
}
return serdata_pserop_fix (tp, d);
}
static struct ddsi_serdata *serdata_pserop_from_keyhash (const struct ddsi_sertopic *tpcmn, const ddsi_keyhash_t *keyhash)
{
const struct { uint16_t identifier, options; ddsi_keyhash_t kh; } in = { CDR_BE, 0, *keyhash };
const ddsrt_iovec_t iov = { .iov_base = (void *) &in, .iov_len = sizeof (in) };
return serdata_pserop_from_ser_iov (tpcmn, SDK_KEY, 1, &iov, sizeof (in) - 4);
}
static bool serdata_pserop_to_sample (const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *) d->c.topic;
if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */
if (d->c.kind == SDK_KEY)
memcpy (sample, d->sample, 16);
else
{
dds_return_t x;
x = plist_deser_generic (sample, d->data, d->pos, d->identifier != tp->native_encoding_identifier, tp->ops);
plist_unalias_generic (sample, tp->ops);
assert (x >= 0);
(void) x;
}
return true; /* FIXME: can't conversion to sample fail? */
}
static void serdata_pserop_to_ser (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, void *buf)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
memcpy (buf, (char *) &d->identifier + off, sz);
}
static struct ddsi_serdata *serdata_pserop_to_ser_ref (const struct ddsi_serdata *serdata_common, size_t off, size_t sz, ddsrt_iovec_t *ref)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
ref->iov_base = (char *) &d->identifier + off;
ref->iov_len = (ddsrt_iov_len_t) sz;
return ddsi_serdata_ref (serdata_common);
}
static void serdata_pserop_to_ser_unref (struct ddsi_serdata *serdata_common, const ddsrt_iovec_t *ref)
{
(void) ref;
ddsi_serdata_unref (serdata_common);
}
static struct ddsi_serdata *serdata_pserop_from_sample (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)tpcmn;
const struct { uint16_t identifier, options; } header = { tp->native_encoding_identifier, 0 };
if (kind == SDK_KEY && tp->ops_key == NULL)
return serdata_pserop_fix (tp, serdata_pserop_new (tp, kind, 0, &header));
else
{
void *data;
size_t size;
if (plist_ser_generic (&data, &size, sample, (kind == SDK_DATA) ? tp->ops : tp->ops_key) < 0)
return NULL;
const size_t size4 = (size + 3) & ~(size_t)3;
struct ddsi_serdata_pserop *d = serdata_pserop_new (tp, kind, size4, &header);
assert (tp->ops_key == NULL || (size >= 16 && tp->memsize >= 16));
memcpy (d->data, data, size);
memset (d->data + size, 0, size4 - size);
d->pos = (uint32_t) size;
ddsrt_free (data); // FIXME: shouldn't allocate twice & copy
// FIXME: and then this silly thing deserialises it immediately again -- perhaps it should be a bit lazier
return serdata_pserop_fix (tp, d);
}
}
static struct ddsi_serdata *serdata_pserop_to_topicless (const struct ddsi_serdata *serdata_common)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)d->c.topic;
ddsrt_iovec_t iov = { .iov_base = (char *) &d->identifier, .iov_len = (ddsrt_iov_len_t) (4 + d->pos) };
struct ddsi_serdata *dcmn_tl = serdata_pserop_from_ser_iov (&tp->c, SDK_KEY, 1, &iov, iov.iov_len);
assert (dcmn_tl != NULL);
dcmn_tl->topic = NULL;
return dcmn_tl;
}
static bool serdata_pserop_topicless_to_sample (const struct ddsi_sertopic *topic_common, const struct ddsi_serdata *serdata_common, void *sample, void **bufptr, void *buflim)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)topic_common;
if (bufptr) abort(); else { (void)buflim; } /* FIXME: haven't implemented that bit yet! */
if (tp->ops_key)
memcpy (sample, d->sample, 16);
return true;
}
static void serdata_pserop_get_keyhash (const struct ddsi_serdata *serdata_common, struct ddsi_keyhash *buf, bool force_md5)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)d->c.topic;
if (tp->ops_key == NULL)
memset (buf, 0, 16);
else
{
/* need big-endian representation for key hash, so be lazy & re-serialize
(and yes, it costs another malloc ...); note that key at offset 0 implies
ops_key is a prefix of ops */
void *be;
size_t besize;
(void) plist_ser_generic_be (&be, &besize, d->sample, tp->ops_key);
assert (besize == 16); /* that's the deal with keys for now */
if (!force_md5)
memcpy (buf, be, 16);
else
{
ddsrt_md5_state_t md5st;
ddsrt_md5_init (&md5st);
ddsrt_md5_append (&md5st, (ddsrt_md5_byte_t *) be, 16);
ddsrt_md5_finish (&md5st, (ddsrt_md5_byte_t *) buf->value);
}
ddsrt_free (be);
}
}
static size_t serdata_pserop_print_pserop (const struct ddsi_sertopic *sertopic_common, const struct ddsi_serdata *serdata_common, char *buf, size_t size)
{
const struct ddsi_serdata_pserop *d = (const struct ddsi_serdata_pserop *)serdata_common;
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)sertopic_common;
return plist_print_generic (buf, size, d->sample, tp->ops);
}
const struct ddsi_serdata_ops ddsi_serdata_ops_pserop = {
.get_size = serdata_pserop_get_size,
.eqkey = serdata_pserop_eqkey,
.free = serdata_pserop_free,
.from_ser = serdata_pserop_from_ser,
.from_ser_iov = serdata_pserop_from_ser_iov,
.from_keyhash = serdata_pserop_from_keyhash,
.from_sample = serdata_pserop_from_sample,
.to_ser = serdata_pserop_to_ser,
.to_sample = serdata_pserop_to_sample,
.to_ser_ref = serdata_pserop_to_ser_ref,
.to_ser_unref = serdata_pserop_to_ser_unref,
.to_topicless = serdata_pserop_to_topicless,
.topicless_to_sample = serdata_pserop_topicless_to_sample,
.print = serdata_pserop_print_pserop,
.get_keyhash = serdata_pserop_get_keyhash
};

View file

@ -56,7 +56,6 @@ uint32_t ddsi_sertopic_hash (const struct ddsi_sertopic *a)
struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *sertopic_const) struct ddsi_sertopic *ddsi_sertopic_ref (const struct ddsi_sertopic *sertopic_const)
{ {
struct ddsi_sertopic *sertopic = (struct ddsi_sertopic *) sertopic_const; struct ddsi_sertopic *sertopic = (struct ddsi_sertopic *) sertopic_const;
if (sertopic)
ddsrt_atomic_inc32 (&sertopic->refc); ddsrt_atomic_inc32 (&sertopic->refc);
return sertopic; return sertopic;
} }
@ -68,7 +67,7 @@ struct ddsi_sertopic *ddsi_sertopic_lookup_locked (struct ddsi_domaingv *gv, con
if (sertopic != NULL) if (sertopic != NULL)
assert (sertopic->gv != NULL); assert (sertopic->gv != NULL);
#endif #endif
return ddsi_sertopic_ref (sertopic); return sertopic ? ddsi_sertopic_ref (sertopic) : NULL;
} }
void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertopic *sertopic) void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertopic *sertopic)
@ -83,8 +82,6 @@ void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertop
} }
void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic) void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic)
{
if (sertopic)
{ {
if (ddsrt_atomic_dec32_ov (&sertopic->refc) == 1) if (ddsrt_atomic_dec32_ov (&sertopic->refc) == 1)
{ {
@ -100,7 +97,6 @@ void ddsi_sertopic_unref (struct ddsi_sertopic *sertopic)
ddsi_sertopic_free (sertopic); ddsi_sertopic_free (sertopic);
} }
} }
}
void ddsi_sertopic_init (struct ddsi_sertopic *tp, const char *name, const char *type_name, const struct ddsi_sertopic_ops *sertopic_ops, const struct ddsi_serdata_ops *serdata_ops, bool topickind_no_key) void ddsi_sertopic_init (struct ddsi_sertopic *tp, const char *name, const char *type_name, const struct ddsi_sertopic_ops *sertopic_ops, const struct ddsi_serdata_ops *serdata_ops, bool topickind_no_key)
{ {

View file

@ -0,0 +1,95 @@
/*
* Copyright(c) 2020 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
*/
#include <stddef.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/mh3.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsi/ddsi_plist.h"
#include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/ddsi_serdata_plist.h"
static bool sertopic_plist_equal (const struct ddsi_sertopic *acmn, const struct ddsi_sertopic *bcmn)
{
const struct ddsi_sertopic_plist *a = (struct ddsi_sertopic_plist *) acmn;
const struct ddsi_sertopic_plist *b = (struct ddsi_sertopic_plist *) bcmn;
if (a->native_encoding_identifier != b->native_encoding_identifier)
return false;
if (a->keyparam != b->keyparam)
return false;
return true;
}
static uint32_t sertopic_plist_hash (const struct ddsi_sertopic *tpcmn)
{
const struct ddsi_sertopic_plist *tp = (struct ddsi_sertopic_plist *) tpcmn;
uint32_t h = 0;
h = ddsrt_mh3 (&tp->native_encoding_identifier, sizeof (tp->native_encoding_identifier), h);
h = ddsrt_mh3 (&tp->keyparam, sizeof (tp->keyparam), h);
return h;
}
static void sertopic_plist_free (struct ddsi_sertopic *tpcmn)
{
struct ddsi_sertopic_plist *tp = (struct ddsi_sertopic_plist *) tpcmn;
ddsi_sertopic_fini (&tp->c);
ddsrt_free (tp);
}
static void sertopic_plist_zero_samples (const struct ddsi_sertopic *sertopic_common, void *sample, size_t count)
{
(void) sertopic_common;
ddsi_plist_t *xs = sample;
for (size_t i = 0; i < count; i++)
ddsi_plist_init_empty (&xs[i]);
}
static void sertopic_plist_realloc_samples (void **ptrs, const struct ddsi_sertopic *sertopic_common, void *old, size_t oldcount, size_t count)
{
(void) sertopic_common;
ddsi_plist_t *new = (oldcount == count) ? old : dds_realloc (old, count * sizeof (ddsi_plist_t));
if (new)
{
for (size_t i = count; i < oldcount; i++)
ddsi_plist_init_empty (&new[i]);
for (size_t i = 0; i < count; i++)
ptrs[i] = &new[i];
}
}
static void sertopic_plist_free_samples (const struct ddsi_sertopic *sertopic_common, void **ptrs, size_t count, dds_free_op_t op)
{
(void) sertopic_common;
if (count > 0)
{
#ifndef NDEBUG
for (size_t i = 0, off = 0; i < count; i++, off += sizeof (ddsi_plist_t))
assert ((char *)ptrs[i] == (char *)ptrs[0] + off);
#endif
ddsi_plist_t *xs = ptrs[0];
for (size_t i = 0; i < count; i++)
ddsi_plist_fini (&xs[i]);
if (op & DDS_FREE_ALL_BIT)
dds_free (ptrs[0]);
}
}
const struct ddsi_sertopic_ops ddsi_sertopic_ops_plist = {
.equal = sertopic_plist_equal,
.hash = sertopic_plist_hash,
.free = sertopic_plist_free,
.zero_samples = sertopic_plist_zero_samples,
.realloc_samples = sertopic_plist_realloc_samples,
.free_samples = sertopic_plist_free_samples
};

View file

@ -0,0 +1,118 @@
/*
* Copyright(c) 2020 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
*/
#include <stddef.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/md5.h"
#include "dds/ddsrt/mh3.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsi/q_bswap.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/q_freelist.h"
#include "dds/ddsi/ddsi_plist_generic.h"
#include "dds/ddsi/ddsi_sertopic.h"
#include "dds/ddsi/ddsi_serdata_pserop.h"
static bool sertopic_pserop_equal (const struct ddsi_sertopic *acmn, const struct ddsi_sertopic *bcmn)
{
const struct ddsi_sertopic_pserop *a = (struct ddsi_sertopic_pserop *) acmn;
const struct ddsi_sertopic_pserop *b = (struct ddsi_sertopic_pserop *) bcmn;
if (a->native_encoding_identifier != b->native_encoding_identifier)
return false;
if (a->memsize != b->memsize)
return false;
if (a->nops != b->nops)
return false;
assert (a->nops > 0);
if (memcmp (a->ops, b->ops, a->nops * sizeof (*a->ops)) != 0)
return false;
if (a->nops_key != b->nops_key)
return false;
if (a->ops_key && memcmp (a->ops_key, b->ops_key, a->nops_key * sizeof (*a->ops_key)) != 0)
return false;
return true;
}
static uint32_t sertopic_pserop_hash (const struct ddsi_sertopic *tpcmn)
{
const struct ddsi_sertopic_pserop *tp = (struct ddsi_sertopic_pserop *) tpcmn;
uint32_t h = 0;
h = ddsrt_mh3 (&tp->native_encoding_identifier, sizeof (tp->native_encoding_identifier), h);
h = ddsrt_mh3 (&tp->memsize, sizeof (tp->memsize), h);
h = ddsrt_mh3 (&tp->nops, sizeof (tp->nops), h);
h = ddsrt_mh3 (tp->ops, tp->nops * sizeof (*tp->ops), h);
h = ddsrt_mh3 (&tp->nops_key, sizeof (tp->nops_key), h);
if (tp->ops_key)
h = ddsrt_mh3 (tp->ops_key, tp->nops_key * sizeof (*tp->ops_key), h);
return h;
}
static void sertopic_pserop_free (struct ddsi_sertopic *tpcmn)
{
struct ddsi_sertopic_pserop *tp = (struct ddsi_sertopic_pserop *) tpcmn;
ddsi_sertopic_fini (&tp->c);
ddsrt_free (tp);
}
static void sertopic_pserop_zero_samples (const struct ddsi_sertopic *sertopic_common, void *sample, size_t count)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)sertopic_common;
memset (sample, 0, tp->memsize * count);
}
static void sertopic_pserop_realloc_samples (void **ptrs, const struct ddsi_sertopic *sertopic_common, void *old, size_t oldcount, size_t count)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)sertopic_common;
const size_t size = tp->memsize;
char *new = (oldcount == count) ? old : dds_realloc (old, size * count);
if (new && count > oldcount)
memset (new + size * oldcount, 0, size * (count - oldcount));
for (size_t i = 0; i < count; i++)
{
void *ptr = (char *) new + i * size;
ptrs[i] = ptr;
}
}
static void sertopic_pserop_free_samples (const struct ddsi_sertopic *sertopic_common, void **ptrs, size_t count, dds_free_op_t op)
{
if (count > 0)
{
const struct ddsi_sertopic_pserop *tp = (const struct ddsi_sertopic_pserop *)sertopic_common;
const size_t size = tp->memsize;
#ifndef NDEBUG
for (size_t i = 0, off = 0; i < count; i++, off += size)
assert ((char *)ptrs[i] == (char *)ptrs[0] + off);
#endif
char *ptr = ptrs[0];
for (size_t i = 0; i < count; i++)
{
plist_fini_generic (ptr, tp->ops, false);
ptr += size;
}
if (op & DDS_FREE_ALL_BIT)
{
dds_free (ptrs[0]);
}
}
}
const struct ddsi_sertopic_ops ddsi_sertopic_ops_pserop = {
.equal = sertopic_pserop_equal,
.hash = sertopic_pserop_hash,
.free = sertopic_pserop_free,
.zero_samples = sertopic_pserop_zero_samples,
.realloc_samples = sertopic_pserop_realloc_samples,
.free_samples = sertopic_pserop_free_samples
};

View file

@ -863,8 +863,6 @@ static const struct cfgelem discovery_cfgelems[] = {
BLURB("<p>This element specifies the interval between spontaneous transmissions of participant discovery packets.</p>") }, BLURB("<p>This element specifies the interval between spontaneous transmissions of participant discovery packets.</p>") },
{ LEAF("DefaultMulticastAddress"), 1, "auto", ABSOFF(defaultMulticastAddressString), 0, uf_networkAddress, 0, pf_networkAddress, { LEAF("DefaultMulticastAddress"), 1, "auto", ABSOFF(defaultMulticastAddressString), 0, uf_networkAddress, 0, pf_networkAddress,
BLURB("<p>This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.</p>") }, BLURB("<p>This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.</p>") },
{ LEAF("EnableTopicDiscovery"), 1, "true", ABSOFF(do_topic_discovery), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>Do not use.</p>") },
{ GROUP("Ports", discovery_ports_cfgelems), { GROUP("Ports", discovery_ports_cfgelems),
BLURB("<p>The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.</p>") }, BLURB("<p>The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.</p>") },
END_MARKER END_MARKER

View file

@ -32,6 +32,7 @@
#include "dds/ddsi/q_xevent.h" #include "dds/ddsi/q_xevent.h"
#include "dds/ddsi/q_addrset.h" #include "dds/ddsi/q_addrset.h"
#include "dds/ddsi/q_ddsi_discovery.h" #include "dds/ddsi/q_ddsi_discovery.h"
#include "dds/ddsi/ddsi_serdata_plist.h"
#include "dds/ddsi/q_radmin.h" #include "dds/ddsi/q_radmin.h"
#include "dds/ddsi/ddsi_entity_index.h" #include "dds/ddsi/ddsi_entity_index.h"
@ -175,36 +176,22 @@ static void maybe_add_pp_as_meta_to_as_disc (struct ddsi_domaingv *gv, const str
} }
} }
static int write_mpayload (struct writer *wr, int alive, nn_parameterid_t keyparam, struct nn_xmsg *mpayload) void get_participant_builtin_topic_data (const struct participant *pp, ddsi_plist_t *dst, struct participant_builtin_topic_data_locators *locs)
{ {
struct thread_state1 * const ts1 = lookup_thread_state ();
struct ddsi_plist_sample plist_sample;
struct ddsi_serdata *serdata;
nn_xmsg_payload_to_plistsample (&plist_sample, keyparam, mpayload);
serdata = ddsi_serdata_from_sample (wr->e.gv->plist_topic, alive ? SDK_DATA : SDK_KEY, &plist_sample);
serdata->statusinfo = alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER;
serdata->timestamp = ddsrt_time_wallclock ();
return write_sample_nogc_notk (ts1, NULL, wr, serdata);
}
void get_participant_builtin_topic_data(const struct participant *pp, struct nn_xmsg *mpayload, bool be)
{
struct nn_locators_one def_uni_loc_one, def_multi_loc_one, meta_uni_loc_one, meta_multi_loc_one;
ddsi_plist_t ps;
size_t size; size_t size;
char node[64]; char node[64];
uint64_t qosdiff; uint64_t qosdiff;
ddsi_plist_init_empty (&ps); ddsi_plist_init_empty (dst);
ps.present |= PP_PARTICIPANT_GUID | PP_BUILTIN_ENDPOINT_SET | dst->present |= PP_PARTICIPANT_GUID | PP_BUILTIN_ENDPOINT_SET |
PP_PROTOCOL_VERSION | PP_VENDORID | PP_PARTICIPANT_LEASE_DURATION | PP_PROTOCOL_VERSION | PP_VENDORID | PP_PARTICIPANT_LEASE_DURATION |
PP_DOMAIN_ID; PP_DOMAIN_ID;
ps.participant_guid = pp->e.guid; dst->participant_guid = pp->e.guid;
ps.builtin_endpoint_set = pp->bes; dst->builtin_endpoint_set = pp->bes;
ps.protocol_version.major = RTPS_MAJOR; dst->protocol_version.major = RTPS_MAJOR;
ps.protocol_version.minor = RTPS_MINOR; dst->protocol_version.minor = RTPS_MINOR;
ps.vendorid = NN_VENDORID_ECLIPSE; dst->vendorid = NN_VENDORID_ECLIPSE;
ps.domain_id = pp->e.gv->config.extDomainId.value; dst->domain_id = pp->e.gv->config.extDomainId.value;
/* Be sure not to send a DOMAIN_TAG when it is the default (an empty) /* Be sure not to send a DOMAIN_TAG when it is the default (an empty)
string: it is an "incompatible-if-unrecognized" parameter, and so string: it is an "incompatible-if-unrecognized" parameter, and so
implementations that don't understand the parameter will refuse to implementations that don't understand the parameter will refuse to
@ -212,34 +199,34 @@ void get_participant_builtin_topic_data(const struct participant *pp, struct nn_
compatibility. */ compatibility. */
if (strcmp (pp->e.gv->config.domainTag, "") != 0) if (strcmp (pp->e.gv->config.domainTag, "") != 0)
{ {
ps.present |= PP_DOMAIN_TAG; dst->present |= PP_DOMAIN_TAG;
ps.aliased |= PP_DOMAIN_TAG; dst->aliased |= PP_DOMAIN_TAG;
ps.domain_tag = pp->e.gv->config.domainTag; dst->domain_tag = pp->e.gv->config.domainTag;
} }
ps.default_unicast_locators.n = 1; dst->default_unicast_locators.n = 1;
ps.default_unicast_locators.first = dst->default_unicast_locators.first =
ps.default_unicast_locators.last = &def_uni_loc_one; dst->default_unicast_locators.last = &locs->def_uni_loc_one;
ps.metatraffic_unicast_locators.n = 1; dst->metatraffic_unicast_locators.n = 1;
ps.metatraffic_unicast_locators.first = dst->metatraffic_unicast_locators.first =
ps.metatraffic_unicast_locators.last = &meta_uni_loc_one; dst->metatraffic_unicast_locators.last = &locs->meta_uni_loc_one;
def_uni_loc_one.next = NULL; locs->def_uni_loc_one.next = NULL;
meta_uni_loc_one.next = NULL; locs->meta_uni_loc_one.next = NULL;
if (pp->e.gv->config.many_sockets_mode == MSM_MANY_UNICAST) if (pp->e.gv->config.many_sockets_mode == MSM_MANY_UNICAST)
{ {
def_uni_loc_one.loc = pp->m_locator; locs->def_uni_loc_one.loc = pp->m_locator;
meta_uni_loc_one.loc = pp->m_locator; locs->meta_uni_loc_one.loc = pp->m_locator;
} }
else else
{ {
def_uni_loc_one.loc = pp->e.gv->loc_default_uc; locs->def_uni_loc_one.loc = pp->e.gv->loc_default_uc;
meta_uni_loc_one.loc = pp->e.gv->loc_meta_uc; locs->meta_uni_loc_one.loc = pp->e.gv->loc_meta_uc;
} }
if (pp->e.gv->config.publish_uc_locators) if (pp->e.gv->config.publish_uc_locators)
{ {
ps.present |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR; dst->present |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
ps.aliased |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR; dst->aliased |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
} }
if (pp->e.gv->config.allowMulticast) if (pp->e.gv->config.allowMulticast)
@ -260,51 +247,51 @@ void get_participant_builtin_topic_data(const struct participant *pp, struct nn_
#endif #endif
if (include) if (include)
{ {
ps.present |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR; dst->present |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR;
ps.aliased |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR; dst->aliased |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR;
ps.default_multicast_locators.n = 1; dst->default_multicast_locators.n = 1;
ps.default_multicast_locators.first = dst->default_multicast_locators.first =
ps.default_multicast_locators.last = &def_multi_loc_one; dst->default_multicast_locators.last = &locs->def_multi_loc_one;
ps.metatraffic_multicast_locators.n = 1; dst->metatraffic_multicast_locators.n = 1;
ps.metatraffic_multicast_locators.first = dst->metatraffic_multicast_locators.first =
ps.metatraffic_multicast_locators.last = &meta_multi_loc_one; dst->metatraffic_multicast_locators.last = &locs->meta_multi_loc_one;
def_multi_loc_one.next = NULL; locs->def_multi_loc_one.next = NULL;
def_multi_loc_one.loc = pp->e.gv->loc_default_mc; locs->def_multi_loc_one.loc = pp->e.gv->loc_default_mc;
meta_multi_loc_one.next = NULL; locs->meta_multi_loc_one.next = NULL;
meta_multi_loc_one.loc = pp->e.gv->loc_meta_mc; locs->meta_multi_loc_one.loc = pp->e.gv->loc_meta_mc;
} }
} }
ps.participant_lease_duration = pp->lease_duration; dst->participant_lease_duration = pp->lease_duration;
/* Add Adlink specific version information */ /* Add Adlink specific version information */
{ {
ps.present |= PP_ADLINK_PARTICIPANT_VERSION_INFO; dst->present |= PP_ADLINK_PARTICIPANT_VERSION_INFO;
memset (&ps.adlink_participant_version_info, 0, sizeof (ps.adlink_participant_version_info)); memset (&dst->adlink_participant_version_info, 0, sizeof (dst->adlink_participant_version_info));
ps.adlink_participant_version_info.version = 0; dst->adlink_participant_version_info.version = 0;
ps.adlink_participant_version_info.flags = dst->adlink_participant_version_info.flags =
NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG | NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG |
NN_ADLINK_FL_PTBES_FIXED_0 | NN_ADLINK_FL_PTBES_FIXED_0 |
NN_ADLINK_FL_SUPPORTS_STATUSINFOX; NN_ADLINK_FL_SUPPORTS_STATUSINFOX;
if (pp->e.gv->config.besmode == BESMODE_MINIMAL) if (pp->e.gv->config.besmode == BESMODE_MINIMAL)
ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_MINIMAL_BES_MODE; dst->adlink_participant_version_info.flags |= NN_ADLINK_FL_MINIMAL_BES_MODE;
ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock);
if (pp->is_ddsi2_pp) if (pp->is_ddsi2_pp)
ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_PARTICIPANT_IS_DDSI2; dst->adlink_participant_version_info.flags |= NN_ADLINK_FL_PARTICIPANT_IS_DDSI2;
ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock); ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock);
if (ddsrt_gethostname(node, sizeof(node)-1) < 0) if (ddsrt_gethostname(node, sizeof(node)-1) < 0)
(void) ddsrt_strlcpy (node, "unknown", sizeof (node)); (void) ddsrt_strlcpy (node, "unknown", sizeof (node));
size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */ size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */
ps.adlink_participant_version_info.internals = ddsrt_malloc(size); dst->adlink_participant_version_info.internals = ddsrt_malloc(size);
(void) snprintf(ps.adlink_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME); (void) snprintf(dst->adlink_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME);
ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.adlink_participant_version_info.internals); ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), dst->adlink_participant_version_info.internals);
} }
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
/* Add Security specific information. */ /* Add Security specific information. */
if (q_omg_get_participant_security_info(pp, &(ps.participant_security_info))) { if (q_omg_get_participant_security_info(pp, &(dst->participant_security_info))) {
ps.present |= PP_PARTICIPANT_SECURITY_INFO; dst->present |= PP_PARTICIPANT_SECURITY_INFO;
ps.aliased |= PP_PARTICIPANT_SECURITY_INFO; dst->aliased |= PP_PARTICIPANT_SECURITY_INFO;
} }
#endif #endif
@ -313,62 +300,28 @@ void get_participant_builtin_topic_data(const struct participant *pp, struct nn_
if (pp->e.gv->config.explicitly_publish_qos_set_to_default) if (pp->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK; qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
assert (ps.qos.present == 0); assert (dst->qos.present == 0);
ddsi_plist_addtomsg_bo (mpayload, &ps, ~(uint64_t)0, 0, be); ddsi_plist_mergein_missing (dst, pp->plist, 0, qosdiff);
ddsi_plist_addtomsg_bo (mpayload, pp->plist, 0, qosdiff, be);
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure(pp)) if (q_omg_participant_is_secure(pp))
ddsi_plist_addtomsg_bo (mpayload, pp->plist, PP_IDENTITY_TOKEN | PP_PERMISSIONS_TOKEN, 0, be); ddsi_plist_mergein_missing (dst, pp->plist, PP_IDENTITY_TOKEN | PP_PERMISSIONS_TOKEN, 0);
#endif #endif
nn_xmsg_addpar_sentinel_bo (mpayload, be); }
ddsi_plist_fini (&ps);
static int write_and_fini_plist (struct writer *wr, ddsi_plist_t *ps, bool alive)
{
struct ddsi_serdata *serdata = ddsi_serdata_from_sample (wr->topic, alive ? SDK_DATA : SDK_KEY, ps);
ddsi_plist_fini (ps);
serdata->statusinfo = alive ? 0 : (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER);
serdata->timestamp = ddsrt_time_wallclock ();
return write_sample_nogc_notk (lookup_thread_state (), NULL, wr, serdata);
} }
int spdp_write (struct participant *pp) int spdp_write (struct participant *pp)
{ {
struct nn_xmsg *mpayload;
struct writer *wr; struct writer *wr;
int ret;
if (pp->e.onlylocal) {
/* This topic is only locally available. */
return 0;
}
ETRACE (pp, "spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid));
if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL)
{
ETRACE (pp, "spdp_write("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid));
return 0;
}
/* First create a fake message for the payload: we can add plists to
xmsgs easily, but not to serdata. But it is rather easy to copy
the payload of an xmsg over to a serdata ... Expected size isn't
terribly important, the msg will grow as needed, address space is
essentially meaningless because we only use the message to
construct the payload. */
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, pp, 0, NN_XMSG_KIND_DATA);
get_participant_builtin_topic_data(pp, mpayload, false);
ret = write_mpayload (wr, 1, PID_PARTICIPANT_GUID, mpayload);
nn_xmsg_free (mpayload);
return ret;
}
#if 0
int spdp_write (struct participant *pp)
{
struct nn_xmsg *mpayload;
struct nn_locators_one def_uni_loc_one, def_multi_loc_one, meta_uni_loc_one, meta_multi_loc_one;
ddsi_plist_t ps; ddsi_plist_t ps;
struct writer *wr; struct participant_builtin_topic_data_locators locs;
size_t size;
char node[64];
uint64_t qosdiff;
int ret;
if (pp->e.onlylocal) { if (pp->e.onlylocal) {
/* This topic is only locally available. */ /* This topic is only locally available. */
@ -383,154 +336,14 @@ int spdp_write (struct participant *pp)
return 0; return 0;
} }
/* First create a fake message for the payload: we can add plists to get_participant_builtin_topic_data (pp, &ps, &locs);
xmsgs easily, but not to serdata. But it is rather easy to copy return write_and_fini_plist (wr, &ps, true);
the payload of an xmsg over to a serdata ... Expected size isn't
terribly important, the msg will grow as needed, address space is
essentially meaningless because we only use the message to
construct the payload. */
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, pp, 0, NN_XMSG_KIND_DATA);
ddsi_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID | PP_BUILTIN_ENDPOINT_SET |
PP_PROTOCOL_VERSION | PP_VENDORID | PP_PARTICIPANT_LEASE_DURATION |
PP_DOMAIN_ID;
ps.participant_guid = pp->e.guid;
ps.builtin_endpoint_set = pp->bes;
ps.protocol_version.major = RTPS_MAJOR;
ps.protocol_version.minor = RTPS_MINOR;
ps.vendorid = NN_VENDORID_ECLIPSE;
ps.domain_id = pp->e.gv->config.extDomainId.value;
/* Be sure not to send a DOMAIN_TAG when it is the default (an empty)
string: it is an "incompatible-if-unrecognized" parameter, and so
implementations that don't understand the parameter will refuse to
discover us, and so sending the default would break backwards
compatibility. */
if (strcmp (pp->e.gv->config.domainTag, "") != 0)
{
ps.present |= PP_DOMAIN_TAG;
ps.aliased |= PP_DOMAIN_TAG;
ps.domain_tag = pp->e.gv->config.domainTag;
} }
ps.default_unicast_locators.n = 1;
ps.default_unicast_locators.first =
ps.default_unicast_locators.last = &def_uni_loc_one;
ps.metatraffic_unicast_locators.n = 1;
ps.metatraffic_unicast_locators.first =
ps.metatraffic_unicast_locators.last = &meta_uni_loc_one;
def_uni_loc_one.next = NULL;
meta_uni_loc_one.next = NULL;
if (pp->e.gv->config.many_sockets_mode == MSM_MANY_UNICAST)
{
def_uni_loc_one.loc = pp->m_locator;
meta_uni_loc_one.loc = pp->m_locator;
}
else
{
def_uni_loc_one.loc = pp->e.gv->loc_default_uc;
meta_uni_loc_one.loc = pp->e.gv->loc_meta_uc;
}
if (pp->e.gv->config.publish_uc_locators)
{
ps.present |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
ps.aliased |= PP_DEFAULT_UNICAST_LOCATOR | PP_METATRAFFIC_UNICAST_LOCATOR;
}
if (pp->e.gv->config.allowMulticast)
{
int include = 0;
#ifdef DDSI_INCLUDE_SSM
/* Note that if the default multicast address is an SSM address,
we will simply advertise it. The recipients better understand
it means the writers will publish to address and the readers
favour SSM. */
if (ddsi_is_ssm_mcaddr (pp->e.gv, &pp->e.gv->loc_default_mc))
include = (pp->e.gv->config.allowMulticast & AMC_SSM) != 0;
else
include = (pp->e.gv->config.allowMulticast & AMC_ASM) != 0;
#else
if (pp->e.gv->config.allowMulticast & AMC_ASM)
include = 1;
#endif
if (include)
{
ps.present |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR;
ps.aliased |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR;
ps.default_multicast_locators.n = 1;
ps.default_multicast_locators.first =
ps.default_multicast_locators.last = &def_multi_loc_one;
ps.metatraffic_multicast_locators.n = 1;
ps.metatraffic_multicast_locators.first =
ps.metatraffic_multicast_locators.last = &meta_multi_loc_one;
def_multi_loc_one.next = NULL;
def_multi_loc_one.loc = pp->e.gv->loc_default_mc;
meta_multi_loc_one.next = NULL;
meta_multi_loc_one.loc = pp->e.gv->loc_meta_mc;
}
}
ps.participant_lease_duration = pp->lease_duration;
/* Add Adlink specific version information */
{
ps.present |= PP_ADLINK_PARTICIPANT_VERSION_INFO;
memset (&ps.adlink_participant_version_info, 0, sizeof (ps.adlink_participant_version_info));
ps.adlink_participant_version_info.version = 0;
ps.adlink_participant_version_info.flags =
NN_ADLINK_FL_DDSI2_PARTICIPANT_FLAG |
NN_ADLINK_FL_PTBES_FIXED_0 |
NN_ADLINK_FL_SUPPORTS_STATUSINFOX;
if (pp->e.gv->config.besmode == BESMODE_MINIMAL)
ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_MINIMAL_BES_MODE;
ddsrt_mutex_lock (&pp->e.gv->privileged_pp_lock);
if (pp->is_ddsi2_pp)
ps.adlink_participant_version_info.flags |= NN_ADLINK_FL_PARTICIPANT_IS_DDSI2;
ddsrt_mutex_unlock (&pp->e.gv->privileged_pp_lock);
if (ddsrt_gethostname(node, sizeof(node)-1) < 0)
(void) ddsrt_strlcpy (node, "unknown", sizeof (node));
size = strlen(node) + strlen(DDS_VERSION) + strlen(DDS_HOST_NAME) + strlen(DDS_TARGET_NAME) + 4; /* + ///'\0' */
ps.adlink_participant_version_info.internals = ddsrt_malloc(size);
(void) snprintf(ps.adlink_participant_version_info.internals, size, "%s/%s/%s/%s", node, DDS_VERSION, DDS_HOST_NAME, DDS_TARGET_NAME);
ETRACE (pp, "spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.adlink_participant_version_info.internals);
}
#ifdef DDSI_INCLUDE_SECURITY
/* Add Security specific information. */
if (q_omg_get_participant_security_info(pp, &(ps.participant_security_info))) {
ps.present |= PP_PARTICIPANT_SECURITY_INFO;
ps.aliased |= PP_PARTICIPANT_SECURITY_INFO;
}
#endif
/* Participant QoS's insofar as they are set, different from the default. Currently, that means just USER_DATA. */
qosdiff = ddsi_xqos_delta (&pp->plist->qos, &pp->e.gv->default_plist_pp.qos, QP_USER_DATA);
if (pp->e.gv->config.explicitly_publish_qos_set_to_default)
qosdiff |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
assert (ps.qos.present == 0);
ddsi_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, 0);
ddsi_plist_addtomsg (mpayload, pp->plist, 0, qosdiff);
#ifdef DDSI_INCLUDE_SECURITY
if (q_omg_participant_is_secure(pp))
ddsi_plist_addtomsg (mpayload, pp->plist, PP_IDENTITY_TOKEN | PP_PERMISSIONS_TOKEN, 0);
#endif
nn_xmsg_addpar_sentinel (mpayload);
ddsi_plist_fini (&ps);
ret = write_mpayload (wr, 1, PID_PARTICIPANT_GUID, mpayload);
nn_xmsg_free (mpayload);
return ret;
}
#endif
static int spdp_dispose_unregister_with_wr (struct participant *pp, unsigned entityid) static int spdp_dispose_unregister_with_wr (struct participant *pp, unsigned entityid)
{ {
struct nn_xmsg *mpayload;
ddsi_plist_t ps; ddsi_plist_t ps;
struct writer *wr; struct writer *wr;
int ret;
if ((wr = get_builtin_writer (pp, entityid)) == NULL) if ((wr = get_builtin_writer (pp, entityid)) == NULL)
{ {
@ -540,17 +353,10 @@ static int spdp_dispose_unregister_with_wr (struct participant *pp, unsigned ent
return 0; return 0;
} }
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, pp, 0, NN_XMSG_KIND_DATA);
ddsi_plist_init_empty (&ps); ddsi_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID; ps.present |= PP_PARTICIPANT_GUID;
ps.participant_guid = pp->e.guid; ps.participant_guid = pp->e.guid;
ddsi_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0); return write_and_fini_plist (wr, &ps, false);
nn_xmsg_addpar_sentinel (mpayload);
ddsi_plist_fini (&ps);
ret = write_mpayload (wr, 0, PID_PARTICIPANT_GUID, mpayload);
nn_xmsg_free (mpayload);
return ret;
} }
int spdp_dispose_unregister (struct participant *pp) int spdp_dispose_unregister (struct participant *pp)
@ -1016,46 +822,23 @@ static int handle_SPDP_alive (const struct receiver_state *rst, seqno_t seq, dds
return 1; return 1;
} }
static void handle_SPDP (const struct receiver_state *rst, ddsi_entityid_t pwr_entityid, seqno_t seq, ddsrt_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, const struct ddsi_serdata *serdata)
{ {
struct ddsi_domaingv * const gv = rst->gv; struct ddsi_domaingv * const gv = rst->gv;
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
if (data == NULL)
{
RSTTRACE ("SPDP ST%x no payload?\n", statusinfo);
return;
}
else
{
ddsi_plist_t decoded_data; ddsi_plist_t decoded_data;
ddsi_plist_src_t src; if (ddsi_serdata_to_sample (serdata, &decoded_data, NULL, NULL))
int interesting = 0;
dds_return_t plist_ret;
src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor;
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
src.strict = NN_STRICT_P (gv->config);
src.factory = gv->m_factory;
src.logconfig = &gv->logconfig;
if ((plist_ret = ddsi_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
if (plist_ret != DDS_RETCODE_UNSUPPORTED) int interesting = 0;
GVWARNING ("SPDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]); switch (serdata->statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
return;
}
switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
{ {
case 0: case 0:
interesting = handle_SPDP_alive (rst, seq, timestamp, &decoded_data); interesting = handle_SPDP_alive (rst, seq, serdata->timestamp, &decoded_data);
break; break;
case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER: case NN_STATUSINFO_UNREGISTER:
case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER): case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER):
interesting = handle_SPDP_dead (rst, pwr_entityid, timestamp, &decoded_data, statusinfo); interesting = handle_SPDP_dead (rst, pwr_entityid, serdata->timestamp, &decoded_data, serdata->statusinfo);
break; break;
} }
@ -1115,10 +898,8 @@ static int sedp_write_endpoint
{ {
struct ddsi_domaingv * const gv = wr->e.gv; struct ddsi_domaingv * const gv = wr->e.gv;
const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv->default_xqos_wr : &gv->default_xqos_rd; const dds_qos_t *defqos = is_writer_entityid (epguid->entityid) ? &gv->default_xqos_wr : &gv->default_xqos_rd;
struct nn_xmsg *mpayload;
uint64_t qosdiff; uint64_t qosdiff;
ddsi_plist_t ps; ddsi_plist_t ps;
int ret;
ddsi_plist_init_empty (&ps); ddsi_plist_init_empty (&ps);
ps.present |= PP_ENDPOINT_GUID; ps.present |= PP_ENDPOINT_GUID;
@ -1193,20 +974,9 @@ static int sedp_write_endpoint
} }
} }
/* The message is only a temporary thing, used only for encoding if (xqos)
the QoS and other settings. So the header fields aren't really ddsi_xqos_mergein_missing (&ps.qos, xqos, qosdiff);
important, except that they need to be set to reasonable things return write_and_fini_plist (wr, &ps, alive);
or it'll crash */
mpayload = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, 0, NN_XMSG_KIND_DATA);
ddsi_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
if (xqos) ddsi_xqos_addtomsg (mpayload, xqos, qosdiff);
nn_xmsg_addpar_sentinel (mpayload);
ddsi_plist_fini (&ps);
GVLOGDISC ("sedp: write for "PGUIDFMT" via "PGUIDFMT"\n", PGUID (*epguid), PGUID (wr->e.guid));
ret = write_mpayload (wr, alive, PID_ENDPOINT_GUID, mpayload);
nn_xmsg_free (mpayload);
return ret;
} }
static struct writer *get_sedp_writer (const struct participant *pp, unsigned entityid) static struct writer *get_sedp_writer (const struct participant *pp, unsigned entityid)
@ -1597,145 +1367,39 @@ static void handle_SEDP_dead (const struct receiver_state *rst, ddsi_plist_t *da
GVLOGDISC (" %s\n", (res < 0) ? " unknown" : " delete"); GVLOGDISC (" %s\n", (res < 0) ? " unknown" : " delete");
} }
static void handle_SEDP (const struct receiver_state *rst, seqno_t seq, ddsrt_wctime_t timestamp, unsigned statusinfo, const void *vdata, uint32_t len) static void handle_SEDP (const struct receiver_state *rst, seqno_t seq, struct ddsi_serdata *serdata)
{
struct ddsi_domaingv * const gv = rst->gv;
const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */
GVLOGDISC ("SEDP ST%x", statusinfo);
if (data == NULL)
{
GVLOGDISC (" no payload?\n");
return;
}
else
{ {
ddsi_plist_t decoded_data; ddsi_plist_t decoded_data;
ddsi_plist_src_t src; if (ddsi_serdata_to_sample (serdata, &decoded_data, NULL, NULL))
dds_return_t plist_ret;
src.protocol_version = rst->protocol_version;
src.vendorid = rst->vendor;
src.encoding = data->identifier;
src.buf = (unsigned char *) data + 4;
src.bufsz = len - 4;
src.strict = NN_STRICT_P (gv->config);
src.factory = gv->m_factory;
src.logconfig = &gv->logconfig;
if ((plist_ret = ddsi_plist_init_frommsg (&decoded_data, NULL, ~(uint64_t)0, ~(uint64_t)0, &src)) < 0)
{ {
if (plist_ret != DDS_RETCODE_UNSUPPORTED) switch (serdata->statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
GVWARNING ("SEDP (vendor %u.%u): invalid qos/parameters\n", src.vendorid.id[0], src.vendorid.id[1]);
return;
}
switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
{ {
case 0: case 0:
handle_SEDP_alive (rst, seq, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp); handle_SEDP_alive (rst, seq, &decoded_data, &rst->src_guid_prefix, rst->vendor, serdata->timestamp);
break; break;
case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_DISPOSE:
case NN_STATUSINFO_UNREGISTER: case NN_STATUSINFO_UNREGISTER:
case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER): case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER):
handle_SEDP_dead (rst, &decoded_data, timestamp); handle_SEDP_dead (rst, &decoded_data, serdata->timestamp);
break; break;
} }
ddsi_plist_fini (&decoded_data); ddsi_plist_fini (&decoded_data);
} }
} }
/****************************************************************************** /******************************************************************************
***
*** Topics
***
*****************************************************************************/ *****************************************************************************/
int sedp_write_topic (struct participant *pp, const struct ddsi_plist *datap)
{
struct writer *sedp_wr;
struct nn_xmsg *mpayload;
uint64_t delta;
int ret;
assert (datap->qos.present & QP_TOPIC_NAME);
if (pp->e.onlylocal) {
/* This topic is only locally available. */
return 0;
}
sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid, pp, 0, NN_XMSG_KIND_DATA);
delta = ddsi_xqos_delta (&datap->qos, &sedp_wr->e.gv->default_xqos_tp, ~(uint64_t)0);
if (sedp_wr->e.gv->config.explicitly_publish_qos_set_to_default)
delta |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
ddsi_plist_addtomsg (mpayload, datap, ~(uint64_t)0, delta);
nn_xmsg_addpar_sentinel (mpayload);
ETRACE (pp, "sedp: write topic %s via "PGUIDFMT"\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid));
ret = write_mpayload (sedp_wr, 1, PID_TOPIC_NAME, mpayload);
nn_xmsg_free (mpayload);
return ret;
}
/******************************************************************************
*****************************************************************************/
/* FIXME: defragment is a copy of the one in q_receive.c, but the deserialised should be enhanced to handle fragmented data (and arguably the processing here should be built on proper data readers) */
static int defragment (unsigned char **datap, const struct nn_rdata *fragchain, uint32_t sz)
{
if (fragchain->nextfrag == NULL)
{
*datap = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain));
return 0;
}
else
{
unsigned char *buf;
uint32_t off = 0;
buf = ddsrt_malloc (sz);
while (fragchain)
{
assert (fragchain->min <= off);
assert (fragchain->maxp1 <= sz);
if (fragchain->maxp1 > off)
{
/* only copy if this fragment adds data */
const unsigned char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain));
memcpy (buf + off, payload + off - fragchain->min, fragchain->maxp1 - off);
off = fragchain->maxp1;
}
fragchain = fragchain->nextfrag;
}
*datap = buf;
return 1;
}
}
int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, UNUSED_ARG (const ddsi_guid_t *rdguid), UNUSED_ARG (void *qarg)) int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, UNUSED_ARG (const ddsi_guid_t *rdguid), UNUSED_ARG (void *qarg))
{ {
struct ddsi_domaingv * const gv = sampleinfo->rst->gv; struct ddsi_domaingv * const gv = sampleinfo->rst->gv;
struct proxy_writer *pwr; struct proxy_writer *pwr;
struct {
struct CDRHeader cdr;
nn_parameter_t p_endpoint_guid;
char kh[16];
nn_parameter_t p_sentinel;
} keyhash_payload;
unsigned statusinfo; unsigned statusinfo;
int need_keyhash; int need_keyhash;
ddsi_guid_t srcguid; ddsi_guid_t srcguid;
Data_DataFrag_common_t *msg; Data_DataFrag_common_t *msg;
unsigned char data_smhdr_flags; unsigned char data_smhdr_flags;
ddsi_plist_t qos; ddsi_plist_t qos;
unsigned char *datap;
int needs_free;
uint32_t datasz = sampleinfo->size;
ddsrt_wctime_t timestamp;
needs_free = defragment (&datap, fragchain, sampleinfo->size);
/* Luckily, most of the Data and DataFrag headers are the same - and /* Luckily, most of the Data and DataFrag headers are the same - and
in particular, all that we care about here is the same. The in particular, all that we care about here is the same. The
@ -1770,7 +1434,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
consequently expect to need the keyhash. Then, if sampleinfo consequently expect to need the keyhash. Then, if sampleinfo
says it is a complex qos, or the keyhash is required, extract all says it is a complex qos, or the keyhash is required, extract all
we need from the inline qos. */ we need from the inline qos. */
need_keyhash = (datasz == 0 || (data_smhdr_flags & (DATA_FLAG_KEYFLAG | DATA_FLAG_DATAFLAG)) == 0); need_keyhash = (sampleinfo->size == 0 || (data_smhdr_flags & (DATA_FLAG_KEYFLAG | DATA_FLAG_DATAFLAG)) == 0);
if (!(sampleinfo->complex_qos || need_keyhash)) if (!(sampleinfo->complex_qos || need_keyhash))
{ {
ddsi_plist_init_empty (&qos); ddsi_plist_init_empty (&qos);
@ -1809,113 +1473,117 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
goto done_upd_deliv; goto done_upd_deliv;
} }
/* Built-ins still do their own deserialization (SPDP <=> pwr == /* proxy writers don't reference a topic object, SPDP doesn't have matched readers
NULL)). */ but all the GUIDs are known, so be practical and map that */
if (statusinfo == 0) const struct ddsi_sertopic *topic;
{
if (datasz == 0 || !(data_smhdr_flags & DATA_FLAG_DATAFLAG))
{
GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": built-in data but no payload\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (srcguid), sampleinfo->seq);
goto done_upd_deliv;
}
}
else if (datasz)
{
/* Raw data must be full payload for write, just keys for
dispose and unregister. First has been checked; the second
hasn't been checked fully yet. */
if (!(data_smhdr_flags & DATA_FLAG_KEYFLAG))
{
GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": dispose/unregister of built-in data but payload not just key\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (srcguid), sampleinfo->seq);
goto done_upd_deliv;
}
}
else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P(gv->config))
{
/* For SPDP/SEDP, fake a parameter list with just a keyhash. For
PMD, just use the keyhash directly. Too hard to fix everything
at the same time ... */
if (srcguid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)
{
datap = qos.keyhash.value;
datasz = sizeof (qos.keyhash);
}
else
{
nn_parameterid_t pid;
keyhash_payload.cdr.identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE);
keyhash_payload.cdr.options = 0;
switch (srcguid.entityid.u) switch (srcguid.entityid.u)
{ {
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER: case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER: topic = gv->spdp_topic;
pid = PID_PARTICIPANT_GUID;
break; break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER: case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
topic = gv->sedp_writer_topic;
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER: case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER: topic = gv->sedp_reader_topic;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
pid = PID_ENDPOINT_GUID;
break; break;
case NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER:
/* placeholders */ topic = gv->pmd_topic;
pid = PID_ENDPOINT_GUID;
break; break;
#ifdef DDSI_INCLUDE_SECURITY
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
topic = gv->spdp_secure_topic;
break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
topic = gv->sedp_writer_secure_topic;
break;
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
topic = gv->sedp_reader_secure_topic;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER:
topic = gv->pmd_secure_topic;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
topic = gv->pgm_stateless_topic;
break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER:
topic = gv->pgm_volatile_topic;
break;
#endif
default: default:
GVLOGDISC ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": mapping keyhash to ENDPOINT_GUID", topic = NULL;
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (srcguid), sampleinfo->seq);
pid = PID_ENDPOINT_GUID;
break; break;
} }
keyhash_payload.p_endpoint_guid.parameterid = pid; if (topic == NULL)
keyhash_payload.p_endpoint_guid.length = sizeof (ddsi_keyhash_t); {
memcpy (keyhash_payload.kh, &qos.keyhash, sizeof (qos.keyhash)); /* unrecognized source entity id => ignore */
keyhash_payload.p_sentinel.parameterid = PID_SENTINEL; goto done_upd_deliv;
keyhash_payload.p_sentinel.length = 0;
datap = (unsigned char *) &keyhash_payload;
datasz = sizeof (keyhash_payload);
}
} }
struct ddsi_serdata *d;
if (data_smhdr_flags & DATA_FLAG_DATAFLAG)
d = ddsi_serdata_from_ser (topic, SDK_DATA, fragchain, sampleinfo->size);
else if (data_smhdr_flags & DATA_FLAG_KEYFLAG)
d = ddsi_serdata_from_ser (topic, SDK_KEY, fragchain, sampleinfo->size);
else if ((qos.present & PP_KEYHASH) && !NN_STRICT_P(gv->config))
d = ddsi_serdata_from_keyhash (topic, &qos.keyhash);
else else
{ {
GVWARNING ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": dispose/unregister with no content\n", GVLOGDISC ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": missing payload\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (srcguid), sampleinfo->seq); PGUID (srcguid), sampleinfo->seq);
goto done_upd_deliv; goto done_upd_deliv;
} }
if (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v) d->timestamp = (sampleinfo->timestamp.v != DDSRT_WCTIME_INVALID.v) ? sampleinfo->timestamp : ddsrt_time_wallclock ();
timestamp = sampleinfo->timestamp; d->statusinfo = statusinfo;
else // set protocol version & vendor id for plist types
timestamp = ddsrt_time_wallclock (); // FIXME: find a better way then fixing these up afterward
if (d->ops == &ddsi_serdata_ops_plist)
{
struct ddsi_serdata_plist *d_plist = (struct ddsi_serdata_plist *) d;
d_plist->protoversion = sampleinfo->rst->protocol_version;
d_plist->vendorid = sampleinfo->rst->vendor;
}
if (gv->logconfig.c.mask & DDS_LC_TRACE)
{
ddsi_guid_t guid;
char tmp[2048];
size_t res = 0;
tmp[0] = 0;
if (gv->logconfig.c.mask & DDS_LC_CONTENT)
res = ddsi_serdata_print (d, tmp, sizeof (tmp));
if (pwr) guid = pwr->e.guid; else memset (&guid, 0, sizeof (guid));
GVTRACE ("data(builtin, vendor %u.%u): "PGUIDFMT" #%"PRId64": ST%x %s/%s:%s%s\n",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (guid), sampleinfo->seq, statusinfo, d->topic->name, d->topic->type_name,
tmp, res < sizeof (tmp) - 1 ? "" : "(trunc)");
}
switch (srcguid.entityid.u) switch (srcguid.entityid.u)
{ {
case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER: case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER:
case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER: case NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER:
handle_SPDP (sampleinfo->rst, srcguid.entityid, sampleinfo->seq, timestamp, statusinfo, datap, datasz); handle_SPDP (sampleinfo->rst, srcguid.entityid, sampleinfo->seq, d);
break; break;
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER: case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER: case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER: case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER:
case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER: case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER:
handle_SEDP (sampleinfo->rst, sampleinfo->seq, timestamp, statusinfo, datap, datasz); handle_SEDP (sampleinfo->rst, sampleinfo->seq, d);
break; break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER:
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER: case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER: {
handle_pmd_message (sampleinfo->rst, timestamp, statusinfo, datap, datasz); handle_pmd_message (sampleinfo->rst, d);
break; break;
}
#ifdef DDSI_INCLUDE_SECURITY #ifdef DDSI_INCLUDE_SECURITY
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER: case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER:
handle_auth_handshake_message(sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz); handle_auth_handshake_message(sampleinfo->rst, srcguid.entityid, d);
break; break;
case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER: case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER:
handle_crypto_exchange_message(sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz); handle_crypto_exchange_message(sampleinfo->rst, d);
break; break;
#endif #endif
default: default:
@ -1925,9 +1593,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
break; break;
} }
ddsi_serdata_unref (d);
done_upd_deliv: done_upd_deliv:
if (needs_free)
ddsrt_free (datap);
if (pwr) if (pwr)
{ {
/* No proxy writer for SPDP */ /* No proxy writer for SPDP */

View file

@ -563,7 +563,7 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER);
wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr); wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->spdp_secure_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
/* But we need the as_disc address set for SPDP, because we need to /* But we need the as_disc address set for SPDP, because we need to
send it to everyone regardless of the existence of readers. */ send it to everyone regardless of the existence of readers. */
@ -572,28 +572,28 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER);
wrinfo = whc_make_wrinfo (NULL, &gv->builtin_stateless_xqos_wr); wrinfo = whc_make_wrinfo (NULL, &gv->builtin_stateless_xqos_wr);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_stateless_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->pgm_stateless_topic, &gv->builtin_stateless_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER);
wrinfo = whc_make_wrinfo (NULL, &gv->builtin_volatile_xqos_wr); wrinfo = whc_make_wrinfo (NULL, &gv->builtin_volatile_xqos_wr);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_volatile_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->pgm_volatile_topic, &gv->builtin_volatile_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_ANNOUNCER; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_ANNOUNCER;
wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr); wrinfo = whc_make_wrinfo (NULL, &gv->builtin_endpoint_xqos_wr);
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER); 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, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->pmd_secure_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER); 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, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->sedp_writer_secure_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER; pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER); 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, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->sedp_reader_secure_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER; pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER;
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
@ -602,11 +602,11 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
if (add_readers) if (add_readers)
{ {
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER); 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); new_reader_guid (NULL, subguid, group_guid, pp, gv->sedp_reader_secure_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR; pp->bes |= NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER); 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); new_reader_guid (NULL, subguid, group_guid, pp, gv->sedp_writer_secure_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR; pp->bes |= NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR;
} }
@ -615,19 +615,19 @@ static void add_security_builtin_endpoints(struct participant *pp, ddsi_guid_t *
* besmode flag setting, because all participant do require authentication. * besmode flag setting, because all participant do require authentication.
*/ */
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER); 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); new_reader_guid (NULL, subguid, group_guid, pp, gv->spdp_secure_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER); subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL); new_reader_guid (NULL, subguid, group_guid, pp, gv->pgm_volatile_topic, &gv->builtin_volatile_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_DETECTOR; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER); 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); new_reader_guid (NULL, subguid, group_guid, pp, gv->pgm_stateless_topic, &gv->builtin_stateless_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER); 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); new_reader_guid (NULL, subguid, group_guid, pp, gv->pmd_secure_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR;
} }
#endif #endif
@ -640,25 +640,18 @@ static void add_builtin_endpoints(struct participant *pp, ddsi_guid_t *subguid,
/* SEDP writers: */ /* SEDP writers: */
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->sedp_reader_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->sedp_writer_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
/* PMD writer: */ /* PMD writer: */
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER); subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, subguid, group_guid, pp, gv->pmd_topic, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
if (gv->config.do_topic_discovery)
{
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
new_writer_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_wr, whc_new(gv, wrinfo), NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER;
}
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
} }
@ -666,19 +659,19 @@ static void add_builtin_endpoints(struct participant *pp, ddsi_guid_t *subguid,
if (add_readers) if (add_readers)
{ {
subguid->entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER); subguid->entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->spdp_endpoint_xqos, NULL, NULL, NULL); new_reader_guid (NULL, subguid, group_guid, pp, gv->spdp_topic, &gv->spdp_endpoint_xqos, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER); subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL); new_reader_guid (NULL, subguid, group_guid, pp, gv->sedp_reader_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER); subguid->entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL); new_reader_guid (NULL, subguid, group_guid, pp, gv->sedp_writer_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR; pp->bes |= NN_DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR;
subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER); subguid->entityid = to_entityid (NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER);
new_reader_guid (NULL, subguid, group_guid, pp, NULL, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL); new_reader_guid (NULL, subguid, group_guid, pp, gv->pmd_topic, &gv->builtin_endpoint_xqos_rd, NULL, NULL, NULL);
pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER; pp->bes |= NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER;
} }
@ -1001,7 +994,7 @@ dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv
{ {
subguid.entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER); subguid.entityid = to_entityid (NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER);
wrinfo = whc_make_wrinfo (NULL, &gv->spdp_endpoint_xqos); wrinfo = whc_make_wrinfo (NULL, &gv->spdp_endpoint_xqos);
new_writer_guid (NULL, &subguid, &group_guid, pp, NULL, &gv->spdp_endpoint_xqos, whc_new(gv, wrinfo), NULL, NULL); new_writer_guid (NULL, &subguid, &group_guid, pp, gv->spdp_topic, &gv->spdp_endpoint_xqos, whc_new(gv, wrinfo), NULL, NULL);
whc_free_wrinfo (wrinfo); whc_free_wrinfo (wrinfo);
/* But we need the as_disc address set for SPDP, because we need to /* But we need the as_disc address set for SPDP, because we need to
send it to everyone regardless of the existence of readers. */ send it to everyone regardless of the existence of readers. */
@ -2590,9 +2583,6 @@ already_matched:
return; return;
} }
static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer *wr, int64_t crypto_handle) static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer *wr, int64_t crypto_handle)
{ {
struct prd_wr_match *m = ddsrt_malloc (sizeof (*m)); struct prd_wr_match *m = ddsrt_malloc (sizeof (*m));
@ -2615,7 +2605,6 @@ static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer
} }
else else
{ {
assert (wr->topic || is_builtin_endpoint (wr->e.guid.entityid, NN_VENDORID_ECLIPSE));
ELOGDISC (prd, " proxy_reader_add_connection(wr "PGUIDFMT" prd "PGUIDFMT")\n", ELOGDISC (prd, " proxy_reader_add_connection(wr "PGUIDFMT" prd "PGUIDFMT")\n",
PGUID (wr->e.guid), PGUID (prd->e.guid)); PGUID (wr->e.guid), PGUID (prd->e.guid));
ddsrt_avl_insert_ipath (&prd_writers_treedef, &prd->writers, m, &path); ddsrt_avl_insert_ipath (&prd_writers_treedef, &prd->writers, m, &path);
@ -2920,7 +2909,6 @@ static void connect_writer_with_proxy_reader_wrapper (struct entity_common *vwr,
struct proxy_reader *prd = (struct proxy_reader *) vprd; struct proxy_reader *prd = (struct proxy_reader *) vprd;
assert (wr->e.kind == EK_WRITER); assert (wr->e.kind == EK_WRITER);
assert (prd->e.kind == EK_PROXY_READER); assert (prd->e.kind == EK_PROXY_READER);
assert (is_builtin_endpoint (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) == is_builtin_endpoint (prd->e.guid.entityid, prd->c.vendor));
connect_writer_with_proxy_reader (wr, prd, tnow); connect_writer_with_proxy_reader (wr, prd, tnow);
} }
@ -2930,7 +2918,6 @@ static void connect_proxy_writer_with_reader_wrapper (struct entity_common *vpwr
struct reader *rd = (struct reader *) vrd; struct reader *rd = (struct reader *) vrd;
assert (pwr->e.kind == EK_PROXY_WRITER); assert (pwr->e.kind == EK_PROXY_WRITER);
assert (rd->e.kind == EK_READER); assert (rd->e.kind == EK_READER);
assert (is_builtin_endpoint (rd->e.guid.entityid, NN_VENDORID_ECLIPSE) == is_builtin_endpoint (pwr->e.guid.entityid, pwr->c.vendor));
connect_proxy_writer_with_reader (pwr, rd, tnow); connect_proxy_writer_with_reader (pwr, rd, tnow);
} }
@ -2940,8 +2927,6 @@ static void connect_writer_with_reader_wrapper (struct entity_common *vwr, struc
struct reader *rd = (struct reader *) vrd; struct reader *rd = (struct reader *) vrd;
assert (wr->e.kind == EK_WRITER); assert (wr->e.kind == EK_WRITER);
assert (rd->e.kind == EK_READER); assert (rd->e.kind == EK_READER);
assert (!is_builtin_endpoint (wr->e.guid.entityid, NN_VENDORID_ECLIPSE) || is_local_orphan_endpoint (&wr->e));
assert (!is_builtin_endpoint (rd->e.guid.entityid, NN_VENDORID_ECLIPSE));
connect_writer_with_reader (wr, rd, tnow); connect_writer_with_reader (wr, rd, tnow);
} }
@ -3234,7 +3219,7 @@ static void new_reader_writer_common (const struct ddsrt_log_cfg *logcfg, const
{ {
const char *partition = "(default)"; const char *partition = "(default)";
const char *partition_suffix = ""; const char *partition_suffix = "";
assert (is_builtin_entityid (guid->entityid, NN_VENDORID_ECLIPSE) ? (topic == NULL) : (topic != NULL)); assert (topic != NULL);
if (is_builtin_entityid (guid->entityid, NN_VENDORID_ECLIPSE)) if (is_builtin_entityid (guid->entityid, NN_VENDORID_ECLIPSE))
{ {
/* continue printing it as not being in a partition, the actual /* continue printing it as not being in a partition, the actual
@ -3252,8 +3237,8 @@ static void new_reader_writer_common (const struct ddsrt_log_cfg *logcfg, const
is_writer_entityid (guid->entityid) ? "writer" : "reader", is_writer_entityid (guid->entityid) ? "writer" : "reader",
PGUID (*guid), PGUID (*guid),
partition, partition_suffix, partition, partition_suffix,
topic ? topic->name : "(null)", topic->name,
topic ? topic->type_name : "(null)"); topic->type_name);
} }
static void endpoint_common_init (struct entity_common *e, struct endpoint_common *c, struct ddsi_domaingv *gv, enum entity_kind kind, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, bool onlylocal) static void endpoint_common_init (struct entity_common *e, struct endpoint_common *c, struct ddsi_domaingv *gv, enum entity_kind kind, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct participant *pp, bool onlylocal)
@ -3282,12 +3267,12 @@ static void endpoint_common_fini (struct entity_common *e, struct endpoint_commo
static int set_topic_type_name (dds_qos_t *xqos, const struct ddsi_sertopic * topic) static int set_topic_type_name (dds_qos_t *xqos, const struct ddsi_sertopic * topic)
{ {
if (!(xqos->present & QP_TYPE_NAME) && topic) if (!(xqos->present & QP_TYPE_NAME))
{ {
xqos->present |= QP_TYPE_NAME; xqos->present |= QP_TYPE_NAME;
xqos->type_name = ddsrt_strdup (topic->type_name); xqos->type_name = ddsrt_strdup (topic->type_name);
} }
if (!(xqos->present & QP_TOPIC_NAME) && topic) if (!(xqos->present & QP_TOPIC_NAME))
{ {
xqos->present |= QP_TOPIC_NAME; xqos->present |= QP_TOPIC_NAME;
xqos->topic_name = ddsrt_strdup (topic->name); xqos->topic_name = ddsrt_strdup (topic->name);
@ -3754,7 +3739,7 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g
delete_participant won't interfere with our ability to address delete_participant won't interfere with our ability to address
the participant */ the participant */
const bool onlylocal = topic && builtintopic_is_builtintopic (pp->e.gv->builtin_topic_interface, topic); const bool onlylocal = builtintopic_is_builtintopic (pp->e.gv->builtin_topic_interface, topic);
endpoint_common_init (&wr->e, &wr->c, pp->e.gv, EK_WRITER, guid, group_guid, pp, onlylocal); endpoint_common_init (&wr->e, &wr->c, pp->e.gv, EK_WRITER, guid, group_guid, pp, onlylocal);
new_writer_guid_common_init(wr, topic, xqos, whc, status_cb, status_entity); new_writer_guid_common_init(wr, topic, xqos, whc, status_cb, status_entity);
@ -4241,7 +4226,7 @@ static dds_return_t new_reader_guid
if (rd_out) if (rd_out)
*rd_out = rd; *rd_out = rd;
const bool onlylocal = topic && builtintopic_is_builtintopic (pp->e.gv->builtin_topic_interface, topic); const bool onlylocal = builtintopic_is_builtintopic (pp->e.gv->builtin_topic_interface, topic);
endpoint_common_init (&rd->e, &rd->c, pp->e.gv, EK_READER, guid, group_guid, pp, onlylocal); endpoint_common_init (&rd->e, &rd->c, pp->e.gv, EK_READER, guid, group_guid, pp, onlylocal);
/* Copy QoS, merging in defaults */ /* Copy QoS, merging in defaults */

View file

@ -50,6 +50,7 @@
#include "dds/ddsi/q_debmon.h" #include "dds/ddsi/q_debmon.h"
#include "dds/ddsi/q_init.h" #include "dds/ddsi/q_init.h"
#include "dds/ddsi/ddsi_threadmon.h" #include "dds/ddsi/ddsi_threadmon.h"
#include "dds/ddsi/ddsi_pmd.h"
#include "dds/ddsi/ddsi_tran.h" #include "dds/ddsi/ddsi_tran.h"
#include "dds/ddsi/ddsi_udp.h" #include "dds/ddsi/ddsi_udp.h"
@ -57,6 +58,8 @@
#include "dds/ddsi/ddsi_raweth.h" #include "dds/ddsi/ddsi_raweth.h"
#include "dds/ddsi/ddsi_mcgroup.h" #include "dds/ddsi/ddsi_mcgroup.h"
#include "dds/ddsi/ddsi_serdata_default.h" #include "dds/ddsi/ddsi_serdata_default.h"
#include "dds/ddsi/ddsi_serdata_pserop.h"
#include "dds/ddsi/ddsi_serdata_plist.h"
#include "dds/ddsi/ddsi_security_omg.h" #include "dds/ddsi/ddsi_security_omg.h"
#include "dds/ddsi/ddsi_tkmap.h" #include "dds/ddsi/ddsi_tkmap.h"
@ -788,38 +791,75 @@ static void wait_for_receive_threads (struct ddsi_domaingv *gv)
} }
} }
static struct ddsi_sertopic *make_special_topic (const char *name, struct serdatapool *serpool, uint16_t enc_id, const struct ddsi_serdata_ops *ops) static struct ddsi_sertopic *make_special_topic_pserop (const char *name, const char *typename, size_t memsize, size_t nops, const enum pserop *ops, size_t nops_key, const enum pserop *ops_key)
{ {
/* FIXME: two things (at least) struct ddsi_sertopic_pserop *st = ddsrt_malloc (sizeof (*st));
- it claims there is a key, but the underlying type description is missing
that only works as long as it ends up comparing the keyhash field ...
the keyhash field should be eliminated; but this can simply be moved over to an alternate
topic class, it need not use the "default" one, that's mere expediency
- initialising/freeing them here, in this manner, is not very clean
it should be moved to somewhere in the topic implementation
(kinda natural if they stop being "default" ones) */
struct ddsi_sertopic_default *st = ddsrt_malloc (sizeof (*st));
memset (st, 0, sizeof (*st)); memset (st, 0, sizeof (*st));
ddsi_sertopic_init (&st->c, name, name, &ddsi_sertopic_ops_default, ops, false); ddsi_sertopic_init (&st->c, name, typename, &ddsi_sertopic_ops_pserop, &ddsi_serdata_ops_pserop, nops_key == 0);
st->native_encoding_identifier = enc_id; st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) ? CDR_LE : CDR_BE;
st->serpool = serpool; st->memsize = memsize;
st->nops = nops;
st->ops = ops;
st->nops_key = nops_key;
st->ops_key = ops_key;
return (struct ddsi_sertopic *) st;
}
static struct ddsi_sertopic *make_special_topic_plist (const char *name, const char *typename, nn_parameterid_t keyparam)
{
struct ddsi_sertopic_plist *st = ddsrt_malloc (sizeof (*st));
memset (st, 0, sizeof (*st));
ddsi_sertopic_init (&st->c, name, typename, &ddsi_sertopic_ops_plist, &ddsi_serdata_ops_plist, false);
st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) ? PL_CDR_LE : PL_CDR_BE;
st->keyparam = keyparam;
return (struct ddsi_sertopic *) st; return (struct ddsi_sertopic *) st;
} }
static void free_special_topics (struct ddsi_domaingv *gv) static void free_special_topics (struct ddsi_domaingv *gv)
{ {
ddsi_sertopic_unref (gv->plist_topic); #ifdef DDSI_INCLUDE_SECURITY
ddsi_sertopic_unref (gv->rawcdr_topic); ddsi_sertopic_unref (gv->pgm_volatile_topic);
ddsi_sertopic_unref (gv->pgm_stateless_topic);
ddsi_sertopic_unref (gv->pmd_secure_topic);
ddsi_sertopic_unref (gv->spdp_secure_topic);
ddsi_sertopic_unref (gv->sedp_reader_secure_topic);
ddsi_sertopic_unref (gv->sedp_writer_secure_topic);
#endif
ddsi_sertopic_unref (gv->pmd_topic);
ddsi_sertopic_unref (gv->spdp_topic);
ddsi_sertopic_unref (gv->sedp_reader_topic);
ddsi_sertopic_unref (gv->sedp_writer_topic);
} }
static void make_special_topics (struct ddsi_domaingv *gv) static void make_special_topics (struct ddsi_domaingv *gv)
{ {
gv->plist_topic = make_special_topic ("plist", gv->serpool, DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? PL_CDR_LE : PL_CDR_BE, &ddsi_serdata_ops_plist); gv->spdp_topic = make_special_topic_plist ("DCPSParticipant", "ParticipantBuiltinTopicData", PID_PARTICIPANT_GUID);
gv->rawcdr_topic = make_special_topic ("rawcdr", gv->serpool, DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE, &ddsi_serdata_ops_rawcdr); gv->sedp_reader_topic = make_special_topic_plist ("DCPSSubscription", "SubscriptionBuiltinTopicData", PID_ENDPOINT_GUID);
gv->sedp_writer_topic = make_special_topic_plist ("DCPSPublication", "PublicationBuiltinTopicData", PID_ENDPOINT_GUID);
gv->pmd_topic = make_special_topic_pserop ("DCPSParticipantMessage", "ParticipantMessageData", sizeof (ParticipantMessageData_t), participant_message_data_nops, participant_message_data_ops, participant_message_data_nops_key, participant_message_data_ops_key);
#ifdef DDSI_INCLUDE_SECURITY
gv->spdp_secure_topic = make_special_topic_plist ("DCPSParticipantsSecure", "ParticipantBuiltinTopicDataSecure", PID_PARTICIPANT_GUID);
gv->sedp_reader_secure_topic = make_special_topic_plist ("DCPSSubscriptionsSecure", "SubscriptionBuiltinTopicDataSecure", PID_ENDPOINT_GUID);
gv->sedp_writer_secure_topic = make_special_topic_plist ("DCPSPublicationsSecure", "PublicationBuiltinTopicDataSecure", PID_ENDPOINT_GUID);
gv->pmd_secure_topic = make_special_topic_pserop ("DCPSParticipantMessageSecure", "ParticipantMessageDataSecure", sizeof (ParticipantMessageData_t), participant_message_data_nops, participant_message_data_ops, participant_message_data_nops_key, participant_message_data_ops_key);
gv->pgm_stateless_topic = make_special_topic_pserop ("DCPSParticipantStatelessMessage", "ParticipantStatelessMessage", sizeof (nn_participant_generic_message_t), pserop_participant_generic_message_nops, pserop_participant_generic_message, 0, NULL);
gv->pgm_volatile_topic = make_special_topic_pserop ("DCPSParticipantVolatileMessageSecure", "ParticipantVolatileMessageSecure", sizeof (nn_participant_generic_message_t), pserop_participant_generic_message_nops, pserop_participant_generic_message, 0, NULL);
#endif
ddsrt_mutex_lock (&gv->sertopics_lock); ddsrt_mutex_lock (&gv->sertopics_lock);
ddsi_sertopic_register_locked (gv, gv->plist_topic); ddsi_sertopic_register_locked (gv, gv->spdp_topic);
ddsi_sertopic_register_locked (gv, gv->rawcdr_topic); ddsi_sertopic_register_locked (gv, gv->sedp_reader_topic);
ddsi_sertopic_register_locked (gv, gv->sedp_writer_topic);
ddsi_sertopic_register_locked (gv, gv->pmd_topic);
#ifdef DDSI_INCLUDE_SECURITY
ddsi_sertopic_register_locked (gv, gv->spdp_secure_topic);
ddsi_sertopic_register_locked (gv, gv->sedp_reader_secure_topic);
ddsi_sertopic_register_locked (gv, gv->sedp_writer_secure_topic);
ddsi_sertopic_register_locked (gv, gv->pmd_secure_topic);
ddsi_sertopic_register_locked (gv, gv->pgm_stateless_topic);
ddsi_sertopic_register_locked (gv, gv->pgm_volatile_topic);
#endif
ddsrt_mutex_unlock (&gv->sertopics_lock); ddsrt_mutex_unlock (&gv->sertopics_lock);
/* register increments refcount (which is reasonable), but at some point /* register increments refcount (which is reasonable), but at some point

View file

@ -1976,7 +1976,7 @@ static struct ddsi_serdata *remote_make_sample (struct ddsi_tkmap_instance **tk,
GVTRACE ("data(application, vendor %u.%u): "PGUIDFMT" #%"PRId64": ST%x %s/%s:%s%s", GVTRACE ("data(application, vendor %u.%u): "PGUIDFMT" #%"PRId64": ST%x %s/%s:%s%s",
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
PGUID (guid), sampleinfo->seq, statusinfo, topic->name, topic->type_name, PGUID (guid), sampleinfo->seq, statusinfo, topic->name, topic->type_name,
tmp, res < sizeof (tmp) ? "" : "(trunc)"); tmp, res < sizeof (tmp) - 1 ? "" : "(trunc)");
} }
} }
return sample; return sample;

View file

@ -966,8 +966,6 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct ddsi_pli
{ {
char ppbuf[1024]; char ppbuf[1024];
int tmp; int tmp;
const char *tname = wr->topic ? wr->topic->name : "(null)";
const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
ppbuf[0] = '\0'; ppbuf[0] = '\0';
tmp = sizeof (ppbuf) - 1; tmp = sizeof (ppbuf) - 1;
if (wr->e.gv->logconfig.c.mask & DDS_LC_CONTENT) if (wr->e.gv->logconfig.c.mask & DDS_LC_CONTENT)
@ -975,7 +973,7 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct ddsi_pli
ETRACE (wr, "write_sample "PGUIDFMT" #%"PRId64, PGUID (wr->e.guid), seq); ETRACE (wr, "write_sample "PGUIDFMT" #%"PRId64, PGUID (wr->e.guid), seq);
if (plist != 0 && (plist->present & PP_COHERENT_SET)) if (plist != 0 && (plist->present & PP_COHERENT_SET))
ETRACE (wr, " C#%"PRId64"", fromSN (plist->coherent_set_seqno)); ETRACE (wr, " C#%"PRId64"", fromSN (plist->coherent_set_seqno));
ETRACE (wr, ": ST%"PRIu32" %s/%s:%s%s\n", serdata->statusinfo, tname, ttname, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)"); ETRACE (wr, ": ST%"PRIu32" %s/%s:%s%s\n", serdata->statusinfo, wr->topic->name, wr->topic->type_name, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
} }
assert (wr->reliable || have_reliable_subs (wr) == 0); assert (wr->reliable || have_reliable_subs (wr) == 0);
@ -1235,13 +1233,11 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
{ {
char ppbuf[1024]; char ppbuf[1024];
int tmp; int tmp;
const char *tname = wr->topic ? wr->topic->name : "(null)";
const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
ppbuf[0] = '\0'; ppbuf[0] = '\0';
tmp = sizeof (ppbuf) - 1; tmp = sizeof (ppbuf) - 1;
GVWARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n", GVWARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n",
ddsi_serdata_size (serdata), gv->config.max_sample_size, ddsi_serdata_size (serdata), gv->config.max_sample_size,
PGUID (wr->e.guid), tname, ttname, ppbuf, PGUID (wr->e.guid), wr->topic->name, wr->topic->type_name, ppbuf,
tmp < (int) sizeof (ppbuf) ? "" : " (trunc)"); tmp < (int) sizeof (ppbuf) ? "" : " (trunc)");
r = DDS_RETCODE_BAD_PARAMETER; r = DDS_RETCODE_BAD_PARAMETER;
goto drop; goto drop;

View file

@ -1099,15 +1099,9 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t
ddsi_plist_init_empty (&ps); ddsi_plist_init_empty (&ps);
ps.present |= PP_PARTICIPANT_GUID; ps.present |= PP_PARTICIPANT_GUID;
ps.participant_guid = *guid; ps.participant_guid = *guid;
struct nn_xmsg *mpayload = nn_xmsg_new (gv->xmsgpool, guid, wr->c.pp, 0, NN_XMSG_KIND_DATA); struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv->spdp_topic, SDK_KEY, &ps);
ddsi_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
nn_xmsg_addpar_sentinel (mpayload);
ddsi_plist_fini (&ps); ddsi_plist_fini (&ps);
struct ddsi_plist_sample plist_sample;
nn_xmsg_payload_to_plistsample (&plist_sample, PID_PARTICIPANT_GUID, mpayload);
struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv->plist_topic, SDK_KEY, &plist_sample);
struct whc_borrowed_sample sample; struct whc_borrowed_sample sample;
nn_xmsg_free (mpayload);
ddsrt_mutex_lock (&wr->e.lock); ddsrt_mutex_lock (&wr->e.lock);
sample_found = whc_borrow_sample_key (wr->whc, sd, &sample); sample_found = whc_borrow_sample_key (wr->whc, sd, &sample);

View file

@ -215,10 +215,6 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t
used with the global one. */ used with the global one. */
assert (domid == cfg->c.domid || cfg == &logconfig); assert (domid == cfg->c.domid || cfg == &logconfig);
if (*fmt == 0) {
return;
}
lb = &log_buffer; lb = &log_buffer;
/* Thread-local buffer is always initialized with all zeroes. The pos /* Thread-local buffer is always initialized with all zeroes. The pos
@ -227,6 +223,20 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t
lb->pos = BUF_OFFSET; lb->pos = BUF_OFFSET;
lb->buf[lb->pos] = 0; lb->buf[lb->pos] = 0;
} }
/* drop any prefix of new lines if there is current no data in the buffer:
there are some tricky problems in tracing some details depending on
enabled categories (like which subset of discovery related data gets
traced), and it sometimes helps to be able to trace just a newline
knowing it won't have any effect if nothing is buffered */
if (lb->pos == BUF_OFFSET) {
while (*fmt == '\n')
fmt++;
}
if (*fmt == 0) {
return;
}
nrem = sizeof (lb->buf) - lb->pos; nrem = sizeof (lb->buf) - lb->pos;
if (nrem > 0) { if (nrem > 0) {
n = vsnprintf (lb->buf + lb->pos, nrem, fmt, ap); n = vsnprintf (lb->buf + lb->pos, nrem, fmt, ap);