Participant generic message (#273)
* Extended DDSI (de)serializer. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Added security Participant Generic Message. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Updated Participant Generic Message. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Updated generic ddsi (de)serializer. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Changed macros for functions. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
parent
7c1e47218d
commit
64cc631137
10 changed files with 881 additions and 94 deletions
|
@ -123,6 +123,17 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
|||
target_sources(ddsc
|
||||
PRIVATE ${srcs_ddsi} ${hdrs_private_ddsi})
|
||||
|
||||
if(ENABLE_SECURITY)
|
||||
PREPEND(security_srcs "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
ddsi_security_msg.c)
|
||||
|
||||
PREPEND(security_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||
ddsi_security_msg.h)
|
||||
|
||||
target_sources(ddsc
|
||||
PRIVATE ${security_srcs} ${security_hdrs})
|
||||
endif()
|
||||
|
||||
target_include_directories(ddsc
|
||||
PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ enum pserop {
|
|||
Xi, Xix2, Xix3, Xix4, /* int32_t, 1 .. 4 in a row */
|
||||
Xu, Xux2, Xux3, Xux4, Xux5, /* uint32_t, 1 .. 5 in a row */
|
||||
XD, XDx2, /* duration, 1 .. 2 in a row */
|
||||
Xl, /* int64_t */
|
||||
Xo, Xox2, /* octet, 1 .. 2 in a row */
|
||||
Xb, Xbx2, /* boolean, 1 .. 2 in a row */
|
||||
XbCOND, /* boolean: compare to ignore remainder if false (for use_... flags) */
|
||||
|
@ -44,15 +45,6 @@ enum pserop {
|
|||
Xopt, /* remainder is optional on deser, 0-init if not present */
|
||||
} ddsrt_attribute_packed;
|
||||
|
||||
inline bool pserop_seralign_is_1 (enum pserop op) {
|
||||
/* NB: XbPROP is never serialized, so its alignment is irrelevant. If ever there
|
||||
is a need to allow calling this function when op = XbPROP, it needs to be changed
|
||||
to taking the address of the pserop, and in that case inspect the following
|
||||
operator */
|
||||
assert (op != XbPROP && op != Xopt && op != XSTOP);
|
||||
return (op >= Xo && op <= XK);
|
||||
}
|
||||
|
||||
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_ser_generic (void **dst, size_t *dstsize, const void *src, const enum pserop * __restrict desc);
|
||||
|
|
91
src/core/ddsi/include/dds/ddsi/ddsi_security_msg.h
Normal file
91
src/core/ddsi/include/dds/ddsi/ddsi_security_msg.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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_SECURITY_MSG_H
|
||||
#define DDSI_SECURITY_MSG_H
|
||||
|
||||
#include "dds/ddsi/q_plist.h"
|
||||
#include "dds/ddsi/ddsi_guid.h"
|
||||
#include "dds/ddsrt/retcode.h"
|
||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GMCLASSID_SECURITY_AUTH_REQUEST "dds.sec.auth_request"
|
||||
#define GMCLASSID_SECURITY_AUTH_HANDSHAKE "dds.sec.auth"
|
||||
|
||||
typedef struct nn_message_identity {
|
||||
ddsi_guid_t source_guid;
|
||||
int64_t sequence_number;
|
||||
} nn_message_identity_t;
|
||||
|
||||
typedef struct nn_participant_generic_message {
|
||||
nn_message_identity_t message_identity;
|
||||
nn_message_identity_t related_message_identity;
|
||||
ddsi_guid_t destinaton_participant_guid;
|
||||
ddsi_guid_t destination_endpoint_guid;
|
||||
ddsi_guid_t source_endpoint_guid;
|
||||
const char *message_class_id;
|
||||
nn_dataholderseq_t message_data;
|
||||
} nn_participant_generic_message_t;
|
||||
|
||||
|
||||
/*
|
||||
* The arguments are aliased in the resulting message structure.
|
||||
* This means that the lifecycle of the arguments should be longer
|
||||
* then that of the message.
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
nn_participant_generic_message_init(
|
||||
nn_participant_generic_message_t *msg,
|
||||
const ddsi_guid_t *wrguid,
|
||||
int64_t wrseq,
|
||||
const ddsi_guid_t *dstpguid,
|
||||
const ddsi_guid_t *dsteguid,
|
||||
const ddsi_guid_t *srceguid,
|
||||
const char *classid,
|
||||
const nn_dataholderseq_t *mdata,
|
||||
const nn_message_identity_t *rmid);
|
||||
|
||||
/*
|
||||
* Aliased struct variables will not be freed.
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
nn_participant_generic_message_deinit(
|
||||
nn_participant_generic_message_t *msg);
|
||||
|
||||
/*
|
||||
* Some struct variables are aliased to the given buffer.
|
||||
* This means that the lifecycle of the data buffer should be
|
||||
* longer then that of the message.
|
||||
*/
|
||||
DDS_EXPORT dds_return_t
|
||||
nn_participant_generic_message_deseralize(
|
||||
nn_participant_generic_message_t *msg,
|
||||
const unsigned char *data,
|
||||
size_t len,
|
||||
bool bswap);
|
||||
|
||||
DDS_EXPORT dds_return_t
|
||||
nn_participant_generic_message_serialize(
|
||||
const nn_participant_generic_message_t *msg,
|
||||
unsigned char **data,
|
||||
size_t *len);
|
||||
|
||||
DDS_EXPORT extern const enum pserop pserop_participant_generic_message[];
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DDSI_SECURITY_MSG_H */
|
|
@ -134,6 +134,11 @@ typedef struct nn_dataholder
|
|||
dds_binarypropertyseq_t binary_properties;
|
||||
} nn_dataholder_t;
|
||||
|
||||
typedef struct nn_dataholderseq {
|
||||
uint32_t n;
|
||||
nn_dataholder_t *tags;
|
||||
} nn_dataholderseq_t;
|
||||
|
||||
typedef nn_dataholder_t nn_token_t;
|
||||
|
||||
/* Used for both nn_participant_security_info and nn_endpoint_security_info. */
|
||||
|
|
149
src/core/ddsi/src/ddsi_security_msg.c
Normal file
149
src/core/ddsi/src/ddsi_security_msg.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
#include "dds/ddsi/ddsi_security_msg.h"
|
||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||
|
||||
const enum pserop pserop_participant_generic_message[] =
|
||||
{
|
||||
/* nn_participant_generic_message */
|
||||
XG, Xl, /* nn_message_identity_t message_identity */
|
||||
XG, Xl, /* nn_message_identity_t related_message_identity */
|
||||
XG, /* ddsi_guid_t destinaton_participant_guid */
|
||||
XG, /* ddsi_guid_t destination_endpoint_guid */
|
||||
XG, /* ddsi_guid_t source_endpoint_guid */
|
||||
XS, /* char* message_class_id */
|
||||
XQ, /* nn_dataholderseq_t message_data */
|
||||
/* nn_dataholder_t */
|
||||
XS, /* char* class_id */
|
||||
XQ, /* dds_propertyseq_t properties */
|
||||
XbPROP, XS, XS, /* dds_property_t */
|
||||
XSTOP,
|
||||
XQ, /* dds_binarypropertyseq_t binary_properties */
|
||||
XbPROP, XS, XO, /* dds_binaryproperty_t */
|
||||
XSTOP,
|
||||
XSTOP,
|
||||
XSTOP /* end */
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
alias_simple_sequence(ddsi_octetseq_t *dst, const ddsi_octetseq_t *src, size_t elem_size)
|
||||
{
|
||||
dst->length = src->length;
|
||||
if (src->length > 0)
|
||||
{
|
||||
/* Even when aliased, sequence buffers are not shared. */
|
||||
dst->value = ddsrt_memdup(src->value, src->length * elem_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
alias_dataholder(nn_dataholder_t *dst, const nn_dataholder_t *src)
|
||||
{
|
||||
dst->class_id = src->class_id;
|
||||
alias_simple_sequence((ddsi_octetseq_t*)&dst->properties,
|
||||
(const ddsi_octetseq_t*)&src->properties,
|
||||
sizeof(dds_property_t));
|
||||
alias_simple_sequence((ddsi_octetseq_t*)&dst->binary_properties,
|
||||
(const ddsi_octetseq_t*)&src->binary_properties,
|
||||
sizeof(dds_binaryproperty_t));
|
||||
}
|
||||
|
||||
static void
|
||||
alias_dataholderseq(nn_dataholderseq_t *dst, const nn_dataholderseq_t *src)
|
||||
{
|
||||
dst->n = src->n;
|
||||
if (src->n > 0)
|
||||
{
|
||||
/* Even when aliased, sequence buffers are not shared. */
|
||||
dst->tags = ddsrt_malloc(src->n * sizeof(nn_dataholder_t));
|
||||
for (uint32_t i = 0; i < src->n; i++)
|
||||
{
|
||||
alias_dataholder(&(dst->tags[i]), &(src->tags[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nn_participant_generic_message_init(
|
||||
nn_participant_generic_message_t *msg,
|
||||
const ddsi_guid_t *wrguid,
|
||||
int64_t wrseq,
|
||||
const ddsi_guid_t *dstpguid,
|
||||
const ddsi_guid_t *dsteguid,
|
||||
const ddsi_guid_t *srceguid,
|
||||
const char *classid,
|
||||
const nn_dataholderseq_t *mdata,
|
||||
const nn_message_identity_t *rmid)
|
||||
{
|
||||
assert(msg);
|
||||
assert(wrguid);
|
||||
assert(classid);
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
|
||||
msg->message_identity.source_guid = *wrguid;
|
||||
msg->message_identity.sequence_number = wrseq;
|
||||
|
||||
if (rmid)
|
||||
{
|
||||
msg->related_message_identity.source_guid = rmid->source_guid;
|
||||
msg->related_message_identity.sequence_number = rmid->sequence_number;
|
||||
}
|
||||
|
||||
if (dstpguid)
|
||||
msg->destinaton_participant_guid = *dstpguid;
|
||||
|
||||
if (dsteguid)
|
||||
msg->destination_endpoint_guid = *dsteguid;
|
||||
|
||||
if (srceguid)
|
||||
msg->source_endpoint_guid = *srceguid;
|
||||
|
||||
msg->message_class_id = classid;
|
||||
|
||||
if (mdata)
|
||||
alias_dataholderseq(&msg->message_data, mdata);
|
||||
}
|
||||
|
||||
void
|
||||
nn_participant_generic_message_deinit(
|
||||
nn_participant_generic_message_t *msg)
|
||||
{
|
||||
assert(msg);
|
||||
plist_fini_generic(msg, pserop_participant_generic_message, true);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
nn_participant_generic_message_serialize(
|
||||
const nn_participant_generic_message_t *msg,
|
||||
unsigned char **data,
|
||||
size_t *len)
|
||||
{
|
||||
return plist_ser_generic ((void**)data, len, (void*)msg, pserop_participant_generic_message);
|
||||
}
|
||||
|
||||
dds_return_t
|
||||
nn_participant_generic_message_deseralize(
|
||||
nn_participant_generic_message_t *msg,
|
||||
const unsigned char *data,
|
||||
size_t len,
|
||||
bool bswap)
|
||||
{
|
||||
assert(sizeof(nn_participant_generic_message_t) == plist_memsize_generic(pserop_participant_generic_message));
|
||||
return plist_deser_generic (msg, data, len, bswap, pserop_participant_generic_message);
|
||||
}
|
|
@ -114,8 +114,6 @@ struct piddesc {
|
|||
dds_return_t (*deser_validate_xform) (void * __restrict dst, const struct dd * __restrict dd);
|
||||
};
|
||||
|
||||
extern inline bool pserop_seralign_is_1 (enum pserop op);
|
||||
|
||||
static void log_octetseq (uint32_t cat, const struct ddsrt_log_cfg *logcfg, uint32_t n, const unsigned char *xs);
|
||||
static dds_return_t validate_history_qospolicy (const dds_history_qospolicy_t *q);
|
||||
static dds_return_t validate_resource_limits_qospolicy (const dds_resource_limits_qospolicy_t *q);
|
||||
|
@ -127,26 +125,70 @@ static dds_return_t final_validation_qos (const dds_qos_t *dest, nn_protocol_ver
|
|||
static int partitions_equal (const dds_partition_qospolicy_t *a, const dds_partition_qospolicy_t *b);
|
||||
static dds_return_t nn_xqos_valid_strictness (const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos, bool strict);
|
||||
|
||||
static size_t align4size (size_t x)
|
||||
static size_t pserop_seralign(enum pserop op)
|
||||
{
|
||||
return (x + 3) & ~(size_t)3;
|
||||
switch(op)
|
||||
{
|
||||
case XSTOP:
|
||||
case XbPROP:
|
||||
case Xopt:
|
||||
/* NB: XbPROP is never serialized, so its alignment is irrelevant. If ever there
|
||||
is a need to allow calling this function when op = XbPROP, it needs to be changed
|
||||
to taking the address of the pserop, and in that case inspect the following
|
||||
operator */
|
||||
assert(false);
|
||||
return 1;
|
||||
case Xo: case Xox2:
|
||||
case Xb: case Xbx2:
|
||||
case XbCOND:
|
||||
case XG:
|
||||
case XK:
|
||||
return 1;
|
||||
case XO:
|
||||
case XS:
|
||||
case XE1: case XE2: case XE3:
|
||||
case Xi: case Xix2: case Xix3: case Xix4:
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5:
|
||||
case XD: case XDx2:
|
||||
case XQ:
|
||||
return 4;
|
||||
case Xl:
|
||||
return 8;
|
||||
}
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *deser_generic_dst (void * __restrict dst, size_t *dstoff, size_t align)
|
||||
static size_t alignN(const size_t off, const size_t align)
|
||||
{
|
||||
*dstoff = (*dstoff + align - 1) & ~(align - 1);
|
||||
return (off + align - 1) & ~(align - 1);
|
||||
}
|
||||
|
||||
static size_t align4(const size_t off)
|
||||
{
|
||||
return alignN(off, 4);
|
||||
}
|
||||
|
||||
static size_t align8(const size_t off)
|
||||
{
|
||||
return alignN(off, 8);
|
||||
}
|
||||
|
||||
static void *deser_generic_dst (void * __restrict dst, size_t *dstoff, const size_t align)
|
||||
{
|
||||
*dstoff = alignN(*dstoff, align);
|
||||
return (char *) dst + *dstoff;
|
||||
}
|
||||
|
||||
static const void *deser_generic_src (const void * __restrict src, size_t *srcoff, size_t align)
|
||||
static const void *deser_generic_src (const void * __restrict src, size_t *srcoff, const size_t align)
|
||||
{
|
||||
*srcoff = (*srcoff + align - 1) & ~(align - 1);
|
||||
*srcoff = alignN(*srcoff, align);
|
||||
return (const char *) src + *srcoff;
|
||||
}
|
||||
|
||||
static void *ser_generic_align4 (char * __restrict p, size_t * __restrict off)
|
||||
static void *ser_generic_aligned (char * __restrict p, size_t * __restrict off, const size_t align)
|
||||
{
|
||||
const size_t off1 = align4size (*off);
|
||||
const size_t off1 = alignN(*off, align);
|
||||
size_t pad = off1 - *off;
|
||||
char *dst = p + *off;
|
||||
*off = off1;
|
||||
|
@ -155,6 +197,16 @@ static void *ser_generic_align4 (char * __restrict p, size_t * __restrict off)
|
|||
return dst;
|
||||
}
|
||||
|
||||
static void *ser_generic_align4(char * __restrict p, size_t * __restrict off)
|
||||
{
|
||||
return ser_generic_aligned(p, off, 4);
|
||||
}
|
||||
|
||||
static void *ser_generic_align8(char * __restrict p, size_t * __restrict off)
|
||||
{
|
||||
return ser_generic_aligned(p, off, 8);
|
||||
}
|
||||
|
||||
static dds_return_t deser_uint32 (uint32_t *dst, const struct dd * __restrict dd, size_t * __restrict off)
|
||||
{
|
||||
size_t off1 = (*off + 3) & ~(size_t)3;
|
||||
|
@ -169,6 +221,20 @@ static dds_return_t deser_uint32 (uint32_t *dst, const struct dd * __restrict dd
|
|||
return 0;
|
||||
}
|
||||
|
||||
static dds_return_t deser_int64 (int64_t *dst, const struct dd * __restrict dd, size_t * __restrict off)
|
||||
{
|
||||
size_t off1 = (*off + 7) & ~(size_t)7;
|
||||
int64_t tmp;
|
||||
if (off1 + 8 > dd->bufsz)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
tmp = *((int64_t *) (dd->buf + off1));
|
||||
if (dd->bswap)
|
||||
tmp = bswap8 (tmp);
|
||||
*dst = tmp;
|
||||
*off = off1 + 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define alignof(type_) offsetof (struct { char c; type_ d; }, d)
|
||||
|
||||
static dds_return_t deser_reliability (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff)
|
||||
|
@ -310,6 +376,28 @@ static dds_return_t fini_locator (void * __restrict dst, size_t * __restrict dst
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const enum pserop* pserop_advance (const enum pserop * __restrict desc)
|
||||
{
|
||||
/* Should not start on an end. */
|
||||
assert(*desc != XSTOP);
|
||||
|
||||
/* If not a sequence, return next. */
|
||||
if (*desc != XQ) return (desc + 1);
|
||||
|
||||
/* Jump over this sequence (ignoring nested ones). */
|
||||
int scope = 1;
|
||||
do
|
||||
{
|
||||
desc++;
|
||||
if (*desc == XQ) scope++;
|
||||
if (*desc == XSTOP) scope--;
|
||||
}
|
||||
while (scope != 0);
|
||||
|
||||
/* We're on the stop, return next. */
|
||||
return (desc + 1);
|
||||
}
|
||||
|
||||
static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
|
||||
{
|
||||
size_t srcoff = 0, srcalign = 0;
|
||||
|
@ -330,6 +418,7 @@ static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
|
|||
case XE1: case XE2: case XE3: SIMPLE (*desc, unsigned); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
|
||||
case Xl: SIMPLE (Xl, int64_t); break;
|
||||
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
|
||||
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
|
||||
|
@ -337,10 +426,10 @@ static size_t ser_generic_srcsize (const enum pserop * __restrict desc)
|
|||
case XG: SIMPLE (XG, ddsi_guid_t); break;
|
||||
case XK: SIMPLE (XK, nn_keyhash_t); break;
|
||||
case XbPROP: SIMPLE (XbPROP, unsigned char); break;
|
||||
case XQ: SIMPLE (XQ, ddsi_octetseq_t); while (*++desc != XSTOP) { } break;
|
||||
case XQ: SIMPLE (XQ, ddsi_octetseq_t); break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef SIMPLE
|
||||
}
|
||||
|
@ -350,8 +439,9 @@ size_t plist_memsize_generic (const enum pserop * __restrict desc)
|
|||
return ser_generic_srcsize (desc);
|
||||
}
|
||||
|
||||
static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased)
|
||||
static bool fini_generic_embeddable (void * __restrict dst, size_t * __restrict dstoff, const enum pserop *desc, const enum pserop * const desc_end, bool aliased)
|
||||
{
|
||||
bool freed = false;
|
||||
#define COMPLEX(basecase_, type_, cleanup_unaliased_, cleanup_always_) do { \
|
||||
type_ *x = deser_generic_dst (dst, dstoff, alignof (type_)); \
|
||||
const uint32_t cnt = 1 + (uint32_t) (*desc - (basecase_)); \
|
||||
|
@ -362,16 +452,17 @@ static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict
|
|||
*dstoff += cnt * sizeof (*x); \
|
||||
} while (0)
|
||||
#define SIMPLE(basecase_, type_) COMPLEX (basecase_, type_, (void) 0, (void) 0)
|
||||
while (desc != desc_end)
|
||||
while ((desc_end == NULL) || (desc < desc_end))
|
||||
{
|
||||
switch (*desc)
|
||||
{
|
||||
case XSTOP: return;
|
||||
case XO: COMPLEX (XO, ddsi_octetseq_t, ddsrt_free (x->value), (void) 0); break;
|
||||
case XS: COMPLEX (XS, char *, ddsrt_free (*x), (void) 0); break;
|
||||
case XSTOP: return freed;
|
||||
case XO: COMPLEX (XO, ddsi_octetseq_t, { ddsrt_free (x->value); freed = true; }, (void) 0); break;
|
||||
case XS: COMPLEX (XS, char *, { ddsrt_free (*x); freed = true; }, (void) 0); break;
|
||||
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, (void) 0, (void) 0); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
|
||||
case Xl: SIMPLE (Xl, int64_t); break;
|
||||
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
|
||||
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
|
||||
|
@ -380,23 +471,27 @@ static void fini_generic_embeddable (void * __restrict dst, size_t * __restrict
|
|||
case XK: SIMPLE (XK, nn_keyhash_t); break;
|
||||
case XbPROP: SIMPLE (XbPROP, unsigned char); break;
|
||||
case XQ:
|
||||
/* non-nested, so never a need to deallocate only some of the entries and no complications
|
||||
in locating the end of the sequence element description */
|
||||
COMPLEX (XQ, ddsi_octetseq_t, {
|
||||
const size_t elem_size = ser_generic_srcsize (desc + 1);
|
||||
for (uint32_t i = 0; i < x->length; i++) {
|
||||
size_t elem_off = i * elem_size;
|
||||
fini_generic_embeddable (x->value, &elem_off, desc + 1, desc_end, aliased);
|
||||
}
|
||||
}, ddsrt_free (x->value));
|
||||
while (desc + 1 != desc_end && *++desc != XSTOP) { }
|
||||
break;
|
||||
{
|
||||
ddsi_octetseq_t *x = deser_generic_dst (dst, dstoff, alignof (ddsi_octetseq_t));
|
||||
const size_t elem_size = ser_generic_srcsize (desc + 1);
|
||||
bool elem_freed = true;
|
||||
for (uint32_t i = 0; (i < x->length) && elem_freed; i++)
|
||||
{
|
||||
size_t elem_off = i * elem_size;
|
||||
elem_freed = fini_generic_embeddable (x->value, &elem_off, desc + 1, desc_end, aliased);
|
||||
}
|
||||
ddsrt_free (x->value);
|
||||
freed = true;
|
||||
*dstoff += sizeof (ddsi_octetseq_t);
|
||||
}
|
||||
break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef SIMPLE
|
||||
#undef COMPLEX
|
||||
return freed;
|
||||
}
|
||||
|
||||
static size_t pserop_memalign (enum pserop op)
|
||||
|
@ -413,13 +508,14 @@ static size_t pserop_memalign (enum pserop op)
|
|||
case XE1: case XE2: case XE3: return sizeof (uint32_t);
|
||||
case Xi: case Xix2: case Xix3: case Xix4: return sizeof (int32_t);
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: return sizeof (uint32_t);
|
||||
case Xl: return alignof (int64_t);
|
||||
case XD: case XDx2: return alignof (dds_duration_t);
|
||||
case XSTOP: case Xopt: assert (0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
|
||||
static dds_return_t deser_generic_r (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
|
||||
{
|
||||
enum pserop const * const desc_in = desc;
|
||||
size_t dstoff_in = *dstoff;
|
||||
|
@ -448,7 +544,7 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
|
|||
char ** const x = deser_generic_dst (dst, dstoff, alignof (char *));
|
||||
ddsi_octetseq_t tmp;
|
||||
size_t tmpoff = 0;
|
||||
if (deser_generic (&tmp, &tmpoff, flagset, flag, dd, srcoff, (enum pserop []) { XO, XSTOP }) < 0)
|
||||
if (deser_generic_r (&tmp, &tmpoff, flagset, flag, dd, srcoff, (enum pserop []) { XO, XSTOP }) < 0)
|
||||
goto fail;
|
||||
if (tmp.length < 1 || tmp.value[tmp.length - 1] != 0)
|
||||
goto fail;
|
||||
|
@ -484,6 +580,13 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
|
|||
*dstoff += cnt * sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case Xl: { /* int64_t */
|
||||
int64_t * const x = deser_generic_dst (dst, dstoff, alignof (int64_t));
|
||||
if (deser_int64(x, dd, srcoff) < 0)
|
||||
goto fail;
|
||||
*dstoff += sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case XD: case XDx2: { /* duration(s): int64_t <=> int32_t.uint32_t (seconds.fraction) */
|
||||
dds_duration_t * const x = deser_generic_dst (dst, dstoff, alignof (dds_duration_t));
|
||||
const uint32_t cnt = 1 + (uint32_t) (*desc - XD);
|
||||
|
@ -547,7 +650,7 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
|
|||
*dstoff += sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case XQ: { /* non-nested but otherwise arbitrary sequence, so no nested mallocs */
|
||||
case XQ: { /* arbitrary sequence */
|
||||
ddsi_octetseq_t * const x = deser_generic_dst (dst, dstoff, alignof (ddsi_octetseq_t));
|
||||
if (deser_uint32 (&x->length, dd, srcoff) < 0 || x->length > dd->bufsz - *srcoff)
|
||||
goto fail;
|
||||
|
@ -556,25 +659,26 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
|
|||
for (uint32_t i = 0; i < x->length; i++)
|
||||
{
|
||||
size_t elem_off = i * elem_size;
|
||||
if (deser_generic (x->value, &elem_off, flagset, flag, dd, srcoff, desc + 1) < 0)
|
||||
if (deser_generic_r (x->value, &elem_off, flagset, flag, dd, srcoff, desc + 1) < 0)
|
||||
{
|
||||
bool elem_freed = true;
|
||||
for (uint32_t f = 0; (f < i) && (elem_freed); f++)
|
||||
{
|
||||
size_t free_off = f * elem_size;
|
||||
elem_freed = fini_generic_embeddable (x->value, &free_off, desc + 1, NULL, *flagset->aliased & flag);
|
||||
}
|
||||
ddsrt_free (x->value);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
*dstoff += sizeof (*x);
|
||||
while (*++desc != XSTOP) { }
|
||||
break;
|
||||
}
|
||||
case Xopt: { /* remainder is optional; alignment is very nearly always 4 */
|
||||
bool end_of_input;
|
||||
if (pserop_seralign_is_1 (desc[1]))
|
||||
end_of_input = (*srcoff + 1 > dd->bufsz);
|
||||
else
|
||||
{
|
||||
*srcoff = (*srcoff + 3) & ~(size_t)3;
|
||||
end_of_input = (*srcoff + 4 > dd->bufsz);
|
||||
}
|
||||
size_t align = pserop_seralign(desc[1]);
|
||||
*srcoff = alignN(*srcoff, align);
|
||||
end_of_input = (*srcoff + align > dd->bufsz);
|
||||
if (end_of_input)
|
||||
{
|
||||
void * const x = deser_generic_dst (dst, dstoff, pserop_memalign (desc[1]));
|
||||
|
@ -584,19 +688,29 @@ static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict ds
|
|||
}
|
||||
}
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
success:
|
||||
*flagset->present |= flag;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fini_generic_embeddable (dst, &dstoff_in, desc_in, desc, *flagset->aliased & flag);
|
||||
*flagset->present &= ~flag;
|
||||
*flagset->aliased &= ~flag;
|
||||
(void)fini_generic_embeddable (dst, &dstoff_in, desc_in, desc, *flagset->aliased & flag);
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
static dds_return_t deser_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const struct dd * __restrict dd, size_t * __restrict srcoff, const enum pserop * __restrict desc)
|
||||
{
|
||||
dds_return_t ret;
|
||||
ret = deser_generic_r (dst, dstoff, flagset, flag, dd, srcoff, desc);
|
||||
if (ret != 0)
|
||||
{
|
||||
*flagset->present &= ~flag;
|
||||
*flagset->aliased &= ~flag;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
dds_return_t plist_deser_generic (void * __restrict dst, const void * __restrict src, size_t srcsize, bool bswap, const enum pserop * __restrict desc)
|
||||
{
|
||||
struct dd dd = {
|
||||
|
@ -622,17 +736,19 @@ static void ser_generic_size_embeddable (size_t *dstoff, const void *src, size_t
|
|||
srcoff += cnt * sizeof (*x); \
|
||||
} while (0)
|
||||
#define SIMPLE1(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = *dstoff + sizeof (*x))
|
||||
#define SIMPLE4(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align4size (*dstoff) + sizeof (*x))
|
||||
#define SIMPLE4(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align4 (*dstoff) + sizeof (*x))
|
||||
#define SIMPLE8(basecase_, type_) COMPLEX (basecase_, type_, *dstoff = align8 (*dstoff) + sizeof (*x))
|
||||
while (true)
|
||||
{
|
||||
switch (*desc)
|
||||
{
|
||||
case XSTOP: return;
|
||||
case XO: COMPLEX (XO, ddsi_octetseq_t, *dstoff = align4size (*dstoff) + 4 + x->length); break;
|
||||
case XS: COMPLEX (XS, const char *, *dstoff = align4size (*dstoff) + 4 + strlen (*x) + 1); break;
|
||||
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, *dstoff = align4size (*dstoff) + 4); break;
|
||||
case XO: COMPLEX (XO, ddsi_octetseq_t, *dstoff = align4 (*dstoff) + 4 + x->length); break;
|
||||
case XS: COMPLEX (XS, const char *, *dstoff = align4 (*dstoff) + 4 + strlen (*x) + 1); break;
|
||||
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, *dstoff = align4 (*dstoff) + 4); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE4 (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE4 (Xu, uint32_t); break;
|
||||
case Xl: SIMPLE8 (Xl, int64_t); break;
|
||||
case XD: case XDx2: SIMPLE4 (XD, dds_duration_t); break;
|
||||
case Xo: case Xox2: SIMPLE1 (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: SIMPLE1 (Xb, unsigned char); break;
|
||||
|
@ -643,14 +759,15 @@ static void ser_generic_size_embeddable (size_t *dstoff, const void *src, size_t
|
|||
COMPLEX (XbPROP, unsigned char, if (! *x) return); break;
|
||||
case XQ: COMPLEX (XQ, ddsi_octetseq_t, {
|
||||
const size_t elem_size = ser_generic_srcsize (desc + 1);
|
||||
*dstoff = align4size (*dstoff) + 4;
|
||||
*dstoff = align4 (*dstoff) + 4;
|
||||
for (uint32_t i = 0; i < x->length; i++)
|
||||
ser_generic_size_embeddable (dstoff, x->value, i * elem_size, desc + 1);
|
||||
}); while (*++desc != XSTOP) { } break;
|
||||
}); break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef SIMPLE8
|
||||
#undef SIMPLE4
|
||||
#undef SIMPLE1
|
||||
#undef COMPLEX
|
||||
|
@ -733,6 +850,14 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
|
|||
srcoff += cnt * sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case Xl: { /* int64_t */
|
||||
int64_t const * const x = deser_generic_src (src, &srcoff, alignof (int64_t));
|
||||
int64_t * const p = ser_generic_align8 (data, dstoff);
|
||||
*p = *x;
|
||||
*dstoff += sizeof (*x);
|
||||
srcoff += sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case XD: case XDx2: { /* duration(s): int64_t <=> int32_t.uint32_t (seconds.fraction) */
|
||||
dds_duration_t const * const x = deser_generic_src (src, &srcoff, alignof (dds_duration_t));
|
||||
const uint32_t cnt = 1 + (uint32_t) (*desc - XD);
|
||||
|
@ -788,7 +913,7 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
|
|||
srcoff += sizeof (*x);
|
||||
break;
|
||||
}
|
||||
case XQ: {
|
||||
case XQ: { /* arbitrary sequence */
|
||||
ddsi_octetseq_t const * const x = deser_generic_src (src, &srcoff, alignof (ddsi_octetseq_t));
|
||||
char * const p = ser_generic_align4 (data, dstoff);
|
||||
*dstoff += 4;
|
||||
|
@ -802,13 +927,12 @@ static dds_return_t ser_generic_embeddable (char * const data, size_t *dstoff, c
|
|||
ser_generic_embeddable (data, dstoff, x->value, i * elem_size, desc + 1);
|
||||
}
|
||||
srcoff += sizeof (*x);
|
||||
while (*++desc != XSTOP) { }
|
||||
break;
|
||||
}
|
||||
case Xopt:
|
||||
break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,6 +976,7 @@ static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict
|
|||
case XE1: case XE2: case XE3: COMPLEX (*desc, unsigned, (void) 0); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: SIMPLE (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: SIMPLE (Xu, uint32_t); break;
|
||||
case Xl: SIMPLE(Xl, int64_t); break;
|
||||
case XD: case XDx2: SIMPLE (XD, dds_duration_t); break;
|
||||
case Xo: case Xox2: SIMPLE (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: SIMPLE (Xb, unsigned char); break;
|
||||
|
@ -877,10 +1002,10 @@ static dds_return_t unalias_generic (void * __restrict dst, size_t * __restrict
|
|||
size_t elem_off = i * elem_size;
|
||||
unalias_generic (x->value, &elem_off, gen_seq_aliased, desc + 1);
|
||||
}
|
||||
}); while (*++desc != XSTOP) { } break;
|
||||
}); break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef SIMPLE
|
||||
#undef COMPLEX
|
||||
|
@ -915,14 +1040,14 @@ static bool fini_generic_required (const enum pserop * __restrict desc)
|
|||
|
||||
static dds_return_t fini_generic (void * __restrict dst, size_t * __restrict dstoff, struct flagset *flagset, uint64_t flag, const enum pserop * __restrict desc)
|
||||
{
|
||||
fini_generic_embeddable (dst, dstoff, desc, NULL, *flagset->aliased & flag);
|
||||
(void)fini_generic_embeddable (dst, dstoff, desc, NULL, *flagset->aliased & flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plist_fini_generic (void * __restrict dst, const enum pserop *desc, bool aliased)
|
||||
{
|
||||
size_t dstoff = 0;
|
||||
fini_generic_embeddable (dst, &dstoff, desc, NULL, aliased);
|
||||
(void)fini_generic_embeddable (dst, &dstoff, desc, NULL, aliased);
|
||||
}
|
||||
|
||||
static dds_return_t valid_generic (const void *src, size_t srcoff, const enum pserop * __restrict desc)
|
||||
|
@ -945,6 +1070,7 @@ static dds_return_t valid_generic (const void *src, size_t srcoff, const enum ps
|
|||
case XE1: case XE2: case XE3: SIMPLE (*desc, unsigned, *x <= 1 + (unsigned) *desc - XE1); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: TRIVIAL (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: TRIVIAL (Xu, uint32_t); break;
|
||||
case Xl: TRIVIAL(Xl, int64_t); break;
|
||||
case XD: case XDx2: SIMPLE (XD, dds_duration_t, *x >= 0); break;
|
||||
case Xo: case Xox2: TRIVIAL (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: SIMPLE (Xb, unsigned char, *x == 0 || *x == 1); break;
|
||||
|
@ -963,10 +1089,10 @@ static dds_return_t valid_generic (const void *src, size_t srcoff, const enum ps
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}); while (*++desc != XSTOP) { } break;
|
||||
}); break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef TRIVIAL
|
||||
#undef SIMPLE
|
||||
|
@ -1001,6 +1127,7 @@ static bool equal_generic (const void *srcx, const void *srcy, size_t srcoff, co
|
|||
case XE1: case XE2: case XE3: TRIVIAL (*desc, unsigned); break;
|
||||
case Xi: case Xix2: case Xix3: case Xix4: TRIVIAL (Xi, int32_t); break;
|
||||
case Xu: case Xux2: case Xux3: case Xux4: case Xux5: TRIVIAL (Xu, uint32_t); break;
|
||||
case Xl: TRIVIAL (Xl, int64_t); break;
|
||||
case XD: case XDx2: TRIVIAL (XD, dds_duration_t); break;
|
||||
case Xo: case Xox2: TRIVIAL (Xo, unsigned char); break;
|
||||
case Xb: case Xbx2: TRIVIAL (Xb, unsigned char); break;
|
||||
|
@ -1025,10 +1152,10 @@ static bool equal_generic (const void *srcx, const void *srcy, size_t srcoff, co
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}); while (*++desc != XSTOP) { } break;
|
||||
}); break;
|
||||
case Xopt: break;
|
||||
}
|
||||
desc++;
|
||||
desc = pserop_advance(desc);
|
||||
}
|
||||
#undef TRIVIAL
|
||||
#undef SIMPLE
|
||||
|
|
|
@ -13,7 +13,12 @@ include(CUnit)
|
|||
|
||||
set(ddsi_test_sources
|
||||
"plist_generic.c"
|
||||
"plist.c")
|
||||
"plist.c"
|
||||
"mem_ser.h")
|
||||
|
||||
if(ENABLE_SECURITY)
|
||||
set(ddsi_test_sources ${ddsi_test_sources} "security_msg.c")
|
||||
endif()
|
||||
|
||||
add_cunit_executable(cunit_ddsi ${ddsi_test_sources})
|
||||
target_include_directories(
|
||||
|
|
55
src/core/ddsi/tests/mem_ser.h
Normal file
55
src/core/ddsi/tests/mem_ser.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright(c) 2019 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_TEST_MEM_SER_H
|
||||
#define DDSI_TEST_MEM_SER_H
|
||||
|
||||
#include "dds/ddsrt/endian.h"
|
||||
|
||||
#if DDSRT_ENDIAN == DDSRT_BIG_ENDIAN
|
||||
#define SER32(v) \
|
||||
(unsigned char)( (uint32_t)(v) >> 24 ), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)( (uint32_t)(v) & 0xff)
|
||||
#define SER32BE(v) SER32(v)
|
||||
#define SER64(v) \
|
||||
(unsigned char)( (uint32_t)(v) >> 56), \
|
||||
(unsigned char)(((uint32_t)(v) >> 48) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 40) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 32) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 24) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)( (uint32_t)(v) & 0xff)
|
||||
#else
|
||||
#define SER32(v) \
|
||||
(unsigned char)( (uint32_t)(v) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)( (uint32_t)(v) >> 24 )
|
||||
#define SER32BE(v) \
|
||||
(unsigned char)( (uint32_t)(v) >> 24 ), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)( (uint32_t)(v) & 0xff)
|
||||
#define SER64(v) \
|
||||
(unsigned char)( (uint64_t)(v) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 24) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 32) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 40) & 0xff), \
|
||||
(unsigned char)(((uint64_t)(v) >> 48) & 0xff), \
|
||||
(unsigned char)( (uint64_t)(v) >> 56)
|
||||
#endif
|
||||
|
||||
#endif /* DDSI_TEST_MEM_SER_H */
|
|
@ -15,6 +15,7 @@
|
|||
#include "dds/ddsrt/endian.h"
|
||||
#include "dds/ddsi/q_xqos.h"
|
||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||
#include "mem_ser.h"
|
||||
|
||||
struct desc {
|
||||
const enum pserop desc[20];
|
||||
|
@ -33,28 +34,9 @@ struct desc_invalid {
|
|||
const unsigned char *ser;
|
||||
};
|
||||
|
||||
#if DDSRT_ENDIAN == DDSRT_BIG_ENDIAN
|
||||
#define SER32(v) \
|
||||
(unsigned char)((uint32_t)(v) >> 24), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)((uint32_t)(v) & 0xff)
|
||||
#define SER32BE(v) SER32(v)
|
||||
#else
|
||||
#define SER32(v) \
|
||||
(unsigned char)((uint32_t)(v) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)((uint32_t)(v) >> 24)
|
||||
#define SER32BE(v) \
|
||||
(unsigned char)((uint32_t)(v) >> 24), \
|
||||
(unsigned char)(((uint32_t)(v) >> 16) & 0xff), \
|
||||
(unsigned char)(((uint32_t)(v) >> 8) & 0xff), \
|
||||
(unsigned char)((uint32_t)(v) & 0xff)
|
||||
#endif
|
||||
|
||||
typedef unsigned char raw[];
|
||||
typedef uint32_t raw32[];
|
||||
typedef uint64_t raw64[];
|
||||
typedef ddsi_octetseq_t oseq;
|
||||
|
||||
struct desc descs[] = {
|
||||
|
@ -75,6 +57,7 @@ struct desc descs[] = {
|
|||
{ {Xux3,XSTOP}, (raw32){4,5,6}, 12, (raw){SER32(4), SER32(5), SER32(6)} },
|
||||
{ {Xux4,XSTOP}, (raw32){7,8,9,10}, 16, (raw){SER32(7), SER32(8), SER32(9), SER32(10)} },
|
||||
{ {Xux5,XSTOP}, (raw32){7,8,9,10,11}, 20, (raw){SER32(7), SER32(8), SER32(9), SER32(10), SER32(11)} },
|
||||
{ {Xl,XSTOP}, (raw64){123456789}, 8, (raw){SER64(123456789)} },
|
||||
{ {XD,XSTOP}, (uint64_t[]){314159265358979324},
|
||||
/* note: fractional part depends on rounding rule used for converting nanoseconds to NTP time
|
||||
Cyclone currently rounds up, so we have to do that too */
|
||||
|
@ -94,6 +77,46 @@ struct desc descs[] = {
|
|||
7, (raw){SER32(3), 1,2,3} },
|
||||
{ {XQ,XS,XSTOP,XSTOP}, &(ddsi_stringseq_t){2, (char*[]){"tree","flower"}},
|
||||
27, (raw){SER32(2), SER32(5),'t','r','e','e',0, 0,0,0, SER32(7), 'f','l','o','w','e','r',0} },
|
||||
{ {Xo,Xl,Xo,Xu,Xo,XSTOP},
|
||||
&(struct{unsigned char a;int64_t b;unsigned char c;uint32_t d;unsigned char e;}){ 1, 2, 3, 4, 5 },
|
||||
25, (raw){1,0,0,0,0,0,0,0,SER64(2),3,0,0,0,SER32(4),5} },
|
||||
{ {Xo,XQ,Xo,Xu,Xo,XSTOP,Xo,XSTOP},
|
||||
&(struct{uint8_t b; oseq seq; uint8_t c;})
|
||||
{1, {2, (unsigned char *)(struct{uint8_t a; uint32_t b; uint8_t c;}[])
|
||||
{ {0x10, 0x11, 0x12},
|
||||
{0x21, 0x22, 0x23} },
|
||||
}, 0x42 },
|
||||
26,
|
||||
(raw){1, /* pad */0,0,0, SER32(2),
|
||||
0x10, /* pad */0,0,0, SER32(0x11), 0x12,
|
||||
0x21, /* pad */0,0, SER32(0x22), 0x23,
|
||||
0x42}
|
||||
},
|
||||
{ {Xo,XQ,Xo,Xl,Xo,XSTOP,Xo,XSTOP},
|
||||
&(struct{uint8_t b; oseq seq; uint8_t c;})
|
||||
{1, {2, (unsigned char *)(struct{uint8_t a; int64_t b; uint8_t c;}[])
|
||||
{ {0x10, 0x11, 0x12},
|
||||
{0x21, 0x22, 0x23} },
|
||||
}, 0x42 },
|
||||
42,
|
||||
(raw){1, /* pad */0,0,0, SER32(2),
|
||||
0x10, /* pad */0,0,0,0,0,0,0, SER64(0x11), 0x12,
|
||||
0x21, /* pad */0,0,0,0,0,0, SER64(0x22), 0x23,
|
||||
0x42}
|
||||
},
|
||||
{ {Xo,XQ,Xo,Xo,XQ,Xo,XSTOP,XSTOP,Xo,XSTOP},
|
||||
&(struct{uint8_t b; oseq seq; uint8_t c;})
|
||||
{1, {2, (unsigned char *)(struct{uint8_t a; uint8_t b; oseq seq;}[])
|
||||
{ {0x10, 0x11, { 3, (unsigned char *)(struct{uint8_t a;}[]){ {'a'}, {'b'}, {'c'}}}},
|
||||
{0x21, 0x22, { 2, (unsigned char *)(struct{uint8_t a;}[]){ {'o'}, {'p'}}}}
|
||||
},
|
||||
}, 0x42 },
|
||||
31,
|
||||
(raw){1, /* pad */0,0,0, SER32(2),
|
||||
0x10, 0x11, /* pad */0,0, SER32(3), 'a','b','c',
|
||||
0x21, 0x22, /* pad */0,0,0, SER32(2), 'o','p',
|
||||
0x42}
|
||||
},
|
||||
{ {Xb,XQ,XbPROP,XS,Xo,XSTOP,XSTOP},
|
||||
&(struct{char b; oseq seq;}){1, {5, (unsigned char *)(struct{char b;char *s;uint8_t o;}[]){
|
||||
{0,"apple",1}, {1,"orange",2}, {0,"cherry",3}, {1,"fig",4}, {1,"prune",5}}}},
|
||||
|
@ -240,7 +263,8 @@ struct desc_invalid descs_invalid[] = {
|
|||
SER32(7), 'o','r','a','n','g','e',0, 2,
|
||||
SER32(4), 'f','i','g',0, 4, 0,0,0,
|
||||
SER32(7), 'p','r','u','n','e',0, 5 // string not terminated
|
||||
} }
|
||||
} },
|
||||
{ {XQ,XQ,Xu,XSTOP,XSTOP}, 16, (raw){SER32(2),SER32(1),SER32(31415),SER32(3)} } // nested sequence failure
|
||||
};
|
||||
|
||||
CU_Test (ddsi_plist_generic, invalid_input)
|
||||
|
|
328
src/core/ddsi/tests/security_msg.c
Normal file
328
src/core/ddsi/tests/security_msg.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright(c) 2019 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 "CUnit/Theory.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsi/ddsi_security_msg.h"
|
||||
#include "mem_ser.h"
|
||||
|
||||
static nn_participant_generic_message_t test_msg_in =
|
||||
{
|
||||
.message_identity = { {{.u={1,2,3}},{4}}, 5 },
|
||||
.related_message_identity = { {{.u={5,4,3}},{2}}, 1 },
|
||||
.destinaton_participant_guid = { {.u={2,3,4}},{5} },
|
||||
.destination_endpoint_guid = { {.u={3,4,5}},{6} },
|
||||
.source_endpoint_guid = { {.u={4,5,6}},{7} },
|
||||
.message_class_id = "testing message",
|
||||
.message_data = {
|
||||
.n = 4,
|
||||
.tags = (nn_dataholder_t[]) {
|
||||
{
|
||||
.class_id = "holder0",
|
||||
.properties = {
|
||||
.n = 3,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder0::prop0name",
|
||||
.value = "holder0::prop0value",
|
||||
},
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder0::prop1name",
|
||||
.value = "holder0::prop1value",
|
||||
},
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder0::prop2name",
|
||||
.value = "holder0::prop2value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 1,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder0::bprop0name",
|
||||
.value = { 2, (unsigned char[]){ 1, 2 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder1",
|
||||
.properties = {
|
||||
.n = 1,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder1::prop0name",
|
||||
.value = "holder1::prop0value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 1,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder1::bprop0name",
|
||||
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder2",
|
||||
.properties = {
|
||||
.n = 1,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder2::prop0name",
|
||||
.value = "holder2::prop0value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 3,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder2::bprop0name",
|
||||
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
|
||||
},
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder2::bprop1name",
|
||||
.value = { 4, (unsigned char[]){ 1, 2, 3, 4 } },
|
||||
},
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder2::bprop2name",
|
||||
.value = { 5, (unsigned char[]){ 1, 2, 3, 4, 5 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder3",
|
||||
.properties = {
|
||||
.n = 1,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder3::prop0name",
|
||||
.value = "holder3::prop0value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 1,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = false,
|
||||
.name = "holder3::bprop0name",
|
||||
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* Same as test_msg_in, excluding the non-propagated properties. */
|
||||
static nn_participant_generic_message_t test_msg_out =
|
||||
{
|
||||
.message_identity = { {{.u={1,2,3}},{4}}, 5 },
|
||||
.related_message_identity = { {{.u={5,4,3}},{2}}, 1 },
|
||||
.destinaton_participant_guid = { {.u={2,3,4}},{5} },
|
||||
.destination_endpoint_guid = { {.u={3,4,5}},{6} },
|
||||
.source_endpoint_guid = { {.u={4,5,6}},{7} },
|
||||
.message_class_id = "testing message",
|
||||
.message_data = {
|
||||
.n = 4,
|
||||
.tags = (nn_dataholder_t[]) {
|
||||
{
|
||||
.class_id = "holder0",
|
||||
.properties = {
|
||||
.n = 1,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder0::prop1name",
|
||||
.value = "holder0::prop1value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 0,
|
||||
.props = NULL
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder1",
|
||||
.properties = {
|
||||
.n = 1,
|
||||
.props = (dds_property_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder1::prop0name",
|
||||
.value = "holder1::prop0value",
|
||||
},
|
||||
}
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 1,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder1::bprop0name",
|
||||
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder2",
|
||||
.properties = {
|
||||
.n = 0,
|
||||
.props = NULL,
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 2,
|
||||
.props = (dds_binaryproperty_t[]) {
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder2::bprop0name",
|
||||
.value = { 3, (unsigned char[]){ 1, 2, 3 } },
|
||||
},
|
||||
{
|
||||
.propagate = true,
|
||||
.name = "holder2::bprop2name",
|
||||
.value = { 5, (unsigned char[]){ 1, 2, 3, 4, 5 } },
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.class_id = "holder3",
|
||||
.properties = {
|
||||
.n = 0,
|
||||
.props = NULL,
|
||||
},
|
||||
.binary_properties = {
|
||||
.n = 0,
|
||||
.props = NULL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* The cdr of test_msg_out. */
|
||||
static unsigned char test_msg_ser[] = {
|
||||
SER32BE(1), SER32BE(2), SER32BE(3), SER32BE(4), SER64(5),
|
||||
SER32BE(5), SER32BE(4), SER32BE(3), SER32BE(2), SER64(1),
|
||||
SER32BE(2), SER32BE(3), SER32BE(4), SER32BE(5),
|
||||
SER32BE(3), SER32BE(4), SER32BE(5), SER32BE(6),
|
||||
SER32BE(4), SER32BE(5), SER32BE(6), SER32BE(7),
|
||||
SER32(16), 't','e','s','t','i','n','g',' ','m','e','s','s','a','g','e',0,
|
||||
SER32(4),
|
||||
/* dataholder 0 */
|
||||
SER32(8), 'h','o','l','d','e','r','0',0,
|
||||
SER32(1),
|
||||
SER32(19), 'h','o','l','d','e','r','0',':',':','p','r','o','p','1','n','a','m','e',0,/* pad */0,
|
||||
SER32(20), 'h','o','l','d','e','r','0',':',':','p','r','o','p','1','v','a','l','u','e',0,
|
||||
SER32(0),
|
||||
/* dataholder 1 */
|
||||
SER32(8), 'h','o','l','d','e','r','1',0,
|
||||
SER32(1),
|
||||
SER32(19), 'h','o','l','d','e','r','1',':',':','p','r','o','p','0','n','a','m','e',0,/* pad */0,
|
||||
SER32(20), 'h','o','l','d','e','r','1',':',':','p','r','o','p','0','v','a','l','u','e',0,
|
||||
SER32(1),
|
||||
SER32(20), 'h','o','l','d','e','r','1',':',':','b','p','r','o','p','0','n','a','m','e',0,
|
||||
SER32(3), 1,2,3, /* pad */0,
|
||||
/* dataholder 2 */
|
||||
SER32(8), 'h','o','l','d','e','r','2',0,
|
||||
SER32(0),
|
||||
SER32(2),
|
||||
SER32(20), 'h','o','l','d','e','r','2',':',':','b','p','r','o','p','0','n','a','m','e',0,
|
||||
SER32(3), 1,2,3, /* pad */0,
|
||||
SER32(20), 'h','o','l','d','e','r','2',':',':','b','p','r','o','p','2','n','a','m','e',0,
|
||||
SER32(5), 1,2,3,4,5, /* pad */0,0,0,
|
||||
/* dataholder 2 */
|
||||
SER32(8), 'h','o','l','d','e','r','3',0,
|
||||
SER32(0),
|
||||
SER32(0)
|
||||
};
|
||||
|
||||
CU_Test (ddsi_security_msg, serializer)
|
||||
{
|
||||
nn_participant_generic_message_t msg_in;
|
||||
nn_participant_generic_message_t msg_ser;
|
||||
unsigned char *data = NULL;
|
||||
dds_return_t ret;
|
||||
size_t len;
|
||||
bool equal;
|
||||
|
||||
/* Create the message (normally with various arguments). */
|
||||
nn_participant_generic_message_init(
|
||||
&msg_in,
|
||||
&test_msg_in.message_identity.source_guid,
|
||||
test_msg_in.message_identity.sequence_number,
|
||||
&test_msg_in.destinaton_participant_guid,
|
||||
&test_msg_in.destination_endpoint_guid,
|
||||
&test_msg_in.source_endpoint_guid,
|
||||
test_msg_in.message_class_id,
|
||||
&test_msg_in.message_data,
|
||||
&test_msg_in.related_message_identity);
|
||||
|
||||
/* Check creation result. */
|
||||
equal = plist_equal_generic(&msg_in, &test_msg_in, pserop_participant_generic_message);
|
||||
CU_ASSERT_FATAL(equal == true);
|
||||
|
||||
/* Serialize the message. */
|
||||
ret = nn_participant_generic_message_serialize(&msg_in, &data, &len);
|
||||
CU_ASSERT_FATAL (ret == DDS_RETCODE_OK);
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(data);
|
||||
CU_ASSERT(len > 0);
|
||||
|
||||
/* Check serialization result. */
|
||||
size_t cmpsize = (len < sizeof(test_msg_ser)) ? len : sizeof(test_msg_ser);
|
||||
if (memcmp (data, test_msg_ser, cmpsize) != 0)
|
||||
{
|
||||
printf ("memcmp(%d)\n", (int)cmpsize);
|
||||
for (size_t k = 0; k < cmpsize; k++)
|
||||
printf (" %3zu %02x %02x (%c) %s\n", k, data[k], test_msg_ser[k],
|
||||
((test_msg_ser[k] >= '0') && (test_msg_ser[k] <= 'z')) ? test_msg_ser[k] : ' ',
|
||||
(data[k] == test_msg_ser[k]) ? "" : "<--");
|
||||
CU_ASSERT (!(bool)"memcmp");
|
||||
}
|
||||
CU_ASSERT_FATAL (len == sizeof(test_msg_ser));
|
||||
|
||||
/* Deserialize the message. */
|
||||
ret = nn_participant_generic_message_deseralize(&msg_ser, data, len, false);
|
||||
CU_ASSERT_FATAL (ret == DDS_RETCODE_OK);
|
||||
|
||||
/* Check deserialization result. */
|
||||
equal = plist_equal_generic(&msg_ser, &test_msg_out, pserop_participant_generic_message);
|
||||
CU_ASSERT_FATAL(equal == true);
|
||||
|
||||
/* Cleanup. */
|
||||
nn_participant_generic_message_deinit(&msg_in);
|
||||
nn_participant_generic_message_deinit(&msg_ser);
|
||||
ddsrt_free(data);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue