Handle malformed pre-emptive ACKNACK from FastRTPS

The pre-emptive ACKNACK messages from FastRTPS have a base sequence
number of 0, which is malformed and must be rejected according to DDSI
8.3.7.1 / 8.3.5.5.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-08-21 12:11:23 +02:00 committed by eboasson
parent 93addbbda0
commit 8964c0b1bc
3 changed files with 14 additions and 3 deletions

View file

@ -60,6 +60,9 @@ inline bool vendor_is_opensplice (nn_vendorid_t vendor) {
inline bool vendor_is_twinoaks (nn_vendorid_t vendor) {
return vendor_equals (vendor, (nn_vendorid_t) {{ 0x01, NN_VENDORID_MINOR_TWINOAKS }});
}
inline bool vendor_is_eprosima (nn_vendorid_t vendor) {
return vendor_equals (vendor, (nn_vendorid_t) {{ 0x01, NN_VENDORID_MINOR_EPROSIMA }});
}
inline bool vendor_is_cloud (nn_vendorid_t vendor) {
return vendor_equals (vendor, (nn_vendorid_t) {{ 0x01, NN_VENDORID_MINOR_PRISMTECH_CLOUD }});
}

View file

@ -16,6 +16,7 @@
extern inline bool vendor_equals (nn_vendorid_t a, nn_vendorid_t b);
extern inline bool vendor_is_rti (nn_vendorid_t vendor);
extern inline bool vendor_is_twinoaks (nn_vendorid_t vendor);
extern inline bool vendor_is_eprosima (nn_vendorid_t vendor);
extern inline bool vendor_is_prismtech (nn_vendorid_t vendor);
extern inline bool vendor_is_opensplice (nn_vendorid_t vendor);
extern inline bool vendor_is_cloud (nn_vendorid_t vendor);

View file

@ -113,7 +113,7 @@ static int valid_fragment_number_set (const nn_fragment_number_set_header_t *fns
return (fnset->bitmap_base > 0 && fnset->numbits <= 256);
}
static int valid_AckNack (AckNack_t *msg, size_t size, int byteswap)
static int valid_AckNack (const struct receiver_state *rst, AckNack_t *msg, size_t size, int byteswap)
{
nn_count_t *count; /* this should've preceded the bitmap */
if (size < ACKNACK_SIZE (0))
@ -129,7 +129,14 @@ static int valid_AckNack (AckNack_t *msg, size_t size, int byteswap)
msg->writerId = nn_ntoh_entityid (msg->writerId);
/* Validation following 8.3.7.1.3 + 8.3.5.5 */
if (!valid_sequence_number_set (&msg->readerSNState))
return 0;
{
/* FastRTPS sends invalid pre-emptive ACKs -- patch the message so we can process it */
if (! NN_STRICT_P (rst->gv->config) && vendor_is_eprosima (rst->vendor) &&
fromSN (msg->readerSNState.bitmap_base) == 0 && msg->readerSNState.numbits == 0)
msg->readerSNState.bitmap_base = toSN (1);
else
return 0;
}
/* Given the number of bits, we can compute the size of the AckNack
submessage, and verify that the submessage is large enough */
if (size < ACKNACK_SIZE (msg->readerSNState.numbits))
@ -2677,7 +2684,7 @@ static int handle_submsg_sequence
break;
case SMID_ACKNACK:
state = "parse:acknack";
if (!valid_AckNack (&sm->acknack, submsg_size, byteswap))
if (!valid_AckNack (rst, &sm->acknack, submsg_size, byteswap))
goto malformed;
handle_AckNack (rst, tnowE, &sm->acknack, ts_for_latmeas ? timestamp : NN_WCTIME_INVALID);
ts_for_latmeas = 0;