Merge pull request #527 from eclipse-cyclonedds/security
Merge security into master
This commit is contained in:
commit
3030a81528
454 changed files with 101361 additions and 3771 deletions
|
@ -16,6 +16,69 @@ if(NOT ${PROJECT_NAME} STREQUAL "CycloneDDS")
|
|||
message(FATAL_ERROR "Top-level CMakeLists.txt was moved to the top-level directory. Please run cmake on ${dir} instead of ${CMAKE_CURRENT_LIST_DIR}")
|
||||
endif()
|
||||
|
||||
# Generate a header file listing compile-time options relevant to the API. Define to
|
||||
# "1" if enabled so that the generated features.h ends up having either
|
||||
#
|
||||
# - #define DDS_HAS_SECURITY 1
|
||||
# or
|
||||
# - /* #undef DDS_HAS_SECURITY */
|
||||
#
|
||||
# which caters both for those who prefer #ifdef DDS_HAS_SECURITY and for those who prefer
|
||||
# #if DDS_HAS_SECURITY.
|
||||
if(ENABLE_SECURITY)
|
||||
set(DDS_HAS_SECURITY "1")
|
||||
endif()
|
||||
if(ENABLE_LIFESPAN)
|
||||
set(DDS_HAS_LIFESPAN "1")
|
||||
endif()
|
||||
if(ENABLE_DEADLINE_MISSED)
|
||||
set(DDS_HAS_DEADLINE_MISSED "1")
|
||||
endif()
|
||||
configure_file(features.h.in "${CMAKE_CURRENT_BINARY_DIR}/core/include/dds/features.h")
|
||||
|
||||
add_definitions(-DDDSI_INCLUDE_NETWORK_PARTITIONS -DDDSI_INCLUDE_SSM)
|
||||
|
||||
# OpenSSL is huge, raising the RSS by 1MB or so, and moreover find_package(OpenSSL) causes
|
||||
# trouble on some older CMake versions that otherwise work fine, so provide an option to avoid
|
||||
# all OpenSSL related things.
|
||||
#
|
||||
# Historically the option was DDSC_ENABLE_OPENSSL so make some allowance for those who are
|
||||
# currently relying on it.
|
||||
option(ENABLE_SSL "Enable openssl support" ON)
|
||||
option(DDSC_ENABLE_OPENSSL "Deprecated: please use ENABLE_SSL instead" ON)
|
||||
if(NOT DDSC_ENABLE_OPENSSL)
|
||||
message(ERROR "DDSC_ENABLE_OPENSSL is deprecated, please use ENABLE_SSL instead")
|
||||
set(ENABLE_SSL OFF)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SSL)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
add_definitions(-DDDSI_INCLUDE_SSL)
|
||||
message(STATUS "Building with OpenSSL support")
|
||||
else()
|
||||
message(STATUS "Building without OpenSSL support")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Support the OMG DDS Security within ddsc adds quite a bit of code.
|
||||
option(ENABLE_SECURITY "Enable OMG DDS Security support" ON)
|
||||
if(NOT ENABLE_SECURITY)
|
||||
message(STATUS "Building without OMG DDS Security support")
|
||||
else()
|
||||
add_definitions(-DDDSI_INCLUDE_SECURITY)
|
||||
endif()
|
||||
|
||||
option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON)
|
||||
if(ENABLE_LIFESPAN)
|
||||
add_definitions(-DDDSI_INCLUDE_LIFESPAN)
|
||||
endif()
|
||||
|
||||
option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON)
|
||||
if(ENABLE_DEADLINE_MISSED)
|
||||
add_definitions(-DDDSI_INCLUDE_DEADLINE_MISSED)
|
||||
endif()
|
||||
|
||||
add_subdirectory(ddsrt)
|
||||
|
||||
# some of the tests in the core rely on preprocessing IDL, so idlc has to
|
||||
|
@ -23,6 +86,7 @@ add_subdirectory(ddsrt)
|
|||
if(BUILD_IDLC)
|
||||
add_subdirectory(idlc)
|
||||
endif()
|
||||
add_subdirectory(security)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(tools)
|
||||
if(BUILD_TESTING AND HAVE_MULTI_PROCESS AND BUILD_IDLC)
|
||||
|
|
|
@ -25,44 +25,21 @@ else()
|
|||
add_library(ddsc)
|
||||
endif()
|
||||
|
||||
add_definitions(-DDDSI_INCLUDE_NETWORK_PARTITIONS -DDDSI_INCLUDE_SSM)
|
||||
|
||||
option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON)
|
||||
if(ENABLE_LIFESPAN)
|
||||
add_definitions(-DDDSI_INCLUDE_LIFESPAN)
|
||||
endif()
|
||||
|
||||
option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON)
|
||||
if(ENABLE_DEADLINE_MISSED)
|
||||
add_definitions(-DDDSI_INCLUDE_DEADLINE_MISSED)
|
||||
endif()
|
||||
|
||||
# OpenSSL is huge, raising the RSS by 1MB or so, and moreover find_package(OpenSSL) causes
|
||||
# trouble on some older CMake versions that otherwise work fine, so provide an option to avoid
|
||||
# all OpenSSL related things.
|
||||
#
|
||||
# Historically the option was DDSC_ENABLE_OPENSSL so make some allowance for those who are
|
||||
# currently relying on it.
|
||||
option(ENABLE_SSL "Enable openssl support" ON)
|
||||
option(DDSC_ENABLE_OPENSSL "Deprecated: please use ENABLE_SSL instead" ON)
|
||||
if(NOT DDSC_ENABLE_OPENSSL)
|
||||
message(ERROR "DDSC_ENABLE_OPENSSL is deprecated, please use ENABLE_SSL instead")
|
||||
set(ENABLE_SSL OFF)
|
||||
endif()
|
||||
if(ENABLE_SSL)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
add_definitions(-DDDSI_INCLUDE_SSL)
|
||||
target_link_libraries(ddsc PRIVATE OpenSSL::SSL)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set_target_properties(ddsc PROPERTIES LINK_FLAGS "/ignore:4099")
|
||||
endif()
|
||||
message(STATUS "Building with OpenSSL support")
|
||||
else()
|
||||
message(STATUS "Building without OpenSSL support")
|
||||
if(ENABLE_SSL AND OPENSSL_FOUND)
|
||||
target_link_libraries(ddsc PRIVATE OpenSSL::SSL)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set_target_properties(ddsc PROPERTIES LINK_FLAGS "/ignore:4099")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Support the OMG DDS Security within ddsc adds quite a bit of code.
|
||||
if(ENABLE_SECURITY)
|
||||
target_link_libraries(ddsc PRIVATE security_core)
|
||||
target_include_directories(
|
||||
ddsc PUBLIC
|
||||
$<BUILD_INTERFACE:$<TARGET_PROPERTY:security_api,INTERFACE_INCLUDE_DIRECTORIES>>)
|
||||
endif()
|
||||
|
||||
include(ddsi/CMakeLists.txt)
|
||||
include(ddsc/CMakeLists.txt)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#endif
|
||||
|
||||
#include "dds/export.h"
|
||||
#include "dds/features.h"
|
||||
|
||||
/**
|
||||
* Handle to an entity. A valid entity handle will always have a positive
|
||||
|
@ -89,6 +90,7 @@ typedef enum dds_status_id {
|
|||
DDS_PUBLICATION_MATCHED_STATUS_ID,
|
||||
DDS_SUBSCRIPTION_MATCHED_STATUS_ID
|
||||
} dds_status_id_t;
|
||||
#define DDS_STATUS_ID_MAX (DDS_SUBSCRIPTION_MATCHED_STATUS_ID)
|
||||
|
||||
/** Another topic exists with the same name but with different characteristics. */
|
||||
#define DDS_INCONSISTENT_TOPIC_STATUS (1u << DDS_INCONSISTENT_TOPIC_STATUS_ID)
|
||||
|
@ -762,8 +764,22 @@ dds_set_listener(dds_entity_t entity, const dds_listener_t * listener);
|
|||
*
|
||||
* @retval >0
|
||||
* A valid participant handle.
|
||||
* @retval DDS_RETCODE_NOT_ALLOWED_BY_SECURITY
|
||||
* An invalid DDS Security configuration was specified (whether
|
||||
* that be missing or incorrect entries, expired certificates,
|
||||
* or anything else related to the security settings and
|
||||
* implementation).
|
||||
* @retval DDS_RETCODE_PRECONDITION_NOT_MET
|
||||
* Some security properties specified in the QoS, but the Cyclone
|
||||
* build does not include support for DDS Security.
|
||||
* @retval DDS_RETCODE_OUT_OF_RESOURCES
|
||||
* Some resource limit (maximum participants, memory, handles,
|
||||
* &c.) prevented creation of the participant.
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* The "CYCLONEDDS_URI" environment variable lists non-existent
|
||||
* or invalid configuration files, or contains invalid embedded
|
||||
* configuration items; or an unspecified internal error has
|
||||
* occurred.
|
||||
*/
|
||||
DDS_EXPORT dds_entity_t
|
||||
dds_create_participant(
|
||||
|
@ -2741,6 +2757,53 @@ dds_take_mask_wl(
|
|||
uint32_t maxs,
|
||||
uint32_t mask);
|
||||
|
||||
#define DDS_HAS_READCDR 1
|
||||
/**
|
||||
* @brief Access the collection of serialized data values (of same type) and
|
||||
* sample info from the data reader, readcondition or querycondition.
|
||||
*
|
||||
* This call accesses the serialized data from the data reader, readcondition or
|
||||
* querycondition and makes it available to the application. The serialized data
|
||||
* is made available through \ref ddsi_serdata structures. Returned samples are
|
||||
* marked as READ.
|
||||
*
|
||||
* Return value provides information about the number of samples read, which will
|
||||
* be <= maxs. Based on the count, the buffer will contain serialized data to be
|
||||
* read only when valid_data bit in sample info structure is set.
|
||||
* The buffer required for data values, could be allocated explicitly or can
|
||||
* use the memory from data reader to prevent copy. In the latter case, buffer and
|
||||
* sample_info should be returned back, once it is no longer using the data.
|
||||
*
|
||||
* @param[in] reader_or_condition Reader, readcondition or querycondition entity.
|
||||
* @param[out] buf An array of pointers to \ref ddsi_serdata structures that contain
|
||||
* the serialized data. The pointers can be NULL.
|
||||
* @param[in] maxs Maximum number of samples to read.
|
||||
* @param[out] si Pointer to an array of \ref dds_sample_info_t returned for each data value.
|
||||
* @param[in] mask Filter the data based on dds_sample_state_t|dds_view_state_t|dds_instance_state_t.
|
||||
*
|
||||
* @returns A dds_return_t with the number of samples read or an error code.
|
||||
*
|
||||
* @retval >=0
|
||||
* Number of samples read.
|
||||
* @retval DDS_RETCODE_ERROR
|
||||
* An internal error has occurred.
|
||||
* @retval DDS_RETCODE_BAD_PARAMETER
|
||||
* One of the given arguments is not valid.
|
||||
* @retval DDS_RETCODE_ILLEGAL_OPERATION
|
||||
* The operation is invoked on an inappropriate object.
|
||||
* @retval DDS_RETCODE_ALREADY_DELETED
|
||||
* The entity has already been deleted.
|
||||
* @retval DDS_RETCODE_PRECONDITION_NOT_MET
|
||||
* The precondition for this operation is not met.
|
||||
*/
|
||||
DDS_EXPORT dds_return_t
|
||||
dds_readcdr(
|
||||
dds_entity_t reader_or_condition,
|
||||
struct ddsi_serdata **buf,
|
||||
uint32_t maxs,
|
||||
dds_sample_info_t *si,
|
||||
uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Access the collection of serialized data values (of same type) and
|
||||
* sample info from the data reader, readcondition or querycondition.
|
||||
|
|
|
@ -225,6 +225,13 @@ enum dds_stream_typecode_subtype {
|
|||
#define DDS_OP_FLAG_KEY 0x01 /* key field: applicable to {1,2,4,8}BY, STR, BST, ARR-of-{1,2,4,8}BY */
|
||||
#define DDS_OP_FLAG_DEF 0x02 /* union has a default case (for DDS_OP_ADR | DDS_OP_TYPE_UNI) */
|
||||
|
||||
/* For a union: (1) the discriminator may be a key field; (2) there may be a default value;
|
||||
and (3) the discriminator can be an integral type (or enumerated - here treated as equivalent).
|
||||
What it can't be is a floating-point type. So DEF and FP need never be set at the same time.
|
||||
There are only a few flag bits, so saving one is not such a bad idea. */
|
||||
#define DDS_OP_FLAG_FP 0x02 /* floating-point: applicable to {4,8}BY and arrays, sequences of them */
|
||||
#define DDS_OP_FLAG_SGN 0x04 /* signed: applicable to {1,2,4,8}BY and arrays, sequences of them */
|
||||
|
||||
/**
|
||||
* Description : Enable or disable write batching. Overrides default configuration
|
||||
* setting for write batching (Internal/WriteBatch).
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
#include "dds/export.h"
|
||||
#include "dds/ddsc/dds_public_qosdefs.h"
|
||||
|
||||
/* Whether or not the "property list" QoS setting is supported in this version. If it is,
|
||||
the "dds.sec." properties are treated specially, preventing the accidental creation of
|
||||
an non-secure participant by an implementation built without support for DDS Security. */
|
||||
#define DDS_HAS_PROPERTY_LIST_QOS 1
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -381,6 +386,72 @@ dds_qset_ignorelocal (
|
|||
dds_qos_t * __restrict qos,
|
||||
dds_ignorelocal_kind_t ignore);
|
||||
|
||||
/**
|
||||
* @brief Stores a property with the provided name and string value in a qos structure.
|
||||
*
|
||||
* In the case a property with the provided name already exists in the qos structure,
|
||||
* the value for this entry is overwritten with the provided string value. If more than
|
||||
* one property with the provided name exists, only the value of the first of these
|
||||
* properties is updated.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the property
|
||||
* @param[in] name - Pointer to name of the property
|
||||
* @param[in] value - Pointer to a (null-terminated) string that will be stored
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
dds_qset_prop (
|
||||
dds_qos_t * __restrict qos,
|
||||
const char * name,
|
||||
const char * value);
|
||||
|
||||
/**
|
||||
* @brief Removes the property with the provided name from a qos structure.
|
||||
*
|
||||
* In case more than one property exists with this name, only the first property
|
||||
* is removed.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains the property
|
||||
* @param[in] name - Pointer to name of the property
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
dds_qunset_prop (
|
||||
dds_qos_t * __restrict qos,
|
||||
const char * name);
|
||||
|
||||
/**
|
||||
* @brief Stores the provided binary data as a property in a qos structure
|
||||
*
|
||||
* In the case a property with the provided name already exists in the qos structure,
|
||||
* the value for this entry is overwritten with the provided data. If more than one
|
||||
* property with the provided name exists, only the value of the first of these
|
||||
* properties is updated.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that will store the property
|
||||
* @param[in] name - Pointer to name of the property
|
||||
* @param[in] value - Pointer to data to be stored in the property
|
||||
* @param[in] sz - Size of the data
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
dds_qset_bprop (
|
||||
dds_qos_t * __restrict qos,
|
||||
const char * name,
|
||||
const void * value,
|
||||
const size_t sz);
|
||||
|
||||
/**
|
||||
* @brief Removes the binary property with the provided name from a qos structure.
|
||||
*
|
||||
* In case more than one binary property exists with this name, only the first binary
|
||||
* property is removed.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains the binary property
|
||||
* @param[in] name - Pointer to name of the property
|
||||
*/
|
||||
DDS_EXPORT void
|
||||
dds_qunset_bprop (
|
||||
dds_qos_t * __restrict qos,
|
||||
const char * name);
|
||||
|
||||
/**
|
||||
* @brief Get the userdata from a qos structure
|
||||
*
|
||||
|
@ -682,6 +753,74 @@ dds_qget_ignorelocal (
|
|||
const dds_qos_t * __restrict qos,
|
||||
dds_ignorelocal_kind_t *ignore);
|
||||
|
||||
/**
|
||||
* @brief Gets the names of the properties from a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains properties
|
||||
* @param[in,out] n - Pointer to number of property names that are returned (optional)
|
||||
* @param[in,out] names - Pointer that will store the string(s) containing property name(s) (optional). This function will allocate the memory for the list of names and for the strings containing the names; the caller gets ownership of the allocated memory
|
||||
*
|
||||
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
|
||||
*/
|
||||
DDS_EXPORT bool
|
||||
dds_qget_propnames (
|
||||
const dds_qos_t * __restrict qos,
|
||||
uint32_t * n,
|
||||
char *** names);
|
||||
|
||||
/**
|
||||
* @brief Get the value of the property with the provided name from a qos structure.
|
||||
*
|
||||
* In case more than one property exists with this name, the value for the first
|
||||
* property with this name will be returned.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains the property
|
||||
* @param[in] name - Pointer to name of the property
|
||||
* @param[in,out] value - Pointer to a string that will store the value of the property. The memory for storing the string value will be allocated by this function and the caller gets ownership of the allocated memory
|
||||
*
|
||||
* @returns - false iff any of the arguments is invalid, the qos is not present in the qos object or there was no property found with the provided name
|
||||
*/
|
||||
DDS_EXPORT bool
|
||||
dds_qget_prop (
|
||||
const dds_qos_t * __restrict qos,
|
||||
const char * name,
|
||||
char ** value);
|
||||
|
||||
/**
|
||||
* @brief Gets the names of the binary properties from a qos structure.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains binary properties
|
||||
* @param[in,out] n - Pointer to number of binary property names that are returned (optional)
|
||||
* @param[in,out] names - Pointer that will store the string(s) containing binary property name(s) (optional). This function will allocate the memory for the list of names and for the strings containing the names; the caller gets ownership of the allocated memory
|
||||
*
|
||||
* @returns - false iff any of the arguments is invalid or the qos is not present in the qos object
|
||||
*/
|
||||
DDS_EXPORT bool
|
||||
dds_qget_bpropnames (
|
||||
const dds_qos_t * __restrict qos,
|
||||
uint32_t * n,
|
||||
char *** names);
|
||||
|
||||
/**
|
||||
* @brief Get the value of the binary property with the provided name from a qos structure.
|
||||
*
|
||||
* In case more than one binary property exists with this name, the value for the first
|
||||
* binary property with this name will be returned.
|
||||
*
|
||||
* @param[in,out] qos - Pointer to a dds_qos_t structure that contains the property
|
||||
* @param[in] name - Pointer to name of the binary property
|
||||
* @param[in,out] value - Pointer to a buffer that will store the value of the property. If sz = 0 then a NULL pointer. The memory for storing the value will be allocated by this function and the caller gets ownership of the allocated memory
|
||||
* @param[in,out] sz - Pointer that will store the size of the returned buffer.
|
||||
*
|
||||
* @returns - false iff any of the arguments is invalid, the qos is not present in the qos object or there was no binary property found with the provided name
|
||||
*/
|
||||
DDS_EXPORT bool
|
||||
dds_qget_bprop (
|
||||
const dds_qos_t * __restrict qos,
|
||||
const char * name,
|
||||
void ** value,
|
||||
size_t * sz);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -50,7 +50,8 @@ typedef enum dds_qos_policy_id {
|
|||
DDS_GROUPDATA_QOS_POLICY_ID,
|
||||
DDS_TRANSPORTPRIORITY_QOS_POLICY_ID,
|
||||
DDS_LIFESPAN_QOS_POLICY_ID,
|
||||
DDS_DURABILITYSERVICE_QOS_POLICY_ID
|
||||
DDS_DURABILITYSERVICE_QOS_POLICY_ID,
|
||||
DDS_PROPERTY_QOS_POLICY_ID,
|
||||
} dds_qos_policy_id_t;
|
||||
|
||||
/* QoS structure is opaque */
|
||||
|
|
|
@ -27,9 +27,8 @@ struct dds_reader;
|
|||
struct ddsi_tkmap;
|
||||
|
||||
typedef dds_return_t (*dds_rhc_associate_t) (struct dds_rhc *rhc, struct dds_reader *reader, const struct ddsi_sertopic *topic, struct ddsi_tkmap *tkmap);
|
||||
typedef int (*dds_rhc_read_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
|
||||
typedef int (*dds_rhc_take_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
|
||||
typedef int (*dds_rhc_takecdr_t) (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
|
||||
typedef int32_t (*dds_rhc_read_take_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
|
||||
typedef int32_t (*dds_rhc_read_take_cdr_t) (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
|
||||
|
||||
typedef bool (*dds_rhc_add_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond);
|
||||
typedef void (*dds_rhc_remove_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond);
|
||||
|
@ -40,9 +39,10 @@ struct dds_rhc_ops {
|
|||
/* A copy of DDSI rhc ops comes first so we can use either interface without
|
||||
additional indirections */
|
||||
struct ddsi_rhc_ops rhc_ops;
|
||||
dds_rhc_read_t read;
|
||||
dds_rhc_take_t take;
|
||||
dds_rhc_takecdr_t takecdr;
|
||||
dds_rhc_read_take_t read;
|
||||
dds_rhc_read_take_t take;
|
||||
dds_rhc_read_take_cdr_t readcdr;
|
||||
dds_rhc_read_take_cdr_t takecdr;
|
||||
dds_rhc_add_readcondition_t add_readcondition;
|
||||
dds_rhc_remove_readcondition_t remove_readcondition;
|
||||
dds_rhc_lock_samples_t lock_samples;
|
||||
|
@ -76,13 +76,16 @@ DDS_EXPORT inline void dds_rhc_set_qos (struct dds_rhc *rhc, const struct dds_qo
|
|||
DDS_EXPORT inline void dds_rhc_free (struct dds_rhc *rhc) {
|
||||
rhc->common.ops->rhc_ops.free (&rhc->common.rhc);
|
||||
}
|
||||
DDS_EXPORT inline int dds_rhc_read (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
|
||||
DDS_EXPORT inline int32_t dds_rhc_read (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
|
||||
return (rhc->common.ops->read) (rhc, lock, values, info_seq, max_samples, mask, handle, cond);
|
||||
}
|
||||
DDS_EXPORT inline int dds_rhc_take (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
|
||||
DDS_EXPORT inline int32_t dds_rhc_take (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
|
||||
return rhc->common.ops->take (rhc, lock, values, info_seq, max_samples, mask, handle, cond);
|
||||
}
|
||||
DDS_EXPORT inline int dds_rhc_takecdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) {
|
||||
DDS_EXPORT inline int32_t dds_rhc_readcdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) {
|
||||
return rhc->common.ops->readcdr (rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle);
|
||||
}
|
||||
DDS_EXPORT inline int32_t dds_rhc_takecdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) {
|
||||
return rhc->common.ops->takecdr (rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle);
|
||||
}
|
||||
DDS_EXPORT inline bool dds_rhc_add_readcondition (struct dds_rhc *rhc, struct dds_readcond *cond) {
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
QP_DESTINATION_ORDER | QP_HISTORY | QP_RESOURCE_LIMITS)
|
||||
|
||||
#define DDS_PARTICIPANT_QOS_MASK \
|
||||
(QP_USER_DATA | QP_ADLINK_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL)
|
||||
(QP_USER_DATA | QP_ADLINK_ENTITY_FACTORY | QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
|
||||
|
||||
#define DDS_PUBLISHER_QOS_MASK \
|
||||
(QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \
|
||||
|
@ -36,7 +36,7 @@ extern "C" {
|
|||
QP_OWNERSHIP | QP_LIVELINESS | QP_TIME_BASED_FILTER | \
|
||||
QP_RELIABILITY | QP_DESTINATION_ORDER | QP_HISTORY | \
|
||||
QP_RESOURCE_LIMITS | QP_ADLINK_READER_DATA_LIFECYCLE | \
|
||||
QP_CYCLONE_IGNORELOCAL)
|
||||
QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
|
||||
|
||||
#define DDS_SUBSCRIBER_QOS_MASK \
|
||||
(QP_PARTITION | QP_PRESENTATION | QP_GROUP_DATA | \
|
||||
|
@ -48,7 +48,7 @@ extern "C" {
|
|||
QP_LIVELINESS | QP_RELIABILITY | QP_TRANSPORT_PRIORITY | \
|
||||
QP_LIFESPAN | QP_DESTINATION_ORDER | QP_HISTORY | \
|
||||
QP_RESOURCE_LIMITS | QP_ADLINK_WRITER_DATA_LIFECYCLE | \
|
||||
QP_CYCLONE_IGNORELOCAL)
|
||||
QP_CYCLONE_IGNORELOCAL | QP_PROPERTY_LIST)
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ DDS_EXPORT void dds_topic_set_filter_with_ctx
|
|||
DDS_EXPORT dds_topic_intern_filter_fn dds_topic_get_filter_with_ctx
|
||||
(dds_entity_t topic);
|
||||
|
||||
DDS_EXPORT dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,7 @@ DEFINE_ENTITY_LOCK_UNLOCK(inline, dds_writer, DDS_KIND_WRITER)
|
|||
struct status_cb_data;
|
||||
|
||||
void dds_writer_status_cb (void *entity, const struct status_cb_data * data);
|
||||
dds_return_t dds__writer_wait_for_acks (struct dds_writer *wr, dds_time_t abstimeout);
|
||||
DDS_EXPORT dds_return_t dds__writer_wait_for_acks (struct dds_writer *wr, ddsi_guid_t *rdguid, dds_time_t abstimeout);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_thread.h"
|
||||
#include "dds/ddsi/q_config.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
#include "dds/ddsi/ddsi_domaingv.h"
|
||||
#include "dds/ddsi/ddsi_plist.h"
|
||||
#include "dds__init.h"
|
||||
|
@ -24,6 +25,7 @@
|
|||
#include "dds__builtin.h"
|
||||
#include "dds__entity.h"
|
||||
#include "dds__subscriber.h"
|
||||
#include "dds__topic.h"
|
||||
#include "dds__write.h"
|
||||
#include "dds__writer.h"
|
||||
#include "dds__whc_builtintopic.h"
|
||||
|
@ -76,7 +78,7 @@ dds_entity_t dds__get_builtin_topic (dds_entity_t entity, dds_entity_t topic)
|
|||
}
|
||||
|
||||
dds_qos_t *qos = dds__create_builtin_qos ();
|
||||
if ((tp = dds_create_topic_generic (par->m_entity.m_hdllink.hdl, &sertopic, qos, NULL, NULL)) > 0)
|
||||
if ((tp = dds_create_topic_impl (par->m_entity.m_hdllink.hdl, &sertopic, qos, NULL, NULL)) > 0)
|
||||
{
|
||||
/* keep ownership for built-in sertopics because there are re-used, lifetime for these
|
||||
sertopics is bound to domain */
|
||||
|
@ -180,10 +182,13 @@ static struct ddsi_tkmap_instance *dds__builtin_get_tkmap_entry (const struct dd
|
|||
struct dds_domain *domain = vdomain;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
struct ddsi_serdata *sd;
|
||||
struct nn_keyhash kh;
|
||||
memcpy (&kh, guid, sizeof (kh));
|
||||
/* any random builtin topic will do (provided it has a GUID for a key), because what matters is the "class" of the topic, not the actual topic; also, this is called early in the initialisation of the entity with this GUID, which simply causes serdata_from_keyhash to create a key-only serdata because the key lookup fails. */
|
||||
sd = ddsi_serdata_from_keyhash (domain->builtin_participant_topic, &kh);
|
||||
union { ddsi_guid_t guid; struct ddsi_keyhash keyhash; } x;
|
||||
x.guid = nn_hton_guid (*guid);
|
||||
/* any random builtin topic will do (provided it has a GUID for a key), because what matters is the "class"
|
||||
of the topic, not the actual topic; also, this is called early in the initialisation of the entity with
|
||||
this GUID, which simply causes serdata_from_keyhash to create a key-only serdata because the key lookup
|
||||
fails. */
|
||||
sd = ddsi_serdata_from_keyhash (domain->builtin_participant_topic, &x.keyhash);
|
||||
tk = ddsi_tkmap_find (domain->gv.m_tkmap, sd, true);
|
||||
ddsi_serdata_unref (sd);
|
||||
return tk;
|
||||
|
@ -195,7 +200,7 @@ struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, dd
|
|||
struct dds_domain *dom = e->gv->builtin_topic_interface->arg;
|
||||
struct ddsi_sertopic *topic = NULL;
|
||||
struct ddsi_serdata *serdata;
|
||||
struct nn_keyhash keyhash;
|
||||
union { ddsi_guid_t guid; struct ddsi_keyhash keyhash; } x;
|
||||
switch (e->kind)
|
||||
{
|
||||
case EK_PARTICIPANT:
|
||||
|
@ -212,8 +217,8 @@ struct ddsi_serdata *dds__builtin_make_sample (const struct entity_common *e, dd
|
|||
break;
|
||||
}
|
||||
assert (topic != NULL);
|
||||
memcpy (&keyhash, &e->guid, sizeof (keyhash));
|
||||
serdata = ddsi_serdata_from_keyhash (topic, &keyhash);
|
||||
x.guid = nn_hton_guid (e->guid);
|
||||
serdata = ddsi_serdata_from_keyhash (topic, &x.keyhash);
|
||||
serdata->timestamp = timestamp;
|
||||
serdata->statusinfo = alive ? 0 : NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER;
|
||||
return serdata;
|
||||
|
|
|
@ -90,8 +90,7 @@ void dds_listener_copy(dds_listener_t * __restrict dst, const dds_listener_t * _
|
|||
static bool dds_combine_listener_merge (uint32_t inherited, void (*dst)(void), void (*src)(void))
|
||||
{
|
||||
(void)inherited;
|
||||
(void)src;
|
||||
return dst == 0;
|
||||
return dst == 0 && src != 0;
|
||||
}
|
||||
|
||||
static bool dds_combine_listener_override_inherited (uint32_t inherited, void (*dst)(void), void (*src)(void))
|
||||
|
|
|
@ -144,8 +144,7 @@ static dds_builtintopic_endpoint_t *make_builtintopic_endpoint (const ddsi_guid_
|
|||
dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t writer, dds_instance_handle_t ih)
|
||||
{
|
||||
dds_writer *wr;
|
||||
dds_return_t rc;
|
||||
if ((rc = dds_writer_lock (writer, &wr)) != DDS_RETCODE_OK)
|
||||
if (dds_writer_lock (writer, &wr))
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
|
@ -187,8 +186,7 @@ dds_builtintopic_endpoint_t *dds_get_matched_subscription_data (dds_entity_t wri
|
|||
dds_builtintopic_endpoint_t *dds_get_matched_publication_data (dds_entity_t reader, dds_instance_handle_t ih)
|
||||
{
|
||||
dds_reader *rd;
|
||||
dds_return_t rc;
|
||||
if ((rc = dds_reader_lock (reader, &rd)) != DDS_RETCODE_OK)
|
||||
if (dds_reader_lock (reader, &rd))
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -96,7 +96,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
|
|||
dds_participant * pp;
|
||||
ddsi_plist_t plist;
|
||||
dds_qos_t *new_qos = NULL;
|
||||
char *config = "";
|
||||
const char *config = "";
|
||||
|
||||
/* Make sure DDS instance is initialized. */
|
||||
if ((ret = dds_init ()) < 0)
|
||||
|
|
|
@ -114,7 +114,7 @@ dds_return_t dds_wait_for_acks (dds_entity_t publisher_or_writer, dds_duration_t
|
|||
return DDS_RETCODE_UNSUPPORTED;
|
||||
|
||||
case DDS_KIND_WRITER:
|
||||
ret = dds__writer_wait_for_acks ((struct dds_writer *) p_or_w_ent, abstimeout);
|
||||
ret = dds__writer_wait_for_acks ((struct dds_writer *) p_or_w_ent, NULL, abstimeout);
|
||||
dds_entity_unpin (p_or_w_ent);
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -335,6 +335,112 @@ void dds_qset_ignorelocal (dds_qos_t * __restrict qos, dds_ignorelocal_kind_t ig
|
|||
qos->present |= QP_CYCLONE_IGNORELOCAL;
|
||||
}
|
||||
|
||||
static void dds_qprop_init (dds_qos_t * qos)
|
||||
{
|
||||
if (!(qos->present & QP_PROPERTY_LIST))
|
||||
{
|
||||
qos->property.value.n = 0;
|
||||
qos->property.value.props = NULL;
|
||||
qos->property.binary_value.n = 0;
|
||||
qos->property.binary_value.props = NULL;
|
||||
qos->present |= QP_PROPERTY_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
#define DDS_QPROP_GET_INDEX(prop_type_, prop_field_) \
|
||||
static bool dds_q##prop_type_##_get_index (const dds_qos_t * qos, const char * name, uint32_t * index) \
|
||||
{ \
|
||||
if (qos == NULL || name == NULL || index == NULL || !(qos->present & QP_PROPERTY_LIST)) \
|
||||
return false; \
|
||||
for (uint32_t i = 0; i < qos->property.prop_field_.n; i++) \
|
||||
{ \
|
||||
if (strcmp (qos->property.prop_field_.props[i].name, name) == 0) \
|
||||
{ \
|
||||
*index = i; \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
DDS_QPROP_GET_INDEX (prop, value)
|
||||
DDS_QPROP_GET_INDEX (bprop, binary_value)
|
||||
|
||||
#define DDS_QUNSET_PROP(prop_type_, prop_field_, value_field_) \
|
||||
void dds_qunset_##prop_type_ (dds_qos_t * __restrict qos, const char * name) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
if (qos == NULL || !(qos->present & QP_PROPERTY_LIST) || qos->property.prop_field_.n == 0 || name == NULL) \
|
||||
return; \
|
||||
if (dds_q##prop_type_##_get_index (qos, name, &i)) \
|
||||
{ \
|
||||
dds_free (qos->property.prop_field_.props[i].name); \
|
||||
dds_free (qos->property.prop_field_.props[i].value_field_); \
|
||||
if (qos->property.prop_field_.n > 1) \
|
||||
{ \
|
||||
if (i < (qos->property.prop_field_.n - 1)) \
|
||||
memmove (qos->property.prop_field_.props + i, qos->property.prop_field_.props + i + 1, \
|
||||
(qos->property.prop_field_.n - i - 1) * sizeof (*qos->property.prop_field_.props)); \
|
||||
qos->property.prop_field_.props = dds_realloc (qos->property.prop_field_.props, \
|
||||
(qos->property.prop_field_.n - 1) * sizeof (*qos->property.prop_field_.props)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dds_free (qos->property.prop_field_.props); \
|
||||
qos->property.prop_field_.props = NULL; \
|
||||
} \
|
||||
qos->property.prop_field_.n--; \
|
||||
} \
|
||||
}
|
||||
DDS_QUNSET_PROP (prop, value, value)
|
||||
DDS_QUNSET_PROP (bprop, binary_value, value.value)
|
||||
|
||||
void dds_qset_prop (dds_qos_t * __restrict qos, const char * name, const char * value)
|
||||
{
|
||||
uint32_t i;
|
||||
if (qos == NULL || name == NULL || value == NULL)
|
||||
return;
|
||||
|
||||
dds_qprop_init (qos);
|
||||
if (dds_qprop_get_index (qos, name, &i))
|
||||
{
|
||||
assert (&qos->property.value.props[i] != NULL); /* for Clang static analyzer */
|
||||
dds_free (qos->property.value.props[i].value);
|
||||
qos->property.value.props[i].value = dds_string_dup (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
qos->property.value.props = dds_realloc (qos->property.value.props,
|
||||
(qos->property.value.n + 1) * sizeof (*qos->property.value.props));
|
||||
qos->property.value.props[qos->property.value.n].propagate = 0;
|
||||
qos->property.value.props[qos->property.value.n].name = dds_string_dup (name);
|
||||
qos->property.value.props[qos->property.value.n].value = dds_string_dup (value);
|
||||
qos->property.value.n++;
|
||||
}
|
||||
}
|
||||
|
||||
void dds_qset_bprop (dds_qos_t * __restrict qos, const char * name, const void * value, const size_t sz)
|
||||
{
|
||||
uint32_t i;
|
||||
if (qos == NULL || name == NULL || (value == NULL && sz > 0))
|
||||
return;
|
||||
|
||||
dds_qprop_init (qos);
|
||||
if (dds_qbprop_get_index (qos, name, &i))
|
||||
{
|
||||
assert (&qos->property.binary_value.props[i].value != NULL); /* for Clang static analyzer */
|
||||
dds_qos_data_copy_in (&qos->property.binary_value.props[i].value, value, sz, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qos->property.binary_value.props = dds_realloc (qos->property.binary_value.props,
|
||||
(qos->property.binary_value.n + 1) * sizeof (*qos->property.binary_value.props));
|
||||
qos->property.binary_value.props[qos->property.binary_value.n].propagate = 0;
|
||||
qos->property.binary_value.props[qos->property.binary_value.n].name = dds_string_dup (name);
|
||||
dds_qos_data_copy_in (&qos->property.binary_value.props[qos->property.binary_value.n].value, value, sz, false);
|
||||
qos->property.binary_value.n++;
|
||||
}
|
||||
}
|
||||
|
||||
bool dds_qget_userdata (const dds_qos_t * __restrict qos, void **value, size_t *sz)
|
||||
{
|
||||
if (qos == NULL || !(qos->present & QP_USER_DATA))
|
||||
|
@ -565,3 +671,66 @@ bool dds_qget_ignorelocal (const dds_qos_t * __restrict qos, dds_ignorelocal_kin
|
|||
*ignore = qos->ignorelocal.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DDS_QGET_PROPNAMES(prop_type_, prop_field_) \
|
||||
bool dds_qget_##prop_type_##names (const dds_qos_t * __restrict qos, uint32_t * n, char *** names) \
|
||||
{ \
|
||||
bool props; \
|
||||
if (qos == NULL || (n == NULL && names == NULL)) \
|
||||
return false; \
|
||||
props = (qos->present & QP_PROPERTY_LIST) && qos->property.prop_field_.n > 0; \
|
||||
if (n != NULL) \
|
||||
*n = props ? qos->property.prop_field_.n : 0; \
|
||||
if (names != NULL) \
|
||||
{ \
|
||||
if (!props) \
|
||||
*names = NULL; \
|
||||
else \
|
||||
{ \
|
||||
*names = dds_alloc (sizeof (char *) * qos->property.prop_field_.n); \
|
||||
for (uint32_t i = 0; i < qos->property.prop_field_.n; i++) \
|
||||
(*names)[i] = dds_string_dup (qos->property.prop_field_.props[i].name); \
|
||||
} \
|
||||
} \
|
||||
return props; \
|
||||
}
|
||||
DDS_QGET_PROPNAMES (prop, value)
|
||||
DDS_QGET_PROPNAMES (bprop, binary_value)
|
||||
|
||||
bool dds_qget_prop (const dds_qos_t * __restrict qos, const char * name, char ** value)
|
||||
{
|
||||
uint32_t i;
|
||||
bool found;
|
||||
|
||||
if (qos == NULL || name == NULL)
|
||||
return false;
|
||||
|
||||
found = dds_qprop_get_index (qos, name, &i);
|
||||
if (value != NULL)
|
||||
*value = found ? dds_string_dup (qos->property.value.props[i].value) : NULL;
|
||||
return found;
|
||||
}
|
||||
|
||||
bool dds_qget_bprop (const dds_qos_t * __restrict qos, const char * name, void ** value, size_t * sz)
|
||||
{
|
||||
uint32_t i;
|
||||
bool found;
|
||||
|
||||
if (qos == NULL || name == NULL || (sz == NULL && value != NULL))
|
||||
return false;
|
||||
|
||||
found = dds_qbprop_get_index (qos, name, &i);
|
||||
if (found)
|
||||
{
|
||||
if (value != NULL || sz != NULL)
|
||||
dds_qos_data_copy_out (&qos->property.binary_value.props[i].value, value, sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value != NULL)
|
||||
*value = NULL;
|
||||
if (sz != NULL)
|
||||
*sz = 0;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
|
|||
#define NC_FREE_BUF 2u
|
||||
#define NC_RESET_BUF 4u
|
||||
|
||||
if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs)
|
||||
if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs || maxs > INT32_MAX)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
|
||||
|
@ -61,14 +61,6 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
|
|||
|
||||
thread_state_awake (ts1, &entity->m_domain->gv);
|
||||
|
||||
if (hand != DDS_HANDLE_NIL)
|
||||
{
|
||||
if (ddsi_tkmap_find_by_id (entity->m_domain->gv.m_tkmap, hand) == NULL) {
|
||||
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||
goto fail_awake_pinned;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate samples if not provided (assuming all or none provided) */
|
||||
if (buf[0] == NULL)
|
||||
{
|
||||
|
@ -142,8 +134,6 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
|
|||
#undef NC_FREE_BUF
|
||||
#undef NC_RESET_BUF
|
||||
|
||||
fail_awake_pinned:
|
||||
thread_state_asleep (ts1);
|
||||
fail_pinned:
|
||||
dds_entity_unpin (entity);
|
||||
fail:
|
||||
|
@ -157,12 +147,8 @@ static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_conditio
|
|||
struct dds_reader *rd;
|
||||
struct dds_entity *entity;
|
||||
|
||||
assert (take);
|
||||
assert (buf);
|
||||
assert (si);
|
||||
assert (hand == DDS_HANDLE_NIL);
|
||||
assert (maxs > 0);
|
||||
(void)take;
|
||||
if (buf == NULL || si == NULL || maxs == 0 || maxs > INT32_MAX)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
|
||||
return ret;
|
||||
|
@ -185,7 +171,11 @@ static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_conditio
|
|||
assert (dds_entity_kind (rd->m_entity.m_parent) == DDS_KIND_SUBSCRIBER);
|
||||
dds_entity_status_reset (rd->m_entity.m_parent, DDS_DATA_ON_READERS_STATUS);
|
||||
|
||||
ret = dds_rhc_takecdr (rd->m_rhc, lock, buf, si, maxs, mask & DDS_ANY_SAMPLE_STATE, mask & DDS_ANY_VIEW_STATE, mask & DDS_ANY_INSTANCE_STATE, hand);
|
||||
if (take)
|
||||
ret = dds_rhc_takecdr (rd->m_rhc, lock, buf, si, maxs, mask & DDS_ANY_SAMPLE_STATE, mask & DDS_ANY_VIEW_STATE, mask & DDS_ANY_INSTANCE_STATE, hand);
|
||||
else
|
||||
ret = dds_rhc_readcdr (rd->m_rhc, lock, buf, si, maxs, mask & DDS_ANY_SAMPLE_STATE, mask & DDS_ANY_VIEW_STATE, mask & DDS_ANY_INSTANCE_STATE, hand);
|
||||
|
||||
dds_entity_unpin (entity);
|
||||
thread_state_asleep (ts1);
|
||||
return ret;
|
||||
|
@ -239,6 +229,18 @@ dds_return_t dds_read_mask_wl (dds_entity_t rd_or_cnd, void **buf, dds_sample_in
|
|||
return dds_read_impl (false, rd_or_cnd, buf, maxs, maxs, si, mask, DDS_HANDLE_NIL, lock, false);
|
||||
}
|
||||
|
||||
dds_return_t dds_readcdr (dds_entity_t rd_or_cnd, struct ddsi_serdata **buf, uint32_t maxs, dds_sample_info_t *si, uint32_t mask)
|
||||
{
|
||||
bool lock = true;
|
||||
if (maxs == DDS_READ_WITHOUT_LOCK)
|
||||
{
|
||||
lock = false;
|
||||
/* FIXME: Fix the interface. */
|
||||
maxs = 100;
|
||||
}
|
||||
return dds_readcdr_impl (false, rd_or_cnd, buf, maxs, si, mask, DDS_HANDLE_NIL, lock);
|
||||
}
|
||||
|
||||
dds_return_t dds_read_instance (dds_entity_t rd_or_cnd, void **buf, dds_sample_info_t *si, size_t bufsz, uint32_t maxs, dds_instance_handle_t handle)
|
||||
{
|
||||
bool lock = true;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "dds__builtin.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
#include "dds/ddsi/ddsi_entity_index.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
|
||||
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_reader)
|
||||
|
||||
|
@ -430,6 +431,7 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
|
|||
|
||||
/* Merge qos from topic and subscriber, dds_copy_qos only fails when it is passed a null
|
||||
argument, but that isn't the case here */
|
||||
struct ddsi_domaingv *gv = &sub->m_entity.m_domain->gv;
|
||||
rqos = dds_create_qos ();
|
||||
if (qos)
|
||||
ddsi_xqos_mergein_missing (rqos, qos, DDS_READER_QOS_MASK);
|
||||
|
@ -437,25 +439,42 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
|
|||
ddsi_xqos_mergein_missing (rqos, sub->m_entity.m_qos, ~(uint64_t)0);
|
||||
if (tp->m_ktopic->qos)
|
||||
ddsi_xqos_mergein_missing (rqos, tp->m_ktopic->qos, ~(uint64_t)0);
|
||||
ddsi_xqos_mergein_missing (rqos, &sub->m_entity.m_domain->gv.default_xqos_rd, ~(uint64_t)0);
|
||||
ddsi_xqos_mergein_missing (rqos, &gv->default_xqos_rd, ~(uint64_t)0);
|
||||
|
||||
if ((rc = ddsi_xqos_valid (&sub->m_entity.m_domain->gv.logconfig, rqos)) < 0 ||
|
||||
(rc = validate_reader_qos(rqos)) != DDS_RETCODE_OK)
|
||||
{
|
||||
dds_delete_qos (rqos);
|
||||
if ((rc = ddsi_xqos_valid (&gv->logconfig, rqos)) < 0 || (rc = validate_reader_qos(rqos)) != DDS_RETCODE_OK)
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
/* Additional checks required for built-in topics: we don't want to
|
||||
run into a resource limit on a built-in topic, it is a needless
|
||||
complication */
|
||||
if (pseudo_topic && !dds__validate_builtin_reader_qos (tp->m_entity.m_domain, pseudo_topic, rqos))
|
||||
{
|
||||
dds_delete_qos (rqos);
|
||||
rc = DDS_RETCODE_INCONSISTENT_POLICY;
|
||||
goto err_bad_qos;
|
||||
}
|
||||
|
||||
thread_state_awake (lookup_thread_state (), gv);
|
||||
const struct ddsi_guid * ppguid = dds_entity_participant_guid (&sub->m_entity);
|
||||
struct participant * pp = entidx_lookup_participant_guid (gv->entity_index, ppguid);
|
||||
|
||||
/* When deleting a participant, the child handles (that include the subscriber)
|
||||
are removed before removing the DDSI participant. So at this point, within
|
||||
the subscriber lock, we can assert that the participant exists. */
|
||||
assert (pp != NULL);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/* Check if DDS Security is enabled */
|
||||
if (q_omg_participant_is_secure (pp))
|
||||
{
|
||||
/* ask to access control security plugin for create reader permissions */
|
||||
if (!q_omg_security_check_create_reader (pp, gv->config.domainId, tp->m_stopic->name, rqos))
|
||||
{
|
||||
rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
|
||||
goto err_not_allowed;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create reader and associated read cache (if not provided by caller) */
|
||||
struct dds_reader * const rd = dds_alloc (sizeof (*rd));
|
||||
const dds_entity_t reader = dds_entity_init (&rd->m_entity, &sub->m_entity, DDS_KIND_READER, false, rqos, listener, DDS_READER_STATUS_MASK);
|
||||
|
@ -474,8 +493,7 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
|
|||
it; and then invoke those listeners that are in the pending set */
|
||||
dds_entity_init_complete (&rd->m_entity);
|
||||
|
||||
thread_state_awake (lookup_thread_state (), &sub->m_entity.m_domain->gv);
|
||||
rc = new_reader (&rd->m_rd, &rd->m_entity.m_domain->gv, &rd->m_entity.m_guid, NULL, dds_entity_participant_guid (&sub->m_entity), tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
|
||||
rc = new_reader (&rd->m_rd, &rd->m_entity.m_guid, NULL, pp, tp->m_stopic, rqos, &rd->m_rhc->common.rhc, dds_reader_status_cb, rd);
|
||||
assert (rc == DDS_RETCODE_OK); /* FIXME: can be out-of-resources at the very least */
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
|
||||
|
@ -487,7 +505,12 @@ static dds_entity_t dds_create_reader_int (dds_entity_t participant_or_subscribe
|
|||
dds_subscriber_unlock (sub);
|
||||
return reader;
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
err_not_allowed:
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
#endif
|
||||
err_bad_qos:
|
||||
dds_delete_qos (rqos);
|
||||
dds_topic_allow_set_qos (tp);
|
||||
err_pp_mismatch:
|
||||
dds_topic_unpin (tp);
|
||||
|
@ -632,3 +655,4 @@ DDS_GET_STATUS (reader, sample_rejected, SAMPLE_REJECTED,
|
|||
DDS_GET_STATUS (reader, sample_lost, SAMPLE_LOST, total_count_change)
|
||||
DDS_GET_STATUS (reader, requested_deadline_missed, REQUESTED_DEADLINE_MISSED, total_count_change)
|
||||
DDS_GET_STATUS (reader, requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QOS, total_count_change)
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ extern inline void dds_rhc_set_qos (struct dds_rhc *rhc, const struct dds_qos *q
|
|||
extern inline void dds_rhc_free (struct dds_rhc *rhc);
|
||||
extern inline int dds_rhc_read (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
|
||||
extern inline int dds_rhc_take (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
|
||||
extern inline int dds_rhc_readcdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
|
||||
extern inline int dds_rhc_takecdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
|
||||
extern inline bool dds_rhc_add_readcondition (struct dds_rhc *rhc, struct dds_readcond *cond);
|
||||
extern inline void dds_rhc_remove_readcondition (struct dds_rhc *rhc, struct dds_readcond *cond);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -126,14 +126,16 @@ static void from_entity_pwr (struct ddsi_serdata_builtintopic *d, const struct p
|
|||
assert (d->xqos.present & QP_TYPE_NAME);
|
||||
}
|
||||
|
||||
static struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash)
|
||||
static struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi_sertopic *tpcmn, const ddsi_keyhash_t *keyhash)
|
||||
{
|
||||
/* FIXME: not quite elegant to manage the creation of a serdata for a built-in topic via this function, but I also find it quite unelegant to let from_sample read straight from the underlying internal entity, and to_sample convert to the external format ... I could claim the internal entity is the "serialised form", but that forces wrapping it in a fragchain in one way or another, which, though possible, is also a bit lacking in elegance. */
|
||||
const struct ddsi_sertopic_builtintopic *tp = (const struct ddsi_sertopic_builtintopic *)tpcmn;
|
||||
/* keyhash must in host format (which the GUIDs always are internally) */
|
||||
struct entity_common *entity = entidx_lookup_guid_untyped (tp->c.gv->entity_index, (const ddsi_guid_t *) keyhash->value);
|
||||
struct ddsi_serdata_builtintopic *d = serdata_builtin_new(tp, entity ? SDK_DATA : SDK_KEY);
|
||||
memcpy (&d->key, keyhash->value, sizeof (d->key));
|
||||
union { ddsi_guid_t guid; ddsi_keyhash_t keyhash; } x;
|
||||
x.keyhash = *keyhash;
|
||||
x.guid = nn_ntoh_guid (x.guid);
|
||||
struct entity_common *entity = entidx_lookup_guid_untyped (tp->c.gv->entity_index, &x.guid);
|
||||
struct ddsi_serdata_builtintopic *d = serdata_builtin_new (tp, entity ? SDK_DATA : SDK_KEY);
|
||||
d->key = x.guid;
|
||||
if (entity)
|
||||
{
|
||||
ddsrt_mutex_lock (&entity->qos_lock);
|
||||
|
@ -169,6 +171,41 @@ static struct ddsi_serdata *ddsi_serdata_builtin_from_keyhash (const struct ddsi
|
|||
return fix_serdata_builtin(d, tp->c.serdata_basehash);
|
||||
}
|
||||
|
||||
static struct ddsi_serdata *ddsi_serdata_builtin_from_sample (const struct ddsi_sertopic *tpcmn, enum ddsi_serdata_kind kind, const void *sample)
|
||||
{
|
||||
const struct ddsi_sertopic_builtintopic *tp = (const struct ddsi_sertopic_builtintopic *)tpcmn;
|
||||
union {
|
||||
dds_guid_t extguid;
|
||||
ddsi_keyhash_t keyhash;
|
||||
} x;
|
||||
|
||||
/* no-one should be trying to convert user-provided data into a built-in topic sample, but converting
|
||||
a key is something that can be necessary, e.g., dds_lookup_instance depends on it */
|
||||
if (kind != SDK_KEY)
|
||||
return NULL;
|
||||
|
||||
/* memset x (even though it is entirely superfluous) so we can leave out a default case from the
|
||||
switch (ensuring at least some compilers will warn when more types are added) without getting
|
||||
warnings from any compiler */
|
||||
memset (&x, 0, sizeof (x));
|
||||
switch (tp->type)
|
||||
{
|
||||
case DSBT_PARTICIPANT: {
|
||||
const dds_builtintopic_participant_t *s = sample;
|
||||
x.extguid = s->key;
|
||||
break;
|
||||
}
|
||||
case DSBT_READER:
|
||||
case DSBT_WRITER: {
|
||||
const dds_builtintopic_endpoint_t *s = sample;
|
||||
x.extguid = s->key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ddsi_serdata_from_keyhash (tpcmn, &x.keyhash);
|
||||
}
|
||||
|
||||
static struct ddsi_serdata *serdata_builtin_to_topicless (const struct ddsi_serdata *serdata_common)
|
||||
{
|
||||
/* All built-in ones are currently topicless */
|
||||
|
@ -289,12 +326,13 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = {
|
|||
.from_ser = 0,
|
||||
.from_ser_iov = 0,
|
||||
.from_keyhash = ddsi_serdata_builtin_from_keyhash,
|
||||
.from_sample = 0,
|
||||
.from_sample = ddsi_serdata_builtin_from_sample,
|
||||
.to_ser = serdata_builtin_to_ser,
|
||||
.to_sample = serdata_builtin_to_sample,
|
||||
.to_ser_ref = serdata_builtin_to_ser_ref,
|
||||
.to_ser_unref = serdata_builtin_to_ser_unref,
|
||||
.to_topicless = serdata_builtin_to_topicless,
|
||||
.topicless_to_sample = serdata_builtin_topicless_to_sample,
|
||||
.print = serdata_builtin_topic_print
|
||||
.print = serdata_builtin_topic_print,
|
||||
.get_keyhash = 0
|
||||
};
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "dds/ddsi/ddsi_plist.h"
|
||||
#include "dds/ddsi/ddsi_domaingv.h"
|
||||
#include "dds/ddsi/ddsi_cdrstream.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
#include "dds__serdata_builtintopic.h"
|
||||
|
||||
DECL_ENTITY_LOCK_UNLOCK (extern inline, dds_topic)
|
||||
|
@ -246,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)
|
||||
{
|
||||
(void) sedp_plist;
|
||||
dds_entity_t hdl;
|
||||
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);
|
||||
|
@ -253,30 +255,11 @@ static dds_entity_t create_topic_pp_locked (struct dds_participant *pp, struct d
|
|||
dds_entity_register_child (&pp->m_entity, &tp->m_entity);
|
||||
tp->m_ktopic = ktp;
|
||||
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);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
|
||||
dds_entity_t dds_create_topic_impl (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
|
||||
{
|
||||
dds_return_t rc;
|
||||
dds_participant *pp;
|
||||
|
@ -315,10 +298,12 @@ dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_ser
|
|||
* reliable ... (and keep behaviour unchanged) */
|
||||
struct ddsi_domaingv * const gv = &pp->m_entity.m_domain->gv;
|
||||
if ((rc = ddsi_xqos_valid (&gv->logconfig, new_qos)) != DDS_RETCODE_OK)
|
||||
goto error;
|
||||
|
||||
if (!q_omg_security_check_create_topic (&pp->m_entity.m_domain->gv, &pp->m_entity.m_guid, (*sertopic)->name, new_qos))
|
||||
{
|
||||
dds_delete_qos (new_qos);
|
||||
dds_entity_unpin (&pp->m_entity);
|
||||
return rc;
|
||||
rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* See if we're allowed to create the topic; ktp is returned pinned & locked
|
||||
|
@ -331,9 +316,8 @@ dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_ser
|
|||
if ((rc = lookup_and_check_ktopic (&ktp, pp, (*sertopic)->name, (*sertopic)->type_name, new_qos)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVTRACE ("dds_create_topic_generic: failed after compatibility check: %s\n", dds_strretcode (rc));
|
||||
dds_participant_unlock (pp);
|
||||
dds_delete_qos (new_qos);
|
||||
return rc;
|
||||
ddsrt_mutex_unlock (&pp->m_entity.m_mutex);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create a ktopic if it doesn't exist yet, else reference existing one and delete the
|
||||
|
@ -375,13 +359,31 @@ dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_ser
|
|||
hdl = create_topic_pp_locked (pp, ktp, (sertopic_registered->ops == &ddsi_sertopic_ops_builtintopic), sertopic_registered, listener, sedp_plist);
|
||||
ddsi_sertopic_unref (*sertopic);
|
||||
*sertopic = sertopic_registered;
|
||||
dds_participant_unlock (pp);
|
||||
ddsrt_mutex_unlock (&pp->m_entity.m_mutex);
|
||||
dds_entity_unpin (&pp->m_entity);
|
||||
GVTRACE ("dds_create_topic_generic: new topic %"PRId32"\n", hdl);
|
||||
return hdl;
|
||||
|
||||
error:
|
||||
dds_entity_unpin (&pp->m_entity);
|
||||
dds_delete_qos (new_qos);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dds_entity_t dds_create_topic_generic (dds_entity_t participant, struct ddsi_sertopic **sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
|
||||
{
|
||||
if (sertopic == NULL || *sertopic == NULL || (*sertopic)->name == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
if (!strncmp((*sertopic)->name, "DCPS", 4))
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
return dds_create_topic_impl (participant, sertopic, qos, listener, sedp_plist);
|
||||
}
|
||||
|
||||
dds_entity_t dds_create_topic_arbitrary (dds_entity_t participant, struct ddsi_sertopic *sertopic, const dds_qos_t *qos, const dds_listener_t *listener, const ddsi_plist_t *sedp_plist)
|
||||
{
|
||||
if (sertopic == NULL)
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
|
||||
dds_entity_t ret;
|
||||
struct ddsi_sertopic *st = sertopic;
|
||||
ddsi_sertopic_ref (st);
|
||||
|
|
|
@ -849,7 +849,7 @@ static void whc_delete_one_intv (struct whc_impl *whc, struct whc_intvnode **p_i
|
|||
assert (new_intv->min < new_intv->maxp1);
|
||||
|
||||
/* insert new node & continue the loop with intv set to the
|
||||
new interval */
|
||||
new interval */
|
||||
if (ddsrt_avl_lookup_ipath (&whc_seq_treedef, &whc->seq, &new_intv->min, &path) != NULL)
|
||||
assert (0);
|
||||
ddsrt_avl_insert_ipath (&whc_seq_treedef, &whc->seq, new_intv, &path);
|
||||
|
|
|
@ -267,8 +267,7 @@ void dds_write_flush (dds_entity_t writer)
|
|||
{
|
||||
struct thread_state1 * const ts1 = lookup_thread_state ();
|
||||
dds_writer *wr;
|
||||
dds_return_t rc;
|
||||
if ((rc = dds_writer_lock (writer, &wr)) == DDS_RETCODE_OK)
|
||||
if (dds_writer_lock (writer, &wr) == DDS_RETCODE_OK)
|
||||
{
|
||||
thread_state_awake (ts1, &wr->m_entity.m_domain->gv);
|
||||
nn_xpack_send (wr->m_xp, true);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "dds/ddsi/q_thread.h"
|
||||
#include "dds/ddsi/q_xmsg.h"
|
||||
#include "dds/ddsi/ddsi_entity_index.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
#include "dds__writer.h"
|
||||
#include "dds__listener.h"
|
||||
#include "dds__init.h"
|
||||
|
@ -312,6 +313,7 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
|
|||
dds_topic_defer_set_qos (tp);
|
||||
|
||||
/* Merge Topic & Publisher qos */
|
||||
struct ddsi_domaingv *gv = &pub->m_entity.m_domain->gv;
|
||||
wqos = dds_create_qos ();
|
||||
if (qos)
|
||||
ddsi_xqos_mergein_missing (wqos, qos, DDS_WRITER_QOS_MASK);
|
||||
|
@ -319,29 +321,45 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
|
|||
ddsi_xqos_mergein_missing (wqos, pub->m_entity.m_qos, ~(uint64_t)0);
|
||||
if (tp->m_ktopic->qos)
|
||||
ddsi_xqos_mergein_missing (wqos, tp->m_ktopic->qos, ~(uint64_t)0);
|
||||
ddsi_xqos_mergein_missing (wqos, &pub->m_entity.m_domain->gv.default_xqos_wr, ~(uint64_t)0);
|
||||
ddsi_xqos_mergein_missing (wqos, &gv->default_xqos_wr, ~(uint64_t)0);
|
||||
|
||||
if ((rc = ddsi_xqos_valid (&pub->m_entity.m_domain->gv.logconfig, wqos)) < 0 ||
|
||||
(rc = validate_writer_qos(wqos)) != DDS_RETCODE_OK)
|
||||
{
|
||||
dds_delete_qos(wqos);
|
||||
if ((rc = ddsi_xqos_valid (&gv->logconfig, wqos)) < 0 || (rc = validate_writer_qos(wqos)) != DDS_RETCODE_OK)
|
||||
goto err_bad_qos;
|
||||
|
||||
thread_state_awake (lookup_thread_state (), gv);
|
||||
const struct ddsi_guid *ppguid = dds_entity_participant_guid (&pub->m_entity);
|
||||
struct participant *pp = entidx_lookup_participant_guid (gv->entity_index, ppguid);
|
||||
/* When deleting a participant, the child handles (that include the publisher)
|
||||
are removed before removing the DDSI participant. So at this point, within
|
||||
the publisher lock, we can assert that the participant exists. */
|
||||
assert (pp != NULL);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/* Check if DDS Security is enabled */
|
||||
if (q_omg_participant_is_secure (pp))
|
||||
{
|
||||
/* ask to access control security plugin for create writer permissions */
|
||||
if (!q_omg_security_check_create_writer (pp, gv->config.domainId, tp->m_stopic->name, wqos))
|
||||
{
|
||||
rc = DDS_RETCODE_NOT_ALLOWED_BY_SECURITY;
|
||||
goto err_not_allowed;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create writer */
|
||||
ddsi_tran_conn_t conn = pub->m_entity.m_domain->gv.xmit_conn;
|
||||
ddsi_tran_conn_t conn = gv->xmit_conn;
|
||||
struct dds_writer * const wr = dds_alloc (sizeof (*wr));
|
||||
const dds_entity_t writer = dds_entity_init (&wr->m_entity, &pub->m_entity, DDS_KIND_WRITER, false, wqos, listener, DDS_WRITER_STATUS_MASK);
|
||||
wr->m_topic = tp;
|
||||
dds_entity_add_ref_locked (&tp->m_entity);
|
||||
wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), pub->m_entity.m_domain->gv.config.xpack_send_async);
|
||||
wr->m_xp = nn_xpack_new (conn, get_bandwidth_limit (wqos->transport_priority), gv->config.xpack_send_async);
|
||||
wrinfo = whc_make_wrinfo (wr, wqos);
|
||||
wr->m_whc = whc_new (&pub->m_entity.m_domain->gv, wrinfo);
|
||||
wr->m_whc = whc_new (gv, wrinfo);
|
||||
whc_free_wrinfo (wrinfo);
|
||||
wr->whc_batch = pub->m_entity.m_domain->gv.config.whc_batch;
|
||||
wr->whc_batch = gv->config.whc_batch;
|
||||
|
||||
thread_state_awake (lookup_thread_state (), &pub->m_entity.m_domain->gv);
|
||||
rc = new_writer (&wr->m_wr, &wr->m_entity.m_domain->gv, &wr->m_entity.m_guid, NULL, dds_entity_participant_guid (&pub->m_entity), tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
|
||||
rc = new_writer (&wr->m_wr, &wr->m_entity.m_guid, NULL, pp, tp->m_stopic, wqos, wr->m_whc, dds_writer_status_cb, wr);
|
||||
assert(rc == DDS_RETCODE_OK);
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
|
||||
|
@ -355,7 +373,12 @@ dds_entity_t dds_create_writer (dds_entity_t participant_or_publisher, dds_entit
|
|||
dds_publisher_unlock (pub);
|
||||
return writer;
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
err_not_allowed:
|
||||
thread_state_asleep (lookup_thread_state ());
|
||||
#endif
|
||||
err_bad_qos:
|
||||
dds_delete_qos(wqos);
|
||||
dds_topic_allow_set_qos (tp);
|
||||
err_pp_mismatch:
|
||||
dds_topic_unpin (tp);
|
||||
|
@ -387,14 +410,14 @@ dds_entity_t dds_get_publisher (dds_entity_t writer)
|
|||
}
|
||||
}
|
||||
|
||||
dds_return_t dds__writer_wait_for_acks (struct dds_writer *wr, dds_time_t abstimeout)
|
||||
dds_return_t dds__writer_wait_for_acks (struct dds_writer *wr, ddsi_guid_t *rdguid, dds_time_t abstimeout)
|
||||
{
|
||||
/* during lifetime of the writer m_wr is constant, it is only during deletion that it
|
||||
gets erased at some point */
|
||||
if (wr->m_wr == NULL)
|
||||
return DDS_RETCODE_OK;
|
||||
else
|
||||
return writer_wait_for_acks (wr->m_wr, abstimeout);
|
||||
return writer_wait_for_acks (wr->m_wr, rdguid, abstimeout);
|
||||
}
|
||||
|
||||
DDS_GET_STATUS(writer, publication_matched, PUBLICATION_MATCHED, total_count_change, current_count_change)
|
||||
|
|
|
@ -59,7 +59,9 @@ set(ddsc_test_sources
|
|||
"write_various_types.c"
|
||||
"writer.c"
|
||||
"test_common.c"
|
||||
"test_common.h")
|
||||
"test_common.h"
|
||||
"test_oneliner.c"
|
||||
"test_oneliner.h")
|
||||
|
||||
if(ENABLE_LIFESPAN)
|
||||
list(APPEND ddsc_test_sources "lifespan.c")
|
||||
|
@ -83,11 +85,10 @@ set(CUnit_ddsc_config_simple_udp_file "${CMAKE_CURRENT_LIST_DIR}/config_simple_u
|
|||
set(CUnit_ddsc_config_simple_udp_uri "file://${CUnit_ddsc_config_simple_udp_file}")
|
||||
set(CUnit_ddsc_config_simple_udp_max_participants "0")
|
||||
set(CUnit_ddsc_config_simple_udp_env "${PROJECT_NAME_CAPS}_URI=${CUnit_ddsc_config_simple_udp_uri};MAX_PARTICIPANTS=${CUnit_ddsc_config_simple_udp_max_participants};${CUnit_ddsc_config_simple_udp_env}")
|
||||
|
||||
set_tests_properties(
|
||||
CUnit_ddsc_config_simple_udp
|
||||
PROPERTIES
|
||||
REQUIRED_FILES ${CUnit_ddsc_config_simple_udp_file}
|
||||
ENVIRONMENT "${CUnit_ddsc_config_simple_udp_env}")
|
||||
|
||||
configure_file("config_env.h.in" "config_env.h")
|
||||
configure_file("config_env.h.in" "config_env.h" @ONLY)
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "dds/ddsrt/cdtors.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsi/q_misc.h"
|
||||
#include "dds/ddsi/ddsi_xqos.h"
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
|
@ -28,7 +30,7 @@
|
|||
|
||||
static void config__check_env (const char *env_variable, const char *expected_value)
|
||||
{
|
||||
char *env_uri = NULL;
|
||||
const char *env_uri = NULL;
|
||||
ddsrt_getenv (env_variable, &env_uri);
|
||||
#ifdef FORCE_ENV
|
||||
{
|
||||
|
@ -84,3 +86,99 @@ CU_Test (ddsc_config, user_config, .init = ddsrt_init, .fini = ddsrt_fini)
|
|||
dds_delete (domain);
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'found' variable will contain flags related to the expected log
|
||||
* messages that were received.
|
||||
* Using flags will allow to show that when message isn't received,
|
||||
* which one it was.
|
||||
*/
|
||||
static uint32_t found;
|
||||
static void logger(void *ptr, const dds_log_data_t *data)
|
||||
{
|
||||
char **expected = (char**)ptr;
|
||||
for (uint32_t i = 0; expected[i] != NULL; i++) {
|
||||
if (ddsi2_patmatch(expected[i], data->message)) {
|
||||
found |= (uint32_t)(1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CU_Test(ddsc_security_config, empty, .init = ddsrt_init, .fini = ddsrt_fini)
|
||||
{
|
||||
/* Expected traces when creating participant with an empty security element. We need to
|
||||
test this one here to be sure that it refuses to start when security is configured
|
||||
but the implementation doesn't include support for it. */
|
||||
const char *log_expected[] = {
|
||||
#ifndef DDSI_INCLUDE_SECURITY
|
||||
"config: //CycloneDDS/Domain: DDSSecurity: unknown element*",
|
||||
#else
|
||||
"config: //CycloneDDS/Domain/DDSSecurity/Authentication/IdentityCertificate/#text: element missing in configuration*",
|
||||
"config: //CycloneDDS/Domain/DDSSecurity/Authentication/IdentityCA/#text: element missing in configuration*",
|
||||
"config: //CycloneDDS/Domain/DDSSecurity/Authentication/PrivateKey/#text: element missing in configuration*",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
dds_entity_t participant;
|
||||
|
||||
/* Set up the trace sinks to detect the config parsing. */
|
||||
dds_set_log_mask(DDS_LC_FATAL|DDS_LC_ERROR|DDS_LC_WARNING|DDS_LC_CONFIG);
|
||||
dds_set_log_sink(&logger, (void*)log_expected);
|
||||
dds_set_trace_sink(&logger, (void*)log_expected);
|
||||
|
||||
/* Create participant with an empty security element. */
|
||||
found = 0;
|
||||
ddsrt_setenv(URI_VARIABLE, "<DDSSecurity/>");
|
||||
participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
ddsrt_setenv(URI_VARIABLE, "");
|
||||
CU_ASSERT_FATAL(participant < 0);
|
||||
dds_set_log_sink(NULL, NULL);
|
||||
dds_set_trace_sink(NULL, NULL);
|
||||
|
||||
/* All traces should have been provided. */
|
||||
#ifndef DDSI_INCLUDE_SECURITY
|
||||
CU_ASSERT_FATAL(found == 0x1);
|
||||
#else
|
||||
CU_ASSERT_FATAL(found == 0x7);
|
||||
#endif
|
||||
}
|
||||
|
||||
CU_Test(ddsc_security_qos, empty, .init = ddsrt_init, .fini = ddsrt_fini)
|
||||
{
|
||||
/* Expected traces when creating participant with some (not all) security QoS
|
||||
settings. We need to test this one here to be sure that it also refuses to
|
||||
start when security is configured but the implementation doesn't include
|
||||
support for it. */
|
||||
const char *log_expected[] = {
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
"new_participant(*): using security settings from QoS*",
|
||||
"new_participant(*): required security property * missing*",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Set up the trace sinks to detect the config parsing. */
|
||||
dds_set_log_mask (DDS_LC_FATAL|DDS_LC_ERROR|DDS_LC_WARNING|DDS_LC_CONFIG);
|
||||
dds_set_log_sink (&logger, (void *) log_expected);
|
||||
dds_set_trace_sink (&logger, (void *) log_expected);
|
||||
|
||||
/* Create participant with incomplete/nonsensical security configuration: this should always fail */
|
||||
found = 0;
|
||||
dds_qos_t *qos = dds_create_qos ();
|
||||
dds_qset_prop (qos, "dds.sec.nonsense", "");
|
||||
dds_entity_t domain = dds_create_domain (0, "<Tracing><Category>trace</Category>");
|
||||
CU_ASSERT_FATAL (domain > 0);
|
||||
dds_entity_t participant = dds_create_participant (0, qos, NULL);
|
||||
dds_delete_qos (qos);
|
||||
CU_ASSERT_FATAL (participant < 0);
|
||||
(void) dds_delete (domain);
|
||||
dds_set_log_sink (NULL, NULL);
|
||||
dds_set_trace_sink (NULL, NULL);
|
||||
|
||||
/* All traces should have been provided. */
|
||||
#ifndef DDSI_INCLUDE_SECURITY
|
||||
CU_ASSERT_FATAL (found == 0x0);
|
||||
#else
|
||||
CU_ASSERT_FATAL (found == 0x3);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ static void deadline_init(void)
|
|||
dds_qset_history(g_qos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED);
|
||||
dds_qset_durability(g_qos, DDS_DURABILITY_TRANSIENT_LOCAL);
|
||||
dds_qset_reliability(g_qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);
|
||||
dds_qset_writer_data_lifecycle(g_qos, false);
|
||||
}
|
||||
|
||||
static void deadline_fini(void)
|
||||
|
@ -422,7 +423,10 @@ CU_Theory((int32_t n_inst, uint8_t unreg_nth, uint8_t dispose_nth), ddsc_deadlin
|
|||
n_dispose++;
|
||||
}
|
||||
}
|
||||
n_alive = n_inst - n_dispose - n_unreg;
|
||||
/* FIXME: should unregistered instances cause deadline expirations? I do think so
|
||||
and that is what it actually implemented
|
||||
if they shouldn't: n_alive = n_inst - n_dispose - n_unreg */
|
||||
n_alive = n_inst - n_dispose;
|
||||
|
||||
/* Sleep deadline_dur + 50% and check missed deadline count */
|
||||
sleepfor(3 * deadline_dur / 2);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -110,6 +110,7 @@ CU_Test (ddsc_loan, success, .init = create_entities, .fini = delete_entities)
|
|||
CU_ASSERT_FATAL (result == DDS_RETCODE_OK);
|
||||
/* return resets buf[0] (so that it picks up the loan the next time) and zeros the data */
|
||||
CU_ASSERT_FATAL (ptrs[0] == NULL);
|
||||
assert (ptr0copy != NULL); /* clang static analyzer */
|
||||
CU_ASSERT_FATAL (memcmp (ptr0copy, zeros, sizeof (s)) == 0);
|
||||
|
||||
/* read 3, return: should work fine, causes realloc */
|
||||
|
@ -121,6 +122,7 @@ CU_Test (ddsc_loan, success, .init = create_entities, .fini = delete_entities)
|
|||
result = dds_return_loan (reader, ptrs, n);
|
||||
CU_ASSERT_FATAL (result == DDS_RETCODE_OK);
|
||||
CU_ASSERT_FATAL (ptrs[0] == NULL);
|
||||
assert (ptr0copy != NULL); /* clang static analyzer */
|
||||
CU_ASSERT_FATAL (memcmp (ptr0copy, zeros, 3 * sizeof (s)) == 0);
|
||||
|
||||
/* read 1 using loan, expecting to get the same address (no realloc needed), defer return.
|
||||
|
@ -145,6 +147,7 @@ CU_Test (ddsc_loan, success, .init = create_entities, .fini = delete_entities)
|
|||
{
|
||||
const struct RoundTripModule_DataType *a = ptrs[0];
|
||||
const struct RoundTripModule_DataType *b = ptrs2[0];
|
||||
assert (a != NULL && b != NULL); /* clang static analyzer */
|
||||
CU_ASSERT_FATAL (a->payload._length == b->payload._length);
|
||||
CU_ASSERT_FATAL (a->payload._buffer != b->payload._buffer);
|
||||
CU_ASSERT_FATAL (a->payload._buffer[0] == b->payload._buffer[0]);
|
||||
|
@ -164,6 +167,7 @@ CU_Test (ddsc_loan, success, .init = create_entities, .fini = delete_entities)
|
|||
|
||||
//This should be a use-after-free
|
||||
//CU_ASSERT_FATAL (memcmp (ptr0copy, zeros, sizeof (s)) == 0);
|
||||
(void) ptr0copy;
|
||||
}
|
||||
|
||||
CU_Test (ddsc_loan, take_cleanup, .init = create_entities, .fini = delete_entities)
|
||||
|
|
|
@ -111,7 +111,7 @@ CU_Test(ddsc_participant, create_with_conf_no_env) {
|
|||
ddsrt_setenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI", CONFIG_ENV_SIMPLE_UDP);
|
||||
ddsrt_setenv("MAX_PARTICIPANTS", CONFIG_ENV_MAX_PARTICIPANTS);
|
||||
|
||||
char * env_uri = NULL;
|
||||
const char * env_uri = NULL;
|
||||
ddsrt_getenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI", &env_uri);
|
||||
CU_ASSERT_PTR_NOT_EQUAL_FATAL(env_uri, NULL);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
#include "CUnit/Test.h"
|
||||
#include "dds/dds.h"
|
||||
#include <assert.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Convenience global policies
|
||||
|
@ -146,7 +147,10 @@ static const char* c_userdata = "user_key";
|
|||
static const char* c_topicdata = "topic_key";
|
||||
static const char* c_groupdata = "group_key";
|
||||
static const char* c_partitions[] = {"Partition1", "Partition2"};
|
||||
|
||||
static const char* c_property_names[] = {"prop1", "prop2", "prop3"};
|
||||
static const char* c_property_values[] = {"val1", "val2", "val3"};
|
||||
static const char* c_bproperty_names[] = {"bprop1", "bprop2", "bprop3"};
|
||||
static const unsigned char c_bproperty_values[3][3] = {{0x0, 0x1, 0x2}, {0x2, 0x3, 0x4}, {0x5, 0x6, 0x7}};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -646,3 +650,191 @@ CU_Test(ddsc_qos, durability_service, .init=qos_init, .fini=qos_fini)
|
|||
CU_ASSERT_EQUAL_FATAL(p.max_samples_per_instance, g_pol_durability_service.max_samples_per_instance);
|
||||
}
|
||||
|
||||
CU_Test(ddsc_qos, property, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
char * value = NULL;
|
||||
char ** names = NULL;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, NULL, NULL));
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, c_property_names[0], NULL));
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, NULL, &value));
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (NULL, c_property_names[0], &value));
|
||||
|
||||
dds_qset_prop (g_qos, NULL, NULL);
|
||||
dds_qset_prop (g_qos, NULL, c_property_values[0]);
|
||||
dds_qset_prop (NULL, c_property_names[0], c_property_values[0]);
|
||||
|
||||
/* Set null value should not succeed, setting empty string should */
|
||||
dds_qset_prop (g_qos, c_property_names[0], NULL);
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
dds_qset_prop (g_qos, c_property_names[0], "");
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, "");
|
||||
dds_free (value);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_prop (g_qos, c_property_names[0], c_property_values[0]);
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[0]);
|
||||
dds_free (value);
|
||||
|
||||
/* Overwrite value for existing property (and reset value) */
|
||||
dds_qset_prop (g_qos, c_property_names[0], c_property_values[1]);
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[1]);
|
||||
dds_free (value);
|
||||
dds_qset_prop (g_qos, c_property_names[0], c_property_values[0]);
|
||||
|
||||
/* Set 2nd prop and get length */
|
||||
dds_qset_prop (g_qos, c_property_names[1], c_property_values[1]);
|
||||
CU_ASSERT_FATAL (dds_qget_propnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 2);
|
||||
|
||||
/* Set another property and get list of property names */
|
||||
dds_qset_prop (g_qos, c_property_names[2], c_property_values[2]);
|
||||
CU_ASSERT_FATAL (dds_qget_propnames (g_qos, &cnt, &names));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 3);
|
||||
for (uint32_t i = 0; i < cnt; i++)
|
||||
{
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (names[i], c_property_names[i]);
|
||||
dds_free (names[i]);
|
||||
}
|
||||
dds_free (names);
|
||||
|
||||
/* Unset a property and check if removed */
|
||||
dds_qunset_prop (g_qos, c_property_names[1]);
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, c_property_names[1], &value));
|
||||
CU_ASSERT_FATAL (dds_qget_propnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 2);
|
||||
CU_ASSERT_FATAL(dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[0]);
|
||||
dds_free (value);
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[2], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[2]);
|
||||
dds_free (value);
|
||||
dds_qunset_prop (g_qos, c_property_names[0]);
|
||||
dds_qunset_prop (g_qos, c_property_names[2]);
|
||||
CU_ASSERT_FATAL (!dds_qget_propnames (g_qos, &cnt, NULL));
|
||||
}
|
||||
|
||||
CU_Test(ddsc_qos, bproperty, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
void * bvalue = NULL;
|
||||
size_t size = 0;
|
||||
char ** names = NULL;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
/* NULLs shouldn't crash and be a noops. */
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (g_qos, NULL, NULL, NULL));
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (g_qos, c_bproperty_names[0], NULL, NULL));
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (g_qos, NULL, &bvalue, &size));
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (NULL, c_bproperty_names[0], &bvalue, &size));
|
||||
|
||||
dds_qset_bprop (g_qos, NULL, NULL, 0);
|
||||
dds_qset_bprop (g_qos, NULL, &c_bproperty_values[0], 0);
|
||||
dds_qset_bprop (NULL, c_bproperty_names[0], c_bproperty_values[0], 0);
|
||||
|
||||
/* Set null value should succeed */
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[0], NULL, 0);
|
||||
CU_ASSERT_FATAL (dds_qget_bprop (g_qos, c_bproperty_names[0], &bvalue, &size));
|
||||
CU_ASSERT_EQUAL_FATAL (bvalue, NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 0);
|
||||
|
||||
/* Getting after setting, should yield the original input. */
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[0], c_bproperty_values[0], 3);
|
||||
CU_ASSERT_FATAL(dds_qget_bprop (g_qos, c_bproperty_names[0], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (bvalue != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 3);
|
||||
assert (c_bproperty_values[0] != NULL); /* for Clang static analyzer */
|
||||
CU_ASSERT_EQUAL_FATAL (memcmp (bvalue, c_bproperty_values[0], size), 0);
|
||||
dds_free (bvalue);
|
||||
|
||||
/* Overwrite value for existing binary property (and reset value) */
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[0], c_bproperty_values[1], 3);
|
||||
CU_ASSERT_FATAL (dds_qget_bprop (g_qos, c_bproperty_names[0], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (bvalue != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 3);
|
||||
assert (c_bproperty_values[1] != NULL); /* for Clang static analyzer */
|
||||
CU_ASSERT_EQUAL_FATAL (memcmp (bvalue, c_bproperty_values[1], size), 0);
|
||||
dds_free (bvalue);
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[0], &c_bproperty_values[0], 3);
|
||||
|
||||
/* Set 2nd binary prop and get length */
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[1], &c_bproperty_values[1], 3);
|
||||
CU_ASSERT_FATAL (dds_qget_bpropnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 2);
|
||||
|
||||
/* Set another binary property and get list of property names */
|
||||
dds_qset_bprop (g_qos, c_bproperty_names[2], &c_bproperty_values[2], 3);
|
||||
CU_ASSERT_FATAL (dds_qget_bpropnames (g_qos, &cnt, &names));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 3);
|
||||
for (uint32_t i = 0; i < cnt; i++)
|
||||
{
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (names[i], c_bproperty_names[i]);
|
||||
dds_free (names[i]);
|
||||
}
|
||||
dds_free (names);
|
||||
|
||||
/* Unset a binary property and check if removed */
|
||||
dds_qunset_bprop (g_qos, c_bproperty_names[1]);
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (g_qos, c_bproperty_names[1], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (dds_qget_bpropnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 2);
|
||||
CU_ASSERT_FATAL (dds_qget_bprop (g_qos, c_bproperty_names[0], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (bvalue != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 3);
|
||||
assert (c_bproperty_values[0] != NULL); /* for Clang static analyzer */
|
||||
CU_ASSERT_EQUAL_FATAL (memcmp (bvalue, c_bproperty_values[0], size), 0);
|
||||
dds_free (bvalue);
|
||||
CU_ASSERT_FATAL (dds_qget_bprop (g_qos, c_bproperty_names[2], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (bvalue != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 3);
|
||||
assert (c_bproperty_values[2] != NULL); /* for Clang static analyzer */
|
||||
CU_ASSERT_EQUAL_FATAL (memcmp (bvalue, c_bproperty_values[2], size), 0);
|
||||
dds_free (bvalue);
|
||||
dds_qunset_bprop (g_qos, c_bproperty_names[0]);
|
||||
dds_qunset_bprop (g_qos, c_bproperty_names[2]);
|
||||
CU_ASSERT_FATAL (!dds_qget_bpropnames (g_qos, &cnt, NULL));
|
||||
}
|
||||
|
||||
CU_Test(ddsc_qos, property_mixed, .init=qos_init, .fini=qos_fini)
|
||||
{
|
||||
char * value = NULL;
|
||||
void * bvalue = NULL;
|
||||
size_t size = 0;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
/* Set property and binary property with same name */
|
||||
dds_qset_prop (g_qos, c_property_names[0], c_property_values[0]);
|
||||
dds_qset_bprop (g_qos, c_property_names[0], c_bproperty_values[0], 3);
|
||||
|
||||
/* Check property values and count */
|
||||
CU_ASSERT_FATAL (dds_qget_bprop (g_qos, c_property_names[0], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (bvalue != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (size, 3);
|
||||
assert (c_bproperty_values[0] != NULL); /* for Clang static analyzer */
|
||||
CU_ASSERT_EQUAL_FATAL (memcmp (bvalue, c_bproperty_values[0], size), 0);
|
||||
dds_free (bvalue);
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[0]);
|
||||
dds_free (value);
|
||||
|
||||
CU_ASSERT_FATAL (dds_qget_propnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 1);
|
||||
CU_ASSERT_FATAL (dds_qget_bpropnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_EQUAL_FATAL (cnt, 1);
|
||||
|
||||
/* Unset and check */
|
||||
dds_qunset_bprop (g_qos, c_property_names[0]);
|
||||
CU_ASSERT_FATAL (!dds_qget_bprop (g_qos, c_property_names[0], &bvalue, &size));
|
||||
CU_ASSERT_FATAL (dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_STRING_EQUAL_FATAL (value, c_property_values[0]);
|
||||
dds_free (value);
|
||||
|
||||
dds_qunset_prop (g_qos, c_property_names[0]);
|
||||
CU_ASSERT_FATAL (!dds_qget_prop (g_qos, c_property_names[0], &value));
|
||||
CU_ASSERT_FATAL (!dds_qget_propnames (g_qos, &cnt, NULL));
|
||||
CU_ASSERT_FATAL (!dds_qget_bpropnames (g_qos, &cnt, NULL));
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#define MAX_SAMPLES 21
|
||||
|
||||
#define RDR_NOT_READ_CNT 11
|
||||
#define RDR_INV_READ_CNT 1
|
||||
#define RDR_INV_READ_CNT 2
|
||||
int rdr_expected_long_2[RDR_NOT_READ_CNT] = { 0, 1, 2, 6, 7, 9, 11, 13, 14, 16, 19 };
|
||||
|
||||
/* Because we only read one sample at a time, only the first sample of an instance
|
||||
|
|
1842
src/core/ddsc/tests/test_oneliner.c
Normal file
1842
src/core/ddsc/tests/test_oneliner.c
Normal file
File diff suppressed because it is too large
Load diff
326
src/core/ddsc/tests/test_oneliner.h
Normal file
326
src/core/ddsc/tests/test_oneliner.h
Normal file
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
#ifndef _TEST_ONELINER_H_
|
||||
#define _TEST_ONELINER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "dds/dds.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
|
||||
/** @brief run a "test" consisting of a sequence of simplish operations
|
||||
*
|
||||
* This operation takes a test description, really a program in a bizarre syntax, and
|
||||
* executes it. Any failures, be it because of error codes coming out of the Cyclone
|
||||
* calls or expected values being wrong cause it to fail the test via CU_ASSERT_FATAL.
|
||||
* While it is doing this, it outputs the test steps to stdout including some actual
|
||||
* values. An invalid program is mostly reported by calling abort(). It is geared towards
|
||||
* checking for listener invocations and the effects on statuses.
|
||||
*
|
||||
* Entities in play:
|
||||
*
|
||||
* - participants: P P' P''
|
||||
* - subscribers: R R' R''
|
||||
* - publishers: W W' W''
|
||||
* - readers: r s t r' s' t' r'' s'' t''
|
||||
* - writers: w x y w' x' y' w'' x'' y''
|
||||
*
|
||||
* The unprimed ones exist in domain 0, the primed ones in domain 1 (but configured such
|
||||
* that it talks to domain 0), and the double-primed ones in domain 2 (again configured such
|
||||
* that it talks to domain 0) so that network-related listener invocations can be checked
|
||||
* as well.
|
||||
*
|
||||
* The first mention of an entity creates it as well as its ancestors. Implicitly created
|
||||
* ancestors always have standard QoS and have no listeners. There is one topic that is
|
||||
* created implicitly when the participant is created.
|
||||
*
|
||||
* Standard QoS is: default + reliable (100ms), by-source-timestamp, keep-all. The QoS of
|
||||
* a reader/writer can be overridden at the first mention of it (i.e., when it is created)
|
||||
* by appending a list of QoS overrides between parentheses.
|
||||
*
|
||||
* A program consists of a sequence of operations separated by whitespace, ';' or '/'
|
||||
* (there is no meaning to the separators, they exist to allow visual grouping):
|
||||
*
|
||||
* PROGRAM ::= (OP (\s+|;)*)*
|
||||
*
|
||||
* OP ::= (LISTENER)* ENTITY-NAME[(QOS[,QOS[,QOS...]])]
|
||||
*
|
||||
* If entity ENTITY-NAME does not exist:
|
||||
* creates the entity with the given listeners installed
|
||||
* QOS can be used to override the standard QoS
|
||||
* else
|
||||
* changes the entity's listeners to the specified ones
|
||||
* (see above for the valid ENTITY-NAMEs)
|
||||
*
|
||||
* | -ENTITY-NAME
|
||||
*
|
||||
* Deletes the specified entity
|
||||
*
|
||||
* | WRITE-LIKE[fail] ENTITY-NAME K[@DT]
|
||||
* | WRITE-LIKE[fail] ENTITY-NAME (K,X,Y)[@DT]
|
||||
*
|
||||
* Writes/disposes/unregisters (K,0,0) (first form) or (K,X,Y). If
|
||||
* "fail" is appended, the expectation is that it fails with a
|
||||
* timeout, if @DT is appended, the timestamp is the start time of
|
||||
* the test + <dt>s rather than the current time; DT is a
|
||||
* floating-point number
|
||||
*
|
||||
* | READ-LIKE ENTITY-NAME
|
||||
* | READ-LIKE(A,B) ENTITY-NAME
|
||||
* | READ-LIKE{[S1[,S2[,S3...]][,...]} ENTITY-NAME
|
||||
*
|
||||
* Reads/takes at most 10 samples. The second form counts the
|
||||
* number of valid and invalid samples seen and checks them against
|
||||
* A and B.
|
||||
*
|
||||
* In the third form, the exact result set is given by the sample
|
||||
* Si, which is a comma-separated list of samples:
|
||||
*
|
||||
* [STATE]K[ENTITY-NAME][@DT]
|
||||
* [STATE](K,X,Y)[ENTITY-NAME][@DT]
|
||||
*
|
||||
* The first form is an invalid sample with only the (integer) key
|
||||
* value K, the second form also specifies the two (integer)
|
||||
* attribute fields.
|
||||
*
|
||||
* STATE specifies allowed sample (f - not-read (fresh), s - read
|
||||
* (stale)), instance (a - alive, u - no-writers (unregistered) d -
|
||||
* disposed) and view states (n - new, o - old). If no sample state
|
||||
* is specified, all sample states are allowed, &c.
|
||||
*
|
||||
* ENTITY-NAME is the name of the publishing writer expected in the
|
||||
* publication_handle. Not specifying a writer means any writer is
|
||||
* ok. DT is the timestamp in the same manner as the write-like
|
||||
* operations. Not specifying a timestamp means any timestamp is
|
||||
* ok.
|
||||
*
|
||||
* If the expected set ends up with "..." there may be other samples
|
||||
* in the result as well.
|
||||
*
|
||||
* | ?LISTENER[(ARGS)] ENTITY-NAME
|
||||
*
|
||||
* Waits until the specified listener has been invoked on <entity
|
||||
* name> using a flag set by the listener function, resets the flag
|
||||
* and verifies that neither the entity status bit nor the "change"
|
||||
* fields in the various statuses were set.
|
||||
*
|
||||
* ARGS is used to check the status argument most recently passed to
|
||||
* the listener:
|
||||
*
|
||||
* da(A) verifies that it has been invoked A times
|
||||
* dor(A) see da
|
||||
* it(A,B) verifies count and change match A and B, policy
|
||||
* matches RELIABILITY
|
||||
* lc(A,B,C,D,E) verifies that alive and not-alive counts match A
|
||||
* and B, that alive and not-alive changes match C and D
|
||||
* and that the last handle matches E if an entity name
|
||||
* (ignored if E = "*")
|
||||
* ll (A,B) verifies count and change match A and B
|
||||
* odm (A,B) verifies count and change match A and B, last handle
|
||||
* is ignored
|
||||
* oiq (A,B,C) verifies that total count and change match A and B
|
||||
* and that the mismatching QoS is C (using the same
|
||||
* abbreviations as used for defining QoS on entity
|
||||
* creation)
|
||||
* pm (A,B,C,D,E) verifies that total count and change match A and
|
||||
* B, that current count and change match C and D and
|
||||
* that the last handle matches E if an entity name
|
||||
* (ignored if E = "*")
|
||||
* rdm see odm
|
||||
* riq see oiq
|
||||
* sl (A,B) verifies that total count and change match A and B
|
||||
* sr (A,B,C) verifies total count and change match A and B, and
|
||||
* that the reason matches C (one of "s" for samples,
|
||||
* "i" for instances, "spi" for samples per instance)
|
||||
* sm see pm
|
||||
*
|
||||
* | ?!LISTENER
|
||||
*
|
||||
* (Not listener) tests that LISTENER has not been invoked since
|
||||
* last reset
|
||||
*
|
||||
* | sleep D
|
||||
*
|
||||
* Delay program execution for D s (D is a floating-point number)
|
||||
*
|
||||
* | deaf ENTITY-NAME
|
||||
* | hearing ENTITY-NAME
|
||||
*
|
||||
* Makes the domain wherein the specified entity exists deaf,
|
||||
* respectively restoring hearing. The entity must be either P or
|
||||
* P' and both must exist. Plays some tricks to speed up lease
|
||||
* expiry and reconnection (like forcibly deleting a proxy
|
||||
* participant or triggering the publication of SPDP packets).
|
||||
*
|
||||
* WRITE-LIKE ::= wr write
|
||||
* | wrdisp write-dispose
|
||||
* | disp dispose
|
||||
* | unreg unregister
|
||||
*
|
||||
* READ-LIKE ::= read dds_read (so any state)
|
||||
* | take dds_take (so any state)
|
||||
*
|
||||
* LISTENER ::= da data available (acts on a reader)
|
||||
* | dor data on readers (acts on a subcsriber)
|
||||
* | it incompatible topic (acts on a topic)
|
||||
* | lc liveliness changed (acts on a reader)
|
||||
* | ll liveliness lost (acts on a writer)
|
||||
* | odm offered deadline missed (acts on a writer)
|
||||
* | oiq offered incompatible QoS (acts on a writer)
|
||||
* | pm publication matched (acts on a writer)
|
||||
* | rdm requested deadline missed (acts on a reader)
|
||||
* | riq requested incompatible QoS (acts on a reader)
|
||||
* | sl sample lost (acts on a reader)
|
||||
* | sr sample rejected (acts on a reader)
|
||||
* | sm subscription matched (acts on a reader)
|
||||
*
|
||||
* QOS ::= ad={y|n} auto-dispose unregistered instances
|
||||
* | d={v|tl|t|p} durability
|
||||
* | dl={inf|DT} deadline (infinite or DT seconds)
|
||||
* | ds=DT/H/RL durability service: cleanup delay, history,
|
||||
* resource limits
|
||||
* | do={r|s} by-reception or by-source destination order
|
||||
* | h={N|all} history keep-last-N or keep-all
|
||||
* | lb={inf|DT} latency budget
|
||||
* | ll={a[:DT]|p:DT|w:DT} liveliness (automatic, manual by
|
||||
* participant, manual by topic)
|
||||
* | ls={inf|DT} lifespan
|
||||
* | o={s|x[:N]} ownership shared or exclusive (strength N)
|
||||
* | p={i|t|g} presentation: instance, coherent-topic or
|
||||
* coherent-group
|
||||
* | r={be|r[:DT]} best-effort or reliable (with max blocking time)
|
||||
* | rl=N[/N[/N]] resource limits (sample, instances, samples per
|
||||
* instance; "inf" is allowed, ommitted ones are
|
||||
* unlimited)
|
||||
* | tp=N transport-priority
|
||||
* | ud=... user data (with escape sequences and hex/octal
|
||||
* input allowed)
|
||||
*
|
||||
* All entities share the listeners with their global state. Only the latest invocation is visible.
|
||||
*
|
||||
* @param[in] ops Program to execute.
|
||||
*
|
||||
* @return > 0 success, 0 failure, < 0 invalid input
|
||||
*/
|
||||
int test_oneliner (const char *ops);
|
||||
|
||||
union oneliner_tokval {
|
||||
int i;
|
||||
int64_t d;
|
||||
char n[32];
|
||||
};
|
||||
|
||||
struct oneliner_lex {
|
||||
const char *inp;
|
||||
dds_time_t tref;
|
||||
int tok;
|
||||
union oneliner_tokval v;
|
||||
};
|
||||
|
||||
struct oneliner_ctx;
|
||||
|
||||
struct oneliner_cb {
|
||||
struct oneliner_ctx *ctx;
|
||||
dds_listener_t *list;
|
||||
uint32_t cb_called[DDS_STATUS_ID_MAX + 1];
|
||||
dds_entity_t cb_topic, cb_writer, cb_reader, cb_subscriber;
|
||||
dds_inconsistent_topic_status_t cb_inconsistent_topic_status;
|
||||
dds_liveliness_changed_status_t cb_liveliness_changed_status;
|
||||
dds_liveliness_lost_status_t cb_liveliness_lost_status;
|
||||
dds_offered_deadline_missed_status_t cb_offered_deadline_missed_status;
|
||||
dds_offered_incompatible_qos_status_t cb_offered_incompatible_qos_status;
|
||||
dds_publication_matched_status_t cb_publication_matched_status;
|
||||
dds_requested_deadline_missed_status_t cb_requested_deadline_missed_status;
|
||||
dds_requested_incompatible_qos_status_t cb_requested_incompatible_qos_status;
|
||||
dds_sample_lost_status_t cb_sample_lost_status;
|
||||
dds_sample_rejected_status_t cb_sample_rejected_status;
|
||||
dds_subscription_matched_status_t cb_subscription_matched_status;
|
||||
};
|
||||
|
||||
struct oneliner_ctx {
|
||||
struct oneliner_lex l;
|
||||
|
||||
dds_entity_t es[3 * 9];
|
||||
dds_entity_t tps[3];
|
||||
dds_entity_t doms[3];
|
||||
dds_instance_handle_t esi[3 * 9];
|
||||
// built-in topic readers for cross-referencing instance handles
|
||||
dds_entity_t pubrd[3];
|
||||
dds_entity_t subrd[3];
|
||||
// topic name used for data
|
||||
char topicname[100];
|
||||
|
||||
const dds_qos_t *qos;
|
||||
dds_qos_t *rwqos;
|
||||
|
||||
int result;
|
||||
char msg[256];
|
||||
|
||||
jmp_buf jb;
|
||||
|
||||
ddsrt_mutex_t g_mutex;
|
||||
ddsrt_cond_t g_cond;
|
||||
struct oneliner_cb cb[3];
|
||||
};
|
||||
|
||||
/** @brief Initialize a "oneliner test" context
|
||||
*
|
||||
* @param[out] ctx context to initialize
|
||||
*/
|
||||
void test_oneliner_init (struct oneliner_ctx *ctx);
|
||||
|
||||
/** @brief Run a sequence of operations in an initialized context
|
||||
*
|
||||
* If the context indicates a preceding step has failed, this is a
|
||||
* no-op and the previous result is propagated to the return value.
|
||||
*
|
||||
* @param[in,out] ctx context to operate in
|
||||
* @param[in] ops sequence of operations to execute (@ref test_oneliner)
|
||||
*
|
||||
* @return integer indicating success or failure
|
||||
*
|
||||
* @retval 1 success
|
||||
* @retval 0 test failure
|
||||
* @retval <0 syntax error unexpected error
|
||||
*/
|
||||
int test_oneliner_step (struct oneliner_ctx *ctx, const char *ops);
|
||||
|
||||
/** @brief Get a pointer to the error message from a "oneliner test"
|
||||
*
|
||||
* If a preceding step has failed, this returns a pointer to a message
|
||||
* containing some information about the failure. If no error
|
||||
* occurred, the message is meaningless.
|
||||
*
|
||||
*
|
||||
* @param[in] ctx context to retrieve message from
|
||||
*
|
||||
* @return pointer to null-terminated string aliasing a string in ctx
|
||||
*/
|
||||
const char *test_oneliner_message (const struct oneliner_ctx *ctx);
|
||||
|
||||
/** @brief Deinitialize a "oneliner test" context
|
||||
*
|
||||
* This releases all resources used by the context.
|
||||
*
|
||||
* @param[in,out] ctx context to operate in
|
||||
*
|
||||
* @return integer indicating success or failure in any of the
|
||||
* preceding steps. If no steps were taken, the result is success.
|
||||
*
|
||||
* @retval 1 success
|
||||
* @retval 0 test failure
|
||||
* @retval <0 syntax error unexpected error
|
||||
*/
|
||||
int test_oneliner_fini (struct oneliner_ctx *ctx);
|
||||
|
||||
#endif
|
|
@ -170,7 +170,7 @@ CU_Test(ddsc_topic_create, desc_null, .init=ddsc_topic_init, .fini=ddsc_topic_fi
|
|||
|
||||
|
||||
CU_TheoryDataPoints(ddsc_topic_create, invalid_names) = {
|
||||
CU_DataPoints(char *, NULL, "", "mi-dle", "-start", "end-", "1st", "Thus$", "pl+s", "t(4)"),
|
||||
CU_DataPoints(char *, NULL, "", "mi-dle", "-start", "end-", "1st", "Thus$", "pl+s", "t(4)", "DCPSmytopic"),
|
||||
};
|
||||
CU_Theory((char *name), ddsc_topic_create, invalid_names, .init=ddsc_topic_init, .fini=ddsc_topic_fini)
|
||||
{
|
||||
|
|
|
@ -18,11 +18,18 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
|
|||
ddsi_raweth.c
|
||||
ddsi_ipaddr.c
|
||||
ddsi_mcgroup.c
|
||||
ddsi_security_util.c
|
||||
ddsi_security_omg.c
|
||||
ddsi_portmapping.c
|
||||
ddsi_handshake.c
|
||||
ddsi_serdata.c
|
||||
ddsi_serdata_default.c
|
||||
ddsi_serdata_pserop.c
|
||||
ddsi_serdata_plist.c
|
||||
ddsi_sertopic.c
|
||||
ddsi_sertopic_default.c
|
||||
ddsi_sertopic_pserop.c
|
||||
ddsi_sertopic_plist.c
|
||||
ddsi_iid.c
|
||||
ddsi_tkmap.c
|
||||
ddsi_vendor.c
|
||||
|
@ -81,10 +88,15 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
|||
ddsi_ipaddr.h
|
||||
ddsi_mcgroup.h
|
||||
ddsi_plist_generic.h
|
||||
ddsi_security_util.h
|
||||
ddsi_security_omg.h
|
||||
ddsi_portmapping.h
|
||||
ddsi_handshake.h
|
||||
ddsi_serdata.h
|
||||
ddsi_sertopic.h
|
||||
ddsi_serdata_default.h
|
||||
ddsi_serdata_pserop.h
|
||||
ddsi_serdata_plist.h
|
||||
ddsi_iid.h
|
||||
ddsi_tkmap.h
|
||||
ddsi_vendor.h
|
||||
|
@ -92,6 +104,7 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
|||
ddsi_builtin_topic_if.h
|
||||
ddsi_rhc.h
|
||||
ddsi_guid.h
|
||||
ddsi_keyhash.h
|
||||
ddsi_entity_index.h
|
||||
ddsi_deadline.h
|
||||
ddsi_deliver_locally.h
|
||||
|
@ -142,6 +155,19 @@ endif()
|
|||
target_sources(ddsc
|
||||
PRIVATE ${srcs_ddsi} ${hdrs_private_ddsi})
|
||||
|
||||
if(ENABLE_SECURITY)
|
||||
PREPEND(security_srcs "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
ddsi_security_msg.c
|
||||
ddsi_security_exchange.c)
|
||||
|
||||
PREPEND(security_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
|
||||
ddsi_security_msg.h
|
||||
ddsi_security_exchange.h)
|
||||
|
||||
target_sources(ddsc
|
||||
PRIVATE ${security_srcs} ${security_hdrs})
|
||||
endif()
|
||||
|
||||
target_include_directories(ddsc
|
||||
PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ struct ddsi_tran_factory;
|
|||
struct ddsrt_thread_pool_s;
|
||||
struct debug_monitor;
|
||||
struct ddsi_tkmap;
|
||||
struct dds_security_context;
|
||||
struct dds_security_match_index;
|
||||
struct ddsi_hsadmin;
|
||||
|
||||
typedef struct config_in_addr_node {
|
||||
nn_locator_t loc;
|
||||
|
@ -258,6 +261,12 @@ struct ddsi_domaingv {
|
|||
dds_qos_t spdp_endpoint_xqos;
|
||||
dds_qos_t builtin_endpoint_xqos_rd;
|
||||
dds_qos_t builtin_endpoint_xqos_wr;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
dds_qos_t builtin_volatile_xqos_rd;
|
||||
dds_qos_t builtin_volatile_xqos_wr;
|
||||
dds_qos_t builtin_stateless_xqos_rd;
|
||||
dds_qos_t builtin_stateless_xqos_wr;
|
||||
#endif
|
||||
|
||||
/* SPDP packets get very special treatment (they're the only packets
|
||||
we accept from writers we don't know) and have their very own
|
||||
|
@ -285,8 +294,18 @@ struct ddsi_domaingv {
|
|||
transmit queue*/
|
||||
struct serdatapool *serpool;
|
||||
struct nn_xmsgpool *xmsgpool;
|
||||
struct ddsi_sertopic *plist_topic; /* used for all discovery data */
|
||||
struct ddsi_sertopic *rawcdr_topic; /* used for participant message data */
|
||||
struct ddsi_sertopic *spdp_topic; /* key = participant GUID */
|
||||
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_cond_t sendq_cond;
|
||||
|
@ -306,6 +325,14 @@ struct ddsi_domaingv {
|
|||
|
||||
ddsrt_mutex_t sertopics_lock;
|
||||
struct ddsrt_hh *sertopics;
|
||||
|
||||
/* security globals */
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct dds_security_context *security_context;
|
||||
struct ddsi_hsadmin *hsadmin;
|
||||
bool handshake_include_optional;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
|
|
@ -112,6 +112,7 @@ struct entidx_enum_proxy_reader { struct entidx_enum st; };
|
|||
|
||||
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind) ddsrt_nonnull_all;
|
||||
void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *gh, enum entity_kind kind, const char *topic, struct match_entities_range_key *max) ddsrt_nonnull_all;
|
||||
void entidx_enum_init_topic_w_prefix (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind, const char *topic, const ddsi_guid_prefix_t *prefix, struct match_entities_range_key *max) ddsrt_nonnull_all;
|
||||
void *entidx_enum_next_max (struct entidx_enum *st, const struct match_entities_range_key *max) ddsrt_nonnull_all;
|
||||
void *entidx_enum_next (struct entidx_enum *st) ddsrt_nonnull_all;
|
||||
void entidx_enum_fini (struct entidx_enum *st) ddsrt_nonnull_all;
|
||||
|
|
226
src/core/ddsi/include/dds/ddsi/ddsi_handshake.h
Normal file
226
src/core/ddsi/include/dds/ddsi/ddsi_handshake.h
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* 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_HANDSHAKE_H
|
||||
#define DDSI_HANDSHAKE_H
|
||||
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct participant;
|
||||
struct proxy_participant;
|
||||
struct ddsi_handshake;
|
||||
struct dssi_hsadmin;
|
||||
|
||||
enum ddsi_handshake_state {
|
||||
STATE_HANDSHAKE_IN_PROGRESS,
|
||||
STATE_HANDSHAKE_TIMED_OUT,
|
||||
STATE_HANDSHAKE_FAILED,
|
||||
STATE_HANDSHAKE_PROCESSED,
|
||||
STATE_HANDSHAKE_SEND_TOKENS,
|
||||
STATE_HANDSHAKE_OK
|
||||
};
|
||||
|
||||
/* The handshake will not use the related handshake object after this callback
|
||||
* was executed. This means that it can be deleted in this callback. */
|
||||
typedef void (*ddsi_handshake_end_cb_t)(
|
||||
struct ddsi_handshake *handshake,
|
||||
struct participant *pp,
|
||||
struct proxy_participant *proxypp,
|
||||
enum ddsi_handshake_state result);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#include "dds/ddsi/ddsi_security_msg.h"
|
||||
|
||||
/**
|
||||
* @brief Release the handshake.
|
||||
*
|
||||
* This function will decrement the refcount associated with the handshake
|
||||
* and delete the handshake when the refcount becomes 0.
|
||||
*
|
||||
* @param[in] handshake The handshake.
|
||||
*/
|
||||
void ddsi_handshake_release(struct ddsi_handshake *handshake);
|
||||
|
||||
/**
|
||||
* @brief Handle an authentication handshake message received from the remote participant.
|
||||
*
|
||||
* During the authentication phase handshake messages are being exchanged between the local and
|
||||
* the remote participant. THis function will handle a handshake message received from a remote
|
||||
* participant.
|
||||
*
|
||||
* @param[in] handshake The handshake.
|
||||
* @param[in] pp The local participant.
|
||||
* @param[in] proxypp The remote participant.
|
||||
* @param[in] msg The handshake message received.
|
||||
*/
|
||||
void ddsi_handshake_handle_message(struct ddsi_handshake *handshake, const struct participant *pp, const struct proxy_participant *proxypp, const struct nn_participant_generic_message *msg);
|
||||
|
||||
/**
|
||||
* @brief Notify the handshake that crypto tokens have been received.
|
||||
*
|
||||
* The handshake could be finished at one end while the other side has not yet processed the
|
||||
* final handshake messages. The arrival of crypto tokens signals that the other side has also finished
|
||||
* processing the handshake. This function is used to signal the handshake that crypto tokens have been
|
||||
* received.
|
||||
*
|
||||
* @param[in] handshake The handshake.
|
||||
*/
|
||||
void ddsi_handshake_crypto_tokens_received(struct ddsi_handshake *handshake);
|
||||
|
||||
/**
|
||||
* @brief Get the shared secret handle.
|
||||
*
|
||||
* During the handshake a shared secret is established which is used to encrypt
|
||||
* and decrypt the crypto token exchange messages. This function will return a
|
||||
* handle to the shared secret which will be passed to the crypto plugin to
|
||||
* determine the session keys used for the echange of the the crypto tokens.
|
||||
*
|
||||
* @param[in] handshake The handshake.
|
||||
*
|
||||
* @returns handle to the shared sercet.
|
||||
*/
|
||||
int64_t ddsi_handshake_get_shared_secret(const struct ddsi_handshake *handshake);
|
||||
|
||||
/**
|
||||
* @brief Get the handshake handle
|
||||
*
|
||||
* This function returns the handshake handle that was returned by the authentication plugin
|
||||
* when starting the handshake.
|
||||
*
|
||||
* @param[in] handshake The handshake.
|
||||
*
|
||||
* @returns The handshake handle.
|
||||
*/
|
||||
int64_t ddsi_handshake_get_handle(const struct ddsi_handshake *handshake);
|
||||
|
||||
/**
|
||||
* @brief Create and start the handshake for the participants
|
||||
*
|
||||
* This function will create a handshake for the specified local
|
||||
* and remote participants when it does not yet exists. It will start the
|
||||
* handshake procedure by calling the corresponding functions of the authentication plugin.
|
||||
* The callback function is called by the handshake when to report events,
|
||||
* for example to indicate that the handshake has finished or has failed.
|
||||
*
|
||||
* @param[in] pp The local participant.
|
||||
* @param[in] proxypp The remote participant.
|
||||
* @param[in] callback The callback function.
|
||||
*
|
||||
*/
|
||||
void ddsi_handshake_register(struct participant *pp, struct proxy_participant *proxypp, ddsi_handshake_end_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief Remove the handshake associated with the specified participants.
|
||||
*
|
||||
* This function will remove the handshake from the handshake administation and release
|
||||
* the handshake. When the handshake argument is not specified the handshake is searched
|
||||
* in the handshake administation.
|
||||
*
|
||||
* @param[in] pp The local participant.
|
||||
* @param[in] proxypp The remote participant.
|
||||
*
|
||||
*/
|
||||
void ddsi_handshake_remove(struct participant *pp, struct proxy_participant *proxypp);
|
||||
|
||||
/**
|
||||
* @brief Searches for the handshake associated with the specified participants
|
||||
*
|
||||
* This function will search through the handshake administration to find the handshake
|
||||
* corresponding the to specified local and remote participant.
|
||||
*
|
||||
* @param[in] pp The local participant.
|
||||
* @param[in] proxypp The remote participant.
|
||||
*
|
||||
* @returns The handshake
|
||||
*/
|
||||
struct ddsi_handshake * ddsi_handshake_find(struct participant *pp, struct proxy_participant *proxypp);
|
||||
|
||||
/**
|
||||
* @brief Searches for the handshake associated with the specified participants
|
||||
*
|
||||
* This function will search through the handshake administration to find the handshake
|
||||
* corresponding the to specified local and remote participant.
|
||||
*
|
||||
* @param[in] pp The local participant.
|
||||
* @param[in] proxypp The remote participant.
|
||||
*
|
||||
* @returns The handshake
|
||||
*/
|
||||
struct ddsi_handshake * ddsi_handshake_find(struct participant *pp, struct proxy_participant *proxypp);
|
||||
|
||||
/**
|
||||
* @brief Initialize the handshake administration
|
||||
*
|
||||
* @param[in] gv The global parameters
|
||||
*/
|
||||
void ddsi_handshake_admin_init(struct ddsi_domaingv *gv);
|
||||
|
||||
/**
|
||||
* @brief Stop handshake background processing.
|
||||
*
|
||||
* @param[in] gv The global parameters
|
||||
*/
|
||||
void ddsi_handshake_admin_stop(struct ddsi_domaingv *gv);
|
||||
|
||||
/**
|
||||
* @brief Deinitialze the handshake administration.
|
||||
*
|
||||
* @param[in] gv The global parameters
|
||||
*/
|
||||
void ddsi_handshake_admin_deinit(struct ddsi_domaingv *gv);
|
||||
|
||||
#else /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#include "dds/ddsi/q_unused.h"
|
||||
|
||||
inline void ddsi_handshake_register(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp), UNUSED_ARG(ddsi_handshake_end_cb_t callback))
|
||||
{
|
||||
}
|
||||
|
||||
inline void ddsi_handshake_release(UNUSED_ARG(struct ddsi_handshake *handshake))
|
||||
{
|
||||
}
|
||||
|
||||
inline void ddsi_handshake_crypto_tokens_received(UNUSED_ARG(struct ddsi_handshake *handshake))
|
||||
{
|
||||
}
|
||||
|
||||
inline int64_t ddsi_handshake_get_shared_secret(UNUSED_ARG(const struct ddsi_handshake *handshake))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int64_t ddsi_handshake_get_handle(UNUSED_ARG(const struct ddsi_handshake *handshake))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void ddsi_handshake_remove(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp), UNUSED_ARG(struct ddsi_handshake *handshake))
|
||||
{
|
||||
}
|
||||
|
||||
inline struct ddsi_handshake * ddsi_handshake_find(UNUSED_ARG(struct participant *pp), UNUSED_ARG(struct proxy_participant *proxypp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DDSI_HANDSHAKE_H */
|
27
src/core/ddsi/include/dds/ddsi/ddsi_keyhash.h
Normal file
27
src/core/ddsi/include/dds/ddsi/ddsi_keyhash.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
#ifndef DDSI_KEYHASH_H
|
||||
#define DDSI_KEYHASH_H
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ddsi_keyhash {
|
||||
unsigned char value[16];
|
||||
} ddsi_keyhash_t;
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "dds/ddsi/q_feature_check.h"
|
||||
#include "dds/ddsi/ddsi_xqos.h"
|
||||
#include "dds/ddsi/ddsi_keyhash.h"
|
||||
#include "dds/ddsi/ddsi_tran.h" /* FIXME: eliminate */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
@ -51,11 +52,15 @@ extern "C" {
|
|||
#ifdef DDSI_INCLUDE_SSM
|
||||
#define PP_READER_FAVOURS_SSM ((uint64_t)1 << 29)
|
||||
#endif
|
||||
#define PP_DOMAIN_ID ((uint64_t)1 << 30)
|
||||
#define PP_DOMAIN_TAG ((uint64_t)1 << 31)
|
||||
/* Security extensions. */
|
||||
#define PP_IDENTITY_TOKEN ((uint64_t)1 << 30)
|
||||
#define PP_PERMISSIONS_TOKEN ((uint64_t)1 << 31)
|
||||
#define PP_DOMAIN_ID ((uint64_t)1 << 32)
|
||||
#define PP_DOMAIN_TAG ((uint64_t)1 << 33)
|
||||
#define PP_IDENTITY_TOKEN ((uint64_t)1 << 32)
|
||||
#define PP_PERMISSIONS_TOKEN ((uint64_t)1 << 33)
|
||||
#define PP_ENDPOINT_SECURITY_INFO ((uint64_t)1 << 34)
|
||||
#define PP_PARTICIPANT_SECURITY_INFO ((uint64_t)1 << 35)
|
||||
#define PP_IDENTITY_STATUS_TOKEN ((uint64_t)1 << 36)
|
||||
#define PP_DATA_TAGS ((uint64_t)1 << 37)
|
||||
/* Set for unrecognized parameters that are in the reserved space or
|
||||
in our own vendor-specific space that have the
|
||||
PID_UNRECOGNIZED_INCOMPATIBLE_FLAG set (see DDSI 2.1 9.6.2.2.1) */
|
||||
|
@ -93,10 +98,21 @@ typedef uint32_t nn_ipv4address_t;
|
|||
|
||||
typedef uint32_t nn_port_t;
|
||||
|
||||
typedef struct nn_keyhash {
|
||||
unsigned char value[16];
|
||||
} nn_keyhash_t;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
typedef struct nn_tag {
|
||||
char *name;
|
||||
char *value;
|
||||
} nn_tag_t;
|
||||
|
||||
typedef struct nn_tagseq {
|
||||
uint32_t n;
|
||||
nn_tag_t *tags;
|
||||
} nn_tagseq_t;
|
||||
|
||||
typedef struct nn_datatags {
|
||||
nn_tagseq_t tags;
|
||||
} nn_datatags_t;
|
||||
#endif
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
typedef struct nn_reader_favours_ssm {
|
||||
|
@ -104,6 +120,57 @@ typedef struct nn_reader_favours_ssm {
|
|||
} nn_reader_favours_ssm_t;
|
||||
#endif
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
typedef struct nn_dataholder
|
||||
{
|
||||
char *class_id;
|
||||
dds_propertyseq_t properties;
|
||||
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. */
|
||||
typedef struct nn_security_info
|
||||
{
|
||||
uint32_t security_attributes;
|
||||
uint32_t plugin_security_attributes;
|
||||
} nn_security_info_t;
|
||||
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_READ_PROTECTED (1u << 0)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_WRITE_PROTECTED (1u << 1)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 2)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED (1u << 3)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED (1u << 4)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_KEY_PROTECTED (1u << 5)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 6)
|
||||
#define NN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID (1u << 31)
|
||||
|
||||
#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED (1u << 0)
|
||||
#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED (1u << 1)
|
||||
#define NN_PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED (1u << 2)
|
||||
|
||||
#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_PROTECTED (1u << 0)
|
||||
#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 1)
|
||||
#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 2)
|
||||
#define NN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_VALID (1u << 31)
|
||||
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED (1u << 0)
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_ENCRYPTED (1u << 1)
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED (1u << 2)
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_RTPS_AUTHENTICATED (1u << 3)
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED (1u << 4)
|
||||
#define NN_PLUGIN_PARTICIPANT_SECURITY_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED (1u << 5)
|
||||
#else
|
||||
struct nn_security_info;
|
||||
typedef struct nn_security_info nn_security_info_t;
|
||||
#endif
|
||||
|
||||
typedef struct nn_adlink_participant_version_info
|
||||
{
|
||||
uint32_t version;
|
||||
|
@ -142,11 +209,19 @@ typedef struct ddsi_plist {
|
|||
uint32_t builtin_endpoint_set;
|
||||
/* int type_max_size_serialized; */
|
||||
char *entity_name;
|
||||
nn_keyhash_t keyhash;
|
||||
ddsi_keyhash_t keyhash;
|
||||
uint32_t statusinfo;
|
||||
nn_adlink_participant_version_info_t adlink_participant_version_info;
|
||||
char *type_description;
|
||||
nn_sequence_number_t coherent_set_seqno;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
nn_token_t identity_token;
|
||||
nn_token_t permissions_token;
|
||||
nn_security_info_t endpoint_security_info;
|
||||
nn_security_info_t participant_security_info;
|
||||
nn_token_t identity_status_token;
|
||||
nn_datatags_t data_tags;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
nn_reader_favours_ssm_t reader_favours_ssm;
|
||||
#endif
|
||||
|
@ -225,6 +300,7 @@ DDS_EXPORT void ddsi_plist_fini (ddsi_plist_t *ps);
|
|||
DDS_EXPORT void ddsi_plist_fini_mask (ddsi_plist_t *plist, uint64_t pmask, uint64_t qmask);
|
||||
DDS_EXPORT void ddsi_plist_unalias (ddsi_plist_t *plist);
|
||||
DDS_EXPORT void ddsi_plist_addtomsg (struct nn_xmsg *m, const ddsi_plist_t *ps, uint64_t pwanted, uint64_t qwanted);
|
||||
DDS_EXPORT void ddsi_plist_addtomsg_bo (struct nn_xmsg *m, const ddsi_plist_t *ps, uint64_t pwanted, uint64_t qwanted, bool be);
|
||||
DDS_EXPORT void ddsi_plist_init_default_participant (ddsi_plist_t *plist);
|
||||
DDS_EXPORT void ddsi_plist_delta (uint64_t *pdelta, uint64_t *qdelta, const ddsi_plist_t *x, const ddsi_plist_t *y, uint64_t pmask, uint64_t qmask);
|
||||
DDS_EXPORT void ddsi_plist_log (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const ddsi_plist_t *plist);
|
||||
|
@ -235,7 +311,7 @@ struct nn_rsample_info;
|
|||
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 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)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "dds/export.h"
|
||||
|
||||
#include "dds/ddsrt/attributes.h"
|
||||
#include "dds/ddsrt/retcode.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -34,6 +35,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,21 +46,14 @@ 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);
|
||||
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 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_print_generic (char * __restrict buf, size_t bufsize, const void * __restrict src, const enum pserop * __restrict desc);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
#ifndef DDSI_PMD_H
|
||||
#define DDSI_PMD_H
|
||||
|
||||
#include <stdint.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)
|
||||
extern "C" {
|
||||
|
@ -25,9 +30,20 @@ struct nn_xpack;
|
|||
struct participant;
|
||||
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 (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)
|
||||
}
|
||||
|
|
49
src/core/ddsi/include/dds/ddsi/ddsi_security_exchange.h
Normal file
49
src/core/ddsi/include/dds/ddsi/ddsi_security_exchange.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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_EXCHANGE_H
|
||||
#define DDSI_SECURITY_EXCHANGE_H
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "dds/ddsi/q_rtps.h"
|
||||
#include "dds/ddsi/q_radmin.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/ddsi_security_msg.h"
|
||||
|
||||
|
||||
#define GMCLASSID_SECURITY_PARTICIPANT_CRYPTO_TOKENS "dds.sec.participant_crypto_tokens"
|
||||
#define GMCLASSID_SECURITY_DATAWRITER_CRYPTO_TOKENS "dds.sec.datawriter_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);
|
||||
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, struct ddsi_serdata *sample);
|
||||
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_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens);
|
||||
bool write_crypto_reader_tokens(const struct reader *rd, const struct proxy_writer *pwr, const nn_dataholderseq_t *tokens);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#define volatile_secure_data_filter NULL
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#endif /* DDSI_SECURITY_EXCHANGE_H */
|
112
src/core/ddsi/include/dds/ddsi/ddsi_security_msg.h
Normal file
112
src/core/ddsi/include/dds/ddsi/ddsi_security_msg.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#include "dds/ddsi/ddsi_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
|
||||
|
||||
struct participant;
|
||||
struct writer;
|
||||
struct proxy_reader;
|
||||
struct ddsi_serdata;
|
||||
|
||||
#define DDS_SECURITY_AUTH_REQUEST "dds.sec.auth_request"
|
||||
#define DDS_SECURITY_AUTH_HANDSHAKE "dds.sec.auth"
|
||||
#define DDS_SECURITY_AUTH_REQUEST_TOKEN_CLASS_ID "DDS:Auth:PKI-DH:1.0+AuthReq"
|
||||
#define DDS_SECURITY_AUTH_HANDSHAKE_REQUEST_TOKEN_ID "DDS:Auth:PKI-DH:1.0+Req"
|
||||
#define DDS_SECURITY_AUTH_HANDSHAKE_REPLY_TOKEN_ID "DDS:Auth:PKI-DH:1.0+Reply"
|
||||
#define DDS_SECURITY_AUTH_HANDSHAKE_FINAL_TOKEN_ID "DDS:Auth:PKI-DH:1.0+Final"
|
||||
|
||||
|
||||
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 destination_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[];
|
||||
DDS_EXPORT extern const size_t pserop_participant_generic_message_nops;
|
||||
|
||||
DDS_EXPORT int
|
||||
volatile_secure_data_filter(
|
||||
struct writer *wr,
|
||||
struct proxy_reader *prd,
|
||||
struct ddsi_serdata *serdata);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* DDSI_SECURITY_MSG_H */
|
1418
src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h
Normal file
1418
src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h
Normal file
File diff suppressed because it is too large
Load diff
64
src/core/ddsi/include/dds/ddsi/ddsi_security_util.h
Normal file
64
src/core/ddsi/include/dds/ddsi/ddsi_security_util.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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_UTIL_H
|
||||
#define DDSI_SECURITY_UTIL_H
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#include "dds/ddsi/ddsi_plist.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void g_omg_shallow_copy_StringSeq(DDS_Security_StringSeq *dst, const ddsi_stringseq_t *src);
|
||||
void g_omg_shallow_free_StringSeq(DDS_Security_StringSeq *obj);
|
||||
void q_omg_copy_PropertySeq(DDS_Security_PropertySeq *dst, const dds_propertyseq_t *src);
|
||||
void q_omg_shallow_copyin_PropertySeq(DDS_Security_PropertySeq *dst, const dds_propertyseq_t *src);
|
||||
void q_omg_shallow_copyout_PropertySeq(dds_propertyseq_t *dst, const DDS_Security_PropertySeq *src);
|
||||
void q_omg_shallow_free_PropertySeq(DDS_Security_PropertySeq *obj);
|
||||
void q_omg_shallow_copyin_BinaryPropertySeq(DDS_Security_BinaryPropertySeq *dst, const dds_binarypropertyseq_t *src);
|
||||
void q_omg_shallow_copyout_BinaryPropertySeq(dds_binarypropertyseq_t *dst, const DDS_Security_BinaryPropertySeq *src);
|
||||
void q_omg_shallow_free_BinaryPropertySeq(DDS_Security_BinaryPropertySeq *obj);
|
||||
void q_omg_shallow_copy_PropertyQosPolicy(DDS_Security_PropertyQosPolicy *dst, const dds_property_qospolicy_t *src);
|
||||
void q_omg_shallow_copy_security_qos(DDS_Security_Qos *dst, const struct dds_qos *src);
|
||||
void q_omg_shallow_free_PropertyQosPolicy(DDS_Security_PropertyQosPolicy *obj);
|
||||
void q_omg_shallow_free_security_qos(DDS_Security_Qos *obj);
|
||||
void q_omg_security_dataholder_copyin(nn_dataholder_t *dh, const DDS_Security_DataHolder *holder);
|
||||
void q_omg_security_dataholder_copyout(DDS_Security_DataHolder *holder, const nn_dataholder_t *dh);
|
||||
void q_omg_shallow_copyin_DataHolder(DDS_Security_DataHolder *dst, const nn_dataholder_t *src);
|
||||
void q_omg_shallow_copyout_DataHolder(nn_dataholder_t *dst, const DDS_Security_DataHolder *src);
|
||||
void q_omg_shallow_free_DataHolder(DDS_Security_DataHolder *obj);
|
||||
void q_omg_shallow_free_nn_dataholder(nn_dataholder_t *holder);
|
||||
void q_omg_shallow_copyin_DataHolderSeq(DDS_Security_DataHolderSeq *dst, const nn_dataholderseq_t *src);
|
||||
void q_omg_copyin_DataHolderSeq(DDS_Security_DataHolderSeq *dst, const nn_dataholderseq_t *src);
|
||||
void q_omg_shallow_copyout_DataHolderSeq(nn_dataholderseq_t *dst, const DDS_Security_DataHolderSeq *src);
|
||||
void q_omg_shallow_free_DataHolderSeq(DDS_Security_DataHolderSeq *obj);
|
||||
void q_omg_shallow_free_nn_dataholderseq(nn_dataholderseq_t *obj);
|
||||
void q_omg_shallow_copy_ParticipantBuiltinTopicDataSecure(DDS_Security_ParticipantBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const ddsi_plist_t *plist);
|
||||
void q_omg_shallow_free_ParticipantBuiltinTopicDataSecure(DDS_Security_ParticipantBuiltinTopicDataSecure *obj);
|
||||
void q_omg_shallow_copy_SubscriptionBuiltinTopicDataSecure(DDS_Security_SubscriptionBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const struct dds_qos *qos, const nn_security_info_t *secinfo);
|
||||
void q_omg_shallow_free_SubscriptionBuiltinTopicDataSecure(DDS_Security_SubscriptionBuiltinTopicDataSecure *obj);
|
||||
void q_omg_shallow_copy_PublicationBuiltinTopicDataSecure(DDS_Security_PublicationBuiltinTopicDataSecure *dst, const ddsi_guid_t *guid, const struct dds_qos *qos, const nn_security_info_t *secinfo);
|
||||
void q_omg_shallow_free_PublicationBuiltinTopicDataSecure(DDS_Security_PublicationBuiltinTopicDataSecure *obj);
|
||||
void q_omg_shallow_copy_TopicBuiltinTopicData(DDS_Security_TopicBuiltinTopicData *dst, const char *topic_name, const char *type_name);
|
||||
void q_omg_shallow_free_TopicBuiltinTopicData(DDS_Security_TopicBuiltinTopicData *obj);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#endif /* DDSI_SECURITY_UTIL_H */
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
#include "dds/ddsrt/sockets.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
#include "dds/ddsi/ddsi_keyhash.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nn_rdata;
|
||||
struct nn_keyhash;
|
||||
|
||||
enum ddsi_serdata_kind {
|
||||
SDK_EMPTY,
|
||||
|
@ -64,7 +64,7 @@ typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_t) (const struct ddsi_sert
|
|||
typedef struct ddsi_serdata * (*ddsi_serdata_from_ser_iov_t) (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size);
|
||||
|
||||
/* Construct a serdata from a keyhash (an SDK_KEY by definition) */
|
||||
typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash);
|
||||
typedef struct ddsi_serdata * (*ddsi_serdata_from_keyhash_t) (const struct ddsi_sertopic *topic, const struct ddsi_keyhash *keyhash);
|
||||
|
||||
/* Construct a serdata from an application sample
|
||||
- "kind" is KEY or DATA depending on the operation invoked by the application;
|
||||
|
@ -134,7 +134,10 @@ typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct
|
|||
returning bufsize-1) if it had to truncate) */
|
||||
typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, char *buf, size_t size);
|
||||
|
||||
#define DDSI_SERDATA_HAS_FROM_SER_IOV 1
|
||||
/* Add keyhash (from serdata) to buffer (forcing md5 when necessary).
|
||||
- key needs to be set within serdata (can already be md5)
|
||||
- buf needs to be at least 16 bytes large */
|
||||
typedef void (*ddsi_serdata_get_keyhash_t) (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5);
|
||||
|
||||
struct ddsi_serdata_ops {
|
||||
ddsi_serdata_eqkey_t eqkey;
|
||||
|
@ -151,9 +154,12 @@ struct ddsi_serdata_ops {
|
|||
ddsi_serdata_topicless_to_sample_t topicless_to_sample;
|
||||
ddsi_serdata_free_t free;
|
||||
ddsi_serdata_print_t print;
|
||||
ddsi_serdata_get_keyhash_t get_keyhash;
|
||||
};
|
||||
|
||||
#define DDSI_SERDATA_HAS_PRINT 1
|
||||
#define DDSI_SERDATA_HAS_FROM_SER_IOV 1
|
||||
#define DDSI_SERDATA_HAS_GET_KEYHASH 1
|
||||
|
||||
DDS_EXPORT void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertopic *tp, enum ddsi_serdata_kind kind);
|
||||
|
||||
|
@ -180,7 +186,7 @@ DDS_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct d
|
|||
return topic->serdata_ops->from_ser_iov (topic, kind, niov, iov, size);
|
||||
}
|
||||
|
||||
DDS_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash) {
|
||||
DDS_EXPORT inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct ddsi_keyhash *keyhash) {
|
||||
return topic->serdata_ops->from_keyhash (topic, keyhash);
|
||||
}
|
||||
|
||||
|
@ -230,6 +236,10 @@ DDS_EXPORT inline bool ddsi_serdata_print_topicless (const struct ddsi_sertopic
|
|||
}
|
||||
}
|
||||
|
||||
DDS_EXPORT inline void ddsi_serdata_get_keyhash (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5) {
|
||||
d->ops->get_keyhash (d, buf, force_md5);
|
||||
}
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dds/ddsrt/avl.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||
|
||||
#include "dds/dds.h"
|
||||
|
||||
|
@ -46,6 +47,7 @@ typedef struct dds_keyhash {
|
|||
unsigned char m_hash [16]; /* Key hash value. Also possibly key. Suitably aligned for accessing as uint32_t's */
|
||||
unsigned m_set : 1; /* has it been initialised? */
|
||||
unsigned m_iskey : 1; /* m_hash is key value */
|
||||
unsigned m_keysize : 5; /* size of the key within the hash buffer */
|
||||
} dds_keyhash_t;
|
||||
|
||||
/* Debug builds may want to keep some additional state */
|
||||
|
@ -135,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_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);
|
||||
void ddsi_serdatapool_free (struct serdatapool * pool);
|
||||
|
|
76
src/core/ddsi/include/dds/ddsi/ddsi_serdata_plist.h
Normal file
76
src/core/ddsi/include/dds/ddsi/ddsi_serdata_plist.h
Normal 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
|
78
src/core/ddsi/include/dds/ddsi/ddsi_serdata_pserop.h
Normal file
78
src/core/ddsi/include/dds/ddsi/ddsi_serdata_pserop.h
Normal 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
|
|
@ -322,6 +322,13 @@ DDS_EXPORT void ddsi_xqos_addtomsg (struct nn_xmsg *m, const dds_qos_t *xqos, ui
|
|||
DDS_EXPORT void ddsi_xqos_log (uint32_t cat, const struct ddsrt_log_cfg *logcfg, const dds_qos_t *xqos);
|
||||
DDS_EXPORT size_t ddsi_xqos_print (char * __restrict buf, size_t bufsize, const dds_qos_t *xqos);
|
||||
DDS_EXPORT dds_qos_t *ddsi_xqos_dup (const dds_qos_t *src);
|
||||
DDS_EXPORT bool ddsi_xqos_has_prop_prefix (const dds_qos_t *xqos, const char *nameprefix);
|
||||
DDS_EXPORT bool ddsi_xqos_find_prop (const dds_qos_t *xqos, const char *name, const char **value);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct omg_security_configuration_type;
|
||||
DDS_EXPORT void ddsi_xqos_mergein_security_config (dds_qos_t *xqos, const struct omg_security_configuration_type *cfg);
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ ddsi_guid_prefix_t nn_hton_guid_prefix (ddsi_guid_prefix_t p);
|
|||
ddsi_guid_prefix_t nn_ntoh_guid_prefix (ddsi_guid_prefix_t p);
|
||||
ddsi_entityid_t nn_hton_entityid (ddsi_entityid_t e);
|
||||
ddsi_entityid_t nn_ntoh_entityid (ddsi_entityid_t e);
|
||||
ddsi_guid_t nn_hton_guid (ddsi_guid_t g);
|
||||
ddsi_guid_t nn_ntoh_guid (ddsi_guid_t g);
|
||||
DDS_EXPORT ddsi_guid_t nn_hton_guid (ddsi_guid_t g);
|
||||
DDS_EXPORT ddsi_guid_t nn_ntoh_guid (ddsi_guid_t g);
|
||||
|
||||
void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_t *snset);
|
||||
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_header_t *snset, uint32_t *bits);
|
||||
|
|
|
@ -161,6 +161,42 @@ enum many_sockets_mode {
|
|||
MSM_MANY_UNICAST
|
||||
};
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
typedef struct plugin_library_properties_type{
|
||||
char *library_path;
|
||||
char *library_init;
|
||||
char *library_finalize;
|
||||
} plugin_library_properties_type;
|
||||
|
||||
typedef struct authentication_properties_type{
|
||||
char *identity_certificate;
|
||||
char *identity_ca;
|
||||
char *private_key;
|
||||
char *password;
|
||||
char *trusted_ca_dir;
|
||||
int include_optional_fields;
|
||||
} authentication_properties_type;
|
||||
|
||||
typedef struct access_control_properties_type{
|
||||
char *permissions;
|
||||
char *permissions_ca;
|
||||
char *governance;
|
||||
} access_control_properties_type;
|
||||
|
||||
typedef struct omg_security_configuration_type {
|
||||
authentication_properties_type authentication_properties;
|
||||
access_control_properties_type access_control_properties;
|
||||
plugin_library_properties_type authentication_plugin;
|
||||
plugin_library_properties_type access_control_plugin;
|
||||
plugin_library_properties_type cryptography_plugin;
|
||||
} omg_security_configuration_type;
|
||||
|
||||
struct config_omg_security_listelem {
|
||||
struct config_omg_security_listelem *next;
|
||||
omg_security_configuration_type cfg;
|
||||
};
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
struct ssl_min_version {
|
||||
int major;
|
||||
|
@ -226,8 +262,6 @@ struct config
|
|||
|
||||
unsigned delivery_queue_maxsamples;
|
||||
|
||||
int do_topic_discovery;
|
||||
|
||||
uint32_t max_msg_size;
|
||||
uint32_t fragment_size;
|
||||
|
||||
|
@ -333,6 +367,10 @@ struct config
|
|||
|
||||
int use_multicast_if_mreqn;
|
||||
struct prune_deleted_ppant prune_deleted_ppant;
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct config_omg_security_listelem *omg_security_configuration;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cfgst;
|
||||
|
|
|
@ -25,6 +25,12 @@ struct nn_rsample_info;
|
|||
struct nn_rdata;
|
||||
struct ddsi_plist;
|
||||
|
||||
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_dispose_unregister (struct participant *pp);
|
||||
|
||||
|
@ -33,8 +39,6 @@ int sedp_write_reader (struct reader *rd);
|
|||
int sedp_dispose_unregister_writer (struct writer *wr);
|
||||
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);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
|
|
@ -18,11 +18,14 @@
|
|||
#include "dds/ddsrt/fibheap.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsi/q_rtps.h"
|
||||
#include "dds/ddsi/ddsi_plist.h"
|
||||
#include "dds/ddsi/q_protocol.h"
|
||||
#include "dds/ddsi/q_lat_estim.h"
|
||||
#include "dds/ddsi/q_hbcontrol.h"
|
||||
#include "dds/ddsi/q_feature_check.h"
|
||||
#include "dds/ddsi/q_inverse_uint32_set.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||
#include "dds/ddsi/ddsi_handshake.h"
|
||||
|
||||
#include "dds/ddsi/ddsi_tran.h"
|
||||
|
||||
|
@ -42,6 +45,10 @@ struct whc;
|
|||
struct dds_qos;
|
||||
struct ddsi_plist;
|
||||
struct lease;
|
||||
struct participant_sec_attributes;
|
||||
struct proxy_participant_sec_attributes;
|
||||
struct writer_sec_attributes;
|
||||
struct reader_sec_attributes;
|
||||
|
||||
struct proxy_group;
|
||||
struct proxy_endpoint_common;
|
||||
|
@ -80,6 +87,9 @@ typedef void (*status_cb_t) (void *entity, const status_cb_data_t *data);
|
|||
struct prd_wr_match {
|
||||
ddsrt_avl_node_t avlnode;
|
||||
ddsi_guid_t wr_guid;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
int64_t crypto_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rd_pwr_match {
|
||||
|
@ -91,6 +101,9 @@ struct rd_pwr_match {
|
|||
nn_locator_t ssm_mc_loc;
|
||||
nn_locator_t ssm_src_loc;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
int64_t crypto_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct wr_rd_match {
|
||||
|
@ -115,6 +128,7 @@ struct wr_prd_match {
|
|||
seqno_t min_seq; /* smallest ack'd seq nr in subtree */
|
||||
seqno_t max_seq; /* sort-of highest ack'd seq nr in subtree (see augment function) */
|
||||
seqno_t seq; /* highest acknowledged seq nr */
|
||||
seqno_t last_seq; /* highest seq send to this reader used when filter is applied */
|
||||
int32_t num_reliable_readers_where_seq_equals_max;
|
||||
ddsi_guid_t arbitrary_unacked_reader;
|
||||
nn_count_t next_acknack; /* next acceptable acknack sequence number */
|
||||
|
@ -124,6 +138,9 @@ struct wr_prd_match {
|
|||
ddsrt_wctime_t hb_to_ack_latency_tlastlog;
|
||||
uint32_t non_responsive_count;
|
||||
uint32_t rexmit_requests;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
int64_t crypto_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum pwr_rd_match_syncstate {
|
||||
|
@ -142,14 +159,19 @@ struct pwr_rd_match {
|
|||
ddsrt_etime_t t_heartbeat_accepted; /* (local) time a heartbeat was last accepted */
|
||||
ddsrt_mtime_t t_last_nack; /* (local) time we last sent a NACK */ /* FIXME: probably elapsed time is better */
|
||||
seqno_t seq_last_nack; /* last seq for which we requested a retransmit */
|
||||
seqno_t last_seq; /* last known sequence number from this writer */
|
||||
struct xevent *acknack_xevent; /* entry in xevent queue for sending acknacks */
|
||||
enum pwr_rd_match_syncstate in_sync; /* whether in sync with the proxy writer */
|
||||
unsigned filtered:1;
|
||||
union {
|
||||
struct {
|
||||
seqno_t end_of_tl_seq; /* when seq >= end_of_tl_seq, it's in sync, =0 when not tl */
|
||||
struct nn_reorder *reorder; /* can be done (mostly) per proxy writer, but that is harder; only when state=OUT_OF_SYNC */
|
||||
} not_in_sync;
|
||||
} u;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
int64_t crypto_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nn_rsample_info;
|
||||
|
@ -209,8 +231,12 @@ struct participant
|
|||
int32_t builtin_refc; /* number of built-in endpoints in this participant [refc_lock] */
|
||||
int builtins_deleted; /* whether deletion of built-in endpoints has been initiated [refc_lock] */
|
||||
ddsrt_fibheap_t ldur_auto_wr; /* Heap that contains lease duration for writers with automatic liveliness in this participant */
|
||||
ddsrt_atomic_voidp_t minl_man; /* lease object for shortest manual-by-participant liveliness writer's lease */
|
||||
ddsrt_atomic_voidp_t minl_man; /* clone of min(leaseheap_man) */
|
||||
ddsrt_fibheap_t leaseheap_man; /* keeps leases for this participant's writers (with liveliness manual-by-participant) */
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct participant_sec_attributes *sec_attr;
|
||||
nn_security_info_t security_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct endpoint_common {
|
||||
|
@ -257,6 +283,7 @@ struct writer
|
|||
unsigned reliable: 1; /* iff 1, writer is reliable <=> heartbeat_xevent != NULL */
|
||||
unsigned handle_as_transient_local: 1; /* controls whether data is retained in WHC */
|
||||
unsigned include_keyhash: 1; /* iff 1, this writer includes a keyhash; keyless topics => include_keyhash = 0 */
|
||||
unsigned force_md5_keyhash: 1; /* iff 1, when keyhash has to be hashed, no matter the size */
|
||||
unsigned retransmitting: 1; /* iff 1, this writer is currently retransmitting */
|
||||
unsigned alive: 1; /* iff 1, the writer is alive (lease for this writer is not expired); field may be modified only when holding both wr->e.lock and wr->c.pp->e.lock */
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
|
@ -264,7 +291,7 @@ struct writer
|
|||
struct addrset *ssm_as;
|
||||
#endif
|
||||
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_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 */
|
||||
|
@ -273,6 +300,7 @@ struct writer
|
|||
uint32_t whc_low, whc_high; /* watermarks for WHC in bytes (counting only unack'd data) */
|
||||
ddsrt_etime_t t_rexmit_end; /* time of last 1->0 transition of "retransmitting" */
|
||||
ddsrt_etime_t t_whc_high_upd; /* time "whc_high" was last updated for controlled ramp-up of throughput */
|
||||
uint32_t num_readers; /* total number of matching PROXY readers */
|
||||
int32_t num_reliable_readers; /* number of matching reliable PROXY readers */
|
||||
ddsrt_avl_tree_t readers; /* all matching PROXY readers, see struct wr_prd_match */
|
||||
ddsrt_avl_tree_t local_readers; /* all matching LOCAL readers, see struct wr_rd_match */
|
||||
|
@ -288,6 +316,9 @@ struct writer
|
|||
struct xeventq *evq; /* timed event queue to be used by this writer */
|
||||
struct local_reader_ary rdary; /* LOCAL readers for fast-pathing; if not fast-pathed, fall back to scanning local_readers */
|
||||
struct lease *lease; /* for liveliness administration (writer can only become inactive when using manual liveliness) */
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct writer_sec_attributes *sec_attr;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline seqno_t writer_read_seq_xmit (const struct writer *wr) {
|
||||
|
@ -319,11 +350,15 @@ struct reader
|
|||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
struct addrset *as;
|
||||
#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 */
|
||||
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 */
|
||||
ddsi2direct_directread_cb_t ddsi2direct_cb;
|
||||
void *ddsi2direct_cbarg;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct reader_sec_attributes *sec_attr;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct proxy_participant
|
||||
|
@ -334,9 +369,9 @@ struct proxy_participant
|
|||
unsigned bes; /* built-in endpoint set */
|
||||
ddsi_guid_t privileged_pp_guid; /* if this PP depends on another PP for its SEDP writing */
|
||||
struct ddsi_plist *plist; /* settings/QoS for this participant */
|
||||
ddsrt_atomic_voidp_t minl_auto; /* lease object for shortest automatic liveliness pwr's lease (includes this proxypp's lease) */
|
||||
ddsrt_atomic_voidp_t minl_auto; /* clone of min(leaseheap_auto) */
|
||||
ddsrt_fibheap_t leaseheap_auto; /* keeps leases for this proxypp and leases for pwrs (with liveliness automatic) */
|
||||
ddsrt_atomic_voidp_t minl_man; /* lease object for shortest manual-by-participant liveliness pwr's lease */
|
||||
ddsrt_atomic_voidp_t minl_man; /* clone of min(leaseheap_man) */
|
||||
ddsrt_fibheap_t leaseheap_man; /* keeps leases for this proxypp and leases for pwrs (with liveliness manual-by-participant) */
|
||||
struct lease *lease; /* lease for this proxypp */
|
||||
struct addrset *as_default; /* default address set to use for user data traffic */
|
||||
|
@ -344,7 +379,6 @@ struct proxy_participant
|
|||
struct proxy_endpoint_common *endpoints; /* all proxy endpoints can be reached from here */
|
||||
ddsrt_avl_tree_t groups; /* table of all groups (publisher, subscriber), see struct proxy_group */
|
||||
seqno_t seq; /* sequence number of most recent SPDP message */
|
||||
unsigned kernel_sequence_numbers : 1; /* whether this proxy participant generates OSPL kernel sequence numbers */
|
||||
unsigned implicitly_created : 1; /* participants are implicitly created for Cloud/Fog discovered endpoints */
|
||||
unsigned is_ddsi2_pp: 1; /* if this is the federation-leader on the remote node */
|
||||
unsigned minimal_bes_mode: 1;
|
||||
|
@ -352,6 +386,10 @@ struct proxy_participant
|
|||
unsigned deleting: 1;
|
||||
unsigned proxypp_have_spdp: 1;
|
||||
unsigned owns_lease: 1;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
nn_security_info_t security_info;
|
||||
struct proxy_participant_sec_attributes *sec_attr;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Representing proxy subscriber & publishers as "groups": until DDSI2
|
||||
|
@ -379,6 +417,9 @@ struct proxy_endpoint_common
|
|||
ddsi_guid_t group_guid; /* 0:0:0:0 if not available */
|
||||
nn_vendorid_t vendor; /* cached from proxypp->vendor */
|
||||
seqno_t seq; /* sequence number of most recent SEDP message */
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
nn_security_info_t security_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct generic_proxy_endpoint {
|
||||
|
@ -401,6 +442,7 @@ struct proxy_writer {
|
|||
unsigned have_seen_heartbeat: 1; /* iff 1, we have received at least on heartbeat from this proxy writer */
|
||||
unsigned local_matching_inprogress: 1; /* iff 1, we are still busy matching local readers; this is so we don't deliver incoming data to some but not all readers initially */
|
||||
unsigned alive: 1; /* iff 1, the proxy writer is alive (lease for this proxy writer is not expired); field may be modified only when holding both pwr->e.lock and pwr->c.proxypp->e.lock */
|
||||
unsigned filtered: 1; /* iff 1, builtin proxy writer uses content filter, which affects heartbeats and gaps. */
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
unsigned supports_ssm: 1; /* iff 1, this proxy writer supports SSM */
|
||||
#endif
|
||||
|
@ -415,6 +457,9 @@ struct proxy_writer {
|
|||
struct lease *lease;
|
||||
};
|
||||
|
||||
|
||||
typedef int (*filter_fn_t)(struct writer *wr, struct proxy_reader *prd, struct ddsi_serdata *serdata);
|
||||
|
||||
struct proxy_reader {
|
||||
struct entity_common e;
|
||||
struct proxy_endpoint_common c;
|
||||
|
@ -424,6 +469,7 @@ struct proxy_reader {
|
|||
unsigned favours_ssm: 1; /* iff 1, this proxy reader favours SSM when available */
|
||||
#endif
|
||||
ddsrt_avl_tree_t writers; /* matching LOCAL writers */
|
||||
filter_fn_t filter;
|
||||
};
|
||||
|
||||
DDS_EXPORT extern const ddsrt_avl_treedef_t wr_readers_treedef;
|
||||
|
@ -507,8 +553,8 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e);
|
|||
/**
|
||||
* @brief Create a new participant with a given GUID in the domain.
|
||||
*
|
||||
* @param[in] ppguid
|
||||
* The GUID of the new participant.
|
||||
* @param[in,out] ppguid
|
||||
* The GUID of the new participant, may be adjusted by security.
|
||||
* @param[in] flags
|
||||
* Zero or more of:
|
||||
* - RTPS_PF_NO_BUILTIN_READERS do not create discovery readers in new ppant
|
||||
|
@ -529,7 +575,7 @@ nn_vendorid_t get_entity_vendorid (const struct entity_common *e);
|
|||
* @retval DDS_RETCODE_OUT_OF_RESOURCES
|
||||
* The configured maximum number of participants has been reached.
|
||||
*/
|
||||
dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const struct ddsi_plist *plist);
|
||||
dds_return_t new_participant_guid (ddsi_guid_t *ppguid, struct ddsi_domaingv *gv, unsigned flags, const struct ddsi_plist *plist);
|
||||
|
||||
/**
|
||||
* @brief Create a new participant in the domain. See also new_participant_guid.
|
||||
|
@ -596,9 +642,8 @@ DDS_EXPORT struct writer *get_builtin_writer (const struct participant *pp, unsi
|
|||
GUID "ppguid". May return NULL if participant unknown or
|
||||
writer/reader already known. */
|
||||
|
||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_domaingv *gv, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, const struct ddsi_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
|
||||
|
||||
dds_return_t new_reader (struct reader **rd_out, struct ddsi_domaingv *gv, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, const struct ddsi_guid *ppguid, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct ddsi_rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
|
||||
dds_return_t new_writer (struct writer **wr_out, struct ddsi_guid *wrguid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct whc * whc, status_cb_t status_cb, void *status_cb_arg);
|
||||
dds_return_t new_reader (struct reader **rd_out, struct ddsi_guid *rdguid, const struct ddsi_guid *group_guid, struct participant *pp, const struct ddsi_sertopic *topic, const struct dds_qos *xqos, struct ddsi_rhc * rhc, status_cb_t status_cb, void *status_cb_arg);
|
||||
|
||||
void update_reader_qos (struct reader *rd, const struct dds_qos *xqos);
|
||||
void update_writer_qos (struct writer *wr, const struct dds_qos *xqos);
|
||||
|
@ -610,7 +655,7 @@ seqno_t writer_max_drop_seq (const struct writer *wr);
|
|||
int writer_must_have_hb_scheduled (const struct writer *wr, const struct whc_state *whcst);
|
||||
void writer_set_retransmitting (struct writer *wr);
|
||||
void writer_clear_retransmitting (struct writer *wr);
|
||||
dds_return_t writer_wait_for_acks (struct writer *wr, dds_time_t abstimeout);
|
||||
dds_return_t writer_wait_for_acks (struct writer *wr, const ddsi_guid_t *rdguid, dds_time_t abstimeout);
|
||||
|
||||
dds_return_t unblock_throttled_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid);
|
||||
dds_return_t delete_writer (struct ddsi_domaingv *gv, const struct ddsi_guid *guid);
|
||||
|
@ -638,22 +683,20 @@ int writer_set_notalive (struct writer *wr, bool notify);
|
|||
XX --
|
||||
*/
|
||||
|
||||
/* Set this custom flag when using nn_adlink_writer_info_t iso nn_adlink_writer_info_old_t */
|
||||
#define CF_INC_KERNEL_SEQUENCE_NUMBERS (1 << 0)
|
||||
/* Set when this proxy participant is created implicitly and has to be deleted upon disappearance
|
||||
of its last endpoint. FIXME: Currently there is a potential race with adding a new endpoint
|
||||
in parallel to deleting the last remaining one. The endpoint will then be created, added to the
|
||||
proxy participant and then both are deleted. With the current single-threaded discovery
|
||||
this can only happen when it is all triggered by lease expiry. */
|
||||
#define CF_IMPLICITLY_CREATED_PROXYPP (1 << 1)
|
||||
#define CF_IMPLICITLY_CREATED_PROXYPP (1 << 0)
|
||||
/* Set when this proxy participant is a DDSI2 participant, to help Cloud figure out whom to send
|
||||
discovery data when used in conjunction with the networking bridge */
|
||||
#define CF_PARTICIPANT_IS_DDSI2 (1 << 2)
|
||||
#define CF_PARTICIPANT_IS_DDSI2 (1 << 1)
|
||||
/* Set when this proxy participant is not to be announced on the built-in topics yet */
|
||||
#define CF_PROXYPP_NO_SPDP (1 << 3)
|
||||
#define CF_PROXYPP_NO_SPDP (1 << 2)
|
||||
|
||||
void new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, seqno_t seq);
|
||||
int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
|
||||
bool new_proxy_participant (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, uint32_t bes, const struct ddsi_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct ddsi_plist *plist, dds_duration_t tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, ddsrt_wctime_t timestamp, seqno_t seq);
|
||||
DDS_EXPORT int delete_proxy_participant_by_guid (struct ddsi_domaingv *gv, const struct ddsi_guid *guid, ddsrt_wctime_t timestamp, int isimplicit);
|
||||
|
||||
int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp);
|
||||
int update_proxy_participant_plist (struct proxy_participant *proxypp, seqno_t seq, const struct ddsi_plist *datap, ddsrt_wctime_t timestamp);
|
||||
|
@ -696,6 +739,10 @@ void rebuild_or_clear_writer_addrsets(struct ddsi_domaingv *gv, int rebuild);
|
|||
|
||||
void local_reader_ary_setfastpath_ok (struct local_reader_ary *x, bool fastpath_ok);
|
||||
|
||||
void connect_writer_with_proxy_reader_secure(struct writer *wr, struct proxy_reader *prd, ddsrt_mtime_t tnow, int64_t crypto_handle);
|
||||
void connect_reader_with_proxy_writer_secure(struct reader *rd, struct proxy_writer *pwr, ddsrt_mtime_t tnow, int64_t crypto_handle);
|
||||
|
||||
|
||||
struct ddsi_writer_info;
|
||||
DDS_EXPORT void ddsi_make_writer_info(struct ddsi_writer_info *wrinfo, const struct entity_common *e, const struct dds_qos *xqos, uint32_t statusinfo);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ extern "C" {
|
|||
|
||||
struct writer;
|
||||
struct whc_state;
|
||||
struct proxy_reader;
|
||||
|
||||
struct hbcontrol {
|
||||
ddsrt_mtime_t t_of_last_write;
|
||||
|
@ -36,6 +37,11 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
|
|||
int writer_hbcontrol_must_send (const struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow);
|
||||
struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, int hbansreq, int issync);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct nn_xmsg *writer_hbcontrol_p2p(struct writer *wr, const struct whc_state *whcst, int hbansreq, struct proxy_reader *prd);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,8 +28,8 @@ struct ddsi_domaingv; /* FIXME: make a special for the lease admin */
|
|||
struct lease {
|
||||
ddsrt_fibheap_node_t heapnode;
|
||||
ddsrt_fibheap_node_t pp_heapnode;
|
||||
ddsrt_etime_t tsched; /* access guarded by leaseheap_lock */
|
||||
ddsrt_atomic_uint64_t tend; /* really an nn_etime_t */
|
||||
ddsrt_etime_t tsched; /* access guarded by leaseheap_lock */
|
||||
ddsrt_atomic_uint64_t tend; /* really an ddsrt_etime_t */
|
||||
dds_duration_t tdur; /* constant (renew depends on it) */
|
||||
struct entity_common *entity; /* constant */
|
||||
};
|
||||
|
|
|
@ -35,7 +35,10 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr);
|
|||
int WildcardOverlap(char * p1, char * p2);
|
||||
#endif
|
||||
|
||||
int ddsi2_patmatch (const char *pat, const char *str);
|
||||
DDS_EXPORT bool guid_prefix_zero (const ddsi_guid_prefix_t *a);
|
||||
DDS_EXPORT int guid_prefix_eq (const ddsi_guid_prefix_t *a, const ddsi_guid_prefix_t *b);
|
||||
DDS_EXPORT int guid_eq (const struct ddsi_guid *a, const struct ddsi_guid *b);
|
||||
DDS_EXPORT int ddsi2_patmatch (const char *pat, const char *str);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -89,13 +89,21 @@ typedef struct {
|
|||
#define NN_DISC_BUILTIN_ENDPOINT_TOPIC_ANNOUNCER (1u << 12)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_TOPIC_DETECTOR (1u << 13)
|
||||
|
||||
/* Adlink extensions: */
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_WRITER (1u << 0)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_READER (1u << 1)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER (1u << 2)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_READER (1u << 3)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER (1u << 4)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_READER (1u << 5)
|
||||
/* Security extensions: */
|
||||
#define NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_ANNOUNCER (1u<<16)
|
||||
#define NN_BUILTIN_ENDPOINT_PUBLICATION_MESSAGE_SECURE_DETECTOR (1u<<17)
|
||||
#define NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_ANNOUNCER (1u<<18)
|
||||
#define NN_BUILTIN_ENDPOINT_SUBSCRIPTION_MESSAGE_SECURE_DETECTOR (1u<<19)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_ANNOUNCER (1u<<20)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_SECURE_DETECTOR (1u<<21)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_ANNOUNCER (1u<<22)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_STATELESS_MESSAGE_DETECTOR (1u<<23)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_ANNOUNCER (1u<<24)
|
||||
#define NN_BUILTIN_ENDPOINT_PARTICIPANT_VOLATILE_SECURE_DETECTOR (1u<<25)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_ANNOUNCER (1u << 26)
|
||||
#define NN_DISC_BUILTIN_ENDPOINT_PARTICIPANT_SECURE_DETECTOR (1u << 27)
|
||||
|
||||
#define NN_BES_MASK_NON_SECURITY 0xf000ffffu
|
||||
|
||||
#define NN_LOCATOR_KIND_INVALID -1
|
||||
#define NN_LOCATOR_KIND_RESERVED 0
|
||||
|
@ -149,6 +157,12 @@ typedef enum SubmessageKind {
|
|||
SMID_HEARTBEAT_FRAG = 0x13,
|
||||
SMID_DATA = 0x15,
|
||||
SMID_DATA_FRAG = 0x16,
|
||||
/* security-specific sub messages */
|
||||
SMID_SEC_BODY = 0x30,
|
||||
SMID_SEC_PREFIX = 0x31,
|
||||
SMID_SEC_POSTFIX = 0x32,
|
||||
SMID_SRTPS_PREFIX = 0x33,
|
||||
SMID_SRTPS_POSTFIX = 0x34,
|
||||
/* vendor-specific sub messages (0x80 .. 0xff) */
|
||||
SMID_ADLINK_MSG_LEN = 0x81,
|
||||
SMID_ADLINK_ENTITY_ID = 0x82
|
||||
|
@ -189,7 +203,7 @@ typedef uint16_t nn_parameterid_t; /* spec says short */
|
|||
typedef struct nn_parameter {
|
||||
nn_parameterid_t parameterid;
|
||||
uint16_t length; /* spec says signed short */
|
||||
/* char value[]; O! how I long for C99 */
|
||||
/* char value[] */
|
||||
} nn_parameter_t;
|
||||
|
||||
typedef struct Data_DataFrag_common {
|
||||
|
@ -304,18 +318,10 @@ typedef union Submessage {
|
|||
NackFrag_t nackfrag;
|
||||
} 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_AUTOMATIC_LIVELINESS_UPDATE 0x1u
|
||||
#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_UNRECOGNIZED_INCOMPATIBLE_FLAG 0x4000u
|
||||
|
@ -384,6 +390,10 @@ DDSRT_WARNING_MSVC_ON(4200)
|
|||
/* Security related PID values. */
|
||||
#define PID_IDENTITY_TOKEN 0x1001u
|
||||
#define PID_PERMISSIONS_TOKEN 0x1002u
|
||||
#define PID_DATA_TAGS 0x1003u
|
||||
#define PID_ENDPOINT_SECURITY_INFO 0x1004u
|
||||
#define PID_PARTICIPANT_SECURITY_INFO 0x1005u
|
||||
#define PID_IDENTITY_STATUS_TOKEN 0x1006u
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
/* To indicate whether a reader favours the use of SSM. Iff the
|
||||
|
|
|
@ -110,10 +110,11 @@ whichever is larger. */
|
|||
#define ALIGNOF_RMSG (sizeof(void *) > 8 ? sizeof(void *) : 8)
|
||||
|
||||
struct receiver_state {
|
||||
ddsi_guid_prefix_t src_guid_prefix; /* 12 */
|
||||
ddsi_guid_prefix_t dst_guid_prefix; /* 12 */
|
||||
ddsi_guid_prefix_t src_guid_prefix; /* 12 */
|
||||
ddsi_guid_prefix_t dst_guid_prefix; /* 12 */
|
||||
struct addrset *reply_locators; /* 4/8 */
|
||||
int forme; /* 4 */
|
||||
uint32_t forme:1; /* 4 */
|
||||
uint32_t rtps_encoded:1; /* - */
|
||||
nn_vendorid_t vendor; /* 2 */
|
||||
nn_protocol_version_t protocol_version; /* 2 => 44/48 */
|
||||
ddsi_tran_conn_t conn; /* Connection for request */
|
||||
|
@ -223,6 +224,7 @@ void nn_defrag_free (struct nn_defrag *defrag);
|
|||
struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata *rdata, const struct nn_rsample_info *sampleinfo);
|
||||
void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1);
|
||||
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz);
|
||||
void nn_defrag_prune (struct nn_defrag *defrag, ddsi_guid_prefix_t *dst, seqno_t min);
|
||||
|
||||
struct nn_reorder *nn_reorder_new (const struct ddsrt_log_cfg *logcfg, enum nn_reorder_mode mode, uint32_t max_samples, bool late_ack_mode);
|
||||
void nn_reorder_free (struct nn_reorder *r);
|
||||
|
@ -233,6 +235,7 @@ nn_reorder_result_t nn_reorder_gap (struct nn_rsample_chain *sc, struct nn_reord
|
|||
int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq);
|
||||
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail);
|
||||
seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder);
|
||||
void nn_reorder_set_next_seq (struct nn_reorder *reorder, seqno_t seq);
|
||||
|
||||
struct nn_dqueue *nn_dqueue_new (const char *name, const struct ddsi_domaingv *gv, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg);
|
||||
void nn_dqueue_free (struct nn_dqueue *q);
|
||||
|
|
|
@ -21,11 +21,25 @@ struct nn_rsample_info;
|
|||
struct nn_rdata;
|
||||
struct ddsi_tran_listener;
|
||||
struct recv_thread_arg;
|
||||
struct writer;
|
||||
struct proxy_reader;
|
||||
|
||||
struct nn_gap_info {
|
||||
int64_t gapstart;
|
||||
int64_t gapend;
|
||||
unsigned gapnumbits;
|
||||
unsigned gapbits[256 / 32];
|
||||
};
|
||||
|
||||
void nn_gap_info_init(struct nn_gap_info *gi);
|
||||
void nn_gap_info_update(struct ddsi_domaingv *gv, struct nn_gap_info *gi, int64_t seqnr);
|
||||
struct nn_xmsg * nn_gap_info_create_gap(struct writer *wr, struct proxy_reader *prd, struct nn_gap_info *gi);
|
||||
|
||||
void trigger_recv_threads (const struct ddsi_domaingv *gv);
|
||||
uint32_t recv_thread (void *vrecv_thread_arg);
|
||||
uint32_t listen_thread (struct ddsi_tran_listener * listener);
|
||||
int user_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const ddsi_guid_t *rdguid, void *qarg);
|
||||
int add_Gap (struct nn_xmsg *msg, struct writer *wr, struct proxy_reader *prd, seqno_t start, seqno_t base, uint32_t numbits, const uint32_t *bits);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -45,6 +45,20 @@ typedef int64_t seqno_t;
|
|||
#define NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER 0x100c7
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER 0x200c2
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER 0x200c7
|
||||
|
||||
#define NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER 0xff0003c2
|
||||
#define NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER 0xff0003c7
|
||||
#define NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER 0xff0004c2
|
||||
#define NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER 0xff0004c7
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER 0x201c3
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER 0x201c4
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER 0xff0200c2
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER 0xff0200c7
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER 0xff0202c3
|
||||
#define NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER 0xff0202c4
|
||||
#define NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER 0xff0101c2
|
||||
#define NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER 0xff0101c7
|
||||
|
||||
#define NN_ENTITYID_SOURCE_MASK 0xc0
|
||||
#define NN_ENTITYID_SOURCE_USER 0x00
|
||||
#define NN_ENTITYID_SOURCE_BUILTIN 0xc0
|
||||
|
|
|
@ -44,6 +44,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
|||
int enqueue_sample_wrlock_held (struct writer *wr, seqno_t seq, const struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct proxy_reader *prd, int isnew);
|
||||
void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_state *whcst, int hbansreq, int hbliveliness, ddsi_entityid_t dst, int issync);
|
||||
dds_return_t write_hb_liveliness (struct ddsi_domaingv * const gv, struct ddsi_guid *wr_guid, struct nn_xpack *xp);
|
||||
int write_sample_p2p_wrlock_held(struct writer *wr, seqno_t seq, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk, struct proxy_reader *prd);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
|
|
@ -50,8 +50,10 @@ DDS_EXPORT dds_return_t xeventq_start (struct xeventq *evq, const char *name); /
|
|||
DDS_EXPORT void xeventq_stop (struct xeventq *evq);
|
||||
|
||||
DDS_EXPORT void qxev_msg (struct xeventq *evq, struct nn_xmsg *msg);
|
||||
DDS_EXPORT void qxev_pwr_entityid (struct proxy_writer * pwr, ddsi_guid_prefix_t * id);
|
||||
DDS_EXPORT void qxev_prd_entityid (struct proxy_reader * prd, ddsi_guid_prefix_t * id);
|
||||
|
||||
DDS_EXPORT void qxev_pwr_entityid (struct proxy_writer * pwr, const ddsi_guid_t *guid);
|
||||
DDS_EXPORT void qxev_prd_entityid (struct proxy_reader * prd, const ddsi_guid_t *guid);
|
||||
DDS_EXPORT void qxev_nt_callback (struct xeventq *evq, void (*cb) (void *arg), void *arg);
|
||||
|
||||
/* Returns 1 if queued, 0 otherwise (no point in returning the
|
||||
event, you can't do anything with it anyway) */
|
||||
|
|
|
@ -26,6 +26,8 @@ struct ddsi_serdata;
|
|||
struct addrset;
|
||||
struct proxy_reader;
|
||||
struct proxy_writer;
|
||||
struct writer;
|
||||
struct participant;
|
||||
|
||||
struct nn_adlink_participant_version_info;
|
||||
struct nn_xmsgpool;
|
||||
|
@ -41,7 +43,8 @@ struct nn_xmsg_marker {
|
|||
enum nn_xmsg_kind {
|
||||
NN_XMSG_KIND_CONTROL,
|
||||
NN_XMSG_KIND_DATA,
|
||||
NN_XMSG_KIND_DATA_REXMIT
|
||||
NN_XMSG_KIND_DATA_REXMIT,
|
||||
NN_XMSG_KIND_DATA_REXMIT_NOMERGE
|
||||
};
|
||||
|
||||
/* XMSGPOOL */
|
||||
|
@ -54,10 +57,11 @@ void nn_xmsgpool_free (struct nn_xmsgpool *pool);
|
|||
/* To allocate a new xmsg from the pool; if expected_size is NOT
|
||||
exceeded, no reallocs will be performed, else the address of the
|
||||
xmsg may change because of reallocing when appending to it. */
|
||||
struct nn_xmsg *nn_xmsg_new (struct nn_xmsgpool *pool, const ddsi_guid_prefix_t *src_guid_prefix, size_t expected_size, enum nn_xmsg_kind kind);
|
||||
struct nn_xmsg *nn_xmsg_new (struct nn_xmsgpool *pool, const ddsi_guid_t *src_guid, struct participant *pp, size_t expected_size, enum nn_xmsg_kind kind);
|
||||
|
||||
/* For sending to a particular destination (participant) */
|
||||
void nn_xmsg_setdst1 (struct nn_xmsg *m, const ddsi_guid_prefix_t *gp, const nn_locator_t *addr);
|
||||
void nn_xmsg_setdst1 (struct ddsi_domaingv *gv, struct nn_xmsg *m, const ddsi_guid_prefix_t *gp, const nn_locator_t *addr);
|
||||
bool nn_xmsg_getdst1prefix (struct nn_xmsg *m, ddsi_guid_prefix_t *gp);
|
||||
|
||||
/* For sending to a particular proxy reader; this is a convenience
|
||||
routine that extracts a suitable address from the proxy reader's
|
||||
|
@ -114,15 +118,23 @@ void nn_xmsg_guid_seq_fragid (const struct nn_xmsg *m, ddsi_guid_t *wrguid, seqn
|
|||
void *nn_xmsg_submsg_from_marker (struct nn_xmsg *msg, struct nn_xmsg_marker marker);
|
||||
void *nn_xmsg_append (struct nn_xmsg *m, struct nn_xmsg_marker *marker, size_t sz);
|
||||
void nn_xmsg_shrink (struct nn_xmsg *m, struct nn_xmsg_marker marker, size_t sz);
|
||||
void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len);
|
||||
void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len, struct writer *wr);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
size_t nn_xmsg_submsg_size (struct nn_xmsg *msg, struct nn_xmsg_marker marker);
|
||||
void nn_xmsg_submsg_remove (struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker);
|
||||
void nn_xmsg_submsg_replace (struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker, unsigned char *new_submsg, size_t new_len);
|
||||
void nn_xmsg_submsg_append_refd_payload (struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker);
|
||||
#endif
|
||||
void nn_xmsg_submsg_setnext (struct nn_xmsg *msg, struct nn_xmsg_marker marker);
|
||||
void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, SubmessageKind_t smkind);
|
||||
void nn_xmsg_add_timestamp (struct nn_xmsg *m, ddsrt_wctime_t t);
|
||||
void nn_xmsg_add_entityid (struct nn_xmsg * m);
|
||||
void *nn_xmsg_addpar_bo (struct nn_xmsg *m, nn_parameterid_t pid, size_t len, bool be);
|
||||
void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len);
|
||||
void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata);
|
||||
void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata, bool force_md5);
|
||||
void nn_xmsg_addpar_statusinfo (struct nn_xmsg *m, unsigned statusinfo);
|
||||
void nn_xmsg_addpar_sentinel (struct nn_xmsg *m);
|
||||
void nn_xmsg_addpar_sentinel_bo (struct nn_xmsg * m, bool be);
|
||||
int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg *m);
|
||||
|
||||
/* XPACK */
|
||||
|
|
|
@ -364,7 +364,8 @@ static void dds_stream_countops1 (const uint32_t * __restrict ops, const uint32_
|
|||
break;
|
||||
}
|
||||
case DDS_OP_JSR: {
|
||||
dds_stream_countops1 (ops + DDS_OP_JUMP (insn), ops_end);
|
||||
if (DDS_OP_JUMP (insn) > 0)
|
||||
dds_stream_countops1 (ops + DDS_OP_JUMP (insn), ops_end);
|
||||
ops++;
|
||||
break;
|
||||
}
|
||||
|
@ -1909,7 +1910,10 @@ void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t *
|
|||
const struct ddsi_sertopic_default_desc *desc = &topic->type;
|
||||
kh->m_set = 1;
|
||||
if (desc->m_nkeys == 0)
|
||||
{
|
||||
kh->m_iskey = 1;
|
||||
kh->m_keysize = 0;
|
||||
}
|
||||
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
dds_ostreamBE_t os;
|
||||
|
@ -1922,12 +1926,14 @@ void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t *
|
|||
else
|
||||
dds_stream_extract_keyBE_from_data (is, &os, topic);
|
||||
assert (os.x.m_index <= 16);
|
||||
kh->m_keysize = (unsigned)os.x.m_index & 0x1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
dds_ostreamBE_t os;
|
||||
ddsrt_md5_state_t md5st;
|
||||
kh->m_iskey = 0;
|
||||
kh->m_keysize = 16;
|
||||
dds_ostreamBE_init (&os, 0);
|
||||
if (just_key)
|
||||
dds_stream_extract_keyBE_from_key (is, &os, topic);
|
||||
|
@ -1990,14 +1996,42 @@ static size_t isprint_runlen (const unsigned char *s, size_t n)
|
|||
return m;
|
||||
}
|
||||
|
||||
static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, enum dds_stream_typecode type)
|
||||
static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, enum dds_stream_typecode type, unsigned flags)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DDS_OP_VAL_1BY: return prtf (buf, bufsize, "%"PRIu8, dds_is_get1 (is));
|
||||
case DDS_OP_VAL_2BY: return prtf (buf, bufsize, "%"PRIu16, dds_is_get2 (is));
|
||||
case DDS_OP_VAL_4BY: return prtf (buf, bufsize, "%"PRIu32, dds_is_get4 (is));
|
||||
case DDS_OP_VAL_8BY: return prtf (buf, bufsize, "%"PRIu64, dds_is_get8 (is));
|
||||
case DDS_OP_VAL_1BY: {
|
||||
const union { int8_t s; uint8_t u; } x = { .u = dds_is_get1 (is) };
|
||||
if (flags & DDS_OP_FLAG_SGN)
|
||||
return prtf (buf, bufsize, "%"PRId8, x.s);
|
||||
else
|
||||
return prtf (buf, bufsize, "%"PRIu8, x.u);
|
||||
}
|
||||
case DDS_OP_VAL_2BY: {
|
||||
const union { int16_t s; uint16_t u; } x = { .u = dds_is_get2 (is) };
|
||||
if (flags & DDS_OP_FLAG_SGN)
|
||||
return prtf (buf, bufsize, "%"PRId16, x.s);
|
||||
else
|
||||
return prtf (buf, bufsize, "%"PRIu16, x.u);
|
||||
}
|
||||
case DDS_OP_VAL_4BY: {
|
||||
const union { int32_t s; uint32_t u; float f; } x = { .u = dds_is_get4 (is) };
|
||||
if (flags & DDS_OP_FLAG_FP)
|
||||
return prtf (buf, bufsize, "%g", x.f);
|
||||
else if (flags & DDS_OP_FLAG_SGN)
|
||||
return prtf (buf, bufsize, "%"PRId32, x.s);
|
||||
else
|
||||
return prtf (buf, bufsize, "%"PRIu32, x.u);
|
||||
}
|
||||
case DDS_OP_VAL_8BY: {
|
||||
const union { int64_t s; uint64_t u; double f; } x = { .u = dds_is_get8 (is) };
|
||||
if (flags & DDS_OP_FLAG_FP)
|
||||
return prtf (buf, bufsize, "%g", x.f);
|
||||
else if (flags & DDS_OP_FLAG_SGN)
|
||||
return prtf (buf, bufsize, "%"PRId64, x.s);
|
||||
else
|
||||
return prtf (buf, bufsize, "%"PRIu64, x.u);
|
||||
}
|
||||
case DDS_OP_VAL_STR: case DDS_OP_VAL_BST: return prtf_str (buf, bufsize, is);
|
||||
case DDS_OP_VAL_ARR: case DDS_OP_VAL_SEQ: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU:
|
||||
abort ();
|
||||
|
@ -2005,7 +2039,7 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool prtf_simple_array (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, uint32_t num, enum dds_stream_typecode type)
|
||||
static bool prtf_simple_array (char * __restrict *buf, size_t * __restrict bufsize, dds_istream_t * __restrict is, uint32_t num, enum dds_stream_typecode type, unsigned flags)
|
||||
{
|
||||
bool cont = prtf (buf, bufsize, "{");
|
||||
switch (type)
|
||||
|
@ -2028,7 +2062,7 @@ static bool prtf_simple_array (char * __restrict *buf, size_t * __restrict bufsi
|
|||
{
|
||||
if (i != 0)
|
||||
(void) prtf (buf, bufsize, ",");
|
||||
cont = prtf_simple (buf, bufsize, is, type);
|
||||
cont = prtf_simple (buf, bufsize, is, type, flags);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -2040,7 +2074,7 @@ static bool prtf_simple_array (char * __restrict *buf, size_t * __restrict bufsi
|
|||
{
|
||||
if (i != 0)
|
||||
(void) prtf (buf, bufsize, ",");
|
||||
cont = prtf_simple (buf, bufsize, is, type);
|
||||
cont = prtf_simple (buf, bufsize, is, type, flags);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -2065,10 +2099,10 @@ static const uint32_t *prtf_seq (char * __restrict *buf, size_t *bufsize, dds_is
|
|||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype);
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype, DDS_OP_FLAGS (insn));
|
||||
return ops + 2;
|
||||
case DDS_OP_VAL_STR: case DDS_OP_VAL_BST:
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype);
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype, DDS_OP_FLAGS (insn));
|
||||
return ops + (subtype == DDS_OP_VAL_STR ? 2 : 3);
|
||||
case DDS_OP_VAL_SEQ: case DDS_OP_VAL_ARR: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU: {
|
||||
const uint32_t jmp = DDS_OP_ADR_JMP (ops[3]);
|
||||
|
@ -2093,10 +2127,10 @@ static const uint32_t *prtf_arr (char * __restrict *buf, size_t *bufsize, dds_is
|
|||
switch (subtype)
|
||||
{
|
||||
case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype);
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype, DDS_OP_FLAGS (insn));
|
||||
return ops + 3;
|
||||
case DDS_OP_VAL_STR: case DDS_OP_VAL_BST:
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype);
|
||||
(void) prtf_simple_array (buf, bufsize, is, num, subtype, DDS_OP_FLAGS (insn));
|
||||
return ops + (subtype == DDS_OP_VAL_STR ? 3 : 5);
|
||||
case DDS_OP_VAL_SEQ: case DDS_OP_VAL_ARR: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU: {
|
||||
const uint32_t *jsr_ops = ops + DDS_OP_ADR_JSR (ops[3]);
|
||||
|
@ -2127,7 +2161,7 @@ static const uint32_t *prtf_uni (char * __restrict *buf, size_t *bufsize, dds_is
|
|||
{
|
||||
case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
|
||||
case DDS_OP_VAL_STR: case DDS_OP_VAL_BST:
|
||||
(void) prtf_simple (buf, bufsize, is, valtype);
|
||||
(void) prtf_simple (buf, bufsize, is, valtype, DDS_OP_FLAGS (jeq_op[0]));
|
||||
break;
|
||||
case DDS_OP_VAL_SEQ: case DDS_OP_VAL_ARR: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU:
|
||||
(void) dds_stream_print_sample1 (buf, bufsize, is, jeq_op + DDS_OP_ADR_JSR (jeq_op[0]), valtype == DDS_OP_VAL_STU);
|
||||
|
@ -2156,11 +2190,11 @@ static bool dds_stream_print_sample1 (char * __restrict *buf, size_t * __restric
|
|||
{
|
||||
case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
|
||||
case DDS_OP_VAL_STR:
|
||||
cont = prtf_simple (buf, bufsize, is, DDS_OP_TYPE (insn));
|
||||
cont = prtf_simple (buf, bufsize, is, DDS_OP_TYPE (insn), DDS_OP_FLAGS (insn));
|
||||
ops += 2;
|
||||
break;
|
||||
case DDS_OP_VAL_BST:
|
||||
cont = prtf_simple (buf, bufsize, is, DDS_OP_TYPE (insn));
|
||||
cont = prtf_simple (buf, bufsize, is, DDS_OP_TYPE (insn), DDS_OP_FLAGS (insn));
|
||||
ops += 3;
|
||||
break;
|
||||
case DDS_OP_VAL_SEQ:
|
||||
|
@ -2212,10 +2246,10 @@ size_t dds_stream_print_key (dds_istream_t * __restrict is, const struct ddsi_se
|
|||
{
|
||||
case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
|
||||
case DDS_OP_VAL_STR: case DDS_OP_VAL_BST:
|
||||
cont = prtf_simple (&buf, &bufsize, is, DDS_OP_TYPE (*op));
|
||||
cont = prtf_simple (&buf, &bufsize, is, DDS_OP_TYPE (*op), DDS_OP_FLAGS (*op));
|
||||
break;
|
||||
case DDS_OP_VAL_ARR:
|
||||
cont = prtf_simple_array (&buf, &bufsize, is, op[2], DDS_OP_SUBTYPE (*op));
|
||||
cont = prtf_simple_array (&buf, &bufsize, is, op[2], DDS_OP_SUBTYPE (*op), DDS_OP_FLAGS (*op));
|
||||
break;
|
||||
case DDS_OP_VAL_SEQ: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU:
|
||||
abort ();
|
||||
|
|
|
@ -25,8 +25,8 @@ static void instance_deadline_missed_cb (struct xevent *xev, void *varg, ddsrt_m
|
|||
|
||||
/* Gets the instance from the list in deadline admin that has the earliest missed deadline and
|
||||
* removes the instance element from the list. If no more instances with missed deadline exist
|
||||
* in the list, the deadline (nn_mtime_t) for the first instance to 'expire' is returned. If the
|
||||
* list is empty, DDSRT_MTIME_NEVER is returned */
|
||||
* in the list, the deadline (ddsrt_mtime_t) for the first instance to 'expire' is returned. If
|
||||
* the list is empty, DDSRT_MTIME_NEVER is returned */
|
||||
ddsrt_mtime_t deadline_next_missed_locked (struct deadline_adm *deadline_adm, ddsrt_mtime_t tnow, void **instance)
|
||||
{
|
||||
struct deadline_elem *elem = NULL;
|
||||
|
|
|
@ -70,20 +70,6 @@ static int entity_guid_eq_wrapper (const void *a, const void *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)
|
||||
{
|
||||
const struct entity_common *a = va;
|
||||
|
@ -104,28 +90,20 @@ static int all_entities_compare (const void *va, const void *vb)
|
|||
case EK_WRITER: {
|
||||
const struct writer *wra = va;
|
||||
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);
|
||||
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);
|
||||
tp_b = wrb->xqos->topic_name;
|
||||
}
|
||||
assert ((wra->xqos->present & QP_TOPIC_NAME) && wra->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;
|
||||
break;
|
||||
}
|
||||
|
||||
case EK_READER: {
|
||||
const struct reader *rda = va;
|
||||
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);
|
||||
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);
|
||||
tp_b = rdb->xqos->topic_name;
|
||||
}
|
||||
assert ((rda->xqos->present & QP_TOPIC_NAME) && rda->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;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -133,14 +111,11 @@ static int all_entities_compare (const void *va, const void *vb)
|
|||
case EK_PROXY_READER: {
|
||||
const struct generic_proxy_endpoint *ga = va;
|
||||
const struct generic_proxy_endpoint *gb = vb;
|
||||
if (!all_entities_compare_isbuiltin (a, ga->c.vendor)) {
|
||||
assert ((ga->c.xqos->present & QP_TOPIC_NAME) && ga->c.xqos->topic_name);
|
||||
/* built-in reader/writer proxies don't have topic name set */
|
||||
if (ga->c.xqos->present & QP_TOPIC_NAME)
|
||||
tp_a = ga->c.xqos->topic_name;
|
||||
}
|
||||
if (!all_entities_compare_isbuiltin (b, gb->c.vendor)) {
|
||||
assert ((gb->c.xqos->present & QP_TOPIC_NAME) && gb->c.xqos->topic_name);
|
||||
if (gb->c.xqos->present & QP_TOPIC_NAME)
|
||||
tp_b = gb->c.xqos->topic_name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -439,6 +414,18 @@ void entidx_enum_init_topic (struct entidx_enum *st, const struct entity_index *
|
|||
st->cur = NULL;
|
||||
}
|
||||
|
||||
void entidx_enum_init_topic_w_prefix (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind, const char *topic, const ddsi_guid_prefix_t *prefix, struct match_entities_range_key *max)
|
||||
{
|
||||
assert (kind == EK_READER || kind == EK_WRITER || kind == EK_PROXY_READER || kind == EK_PROXY_WRITER);
|
||||
struct match_entities_range_key min;
|
||||
match_endpoint_range (kind, topic, &min, max);
|
||||
min.entity.e.guid.prefix = *prefix;
|
||||
max->entity.e.guid.prefix = *prefix;
|
||||
entidx_enum_init_minmax_int (st, ei, &min);
|
||||
if (st->cur && all_entities_compare (st->cur, &max->entity) > 0)
|
||||
st->cur = NULL;
|
||||
}
|
||||
|
||||
void entidx_enum_init (struct entidx_enum *st, const struct entity_index *ei, enum entity_kind kind)
|
||||
{
|
||||
struct match_entities_range_key min;
|
||||
|
|
1302
src/core/ddsi/src/ddsi_handshake.c
Normal file
1302
src/core/ddsi/src/ddsi_handshake.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -34,7 +34,7 @@ static void lifespan_rhc_node_exp (struct xevent *xev, void *varg, ddsrt_mtime_t
|
|||
|
||||
|
||||
/* Gets the sample from the fibheap in lifespan admin that was expired first. If no more
|
||||
* expired samples exist in the fibheap, the expiry time (nn_mtime_t) for the next sample to
|
||||
* expired samples exist in the fibheap, the expiry time (ddsrt_mtime_t) for the next sample to
|
||||
* expire is returned. If the fibheap contains no more samples, DDSRT_MTIME_NEVER is returned */
|
||||
ddsrt_mtime_t lifespan_next_expired_locked (const struct lifespan_adm *lifespan_adm, ddsrt_mtime_t tnow, void **sample)
|
||||
{
|
||||
|
|
|
@ -203,7 +203,7 @@ static int joinleave_mcgroups (const struct ddsi_domaingv *gv, ddsi_tran_conn_t
|
|||
{
|
||||
if (gv->recvips_mode == RECVIPS_MODE_ALL || interface_in_recvips_p (gv->recvips, &gv->interfaces[i]))
|
||||
{
|
||||
if ((rc = joinleave_mcgroup (conn, join, srcloc, mcloc, &gv->interfaces[i])) < 0)
|
||||
if (joinleave_mcgroup (conn, join, srcloc, mcloc, &gv->interfaces[i]) < 0)
|
||||
fails++;
|
||||
else
|
||||
oks++;
|
||||
|
|
|
@ -103,10 +103,10 @@ int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address)
|
|||
switch (ifa->type)
|
||||
{
|
||||
case DDSRT_IFTYPE_WIFI:
|
||||
DDS_LOG(DDS_LC_CONFIG, " wireless");
|
||||
GVLOG (DDS_LC_CONFIG, " wireless");
|
||||
break;
|
||||
case DDSRT_IFTYPE_WIRED:
|
||||
DDS_LOG(DDS_LC_CONFIG, " wired");
|
||||
GVLOG (DDS_LC_CONFIG, " wired");
|
||||
break;
|
||||
case DDSRT_IFTYPE_UNKNOWN:
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,6 +14,7 @@
|
|||
#include "dds/ddsi/ddsi_pmd.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||
#include "dds/ddsi/ddsi_serdata_pserop.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
|
@ -30,20 +31,13 @@
|
|||
|
||||
#include "dds/ddsi/sysdeps.h"
|
||||
|
||||
static void debug_print_rawdata (const struct ddsi_domaingv *gv, const char *msg, const void *data, size_t len)
|
||||
{
|
||||
const unsigned char *c = data;
|
||||
size_t i;
|
||||
GVTRACE ("%s<", msg);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
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 (">");
|
||||
}
|
||||
/* 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
|
||||
representation and the internal representation */
|
||||
const enum pserop participant_message_data_ops[] = { XG, XO, XSTOP };
|
||||
size_t participant_message_data_nops = sizeof (participant_message_data_ops) / sizeof (participant_message_data_ops[0]);
|
||||
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]);
|
||||
|
||||
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
|
||||
struct ddsi_domaingv * const gv = pp->e.gv;
|
||||
struct writer *wr;
|
||||
union {
|
||||
ParticipantMessageData_t pmd;
|
||||
char pad[offsetof (ParticipantMessageData_t, value) + PMD_DATA_LENGTH];
|
||||
} u;
|
||||
unsigned char data[PMD_DATA_LENGTH] = { 0 };
|
||||
ParticipantMessageData_t pmd;
|
||||
struct ddsi_serdata *serdata;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
|
||||
|
@ -80,18 +72,11 @@ void write_pmd_message (struct thread_state1 * const ts1, struct nn_xpack *xp, s
|
|||
return;
|
||||
}
|
||||
|
||||
u.pmd.participantGuidPrefix = nn_hton_guid_prefix (pp->e.guid.prefix);
|
||||
u.pmd.kind = ddsrt_toBE4u (pmd_kind);
|
||||
u.pmd.length = PMD_DATA_LENGTH;
|
||||
memset (u.pmd.value, 0, u.pmd.length);
|
||||
|
||||
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);
|
||||
pmd.participantGuidPrefix = pp->e.guid.prefix;
|
||||
pmd.kind = pmd_kind;
|
||||
pmd.value.length = (uint32_t) sizeof (data);
|
||||
pmd.value.value = data;
|
||||
serdata = ddsi_serdata_from_sample (gv->pmd_topic, SDK_DATA, &pmd);
|
||||
serdata->timestamp = ddsrt_time_wallclock ();
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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) */
|
||||
const int bswap = (data->identifier == CDR_LE) ^ (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN);
|
||||
/* use sample with knowledge of internal representation: there's a deserialized sample inside already */
|
||||
const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
|
||||
struct proxy_participant *proxypp;
|
||||
ddsi_guid_t ppguid;
|
||||
struct lease *l;
|
||||
RSTTRACE (" PMD ST%x", statusinfo);
|
||||
if (data->identifier != CDR_LE && data->identifier != CDR_BE)
|
||||
RSTTRACE (" PMD ST%x", sample->c.statusinfo);
|
||||
switch (sample->c.statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))
|
||||
{
|
||||
RSTTRACE (" PMD data->identifier %u !?\n", ntohs (data->identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
case 0: {
|
||||
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;
|
||||
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
if ((proxypp = entidx_lookup_proxy_participant_guid (rst->gv->entity_index, &ppguid)) == NULL)
|
||||
RSTTRACE (" PPunknown");
|
||||
else if (pmd->kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE &&
|
||||
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
|
||||
{
|
||||
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;
|
||||
if ((proxypp = entidx_lookup_proxy_participant_guid (rst->gv->entity_index, &ppguid)) == NULL)
|
||||
RSTTRACE (" PPunknown");
|
||||
else if (kind == PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE &&
|
||||
(l = ddsrt_atomic_ldvoidp (&proxypp->minl_man)) != NULL)
|
||||
{
|
||||
/* Renew lease for entity with shortest manual-by-participant lease */
|
||||
lease_renew (l, ddsrt_time_elapsed ());
|
||||
}
|
||||
/* Renew lease for entity with shortest manual-by-participant lease */
|
||||
lease_renew (l, ddsrt_time_elapsed ());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NN_STATUSINFO_DISPOSE:
|
||||
case NN_STATUSINFO_UNREGISTER:
|
||||
case NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER:
|
||||
/* Serialized key; BE or LE doesn't matter as both fields are
|
||||
defined as octets. */
|
||||
if (len < sizeof (struct CDRHeader) + sizeof (ddsi_guid_prefix_t))
|
||||
debug_print_rawdata (rst->gv, " SHORT3", data, len);
|
||||
case NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER: {
|
||||
const ParticipantMessageData_t *pmd = sample->sample;
|
||||
ppguid.prefix = pmd->participantGuidPrefix;
|
||||
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
if (delete_proxy_participant_by_guid (rst->gv, &ppguid, sample->c.timestamp, 0) < 0)
|
||||
RSTTRACE (" unknown");
|
||||
else
|
||||
{
|
||||
ppguid.prefix = nn_ntoh_guid_prefix (*((ddsi_guid_prefix_t *) (data + 1)));
|
||||
ppguid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
if (delete_proxy_participant_by_guid (rst->gv, &ppguid, timestamp, 0) < 0)
|
||||
RSTTRACE (" unknown");
|
||||
else
|
||||
RSTTRACE (" delete");
|
||||
}
|
||||
RSTTRACE (" delete");
|
||||
break;
|
||||
}
|
||||
}
|
||||
RSTTRACE ("\n");
|
||||
}
|
||||
|
|
261
src/core/ddsi/src/ddsi_security_exchange.c
Normal file
261
src/core/ddsi/src/ddsi_security_exchange.c
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/md5.h"
|
||||
|
||||
#include "dds/ddsi/ddsi_domaingv.h"
|
||||
#include "dds/ddsi/ddsi_entity_index.h"
|
||||
#include "dds/ddsi/ddsi_security_exchange.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
#include "dds/ddsi/ddsi_handshake.h"
|
||||
#include "dds/ddsi/ddsi_serdata_pserop.h"
|
||||
#include "dds/ddsi/q_ddsi_discovery.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/q_xmsg.h"
|
||||
#include "dds/ddsi/q_transmit.h"
|
||||
#include "dds/ddsi/q_log.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
|
||||
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 nn_participant_generic_message pmg;
|
||||
struct ddsi_serdata *serdata;
|
||||
struct writer *wr;
|
||||
int64_t seq;
|
||||
struct proxy_reader *prd;
|
||||
ddsi_guid_t prd_guid;
|
||||
bool result = false;
|
||||
|
||||
if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)) == NULL) {
|
||||
GVTRACE ("write_handshake("PGUIDFMT") - builtin stateless message writer not found", PGUID (pp->e.guid));
|
||||
return false;
|
||||
}
|
||||
|
||||
prd_guid.prefix = proxypp->e.guid.prefix;
|
||||
prd_guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_READER;
|
||||
if ((prd = entidx_lookup_proxy_reader_guid (gv->entity_index, &prd_guid)) == NULL) {
|
||||
GVTRACE ("write_handshake("PGUIDFMT") - builtin stateless message proxy reader not found", PGUID (prd_guid));
|
||||
return false;
|
||||
}
|
||||
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
seq = ++wr->seq;
|
||||
|
||||
if (request) {
|
||||
nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, &proxypp->e.guid, NULL, NULL, DDS_SECURITY_AUTH_REQUEST, mdata, NULL);
|
||||
} else {
|
||||
nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, &proxypp->e.guid, NULL, NULL, DDS_SECURITY_AUTH_HANDSHAKE, mdata, related_message_id);
|
||||
}
|
||||
|
||||
serdata = ddsi_serdata_from_sample (wr->topic, SDK_DATA, &pmg);
|
||||
serdata->timestamp = ddsrt_time_wallclock ();
|
||||
result = enqueue_sample_wrlock_held (wr, seq, NULL, serdata, prd, 1) == 0;
|
||||
ddsi_serdata_unref (serdata);
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
nn_participant_generic_message_deinit(&pmg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void auth_get_serialized_participant_data(struct participant *pp, ddsi_octetseq_t *seq)
|
||||
{
|
||||
struct nn_xmsg *mpayload;
|
||||
ddsi_plist_t ps;
|
||||
struct participant_builtin_topic_data_locators locs;
|
||||
size_t sz;
|
||||
char *payload;
|
||||
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);
|
||||
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);
|
||||
seq->length = (uint32_t) sz;
|
||||
seq->value = ddsrt_malloc (sz);
|
||||
memcpy (seq->value, payload, sz);
|
||||
nn_xmsg_free (mpayload);
|
||||
}
|
||||
|
||||
void handle_auth_handshake_message(const struct receiver_state *rst, ddsi_entityid_t wr_entity_id, struct ddsi_serdata *sample_common)
|
||||
{
|
||||
const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
|
||||
const struct nn_participant_generic_message *msg = sample->sample;
|
||||
struct participant *pp = NULL;
|
||||
struct proxy_writer *pwr = NULL;
|
||||
ddsi_guid_t guid;
|
||||
const ddsi_guid_t *pwr_guid;
|
||||
struct ddsi_handshake *handshake;
|
||||
|
||||
DDSRT_UNUSED_ARG(wr_entity_id);
|
||||
|
||||
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;
|
||||
pwr_guid = &guid;
|
||||
}
|
||||
else if (msg->message_identity.source_guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)
|
||||
{
|
||||
pwr_guid = &msg->message_identity.source_guid;
|
||||
}
|
||||
else
|
||||
{
|
||||
RSTTRACE ("invalid source entity id\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
else if ((pwr = entidx_lookup_proxy_writer_guid(rst->gv->entity_index, pwr_guid)) == NULL)
|
||||
{
|
||||
RSTTRACE ("proxy writer ("PGUIDFMT") not found\n", PGUID(*pwr_guid));
|
||||
}
|
||||
else if ((handshake = ddsi_handshake_find(pp, pwr->c.proxypp)) == NULL)
|
||||
{
|
||||
RSTTRACE ("handshake not found ("PGUIDFMT" --> "PGUIDFMT")\n", PGUID (pwr->c.proxypp->e.guid), PGUID(pp->e.guid));
|
||||
}
|
||||
else
|
||||
{
|
||||
//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_release (handshake);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = pp->e.gv;
|
||||
struct nn_participant_generic_message pmg;
|
||||
struct ddsi_tkmap_instance *tk;
|
||||
struct ddsi_serdata *serdata;
|
||||
struct proxy_reader *prd;
|
||||
ddsi_guid_t prd_guid;
|
||||
struct writer *wr;
|
||||
seqno_t seq;
|
||||
int r;
|
||||
|
||||
if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER)) == NULL)
|
||||
{
|
||||
GVLOG (DDS_LC_DISCOVERY, "write_crypto_exchange_message("PGUIDFMT") - builtin volatile secure writer not found\n", PGUID (pp->e.guid));
|
||||
return false;
|
||||
}
|
||||
|
||||
prd_guid.prefix = dst_pguid->prefix;
|
||||
prd_guid.entityid.u = NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER;
|
||||
if ((prd = entidx_lookup_proxy_reader_guid (gv->entity_index, &prd_guid)) == NULL)
|
||||
return false;
|
||||
|
||||
GVLOG (DDS_LC_DISCOVERY, "send crypto tokens("PGUIDFMT" --> "PGUIDFMT")\n", PGUID (wr->e.guid), PGUID (prd_guid));
|
||||
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
seq = ++wr->seq;
|
||||
|
||||
/* Get serialized message. */
|
||||
nn_participant_generic_message_init(&pmg, &wr->e.guid, seq, dst_pguid, dst_eguid, src_eguid, classid, tokens, NULL);
|
||||
serdata = ddsi_serdata_from_sample (wr->topic, SDK_DATA, &pmg);
|
||||
serdata->timestamp = ddsrt_time_wallclock ();
|
||||
tk = ddsi_tkmap_lookup_instance_ref (gv->m_tkmap, serdata);
|
||||
r = write_sample_p2p_wrlock_held(wr, seq, NULL, serdata, tk, prd);
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
ddsi_tkmap_instance_unref (gv->m_tkmap, tk);
|
||||
ddsi_serdata_unref (serdata);
|
||||
|
||||
nn_participant_generic_message_deinit(&pmg);
|
||||
|
||||
return (r < 0 ? false : true);
|
||||
}
|
||||
|
||||
bool write_crypto_participant_tokens(const struct participant *pp, const struct proxy_participant *proxypp, const nn_dataholderseq_t *tokens)
|
||||
{
|
||||
return write_crypto_exchange_message(pp, &proxypp->e.guid, NULL, NULL, GMCLASSID_SECURITY_PARTICIPANT_CRYPTO_TOKENS, tokens);
|
||||
}
|
||||
|
||||
bool write_crypto_writer_tokens(const struct writer *wr, const struct proxy_reader *prd, const nn_dataholderseq_t *tokens)
|
||||
{
|
||||
struct participant *pp = wr->c.pp;
|
||||
struct proxy_participant *proxypp = prd->c.proxypp;
|
||||
|
||||
return write_crypto_exchange_message(pp, &proxypp->e.guid, &wr->e.guid, &prd->e.guid, GMCLASSID_SECURITY_DATAWRITER_CRYPTO_TOKENS, tokens);
|
||||
}
|
||||
|
||||
bool write_crypto_reader_tokens(const struct reader *rd, const struct proxy_writer *pwr, const nn_dataholderseq_t *tokens)
|
||||
{
|
||||
struct participant *pp = rd->c.pp;
|
||||
struct proxy_participant *proxypp = pwr->c.proxypp;
|
||||
|
||||
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, struct ddsi_serdata *sample_common)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = rst->gv;
|
||||
const struct ddsi_serdata_pserop *sample = (const struct ddsi_serdata_pserop *) sample_common;
|
||||
const struct nn_participant_generic_message *msg = sample->sample;
|
||||
ddsi_guid_t proxypp_guid;
|
||||
|
||||
proxypp_guid.prefix = msg->message_identity.source_guid.prefix;
|
||||
proxypp_guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
|
||||
if (strcmp(GMCLASSID_SECURITY_PARTICIPANT_CRYPTO_TOKENS, msg->message_class_id) == 0)
|
||||
{
|
||||
struct participant * const pp = entidx_lookup_participant_guid(gv->entity_index, &msg->destination_participant_guid);
|
||||
if (!pp)
|
||||
{
|
||||
GVWARNING("received a crypto exchange message from "PGUIDFMT" with participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
|
||||
return;
|
||||
}
|
||||
struct proxy_participant *proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &proxypp_guid);
|
||||
if (!proxypp)
|
||||
{
|
||||
GVWARNING("received a crypto exchange message from "PGUIDFMT" with proxy participant unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
|
||||
return;
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct reader * const rd = entidx_lookup_reader_guid(gv->entity_index, &msg->destination_endpoint_guid);
|
||||
if (!rd)
|
||||
{
|
||||
GVWARNING("received a crypto exchange message from "PGUIDFMT" with reader unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
|
||||
return;
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct writer * const wr = entidx_lookup_writer_guid(gv->entity_index, &msg->destination_endpoint_guid);
|
||||
if (!wr)
|
||||
{
|
||||
GVWARNING("received a crypto exchange message from "PGUIDFMT" with writer unknown "PGUIDFMT, PGUID(proxypp_guid), PGUID(msg->destination_participant_guid));
|
||||
return;
|
||||
}
|
||||
q_omg_security_set_remote_reader_crypto_tokens(wr, &msg->source_endpoint_guid, &msg->message_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 unknown class_id", PGUID(guid));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
193
src/core/ddsi/src/ddsi_security_msg.c
Normal file
193
src/core/ddsi/src/ddsi_security_msg.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* 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/md5.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsi/q_bswap.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_transmit.h"
|
||||
#include "dds/ddsi/q_misc.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/ddsi_entity_index.h"
|
||||
#include "dds/ddsi/ddsi_security_msg.h"
|
||||
#include "dds/ddsi/ddsi_plist_generic.h"
|
||||
#include "dds/ddsi/ddsi_plist.h"
|
||||
#include "dds/security/core/dds_security_utils.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 destination_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 */
|
||||
};
|
||||
const size_t pserop_participant_generic_message_nops = sizeof (pserop_participant_generic_message) / sizeof (pserop_participant_generic_message[0]);
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
dst->value = NULL;
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
}
|
||||
else
|
||||
dst->tags = NULL;
|
||||
}
|
||||
|
||||
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->destination_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);
|
||||
}
|
||||
|
||||
int volatile_secure_data_filter(struct writer *wr, struct proxy_reader *prd, struct ddsi_serdata *serdata)
|
||||
{
|
||||
static const size_t guid_offset = offsetof(nn_participant_generic_message_t, destination_participant_guid);
|
||||
ddsrt_iovec_t guid_ref = { .iov_len=0, .iov_base=NULL };
|
||||
ddsi_guid_t *msg_guid;
|
||||
ddsi_guid_t pp_guid;
|
||||
int pass;
|
||||
|
||||
DDSRT_UNUSED_ARG(wr);
|
||||
|
||||
assert(wr);
|
||||
assert(prd);
|
||||
assert(serdata);
|
||||
|
||||
/* guid_offset + 4 because 4 bytes header is at 0 */
|
||||
(void)ddsi_serdata_to_ser_ref(serdata, guid_offset + 4, sizeof(ddsi_guid_t), &guid_ref);
|
||||
assert(guid_ref.iov_len == sizeof(ddsi_guid_t));
|
||||
assert(guid_ref.iov_base);
|
||||
msg_guid = (ddsi_guid_t*)guid_ref.iov_base;
|
||||
|
||||
pass = is_null_guid(msg_guid);
|
||||
if (!pass)
|
||||
{
|
||||
pp_guid = nn_hton_guid(prd->c.proxypp->e.guid);
|
||||
pass = guid_eq(msg_guid, &pp_guid);
|
||||
}
|
||||
|
||||
ddsi_serdata_to_ser_unref(serdata, &guid_ref);
|
||||
|
||||
return pass;
|
||||
}
|
4014
src/core/ddsi/src/ddsi_security_omg.c
Normal file
4014
src/core/ddsi/src/ddsi_security_omg.c
Normal file
File diff suppressed because it is too large
Load diff
726
src/core/ddsi/src/ddsi_security_util.c
Normal file
726
src/core/ddsi/src/ddsi_security_util.c
Normal file
|
@ -0,0 +1,726 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
|
||||
#include "dds/ddsi/ddsi_security_util.h"
|
||||
|
||||
void
|
||||
g_omg_shallow_copy_StringSeq(
|
||||
DDS_Security_StringSeq *dst,
|
||||
const ddsi_stringseq_t *src)
|
||||
{
|
||||
unsigned i;
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
dst->_length = src->n;
|
||||
dst->_maximum = src->n;
|
||||
dst->_buffer = NULL;
|
||||
if (src->n > 0)
|
||||
{
|
||||
dst->_buffer = ddsrt_malloc(src->n * sizeof(DDS_Security_string));
|
||||
for (i = 0; i < src->n; i++)
|
||||
dst->_buffer[i] = src->strs[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_omg_shallow_free_StringSeq(
|
||||
DDS_Security_StringSeq *obj)
|
||||
{
|
||||
if (obj)
|
||||
ddsrt_free(obj->_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_copy_PropertySeq(
|
||||
DDS_Security_PropertySeq *dst,
|
||||
const dds_propertyseq_t *src)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (src)
|
||||
{
|
||||
dst->_length = dst->_maximum = src->n;
|
||||
if (src->n > 0)
|
||||
dst->_buffer = DDS_Security_PropertySeq_allocbuf(src->n);
|
||||
else
|
||||
dst->_buffer = NULL;
|
||||
|
||||
for (i = 0; i < src->n; i++)
|
||||
{
|
||||
dst->_buffer[i].name = src->props->name ? ddsrt_strdup(src->props->name) : ddsrt_strdup("");
|
||||
dst->_buffer[i].value = src->props->value ? ddsrt_strdup(src->props->value) : ddsrt_strdup("");
|
||||
}
|
||||
}
|
||||
else
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyin_PropertySeq(
|
||||
DDS_Security_PropertySeq *dst,
|
||||
const dds_propertyseq_t *src)
|
||||
{
|
||||
unsigned i;
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
dst->_length = src->n;
|
||||
dst->_maximum = src->n;
|
||||
dst->_buffer = NULL;
|
||||
|
||||
if (src->n > 0)
|
||||
{
|
||||
dst->_buffer = ddsrt_malloc(src->n * sizeof(DDS_Security_Property_t));
|
||||
for (i = 0; i < src->n; i++)
|
||||
{
|
||||
dst->_buffer[i].name = src->props[i].name;
|
||||
dst->_buffer[i].value = src->props[i].value;
|
||||
dst->_buffer[i].propagate = src->props[i].propagate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyout_PropertySeq(
|
||||
dds_propertyseq_t *dst,
|
||||
const DDS_Security_PropertySeq *src)
|
||||
{
|
||||
unsigned i;
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
dst->n = src->_length;
|
||||
dst->props = NULL;
|
||||
|
||||
if (src->_length > 0)
|
||||
{
|
||||
dst->props = ddsrt_malloc(src->_length * sizeof(dds_property_t));
|
||||
for (i = 0; i < src->_length; i++)
|
||||
{
|
||||
dst->props[i].name = src->_buffer[i].name;
|
||||
dst->props[i].value = src->_buffer[i].value;
|
||||
// dst->props[i].propagate = src->_buffer[i].propagate;
|
||||
dst->props[i].propagate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_PropertySeq(
|
||||
DDS_Security_PropertySeq *obj)
|
||||
{
|
||||
assert(obj);
|
||||
ddsrt_free(obj->_buffer);
|
||||
obj->_length = 0;
|
||||
obj->_maximum = 0;
|
||||
obj->_buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
q_omg_shallow_free_dds_propertyseq(
|
||||
dds_propertyseq_t *obj)
|
||||
{
|
||||
ddsrt_free(obj->props);
|
||||
obj->n = 0;
|
||||
obj->props = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyin_BinaryPropertySeq(
|
||||
DDS_Security_BinaryPropertySeq *dst,
|
||||
const dds_binarypropertyseq_t *src)
|
||||
{
|
||||
unsigned i;
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
dst->_length = src->n;
|
||||
dst->_maximum = src->n;
|
||||
dst->_buffer = NULL;
|
||||
|
||||
if (src->n > 0)
|
||||
{
|
||||
dst->_buffer = ddsrt_malloc(src->n * sizeof(DDS_Security_BinaryProperty_t));
|
||||
for (i = 0; i < src->n; i++)
|
||||
{
|
||||
dst->_buffer[i].name = src->props[i].name;
|
||||
dst->_buffer[i].value._length = src->props[i].value.length;
|
||||
dst->_buffer[i].value._maximum = src->props[i].value.length;
|
||||
dst->_buffer[i].value._buffer = src->props[i].value.value;
|
||||
// dst->_buffer[i].propagate = src->props[i].propagate;
|
||||
dst->_buffer[i].propagate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyout_BinaryPropertySeq(
|
||||
dds_binarypropertyseq_t *dst,
|
||||
const DDS_Security_BinaryPropertySeq *src)
|
||||
{
|
||||
unsigned i;
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
dst->n = src->_length;
|
||||
dst->props = NULL;
|
||||
|
||||
if (src->_length > 0)
|
||||
{
|
||||
dst->props = ddsrt_malloc(src->_length * sizeof(dds_binaryproperty_t));
|
||||
for (i = 0; i < src->_length; i++)
|
||||
{
|
||||
dst->props[i].name = src->_buffer[i].name;
|
||||
dst->props[i].value.length = src->_buffer[i].value._length;
|
||||
dst->props[i].value.value = src->_buffer[i].value._buffer;
|
||||
dst->props[i].propagate = src->_buffer[i].propagate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_BinaryPropertySeq(
|
||||
DDS_Security_BinaryPropertySeq *obj)
|
||||
{
|
||||
ddsrt_free(obj->_buffer);
|
||||
obj->_length = 0;
|
||||
obj->_maximum = 0;
|
||||
obj->_buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
q_omg_shallow_free_dds_binarypropertyseq(
|
||||
dds_binarypropertyseq_t *obj)
|
||||
{
|
||||
ddsrt_free(obj->props);
|
||||
obj->n = 0;
|
||||
obj->props = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_PropertyQosPolicy(
|
||||
DDS_Security_PropertyQosPolicy *dst,
|
||||
const dds_property_qospolicy_t *src)
|
||||
{
|
||||
assert(dst);
|
||||
assert(src);
|
||||
q_omg_shallow_copyin_PropertySeq(&(dst->value), &(src->value));
|
||||
q_omg_shallow_copyin_BinaryPropertySeq(&(dst->binary_value), &(src->binary_value));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_security_qos(
|
||||
DDS_Security_Qos *dst,
|
||||
const struct dds_qos *src)
|
||||
{
|
||||
assert(src);
|
||||
assert(dst);
|
||||
|
||||
/* DataTags not supported yet. */
|
||||
memset(&(dst->data_tags), 0, sizeof(DDS_Security_DataTagQosPolicy));
|
||||
|
||||
if (src->present & QP_PROPERTY_LIST)
|
||||
q_omg_shallow_copy_PropertyQosPolicy(&(dst->property), &(src->property));
|
||||
else
|
||||
memset(&(dst->property), 0, sizeof(DDS_Security_PropertyQosPolicy));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_PropertyQosPolicy(
|
||||
DDS_Security_PropertyQosPolicy *obj)
|
||||
{
|
||||
q_omg_shallow_free_PropertySeq(&(obj->value));
|
||||
q_omg_shallow_free_BinaryPropertySeq(&(obj->binary_value));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_security_qos(
|
||||
DDS_Security_Qos *obj)
|
||||
{
|
||||
q_omg_shallow_free_PropertyQosPolicy(&(obj->property));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_security_dataholder_copyin(
|
||||
nn_dataholder_t *dh,
|
||||
const DDS_Security_DataHolder *holder)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
dh->class_id = holder->class_id ? ddsrt_strdup(holder->class_id) : NULL;
|
||||
dh->properties.n = holder->properties._length;
|
||||
dh->properties.props = dh->properties.n ? ddsrt_malloc(dh->properties.n * sizeof(dds_property_t)) : NULL;
|
||||
for (i = 0; i < dh->properties.n; i++)
|
||||
{
|
||||
DDS_Security_Property_t *prop = &(holder->properties._buffer[i]);
|
||||
dh->properties.props[i].name = prop->name ? ddsrt_strdup(prop->name) : NULL;
|
||||
dh->properties.props[i].value = prop->value ? ddsrt_strdup(prop->value) : NULL;
|
||||
dh->properties.props[i].propagate = prop->propagate;
|
||||
}
|
||||
dh->binary_properties.n = holder->binary_properties._length;
|
||||
dh->binary_properties.props = dh->binary_properties.n ? ddsrt_malloc(dh->binary_properties.n * sizeof(dds_binaryproperty_t)) : NULL;
|
||||
for (i = 0; i < dh->binary_properties.n; i++)
|
||||
{
|
||||
DDS_Security_BinaryProperty_t *prop = &(holder->binary_properties._buffer[i]);
|
||||
dh->binary_properties.props[i].name = prop->name ? ddsrt_strdup(prop->name) : NULL;
|
||||
dh->binary_properties.props[i].value.length = prop->value._length;
|
||||
if (dh->binary_properties.props[i].value.length)
|
||||
{
|
||||
dh->binary_properties.props[i].value.value = ddsrt_malloc(prop->value._length);
|
||||
memcpy(dh->binary_properties.props[i].value.value, prop->value._buffer, prop->value._length);
|
||||
}
|
||||
else
|
||||
{
|
||||
dh->binary_properties.props[i].value.value = NULL;
|
||||
}
|
||||
dh->binary_properties.props[i].propagate = prop->propagate;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_security_dataholder_copyout(
|
||||
DDS_Security_DataHolder *holder,
|
||||
const nn_dataholder_t *dh)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
holder->class_id = dh->class_id ? ddsrt_strdup(dh->class_id) : NULL;
|
||||
holder->properties._length = holder->properties._maximum = dh->properties.n;
|
||||
holder->properties._buffer = dh->properties.n ? DDS_Security_PropertySeq_allocbuf(dh->properties.n) : NULL;
|
||||
for (i = 0; i < dh->properties.n; i++)
|
||||
{
|
||||
dds_property_t *props = &(dh->properties.props[i]);
|
||||
holder->properties._buffer[i].name = props->name ? ddsrt_strdup(props->name) : NULL;
|
||||
holder->properties._buffer[i].value = props->value ? ddsrt_strdup(props->value) : NULL;
|
||||
holder->properties._buffer[i].propagate = props->propagate;
|
||||
}
|
||||
holder->binary_properties._length = holder->binary_properties._maximum = dh->binary_properties.n;
|
||||
holder->binary_properties._buffer = dh->binary_properties.n ? DDS_Security_BinaryPropertySeq_allocbuf(dh->binary_properties.n) : NULL;
|
||||
for (i = 0; i < dh->binary_properties.n; i++)
|
||||
{
|
||||
dds_binaryproperty_t *props = &(dh->binary_properties.props[i]);
|
||||
holder->binary_properties._buffer[i].name = props->name ? ddsrt_strdup(props->name) : NULL;
|
||||
holder->binary_properties._buffer[i].value._length = holder->binary_properties._buffer[i].value._maximum = props->value.length;
|
||||
if (props->value.length)
|
||||
{
|
||||
holder->binary_properties._buffer[i].value._buffer = ddsrt_malloc(props->value.length);
|
||||
memcpy(holder->binary_properties._buffer[i].value._buffer, props->value.value, props->value.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder->binary_properties._buffer[i].value._buffer= NULL;
|
||||
}
|
||||
holder->binary_properties._buffer[i].propagate = props->propagate;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyin_DataHolder(
|
||||
DDS_Security_DataHolder *dst,
|
||||
const nn_dataholder_t *src)
|
||||
{
|
||||
assert(dst);
|
||||
assert(src);
|
||||
dst->class_id = src->class_id;
|
||||
q_omg_shallow_copyin_PropertySeq(&dst->properties, &src->properties);
|
||||
q_omg_shallow_copyin_BinaryPropertySeq(&dst->binary_properties, &src->binary_properties);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyout_DataHolder(
|
||||
nn_dataholder_t *dst,
|
||||
const DDS_Security_DataHolder *src)
|
||||
{
|
||||
assert(dst);
|
||||
assert(src);
|
||||
dst->class_id = src->class_id;
|
||||
q_omg_shallow_copyout_PropertySeq(&dst->properties, &src->properties);
|
||||
q_omg_shallow_copyout_BinaryPropertySeq(&dst->binary_properties, &src->binary_properties);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_DataHolder(
|
||||
DDS_Security_DataHolder *obj)
|
||||
{
|
||||
q_omg_shallow_free_PropertySeq(&obj->properties);
|
||||
q_omg_shallow_free_BinaryPropertySeq(&obj->binary_properties);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_nn_dataholder(
|
||||
nn_dataholder_t *holder)
|
||||
{
|
||||
q_omg_shallow_free_dds_propertyseq(&holder->properties);
|
||||
q_omg_shallow_free_dds_binarypropertyseq(&holder->binary_properties);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copyin_DataHolderSeq(
|
||||
DDS_Security_DataHolderSeq *dst,
|
||||
const nn_dataholderseq_t *src)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst->_length = src->n;
|
||||
dst->_maximum = src->n;
|
||||
dst->_buffer = NULL;
|
||||
|
||||
if (src->n > 0)
|
||||
{
|
||||
dst->_buffer = ddsrt_malloc(src->n * sizeof(DDS_Security_DataHolder));
|
||||
for (i = 0; i < src->n; i++)
|
||||
{
|
||||
q_omg_shallow_copyin_DataHolder(&dst->_buffer[i], &src->tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_copyin_DataHolderSeq(
|
||||
DDS_Security_DataHolderSeq *dst,
|
||||
const nn_dataholderseq_t *src)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst->_length = src->n;
|
||||
dst->_maximum = src->n;
|
||||
dst->_buffer = NULL;
|
||||
|
||||
if (src->n > 0)
|
||||
{
|
||||
dst->_buffer = ddsrt_malloc(src->n * sizeof(DDS_Security_DataHolder));
|
||||
for (i = 0; i < src->n; i++)
|
||||
{
|
||||
q_omg_security_dataholder_copyout(&dst->_buffer[i], &src->tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
q_omg_shallow_copyout_DataHolderSeq(
|
||||
nn_dataholderseq_t *dst,
|
||||
const DDS_Security_DataHolderSeq *src)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst->n = src->_length;
|
||||
dst->tags = NULL;
|
||||
|
||||
if (src->_length > 0)
|
||||
{
|
||||
dst->tags = ddsrt_malloc(src->_length * sizeof(nn_dataholder_t));
|
||||
for (i = 0; i < src->_length; i++)
|
||||
{
|
||||
q_omg_shallow_copyout_DataHolder(&dst->tags[i], &src->_buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_DataHolderSeq(
|
||||
DDS_Security_DataHolderSeq *obj)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < obj->_length; i++)
|
||||
{
|
||||
q_omg_shallow_free_DataHolder(&(obj->_buffer[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_nn_dataholderseq(
|
||||
nn_dataholderseq_t *obj)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < obj->n; i++)
|
||||
{
|
||||
q_omg_shallow_free_nn_dataholder(&(obj->tags[i]));
|
||||
}
|
||||
if (obj->n > 0)
|
||||
ddsrt_free(obj->tags);
|
||||
}
|
||||
|
||||
static DDS_Security_Duration_t convert_duration(dds_duration_t d)
|
||||
{
|
||||
DDS_Security_Duration_t sd;
|
||||
|
||||
if (d == DDS_INFINITY)
|
||||
{
|
||||
sd.sec = INT32_MAX;
|
||||
sd.nanosec = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd.sec = ((int)(d/DDS_NSECS_IN_SEC));
|
||||
sd.nanosec = ((uint32_t)((d)%DDS_NSECS_IN_SEC));
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
static void
|
||||
g_omg_shallow_copy_octSeq(
|
||||
DDS_Security_OctetSeq *dst,
|
||||
const ddsi_octetseq_t *src)
|
||||
{
|
||||
dst->_length = src->length;
|
||||
dst->_maximum = src->length;
|
||||
dst->_buffer = src->value;
|
||||
}
|
||||
|
||||
static void
|
||||
g_omg_shallow_free_octSeq(
|
||||
DDS_Security_OctetSeq *obj)
|
||||
{
|
||||
DDSRT_UNUSED_ARG(obj);
|
||||
/* Nothing to free. */
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_ParticipantBuiltinTopicDataSecure(
|
||||
DDS_Security_ParticipantBuiltinTopicDataSecure *dst,
|
||||
const ddsi_guid_t *guid,
|
||||
const ddsi_plist_t *plist)
|
||||
{
|
||||
assert(dst);
|
||||
assert(guid);
|
||||
assert(plist);
|
||||
|
||||
memset(dst, 0, sizeof(DDS_Security_ParticipantBuiltinTopicDataSecure));
|
||||
|
||||
/* The participant guid is the key. */
|
||||
dst->key[0] = guid->prefix.u[0];
|
||||
dst->key[1] = guid->prefix.u[1];
|
||||
dst->key[2] = guid->prefix.u[2];
|
||||
|
||||
/* Copy the DDS_Security_OctetSeq content (length, pointer, etc), not the buffer content. */
|
||||
if (plist->qos.present & QP_USER_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->user_data.value, &plist->qos.user_data);
|
||||
/* Tokens are actually DataHolders. */
|
||||
if (plist->present & PP_IDENTITY_TOKEN)
|
||||
q_omg_shallow_copyin_DataHolder(&(dst->identity_token), &(plist->identity_token));
|
||||
if (plist->present & PP_PERMISSIONS_TOKEN)
|
||||
q_omg_shallow_copyin_DataHolder(&(dst->permissions_token), &(plist->permissions_token));
|
||||
if (plist->present & PP_IDENTITY_STATUS_TOKEN)
|
||||
q_omg_shallow_copyin_DataHolder(&(dst->identity_status_token), &(plist->identity_status_token));
|
||||
if (plist->qos.present & QP_PROPERTY_LIST)
|
||||
q_omg_shallow_copy_PropertyQosPolicy(&(dst->property), &(plist->qos.property));
|
||||
if (plist->present & PP_PARTICIPANT_SECURITY_INFO)
|
||||
{
|
||||
dst->security_info.participant_security_attributes = plist->participant_security_info.security_attributes;
|
||||
dst->security_info.plugin_participant_security_attributes = plist->participant_security_info.plugin_security_attributes;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_ParticipantBuiltinTopicDataSecure(
|
||||
DDS_Security_ParticipantBuiltinTopicDataSecure *obj)
|
||||
{
|
||||
assert(obj);
|
||||
q_omg_shallow_free_DataHolder(&(obj->identity_token));
|
||||
q_omg_shallow_free_DataHolder(&(obj->permissions_token));
|
||||
q_omg_shallow_free_DataHolder(&(obj->identity_status_token));
|
||||
q_omg_shallow_free_PropertyQosPolicy(&(obj->property));
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_SubscriptionBuiltinTopicDataSecure(
|
||||
DDS_Security_SubscriptionBuiltinTopicDataSecure *dst,
|
||||
const ddsi_guid_t *guid,
|
||||
const struct dds_qos *qos,
|
||||
const nn_security_info_t *secinfo)
|
||||
{
|
||||
memset(dst, 0, sizeof(DDS_Security_SubscriptionBuiltinTopicDataSecure));
|
||||
|
||||
/* Keys are inspired by write_builtin_topic_copyin_subscriptionInfo() */
|
||||
dst->key[0] = ddsrt_toBE4u(guid->prefix.u[0]);
|
||||
dst->key[1] = ddsrt_toBE4u(guid->prefix.u[1]);
|
||||
dst->key[2] = ddsrt_toBE4u(guid->prefix.u[2]);
|
||||
|
||||
dst->participant_key[0] = ddsrt_toBE4u(guid->prefix.u[0]);
|
||||
dst->participant_key[1] = ddsrt_toBE4u(guid->prefix.u[1]);
|
||||
dst->participant_key[2] = ddsrt_toBE4u(guid->prefix.u[2]);
|
||||
|
||||
if (qos->present & QP_TOPIC_NAME)
|
||||
dst->topic_name = (DDS_Security_string)qos->topic_name;
|
||||
if (qos->present & QP_TYPE_NAME)
|
||||
dst->type_name = (DDS_Security_string)qos->type_name;
|
||||
|
||||
dst->security_info.endpoint_security_mask = secinfo->security_attributes;
|
||||
dst->security_info.plugin_endpoint_security_mask = secinfo->plugin_security_attributes;
|
||||
|
||||
if (qos->present & QP_DURABILITY)
|
||||
dst->durability.kind = (DDS_Security_DurabilityQosPolicyKind)qos->durability.kind;
|
||||
if (qos->present & QP_DEADLINE)
|
||||
dst->deadline.period = convert_duration(qos->deadline.deadline);
|
||||
if (qos->present & QP_LATENCY_BUDGET)
|
||||
dst->latency_budget.duration = convert_duration(qos->latency_budget.duration);
|
||||
if (qos->present & QP_LIVELINESS)
|
||||
{
|
||||
dst->liveliness.kind = (DDS_Security_LivelinessQosPolicyKind)qos->liveliness.kind;
|
||||
dst->liveliness.lease_duration = convert_duration(qos->liveliness.lease_duration);
|
||||
}
|
||||
if (qos->present & QP_OWNERSHIP)
|
||||
dst->ownership.kind = qos->ownership.kind == DDS_OWNERSHIP_SHARED ? DDS_SECURITY_SHARED_OWNERSHIP_QOS : DDS_SECURITY_EXCLUSIVE_OWNERSHIP_QOS;
|
||||
if (qos->present & QP_DESTINATION_ORDER)
|
||||
dst->destination_order.kind = (DDS_Security_DestinationOrderQosPolicyKind)qos->destination_order.kind;
|
||||
if (qos->present & QP_PRESENTATION)
|
||||
{
|
||||
dst->presentation.access_scope = (DDS_Security_PresentationQosPolicyAccessScopeKind)qos->presentation.access_scope;
|
||||
dst->presentation.coherent_access = qos->presentation.coherent_access;
|
||||
dst->presentation.ordered_access = qos->presentation.ordered_access;
|
||||
}
|
||||
if (qos->present & QP_TIME_BASED_FILTER)
|
||||
dst->time_based_filter.minimum_separation = convert_duration(qos->time_based_filter.minimum_separation);
|
||||
if (qos->present & QP_RELIABILITY)
|
||||
{
|
||||
dst->reliability.kind = (DDS_Security_ReliabilityQosPolicyKind)(qos->reliability.kind);
|
||||
dst->reliability.max_blocking_time = convert_duration(qos->reliability.max_blocking_time);
|
||||
dst->reliability.synchronous = 0;
|
||||
}
|
||||
if (qos->present & QP_PARTITION)
|
||||
g_omg_shallow_copy_StringSeq(&dst->partition.name, &qos->partition);
|
||||
if (qos->present & QP_USER_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->user_data.value, &qos->user_data);
|
||||
if (qos->present & QP_TOPIC_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->topic_data.value, &qos->topic_data);
|
||||
if (qos->present & QP_GROUP_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->group_data.value, &qos->group_data);
|
||||
|
||||
/* The dst->data_tags is not supported yet. It is memset to 0, so ok. */
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_SubscriptionBuiltinTopicDataSecure(
|
||||
DDS_Security_SubscriptionBuiltinTopicDataSecure *obj)
|
||||
{
|
||||
g_omg_shallow_free_octSeq(&obj->user_data.value);
|
||||
g_omg_shallow_free_octSeq(&obj->topic_data.value);
|
||||
g_omg_shallow_free_octSeq(&obj->group_data.value);
|
||||
g_omg_shallow_free_StringSeq(&obj->partition.name);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_PublicationBuiltinTopicDataSecure(
|
||||
DDS_Security_PublicationBuiltinTopicDataSecure *dst,
|
||||
const ddsi_guid_t *guid,
|
||||
const struct dds_qos *qos,
|
||||
const nn_security_info_t *secinfo)
|
||||
{
|
||||
|
||||
memset(dst, 0, sizeof(DDS_Security_PublicationBuiltinTopicDataSecure));
|
||||
|
||||
/* Keys are inspired by write_builtin_topic_copyin_subscriptionInfo() */
|
||||
dst->key[0] = ddsrt_toBE4u(guid->prefix.u[0]);
|
||||
dst->key[1] = ddsrt_toBE4u(guid->prefix.u[1]);
|
||||
dst->key[2] = ddsrt_toBE4u(guid->prefix.u[2]);
|
||||
|
||||
dst->participant_key[0] = ddsrt_toBE4u(guid->prefix.u[0]);
|
||||
dst->participant_key[1] = ddsrt_toBE4u(guid->prefix.u[1]);
|
||||
dst->participant_key[2] = ddsrt_toBE4u(guid->prefix.u[2]);
|
||||
|
||||
if (qos->present & QP_TOPIC_NAME)
|
||||
dst->topic_name = (DDS_Security_string)qos->topic_name;
|
||||
if (qos->present & QP_TYPE_NAME)
|
||||
dst->type_name = (DDS_Security_string)qos->type_name;
|
||||
|
||||
dst->security_info.endpoint_security_mask = secinfo->security_attributes;
|
||||
dst->security_info.plugin_endpoint_security_mask = secinfo->plugin_security_attributes;
|
||||
|
||||
if (qos->present & QP_DURABILITY)
|
||||
dst->durability.kind = (DDS_Security_DurabilityQosPolicyKind)qos->durability.kind;
|
||||
if (qos->present & QP_DEADLINE)
|
||||
dst->deadline.period = convert_duration(qos->deadline.deadline);
|
||||
if (qos->present & QP_LATENCY_BUDGET)
|
||||
dst->latency_budget.duration = convert_duration(qos->latency_budget.duration);
|
||||
if (qos->present & QP_LIVELINESS)
|
||||
{
|
||||
dst->liveliness.kind = (DDS_Security_LivelinessQosPolicyKind)qos->liveliness.kind;
|
||||
dst->liveliness.lease_duration = convert_duration(qos->liveliness.lease_duration);
|
||||
}
|
||||
if (qos->present & QP_OWNERSHIP)
|
||||
dst->ownership.kind = qos->ownership.kind == DDS_OWNERSHIP_SHARED ? DDS_SECURITY_SHARED_OWNERSHIP_QOS : DDS_SECURITY_EXCLUSIVE_OWNERSHIP_QOS;
|
||||
if (qos->present & QP_DESTINATION_ORDER)
|
||||
dst->destination_order.kind = (DDS_Security_DestinationOrderQosPolicyKind)qos->destination_order.kind;
|
||||
if (qos->present & QP_PRESENTATION)
|
||||
{
|
||||
dst->presentation.access_scope = (DDS_Security_PresentationQosPolicyAccessScopeKind)qos->presentation.access_scope;
|
||||
dst->presentation.coherent_access = qos->presentation.coherent_access;
|
||||
dst->presentation.ordered_access = qos->presentation.ordered_access;
|
||||
}
|
||||
if (qos->present & QP_OWNERSHIP_STRENGTH)
|
||||
dst->ownership_strength.value = qos->ownership_strength.value;
|
||||
if (qos->present & QP_RELIABILITY)
|
||||
{
|
||||
dst->reliability.kind = (DDS_Security_ReliabilityQosPolicyKind)(qos->reliability.kind);
|
||||
dst->reliability.max_blocking_time = convert_duration(qos->reliability.max_blocking_time);
|
||||
dst->reliability.synchronous = 0;
|
||||
}
|
||||
if (qos->present & QP_LIFESPAN)
|
||||
dst->lifespan.duration = convert_duration(qos->lifespan.duration);
|
||||
if (qos->present & QP_PARTITION)
|
||||
g_omg_shallow_copy_StringSeq(&dst->partition.name, &qos->partition);
|
||||
if (qos->present & QP_USER_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->user_data.value, &qos->user_data);
|
||||
|
||||
if (qos->present & QP_TOPIC_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->topic_data.value, &qos->topic_data);
|
||||
if (qos->present & QP_GROUP_DATA)
|
||||
g_omg_shallow_copy_octSeq(&dst->group_data.value, &qos->group_data);
|
||||
|
||||
/* The dst->data_tags is not supported yet. It is memset to 0, so ok. */
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_PublicationBuiltinTopicDataSecure(
|
||||
DDS_Security_PublicationBuiltinTopicDataSecure *obj)
|
||||
{
|
||||
g_omg_shallow_free_octSeq(&obj->user_data.value);
|
||||
g_omg_shallow_free_octSeq(&obj->topic_data.value);
|
||||
g_omg_shallow_free_octSeq(&obj->group_data.value);
|
||||
g_omg_shallow_free_StringSeq(&obj->partition.name);
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_copy_TopicBuiltinTopicData(
|
||||
DDS_Security_TopicBuiltinTopicData *dst,
|
||||
const char *topic_name,
|
||||
const char *type_name)
|
||||
{
|
||||
memset(dst, 0, sizeof(DDS_Security_TopicBuiltinTopicData));
|
||||
dst->name = (DDS_Security_string)topic_name;
|
||||
dst->type_name = (DDS_Security_string)type_name;
|
||||
}
|
||||
|
||||
void
|
||||
q_omg_shallow_free_TopicBuiltinTopicData(
|
||||
DDS_Security_TopicBuiltinTopicData *obj)
|
||||
{
|
||||
DDSRT_UNUSED_ARG(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
|
@ -37,7 +37,7 @@ extern inline void ddsi_serdata_unref (struct ddsi_serdata *serdata);
|
|||
extern inline uint32_t ddsi_serdata_size (const struct ddsi_serdata *d);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_from_ser (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const struct nn_rdata *fragchain, size_t size);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_from_ser_iov (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, ddsrt_msg_iovlen_t niov, const ddsrt_iovec_t *iov, size_t size);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct nn_keyhash *keyhash);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_from_keyhash (const struct ddsi_sertopic *topic, const struct ddsi_keyhash *keyhash);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_from_sample (const struct ddsi_sertopic *topic, enum ddsi_serdata_kind kind, const void *sample);
|
||||
extern inline struct ddsi_serdata *ddsi_serdata_to_topicless (const struct ddsi_serdata *d);
|
||||
extern inline void ddsi_serdata_to_ser (const struct ddsi_serdata *d, size_t off, size_t sz, void *buf);
|
||||
|
@ -48,3 +48,4 @@ extern inline bool ddsi_serdata_topicless_to_sample (const struct ddsi_sertopic
|
|||
extern inline bool ddsi_serdata_eqkey (const struct ddsi_serdata *a, const struct ddsi_serdata *b);
|
||||
extern inline bool ddsi_serdata_print (const struct ddsi_serdata *d, char *buf, size_t size);
|
||||
extern inline bool ddsi_serdata_print_topicless (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, char *buf, size_t size);
|
||||
extern inline void ddsi_serdata_get_keyhash (const struct ddsi_serdata *d, struct ddsi_keyhash *buf, bool force_md5);
|
||||
|
|
|
@ -183,6 +183,7 @@ static void serdata_default_init(struct ddsi_serdata_default *d, const struct dd
|
|||
memset (d->keyhash.m_hash, 0, sizeof (d->keyhash.m_hash));
|
||||
d->keyhash.m_set = 0;
|
||||
d->keyhash.m_iskey = 0;
|
||||
d->keyhash.m_keysize = 0;
|
||||
}
|
||||
|
||||
static struct ddsi_serdata_default *serdata_default_allocnew (struct serdatapool *serpool, uint32_t init_size)
|
||||
|
@ -345,7 +346,7 @@ static struct ddsi_serdata *serdata_default_from_ser_iov_nokey (const struct dds
|
|||
return fix_serdata_default_nokey (d, tpcmn->serdata_basehash);
|
||||
}
|
||||
|
||||
static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash)
|
||||
static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_sertopic *tpcmn, const ddsi_keyhash_t *keyhash)
|
||||
{
|
||||
/* FIXME: not quite sure this is correct, though a check against a specially hacked OpenSplice suggests it is */
|
||||
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
|
||||
|
@ -368,11 +369,12 @@ static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr (const struct ddsi_ser
|
|||
memcpy (d->keyhash.m_hash, keyhash->value, sizeof (d->keyhash.m_hash));
|
||||
d->keyhash.m_set = 1;
|
||||
d->keyhash.m_iskey = 1;
|
||||
d->keyhash.m_keysize = sizeof (d->keyhash.m_hash);
|
||||
return fix_serdata_default(d, tp->c.serdata_basehash);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct ddsi_sertopic *tpcmn, const nn_keyhash_t *keyhash)
|
||||
static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct ddsi_sertopic *tpcmn, const ddsi_keyhash_t *keyhash)
|
||||
{
|
||||
const struct ddsi_sertopic_default *tp = (const struct ddsi_sertopic_default *)tpcmn;
|
||||
struct ddsi_serdata_default *d = serdata_default_new(tp, SDK_KEY);
|
||||
|
@ -381,6 +383,7 @@ static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct dd
|
|||
(void)keyhash;
|
||||
d->keyhash.m_set = 1;
|
||||
d->keyhash.m_iskey = 1;
|
||||
d->keyhash.m_keysize = 0;
|
||||
return fix_serdata_default_nokey(d, tp->c.serdata_basehash);
|
||||
}
|
||||
|
||||
|
@ -389,11 +392,15 @@ static void gen_keyhash_from_sample (const struct ddsi_sertopic_default *topic,
|
|||
const struct ddsi_sertopic_default_desc *desc = &topic->type;
|
||||
kh->m_set = 1;
|
||||
if (desc->m_nkeys == 0)
|
||||
{
|
||||
kh->m_iskey = 1;
|
||||
kh->m_keysize = 0;
|
||||
}
|
||||
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
|
||||
{
|
||||
dds_ostreamBE_t os;
|
||||
kh->m_iskey = 1;
|
||||
kh->m_keysize = sizeof(kh->m_hash);
|
||||
dds_ostreamBE_init (&os, 0);
|
||||
os.x.m_buffer = kh->m_hash;
|
||||
os.x.m_size = 16;
|
||||
|
@ -404,6 +411,7 @@ static void gen_keyhash_from_sample (const struct ddsi_sertopic_default *topic,
|
|||
dds_ostreamBE_t os;
|
||||
ddsrt_md5_state_t md5st;
|
||||
kh->m_iskey = 0;
|
||||
kh->m_keysize = sizeof(kh->m_hash);
|
||||
dds_ostreamBE_init (&os, 64);
|
||||
dds_stream_write_keyBE (&os, sample, topic);
|
||||
ddsrt_md5_init (&md5st);
|
||||
|
@ -453,86 +461,6 @@ static struct ddsi_serdata *serdata_default_from_sample_cdr_nokey (const struct
|
|||
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;
|
||||
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;
|
||||
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)
|
||||
return fix_serdata_default_nokey (d, tp->c.serdata_basehash);
|
||||
else
|
||||
{
|
||||
memcpy (&d->keyhash.m_hash, sample->key, sample->keysize);
|
||||
return fix_serdata_default (d, tp->c.serdata_basehash);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -655,37 +583,24 @@ static size_t serdata_default_print_cdr (const struct ddsi_sertopic *sertopic_co
|
|||
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)
|
||||
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_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)");
|
||||
assert(buf);
|
||||
assert(d->keyhash.m_set);
|
||||
if (force_md5 && d->keyhash.m_iskey /* m_iskey == !md5 */)
|
||||
{
|
||||
ddsrt_md5_state_t md5st;
|
||||
ddsrt_md5_init (&md5st);
|
||||
ddsrt_md5_append(&md5st, (ddsrt_md5_byte_t*)(d->keyhash.m_hash), d->keyhash.m_keysize);
|
||||
ddsrt_md5_finish(&md5st, (ddsrt_md5_byte_t*)(buf->value));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t ret = ddsi_plist_print (buf, size, &tmp);
|
||||
ddsi_plist_fini (&tmp);
|
||||
return ret;
|
||||
memcpy (buf->value, d->keyhash.m_hash, 16);
|
||||
}
|
||||
}
|
||||
|
||||
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)");
|
||||
}
|
||||
|
||||
const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = {
|
||||
.get_size = serdata_default_get_size,
|
||||
.eqkey = serdata_default_eqkey,
|
||||
|
@ -700,7 +615,8 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = {
|
|||
.to_ser_unref = serdata_default_to_ser_unref,
|
||||
.to_topicless = serdata_default_to_topicless,
|
||||
.topicless_to_sample = serdata_default_topicless_to_sample_cdr,
|
||||
.print = serdata_default_print_cdr
|
||||
.print = serdata_default_print_cdr,
|
||||
.get_keyhash = serdata_default_get_keyhash
|
||||
};
|
||||
|
||||
const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
|
||||
|
@ -717,39 +633,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
|
|||
.to_ser_unref = serdata_default_to_ser_unref,
|
||||
.to_topicless = serdata_default_to_topicless,
|
||||
.topicless_to_sample = serdata_default_topicless_to_sample_cdr_nokey,
|
||||
.print = serdata_default_print_cdr
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
.print = serdata_default_print_cdr,
|
||||
.get_keyhash = serdata_default_get_keyhash
|
||||
};
|
||||
|
|
311
src/core/ddsi/src/ddsi_serdata_plist.c
Normal file
311
src/core/ddsi/src/ddsi_serdata_plist.c
Normal file
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* 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)));
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
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);
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
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; nn_parameter_t sentinel; } in = {
|
||||
.identifier = PL_CDR_BE,
|
||||
.options = 0,
|
||||
.par = {
|
||||
.parameterid = ddsrt_toBE2u (tp->keyparam),
|
||||
.length = ddsrt_toBE2u ((uint16_t) sizeof (*keyhash))
|
||||
},
|
||||
.kh = *keyhash,
|
||||
.sentinel = {
|
||||
.parameterid = ddsrt_toBE2u (PID_SENTINEL),
|
||||
.length = 0
|
||||
}
|
||||
};
|
||||
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
|
||||
};
|
298
src/core/ddsi/src/ddsi_serdata_pserop.c
Normal file
298
src/core/ddsi/src/ddsi_serdata_pserop.c
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* 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));
|
||||
assert (d->data != NULL); // clang static analyzer
|
||||
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
|
||||
};
|
|
@ -56,8 +56,7 @@ 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 *sertopic = (struct ddsi_sertopic *) sertopic_const;
|
||||
if (sertopic)
|
||||
ddsrt_atomic_inc32 (&sertopic->refc);
|
||||
ddsrt_atomic_inc32 (&sertopic->refc);
|
||||
return sertopic;
|
||||
}
|
||||
|
||||
|
@ -68,7 +67,7 @@ struct ddsi_sertopic *ddsi_sertopic_lookup_locked (struct ddsi_domaingv *gv, con
|
|||
if (sertopic != NULL)
|
||||
assert (sertopic->gv != NULL);
|
||||
#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)
|
||||
|
@ -84,21 +83,18 @@ void ddsi_sertopic_register_locked (struct ddsi_domaingv *gv, struct ddsi_sertop
|
|||
|
||||
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)
|
||||
/* if registered, drop from set of registered sertopics */
|
||||
if (sertopic->gv)
|
||||
{
|
||||
/* if registered, drop from set of registered sertopics */
|
||||
if (sertopic->gv)
|
||||
{
|
||||
ddsrt_mutex_lock (&sertopic->gv->sertopics_lock);
|
||||
(void) ddsrt_hh_remove (sertopic->gv->sertopics, sertopic);
|
||||
ddsrt_mutex_unlock (&sertopic->gv->sertopics_lock);
|
||||
sertopic->gv = NULL;
|
||||
}
|
||||
|
||||
ddsi_sertopic_free (sertopic);
|
||||
ddsrt_mutex_lock (&sertopic->gv->sertopics_lock);
|
||||
(void) ddsrt_hh_remove (sertopic->gv->sertopics, sertopic);
|
||||
ddsrt_mutex_unlock (&sertopic->gv->sertopics_lock);
|
||||
sertopic->gv = NULL;
|
||||
}
|
||||
|
||||
ddsi_sertopic_free (sertopic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
95
src/core/ddsi/src/ddsi_sertopic_plist.c
Normal file
95
src/core/ddsi/src/ddsi_sertopic_plist.c
Normal 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
|
||||
};
|
118
src/core/ddsi/src/ddsi_sertopic_pserop.c
Normal file
118
src/core/ddsi/src/ddsi_sertopic_pserop.c
Normal 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
|
||||
};
|
|
@ -477,11 +477,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_
|
|||
}
|
||||
}
|
||||
|
||||
if ((rc = set_rcvbuf (gv, sock, &gv->config.socket_min_rcvbuf_size)) != DDS_RETCODE_OK)
|
||||
if (set_rcvbuf (gv, sock, &gv->config.socket_min_rcvbuf_size) != DDS_RETCODE_OK)
|
||||
goto fail_w_socket;
|
||||
if ((rc = set_sndbuf (gv, sock, gv->config.socket_min_sndbuf_size)) != DDS_RETCODE_OK)
|
||||
if (set_sndbuf (gv, sock, gv->config.socket_min_sndbuf_size) != DDS_RETCODE_OK)
|
||||
goto fail_w_socket;
|
||||
if (gv->config.dontRoute && (rc = set_dont_route (gv, sock, ipv6)) != DDS_RETCODE_OK)
|
||||
if (gv->config.dontRoute && set_dont_route (gv, sock, ipv6) != DDS_RETCODE_OK)
|
||||
goto fail_w_socket;
|
||||
|
||||
if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
|
||||
|
|
|
@ -207,6 +207,9 @@ DI(if_partition_mapping);
|
|||
#endif
|
||||
DI(if_peer);
|
||||
DI(if_thread_properties);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
DI(if_omg_security);
|
||||
#endif
|
||||
#undef DI
|
||||
|
||||
#define CO(name) ((int) offsetof (struct config, name))
|
||||
|
@ -277,6 +280,151 @@ static const struct cfgelem general_cfgelems[] = {
|
|||
END_MARKER
|
||||
};
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/** Security Configuration */
|
||||
static const struct cfgelem authentication_library_attributes[] = {
|
||||
{ ATTR ("path"), 1, "dds_security_auth", RELOFF (config_omg_security_listelem, cfg.authentication_plugin.library_path), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element points to the path of Authentication plugin library.</p>\n\
|
||||
<p>It can be either absolute path excluding file extension ( /usr/lib/dds_security_auth ) or single file without extension ( dds_security_auth ).</p>\n\
|
||||
<p>If single file is supplied, the library located by way of the current working directory, or LD_LIBRARY_PATH for Unix systems, and PATH for Windows systems.</p>") },
|
||||
{ ATTR ("initFunction"), 1, "init_authentication", RELOFF (config_omg_security_listelem, cfg.authentication_plugin.library_init), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the initialization function of Authentication plugin. This function is called after loading the plugin library for instantiation purposes. Init function must return an object that implements DDS Security Authentication interface.</p>") },
|
||||
{ ATTR ("finalizeFunction"), 1, "finalize_authentication", RELOFF (config_omg_security_listelem, cfg.authentication_plugin.library_finalize), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the finalization function of Authentication plugin. This function is called to let the plugin release its resources.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
static const struct cfgelem access_control_library_attributes[] = {
|
||||
{ ATTR ("path"), 1, "dds_security_ac", RELOFF (config_omg_security_listelem, cfg.access_control_plugin.library_path), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element points to the path of Access Control plugin library.</p>\n\
|
||||
<p>It can be either absolute path excluding file extension ( /usr/lib/dds_security_ac ) or single file without extension ( dds_security_ac ).</p>\n\
|
||||
<p>If single file is supplied, the library located by way of the current working directory, or LD_LIBRARY_PATH for Unix systems, and PATH for Windows systems.</p>") },
|
||||
{ ATTR ("initFunction"), 1, "init_access_control", RELOFF (config_omg_security_listelem, cfg.access_control_plugin.library_init), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the initialization function of Access Control plugin. This function is called after loading the plugin library for instantiation purposes. Init function must return an object that implements DDS Security Access Control interface.</p>") },
|
||||
{ ATTR ("finalizeFunction"), 1, "finalize_access_control", RELOFF (config_omg_security_listelem, cfg.access_control_plugin.library_finalize), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the finalization function of Access Control plugin. This function is called to let the plugin release its resources.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
static const struct cfgelem cryptography_library_attributes[] = {
|
||||
{ ATTR ("path"), 1, "dds_security_crypto", RELOFF (config_omg_security_listelem, cfg.cryptography_plugin.library_path), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element points to the path of Cryptographic plugin library.</p>\n\
|
||||
<p>It can be either absolute path excluding file extension ( /usr/lib/dds_security_crypto ) or single file without extension ( dds_security_crypto ).</p>\n\
|
||||
<p>If single file is supplied, the library located by way of the current working directory, or LD_LIBRARY_PATH for Unix systems, and PATH for Windows systems.</p>") },
|
||||
{ ATTR ("initFunction"), 1, "init_crypto", RELOFF (config_omg_security_listelem, cfg.cryptography_plugin.library_init), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the initialization function of Cryptographic plugin. This function is called after loading the plugin library for instantiation purposes. Init function must return an object that implements DDS Security Cryptographic interface.</p>") },
|
||||
{ ATTR ("finalizeFunction"), 1, "finalize_crypto", RELOFF (config_omg_security_listelem, cfg.cryptography_plugin.library_finalize), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>This element names the finalization function of Cryptographic plugin. This function is called to let the plugin release its resources.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
|
||||
static const struct cfgelem authentication_config_elements[] = {
|
||||
{ LEAF_W_ATTRS("Library", authentication_library_attributes), 1, "", RELOFF (config_omg_security_listelem, cfg.authentication_plugin), 0, 0, 0, pf_string,
|
||||
BLURB("<p>This element specifies the library to be loaded as the DDS Security Access Control plugin.</p>") },
|
||||
{ LEAF ("IdentityCertificate"), 1, NULL, RELOFF (config_omg_security_listelem, cfg.authentication_properties.identity_certificate), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>Identity certificate that will be used for identifying all participants in the OSPL instance.<br>The content is URI to a X509 certificate signed by the IdentityCA in PEM format containing the signed public key.</p>\n\
|
||||
<p>Supported URI schemes: file, data</p>\n\
|
||||
<p>Examples:</p>\n\
|
||||
<p><IdentityCertificate>file:participant1_identity_cert.pem</IdentityCertificate></p>\n\
|
||||
<p><IdentityCertificate>data:,-----BEGIN CERTIFICATE-----<br>\n\
|
||||
MIIDjjCCAnYCCQDCEu9...6rmT87dhTo=<br>\n\
|
||||
-----END CERTIFICATE-----</IdentityCertificate></p>") },
|
||||
{ LEAF ("IdentityCA"), 1, NULL, RELOFF (config_omg_security_listelem, cfg.authentication_properties.identity_ca), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>URI to the X509 certificate [39] of the Identity CA that is the signer of Identity Certificate.</p>\n\
|
||||
<p>Supported URI schemes: file, data</p>\n\
|
||||
<p>The file and data schemas shall refer to a X.509 v3 certificate (see X.509 v3 ITU-T Recommendation X.509 (2005) [39]) in PEM format.</p>\n\
|
||||
<p>Examples:</p>\n\
|
||||
<p><IdentityCA>file:identity_ca.pem</IdentityCA></p>\n\
|
||||
<p><IdentityCA>data:,-----BEGIN CERTIFICATE-----<br>\n\
|
||||
MIIC3DCCAcQCCQCWE5x+Z...PhovK0mp2ohhRLYI0ZiyYQ==<br>\n\
|
||||
-----END CERTIFICATE-----</IdentityCA></p>") },
|
||||
{ LEAF ("PrivateKey"), 1, NULL, RELOFF (config_omg_security_listelem, cfg.authentication_properties.private_key), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>URI to access the private Private Key for all of the participants in the OSPL federation.</p>\n\
|
||||
<p>Supported URI schemes: file, data</p>\n\
|
||||
<p>Examples:</p>\n\
|
||||
<p><PrivateKey>file:identity_ca_private_key.pem</PrivateKey></p>\n\
|
||||
<p><PrivateKey>data:,-----BEGIN RSA PRIVATE KEY-----<br>\n\
|
||||
MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>\n\
|
||||
-----END RSA PRIVATE KEY-----</PrivateKey></p>") },
|
||||
{ LEAF ("Password"), 1, "", RELOFF (config_omg_security_listelem, cfg.authentication_properties.password), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>A password used to decrypt the private_key.</p>\n\
|
||||
The value of the password property shall be interpreted as the Base64 encoding of the AES-128 key that shall be used to decrypt the private_key using AES128-CBC.</p>\n\
|
||||
If the password property is not present, then the value supplied in the private_key property must contain the unencrypted private key. </p>") },
|
||||
{ LEAF ("TrustedCADirectory"), 1, "", RELOFF (config_omg_security_listelem, cfg.authentication_properties.trusted_ca_dir), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>Trusted CA Directory which contains trusted CA certificates as separated files.</p>") },
|
||||
{ LEAF ("IncludeOptionalFields"), 1, "false", RELOFF (config_omg_security_listelem, cfg.authentication_properties.include_optional_fields), 0, uf_boolean, 0, pf_boolean,
|
||||
BLURB("<p>The authentication handshake tokens may contain optional fields to be included for finding interoperability problems.\n\
|
||||
If this parameter is set to true the optional fields are included in the handshake token exchange.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
static const struct cfgelem access_control_config_elements[] = {
|
||||
{ LEAF_W_ATTRS("Library", access_control_library_attributes), 1, "", RELOFF (config_omg_security_listelem, cfg.access_control_plugin), 0, 0, 0, pf_string,
|
||||
BLURB("<p>This element specifies the library to be loaded as the DDS Security Access Control plugin.</p>") },
|
||||
{ LEAF ("PermissionsCA"), 1, "", RELOFF (config_omg_security_listelem, cfg.access_control_properties.permissions_ca), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>URI to a X509 certificate for the PermissionsCA in PEM format.</p>\n\
|
||||
<p>Supported URI schemes: file, data</p>\n\
|
||||
<p>The file and data schemas shall refer to a X.509 v3 certificate (see X.509 v3 ITU-T Recommendation X.509 (2005) [39]) in PEM format.</p><br>\n\
|
||||
<p>Examples:</p><br>\n\
|
||||
<p><PermissionsCA>file:permissions_ca.pem</PermissionsCA></p>\n\
|
||||
<p><PermissionsCA>file:/home/myuser/permissions_ca.pem</PermissionsCA></p><br>\n\
|
||||
<p><PermissionsCA>data:<strong>,</strong>-----BEGIN CERTIFICATE-----</p>\n\
|
||||
<p>MIIC3DCCAcQCCQCWE5x+Z ... PhovK0mp2ohhRLYI0ZiyYQ==</p>\n\
|
||||
<p>-----END CERTIFICATE-----</PermissionsCA></p>") },
|
||||
{ LEAF ("Governance"), 1, "", RELOFF (config_omg_security_listelem, cfg.access_control_properties.governance), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>URI to the shared Governance Document signed by the Permissions CA in S/MIME format</p>\n\
|
||||
<p>URI schemes: file, data</p><br>\n\
|
||||
<p>Examples file URIs:</p>\n\
|
||||
<p><Governance>file:governance.smime</Governance></p>\n\
|
||||
<p><Governance>file:/home/myuser/governance.smime</Governance></p><br>\n\
|
||||
<p><Governance><![CDATA[data:,MIME-Version: 1.0</p>\n\
|
||||
<p>Content-Type: multipart/signed; protocol=\"application/x-pkcs7-signature\"; micalg=\"sha-256\"; boundary=\"----F9A8A198D6F08E1285A292ADF14DD04F\"</p>\n\
|
||||
<p>This is an S/MIME signed message </p>\n\
|
||||
<p>------F9A8A198D6F08E1285A292ADF14DD04F</p>\n\
|
||||
<p><?xml version=\"1.0\" encoding=\"UTF-8\"?></p>\n\
|
||||
<p><dds xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"</p>\n\
|
||||
<p>xsi:noNamespaceSchemaLocation=\"omg_shared_ca_governance.xsd\"></p>\n\
|
||||
<p><domain_access_rules></p>\n\
|
||||
<p> . . . </p>\n\
|
||||
<p></domain_access_rules></p>\n\
|
||||
<p></dds></p>\n\
|
||||
<p>...</p>\n\
|
||||
<p>------F9A8A198D6F08E1285A292ADF14DD04F</p>\n\
|
||||
<p>Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"</p>\n\
|
||||
<p>Content-Transfer-Encoding: base64</p>\n\
|
||||
<p>Content-Disposition: attachment; filename=\"smime.p7s\"</p>\n\
|
||||
<p>MIIDuAYJKoZIhv ...al5s=</p>\n\
|
||||
<p>------F9A8A198D6F08E1285A292ADF14DD04F-]]</Governance></p>") },
|
||||
{ LEAF ("Permissions"), 1, "", RELOFF (config_omg_security_listelem, cfg.access_control_properties.permissions), 0, uf_string, ff_free, pf_string,
|
||||
BLURB("<p>URI to the DomainParticipant permissions document signed by the Permissions CA in S/MIME format</p>\n\
|
||||
<p>The permissions document specifies the permissions to be applied to a domain.</p><br>\n\
|
||||
<p>Example file URIs:</p>\n\
|
||||
<p><Permissions>file:permissions_document.p7s</Permissions></p>\n\
|
||||
<p><Permissions>file:/path_to/permissions_document.p7s</Permissions></p>\n\
|
||||
<p>Example data URI:</p>\n\
|
||||
<p><Permissions><![CDATA[data:,.........]]</Permissions></p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
static const struct cfgelem cryptography_config_elements[] = {
|
||||
{ LEAF_W_ATTRS("Library", cryptography_library_attributes), 1, "", RELOFF (config_omg_security_listelem, cfg.cryptography_plugin), 0, 0, 0, pf_string,
|
||||
BLURB("<p>This element specifies the library to be loaded as the DDS Security Cryptographic plugin.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
|
||||
static const struct cfgelem security_omg_config_elements[] = {
|
||||
{ GROUP ("Authentication", authentication_config_elements),
|
||||
BLURB("<p>This element configures the Authentication plugin of the DDS Security specification.</p>") },
|
||||
{ GROUP ("AccessControl", access_control_config_elements),
|
||||
BLURB("<p>This element configures the Access Control plugin of the DDS Security specification.</p>") },
|
||||
{ GROUP ("Cryptographic", cryptography_config_elements),
|
||||
BLURB("<p>This element configures the Cryptographic plugin of the DDS Security specification.</p>") },
|
||||
END_MARKER
|
||||
};
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
static const struct cfgelem networkpartition_cfgattrs[] = {
|
||||
{ ATTR("Name"), 1, NULL, RELOFF(config_networkpartition_listelem, name), 0, uf_string, ff_free, pf_string,
|
||||
|
@ -382,6 +530,7 @@ static const struct cfgelem thread_properties_cfgattrs[] = {
|
|||
<li><i>dq.builtins</i>: delivery thread for DDSI-builtin data, primarily for discovery;</li>\n\
|
||||
<li><i>lease</i>: DDSI liveliness monitoring;</li>\n\
|
||||
<li><i>tev</i>: general timed-event handling, retransmits and discovery;</li>\n\
|
||||
<li><i>fsm</i>: finite state machine thread for handling security handshake;</li>\n\
|
||||
<li><i>xmit.CHAN</i>: transmit thread for channel CHAN;</li>\n\
|
||||
<li><i>dq.CHAN</i>: delivery thread for channel CHAN;</li>\n\
|
||||
<li><i>tev.CHAN</i>: timed-event thread for channel CHAN.</li></ul>") },
|
||||
|
@ -579,7 +728,7 @@ static const struct cfgelem internal_cfgelems[] = {
|
|||
BLURB("<p>Do not use.</p>") },
|
||||
{ LEAF("SendAsync"), 1, "false", ABSOFF(xpack_send_async), 0, uf_boolean, 0, pf_boolean,
|
||||
BLURB("<p>This element controls whether the actual sending of packets occurs on the same thread that prepares them, or is done asynchronously by another thread.</p>") },
|
||||
{ LEAF_W_ATTRS("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "10s", ABSOFF(prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration,
|
||||
{ LEAF_W_ATTRS("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "0s", ABSOFF(prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration,
|
||||
BLURB("<p>This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.</p>") },
|
||||
{ LEAF_W_ATTRS("MultipleReceiveThreads", multiple_recv_threads_attrs), 1, "default", ABSOFF(multiple_recv_threads), 0, uf_boolean_default, 0, pf_boolean_default,
|
||||
BLURB("<p>This element controls whether all traffic is handled by a single receive thread (false) or whether multiple receive threads may be used to improve latency (true). By default it is disabled on Windows because it appears that one cannot count on being able to send packets to oneself, which is necessary to stop the thread during shutdown. Currently multiple receive threads are only used for connectionless transport (e.g., UDP) and ManySocketsMode not set to single (the default).</p>") },
|
||||
|
@ -716,8 +865,6 @@ static const struct cfgelem discovery_cfgelems[] = {
|
|||
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,
|
||||
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),
|
||||
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
|
||||
|
@ -773,6 +920,10 @@ static const struct cfgelem domain_cfgelems[] = {
|
|||
{ MOVED("Id", "CycloneDDS/Domain[@Id]") },
|
||||
{ GROUP("General", general_cfgelems),
|
||||
BLURB("<p>The General element specifies overall DDSI2E service settings.</p>") },
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
{ MGROUP ("DDSSecurity", security_omg_config_elements, NULL), INT_MAX, NULL, ABSOFF(omg_security_configuration), if_omg_security, 0, 0, 0,
|
||||
BLURB("<p>This element is used to configure DDSI2E with the DDS Security specification plugins and settings.</p>") },
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
{ GROUP("Partitioning", partitioning_cfgelems),
|
||||
BLURB("<p>The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.</p>") },
|
||||
|
@ -822,6 +973,9 @@ static const struct cfgelem root_cfgelems[] = {
|
|||
{ MOVED("Internal|Unsupported", "CycloneDDS/Domain/Internal") },
|
||||
{ MOVED("TCP", "CycloneDDS/Domain/TCP") },
|
||||
{ MOVED("ThreadPool", "CycloneDDS/Domain/ThreadPool") },
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
{ MOVED("DDSSecurity", "CycloneDDS/Domain/DDSSecurity") },
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
{ MOVED("SSL", "CycloneDDS/Domain/SSL") },
|
||||
#endif
|
||||
|
@ -1234,20 +1388,30 @@ static int if_network_partition (struct cfgst *cfgst, void *parent, struct cfgel
|
|||
if (new == NULL)
|
||||
return -1;
|
||||
new->address_string = NULL;
|
||||
new->as = NULL;
|
||||
new->name = NULL;
|
||||
new->partitionId = 0;
|
||||
new->connected = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int if_ignored_partition (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
|
||||
{
|
||||
struct config_ignoredpartition_listelem *new = if_common (cfgst, parent, cfgelem, sizeof(*new));
|
||||
if (if_common (cfgst, parent, cfgelem, sizeof (struct config_ignoredpartition_listelem)) == NULL)
|
||||
return -1;
|
||||
new->DCPSPartitionTopic = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int if_partition_mapping (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
|
||||
{
|
||||
if (if_common (cfgst, parent, cfgelem, sizeof (struct config_partitionmapping_listelem)) == NULL)
|
||||
struct config_partitionmapping_listelem *new = if_common (cfgst, parent, cfgelem, sizeof(*new));
|
||||
if (new == NULL)
|
||||
return -1;
|
||||
new->DCPSPartitionTopic = NULL;
|
||||
new->networkPartition = NULL;
|
||||
new->partition = NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */
|
||||
|
@ -1261,6 +1425,17 @@ static int if_peer (struct cfgst *cfgst, void *parent, struct cfgelem const * co
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
static int if_omg_security (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
|
||||
{
|
||||
struct config_omg_security_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (struct config_omg_security_listelem));
|
||||
if (new == NULL)
|
||||
return -1;
|
||||
memset(&new->cfg, 0, sizeof(new->cfg));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ff_free (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
|
||||
{
|
||||
void ** const elem = cfg_address (cfgst, parent, cfgelem);
|
||||
|
@ -2081,14 +2256,13 @@ static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct c
|
|||
int ok = 1;
|
||||
for (const struct cfgelem *ce = cfgelem; ce && ce->name; ce++)
|
||||
{
|
||||
struct cfgst_node *n;
|
||||
struct cfgst_nodekey key;
|
||||
key.e = ce;
|
||||
key.p = parent;
|
||||
cfgst_push (cfgst, isattr, ce, parent);
|
||||
if (ce->multiplicity <= 1)
|
||||
{
|
||||
if ((n = ddsrt_avl_lookup (&cfgst_found_treedef, &cfgst->found, &key)) == NULL)
|
||||
if (ddsrt_avl_lookup (&cfgst_found_treedef, &cfgst->found, &key) == NULL)
|
||||
{
|
||||
if (ce->update)
|
||||
{
|
||||
|
@ -2773,6 +2947,7 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
|
|||
|
||||
/* Compatibility settings of IPv6, TCP -- a bit too complicated for
|
||||
the poor framework */
|
||||
if (ok)
|
||||
{
|
||||
int ok1 = 1;
|
||||
switch (cfgst->cfg->transport_selector)
|
||||
|
@ -2782,7 +2957,7 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
|
|||
cfgst->cfg->transport_selector = (cfgst->cfg->compat_use_ipv6 == BOOLDEF_TRUE) ? TRANS_TCP6 : TRANS_TCP;
|
||||
else
|
||||
cfgst->cfg->transport_selector = (cfgst->cfg->compat_use_ipv6 == BOOLDEF_TRUE) ? TRANS_UDP6 : TRANS_UDP;
|
||||
break;
|
||||
break;
|
||||
case TRANS_TCP:
|
||||
ok1 = !(cfgst->cfg->compat_tcp_enable == BOOLDEF_FALSE || cfgst->cfg->compat_use_ipv6 == BOOLDEF_TRUE);
|
||||
break;
|
||||
|
@ -2809,14 +2984,18 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
|
|||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
/* Default channel gets set outside set_defaults -- a bit too
|
||||
complicated for the poor framework */
|
||||
if (set_default_channel (cfgst->cfg) < 0)
|
||||
ok = 0;
|
||||
if (cfgst->cfg->channels && sort_channels_check_nodups (cfgst->cfg) < 0)
|
||||
ok = 0;
|
||||
if (ok)
|
||||
{
|
||||
if (set_default_channel (cfgst->cfg) < 0)
|
||||
ok = 0;
|
||||
if (cfgst->cfg->channels && sort_channels_check_nodups (cfgst->cfg) < 0)
|
||||
ok = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
/* Assign network partition ids */
|
||||
if (ok)
|
||||
{
|
||||
struct config_networkpartition_listelem *p = cfgst->cfg->networkPartitions;
|
||||
cfgst->cfg->nof_networkPartitions = 0;
|
||||
|
@ -2830,6 +3009,7 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
|
|||
|
||||
/* Create links from the partitionmappings to the network partitions
|
||||
and signal errors if partitions do not exist */
|
||||
if (ok)
|
||||
{
|
||||
struct config_partitionmapping_listelem * m = cfgst->cfg->partitionMappings;
|
||||
while (m)
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -50,6 +50,7 @@
|
|||
#include "dds/ddsi/q_debmon.h"
|
||||
#include "dds/ddsi/q_init.h"
|
||||
#include "dds/ddsi/ddsi_threadmon.h"
|
||||
#include "dds/ddsi/ddsi_pmd.h"
|
||||
|
||||
#include "dds/ddsi/ddsi_tran.h"
|
||||
#include "dds/ddsi/ddsi_udp.h"
|
||||
|
@ -57,11 +58,16 @@
|
|||
#include "dds/ddsi/ddsi_raweth.h"
|
||||
#include "dds/ddsi/ddsi_mcgroup.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_tkmap.h"
|
||||
#include "dds__whc.h"
|
||||
#include "dds/ddsi/ddsi_iid.h"
|
||||
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
|
||||
static void add_peer_addresses (const struct ddsi_domaingv *gv, struct addrset *as, const struct config_peer_listelem *list)
|
||||
{
|
||||
while (list)
|
||||
|
@ -133,6 +139,29 @@ static void make_builtin_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template)
|
|||
q->durability.kind = DDS_DURABILITY_TRANSIENT_LOCAL;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
static void make_builtin_volatile_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template)
|
||||
{
|
||||
ddsi_xqos_copy (q, template);
|
||||
q->reliability.kind = DDS_RELIABILITY_RELIABLE;
|
||||
q->reliability.max_blocking_time = DDS_MSECS (100);
|
||||
q->durability.kind = DDS_DURABILITY_VOLATILE;
|
||||
q->history.kind = DDS_HISTORY_KEEP_ALL;
|
||||
}
|
||||
|
||||
static void add_property_to_xqos(dds_qos_t *q, const char *name, const char *value)
|
||||
{
|
||||
assert(!(q->present & QP_PROPERTY_LIST));
|
||||
q->present |= QP_PROPERTY_LIST;
|
||||
q->property.value.n = 1;
|
||||
q->property.value.props = ddsrt_malloc(sizeof(dds_property_t));
|
||||
q->property.binary_value.n = 0;
|
||||
q->property.binary_value.props = NULL;
|
||||
q->property.value.props[0].name = ddsrt_strdup(name);
|
||||
q->property.value.props[0].value = ddsrt_strdup(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int set_recvips (struct ddsi_domaingv *gv)
|
||||
{
|
||||
gv->recvips = NULL;
|
||||
|
@ -374,10 +403,10 @@ static int known_channel_p (const struct ddsi_domaingv *gv, const char *name)
|
|||
static int check_thread_properties (const struct ddsi_domaingv *gv)
|
||||
{
|
||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "debmon", NULL };
|
||||
static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "debmon", "fsm", NULL };
|
||||
static const char *chanprefix[] = { "xmit.", "tev.","dq.",NULL };
|
||||
#else
|
||||
static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "xmit.user", "dq.user", "debmon", NULL };
|
||||
static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "xmit.user", "dq.user", "debmon", "fsm", NULL };
|
||||
#endif
|
||||
const struct config_thread_properties_listelem *e;
|
||||
int ok = 1, i;
|
||||
|
@ -762,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)
|
||||
- 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));
|
||||
struct ddsi_sertopic_pserop *st = ddsrt_malloc (sizeof (*st));
|
||||
memset (st, 0, sizeof (*st));
|
||||
ddsi_sertopic_init (&st->c, name, name, &ddsi_sertopic_ops_default, ops, false);
|
||||
st->native_encoding_identifier = enc_id;
|
||||
st->serpool = serpool;
|
||||
ddsi_sertopic_init (&st->c, name, typename, &ddsi_sertopic_ops_pserop, &ddsi_serdata_ops_pserop, nops_key == 0);
|
||||
st->native_encoding_identifier = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) ? CDR_LE : CDR_BE;
|
||||
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;
|
||||
}
|
||||
|
||||
static void free_special_topics (struct ddsi_domaingv *gv)
|
||||
{
|
||||
ddsi_sertopic_unref (gv->plist_topic);
|
||||
ddsi_sertopic_unref (gv->rawcdr_topic);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
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)
|
||||
{
|
||||
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->rawcdr_topic = make_special_topic ("rawcdr", gv->serpool, DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? CDR_LE : CDR_BE, &ddsi_serdata_ops_rawcdr);
|
||||
gv->spdp_topic = make_special_topic_plist ("DCPSParticipant", "ParticipantBuiltinTopicData", PID_PARTICIPANT_GUID);
|
||||
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);
|
||||
ddsi_sertopic_register_locked (gv, gv->plist_topic);
|
||||
ddsi_sertopic_register_locked (gv, gv->rawcdr_topic);
|
||||
ddsi_sertopic_register_locked (gv, gv->spdp_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);
|
||||
|
||||
/* register increments refcount (which is reasonable), but at some point
|
||||
|
@ -1121,6 +1187,19 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
gv->spdp_endpoint_xqos.durability.kind = DDS_DURABILITY_TRANSIENT_LOCAL;
|
||||
make_builtin_endpoint_xqos (&gv->builtin_endpoint_xqos_rd, &gv->default_xqos_rd);
|
||||
make_builtin_endpoint_xqos (&gv->builtin_endpoint_xqos_wr, &gv->default_xqos_wr);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
make_builtin_volatile_endpoint_xqos(&gv->builtin_volatile_xqos_rd, &gv->default_xqos_rd);
|
||||
make_builtin_volatile_endpoint_xqos(&gv->builtin_volatile_xqos_wr, &gv->default_xqos_wr);
|
||||
ddsi_xqos_copy (&gv->builtin_stateless_xqos_rd, &gv->default_xqos_rd);
|
||||
ddsi_xqos_copy (&gv->builtin_stateless_xqos_wr, &gv->default_xqos_wr);
|
||||
gv->builtin_stateless_xqos_wr.reliability.kind = DDS_RELIABILITY_BEST_EFFORT;
|
||||
gv->builtin_stateless_xqos_wr.durability.kind = DDS_DURABILITY_VOLATILE;
|
||||
|
||||
/* Setting these properties allows the CryptoKeyFactory to recognize
|
||||
* the entities (see DDS Security spec chapter 8.8.8.1). */
|
||||
add_property_to_xqos(&gv->builtin_volatile_xqos_rd, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureReader");
|
||||
add_property_to_xqos(&gv->builtin_volatile_xqos_wr, "dds.sec.builtin_endpoint_name", "BuiltinParticipantVolatileMessageSecureWriter");
|
||||
#endif
|
||||
|
||||
ddsrt_mutex_init (&gv->sertopics_lock);
|
||||
gv->sertopics = ddsrt_hh_new (1, ddsi_sertopic_hash_wrap, ddsi_sertopic_equal_wrap);
|
||||
|
@ -1389,6 +1468,10 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
#endif
|
||||
);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
q_omg_security_init(gv);
|
||||
#endif
|
||||
|
||||
gv->as_disc = new_addrset ();
|
||||
if (gv->config.allowMulticast & AMC_SPDP)
|
||||
add_to_addrset (gv, gv->as_disc, &gv->loc_spdp_mc);
|
||||
|
@ -1476,6 +1559,15 @@ err_unicast_sockets:
|
|||
#endif
|
||||
ddsrt_hh_free (gv->sertopics);
|
||||
ddsrt_mutex_destroy (&gv->sertopics_lock);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
q_omg_security_stop (gv); // should be a no-op as it starts lazily
|
||||
q_omg_security_deinit(gv->security_context);
|
||||
q_omg_security_free (gv);
|
||||
ddsi_xqos_fini (&gv->builtin_stateless_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_stateless_xqos_rd);
|
||||
ddsi_xqos_fini (&gv->builtin_volatile_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_volatile_xqos_rd);
|
||||
#endif
|
||||
ddsi_xqos_fini (&gv->builtin_endpoint_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_endpoint_xqos_rd);
|
||||
ddsi_xqos_fini (&gv->spdp_endpoint_xqos);
|
||||
|
@ -1487,6 +1579,7 @@ err_unicast_sockets:
|
|||
ddsi_xqos_fini (&gv->default_xqos_rd);
|
||||
ddsi_plist_fini (&gv->default_local_plist_pp);
|
||||
ddsi_plist_fini (&gv->default_plist_pp);
|
||||
|
||||
ddsi_serdatapool_free (gv->serpool);
|
||||
nn_xmsgpool_free (gv->xmsgpool);
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
|
@ -1699,6 +1792,12 @@ void rtps_stop (struct ddsi_domaingv *gv)
|
|||
thread_state_asleep (ts1);
|
||||
}
|
||||
|
||||
/* Stop background (handshake) processing in security implementation,
|
||||
do this only once we know no new events will be coming in. */
|
||||
#if DDSI_INCLUDE_SECURITY
|
||||
q_omg_security_stop (gv);
|
||||
#endif
|
||||
|
||||
/* Wait until all participants are really gone => by then we can be
|
||||
certain that no new GC requests will be added, short of what we
|
||||
do here */
|
||||
|
@ -1739,6 +1838,10 @@ void rtps_fini (struct ddsi_domaingv *gv)
|
|||
nn_dqueue_free (gv->user_dqueue);
|
||||
#endif
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
q_omg_security_deinit (gv->security_context);
|
||||
#endif
|
||||
|
||||
xeventq_free (gv->xevents);
|
||||
|
||||
if (gv->config.xpack_send_async)
|
||||
|
@ -1804,7 +1907,6 @@ void rtps_fini (struct ddsi_domaingv *gv)
|
|||
}
|
||||
|
||||
ddsi_tkmap_free (gv->m_tkmap);
|
||||
|
||||
entity_index_free (gv->entity_index);
|
||||
gv->entity_index = NULL;
|
||||
deleted_participants_admin_free (gv->deleted_participants);
|
||||
|
@ -1822,6 +1924,13 @@ void rtps_fini (struct ddsi_domaingv *gv)
|
|||
ddsrt_hh_free (gv->sertopics);
|
||||
ddsrt_mutex_destroy (&gv->sertopics_lock);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
q_omg_security_free (gv);
|
||||
ddsi_xqos_fini (&gv->builtin_stateless_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_stateless_xqos_rd);
|
||||
ddsi_xqos_fini (&gv->builtin_volatile_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_volatile_xqos_rd);
|
||||
#endif
|
||||
ddsi_xqos_fini (&gv->builtin_endpoint_xqos_wr);
|
||||
ddsi_xqos_fini (&gv->builtin_endpoint_xqos_rd);
|
||||
ddsi_xqos_fini (&gv->spdp_endpoint_xqos);
|
||||
|
|
|
@ -42,6 +42,21 @@ int WildcardOverlap(char * p1, char * p2)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool guid_prefix_zero (const ddsi_guid_prefix_t *a)
|
||||
{
|
||||
return a->u[0] == 0 && a->u[1] == 0 && a->u[2] == 0;
|
||||
}
|
||||
|
||||
int guid_prefix_eq (const ddsi_guid_prefix_t *a, const ddsi_guid_prefix_t *b)
|
||||
{
|
||||
return a->u[0] == b->u[0] && a->u[1] == b->u[1] && a->u[2] == b->u[2];
|
||||
}
|
||||
|
||||
int guid_eq (const struct ddsi_guid *a, const struct ddsi_guid *b)
|
||||
{
|
||||
return guid_prefix_eq(&a->prefix, &b->prefix) && (a->entityid.u == b->entityid.u);
|
||||
}
|
||||
|
||||
int ddsi2_patmatch (const char *pat, const char *str)
|
||||
{
|
||||
while (*pat)
|
||||
|
|
|
@ -1547,6 +1547,28 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
|
|||
return (int) map->numbits;
|
||||
}
|
||||
|
||||
/* There is only one defrag per proxy writer. However for the Volatile Secure writer a filter
|
||||
* is applied to filter on the destination participant. Note that there will be one
|
||||
* builtin Volatile Secure reader for each local participant. When this local participant
|
||||
* is deleted the defrag buffer may still contain fragments for the associated reader.
|
||||
* The nn_defrag_prune is used to remove these fragments and should only be used when
|
||||
* the Volatile Secure reader is deleted.
|
||||
*/
|
||||
void nn_defrag_prune (struct nn_defrag *defrag, ddsi_guid_prefix_t *dst, seqno_t min)
|
||||
{
|
||||
struct nn_rsample *s = ddsrt_avl_lookup_succ_eq (&defrag_sampletree_treedef, &defrag->sampletree, &min);
|
||||
while (s)
|
||||
{
|
||||
struct nn_rsample *s1 = ddsrt_avl_find_succ (&defrag_sampletree_treedef, &defrag->sampletree, s);
|
||||
if (guid_prefix_eq(&s->u.defrag.sampleinfo->rst->dst_guid_prefix, dst))
|
||||
{
|
||||
defrag_rsample_drop (defrag, s);
|
||||
}
|
||||
s = s1;
|
||||
}
|
||||
defrag->max_sample = ddsrt_avl_find_max (&defrag_sampletree_treedef, &defrag->sampletree);
|
||||
}
|
||||
|
||||
/* REORDER -------------------------------------------------------------
|
||||
|
||||
The reorder index tracks out-of-order messages as non-overlapping,
|
||||
|
@ -2368,6 +2390,11 @@ seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder)
|
|||
return reorder->next_seq;
|
||||
}
|
||||
|
||||
void nn_reorder_set_next_seq (struct nn_reorder *reorder, seqno_t seq)
|
||||
{
|
||||
reorder->next_seq = seq;
|
||||
}
|
||||
|
||||
/* DQUEUE -------------------------------------------------------------- */
|
||||
|
||||
struct nn_dqueue {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,7 @@
|
|||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
|
@ -31,10 +32,12 @@
|
|||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_unused.h"
|
||||
#include "dds/ddsi/q_hbcontrol.h"
|
||||
#include "dds/ddsi/q_receive.h"
|
||||
#include "dds/ddsi/q_lease.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_sertopic.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
|
||||
#include "dds/ddsi/sysdeps.h"
|
||||
#include "dds__whc.h"
|
||||
|
@ -141,7 +144,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
|
|||
assert (wr->reliable);
|
||||
assert (hbansreq >= 0);
|
||||
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
/* out of memory at worst slows down traffic */
|
||||
return NULL;
|
||||
|
||||
|
@ -219,6 +222,13 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
|
|||
add_Heartbeat (msg, wr, whcst, hbansreq, 0, prd_guid->entityid, issync);
|
||||
}
|
||||
|
||||
/* It is possible that the encoding removed the submessage(s). */
|
||||
if (nn_xmsg_size(msg) == 0)
|
||||
{
|
||||
nn_xmsg_free (msg);
|
||||
msg = NULL;
|
||||
}
|
||||
|
||||
writer_hbcontrol_note_hb (wr, tnow, hbansreq);
|
||||
return msg;
|
||||
}
|
||||
|
@ -308,12 +318,53 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
|
|||
(hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
|
||||
ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->min_seq,
|
||||
ddsrt_avl_is_empty (&wr->readers) || root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!",
|
||||
whcst->max_seq, writer_read_seq_xmit (wr));
|
||||
whcst->max_seq, writer_read_seq_xmit(wr));
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
struct nn_xmsg *writer_hbcontrol_p2p(struct writer *wr, const struct whc_state *whcst, int hbansreq, struct proxy_reader *prd)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = wr->e.gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
||||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||
assert (wr->reliable);
|
||||
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
return NULL;
|
||||
|
||||
ETRACE (wr, "writer_hbcontrol_p2p: wr "PGUIDFMT" unicasting to prd "PGUIDFMT" ", PGUID (wr->e.guid), PGUID (prd->e.guid));
|
||||
ETRACE (wr, "(rel-prd %d seq-eq-max %d seq %"PRId64" maxseq %"PRId64")\n",
|
||||
wr->num_reliable_readers,
|
||||
ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->num_reliable_readers_where_seq_equals_max,
|
||||
wr->seq,
|
||||
ddsrt_avl_is_empty (&wr->readers) ? (int64_t) -1 : root_rdmatch (wr)->max_seq);
|
||||
|
||||
/* set the destination explicitly to the unicast destination and the fourth
|
||||
param of add_Heartbeat needs to be the guid of the reader */
|
||||
if (nn_xmsg_setdstPRD (msg, prd) < 0)
|
||||
{
|
||||
nn_xmsg_free (msg);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
nn_xmsg_setencoderid (msg, wr->partition_id);
|
||||
#endif
|
||||
add_Heartbeat (msg, wr, whcst, hbansreq, 0, prd->e.guid.entityid, 1);
|
||||
|
||||
if (nn_xmsg_size(msg) == 0)
|
||||
{
|
||||
nn_xmsg_free (msg);
|
||||
msg = NULL;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif
|
||||
|
||||
void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_state *whcst, int hbansreq, int hbliveliness, ddsi_entityid_t dst, int issync)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = wr->e.gv;
|
||||
|
@ -383,6 +434,7 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta
|
|||
hb->count = ++wr->hbcount;
|
||||
|
||||
nn_xmsg_submsg_setnext (msg, sm_marker);
|
||||
encode_datawriter_submsg(msg, sm_marker, wr);
|
||||
}
|
||||
|
||||
static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t seq, struct ddsi_serdata *serdata, struct nn_xmsg **pmsg)
|
||||
|
@ -415,7 +467,7 @@ static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t s
|
|||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||
|
||||
/* INFO_TS: 12 bytes, Data_t: 24 bytes, expected inline QoS: 32 => should be single chunk */
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (Data_t) + expected_inline_qos_size, NN_XMSG_KIND_DATA)) == NULL)
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTimestamp_t) + sizeof (Data_t) + expected_inline_qos_size, NN_XMSG_KIND_DATA)) == NULL)
|
||||
return DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
|
@ -441,7 +493,7 @@ static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t s
|
|||
|
||||
/* Adding parameters means potential reallocing, so sm, ddcmn now likely become invalid */
|
||||
if (wr->include_keyhash)
|
||||
nn_xmsg_addpar_keyhash (*pmsg, serdata);
|
||||
nn_xmsg_addpar_keyhash (*pmsg, serdata, wr->force_md5_keyhash);
|
||||
if (serdata->statusinfo)
|
||||
nn_xmsg_addpar_statusinfo (*pmsg, serdata->statusinfo);
|
||||
if (nn_xmsg_addpar_sentinel_ifparam (*pmsg) > 0)
|
||||
|
@ -452,9 +504,9 @@ static dds_return_t create_fragment_message_simple (struct writer *wr, seqno_t s
|
|||
|
||||
#if TEST_KEYHASH
|
||||
if (serdata->kind != SDK_KEY || !wr->include_keyhash)
|
||||
nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata));
|
||||
nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata), wr);
|
||||
#else
|
||||
nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata));
|
||||
nn_xmsg_serdata (*pmsg, serdata, 0, ddsi_serdata_size (serdata), wr);
|
||||
#endif
|
||||
nn_xmsg_submsg_setnext (*pmsg, sm_marker);
|
||||
return 0;
|
||||
|
@ -501,7 +553,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
|||
fragging = (gv->config.fragment_size < size);
|
||||
|
||||
/* INFO_TS: 12 bytes, DataFrag_t: 36 bytes, expected inline QoS: 32 => should be single chunk */
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (DataFrag_t) + expected_inline_qos_size, xmsg_kind)) == NULL)
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTimestamp_t) + sizeof (DataFrag_t) + expected_inline_qos_size, xmsg_kind)) == NULL)
|
||||
return DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
|
@ -608,7 +660,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
|||
/* Adding parameters means potential reallocing, so sm, ddcmn now likely become invalid */
|
||||
if (wr->include_keyhash)
|
||||
{
|
||||
nn_xmsg_addpar_keyhash (*pmsg, serdata);
|
||||
nn_xmsg_addpar_keyhash (*pmsg, serdata, wr->force_md5_keyhash);
|
||||
}
|
||||
if (serdata->statusinfo)
|
||||
{
|
||||
|
@ -622,7 +674,7 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
|||
}
|
||||
}
|
||||
|
||||
nn_xmsg_serdata (*pmsg, serdata, fragstart, fraglen);
|
||||
nn_xmsg_serdata (*pmsg, serdata, fragstart, fraglen, wr);
|
||||
nn_xmsg_submsg_setnext (*pmsg, sm_marker);
|
||||
#if 0
|
||||
GVTRACE ("queue data%s "PGUIDFMT" #%lld/%u[%u..%u)\n",
|
||||
|
@ -630,6 +682,15 @@ dds_return_t create_fragment_message (struct writer *wr, seqno_t seq, const stru
|
|||
seq, fragnum+1, fragstart, fragstart + fraglen);
|
||||
#endif
|
||||
|
||||
encode_datawriter_submsg(*pmsg, sm_marker, wr);
|
||||
|
||||
/* It is possible that the encoding removed the submessage.
|
||||
* If there is no content, free the message. */
|
||||
if (nn_xmsg_size(*pmsg) == 0) {
|
||||
nn_xmsg_free (*pmsg);
|
||||
*pmsg = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -639,7 +700,7 @@ static void create_HeartbeatFrag (struct writer *wr, seqno_t seq, unsigned fragn
|
|||
struct nn_xmsg_marker sm_marker;
|
||||
HeartbeatFrag_t *hbf;
|
||||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (HeartbeatFrag_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
if ((*pmsg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (HeartbeatFrag_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
return; /* ignore out-of-memory: HeartbeatFrag is only advisory anyway */
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
nn_xmsg_setencoderid (*pmsg, wr->partition_id);
|
||||
|
@ -668,6 +729,15 @@ static void create_HeartbeatFrag (struct writer *wr, seqno_t seq, unsigned fragn
|
|||
hbf->count = ++wr->hbfragcount;
|
||||
|
||||
nn_xmsg_submsg_setnext (*pmsg, sm_marker);
|
||||
encode_datawriter_submsg(*pmsg, sm_marker, wr);
|
||||
|
||||
/* It is possible that the encoding removed the submessage.
|
||||
* If there is no content, free the message. */
|
||||
if (nn_xmsg_size(*pmsg) == 0)
|
||||
{
|
||||
nn_xmsg_free(*pmsg);
|
||||
*pmsg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dds_return_t write_hb_liveliness (struct ddsi_domaingv * const gv, struct ddsi_guid *wr_guid, struct nn_xpack *xp)
|
||||
|
@ -690,7 +760,7 @@ dds_return_t write_hb_liveliness (struct ddsi_domaingv * const gv, struct ddsi_g
|
|||
else if (wr->xqos->liveliness.kind == DDS_LIVELINESS_MANUAL_BY_TOPIC && wr->lease != NULL)
|
||||
lease_renew (wr->lease, ddsrt_time_elapsed());
|
||||
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, wr->c.pp, sizeof (InfoTS_t) + sizeof (Heartbeat_t), NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
return DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
nn_xmsg_setdstN (msg, wr->as, wr->as_group);
|
||||
|
@ -796,7 +866,7 @@ static void transmit_sample_unlocks_wr (struct nn_xpack *xp, struct writer *wr,
|
|||
assert((wr->heartbeat_xevent != NULL) == (whcst != NULL));
|
||||
|
||||
sz = ddsi_serdata_size (serdata);
|
||||
if (sz > gv->config.fragment_size || !isnew || plist != NULL || prd != NULL)
|
||||
if (sz > gv->config.fragment_size || !isnew || plist != NULL || prd != NULL || q_omg_writer_is_submessage_protected(wr))
|
||||
{
|
||||
uint32_t nfrags;
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
|
@ -896,8 +966,6 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct ddsi_pli
|
|||
{
|
||||
char ppbuf[1024];
|
||||
int tmp;
|
||||
const char *tname = wr->topic ? wr->topic->name : "(null)";
|
||||
const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
|
||||
ppbuf[0] = '\0';
|
||||
tmp = sizeof (ppbuf) - 1;
|
||||
if (wr->e.gv->logconfig.c.mask & DDS_LC_CONTENT)
|
||||
|
@ -905,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);
|
||||
if (plist != 0 && (plist->present & PP_COHERENT_SET))
|
||||
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);
|
||||
|
@ -945,7 +1013,9 @@ static int insert_sample_in_whc (struct writer *wr, seqno_t seq, struct ddsi_pli
|
|||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER && !is_local_orphan_endpoint (&wr->e))
|
||||
if (((wr->e.guid.entityid.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) ||
|
||||
(wr->e.guid.entityid.u == NN_ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER)) &&
|
||||
!is_local_orphan_endpoint (&wr->e))
|
||||
{
|
||||
struct whc_state whcst;
|
||||
whc_get_state(wr->whc, &whcst);
|
||||
|
@ -1083,6 +1153,74 @@ static int maybe_grow_whc (struct writer *wr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int write_sample_p2p_wrlock_held(struct writer *wr, seqno_t seq, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk, struct proxy_reader *prd)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = wr->e.gv;
|
||||
int r = 0;
|
||||
ddsrt_mtime_t tnow;
|
||||
int rexmit = 1;
|
||||
struct wr_prd_match *wprd = NULL;
|
||||
seqno_t gseq;
|
||||
struct nn_xmsg *gap = NULL;
|
||||
|
||||
tnow = ddsrt_time_monotonic ();
|
||||
serdata->twrite = tnow;
|
||||
serdata->timestamp = ddsrt_time_wallclock ();
|
||||
|
||||
|
||||
if (prd->filter)
|
||||
{
|
||||
if ((wprd = ddsrt_avl_lookup (&wr_readers_treedef, &wr->readers, &prd->e.guid)) != NULL)
|
||||
{
|
||||
if (wprd->seq == MAX_SEQ_NUMBER)
|
||||
goto prd_is_deleting;
|
||||
|
||||
rexmit = prd->filter(wr, prd, serdata);
|
||||
/* determine if gap has to added */
|
||||
if (rexmit)
|
||||
{
|
||||
struct nn_gap_info gi;
|
||||
|
||||
GVLOG (DDS_LC_DISCOVERY, "send filtered "PGUIDFMT" last_seq=%"PRIu64" seq=%"PRIu64"\n", PGUID (wr->e.guid), wprd->seq, seq);
|
||||
|
||||
nn_gap_info_init(&gi);
|
||||
for (gseq = wprd->seq + 1; gseq < seq; gseq++)
|
||||
{
|
||||
struct whc_borrowed_sample sample;
|
||||
if (whc_borrow_sample (wr->whc, seq, &sample))
|
||||
{
|
||||
if (prd->filter(wr, prd, sample.serdata) == 0)
|
||||
{
|
||||
nn_gap_info_update(wr->e.gv, &gi, gseq);
|
||||
}
|
||||
whc_return_sample (wr->whc, &sample, false);
|
||||
}
|
||||
}
|
||||
gap = nn_gap_info_create_gap(wr, prd, &gi);
|
||||
}
|
||||
wprd->last_seq = seq;
|
||||
}
|
||||
}
|
||||
|
||||
if ((r = insert_sample_in_whc (wr, seq, plist, serdata, tk)) >= 0)
|
||||
{
|
||||
enqueue_sample_wrlock_held (wr, seq, plist, serdata, prd, 1);
|
||||
|
||||
if (gap)
|
||||
qxev_msg (wr->evq, gap);
|
||||
|
||||
if (wr->heartbeat_xevent)
|
||||
writer_hbcontrol_note_asyncwrite(wr, tnow);
|
||||
}
|
||||
else if (gap)
|
||||
{
|
||||
nn_xmsg_free (gap);
|
||||
}
|
||||
|
||||
prd_is_deleting:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *xp, struct writer *wr, struct ddsi_plist *plist, struct ddsi_serdata *serdata, struct ddsi_tkmap_instance *tk, int end_of_txn, int gc_allowed)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = wr->e.gv;
|
||||
|
@ -1099,13 +1237,11 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
|
|||
{
|
||||
char ppbuf[1024];
|
||||
int tmp;
|
||||
const char *tname = wr->topic ? wr->topic->name : "(null)";
|
||||
const char *ttname = wr->topic ? wr->topic->type_name : "(null)";
|
||||
ppbuf[0] = '\0';
|
||||
tmp = sizeof (ppbuf) - 1;
|
||||
GVWARNING ("dropping oversize (%"PRIu32" > %"PRIu32") sample from local writer "PGUIDFMT" %s/%s:%s%s\n",
|
||||
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)");
|
||||
r = DDS_RETCODE_BAD_PARAMETER;
|
||||
goto drop;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
#include "dds/ddsi/ddsi_tkmap.h"
|
||||
#include "dds/ddsi/ddsi_pmd.h"
|
||||
#include "dds__whc.h"
|
||||
|
@ -102,7 +103,9 @@ enum xeventkind_nt
|
|||
{
|
||||
XEVK_MSG,
|
||||
XEVK_MSG_REXMIT,
|
||||
XEVK_ENTITYID
|
||||
XEVK_MSG_REXMIT_NOMERGE,
|
||||
XEVK_ENTITYID,
|
||||
XEVK_NT_CALLBACK
|
||||
};
|
||||
|
||||
struct untimed_listelem {
|
||||
|
@ -124,11 +127,15 @@ struct xevent_nt
|
|||
struct nn_xmsg *msg;
|
||||
size_t queued_rexmit_bytes;
|
||||
ddsrt_avl_node_t msg_avlnode;
|
||||
} msg_rexmit;
|
||||
} msg_rexmit; /* and msg_rexmit_nomerge */
|
||||
struct {
|
||||
/* xmsg is self-contained / relies on reference counts */
|
||||
struct nn_xmsg *msg;
|
||||
} entityid;
|
||||
struct {
|
||||
void (*cb) (void *arg);
|
||||
void *arg;
|
||||
} callback;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -172,7 +179,7 @@ static void update_rexmit_counts (struct xeventq *evq, struct xevent_nt *ev)
|
|||
#if 0
|
||||
EVQTRACE ("ZZZ(%p,%"PRIuSIZE")", (void *) ev, ev->u.msg_rexmit.queued_rexmit_bytes);
|
||||
#endif
|
||||
assert (ev->kind == XEVK_MSG_REXMIT);
|
||||
assert (ev->kind == XEVK_MSG_REXMIT || ev->kind == XEVK_MSG_REXMIT_NOMERGE);
|
||||
assert (ev->u.msg_rexmit.queued_rexmit_bytes <= evq->queued_rexmit_bytes);
|
||||
assert (evq->queued_rexmit_msgs > 0);
|
||||
evq->queued_rexmit_bytes -= ev->u.msg_rexmit.queued_rexmit_bytes;
|
||||
|
@ -184,7 +191,7 @@ static void trace_msg (struct xeventq *evq, const char *func, const struct nn_xm
|
|||
{
|
||||
if (dds_get_log_mask() & DDS_LC_TRACE)
|
||||
{
|
||||
nn_guid_t wrguid;
|
||||
ddsi_guid_t wrguid;
|
||||
seqno_t wrseq;
|
||||
nn_fragment_number_t wrfragid;
|
||||
nn_xmsg_guid_seq_fragid (m, &wrguid, &wrseq, &wrfragid);
|
||||
|
@ -199,9 +206,20 @@ static void trace_msg (UNUSED_ARG (struct xeventq *evq), UNUSED_ARG (const char
|
|||
|
||||
static struct xevent_nt *lookup_msg (struct xeventq *evq, struct nn_xmsg *msg)
|
||||
{
|
||||
assert (nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT);
|
||||
trace_msg (evq, "lookup-msg", msg);
|
||||
return ddsrt_avl_lookup (&msg_xevents_treedef, &evq->msg_xevents, msg);
|
||||
switch (nn_xmsg_kind (msg))
|
||||
{
|
||||
case NN_XMSG_KIND_CONTROL:
|
||||
case NN_XMSG_KIND_DATA:
|
||||
assert (0);
|
||||
return NULL;
|
||||
case NN_XMSG_KIND_DATA_REXMIT:
|
||||
trace_msg (evq, "lookup-msg", msg);
|
||||
return ddsrt_avl_lookup (&msg_xevents_treedef, &evq->msg_xevents, msg);
|
||||
case NN_XMSG_KIND_DATA_REXMIT_NOMERGE:
|
||||
return NULL;
|
||||
}
|
||||
assert (0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void remember_msg (struct xeventq *evq, struct xevent_nt *ev)
|
||||
|
@ -601,7 +619,96 @@ static void handle_xevk_entityid (struct nn_xpack *xp, struct xevent_nt *ev)
|
|||
nn_xpack_addmsg (xp, ev->u.entityid.msg, 0);
|
||||
}
|
||||
|
||||
static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow /* monotonic */)
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
static int send_heartbeat_to_all_readers_check_and_sched (struct xevent *ev, struct writer *wr, const struct whc_state *whcst, ddsrt_mtime_t tnow, ddsrt_mtime_t *t_next)
|
||||
{
|
||||
int send;
|
||||
if (!writer_must_have_hb_scheduled (wr, whcst))
|
||||
{
|
||||
wr->hbcontrol.tsched = DDSRT_MTIME_NEVER;
|
||||
send = -1;
|
||||
}
|
||||
else if (!writer_hbcontrol_must_send (wr, whcst, tnow))
|
||||
{
|
||||
wr->hbcontrol.tsched = ddsrt_mtime_add_duration (tnow, writer_hbcontrol_intv (wr, whcst, tnow));
|
||||
send = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int hbansreq = writer_hbcontrol_ack_required (wr, whcst, tnow);
|
||||
wr->hbcontrol.tsched = ddsrt_mtime_add_duration (tnow, writer_hbcontrol_intv (wr, whcst, tnow));
|
||||
send = hbansreq;
|
||||
}
|
||||
|
||||
resched_xevent_if_earlier (ev, wr->hbcontrol.tsched);
|
||||
*t_next = wr->hbcontrol.tsched;
|
||||
return send;
|
||||
}
|
||||
|
||||
static void send_heartbeat_to_all_readers (struct nn_xpack *xp, struct xevent *ev, struct writer *wr, ddsrt_mtime_t tnow)
|
||||
{
|
||||
struct whc_state whcst;
|
||||
ddsrt_mtime_t t_next;
|
||||
unsigned count = 0;
|
||||
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
|
||||
whc_get_state(wr->whc, &whcst);
|
||||
const int hbansreq = send_heartbeat_to_all_readers_check_and_sched (ev, wr, &whcst, tnow, &t_next);
|
||||
if (hbansreq >= 0)
|
||||
{
|
||||
struct wr_prd_match *m;
|
||||
struct ddsi_guid last_guid = { .prefix = {.u = {0,0,0}}, .entityid = {0} };
|
||||
|
||||
while ((m = ddsrt_avl_lookup_succ (&wr_readers_treedef, &wr->readers, &last_guid)) != NULL)
|
||||
{
|
||||
last_guid = m->prd_guid;
|
||||
if (m->seq < m->last_seq)
|
||||
{
|
||||
struct proxy_reader *prd;
|
||||
|
||||
prd = entidx_lookup_proxy_reader_guid(wr->e.gv->entity_index, &m->prd_guid);
|
||||
if (prd)
|
||||
{
|
||||
ETRACE (wr, " heartbeat(wr "PGUIDFMT" rd "PGUIDFMT" %s) send, resched in %g s (min-ack %"PRId64", avail-seq %"PRId64")\n",
|
||||
PGUID (wr->e.guid),
|
||||
PGUID (m->prd_guid),
|
||||
hbansreq ? "" : " final",
|
||||
(double)(t_next.v - tnow.v) / 1e9,
|
||||
m->seq,
|
||||
m->last_seq);
|
||||
|
||||
struct nn_xmsg *msg = writer_hbcontrol_p2p(wr, &whcst, hbansreq, prd);
|
||||
if (msg != NULL)
|
||||
{
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
nn_xpack_addmsg (xp, msg, 0);
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
ETRACE (wr, "heartbeat(wr "PGUIDFMT") suppressed, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRId64", xmit %"PRId64")\n",
|
||||
PGUID (wr->e.guid),
|
||||
(t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
|
||||
ddsrt_avl_is_empty (&wr->readers) ? (int64_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->min_seq,
|
||||
ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
|
||||
whcst.max_seq,
|
||||
writer_read_seq_xmit(wr));
|
||||
}
|
||||
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = ev->evq->gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
@ -616,6 +723,14 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
if (wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER)
|
||||
{
|
||||
send_heartbeat_to_all_readers(xp, ev, wr, tnow);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
assert (wr->reliable);
|
||||
whc_get_state(wr->whc, &whcst);
|
||||
|
@ -723,7 +838,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
AckNack_t *an;
|
||||
struct nn_xmsg_marker sm_marker;
|
||||
uint32_t i, numbits;
|
||||
seqno_t base;
|
||||
seqno_t base, last_seq;
|
||||
|
||||
DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0);
|
||||
struct {
|
||||
|
@ -738,7 +853,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
|
||||
/* if in sync, look at proxy writer status, else look at
|
||||
proxy-writer--reader match status */
|
||||
if (rwn->in_sync != PRMSS_OUT_OF_SYNC)
|
||||
if (rwn->in_sync != PRMSS_OUT_OF_SYNC && !rwn->filtered)
|
||||
{
|
||||
reorder = pwr->reorder;
|
||||
if (!pwr->e.gv->config.late_ack_mode)
|
||||
|
@ -756,6 +871,11 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
bitmap_base = nn_reorder_next_seq (reorder);
|
||||
}
|
||||
|
||||
if (rwn->filtered)
|
||||
last_seq = rwn->last_seq;
|
||||
else
|
||||
last_seq = pwr->last_seq;
|
||||
|
||||
an = nn_xmsg_append (msg, &sm_marker, ACKNACK_SIZE_MAX);
|
||||
nn_xmsg_submsg_init (msg, sm_marker, SMID_ACKNACK);
|
||||
an->readerId = nn_hton_entityid (rwn->rd_guid.entityid);
|
||||
|
@ -763,7 +883,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
|
||||
/* Make bitmap; note that we've made sure to have room for the
|
||||
maximum bitmap size. */
|
||||
numbits = nn_reorder_nackmap (reorder, bitmap_base, pwr->last_seq, &an->readerSNState, an->bits, max_numbits, notail);
|
||||
numbits = nn_reorder_nackmap (reorder, bitmap_base, last_seq, &an->readerSNState, an->bits, max_numbits, notail);
|
||||
base = fromSN (an->readerSNState.bitmap_base);
|
||||
|
||||
/* Scan through bitmap, cutting it off at the first missing sample
|
||||
|
@ -776,7 +896,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
nackfrag_seq = base + i;
|
||||
if (!nn_bitset_isset (numbits, an->bits, i))
|
||||
continue;
|
||||
if (nackfrag_seq == pwr->last_seq)
|
||||
if (nackfrag_seq == last_seq)
|
||||
fragnum = pwr->last_fragnum;
|
||||
else
|
||||
fragnum = UINT32_MAX;
|
||||
|
@ -800,7 +920,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
*nack_seq = (numbits > 0) ? base + numbits : 0;
|
||||
if (!pwr->have_seen_heartbeat) {
|
||||
/* We must have seen a heartbeat for us to consider setting FINAL */
|
||||
} else if (*nack_seq && base + numbits <= pwr->last_seq) {
|
||||
} else if (*nack_seq && base + numbits <= last_seq) {
|
||||
/* If it's a NACK and it doesn't cover samples all the way up to
|
||||
the highest known sequence number, there's some reason to expect
|
||||
we may to do another round. For which we need a Heartbeat.
|
||||
|
@ -828,6 +948,9 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
base, an->readerSNState.numbits);
|
||||
for (uint32_t ui = 0; ui != an->readerSNState.numbits; ui++)
|
||||
ETRACE (pwr, "%c", nn_bitset_isset (numbits, an->bits, ui) ? '1' : '0');
|
||||
|
||||
/* Encode the sub-message when needed. */
|
||||
encode_datareader_submsg(msg, sm_marker, pwr, &rwn->rd_guid);
|
||||
}
|
||||
|
||||
if (nackfrag_numbits > 0)
|
||||
|
@ -858,12 +981,15 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
|
|||
for (uint32_t ui = 0; ui != nf->fragmentNumberState.numbits; ui++)
|
||||
ETRACE (pwr, "%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->bits, ui) ? '1' : '0');
|
||||
}
|
||||
|
||||
/* Encode the sub-message when needed. */
|
||||
encode_datareader_submsg(msg, sm_marker, pwr, &rwn->rd_guid);
|
||||
}
|
||||
|
||||
ETRACE (pwr, "\n");
|
||||
}
|
||||
|
||||
static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, ddsrt_mtime_t tnow)
|
||||
static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, ddsrt_mtime_t tnow)
|
||||
{
|
||||
/* FIXME: ought to keep track of which NACKs are being generated in
|
||||
response to a Heartbeat. There is no point in having multiple
|
||||
|
@ -894,10 +1020,20 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
|
|||
|
||||
if (addrset_any_uc (pwr->c.as, &loc) || addrset_any_mc (pwr->c.as, &loc))
|
||||
{
|
||||
struct participant *pp = NULL;
|
||||
seqno_t nack_seq;
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &ev->u.acknack.rd_guid.prefix, ACKNACK_SIZE_MAX, NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
|
||||
if (q_omg_proxy_participant_is_secure(pwr->c.proxypp))
|
||||
{
|
||||
struct reader *rd = entidx_lookup_reader_guid(pwr->e.gv->entity_index, &ev->u.acknack.rd_guid);
|
||||
|
||||
if (rd)
|
||||
pp = rd->c.pp;
|
||||
}
|
||||
|
||||
if ((msg = nn_xmsg_new (gv->xmsgpool, &ev->u.acknack.rd_guid, pp, ACKNACK_SIZE_MAX, NN_XMSG_KIND_CONTROL)) == NULL)
|
||||
goto outofmem;
|
||||
nn_xmsg_setdst1 (msg, &ev->u.acknack.pwr_guid.prefix, &loc);
|
||||
nn_xmsg_setdst1 (gv, msg, &ev->u.acknack.pwr_guid.prefix, &loc);
|
||||
if (gv->config.meas_hb_to_ack_latency && rwn->hb_timestamp.v)
|
||||
{
|
||||
/* If HB->ACK latency measurement is enabled, and we have a
|
||||
|
@ -909,7 +1045,13 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent
|
|||
rwn->hb_timestamp.v = 0;
|
||||
}
|
||||
add_AckNack (msg, pwr, rwn, &nack_seq);
|
||||
if (nack_seq)
|
||||
if (nn_xmsg_size(msg) == 0)
|
||||
{
|
||||
/* No AckNack added. */
|
||||
nn_xmsg_free(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
else if (nack_seq)
|
||||
{
|
||||
rwn->t_last_nack = tnow;
|
||||
rwn->seq_last_nack = nack_seq;
|
||||
|
@ -971,15 +1113,9 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t
|
|||
ddsi_plist_init_empty (&ps);
|
||||
ps.present |= PP_PARTICIPANT_GUID;
|
||||
ps.participant_guid = *guid;
|
||||
struct nn_xmsg *mpayload = nn_xmsg_new (gv->xmsgpool, &guid->prefix, 0, NN_XMSG_KIND_DATA);
|
||||
ddsi_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
|
||||
nn_xmsg_addpar_sentinel (mpayload);
|
||||
struct ddsi_serdata *sd = ddsi_serdata_from_sample (gv->spdp_topic, SDK_KEY, &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;
|
||||
nn_xmsg_free (mpayload);
|
||||
|
||||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
sample_found = whc_borrow_sample_key (wr->whc, sd, &sample);
|
||||
|
@ -1208,11 +1344,15 @@ static void handle_individual_xevent_nt (struct xevent_nt *xev, struct nn_xpack
|
|||
handle_xevk_msg (xp, xev);
|
||||
break;
|
||||
case XEVK_MSG_REXMIT:
|
||||
case XEVK_MSG_REXMIT_NOMERGE:
|
||||
handle_xevk_msg_rexmit (xp, xev);
|
||||
break;
|
||||
case XEVK_ENTITYID:
|
||||
handle_xevk_entityid (xp, xev);
|
||||
break;
|
||||
case XEVK_NT_CALLBACK:
|
||||
xev->u.callback.cb (xev->u.callback.arg);
|
||||
break;
|
||||
}
|
||||
ddsrt_free (xev);
|
||||
}
|
||||
|
@ -1369,7 +1509,19 @@ void qxev_msg (struct xeventq *evq, struct nn_xmsg *msg)
|
|||
ddsrt_mutex_unlock (&evq->lock);
|
||||
}
|
||||
|
||||
void qxev_prd_entityid (struct proxy_reader *prd, ddsi_guid_prefix_t *id)
|
||||
void qxev_nt_callback (struct xeventq *evq, void (*cb) (void *arg), void *arg)
|
||||
{
|
||||
struct xevent_nt *ev;
|
||||
assert (evq);
|
||||
ddsrt_mutex_lock (&evq->lock);
|
||||
ev = qxev_common_nt (evq, XEVK_NT_CALLBACK);
|
||||
ev->u.callback.cb = cb;
|
||||
ev->u.callback.arg = arg;
|
||||
qxev_insert_nt (ev);
|
||||
ddsrt_mutex_unlock (&evq->lock);
|
||||
}
|
||||
|
||||
void qxev_prd_entityid (struct proxy_reader *prd, const ddsi_guid_t *guid)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = prd->e.gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
@ -1379,10 +1531,10 @@ void qxev_prd_entityid (struct proxy_reader *prd, ddsi_guid_prefix_t *id)
|
|||
|
||||
if (! gv->xevents->tev_conn->m_connless)
|
||||
{
|
||||
msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
|
||||
msg = nn_xmsg_new (gv->xmsgpool, guid, NULL, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
|
||||
if (nn_xmsg_setdstPRD (msg, prd) == 0)
|
||||
{
|
||||
GVTRACE (" qxev_prd_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
|
||||
GVTRACE (" qxev_prd_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (guid->prefix));
|
||||
nn_xmsg_add_entityid (msg);
|
||||
ddsrt_mutex_lock (&gv->xevents->lock);
|
||||
ev = qxev_common_nt (gv->xevents, XEVK_ENTITYID);
|
||||
|
@ -1397,7 +1549,7 @@ void qxev_prd_entityid (struct proxy_reader *prd, ddsi_guid_prefix_t *id)
|
|||
}
|
||||
}
|
||||
|
||||
void qxev_pwr_entityid (struct proxy_writer *pwr, ddsi_guid_prefix_t *id)
|
||||
void qxev_pwr_entityid (struct proxy_writer *pwr, const ddsi_guid_t *guid)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = pwr->e.gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
@ -1407,10 +1559,10 @@ void qxev_pwr_entityid (struct proxy_writer *pwr, ddsi_guid_prefix_t *id)
|
|||
|
||||
if (! pwr->evq->tev_conn->m_connless)
|
||||
{
|
||||
msg = nn_xmsg_new (gv->xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
|
||||
msg = nn_xmsg_new (gv->xmsgpool, guid, NULL, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL);
|
||||
if (nn_xmsg_setdstPWR (msg, pwr) == 0)
|
||||
{
|
||||
GVTRACE (" qxev_pwr_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (*id));
|
||||
GVTRACE (" qxev_pwr_entityid (%"PRIx32":%"PRIx32":%"PRIx32")\n", PGUIDPREFIX (guid->prefix));
|
||||
nn_xmsg_add_entityid (msg);
|
||||
ddsrt_mutex_lock (&pwr->evq->lock);
|
||||
ev = qxev_common_nt (pwr->evq, XEVK_ENTITYID);
|
||||
|
@ -1432,7 +1584,7 @@ int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int f
|
|||
struct xevent_nt *ev;
|
||||
|
||||
assert (evq);
|
||||
assert (nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT);
|
||||
assert (nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT || nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT_NOMERGE);
|
||||
ddsrt_mutex_lock (&evq->lock);
|
||||
if ((ev = lookup_msg (evq, msg)) != NULL && nn_xmsg_merge_rexmit_destinations_wrlock_held (gv, ev->u.msg_rexmit.msg, msg))
|
||||
{
|
||||
|
@ -1456,7 +1608,9 @@ int qxev_msg_rexmit_wrlock_held (struct xeventq *evq, struct nn_xmsg *msg, int f
|
|||
}
|
||||
else
|
||||
{
|
||||
ev = qxev_common_nt (evq, XEVK_MSG_REXMIT);
|
||||
const enum xeventkind_nt kind =
|
||||
(nn_xmsg_kind (msg) == NN_XMSG_KIND_DATA_REXMIT) ? XEVK_MSG_REXMIT : XEVK_MSG_REXMIT_NOMERGE;
|
||||
ev = qxev_common_nt (evq, kind);
|
||||
ev->u.msg_rexmit.msg = msg;
|
||||
ev->u.msg_rexmit.queued_rexmit_bytes = msg_size;
|
||||
evq->queued_rexmit_bytes += msg_size;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "dds/ddsi/ddsi_entity_index.h"
|
||||
#include "dds/ddsi/q_freelist.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h"
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
|
||||
#define NN_XMSG_MAX_ALIGN 8
|
||||
#define NN_XMSG_CHUNK_SIZE 128
|
||||
|
@ -72,6 +73,11 @@ struct nn_xmsg {
|
|||
int have_params;
|
||||
struct ddsi_serdata *refd_payload;
|
||||
ddsrt_iovec_t refd_payload_iov;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/* Used as pointer to contain encoded payload to which iov can alias. */
|
||||
unsigned char *refd_payload_encoded;
|
||||
nn_msg_sec_info_t sec_info;
|
||||
#endif
|
||||
int64_t maxdelay;
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
uint32_t encoderid;
|
||||
|
@ -136,7 +142,7 @@ struct nn_xmsg_chain {
|
|||
struct nn_bw_limiter {
|
||||
uint32_t bandwidth; /*gv.config in bytes/s (0 = UNLIMITED)*/
|
||||
int64_t balance;
|
||||
nn_mtime_t last_update;
|
||||
ddsrt_mtime_t last_update;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -223,6 +229,9 @@ struct nn_xpack
|
|||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
uint32_t encoderId;
|
||||
#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
nn_msg_sec_info_t sec_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
static size_t align4u (size_t x)
|
||||
|
@ -283,6 +292,12 @@ static void nn_xmsg_reinit (struct nn_xmsg *m, enum nn_xmsg_kind kind)
|
|||
m->dstmode = NN_XMSG_DST_UNSET;
|
||||
m->kind = kind;
|
||||
m->maxdelay = 0;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
m->refd_payload_encoded = NULL;
|
||||
m->sec_info.use_rtps_encoding = 0;
|
||||
m->sec_info.src_pp_handle = 0;
|
||||
m->sec_info.dst_pp_handle = 0;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
m->encoderid = 0;
|
||||
#endif
|
||||
|
@ -322,14 +337,29 @@ static struct nn_xmsg *nn_xmsg_allocnew (struct nn_xmsgpool *pool, size_t expect
|
|||
return m;
|
||||
}
|
||||
|
||||
struct nn_xmsg *nn_xmsg_new (struct nn_xmsgpool *pool, const ddsi_guid_prefix_t *src_guid_prefix, size_t expected_size, enum nn_xmsg_kind kind)
|
||||
struct nn_xmsg *nn_xmsg_new (struct nn_xmsgpool *pool, const ddsi_guid_t *src_guid, struct participant *pp, size_t expected_size, enum nn_xmsg_kind kind)
|
||||
{
|
||||
struct nn_xmsg *m;
|
||||
if ((m = nn_freelist_pop (&pool->freelist)) != NULL)
|
||||
nn_xmsg_reinit (m, kind);
|
||||
else if ((m = nn_xmsg_allocnew (pool, expected_size, kind)) == NULL)
|
||||
return NULL;
|
||||
m->data->src.guid_prefix = nn_hton_guid_prefix (*src_guid_prefix);
|
||||
m->data->src.guid_prefix = nn_hton_guid_prefix (src_guid->prefix);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
m->sec_info.use_rtps_encoding = 0;
|
||||
if (pp && q_omg_participant_is_secure(pp))
|
||||
{
|
||||
if (q_omg_security_is_local_rtps_protected(pp, src_guid->entityid))
|
||||
{
|
||||
m->sec_info.use_rtps_encoding = 1;
|
||||
m->sec_info.src_pp_handle = q_omg_security_get_local_participant_handle(pp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
DDSRT_UNUSED_ARG(pp);
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -344,6 +374,9 @@ void nn_xmsg_free (struct nn_xmsg *m)
|
|||
struct nn_xmsgpool *pool = m->pool;
|
||||
if (m->refd_payload)
|
||||
ddsi_serdata_to_ser_unref (m->refd_payload, &m->refd_payload_iov);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
ddsrt_free(m->refd_payload_encoded);
|
||||
#endif
|
||||
if (m->dstmode == NN_XMSG_DST_ALL)
|
||||
{
|
||||
unref_addrset (m->dstaddr.all.as);
|
||||
|
@ -384,11 +417,19 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk
|
|||
case SMID_DATA: case SMID_DATA_FRAG:
|
||||
/* but data is strictly verboten */
|
||||
return 0;
|
||||
case SMID_SEC_BODY:
|
||||
case SMID_SEC_PREFIX:
|
||||
case SMID_SEC_POSTFIX:
|
||||
case SMID_SRTPS_PREFIX:
|
||||
case SMID_SRTPS_POSTFIX:
|
||||
/* and the security sm are basically data. */
|
||||
return 0;
|
||||
}
|
||||
assert (0);
|
||||
break;
|
||||
case NN_XMSG_KIND_DATA:
|
||||
case NN_XMSG_KIND_DATA_REXMIT:
|
||||
case NN_XMSG_KIND_DATA_REXMIT_NOMERGE:
|
||||
switch (smkind)
|
||||
{
|
||||
case SMID_PAD:
|
||||
|
@ -405,6 +446,13 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk
|
|||
won't work for initial transmits, but those currently
|
||||
don't allow a readerId */
|
||||
return msg->kindspecific.data.readerId_off == 0;
|
||||
case SMID_SEC_BODY:
|
||||
case SMID_SEC_PREFIX:
|
||||
case SMID_SEC_POSTFIX:
|
||||
case SMID_SRTPS_PREFIX:
|
||||
case SMID_SRTPS_POSTFIX:
|
||||
/* Just do the same as 'normal' data sm. */
|
||||
return msg->kindspecific.data.readerId_off == 0;
|
||||
case SMID_ACKNACK:
|
||||
case SMID_HEARTBEAT:
|
||||
case SMID_GAP:
|
||||
|
@ -492,6 +540,97 @@ void nn_xmsg_submsg_setnext (struct nn_xmsg *msg, struct nn_xmsg_marker marker)
|
|||
((unsigned)(msg->data->payload + msg->sz + plsize - (char *) hdr) - RTPS_SUBMESSAGE_HEADER_SIZE);
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
size_t nn_xmsg_submsg_size (struct nn_xmsg *msg, struct nn_xmsg_marker marker)
|
||||
{
|
||||
SubmessageHeader_t *hdr = (SubmessageHeader_t*)nn_xmsg_submsg_from_marker(msg, marker);
|
||||
return align4u(hdr->octetsToNextHeader + sizeof(SubmessageHeader_t));
|
||||
}
|
||||
|
||||
void nn_xmsg_submsg_remove(struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker)
|
||||
{
|
||||
/* Just reset the message size to the start of the current sub-message. */
|
||||
msg->sz = sm_marker.offset;
|
||||
|
||||
/* Deleting the submessage means the readerId offset in a DATA_REXMIT message is no
|
||||
longer valid. Converting the message kind to a _NOMERGE one ensures no subsequent
|
||||
operation will assume its validity. */
|
||||
if (msg->kind == NN_XMSG_KIND_DATA_REXMIT)
|
||||
msg->kind = NN_XMSG_KIND_DATA_REXMIT_NOMERGE;
|
||||
}
|
||||
|
||||
void nn_xmsg_submsg_replace(struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker, unsigned char *new_submsg, size_t new_len)
|
||||
{
|
||||
/* Size of current sub-message. */
|
||||
size_t old_len = msg->sz - sm_marker.offset;
|
||||
|
||||
/* Adjust the message size to the new sub-message. */
|
||||
if (old_len < new_len)
|
||||
{
|
||||
nn_xmsg_append(msg, NULL, new_len - old_len);
|
||||
}
|
||||
else if (old_len > new_len)
|
||||
{
|
||||
nn_xmsg_shrink(msg, sm_marker, new_len);
|
||||
}
|
||||
|
||||
/* Just a sanity check: assert(msg_end == submsg_end) */
|
||||
assert((msg->data->payload + msg->sz) == (msg->data->payload + sm_marker.offset + new_len));
|
||||
|
||||
/* Replace the sub-message. */
|
||||
memcpy(msg->data->payload + sm_marker.offset, new_submsg, new_len);
|
||||
|
||||
/* The replacement submessage may have undergone any transformation and so the readerId
|
||||
offset in a DATA_REXMIT message is potentially no longer valid. Converting the
|
||||
message kind to a _NOMERGE one ensures no subsequent operation will assume its
|
||||
validity. This is used by the security implementation when encrypting and/or signing
|
||||
messages and apart from the offset possibly no longer being valid (for which one
|
||||
might conceivably be able to correct), there is also the issue that it may now be
|
||||
meaningless junk or that rewriting it would make the receiver reject it as having
|
||||
been tampered with. */
|
||||
if (msg->kind == NN_XMSG_KIND_DATA_REXMIT)
|
||||
msg->kind = NN_XMSG_KIND_DATA_REXMIT_NOMERGE;
|
||||
}
|
||||
|
||||
void nn_xmsg_submsg_append_refd_payload(struct nn_xmsg *msg, struct nn_xmsg_marker sm_marker)
|
||||
{
|
||||
DDSRT_UNUSED_ARG(sm_marker);
|
||||
/*
|
||||
* Normally, the refd payload pointer is moved around until it is added to
|
||||
* the iov of the socket. This reduces the amount of allocations and copies.
|
||||
*
|
||||
* However, in a few cases (like security), the sub-message should be one
|
||||
* complete blob.
|
||||
* Appending the payload will just do that.
|
||||
*/
|
||||
if (msg->refd_payload)
|
||||
{
|
||||
void *dst;
|
||||
|
||||
/* Get payload information. */
|
||||
char *payload_ptr = msg->refd_payload_iov.iov_base;
|
||||
size_t payload_len = msg->refd_payload_iov.iov_len;
|
||||
|
||||
/* Make space for the payload (dst points to the start of the appended space). */
|
||||
dst = nn_xmsg_append(msg, NULL, payload_len);
|
||||
|
||||
/* Copy the payload into the submessage. */
|
||||
memcpy(dst, payload_ptr, payload_len);
|
||||
|
||||
/* No need to remember the payload now. */
|
||||
ddsi_serdata_unref(msg->refd_payload);
|
||||
msg->refd_payload = NULL;
|
||||
if (msg->refd_payload_encoded)
|
||||
{
|
||||
ddsrt_free(msg->refd_payload_encoded);
|
||||
msg->refd_payload_encoded = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
void *nn_xmsg_submsg_from_marker (struct nn_xmsg *msg, struct nn_xmsg_marker marker)
|
||||
{
|
||||
return msg->data->payload + marker.offset;
|
||||
|
@ -558,22 +697,66 @@ void nn_xmsg_add_entityid (struct nn_xmsg * m)
|
|||
nn_xmsg_submsg_setnext (m, sm);
|
||||
}
|
||||
|
||||
void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len)
|
||||
void nn_xmsg_serdata (struct nn_xmsg *m, struct ddsi_serdata *serdata, size_t off, size_t len, struct writer *wr)
|
||||
{
|
||||
if (serdata->kind != SDK_EMPTY)
|
||||
{
|
||||
size_t len4 = align4u (len);
|
||||
assert (m->refd_payload == NULL);
|
||||
m->refd_payload = ddsi_serdata_to_ser_ref (serdata, off, len4, &m->refd_payload_iov);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
assert (m->refd_payload_encoded == NULL);
|
||||
/* When encoding is necessary, m->refd_payload_encoded will be allocated
|
||||
* and m->refd_payload_iov contents will change to point to that buffer.
|
||||
* If no encoding is necessary, nothing changes. */
|
||||
if (!encode_payload(wr, &(m->refd_payload_iov), &(m->refd_payload_encoded)))
|
||||
{
|
||||
DDS_CWARNING (&wr->e.gv->logconfig, "nn_xmsg_serdata: failed to encrypt data for "PGUIDFMT"", PGUID (wr->e.guid));
|
||||
ddsi_serdata_to_ser_unref (m->refd_payload, &m->refd_payload_iov);
|
||||
assert (m->refd_payload_encoded == NULL);
|
||||
m->refd_payload_iov.iov_base = NULL;
|
||||
m->refd_payload_iov.iov_len = 0;
|
||||
m->refd_payload = NULL;
|
||||
}
|
||||
#else
|
||||
DDSRT_UNUSED_ARG(wr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void nn_xmsg_setdst1 (struct nn_xmsg *m, const ddsi_guid_prefix_t *gp, const nn_locator_t *loc)
|
||||
void nn_xmsg_setdst1 (struct ddsi_domaingv *gv, struct nn_xmsg *m, const ddsi_guid_prefix_t *gp, const nn_locator_t *loc)
|
||||
{
|
||||
assert (m->dstmode == NN_XMSG_DST_UNSET);
|
||||
m->dstmode = NN_XMSG_DST_ONE;
|
||||
m->dstaddr.one.loc = *loc;
|
||||
m->data->dst.guid_prefix = nn_hton_guid_prefix (*gp);
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
if (m->sec_info.use_rtps_encoding && !m->sec_info.dst_pp_handle)
|
||||
{
|
||||
struct proxy_participant *proxypp;
|
||||
ddsi_guid_t guid;
|
||||
|
||||
guid.prefix = *gp;
|
||||
guid.entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
|
||||
proxypp = entidx_lookup_proxy_participant_guid(gv->entity_index, &guid);
|
||||
if (proxypp)
|
||||
m->sec_info.dst_pp_handle = q_omg_security_get_remote_participant_handle(proxypp);
|
||||
}
|
||||
#else
|
||||
DDSRT_UNUSED_ARG(gv);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool nn_xmsg_getdst1prefix (struct nn_xmsg *m, ddsi_guid_prefix_t *gp)
|
||||
{
|
||||
if (m->dstmode == NN_XMSG_DST_ONE)
|
||||
{
|
||||
*gp = nn_hton_guid_prefix(m->data->dst.guid_prefix);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
dds_return_t nn_xmsg_setdstPRD (struct nn_xmsg *m, const struct proxy_reader *prd)
|
||||
|
@ -581,7 +764,7 @@ dds_return_t nn_xmsg_setdstPRD (struct nn_xmsg *m, const struct proxy_reader *pr
|
|||
nn_locator_t loc;
|
||||
if (addrset_any_uc (prd->c.as, &loc) || addrset_any_mc (prd->c.as, &loc))
|
||||
{
|
||||
nn_xmsg_setdst1 (m, &prd->e.guid.prefix, &loc);
|
||||
nn_xmsg_setdst1 (prd->e.gv, m, &prd->e.guid.prefix, &loc);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
@ -596,7 +779,7 @@ dds_return_t nn_xmsg_setdstPWR (struct nn_xmsg *m, const struct proxy_writer *pw
|
|||
nn_locator_t loc;
|
||||
if (addrset_any_uc (pwr->c.as, &loc) || addrset_any_mc (pwr->c.as, &loc))
|
||||
{
|
||||
nn_xmsg_setdst1 (m, &pwr->e.guid.prefix, &loc);
|
||||
nn_xmsg_setdst1 (pwr->e.gv, m, &pwr->e.guid.prefix, &loc);
|
||||
return 0;
|
||||
}
|
||||
DDS_CWARNING (&pwr->e.gv->logconfig, "nn_xmsg_setdstPRD: no address for "PGUIDFMT, PGUID (pwr->e.guid));
|
||||
|
@ -753,31 +936,39 @@ void nn_xmsg_setwriterseq_fragid (struct nn_xmsg *msg, const ddsi_guid_t *wrguid
|
|||
msg->kindspecific.data.wrfragid = wrfragid;
|
||||
}
|
||||
|
||||
void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len)
|
||||
void *nn_xmsg_addpar_bo (struct nn_xmsg *m, nn_parameterid_t pid, size_t len, bool be)
|
||||
{
|
||||
#define BO2U(x) (be ? ddsrt_toBE2u((x)) : (x))
|
||||
|
||||
const size_t len4 = (len + 3) & ~(size_t)3; /* must alloc a multiple of 4 */
|
||||
nn_parameter_t *phdr;
|
||||
char *p;
|
||||
assert (len4 < UINT16_MAX); /* FIXME: return error */
|
||||
m->have_params = 1;
|
||||
phdr = nn_xmsg_append (m, NULL, sizeof (nn_parameter_t) + len4);
|
||||
phdr->parameterid = pid;
|
||||
phdr->length = (uint16_t) len4;
|
||||
phdr->parameterid = BO2U(pid);
|
||||
phdr->length = BO2U((uint16_t) len4);
|
||||
p = (char *) (phdr + 1);
|
||||
/* zero out padding bytes added to satisfy parameter alignment: this way
|
||||
valgrind can tell us where we forgot to initialize something */
|
||||
while (len < len4)
|
||||
p[len++] = 0;
|
||||
return p;
|
||||
|
||||
#undef BO2U
|
||||
}
|
||||
|
||||
void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata)
|
||||
void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len)
|
||||
{
|
||||
return nn_xmsg_addpar_bo(m, pid, len, false);
|
||||
}
|
||||
|
||||
void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct ddsi_serdata *serdata, bool force_md5)
|
||||
{
|
||||
if (serdata->kind != SDK_EMPTY)
|
||||
{
|
||||
const struct ddsi_serdata_default *serdata_def = (const struct ddsi_serdata_default *)serdata;
|
||||
char *p = nn_xmsg_addpar (m, PID_KEYHASH, 16);
|
||||
memcpy (p, serdata_def->keyhash.m_hash, 16);
|
||||
ddsi_serdata_get_keyhash(serdata, (struct ddsi_keyhash*)p, force_md5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,6 +999,11 @@ void nn_xmsg_addpar_sentinel (struct nn_xmsg * m)
|
|||
nn_xmsg_addpar (m, PID_SENTINEL, 0);
|
||||
}
|
||||
|
||||
void nn_xmsg_addpar_sentinel_bo (struct nn_xmsg * m, bool be)
|
||||
{
|
||||
nn_xmsg_addpar_bo (m, PID_SENTINEL, 0, be);
|
||||
}
|
||||
|
||||
int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg * m)
|
||||
{
|
||||
if (m->have_params)
|
||||
|
@ -888,7 +1084,7 @@ static void nn_xmsg_chain_add (struct nn_xmsg_chain *chain, struct nn_xmsg *m)
|
|||
static void nn_bw_limit_sleep_if_needed (struct ddsi_domaingv const * const gv, struct nn_bw_limiter *this, ssize_t size)
|
||||
{
|
||||
if ( this->bandwidth > 0 ) {
|
||||
nn_mtime_t tnow = now_mt();
|
||||
ddsrt_mtime_t tnow = ddsrt_time_monotonic();
|
||||
int64_t actual_interval;
|
||||
int64_t target_interval;
|
||||
|
||||
|
@ -931,7 +1127,7 @@ static void nn_bw_limit_init (struct nn_bw_limiter *limiter, uint32_t bandwidth_
|
|||
limiter->bandwidth = bandwidth_limit;
|
||||
limiter->balance = 0;
|
||||
if (bandwidth_limit)
|
||||
limiter->last_update = now_mt ();
|
||||
limiter->last_update = ddsrt_time_monotonic();
|
||||
else
|
||||
limiter->last_update.v = 0;
|
||||
}
|
||||
|
@ -951,6 +1147,9 @@ static void nn_xpack_reinit (struct nn_xpack *xp)
|
|||
xp->msg_len.length = 0;
|
||||
xp->included_msgs.latest = NULL;
|
||||
xp->maxdelay = DDS_INFINITY;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
xp->sec_info.use_rtps_encoding = 0;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
xp->encoderId = 0;
|
||||
#endif
|
||||
|
@ -1010,6 +1209,35 @@ void nn_xpack_free (struct nn_xpack *xp)
|
|||
ddsrt_free (xp);
|
||||
}
|
||||
|
||||
static ssize_t nn_xpack_send_rtps(struct nn_xpack * xp, const nn_locator_t *loc)
|
||||
{
|
||||
ssize_t ret = -1;
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/* Only encode when needed. */
|
||||
if (xp->sec_info.use_rtps_encoding)
|
||||
{
|
||||
ret = secure_conn_write(
|
||||
xp->gv,
|
||||
xp->conn,
|
||||
loc,
|
||||
xp->niov,
|
||||
xp->iov,
|
||||
xp->call_flags,
|
||||
&(xp->msg_len),
|
||||
(xp->dstmode == NN_XMSG_DST_ONE),
|
||||
&(xp->sec_info),
|
||||
ddsi_conn_write);
|
||||
}
|
||||
else
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
{
|
||||
ret = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
|
||||
{
|
||||
struct nn_xpack *xp = varg;
|
||||
|
@ -1036,14 +1264,17 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
|
|||
|
||||
if (!gv->mute)
|
||||
{
|
||||
nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
|
||||
nbytes = nn_xpack_send_rtps(xp, loc);
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
size_t i, len;
|
||||
for (i = 0, len = 0; i < xp->niov; i++) {
|
||||
len += xp->iov[i].iov_len;
|
||||
}
|
||||
assert (nbytes == -1 || (size_t) nbytes == len);
|
||||
/* Possible number of bytes written can be larger
|
||||
* due to security. */
|
||||
assert (nbytes == -1 || (size_t) nbytes >= len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1337,12 +1568,13 @@ static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg *
|
|||
return 0;
|
||||
#endif
|
||||
|
||||
return addressing_info_eq_onesidederr (xp, m);
|
||||
}
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
/* Don't mix up encoded and plain rtps messages */
|
||||
if (xp->sec_info.use_rtps_encoding != m->sec_info.use_rtps_encoding)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
static int guid_prefix_eq (const ddsi_guid_prefix_t *a, const ddsi_guid_prefix_t *b)
|
||||
{
|
||||
return a->u[0] == b->u[0] && a->u[1] == b->u[1] && a->u[2] == b->u[2];
|
||||
return addressing_info_eq_onesidederr (xp, m);
|
||||
}
|
||||
|
||||
int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flags)
|
||||
|
@ -1400,6 +1632,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
|
|||
break;
|
||||
case NN_XMSG_KIND_DATA:
|
||||
case NN_XMSG_KIND_DATA_REXMIT:
|
||||
case NN_XMSG_KIND_DATA_REXMIT_NOMERGE:
|
||||
GVTRACE ("%s("PGUIDFMT":#%"PRId64"/%u)",
|
||||
(m->kind == NN_XMSG_KIND_DATA) ? "data" : "rexmit",
|
||||
PGUID (m->kindspecific.data.wrguid),
|
||||
|
@ -1430,6 +1663,9 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
|
|||
niov++;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
xp->sec_info = m->sec_info;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
xp->encoderId = m->encoderid;
|
||||
#endif
|
||||
|
|
|
@ -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 */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue