Force md5 keyhash when needed.

Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
Martin Bremmer 2019-12-13 14:29:30 +01:00 committed by eboasson
parent 80d0be83e0
commit 91111af0ea
11 changed files with 67 additions and 11 deletions

View file

@ -295,5 +295,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_builtintopic = {
.to_ser_unref = serdata_builtin_to_ser_unref, .to_ser_unref = serdata_builtin_to_ser_unref,
.to_topicless = serdata_builtin_to_topicless, .to_topicless = serdata_builtin_to_topicless,
.topicless_to_sample = serdata_builtin_topicless_to_sample, .topicless_to_sample = serdata_builtin_topicless_to_sample,
.print = serdata_builtin_topic_print .print = serdata_builtin_topic_print,
.get_keyhash = 0
}; };

View file

@ -1579,7 +1579,10 @@ void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t *
const dds_topic_descriptor_t *desc = topic->type; const dds_topic_descriptor_t *desc = topic->type;
kh->m_set = 1; kh->m_set = 1;
if (desc->m_nkeys == 0) if (desc->m_nkeys == 0)
{
kh->m_iskey = 1; kh->m_iskey = 1;
kh->m_keysize = 0;
}
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
{ {
dds_ostreamBE_t os; dds_ostreamBE_t os;
@ -1592,12 +1595,14 @@ void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t *
else else
dds_stream_extract_keyBE_from_data (is, &os, topic); dds_stream_extract_keyBE_from_data (is, &os, topic);
assert (os.x.m_index <= 16); assert (os.x.m_index <= 16);
kh->m_keysize = (unsigned)os.x.m_index & 0x1f;
} }
else else
{ {
dds_ostreamBE_t os; dds_ostreamBE_t os;
ddsrt_md5_state_t md5st; ddsrt_md5_state_t md5st;
kh->m_iskey = 0; kh->m_iskey = 0;
kh->m_keysize = 16;
dds_ostreamBE_init (&os, 0); dds_ostreamBE_init (&os, 0);
if (just_key) if (just_key)
dds_stream_extract_keyBE_from_key (is, &os, topic); dds_stream_extract_keyBE_from_key (is, &os, topic);

View file

@ -132,6 +132,11 @@ typedef bool (*ddsi_serdata_eqkey_t) (const struct ddsi_serdata *a, const struct
returning bufsize-1) if it had to truncate) */ 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); typedef size_t (*ddsi_serdata_print_t) (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, char *buf, size_t size);
/* 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 nn_keyhash *buf, bool force_md5);
struct ddsi_serdata_ops { struct ddsi_serdata_ops {
ddsi_serdata_eqkey_t eqkey; ddsi_serdata_eqkey_t eqkey;
ddsi_serdata_size_t get_size; ddsi_serdata_size_t get_size;
@ -146,9 +151,11 @@ struct ddsi_serdata_ops {
ddsi_serdata_topicless_to_sample_t topicless_to_sample; ddsi_serdata_topicless_to_sample_t topicless_to_sample;
ddsi_serdata_free_t free; ddsi_serdata_free_t free;
ddsi_serdata_print_t print; ddsi_serdata_print_t print;
ddsi_serdata_get_keyhash_t get_keyhash;
}; };
#define DDSI_SERDATA_HAS_PRINT 1 #define DDSI_SERDATA_HAS_PRINT 1
#define DDSI_SERDATA_HAS_ADD_KEYHASH 1
DDS_EXPORT void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertopic *tp, enum ddsi_serdata_kind kind); DDS_EXPORT void ddsi_serdata_init (struct ddsi_serdata *d, const struct ddsi_sertopic *tp, enum ddsi_serdata_kind kind);
@ -221,6 +228,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 nn_keyhash *buf, bool force_md5) {
d->ops->get_keyhash (d, buf, force_md5);
}
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif

View file

@ -47,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 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_set : 1; /* has it been initialised? */
unsigned m_iskey : 1; /* m_hash is key value */ unsigned m_iskey : 1; /* m_hash is key value */
unsigned m_keysize : 5; /* size of the key within the hash buffer */
} dds_keyhash_t; } dds_keyhash_t;
/* Debug builds may want to keep some additional state */ /* Debug builds may want to keep some additional state */

View file

@ -251,6 +251,7 @@ struct writer
unsigned reliable: 1; /* iff 1, writer is reliable <=> heartbeat_xevent != NULL */ 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 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 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 retransmitting: 1; /* iff 1, this writer is currently retransmitting */
#ifdef DDSI_INCLUDE_SSM #ifdef DDSI_INCLUDE_SSM
unsigned supports_ssm: 1; unsigned supports_ssm: 1;

View file

@ -129,7 +129,7 @@ void nn_xmsg_submsg_init (struct nn_xmsg *msg, struct nn_xmsg_marker marker, Sub
void nn_xmsg_add_timestamp (struct nn_xmsg *m, nn_wctime_t t); void nn_xmsg_add_timestamp (struct nn_xmsg *m, nn_wctime_t t);
void nn_xmsg_add_entityid (struct nn_xmsg * m); void nn_xmsg_add_entityid (struct nn_xmsg * m);
void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len); 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_statusinfo (struct nn_xmsg *m, unsigned statusinfo);
void nn_xmsg_addpar_sentinel (struct nn_xmsg *m); void nn_xmsg_addpar_sentinel (struct nn_xmsg *m);
int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg *m); int nn_xmsg_addpar_sentinel_ifparam (struct nn_xmsg *m);

