Encoding preparations (#329)
* Payload encoding/decoding preparations. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Sub-message encoding/decoding preparations. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * RTPS message encoding/decoding preparations. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Removed redundant destination acquiring. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com> * Refactored secure writing of RTPS messages slightly. Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
parent
30bd6e4c1c
commit
66c0d87886
13 changed files with 2134 additions and 121 deletions
|
@ -12,16 +12,40 @@
|
|||
#ifndef DDSI_OMG_SECURITY_H
|
||||
#define DDSI_OMG_SECURITY_H
|
||||
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_plist.h"
|
||||
#include "dds/ddsi/q_entity.h"
|
||||
#include "dds/ddsi/q_globals.h"
|
||||
#include "dds/ddsi/q_radmin.h"
|
||||
#include "dds/ddsi/q_xmsg.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
NN_RTPS_MSG_STATE_ERROR,
|
||||
NN_RTPS_MSG_STATE_PLAIN,
|
||||
NN_RTPS_MSG_STATE_ENCODED
|
||||
} nn_rtps_msg_state_t;
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
|
||||
typedef struct nn_msg_sec_info {
|
||||
int64_t src_pp_handle;
|
||||
int64_t dst_pp_handle;
|
||||
bool use_rtps_encoding;
|
||||
} nn_msg_sec_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if any participant has security enabled.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Some participant is secure
|
||||
* @retval false No participant is not secure
|
||||
*/
|
||||
bool q_omg_security_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Check if security is enabled for the participant.
|
||||
*
|
||||
|
@ -33,6 +57,26 @@ extern "C" {
|
|||
*/
|
||||
bool q_omg_participant_is_secure(const struct participant *pp);
|
||||
|
||||
/**
|
||||
* @brief Get the security handle of the given local participant.
|
||||
*
|
||||
* @param[in] pp Participant to check if it is secure.
|
||||
*
|
||||
* @returns int64_t
|
||||
* @retval Local participant security handle
|
||||
*/
|
||||
int64_t q_omg_security_get_local_participant_handle(struct participant *pp);
|
||||
|
||||
/**
|
||||
* @brief Get the security handle of the given remote participant.
|
||||
*
|
||||
* @param[in] proxypp Participant to check if it is secure.
|
||||
*
|
||||
* @returns int64_t
|
||||
* @retval Remote participant security handle
|
||||
*/
|
||||
int64_t q_omg_security_get_remote_participant_handle(struct proxy_participant *proxypp);
|
||||
|
||||
/**
|
||||
* @brief Get security info flags of the given writer.
|
||||
*
|
||||
|
@ -107,12 +151,355 @@ unsigned determine_publication_writer(const struct writer *wr);
|
|||
* @retval true The proxy participant may be deleted.
|
||||
* @retval false The proxy participant may not be deleted by this writer.
|
||||
*/
|
||||
bool allow_proxy_participant_deletion(struct q_globals * const gv, const struct ddsi_guid *guid, const ddsi_entityid_t pwr_entityid);
|
||||
bool
|
||||
is_proxy_participant_deletion_allowed(
|
||||
struct q_globals * const gv,
|
||||
const struct ddsi_guid *guid,
|
||||
const ddsi_entityid_t pwr_entityid);
|
||||
|
||||
/**
|
||||
* @brief Determine if the messages, related to the given remote
|
||||
* entity, are RTPS protected or not.
|
||||
*
|
||||
* @param[in] proxy_pp Related proxy participant.
|
||||
* @param[in] entityid ID of the entity to check.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true The entity messages are RTPS protected.
|
||||
* @retval false The entity messages are not RTPS protected.
|
||||
*/
|
||||
bool
|
||||
q_omg_security_is_remote_rtps_protected(
|
||||
struct proxy_participant *proxy_pp,
|
||||
ddsi_entityid_t entityid);
|
||||
|
||||
/**
|
||||
* @brief Determine if the messages, related to the given local
|
||||
* entity, are RTPS protected or not.
|
||||
*
|
||||
* @param[in] pp Related participant.
|
||||
* @param[in] entityid ID of the entity to check.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true The entity messages are RTPS protected.
|
||||
* @retval false The entity messages are not RTPS protected.
|
||||
*/
|
||||
bool
|
||||
q_omg_security_is_local_rtps_protected(
|
||||
struct participant *pp,
|
||||
ddsi_entityid_t entityid);
|
||||
|
||||
/**
|
||||
* @brief Set security information, depending on plist, into the given
|
||||
* proxy participant.
|
||||
*
|
||||
* @param[in] proxypp Proxy participant to set security info on.
|
||||
* @param[in] plist Paramater list, possibly contains security info.
|
||||
*/
|
||||
void
|
||||
set_proxy_participant_security_info(
|
||||
struct proxy_participant *proxypp,
|
||||
const nn_plist_t *plist);
|
||||
|
||||
/**
|
||||
* @brief Set security information, depending on plist and proxy participant,
|
||||
* into the given proxy reader.
|
||||
*
|
||||
* @param[in] prd Proxy reader to set security info on.
|
||||
* @param[in] plist Paramater list, possibly contains security info.
|
||||
*/
|
||||
void
|
||||
set_proxy_reader_security_info(
|
||||
struct proxy_reader *prd,
|
||||
const nn_plist_t *plist);
|
||||
|
||||
/**
|
||||
* @brief Set security information, depending on plist and proxy participant,
|
||||
* into the given proxy writer.
|
||||
*
|
||||
* @param[in] pwr Proxy writer to set security info on.
|
||||
* @param[in] plist Paramater list, possibly contains security info.
|
||||
*/
|
||||
void
|
||||
set_proxy_writer_security_info(
|
||||
struct proxy_writer *pwr,
|
||||
const nn_plist_t *plist);
|
||||
|
||||
/**
|
||||
* @brief Encode RTPS message.
|
||||
*
|
||||
* @param[in] src_handle Security handle of data source.
|
||||
* @param[in] src_guid GUID of the entity data source.
|
||||
* @param[in] src_buf Original RTPS message.
|
||||
* @param[in] src_len Original RTPS message size.
|
||||
* @param[out] dst_buf Encoded RTPS message.
|
||||
* @param[out] dst_len Encoded RTPS message size.
|
||||
* @param[in] dst_handle Security handle of data destination.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Encoding succeeded.
|
||||
* @retval false Encoding failed.
|
||||
*/
|
||||
bool
|
||||
q_omg_security_encode_rtps_message(
|
||||
int64_t src_handle,
|
||||
ddsi_guid_t *src_guid,
|
||||
const unsigned char *src_buf,
|
||||
const unsigned int src_len,
|
||||
unsigned char **dst_buf,
|
||||
unsigned int *dst_len,
|
||||
int64_t dst_handle);
|
||||
|
||||
/**
|
||||
* @brief Encode payload when necessary.
|
||||
*
|
||||
* When encoding is necessary, *buf will be allocated and the vec contents
|
||||
* will change to point to that buffer.
|
||||
* It is expected that the vec contents is always aliased.
|
||||
*
|
||||
* If no encoding is necessary, nothing changes.
|
||||
*
|
||||
* encoding( not needed) -> return( true), vec(untouched), buf(NULL)
|
||||
* encoding(needed&success) -> return( true), vec( buf(new))
|
||||
* encoding(needed&failure) -> return(false), vec(untouched), buf(NULL)
|
||||
*
|
||||
* @param[in] wr Writer that writes the payload.
|
||||
* @param[in,out] vec An iovec that contains the payload.
|
||||
* @param[out] buf Buffer to contain the encoded payload.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Encoding succeeded or not necessary. Either way, vec
|
||||
* contains the payload that should be send.
|
||||
* @retval false Encoding was necessary, but failed.
|
||||
*/
|
||||
bool
|
||||
encode_payload(
|
||||
struct writer *wr,
|
||||
ddsrt_iovec_t *vec,
|
||||
unsigned char **buf);
|
||||
|
||||
/**
|
||||
* @brief Decode the payload of a Data submessage.
|
||||
*
|
||||
* When decoding is necessary, the payloadp memory will be replaced
|
||||
* by the decoded payload. This means that the original submessage
|
||||
* now contains payload that can be deserialized.
|
||||
*
|
||||
* If no decoding is necessary, nothing changes.
|
||||
*
|
||||
* @param[in] gv Global information.
|
||||
* @param[in] sampleinfo Sample information.
|
||||
* @param[in,out] payloadp Pointer to payload memory.
|
||||
* @param[in] payloadsz Size of payload.
|
||||
* @param[in,out] submsg_len Size of submessage.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Decoding succeeded or not necessary. Either way, payloadp
|
||||
* contains the data that should be deserialized.
|
||||
* @retval false Decoding was necessary, but failed.
|
||||
*/
|
||||
bool
|
||||
decode_Data(
|
||||
const struct q_globals *gv,
|
||||
struct nn_rsample_info *sampleinfo,
|
||||
unsigned char *payloadp,
|
||||
uint32_t payloadsz,
|
||||
size_t *submsg_len);
|
||||
|
||||
/**
|
||||
* @brief Decode the payload of a DataFrag submessage.
|
||||
*
|
||||
* When decoding is necessary, the payloadp memory will be replaced
|
||||
* by the decoded payload. This means that the original submessage
|
||||
* now contains payload that can be deserialized.
|
||||
*
|
||||
* If no decoding is necessary, nothing changes.
|
||||
*
|
||||
* @param[in] gv Global information.
|
||||
* @param[in] sampleinfo Sample information.
|
||||
* @param[in,out] payloadp Pointer to payload memory.
|
||||
* @param[in] payloadsz Size of payload.
|
||||
* @param[in,out] submsg_len Size of submessage.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Decoding succeeded or not necessary. Either way, payloadp
|
||||
* contains the data that should be deserialized.
|
||||
* @retval false Decoding was necessary, but failed.
|
||||
*/
|
||||
bool
|
||||
decode_DataFrag(
|
||||
const struct q_globals *gv,
|
||||
struct nn_rsample_info *sampleinfo,
|
||||
unsigned char *payloadp,
|
||||
uint32_t payloadsz,
|
||||
size_t *submsg_len);
|
||||
|
||||
/**
|
||||
* @brief Encode datareader submessage when necessary.
|
||||
*
|
||||
* When encoding is necessary, the original submessage will be replaced
|
||||
* by a new encoded submessage.
|
||||
* If the encoding fails, the original submessage will be removed.
|
||||
*
|
||||
* If no encoding is necessary, nothing changes.
|
||||
*
|
||||
* @param[in,out] msg Complete message.
|
||||
* @param[in,out] sm_marker Submessage location within message.
|
||||
* @param[in] pwr Writer for which the message is intended.
|
||||
* @param[in] rd_guid Origin reader guid.
|
||||
*/
|
||||
void
|
||||
encode_datareader_submsg(
|
||||
struct nn_xmsg *msg,
|
||||
struct nn_xmsg_marker sm_marker,
|
||||
struct proxy_writer *pwr,
|
||||
const struct ddsi_guid *rd_guid);
|
||||
|
||||
/**
|
||||
* @brief Encode datawriter submessage when necessary.
|
||||
*
|
||||
* When encoding is necessary, the original submessage will be replaced
|
||||
* by a new encoded submessage.
|
||||
* If the encoding fails, the original submessage will be removed.
|
||||
*
|
||||
* If no encoding is necessary, nothing changes.
|
||||
*
|
||||
* @param[in,out] msg Complete message.
|
||||
* @param[in,out] sm_marker Submessage location within message.
|
||||
* @param[in] wr Origin writer guid.
|
||||
*/
|
||||
void
|
||||
encode_datawriter_submsg(
|
||||
struct nn_xmsg *msg,
|
||||
struct nn_xmsg_marker sm_marker,
|
||||
struct writer *wr);
|
||||
|
||||
/**
|
||||
* @brief Check if given submessage is properly decoded.
|
||||
*
|
||||
* When decoding is necessary, it should be checked if a plain submessage was
|
||||
* actually decoded. Otherwise data can be injected just by inserting a plain
|
||||
* submessage directly.
|
||||
*
|
||||
* @param[in] e Entity information.
|
||||
* @param[in] c Proxy endpoint information.
|
||||
* @param[in] proxypp Related proxy participant.
|
||||
* @param[in] rst Receiver information.
|
||||
* @param[in] prev_smid Previously handled submessage ID.
|
||||
*
|
||||
* @returns bool
|
||||
* @retval true Decoding succeeded or was not necessary.
|
||||
* @retval false Decoding was necessary, but not detected.
|
||||
*/
|
||||
bool
|
||||
validate_msg_decoding(
|
||||
const struct entity_common *e,
|
||||
const struct proxy_endpoint_common *c,
|
||||
struct proxy_participant *proxypp,
|
||||
struct receiver_state *rst,
|
||||
SubmessageKind_t prev_smid);
|
||||
|
||||
/**
|
||||
* @brief Decode not only SecPrefix, but also the SecBody and SecPostfix
|
||||
* sub-messages.
|
||||
*
|
||||
* When encrypted, the original SecBody will be replaced by the decrypted
|
||||
* submessage. Then the normal sequence can continue as if there was no
|
||||
* encrypted data.
|
||||
*
|
||||
* @param[in] rst Receiver information.
|
||||
* @param[in,out] submsg Pointer to SecPrefix/(SecBody|Submsg)/SecPostfix.
|
||||
* @param[in] submsg_size Size of SecPrefix submessage.
|
||||
* @param[in] msg_end End of the complete message.
|
||||
* @param[in] src_prefix Prefix of the source entity.
|
||||
* @param[in] dst_prefix Prefix of the destination entity.
|
||||
* @param[in] byteswap Do the bytes need swapping?
|
||||
*
|
||||
* @returns int
|
||||
* @retval >= 0 Decoding succeeded.
|
||||
* @retval < 0 Decoding failed.
|
||||
*/
|
||||
int
|
||||
decode_SecPrefix(
|
||||
struct receiver_state *rst,
|
||||
unsigned char *submsg,
|
||||
size_t submsg_size,
|
||||
unsigned char * const msg_end,
|
||||
const ddsi_guid_prefix_t * const src_prefix,
|
||||
const ddsi_guid_prefix_t * const dst_prefix,
|
||||
int byteswap);
|
||||
|
||||
/**
|
||||
* @brief Decode the RTPS message.
|
||||
*
|
||||
* When encrypted, the original buffers and information will be replaced
|
||||
* by the decrypted RTPS message. Then the normal sequence can continue
|
||||
* as if there was no encrypted data.
|
||||
*
|
||||
* @param[in] ts1 Thread information.
|
||||
* @param[in] gv Global information.
|
||||
* @param[in,out] rmsg Message information.
|
||||
* @param[in,out] hdr Message header.
|
||||
* @param[in,out] buff Message buffer.
|
||||
* @param[in,out] sz Message size.
|
||||
* @param[in] rbpool Buffers pool.
|
||||
* @param[in] isstream Is message a stream variant?
|
||||
*
|
||||
* @returns nn_rtps_msg_state_t
|
||||
* @retval NN_RTPS_MSG_STATE_PLAIN No decoding was necessary.
|
||||
* @retval NN_RTPS_MSG_STATE_ENCODED Decoding succeeded.
|
||||
* @retval NN_RTPS_MSG_STATE_ERROR Decoding failed.
|
||||
*/
|
||||
nn_rtps_msg_state_t
|
||||
decode_rtps_message(
|
||||
struct thread_state1 * const ts1,
|
||||
struct q_globals *gv,
|
||||
struct nn_rmsg **rmsg,
|
||||
Header_t **hdr,
|
||||
unsigned char **buff,
|
||||
ssize_t *sz,
|
||||
struct nn_rbufpool *rbpool,
|
||||
bool isstream);
|
||||
|
||||
/**
|
||||
* @brief Send the RTPS message securely.
|
||||
*
|
||||
* @param[in] conn Connection to use.
|
||||
* @param[in] dst Possible destination information.
|
||||
* @param[in] niov Number of io vectors.
|
||||
* @param[in] iov Array of io vectors.
|
||||
* @param[in] flags Connection write flags.
|
||||
* @param[in,out] msg_len Submessage containing length.
|
||||
* @param[in] dst_one Is there only one specific destination?
|
||||
* @param[in] sec_info Security information for handles.
|
||||
* @param[in] conn_write_cb Function to call to do the actual writing.
|
||||
*
|
||||
* @returns ssize_t
|
||||
* @retval negative/zero Something went wrong.
|
||||
* @retval positive Secure writing succeeded.
|
||||
*/
|
||||
ssize_t
|
||||
secure_conn_write(
|
||||
ddsi_tran_conn_t conn,
|
||||
const nn_locator_t *dst,
|
||||
size_t niov,
|
||||
const ddsrt_iovec_t *iov,
|
||||
uint32_t flags,
|
||||
MsgLen_t *msg_len,
|
||||
bool dst_one,
|
||||
nn_msg_sec_info_t *sec_info,
|
||||
ddsi_tran_write_fn_t conn_write_cb);
|
||||
|
||||
#else /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#include "dds/ddsi/q_unused.h"
|
||||
|
||||
inline bool
|
||||
q_omg_security_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
q_omg_participant_is_secure(
|
||||
UNUSED_ARG(const struct participant *pp))
|
||||
|
@ -135,7 +522,7 @@ determine_publication_writer(
|
|||
}
|
||||
|
||||
inline bool
|
||||
allow_proxy_participant_deletion(
|
||||
is_proxy_participant_deletion_allowed(
|
||||
UNUSED_ARG(struct q_globals * const gv),
|
||||
UNUSED_ARG(const struct ddsi_guid *guid),
|
||||
UNUSED_ARG(const ddsi_entityid_t pwr_entityid))
|
||||
|
@ -143,6 +530,106 @@ allow_proxy_participant_deletion(
|
|||
return true;
|
||||
}
|
||||
|
||||
inline void
|
||||
set_proxy_participant_security_info(
|
||||
UNUSED_ARG(struct proxy_participant *prd),
|
||||
UNUSED_ARG(const nn_plist_t *plist))
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
set_proxy_reader_security_info(
|
||||
UNUSED_ARG(struct proxy_reader *prd),
|
||||
UNUSED_ARG(const nn_plist_t *plist))
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
set_proxy_writer_security_info(
|
||||
UNUSED_ARG(struct proxy_writer *pwr),
|
||||
UNUSED_ARG(const nn_plist_t *plist))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
decode_Data(
|
||||
UNUSED_ARG(const struct q_globals *gv),
|
||||
UNUSED_ARG(struct nn_rsample_info *sampleinfo),
|
||||
UNUSED_ARG(unsigned char *payloadp),
|
||||
UNUSED_ARG(uint32_t payloadsz),
|
||||
UNUSED_ARG(size_t *submsg_len))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
decode_DataFrag(
|
||||
UNUSED_ARG(const struct q_globals *gv),
|
||||
UNUSED_ARG(struct nn_rsample_info *sampleinfo),
|
||||
UNUSED_ARG(unsigned char *payloadp),
|
||||
UNUSED_ARG(uint32_t payloadsz),
|
||||
UNUSED_ARG(size_t *submsg_len))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void
|
||||
encode_datareader_submsg(
|
||||
UNUSED_ARG(struct nn_xmsg *msg),
|
||||
UNUSED_ARG(struct nn_xmsg_marker sm_marker),
|
||||
UNUSED_ARG(struct proxy_writer *pwr),
|
||||
UNUSED_ARG(const struct ddsi_guid *rd_guid))
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
encode_datawriter_submsg(
|
||||
UNUSED_ARG(struct nn_xmsg *msg),
|
||||
UNUSED_ARG(struct nn_xmsg_marker sm_marker),
|
||||
UNUSED_ARG(struct writer *wr))
|
||||
{
|
||||
}
|
||||
|
||||
inline bool
|
||||
validate_msg_decoding(
|
||||
UNUSED_ARG(const struct entity_common *e),
|
||||
UNUSED_ARG(const struct proxy_endpoint_common *c),
|
||||
UNUSED_ARG(struct proxy_participant *proxypp),
|
||||
UNUSED_ARG(struct receiver_state *rst),
|
||||
UNUSED_ARG(SubmessageKind_t prev_smid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int
|
||||
decode_SecPrefix(
|
||||
UNUSED_ARG(struct receiver_state *rst),
|
||||
UNUSED_ARG(unsigned char *submsg),
|
||||
UNUSED_ARG(size_t submsg_size),
|
||||
UNUSED_ARG(unsigned char * const msg_end),
|
||||
UNUSED_ARG(const ddsi_guid_prefix_t * const src_prefix),
|
||||
UNUSED_ARG(const ddsi_guid_prefix_t * const dst_prefix),
|
||||
UNUSED_ARG(int byteswap))
|
||||
{
|
||||
/* Just let the parsing ignore the security sub-messages. */
|
||||
return true;
|
||||
}
|
||||
|
||||
inline nn_rtps_msg_state_t
|
||||
decode_rtps_message(
|
||||
UNUSED_ARG(struct thread_state1 * const ts1),
|
||||
UNUSED_ARG(struct q_globals *gv),
|
||||
UNUSED_ARG(struct nn_rmsg **rmsg),
|
||||
UNUSED_ARG(Header_t **hdr),
|
||||
UNUSED_ARG(unsigned char **buff),
|
||||
UNUSED_ARG(ssize_t *sz),
|
||||
UNUSED_ARG(struct nn_rbufpool *rbpool),
|
||||
UNUSED_ARG(bool isstream))
|
||||
{
|
||||
return NN_RTPS_MSG_STATE_PLAIN;
|
||||
}
|
||||
|
||||
#endif /* DDSI_INCLUDE_SECURITY */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "dds/ddsrt/avl.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsi/q_rtps.h"
|
||||
#include "dds/ddsi/q_plist.h"
|
||||
#include "dds/ddsi/q_protocol.h"
|
||||
#include "dds/ddsi/q_lat_estim.h"
|
||||
#include "dds/ddsi/q_ephash.h"
|
||||
|
@ -314,6 +315,9 @@ struct proxy_participant
|
|||
unsigned proxypp_have_spdp: 1;
|
||||
unsigned proxypp_have_cm: 1;
|
||||
unsigned owns_lease: 1;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
nn_security_info_t security_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Representing proxy subscriber & publishers as "groups": until DDSI2
|
||||
|
@ -341,6 +345,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 proxy_writer {
|
||||
|
|
|
@ -162,6 +162,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_PT_INFO_CONTAINER = 0x80,
|
||||
SMID_PT_MSG_LEN = 0x81,
|
||||
|
|
|
@ -102,10 +102,11 @@ struct nn_rmsg {
|
|||
#define NN_RMSG_PAYLOADOFF(m, o) (NN_RMSG_PAYLOAD (m) + (o))
|
||||
|
||||
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 */
|
||||
|
|
|
@ -46,8 +46,8 @@ 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);
|
||||
|
||||
/* 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_prismtech_participant_version_info;
|
||||
struct nn_xmsgpool;
|
||||
|
@ -54,10 +56,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 q_globals *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,7 +117,13 @@ 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, nn_wctime_t t);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -213,7 +213,7 @@ int spdp_write (struct participant *pp)
|
|||
terribly important, the msg will grow as needed, address space is
|
||||
essentially meaningless because we only use the message to
|
||||
construct the payload. */
|
||||
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, NULL, 0, NN_XMSG_KIND_DATA);
|
||||
|
||||
nn_plist_init_empty (&ps);
|
||||
ps.present |= PP_PARTICIPANT_GUID | PP_BUILTIN_ENDPOINT_SET |
|
||||
|
@ -343,7 +343,7 @@ static int spdp_dispose_unregister_with_wr (struct participant *pp, unsigned ent
|
|||
return 0;
|
||||
}
|
||||
|
||||
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
mpayload = nn_xmsg_new (pp->e.gv->xmsgpool, &pp->e.guid, NULL, 0, NN_XMSG_KIND_DATA);
|
||||
nn_plist_init_empty (&ps);
|
||||
ps.present |= PP_PARTICIPANT_GUID;
|
||||
ps.participant_guid = pp->e.guid;
|
||||
|
@ -437,7 +437,7 @@ static int handle_SPDP_dead (const struct receiver_state *rst, ddsi_entityid_t p
|
|||
guid = datap->participant_guid;
|
||||
GVLOGDISC (" %"PRIx32":%"PRIx32":%"PRIx32":%"PRIx32, PGUID (guid));
|
||||
assert (guid.entityid.u == NN_ENTITYID_PARTICIPANT);
|
||||
if (allow_proxy_participant_deletion(gv, &guid, pwr_entityid))
|
||||
if (is_proxy_participant_deletion_allowed(gv, &guid, pwr_entityid))
|
||||
{
|
||||
if (delete_proxy_participant_by_guid (gv, &guid, timestamp, 0) < 0)
|
||||
{
|
||||
|
@ -999,7 +999,7 @@ static int sedp_write_endpoint
|
|||
the QoS and other settings. So the header fields aren't really
|
||||
important, except that they need to be set to reasonable things
|
||||
or it'll crash */
|
||||
mpayload = nn_xmsg_new (gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
mpayload = nn_xmsg_new (gv->xmsgpool, &wr->e.guid, NULL, 0, NN_XMSG_KIND_DATA);
|
||||
nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
|
||||
if (xqos) nn_xqos_addtomsg (mpayload, xqos, qosdiff);
|
||||
nn_xmsg_addpar_sentinel (mpayload);
|
||||
|
@ -1467,7 +1467,7 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap)
|
|||
|
||||
sedp_wr = get_sedp_writer (pp, NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER);
|
||||
|
||||
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid, NULL, 0, NN_XMSG_KIND_DATA);
|
||||
delta = nn_xqos_delta (&datap->qos, &sedp_wr->e.gv->default_xqos_tp, ~(uint64_t)0);
|
||||
if (sedp_wr->e.gv->config.explicitly_publish_qos_set_to_default)
|
||||
delta |= ~QP_UNRECOGNIZED_INCOMPATIBLE_MASK;
|
||||
|
@ -1505,7 +1505,7 @@ int sedp_write_cm_participant (struct participant *pp, int alive)
|
|||
the QoS and other settings. So the header fields aren't really
|
||||
important, except that they need to be set to reasonable things
|
||||
or it'll crash */
|
||||
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid.prefix, 0, NN_XMSG_KIND_DATA);
|
||||
mpayload = nn_xmsg_new (sedp_wr->e.gv->xmsgpool, &sedp_wr->e.guid, NULL, 0, NN_XMSG_KIND_DATA);
|
||||
nn_plist_init_empty (&ps);
|
||||
ps.present = PP_PARTICIPANT_GUID;
|
||||
ps.participant_guid = pp->e.guid;
|
||||
|
|
|
@ -2119,7 +2119,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader
|
|||
ddsrt_avl_insert_ipath (&pwr_readers_treedef, &pwr->readers, m, &path);
|
||||
local_reader_ary_insert(&pwr->rdary, rd);
|
||||
ddsrt_mutex_unlock (&pwr->e.lock);
|
||||
qxev_pwr_entityid (pwr, &rd->e.guid.prefix);
|
||||
qxev_pwr_entityid (pwr, &rd->e.guid);
|
||||
|
||||
ELOGDISC (pwr, "\n");
|
||||
|
||||
|
@ -2163,7 +2163,7 @@ static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer
|
|||
PGUID (wr->e.guid), PGUID (prd->e.guid));
|
||||
ddsrt_avl_insert_ipath (&prd_writers_treedef, &prd->writers, m, &path);
|
||||
ddsrt_mutex_unlock (&prd->e.lock);
|
||||
qxev_prd_entityid (prd, &wr->e.guid.prefix);
|
||||
qxev_prd_entityid (prd, &wr->e.guid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3974,6 +3974,8 @@ void new_proxy_participant
|
|||
nn_xqos_mergein_missing (&proxypp->plist->qos, &gv->default_plist_pp.qos, ~(uint64_t)0);
|
||||
ddsrt_avl_init (&proxypp_groups_treedef, &proxypp->groups);
|
||||
|
||||
set_proxy_participant_security_info(proxypp, plist);
|
||||
|
||||
if (custom_flags & CF_INC_KERNEL_SEQUENCE_NUMBERS)
|
||||
proxypp->kernel_sequence_numbers = 1;
|
||||
else
|
||||
|
@ -4289,6 +4291,11 @@ static void proxy_endpoint_common_init (struct entity_common *e, struct proxy_en
|
|||
else
|
||||
memset (&c->group_guid, 0, sizeof (c->group_guid));
|
||||
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
c->security_info.security_attributes = 0;
|
||||
c->security_info.plugin_security_attributes = 0;
|
||||
#endif
|
||||
|
||||
ref_proxy_participant (proxypp, c);
|
||||
}
|
||||
|
||||
|
@ -4394,6 +4401,8 @@ int new_proxy_writer (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
|||
pwr->ddsi2direct_cb = 0;
|
||||
pwr->ddsi2direct_cbarg = 0;
|
||||
|
||||
set_proxy_writer_security_info(pwr, plist);
|
||||
|
||||
local_reader_ary_init (&pwr->rdary);
|
||||
|
||||
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
||||
|
@ -4437,7 +4446,7 @@ void update_proxy_writer (struct proxy_writer *pwr, seqno_t seq, struct addrset
|
|||
rd = ephash_lookup_reader_guid (pwr->e.gv->guid_hash, &m->rd_guid);
|
||||
if (rd)
|
||||
{
|
||||
qxev_pwr_entityid (pwr, &rd->e.guid.prefix);
|
||||
qxev_pwr_entityid (pwr, &rd->e.guid);
|
||||
}
|
||||
m = ddsrt_avl_iter_next (&iter);
|
||||
}
|
||||
|
@ -4494,7 +4503,7 @@ void update_proxy_reader (struct proxy_reader *prd, seqno_t seq, struct addrset
|
|||
ddsrt_mutex_lock (&wr->e.lock);
|
||||
rebuild_writer_addrset (wr);
|
||||
ddsrt_mutex_unlock (&wr->e.lock);
|
||||
qxev_prd_entityid (prd, &wr->e.guid.prefix);
|
||||
qxev_prd_entityid (prd, &wr->e.guid);
|
||||
}
|
||||
wrguid = guid_next;
|
||||
ddsrt_mutex_lock (&prd->e.lock);
|
||||
|
@ -4582,6 +4591,8 @@ int new_proxy_reader (struct q_globals *gv, const struct ddsi_guid *ppguid, cons
|
|||
#endif
|
||||
prd->is_fict_trans_reader = 0;
|
||||
|
||||
set_proxy_reader_security_info(prd, plist);
|
||||
|
||||
ddsrt_avl_init (&prd_writers_treedef, &prd->writers);
|
||||
|
||||
/* locking the entity prevents matching while the built-in topic hasn't been published yet */
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "dds/ddsi/ddsi_mcgroup.h"
|
||||
#include "dds/ddsi/ddsi_serdata.h"
|
||||
#include "dds/ddsi/ddsi_serdata_default.h" /* FIXME: get rid of this */
|
||||
#include "dds/ddsi/ddsi_security_omg.h"
|
||||
|
||||
#include "dds/ddsi/sysdeps.h"
|
||||
#include "dds__whc.h"
|
||||
|
@ -278,7 +279,34 @@ static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, dds
|
|||
sampleinfo->pwr = pwr;
|
||||
}
|
||||
|
||||
static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, Data_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp)
|
||||
static int set_sampleinfo_bswap (struct nn_rsample_info *sampleinfo, struct CDRHeader *hdr)
|
||||
{
|
||||
if (hdr)
|
||||
{
|
||||
switch (hdr->identifier)
|
||||
{
|
||||
case CDR_BE:
|
||||
case PL_CDR_BE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
case CDR_LE:
|
||||
case PL_CDR_LE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, Data_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz)
|
||||
{
|
||||
/* on success: sampleinfo->{seq,rst,statusinfo,pt_wr_info_zoff,bswap,complex_qos} all set */
|
||||
ddsi_guid_t pwr_guid;
|
||||
|
@ -354,6 +382,7 @@ static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, D
|
|||
{
|
||||
/*TRACE (("no payload\n"));*/
|
||||
*payloadp = NULL;
|
||||
*payloadsz = 0;
|
||||
sampleinfo->size = 0;
|
||||
}
|
||||
else if ((size_t) ((char *) ptr + 4 - (char *) msg) > size)
|
||||
|
@ -363,35 +392,16 @@ static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, D
|
|||
}
|
||||
else
|
||||
{
|
||||
struct CDRHeader *hdr;
|
||||
sampleinfo->size = (uint32_t) ((char *) msg + size - (char *) ptr);
|
||||
*payloadsz = sampleinfo->size;
|
||||
*payloadp = ptr;
|
||||
hdr = (struct CDRHeader *) ptr;
|
||||
switch (hdr->identifier)
|
||||
{
|
||||
case CDR_BE:
|
||||
case PL_CDR_BE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case CDR_LE:
|
||||
case PL_CDR_LE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? 0 : 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rmsg, DataFrag_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp)
|
||||
static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rmsg, DataFrag_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp, uint32_t *payloadsz)
|
||||
{
|
||||
/* on success: sampleinfo->{rst,statusinfo,pt_wr_info_zoff,bswap,complex_qos} all set */
|
||||
uint32_t payloadsz;
|
||||
ddsi_guid_t pwr_guid;
|
||||
unsigned char *ptr;
|
||||
|
||||
|
@ -473,18 +483,17 @@ static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rms
|
|||
}
|
||||
|
||||
*payloadp = ptr;
|
||||
payloadsz = (uint32_t) ((char *) msg + size - (char *) ptr);
|
||||
if ((uint32_t) msg->fragmentsInSubmessage * msg->fragmentSize <= payloadsz)
|
||||
*payloadsz = (uint32_t) ((char *) msg + size - (char *) ptr);
|
||||
if ((uint32_t) msg->fragmentsInSubmessage * msg->fragmentSize <= (*payloadsz))
|
||||
; /* all spec'd fragments fit in payload */
|
||||
else if ((uint32_t) (msg->fragmentsInSubmessage - 1) * msg->fragmentSize >= payloadsz)
|
||||
else if ((uint32_t) (msg->fragmentsInSubmessage - 1) * msg->fragmentSize >= (*payloadsz))
|
||||
return 0; /* I can live with a short final fragment, but _only_ the final one */
|
||||
else if ((uint32_t) (msg->fragmentStartingNum - 1) * msg->fragmentSize + payloadsz >= msg->sampleSize)
|
||||
else if ((uint32_t) (msg->fragmentStartingNum - 1) * msg->fragmentSize + (*payloadsz) >= msg->sampleSize)
|
||||
; /* final fragment is long enough to cover rest of sample */
|
||||
else
|
||||
return 0;
|
||||
if (msg->fragmentStartingNum == 1)
|
||||
{
|
||||
struct CDRHeader *hdr = (struct CDRHeader *) ptr;
|
||||
if ((size_t) ((char *) ptr + 4 - (char *) msg) > size)
|
||||
{
|
||||
/* no space for the header -- technically, allowing small
|
||||
|
@ -492,23 +501,6 @@ static int valid_DataFrag (const struct receiver_state *rst, struct nn_rmsg *rms
|
|||
prefer this */
|
||||
return 0;
|
||||
}
|
||||
switch (hdr->identifier)
|
||||
{
|
||||
case CDR_BE:
|
||||
case PL_CDR_BE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case CDR_LE:
|
||||
case PL_CDR_LE:
|
||||
{
|
||||
sampleinfo->bswap = (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN ? 0 : 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -527,6 +519,7 @@ static int add_Gap (struct nn_xmsg *msg, struct writer *wr, struct proxy_reader
|
|||
gap->gapList.numbits = numbits;
|
||||
memcpy (gap->bits, bits, NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits));
|
||||
nn_xmsg_submsg_setnext (msg, sm_marker);
|
||||
encode_datawriter_submsg(msg, sm_marker, wr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -537,7 +530,7 @@ static void force_heartbeat_to_peer (struct writer *wr, const struct whc_state *
|
|||
ASSERT_MUTEX_HELD (&wr->e.lock);
|
||||
assert (wr->reliable);
|
||||
|
||||
m = nn_xmsg_new (wr->e.gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
|
||||
m = nn_xmsg_new (wr->e.gv->xmsgpool, &wr->e.guid, wr->c.pp, 0, NN_XMSG_KIND_CONTROL);
|
||||
if (nn_xmsg_setdstPRD (m, prd) < 0)
|
||||
{
|
||||
/* If we don't have an address, give up immediately */
|
||||
|
@ -610,7 +603,7 @@ static int accept_ack_or_hb_w_timeout (nn_count_t new_count, nn_count_t *exp_cou
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const AckNack_t *msg, nn_wctime_t timestamp)
|
||||
static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const AckNack_t *msg, nn_wctime_t timestamp, SubmessageKind_t prev_smid)
|
||||
{
|
||||
struct proxy_reader *prd;
|
||||
struct wr_prd_match *rn;
|
||||
|
@ -666,6 +659,12 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!validate_msg_decoding(&(prd->e), &(prd->c), prd->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" clear submsg from protected src)", PGUID (src), PGUID (dst));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* liveliness is still only implemented partially (with all set to AUTOMATIC, BY_PARTICIPANT, &c.), so we simply renew the proxy participant's lease. */
|
||||
lease_renew (ddsrt_atomic_ldvoidp (&prd->c.proxypp->lease), tnow);
|
||||
|
||||
|
@ -934,7 +933,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
|||
RSTTRACE (" XGAP%"PRId64"..%"PRId64"/%u:", gapstart, gapend, gapnumbits);
|
||||
for (uint32_t i = 0; i < gapnumbits; i++)
|
||||
RSTTRACE ("%c", nn_bitset_isset (gapnumbits, gapbits, i) ? '1' : '0');
|
||||
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
|
||||
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid, wr->c.pp, 0, NN_XMSG_KIND_CONTROL);
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
nn_xmsg_setencoderid (m, wr->partition_id);
|
||||
#endif
|
||||
|
@ -1094,7 +1093,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand
|
|||
}
|
||||
}
|
||||
|
||||
static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Heartbeat_t *msg, nn_wctime_t timestamp)
|
||||
static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Heartbeat_t *msg, nn_wctime_t timestamp, SubmessageKind_t prev_smid)
|
||||
{
|
||||
/* We now cheat: and process the heartbeat for _all_ readers,
|
||||
always, regardless of the destination address in the Heartbeat
|
||||
|
@ -1132,6 +1131,12 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!validate_msg_decoding(&(pwr->e), &(pwr->c), pwr->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" clear submsg from protected src)", PGUID (src), PGUID (dst));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* liveliness is still only implemented partially (with all set to AUTOMATIC,
|
||||
BY_PARTICIPANT, &c.), so we simply renew the proxy participant's lease. */
|
||||
lease_renew (ddsrt_atomic_ldvoidp (&pwr->c.proxypp->lease), tnow);
|
||||
|
@ -1244,7 +1249,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime_t tnow), const HeartbeatFrag_t *msg)
|
||||
static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime_t tnow), const HeartbeatFrag_t *msg, SubmessageKind_t prev_smid)
|
||||
{
|
||||
const seqno_t seq = fromSN (msg->writerSN);
|
||||
const nn_fragment_number_t fragnum = msg->lastFragmentNum - 1; /* we do 0-based */
|
||||
|
@ -1269,6 +1274,12 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!validate_msg_decoding(&(pwr->e), &(pwr->c), pwr->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" clear submsg from protected src)", PGUID (src), PGUID (dst));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* liveliness is still only implemented partially (with all set to AUTOMATIC, BY_PARTICIPANT, &c.), so we simply renew the proxy participant's lease. */
|
||||
lease_renew (ddsrt_atomic_ldvoidp (&pwr->c.proxypp->lease), tnow);
|
||||
|
||||
|
@ -1355,7 +1366,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const NackFrag_t *msg)
|
||||
static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const NackFrag_t *msg, SubmessageKind_t prev_smid)
|
||||
{
|
||||
struct proxy_reader *prd;
|
||||
struct wr_prd_match *rn;
|
||||
|
@ -1396,6 +1407,12 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!validate_msg_decoding(&(prd->e), &(prd->c), prd->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" clear submsg from protected src)", PGUID (src), PGUID (dst));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* liveliness is still only implemented partially (with all set to AUTOMATIC, BY_PARTICIPANT, &c.), so we simply renew the proxy participant's lease. */
|
||||
lease_renew (ddsrt_atomic_ldvoidp (&prd->c.proxypp->lease), tnow);
|
||||
|
||||
|
@ -1446,7 +1463,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
|
|||
static uint32_t zero = 0;
|
||||
struct nn_xmsg *m;
|
||||
RSTTRACE (" msg not available: scheduling Gap\n");
|
||||
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL);
|
||||
m = nn_xmsg_new (rst->gv->xmsgpool, &wr->e.guid, wr->c.pp, 0, NN_XMSG_KIND_CONTROL);
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
nn_xmsg_setencoderid (m, wr->partition_id);
|
||||
#endif
|
||||
|
@ -1590,7 +1607,7 @@ static int handle_one_gap (struct proxy_writer *pwr, struct pwr_rd_match *wn, se
|
|||
return gap_was_valuable;
|
||||
}
|
||||
|
||||
static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Gap_t *msg)
|
||||
static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Gap_t *msg, SubmessageKind_t prev_smid)
|
||||
{
|
||||
/* Option 1: Process the Gap for the proxy writer and all
|
||||
out-of-sync readers: what do I care which reader is being
|
||||
|
@ -1643,6 +1660,12 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!validate_msg_decoding(&(pwr->e), &(pwr->c), pwr->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" "PGUIDFMT" -> "PGUIDFMT" clear submsg from protected src)", PGUID (src), PGUID (dst));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* liveliness is still only implemented partially (with all set to AUTOMATIC, BY_PARTICIPANT, &c.), so we simply renew the proxy participant's lease. */
|
||||
lease_renew (ddsrt_atomic_ldvoidp (&pwr->c.proxypp->lease), tnow);
|
||||
|
||||
|
@ -2346,7 +2369,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con
|
|||
}
|
||||
}
|
||||
|
||||
static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Data_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup)
|
||||
static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Data_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid)
|
||||
{
|
||||
RSTTRACE ("DATA("PGUIDFMT" -> "PGUIDFMT" #%"PRId64,
|
||||
PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u,
|
||||
|
@ -2358,6 +2381,15 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (sampleinfo->pwr)
|
||||
{
|
||||
if (!validate_msg_decoding(&(sampleinfo->pwr->e), &(sampleinfo->pwr->c), sampleinfo->pwr->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" clear submsg from protected src "PGUIDFMT")", PGUID (sampleinfo->pwr->e.guid));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sampleinfo->size > rst->gv->config.max_sample_size)
|
||||
drop_oversize (rst, rmsg, &msg->x, sampleinfo);
|
||||
else
|
||||
|
@ -2391,7 +2423,7 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const DataFrag_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup)
|
||||
static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const DataFrag_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap, struct nn_dqueue **deferred_wakeup, SubmessageKind_t prev_smid)
|
||||
{
|
||||
RSTTRACE ("DATAFRAG("PGUIDFMT" -> "PGUIDFMT" #%"PRId64"/[%u..%u]",
|
||||
PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u,
|
||||
|
@ -2404,6 +2436,15 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (sampleinfo->pwr)
|
||||
{
|
||||
if (!validate_msg_decoding(&(sampleinfo->pwr->e), &(sampleinfo->pwr->c), sampleinfo->pwr->c.proxypp, rst, prev_smid))
|
||||
{
|
||||
RSTTRACE (" clear submsg from protected src "PGUIDFMT")", PGUID (sampleinfo->pwr->e.guid));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sampleinfo->size > rst->gv->config.max_sample_size)
|
||||
drop_oversize (rst, rmsg, &msg->x, sampleinfo);
|
||||
else
|
||||
|
@ -2606,7 +2647,8 @@ static int handle_submsg_sequence
|
|||
unsigned char * const msg /* NOT const - we may byteswap it */,
|
||||
const size_t len,
|
||||
unsigned char * submsg /* aliases somewhere in msg */,
|
||||
struct nn_rmsg * const rmsg
|
||||
struct nn_rmsg * const rmsg,
|
||||
bool rtps_encoded /* indicate if the message was rtps encoded */
|
||||
)
|
||||
{
|
||||
const char *state;
|
||||
|
@ -2618,6 +2660,7 @@ static int handle_submsg_sequence
|
|||
size_t submsg_size = 0;
|
||||
unsigned char * end = msg + len;
|
||||
struct nn_dqueue *deferred_wakeup = NULL;
|
||||
SubmessageKind_t prev_smid = SMID_PAD;
|
||||
|
||||
/* Receiver state is dynamically allocated with lifetime bound to
|
||||
the message. Updates cause a new copy to be created if the
|
||||
|
@ -2639,6 +2682,7 @@ static int handle_submsg_sequence
|
|||
false at any time. That's ok: it's real purpose is to filter out
|
||||
discovery data accidentally sent by Cloud */
|
||||
rst->forme = 1;
|
||||
rst->rtps_encoded = rtps_encoded;
|
||||
rst->vendor = hdr->vendorid;
|
||||
rst->protocol_version = hdr->version;
|
||||
rst->srcloc = *srcloc;
|
||||
|
@ -2700,14 +2744,14 @@ static int handle_submsg_sequence
|
|||
state = "parse:acknack";
|
||||
if (!valid_AckNack (rst, &sm->acknack, submsg_size, byteswap))
|
||||
goto malformed;
|
||||
handle_AckNack (rst, tnowE, &sm->acknack, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID);
|
||||
handle_AckNack (rst, tnowE, &sm->acknack, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID, prev_smid);
|
||||
ts_for_latmeas = 0;
|
||||
break;
|
||||
case SMID_HEARTBEAT:
|
||||
state = "parse:heartbeat";
|
||||
if (!valid_Heartbeat (&sm->heartbeat, submsg_size, byteswap))
|
||||
goto malformed;
|
||||
handle_Heartbeat (rst, tnowE, rmsg, &sm->heartbeat, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID);
|
||||
handle_Heartbeat (rst, tnowE, rmsg, &sm->heartbeat, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID, prev_smid);
|
||||
ts_for_latmeas = 0;
|
||||
break;
|
||||
case SMID_GAP:
|
||||
|
@ -2719,7 +2763,7 @@ static int handle_submsg_sequence
|
|||
rst after inserting the gap in the admin. */
|
||||
if (!valid_Gap (&sm->gap, submsg_size, byteswap))
|
||||
goto malformed;
|
||||
handle_Gap (rst, tnowE, rmsg, &sm->gap);
|
||||
handle_Gap (rst, tnowE, rmsg, &sm->gap, prev_smid);
|
||||
ts_for_latmeas = 0;
|
||||
break;
|
||||
case SMID_INFO_TS:
|
||||
|
@ -2763,27 +2807,37 @@ static int handle_submsg_sequence
|
|||
state = "parse:nackfrag";
|
||||
if (!valid_NackFrag (&sm->nackfrag, submsg_size, byteswap))
|
||||
goto malformed;
|
||||
handle_NackFrag (rst, tnowE, &sm->nackfrag);
|
||||
handle_NackFrag (rst, tnowE, &sm->nackfrag, prev_smid);
|
||||
ts_for_latmeas = 0;
|
||||
break;
|
||||
case SMID_HEARTBEAT_FRAG:
|
||||
state = "parse:heartbeatfrag";
|
||||
if (!valid_HeartbeatFrag (&sm->heartbeatfrag, submsg_size, byteswap))
|
||||
goto malformed;
|
||||
handle_HeartbeatFrag (rst, tnowE, &sm->heartbeatfrag);
|
||||
handle_HeartbeatFrag (rst, tnowE, &sm->heartbeatfrag, prev_smid);
|
||||
ts_for_latmeas = 0;
|
||||
break;
|
||||
case SMID_DATA_FRAG:
|
||||
state = "parse:datafrag";
|
||||
{
|
||||
struct nn_rsample_info sampleinfo;
|
||||
uint32_t datasz = 0;
|
||||
unsigned char *datap;
|
||||
size_t submsg_len = submsg_size;
|
||||
/* valid_DataFrag does not validate the payload */
|
||||
if (!valid_DataFrag (rst, rmsg, &sm->datafrag, submsg_size, byteswap, &sampleinfo, &datap))
|
||||
if (!valid_DataFrag (rst, rmsg, &sm->datafrag, submsg_size, byteswap, &sampleinfo, &datap, &datasz))
|
||||
goto malformed;
|
||||
/* This only decodes the payload when needed (possibly reducing the submsg size). */
|
||||
if (!decode_DataFrag (rst->gv, &sampleinfo, datap, datasz, &submsg_len))
|
||||
goto malformed;
|
||||
/* Set the sample bswap according to the payload info (only first fragment has proper header). */
|
||||
if (sm->datafrag.fragmentStartingNum == 1) {
|
||||
if (!set_sampleinfo_bswap(&sampleinfo, (struct CDRHeader *)datap))
|
||||
goto malformed;
|
||||
}
|
||||
sampleinfo.timestamp = timestamp;
|
||||
sampleinfo.reception_timestamp = tnowWC;
|
||||
handle_DataFrag (rst, tnowE, rmsg, &sm->datafrag, submsg_size, &sampleinfo, datap, &deferred_wakeup);
|
||||
handle_DataFrag (rst, tnowE, rmsg, &sm->datafrag, submsg_len, &sampleinfo, datap, &deferred_wakeup, prev_smid);
|
||||
rst_live = 1;
|
||||
ts_for_latmeas = 0;
|
||||
}
|
||||
|
@ -2793,12 +2847,20 @@ static int handle_submsg_sequence
|
|||
{
|
||||
struct nn_rsample_info sampleinfo;
|
||||
unsigned char *datap;
|
||||
uint32_t datasz = 0;
|
||||
size_t submsg_len = submsg_size;
|
||||
/* valid_Data does not validate the payload */
|
||||
if (!valid_Data (rst, rmsg, &sm->data, submsg_size, byteswap, &sampleinfo, &datap))
|
||||
if (!valid_Data (rst, rmsg, &sm->data, submsg_size, byteswap, &sampleinfo, &datap, &datasz))
|
||||
goto malformed;
|
||||
/* This only decodes the payload when needed (possibly reducing the submsg size). */
|
||||
if (!decode_Data (rst->gv, &sampleinfo, datap, datasz, &submsg_len))
|
||||
goto malformed;
|
||||
/* Set the sample bswap according to the payload info. */
|
||||
if (!set_sampleinfo_bswap(&sampleinfo, (struct CDRHeader *)datap))
|
||||
goto malformed;
|
||||
sampleinfo.timestamp = timestamp;
|
||||
sampleinfo.reception_timestamp = tnowWC;
|
||||
handle_Data (rst, tnowE, rmsg, &sm->data, submsg_size, &sampleinfo, datap, &deferred_wakeup);
|
||||
handle_Data (rst, tnowE, rmsg, &sm->data, submsg_len, &sampleinfo, datap, &deferred_wakeup, prev_smid);
|
||||
rst_live = 1;
|
||||
ts_for_latmeas = 0;
|
||||
}
|
||||
|
@ -2819,6 +2881,38 @@ static int handle_submsg_sequence
|
|||
GVTRACE ("ENTITY_ID");
|
||||
break;
|
||||
}
|
||||
case SMID_SEC_PREFIX:
|
||||
state = "parse:sec_prefix";
|
||||
{
|
||||
GVTRACE ("SEC_PREFIX");
|
||||
if (decode_SecPrefix(rst, submsg, submsg_size, end, &rst->src_guid_prefix, &rst->dst_guid_prefix, byteswap) < 0)
|
||||
goto malformed;
|
||||
}
|
||||
break;
|
||||
case SMID_SEC_BODY:
|
||||
{
|
||||
/* Ignore: because it should have been handled by SMID_SEC_PREFIX. */
|
||||
GVTRACE ("SEC_BODY");
|
||||
}
|
||||
break;
|
||||
case SMID_SEC_POSTFIX:
|
||||
{
|
||||
/* Ignore: because it should have been handled by SMID_SEC_PREFIX. */
|
||||
GVTRACE ("SEC_POSTFIX");
|
||||
}
|
||||
break;
|
||||
case SMID_SRTPS_PREFIX:
|
||||
{
|
||||
/* Ignore: it should already have been handled. */
|
||||
GVTRACE ("SRTPS_PREFIX");
|
||||
}
|
||||
break;
|
||||
case SMID_SRTPS_POSTFIX:
|
||||
{
|
||||
/* Ignore: it should already have been handled. */
|
||||
GVTRACE ("SRTPS_POSTFIX");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
state = "parse:undefined";
|
||||
GVTRACE ("UNDEFINED(%x)", sm->smhdr.submessageId);
|
||||
|
@ -2849,6 +2943,7 @@ static int handle_submsg_sequence
|
|||
ts_for_latmeas = 0;
|
||||
break;
|
||||
}
|
||||
prev_smid = state_smkind;
|
||||
submsg += submsg_size;
|
||||
GVTRACE ("\n");
|
||||
}
|
||||
|
@ -2985,8 +3080,36 @@ static bool do_packet (struct thread_state1 * const ts1, struct q_globals *gv, d
|
|||
GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu from %s\n",
|
||||
PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, addrstr);
|
||||
}
|
||||
nn_rtps_msg_state_t res = decode_rtps_message(ts1,
|
||||
gv,
|
||||
&rmsg,
|
||||
&hdr,
|
||||
&buff,
|
||||
&sz,
|
||||
rbpool,
|
||||
conn->m_stream);
|
||||
|
||||
handle_submsg_sequence (ts1, gv, conn, &srcloc, now (), now_et (), &hdr->guid_prefix, guidprefix, buff, (size_t) sz, buff + RTPS_MESSAGE_HEADER_SIZE, rmsg);
|
||||
if (res != NN_RTPS_MSG_STATE_ERROR)
|
||||
{
|
||||
handle_submsg_sequence (ts1,
|
||||
gv,
|
||||
conn,
|
||||
&srcloc,
|
||||
now (),
|
||||
now_et (),
|
||||
&hdr->guid_prefix,
|
||||
guidprefix,
|
||||
buff,
|
||||
(size_t) sz,
|
||||
buff + RTPS_MESSAGE_HEADER_SIZE,
|
||||
rmsg,
|
||||
res == NN_RTPS_MSG_STATE_ENCODED);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* drop message */
|
||||
sz = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
nn_rmsg_commit (rmsg);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#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"
|
||||
|
@ -140,7 +141,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;
|
||||
|
||||
|
@ -218,6 +219,13 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, const stru
|
|||
add_Heartbeat (msg, wr, whcst, hbansreq, 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;
|
||||
}
|
||||
|
@ -379,6 +387,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)
|
||||
|
@ -411,7 +420,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
|
||||
|
@ -448,9 +457,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;
|
||||
|
@ -497,7 +506,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
|
||||
|
@ -618,7 +627,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",
|
||||
|
@ -626,6 +635,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;
|
||||
}
|
||||
|
||||
|
@ -635,7 +653,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);
|
||||
|
@ -664,6 +682,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;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "dds/ddsi/q_xmsg.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__whc.h"
|
||||
|
||||
|
@ -182,7 +183,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);
|
||||
|
@ -805,6 +806,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)
|
||||
|
@ -835,12 +839,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, nn_mtime_t tnow)
|
||||
static void handle_xevk_acknack (struct nn_xpack *xp, struct xevent *ev, nn_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
|
||||
|
@ -872,9 +879,18 @@ 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))
|
||||
{
|
||||
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)
|
||||
|
||||
struct participant *pp = NULL;
|
||||
if (q_omg_security_enabled())
|
||||
{
|
||||
struct reader *rd = ephash_lookup_reader_guid(pwr->e.gv->guid_hash, &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
|
||||
|
@ -886,7 +902,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;
|
||||
|
@ -948,7 +970,7 @@ static bool resend_spdp_sample_by_guid_key (struct writer *wr, const ddsi_guid_t
|
|||
nn_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);
|
||||
struct nn_xmsg *mpayload = nn_xmsg_new (gv->xmsgpool, guid, wr->c.pp, 0, NN_XMSG_KIND_DATA);
|
||||
nn_plist_addtomsg (mpayload, &ps, ~(uint64_t)0, ~(uint64_t)0);
|
||||
nn_xmsg_addpar_sentinel (mpayload);
|
||||
nn_plist_fini (&ps);
|
||||
|
@ -1387,7 +1409,7 @@ 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_prd_entityid (struct proxy_reader *prd, const ddsi_guid_t *guid)
|
||||
{
|
||||
struct q_globals * const gv = prd->e.gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
@ -1397,10 +1419,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);
|
||||
|
@ -1415,7 +1437,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 q_globals * const gv = pwr->e.gv;
|
||||
struct nn_xmsg *msg;
|
||||
|
@ -1425,10 +1447,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);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "dds/ddsi/q_ephash.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;
|
||||
|
@ -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);
|
||||
|
@ -385,6 +418,13 @@ 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;
|
||||
|
@ -406,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:
|
||||
|
@ -494,6 +541,80 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -560,22 +681,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 q_globals *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 = ephash_lookup_proxy_participant_guid(gv->guid_hash, &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)
|
||||
|
@ -583,7 +748,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
|
||||
|
@ -598,7 +763,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));
|
||||
|
@ -953,6 +1118,9 @@ static void nn_xpack_reinit (struct nn_xpack *xp)
|
|||
xp->msg_len.length = 0;
|
||||
xp->included_msgs.latest = NULL;
|
||||
xp->maxdelay = T_NEVER;
|
||||
#ifdef DDSI_INCLUDE_SECURITY
|
||||
xp->sec_info.use_rtps_encoding = 0;
|
||||
#endif
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
xp->encoderId = 0;
|
||||
#endif
|
||||
|
@ -1012,6 +1180,34 @@ 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->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;
|
||||
|
@ -1038,14 +1234,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
|
||||
}
|
||||
|
@ -1338,6 +1537,12 @@ static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg *
|
|||
return 0;
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
return addressing_info_eq_onesidederr (xp, m);
|
||||
}
|
||||
|
||||
|
@ -1431,6 +1636,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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue