Skip to content

Commit ba08f7b

Browse files
committed
[C] Add aeron_is_frame_valid method.
1 parent 6004e36 commit ba08f7b

6 files changed

Lines changed: 50 additions & 9 deletions

File tree

aeron-client/src/main/c/protocol/aeron_udp_protocol.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ int aeron_udp_protocol_group_tag(aeron_status_message_header_t *sm, int64_t *gro
4343
return (int)((size_t)sm->frame_header.frame_length - group_tag_offset);
4444
}
4545

46+
extern bool aeron_is_frame_valid(const aeron_frame_header_t *header, size_t frame_length);
47+
4648
extern size_t aeron_res_header_address_length(int8_t res_type);
4749

4850
extern size_t aeron_compute_max_message_length(size_t term_length);

aeron-client/src/main/c/protocol/aeron_udp_protocol.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef AERON_UDP_PROTOCOL_H
1818
#define AERON_UDP_PROTOCOL_H
1919

20+
#include <stdbool.h>
2021
#include <stdint.h>
2122
#include <stddef.h>
2223

@@ -233,6 +234,11 @@ int aeron_udp_protocol_group_tag(aeron_status_message_header_t *sm, int64_t *gro
233234
#define AERON_ERROR_MAX_FRAME_LENGTH (AERON_ERROR_HEADER_LENGTH + AERON_ERROR_MAX_TEXT_LENGTH)
234235
#define AERON_ERROR_HAS_GROUP_TAG_FLAG (0x08)
235236

237+
inline bool aeron_is_frame_valid(const aeron_frame_header_t *header, const size_t frame_length)
238+
{
239+
return frame_length >= AERON_FRAME_HEADER_LENGTH && AERON_FRAME_HEADER_VERSION == header->version;
240+
}
241+
236242
inline size_t aeron_res_header_address_length(int8_t res_type)
237243
{
238244
return AERON_RES_HEADER_TYPE_NAME_TO_IP6_MD == res_type ?
@@ -241,8 +247,7 @@ inline size_t aeron_res_header_address_length(int8_t res_type)
241247

242248
inline size_t aeron_compute_max_message_length(size_t term_length)
243249
{
244-
size_t max_length_for_term = term_length / 8;
245-
250+
size_t max_length_for_term = term_length >> 3;
246251
return max_length_for_term < AERON_FRAME_MAX_MESSAGE_LENGTH ? max_length_for_term : AERON_FRAME_MAX_MESSAGE_LENGTH;
247252
}
248253

aeron-driver/src/main/c/aeron_driver_name_resolver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ void aeron_driver_name_resolver_receive(
602602
aeron_frame_header_t *frame_header = (aeron_frame_header_t *)buffer;
603603
size_t remaining = length;
604604

605-
if ((remaining < AERON_FRAME_HEADER_LENGTH) || (frame_header->version != AERON_FRAME_HEADER_VERSION))
605+
if (!aeron_is_frame_valid(frame_header, length) || length < (size_t)frame_header->frame_length)
606606
{
607607
aeron_counter_increment(resolver->invalid_packets_counter);
608608
return;

aeron-driver/src/main/c/media/aeron_receive_channel_endpoint.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ void aeron_receive_channel_endpoint_dispatch(
487487
aeron_receive_channel_endpoint_t *endpoint = (aeron_receive_channel_endpoint_t *)endpoint_clientd;
488488
aeron_receive_destination_t *destination = (aeron_receive_destination_t *)destination_clientd;
489489

490-
if ((length < AERON_FRAME_HEADER_LENGTH) || (frame_header->version != AERON_FRAME_HEADER_VERSION))
490+
if (!aeron_is_frame_valid(frame_header, length))
491491
{
492492
aeron_counter_increment(receiver->invalid_frames_counter);
493493
return;
@@ -513,7 +513,7 @@ void aeron_receive_channel_endpoint_dispatch(
513513
break;
514514

515515
case AERON_HDR_TYPE_SETUP:
516-
if (length >= AERON_SETUP_HEADER_LENGTH)
516+
if (length >= AERON_SETUP_HEADER_LENGTH && length >= (size_t)frame_header->frame_length)
517517
{
518518
if (aeron_receive_channel_endpoint_on_setup(endpoint, destination, buffer, length, addr) < 0)
519519
{
@@ -528,7 +528,7 @@ void aeron_receive_channel_endpoint_dispatch(
528528
break;
529529

530530
case AERON_HDR_TYPE_RTTM:
531-
if (length >= AERON_RTTM_HEADER_LENGTH)
531+
if (length >= AERON_RTTM_HEADER_LENGTH && length >= (size_t)frame_header->frame_length)
532532
{
533533
if (aeron_receive_channel_endpoint_on_rttm(endpoint, destination, buffer, length, addr) < 0)
534534
{

aeron-driver/src/main/c/media/aeron_send_channel_endpoint.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,16 @@ void aeron_send_channel_endpoint_dispatch(
419419

420420
int result = 0;
421421

422+
if (!aeron_is_frame_valid(frame_header, length))
423+
{
424+
aeron_counter_increment(sender->invalid_frames_counter);
425+
return;
426+
}
427+
422428
switch (frame_header->type)
423429
{
424430
case AERON_HDR_TYPE_NAK:
425-
if (length >= AERON_NAK_HEADER_LENGTH)
431+
if (length >= AERON_NAK_HEADER_LENGTH && length >= (size_t)frame_header->frame_length)
426432
{
427433
result = aeron_send_channel_endpoint_on_nak(endpoint, buffer, length, addr);
428434
aeron_counter_increment_release(sender->nak_messages_received_counter);
@@ -458,7 +464,7 @@ void aeron_send_channel_endpoint_dispatch(
458464
break;
459465

460466
case AERON_HDR_TYPE_RTTM:
461-
if (length >= AERON_RTTM_HEADER_LENGTH)
467+
if (length >= AERON_RTTM_HEADER_LENGTH && length >= (size_t)frame_header->frame_length)
462468
{
463469
aeron_send_channel_endpoint_on_rttm(endpoint, buffer, length, addr);
464470
}
@@ -469,7 +475,7 @@ void aeron_send_channel_endpoint_dispatch(
469475
break;
470476

471477
case AERON_HDR_TYPE_RSP_SETUP:
472-
if (length >= AERON_RSP_SETUP_HEADER_LENGTH)
478+
if (length >= AERON_RSP_SETUP_HEADER_LENGTH && length >= (size_t)frame_header->frame_length)
473479
{
474480
aeron_send_channel_endpoint_on_response_setup(endpoint, conductor_proxy, buffer, length, addr);
475481
}

aeron-driver/src/test/c/aeron_udp_channel_test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,34 @@ TEST_F(UdpChannelTest, constantSanityChecks)
136136
EXPECT_EQ(AERON_RSP_SETUP_HEADER_LENGTH, sizeof(aeron_response_setup_header_t));
137137
}
138138

139+
TEST_F(UdpChannelTest, shouldComputeMaxMessageLength)
140+
{
141+
EXPECT_EQ(0, aeron_compute_max_message_length(0));
142+
EXPECT_EQ(4, aeron_compute_max_message_length(32));
143+
EXPECT_EQ(8192, aeron_compute_max_message_length(64 * 1024));
144+
EXPECT_EQ(8 * 1024 * 1024, aeron_compute_max_message_length(64 * 1024 * 1024));
145+
EXPECT_EQ(AERON_FRAME_MAX_MESSAGE_LENGTH, aeron_compute_max_message_length(1024 * 1024 * 1024));
146+
EXPECT_EQ(16 * 1024 * 1024, aeron_compute_max_message_length(512 * 1024 * 1024));
147+
}
148+
149+
TEST_F(UdpChannelTest, shouldCheckIfFrameIsValid)
150+
{
151+
aeron_frame_header_t header = {};
152+
153+
EXPECT_FALSE(aeron_is_frame_valid(&header, 1)); // length below min header length
154+
155+
header.version = 123;
156+
EXPECT_FALSE(aeron_is_frame_valid(&header, AERON_FRAME_HEADER_LENGTH)); // wrong version
157+
158+
header.version = AERON_FRAME_HEADER_VERSION;
159+
header.frame_length = 100;
160+
EXPECT_TRUE(aeron_is_frame_valid(&header, AERON_FRAME_HEADER_LENGTH + 1));
161+
header.type = 123;
162+
EXPECT_TRUE(aeron_is_frame_valid(&header, header.frame_length));
163+
header.flags = 0xAE;
164+
EXPECT_TRUE(aeron_is_frame_valid(&header, INT32_MAX));
165+
}
166+
139167
TEST_F(UdpChannelTest, shouldParseExplicitLocalAddressAndPortFormat)
140168
{
141169
ASSERT_EQ(parse_udp_channel("aeron:udp?interface=localhost:40123|endpoint=localhost:40124"), 0) << aeron_errmsg();

0 commit comments

Comments
 (0)