View file

@ -47,3 +47,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_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 (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 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 nn_keyhash *buf, bool force_md5);

View file

@ -231,6 +231,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)); memset (d->keyhash.m_hash, 0, sizeof (d->keyhash.m_hash));
d->keyhash.m_set = 0; d->keyhash.m_set = 0;
d->keyhash.m_iskey = 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) static struct ddsi_serdata_default *serdata_default_allocnew (struct serdatapool *serpool, uint32_t init_size)
@ -355,6 +356,7 @@ 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)); memcpy (d->keyhash.m_hash, keyhash->value, sizeof (d->keyhash.m_hash));
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
d->keyhash.m_keysize = sizeof (d->keyhash.m_hash);
return fix_serdata_default(d, tp->c.serdata_basehash); return fix_serdata_default(d, tp->c.serdata_basehash);
} }
} }
@ -368,6 +370,7 @@ static struct ddsi_serdata *ddsi_serdata_from_keyhash_cdr_nokey (const struct dd
(void)keyhash; (void)keyhash;
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
d->keyhash.m_keysize = 0;
return fix_serdata_default_nokey(d, tp->c.serdata_basehash); return fix_serdata_default_nokey(d, tp->c.serdata_basehash);
} }
@ -376,11 +379,15 @@ static void gen_keyhash_from_sample (const struct ddsi_sertopic_default *topic,
const struct dds_topic_descriptor *desc = (const struct dds_topic_descriptor *) topic->type; const struct dds_topic_descriptor *desc = (const struct dds_topic_descriptor *) topic->type;
kh->m_set = 1; kh->m_set = 1;
if (desc->m_nkeys == 0) if (desc->m_nkeys == 0)
{
kh->m_iskey = 1; kh->m_iskey = 1;
kh->m_keysize = 0;
}
else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY) else if (desc->m_flagset & DDS_TOPIC_FIXED_KEY)
{ {
dds_ostreamBE_t os; dds_ostreamBE_t os;
kh->m_iskey = 1; kh->m_iskey = 1;
kh->m_keysize = sizeof(kh->m_hash);
dds_ostreamBE_init (&os, 0); dds_ostreamBE_init (&os, 0);
os.x.m_buffer = kh->m_hash; os.x.m_buffer = kh->m_hash;
os.x.m_size = 16; os.x.m_size = 16;
@ -391,6 +398,7 @@ static void gen_keyhash_from_sample (const struct ddsi_sertopic_default *topic,
dds_ostreamBE_t os; dds_ostreamBE_t os;
ddsrt_md5_state_t md5st; ddsrt_md5_state_t md5st;
kh->m_iskey = 0; kh->m_iskey = 0;
kh->m_keysize = sizeof(kh->m_hash);
dds_ostreamBE_init (&os, 64); dds_ostreamBE_init (&os, 64);
dds_stream_write_keyBE (&os, sample, topic); dds_stream_write_keyBE (&os, sample, topic);
ddsrt_md5_init (&md5st); ddsrt_md5_init (&md5st);
@ -461,6 +469,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi
case PID_GROUP_GUID: case PID_GROUP_GUID:
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
d->keyhash.m_keysize = sizeof(d->keyhash.m_hash);
memcpy (d->keyhash.m_hash, rawkey, 16); memcpy (d->keyhash.m_hash, rawkey, 16);
#ifndef NDEBUG #ifndef NDEBUG
keysize = 16; keysize = 16;
@ -477,6 +486,7 @@ static struct ddsi_serdata *serdata_default_from_sample_plist (const struct ddsi
topic_name_sz_BE = ddsrt_toBE4u (topic_name_sz); topic_name_sz_BE = ddsrt_toBE4u (topic_name_sz);
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 0; d->keyhash.m_iskey = 0;
d->keyhash.m_keysize = sizeof(d->keyhash.m_hash);
ddsrt_md5_init (&md5st); 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_sz_BE, sizeof (topic_name_sz_BE));
ddsrt_md5_append (&md5st, (const ddsrt_md5_byte_t *) topic_name, topic_name_sz); ddsrt_md5_append (&md5st, (const ddsrt_md5_byte_t *) topic_name, topic_name_sz);
@ -512,10 +522,14 @@ static struct ddsi_serdata *serdata_default_from_sample_rawcdr (const struct dds
d->keyhash.m_set = 1; d->keyhash.m_set = 1;
d->keyhash.m_iskey = 1; d->keyhash.m_iskey = 1;
if (sample->keysize == 0) if (sample->keysize == 0)
{
d->keyhash.m_keysize = 0;
return fix_serdata_default_nokey (d, tp->c.serdata_basehash); return fix_serdata_default_nokey (d, tp->c.serdata_basehash);
}
else else
{ {
memcpy (&d->keyhash.m_hash, sample->key, sample->keysize); memcpy (&d->keyhash.m_hash, sample->key, sample->keysize);
d->keyhash.m_keysize = (unsigned)sample->keysize & 0x1f;
return fix_serdata_default (d, tp->c.serdata_basehash); return fix_serdata_default (d, tp->c.serdata_basehash);
} }
} }
@ -656,6 +670,24 @@ static size_t serdata_default_print_raw (const struct ddsi_sertopic *sertopic_co
return (size_t) snprintf (buf, size, "(blob)"); return (size_t) snprintf (buf, size, "(blob)");
} }
static void serdata_default_get_keyhash (const struct ddsi_serdata *serdata_common, struct nn_keyhash *buf, bool force_md5)
{
const struct ddsi_serdata_default *d = (const struct ddsi_serdata_default *)serdata_common;
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
{
memcpy (buf->value, d->keyhash.m_hash, 16);
}
}
const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = { const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = {
.get_size = serdata_default_get_size, .get_size = serdata_default_get_size,
.eqkey = serdata_default_eqkey, .eqkey = serdata_default_eqkey,
@ -669,7 +701,8 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr = {
.to_ser_unref = serdata_default_to_ser_unref, .to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless, .to_topicless = serdata_default_to_topicless,
.topicless_to_sample = serdata_default_topicless_to_sample_cdr, .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 = { const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
@ -685,7 +718,8 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_cdr_nokey = {
.to_ser_unref = serdata_default_to_ser_unref, .to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless, .to_topicless = serdata_default_to_topicless,
.topicless_to_sample = serdata_default_topicless_to_sample_cdr_nokey, .topicless_to_sample = serdata_default_topicless_to_sample_cdr_nokey,
.print = serdata_default_print_cdr .print = serdata_default_print_cdr,
.get_keyhash = serdata_default_get_keyhash
}; };
const struct ddsi_serdata_ops ddsi_serdata_ops_plist = { const struct ddsi_serdata_ops ddsi_serdata_ops_plist = {
@ -701,7 +735,8 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_plist = {
.to_ser_unref = serdata_default_to_ser_unref, .to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless, .to_topicless = serdata_default_to_topicless,
.topicless_to_sample = 0, .topicless_to_sample = 0,
.print = serdata_default_print_plist .print = serdata_default_print_plist,
.get_keyhash = serdata_default_get_keyhash
}; };
const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = { const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = {
@ -717,5 +752,6 @@ const struct ddsi_serdata_ops ddsi_serdata_ops_rawcdr = {
.to_ser_unref = serdata_default_to_ser_unref, .to_ser_unref = serdata_default_to_ser_unref,
.to_topicless = serdata_default_to_topicless, .to_topicless = serdata_default_to_topicless,
.topicless_to_sample = 0, .topicless_to_sample = 0,
.print = serdata_default_print_raw .print = serdata_default_print_raw,
.get_keyhash = serdata_default_get_keyhash
}; };

View file

@ -3063,6 +3063,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
wr->throttle_tracing = 0; wr->throttle_tracing = 0;
wr->rexmit_count = 0; wr->rexmit_count = 0;
wr->rexmit_lost_count = 0; wr->rexmit_lost_count = 0;
wr->force_md5_keyhash = 0;
wr->status_cb = status_cb; wr->status_cb = status_cb;
wr->status_cb_entity = status_entity; wr->status_cb_entity = status_entity;

View file

@ -492,7 +492,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 */ /* Adding parameters means potential reallocing, so sm, ddcmn now likely become invalid */
if (wr->include_keyhash) if (wr->include_keyhash)
nn_xmsg_addpar_keyhash (*pmsg, serdata); nn_xmsg_addpar_keyhash (*pmsg, serdata, wr->force_md5_keyhash);
if (serdata->statusinfo) if (serdata->statusinfo)
nn_xmsg_addpar_statusinfo (*pmsg, serdata->statusinfo); nn_xmsg_addpar_statusinfo (*pmsg, serdata->statusinfo);
if (nn_xmsg_addpar_sentinel_ifparam (*pmsg) > 0) if (nn_xmsg_addpar_sentinel_ifparam (*pmsg) > 0)
@ -659,7 +659,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 */ /* Adding parameters means potential reallocing, so sm, ddcmn now likely become invalid */
if (wr->include_keyhash) if (wr->include_keyhash)
{ {
nn_xmsg_addpar_keyhash (*pmsg, serdata); nn_xmsg_addpar_keyhash (*pmsg, serdata, wr->force_md5_keyhash);
} }
if (serdata->statusinfo) if (serdata->statusinfo)
{ {

View file

@ -938,13 +938,12 @@ void *nn_xmsg_addpar (struct nn_xmsg *m, nn_parameterid_t pid, size_t len)
return p; return p;
} }
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)
{ {
if (serdata->kind != SDK_EMPTY) 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); char *p = nn_xmsg_addpar (m, PID_KEYHASH, 16);
memcpy (p, serdata_def->keyhash.m_hash, 16); ddsi_serdata_get_keyhash(serdata, (struct nn_keyhash*)p, force_md5);
} }
} }